stable-harness 0.0.77 → 0.0.79

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1 +1 @@
1
- import{ToolMessage as t}from"@langchain/core/messages";import{afterToolInvoke as e,beforeToolInvoke as o,createToolRepeatState as r}from"@stable-harness/core";import{filesystemBuiltinToolIds as n,isFilesystemDisabled as i,isFilesystemTool as s,validateFilesystemBuiltinCall as a}from"./builtin/permissions.js";import{repairTaskCall as l}from"./builtin/task-inventory.js";import{repairBuiltinToolRequest as u}from"./builtin-call-repair.js";import{stringifyDeepAgentResult as c,toolControlProjection as d}from"./gateway-tools.js";import{isSuccessfulEvidenceOutput as p,observedToolEvidence as g,recordObservedToolEvidence as m}from"./gateway/tool-evidence.js";import{filterRepeatLimitedTools as f}from"./tool-repeat-visibility.js";import{traceProjectionForBuiltinTool as v}from"./trace-projection.js";const b=new Set(["write_todos","read_todos","task","execute",...n]);export function createBuiltinToolPolicyMiddleware(t,e={}){return{name:"StableHarnessBuiltinToolPolicy",async wrapModelCall(o,r){const n=Array.isArray(o.tools)?f(o.tools.filter(e=>!function hasHiddenBuiltins(t){return i(t)||!isTaskVisible(t)}(t)||isModelVisibleBuiltin(t,e.name)),e.repeatState):o.tools,s=function normalizeToolChoice(t,e,o){return"required"===e?o&&o.length>0?e:"auto":function isForcedHiddenTool(t,e){return"string"==typeof e?.function?.name&&!isModelVisibleBuiltin(t,e.function.name)}(t,e)?"auto":e}(t,o.toolChoice,n);return r({...o,tools:n,toolChoice:s})}}}export function createObserverMiddleware(n,i={}){const s=i.repeatState??r(n.workspace.runtime.toolGateway);return{name:"StableHarnessObserver",async wrapToolCall(r,d){const m=r.toolCall?.name;if(!m||!b.has(m))return d(r);const f=await u({toolId:m,request:r,workspaceRoot:n.workspace.root});emitToolEvent(n,m,"agent.tool.start",f.toolCall?.args);const v="task"===m?await l(n,f,{repairModel:i.repairModel}):{request:f},T=v.request,h=v.blocked;if(h)return emitToolEvent(n,m,"agent.tool.result",T.toolCall?.args,{output:h.content}),h;const y=a(n,m,T);if(y)return emitToolEvent(n,m,"agent.tool.result",T.toolCall?.args,{output:y.content}),y;try{const a=s?o(m,T.toolCall?.args,s):void 0;if(a)return emitToolEvent(n,m,"agent.tool.result",T.toolCall?.args,{output:a.eventOutput}),builtinToolMessage(r,m,function modelOutputForRepeatedBuiltin(t,e){return"task"!==t?e:function readPreviousOutput(t){try{const e=JSON.parse(t);if(!isRecord(e)||"repeated_tool_call_limit"!==e.status||"string"!=typeof e.previousOutput)return;const o=e.previousOutput.trim();return o.length>0?o:void 0}catch{return}}(e)??e}(m,a.modelOutput));const l=await d(T),u=function observedToolOutput(t,e,o){return"write_todos"===t?JSON.stringify({status:"recorded",args:e.toolCall?.args}):c(o)}(m,T,l),g=s?e({toolId:m,args:T.toolCall?.args,output:u,successful:!(l instanceof t&&"error"===l.status)&&p(u),state:s}):{};return emitToolEvent(n,m,"agent.tool.result",T.toolCall?.args,{output:g.eventOutput??u}),i.observedToolIds?.add(m),void 0===g.modelOutput?l:builtinToolMessage(r,m,g.modelOutput)}catch(e){const o=function recoverableBuiltinToolError(e,o,r,n){const i=formatError(n);if("task"===o&&/repeat limit reached for tool/iu.test(i)){const o=function formatObservedEvidence(t){const e=g(t);if(0===e.length)return"";const o=e.map(t=>[`Agent: ${t.agentId}`,`Tool: ${t.toolId}`,t.output].join("\n")).join("\n\n---\n\n");return o.length>12e3?`${o.slice(0,12e3)}\n[truncated]`:o}(e);return new t({tool_call_id:r.toolCall?.id??"stable-harness-task-repeat-limit",name:"task",content:JSON.stringify({status:"delegated_task_repeat_limit",finalizationRequired:!0,instruction:"The delegated agent reached a configured tool repeat limit. Stop delegating this evidence need and do not send a synthesis task to another subagent for the same need. Finalize only from observedEvidence and other evidence that is already visible in this run. If the visible evidence is insufficient for a requested claim, report an explicit blocker or evidence gap instead of estimating, inventing, or using generic knowledge.",...o?{observedEvidence:o}:{},error:previewError(i)})})}if(/Received tool input did not match expected schema|Invalid input:/iu.test(i))return new t({tool_call_id:r.toolCall?.id??`stable-harness-${o}-argument-error`,name:o,status:"error",content:JSON.stringify({status:"tool_argument_error",toolId:o,instruction:"The upstream builtin tool rejected these arguments. Fix the tool arguments according to the tool schema, or choose a more appropriate available tool.",error:previewError(i)})})}(n,m,r,e);if(o)return emitToolEvent(n,m,"agent.tool.result",f.toolCall?.args,{output:o.content}),o;throw emitToolEvent(n,m,"agent.tool.result",f.toolCall?.args,{error:formatError(e)}),e}}}}function builtinToolMessage(e,o,r){return new t({tool_call_id:e.toolCall?.id??`stable-harness-${o}-repeat-guard`,name:o,content:r})}function emitToolEvent(t,e,o,r,n={}){"string"==typeof n.output&&m(t,t.agent.id,e,n.output),t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",eventGroup:"tool_execution",eventType:"agent.tool.start"===o?"deepagents.tool_execution.start":"deepagents.tool_execution.result",phase:o,toolId:e,..."agent.tool.start"===o?{args:r}:{},...n,..."string"==typeof n.output?d(n.output):{},...v(e,o,r)}})}function isTaskVisible(t){const e=function readConfigRecord(t,e){const o=isRecord(t)?t:{};return isRecord(o[e])?o[e]:void 0}(t.agent.config,"builtinTools")?.modelExposed;return!1!==e&&(!Array.isArray(e)||e.includes("task"))}function isModelVisibleBuiltin(t,e){return(!i(t)||!s(e))&&("task"!==e||isTaskVisible(t))}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function formatError(t){return t instanceof Error?t.message:String(t)}function previewError(t){const e=t.replace(/\s+/gu," ").trim();return e.length>800?`${e.slice(0,797)}...`:e}
1
+ import{ToolMessage as t}from"@langchain/core/messages";import{afterToolInvoke as e,beforeToolInvoke as o,createToolRepeatState as r}from"@stable-harness/core";import{filesystemBuiltinToolIds as i,isFilesystemDisabled as n,isFilesystemTool as l,validateFilesystemBuiltinCall as s}from"./builtin/permissions.js";import{repairTaskCall as a}from"./builtin/task-inventory.js";import{repairBuiltinToolRequest as u}from"./builtin-call-repair.js";import{stringifyDeepAgentResult as c,toolControlProjection as d}from"./gateway-tools.js";import{isSuccessfulEvidenceOutput as p,observedToolEvidence as g,recordObservedToolEvidence as m}from"./gateway/tool-evidence.js";import{filterRepeatLimitedTools as f}from"./tool-repeat-visibility.js";import{traceProjectionForBuiltinTool as v}from"./trace-projection.js";const b=new Set(["write_todos","read_todos","task","execute",...i]),h=new Set(["task","execute"]);export function createBuiltinToolPolicyMiddleware(t,e={}){return{name:"StableHarnessBuiltinToolPolicy",async wrapModelCall(o,r){const i=Array.isArray(o.tools)?f(o.tools.filter(e=>!function hasHiddenBuiltins(t){return n(t)||[...h].some(e=>!isConfiguredModelVisibleBuiltin(t,e))}(t)||isModelVisibleBuiltin(t,e.name)),e.repeatState):o.tools,l=function normalizeToolChoice(t,e,o){return"required"===e?o&&o.length>0?e:"auto":function isForcedHiddenTool(t,e){return"string"==typeof e?.function?.name&&!isModelVisibleBuiltin(t,e.function.name)}(t,e)?"auto":e}(t,o.toolChoice,i);return r({...o,tools:i,toolChoice:l})}}}export function createObserverMiddleware(i,n={}){const l=n.repeatState??r(i.workspace.runtime.toolGateway);return{name:"StableHarnessObserver",async wrapToolCall(r,d){const m=r.toolCall?.name;if(!m||!b.has(m))return d(r);const f=await u({toolId:m,request:r,workspaceRoot:i.workspace.root});if(emitToolEvent(i,m,"agent.tool.start",f.toolCall?.args),"task"===m){const t=l?o(m,f.toolCall?.args,l):void 0;if(t)return emitToolEvent(i,m,"agent.tool.result",f.toolCall?.args,{output:t.eventOutput}),builtinToolMessage(r,m,modelOutputForRepeatedBuiltin(m,t.modelOutput))}const v="task"===m?await a(i,f,{repairModel:n.repairModel}):{request:f},y=v.request,T=v.blocked;if(T)return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:T.content}),T;const C=function validateModelVisibleBuiltinCall(e,o,r){if(h.has(o)&&!isModelVisibleBuiltin(e,o))return new t({tool_call_id:r.toolCall?.id??`stable-harness-${o}-visibility-policy`,name:o,status:"error",content:JSON.stringify({status:"blocked_builtin_tool",toolId:o,instruction:"This builtin tool is disabled by runtime policy for the current agent. Use the declared workspace tools that remain visible, or finalize from evidence already collected."})})}(i,m,y);if(C)return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:C.content}),C;const w=s(i,m,y);if(w)return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:w.content}),w;try{const s="task"===m?void 0:l?o(m,y.toolCall?.args,l):void 0;if(s)return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:s.eventOutput}),builtinToolMessage(r,m,modelOutputForRepeatedBuiltin(m,s.modelOutput));const a=await d(y),u=function observedToolOutput(t,e,o){return"write_todos"===t?JSON.stringify({status:"recorded",args:e.toolCall?.args}):c(o)}(m,y,a),g=l?e({toolId:m,args:y.toolCall?.args,output:u,successful:!(a instanceof t&&"error"===a.status)&&p(u),state:l}):{};return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:g.eventOutput??u}),n.observedToolIds?.add(m),void 0===g.modelOutput?a:builtinToolMessage(r,m,g.modelOutput)}catch(e){const o=function recoverableBuiltinToolError(e,o,r,i){const n=formatError(i);if("task"===o&&/repeat limit reached for tool/iu.test(n)){const o=function formatObservedEvidence(t){const e=g(t);if(0===e.length)return"";const o=e.map(t=>[`Agent: ${t.agentId}`,`Tool: ${t.toolId}`,t.output].join("\n")).join("\n\n---\n\n");return o.length>12e3?`${o.slice(0,12e3)}\n[truncated]`:o}(e);return new t({tool_call_id:r.toolCall?.id??"stable-harness-task-repeat-limit",name:"task",content:JSON.stringify({status:"delegated_task_repeat_limit",finalizationRequired:!0,instruction:"The delegated agent reached a configured tool repeat limit. Stop delegating this evidence need and do not send a synthesis task to another subagent for the same need. Finalize only from observedEvidence and other evidence that is already visible in this run. If the visible evidence is insufficient for a requested claim, report an explicit blocker or evidence gap instead of estimating, inventing, or using generic knowledge.",...o?{observedEvidence:o}:{},error:previewError(n)})})}if(/Received tool input did not match expected schema|Invalid input:/iu.test(n))return new t({tool_call_id:r.toolCall?.id??`stable-harness-${o}-argument-error`,name:o,status:"error",content:JSON.stringify({status:"tool_argument_error",toolId:o,instruction:"The upstream builtin tool rejected these arguments. Fix the tool arguments according to the tool schema, or choose a more appropriate available tool.",error:previewError(n)})})}(i,m,r,e);if(o)return emitToolEvent(i,m,"agent.tool.result",f.toolCall?.args,{output:o.content}),o;throw emitToolEvent(i,m,"agent.tool.result",f.toolCall?.args,{error:formatError(e)}),e}}}}function builtinToolMessage(e,o,r){return new t({tool_call_id:e.toolCall?.id??`stable-harness-${o}-repeat-guard`,name:o,content:r})}function modelOutputForRepeatedBuiltin(t,e){return"task"!==t?e:function readPreviousOutput(t){try{const e=JSON.parse(t);if(!isRecord(e)||"repeated_tool_call_limit"!==e.status||"string"!=typeof e.previousOutput)return;const o=e.previousOutput.trim();return o.length>0?o:void 0}catch{return}}(e)??e}function emitToolEvent(t,e,o,r,i={}){"string"==typeof i.output&&m(t,t.agent.id,e,i.output),t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",eventGroup:"tool_execution",eventType:"agent.tool.start"===o?"deepagents.tool_execution.start":"deepagents.tool_execution.result",phase:o,toolId:e,..."agent.tool.start"===o?{args:r}:{},...i,..."string"==typeof i.output?d(i.output):{},...v(e,o,r)}})}function isConfiguredModelVisibleBuiltin(t,e){const o=function readConfigRecord(t,e){const o=isRecord(t)?t:{};return isRecord(o[e])?o[e]:void 0}(t.agent.config,"builtinTools")?.modelExposed;return!1!==o&&(!Array.isArray(o)||o.includes(e))}function isModelVisibleBuiltin(t,e){return(!n(t)||!l(e))&&("string"!=typeof e||!h.has(e)||isConfiguredModelVisibleBuiltin(t,e))}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function formatError(t){return t instanceof Error?t.message:String(t)}function previewError(t){const e=t.replace(/\s+/gu," ").trim();return e.length>800?`${e.slice(0,797)}...`:e}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/adapter-deepagents",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -15,7 +15,7 @@
15
15
  "@langchain/node-vfs": "^0.1.4",
16
16
  "@langchain/ollama": "^1.2.7",
17
17
  "@langchain/openai": "^1.4.5",
18
- "@stable-harness/core": "0.0.77",
18
+ "@stable-harness/core": "0.0.79",
19
19
  "deepagents": "^1.10.1",
20
20
  "langchain": "^1.4.0"
21
21
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/adapter-langgraph",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,6 +11,6 @@
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
13
  "@langchain/langgraph": "^1.3.0",
14
- "@stable-harness/core": "0.0.77"
14
+ "@stable-harness/core": "0.0.79"
15
15
  }
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/core",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,7 +11,7 @@
11
11
  ".": "./dist/index.js"
12
12
  },
13
13
  "peerDependencies": {
14
- "@stable-harness/governance": "0.0.77",
15
- "@stable-harness/memory": "0.0.77"
14
+ "@stable-harness/governance": "0.0.79",
15
+ "@stable-harness/memory": "0.0.79"
16
16
  }
17
17
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/governance",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/memory",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/protocols",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -10,6 +10,6 @@
10
10
  "main": "dist/src/index.js",
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
- "@stable-harness/core": "0.0.77"
13
+ "@stable-harness/core": "0.0.79"
14
14
  }
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/tool-gateway",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/workspace-yaml",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,6 +11,6 @@
11
11
  ".": "./dist/index.js"
12
12
  },
13
13
  "peerDependencies": {
14
- "@stable-harness/core": "0.0.77"
14
+ "@stable-harness/core": "0.0.79"
15
15
  }
16
16
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "stable-harness",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
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.77",
86
- "@stable-harness/adapter-langgraph": "0.0.77",
87
- "@stable-harness/core": "0.0.77",
88
- "@stable-harness/governance": "0.0.77",
89
- "@stable-harness/memory": "0.0.77",
90
- "@stable-harness/protocols": "0.0.77",
91
- "@stable-harness/tool-gateway": "0.0.77",
92
- "@stable-harness/workspace-yaml": "0.0.77",
85
+ "@stable-harness/adapter-deepagents": "0.0.79",
86
+ "@stable-harness/adapter-langgraph": "0.0.79",
87
+ "@stable-harness/core": "0.0.79",
88
+ "@stable-harness/governance": "0.0.79",
89
+ "@stable-harness/memory": "0.0.79",
90
+ "@stable-harness/protocols": "0.0.79",
91
+ "@stable-harness/tool-gateway": "0.0.79",
92
+ "@stable-harness/workspace-yaml": "0.0.79",
93
93
  "deepagents": "^1.10.1",
94
94
  "langchain": "^1.4.0",
95
95
  "yaml": "^2.8.2",
@@ -1 +1 @@
1
- import{ToolMessage as t}from"@langchain/core/messages";import{afterToolInvoke as e,beforeToolInvoke as o,createToolRepeatState as r}from"@stable-harness/core";import{filesystemBuiltinToolIds as n,isFilesystemDisabled as i,isFilesystemTool as s,validateFilesystemBuiltinCall as a}from"./builtin/permissions.js";import{repairTaskCall as l}from"./builtin/task-inventory.js";import{repairBuiltinToolRequest as u}from"./builtin-call-repair.js";import{stringifyDeepAgentResult as c,toolControlProjection as d}from"./gateway-tools.js";import{isSuccessfulEvidenceOutput as p,observedToolEvidence as g,recordObservedToolEvidence as m}from"./gateway/tool-evidence.js";import{filterRepeatLimitedTools as f}from"./tool-repeat-visibility.js";import{traceProjectionForBuiltinTool as v}from"./trace-projection.js";const b=new Set(["write_todos","read_todos","task","execute",...n]);export function createBuiltinToolPolicyMiddleware(t,e={}){return{name:"StableHarnessBuiltinToolPolicy",async wrapModelCall(o,r){const n=Array.isArray(o.tools)?f(o.tools.filter(e=>!function hasHiddenBuiltins(t){return i(t)||!isTaskVisible(t)}(t)||isModelVisibleBuiltin(t,e.name)),e.repeatState):o.tools,s=function normalizeToolChoice(t,e,o){return"required"===e?o&&o.length>0?e:"auto":function isForcedHiddenTool(t,e){return"string"==typeof e?.function?.name&&!isModelVisibleBuiltin(t,e.function.name)}(t,e)?"auto":e}(t,o.toolChoice,n);return r({...o,tools:n,toolChoice:s})}}}export function createObserverMiddleware(n,i={}){const s=i.repeatState??r(n.workspace.runtime.toolGateway);return{name:"StableHarnessObserver",async wrapToolCall(r,d){const m=r.toolCall?.name;if(!m||!b.has(m))return d(r);const f=await u({toolId:m,request:r,workspaceRoot:n.workspace.root});emitToolEvent(n,m,"agent.tool.start",f.toolCall?.args);const v="task"===m?await l(n,f,{repairModel:i.repairModel}):{request:f},T=v.request,h=v.blocked;if(h)return emitToolEvent(n,m,"agent.tool.result",T.toolCall?.args,{output:h.content}),h;const y=a(n,m,T);if(y)return emitToolEvent(n,m,"agent.tool.result",T.toolCall?.args,{output:y.content}),y;try{const a=s?o(m,T.toolCall?.args,s):void 0;if(a)return emitToolEvent(n,m,"agent.tool.result",T.toolCall?.args,{output:a.eventOutput}),builtinToolMessage(r,m,function modelOutputForRepeatedBuiltin(t,e){return"task"!==t?e:function readPreviousOutput(t){try{const e=JSON.parse(t);if(!isRecord(e)||"repeated_tool_call_limit"!==e.status||"string"!=typeof e.previousOutput)return;const o=e.previousOutput.trim();return o.length>0?o:void 0}catch{return}}(e)??e}(m,a.modelOutput));const l=await d(T),u=function observedToolOutput(t,e,o){return"write_todos"===t?JSON.stringify({status:"recorded",args:e.toolCall?.args}):c(o)}(m,T,l),g=s?e({toolId:m,args:T.toolCall?.args,output:u,successful:!(l instanceof t&&"error"===l.status)&&p(u),state:s}):{};return emitToolEvent(n,m,"agent.tool.result",T.toolCall?.args,{output:g.eventOutput??u}),i.observedToolIds?.add(m),void 0===g.modelOutput?l:builtinToolMessage(r,m,g.modelOutput)}catch(e){const o=function recoverableBuiltinToolError(e,o,r,n){const i=formatError(n);if("task"===o&&/repeat limit reached for tool/iu.test(i)){const o=function formatObservedEvidence(t){const e=g(t);if(0===e.length)return"";const o=e.map(t=>[`Agent: ${t.agentId}`,`Tool: ${t.toolId}`,t.output].join("\n")).join("\n\n---\n\n");return o.length>12e3?`${o.slice(0,12e3)}\n[truncated]`:o}(e);return new t({tool_call_id:r.toolCall?.id??"stable-harness-task-repeat-limit",name:"task",content:JSON.stringify({status:"delegated_task_repeat_limit",finalizationRequired:!0,instruction:"The delegated agent reached a configured tool repeat limit. Stop delegating this evidence need and do not send a synthesis task to another subagent for the same need. Finalize only from observedEvidence and other evidence that is already visible in this run. If the visible evidence is insufficient for a requested claim, report an explicit blocker or evidence gap instead of estimating, inventing, or using generic knowledge.",...o?{observedEvidence:o}:{},error:previewError(i)})})}if(/Received tool input did not match expected schema|Invalid input:/iu.test(i))return new t({tool_call_id:r.toolCall?.id??`stable-harness-${o}-argument-error`,name:o,status:"error",content:JSON.stringify({status:"tool_argument_error",toolId:o,instruction:"The upstream builtin tool rejected these arguments. Fix the tool arguments according to the tool schema, or choose a more appropriate available tool.",error:previewError(i)})})}(n,m,r,e);if(o)return emitToolEvent(n,m,"agent.tool.result",f.toolCall?.args,{output:o.content}),o;throw emitToolEvent(n,m,"agent.tool.result",f.toolCall?.args,{error:formatError(e)}),e}}}}function builtinToolMessage(e,o,r){return new t({tool_call_id:e.toolCall?.id??`stable-harness-${o}-repeat-guard`,name:o,content:r})}function emitToolEvent(t,e,o,r,n={}){"string"==typeof n.output&&m(t,t.agent.id,e,n.output),t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",eventGroup:"tool_execution",eventType:"agent.tool.start"===o?"deepagents.tool_execution.start":"deepagents.tool_execution.result",phase:o,toolId:e,..."agent.tool.start"===o?{args:r}:{},...n,..."string"==typeof n.output?d(n.output):{},...v(e,o,r)}})}function isTaskVisible(t){const e=function readConfigRecord(t,e){const o=isRecord(t)?t:{};return isRecord(o[e])?o[e]:void 0}(t.agent.config,"builtinTools")?.modelExposed;return!1!==e&&(!Array.isArray(e)||e.includes("task"))}function isModelVisibleBuiltin(t,e){return(!i(t)||!s(e))&&("task"!==e||isTaskVisible(t))}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function formatError(t){return t instanceof Error?t.message:String(t)}function previewError(t){const e=t.replace(/\s+/gu," ").trim();return e.length>800?`${e.slice(0,797)}...`:e}
1
+ import{ToolMessage as t}from"@langchain/core/messages";import{afterToolInvoke as e,beforeToolInvoke as o,createToolRepeatState as r}from"@stable-harness/core";import{filesystemBuiltinToolIds as i,isFilesystemDisabled as n,isFilesystemTool as l,validateFilesystemBuiltinCall as s}from"./builtin/permissions.js";import{repairTaskCall as a}from"./builtin/task-inventory.js";import{repairBuiltinToolRequest as u}from"./builtin-call-repair.js";import{stringifyDeepAgentResult as c,toolControlProjection as d}from"./gateway-tools.js";import{isSuccessfulEvidenceOutput as p,observedToolEvidence as g,recordObservedToolEvidence as m}from"./gateway/tool-evidence.js";import{filterRepeatLimitedTools as f}from"./tool-repeat-visibility.js";import{traceProjectionForBuiltinTool as v}from"./trace-projection.js";const b=new Set(["write_todos","read_todos","task","execute",...i]),h=new Set(["task","execute"]);export function createBuiltinToolPolicyMiddleware(t,e={}){return{name:"StableHarnessBuiltinToolPolicy",async wrapModelCall(o,r){const i=Array.isArray(o.tools)?f(o.tools.filter(e=>!function hasHiddenBuiltins(t){return n(t)||[...h].some(e=>!isConfiguredModelVisibleBuiltin(t,e))}(t)||isModelVisibleBuiltin(t,e.name)),e.repeatState):o.tools,l=function normalizeToolChoice(t,e,o){return"required"===e?o&&o.length>0?e:"auto":function isForcedHiddenTool(t,e){return"string"==typeof e?.function?.name&&!isModelVisibleBuiltin(t,e.function.name)}(t,e)?"auto":e}(t,o.toolChoice,i);return r({...o,tools:i,toolChoice:l})}}}export function createObserverMiddleware(i,n={}){const l=n.repeatState??r(i.workspace.runtime.toolGateway);return{name:"StableHarnessObserver",async wrapToolCall(r,d){const m=r.toolCall?.name;if(!m||!b.has(m))return d(r);const f=await u({toolId:m,request:r,workspaceRoot:i.workspace.root});if(emitToolEvent(i,m,"agent.tool.start",f.toolCall?.args),"task"===m){const t=l?o(m,f.toolCall?.args,l):void 0;if(t)return emitToolEvent(i,m,"agent.tool.result",f.toolCall?.args,{output:t.eventOutput}),builtinToolMessage(r,m,modelOutputForRepeatedBuiltin(m,t.modelOutput))}const v="task"===m?await a(i,f,{repairModel:n.repairModel}):{request:f},y=v.request,T=v.blocked;if(T)return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:T.content}),T;const C=function validateModelVisibleBuiltinCall(e,o,r){if(h.has(o)&&!isModelVisibleBuiltin(e,o))return new t({tool_call_id:r.toolCall?.id??`stable-harness-${o}-visibility-policy`,name:o,status:"error",content:JSON.stringify({status:"blocked_builtin_tool",toolId:o,instruction:"This builtin tool is disabled by runtime policy for the current agent. Use the declared workspace tools that remain visible, or finalize from evidence already collected."})})}(i,m,y);if(C)return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:C.content}),C;const w=s(i,m,y);if(w)return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:w.content}),w;try{const s="task"===m?void 0:l?o(m,y.toolCall?.args,l):void 0;if(s)return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:s.eventOutput}),builtinToolMessage(r,m,modelOutputForRepeatedBuiltin(m,s.modelOutput));const a=await d(y),u=function observedToolOutput(t,e,o){return"write_todos"===t?JSON.stringify({status:"recorded",args:e.toolCall?.args}):c(o)}(m,y,a),g=l?e({toolId:m,args:y.toolCall?.args,output:u,successful:!(a instanceof t&&"error"===a.status)&&p(u),state:l}):{};return emitToolEvent(i,m,"agent.tool.result",y.toolCall?.args,{output:g.eventOutput??u}),n.observedToolIds?.add(m),void 0===g.modelOutput?a:builtinToolMessage(r,m,g.modelOutput)}catch(e){const o=function recoverableBuiltinToolError(e,o,r,i){const n=formatError(i);if("task"===o&&/repeat limit reached for tool/iu.test(n)){const o=function formatObservedEvidence(t){const e=g(t);if(0===e.length)return"";const o=e.map(t=>[`Agent: ${t.agentId}`,`Tool: ${t.toolId}`,t.output].join("\n")).join("\n\n---\n\n");return o.length>12e3?`${o.slice(0,12e3)}\n[truncated]`:o}(e);return new t({tool_call_id:r.toolCall?.id??"stable-harness-task-repeat-limit",name:"task",content:JSON.stringify({status:"delegated_task_repeat_limit",finalizationRequired:!0,instruction:"The delegated agent reached a configured tool repeat limit. Stop delegating this evidence need and do not send a synthesis task to another subagent for the same need. Finalize only from observedEvidence and other evidence that is already visible in this run. If the visible evidence is insufficient for a requested claim, report an explicit blocker or evidence gap instead of estimating, inventing, or using generic knowledge.",...o?{observedEvidence:o}:{},error:previewError(n)})})}if(/Received tool input did not match expected schema|Invalid input:/iu.test(n))return new t({tool_call_id:r.toolCall?.id??`stable-harness-${o}-argument-error`,name:o,status:"error",content:JSON.stringify({status:"tool_argument_error",toolId:o,instruction:"The upstream builtin tool rejected these arguments. Fix the tool arguments according to the tool schema, or choose a more appropriate available tool.",error:previewError(n)})})}(i,m,r,e);if(o)return emitToolEvent(i,m,"agent.tool.result",f.toolCall?.args,{output:o.content}),o;throw emitToolEvent(i,m,"agent.tool.result",f.toolCall?.args,{error:formatError(e)}),e}}}}function builtinToolMessage(e,o,r){return new t({tool_call_id:e.toolCall?.id??`stable-harness-${o}-repeat-guard`,name:o,content:r})}function modelOutputForRepeatedBuiltin(t,e){return"task"!==t?e:function readPreviousOutput(t){try{const e=JSON.parse(t);if(!isRecord(e)||"repeated_tool_call_limit"!==e.status||"string"!=typeof e.previousOutput)return;const o=e.previousOutput.trim();return o.length>0?o:void 0}catch{return}}(e)??e}function emitToolEvent(t,e,o,r,i={}){"string"==typeof i.output&&m(t,t.agent.id,e,i.output),t.emit({type:"runtime.adapter.event",requestId:t.requestId,sessionId:t.sessionId,agentId:t.agent.id,event:{adapter:"deepagents",eventGroup:"tool_execution",eventType:"agent.tool.start"===o?"deepagents.tool_execution.start":"deepagents.tool_execution.result",phase:o,toolId:e,..."agent.tool.start"===o?{args:r}:{},...i,..."string"==typeof i.output?d(i.output):{},...v(e,o,r)}})}function isConfiguredModelVisibleBuiltin(t,e){const o=function readConfigRecord(t,e){const o=isRecord(t)?t:{};return isRecord(o[e])?o[e]:void 0}(t.agent.config,"builtinTools")?.modelExposed;return!1!==o&&(!Array.isArray(o)||o.includes(e))}function isModelVisibleBuiltin(t,e){return(!n(t)||!l(e))&&("string"!=typeof e||!h.has(e)||isConfiguredModelVisibleBuiltin(t,e))}function isRecord(t){return"object"==typeof t&&null!==t&&!Array.isArray(t)}function formatError(t){return t instanceof Error?t.message:String(t)}function previewError(t){const e=t.replace(/\s+/gu," ").trim();return e.length>800?`${e.slice(0,797)}...`:e}
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/adapter-deepagents",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -15,7 +15,7 @@
15
15
  "@langchain/node-vfs": "^0.1.4",
16
16
  "@langchain/ollama": "^1.2.7",
17
17
  "@langchain/openai": "^1.4.5",
18
- "@stable-harness/core": "0.0.77",
18
+ "@stable-harness/core": "0.0.79",
19
19
  "deepagents": "^1.10.1",
20
20
  "langchain": "^1.4.0"
21
21
  },
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/adapter-langgraph",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,6 +11,6 @@
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
13
  "@langchain/langgraph": "^1.3.0",
14
- "@stable-harness/core": "0.0.77"
14
+ "@stable-harness/core": "0.0.79"
15
15
  }
16
16
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/cli",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -14,12 +14,12 @@
14
14
  "types": "dist/src/index.d.ts",
15
15
  "peerDependencies": {
16
16
  "@langchain/langgraph-api": "^1.2.1",
17
- "@stable-harness/adapter-deepagents": "0.0.77",
18
- "@stable-harness/adapter-langgraph": "0.0.77",
19
- "@stable-harness/core": "0.0.77",
20
- "@stable-harness/memory": "0.0.77",
21
- "@stable-harness/protocols": "0.0.77",
22
- "@stable-harness/tool-gateway": "0.0.77",
23
- "@stable-harness/workspace-yaml": "0.0.77"
17
+ "@stable-harness/adapter-deepagents": "0.0.79",
18
+ "@stable-harness/adapter-langgraph": "0.0.79",
19
+ "@stable-harness/core": "0.0.79",
20
+ "@stable-harness/memory": "0.0.79",
21
+ "@stable-harness/protocols": "0.0.79",
22
+ "@stable-harness/tool-gateway": "0.0.79",
23
+ "@stable-harness/workspace-yaml": "0.0.79"
24
24
  }
25
25
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/core",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,7 +11,7 @@
11
11
  ".": "./dist/index.js"
12
12
  },
13
13
  "peerDependencies": {
14
- "@stable-harness/governance": "0.0.77",
15
- "@stable-harness/memory": "0.0.77"
14
+ "@stable-harness/governance": "0.0.79",
15
+ "@stable-harness/memory": "0.0.79"
16
16
  }
17
17
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/evaluation",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -10,6 +10,6 @@
10
10
  "main": "dist/src/index.js",
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
- "@stable-harness/core": "0.0.77"
13
+ "@stable-harness/core": "0.0.79"
14
14
  }
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/governance",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/memory",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/protocols",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -10,6 +10,6 @@
10
10
  "main": "dist/src/index.js",
11
11
  "types": "dist/src/index.d.ts",
12
12
  "peerDependencies": {
13
- "@stable-harness/core": "0.0.77"
13
+ "@stable-harness/core": "0.0.79"
14
14
  }
15
15
  }
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/tool-gateway",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@stable-harness/workspace-yaml",
3
- "version": "0.0.77",
3
+ "version": "0.0.79",
4
4
  "type": "module",
5
5
  "files": [
6
6
  "dist/**/*.js",
@@ -11,6 +11,6 @@
11
11
  ".": "./dist/index.js"
12
12
  },
13
13
  "peerDependencies": {
14
- "@stable-harness/core": "0.0.77"
14
+ "@stable-harness/core": "0.0.79"
15
15
  }
16
16
  }