Skip to content

Commit 1a4910e

Browse files
committed
test(js/client): cover full chat-response payload survival
Asserts finish_reason, tool_calls, and usage are all surfaced to the chat() caller. Mutation-verified — reverting the fix fails on the finish_reason assertion.
1 parent 5f8aa4c commit 1a4910e

1 file changed

Lines changed: 61 additions & 0 deletions

File tree

js/test/client.test.ts

Lines changed: 61 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -163,3 +163,64 @@ describe('ZhubConnection chat() happy path', () => {
163163
await conn.stop();
164164
});
165165
});
166+
167+
describe('ZhubConnection chat() preserves full response payload', () => {
168+
let wss: WebSocketServer;
169+
let port: number;
170+
let closeServer: () => Promise<void>;
171+
172+
before(async () => {
173+
const s = await startServer();
174+
wss = s.wss;
175+
port = s.port;
176+
closeServer = s.close;
177+
178+
// Responds with a tool_calls finish — Python's chat() returns the whole
179+
// dict; JS previously dropped everything except `text`, losing tool_calls,
180+
// finish_reason, usage. Regression: must survive.
181+
wss.on('connection', (ws) => {
182+
ws.send(JSON.stringify({ type: 'registered', request_id: 'r0', payload: {} }));
183+
ws.on('message', (raw) => {
184+
const env = JSON.parse(raw.toString());
185+
if (env.type === 'chat-request') {
186+
ws.send(JSON.stringify({
187+
type: 'chat-response',
188+
request_id: env.request_id,
189+
payload: {
190+
text: '',
191+
finish_reason: 'tool_calls',
192+
tool_calls: [
193+
{ id: 'c_1', type: 'function', function: { name: 'lookup', arguments: '{"city":"Paris"}' } },
194+
],
195+
usage: { prompt_tokens: 12, completion_tokens: 7 },
196+
},
197+
}));
198+
}
199+
});
200+
});
201+
});
202+
203+
after(async () => {
204+
await closeServer();
205+
});
206+
207+
it('surfaces finish_reason, tool_calls, and usage alongside text', async () => {
208+
const conn = connect({
209+
aiName: 'test-ai',
210+
apiKey: 'zk_test',
211+
hubUrl: makeHubUrl(port),
212+
});
213+
214+
await new Promise<void>((r) => setTimeout(r, 100));
215+
216+
const result = await conn.chat([{ role: 'user', content: 'where' }], { timeoutMs: 5_000 });
217+
assert.equal(result.text, '');
218+
assert.equal(result.finish_reason, 'tool_calls');
219+
assert.deepEqual(result.tool_calls, [
220+
{ id: 'c_1', type: 'function', function: { name: 'lookup', arguments: '{"city":"Paris"}' } },
221+
]);
222+
assert.deepEqual(result.usage, { prompt_tokens: 12, completion_tokens: 7 });
223+
224+
await conn.stop();
225+
});
226+
});

0 commit comments

Comments
 (0)