stable-harness 0.0.104 → 0.0.105

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/adapter-deepagents",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -15,7 +15,7 @@
15
15
  "@langchain/node-vfs": "^0.1.4",
16
16
  "@langchain/ollama": "^1.2.7",
17
17
  "@langchain/openai": "^1.4.5",
18
- "@stable-harness/core": "0.0.104",
18
+ "@stable-harness/core": "0.0.105",
19
19
  "deepagents": "^1.10.1",
20
20
  "langchain": "^1.4.0"
21
21
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/adapter-langgraph",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,6 +11,6 @@
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
13
  "@langchain/langgraph": "^1.3.0",
14
- "@stable-harness/core": "0.0.104"
14
+ "@stable-harness/core": "0.0.105"
15
15
  }
16
16
  }
@@ -1 +1 @@
1
- import{evaluateToolGuardrails as t}from"./policy/tool-invocation.js";import{toolCircuitOpenEvent as o,toolFailureEvent as e}from"./tool-failure.js";export async function runDirectToolCall(o){const e=o.request.toolCall;if(!e)throw new Error("Direct tool call request is missing");if(!o.gateway)throw new Error("Runtime tool gateway is not configured");const r=await async function resolveDirectToolCall(t){if(t.agent.tools.includes(t.toolId)&&t.gateway.get(t.toolId))return{toolId:t.toolId,args:t.args};const o=await(t.gateway.repairToolCall?.({toolId:t.toolId,args:t.args,allowedToolIds:t.agent.tools,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,requestInput:t.request.input,approvalIds:readApprovalIds(t.request.metadata)}}));if(o&&t.agent.tools.includes(o.toolId)&&t.gateway.get(o.toolId))return emitToolRepair(t,"repaired",o.toolId),o;if(!t.agent.tools.includes(t.toolId))throw emitToolRepair(t,"blocked",void 0,`Tool ${t.toolId} is not assigned to agent ${t.agent.id}`),new Error(`Tool ${t.toolId} is not assigned to agent ${t.agent.id}`);throw emitToolRepair(t,"blocked",void 0,`Tool is not registered: ${t.toolId}`),new Error(`Tool is not registered: ${t.toolId}`)}({gateway:o.gateway,workspace:o.workspace,requestId:o.requestId,sessionId:o.sessionId,agent:o.agent,emit:o.emit,request:o.request,toolId:e.toolId,args:e.args});o.emit({type:"runtime.tool.direct.started",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:r.toolId});const s=t({agent:o.agent,args:r.args,events:o.events??[],toolId:r.toolId},o.toolGuardrails);if(s)return o.emit({type:"runtime.tool.direct.completed",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:r.toolId,output:s.eventOutput}),{text:s.modelOutput,metadata:{toolCall:{toolId:r.toolId},controlStatus:s.status}};if(o.toolFailureTracker?.isCircuitOpen(r.toolId)){const t=new Error(`Tool circuit is open: ${r.toolId}`);throw emitToolFailure(o,r.toolId,t),t}const a=await async function invokeToolWithFailureEvents(t,o){try{return await t.gateway.invoke({toolId:o.toolId,args:o.args,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,requestInput:t.request.input,approvalIds:readApprovalIds(t.request.metadata)}})}catch(e){throw emitToolFailure(t,o.toolId,e),e}}(o,r);return o.toolFailureTracker?.recordSuccess(a.toolId),o.emit({type:"runtime.tool.direct.completed",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:a.toolId,output:a.output}),{text:(i=a.output,"string"==typeof i?i:JSON.stringify(i)),metadata:{toolCall:{toolId:a.toolId}}};var i}function emitToolFailure(t,r,s){const a=e({requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,toolId:r,error:s});t.emit(a),t.toolFailureTracker?.recordFailure(r)&&t.emit(o({requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,toolId:r,reason:"runtime.tool.failure"===a.type?a.failure.reason:"unknown"}))}function emitToolRepair(t,o,e,r){t.emit({type:"runtime.inventory.repair",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,status:o,diagnostic:{layer:"tool",owner:"stable_runtime_policy",originalId:t.toolId,repairedId:e,candidateIds:t.agent.tools,reason:r}})}function readApprovalIds(t){const o=t?.approvalIds??t?.approvalId;return"string"==typeof o&&o.trim()?[o.trim()]:Array.isArray(o)?o.filter(t=>"string"==typeof t&&t.trim().length>0):void 0}
1
+ import{evaluateToolGuardrails as t}from"./policy/tool-invocation.js";import{toolCircuitOpenEvent as o,toolFailureEvent as e}from"./tool-failure.js";export async function runDirectToolCall(o){const e=o.request.toolCall;if(!e)throw new Error("Direct tool call request is missing");if(!o.gateway)throw new Error("Runtime tool gateway is not configured");const r=await async function resolveDirectToolCall(t){if(t.agent.tools.includes(t.toolId)&&t.gateway.get(t.toolId))return{toolId:t.toolId,args:t.args};const o=await(t.gateway.repairToolCall?.({toolId:t.toolId,args:t.args,allowedToolIds:t.agent.tools,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,requestInput:t.request.input,approvalIds:readApprovalIds(t.request.metadata)}}));if(o&&t.agent.tools.includes(o.toolId)&&t.gateway.get(o.toolId))return emitToolRepair(t,"repaired",o.toolId),o;if(!t.agent.tools.includes(t.toolId))throw emitToolRepair(t,"blocked",void 0,`Tool ${t.toolId} is not assigned to agent ${t.agent.id}`),new Error(`Tool ${t.toolId} is not assigned to agent ${t.agent.id}`);throw emitToolRepair(t,"blocked",void 0,`Tool is not registered: ${t.toolId}`),new Error(`Tool is not registered: ${t.toolId}`)}({gateway:o.gateway,workspace:o.workspace,requestId:o.requestId,sessionId:o.sessionId,agent:o.agent,emit:o.emit,request:o.request,toolId:e.toolId,args:e.args});o.emit({type:"runtime.tool.direct.started",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:r.toolId});const s=t({agent:o.agent,args:r.args,events:o.events??[],toolId:r.toolId},o.toolGuardrails);if(s)return o.emit({type:"runtime.tool.direct.completed",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:r.toolId,output:s.eventOutput}),{text:s.modelOutput,metadata:{toolCall:{toolId:r.toolId},controlStatus:s.status}};if(o.toolFailureTracker?.isCircuitOpen(r.toolId)){const t=new Error(`Tool circuit is open: ${r.toolId}`);throw emitToolFailure(o,r.toolId,t),t}const a=await async function invokeToolWithFailureEvents(t,o){try{return await t.gateway.invoke({toolId:o.toolId,args:o.args,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,requestInput:t.request.input,approvalIds:readApprovalIds(t.request.metadata)}})}catch(e){throw emitToolFailure(t,o.toolId,e),e}}(o,r);return o.toolFailureTracker?.recordSuccess(a.toolId),o.emit({type:"runtime.tool.direct.completed",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:a.toolId,output:a.output}),{text:stringifyToolOutput(a.output),metadata:{toolCall:{toolId:a.toolId}}}}function emitToolFailure(t,r,s){const a=e({requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,toolId:r,error:s});t.emit(a),t.toolFailureTracker?.recordFailure(r)&&t.emit(o({requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,toolId:r,reason:"runtime.tool.failure"===a.type?a.failure.reason:"unknown"}))}function emitToolRepair(t,o,e,r){t.emit({type:"runtime.inventory.repair",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,status:o,diagnostic:{layer:"tool",owner:"stable_runtime_policy",originalId:t.toolId,repairedId:e,candidateIds:t.agent.tools,reason:r}})}function stringifyToolOutput(t){if("string"==typeof t)return t;const o=JSON.stringify(t);return"string"==typeof o?o:""}function readApprovalIds(t){const o=t?.approvalIds??t?.approvalId;return"string"==typeof o&&o.trim()?[o.trim()]:Array.isArray(o)?o.filter(t=>"string"==typeof t&&t.trim().length>0):void 0}
@@ -1 +1 @@
1
- import{assertNoDeclaredActionOmissionOutput as e}from"../../recovery/control-omission.js";import{buildRawArgsRecoveryRequest as t,buildRawArgsToolEvidenceRecoveryRequest as o,hasUniqueRawArgsTool as r,matchUniqueRawArgsTool as a}from"../../recovery/raw-args.js";import{assertNoProgressOnlyToolIntentOutput as s,assertNoRawToolCallOutput as l,assertNoRawToolResultOutput as i,assertNoToolExecutionErrorOutput as u,buildEvidenceSynthesisOutput as n,buildResultRecoveryRequest as c,containsRawToolCallOutput as p,rawToolCallFailureMessage as y,rawToolCallOutputPreview as d,toolCallRecoveryEnabled as v}from"../../recovery/tool-call.js";export async function recoverAdapterResultOutput(o){let g=o.result,w=o.request;const R=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,o="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,r="object"!=typeof o||null===o||Array.isArray(o)?void 0:o.maxResultRecoveryAttempts;return"number"==typeof r&&Number.isInteger(r)&&r>0?r:3}(o.recoveryPolicy),m=new Set,_=new Set;for(let e=0;;e+=1){const r=o.store.getRun(o.requestId)?.events??[],s=a({output:g.text,agent:o.agent,workspace:o.workspace,toolGateway:o.toolGateway,events:r,policy:o.recoveryPolicy}),l=s?rawArgsToolKey(s):void 0,i=l&&!m.has(l)?t({request:w,output:g.text,agent:o.agent,workspace:o.workspace,toolGateway:o.toolGateway,events:r,policy:o.recoveryPolicy}):void 0,u=e<R?c({request:w,output:g.text,events:r,availableToolIds:o.agent.tools,policy:o.recoveryPolicy}):void 0,n=i??u;if(!n)break;if(n===i&&m.add(l),w=n,emitRepair(o,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(g.text,o.agent.tools)),g=await o.runAdapter(n),emitRepair(o,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(g.text,o.agent.tools)),n===i){const t=await recoverRepeatedRawArgsByToolGateway(o,w,g,m,_,e+1);t&&(w=t.request,g=t.result)}}return function finalizeRecoveredOutput(t,o){if(!v(t.recoveryPolicy))return o;let a=!1;if(p(o.text,t.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(t.request.metadata)){const e=o.text;o={...o,text:y(),metadata:{...o.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(e,t.agent.tools))}const c=n({request:t.request,output:o.text,events:t.store.getRun(t.requestId)?.events??[],policy:t.recoveryPolicy});return c&&(a=!0,o={...o,text:c,metadata:{...o.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(t,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),a||(p(o.text,t.recoveryPolicy)&&emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(o.text,t.agent.tools)),l(o.text,t.recoveryPolicy),function assertNoRawArgsToolOutput(e,t){if(r({output:t,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],policy:e.recoveryPolicy}))throw new Error(`Adapter returned raw tool argument JSON as the final answer after recovery. The backend must execute the matching tool instead. Output preview: ${d(t)}`)}(t,o.text),s(o.text,t.agent.tools,t.recoveryPolicy),i(o.text,t.store.getRun(t.requestId)?.events??[],t.recoveryPolicy),u(o.text,t.recoveryPolicy),e({output:o.text,events:t.store.getRun(t.requestId)?.events??[],availableToolIds:t.agent.tools})),o}(o,g)}async function recoverRepeatedRawArgsByToolGateway(e,t,r,s,l,i){const u=a({output:r.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],policy:e.recoveryPolicy});if(!u||!e.runRecoveredToolCall)return;const n=rawArgsToolKey(u);if(!s.has(n)||l.has(n))return;l.add(n),emitRepair(e,"runtime.repair.started","result_output",i,"raw_args_tool_gateway_recovery",void 0,repairDiagnostics(r.text,e.agent.tools));const c=await e.runRecoveredToolCall(u.toolId,u.args),p=o({request:t,match:u,toolOutput:c.text}),y=await e.runAdapter(p);return emitRepair(e,"runtime.repair.completed","result_output",i,"raw_args_tool_gateway_recovery","retried",repairDiagnostics(y.text,e.agent.tools)),{request:p,result:y}}function emitRepair(e,t,o,r,a,s,l){const i={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...l?{diagnostics:l}:{}};e.emit("runtime.repair.started"===t?{type:t,...i}:{type:t,...i,outcome:s??"retried"})}function repairDiagnostics(e,t){return{outputPreview:d(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])new RegExp(`(?:^|[^A-Za-z0-9_-])${escapeRegexp(r)}(?:$|[^A-Za-z0-9_-])`,"u").test(e)&&o.add(r);return[...o]}function escapeRegexp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&")}function rawArgsToolKey(e){return`${e.toolId}:${JSON.stringify(e.args)}`}
1
+ import{assertNoDeclaredActionOmissionOutput as e}from"../../recovery/control-omission.js";import{buildRawArgsRecoveryRequest as t,buildRawArgsToolEvidenceRecoveryRequest as o,hasUniqueRawArgsTool as r,matchUniqueRawArgsTool as a}from"../../recovery/raw-args.js";import{assertNoProgressOnlyToolIntentOutput as s,assertNoRawToolCallOutput as l,assertNoRawToolResultOutput as u,assertNoToolExecutionErrorOutput as i,buildEvidenceSynthesisOutput as n,buildResultRecoveryRequest as c,containsRawToolCallOutput as p,rawToolCallFailureMessage as d,rawToolCallOutputPreview as y,toolCallRecoveryEnabled as v}from"../../recovery/tool-call.js";import{controlGaps as g}from"../../quality/event-evidence.js";export async function recoverAdapterResultOutput(o){let g=o.result,m=o.request;const w=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,o="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,r="object"!=typeof o||null===o||Array.isArray(o)?void 0:o.maxResultRecoveryAttempts;return"number"==typeof r&&Number.isInteger(r)&&r>0?r:3}(o.recoveryPolicy),R=new Set,_=new Set;for(let e=0;;e+=1){const r=o.store.getRun(o.requestId)?.events??[],s=a({output:g.text,agent:o.agent,workspace:o.workspace,toolGateway:o.toolGateway,events:r,policy:o.recoveryPolicy}),l=s?rawArgsToolKey(s):void 0,u=l&&!R.has(l)?t({request:m,output:g.text,agent:o.agent,workspace:o.workspace,toolGateway:o.toolGateway,events:r,policy:o.recoveryPolicy}):void 0,i=e<w?c({request:m,output:g.text,events:r,availableToolIds:o.agent.tools,policy:o.recoveryPolicy}):void 0,n=u??i;if(!n)break;if(n===u&&R.add(l),m=n,emitRepair(o,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(g.text,o.agent.tools)),g=await o.runAdapter(n),emitRepair(o,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(g.text,o.agent.tools)),n===u){const t=await recoverRepeatedRawArgsByToolGateway(o,m,g,R,_,e+1);t&&(m=t.request,g=t.result)}}return function finalizeRecoveredOutput(t,o){if(!v(t.recoveryPolicy))return o;let a=!1;if(p(o.text,t.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(t.request.metadata)){const e=o.text;o={...o,text:d(),metadata:{...o.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(e,t.agent.tools))}const c=n({request:t.request,output:o.text,events:t.store.getRun(t.requestId)?.events??[],policy:t.recoveryPolicy});return c&&(a=!0,o={...o,text:c,metadata:{...o.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(t,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),a||(p(o.text,t.recoveryPolicy)&&emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(o.text,t.agent.tools)),l(o.text,t.recoveryPolicy),function assertNoRawArgsToolOutput(e,t){if(r({output:t,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],policy:e.recoveryPolicy}))throw new Error(`Adapter returned raw tool argument JSON as the final answer after recovery. The backend must execute the matching tool instead. Output preview: ${y(t)}`)}(t,o.text),s(o.text,t.agent.tools,t.recoveryPolicy),u(o.text,t.store.getRun(t.requestId)?.events??[],t.recoveryPolicy),i(o.text,t.recoveryPolicy),e({output:o.text,events:t.store.getRun(t.requestId)?.events??[],availableToolIds:t.agent.tools})),o}(o,g)}async function recoverRepeatedRawArgsByToolGateway(e,t,r,s,l,u){const i=a({output:r.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],policy:e.recoveryPolicy});if(!i||!e.runRecoveredToolCall)return;const n=rawArgsToolKey(i);if(!s.has(n)||l.has(n))return;l.add(n),emitRepair(e,"runtime.repair.started","result_output",u,"raw_args_tool_gateway_recovery",void 0,repairDiagnostics(r.text,e.agent.tools));const c=function visibleRecoveredToolOutput(e){return("string"==typeof e.text?e.text.trim():"")||"The recovered tool completed successfully but returned no user-visible output."}(await e.runRecoveredToolCall(i.toolId,i.args)),p=o({request:t,match:i,toolOutput:c}),d=await e.runAdapter(p),y=d.text.trim()?d:{...d,text:buildEmptyRecoveredToolBlocker({match:i,toolOutput:c,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...d.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool"}}};return emitRepair(e,"runtime.repair.completed","result_output",u,"raw_args_tool_gateway_recovery","retried",repairDiagnostics(y.text,e.agent.tools)),{request:p,result:y}}function emitRepair(e,t,o,r,a,s,l){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...l?{diagnostics:l}:{}};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:s??"retried"})}function repairDiagnostics(e,t){return{outputPreview:y(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])new RegExp(`(?:^|[^A-Za-z0-9_-])${escapeRegexp(r)}(?:$|[^A-Za-z0-9_-])`,"u").test(e)&&o.add(r);return[...o]}function escapeRegexp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&")}function rawArgsToolKey(e){return`${e.toolId}:${JSON.stringify(e.args)}`}function buildEmptyRecoveredToolBlocker(e){const t=g(e.events);return["Stable runtime recovery executed the matched declared tool, but the backend returned no user-facing output after receiving the executed evidence.","",`Executed tool: ${e.match.toolId}`,"","Executed JSON arguments:",JSON.stringify(e.match.args),"","Executed tool evidence:",e.toolOutput,...t.length>0?["","Unresolved control gaps:",...t.map(e=>`- ${e}`)]:[]].join("\n")}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/core",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,7 +11,7 @@
11
11
  ".": "./dist/index.js"
12
12
  },
13
13
  "peerDependencies": {
14
- "@stable-harness/governance": "0.0.104",
15
- "@stable-harness/memory": "0.0.104"
14
+ "@stable-harness/governance": "0.0.105",
15
+ "@stable-harness/memory": "0.0.105"
16
16
  }
17
17
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/governance",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/memory",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/protocols",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -10,6 +10,6 @@
10
10
  "main": "dist/src/index.js",
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
- "@stable-harness/core": "0.0.104"
13
+ "@stable-harness/core": "0.0.105"
14
14
  }
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/tool-gateway",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/workspace-yaml",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,6 +11,6 @@
11
11
  ".": "./dist/index.js"
12
12
  },
13
13
  "peerDependencies": {
14
- "@stable-harness/core": "0.0.104"
14
+ "@stable-harness/core": "0.0.105"
15
15
  }
16
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stable-harness",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "description": "Stable application runtime and operator control plane for agent workspaces.",
6
6
  "license": "Apache-2.0",
@@ -82,14 +82,14 @@
82
82
  "@langchain/node-vfs": "^0.1.4",
83
83
  "@langchain/ollama": "^1.2.7",
84
84
  "@langchain/openai": "^1.4.5",
85
- "@stable-harness/adapter-deepagents": "0.0.104",
86
- "@stable-harness/adapter-langgraph": "0.0.104",
87
- "@stable-harness/core": "0.0.104",
88
- "@stable-harness/governance": "0.0.104",
89
- "@stable-harness/memory": "0.0.104",
90
- "@stable-harness/protocols": "0.0.104",
91
- "@stable-harness/tool-gateway": "0.0.104",
92
- "@stable-harness/workspace-yaml": "0.0.104",
85
+ "@stable-harness/adapter-deepagents": "0.0.105",
86
+ "@stable-harness/adapter-langgraph": "0.0.105",
87
+ "@stable-harness/core": "0.0.105",
88
+ "@stable-harness/governance": "0.0.105",
89
+ "@stable-harness/memory": "0.0.105",
90
+ "@stable-harness/protocols": "0.0.105",
91
+ "@stable-harness/tool-gateway": "0.0.105",
92
+ "@stable-harness/workspace-yaml": "0.0.105",
93
93
  "deepagents": "^1.10.1",
94
94
  "langchain": "^1.4.0",
95
95
  "yaml": "^2.8.2",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/adapter-deepagents",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -15,7 +15,7 @@
15
15
  "@langchain/node-vfs": "^0.1.4",
16
16
  "@langchain/ollama": "^1.2.7",
17
17
  "@langchain/openai": "^1.4.5",
18
- "@stable-harness/core": "0.0.104",
18
+ "@stable-harness/core": "0.0.105",
19
19
  "deepagents": "^1.10.1",
20
20
  "langchain": "^1.4.0"
21
21
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/adapter-langgraph",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,6 +11,6 @@
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
13
  "@langchain/langgraph": "^1.3.0",
14
- "@stable-harness/core": "0.0.104"
14
+ "@stable-harness/core": "0.0.105"
15
15
  }
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/cli",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -14,12 +14,12 @@
14
14
  "types": "dist/src/index.d.ts",
15
15
  "peerDependencies": {
16
16
  "@langchain/langgraph-api": "^1.2.1",
17
- "@stable-harness/adapter-deepagents": "0.0.104",
18
- "@stable-harness/adapter-langgraph": "0.0.104",
19
- "@stable-harness/core": "0.0.104",
20
- "@stable-harness/memory": "0.0.104",
21
- "@stable-harness/protocols": "0.0.104",
22
- "@stable-harness/tool-gateway": "0.0.104",
23
- "@stable-harness/workspace-yaml": "0.0.104"
17
+ "@stable-harness/adapter-deepagents": "0.0.105",
18
+ "@stable-harness/adapter-langgraph": "0.0.105",
19
+ "@stable-harness/core": "0.0.105",
20
+ "@stable-harness/memory": "0.0.105",
21
+ "@stable-harness/protocols": "0.0.105",
22
+ "@stable-harness/tool-gateway": "0.0.105",
23
+ "@stable-harness/workspace-yaml": "0.0.105"
24
24
  }
25
25
  }
@@ -1 +1 @@
1
- import{evaluateToolGuardrails as t}from"./policy/tool-invocation.js";import{toolCircuitOpenEvent as o,toolFailureEvent as e}from"./tool-failure.js";export async function runDirectToolCall(o){const e=o.request.toolCall;if(!e)throw new Error("Direct tool call request is missing");if(!o.gateway)throw new Error("Runtime tool gateway is not configured");const r=await async function resolveDirectToolCall(t){if(t.agent.tools.includes(t.toolId)&&t.gateway.get(t.toolId))return{toolId:t.toolId,args:t.args};const o=await(t.gateway.repairToolCall?.({toolId:t.toolId,args:t.args,allowedToolIds:t.agent.tools,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,requestInput:t.request.input,approvalIds:readApprovalIds(t.request.metadata)}}));if(o&&t.agent.tools.includes(o.toolId)&&t.gateway.get(o.toolId))return emitToolRepair(t,"repaired",o.toolId),o;if(!t.agent.tools.includes(t.toolId))throw emitToolRepair(t,"blocked",void 0,`Tool ${t.toolId} is not assigned to agent ${t.agent.id}`),new Error(`Tool ${t.toolId} is not assigned to agent ${t.agent.id}`);throw emitToolRepair(t,"blocked",void 0,`Tool is not registered: ${t.toolId}`),new Error(`Tool is not registered: ${t.toolId}`)}({gateway:o.gateway,workspace:o.workspace,requestId:o.requestId,sessionId:o.sessionId,agent:o.agent,emit:o.emit,request:o.request,toolId:e.toolId,args:e.args});o.emit({type:"runtime.tool.direct.started",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:r.toolId});const s=t({agent:o.agent,args:r.args,events:o.events??[],toolId:r.toolId},o.toolGuardrails);if(s)return o.emit({type:"runtime.tool.direct.completed",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:r.toolId,output:s.eventOutput}),{text:s.modelOutput,metadata:{toolCall:{toolId:r.toolId},controlStatus:s.status}};if(o.toolFailureTracker?.isCircuitOpen(r.toolId)){const t=new Error(`Tool circuit is open: ${r.toolId}`);throw emitToolFailure(o,r.toolId,t),t}const a=await async function invokeToolWithFailureEvents(t,o){try{return await t.gateway.invoke({toolId:o.toolId,args:o.args,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,requestInput:t.request.input,approvalIds:readApprovalIds(t.request.metadata)}})}catch(e){throw emitToolFailure(t,o.toolId,e),e}}(o,r);return o.toolFailureTracker?.recordSuccess(a.toolId),o.emit({type:"runtime.tool.direct.completed",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:a.toolId,output:a.output}),{text:(i=a.output,"string"==typeof i?i:JSON.stringify(i)),metadata:{toolCall:{toolId:a.toolId}}};var i}function emitToolFailure(t,r,s){const a=e({requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,toolId:r,error:s});t.emit(a),t.toolFailureTracker?.recordFailure(r)&&t.emit(o({requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,toolId:r,reason:"runtime.tool.failure"===a.type?a.failure.reason:"unknown"}))}function emitToolRepair(t,o,e,r){t.emit({type:"runtime.inventory.repair",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,status:o,diagnostic:{layer:"tool",owner:"stable_runtime_policy",originalId:t.toolId,repairedId:e,candidateIds:t.agent.tools,reason:r}})}function readApprovalIds(t){const o=t?.approvalIds??t?.approvalId;return"string"==typeof o&&o.trim()?[o.trim()]:Array.isArray(o)?o.filter(t=>"string"==typeof t&&t.trim().length>0):void 0}
1
+ import{evaluateToolGuardrails as t}from"./policy/tool-invocation.js";import{toolCircuitOpenEvent as o,toolFailureEvent as e}from"./tool-failure.js";export async function runDirectToolCall(o){const e=o.request.toolCall;if(!e)throw new Error("Direct tool call request is missing");if(!o.gateway)throw new Error("Runtime tool gateway is not configured");const r=await async function resolveDirectToolCall(t){if(t.agent.tools.includes(t.toolId)&&t.gateway.get(t.toolId))return{toolId:t.toolId,args:t.args};const o=await(t.gateway.repairToolCall?.({toolId:t.toolId,args:t.args,allowedToolIds:t.agent.tools,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,requestInput:t.request.input,approvalIds:readApprovalIds(t.request.metadata)}}));if(o&&t.agent.tools.includes(o.toolId)&&t.gateway.get(o.toolId))return emitToolRepair(t,"repaired",o.toolId),o;if(!t.agent.tools.includes(t.toolId))throw emitToolRepair(t,"blocked",void 0,`Tool ${t.toolId} is not assigned to agent ${t.agent.id}`),new Error(`Tool ${t.toolId} is not assigned to agent ${t.agent.id}`);throw emitToolRepair(t,"blocked",void 0,`Tool is not registered: ${t.toolId}`),new Error(`Tool is not registered: ${t.toolId}`)}({gateway:o.gateway,workspace:o.workspace,requestId:o.requestId,sessionId:o.sessionId,agent:o.agent,emit:o.emit,request:o.request,toolId:e.toolId,args:e.args});o.emit({type:"runtime.tool.direct.started",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:r.toolId});const s=t({agent:o.agent,args:r.args,events:o.events??[],toolId:r.toolId},o.toolGuardrails);if(s)return o.emit({type:"runtime.tool.direct.completed",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:r.toolId,output:s.eventOutput}),{text:s.modelOutput,metadata:{toolCall:{toolId:r.toolId},controlStatus:s.status}};if(o.toolFailureTracker?.isCircuitOpen(r.toolId)){const t=new Error(`Tool circuit is open: ${r.toolId}`);throw emitToolFailure(o,r.toolId,t),t}const a=await async function invokeToolWithFailureEvents(t,o){try{return await t.gateway.invoke({toolId:o.toolId,args:o.args,context:{workspaceRoot:t.workspace.root,requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,requestInput:t.request.input,approvalIds:readApprovalIds(t.request.metadata)}})}catch(e){throw emitToolFailure(t,o.toolId,e),e}}(o,r);return o.toolFailureTracker?.recordSuccess(a.toolId),o.emit({type:"runtime.tool.direct.completed",requestId:o.requestId,sessionId:o.sessionId,agentId:o.agent.id,toolId:a.toolId,output:a.output}),{text:stringifyToolOutput(a.output),metadata:{toolCall:{toolId:a.toolId}}}}function emitToolFailure(t,r,s){const a=e({requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,toolId:r,error:s});t.emit(a),t.toolFailureTracker?.recordFailure(r)&&t.emit(o({requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,toolId:r,reason:"runtime.tool.failure"===a.type?a.failure.reason:"unknown"}))}function emitToolRepair(t,o,e,r){t.emit({type:"runtime.inventory.repair",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,status:o,diagnostic:{layer:"tool",owner:"stable_runtime_policy",originalId:t.toolId,repairedId:e,candidateIds:t.agent.tools,reason:r}})}function stringifyToolOutput(t){if("string"==typeof t)return t;const o=JSON.stringify(t);return"string"==typeof o?o:""}function readApprovalIds(t){const o=t?.approvalIds??t?.approvalId;return"string"==typeof o&&o.trim()?[o.trim()]:Array.isArray(o)?o.filter(t=>"string"==typeof t&&t.trim().length>0):void 0}
@@ -1 +1 @@
1
- import{assertNoDeclaredActionOmissionOutput as e}from"../../recovery/control-omission.js";import{buildRawArgsRecoveryRequest as t,buildRawArgsToolEvidenceRecoveryRequest as o,hasUniqueRawArgsTool as r,matchUniqueRawArgsTool as a}from"../../recovery/raw-args.js";import{assertNoProgressOnlyToolIntentOutput as s,assertNoRawToolCallOutput as l,assertNoRawToolResultOutput as i,assertNoToolExecutionErrorOutput as u,buildEvidenceSynthesisOutput as n,buildResultRecoveryRequest as c,containsRawToolCallOutput as p,rawToolCallFailureMessage as y,rawToolCallOutputPreview as d,toolCallRecoveryEnabled as v}from"../../recovery/tool-call.js";export async function recoverAdapterResultOutput(o){let g=o.result,w=o.request;const R=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,o="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,r="object"!=typeof o||null===o||Array.isArray(o)?void 0:o.maxResultRecoveryAttempts;return"number"==typeof r&&Number.isInteger(r)&&r>0?r:3}(o.recoveryPolicy),m=new Set,_=new Set;for(let e=0;;e+=1){const r=o.store.getRun(o.requestId)?.events??[],s=a({output:g.text,agent:o.agent,workspace:o.workspace,toolGateway:o.toolGateway,events:r,policy:o.recoveryPolicy}),l=s?rawArgsToolKey(s):void 0,i=l&&!m.has(l)?t({request:w,output:g.text,agent:o.agent,workspace:o.workspace,toolGateway:o.toolGateway,events:r,policy:o.recoveryPolicy}):void 0,u=e<R?c({request:w,output:g.text,events:r,availableToolIds:o.agent.tools,policy:o.recoveryPolicy}):void 0,n=i??u;if(!n)break;if(n===i&&m.add(l),w=n,emitRepair(o,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(g.text,o.agent.tools)),g=await o.runAdapter(n),emitRepair(o,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(g.text,o.agent.tools)),n===i){const t=await recoverRepeatedRawArgsByToolGateway(o,w,g,m,_,e+1);t&&(w=t.request,g=t.result)}}return function finalizeRecoveredOutput(t,o){if(!v(t.recoveryPolicy))return o;let a=!1;if(p(o.text,t.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(t.request.metadata)){const e=o.text;o={...o,text:y(),metadata:{...o.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(e,t.agent.tools))}const c=n({request:t.request,output:o.text,events:t.store.getRun(t.requestId)?.events??[],policy:t.recoveryPolicy});return c&&(a=!0,o={...o,text:c,metadata:{...o.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(t,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),a||(p(o.text,t.recoveryPolicy)&&emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(o.text,t.agent.tools)),l(o.text,t.recoveryPolicy),function assertNoRawArgsToolOutput(e,t){if(r({output:t,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],policy:e.recoveryPolicy}))throw new Error(`Adapter returned raw tool argument JSON as the final answer after recovery. The backend must execute the matching tool instead. Output preview: ${d(t)}`)}(t,o.text),s(o.text,t.agent.tools,t.recoveryPolicy),i(o.text,t.store.getRun(t.requestId)?.events??[],t.recoveryPolicy),u(o.text,t.recoveryPolicy),e({output:o.text,events:t.store.getRun(t.requestId)?.events??[],availableToolIds:t.agent.tools})),o}(o,g)}async function recoverRepeatedRawArgsByToolGateway(e,t,r,s,l,i){const u=a({output:r.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],policy:e.recoveryPolicy});if(!u||!e.runRecoveredToolCall)return;const n=rawArgsToolKey(u);if(!s.has(n)||l.has(n))return;l.add(n),emitRepair(e,"runtime.repair.started","result_output",i,"raw_args_tool_gateway_recovery",void 0,repairDiagnostics(r.text,e.agent.tools));const c=await e.runRecoveredToolCall(u.toolId,u.args),p=o({request:t,match:u,toolOutput:c.text}),y=await e.runAdapter(p);return emitRepair(e,"runtime.repair.completed","result_output",i,"raw_args_tool_gateway_recovery","retried",repairDiagnostics(y.text,e.agent.tools)),{request:p,result:y}}function emitRepair(e,t,o,r,a,s,l){const i={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...l?{diagnostics:l}:{}};e.emit("runtime.repair.started"===t?{type:t,...i}:{type:t,...i,outcome:s??"retried"})}function repairDiagnostics(e,t){return{outputPreview:d(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])new RegExp(`(?:^|[^A-Za-z0-9_-])${escapeRegexp(r)}(?:$|[^A-Za-z0-9_-])`,"u").test(e)&&o.add(r);return[...o]}function escapeRegexp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&")}function rawArgsToolKey(e){return`${e.toolId}:${JSON.stringify(e.args)}`}
1
+ import{assertNoDeclaredActionOmissionOutput as e}from"../../recovery/control-omission.js";import{buildRawArgsRecoveryRequest as t,buildRawArgsToolEvidenceRecoveryRequest as o,hasUniqueRawArgsTool as r,matchUniqueRawArgsTool as a}from"../../recovery/raw-args.js";import{assertNoProgressOnlyToolIntentOutput as s,assertNoRawToolCallOutput as l,assertNoRawToolResultOutput as u,assertNoToolExecutionErrorOutput as i,buildEvidenceSynthesisOutput as n,buildResultRecoveryRequest as c,containsRawToolCallOutput as p,rawToolCallFailureMessage as d,rawToolCallOutputPreview as y,toolCallRecoveryEnabled as v}from"../../recovery/tool-call.js";import{controlGaps as g}from"../../quality/event-evidence.js";export async function recoverAdapterResultOutput(o){let g=o.result,m=o.request;const w=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,o="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,r="object"!=typeof o||null===o||Array.isArray(o)?void 0:o.maxResultRecoveryAttempts;return"number"==typeof r&&Number.isInteger(r)&&r>0?r:3}(o.recoveryPolicy),R=new Set,_=new Set;for(let e=0;;e+=1){const r=o.store.getRun(o.requestId)?.events??[],s=a({output:g.text,agent:o.agent,workspace:o.workspace,toolGateway:o.toolGateway,events:r,policy:o.recoveryPolicy}),l=s?rawArgsToolKey(s):void 0,u=l&&!R.has(l)?t({request:m,output:g.text,agent:o.agent,workspace:o.workspace,toolGateway:o.toolGateway,events:r,policy:o.recoveryPolicy}):void 0,i=e<w?c({request:m,output:g.text,events:r,availableToolIds:o.agent.tools,policy:o.recoveryPolicy}):void 0,n=u??i;if(!n)break;if(n===u&&R.add(l),m=n,emitRepair(o,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(g.text,o.agent.tools)),g=await o.runAdapter(n),emitRepair(o,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(g.text,o.agent.tools)),n===u){const t=await recoverRepeatedRawArgsByToolGateway(o,m,g,R,_,e+1);t&&(m=t.request,g=t.result)}}return function finalizeRecoveredOutput(t,o){if(!v(t.recoveryPolicy))return o;let a=!1;if(p(o.text,t.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(t.request.metadata)){const e=o.text;o={...o,text:d(),metadata:{...o.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(e,t.agent.tools))}const c=n({request:t.request,output:o.text,events:t.store.getRun(t.requestId)?.events??[],policy:t.recoveryPolicy});return c&&(a=!0,o={...o,text:c,metadata:{...o.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(t,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),a||(p(o.text,t.recoveryPolicy)&&emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(o.text,t.agent.tools)),l(o.text,t.recoveryPolicy),function assertNoRawArgsToolOutput(e,t){if(r({output:t,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],policy:e.recoveryPolicy}))throw new Error(`Adapter returned raw tool argument JSON as the final answer after recovery. The backend must execute the matching tool instead. Output preview: ${y(t)}`)}(t,o.text),s(o.text,t.agent.tools,t.recoveryPolicy),u(o.text,t.store.getRun(t.requestId)?.events??[],t.recoveryPolicy),i(o.text,t.recoveryPolicy),e({output:o.text,events:t.store.getRun(t.requestId)?.events??[],availableToolIds:t.agent.tools})),o}(o,g)}async function recoverRepeatedRawArgsByToolGateway(e,t,r,s,l,u){const i=a({output:r.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],policy:e.recoveryPolicy});if(!i||!e.runRecoveredToolCall)return;const n=rawArgsToolKey(i);if(!s.has(n)||l.has(n))return;l.add(n),emitRepair(e,"runtime.repair.started","result_output",u,"raw_args_tool_gateway_recovery",void 0,repairDiagnostics(r.text,e.agent.tools));const c=function visibleRecoveredToolOutput(e){return("string"==typeof e.text?e.text.trim():"")||"The recovered tool completed successfully but returned no user-visible output."}(await e.runRecoveredToolCall(i.toolId,i.args)),p=o({request:t,match:i,toolOutput:c}),d=await e.runAdapter(p),y=d.text.trim()?d:{...d,text:buildEmptyRecoveredToolBlocker({match:i,toolOutput:c,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...d.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool"}}};return emitRepair(e,"runtime.repair.completed","result_output",u,"raw_args_tool_gateway_recovery","retried",repairDiagnostics(y.text,e.agent.tools)),{request:p,result:y}}function emitRepair(e,t,o,r,a,s,l){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...l?{diagnostics:l}:{}};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:s??"retried"})}function repairDiagnostics(e,t){return{outputPreview:y(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])new RegExp(`(?:^|[^A-Za-z0-9_-])${escapeRegexp(r)}(?:$|[^A-Za-z0-9_-])`,"u").test(e)&&o.add(r);return[...o]}function escapeRegexp(e){return e.replace(/[.*+?^${}()|[\]\\]/gu,"\\$&")}function rawArgsToolKey(e){return`${e.toolId}:${JSON.stringify(e.args)}`}function buildEmptyRecoveredToolBlocker(e){const t=g(e.events);return["Stable runtime recovery executed the matched declared tool, but the backend returned no user-facing output after receiving the executed evidence.","",`Executed tool: ${e.match.toolId}`,"","Executed JSON arguments:",JSON.stringify(e.match.args),"","Executed tool evidence:",e.toolOutput,...t.length>0?["","Unresolved control gaps:",...t.map(e=>`- ${e}`)]:[]].join("\n")}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/core",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,7 +11,7 @@
11
11
  ".": "./dist/index.js"
12
12
  },
13
13
  "peerDependencies": {
14
- "@stable-harness/governance": "0.0.104",
15
- "@stable-harness/memory": "0.0.104"
14
+ "@stable-harness/governance": "0.0.105",
15
+ "@stable-harness/memory": "0.0.105"
16
16
  }
17
17
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/evaluation",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -10,6 +10,6 @@
10
10
  "main": "dist/src/index.js",
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
- "@stable-harness/core": "0.0.104"
13
+ "@stable-harness/core": "0.0.105"
14
14
  }
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/governance",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/memory",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/protocols",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -10,6 +10,6 @@
10
10
  "main": "dist/src/index.js",
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
- "@stable-harness/core": "0.0.104"
13
+ "@stable-harness/core": "0.0.105"
14
14
  }
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/tool-gateway",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/workspace-yaml",
3
- "version": "0.0.104",
3
+ "version": "0.0.105",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,6 +11,6 @@
11
11
  ".": "./dist/index.js"
12
12
  },
13
13
  "peerDependencies": {
14
- "@stable-harness/core": "0.0.104"
14
+ "@stable-harness/core": "0.0.105"
15
15
  }
16
16
  }