@@ -25,6 +25,7 @@ import {
2525 executeFunctionToolCalls ,
2626 executeComputerActions ,
2727 executeHandoffCalls ,
28+ executeToolsAndSideEffects ,
2829} from '../src/runImplementation' ;
2930import { FunctionTool , FunctionToolResult , tool } from '../src/tool' ;
3031import { handoff } from '../src/handoff' ;
@@ -40,6 +41,7 @@ import {
4041 TEST_MODEL_RESPONSE_WITH_FUNCTION ,
4142 TEST_TOOL ,
4243 FakeModelProvider ,
44+ fakeModelMessage ,
4345} from './stubs' ;
4446import { computerTool } from '../src/tool' ;
4547import * as protocol from '../src/types/protocol' ;
@@ -790,3 +792,39 @@ describe('empty execution helpers', () => {
790792 expect ( comp ) . toEqual ( [ ] ) ;
791793 } ) ;
792794} ) ;
795+
796+ describe ( 'executeToolsAndSideEffects with text and tool calls' , ( ) => {
797+ it ( 'continues agent loop when model returns both text and tool calls' , async ( ) => {
798+ const runner = new Runner ( { tracingDisabled : true } ) ;
799+ const state = new RunState ( new RunContext ( ) , '' , TEST_AGENT , 1 ) ;
800+
801+ const responseWithBothTextAndTool : ModelResponse = {
802+ output : [
803+ TEST_MODEL_FUNCTION_CALL ,
804+ fakeModelMessage ( 'Some text response' ) ,
805+ ] ,
806+ usage : new Usage ( ) ,
807+ } ;
808+
809+ const processedResponse = processModelResponse (
810+ responseWithBothTextAndTool ,
811+ TEST_AGENT ,
812+ [ TEST_TOOL ] ,
813+ [ ] ,
814+ ) ;
815+
816+ const result = await withTrace ( 'test' , ( ) =>
817+ executeToolsAndSideEffects (
818+ TEST_AGENT ,
819+ '' ,
820+ [ ] ,
821+ responseWithBothTextAndTool ,
822+ processedResponse ,
823+ runner ,
824+ state ,
825+ ) ,
826+ ) ;
827+
828+ expect ( result . nextStep . type ) . toBe ( 'next_step_run_again' ) ;
829+ } ) ;
830+ } ) ;
0 commit comments