stable-harness 0.0.50 → 0.0.52
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/docs/granite-tool-calling-comparison.zh.md +3 -3
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/adapter.js +1 -1
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin-tool-policy.js +1 -1
- package/node_modules/@stable-harness/core/dist/runtime/policy/projection.js +1 -1
- package/package.json +1 -1
- package/packages/adapter-deepagents/dist/src/adapter.js +1 -1
- package/packages/adapter-deepagents/dist/src/internal/builtin-tool-policy.js +1 -1
- package/packages/core/dist/runtime/policy/projection.js +1 -1
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/skill-file-policy.d.ts +0 -10
- package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/skill-file-policy.js +0 -1
- package/packages/adapter-deepagents/dist/src/internal/skill-file-policy.d.ts +0 -10
- package/packages/adapter-deepagents/dist/src/internal/skill-file-policy.js +0 -1
|
@@ -185,10 +185,10 @@ Fast matrix results:
|
|
|
185
185
|
| Ollama | `qwen3.5:9b` | native auto tools | 15/15 | none |
|
|
186
186
|
| Ollama | `qwen3.5:0.8b` | native auto tools | 14/15 | `freshness` day instead of month |
|
|
187
187
|
| Ollama | `granite4.1:3b` | native auto tools | 14/15 | Chinese news query became unnatural text |
|
|
188
|
-
| Ollama | `qwen3:latest` | native auto tools | 14/15 |
|
|
188
|
+
| Ollama | `qwen3:latest` | native auto tools | 14/15 | ExampleCo ticker became `EXCO` |
|
|
189
189
|
| Ollama | `qwen2.5:7b-instruct` | native auto tools | 14/15 | path with space was collapsed |
|
|
190
|
-
| Ollama | `gemma4:e2b` | native auto tools | 14/15 | missed Chinese
|
|
191
|
-
| Ollama | `gemma4:e4b` | native auto tools | 14/15 | missed Chinese
|
|
190
|
+
| Ollama | `gemma4:e2b` | native auto tools | 14/15 | missed Chinese ExampleCo stock tool call |
|
|
191
|
+
| Ollama | `gemma4:e4b` | native auto tools | 14/15 | missed Chinese ExampleCo stock tool call |
|
|
192
192
|
| Ollama | `lfm2.5-thinking:latest` | native auto tools | 13/15 | namespace typo and HK market error |
|
|
193
193
|
| Ollama | `qwen3:0.6b` | native auto tools | 12/15 | one timeout, weaker exact title/query handling |
|
|
194
194
|
| Ollama | `gpt-oss:latest` | native auto tools | 12/15 | path and freshness enum errors |
|
|
@@ -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 p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as c}from"./internal/messages.js";import{createRawToolCallParserMiddleware as l}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){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,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=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)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o=n(function buildDeepAgentParams(e,t,r){const n={...readDeepAgentsConfig(t),...readDeepAgentsConfig(e.agent.config.deepagents)},o=resolveDeepAgentsSkills(e,e.agent),a=n.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:n.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:n.backend??resolveDeepAgentsBackend(e,r,o),checkpointer:n.checkpointer,store:n.store,middleware:mergeMiddleware(e,e.agent,n.middleware,p),responseFormat:n.responseFormat,contextSchema:n.contextSchema,interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(e,e.agent,n),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=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(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(a,r,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,e.config,r)),a=c(t),d=function buildDeepAgentInvokeConfig(e){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit)})}(t.agent);if(!0===t.request.metadata?.openaiStream&&o.streamEvents){const e=await o.streamEvents(a,{version:"v3",...d});return g(t,e,p)}const l=await o.invoke(a,d);return p(l)}}}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:[],p=scopedInput(e,t),d=new Set,c=readDeepAgentsConfig(t?.config.deepagents);return[o(p,{observedToolIds:d,repeatState:s,repairModel:resolveAgentRepairModel(p,t,c)}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,l(p)]}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;if(isRepairModel(n))return n;if(!t)return;const o=resolveAgentModel(e,t);return isRepairModel(o)?o: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)}function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}
|
|
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 p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as c}from"./internal/messages.js";import{createRawToolCallParserMiddleware as l}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){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,skills:t.agent.skills,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=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)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o=n(function buildDeepAgentParams(e,t,r){const n={...readDeepAgentsConfig(t),...readDeepAgentsConfig(e.agent.config.deepagents)},o=resolveDeepAgentsSkills(e,e.agent),a=n.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:n.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:n.backend??resolveDeepAgentsBackend(e,r,o),checkpointer:n.checkpointer,store:n.store,middleware:mergeMiddleware(e,e.agent,n.middleware,p),responseFormat:n.responseFormat,contextSchema:n.contextSchema,interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(e,e.agent,n),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=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(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(a,r,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,e.config,r)),a=c(t),d=function buildDeepAgentInvokeConfig(e){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit)})}(t.agent);if(!0===t.request.metadata?.openaiStream&&o.streamEvents){const e=await o.streamEvents(a,{version:"v3",...d});return g(t,e,p)}const l=await o.invoke(a,d);return p(l)}}}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:[],p=scopedInput(e,t),d=new Set,c=readDeepAgentsConfig(t?.config.deepagents);return[o(p,{observedToolIds:d,repeatState:s,repairModel:resolveAgentRepairModel(p,t,c)}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,l(p)]}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;if(isRepairModel(n))return n;if(!t)return;const o=resolveAgentModel(e,t);return isRepairModel(o)?o: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)}function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}
|
package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/builtin-tool-policy.js
CHANGED
|
@@ -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
|
|
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 +1 @@
|
|
|
1
|
-
export function projectRuntimePolicies(e){return{systemPromptSections:[skillInventoryPolicy(e),responseLanguagePolicy(e),responsePresentationPolicy(e)].filter(e=>Boolean(e))}}export function buildRuntimeSystemPrompt(e,t){const n=[t,...projectRuntimePolicies(e).systemPromptSections].filter(e=>Boolean(e));return n.length>0?n.join("\n\n"):void 0}function skillInventoryPolicy(e){const t=(e.agent?.skills??[]).map(t=>e.workspace.skills.get(t)).filter(e=>Boolean(e));if(0!==t.length)return["## Stable Harness Skill Inventory","Use only the skills listed in this workspace inventory. Do not infer or invent skill names, skill directories, or SKILL.md paths from generic examples.","
|
|
1
|
+
export function projectRuntimePolicies(e){return{systemPromptSections:[skillInventoryPolicy(e),responseLanguagePolicy(e),responsePresentationPolicy(e)].filter(e=>Boolean(e))}}export function buildRuntimeSystemPrompt(e,t){const n=[t,...projectRuntimePolicies(e).systemPromptSections].filter(e=>Boolean(e));return n.length>0?n.join("\n\n"):void 0}function skillInventoryPolicy(e){const t=(e.agent?.skills??[]).map(t=>e.workspace.skills.get(t)).filter(e=>Boolean(e));if(0!==t.length)return["## Stable Harness Skill Inventory","Use only the skills listed in this workspace inventory. Do not infer or invent skill names, skill directories, or SKILL.md paths from generic examples.","When a listed skill matches the task, use DeepAgents progressive disclosure: read that registered SKILL.md path through builtin filesystem tools before applying the detailed workflow.","If none of these skills match the task, continue with the configured tools and collected evidence instead of reading an unlisted skill path.",t.map(e=>{const t=e.allowedTools.length>0?`; allowed tools: ${e.allowedTools.join(", ")}`:"",n=e.description?`: ${e.description}${t}`:t;return`- ${e.id}${n}`}).join("\n")].join("\n")}function responseLanguagePolicy(e){const t=readRecord(e.workspace.runtime.responseLanguage);if("matchUser"!==(readString(t.mode)??readString(t.strategy)))return;const n=function detectRequestLanguage(e){return/\p{Script=Han}/u.test(e)?"Chinese":/[\p{Script=Hiragana}\p{Script=Katakana}]/u.test(e)?"Japanese":/\p{Script=Hangul}/u.test(e)?"Korean":/\p{Script=Arabic}/u.test(e)?"Arabic":/\p{Script=Hebrew}/u.test(e)?"Hebrew":/\p{Script=Thai}/u.test(e)?"Thai":/\p{Script=Cyrillic}/u.test(e)?"Cyrillic-script language":void 0}(e.request.input);return["Stable runtime response language policy:",...n?[`- Detected request language: ${n}.`]:[],"- Match the final answer language to the original user request unless the user explicitly asks for another language.","- If tool or subagent evidence is in a different language, translate the final user-facing answer into the detected request language.","- When delegating to subagents, include the same response-language requirement in delegated instructions.","- Do not call another tool or subagent only to translate, rewrite, format, or synthesize a completed answer.",`Original user request:\n${e.request.input}`].join("\n")}function responsePresentationPolicy(e){const t=readRecord(e.workspace.runtime.responsePresentation);if(!0===t.enabled&&!function hasStructuredResponseFormat(e){return void 0!==e?.config.responseFormat||isRecord(e?.config.deepagents)&&void 0!==e.config.deepagents.responseFormat}(e.agent))return"markdown"===(readString(t.style)??"markdown")?["Stable runtime final-answer presentation policy:","- For user-facing natural-language final answers, use GitHub-flavored Markdown.","- Prefer clear section headings, short paragraphs, and concise bullets over dense prose.","- Use tables only when they make comparison or planning details easier to scan.","- For detailed investigations, plans, or reports, include assumptions, findings, recommendations, and concrete next steps.","- Preserve exact plain text, JSON, code, or other structured output when the user or response format asks for it.","- Do not end with generic follow-up offers; deliver the requested answer directly."].join("\n"):void 0}function readRecord(e){return isRecord(e)?e:{}}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
package/package.json
CHANGED
|
@@ -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 p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as c}from"./internal/messages.js";import{createRawToolCallParserMiddleware as l}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){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,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=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)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o=n(function buildDeepAgentParams(e,t,r){const n={...readDeepAgentsConfig(t),...readDeepAgentsConfig(e.agent.config.deepagents)},o=resolveDeepAgentsSkills(e,e.agent),a=n.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:n.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:n.backend??resolveDeepAgentsBackend(e,r,o),checkpointer:n.checkpointer,store:n.store,middleware:mergeMiddleware(e,e.agent,n.middleware,p),responseFormat:n.responseFormat,contextSchema:n.contextSchema,interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(e,e.agent,n),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=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(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(a,r,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,e.config,r)),a=c(t),d=function buildDeepAgentInvokeConfig(e){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit)})}(t.agent);if(!0===t.request.metadata?.openaiStream&&o.streamEvents){const e=await o.streamEvents(a,{version:"v3",...d});return g(t,e,p)}const l=await o.invoke(a,d);return p(l)}}}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:[],p=scopedInput(e,t),d=new Set,c=readDeepAgentsConfig(t?.config.deepagents);return[o(p,{observedToolIds:d,repeatState:s,repairModel:resolveAgentRepairModel(p,t,c)}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,l(p)]}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;if(isRepairModel(n))return n;if(!t)return;const o=resolveAgentModel(e,t);return isRepairModel(o)?o: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)}function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}
|
|
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 p}from"./internal/gateway-tools.js";import{resolveDeepAgentsNativeMemories as d}from"./memory.js";import{buildDeepAgentRequest as c}from"./internal/messages.js";import{createRawToolCallParserMiddleware as l}from"./internal/raw-tool-call-parser.js";import{createBackendModel as u}from"./model-providers.js";import{createDeepAgentsRetryMiddleware as m}from"./retry-policy.js";import{streamDeepAgentResult as g}from"./internal/stream-events.js";export function createDeepAgentsAdapter(e={}){return{name:"deepagents",canRun:e=>"deepagents"===e.backend,async run(t){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,skills:t.agent.skills,subagents:t.agent.subagents}}),e.runner)return e.runner(t);const r=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)}`)}}(),n=e.createDeepAgent??function readCreateDeepAgent(e){const t=e?.createDeepAgent;if("function"==typeof t)return t;throw new Error("DeepAgents package does not export createDeepAgent.")}(r),o=n(function buildDeepAgentParams(e,t,r){const n={...readDeepAgentsConfig(t),...readDeepAgentsConfig(e.agent.config.deepagents)},o=resolveDeepAgentsSkills(e,e.agent),a=n.permissions??s(e,e.agent),p=requestScopedRepeatState(e,e.agent.id);return pruneUndefined({name:e.agent.id,model:n.model??resolveAgentModel(e,e.agent),systemPrompt:buildSystemPrompt(e,e.agent),backend:n.backend??resolveDeepAgentsBackend(e,r,o),checkpointer:n.checkpointer,store:n.store,middleware:mergeMiddleware(e,e.agent,n.middleware,p),responseFormat:n.responseFormat,contextSchema:n.contextSchema,interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:a,tools:i(e,e.agent.id,e.agent.tools,resolveAgentRepairModel(e,e.agent,n),p),subagents:e.agent.subagents.map(t=>{const r=e.workspace.agents.get(t),n=readDeepAgentsConfig(r?.config.deepagents),o=n.permissions??s(e,r),a=scopedInput(e,r),p=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(a,r,n.middleware,p),interruptOn:n.interruptOn,generalPurposeAgent:readBoolean(n.generalPurposeAgent),taskDescription:readString(n.taskDescription),permissions:o,responseFormat:n.responseFormat,tools:i(e,t,r?.tools??[],resolveAgentRepairModel(a,r,n),p),memory:resolveDeepAgentsMemory(e,r),skills:resolveDeepAgentsSkills(e,r)})}),memory:resolveDeepAgentsMemory(e,e.agent),skills:o})}(t,e.config,r)),a=c(t),d=function buildDeepAgentInvokeConfig(e){return pruneUndefined({recursionLimit:readNumber(readDeepAgentsConfig(e.config.deepagents).recursionLimit)??readNumber(e.config.recursionLimit)})}(t.agent);if(!0===t.request.metadata?.openaiStream&&o.streamEvents){const e=await o.streamEvents(a,{version:"v3",...d});return g(t,e,p)}const l=await o.invoke(a,d);return p(l)}}}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:[],p=scopedInput(e,t),d=new Set,c=readDeepAgentsConfig(t?.config.deepagents);return[o(p,{observedToolIds:d,repeatState:s,repairModel:resolveAgentRepairModel(p,t,c)}),n(p,{repeatState:s}),...m(e.workspace.runtime.retry),...i,l(p)]}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;if(isRepairModel(n))return n;if(!t)return;const o=resolveAgentModel(e,t);return isRepairModel(o)?o: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)}function isRepairModel(e){return"object"==typeof e&&null!==e&&"invoke"in e&&"function"==typeof e.invoke}
|
|
@@ -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
|
|
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 +1 @@
|
|
|
1
|
-
export function projectRuntimePolicies(e){return{systemPromptSections:[skillInventoryPolicy(e),responseLanguagePolicy(e),responsePresentationPolicy(e)].filter(e=>Boolean(e))}}export function buildRuntimeSystemPrompt(e,t){const n=[t,...projectRuntimePolicies(e).systemPromptSections].filter(e=>Boolean(e));return n.length>0?n.join("\n\n"):void 0}function skillInventoryPolicy(e){const t=(e.agent?.skills??[]).map(t=>e.workspace.skills.get(t)).filter(e=>Boolean(e));if(0!==t.length)return["## Stable Harness Skill Inventory","Use only the skills listed in this workspace inventory. Do not infer or invent skill names, skill directories, or SKILL.md paths from generic examples.","
|
|
1
|
+
export function projectRuntimePolicies(e){return{systemPromptSections:[skillInventoryPolicy(e),responseLanguagePolicy(e),responsePresentationPolicy(e)].filter(e=>Boolean(e))}}export function buildRuntimeSystemPrompt(e,t){const n=[t,...projectRuntimePolicies(e).systemPromptSections].filter(e=>Boolean(e));return n.length>0?n.join("\n\n"):void 0}function skillInventoryPolicy(e){const t=(e.agent?.skills??[]).map(t=>e.workspace.skills.get(t)).filter(e=>Boolean(e));if(0!==t.length)return["## Stable Harness Skill Inventory","Use only the skills listed in this workspace inventory. Do not infer or invent skill names, skill directories, or SKILL.md paths from generic examples.","When a listed skill matches the task, use DeepAgents progressive disclosure: read that registered SKILL.md path through builtin filesystem tools before applying the detailed workflow.","If none of these skills match the task, continue with the configured tools and collected evidence instead of reading an unlisted skill path.",t.map(e=>{const t=e.allowedTools.length>0?`; allowed tools: ${e.allowedTools.join(", ")}`:"",n=e.description?`: ${e.description}${t}`:t;return`- ${e.id}${n}`}).join("\n")].join("\n")}function responseLanguagePolicy(e){const t=readRecord(e.workspace.runtime.responseLanguage);if("matchUser"!==(readString(t.mode)??readString(t.strategy)))return;const n=function detectRequestLanguage(e){return/\p{Script=Han}/u.test(e)?"Chinese":/[\p{Script=Hiragana}\p{Script=Katakana}]/u.test(e)?"Japanese":/\p{Script=Hangul}/u.test(e)?"Korean":/\p{Script=Arabic}/u.test(e)?"Arabic":/\p{Script=Hebrew}/u.test(e)?"Hebrew":/\p{Script=Thai}/u.test(e)?"Thai":/\p{Script=Cyrillic}/u.test(e)?"Cyrillic-script language":void 0}(e.request.input);return["Stable runtime response language policy:",...n?[`- Detected request language: ${n}.`]:[],"- Match the final answer language to the original user request unless the user explicitly asks for another language.","- If tool or subagent evidence is in a different language, translate the final user-facing answer into the detected request language.","- When delegating to subagents, include the same response-language requirement in delegated instructions.","- Do not call another tool or subagent only to translate, rewrite, format, or synthesize a completed answer.",`Original user request:\n${e.request.input}`].join("\n")}function responsePresentationPolicy(e){const t=readRecord(e.workspace.runtime.responsePresentation);if(!0===t.enabled&&!function hasStructuredResponseFormat(e){return void 0!==e?.config.responseFormat||isRecord(e?.config.deepagents)&&void 0!==e.config.deepagents.responseFormat}(e.agent))return"markdown"===(readString(t.style)??"markdown")?["Stable runtime final-answer presentation policy:","- For user-facing natural-language final answers, use GitHub-flavored Markdown.","- Prefer clear section headings, short paragraphs, and concise bullets over dense prose.","- Use tables only when they make comparison or planning details easier to scan.","- For detailed investigations, plans, or reports, include assumptions, findings, recommendations, and concrete next steps.","- Preserve exact plain text, JSON, code, or other structured output when the user or response format asks for it.","- Do not end with generic follow-up offers; deliver the requested answer directly."].join("\n"):void 0}function readRecord(e){return isRecord(e)?e:{}}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/skill-file-policy.d.ts
DELETED
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ToolMessage } from "@langchain/core/messages";
|
|
2
|
-
import type { RuntimeAdapter } from "@stable-harness/core";
|
|
3
|
-
type AdapterRunInput = Parameters<RuntimeAdapter["run"]>[0];
|
|
4
|
-
export declare function validateSkillFileBuiltinCall(input: AdapterRunInput, toolId: string, request: {
|
|
5
|
-
toolCall?: {
|
|
6
|
-
id?: string;
|
|
7
|
-
args?: unknown;
|
|
8
|
-
};
|
|
9
|
-
}): ToolMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>> | undefined;
|
|
10
|
-
export {};
|
package/node_modules/@stable-harness/adapter-deepagents/dist/src/internal/skill-file-policy.js
DELETED
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ToolMessage as e}from"@langchain/core/messages";export function validateSkillFileBuiltinCall(t,l,r){const i=function readFilesystemTarget(e){const t=function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e)?e:{};for(const e of["file_path","path","pattern","query"]){const l=t[e];if("string"==typeof l&&l.trim())return l.trim()}}(r.toolCall?.args);if(i&&function targetsRegisteredSkill(e,t){return[...e.workspace.skills.values()].some(l=>{const r=function virtualSkillDir(e,t){const l=function pathRelative(e,t){const l=e.split("/").filter(Boolean),r=t.split("/").filter(Boolean);if(!(r.length<l.length)){for(let e=0;e<l.length;e+=1)if(l[e]!==r[e])return;return r.slice(l.length).join("/")}}(e,t);if(void 0===l)return;const r=l.split("/").filter(Boolean),i=r.lastIndexOf("skills");return i<0?`/${r.slice(0,-1).join("/")}`:`/${r.slice(0,i+2).join("/")}`}(e.workspace.root,l.path);return!!r&&function pathMatches(e,t){const l=t.replace(/\/+$/u,"");return e===l||e.startsWith(`${l}/`)||e.includes(`${l}/`)||e.includes("SKILL.md")}(t,r)})}(t,i))return new e({tool_call_id:r.toolCall?.id??`stable-harness-${l}-skill-policy`,name:l,status:"error",content:[`Filesystem builtin tool '${l}' targeted registered skill inventory: ${i}.`,"Skills are already registered with the backend and are not evidence files for the user request.","Do not read, list, glob, or grep SKILL.md files or skill directories.","Continue with the declared agent tools, the skill behavior already loaded by the backend, and the evidence already collected."].join(" ")})}
|
|
@@ -1,10 +0,0 @@
|
|
|
1
|
-
import { ToolMessage } from "@langchain/core/messages";
|
|
2
|
-
import type { RuntimeAdapter } from "@stable-harness/core";
|
|
3
|
-
type AdapterRunInput = Parameters<RuntimeAdapter["run"]>[0];
|
|
4
|
-
export declare function validateSkillFileBuiltinCall(input: AdapterRunInput, toolId: string, request: {
|
|
5
|
-
toolCall?: {
|
|
6
|
-
id?: string;
|
|
7
|
-
args?: unknown;
|
|
8
|
-
};
|
|
9
|
-
}): ToolMessage<import("@langchain/core/messages").MessageStructure<import("@langchain/core/messages").MessageToolSet>> | undefined;
|
|
10
|
-
export {};
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
import{ToolMessage as e}from"@langchain/core/messages";export function validateSkillFileBuiltinCall(t,l,r){const i=function readFilesystemTarget(e){const t=function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}(e)?e:{};for(const e of["file_path","path","pattern","query"]){const l=t[e];if("string"==typeof l&&l.trim())return l.trim()}}(r.toolCall?.args);if(i&&function targetsRegisteredSkill(e,t){return[...e.workspace.skills.values()].some(l=>{const r=function virtualSkillDir(e,t){const l=function pathRelative(e,t){const l=e.split("/").filter(Boolean),r=t.split("/").filter(Boolean);if(!(r.length<l.length)){for(let e=0;e<l.length;e+=1)if(l[e]!==r[e])return;return r.slice(l.length).join("/")}}(e,t);if(void 0===l)return;const r=l.split("/").filter(Boolean),i=r.lastIndexOf("skills");return i<0?`/${r.slice(0,-1).join("/")}`:`/${r.slice(0,i+2).join("/")}`}(e.workspace.root,l.path);return!!r&&function pathMatches(e,t){const l=t.replace(/\/+$/u,"");return e===l||e.startsWith(`${l}/`)||e.includes(`${l}/`)||e.includes("SKILL.md")}(t,r)})}(t,i))return new e({tool_call_id:r.toolCall?.id??`stable-harness-${l}-skill-policy`,name:l,status:"error",content:[`Filesystem builtin tool '${l}' targeted registered skill inventory: ${i}.`,"Skills are already registered with the backend and are not evidence files for the user request.","Do not read, list, glob, or grep SKILL.md files or skill directories.","Continue with the declared agent tools, the skill behavior already loaded by the backend, and the evidence already collected."].join(" ")})}
|