stable-harness 0.0.129 → 0.0.131
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.
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/adapter.js +1 -1
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin/permissions.d.ts +3 -1
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin/permissions.js +1 -1
- package/node_modules/@stable-harness/adapter-deepagents/package.json +2 -2
- package/node_modules/@stable-harness/adapter-langgraph/package.json +2 -2
- package/node_modules/@stable-harness/core/dist/quality/event-evidence.js +1 -1
- package/node_modules/@stable-harness/core/dist/recovery/execution-contract.js +1 -1
- package/node_modules/@stable-harness/core/dist/runtime/recovery/adapter-result.js +1 -1
- package/node_modules/@stable-harness/core/package.json +3 -3
- package/node_modules/@stable-harness/governance/package.json +1 -1
- package/node_modules/@stable-harness/memory/package.json +1 -1
- package/node_modules/@stable-harness/protocols/package.json +2 -2
- package/node_modules/@stable-harness/tool-gateway/package.json +1 -1
- package/node_modules/@stable-harness/workspace-yaml/package.json +2 -2
- package/package.json +9 -9
- package/packages/adapter-deepagents/dist/src/adapter.js +1 -1
- package/packages/adapter-deepagents/dist/src/internal/builtin/permissions.d.ts +3 -1
- package/packages/adapter-deepagents/dist/src/internal/builtin/permissions.js +1 -1
- package/packages/adapter-deepagents/package.json +2 -2
- package/packages/adapter-langgraph/package.json +2 -2
- package/packages/cli/package.json +8 -8
- package/packages/core/dist/quality/event-evidence.js +1 -1
- package/packages/core/dist/recovery/execution-contract.js +1 -1
- package/packages/core/dist/runtime/recovery/adapter-result.js +1 -1
- package/packages/core/package.json +3 -3
- package/packages/evaluation/package.json +2 -2
- package/packages/governance/package.json +1 -1
- package/packages/memory/package.json +1 -1
- package/packages/protocols/package.json +2 -2
- package/packages/tool-gateway/package.json +1 -1
- package/packages/workspace-yaml/package.json +2 -2
|
@@ -1 +1 @@
|
|
|
1
|
-
import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as l}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as
|
|
1
|
+
import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as l}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as c}from"./internal/messages.js";import{createRawToolCallParserMiddleware as p}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as g}from"./retry-policy.js";import{streamDeepAgentResult as m}from"./internal/stream-events.js";import{cleanupDeepAgentsRuntimeSubstrate as f,resolveDeepAgentsRuntimeSubstrate as y}from"./internal/substrate/runtime.js";import{createDefaultDeepAgentsBackend as v}from"./internal/vfs-backend.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){const r=focusedRecoveryToolIds(t),n=recoveryVisibleTools(t,t.agent.tools);if(t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.handoff",modelRef:t.agent.modelRef,tools:t.agent.tools,gatewayTools:n,...r.length>0?{focusedRecoveryTools:r,recoveryMode:"required_evidence_tools"}:{},skills:t.agent.skills,subagents:t.agent.subagents}}),(r.length>0||n.length!==t.agent.tools.length)&&t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.gateway.tools",tools:n,declaredTools:t.agent.tools,...r.length>0?{focusedRecoveryTools:r,recoveryMode:"required_evidence_tools"}:{}}}),e.runner)return e.runner(t);const o=e.createDeepAgent?void 0:await async function loadDeepAgentsModule(){try{return await async function importOptionalPackage(e){return import(e)}("deepagents")}catch(e){throw new Error(`DeepAgents package is required for the default adapter path: ${function formatError(e){return e instanceof Error?e.message:String(e)}(e)}`)}}(),a=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(o),d={...readDeepAgentsConfig(e.config),...readDeepAgentsConfig(t.agent.config.deepagents)},p=y(t,d),u=resolveDeepAgentsSkills(t,t.agent),g=resolveDeepAgentsMemory(t,t.agent),A=void 0===d.backend?await v({workspaceRoot:t.workspace.root,skills:u,memory:g,config:d}):{cleanup:async()=>{}};try{const e=void 0===A.backend&&void 0===d.backend,r=a(function buildDeepAgentParams(e,t,r,n,o={}){const a=o.skills??resolveDeepAgentsSkills(e,e.agent),l=o.memory??resolveDeepAgentsMemory(e,e.agent),d=t.permissions??s(e,e.agent,{enabled:!0===o.autoPathPermissions}),c=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:t.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:t.backend??o.backend??resolveDeepAgentsBackend(e,n,a),checkpointer:r.checkpointer,store:r.store,middleware:mergeMiddleware(e,e.agent,t.middleware,c),responseFormat:t.responseFormat,contextSchema:t.contextSchema,interruptOn:t.interruptOn,generalPurposeAgent:readBoolean(t.generalPurposeAgent),taskDescription:readString(t.taskDescription),permissions:d,tools:i(e,e.agent.id,recoveryVisibleTools(e,e.agent.tools),resolveAgentRepairModel(0,e.agent,t),c),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),a=n.permissions??s(e,r,{enabled:!0===o.autoPathPermissions}),l=scopedInput(e,r),d=requestScopedRepeatState(e,t);return pruneUndefined({name:t,description:r?.description??readString(r?.config.description)??r?.id,systemPrompt:buildSystemPrompt(e,r),model:n.model??(r?resolveAgentModel(e,r):void 0),middleware:mergeMiddleware(l,r,n.middleware,d),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,responseFormat:n.responseFormat,tools:i(e,t,recoveryVisibleTools(e,r?.tools??[]),resolveAgentRepairModel(0,0,n),d),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:l,skills:a})}(t,d,p,o,{backend:A.backend,skills:u,memory:g,autoPathPermissions:e})),n=c(t),f=function buildDeepAgentInvokeConfig(e,t){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit),configurable:{thread_id:t}})}(t.agent,p.threadId);if(!0===t.request.metadata?.openaiStream&&r.streamEvents){const e=await r.streamEvents(n,{version:"v3",...f});return await m(t,e,l)}const y=await r.invoke(n,f);return l(y)}finally{await A.cleanup(),await f(p)}}}}function recoveryVisibleTools(e,t){const r=focusedRecoveryToolIds(e);return 0===r.length?t:t.filter(e=>r.includes(e))}function focusedRecoveryToolIds(e){return readStringArray(e.request.metadata?.stableHarnessRequiredEvidenceTools)??[]}function buildSystemPrompt(e,t){const n=t?.systemPrompt??readString(t?.config.systemPrompt);return r({workspace:e.workspace,request:e.request,agent:t},n)}function resolveDeepAgentsMemory(e,t){const r=readDeepAgentsStringArray(t?.config,"memory");if(r)return r;const n=[...readAgentMemorySources(e.workspace.root,t),...d(e.workspace).map(e=>`/memories/${e.id}.md`)],o=[...new Set(n)];return o.length>0?o:void 0}function readAgentMemorySources(e,t){return(t?.memory??[]).flatMap(t=>"string"==typeof t&&t.trim()?[backendMemorySourcePath(e,t.trim())]:isRecord(t)&&"string"==typeof t.path&&t.path.trim()?[backendMemorySourcePath(e,t.path.trim())]:[])}function backendMemorySourcePath(e,r){if(r.startsWith("/"))return r;if(t.isAbsolute(r)){const n=t.relative(e,r);return n&&!n.startsWith("..")?`/${n.split(t.sep).join("/")}`:canonicalPath(r)}const n=r.split(t.sep).join("/");return n.startsWith("/")?n:`/${n}`}function resolveDeepAgentsSkills(e,r){const n=readDeepAgentsStringArray(r?.config,"skills");if(n)return n;const o=[...new Set((r?.skills??[]).map(t=>e.workspace.skills.get(t)?.path).filter(e=>"string"==typeof e&&e.trim().length>0).map(r=>function backendSkillSourcePath(e,r){const n=t.dirname(t.dirname(r)),o=t.relative(e,n);return!o||o.startsWith("..")||t.isAbsolute(o)?""===o?"/":canonicalPath(n):`/${o.split(t.sep).join("/")}`}(e.workspace.root,r)))];return o.length>0?o:void 0}function resolveDeepAgentsBackend(e,t,r){if(t?.FilesystemBackend&&r&&0!==r.length)return()=>new t.FilesystemBackend({rootDir:e.workspace.root})}function mergeMiddleware(e,t,r,s=a(e.workspace.runtime.toolGateway)){const i=Array.isArray(r)?r:[],l=scopedInput(e,t),d=new Set,c=readDeepAgentsConfig(t?.config.deepagents);return[o(l,{observedToolIds:d,repeatState:s,repairModel:resolveAgentRepairModel(0,0,c)}),n(l,{repeatState:s}),...g(e.workspace.runtime.retry),...i,p(l)]}function requestScopedRepeatState(e,t){const r=`deepagents.repeat.${t}`,n=e.requestState?.get(r);if(n)return n;const o=a(e.workspace.runtime.toolGateway);return e.requestState&&o&&e.requestState.set(r,o),o}function scopedInput(e,t){return t?{...e,agent:t}:e}function resolveAgentModel(e,t){const r=t.modelRef?e.workspace.models.get(t.modelRef):void 0;return r?u(r):void 0}function resolveAgentRepairModel(e,t,r){const n=r.model;return function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}(n)?n:void 0}function readDeepAgentsConfig(e){return isRecord(e)?e:{}}function readDeepAgentsStringArray(e,t){const r=isRecord(e)?e:{},n=readDeepAgentsConfig(r.deepagents),o="memory"===t?["memory","memorySources"]:["skills","skillSources"];for(const e of o){const t=readStringArray(n[e]);if(t)return t}return readStringArray(r[t])}function pruneUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e))}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):void 0}function canonicalPath(t){try{return e.native(t)}catch{return t}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin/permissions.d.ts
CHANGED
|
@@ -7,7 +7,9 @@ export declare function validateFilesystemBuiltinCall(input: AdapterRunInput, to
|
|
|
7
7
|
id?: string;
|
|
8
8
|
};
|
|
9
9
|
}): ToolMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>> | undefined;
|
|
10
|
-
export declare function resolveFilesystemPermissions(input: AdapterRunInput, agent: WorkspaceAgent | undefined
|
|
10
|
+
export declare function resolveFilesystemPermissions(input: AdapterRunInput, agent: WorkspaceAgent | undefined, options?: {
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
}): {
|
|
11
13
|
operations: string[];
|
|
12
14
|
paths: string[];
|
|
13
15
|
mode: string;
|
package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin/permissions.js
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
import{realpathSync as e}from"node:fs";import{ToolMessage as t}from"@langchain/core/messages";export const filesystemBuiltinToolIds=new Set(["ls","read_file","write_file","edit_file","glob","grep"]);export function validateFilesystemBuiltinCall(e,n,i){if(isFilesystemDisabled(e)&&filesystemBuiltinToolIds.has(n))return new t({tool_call_id:i.toolCall?.id??`stable-harness-${n}-policy`,name:n,content:`Filesystem builtin tool '${n}' is disabled for this agent. Do not retry filesystem tools; use the agent's registered workspace tools and already collected evidence instead.`})}export function resolveFilesystemPermissions(e,t){const
|
|
1
|
+
import{realpathSync as e}from"node:fs";import{ToolMessage as t}from"@langchain/core/messages";export const filesystemBuiltinToolIds=new Set(["ls","read_file","write_file","edit_file","glob","grep"]);export function validateFilesystemBuiltinCall(e,n,i){if(isFilesystemDisabled(e)&&filesystemBuiltinToolIds.has(n))return new t({tool_call_id:i.toolCall?.id??`stable-harness-${n}-policy`,name:n,content:`Filesystem builtin tool '${n}' is disabled for this agent. Do not retry filesystem tools; use the agent's registered workspace tools and already collected evidence instead.`})}export function resolveFilesystemPermissions(e,t,n={}){if(!0!==n.enabled)return;const i=readConfigRecord(t?.config,"builtinTools");if(!1===i?.filesystem)return;const o=[];return o.push(...function skillReadPermissions(e,t){const n=[...new Set((t?.skills??[]).flatMap(t=>function skillReadPaths(e,t){return t?[...new Set([t,canonicalPath(t),backendSkillPath(e,t)])].flatMap(e=>function skillReadPathCandidates(e){const t=e.replace(/\/+$/u,""),n=t.endsWith("/SKILL.md")?t.slice(0,-9):t,i=function parentPath(e){const t=e.lastIndexOf("/");return t>0?e.slice(0,t):void 0}(n);return[t,n,`${n}/**`,...i?[i,`${i}/**`]:[]]}(e)):[]}(e.workspace.root,e.workspace.skills.get(t)?.path)).filter(e=>e.startsWith("/")))];return n.length>0?[{operations:["read"],paths:n,mode:"allow"}]:[]}(e,t)),deepagentsMemoryWritable(e)||deepagentsMemoryWritable(e)||o.push({operations:["write"],paths:["/memories/**"],mode:"deny"}),o.length>0?o:void 0}export function isFilesystemDisabled(e){const t=readConfigRecord(e.agent.config,"builtinTools");return!1===t?.filesystem}export function isFilesystemTool(e){return"string"==typeof e&&filesystemBuiltinToolIds.has(e)}function backendSkillPath(e,t){const n=function pathRelative(e,t){const n=e.split("/").filter(Boolean),i=t.split("/").filter(Boolean);if(!(i.length<n.length)){for(let e=0;e<n.length;e+=1)if(n[e]!==i[e])return;return i.slice(n.length).join("/")}}(e,t);return void 0===n?t:`/${n.split("/").filter(Boolean).join("/")}`}function canonicalPath(t){try{return e.native(t)}catch{return t}}function deepagentsMemoryWritable(e){const t=readConfigRecord(e.workspace.runtime.memory,"deepagentsMem");return!1!==t?.write}function readConfigRecord(e,t){const n=isRecord(e)?e:{};return isRecord(n[t])?n[t]:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/adapter-deepagents",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@langchain/node-vfs": "^0.1.4",
|
|
17
17
|
"@langchain/ollama": "^1.2.7",
|
|
18
18
|
"@langchain/openai": "^1.4.5",
|
|
19
|
-
"@stable-harness/core": "0.0.
|
|
19
|
+
"@stable-harness/core": "0.0.131",
|
|
20
20
|
"deepagents": "^1.10.1",
|
|
21
21
|
"langchain": "^1.4.0"
|
|
22
22
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/adapter-langgraph",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
"types": "dist/src/index.d.ts",
|
|
13
13
|
"peerDependencies": {
|
|
14
14
|
"@langchain/langgraph": "^1.3.0",
|
|
15
|
-
"@stable-harness/core": "0.0.
|
|
15
|
+
"@stable-harness/core": "0.0.131"
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function hasPlanningEvidence(t){return t.some(t=>{const e=readAdapterEvent(t);return!!e&&("plan"===e.traceType||String(e.traceLabel??"").startsWith("plan.")||"write_todos"===e.toolId&&String(e.phase??"").startsWith("agent.tool."))})}export function successfulEvidenceToolIds(t){const e=t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return[t.toolId];const e=readAdapterEvent(t);return isToolResultEvent(e)&&
|
|
1
|
+
export function hasPlanningEvidence(t){return t.some(t=>{const e=readAdapterEvent(t);return!!e&&("plan"===e.traceType||String(e.traceLabel??"").startsWith("plan.")||"write_todos"===e.toolId&&String(e.phase??"").startsWith("agent.tool."))})}export function successfulEvidenceToolIds(t){const e=t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return[t.toolId];const e=readAdapterEvent(t),n=readToolSource(e);return isToolResultEvent(e)&&n&&isSuccessfulEvidenceEvent(e)?[n]:[]});return[...new Set(e)]}export function successfulEvidenceOutputs(t){return successfulEvidenceItems(t).map(t=>t.output)}export function successfulEvidenceItems(t){return t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return stringifyEvidence(t.output).map(e=>({source:t.toolId,output:e}));const e=readAdapterEvent(t),n=readToolSource(e);return isToolResultEvent(e)&&n?!isSuccessfulEvidenceEvent(e)||function isPlanningTool(t){return"write_todos"===t||"read_todos"===t}(n)?[]:stringifyEvidence(e.evidenceOutput??e.output).filter(t=>function isUsableEvidenceOutput(t,e){return!("task"===t&&function looksLikeUnexecutedToolIntent(t){const e=t.trim();if(e.length>4e3)return!1;const n=function extractJsonSource(t){const e=t.trim();if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))return e;if(!e.startsWith("```"))return;const n=e.indexOf("\n"),r=e.lastIndexOf("```");return n<0||r<=n?void 0:e.slice(n+1,r).trim()}(e);return n?function containsToolEnvelope(t){try{const e=JSON.parse(t);return Array.isArray(e)?e.some(isToolEnvelopeRecord):isToolEnvelopeRecord(e)}catch{return!1}}(n):function containsToolMarkup(t){const e=t.toLowerCase();return e.includes("<tool_call")||e.includes("</tool_call")||e.includes("<tool_code")||e.includes("</tool_code")}(e)||function containsBareToolFence(t){const e=t.trim(),n=e.indexOf("```");if(n<0||e.indexOf("```",n+3)!==e.lastIndexOf("```"))return!1;const r=e.indexOf("\n",n+3),o=e.lastIndexOf("```");return!(r<0||o<=r)&&function isIdentifierPath(t){return t.length>0&&[...t].every((t,e)=>{const n=t>="A"&&t<="Z"||t>="a"&&t<="z"||"_"===t;return 0===e?n:n||t>="0"&&t<="9"||"."===t||"-"===t})}(e.slice(r+1,o).trim())}(e)}(e))}(n,t)).map(t=>({source:n,output:t})):[]})}export function controlBlockers(t){const e=successfulEventIndexesBySource(t);return t.flatMap((t,n)=>{const r=readAdapterEvent(t),o=readControlStatus(r),s=readControlSource(r)??"tool";return o&&isBlockerStatus(o)?isResolvedByLaterCompletion(o)&&completedAfter(e,s,n)||isResolvedByLaterAnyCompletion(o)&&completedAfterAny(e,n)?[]:[`${s}:${o}`]:[]})}export function controlGaps(t){const e=new Set(successfulEvidenceItems(t).map(t=>t.source));return t.flatMap(t=>{const n=readAdapterEvent(t),r=readControlStatus(n),o=readControlSource(n)??"tool";return r&&isGapStatus(r)?e.has(o)&&isResolvedByLaterCompletion(r)?[]:[`${o}:${r}`]:[]})}export function omittedControlGaps(t,e){const n=successfulEventIndexesBySource(t),r=successfulEvidenceItems(t),o=function outputHasUnsupportedEvidenceClaims(t,e,n){const r=function evidenceCorpus(t,e){return[...e.map(t=>t.output),...t.flatMap(t=>"runtime.request.started"===t.type?[t.input??""]:[]),...t.flatMap(t=>"runtime.memory.recall.completed"===t.type?[t.context]:[])].join("\n")}(e,n).toLowerCase();return unsupportedTokens(t,r,/\b[A-Z][A-Z0-9]{1,12}-\d+\b/gu).length>0||unsupportedTokens(t,r,/\b[A-Za-z_$][A-Za-z0-9_$]*[A-Z][A-Za-z0-9_$]*\b/gu).filter(isCodeLikeIdentifier).length>=2}(e,t,r);return t.flatMap((t,s)=>{const u=readAdapterEvent(t),i=readControlStatus(u),a=readControlSource(u)??"tool";return i&&function isOmittedControlStatus(t){return isGapStatus(t)||isBlockerStatus(t)}(i)?isResolvedByLaterCompletion(i)&&completedAfter(n,a,s)||isResolvedByLaterAnyCompletion(i)&&completedAfterAny(n,s)||!o&&outputUsesPriorEvidence(e,a,r)?[]:[`${a}:${i}`]:[]})}function stringifyEvidence(t){return"string"==typeof t?t.trim()?[t]:[]:null==t?[]:[JSON.stringify(t)]}function isToolEnvelopeRecord(t){return!!isRecord(t)&&["tool","toolId","toolName","tool_name","name","type","subagent_type"].some(e=>"string"==typeof t[e])&&["args","arguments","parameters","params","kwargs","task"].some(e=>e in t)}function readAdapterEvent(t){if("runtime.adapter.event"===t.type&&isRecord(t.event))return t.event;const e=t;return isRecord(e)&&isToolResultEvent(e)?e:void 0}function isSuccessfulEvidenceEvent(t){const e=readEventStatus(t);return!e||/^(?:completed|success|ok|recorded)$/iu.test(e)}function isBlockerStatus(t){return/^(?:blocked|approval_required|schema_repair_failed|tool_argument_error|invalid_input|task_inventory_blocked)$/iu.test(t)}function isGapStatus(t){return/^(?:dependency_required|plan_required|repeated_tool_call_limit|duplicate_tool_call)$/iu.test(t)}function isResolvedByLaterCompletion(t){return isGapStatus(t)||isBlockerStatus(t)}function isResolvedByLaterAnyCompletion(t){return"task_inventory_blocked"===t}function successfulEventIndexesBySource(t){const e=new Map;return t.forEach((t,n)=>{const r=function successfulEventSource(t){if("runtime.tool.direct.completed"===t.type)return t.toolId;const e=readAdapterEvent(t),n=readToolSource(e);return isToolResultEvent(e)&&n&&isSuccessfulEvidenceEvent(e)?n:void 0}(t);r&&e.set(r,[...e.get(r)??[],n])}),e}function isToolResultEvent(t){return"deepagents.tool_execution.result"===t?.eventType||"agent.tool.result"===t?.phase||"agent.tool.result"===t?.type||"deepagents.tool_execution.result"===t?.type}function completedAfter(t,e,n){return(t.get(e)??[]).some(t=>t>n)}function completedAfterAny(t,e){return[...t.values()].some(t=>t.some(t=>t>e))}export function outputUsesPriorEvidence(t,e,n){const r=t.toLowerCase();return n.filter(t=>t.source===e).some(t=>{const e=t.output.trim();return!!e&&(!!r.includes(e.slice(0,500).toLowerCase())||function matchingEvidenceTokens(t,e){const n=new Set(["status","completed","success","recorded"]);return[...new Set(e.toLowerCase().match(/[a-z0-9][a-z0-9_.-]{1,}/gu)??[])].filter(t=>!n.has(t)).filter(e=>t.includes(e)).length}(r,e)>=2)})}function unsupportedTokens(t,e,n){return[...new Set(t.match(n)??[])].filter(t=>!e.includes(t.toLowerCase()))}function isCodeLikeIdentifier(t){return!(t.length<8)&&(/(?:Service|Controller|Repository|Manager|Client|Resolver|Agent|Tool|Async)$/u.test(t)||/[a-z][A-Z]/u.test(t))}function readOutputStatus(t){if(isRecord(t)&&"string"==typeof t.status)return t.status;if("string"==typeof t){const e=parseJsonRecord(t);return"string"==typeof e?.status?e.status:t.match(/^Status:\s*([A-Za-z0-9_-]+)/imu)?.[1]}}function parseJsonRecord(t){try{const e=JSON.parse(t);return isRecord(e)?e:void 0}catch{return}}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function readString(t){return"string"==typeof t&&t.trim()?t:void 0}function readEventStatus(t){return readString(t?.controlStatus)??readString(t?.status)??readOutputStatus(t?.output)}function readToolSource(t){return readString(t?.toolId)??readString(t?.toolName)??readString(t?.name)}function readControlStatus(t){const e=function readInventoryRepairControlStatus(t){if("inventory.repair"===t?.phase&&"blocked"===t.status)return"task"===readInventoryRepairSource(t)?"task_inventory_blocked":"blocked"}(t);if(e)return e;const n=readEventStatus(t);return n&&isControlStatus(n)?n:findNestedControlStatus(t)}function readControlSource(t){return readToolSource(t)??readInventoryRepairSource(t)??findNestedToolSource(t)}function isControlStatus(t){return isGapStatus(t)||isBlockerStatus(t)}function findNestedControlStatus(t,e=0){if(e>5||null==t)return;if("string"==typeof t)return function readNestedStringStatus(t,e){const n=parseJsonRecord(t);if(n)return findNestedControlStatus(n,e+1);const r=t.match(/^Status:\s*([A-Za-z0-9_-]+)/imu)?.[1];return r&&isControlStatus(r)?r:function readControlToken(t){const e=t.match(/\b(?:blocked|approval_required|schema_repair_failed|tool_argument_error|invalid_input|task_inventory_blocked|dependency_required|plan_required|repeated_tool_call_limit|duplicate_tool_call)\b/iu)?.[0];return e&&isControlStatus(e)?e:void 0}(t)}(t,e);if(Array.isArray(t))return findFirstNested(t,t=>findNestedControlStatus(t,e+1));if(!isRecord(t))return;const n=readString(t.controlStatus)??readString(t.status);if(n&&isControlStatus(n))return n;const r=readOutputStatus(t.output);return r&&isControlStatus(r)?r:findFirstNested(Object.values(t),t=>findNestedControlStatus(t,e+1))}function findNestedToolSource(t,e=0){if(!(e>5||null==t)){if("string"==typeof t)return function readToolSourceFromText(t){const e=t.match(/["'](?:toolId|toolName|name)["']\s*:\s*["']([^"']+)["']/u)?.[1];return readString(e)}(t);if(Array.isArray(t))return findFirstNested(t,t=>findNestedToolSource(t,e+1));if(isRecord(t))return(readString(t.toolId)??readString(t.toolName)??readString(t.name))||findFirstNested(Object.values(t),t=>findNestedToolSource(t,e+1))}}function findFirstNested(t,e){for(const n of t){const t=e(n);if(void 0!==t)return t}}function readInventoryRepairSource(t){const e=isRecord(t?.diagnostic)?t.diagnostic:void 0;return readString(e?.layer)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{successfulEvidenceItems as e}from"../quality/event-evidence.js";export function buildExecutionContractRecoveryRequest(
|
|
1
|
+
import{successfulEvidenceItems as e,successfulEvidenceToolIds as t}from"../quality/event-evidence.js";export function buildExecutionContractRecoveryRequest(e){if(!0!==function readToolCallRecovery(e){if(!isRecord(e))return{};const t=isRecord(e.recovery)?e.recovery:{};return isRecord(t.toolCall)?t.toolCall:{}}(e.policy).enabled)return;const n=function lastExecutionContractFailure(e){for(let t=e.length-1;t>=0;t-=1){const n=e[t];if("runtime.execution.contract.failed"===n?.type)return{reason:n.reason,missing:readStringArray(n.missingEvidenceTools)}}return{missing:[]}}(e.events);if(0===n.missing.length)return;if("missing_required_evidence_usage"===n.reason){const t=recentSuccessfulEvidence(e.events);return recoverRequest(e.request,["Stable runtime recovery: the execution contract was not satisfied.",`The final answer did not use required executed evidence from: ${n.missing.join(", ")}`,"Synthesize from those required source(s), or call them through normal structured tool calling if their evidence is unavailable.","Do not replace required evidence with unrelated intermediate evidence, progress text, or summaries from other tools.",...t.length>0?["","Prior successful tool evidence:",...t]:[]])}const r=recentSuccessfulEvidence(e.events),o=function recoveryToolTargets(e,n,r){const o=function readToolDependencies(e){return isRecord(e)?new Map(Object.entries(e).map(([e,t])=>[e,readStringArray(t)]).filter(e=>e[1].length>0)):new Map}(function readExecutionContract(e){return isRecord(e.config.executionContract)?e.config.executionContract:{}}(e).toolDependencies),i=new Set(t(r)),s=new Set;for(const e of n)s.add(e),collectUnmetDependencies(e,o,i,s,new Set([e]));return[...s].filter(t=>e.tools.includes(t))}(e.agent,n.missing,e.events);return recoverRequest(e.request,["Stable runtime recovery: the execution contract was not satisfied.",`Required evidence tool(s) were missing: ${n.missing.join(", ")}`,`For this recovery turn, the allowed next tool call target(s) are: ${o.join(", ")}`,"Allowed targets include missing required evidence tools and any declared dependency tools that are still needed to build valid arguments.","Reuse exact values from prior successful tool evidence when building the required tool call. Do not invent replacement paths, IDs, handles, URLs, or parameters.","The next assistant action must be the backend's structured tool call for one allowed target, with no prose before it.","Do not call already completed intermediate tools unless they are listed above.","Do not produce a final answer until the required evidence tool call has executed and you have synthesized its result.","Do not print XML, JSON, markdown fences, pseudo tool-call text, plans, or future-intent text in the final answer.",...r.length>0?["","Prior successful tool evidence:",...r]:[]],{stableHarnessRequiredEvidenceTools:o})}function recoverRequest(e,t,n={}){return{...e,input:[e.input,"",...t].join("\n"),metadata:{...e.metadata,stableHarnessRecovery:"tool_call",...n}}}function collectUnmetDependencies(e,t,n,r,o){for(const i of t.get(e)??[])o.has(i)||(o.add(i),n.has(i)||r.add(i),collectUnmetDependencies(i,t,n,r,o))}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[]}function recentSuccessfulEvidence(t){return e(t).slice(-5).map(e=>`- ${e.source}: ${function previewEvidence(e){const t=e.replace(/\s+/gu," ").trim();return t.length>1500?`${t.slice(0,1497)}...`:t}(e.output)}`)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{assertNoDeclaredActionOmissionOutput as e}from"../../recovery/control-omission.js";import{containsProgressOnlyToolIntent as t}from"../../recovery/progress-intent.js";import{buildRawArgsRecoveryRequest as o,buildRawArgsToolEvidenceRecoveryRequest as r,buildRawArgsToolSequenceEvidenceRecoveryRequest as a,hasUniqueRawArgsTool as s,matchRawArgsToolSequence as n,matchUniqueRawArgsTool as u}from"../../recovery/raw-args.js";import{assertNoProgressOnlyToolIntentOutput as l,assertNoRawToolCallOutput as c,assertNoRawToolResultOutput as i,assertNoStructurallyIncompleteFinalOutput as d,assertNoToolExecutionErrorOutput as p,buildEvidenceSynthesisOutput as y,buildResultRecoveryRequest as v,containsRawToolCallOutput as g,rawToolCallFailureMessage as m,rawToolCallOutputPreview as f,toolCallRecoveryEnabled as w}from"../../recovery/tool-call.js";import{controlGaps as R,successfulEvidenceItems as h}from"../../quality/event-evidence.js";export async function recoverAdapterResultOutput(t){let r=t.result,a=t.request;const n=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}(t.recoveryPolicy),R=new Set,h=new Set;for(let e=0;;e+=1){const s=t.store.getRun(t.requestId)?.events??[],l=effectiveRecoveryToolIds(a,t.agent.tools),c=buildNonFocusedRecoveryRequest({request:a,output:r.text,events:s,policy:t.recoveryPolicy,declaredToolIds:t.agent.tools,visibleToolIds:l});if(c){e>=n&&assertNoNonFocusedRecoveryIntent(r.text,t.recoveryPolicy,t.agent.tools,l,s),a=c,emitRepair(t,"runtime.repair.started","result_output",e+1,"non_focused_recovery_intent",void 0,repairDiagnostics(r.text,l)),r=await t.runAdapter(c),emitRepair(t,"runtime.repair.completed","result_output",e+1,"non_focused_recovery_intent","retried",repairDiagnostics(r.text,l));continue}assertNoNonFocusedRecoveryIntent(r.text,t.recoveryPolicy,t.agent.tools,l,s);const i=await recoverRawArgsSequenceByToolGateway(t,a,r,h,e+1,l);if(i){a=i.request,r=i.result;continue}const d=u({output:r.text,agent:t.agent,workspace:t.workspace,toolGateway:t.toolGateway,events:s,candidateToolIds:l,policy:t.recoveryPolicy}),p=d?rawArgsToolKey(d):void 0;if(d&&p&&h.size>0&&!h.has(p)){const o=await recoverRawArgsByToolGateway(t,a,r,d,h,e+1);if(o){a=o.request,r=o.result;continue}}const y=p&&!R.has(p)?o({request:a,output:r.text,agent:t.agent,workspace:t.workspace,toolGateway:t.toolGateway,events:s,candidateToolIds:l,policy:t.recoveryPolicy}):void 0,g=e<n?v({request:a,output:r.text,events:s,availableToolIds:l,policy:t.recoveryPolicy}):void 0,m=y??g;if(!m)break;if(m===y&&R.add(p),a=m,emitRepair(t,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(r.text,l)),r=await t.runAdapter(m),emitRepair(t,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(r.text,l)),m===y){const o=await recoverRepeatedRawArgsByToolGateway(t,a,r,R,h,e+1);o&&(a=o.request,r=o.result)}}return function finalizeRecoveredOutput(t,o){if(!w(t.recoveryPolicy))return o;let r=!1;if(g(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:m(),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 a=y({request:t.request,output:o.text,events:t.store.getRun(t.requestId)?.events??[],policy:t.recoveryPolicy});return a&&(r=!0,o={...o,text:a,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")),r||(g(o.text,t.recoveryPolicy)&&emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(o.text,t.agent.tools)),c(o.text,t.recoveryPolicy),function assertNoRawArgsToolOutput(e,t){if(s({output:t,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:effectiveRecoveryToolIds(e.request,e.agent.tools),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: ${f(t)}`)}(t,o.text),l(o.text,t.agent.tools,t.recoveryPolicy),i(o.text,t.store.getRun(t.requestId)?.events??[],t.recoveryPolicy),p(o.text,t.recoveryPolicy),d(o.text,t.recoveryPolicy),e({output:o.text,events:t.store.getRun(t.requestId)?.events??[],availableToolIds:t.agent.tools})),o}(t,r)}async function recoverRawArgsSequenceByToolGateway(e,t,o,r,s,u){if(!e.runRecoveredToolCall)return;const l=n({output:o.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:u,policy:e.recoveryPolicy});if(l.length<2||l.some(e=>r.has(rawArgsToolKey(e))))return;emitRepair(e,"runtime.repair.started","result_output",s,"raw_args_tool_sequence_gateway_recovery",void 0,repairDiagnostics(o.text,u));const c=[];for(const t of l){r.add(rawArgsToolKey(t));const o=await e.runRecoveredToolCall(t.toolId,t.args);c.push({match:t,toolOutput:visibleRecoveredToolOutput(o)})}const i=a({request:t,evidences:c}),d=await e.runAdapter(i),p=d.text.trim()?d:{...d,text:buildEmptyRecoveredToolSequenceBlocker({evidences:c,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...d.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool_sequence"}}};return emitRepair(e,"runtime.repair.completed","result_output",s,"raw_args_tool_sequence_gateway_recovery","retried",repairDiagnostics(p.text,u)),{request:i,result:p}}async function recoverRepeatedRawArgsByToolGateway(e,t,o,r,a,s){const n=u({output:o.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:effectiveRecoveryToolIds(t,e.agent.tools),policy:e.recoveryPolicy});if(!n||!e.runRecoveredToolCall)return;const l=rawArgsToolKey(n);return r.has(l)&&!a.has(l)?recoverRawArgsByToolGateway(e,t,o,n,a,s):void 0}async function recoverRawArgsByToolGateway(e,t,o,a,s,n){if(!e.runRecoveredToolCall)return;const u=rawArgsToolKey(a);if(s.has(u))return;s.add(u),emitRepair(e,"runtime.repair.started","result_output",n,"raw_args_tool_gateway_recovery",void 0,repairDiagnostics(o.text,e.agent.tools));const l=visibleRecoveredToolOutput(await e.runRecoveredToolCall(a.toolId,a.args)),c=r({request:t,match:a,toolOutput:l}),i=await e.runAdapter(c),d=i.text.trim()?i:{...i,text:buildEmptyRecoveredToolBlocker({match:a,toolOutput:l,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...i.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool"}}};return emitRepair(e,"runtime.repair.completed","result_output",n,"raw_args_tool_gateway_recovery","retried",repairDiagnostics(d.text,e.agent.tools)),{request:c,result:d}}function assertNoNonFocusedRecoveryIntent(e,t,o,r,a){const s=nonFocusedRecoveryIntent(e,t,o,r);if(!s)return;const n=new Set(h(a).map(e=>e.source)),u=s.nonFocused.filter(e=>!n.has(e)),l=u.length>0?u:s.nonFocused;throw new Error(`Focused recovery output referenced non-focused tool(s): ${l.join(", ")}. The backend must call one of the focused gateway tools: ${r.join(", ")}.`)}function buildNonFocusedRecoveryRequest(e){const t=nonFocusedRecoveryIntent(e.output,e.policy,e.declaredToolIds,e.visibleToolIds);if(!t)return;const o=h(e.events),r=new Set(o.map(e=>e.source));if(t.nonFocused.some(e=>!r.has(e)))return;const a=o.slice(-5).map(e=>`- ${e.source}: ${function previewRecoveredEvidence(e){const t=e.replace(/\s+/gu," ").trim();return t.length>1e3?`${t.slice(0,997)}...`:t}(e.output)}`);return{...e.request,input:[e.request.input,"","Stable runtime recovery: the previous recovery output referenced tool(s) that already have successful evidence but are not allowed targets for this focused turn.",`Already completed non-focused tool(s): ${t.nonFocused.join(", ")}`,`Allowed focused tool target(s): ${e.visibleToolIds.join(", ")}`,"Reuse the prior successful evidence below to build one allowed focused tool call. Do not call already completed non-focused tools again.","The next assistant action must be the backend's structured tool call for one allowed focused target, with no prose before it.","","Prior successful tool evidence:",...a,"","Previous invalid recovery output:",e.output].join("\n"),metadata:{...e.request.metadata,stableHarnessRecovery:"tool_call"}}}function nonFocusedRecoveryIntent(e,o,r,a){if(0===a.length||a.length===r.length)return;const s=new Set(a),n=visibleToolCandidates(e,r).filter(e=>!s.has(e)),u=g(e,o)||t(e,r)||function containsJsonToolEnvelope(e){const t=e.trim(),o=t.match(/^```(?:json)?\s*\n([\s\S]*?)\n```$/iu)?.[1]?.trim(),r=o??t;if(!r.startsWith("{")||!r.endsWith("}")||r.length>6e3)return!1;try{const e=JSON.parse(r);if(!function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e))return!1;const t=["tool","tool_name","name","type","subagent_type"].some(t=>"string"==typeof e[t]),o=["args","arguments","parameters","params","kwargs"].some(t=>t in e);return t&&o}catch{return!1}}(e);return n.length>0&&u?{nonFocused:n}:void 0}function emitRepair(e,t,o,r,a,s,n){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...n?{diagnostics:n}:{}};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:s??"retried"})}function repairDiagnostics(e,t){return{outputPreview:f(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])containsDelimitedToken(e,r)&&o.add(r);return[...o]}function containsDelimitedToken(e,t){if(!t)return!1;let o=e.indexOf(t);for(;o>=0;){const r=0===o?"":e[o-1],a=e[o+t.length]??"";if(!isTokenChar(r)&&!isTokenChar(a))return!0;o=e.indexOf(t,o+t.length)}return!1}function isTokenChar(e){return"_"===e||"-"===e||e>="A"&&e<="Z"||e>="a"&&e<="z"||e>="0"&&e<="9"}function effectiveRecoveryToolIds(e,t){const o=function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[]}(e.metadata?.stableHarnessRequiredEvidenceTools).filter(e=>t.includes(e));return o.length>0?o:t}function rawArgsToolKey(e){return`${e.toolId}:${JSON.stringify(e.args)}`}function visibleRecoveredToolOutput(e){return("string"==typeof e.text?e.text.trim():"")||"The recovered tool completed successfully but returned no user-visible output."}function buildEmptyRecoveredToolBlocker(e){const t=R(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")}function buildEmptyRecoveredToolSequenceBlocker(e){const t=R(e.events);return["Stable runtime recovery executed matched declared tools, but the backend returned no user-facing output after receiving the executed evidence.","",...e.evidences.flatMap((e,t)=>[`Executed tool ${t+1}: ${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
|
+
import{assertNoDeclaredActionOmissionOutput as e}from"../../recovery/control-omission.js";import{containsProgressOnlyToolIntent as t}from"../../recovery/progress-intent.js";import{buildRawArgsRecoveryRequest as o,buildRawArgsToolEvidenceRecoveryRequest as r,buildRawArgsToolSequenceEvidenceRecoveryRequest as a,hasUniqueRawArgsTool as s,matchRawArgsToolSequence as n,matchUniqueRawArgsTool as u}from"../../recovery/raw-args.js";import{assertNoProgressOnlyToolIntentOutput as l,assertNoRawToolCallOutput as c,assertNoRawToolResultOutput as i,assertNoStructurallyIncompleteFinalOutput as d,assertNoToolExecutionErrorOutput as v,buildEvidenceSynthesisOutput as p,buildResultRecoveryRequest as y,containsRawToolCallOutput as g,rawToolCallFailureMessage as f,rawToolCallOutputPreview as m,toolCallRecoveryEnabled as w}from"../../recovery/tool-call.js";import{controlGaps as R,successfulEvidenceItems as h,successfulEvidenceToolIds as T}from"../../quality/event-evidence.js";export async function recoverAdapterResultOutput(t){let r=t.result,a=t.request;const n=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}(t.recoveryPolicy),R=new Set,h=new Set;for(let e=0;;e+=1){const s=t.store.getRun(t.requestId)?.events??[],l=effectiveRecoveryToolIds(a,t.agent.tools),c=buildNonFocusedRecoveryRequest({request:a,output:r.text,events:s,policy:t.recoveryPolicy,declaredToolIds:t.agent.tools,visibleToolIds:l});if(c){e>=n&&assertNoNonFocusedRecoveryIntent(r.text,t.recoveryPolicy,t.agent.tools,l,s),a=c,emitRepair(t,"runtime.repair.started","result_output",e+1,"non_focused_recovery_intent",void 0,repairDiagnostics(r.text,l)),r=await t.runAdapter(c),emitRepair(t,"runtime.repair.completed","result_output",e+1,"non_focused_recovery_intent","retried",repairDiagnostics(r.text,l));continue}assertNoNonFocusedRecoveryIntent(r.text,t.recoveryPolicy,t.agent.tools,l,s);const i=await recoverRawArgsSequenceByToolGateway(t,a,r,h,e+1,l);if(i){a=i.request,r=i.result;continue}const d=u({output:r.text,agent:t.agent,workspace:t.workspace,toolGateway:t.toolGateway,events:s,candidateToolIds:l,policy:t.recoveryPolicy}),v=d?rawArgsToolKey(d):void 0;if(d&&v&&h.size>0&&!h.has(v)){const o=await recoverRawArgsByToolGateway(t,a,r,d,h,e+1);if(o){a=o.request,r=o.result;continue}}const p=v&&!R.has(v)?o({request:a,output:r.text,agent:t.agent,workspace:t.workspace,toolGateway:t.toolGateway,events:s,candidateToolIds:l,policy:t.recoveryPolicy}):void 0,g=e<n?y({request:a,output:r.text,events:s,availableToolIds:l,policy:t.recoveryPolicy}):void 0,f=p??g;if(!f)break;if(f===p&&R.add(v),a=f,emitRepair(t,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(r.text,l)),r=await t.runAdapter(f),emitRepair(t,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(r.text,l)),f===p){const o=await recoverRepeatedRawArgsByToolGateway(t,a,r,R,h,e+1);o&&(a=o.request,r=o.result)}}return function finalizeRecoveredOutput(t,o){if(!w(t.recoveryPolicy))return o;let r=!1;if(g(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:f(),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 a=p({request:t.request,output:o.text,events:t.store.getRun(t.requestId)?.events??[],policy:t.recoveryPolicy});return a&&(r=!0,o={...o,text:a,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")),r||(g(o.text,t.recoveryPolicy)&&emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(o.text,t.agent.tools)),c(o.text,t.recoveryPolicy),function assertNoRawArgsToolOutput(e,t){if(s({output:t,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:effectiveRecoveryToolIds(e.request,e.agent.tools),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: ${m(t)}`)}(t,o.text),l(o.text,t.agent.tools,t.recoveryPolicy),i(o.text,t.store.getRun(t.requestId)?.events??[],t.recoveryPolicy),v(o.text,t.recoveryPolicy),d(o.text,t.recoveryPolicy),e({output:o.text,events:t.store.getRun(t.requestId)?.events??[],availableToolIds:t.agent.tools})),o}(t,r)}async function recoverRawArgsSequenceByToolGateway(e,t,o,r,s,u){if(!e.runRecoveredToolCall)return;const l=n({output:o.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:u,policy:e.recoveryPolicy});if(l.length<2||l.some(e=>r.has(rawArgsToolKey(e))))return;emitRepair(e,"runtime.repair.started","result_output",s,"raw_args_tool_sequence_gateway_recovery",void 0,repairDiagnostics(o.text,u));const c=[];for(const t of l){r.add(rawArgsToolKey(t));const o=await e.runRecoveredToolCall(t.toolId,t.args);c.push({match:t,toolOutput:visibleRecoveredToolOutput(o)})}const i=a({request:t,evidences:c}),d=await e.runAdapter(i),v=d.text.trim()?d:{...d,text:buildEmptyRecoveredToolSequenceBlocker({evidences:c,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...d.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool_sequence"}}};return emitRepair(e,"runtime.repair.completed","result_output",s,"raw_args_tool_sequence_gateway_recovery","retried",repairDiagnostics(v.text,u)),{request:i,result:v}}async function recoverRepeatedRawArgsByToolGateway(e,t,o,r,a,s){const n=u({output:o.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:effectiveRecoveryToolIds(t,e.agent.tools),policy:e.recoveryPolicy});if(!n||!e.runRecoveredToolCall)return;const l=rawArgsToolKey(n);return r.has(l)&&!a.has(l)?recoverRawArgsByToolGateway(e,t,o,n,a,s):void 0}async function recoverRawArgsByToolGateway(e,t,o,a,s,n){if(!e.runRecoveredToolCall)return;const u=rawArgsToolKey(a);if(s.has(u))return;s.add(u),emitRepair(e,"runtime.repair.started","result_output",n,"raw_args_tool_gateway_recovery",void 0,repairDiagnostics(o.text,e.agent.tools));const l=visibleRecoveredToolOutput(await e.runRecoveredToolCall(a.toolId,a.args)),c=r({request:t,match:a,toolOutput:l}),i=await e.runAdapter(c),d=i.text.trim()?i:{...i,text:buildEmptyRecoveredToolBlocker({match:a,toolOutput:l,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...i.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool"}}};return emitRepair(e,"runtime.repair.completed","result_output",n,"raw_args_tool_gateway_recovery","retried",repairDiagnostics(d.text,e.agent.tools)),{request:c,result:d}}function assertNoNonFocusedRecoveryIntent(e,t,o,r,a){const s=nonFocusedRecoveryIntent(e,t,o,r);if(!s)return;const n=new Set(T(a)),u=s.nonFocused.filter(e=>!n.has(e)),l=u.length>0?u:s.nonFocused;throw new Error(`Focused recovery output referenced non-focused tool(s): ${l.join(", ")}. The backend must call one of the focused gateway tools: ${r.join(", ")}.`)}function buildNonFocusedRecoveryRequest(e){const t=nonFocusedRecoveryIntent(e.output,e.policy,e.declaredToolIds,e.visibleToolIds);if(!t)return;const o=h(e.events),r=new Set(T(e.events));if(t.nonFocused.some(e=>!r.has(e)))return;const a=o.slice(-5).map(e=>`- ${e.source}: ${function previewRecoveredEvidence(e){const t=e.replace(/\s+/gu," ").trim();return t.length>1e3?`${t.slice(0,997)}...`:t}(e.output)}`);return{...e.request,input:[e.request.input,"","Stable runtime recovery: the previous recovery output referenced tool(s) that already have successful evidence but are not allowed targets for this focused turn.",`Already completed non-focused tool(s): ${t.nonFocused.join(", ")}`,`Allowed focused tool target(s): ${e.visibleToolIds.join(", ")}`,"Reuse the prior successful evidence below to build one allowed focused tool call. Do not call already completed non-focused tools again.","The next assistant action must be the backend's structured tool call for one allowed focused target, with no prose before it.","","Prior successful tool evidence:",...a,"","Previous invalid recovery output:",e.output].join("\n"),metadata:{...e.request.metadata,stableHarnessRecovery:"tool_call"}}}function nonFocusedRecoveryIntent(e,o,r,a){if(0===a.length||a.length===r.length)return;const s=new Set(a),n=visibleToolCandidates(e,r).filter(e=>!s.has(e)),u=g(e,o)||t(e,r)||function containsJsonToolEnvelope(e){const t=e.trim(),o=t.match(/^```(?:json)?\s*\n([\s\S]*?)\n```$/iu)?.[1]?.trim(),r=o??t;if(!r.startsWith("{")||!r.endsWith("}")||r.length>6e3)return!1;try{const e=JSON.parse(r);if(!function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e))return!1;const t=["tool","tool_name","name","type","subagent_type"].some(t=>"string"==typeof e[t]),o=["args","arguments","parameters","params","kwargs"].some(t=>t in e);return t&&o}catch{return!1}}(e);return n.length>0&&u?{nonFocused:n}:void 0}function emitRepair(e,t,o,r,a,s,n){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...n?{diagnostics:n}:{}};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:s??"retried"})}function repairDiagnostics(e,t){return{outputPreview:m(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])containsDelimitedToken(e,r)&&o.add(r);return[...o]}function containsDelimitedToken(e,t){if(!t)return!1;let o=e.indexOf(t);for(;o>=0;){const r=0===o?"":e[o-1],a=e[o+t.length]??"";if(!isTokenChar(r)&&!isTokenChar(a))return!0;o=e.indexOf(t,o+t.length)}return!1}function isTokenChar(e){return"_"===e||"-"===e||e>="A"&&e<="Z"||e>="a"&&e<="z"||e>="0"&&e<="9"}function effectiveRecoveryToolIds(e,t){const o=function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[]}(e.metadata?.stableHarnessRequiredEvidenceTools).filter(e=>t.includes(e));return o.length>0?o:t}function rawArgsToolKey(e){return`${e.toolId}:${JSON.stringify(e.args)}`}function visibleRecoveredToolOutput(e){return("string"==typeof e.text?e.text.trim():"")||"The recovered tool completed successfully but returned no user-visible output."}function buildEmptyRecoveredToolBlocker(e){const t=R(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")}function buildEmptyRecoveredToolSequenceBlocker(e){const t=R(e.events);return["Stable runtime recovery executed matched declared tools, but the backend returned no user-facing output after receiving the executed evidence.","",...e.evidences.flatMap((e,t)=>[`Executed tool ${t+1}: ${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.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
".": "./dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@stable-harness/governance": "0.0.
|
|
16
|
-
"@stable-harness/memory": "0.0.
|
|
15
|
+
"@stable-harness/governance": "0.0.131",
|
|
16
|
+
"@stable-harness/memory": "0.0.131"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/protocols",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
"main": "dist/src/index.js",
|
|
12
12
|
"types": "dist/src/index.d.ts",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"@stable-harness/core": "0.0.
|
|
14
|
+
"@stable-harness/core": "0.0.131"
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/workspace-yaml",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
".": "./dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@stable-harness/core": "0.0.
|
|
15
|
+
"@stable-harness/core": "0.0.131"
|
|
16
16
|
}
|
|
17
17
|
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "stable-harness",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
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.
|
|
86
|
-
"@stable-harness/adapter-langgraph": "0.0.
|
|
87
|
-
"@stable-harness/core": "0.0.
|
|
88
|
-
"@stable-harness/governance": "0.0.
|
|
89
|
-
"@stable-harness/memory": "0.0.
|
|
90
|
-
"@stable-harness/protocols": "0.0.
|
|
91
|
-
"@stable-harness/tool-gateway": "0.0.
|
|
92
|
-
"@stable-harness/workspace-yaml": "0.0.
|
|
85
|
+
"@stable-harness/adapter-deepagents": "0.0.131",
|
|
86
|
+
"@stable-harness/adapter-langgraph": "0.0.131",
|
|
87
|
+
"@stable-harness/core": "0.0.131",
|
|
88
|
+
"@stable-harness/governance": "0.0.131",
|
|
89
|
+
"@stable-harness/memory": "0.0.131",
|
|
90
|
+
"@stable-harness/protocols": "0.0.131",
|
|
91
|
+
"@stable-harness/tool-gateway": "0.0.131",
|
|
92
|
+
"@stable-harness/workspace-yaml": "0.0.131",
|
|
93
93
|
"deepagents": "^1.10.1",
|
|
94
94
|
"langchain": "^1.4.0",
|
|
95
95
|
"yaml": "^2.8.2",
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as l}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as
|
|
1
|
+
import{realpathSync as e}from"node:fs";import t from"node:path";import{buildRuntimeSystemPrompt as r}from"@stable-harness/core";import{createBuiltinToolPolicyMiddleware as n,createObserverMiddleware as o}from"./internal/builtin-tool-policy.js";import{resolveFilesystemPermissions as s}from"./internal/builtin/permissions.js";import{createToolRepeatState as a}from"@stable-harness/core";import{buildGatewayTools as i,stringifyDeepAgentResult as l}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as c}from"./internal/messages.js";import{createRawToolCallParserMiddleware as p}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as g}from"./retry-policy.js";import{streamDeepAgentResult as m}from"./internal/stream-events.js";import{cleanupDeepAgentsRuntimeSubstrate as f,resolveDeepAgentsRuntimeSubstrate as y}from"./internal/substrate/runtime.js";import{createDefaultDeepAgentsBackend as v}from"./internal/vfs-backend.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){const r=focusedRecoveryToolIds(t),n=recoveryVisibleTools(t,t.agent.tools);if(t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.handoff",modelRef:t.agent.modelRef,tools:t.agent.tools,gatewayTools:n,...r.length>0?{focusedRecoveryTools:r,recoveryMode:"required_evidence_tools"}:{},skills:t.agent.skills,subagents:t.agent.subagents}}),(r.length>0||n.length!==t.agent.tools.length)&&t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",phase:"agent.gateway.tools",tools:n,declaredTools:t.agent.tools,...r.length>0?{focusedRecoveryTools:r,recoveryMode:"required_evidence_tools"}:{}}}),e.runner)return e.runner(t);const o=e.createDeepAgent?void 0:await async function loadDeepAgentsModule(){try{return await async function importOptionalPackage(e){return import(e)}("deepagents")}catch(e){throw new Error(`DeepAgents package is required for the default adapter path: ${function formatError(e){return e instanceof Error?e.message:String(e)}(e)}`)}}(),a=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(o),d={...readDeepAgentsConfig(e.config),...readDeepAgentsConfig(t.agent.config.deepagents)},p=y(t,d),u=resolveDeepAgentsSkills(t,t.agent),g=resolveDeepAgentsMemory(t,t.agent),A=void 0===d.backend?await v({workspaceRoot:t.workspace.root,skills:u,memory:g,config:d}):{cleanup:async()=>{}};try{const e=void 0===A.backend&&void 0===d.backend,r=a(function buildDeepAgentParams(e,t,r,n,o={}){const a=o.skills??resolveDeepAgentsSkills(e,e.agent),l=o.memory??resolveDeepAgentsMemory(e,e.agent),d=t.permissions??s(e,e.agent,{enabled:!0===o.autoPathPermissions}),c=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:t.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:t.backend??o.backend??resolveDeepAgentsBackend(e,n,a),checkpointer:r.checkpointer,store:r.store,middleware:mergeMiddleware(e,e.agent,t.middleware,c),responseFormat:t.responseFormat,contextSchema:t.contextSchema,interruptOn:t.interruptOn,generalPurposeAgent:readBoolean(t.generalPurposeAgent),taskDescription:readString(t.taskDescription),permissions:d,tools:i(e,e.agent.id,recoveryVisibleTools(e,e.agent.tools),resolveAgentRepairModel(0,e.agent,t),c),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),a=n.permissions??s(e,r,{enabled:!0===o.autoPathPermissions}),l=scopedInput(e,r),d=requestScopedRepeatState(e,t);return pruneUndefined({name:t,description:r?.description??readString(r?.config.description)??r?.id,systemPrompt:buildSystemPrompt(e,r),model:n.model??(r?resolveAgentModel(e,r):void 0),middleware:mergeMiddleware(l,r,n.middleware,d),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,responseFormat:n.responseFormat,tools:i(e,t,recoveryVisibleTools(e,r?.tools??[]),resolveAgentRepairModel(0,0,n),d),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:l,skills:a})}(t,d,p,o,{backend:A.backend,skills:u,memory:g,autoPathPermissions:e})),n=c(t),f=function buildDeepAgentInvokeConfig(e,t){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit),configurable:{thread_id:t}})}(t.agent,p.threadId);if(!0===t.request.metadata?.openaiStream&&r.streamEvents){const e=await r.streamEvents(n,{version:"v3",...f});return await m(t,e,l)}const y=await r.invoke(n,f);return l(y)}finally{await A.cleanup(),await f(p)}}}}function recoveryVisibleTools(e,t){const r=focusedRecoveryToolIds(e);return 0===r.length?t:t.filter(e=>r.includes(e))}function focusedRecoveryToolIds(e){return readStringArray(e.request.metadata?.stableHarnessRequiredEvidenceTools)??[]}function buildSystemPrompt(e,t){const n=t?.systemPrompt??readString(t?.config.systemPrompt);return r({workspace:e.workspace,request:e.request,agent:t},n)}function resolveDeepAgentsMemory(e,t){const r=readDeepAgentsStringArray(t?.config,"memory");if(r)return r;const n=[...readAgentMemorySources(e.workspace.root,t),...d(e.workspace).map(e=>`/memories/${e.id}.md`)],o=[...new Set(n)];return o.length>0?o:void 0}function readAgentMemorySources(e,t){return(t?.memory??[]).flatMap(t=>"string"==typeof t&&t.trim()?[backendMemorySourcePath(e,t.trim())]:isRecord(t)&&"string"==typeof t.path&&t.path.trim()?[backendMemorySourcePath(e,t.path.trim())]:[])}function backendMemorySourcePath(e,r){if(r.startsWith("/"))return r;if(t.isAbsolute(r)){const n=t.relative(e,r);return n&&!n.startsWith("..")?`/${n.split(t.sep).join("/")}`:canonicalPath(r)}const n=r.split(t.sep).join("/");return n.startsWith("/")?n:`/${n}`}function resolveDeepAgentsSkills(e,r){const n=readDeepAgentsStringArray(r?.config,"skills");if(n)return n;const o=[...new Set((r?.skills??[]).map(t=>e.workspace.skills.get(t)?.path).filter(e=>"string"==typeof e&&e.trim().length>0).map(r=>function backendSkillSourcePath(e,r){const n=t.dirname(t.dirname(r)),o=t.relative(e,n);return!o||o.startsWith("..")||t.isAbsolute(o)?""===o?"/":canonicalPath(n):`/${o.split(t.sep).join("/")}`}(e.workspace.root,r)))];return o.length>0?o:void 0}function resolveDeepAgentsBackend(e,t,r){if(t?.FilesystemBackend&&r&&0!==r.length)return()=>new t.FilesystemBackend({rootDir:e.workspace.root})}function mergeMiddleware(e,t,r,s=a(e.workspace.runtime.toolGateway)){const i=Array.isArray(r)?r:[],l=scopedInput(e,t),d=new Set,c=readDeepAgentsConfig(t?.config.deepagents);return[o(l,{observedToolIds:d,repeatState:s,repairModel:resolveAgentRepairModel(0,0,c)}),n(l,{repeatState:s}),...g(e.workspace.runtime.retry),...i,p(l)]}function requestScopedRepeatState(e,t){const r=`deepagents.repeat.${t}`,n=e.requestState?.get(r);if(n)return n;const o=a(e.workspace.runtime.toolGateway);return e.requestState&&o&&e.requestState.set(r,o),o}function scopedInput(e,t){return t?{...e,agent:t}:e}function resolveAgentModel(e,t){const r=t.modelRef?e.workspace.models.get(t.modelRef):void 0;return r?u(r):void 0}function resolveAgentRepairModel(e,t,r){const n=r.model;return function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}(n)?n:void 0}function readDeepAgentsConfig(e){return isRecord(e)?e:{}}function readDeepAgentsStringArray(e,t){const r=isRecord(e)?e:{},n=readDeepAgentsConfig(r.deepagents),o="memory"===t?["memory","memorySources"]:["skills","skillSources"];for(const e of o){const t=readStringArray(n[e]);if(t)return t}return readStringArray(r[t])}function pruneUndefined(e){return Object.fromEntries(Object.entries(e).filter(([,e])=>void 0!==e))}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readNumber(e){return"number"==typeof e&&Number.isFinite(e)?e:void 0}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e):void 0}function canonicalPath(t){try{return e.native(t)}catch{return t}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
@@ -7,7 +7,9 @@ export declare function validateFilesystemBuiltinCall(input: AdapterRunInput, to
|
|
|
7
7
|
id?: string;
|
|
8
8
|
};
|
|
9
9
|
}): ToolMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>> | undefined;
|
|
10
|
-
export declare function resolveFilesystemPermissions(input: AdapterRunInput, agent: WorkspaceAgent | undefined
|
|
10
|
+
export declare function resolveFilesystemPermissions(input: AdapterRunInput, agent: WorkspaceAgent | undefined, options?: {
|
|
11
|
+
enabled?: boolean;
|
|
12
|
+
}): {
|
|
11
13
|
operations: string[];
|
|
12
14
|
paths: string[];
|
|
13
15
|
mode: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{realpathSync as e}from"node:fs";import{ToolMessage as t}from"@langchain/core/messages";export const filesystemBuiltinToolIds=new Set(["ls","read_file","write_file","edit_file","glob","grep"]);export function validateFilesystemBuiltinCall(e,n,i){if(isFilesystemDisabled(e)&&filesystemBuiltinToolIds.has(n))return new t({tool_call_id:i.toolCall?.id??`stable-harness-${n}-policy`,name:n,content:`Filesystem builtin tool '${n}' is disabled for this agent. Do not retry filesystem tools; use the agent's registered workspace tools and already collected evidence instead.`})}export function resolveFilesystemPermissions(e,t){const
|
|
1
|
+
import{realpathSync as e}from"node:fs";import{ToolMessage as t}from"@langchain/core/messages";export const filesystemBuiltinToolIds=new Set(["ls","read_file","write_file","edit_file","glob","grep"]);export function validateFilesystemBuiltinCall(e,n,i){if(isFilesystemDisabled(e)&&filesystemBuiltinToolIds.has(n))return new t({tool_call_id:i.toolCall?.id??`stable-harness-${n}-policy`,name:n,content:`Filesystem builtin tool '${n}' is disabled for this agent. Do not retry filesystem tools; use the agent's registered workspace tools and already collected evidence instead.`})}export function resolveFilesystemPermissions(e,t,n={}){if(!0!==n.enabled)return;const i=readConfigRecord(t?.config,"builtinTools");if(!1===i?.filesystem)return;const o=[];return o.push(...function skillReadPermissions(e,t){const n=[...new Set((t?.skills??[]).flatMap(t=>function skillReadPaths(e,t){return t?[...new Set([t,canonicalPath(t),backendSkillPath(e,t)])].flatMap(e=>function skillReadPathCandidates(e){const t=e.replace(/\/+$/u,""),n=t.endsWith("/SKILL.md")?t.slice(0,-9):t,i=function parentPath(e){const t=e.lastIndexOf("/");return t>0?e.slice(0,t):void 0}(n);return[t,n,`${n}/**`,...i?[i,`${i}/**`]:[]]}(e)):[]}(e.workspace.root,e.workspace.skills.get(t)?.path)).filter(e=>e.startsWith("/")))];return n.length>0?[{operations:["read"],paths:n,mode:"allow"}]:[]}(e,t)),deepagentsMemoryWritable(e)||deepagentsMemoryWritable(e)||o.push({operations:["write"],paths:["/memories/**"],mode:"deny"}),o.length>0?o:void 0}export function isFilesystemDisabled(e){const t=readConfigRecord(e.agent.config,"builtinTools");return!1===t?.filesystem}export function isFilesystemTool(e){return"string"==typeof e&&filesystemBuiltinToolIds.has(e)}function backendSkillPath(e,t){const n=function pathRelative(e,t){const n=e.split("/").filter(Boolean),i=t.split("/").filter(Boolean);if(!(i.length<n.length)){for(let e=0;e<n.length;e+=1)if(n[e]!==i[e])return;return i.slice(n.length).join("/")}}(e,t);return void 0===n?t:`/${n.split("/").filter(Boolean).join("/")}`}function canonicalPath(t){try{return e.native(t)}catch{return t}}function deepagentsMemoryWritable(e){const t=readConfigRecord(e.workspace.runtime.memory,"deepagentsMem");return!1!==t?.write}function readConfigRecord(e,t){const n=isRecord(e)?e:{};return isRecord(n[t])?n[t]:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/adapter-deepagents",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -16,7 +16,7 @@
|
|
|
16
16
|
"@langchain/node-vfs": "^0.1.4",
|
|
17
17
|
"@langchain/ollama": "^1.2.7",
|
|
18
18
|
"@langchain/openai": "^1.4.5",
|
|
19
|
-
"@stable-harness/core": "0.0.
|
|
19
|
+
"@stable-harness/core": "0.0.131",
|
|
20
20
|
"deepagents": "^1.10.1",
|
|
21
21
|
"langchain": "^1.4.0"
|
|
22
22
|
},
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/adapter-langgraph",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
"types": "dist/src/index.d.ts",
|
|
13
13
|
"peerDependencies": {
|
|
14
14
|
"@langchain/langgraph": "^1.3.0",
|
|
15
|
-
"@stable-harness/core": "0.0.
|
|
15
|
+
"@stable-harness/core": "0.0.131"
|
|
16
16
|
}
|
|
17
17
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/cli",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -15,12 +15,12 @@
|
|
|
15
15
|
"types": "dist/src/index.d.ts",
|
|
16
16
|
"peerDependencies": {
|
|
17
17
|
"@langchain/langgraph-api": "^1.2.1",
|
|
18
|
-
"@stable-harness/adapter-deepagents": "0.0.
|
|
19
|
-
"@stable-harness/adapter-langgraph": "0.0.
|
|
20
|
-
"@stable-harness/core": "0.0.
|
|
21
|
-
"@stable-harness/memory": "0.0.
|
|
22
|
-
"@stable-harness/protocols": "0.0.
|
|
23
|
-
"@stable-harness/tool-gateway": "0.0.
|
|
24
|
-
"@stable-harness/workspace-yaml": "0.0.
|
|
18
|
+
"@stable-harness/adapter-deepagents": "0.0.131",
|
|
19
|
+
"@stable-harness/adapter-langgraph": "0.0.131",
|
|
20
|
+
"@stable-harness/core": "0.0.131",
|
|
21
|
+
"@stable-harness/memory": "0.0.131",
|
|
22
|
+
"@stable-harness/protocols": "0.0.131",
|
|
23
|
+
"@stable-harness/tool-gateway": "0.0.131",
|
|
24
|
+
"@stable-harness/workspace-yaml": "0.0.131"
|
|
25
25
|
}
|
|
26
26
|
}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function hasPlanningEvidence(t){return t.some(t=>{const e=readAdapterEvent(t);return!!e&&("plan"===e.traceType||String(e.traceLabel??"").startsWith("plan.")||"write_todos"===e.toolId&&String(e.phase??"").startsWith("agent.tool."))})}export function successfulEvidenceToolIds(t){const e=t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return[t.toolId];const e=readAdapterEvent(t);return isToolResultEvent(e)&&
|
|
1
|
+
export function hasPlanningEvidence(t){return t.some(t=>{const e=readAdapterEvent(t);return!!e&&("plan"===e.traceType||String(e.traceLabel??"").startsWith("plan.")||"write_todos"===e.toolId&&String(e.phase??"").startsWith("agent.tool."))})}export function successfulEvidenceToolIds(t){const e=t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return[t.toolId];const e=readAdapterEvent(t),n=readToolSource(e);return isToolResultEvent(e)&&n&&isSuccessfulEvidenceEvent(e)?[n]:[]});return[...new Set(e)]}export function successfulEvidenceOutputs(t){return successfulEvidenceItems(t).map(t=>t.output)}export function successfulEvidenceItems(t){return t.flatMap(t=>{if("runtime.tool.direct.completed"===t.type)return stringifyEvidence(t.output).map(e=>({source:t.toolId,output:e}));const e=readAdapterEvent(t),n=readToolSource(e);return isToolResultEvent(e)&&n?!isSuccessfulEvidenceEvent(e)||function isPlanningTool(t){return"write_todos"===t||"read_todos"===t}(n)?[]:stringifyEvidence(e.evidenceOutput??e.output).filter(t=>function isUsableEvidenceOutput(t,e){return!("task"===t&&function looksLikeUnexecutedToolIntent(t){const e=t.trim();if(e.length>4e3)return!1;const n=function extractJsonSource(t){const e=t.trim();if(e.startsWith("{")&&e.endsWith("}")||e.startsWith("[")&&e.endsWith("]"))return e;if(!e.startsWith("```"))return;const n=e.indexOf("\n"),r=e.lastIndexOf("```");return n<0||r<=n?void 0:e.slice(n+1,r).trim()}(e);return n?function containsToolEnvelope(t){try{const e=JSON.parse(t);return Array.isArray(e)?e.some(isToolEnvelopeRecord):isToolEnvelopeRecord(e)}catch{return!1}}(n):function containsToolMarkup(t){const e=t.toLowerCase();return e.includes("<tool_call")||e.includes("</tool_call")||e.includes("<tool_code")||e.includes("</tool_code")}(e)||function containsBareToolFence(t){const e=t.trim(),n=e.indexOf("```");if(n<0||e.indexOf("```",n+3)!==e.lastIndexOf("```"))return!1;const r=e.indexOf("\n",n+3),o=e.lastIndexOf("```");return!(r<0||o<=r)&&function isIdentifierPath(t){return t.length>0&&[...t].every((t,e)=>{const n=t>="A"&&t<="Z"||t>="a"&&t<="z"||"_"===t;return 0===e?n:n||t>="0"&&t<="9"||"."===t||"-"===t})}(e.slice(r+1,o).trim())}(e)}(e))}(n,t)).map(t=>({source:n,output:t})):[]})}export function controlBlockers(t){const e=successfulEventIndexesBySource(t);return t.flatMap((t,n)=>{const r=readAdapterEvent(t),o=readControlStatus(r),s=readControlSource(r)??"tool";return o&&isBlockerStatus(o)?isResolvedByLaterCompletion(o)&&completedAfter(e,s,n)||isResolvedByLaterAnyCompletion(o)&&completedAfterAny(e,n)?[]:[`${s}:${o}`]:[]})}export function controlGaps(t){const e=new Set(successfulEvidenceItems(t).map(t=>t.source));return t.flatMap(t=>{const n=readAdapterEvent(t),r=readControlStatus(n),o=readControlSource(n)??"tool";return r&&isGapStatus(r)?e.has(o)&&isResolvedByLaterCompletion(r)?[]:[`${o}:${r}`]:[]})}export function omittedControlGaps(t,e){const n=successfulEventIndexesBySource(t),r=successfulEvidenceItems(t),o=function outputHasUnsupportedEvidenceClaims(t,e,n){const r=function evidenceCorpus(t,e){return[...e.map(t=>t.output),...t.flatMap(t=>"runtime.request.started"===t.type?[t.input??""]:[]),...t.flatMap(t=>"runtime.memory.recall.completed"===t.type?[t.context]:[])].join("\n")}(e,n).toLowerCase();return unsupportedTokens(t,r,/\b[A-Z][A-Z0-9]{1,12}-\d+\b/gu).length>0||unsupportedTokens(t,r,/\b[A-Za-z_$][A-Za-z0-9_$]*[A-Z][A-Za-z0-9_$]*\b/gu).filter(isCodeLikeIdentifier).length>=2}(e,t,r);return t.flatMap((t,s)=>{const u=readAdapterEvent(t),i=readControlStatus(u),a=readControlSource(u)??"tool";return i&&function isOmittedControlStatus(t){return isGapStatus(t)||isBlockerStatus(t)}(i)?isResolvedByLaterCompletion(i)&&completedAfter(n,a,s)||isResolvedByLaterAnyCompletion(i)&&completedAfterAny(n,s)||!o&&outputUsesPriorEvidence(e,a,r)?[]:[`${a}:${i}`]:[]})}function stringifyEvidence(t){return"string"==typeof t?t.trim()?[t]:[]:null==t?[]:[JSON.stringify(t)]}function isToolEnvelopeRecord(t){return!!isRecord(t)&&["tool","toolId","toolName","tool_name","name","type","subagent_type"].some(e=>"string"==typeof t[e])&&["args","arguments","parameters","params","kwargs","task"].some(e=>e in t)}function readAdapterEvent(t){if("runtime.adapter.event"===t.type&&isRecord(t.event))return t.event;const e=t;return isRecord(e)&&isToolResultEvent(e)?e:void 0}function isSuccessfulEvidenceEvent(t){const e=readEventStatus(t);return!e||/^(?:completed|success|ok|recorded)$/iu.test(e)}function isBlockerStatus(t){return/^(?:blocked|approval_required|schema_repair_failed|tool_argument_error|invalid_input|task_inventory_blocked)$/iu.test(t)}function isGapStatus(t){return/^(?:dependency_required|plan_required|repeated_tool_call_limit|duplicate_tool_call)$/iu.test(t)}function isResolvedByLaterCompletion(t){return isGapStatus(t)||isBlockerStatus(t)}function isResolvedByLaterAnyCompletion(t){return"task_inventory_blocked"===t}function successfulEventIndexesBySource(t){const e=new Map;return t.forEach((t,n)=>{const r=function successfulEventSource(t){if("runtime.tool.direct.completed"===t.type)return t.toolId;const e=readAdapterEvent(t),n=readToolSource(e);return isToolResultEvent(e)&&n&&isSuccessfulEvidenceEvent(e)?n:void 0}(t);r&&e.set(r,[...e.get(r)??[],n])}),e}function isToolResultEvent(t){return"deepagents.tool_execution.result"===t?.eventType||"agent.tool.result"===t?.phase||"agent.tool.result"===t?.type||"deepagents.tool_execution.result"===t?.type}function completedAfter(t,e,n){return(t.get(e)??[]).some(t=>t>n)}function completedAfterAny(t,e){return[...t.values()].some(t=>t.some(t=>t>e))}export function outputUsesPriorEvidence(t,e,n){const r=t.toLowerCase();return n.filter(t=>t.source===e).some(t=>{const e=t.output.trim();return!!e&&(!!r.includes(e.slice(0,500).toLowerCase())||function matchingEvidenceTokens(t,e){const n=new Set(["status","completed","success","recorded"]);return[...new Set(e.toLowerCase().match(/[a-z0-9][a-z0-9_.-]{1,}/gu)??[])].filter(t=>!n.has(t)).filter(e=>t.includes(e)).length}(r,e)>=2)})}function unsupportedTokens(t,e,n){return[...new Set(t.match(n)??[])].filter(t=>!e.includes(t.toLowerCase()))}function isCodeLikeIdentifier(t){return!(t.length<8)&&(/(?:Service|Controller|Repository|Manager|Client|Resolver|Agent|Tool|Async)$/u.test(t)||/[a-z][A-Z]/u.test(t))}function readOutputStatus(t){if(isRecord(t)&&"string"==typeof t.status)return t.status;if("string"==typeof t){const e=parseJsonRecord(t);return"string"==typeof e?.status?e.status:t.match(/^Status:\s*([A-Za-z0-9_-]+)/imu)?.[1]}}function parseJsonRecord(t){try{const e=JSON.parse(t);return isRecord(e)?e:void 0}catch{return}}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function readString(t){return"string"==typeof t&&t.trim()?t:void 0}function readEventStatus(t){return readString(t?.controlStatus)??readString(t?.status)??readOutputStatus(t?.output)}function readToolSource(t){return readString(t?.toolId)??readString(t?.toolName)??readString(t?.name)}function readControlStatus(t){const e=function readInventoryRepairControlStatus(t){if("inventory.repair"===t?.phase&&"blocked"===t.status)return"task"===readInventoryRepairSource(t)?"task_inventory_blocked":"blocked"}(t);if(e)return e;const n=readEventStatus(t);return n&&isControlStatus(n)?n:findNestedControlStatus(t)}function readControlSource(t){return readToolSource(t)??readInventoryRepairSource(t)??findNestedToolSource(t)}function isControlStatus(t){return isGapStatus(t)||isBlockerStatus(t)}function findNestedControlStatus(t,e=0){if(e>5||null==t)return;if("string"==typeof t)return function readNestedStringStatus(t,e){const n=parseJsonRecord(t);if(n)return findNestedControlStatus(n,e+1);const r=t.match(/^Status:\s*([A-Za-z0-9_-]+)/imu)?.[1];return r&&isControlStatus(r)?r:function readControlToken(t){const e=t.match(/\b(?:blocked|approval_required|schema_repair_failed|tool_argument_error|invalid_input|task_inventory_blocked|dependency_required|plan_required|repeated_tool_call_limit|duplicate_tool_call)\b/iu)?.[0];return e&&isControlStatus(e)?e:void 0}(t)}(t,e);if(Array.isArray(t))return findFirstNested(t,t=>findNestedControlStatus(t,e+1));if(!isRecord(t))return;const n=readString(t.controlStatus)??readString(t.status);if(n&&isControlStatus(n))return n;const r=readOutputStatus(t.output);return r&&isControlStatus(r)?r:findFirstNested(Object.values(t),t=>findNestedControlStatus(t,e+1))}function findNestedToolSource(t,e=0){if(!(e>5||null==t)){if("string"==typeof t)return function readToolSourceFromText(t){const e=t.match(/["'](?:toolId|toolName|name)["']\s*:\s*["']([^"']+)["']/u)?.[1];return readString(e)}(t);if(Array.isArray(t))return findFirstNested(t,t=>findNestedToolSource(t,e+1));if(isRecord(t))return(readString(t.toolId)??readString(t.toolName)??readString(t.name))||findFirstNested(Object.values(t),t=>findNestedToolSource(t,e+1))}}function findFirstNested(t,e){for(const n of t){const t=e(n);if(void 0!==t)return t}}function readInventoryRepairSource(t){const e=isRecord(t?.diagnostic)?t.diagnostic:void 0;return readString(e?.layer)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{successfulEvidenceItems as e}from"../quality/event-evidence.js";export function buildExecutionContractRecoveryRequest(
|
|
1
|
+
import{successfulEvidenceItems as e,successfulEvidenceToolIds as t}from"../quality/event-evidence.js";export function buildExecutionContractRecoveryRequest(e){if(!0!==function readToolCallRecovery(e){if(!isRecord(e))return{};const t=isRecord(e.recovery)?e.recovery:{};return isRecord(t.toolCall)?t.toolCall:{}}(e.policy).enabled)return;const n=function lastExecutionContractFailure(e){for(let t=e.length-1;t>=0;t-=1){const n=e[t];if("runtime.execution.contract.failed"===n?.type)return{reason:n.reason,missing:readStringArray(n.missingEvidenceTools)}}return{missing:[]}}(e.events);if(0===n.missing.length)return;if("missing_required_evidence_usage"===n.reason){const t=recentSuccessfulEvidence(e.events);return recoverRequest(e.request,["Stable runtime recovery: the execution contract was not satisfied.",`The final answer did not use required executed evidence from: ${n.missing.join(", ")}`,"Synthesize from those required source(s), or call them through normal structured tool calling if their evidence is unavailable.","Do not replace required evidence with unrelated intermediate evidence, progress text, or summaries from other tools.",...t.length>0?["","Prior successful tool evidence:",...t]:[]])}const r=recentSuccessfulEvidence(e.events),o=function recoveryToolTargets(e,n,r){const o=function readToolDependencies(e){return isRecord(e)?new Map(Object.entries(e).map(([e,t])=>[e,readStringArray(t)]).filter(e=>e[1].length>0)):new Map}(function readExecutionContract(e){return isRecord(e.config.executionContract)?e.config.executionContract:{}}(e).toolDependencies),i=new Set(t(r)),s=new Set;for(const e of n)s.add(e),collectUnmetDependencies(e,o,i,s,new Set([e]));return[...s].filter(t=>e.tools.includes(t))}(e.agent,n.missing,e.events);return recoverRequest(e.request,["Stable runtime recovery: the execution contract was not satisfied.",`Required evidence tool(s) were missing: ${n.missing.join(", ")}`,`For this recovery turn, the allowed next tool call target(s) are: ${o.join(", ")}`,"Allowed targets include missing required evidence tools and any declared dependency tools that are still needed to build valid arguments.","Reuse exact values from prior successful tool evidence when building the required tool call. Do not invent replacement paths, IDs, handles, URLs, or parameters.","The next assistant action must be the backend's structured tool call for one allowed target, with no prose before it.","Do not call already completed intermediate tools unless they are listed above.","Do not produce a final answer until the required evidence tool call has executed and you have synthesized its result.","Do not print XML, JSON, markdown fences, pseudo tool-call text, plans, or future-intent text in the final answer.",...r.length>0?["","Prior successful tool evidence:",...r]:[]],{stableHarnessRequiredEvidenceTools:o})}function recoverRequest(e,t,n={}){return{...e,input:[e.input,"",...t].join("\n"),metadata:{...e.metadata,stableHarnessRecovery:"tool_call",...n}}}function collectUnmetDependencies(e,t,n,r,o){for(const i of t.get(e)??[])o.has(i)||(o.add(i),n.has(i)||r.add(i),collectUnmetDependencies(i,t,n,r,o))}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[]}function recentSuccessfulEvidence(t){return e(t).slice(-5).map(e=>`- ${e.source}: ${function previewEvidence(e){const t=e.replace(/\s+/gu," ").trim();return t.length>1500?`${t.slice(0,1497)}...`:t}(e.output)}`)}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{assertNoDeclaredActionOmissionOutput as e}from"../../recovery/control-omission.js";import{containsProgressOnlyToolIntent as t}from"../../recovery/progress-intent.js";import{buildRawArgsRecoveryRequest as o,buildRawArgsToolEvidenceRecoveryRequest as r,buildRawArgsToolSequenceEvidenceRecoveryRequest as a,hasUniqueRawArgsTool as s,matchRawArgsToolSequence as n,matchUniqueRawArgsTool as u}from"../../recovery/raw-args.js";import{assertNoProgressOnlyToolIntentOutput as l,assertNoRawToolCallOutput as c,assertNoRawToolResultOutput as i,assertNoStructurallyIncompleteFinalOutput as d,assertNoToolExecutionErrorOutput as p,buildEvidenceSynthesisOutput as y,buildResultRecoveryRequest as v,containsRawToolCallOutput as g,rawToolCallFailureMessage as m,rawToolCallOutputPreview as f,toolCallRecoveryEnabled as w}from"../../recovery/tool-call.js";import{controlGaps as R,successfulEvidenceItems as h}from"../../quality/event-evidence.js";export async function recoverAdapterResultOutput(t){let r=t.result,a=t.request;const n=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}(t.recoveryPolicy),R=new Set,h=new Set;for(let e=0;;e+=1){const s=t.store.getRun(t.requestId)?.events??[],l=effectiveRecoveryToolIds(a,t.agent.tools),c=buildNonFocusedRecoveryRequest({request:a,output:r.text,events:s,policy:t.recoveryPolicy,declaredToolIds:t.agent.tools,visibleToolIds:l});if(c){e>=n&&assertNoNonFocusedRecoveryIntent(r.text,t.recoveryPolicy,t.agent.tools,l,s),a=c,emitRepair(t,"runtime.repair.started","result_output",e+1,"non_focused_recovery_intent",void 0,repairDiagnostics(r.text,l)),r=await t.runAdapter(c),emitRepair(t,"runtime.repair.completed","result_output",e+1,"non_focused_recovery_intent","retried",repairDiagnostics(r.text,l));continue}assertNoNonFocusedRecoveryIntent(r.text,t.recoveryPolicy,t.agent.tools,l,s);const i=await recoverRawArgsSequenceByToolGateway(t,a,r,h,e+1,l);if(i){a=i.request,r=i.result;continue}const d=u({output:r.text,agent:t.agent,workspace:t.workspace,toolGateway:t.toolGateway,events:s,candidateToolIds:l,policy:t.recoveryPolicy}),p=d?rawArgsToolKey(d):void 0;if(d&&p&&h.size>0&&!h.has(p)){const o=await recoverRawArgsByToolGateway(t,a,r,d,h,e+1);if(o){a=o.request,r=o.result;continue}}const y=p&&!R.has(p)?o({request:a,output:r.text,agent:t.agent,workspace:t.workspace,toolGateway:t.toolGateway,events:s,candidateToolIds:l,policy:t.recoveryPolicy}):void 0,g=e<n?v({request:a,output:r.text,events:s,availableToolIds:l,policy:t.recoveryPolicy}):void 0,m=y??g;if(!m)break;if(m===y&&R.add(p),a=m,emitRepair(t,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(r.text,l)),r=await t.runAdapter(m),emitRepair(t,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(r.text,l)),m===y){const o=await recoverRepeatedRawArgsByToolGateway(t,a,r,R,h,e+1);o&&(a=o.request,r=o.result)}}return function finalizeRecoveredOutput(t,o){if(!w(t.recoveryPolicy))return o;let r=!1;if(g(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:m(),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 a=y({request:t.request,output:o.text,events:t.store.getRun(t.requestId)?.events??[],policy:t.recoveryPolicy});return a&&(r=!0,o={...o,text:a,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")),r||(g(o.text,t.recoveryPolicy)&&emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(o.text,t.agent.tools)),c(o.text,t.recoveryPolicy),function assertNoRawArgsToolOutput(e,t){if(s({output:t,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:effectiveRecoveryToolIds(e.request,e.agent.tools),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: ${f(t)}`)}(t,o.text),l(o.text,t.agent.tools,t.recoveryPolicy),i(o.text,t.store.getRun(t.requestId)?.events??[],t.recoveryPolicy),p(o.text,t.recoveryPolicy),d(o.text,t.recoveryPolicy),e({output:o.text,events:t.store.getRun(t.requestId)?.events??[],availableToolIds:t.agent.tools})),o}(t,r)}async function recoverRawArgsSequenceByToolGateway(e,t,o,r,s,u){if(!e.runRecoveredToolCall)return;const l=n({output:o.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:u,policy:e.recoveryPolicy});if(l.length<2||l.some(e=>r.has(rawArgsToolKey(e))))return;emitRepair(e,"runtime.repair.started","result_output",s,"raw_args_tool_sequence_gateway_recovery",void 0,repairDiagnostics(o.text,u));const c=[];for(const t of l){r.add(rawArgsToolKey(t));const o=await e.runRecoveredToolCall(t.toolId,t.args);c.push({match:t,toolOutput:visibleRecoveredToolOutput(o)})}const i=a({request:t,evidences:c}),d=await e.runAdapter(i),p=d.text.trim()?d:{...d,text:buildEmptyRecoveredToolSequenceBlocker({evidences:c,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...d.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool_sequence"}}};return emitRepair(e,"runtime.repair.completed","result_output",s,"raw_args_tool_sequence_gateway_recovery","retried",repairDiagnostics(p.text,u)),{request:i,result:p}}async function recoverRepeatedRawArgsByToolGateway(e,t,o,r,a,s){const n=u({output:o.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:effectiveRecoveryToolIds(t,e.agent.tools),policy:e.recoveryPolicy});if(!n||!e.runRecoveredToolCall)return;const l=rawArgsToolKey(n);return r.has(l)&&!a.has(l)?recoverRawArgsByToolGateway(e,t,o,n,a,s):void 0}async function recoverRawArgsByToolGateway(e,t,o,a,s,n){if(!e.runRecoveredToolCall)return;const u=rawArgsToolKey(a);if(s.has(u))return;s.add(u),emitRepair(e,"runtime.repair.started","result_output",n,"raw_args_tool_gateway_recovery",void 0,repairDiagnostics(o.text,e.agent.tools));const l=visibleRecoveredToolOutput(await e.runRecoveredToolCall(a.toolId,a.args)),c=r({request:t,match:a,toolOutput:l}),i=await e.runAdapter(c),d=i.text.trim()?i:{...i,text:buildEmptyRecoveredToolBlocker({match:a,toolOutput:l,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...i.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool"}}};return emitRepair(e,"runtime.repair.completed","result_output",n,"raw_args_tool_gateway_recovery","retried",repairDiagnostics(d.text,e.agent.tools)),{request:c,result:d}}function assertNoNonFocusedRecoveryIntent(e,t,o,r,a){const s=nonFocusedRecoveryIntent(e,t,o,r);if(!s)return;const n=new Set(h(a).map(e=>e.source)),u=s.nonFocused.filter(e=>!n.has(e)),l=u.length>0?u:s.nonFocused;throw new Error(`Focused recovery output referenced non-focused tool(s): ${l.join(", ")}. The backend must call one of the focused gateway tools: ${r.join(", ")}.`)}function buildNonFocusedRecoveryRequest(e){const t=nonFocusedRecoveryIntent(e.output,e.policy,e.declaredToolIds,e.visibleToolIds);if(!t)return;const o=h(e.events),r=new Set(o.map(e=>e.source));if(t.nonFocused.some(e=>!r.has(e)))return;const a=o.slice(-5).map(e=>`- ${e.source}: ${function previewRecoveredEvidence(e){const t=e.replace(/\s+/gu," ").trim();return t.length>1e3?`${t.slice(0,997)}...`:t}(e.output)}`);return{...e.request,input:[e.request.input,"","Stable runtime recovery: the previous recovery output referenced tool(s) that already have successful evidence but are not allowed targets for this focused turn.",`Already completed non-focused tool(s): ${t.nonFocused.join(", ")}`,`Allowed focused tool target(s): ${e.visibleToolIds.join(", ")}`,"Reuse the prior successful evidence below to build one allowed focused tool call. Do not call already completed non-focused tools again.","The next assistant action must be the backend's structured tool call for one allowed focused target, with no prose before it.","","Prior successful tool evidence:",...a,"","Previous invalid recovery output:",e.output].join("\n"),metadata:{...e.request.metadata,stableHarnessRecovery:"tool_call"}}}function nonFocusedRecoveryIntent(e,o,r,a){if(0===a.length||a.length===r.length)return;const s=new Set(a),n=visibleToolCandidates(e,r).filter(e=>!s.has(e)),u=g(e,o)||t(e,r)||function containsJsonToolEnvelope(e){const t=e.trim(),o=t.match(/^```(?:json)?\s*\n([\s\S]*?)\n```$/iu)?.[1]?.trim(),r=o??t;if(!r.startsWith("{")||!r.endsWith("}")||r.length>6e3)return!1;try{const e=JSON.parse(r);if(!function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e))return!1;const t=["tool","tool_name","name","type","subagent_type"].some(t=>"string"==typeof e[t]),o=["args","arguments","parameters","params","kwargs"].some(t=>t in e);return t&&o}catch{return!1}}(e);return n.length>0&&u?{nonFocused:n}:void 0}function emitRepair(e,t,o,r,a,s,n){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...n?{diagnostics:n}:{}};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:s??"retried"})}function repairDiagnostics(e,t){return{outputPreview:f(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])containsDelimitedToken(e,r)&&o.add(r);return[...o]}function containsDelimitedToken(e,t){if(!t)return!1;let o=e.indexOf(t);for(;o>=0;){const r=0===o?"":e[o-1],a=e[o+t.length]??"";if(!isTokenChar(r)&&!isTokenChar(a))return!0;o=e.indexOf(t,o+t.length)}return!1}function isTokenChar(e){return"_"===e||"-"===e||e>="A"&&e<="Z"||e>="a"&&e<="z"||e>="0"&&e<="9"}function effectiveRecoveryToolIds(e,t){const o=function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[]}(e.metadata?.stableHarnessRequiredEvidenceTools).filter(e=>t.includes(e));return o.length>0?o:t}function rawArgsToolKey(e){return`${e.toolId}:${JSON.stringify(e.args)}`}function visibleRecoveredToolOutput(e){return("string"==typeof e.text?e.text.trim():"")||"The recovered tool completed successfully but returned no user-visible output."}function buildEmptyRecoveredToolBlocker(e){const t=R(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")}function buildEmptyRecoveredToolSequenceBlocker(e){const t=R(e.events);return["Stable runtime recovery executed matched declared tools, but the backend returned no user-facing output after receiving the executed evidence.","",...e.evidences.flatMap((e,t)=>[`Executed tool ${t+1}: ${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
|
+
import{assertNoDeclaredActionOmissionOutput as e}from"../../recovery/control-omission.js";import{containsProgressOnlyToolIntent as t}from"../../recovery/progress-intent.js";import{buildRawArgsRecoveryRequest as o,buildRawArgsToolEvidenceRecoveryRequest as r,buildRawArgsToolSequenceEvidenceRecoveryRequest as a,hasUniqueRawArgsTool as s,matchRawArgsToolSequence as n,matchUniqueRawArgsTool as u}from"../../recovery/raw-args.js";import{assertNoProgressOnlyToolIntentOutput as l,assertNoRawToolCallOutput as c,assertNoRawToolResultOutput as i,assertNoStructurallyIncompleteFinalOutput as d,assertNoToolExecutionErrorOutput as v,buildEvidenceSynthesisOutput as p,buildResultRecoveryRequest as y,containsRawToolCallOutput as g,rawToolCallFailureMessage as f,rawToolCallOutputPreview as m,toolCallRecoveryEnabled as w}from"../../recovery/tool-call.js";import{controlGaps as R,successfulEvidenceItems as h,successfulEvidenceToolIds as T}from"../../quality/event-evidence.js";export async function recoverAdapterResultOutput(t){let r=t.result,a=t.request;const n=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}(t.recoveryPolicy),R=new Set,h=new Set;for(let e=0;;e+=1){const s=t.store.getRun(t.requestId)?.events??[],l=effectiveRecoveryToolIds(a,t.agent.tools),c=buildNonFocusedRecoveryRequest({request:a,output:r.text,events:s,policy:t.recoveryPolicy,declaredToolIds:t.agent.tools,visibleToolIds:l});if(c){e>=n&&assertNoNonFocusedRecoveryIntent(r.text,t.recoveryPolicy,t.agent.tools,l,s),a=c,emitRepair(t,"runtime.repair.started","result_output",e+1,"non_focused_recovery_intent",void 0,repairDiagnostics(r.text,l)),r=await t.runAdapter(c),emitRepair(t,"runtime.repair.completed","result_output",e+1,"non_focused_recovery_intent","retried",repairDiagnostics(r.text,l));continue}assertNoNonFocusedRecoveryIntent(r.text,t.recoveryPolicy,t.agent.tools,l,s);const i=await recoverRawArgsSequenceByToolGateway(t,a,r,h,e+1,l);if(i){a=i.request,r=i.result;continue}const d=u({output:r.text,agent:t.agent,workspace:t.workspace,toolGateway:t.toolGateway,events:s,candidateToolIds:l,policy:t.recoveryPolicy}),v=d?rawArgsToolKey(d):void 0;if(d&&v&&h.size>0&&!h.has(v)){const o=await recoverRawArgsByToolGateway(t,a,r,d,h,e+1);if(o){a=o.request,r=o.result;continue}}const p=v&&!R.has(v)?o({request:a,output:r.text,agent:t.agent,workspace:t.workspace,toolGateway:t.toolGateway,events:s,candidateToolIds:l,policy:t.recoveryPolicy}):void 0,g=e<n?y({request:a,output:r.text,events:s,availableToolIds:l,policy:t.recoveryPolicy}):void 0,f=p??g;if(!f)break;if(f===p&&R.add(v),a=f,emitRepair(t,"runtime.repair.started","result_output",e+1,"recoverable_result_output",void 0,repairDiagnostics(r.text,l)),r=await t.runAdapter(f),emitRepair(t,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried",repairDiagnostics(r.text,l)),f===p){const o=await recoverRepeatedRawArgsByToolGateway(t,a,r,R,h,e+1);o&&(a=o.request,r=o.result)}}return function finalizeRecoveredOutput(t,o){if(!w(t.recoveryPolicy))return o;let r=!1;if(g(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:f(),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 a=p({request:t.request,output:o.text,events:t.store.getRun(t.requestId)?.events??[],policy:t.recoveryPolicy});return a&&(r=!0,o={...o,text:a,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")),r||(g(o.text,t.recoveryPolicy)&&emitRepair(t,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked",repairDiagnostics(o.text,t.agent.tools)),c(o.text,t.recoveryPolicy),function assertNoRawArgsToolOutput(e,t){if(s({output:t,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:effectiveRecoveryToolIds(e.request,e.agent.tools),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: ${m(t)}`)}(t,o.text),l(o.text,t.agent.tools,t.recoveryPolicy),i(o.text,t.store.getRun(t.requestId)?.events??[],t.recoveryPolicy),v(o.text,t.recoveryPolicy),d(o.text,t.recoveryPolicy),e({output:o.text,events:t.store.getRun(t.requestId)?.events??[],availableToolIds:t.agent.tools})),o}(t,r)}async function recoverRawArgsSequenceByToolGateway(e,t,o,r,s,u){if(!e.runRecoveredToolCall)return;const l=n({output:o.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:u,policy:e.recoveryPolicy});if(l.length<2||l.some(e=>r.has(rawArgsToolKey(e))))return;emitRepair(e,"runtime.repair.started","result_output",s,"raw_args_tool_sequence_gateway_recovery",void 0,repairDiagnostics(o.text,u));const c=[];for(const t of l){r.add(rawArgsToolKey(t));const o=await e.runRecoveredToolCall(t.toolId,t.args);c.push({match:t,toolOutput:visibleRecoveredToolOutput(o)})}const i=a({request:t,evidences:c}),d=await e.runAdapter(i),v=d.text.trim()?d:{...d,text:buildEmptyRecoveredToolSequenceBlocker({evidences:c,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...d.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool_sequence"}}};return emitRepair(e,"runtime.repair.completed","result_output",s,"raw_args_tool_sequence_gateway_recovery","retried",repairDiagnostics(v.text,u)),{request:i,result:v}}async function recoverRepeatedRawArgsByToolGateway(e,t,o,r,a,s){const n=u({output:o.text,agent:e.agent,workspace:e.workspace,toolGateway:e.toolGateway,events:e.store.getRun(e.requestId)?.events??[],candidateToolIds:effectiveRecoveryToolIds(t,e.agent.tools),policy:e.recoveryPolicy});if(!n||!e.runRecoveredToolCall)return;const l=rawArgsToolKey(n);return r.has(l)&&!a.has(l)?recoverRawArgsByToolGateway(e,t,o,n,a,s):void 0}async function recoverRawArgsByToolGateway(e,t,o,a,s,n){if(!e.runRecoveredToolCall)return;const u=rawArgsToolKey(a);if(s.has(u))return;s.add(u),emitRepair(e,"runtime.repair.started","result_output",n,"raw_args_tool_gateway_recovery",void 0,repairDiagnostics(o.text,e.agent.tools));const l=visibleRecoveredToolOutput(await e.runRecoveredToolCall(a.toolId,a.args)),c=r({request:t,match:a,toolOutput:l}),i=await e.runAdapter(c),d=i.text.trim()?i:{...i,text:buildEmptyRecoveredToolBlocker({match:a,toolOutput:l,events:e.store.getRun(e.requestId)?.events??[]}),metadata:{...i.metadata,toolCallRecovery:{blocked:!0,reason:"empty_output_after_recovered_tool"}}};return emitRepair(e,"runtime.repair.completed","result_output",n,"raw_args_tool_gateway_recovery","retried",repairDiagnostics(d.text,e.agent.tools)),{request:c,result:d}}function assertNoNonFocusedRecoveryIntent(e,t,o,r,a){const s=nonFocusedRecoveryIntent(e,t,o,r);if(!s)return;const n=new Set(T(a)),u=s.nonFocused.filter(e=>!n.has(e)),l=u.length>0?u:s.nonFocused;throw new Error(`Focused recovery output referenced non-focused tool(s): ${l.join(", ")}. The backend must call one of the focused gateway tools: ${r.join(", ")}.`)}function buildNonFocusedRecoveryRequest(e){const t=nonFocusedRecoveryIntent(e.output,e.policy,e.declaredToolIds,e.visibleToolIds);if(!t)return;const o=h(e.events),r=new Set(T(e.events));if(t.nonFocused.some(e=>!r.has(e)))return;const a=o.slice(-5).map(e=>`- ${e.source}: ${function previewRecoveredEvidence(e){const t=e.replace(/\s+/gu," ").trim();return t.length>1e3?`${t.slice(0,997)}...`:t}(e.output)}`);return{...e.request,input:[e.request.input,"","Stable runtime recovery: the previous recovery output referenced tool(s) that already have successful evidence but are not allowed targets for this focused turn.",`Already completed non-focused tool(s): ${t.nonFocused.join(", ")}`,`Allowed focused tool target(s): ${e.visibleToolIds.join(", ")}`,"Reuse the prior successful evidence below to build one allowed focused tool call. Do not call already completed non-focused tools again.","The next assistant action must be the backend's structured tool call for one allowed focused target, with no prose before it.","","Prior successful tool evidence:",...a,"","Previous invalid recovery output:",e.output].join("\n"),metadata:{...e.request.metadata,stableHarnessRecovery:"tool_call"}}}function nonFocusedRecoveryIntent(e,o,r,a){if(0===a.length||a.length===r.length)return;const s=new Set(a),n=visibleToolCandidates(e,r).filter(e=>!s.has(e)),u=g(e,o)||t(e,r)||function containsJsonToolEnvelope(e){const t=e.trim(),o=t.match(/^```(?:json)?\s*\n([\s\S]*?)\n```$/iu)?.[1]?.trim(),r=o??t;if(!r.startsWith("{")||!r.endsWith("}")||r.length>6e3)return!1;try{const e=JSON.parse(r);if(!function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e))return!1;const t=["tool","tool_name","name","type","subagent_type"].some(t=>"string"==typeof e[t]),o=["args","arguments","parameters","params","kwargs"].some(t=>t in e);return t&&o}catch{return!1}}(e);return n.length>0&&u?{nonFocused:n}:void 0}function emitRepair(e,t,o,r,a,s,n){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:o,attempt:r,reason:a,...n?{diagnostics:n}:{}};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:s??"retried"})}function repairDiagnostics(e,t){return{outputPreview:m(e),toolCandidateIds:visibleToolCandidates(e,t)}}function visibleToolCandidates(e,t){const o=new Set;for(const r of t??[])containsDelimitedToken(e,r)&&o.add(r);return[...o]}function containsDelimitedToken(e,t){if(!t)return!1;let o=e.indexOf(t);for(;o>=0;){const r=0===o?"":e[o-1],a=e[o+t.length]??"";if(!isTokenChar(r)&&!isTokenChar(a))return!0;o=e.indexOf(t,o+t.length)}return!1}function isTokenChar(e){return"_"===e||"-"===e||e>="A"&&e<="Z"||e>="a"&&e<="z"||e>="0"&&e<="9"}function effectiveRecoveryToolIds(e,t){const o=function readStringArray(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.length>0):[]}(e.metadata?.stableHarnessRequiredEvidenceTools).filter(e=>t.includes(e));return o.length>0?o:t}function rawArgsToolKey(e){return`${e.toolId}:${JSON.stringify(e.args)}`}function visibleRecoveredToolOutput(e){return("string"==typeof e.text?e.text.trim():"")||"The recovered tool completed successfully but returned no user-visible output."}function buildEmptyRecoveredToolBlocker(e){const t=R(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")}function buildEmptyRecoveredToolSequenceBlocker(e){const t=R(e.events);return["Stable runtime recovery executed matched declared tools, but the backend returned no user-facing output after receiving the executed evidence.","",...e.evidences.flatMap((e,t)=>[`Executed tool ${t+1}: ${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.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -12,7 +12,7 @@
|
|
|
12
12
|
".": "./dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@stable-harness/governance": "0.0.
|
|
16
|
-
"@stable-harness/memory": "0.0.
|
|
15
|
+
"@stable-harness/governance": "0.0.131",
|
|
16
|
+
"@stable-harness/memory": "0.0.131"
|
|
17
17
|
}
|
|
18
18
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/evaluation",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
"main": "dist/src/index.js",
|
|
12
12
|
"types": "dist/src/index.d.ts",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"@stable-harness/core": "0.0.
|
|
14
|
+
"@stable-harness/core": "0.0.131"
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/protocols",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -11,6 +11,6 @@
|
|
|
11
11
|
"main": "dist/src/index.js",
|
|
12
12
|
"types": "dist/src/index.d.ts",
|
|
13
13
|
"peerDependencies": {
|
|
14
|
-
"@stable-harness/core": "0.0.
|
|
14
|
+
"@stable-harness/core": "0.0.131"
|
|
15
15
|
}
|
|
16
16
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@stable-harness/workspace-yaml",
|
|
3
|
-
"version": "0.0.
|
|
3
|
+
"version": "0.0.131",
|
|
4
4
|
"license": "Apache-2.0",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"files": [
|
|
@@ -12,6 +12,6 @@
|
|
|
12
12
|
".": "./dist/index.js"
|
|
13
13
|
},
|
|
14
14
|
"peerDependencies": {
|
|
15
|
-
"@stable-harness/core": "0.0.
|
|
15
|
+
"@stable-harness/core": "0.0.131"
|
|
16
16
|
}
|
|
17
17
|
}
|