@@ -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