@@ -437,6 +437,78 @@ func TestOpenAIChatCompletions(t *testing.T) {
437437 })
438438 }
439439 })
440+
441+ t .Run ("streaming injected tool call only" , func (t * testing.T ) {
442+ t .Parallel ()
443+
444+ arc := txtar .Parse (fixtures .OaiChatStreamingToolCallOnly )
445+ t .Logf ("%s: %s" , t .Name (), arc .Comment )
446+
447+ files := filesMap (arc )
448+ require .Len (t , files , 2 )
449+ require .Contains (t , files , fixtureRequest )
450+ require .Contains (t , files , fixtureStreamingResponse )
451+
452+ reqBody := files [fixtureRequest ]
453+
454+ // Add the stream param to the request.
455+ newBody , err := setJSON (reqBody , "stream" , true )
456+ require .NoError (t , err )
457+ reqBody = newBody
458+
459+ ctx , cancel := context .WithTimeout (t .Context (), time .Second * 30 )
460+ t .Cleanup (cancel )
461+ srv := newMockServer (ctx , t , files , nil )
462+ t .Cleanup (srv .Close )
463+
464+ fmt .Printf ("########## Fixture streaming content length: %d\n " , len (files [fixtureStreamingResponse ]))
465+ fmt .Printf ("########## Fixture streaming content:\n %s\n " , string (files [fixtureStreamingResponse ]))
466+
467+ recorderClient := & testutil.MockRecorder {}
468+
469+ // Setup MCP proxies with the tool from the fixture
470+ mcpProxiers , mcpCalls := setupMCPServerProxiesForTest (t , testTracer )
471+ mcpMgr := mcp .NewServerProxyManager (mcpProxiers , testTracer )
472+ require .NoError (t , mcpMgr .Init (ctx ))
473+
474+ logger := slogtest .Make (t , & slogtest.Options {IgnoreErrors : false }).Leveled (slog .LevelDebug )
475+ providers := []aibridge.Provider {provider .NewOpenAI (openaiCfg (srv .URL , apiKey ))}
476+ b , err := aibridge .NewRequestBridge (t .Context (), providers , recorderClient , mcpMgr , logger , nil , testTracer )
477+ require .NoError (t , err )
478+
479+ mockSrv := httptest .NewUnstartedServer (b )
480+ t .Cleanup (mockSrv .Close )
481+ mockSrv .Config .BaseContext = func (_ net.Listener ) context.Context {
482+ return aibcontext .AsActor (ctx , userID , nil )
483+ }
484+ mockSrv .Start ()
485+
486+ req := createOpenAIChatCompletionsReq (t , mockSrv .URL , reqBody )
487+
488+ client := & http.Client {}
489+ resp , err := client .Do (req )
490+ require .NoError (t , err )
491+ require .Equal (t , http .StatusOK , resp .StatusCode )
492+ defer resp .Body .Close ()
493+
494+ // Verify the MCP tool was actually invoked
495+ invocations := mcpCalls .getCallsByTool (mockToolName )
496+ require .Len (t , invocations , 1 , "expected MCP tool to be invoked" )
497+
498+ // Verify tool was invoked with the args from the fixture
499+ expected , err := json .Marshal (map [string ]any {"owner" : "me" })
500+ require .NoError (t , err )
501+ actual , err := json .Marshal (invocations [0 ])
502+ require .NoError (t , err )
503+ require .EqualValues (t , expected , actual )
504+
505+ // Verify tool usage was recorded
506+ toolUsages := recorderClient .RecordedToolUsages ()
507+ require .Len (t , toolUsages , 1 )
508+ assert .Equal (t , mockToolName , toolUsages [0 ].Tool )
509+
510+ recorderClient .VerifyAllInterceptionsEnded (t )
511+ })
440512}
441513
442514func TestSimple (t * testing.T ) {
0 commit comments