@@ -98,6 +98,69 @@ async function writeLiveRuntimeToolEvidence(env: QaSuiteRuntimeEnv, toolName = "
9898 ] ) ;
9999}
100100
101+ async function runMockRuntimeToolFixtureWithOutputs ( params : {
102+ toolName : string ;
103+ happyArgs : Record < string , unknown > ;
104+ failureArgs : Record < string , unknown > ;
105+ happyOutput : string ;
106+ failureOutput : string ;
107+ } ) {
108+ const env = await makeEnv ( {
109+ mock : { baseUrl : "http://127.0.0.1:9999" } ,
110+ } ) ;
111+ const promptSnippet = `target=${ params . toolName } ` ;
112+ const failurePromptSnippet = `failure target=${ params . toolName } ` ;
113+ const happyCallId = `call-${ params . toolName } -happy` ;
114+ const failureCallId = `call-${ params . toolName } -failure` ;
115+ const fetchJson = vi
116+ . fn ( )
117+ . mockResolvedValueOnce ( [ ] )
118+ . mockResolvedValueOnce ( [
119+ {
120+ allInputText : promptSnippet ,
121+ plannedToolCallId : happyCallId ,
122+ plannedToolName : params . toolName ,
123+ plannedToolArgs : params . happyArgs ,
124+ } ,
125+ {
126+ allInputText : promptSnippet ,
127+ toolOutputCallId : happyCallId ,
128+ toolOutput : params . happyOutput ,
129+ } ,
130+ {
131+ allInputText : failurePromptSnippet ,
132+ plannedToolCallId : failureCallId ,
133+ plannedToolName : params . toolName ,
134+ plannedToolArgs : params . failureArgs ,
135+ } ,
136+ {
137+ allInputText : failurePromptSnippet ,
138+ toolOutputCallId : failureCallId ,
139+ toolOutput : params . failureOutput ,
140+ } ,
141+ ] ) ;
142+
143+ return runRuntimeToolFixture (
144+ env ,
145+ {
146+ toolName : params . toolName ,
147+ toolCoverage : {
148+ bucket : "openclaw-dynamic-integration" ,
149+ expectedLayer : "openclaw-dynamic" ,
150+ } ,
151+ promptSnippet,
152+ failurePromptSnippet,
153+ } ,
154+ {
155+ createSession : vi . fn ( async ( _env , _label , key ) => key ! ) ,
156+ readEffectiveTools : vi . fn ( async ( ) => new Set ( [ params . toolName ] ) ) ,
157+ runAgentPrompt : vi . fn ( async ( ) => ( { } ) ) ,
158+ fetchJson,
159+ ensureImageGenerationConfigured : vi . fn ( ) ,
160+ } ,
161+ ) ;
162+ }
163+
101164afterEach ( async ( ) => {
102165 await Promise . all (
103166 tempRoots . splice ( 0 ) . map ( ( tempRoot ) => fs . rm ( tempRoot , { recursive : true , force : true } ) ) ,
@@ -595,6 +658,59 @@ describe("runtime tool fixture", () => {
595658 ) . rejects . toThrow ( "expected mock failure-path tool failure output for read" ) ;
596659 } ) ;
597660
661+ it . each ( [
662+ {
663+ name : "required-field" ,
664+ toolName : "sessions_spawn" ,
665+ happyArgs : { task : "reply ok" } ,
666+ happyOutput : "accepted" ,
667+ failureOutput : "task required" ,
668+ } ,
669+ {
670+ name : "unavailable-provider" ,
671+ toolName : "web_search" ,
672+ happyArgs : { query : "OpenClaw runtime parity fixed query" } ,
673+ happyOutput : "result" ,
674+ failureOutput : "web_search is disabled or no provider is available." ,
675+ } ,
676+ ] ) ( "accepts $name messages as mock failure fixture output" , async ( fixture ) => {
677+ const details = await runMockRuntimeToolFixtureWithOutputs ( {
678+ ...fixture ,
679+ failureArgs : { __qaFailureMode : "denied-input" } ,
680+ } ) ;
681+
682+ expect ( details ) . toContain ( `${ fixture . toolName } mock provider failure planned args` ) ;
683+ } ) ;
684+
685+ it . each ( [
686+ {
687+ name : "neutral required-text" ,
688+ toolName : "sessions_spawn" ,
689+ happyArgs : { task : "reply ok" } ,
690+ happyOutput : "accepted" ,
691+ failureOutput : "no action required" ,
692+ expectedError : "expected mock failure-path tool failure output for sessions_spawn" ,
693+ } ,
694+ {
695+ name : "unavailable-provider happy output" ,
696+ toolName : "web_search" ,
697+ happyArgs : { query : "OpenClaw runtime parity fixed query" } ,
698+ happyOutput : "web_search is disabled or no provider is available." ,
699+ failureOutput : "web_search is disabled or no provider is available." ,
700+ expectedError : "expected mock happy-path successful tool output for web_search" ,
701+ } ,
702+ ] ) ( "rejects $name as mock fixture output" , async ( fixture ) => {
703+ await expect (
704+ runMockRuntimeToolFixtureWithOutputs ( {
705+ toolName : fixture . toolName ,
706+ happyArgs : fixture . happyArgs ,
707+ failureArgs : { __qaFailureMode : "denied-input" } ,
708+ happyOutput : fixture . happyOutput ,
709+ failureOutput : fixture . failureOutput ,
710+ } ) ,
711+ ) . rejects . toThrow ( fixture . expectedError ) ;
712+ } ) ;
713+
598714 it ( "allows successful happy-path tool output to mention errors" , async ( ) => {
599715 const env = await makeEnv ( {
600716 mock : { baseUrl : "http://127.0.0.1:9999" } ,
0 commit comments