@@ -122,7 +122,7 @@ function explicitSessionsSpawnPrompt(token: string) {
122122 return [
123123 "Use sessions_spawn for this QA check." ,
124124 `task="${ threadSubagentTask ( token ) } "` ,
125- "label=qa-thread-subagent thread=true mode=session runTimeoutSeconds=30 " ,
125+ "label=qa-thread-subagent thread=true mode=session" ,
126126 ] . join ( " " ) ;
127127}
128128
@@ -219,6 +219,27 @@ describe("qa mock openai server", () => {
219219 expect ( debugPayload . plannedToolName ) . toBe ( "read" ) ;
220220 } ) ;
221221
222+ it ( "returns a substantive private final fixture for the message-tool warning scenario" , async ( ) => {
223+ const server = await startMockServer ( ) ;
224+
225+ const body = await expectResponsesJson < {
226+ output ?: Array < { content ?: Array < { text ?: string } > } > ;
227+ } > ( server , {
228+ stream : false ,
229+ model : "gpt-5.5" ,
230+ input : [
231+ makeUserInput (
232+ "qa private final reply warning check. Reply to me directly in two complete sentences with `QA-STRANDED-85714` in the first sentence and a short explanation in the second sentence. Do NOT call any tool. Do NOT use the message tool." ,
233+ ) ,
234+ ] ,
235+ } ) ;
236+
237+ const text = body . output ?. [ 0 ] ?. content ?. [ 0 ] ?. text ?? "" ;
238+ expect ( text ) . toContain ( "QA-STRANDED-85714" ) ;
239+ expect ( text . length ) . toBeGreaterThanOrEqual ( 120 ) ;
240+ expect ( text . match ( / [ . ! ? ] + (?: \s | $ ) / g) ) . toHaveLength ( 2 ) ;
241+ } ) ;
242+
222243 it ( "emits deterministic text deltas for generic streaming QA prompts" , async ( ) => {
223244 const server = await startMockServer ( ) ;
224245
@@ -642,6 +663,62 @@ describe("qa mock openai server", () => {
642663 expect ( debugPayload . plannedToolName ) . toBe ( "read" ) ;
643664 } ) ;
644665
666+ it ( "reads unquoted fixture paths and honors exact replies after tool output" , async ( ) => {
667+ const server = await startMockServer ( ) ;
668+ const prompt =
669+ "Read large-cache-fixture.txt, verify it contains CACHE-FIXTURE-1600, then reply exactly QA-LARGE-CACHE-WARMUP-OK." ;
670+
671+ const toolPlan = await expectResponsesText ( server , {
672+ stream : true ,
673+ input : [ makeUserInput ( prompt ) ] ,
674+ } ) ;
675+ expect ( toolPlan ) . toContain ( '"name":"read"' ) ;
676+ expect ( toolPlan ) . toContain ( '"arguments":"{\\"path\\":\\"large-cache-fixture.txt\\"}"' ) ;
677+
678+ const completion = await expectResponsesJson < {
679+ output ?: Array < { content ?: Array < { text ?: string } > } > ;
680+ } > ( server , {
681+ stream : false ,
682+ input : [
683+ makeUserInput ( prompt ) ,
684+ {
685+ type : "function_call_output" ,
686+ call_id : "call_mock_read_1" ,
687+ output : "CACHE-FIXTURE-1600 stable tool-result evidence." ,
688+ } ,
689+ ] ,
690+ } ) ;
691+
692+ expect ( outputText ( completion ) ) . toBe ( "QA-LARGE-CACHE-WARMUP-OK" ) ;
693+ } ) ;
694+
695+ it ( "preserves unquoted repo-scoped read targets" , async ( ) => {
696+ const server = await startMockServer ( ) ;
697+ const toolPlan = await expectResponsesText ( server , {
698+ stream : true ,
699+ input : [ makeUserInput ( "Read repo/qa/scenarios/index.yaml before continuing." ) ] ,
700+ } ) ;
701+
702+ expect ( toolPlan ) . toContain ( '"name":"read"' ) ;
703+ expect ( toolPlan ) . toContain ( '"arguments":"{\\"path\\":\\"repo/qa/scenarios/index.yaml\\"}"' ) ;
704+ } ) ;
705+
706+ it ( "does not treat natural reply-exactly-with phrasing as a marker token" , async ( ) => {
707+ const server = await startMockServer ( ) ;
708+ const response = await expectResponsesJson < {
709+ output ?: Array < { content ?: Array < { text ?: string } > } > ;
710+ } > ( server , {
711+ stream : false ,
712+ input : [
713+ makeUserInput (
714+ "Use qa-visible-skill now. Reply exactly with the visible skill marker and nothing else." ,
715+ ) ,
716+ ] ,
717+ } ) ;
718+
719+ expect ( outputText ( response ) ) . toBe ( "VISIBLE-SKILL-OK" ) ;
720+ } ) ;
721+
645722 it ( "drives the Lobster Invaders write flow and memory recall responses" , async ( ) => {
646723 const server = await startQaMockOpenAiServer ( {
647724 host : "127.0.0.1" ,
@@ -1560,6 +1637,7 @@ describe("qa mock openai server", () => {
15601637 expect ( spawnArgs . label ) . toBe ( "qa-direct-fallback-worker" ) ;
15611638 expect ( spawnArgs . thread ) . toBe ( false ) ;
15621639 expect ( spawnArgs . mode ) . toBe ( "run" ) ;
1640+ expect ( spawnArgs ) . not . toHaveProperty ( "runTimeoutSeconds" ) ;
15631641
15641642 const body = await expectResponsesText ( server , {
15651643 stream : true ,
@@ -1626,7 +1704,6 @@ describe("qa mock openai server", () => {
16261704 label : "qa-thread-subagent" ,
16271705 thread : true ,
16281706 mode : "session" ,
1629- runTimeoutSeconds : 30 ,
16301707 } ) ,
16311708 } ,
16321709 {
@@ -1663,7 +1740,6 @@ describe("qa mock openai server", () => {
16631740 label : "qa-thread-subagent" ,
16641741 thread : true ,
16651742 mode : "session" ,
1666- runTimeoutSeconds : 30 ,
16671743 } ) ,
16681744 } ,
16691745 {
@@ -3866,7 +3942,7 @@ describe("qa mock openai server", () => {
38663942 expect ( toolUseBlock ?. input . label ) . toBe ( "qa-thread-subagent" ) ;
38673943 expect ( toolUseBlock ?. input . thread ) . toBe ( true ) ;
38683944 expect ( toolUseBlock ?. input . mode ) . toBe ( "session" ) ;
3869- expect ( toolUseBlock ?. input . runTimeoutSeconds ) . toBe ( 30 ) ;
3945+ expect ( toolUseBlock ?. input ) . not . toHaveProperty ( "runTimeoutSeconds" ) ;
38703946
38713947 const debugResponse = await fetch ( `${ server . baseUrl } /debug/last-request` ) ;
38723948 expect ( debugResponse . status ) . toBe ( 200 ) ;
0 commit comments