stable-harness 0.0.48 → 0.0.50
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/README.md +7 -0
- package/docs/guides/runtime-governance-proof.md +54 -0
- package/docs/product/runtime-substrate-for-flev.md +55 -0
- package/docs/product-boundary.md +6 -0
- package/node_modules/@stable-harness/core/dist/memory-plugins.d.ts +3 -0
- package/node_modules/@stable-harness/core/dist/memory-plugins.js +1 -1
- package/node_modules/@stable-harness/core/dist/runtime/events.d.ts +19 -0
- package/node_modules/@stable-harness/core/dist/runtime/memory.js +1 -1
- package/node_modules/@stable-harness/core/dist/runtime/progress-narration.js +1 -1
- package/node_modules/@stable-harness/core/dist/runtime/recovery/adapter-result.d.ts +12 -0
- package/node_modules/@stable-harness/core/dist/runtime/recovery/adapter-result.js +1 -0
- package/node_modules/@stable-harness/core/dist/runtime.js +1 -1
- package/node_modules/@stable-harness/core/dist/trace.js +1 -1
- package/package.json +1 -1
- package/packages/cli/dist/src/cli.js +1 -1
- package/packages/cli/dist/src/event-view.js +1 -1
- package/packages/cli/dist/src/init.js +1 -1
- package/packages/cli/dist/src/memory/defaults.d.ts +1 -0
- package/packages/cli/dist/src/memory/defaults.js +1 -0
- package/packages/cli/dist/src/memory/lifecycle.js +1 -1
- package/packages/cli/dist/src/memory/providers.js +1 -1
- package/packages/core/dist/memory-plugins.d.ts +3 -0
- package/packages/core/dist/memory-plugins.js +1 -1
- package/packages/core/dist/runtime/events.d.ts +19 -0
- package/packages/core/dist/runtime/memory.js +1 -1
- package/packages/core/dist/runtime/progress-narration.js +1 -1
- package/packages/core/dist/runtime/recovery/adapter-result.d.ts +12 -0
- package/packages/core/dist/runtime/recovery/adapter-result.js +1 -0
- package/packages/core/dist/runtime.js +1 -1
- package/packages/core/dist/trace.js +1 -1
package/README.md
CHANGED
|
@@ -13,6 +13,11 @@ tool repair, and protocol access.
|
|
|
13
13
|
It is not another agent execution framework. Upstream frameworks own execution
|
|
14
14
|
semantics. Stable Harness owns the runtime boundary around them.
|
|
15
15
|
|
|
16
|
+
In the EasyNet World stack, Stable Harness is the runtime substrate under Flev.
|
|
17
|
+
Better Call hardens the tool-call boundary, Stable Harness governs the agent
|
|
18
|
+
workspace runtime, and Flev turns that governed workspace into user-facing
|
|
19
|
+
product surfaces such as Studio, chat, embed, review, and delivery workflows.
|
|
20
|
+
|
|
16
21
|
## Why Use It
|
|
17
22
|
|
|
18
23
|
Agent frameworks are good at deciding what an agent should do next. Production
|
|
@@ -224,6 +229,8 @@ This is constrained repair, not silent magic:
|
|
|
224
229
|
- [Getting started](docs/guides/getting-started.md)
|
|
225
230
|
- [Workspace authoring](docs/guides/workspace-authoring.md)
|
|
226
231
|
- [Workspace Docker build](docs/guides/workspace-docker-build.md)
|
|
232
|
+
- [Runtime substrate for Flev](docs/product/runtime-substrate-for-flev.md)
|
|
233
|
+
- [Runtime governance proof](docs/guides/runtime-governance-proof.md)
|
|
227
234
|
- [Integration guide](docs/guides/integration-guide.md)
|
|
228
235
|
- [Operator runbook](docs/guides/operator-runbook.md)
|
|
229
236
|
- [Adoption playbook](docs/product/adoption-playbook.md)
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
# Runtime Governance Proof
|
|
2
|
+
|
|
3
|
+
Use this page as the compact proof checklist for public claims about Stable
|
|
4
|
+
Harness runtime governance. It is meant to give Flev and the EasyNet World site
|
|
5
|
+
specific runtime evidence to cite without turning Stable Harness into the
|
|
6
|
+
end-user product.
|
|
7
|
+
|
|
8
|
+
## Minimal Proof Run
|
|
9
|
+
|
|
10
|
+
```bash
|
|
11
|
+
npm install
|
|
12
|
+
npm run build
|
|
13
|
+
stable-harness -w ./examples/minimal-deepagents "hello stable harness"
|
|
14
|
+
```
|
|
15
|
+
|
|
16
|
+
Inspect the workspace without executing the agent:
|
|
17
|
+
|
|
18
|
+
```bash
|
|
19
|
+
stable-harness -w ./examples/minimal-deepagents
|
|
20
|
+
stable-harness agent render orchestra -w ./examples/minimal-deepagents
|
|
21
|
+
```
|
|
22
|
+
|
|
23
|
+
Start the protocol facade:
|
|
24
|
+
|
|
25
|
+
```bash
|
|
26
|
+
stable-harness start -w ./examples/minimal-deepagents --port 8642
|
|
27
|
+
curl -fsS http://127.0.0.1:8642/v1/models
|
|
28
|
+
```
|
|
29
|
+
|
|
30
|
+
Package the same workspace as a portable Docker runtime:
|
|
31
|
+
|
|
32
|
+
```bash
|
|
33
|
+
stable-harness build --target docker -w ./examples/minimal-deepagents --output ./dist/workspace-docker
|
|
34
|
+
cd ./dist/workspace-docker
|
|
35
|
+
STABLE_HARNESS_PORT=8642 docker compose up --build
|
|
36
|
+
curl -fsS http://127.0.0.1:8642/v1/models
|
|
37
|
+
```
|
|
38
|
+
|
|
39
|
+
## What The Proof Shows
|
|
40
|
+
|
|
41
|
+
| Claim | Evidence surface |
|
|
42
|
+
| --- | --- |
|
|
43
|
+
| Workspace configuration is reviewable | `agent render`, runtime inventory, YAML workspace files |
|
|
44
|
+
| Provider and model choice stay behind runtime boundaries | runtime config and `/v1/models` protocol output |
|
|
45
|
+
| Tool policy can be governed before execution | tool gateway plus Better Call repair/validation events |
|
|
46
|
+
| Runtime work can be inspected | request, session, event, artifact, approval, and replay APIs |
|
|
47
|
+
| Deployment has a stable boundary | generated Dockerfile, Compose file, `.env.example`, and `stable-workspace.json` |
|
|
48
|
+
|
|
49
|
+
## Public Copy Boundary
|
|
50
|
+
|
|
51
|
+
Stable Harness proof should describe runtime governance: sessions, events,
|
|
52
|
+
providers, tools, approvals, receipts, replay, protocols, and packaging. Flev
|
|
53
|
+
proof should describe user-facing product surfaces: Studio, chat, embed, review,
|
|
54
|
+
templates, and vertical workflow delivery.
|
|
@@ -0,0 +1,55 @@
|
|
|
1
|
+
# Stable Harness as Flev's Runtime Substrate
|
|
2
|
+
|
|
3
|
+
Stable Harness is the runtime and operator-control layer under Flev. It should
|
|
4
|
+
stay generic: it gives agent workspaces a governed execution boundary, while
|
|
5
|
+
Flev owns the user-facing product workspace, Studio views, embedded clients,
|
|
6
|
+
review flows, and vertical product packaging.
|
|
7
|
+
|
|
8
|
+
```text
|
|
9
|
+
Better Call -> Stable Harness -> Flev -> end-to-end products
|
|
10
|
+
tool-call reliability -> runtime control -> product workspace -> vertical workflow
|
|
11
|
+
```
|
|
12
|
+
|
|
13
|
+
## What Stable Harness Owns
|
|
14
|
+
|
|
15
|
+
- Workspace loading and validation.
|
|
16
|
+
- Session, request, run, and event lifecycle.
|
|
17
|
+
- Provider and model resolution.
|
|
18
|
+
- Tool gateway policy, including Better Call integration.
|
|
19
|
+
- Approval checkpoints and governance state.
|
|
20
|
+
- Runtime receipts for tool calls, provider choices, approvals, artifacts, and
|
|
21
|
+
final output.
|
|
22
|
+
- Runtime APIs, CLI, protocol facades, and in-process SDK access.
|
|
23
|
+
- Generic workspace-to-Docker artifact generation.
|
|
24
|
+
|
|
25
|
+
## What Stable Harness Does Not Own
|
|
26
|
+
|
|
27
|
+
- Flev Studio product layout and interaction decisions.
|
|
28
|
+
- Vertical workflow UX such as DevOps, finance, research, or compliance
|
|
29
|
+
product flows.
|
|
30
|
+
- Business-specific orchestration rules.
|
|
31
|
+
- Product packaging, customer account model, billing, or onboarding.
|
|
32
|
+
- Backend-native reasoning, planning, or delegation semantics when the selected
|
|
33
|
+
upstream framework already owns them.
|
|
34
|
+
|
|
35
|
+
## Website-Ready Copy
|
|
36
|
+
|
|
37
|
+
English:
|
|
38
|
+
|
|
39
|
+
> Stable Harness is the runtime substrate behind Flev. It gives agent
|
|
40
|
+
> workspaces sessions, provider boundaries, tool governance, approvals, events,
|
|
41
|
+
> receipts, replay, protocol access, and Docker packaging while leaving product
|
|
42
|
+
> UX and vertical workflow design to Flev.
|
|
43
|
+
|
|
44
|
+
Chinese:
|
|
45
|
+
|
|
46
|
+
> Stable Harness 是 Flev 背后的运行时底座。它为 Agent 工作区提供 session、
|
|
47
|
+
> provider 边界、工具治理、审批、事件、运行凭证、回放、协议访问和 Docker
|
|
48
|
+
> 打包;产品界面和垂直工作流设计则由 Flev 承担。
|
|
49
|
+
|
|
50
|
+
## Design Rule
|
|
51
|
+
|
|
52
|
+
If a capability is generic runtime governance, it belongs in Stable Harness. If
|
|
53
|
+
it turns a workflow into a user-facing product, it belongs in Flev. If it repairs
|
|
54
|
+
or validates model/tool-call shape at the execution boundary, it belongs in
|
|
55
|
+
Better Call.
|
package/docs/product-boundary.md
CHANGED
|
@@ -6,6 +6,12 @@ It is not a new agent framework. It wraps upstream frameworks such as DeepAgents
|
|
|
6
6
|
|
|
7
7
|
DeepAgents is the first backend target. The current DeepAgents feature set must be audited before adding any overlapping `stable-harness` behavior.
|
|
8
8
|
|
|
9
|
+
In the EasyNet World product stack, `stable-harness` is the runtime substrate
|
|
10
|
+
under Flev. Flev owns the product workspace and user-facing surfaces. Better
|
|
11
|
+
Call owns reusable tool-call reliability. Stable Harness should expose the
|
|
12
|
+
runtime evidence and control surfaces that Flev can package, not absorb Flev's
|
|
13
|
+
vertical product behavior into the generic runtime.
|
|
14
|
+
|
|
9
15
|
## Product Mission
|
|
10
16
|
|
|
11
17
|
The product should let a team define a production agent workspace in YAML, choose an execution backend, and get stable runtime operations without rewriting the backend framework.
|
|
@@ -15,6 +15,9 @@ export declare function runMemoryPlugins(input: {
|
|
|
15
15
|
}): Promise<void>;
|
|
16
16
|
export declare function recallMemoryPlugins(input: {
|
|
17
17
|
providers: MemoryProvider[] | undefined;
|
|
18
|
+
emit?: RuntimeEmit;
|
|
19
|
+
requestId?: string;
|
|
20
|
+
sessionId?: string;
|
|
18
21
|
request: RuntimeRequest;
|
|
19
22
|
agent: WorkspaceAgent;
|
|
20
23
|
workspace: CompiledWorkspace;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{formatError as e,readRecord as r,readWorkspaceId as t,resolveEnabledMemories as n,resolveMemoryProvider as o,resolvePluginNamespace as a}from"./memory-plugins/shared.js";export{resolveEnabledMemories,resolvePluginNamespace}from"./memory-plugins/shared.js";export{createLangMemMaintenanceTarget,createMemoryMaintenanceDaemon,createSkillCandidateMinerTarget}from"./memory-plugins/maintenance.js";export async function runMemoryPlugins(e){const r=n(e.workspace,"write");if(e.providers?.length&&0!==r.length&&!1!==e.request.metadata?.memoryWrite)for(const t of r)await runMemoryPlugin(e,t)}export async function recallMemoryPlugins(e){const r=n(e.workspace,"recall");if(!e.providers?.length||0===r.length)return[];const t=await Promise.all(r.map(async r=>{try{return await async function recallMemoryPlugin(e,r){const t=o(e.providers??[],r.provider);if(!t)return;const n=a(e.workspace,e.agent,e.request,r),s=await t.search({namespace:n,query:buildRecallQuery(e),limit:readRecallLimit(e.workspace)});return{namespace:n,records:s,context:formatRecallContext(e.workspace,s)}}(e,r)}catch{return}}));return t.filter(e=>Boolean(e?.context))}async function runMemoryPlugin(r,t){const n=o(r.providers??[],t.provider);if(!n)return;const s=a(r.workspace,r.agent,r.request,t);r.emit({type:"runtime.memory.plugin.started",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s});try{const e=await n.propose(function createPluginProposeInput(e,r,t){return{namespace:t,content:[`User input:\n${e.request.input}`,`Agent output:\n${e.result.text}`].join("\n\n"),sourceType:"runtime-run",sourceRef:e.requestId,metadata:{memoryId:r.id,provider:r.provider,profile:r.profile,mode:r.mode,prompts:r.prompts,workspaceRoot:e.workspace.root,agentId:e.agent.id,sessionId:e.sessionId,requestMetadata:e.request.metadata}}}(r,t,s));r.emit({type:"runtime.memory.plugin.completed",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s,candidateCount:e.length})}catch(o){r.emit({type:"runtime.memory.plugin.failed",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s,error:e(o)})}}function buildRecallQuery(e){const r=[`task: ${e.request.input}`,`workspace: ${t(e.workspace)}`,`agent: ${e.agent.id}`,"memory_needed: durable preferences, workspace facts, reusable procedures, prior corrections"],n=function readRecentContext(e){return"string"==typeof e?.recentContext?e.recentContext.slice(0,3e3):Array.isArray(e?.recentTurns)?e.recentTurns.filter(e=>"string"==typeof e).slice(-6).join("\n").slice(0,3e3):void 0}(e.request.metadata);return n?[...r,`recent_context: ${n}`].join("\n"):r.join("\n")}function readRecallLimit(e){const t=r(e.runtime.memory?.LangMem),n=r(t?.recall),o=n?.topK??n?.limit;return"number"==typeof o&&Number.isFinite(o)?o:10}function formatRecallContext(e,t){const n=function readRecallContextLimits(e){const t=r(e.runtime.memory?.LangMem),n=r(t?.recall);return{maxContextChars:readPositiveNumber(n?.maxContextChars)??4e3,maxRecordChars:readPositiveNumber(n?.maxRecordChars)??1e3}}(e),o=[];let a=n.maxContextChars;for(const e of t){if(a<=0)break;const r=truncateText(formatRecallRecord(e),Math.min(n.maxRecordChars,a));r.trim()&&(o.push(r),a-=r.length+1)}return o.join("\n")}function formatRecallRecord(e){return`- ${e.summary??e.content}\n ${e.content}`}function readPositiveNumber(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}function truncateText(e,r){return e.length>r?`${e.slice(0,Math.max(0,r-13))}\n [truncated]`:e}
|
|
1
|
+
import{formatError as e,readRecord as r,readWorkspaceId as t,resolveEnabledMemories as n,resolveMemoryProvider as o,resolvePluginNamespace as a}from"./memory-plugins/shared.js";export{resolveEnabledMemories,resolvePluginNamespace}from"./memory-plugins/shared.js";export{createLangMemMaintenanceTarget,createMemoryMaintenanceDaemon,createSkillCandidateMinerTarget}from"./memory-plugins/maintenance.js";export async function runMemoryPlugins(e){const r=n(e.workspace,"write");if(e.providers?.length&&0!==r.length&&!1!==e.request.metadata?.memoryWrite)for(const t of r)await runMemoryPlugin(e,t)}export async function recallMemoryPlugins(e){const r=n(e.workspace,"recall");if(!e.providers?.length||0===r.length)return[];const t=await Promise.all(r.map(async r=>{try{return await async function recallMemoryPlugin(e,r){const t=o(e.providers??[],r.provider);if(!t)return;const n=a(e.workspace,e.agent,e.request,r),s=await t.search({namespace:n,query:buildRecallQuery(e),limit:readRecallLimit(e.workspace)});return e.emit&&e.requestId&&e.sessionId&&e.emit({type:"runtime.memory.recall.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,namespace:n,recordIds:s.map(e=>e.id),context:formatRecallContext(e.workspace,s)}),{namespace:n,records:s,context:formatRecallContext(e.workspace,s)}}(e,r)}catch{return}}));return t.filter(e=>Boolean(e?.context))}async function runMemoryPlugin(r,t){const n=o(r.providers??[],t.provider);if(!n)return;const s=a(r.workspace,r.agent,r.request,t);r.emit({type:"runtime.memory.plugin.started",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s});try{const e=await n.propose(function createPluginProposeInput(e,r,t){return{namespace:t,content:[`User input:\n${e.request.input}`,`Agent output:\n${e.result.text}`].join("\n\n"),sourceType:"runtime-run",sourceRef:e.requestId,metadata:{memoryId:r.id,provider:r.provider,profile:r.profile,mode:r.mode,prompts:r.prompts,workspaceRoot:e.workspace.root,agentId:e.agent.id,sessionId:e.sessionId,requestMetadata:e.request.metadata}}}(r,t,s));r.emit({type:"runtime.memory.plugin.completed",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s,candidateCount:e.length})}catch(o){r.emit({type:"runtime.memory.plugin.failed",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s,error:e(o)})}}function buildRecallQuery(e){const r=[`task: ${e.request.input}`,`workspace: ${t(e.workspace)}`,`agent: ${e.agent.id}`,"memory_needed: durable preferences, workspace facts, reusable procedures, prior corrections"],n=function readRecentContext(e){return"string"==typeof e?.recentContext?e.recentContext.slice(0,3e3):Array.isArray(e?.recentTurns)?e.recentTurns.filter(e=>"string"==typeof e).slice(-6).join("\n").slice(0,3e3):void 0}(e.request.metadata);return n?[...r,`recent_context: ${n}`].join("\n"):r.join("\n")}function readRecallLimit(e){const t=r(e.runtime.memory?.LangMem),n=r(t?.recall),o=n?.topK??n?.limit;return"number"==typeof o&&Number.isFinite(o)?o:10}function formatRecallContext(e,t){const n=function readRecallContextLimits(e){const t=r(e.runtime.memory?.LangMem),n=r(t?.recall);return{maxContextChars:readPositiveNumber(n?.maxContextChars)??4e3,maxRecordChars:readPositiveNumber(n?.maxRecordChars)??1e3}}(e),o=[];let a=n.maxContextChars;for(const e of t){if(a<=0)break;const r=truncateText(formatRecallRecord(e),Math.min(n.maxRecordChars,a));r.trim()&&(o.push(r),a-=r.length+1)}return o.join("\n")}function formatRecallRecord(e){return`- ${e.summary??e.content}\n ${e.content}`}function readPositiveNumber(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}function truncateText(e,r){return e.length>r?`${e.slice(0,Math.max(0,r-13))}\n [truncated]`:e}
|
|
@@ -5,6 +5,8 @@ import type { RuntimeSandboxDecision } from "./tool-gateway.js";
|
|
|
5
5
|
import type { RuntimeToolFailureClassification, RuntimeToolFailureReason } from "./tool-failure.js";
|
|
6
6
|
export type RuntimeInventoryRepairLayer = "agent" | "workflow_route" | "workflow" | "tool" | "task" | "skill";
|
|
7
7
|
export type RuntimeInventoryRepairStatus = "repaired" | "blocked";
|
|
8
|
+
export type RuntimeRepairLayer = "adapter_error" | "result_output" | "execution_contract" | "evidence_synthesis";
|
|
9
|
+
export type RuntimeRepairOutcome = "retried" | "synthesized" | "blocked";
|
|
8
10
|
export type RuntimeInventoryRepairDiagnostic = {
|
|
9
11
|
layer: RuntimeInventoryRepairLayer;
|
|
10
12
|
owner: "stable_runtime_policy" | "protocol_adapter" | "upstream_backend" | "workspace_config";
|
|
@@ -56,6 +58,23 @@ export type RuntimeEvent = RuntimeEventMetadata & ({
|
|
|
56
58
|
agentId: string;
|
|
57
59
|
reason: string;
|
|
58
60
|
missingEvidenceTools?: string[];
|
|
61
|
+
} | {
|
|
62
|
+
type: "runtime.repair.started";
|
|
63
|
+
requestId: string;
|
|
64
|
+
sessionId: string;
|
|
65
|
+
agentId: string;
|
|
66
|
+
layer: RuntimeRepairLayer;
|
|
67
|
+
attempt?: number;
|
|
68
|
+
reason?: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: "runtime.repair.completed";
|
|
71
|
+
requestId: string;
|
|
72
|
+
sessionId: string;
|
|
73
|
+
agentId: string;
|
|
74
|
+
layer: RuntimeRepairLayer;
|
|
75
|
+
outcome: RuntimeRepairOutcome;
|
|
76
|
+
attempt?: number;
|
|
77
|
+
reason?: string;
|
|
59
78
|
} | {
|
|
60
79
|
type: "runtime.inventory.repair";
|
|
61
80
|
requestId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{recallMemoryPlugins as e,runMemoryPlugins as r}from"../memory-plugins.js";export function emitMemoryLifecycle(e,r,s,t,o,a){e&&r({type:"runtime.memory.lifecycle",requestId:s,sessionId:t,agentId:o,hook:a})}export async function runMemoryRecall(e){if(!e.memory)return;if(emitMemoryLifecycle(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-plan"),!1===e.request.memory?.recall)return;const r=resolveMemoryNamespace(e.workspace,e.agent,e.request),s=e.request.memory?.recall?.query??e.request.input,t=await e.memory.recall({namespace:r,query:s,limit:e.request.memory?.recall?.limit});return e.emit({type:"runtime.memory.recall.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,namespace:r,recordIds:t.records.map(e=>e.id),context:t.context}),{namespace:r,records:t.records,context:t.context}}export async function submitMemoryCandidates(e){if(!e.memory||!e.request.memory?.candidates?.length)return;emitMemoryLifecycle(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"write-after-run");const r=resolveMemoryNamespace(e.workspace,e.agent,e.request);for(const s of e.request.memory.candidates){const t={...s,namespace:s.namespace??r},o=await e.memory.submitCandidate(t);if(e.emit({type:"runtime.memory.candidate.submitted",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,candidate:o.candidate,decision:o.decision,record:o.record}),"review"===o.decision.action&&e.approvals){const r=await e.approvals.create({kind:"memory_write",reason:o.decision.reason,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,subject:{candidate:o.candidate,decision:o.decision}});e.emit({type:"runtime.memory.approval.requested",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,approval:r})}}}export function createMemoryRuntimeCapability(s){return{id:"runtime.memory",beforeAdapterRun:async r=>({memory:await runMemoryRecall({memory:s.memory,emit:r.emit,request:r.request,requestId:r.requestId,sessionId:r.sessionId,agent:r.agent,workspace:r.workspace}),pluginMemories:await e({providers:s.memoryProviders,request:r.request,agent:r.agent,workspace:r.workspace})}),async beforeAdapterResultContract(e){emitMemoryLifecycle(s.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-finalize"),await submitMemoryCandidates({memory:s.memory,approvals:s.approvals,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.workspace})},async afterAdapterResponse(e){await r({providers:s.memoryProviders,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.workspace,result:e.result})}}}function resolveMemoryNamespace(e,r,s){return s.memory?.namespace??`${e.root}:${r.id}`}
|
|
1
|
+
import{recallMemoryPlugins as e,runMemoryPlugins as r}from"../memory-plugins.js";export function emitMemoryLifecycle(e,r,s,t,o,a){e&&r({type:"runtime.memory.lifecycle",requestId:s,sessionId:t,agentId:o,hook:a})}export async function runMemoryRecall(e){if(!e.memory)return;if(emitMemoryLifecycle(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-plan"),!1===e.request.memory?.recall)return;const r=resolveMemoryNamespace(e.workspace,e.agent,e.request),s=e.request.memory?.recall?.query??e.request.input,t=await e.memory.recall({namespace:r,query:s,limit:e.request.memory?.recall?.limit});return e.emit({type:"runtime.memory.recall.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,namespace:r,recordIds:t.records.map(e=>e.id),context:t.context}),{namespace:r,records:t.records,context:t.context}}export async function submitMemoryCandidates(e){if(!e.memory||!e.request.memory?.candidates?.length)return;emitMemoryLifecycle(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"write-after-run");const r=resolveMemoryNamespace(e.workspace,e.agent,e.request);for(const s of e.request.memory.candidates){const t={...s,namespace:s.namespace??r},o=await e.memory.submitCandidate(t);if(e.emit({type:"runtime.memory.candidate.submitted",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,candidate:o.candidate,decision:o.decision,record:o.record}),"review"===o.decision.action&&e.approvals){const r=await e.approvals.create({kind:"memory_write",reason:o.decision.reason,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,subject:{candidate:o.candidate,decision:o.decision}});e.emit({type:"runtime.memory.approval.requested",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,approval:r})}}}export function createMemoryRuntimeCapability(s){return{id:"runtime.memory",beforeAdapterRun:async r=>({memory:await runMemoryRecall({memory:s.memory,emit:r.emit,request:r.request,requestId:r.requestId,sessionId:r.sessionId,agent:r.agent,workspace:r.workspace}),pluginMemories:await e({providers:s.memoryProviders,emit:r.emit,requestId:r.requestId,sessionId:r.sessionId,request:r.request,agent:r.agent,workspace:r.workspace})}),async beforeAdapterResultContract(e){emitMemoryLifecycle(s.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-finalize"),await submitMemoryCandidates({memory:s.memory,approvals:s.approvals,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.workspace})},async afterAdapterResponse(e){await r({providers:s.memoryProviders,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.workspace,result:e.result})}}}function resolveMemoryNamespace(e,r,s){return s.memory?.namespace??`${e.root}:${r.id}`}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function resolveProgressNarrator(e){if(!1===e.options)return;const t=readProgressPolicy(e.policy);return e.options?.enabled??t.enabled?e.options?.provider??function createTemplateProgressNarrator(){const e=new Map,t=new Map;return{name:"template",narrate(r,n){var o;"runtime.request.started"===r.type&&(e.set(r.requestId,{language:(o=r.input??"",/\p{Script=Han}/u.test(o)?"zh":void 0),input:r.input}),t.delete(r.requestId));const i=function templateMessage(e,t){const r="zh"===t?.language;return"runtime.request.started"===e.type?r?`我开始处理这个请求:${summarizeText(e.input)}`:`I'm starting on this request: ${summarizeText(e.input)}`:"runtime.request.completed"===e.type?r?"我已经完成执行链,正在交付最终结果。":"I've finished the execution chain and am returning the final result.":"runtime.request.failed"===e.type?r?"执行链失败了,我会保留具体错误方便定位。":"The execution chain failed; I'm keeping the concrete error visible for diagnosis.":"runtime.request.cancelled"===e.type?r?"这个请求已取消,后续执行会停止。":"The request was cancelled, so the remaining execution will stop.":"runtime.tool.direct.started"===e.type?r?`我正在运行 ${e.toolId}。`:`I'm running ${e.toolId}.`:"runtime.tool.direct.completed"===e.type?r?`${e.toolId} 已返回结果,我会继续使用这份证据。`:`${e.toolId} returned; I'll keep using that evidence.`:"runtime.workflow.started"===e.type?r?`我正在启动 workflow ${e.workflowId}。`:`I'm starting workflow ${e.workflowId}.`:"runtime.workflow.completed"===e.type?r?`workflow ${e.workflowId} 已完成。`:`Workflow ${e.workflowId} is complete.`:"runtime.specDriven.phase.started"===e.type?r?`我正在进入 spec-driven 阶段 ${e.phaseId}。`:`I'm starting spec-driven phase ${e.phaseId}.`:"runtime.specDriven.phase.blocked"===e.type?r?`spec-driven 阶段 ${e.phaseId} 被 gate 阻塞。`:`Spec-driven phase ${e.phaseId} is blocked by a gate.`:"runtime.specDriven.phase.completed"===e.type?r?`spec-driven 阶段 ${e.phaseId} 已完成。`:`Spec-driven phase ${e.phaseId} is complete.`:"runtime.specDriven.phase.verified"===e.type?r?`spec-driven 阶段 ${e.phaseId} 已验证。`:`Spec-driven phase ${e.phaseId} is verified.`:"runtime.artifact.created"===e.type?r?"我已经保存一份运行产物。":"I've saved a runtime artifact.":"runtime.execution.contract.failed"===e.type?r?"运行证据没有满足执行契约,我会进入恢复或失败路径。":"The run evidence did not satisfy the execution contract, so I'll recover or fail explicitly.":"runtime.inventory.repair"===e.type?inventoryRepairMessage(e.status,e.diagnostic.layer,r):"runtime.skill.candidate.created"===e.type?r?`我发现一个可沉淀的 skill 候选:${e.name}。`:`I found a reusable skill candidate: ${e.name}.`:e.type.startsWith("runtime.memory.")?function memoryMessage(e,t){return"runtime.memory.lifecycle"===e.type?t?`我进入记忆阶段:${e.hook}。`:`I'm in the memory lifecycle phase: ${e.hook}.`:"runtime.memory.recall.completed"===e.type?t?`我召回了 ${e.recordIds.length} 条相关记忆。`:`I recalled ${e.recordIds.length} relevant memory records.`:"runtime.memory.candidate.submitted"===e.type?t?"我提交了一条候选记忆。":"I submitted a memory candidate.":"runtime.memory.approval.requested"===e.type?t?"我提交了记忆审批请求。":"I requested memory approval.":"runtime.memory.plugin.started"===e.type?t?`我正在运行记忆插件 ${e.provider}。`:`I'm running memory plugin ${e.provider}.`:"runtime.memory.plugin.completed"===e.type?t?`记忆插件 ${e.provider} 已完成。`:`Memory plugin ${e.provider} completed.`:"runtime.memory.plugin.failed"===e.type?t?`记忆插件 ${e.provider} 失败了;主任务会继续,不把它当成执行结果。`:`Memory plugin ${e.provider} failed; the main task will continue without treating it as the result.`:"runtime.memory.maintenance.started"===e.type?t?`我正在维护 ${e.target} 记忆。`:`I'm maintaining ${e.target} memory.`:"runtime.memory.maintenance.completed"===e.type?t?`${e.target} 记忆维护完成。`:`${e.target} memory maintenance completed.`:"runtime.memory.maintenance.failed"===e.type?t?`${e.target} 记忆维护失败。`:`${e.target} memory maintenance failed.`:void 0}(e,r):"runtime.adapter.event"===e.type?function adapterMessage(e,t){if(isRecord(e)){if("agent.handoff"===e.phase)return t?"我把请求交给上游 agent backend,让它负责规划和执行。":"I'm handing the request to the upstream agent backend for planning and execution.";if(function isToolStartEvent(e){return"deepagents.tool_execution.start"===e.eventType||"agent.tool.start"===e.phase}(e)&&"string"==typeof e.toolId)return function toolStartMessage(e,t,r){if("task"===e){const e=function readTaskTarget(e){const t=isRecord(e)?e:{};return readString(t.subagent_type)??readString(t.subagentType)}(t),n=function readDescription(e){const t=isRecord(e)?e:{};return summarizeText(readString(t.description)??readString(t.task))}(t);if(e&&n)return r?`我正在请求 task 工具委派给 ${e}:${n}`:`I'm asking the task tool to delegate to ${e}: ${n}`;if(e)return r?`我正在请求 task 工具委派给 ${e}。`:`I'm asking the task tool to delegate to ${e}.`}return r?`我正在运行 ${e} 收集证据。`:`I'm running ${e} to gather evidence.`}(e.toolId,e.args,t);if(function isToolResultEvent(e){return"deepagents.tool_execution.result"===e.eventType||"agent.tool.result"===e.phase}(e)&&"string"==typeof e.toolId)return function toolResultMessage(e,t,r,n,o){if(r)return o?`${e} 返回错误:${summarizeText(String(r))}`:`${e} returned an error: ${summarizeText(String(r))}`;const i="string"==typeof n?n:function readToolControlStatus(e){const t=function parseToolOutputRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e);return"string"==typeof t?.status?t.status:"string"==typeof t?.error?t.error:"string"==typeof e&&e.startsWith("Task delegation target is not in the workspace inventory")?"task_inventory_blocked":void 0}(t);if(i)return function toolControlMessage(e,t,r){return"duplicate_tool_call"===t?r?`${e} 重复调用已复用已有证据。`:`${e} repeated an equivalent call, so the existing evidence was reused.`:"repeated_tool_call_limit"===t?r?`${e} 出现重复调用循环,我会基于已有证据继续收敛。`:`${e} entered a repeated-call loop, so I'll continue from the evidence already collected.`:"tool_argument_error"===t||"tool_argument_validation_failed"===t?r?`${e} 参数被工具 schema 拒绝,我会让 agent 修正参数或改用合适工具。`:`${e} arguments were rejected by the tool schema; I'll have the agent repair them or choose a suitable tool.`:"task_inventory_blocked"===t?r?"task 委派目标不在当前 workspace inventory 中,已被运行时策略阻止。":"The task delegation target is not in the current workspace inventory and was blocked by runtime policy.":r?`${e} 返回运行时控制状态:${t}。`:`${e} returned runtime control status: ${t}.`}(e,i,o);if("task"===e)return o?"委派任务已返回结果,我会基于这些证据继续推进。":"The delegated task returned; I'll keep going with that evidence.";const a=function summarizeToolOutput(e){if("string"==typeof e)return summarizeText(e);if(isRecord(e)){if("string"==typeof e.status)return summarizeText(e.status);if("string"==typeof e.summary)return summarizeText(e.summary)}}(t);return o?`${e} 已返回${a?`:${a}`:",我会继续判断下一步。"}`:`${e} returned${a?`: ${a}`:"; I'll decide the next step from here."}`}(e.toolId,e.output,e.error,e.controlStatus,t);if("agent.langgraph.invoke"===e.phase)return t?"我正在调用 workflow backend。":"I'm invoking the workflow backend.";if("agent.node.completed"===e.phase&&"string"==typeof e.nodeId)return t?`节点 ${e.nodeId} 已完成。`:`Node ${e.nodeId} is complete.`;if("inventory.repair"===e.phase&&"string"==typeof e.status){const r=isRecord(e.diagnostic)?e.diagnostic:{};return inventoryRepairMessage(e.status,readString(r.layer)??"selection",t)}}}(e.event,r):void 0}(r,e.get(r.requestId));if(i&&i!==t.get(r.requestId))return t.set(r.requestId,i),"runtime.request.failed"!==r.type&&"runtime.request.cancelled"!==r.type||(e.delete(r.requestId),t.delete(r.requestId)),function pruneRequestState(e,t){for(;e.size>200;){const r=e.keys().next().value;if(!r)break;e.delete(r),t.delete(r)}}(e,t),{message:i,style:n.style,model:n.model}}}}():void 0}export function createProgressNarrationEvent(e){if(!e.narrator||"runtime.progress.narration"===e.source.type)return;const t=readProgressPolicy(e.policy),r=!1===e.options?void 0:e.options,n=e.narrator.narrate(e.source,{style:r?.style??t.style,model:r?.model??t.model});return function isPromiseLike(e){return isRecord(e)&&"function"==typeof e.then}(n)?n.then(t=>toNarrationEvent(e.source,e.narrator,t)):toNarrationEvent(e.source,e.narrator,n)}export function createProgressNarrationCapability(e){const t=resolveProgressNarrator(e);if(t)return{id:"runtime.progress.narration",onEvent(r,n){try{const o=createProgressNarrationEvent({source:r,narrator:t,options:e.options,policy:e.policy});!function isRuntimeEventPromise(e){return isRecord(e)&&"function"==typeof e.then}(o)?o&&n(o):o.then(e=>{e&&n(e)}).catch(()=>{})}catch{return}}}}function toNarrationEvent(e,t,r){if(r?.message.trim())return{type:"runtime.progress.narration",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,message:r.message,provider:t.name,sourceEventTypes:r.sourceEventTypes??[e.type],sourceEventIds:r.sourceEventIds??(e.eventId?[e.eventId]:void 0),model:r.model,style:r.style}}function inventoryRepairMessage(e,t,r){return"repaired"===e?r?`${t} 选择已按 workspace inventory 修正。`:`${t} selection was repaired against the workspace inventory.`:r?`${t} 选择不在 workspace inventory 中,已被阻止。`:`${t} selection was blocked because it is outside the workspace inventory.`}function summarizeText(e){const t=e?.replace(/\s+/gu," ").trim();return t?t.length>120?`${t.slice(0,117)}...`:t:""}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readProgressPolicy(e){const t=isRecord(e?.progress)?e.progress:{},r=isRecord(t.narration)?t.narration:{};return{enabled:"boolean"==typeof r.enabled?r.enabled:void 0,style:"string"==typeof r.style?r.style:void 0,model:"string"==typeof r.model?r.model:void 0}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
1
|
+
export function resolveProgressNarrator(e){if(!1===e.options)return;const t=readProgressPolicy(e.policy);return e.options?.enabled??t.enabled?e.options?.provider??function createTemplateProgressNarrator(){const e=new Map,t=new Map;return{name:"template",narrate(r,n){var o;"runtime.request.started"===r.type&&(e.set(r.requestId,{language:(o=r.input??"",/\p{Script=Han}/u.test(o)?"zh":void 0),input:r.input}),t.delete(r.requestId));const i=function templateMessage(e,t){const r="zh"===t?.language;return"runtime.request.started"===e.type?r?`我开始处理这个请求:${summarizeText(e.input)}`:`I'm starting on this request: ${summarizeText(e.input)}`:"runtime.request.completed"===e.type?r?"我已经完成执行链,正在交付最终结果。":"I've finished the execution chain and am returning the final result.":"runtime.request.failed"===e.type?r?"执行链失败了,我会保留具体错误方便定位。":"The execution chain failed; I'm keeping the concrete error visible for diagnosis.":"runtime.request.cancelled"===e.type?r?"这个请求已取消,后续执行会停止。":"The request was cancelled, so the remaining execution will stop.":"runtime.tool.direct.started"===e.type?r?`我正在运行 ${e.toolId}。`:`I'm running ${e.toolId}.`:"runtime.tool.direct.completed"===e.type?r?`${e.toolId} 已返回结果,我会继续使用这份证据。`:`${e.toolId} returned; I'll keep using that evidence.`:"runtime.workflow.started"===e.type?r?`我正在启动 workflow ${e.workflowId}。`:`I'm starting workflow ${e.workflowId}.`:"runtime.workflow.completed"===e.type?r?`workflow ${e.workflowId} 已完成。`:`Workflow ${e.workflowId} is complete.`:"runtime.specDriven.phase.started"===e.type?r?`我正在进入 spec-driven 阶段 ${e.phaseId}。`:`I'm starting spec-driven phase ${e.phaseId}.`:"runtime.specDriven.phase.blocked"===e.type?r?`spec-driven 阶段 ${e.phaseId} 被 gate 阻塞。`:`Spec-driven phase ${e.phaseId} is blocked by a gate.`:"runtime.specDriven.phase.completed"===e.type?r?`spec-driven 阶段 ${e.phaseId} 已完成。`:`Spec-driven phase ${e.phaseId} is complete.`:"runtime.specDriven.phase.verified"===e.type?r?`spec-driven 阶段 ${e.phaseId} 已验证。`:`Spec-driven phase ${e.phaseId} is verified.`:"runtime.artifact.created"===e.type?r?"我已经保存一份运行产物。":"I've saved a runtime artifact.":"runtime.execution.contract.failed"===e.type?r?"运行证据没有满足执行契约,我会进入恢复或失败路径。":"The run evidence did not satisfy the execution contract, so I'll recover or fail explicitly.":"runtime.repair.started"===e.type?repairMessage(e.layer,"started",r):"runtime.repair.completed"===e.type?repairMessage(e.layer,e.outcome,r):"runtime.inventory.repair"===e.type?inventoryRepairMessage(e.status,e.diagnostic.layer,r):"runtime.skill.candidate.created"===e.type?r?`我发现一个可沉淀的 skill 候选:${e.name}。`:`I found a reusable skill candidate: ${e.name}.`:e.type.startsWith("runtime.memory.")?function memoryMessage(e,t){return"runtime.memory.lifecycle"===e.type?t?`我进入记忆阶段:${e.hook}。`:`I'm in the memory lifecycle phase: ${e.hook}.`:"runtime.memory.recall.completed"===e.type?t?`我召回了 ${e.recordIds.length} 条相关记忆。`:`I recalled ${e.recordIds.length} relevant memory records.`:"runtime.memory.candidate.submitted"===e.type?t?"我提交了一条候选记忆。":"I submitted a memory candidate.":"runtime.memory.approval.requested"===e.type?t?"我提交了记忆审批请求。":"I requested memory approval.":"runtime.memory.plugin.started"===e.type?t?`我正在运行记忆插件 ${e.provider}。`:`I'm running memory plugin ${e.provider}.`:"runtime.memory.plugin.completed"===e.type?t?`记忆插件 ${e.provider} 已完成。`:`Memory plugin ${e.provider} completed.`:"runtime.memory.plugin.failed"===e.type?t?`记忆插件 ${e.provider} 失败了;主任务会继续,不把它当成执行结果。`:`Memory plugin ${e.provider} failed; the main task will continue without treating it as the result.`:"runtime.memory.maintenance.started"===e.type?t?`我正在维护 ${e.target} 记忆。`:`I'm maintaining ${e.target} memory.`:"runtime.memory.maintenance.completed"===e.type?t?`${e.target} 记忆维护完成。`:`${e.target} memory maintenance completed.`:"runtime.memory.maintenance.failed"===e.type?t?`${e.target} 记忆维护失败。`:`${e.target} memory maintenance failed.`:void 0}(e,r):"runtime.adapter.event"===e.type?function adapterMessage(e,t){if(isRecord(e)){if("agent.handoff"===e.phase)return t?"我把请求交给上游 agent backend,让它负责规划和执行。":"I'm handing the request to the upstream agent backend for planning and execution.";if(function isToolStartEvent(e){return"deepagents.tool_execution.start"===e.eventType||"agent.tool.start"===e.phase}(e)&&"string"==typeof e.toolId)return function toolStartMessage(e,t,r){if("task"===e){const e=function readTaskTarget(e){const t=isRecord(e)?e:{};return readString(t.subagent_type)??readString(t.subagentType)}(t),n=function readDescription(e){const t=isRecord(e)?e:{};return summarizeText(readString(t.description)??readString(t.task))}(t);if(e&&n)return r?`我正在请求 task 工具委派给 ${e}:${n}`:`I'm asking the task tool to delegate to ${e}: ${n}`;if(e)return r?`我正在请求 task 工具委派给 ${e}。`:`I'm asking the task tool to delegate to ${e}.`}return r?`我正在运行 ${e} 收集证据。`:`I'm running ${e} to gather evidence.`}(e.toolId,e.args,t);if(function isToolResultEvent(e){return"deepagents.tool_execution.result"===e.eventType||"agent.tool.result"===e.phase}(e)&&"string"==typeof e.toolId)return function toolResultMessage(e,t,r,n,o){if(r)return o?`${e} 返回错误:${summarizeText(String(r))}`:`${e} returned an error: ${summarizeText(String(r))}`;const i="string"==typeof n?n:function readToolControlStatus(e){const t=function parseToolOutputRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e);return"string"==typeof t?.status?t.status:"string"==typeof t?.error?t.error:"string"==typeof e&&e.startsWith("Task delegation target is not in the workspace inventory")?"task_inventory_blocked":void 0}(t);if(i)return function toolControlMessage(e,t,r){return"duplicate_tool_call"===t?r?`${e} 重复调用已复用已有证据。`:`${e} repeated an equivalent call, so the existing evidence was reused.`:"repeated_tool_call_limit"===t?r?`${e} 出现重复调用循环,我会基于已有证据继续收敛。`:`${e} entered a repeated-call loop, so I'll continue from the evidence already collected.`:"tool_argument_error"===t||"tool_argument_validation_failed"===t?r?`${e} 参数被工具 schema 拒绝,我会让 agent 修正参数或改用合适工具。`:`${e} arguments were rejected by the tool schema; I'll have the agent repair them or choose a suitable tool.`:"task_inventory_blocked"===t?r?"task 委派目标不在当前 workspace inventory 中,已被运行时策略阻止。":"The task delegation target is not in the current workspace inventory and was blocked by runtime policy.":r?`${e} 返回运行时控制状态:${t}。`:`${e} returned runtime control status: ${t}.`}(e,i,o);if("task"===e)return o?"委派任务已返回结果,我会基于这些证据继续推进。":"The delegated task returned; I'll keep going with that evidence.";const a=function summarizeToolOutput(e){if("string"==typeof e)return summarizeText(e);if(isRecord(e)){if("string"==typeof e.status)return summarizeText(e.status);if("string"==typeof e.summary)return summarizeText(e.summary)}}(t);return o?`${e} 已返回${a?`:${a}`:",我会继续判断下一步。"}`:`${e} returned${a?`: ${a}`:"; I'll decide the next step from here."}`}(e.toolId,e.output,e.error,e.controlStatus,t);if("agent.langgraph.invoke"===e.phase)return t?"我正在调用 workflow backend。":"I'm invoking the workflow backend.";if("agent.node.completed"===e.phase&&"string"==typeof e.nodeId)return t?`节点 ${e.nodeId} 已完成。`:`Node ${e.nodeId} is complete.`;if("inventory.repair"===e.phase&&"string"==typeof e.status){const r=isRecord(e.diagnostic)?e.diagnostic:{};return inventoryRepairMessage(e.status,readString(r.layer)??"selection",t)}}}(e.event,r):void 0}(r,e.get(r.requestId));if(i&&i!==t.get(r.requestId))return t.set(r.requestId,i),"runtime.request.failed"!==r.type&&"runtime.request.cancelled"!==r.type||(e.delete(r.requestId),t.delete(r.requestId)),function pruneRequestState(e,t){for(;e.size>200;){const r=e.keys().next().value;if(!r)break;e.delete(r),t.delete(r)}}(e,t),{message:i,style:n.style,model:n.model}}}}():void 0}export function createProgressNarrationEvent(e){if(!e.narrator||"runtime.progress.narration"===e.source.type)return;const t=readProgressPolicy(e.policy),r=!1===e.options?void 0:e.options,n=e.narrator.narrate(e.source,{style:r?.style??t.style,model:r?.model??t.model});return function isPromiseLike(e){return isRecord(e)&&"function"==typeof e.then}(n)?n.then(t=>toNarrationEvent(e.source,e.narrator,t)):toNarrationEvent(e.source,e.narrator,n)}export function createProgressNarrationCapability(e){const t=resolveProgressNarrator(e);if(t)return{id:"runtime.progress.narration",onEvent(r,n){try{const o=createProgressNarrationEvent({source:r,narrator:t,options:e.options,policy:e.policy});!function isRuntimeEventPromise(e){return isRecord(e)&&"function"==typeof e.then}(o)?o&&n(o):o.then(e=>{e&&n(e)}).catch(()=>{})}catch{return}}}}function toNarrationEvent(e,t,r){if(r?.message.trim())return{type:"runtime.progress.narration",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,message:r.message,provider:t.name,sourceEventTypes:r.sourceEventTypes??[e.type],sourceEventIds:r.sourceEventIds??(e.eventId?[e.eventId]:void 0),model:r.model,style:r.style}}function inventoryRepairMessage(e,t,r){return"repaired"===e?r?`${t} 选择已按 workspace inventory 修正。`:`${t} selection was repaired against the workspace inventory.`:r?`${t} 选择不在 workspace inventory 中,已被阻止。`:`${t} selection was blocked because it is outside the workspace inventory.`}function repairMessage(e,t,r){return r?"started"===t?`runtime 正在执行 ${e} repair。`:"synthesized"===t?`runtime 已通过 ${e} repair 合成可交付结果。`:"blocked"===t?`runtime 已阻止 ${e} repair 的不可靠输出。`:`runtime 已完成 ${e} repair。`:"started"===t?`Runtime is starting ${e} repair.`:"synthesized"===t?`Runtime synthesized a deliverable result through ${e} repair.`:"blocked"===t?`Runtime blocked unreliable output during ${e} repair.`:`Runtime completed ${e} repair.`}function summarizeText(e){const t=e?.replace(/\s+/gu," ").trim();return t?t.length>120?`${t.slice(0,117)}...`:t:""}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readProgressPolicy(e){const t=isRecord(e?.progress)?e.progress:{},r=isRecord(t.narration)?t.narration:{};return{enabled:"boolean"==typeof r.enabled?r.enabled:void 0,style:"string"==typeof r.style?r.style:void 0,model:"string"==typeof r.model?r.model:void 0}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RuntimeEvent, RuntimeOutput, RuntimeRequest, RuntimeStore, WorkspaceAgent } from "../../types.js";
|
|
2
|
+
export declare function recoverAdapterResultOutput(input: {
|
|
3
|
+
request: RuntimeRequest;
|
|
4
|
+
result: RuntimeOutput;
|
|
5
|
+
recoveryPolicy: unknown;
|
|
6
|
+
store: RuntimeStore;
|
|
7
|
+
emit: (event: RuntimeEvent) => void;
|
|
8
|
+
requestId: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
agent: WorkspaceAgent;
|
|
11
|
+
runAdapter: (request: RuntimeRequest) => Promise<RuntimeOutput>;
|
|
12
|
+
}): Promise<RuntimeOutput>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{assertNoRawToolCallOutput as e,assertNoToolExecutionErrorOutput as t,buildEvidenceSynthesisOutput as r,buildResultRecoveryRequest as o,containsRawToolCallOutput as l,rawToolCallFailureMessage as a,toolCallRecoveryEnabled as u}from"../../recovery/tool-call.js";export async function recoverAdapterResultOutput(s){let i=s.result,n=s.request;const c=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,r="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,o="object"!=typeof r||null===r||Array.isArray(r)?void 0:r.maxResultRecoveryAttempts;return"number"==typeof o&&Number.isInteger(o)&&o>0?o:3}(s.recoveryPolicy);let y=0;for(let e=0;e<c;e+=1){const t=s.store.getRun(s.requestId)?.events??[],r=o({request:n,output:i.text,events:t.slice(y),availableToolIds:s.agent.tools,policy:s.recoveryPolicy});if(!r)break;n=r,y=s.store.getRun(s.requestId)?.events.length??0,emitRepair(s,"runtime.repair.started","result_output",e+1,"recoverable_result_output"),i=await s.runAdapter(r),emitRepair(s,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried")}return function finalizeRecoveredOutput(o,s){if(!u(o.recoveryPolicy))return s;let i=!1;l(s.text,o.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(o.request.metadata)&&(s={...s,text:a(),metadata:{...s.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(o,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked"));const n=r({request:o.request,output:s.text,events:o.store.getRun(o.requestId)?.events??[],policy:o.recoveryPolicy});return n&&(i=!0,s={...s,text:n,metadata:{...s.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(o,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),i||(e(s.text,o.recoveryPolicy),t(s.text,o.recoveryPolicy)),s}(s,i)}function emitRepair(e,t,r,o,l,a){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:r,attempt:o,reason:l};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:a??"retried"})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{
|
|
1
|
+
import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{buildAdapterErrorRecoveryPrompt as r,buildExecutionContractRecoveryRequest as a,isRecoverableAdapterError as s}from"./recovery/tool-call.js";import{recoverQualityReview as n,resolveQualityPolicy as o}from"./quality/index.js";import{recoverAdapterResultOutput as i}from"./runtime/recovery/adapter-result.js";import{completeRun as u,failRun as c}from"./runtime/completion.js";import{runDirectToolCall as p}from"./runtime/direct-tool-call.js";import{createApprovalGatedToolGateway as d}from"./runtime/governance/approval-gate.js";import{createSandboxedToolGateway as m}from"./runtime/governance/sandbox.js";import{createRuntimeInspectionMethods as l}from"./runtime/inspection/methods.js";import{createRuntimeCapabilityRegistry as w,normalizeAdapterResult as f}from"./runtime/capabilities.js";import{createMemoryRuntimeCapability as g}from"./runtime/memory.js";import{createInMemoryRuntimeStore as I}from"./runtime/persistence/stores.js";import{createProgressNarrationCapability as y}from"./runtime/progress-narration.js";import{repairRuntimeSelection as q}from"./runtime/selection-repair.js";import{createLangSmithTracingCapability as R}from"./runtime/tracing/langsmith.js";import{createToolFailureTracker as k}from"./runtime/tool-failure.js";import{runWorkflowRequest as v}from"./workflows/runtime.js";export function createStableHarnessRuntime(t){const f=new Set,b=t.store??I(),A=w([g(t),y({options:t.progressNarration,policy:t.workspace.runtime}),R({policy:t.workspace.runtime,store:b,options:t.langSmithTracing}),...t.capabilities??[]]),emitBase=t=>{const r=function enrichRuntimeEvent(t){return{...t,eventId:t.eventId??e(),emittedAt:t.emittedAt??(new Date).toISOString()}}(t);b.appendEvent(r);for(const e of f)e(r)},emit=e=>{emitBase(e),A.emitSideEffects(e,emitBase)},C=m({gateway:d({gateway:t.toolGateway,approvals:t.approvals,workspace:t.workspace,emit:emit}),workspace:t.workspace,sandbox:t.sandbox,emit:emit}),h={...t,toolGateway:C},x=k(function readToolFailurePolicy(e){if("object"!=typeof e||null===e||Array.isArray(e))return;const t=e.failurePolicy;return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}(t.workspace.runtime.toolGateway));return{request:async t=>async function runRuntimeRequest(t){const d=t.request.requestId??e(),m=t.request.sessionId??e(),l=[],{agent:w,adapter:f}=await async function resolveExecution(e,t,r){const a=t.agentId?await async function resolveRequestedAgentId(e,t,r){if(e.agents.has(t))return t;const a=await q({id:t,candidates:[...e.agents.values()].map(e=>({id:e.id,description:e.description})),trace:{...r,agentId:t,layer:"agent",owner:"stable_runtime_policy"}});return a.ok?a.id:t}(e.workspace,t.agentId,r):function resolveRoutedAgentId(e,t){for(const r of e.runtime.routes??[])if(routeMatches(r,t))return r.agentId;return e.runtime.defaultAgentId}(e.workspace,t.input),s=e.workspace.agents.get(a);if(!s)throw new Error(`Agent ${a} is not defined in the workspace`);if(t.toolCall||t.workflow)return{agent:s,adapter:void 0};const n=e.adapters.find(e=>e.canRun(s));if(!n)throw new Error(`No runtime adapter can run backend ${s.backend} for agent ${s.id}`);return{agent:s,adapter:n}}(t.input,t.request,{requestId:d,sessionId:m,emit:e=>l.push(e)});t.store.createRun(function createRunRecord(e,t,r,a){return{requestId:t,sessionId:r,agentId:a.id,input:e.input,state:"running",parentRunId:e.parentRunId,metadata:e.metadata,artifacts:[],startedAt:(new Date).toISOString(),events:[]}}(t.request,d,m,w)),l.forEach(t.emit),t.emit({type:"runtime.request.started",requestId:d,sessionId:m,agentId:w.id,input:t.request.input});try{if(t.request.workflow){const e=await v({workspace:t.input.workspace,adapters:t.input.workflowAdapters??[],toolGateway:t.input.toolGateway,request:{input:t.request.input,...t.request.workflow},requestId:d,sessionId:m,agentId:w.id,emit:t.emit});return u({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}if(t.request.toolCall){const e=await p({gateway:t.input.toolGateway,workspace:t.input.workspace,emit:t.emit,request:t.request,requestId:d,sessionId:m,agent:w,toolFailureTracker:t.toolFailureTracker});return u({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}return await async function runAdapterRequest(e){if(!e.adapter)throw new Error(`No runtime adapter can run backend ${e.agent.backend} for agent ${e.agent.id}`);const t=e.adapter,c=await e.capabilities.beforeAdapterRun(createCapabilityContext(e)),p=c.memory,d=c.pluginMemories??[],m=e.input.workspace.runtime,l=o(e.input.workspace.runtime,e.agent),w=new Map;let f;try{f=await runAdapterOnce(e,t,e.request,p,d,w)}catch(a){if(!s(a,m))throw a;e.emit(repairStarted(e,"adapter_error",1,errorMessage(a))),f=await runAdapterOnce(e,t,r(e.request,a,m),p,d,w),e.emit(repairCompleted(e,"adapter_error","retried",1,errorMessage(a)))}f=await i({...e,request:e.request,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),e.request,f,l),await e.capabilities.beforeAdapterResultContract({...createCapabilityContext(e),result:f});try{assertRequestExecutionContract(e)}catch(r){const s=a({request:e.request,events:e.store.getRun(e.requestId)?.events??[],policy:m});if(!s)throw r;e.emit(repairStarted(e,"execution_contract",1,errorMessage(r))),f=await runAdapterOnce(e,t,s,p,d,w),f=await i({...e,request:s,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),s,f,l),assertRequestExecutionContract(e),e.emit(repairCompleted(e,"execution_contract","retried",1,errorMessage(r)))}const g=u({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,result:f,artifacts:e.input.artifacts});return await e.capabilities.afterAdapterResponse({...createCapabilityContext(e),result:f,response:g}),g}({...t,adapter:f,requestId:d,sessionId:m,agent:w})}catch(e){return c({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,error:e})}}({input:h,capabilities:A,store:b,emit:emit,request:t,toolFailureTracker:x}),subscribe:e=>(f.add(e),()=>f.delete(e)),...l({workspace:t.workspace,store:b,artifacts:t.artifacts,approvals:t.approvals,emit:emit}),cancel(e,t){const r=b.getRun(e);r&&"running"===r.state&&(b.updateRun(e,{state:"cancelled",completedAt:(new Date).toISOString()}),emit({type:"runtime.request.cancelled",requestId:e,sessionId:r.sessionId,agentId:r.agentId,reason:t}))},async stop(){await A.stop(),f.clear()}}}function createCapabilityContext(e){return{workspace:e.input.workspace,store:e.store,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent}}function createQualityRuntimeInput(e,t,r,a){return{workspace:e.input.workspace,agent:e.agent,request:e.request,requestId:e.requestId,sessionId:e.sessionId,events:e.store.getRun(e.requestId)?.events??[],emit:e.emit,getEvents:()=>e.store.getRun(e.requestId)?.events??[],runAdapter:s=>runAdapterOnce(e,e.adapter,s,t,r,a),reviewModel:e.input.qualityReviewModel,memory:t,pluginMemories:r}}function assertRequestExecutionContract(e){t({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,metadata:e.request.metadata})}async function runAdapterOnce(e,t,r,a,s,n){return f(await t.run({workspace:e.input.workspace,agent:e.agent,request:r,requestId:e.requestId,sessionId:e.sessionId,memory:a,pluginMemories:s,toolGateway:e.input.toolGateway,toolFailureTracker:e.input.toolFailureTracker,requestState:n,getEvents:()=>e.store.getRun(e.requestId)?.events??[],emit:e.emit}))}function repairStarted(e,t,r,a){return{type:"runtime.repair.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,attempt:r,reason:a}}function repairCompleted(e,t,r,a,s){return{type:"runtime.repair.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,outcome:r,attempt:a,reason:s}}function errorMessage(e){return e instanceof Error?e.message:String(e)}function routeMatches(e,t){if(e.pattern)try{if(new RegExp(e.pattern,"iu").test(t))return!0}catch{return!1}const r=t.toLowerCase();return(e.keywords??[]).some(e=>r.includes(e.toLowerCase()))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function createDelegationTraceProjection(e,t={}){return{traceType:"delegation",traceLabel:e,...t}}export function createPlanTraceProjection(e,t={}){return{traceType:"plan",traceLabel:e,...t}}export function projectRuntimeTrace(e){return e.events.map(projectEvent).filter(isTraceEntry)}export function projectRuntimeTraceSpans(e){const t=function createSpanBuilder(e){const t=`run:${e.requestId}`,r=[],o=new Map;return{ensureRoot(){if(o.has(t))return;const n={spanId:t,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,kind:"run",name:e.agentId,status:(a=e.state,"completed"===a?"completed":"failed"===a?"failed":"cancelled"===a?"blocked":"running"),startedAt:e.startedAt,completedAt:e.completedAt,startEventIndex:0,...e.parentRunId?{parentSpanId:`run:${e.parentRunId}`}:{},events:[]};var a;r.push(n),o.set(t,n)},markRoot(e,r,n,a){const i=o.get(t);i&&(addEvent(i,e,r),i.status=n,i.attributes=merge(i.attributes,a),"running"!==n&&close(i,e,r))},start(e,n,a,i,s,d){const p=createSpan(`${t}/${e}:${s}`,t,n,a,i,s,d);r.push(p),o.set(e,p)},complete(e,n,a,i){const s=o.get(e)??createSpan(`${t}/${e}:${a}`,t,"adapter",e,n,a);return o.has(e)||r.push(s),addEvent(s,n,a),s.attributes=merge(s.attributes,i),close(s,n,a),o.delete(e),s},fail(e,t,r,o){this.complete(e,t,r,o).status="failed"},event(e,o,n,a,i){const s=createSpan(`${t}/event:${a}`,t,e,o,n,a,i);s.status=function readBlockedStatus(e){return e.type.endsWith(".blocked")||e.type.includes(".approval.")?"blocked":void 0}(n)??"event",close(s,n,a),r.push(s)},closeRoot(){const r=o.get(t);r&&e.completedAt&&(r.completedAt=e.completedAt)},spans:()=>r}}(e);return t.ensureRoot(),e.events.forEach((e,r)=>function projectSpanEvent(e,t,r){return t.type.startsWith("runtime.request.")?function projectRequestSpanEvent(e,t,r){return"runtime.request.started"===t.type?e.markRoot(t,r,"running",{input:t.input}):"runtime.request.completed"===t.type?e.markRoot(t,r,"completed",{output:t.output}):"runtime.request.failed"===t.type?e.markRoot(t,r,"failed",{error:t.error}):"runtime.request.cancelled"===t.type?e.markRoot(t,r,"blocked",{reason:t.reason}):"runtime.execution.contract.failed"===t.type?projectSingleSpan(e,t,r,"quality",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):void 0}(e,t,r):"runtime.tool.direct.started"===t.type?e.start(`tool:${t.toolId}`,"tool",t.toolId,t,r,{toolId:t.toolId}):"runtime.tool.direct.completed"===t.type?e.complete(`tool:${t.toolId}`,t,r,{toolId:t.toolId,output:t.output}):"runtime.workflow.started"===t.type?e.start(`workflow:${t.workflowId}`,"workflow",t.workflowId,t,r,{workflowId:t.workflowId,adapter:t.adapter}):"runtime.workflow.completed"===t.type?e.complete(`workflow:${t.workflowId}`,t,r,{workflowId:t.workflowId,adapter:t.adapter}):t.type.startsWith("runtime.approval.")||t.type.startsWith("runtime.memory.approval.")?projectSingleSpan(e,t,r,"approval",t.type):t.type.startsWith("runtime.specDriven.phase.")?projectSingleSpan(e,t,r,"spec",function readPhaseName(e,t){return"phaseId"in e&&"string"==typeof e.phaseId?e.phaseId:t}(t,"phase")):t.type.startsWith("runtime.memory.")?projectSingleSpan(e,t,r,"memory",t.type):t.type.startsWith("runtime.quality.")?projectSingleSpan(e,t,r,"quality",t.type):"runtime.artifact.created"===t.type?projectSingleSpan(e,t,r,"artifact",t.artifact.id,{artifact:t.artifact}):"runtime.progress.narration"===t.type?projectSingleSpan(e,t,r,"progress",t.message,{provider:t.provider}):"runtime.adapter.event"===t.type?function projectAdapterSpanEvent(e,t,r){const o=isRecord(t.event)?t.event:void 0,n=readString(o?.phase)??"runtime.adapter.event",a=readTraceType(o?.traceType),i=readString(o?.traceLabel);return"delegation"===a&&i?.endsWith(".start")?e.start(delegationKey(o),"delegation",readString(o?.subagentType)??i,t,r,o):"delegation"===a&&i?.endsWith(".completed")?e.complete(delegationKey(o),t,r,o):"plan"===a&&i?projectSingleSpan(e,t,r,"plan",i,o):function isToolStartEvent(e){return"deepagents.tool_execution.start"===e?.eventType||"agent.tool.start"===e?.phase}(o)?e.start(`agent-tool:${readString(o?.toolId)??"unknown"}`,"tool",readString(o?.toolId)??n,t,r,o):function isToolResultEvent(e){return"deepagents.tool_execution.result"===e?.eventType||"agent.tool.result"===e?.phase}(o)?e.complete(`agent-tool:${readString(o?.toolId)??"unknown"}`,t,r,o):projectSingleSpan(e,t,r,"adapter",n,o)}(e,t,r):"runtime.inventory.repair"===t.type?projectSingleSpan(e,t,r,"adapter","runtime.inventory.repair",{status:t.status,...t.diagnostic}):"runtime.sandbox.decision"===t.type?projectSingleSpan(e,t,r,"tool",`sandbox:${t.toolId}`,{toolId:t.toolId,...t.decision}):"runtime.tool.failure"===t.type?e.fail(`tool:${t.toolId}`,t,r,{toolId:t.toolId,...t.failure}):"runtime.tool.circuit.opened"===t.type?projectSingleSpan(e,t,r,"tool",`circuit:${t.toolId}`,{toolId:t.toolId,reason:t.reason}):void 0}(t,e,r)),t.closeRoot(),t.spans()}export function projectEvent(e){return"runtime.request.started"===e.type||"runtime.request.completed"===e.type||"runtime.request.failed"===e.type?base(e,"request",e.type):"runtime.request.cancelled"===e.type?base(e,"request",e.type,{reason:e.reason}):"runtime.execution.contract.failed"===e.type?base(e,"request",e.type,{reason:e.reason,missingEvidenceTools:e.missingEvidenceTools}):"runtime.inventory.repair"===e.type?base(e,"adapter","runtime.inventory.repair",{status:e.status,...e.diagnostic}):"runtime.tool.direct.started"===e.type?base(e,"tool","runtime.tool.direct.started",{toolId:e.toolId}):"runtime.tool.direct.completed"===e.type?base(e,"tool","runtime.tool.direct.completed",{toolId:e.toolId}):"runtime.sandbox.decision"===e.type?base(e,"tool","runtime.sandbox.decision",{toolId:e.toolId,...e.decision}):"runtime.tool.failure"===e.type?base(e,"tool","runtime.tool.failure",{toolId:e.toolId,...e.failure}):"runtime.tool.circuit.opened"===e.type?base(e,"tool","runtime.tool.circuit.opened",{toolId:e.toolId,reason:e.reason}):"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?base(e,"workflow",e.type,{workflowId:e.workflowId,adapter:e.adapter}):function isSpecDrivenPhaseEvent(e){return e.type.startsWith("runtime.specDriven.phase.")}(e)?base(e,"spec",e.type,{phaseId:e.phaseId,..."workflowId"in e&&e.workflowId?{workflowId:e.workflowId}:{},..."reason"in e?{reason:e.reason}:{},..."artifact"in e&&e.artifact?{artifact:e.artifact}:{}}):"runtime.adapter.event"===e.type?function adapterTrace(e){const t=e.event;if(isRecord(t)&&"string"==typeof t.phase){const r=function semanticAdapterTrace(e,t){if("inventory.repair"===t.phase)return base(e,"adapter","runtime.inventory.repair",{status:t.status,...isRecord(t.diagnostic)?t.diagnostic:{}});const r=readTraceType(t.traceType),o=readString(t.traceLabel);return r&&o?base(e,r,o,t):void 0}(e,t);return r||base(e,"adapter",t.phase.startsWith("agent.")?t.phase:`adapter.${t.phase}`,t)}return base(e,"adapter","runtime.adapter.event",{event:t})}(e):"runtime.artifact.created"===e.type?base(e,"artifact","runtime.artifact.created",{artifact:e.artifact}):e.type.startsWith("runtime.memory.")?base(e,"memory",e.type):"runtime.progress.narration"===e.type?base(e,"progress",e.type,{message:e.message,provider:e.provider,sourceEventTypes:e.sourceEventTypes}):void 0}export function readPlanTodos(e){const t=function readPlanRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e),r=function readTodosArray(e){const t=isRecord(e?.args)?e.args:void 0;return Array.isArray(e?.todos)?e.todos:Array.isArray(t?.todos)?t.todos:[]}(t);return r.map(readTodo).filter(isPlanTodoItem)}function readTodo(e){if(isRecord(e)&&"string"==typeof e.content)return{content:e.content,status:"string"==typeof e.status?e.status:"pending"}}function isPlanTodoItem(e){return void 0!==e}function base(e,t,r,o){return{type:t,label:r,agentId:e.agentId,requestId:e.requestId,detail:o}}function isTraceEntry(e){return void 0!==e}function projectSingleSpan(e,t,r,o,n,a){return e.event(o,n,t,r,a)}function delegationKey(e){return`delegation:${readString(e?.subagentType)??readString(e?.toolId)??"task"}`}function createSpan(e,t,r,o,n,a,i){const s={spanId:e,parentSpanId:t,requestId:n.requestId,sessionId:n.sessionId,agentId:n.agentId,kind:r,name:o,status:"running",startedAt:n.emittedAt,startEventIndex:a,attributes:i,events:[]};return addEvent(s,n,a),s}function addEvent(e,t,r){e.events.push({index:r,eventId:t.eventId??`${t.requestId}:${r}`,type:t.type,emittedAt:t.emittedAt})}function close(e,t,r){e.status="failed"===e.status||"blocked"===e.status?e.status:"completed",e.completedAt=t.emittedAt,e.endEventIndex=r,e.durationMs=function durationMs(e,t){if(!e||!t)return;const r=Date.parse(t)-Date.parse(e);return Number.isFinite(r)&&r>=0?r:void 0}(e.startedAt,e.completedAt)}function merge(e,t){return t?{...e,...t}:e}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readTraceType(e){const t=readString(e);return"request"===t||"tool"===t||"workflow"===t||"spec"===t||"adapter"===t||"memory"===t||"artifact"===t||"progress"===t||"plan"===t||"delegation"===t?t:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
|
|
1
|
+
export function createDelegationTraceProjection(e,t={}){return{traceType:"delegation",traceLabel:e,...t}}export function createPlanTraceProjection(e,t={}){return{traceType:"plan",traceLabel:e,...t}}export function projectRuntimeTrace(e){return e.events.map(projectEvent).filter(isTraceEntry)}export function projectRuntimeTraceSpans(e){const t=function createSpanBuilder(e){const t=`run:${e.requestId}`,r=[],o=new Map;return{ensureRoot(){if(o.has(t))return;const n={spanId:t,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,kind:"run",name:e.agentId,status:(a=e.state,"completed"===a?"completed":"failed"===a?"failed":"cancelled"===a?"blocked":"running"),startedAt:e.startedAt,completedAt:e.completedAt,startEventIndex:0,...e.parentRunId?{parentSpanId:`run:${e.parentRunId}`}:{},events:[]};var a;r.push(n),o.set(t,n)},markRoot(e,r,n,a){const i=o.get(t);i&&(addEvent(i,e,r),i.status=n,i.attributes=merge(i.attributes,a),"running"!==n&&close(i,e,r))},start(e,n,a,i,s,d){const p=createSpan(`${t}/${e}:${s}`,t,n,a,i,s,d);r.push(p),o.set(e,p)},complete(e,n,a,i){const s=o.get(e)??createSpan(`${t}/${e}:${a}`,t,"adapter",e,n,a);return o.has(e)||r.push(s),addEvent(s,n,a),s.attributes=merge(s.attributes,i),close(s,n,a),o.delete(e),s},fail(e,t,r,o){this.complete(e,t,r,o).status="failed"},event(e,o,n,a,i){const s=createSpan(`${t}/event:${a}`,t,e,o,n,a,i);s.status=function readBlockedStatus(e){return e.type.endsWith(".blocked")||e.type.includes(".approval.")?"blocked":void 0}(n)??"event",close(s,n,a),r.push(s)},closeRoot(){const r=o.get(t);r&&e.completedAt&&(r.completedAt=e.completedAt)},spans:()=>r}}(e);return t.ensureRoot(),e.events.forEach((e,r)=>function projectSpanEvent(e,t,r){return t.type.startsWith("runtime.request.")?function projectRequestSpanEvent(e,t,r){return"runtime.request.started"===t.type?e.markRoot(t,r,"running",{input:t.input}):"runtime.request.completed"===t.type?e.markRoot(t,r,"completed",{output:t.output}):"runtime.request.failed"===t.type?e.markRoot(t,r,"failed",{error:t.error}):"runtime.request.cancelled"===t.type?e.markRoot(t,r,"blocked",{reason:t.reason}):"runtime.execution.contract.failed"===t.type?projectSingleSpan(e,t,r,"quality",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):void 0}(e,t,r):"runtime.tool.direct.started"===t.type?e.start(`tool:${t.toolId}`,"tool",t.toolId,t,r,{toolId:t.toolId}):"runtime.tool.direct.completed"===t.type?e.complete(`tool:${t.toolId}`,t,r,{toolId:t.toolId,output:t.output}):"runtime.workflow.started"===t.type?e.start(`workflow:${t.workflowId}`,"workflow",t.workflowId,t,r,{workflowId:t.workflowId,adapter:t.adapter}):"runtime.workflow.completed"===t.type?e.complete(`workflow:${t.workflowId}`,t,r,{workflowId:t.workflowId,adapter:t.adapter}):t.type.startsWith("runtime.approval.")||t.type.startsWith("runtime.memory.approval.")?projectSingleSpan(e,t,r,"approval",t.type):t.type.startsWith("runtime.specDriven.phase.")?projectSingleSpan(e,t,r,"spec",function readPhaseName(e,t){return"phaseId"in e&&"string"==typeof e.phaseId?e.phaseId:t}(t,"phase")):t.type.startsWith("runtime.memory.")?projectSingleSpan(e,t,r,"memory",t.type):t.type.startsWith("runtime.quality.")?projectSingleSpan(e,t,r,"quality",t.type):t.type.startsWith("runtime.repair.")?projectSingleSpan(e,t,r,"adapter",t.type):"runtime.artifact.created"===t.type?projectSingleSpan(e,t,r,"artifact",t.artifact.id,{artifact:t.artifact}):"runtime.progress.narration"===t.type?projectSingleSpan(e,t,r,"progress",t.message,{provider:t.provider}):"runtime.adapter.event"===t.type?function projectAdapterSpanEvent(e,t,r){const o=isRecord(t.event)?t.event:void 0,n=readString(o?.phase)??"runtime.adapter.event",a=readTraceType(o?.traceType),i=readString(o?.traceLabel);return"delegation"===a&&i?.endsWith(".start")?e.start(delegationKey(o),"delegation",readString(o?.subagentType)??i,t,r,o):"delegation"===a&&i?.endsWith(".completed")?e.complete(delegationKey(o),t,r,o):"plan"===a&&i?projectSingleSpan(e,t,r,"plan",i,o):function isToolStartEvent(e){return"deepagents.tool_execution.start"===e?.eventType||"agent.tool.start"===e?.phase}(o)?e.start(`agent-tool:${readString(o?.toolId)??"unknown"}`,"tool",readString(o?.toolId)??n,t,r,o):function isToolResultEvent(e){return"deepagents.tool_execution.result"===e?.eventType||"agent.tool.result"===e?.phase}(o)?e.complete(`agent-tool:${readString(o?.toolId)??"unknown"}`,t,r,o):projectSingleSpan(e,t,r,"adapter",n,o)}(e,t,r):"runtime.inventory.repair"===t.type?projectSingleSpan(e,t,r,"adapter","runtime.inventory.repair",{status:t.status,...t.diagnostic}):"runtime.sandbox.decision"===t.type?projectSingleSpan(e,t,r,"tool",`sandbox:${t.toolId}`,{toolId:t.toolId,...t.decision}):"runtime.tool.failure"===t.type?e.fail(`tool:${t.toolId}`,t,r,{toolId:t.toolId,...t.failure}):"runtime.tool.circuit.opened"===t.type?projectSingleSpan(e,t,r,"tool",`circuit:${t.toolId}`,{toolId:t.toolId,reason:t.reason}):void 0}(t,e,r)),t.closeRoot(),t.spans()}export function projectEvent(e){return"runtime.request.started"===e.type||"runtime.request.completed"===e.type||"runtime.request.failed"===e.type?base(e,"request",e.type):"runtime.request.cancelled"===e.type?base(e,"request",e.type,{reason:e.reason}):"runtime.execution.contract.failed"===e.type?base(e,"request",e.type,{reason:e.reason,missingEvidenceTools:e.missingEvidenceTools}):"runtime.inventory.repair"===e.type?base(e,"adapter","runtime.inventory.repair",{status:e.status,...e.diagnostic}):"runtime.repair.started"===e.type||"runtime.repair.completed"===e.type?base(e,"adapter",e.type,{layer:e.layer,..."outcome"in e?{outcome:e.outcome}:{},..."attempt"in e?{attempt:e.attempt}:{},..."reason"in e?{reason:e.reason}:{}}):"runtime.tool.direct.started"===e.type?base(e,"tool","runtime.tool.direct.started",{toolId:e.toolId}):"runtime.tool.direct.completed"===e.type?base(e,"tool","runtime.tool.direct.completed",{toolId:e.toolId}):"runtime.sandbox.decision"===e.type?base(e,"tool","runtime.sandbox.decision",{toolId:e.toolId,...e.decision}):"runtime.tool.failure"===e.type?base(e,"tool","runtime.tool.failure",{toolId:e.toolId,...e.failure}):"runtime.tool.circuit.opened"===e.type?base(e,"tool","runtime.tool.circuit.opened",{toolId:e.toolId,reason:e.reason}):"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?base(e,"workflow",e.type,{workflowId:e.workflowId,adapter:e.adapter}):function isSpecDrivenPhaseEvent(e){return e.type.startsWith("runtime.specDriven.phase.")}(e)?base(e,"spec",e.type,{phaseId:e.phaseId,..."workflowId"in e&&e.workflowId?{workflowId:e.workflowId}:{},..."reason"in e?{reason:e.reason}:{},..."artifact"in e&&e.artifact?{artifact:e.artifact}:{}}):"runtime.adapter.event"===e.type?function adapterTrace(e){const t=e.event;if(isRecord(t)&&"string"==typeof t.phase){const r=function semanticAdapterTrace(e,t){if("inventory.repair"===t.phase)return base(e,"adapter","runtime.inventory.repair",{status:t.status,...isRecord(t.diagnostic)?t.diagnostic:{}});const r=readTraceType(t.traceType),o=readString(t.traceLabel);return r&&o?base(e,r,o,t):void 0}(e,t);return r||base(e,"adapter",t.phase.startsWith("agent.")?t.phase:`adapter.${t.phase}`,t)}return base(e,"adapter","runtime.adapter.event",{event:t})}(e):"runtime.artifact.created"===e.type?base(e,"artifact","runtime.artifact.created",{artifact:e.artifact}):e.type.startsWith("runtime.memory.")?base(e,"memory",e.type):"runtime.progress.narration"===e.type?base(e,"progress",e.type,{message:e.message,provider:e.provider,sourceEventTypes:e.sourceEventTypes}):void 0}export function readPlanTodos(e){const t=function readPlanRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e),r=function readTodosArray(e){const t=isRecord(e?.args)?e.args:void 0;return Array.isArray(e?.todos)?e.todos:Array.isArray(t?.todos)?t.todos:[]}(t);return r.map(readTodo).filter(isPlanTodoItem)}function readTodo(e){if(isRecord(e)&&"string"==typeof e.content)return{content:e.content,status:"string"==typeof e.status?e.status:"pending"}}function isPlanTodoItem(e){return void 0!==e}function base(e,t,r,o){return{type:t,label:r,agentId:e.agentId,requestId:e.requestId,detail:o}}function isTraceEntry(e){return void 0!==e}function projectSingleSpan(e,t,r,o,n,a){return e.event(o,n,t,r,a)}function delegationKey(e){return`delegation:${readString(e?.subagentType)??readString(e?.toolId)??"task"}`}function createSpan(e,t,r,o,n,a,i){const s={spanId:e,parentSpanId:t,requestId:n.requestId,sessionId:n.sessionId,agentId:n.agentId,kind:r,name:o,status:"running",startedAt:n.emittedAt,startEventIndex:a,attributes:i,events:[]};return addEvent(s,n,a),s}function addEvent(e,t,r){e.events.push({index:r,eventId:t.eventId??`${t.requestId}:${r}`,type:t.type,emittedAt:t.emittedAt})}function close(e,t,r){e.status="failed"===e.status||"blocked"===e.status?e.status:"completed",e.completedAt=t.emittedAt,e.endEventIndex=r,e.durationMs=function durationMs(e,t){if(!e||!t)return;const r=Date.parse(t)-Date.parse(e);return Number.isFinite(r)&&r>=0?r:void 0}(e.startedAt,e.completedAt)}function merge(e,t){return t?{...e,...t}:e}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readTraceType(e){const t=readString(e);return"request"===t||"tool"===t||"workflow"===t||"spec"===t||"adapter"===t||"memory"===t||"artifact"===t||"progress"===t||"plan"===t||"delegation"===t?t:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
|
package/package.json
CHANGED
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
|
-
import{realpathSync as e}from"node:fs";import{fileURLToPath as t}from"node:url";import{createBackendModel as r,createDeepAgentsAdapter as o}from"@stable-harness/adapter-deepagents";import{createLangGraphWorkflowAdapter as s}from"@stable-harness/adapter-langgraph";import{createStableHarnessRuntime as a}from"@stable-harness/core";import{projectEvent as i,projectRuntimeTrace as n}from"@stable-harness/core";import{createInMemoryApprovalQueue as u}from"@stable-harness/governance";import{createModuleToolGateway as d}from"@stable-harness/tool-gateway";import{loadWorkspaceFromYaml as l}from"@stable-harness/workspace-yaml";import{helpText as p,parseArgs as c}from"./args.js";import{buildWorkspaceArtifact as
|
|
2
|
+
import{realpathSync as e}from"node:fs";import{fileURLToPath as t}from"node:url";import{createBackendModel as r,createDeepAgentsAdapter as o}from"@stable-harness/adapter-deepagents";import{createLangGraphWorkflowAdapter as s}from"@stable-harness/adapter-langgraph";import{createStableHarnessRuntime as a}from"@stable-harness/core";import{projectEvent as i,projectRuntimeTrace as n}from"@stable-harness/core";import{createInMemoryApprovalQueue as u}from"@stable-harness/governance";import{createModuleToolGateway as d}from"@stable-harness/tool-gateway";import{loadWorkspaceFromYaml as l}from"@stable-harness/workspace-yaml";import{helpText as p,parseArgs as c}from"./args.js";import{buildWorkspaceArtifact as m}from"./build.js";import{formatCliRuntimeEvent as f,readCliEventViewConfig as w,shouldEnableCliProgressNarration as v}from"./event-view.js";import{initWorkspace as g}from"./init.js";import{ensureCliMemoryServices as y}from"./memory/lifecycle.js";import{createCliMemoryProviders as I}from"./memory/providers.js";import{formatDetail as k,inspectWorkflow as R,renderAgent as h,renderWorkflow as b,workspaceStatus as q}from"./output.js";import{serveProtocol as A,stopProtocol as C}from"./server.js";export async function runCli(e=process.argv.slice(2)){const t=c(e);if(t.help)return void process.stdout.write(p());const r=setTimeout(()=>{process.stderr.write(`stable-harness request timed out after ${t.timeoutMs}ms\n`),process.exit(124)},t.timeoutMs),s=t.workspaceRoot;try{if("init"===t.command)return void process.stdout.write(await g(t.prompt||s));const e=await l(s);if(t.workflowRenderId)return void process.stdout.write(b(e,t.workflowRenderId));if(t.workflowInspectId)return void process.stdout.write(R(e,t.workflowInspectId));if(t.agentRenderId)return void process.stdout.write(h(e,t.agentRenderId));if("build"===t.command)return void process.stdout.write(await m({workspace:e,workspaceRoot:s,outputDir:t.buildOutput,target:t.buildTarget}));if("stop"===t.command)return clearTimeout(r),void await C(e,t);const p=await d({tools:e.tools.values(),options:{betterCall:{mode:"repair"}}}),c=u(),M=w(e.runtime),j=await async function createCliMemoryProvidersForCommand(e,t){return t.serveOpenAi||t.shouldRunRequest&&!t.toolId?(await y(e),I(e)):[]}(e,t);let $;if($=a({workspace:e,toolGateway:p,approvals:c,memoryProviders:j,adapters:[o()],workflowAdapters:[createCliWorkflowAdapter(p,()=>$)],progressNarration:v(M,e.runtime)?{enabled:!0,style:"cli"}:void 0,qualityReviewModel:createQualityReviewModel(e)}),t.serveOpenAi)return clearTimeout(r),void await A($,t);if(!t.shouldRunRequest)return void process.stdout.write(q(e,s));t.trace&&$.subscribe(e=>{const t=i(e);t&&process.stdout.write(`trace:${t.agentId}:${t.label}${k(t.detail)}\n`)}),$.subscribe(e=>{const t=f(e,M);t&&process.stdout.write(`${t}\n`)});const S=await $.request({input:t.prompt,agentId:t.agentId,sessionId:t.sessionId,toolCall:t.toolId?{toolId:t.toolId,args:t.toolArgs}:void 0,workflow:t.workflowRunId?{workflowId:t.workflowRunId,input:t.prompt}:void 0});if(t.trace||t.traceJson){const e=$.getRun(S.requestId),r=e?n(e):[];t.traceJson&&process.stdout.write(`${JSON.stringify({trace:r})}\n`)}process.stdout.write(`${S.output}\n`)}finally{clearTimeout(r)}}function createQualityReviewModel(e){const t=function readQualityModelRef(e){const t=isRecord(e)?e:{},r=isRecord(t.reviewer)?t.reviewer:t;return"string"==typeof r.modelRef&&r.modelRef.trim()?r.modelRef.trim():void 0}(e.runtime.quality),o=t?e.models.get(t):void 0,s=o?r(o):void 0;return function isQualityReviewModel(e){return isRecord(e)&&"function"==typeof e.invoke}(s)?s:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function createCliWorkflowAdapter(e,t){return s({nodeResolvers:{tools:async({id:t,node:r,request:o,requestId:s,sessionId:a,state:i,workspace:n})=>{return(await e.invoke({toolId:t,args:(u=r.config,d=o.input,l=i.outputs,!0===u?.inputFromState?{...u,requestInput:d,outputs:l}:u&&"requiredInput"in u?u.requiredInput:u&&("args"in u||"cwd"in u||"timeoutMs"in u)?u:"object"==typeof d&&null!==d?d:{}),context:{workspaceRoot:n.root,requestId:s,sessionId:a,agentId:`workflow:${r.id}`,approvalIds:readApprovalIds(o.metadata)}})).output;var u,d,l},agents:async({id:e,node:r,request:o,sessionId:s,state:a})=>{var i,n,u,d;return(await t().request({input:(i=e,n=o.input,u=a.outputs,d=r.config,[`Workflow node agents.${i}: synthesize the workflow evidence into the requested final output.`,`Original request: ${"string"==typeof n?n:JSON.stringify(n)}`,"Requirements:","- Produce the final answer now; do not ask follow-up questions.","- Match the original request language unless workflow config explicitly says otherwise.","- Use only the workflow outputs as evidence; call out uncertainty directly.",...d?[`Workflow node config: ${JSON.stringify(d)}`]:[],"Prior workflow outputs:",JSON.stringify(u)].join("\n")),agentId:e,sessionId:s,metadata:o.metadata})).output}}})}function readApprovalIds(e){const t=e?.approvalIds??e?.approvalId;return"string"==typeof t&&t.trim()?[t.trim()]:Array.isArray(t)?t.filter(e=>"string"==typeof e&&e.trim().length>0):void 0}(function isCliEntrypoint(){const r=process.argv[1];if(!r)return!1;try{return e(t(import.meta.url))===e(r)}catch{return!1}})()&&runCli().catch(e=>{process.stderr.write(`${e instanceof Error?e.message:String(e)}\n`),process.exitCode=1});
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function readCliEventViewConfig(e){const t=readRecord(e.cli),r=readRecord(t?.events);return{enabled:readBoolean(r?.enabled)??!0,include:readStringList(r?.include)??["runtime.progress.narration"],exclude:readStringList(r?.exclude)??[]}}export function shouldEnableCliProgressNarration(e,t){if(!e.enabled)return!1;const r=readRecord(readRecord(t.progress)?.narration);return!1!==readBoolean(r?.enabled)&&e.include.some(e=>matchesEventPattern("runtime.progress.narration",e))}export function formatCliRuntimeEvent(e,t){if(!t.enabled||!function isIncluded(e,t){const r=function eventKeys(e){return"runtime.adapter.event"===e.type&&isRecord(e.event)&&"string"==typeof e.event.phase?[e.type,e.event.phase]:[e.type]}(e),n=t.include.some(e=>r.some(t=>matchesEventPattern(t,e))),i=t.exclude.some(e=>r.some(t=>matchesEventPattern(t,e)));return n&&!i}(e,t))return;const r=function projectCliEventView(e){return"runtime.progress.narration"===e.type?{group:"Progress",title:e.message}:e.type.startsWith("runtime.request.")?{group:"Run",title:e.type}:"runtime.tool.direct.started"===e.type||"runtime.tool.direct.completed"===e.type?{group:"Tool",title:e.type,detail:e.toolId}:"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?{group:"Workflow",title:e.type,detail:e.workflowId}:"runtime.approval.requested"===e.type||"runtime.approval.resolved"===e.type?{group:"Approval",title:e.type,detail:`${e.approval.kind}:${e.approval.status}`}:e.type.startsWith("runtime.memory.")?{group:"Memory",title:e.type,detail:memoryDetail(e)}:"runtime.skill.candidate.created"===e.type?{group:"Skill",title:e.type,detail:e.name}:"runtime.artifact.created"===e.type?{group:"Artifact",title:e.type}:"runtime.execution.contract.failed"===e.type?{group:"Contract",title:e.type,detail:e.reason}:"runtime.adapter.event"===e.type?function adapterEventView(e){if(!isRecord(e))return{group:"Adapter",title:"runtime.adapter.event"};const t="string"==typeof e.phase?e.phase:"runtime.adapter.event";return t.startsWith("agent.tool.")?{group:"Agent Tool",title:t,detail:readString(e.toolId)}:t.startsWith("agent.output.")?{group:"Agent Output",title:t,detail:readString(e.text)}:t.startsWith("agent.")?{group:"Agent",title:t,detail:readString(e.adapter)}:{group:"Adapter",title:t,detail:readString(e.adapter)}}(e.event):{group:"event",title:e.type}}(e);return`[${r.group}] ${e.agentId} | ${r.title}${r.detail?` | ${r.detail}`:""}`}function matchesEventPattern(e,t){return"*"===t||(t.endsWith(".*")?e===t.slice(0,-2)||e.startsWith(t.slice(0,-1)):e===t)}function memoryDetail(e){return"runtime.memory.recall.completed"===e.type?`${e.recordIds.length} records`:"provider"in e?e.provider:"target"in e?e.target:void 0}function readRecord(e){return isRecord(e)?e:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringList(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.trim().length>0):void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
|
|
1
|
+
export function readCliEventViewConfig(e){const t=readRecord(e.cli),r=readRecord(t?.events);return{enabled:readBoolean(r?.enabled)??!0,include:readStringList(r?.include)??["runtime.progress.narration"],exclude:readStringList(r?.exclude)??[]}}export function shouldEnableCliProgressNarration(e,t){if(!e.enabled)return!1;const r=readRecord(readRecord(t.progress)?.narration);return!1!==readBoolean(r?.enabled)&&e.include.some(e=>matchesEventPattern("runtime.progress.narration",e))}export function formatCliRuntimeEvent(e,t){if(!t.enabled||!function isIncluded(e,t){const r=function eventKeys(e){return"runtime.adapter.event"===e.type&&isRecord(e.event)&&"string"==typeof e.event.phase?[e.type,e.event.phase]:[e.type]}(e),n=t.include.some(e=>r.some(t=>matchesEventPattern(t,e))),i=t.exclude.some(e=>r.some(t=>matchesEventPattern(t,e)));return n&&!i}(e,t))return;const r=function projectCliEventView(e){return"runtime.progress.narration"===e.type?{group:"Progress",title:e.message}:e.type.startsWith("runtime.request.")?{group:"Run",title:e.type}:"runtime.tool.direct.started"===e.type||"runtime.tool.direct.completed"===e.type?{group:"Tool",title:e.type,detail:e.toolId}:"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?{group:"Workflow",title:e.type,detail:e.workflowId}:"runtime.approval.requested"===e.type||"runtime.approval.resolved"===e.type?{group:"Approval",title:e.type,detail:`${e.approval.kind}:${e.approval.status}`}:e.type.startsWith("runtime.memory.")?{group:"Memory",title:e.type,detail:memoryDetail(e)}:"runtime.skill.candidate.created"===e.type?{group:"Skill",title:e.type,detail:e.name}:"runtime.artifact.created"===e.type?{group:"Artifact",title:e.type}:"runtime.execution.contract.failed"===e.type?{group:"Contract",title:e.type,detail:e.reason}:"runtime.repair.started"===e.type?{group:"Repair",title:e.type,detail:`${e.layer}${e.attempt?`#${e.attempt}`:""}`}:"runtime.repair.completed"===e.type?{group:"Repair",title:e.type,detail:`${e.layer}:${e.outcome}`}:"runtime.adapter.event"===e.type?function adapterEventView(e){if(!isRecord(e))return{group:"Adapter",title:"runtime.adapter.event"};const t="string"==typeof e.phase?e.phase:"runtime.adapter.event";return t.startsWith("agent.tool.")?{group:"Agent Tool",title:t,detail:readString(e.toolId)}:t.startsWith("agent.output.")?{group:"Agent Output",title:t,detail:readString(e.text)}:t.startsWith("agent.")?{group:"Agent",title:t,detail:readString(e.adapter)}:{group:"Adapter",title:t,detail:readString(e.adapter)}}(e.event):{group:"event",title:e.type}}(e);return`[${r.group}] ${e.agentId} | ${r.title}${r.detail?` | ${r.detail}`:""}`}function matchesEventPattern(e,t){return"*"===t||(t.endsWith(".*")?e===t.slice(0,-2)||e.startsWith(t.slice(0,-1)):e===t)}function memoryDetail(e){return"runtime.memory.recall.completed"===e.type?`${e.recordIds.length} records`:"provider"in e?e.provider:"target"in e?e.target:void 0}function readRecord(e){return isRecord(e)?e:void 0}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readBoolean(e){return"boolean"==typeof e?e:void 0}function readStringList(e){return Array.isArray(e)?e.filter(e=>"string"==typeof e&&e.trim().length>0):void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{mkdir as e,writeFile as o}from"node:fs/promises";import a from"node:path";export async function initWorkspace(o){const
|
|
1
|
+
import{mkdir as e,writeFile as o}from"node:fs/promises";import a from"node:path";export async function initWorkspace(o){const r=a.resolve(o||".");return await e(a.join(r,"config","agents"),{recursive:!0}),await e(a.join(r,"config","catalogs"),{recursive:!0}),await e(a.join(r,"config","memory"),{recursive:!0}),await e(a.join(r,"config","runtime"),{recursive:!0}),await e(a.join(r,"resources","tools"),{recursive:!0}),await Promise.all([writeScaffoldFile(a.join(r,"config","runtime","workspace.yaml"),["apiVersion: stable-harness.dev/v1","kind: Runtime","metadata:"," name: app-runtime","spec:"," routing:"," defaultAgentId: orchestra"," protocols:"," inProcess: true"," openaiCompatible:"," host: 127.0.0.1"," port: 8642"," memory:"," enabled: true"," LangMem:"," read: true"," write: true"," refs:"," - workspace",""].join("\n")),writeScaffoldFile(a.join(r,"config","agents","orchestra.yaml"),["apiVersion: stable-harness.dev/v1","kind: Agent","metadata:"," name: orchestra","spec:"," backend: deepagents"," modelRef: local-dev"," systemPrompt: You are a concise workspace agent."," tools:"," - echo_tool"," subagents: []",""].join("\n")),writeScaffoldFile(a.join(r,"config","catalogs","models.yaml"),["apiVersion: stable-harness.dev/v1","kind: Model","metadata:"," name: local-dev","spec:"," provider: openai-compatible"," model: ${env:STABLE_HARNESS_MODEL:-gpt-4.1-mini}"," baseUrl: ${env:STABLE_HARNESS_OPENAI_BASE_URL:-https://api.openai.com/v1}"," apiKey: ${env:OPENAI_API_KEY}",""].join("\n")),writeScaffoldFile(a.join(r,"config","memory","workspace.yaml"),["apiVersion: stable-harness.dev/v1","kind: Memory","metadata:"," name: workspace"," description: Workspace-level long-term memory managed by LangMem.","spec:"," provider: langmem"," profile: workspace"," enabled: true"," mode: background"," prompts:"," semantic: Remember durable workspace facts, architecture decisions, validation commands, and project constraints."," episodic: Remember important workspace events, validation results, incidents, migrations, and fixes."," procedural: Remember reusable operating procedures, recovery steps, release steps, and engineering rules.",""].join("\n")),writeScaffoldFile(a.join(r,"resources","tools","echo_tool.mjs"),["export const echo_tool = {"," description: 'Echo input through the Stable Harness tool gateway.',"," schema: {"," type: 'object',"," properties: { value: { type: 'string' } },"," required: ['value'],"," },"," async invoke(args) {"," return JSON.stringify({ echoed: args.value });"," },","};",""].join("\n"))]),[`Initialized Stable Harness workspace at ${r}`,"","Try:",` stable-harness -w ${shellPath(r)}`,` stable-harness -w ${shellPath(r)} --agent orchestra --tool echo_tool --tool-args-json '{"value":"hello"}'`,""].join("\n")}async function writeScaffoldFile(e,a){try{await o(e,a,{flag:"wx"})}catch(o){if(function isFileExists(e){return e instanceof Error&&"code"in e&&"EEXIST"===e.code}(o))throw new Error(`Refusing to overwrite existing scaffold file: ${e}`);throw o}}function shellPath(e){return JSON.stringify(e)}
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export declare const DEFAULT_LANGMEM_BASE_URL = "http://127.0.0.1:8878";
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
export const DEFAULT_LANGMEM_BASE_URL="http://127.0.0.1:8878";
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{spawn as e}from"node:child_process";import{existsSync as r}from"node:fs";import t from"node:path";import{fileURLToPath as n}from"node:url";export async function ensureCliMemoryServices(r){const t=function readLangMemServiceConfig(e){const r=readRecord(e.runtime.memory?.LangMem)??readRecord(e.runtime.memory?.langmem);if(!function shouldAutoStart(e,r){return!1!==(e.runtime.memory??{}).enabled&&!1!==r?.enabled&&(!1!==r?.read||!1!==r?.write)&&[...e.memories.values()].some(e=>e.enabled&&"langmem"===e.provider)}(e,r))return;const t=readString(r?.baseUrl)??readString(r?.url)??process.env.STABLE_HARNESS_LANGMEM_URL;
|
|
1
|
+
import{spawn as e}from"node:child_process";import{existsSync as r}from"node:fs";import t from"node:path";import{fileURLToPath as n}from"node:url";import{DEFAULT_LANGMEM_BASE_URL as o}from"./defaults.js";export async function ensureCliMemoryServices(r){const t=function readLangMemServiceConfig(e){const r=readRecord(e.runtime.memory?.LangMem)??readRecord(e.runtime.memory?.langmem);if(!function shouldAutoStart(e,r){return!1!==(e.runtime.memory??{}).enabled&&!1!==r?.enabled&&(!1!==r?.read||!1!==r?.write)&&[...e.memories.values()].some(e=>e.enabled&&"langmem"===e.provider)}(e,r))return;const t=readString(r?.baseUrl)??readString(r?.url)??process.env.STABLE_HARNESS_LANGMEM_URL??o;return{baseUrl:t,autoStart:!1!==r?.autoStart,command:readString(r?.command)??"python3",args:(n=r?.args,(Array.isArray(n)?n.filter(e=>"string"==typeof e&&e.trim().length>0):void 0)??["-m","stable_harness_langmem_service"]),env:{...defaultLangMemEnv(e,t),...readStringRecord(r?.env)}};var n}(r);if(!t||!t.autoStart||!function isLocalBaseUrl(e){const r=new URL(e);return["localhost","127.0.0.1","::1"].includes(r.hostname)}(t.baseUrl)||await isHealthy(t.baseUrl))return;const n=e(t.command,t.args,{cwd:r.root,detached:!0,env:{...process.env,...t.env},stdio:"ignore"});n.unref(),await async function waitForStartedService(e,r){await Promise.race([waitForHealth(r.baseUrl),new Promise((r,t)=>e.once("error",t)),new Promise((t,n)=>{e.once("exit",(e,t)=>{n(new Error(`LangMem service exited before becoming healthy: ${r.command} code=${e??"null"} signal=${t??"null"}`))})})])}(n,t)}function defaultLangMemEnv(e,o){const a=new URL(o),i=readString(e.runtime.dataRoot)??".stable-harness",s=t.resolve(function packageRoot(){return t.resolve(t.dirname(n(import.meta.url)),"../../../../..")}(),"services/langmem-python/src");return{HOST:"localhost"===a.hostname?"127.0.0.1":a.hostname,PORT:a.port||("https:"===a.protocol?"443":"80"),LANGMEM_SQLITE_PATH:t.join(t.resolve(e.root,i),"memory/langmem/langmem.sqlite"),...r(s)?{PYTHONPATH:mergePythonPath(s)}:{}}}async function waitForHealth(e){for(let r=0;r<60;r+=1){if(await isHealthy(e))return;await new Promise(e=>setTimeout(e,500))}throw new Error(`LangMem service did not become healthy at ${e}`)}async function isHealthy(e){try{const r=await fetch(`${e.replace(/\/+$/u,"")}/health`,{signal:AbortSignal.timeout(1e3)}),t=await r.json();return r.ok&&!0===t.ok}catch{return!1}}function mergePythonPath(e){return process.env.PYTHONPATH?`${e}${t.delimiter}${process.env.PYTHONPATH}`:e}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function readString(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function readStringRecord(e){const r=readRecord(e);return Object.fromEntries(Object.entries(r??{}).filter(e=>"string"==typeof e[1]))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{createLangMemServiceProvider as e}from"@stable-harness/memory";export function createCliMemoryProviders(
|
|
1
|
+
import{createLangMemServiceProvider as e}from"@stable-harness/memory";import{DEFAULT_LANGMEM_BASE_URL as r}from"./defaults.js";export function createCliMemoryProviders(o){const d=readRecord(o.runtime.memory?.LangMem)??readRecord(o.runtime.memory?.langmem);if(!function shouldEnableLangMemProvider(e,r){return!1!==(e.runtime.memory??{}).enabled&&!1!==r?.enabled&&(!1!==r?.read||!1!==r?.write)&&[...e.memories.values()].some(e=>e.enabled&&"langmem"===e.provider)}(o,d))return[];const a=readString(d?.baseUrl)??readString(d?.url)??process.env.STABLE_HARNESS_LANGMEM_URL??r;return[e({baseUrl:a,timeoutMs:(n=d?.timeoutMs,("number"==typeof n&&Number.isFinite(n)?n:void 0)??readEnvNumber("STABLE_HARNESS_LANGMEM_TIMEOUT_MS")),config:readProviderConfig(d)})];var n}function readProviderConfig(e){return{provider:"langmem-service",...readRecord(e?.mode)?{mode:readRecord(e?.mode)}:{},...readRecord(e?.types)?{types:readRecord(e?.types)}:{},...readRecord(e?.approval)?{approval:readRecord(e?.approval)}:{},...readRecord(e?.defaults)?{defaults:readRecord(e?.defaults)}:{}}}function readRecord(e){return"object"!=typeof e||null===e||Array.isArray(e)?void 0:e}function readString(e){return"string"==typeof e&&e.trim()?e.trim():void 0}function readEnvNumber(e){const r=process.env[e];return r?Number(r):void 0}
|
|
@@ -15,6 +15,9 @@ export declare function runMemoryPlugins(input: {
|
|
|
15
15
|
}): Promise<void>;
|
|
16
16
|
export declare function recallMemoryPlugins(input: {
|
|
17
17
|
providers: MemoryProvider[] | undefined;
|
|
18
|
+
emit?: RuntimeEmit;
|
|
19
|
+
requestId?: string;
|
|
20
|
+
sessionId?: string;
|
|
18
21
|
request: RuntimeRequest;
|
|
19
22
|
agent: WorkspaceAgent;
|
|
20
23
|
workspace: CompiledWorkspace;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{formatError as e,readRecord as r,readWorkspaceId as t,resolveEnabledMemories as n,resolveMemoryProvider as o,resolvePluginNamespace as a}from"./memory-plugins/shared.js";export{resolveEnabledMemories,resolvePluginNamespace}from"./memory-plugins/shared.js";export{createLangMemMaintenanceTarget,createMemoryMaintenanceDaemon,createSkillCandidateMinerTarget}from"./memory-plugins/maintenance.js";export async function runMemoryPlugins(e){const r=n(e.workspace,"write");if(e.providers?.length&&0!==r.length&&!1!==e.request.metadata?.memoryWrite)for(const t of r)await runMemoryPlugin(e,t)}export async function recallMemoryPlugins(e){const r=n(e.workspace,"recall");if(!e.providers?.length||0===r.length)return[];const t=await Promise.all(r.map(async r=>{try{return await async function recallMemoryPlugin(e,r){const t=o(e.providers??[],r.provider);if(!t)return;const n=a(e.workspace,e.agent,e.request,r),s=await t.search({namespace:n,query:buildRecallQuery(e),limit:readRecallLimit(e.workspace)});return{namespace:n,records:s,context:formatRecallContext(e.workspace,s)}}(e,r)}catch{return}}));return t.filter(e=>Boolean(e?.context))}async function runMemoryPlugin(r,t){const n=o(r.providers??[],t.provider);if(!n)return;const s=a(r.workspace,r.agent,r.request,t);r.emit({type:"runtime.memory.plugin.started",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s});try{const e=await n.propose(function createPluginProposeInput(e,r,t){return{namespace:t,content:[`User input:\n${e.request.input}`,`Agent output:\n${e.result.text}`].join("\n\n"),sourceType:"runtime-run",sourceRef:e.requestId,metadata:{memoryId:r.id,provider:r.provider,profile:r.profile,mode:r.mode,prompts:r.prompts,workspaceRoot:e.workspace.root,agentId:e.agent.id,sessionId:e.sessionId,requestMetadata:e.request.metadata}}}(r,t,s));r.emit({type:"runtime.memory.plugin.completed",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s,candidateCount:e.length})}catch(o){r.emit({type:"runtime.memory.plugin.failed",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s,error:e(o)})}}function buildRecallQuery(e){const r=[`task: ${e.request.input}`,`workspace: ${t(e.workspace)}`,`agent: ${e.agent.id}`,"memory_needed: durable preferences, workspace facts, reusable procedures, prior corrections"],n=function readRecentContext(e){return"string"==typeof e?.recentContext?e.recentContext.slice(0,3e3):Array.isArray(e?.recentTurns)?e.recentTurns.filter(e=>"string"==typeof e).slice(-6).join("\n").slice(0,3e3):void 0}(e.request.metadata);return n?[...r,`recent_context: ${n}`].join("\n"):r.join("\n")}function readRecallLimit(e){const t=r(e.runtime.memory?.LangMem),n=r(t?.recall),o=n?.topK??n?.limit;return"number"==typeof o&&Number.isFinite(o)?o:10}function formatRecallContext(e,t){const n=function readRecallContextLimits(e){const t=r(e.runtime.memory?.LangMem),n=r(t?.recall);return{maxContextChars:readPositiveNumber(n?.maxContextChars)??4e3,maxRecordChars:readPositiveNumber(n?.maxRecordChars)??1e3}}(e),o=[];let a=n.maxContextChars;for(const e of t){if(a<=0)break;const r=truncateText(formatRecallRecord(e),Math.min(n.maxRecordChars,a));r.trim()&&(o.push(r),a-=r.length+1)}return o.join("\n")}function formatRecallRecord(e){return`- ${e.summary??e.content}\n ${e.content}`}function readPositiveNumber(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}function truncateText(e,r){return e.length>r?`${e.slice(0,Math.max(0,r-13))}\n [truncated]`:e}
|
|
1
|
+
import{formatError as e,readRecord as r,readWorkspaceId as t,resolveEnabledMemories as n,resolveMemoryProvider as o,resolvePluginNamespace as a}from"./memory-plugins/shared.js";export{resolveEnabledMemories,resolvePluginNamespace}from"./memory-plugins/shared.js";export{createLangMemMaintenanceTarget,createMemoryMaintenanceDaemon,createSkillCandidateMinerTarget}from"./memory-plugins/maintenance.js";export async function runMemoryPlugins(e){const r=n(e.workspace,"write");if(e.providers?.length&&0!==r.length&&!1!==e.request.metadata?.memoryWrite)for(const t of r)await runMemoryPlugin(e,t)}export async function recallMemoryPlugins(e){const r=n(e.workspace,"recall");if(!e.providers?.length||0===r.length)return[];const t=await Promise.all(r.map(async r=>{try{return await async function recallMemoryPlugin(e,r){const t=o(e.providers??[],r.provider);if(!t)return;const n=a(e.workspace,e.agent,e.request,r),s=await t.search({namespace:n,query:buildRecallQuery(e),limit:readRecallLimit(e.workspace)});return e.emit&&e.requestId&&e.sessionId&&e.emit({type:"runtime.memory.recall.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,namespace:n,recordIds:s.map(e=>e.id),context:formatRecallContext(e.workspace,s)}),{namespace:n,records:s,context:formatRecallContext(e.workspace,s)}}(e,r)}catch{return}}));return t.filter(e=>Boolean(e?.context))}async function runMemoryPlugin(r,t){const n=o(r.providers??[],t.provider);if(!n)return;const s=a(r.workspace,r.agent,r.request,t);r.emit({type:"runtime.memory.plugin.started",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s});try{const e=await n.propose(function createPluginProposeInput(e,r,t){return{namespace:t,content:[`User input:\n${e.request.input}`,`Agent output:\n${e.result.text}`].join("\n\n"),sourceType:"runtime-run",sourceRef:e.requestId,metadata:{memoryId:r.id,provider:r.provider,profile:r.profile,mode:r.mode,prompts:r.prompts,workspaceRoot:e.workspace.root,agentId:e.agent.id,sessionId:e.sessionId,requestMetadata:e.request.metadata}}}(r,t,s));r.emit({type:"runtime.memory.plugin.completed",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s,candidateCount:e.length})}catch(o){r.emit({type:"runtime.memory.plugin.failed",requestId:r.requestId,sessionId:r.sessionId,agentId:r.agent.id,memoryId:t.id,provider:n.name,namespace:s,error:e(o)})}}function buildRecallQuery(e){const r=[`task: ${e.request.input}`,`workspace: ${t(e.workspace)}`,`agent: ${e.agent.id}`,"memory_needed: durable preferences, workspace facts, reusable procedures, prior corrections"],n=function readRecentContext(e){return"string"==typeof e?.recentContext?e.recentContext.slice(0,3e3):Array.isArray(e?.recentTurns)?e.recentTurns.filter(e=>"string"==typeof e).slice(-6).join("\n").slice(0,3e3):void 0}(e.request.metadata);return n?[...r,`recent_context: ${n}`].join("\n"):r.join("\n")}function readRecallLimit(e){const t=r(e.runtime.memory?.LangMem),n=r(t?.recall),o=n?.topK??n?.limit;return"number"==typeof o&&Number.isFinite(o)?o:10}function formatRecallContext(e,t){const n=function readRecallContextLimits(e){const t=r(e.runtime.memory?.LangMem),n=r(t?.recall);return{maxContextChars:readPositiveNumber(n?.maxContextChars)??4e3,maxRecordChars:readPositiveNumber(n?.maxRecordChars)??1e3}}(e),o=[];let a=n.maxContextChars;for(const e of t){if(a<=0)break;const r=truncateText(formatRecallRecord(e),Math.min(n.maxRecordChars,a));r.trim()&&(o.push(r),a-=r.length+1)}return o.join("\n")}function formatRecallRecord(e){return`- ${e.summary??e.content}\n ${e.content}`}function readPositiveNumber(e){return"number"==typeof e&&Number.isFinite(e)&&e>0?Math.floor(e):void 0}function truncateText(e,r){return e.length>r?`${e.slice(0,Math.max(0,r-13))}\n [truncated]`:e}
|
|
@@ -5,6 +5,8 @@ import type { RuntimeSandboxDecision } from "./tool-gateway.js";
|
|
|
5
5
|
import type { RuntimeToolFailureClassification, RuntimeToolFailureReason } from "./tool-failure.js";
|
|
6
6
|
export type RuntimeInventoryRepairLayer = "agent" | "workflow_route" | "workflow" | "tool" | "task" | "skill";
|
|
7
7
|
export type RuntimeInventoryRepairStatus = "repaired" | "blocked";
|
|
8
|
+
export type RuntimeRepairLayer = "adapter_error" | "result_output" | "execution_contract" | "evidence_synthesis";
|
|
9
|
+
export type RuntimeRepairOutcome = "retried" | "synthesized" | "blocked";
|
|
8
10
|
export type RuntimeInventoryRepairDiagnostic = {
|
|
9
11
|
layer: RuntimeInventoryRepairLayer;
|
|
10
12
|
owner: "stable_runtime_policy" | "protocol_adapter" | "upstream_backend" | "workspace_config";
|
|
@@ -56,6 +58,23 @@ export type RuntimeEvent = RuntimeEventMetadata & ({
|
|
|
56
58
|
agentId: string;
|
|
57
59
|
reason: string;
|
|
58
60
|
missingEvidenceTools?: string[];
|
|
61
|
+
} | {
|
|
62
|
+
type: "runtime.repair.started";
|
|
63
|
+
requestId: string;
|
|
64
|
+
sessionId: string;
|
|
65
|
+
agentId: string;
|
|
66
|
+
layer: RuntimeRepairLayer;
|
|
67
|
+
attempt?: number;
|
|
68
|
+
reason?: string;
|
|
69
|
+
} | {
|
|
70
|
+
type: "runtime.repair.completed";
|
|
71
|
+
requestId: string;
|
|
72
|
+
sessionId: string;
|
|
73
|
+
agentId: string;
|
|
74
|
+
layer: RuntimeRepairLayer;
|
|
75
|
+
outcome: RuntimeRepairOutcome;
|
|
76
|
+
attempt?: number;
|
|
77
|
+
reason?: string;
|
|
59
78
|
} | {
|
|
60
79
|
type: "runtime.inventory.repair";
|
|
61
80
|
requestId: string;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{recallMemoryPlugins as e,runMemoryPlugins as r}from"../memory-plugins.js";export function emitMemoryLifecycle(e,r,s,t,o,a){e&&r({type:"runtime.memory.lifecycle",requestId:s,sessionId:t,agentId:o,hook:a})}export async function runMemoryRecall(e){if(!e.memory)return;if(emitMemoryLifecycle(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-plan"),!1===e.request.memory?.recall)return;const r=resolveMemoryNamespace(e.workspace,e.agent,e.request),s=e.request.memory?.recall?.query??e.request.input,t=await e.memory.recall({namespace:r,query:s,limit:e.request.memory?.recall?.limit});return e.emit({type:"runtime.memory.recall.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,namespace:r,recordIds:t.records.map(e=>e.id),context:t.context}),{namespace:r,records:t.records,context:t.context}}export async function submitMemoryCandidates(e){if(!e.memory||!e.request.memory?.candidates?.length)return;emitMemoryLifecycle(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"write-after-run");const r=resolveMemoryNamespace(e.workspace,e.agent,e.request);for(const s of e.request.memory.candidates){const t={...s,namespace:s.namespace??r},o=await e.memory.submitCandidate(t);if(e.emit({type:"runtime.memory.candidate.submitted",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,candidate:o.candidate,decision:o.decision,record:o.record}),"review"===o.decision.action&&e.approvals){const r=await e.approvals.create({kind:"memory_write",reason:o.decision.reason,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,subject:{candidate:o.candidate,decision:o.decision}});e.emit({type:"runtime.memory.approval.requested",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,approval:r})}}}export function createMemoryRuntimeCapability(s){return{id:"runtime.memory",beforeAdapterRun:async r=>({memory:await runMemoryRecall({memory:s.memory,emit:r.emit,request:r.request,requestId:r.requestId,sessionId:r.sessionId,agent:r.agent,workspace:r.workspace}),pluginMemories:await e({providers:s.memoryProviders,request:r.request,agent:r.agent,workspace:r.workspace})}),async beforeAdapterResultContract(e){emitMemoryLifecycle(s.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-finalize"),await submitMemoryCandidates({memory:s.memory,approvals:s.approvals,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.workspace})},async afterAdapterResponse(e){await r({providers:s.memoryProviders,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.workspace,result:e.result})}}}function resolveMemoryNamespace(e,r,s){return s.memory?.namespace??`${e.root}:${r.id}`}
|
|
1
|
+
import{recallMemoryPlugins as e,runMemoryPlugins as r}from"../memory-plugins.js";export function emitMemoryLifecycle(e,r,s,t,o,a){e&&r({type:"runtime.memory.lifecycle",requestId:s,sessionId:t,agentId:o,hook:a})}export async function runMemoryRecall(e){if(!e.memory)return;if(emitMemoryLifecycle(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-plan"),!1===e.request.memory?.recall)return;const r=resolveMemoryNamespace(e.workspace,e.agent,e.request),s=e.request.memory?.recall?.query??e.request.input,t=await e.memory.recall({namespace:r,query:s,limit:e.request.memory?.recall?.limit});return e.emit({type:"runtime.memory.recall.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,namespace:r,recordIds:t.records.map(e=>e.id),context:t.context}),{namespace:r,records:t.records,context:t.context}}export async function submitMemoryCandidates(e){if(!e.memory||!e.request.memory?.candidates?.length)return;emitMemoryLifecycle(e.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"write-after-run");const r=resolveMemoryNamespace(e.workspace,e.agent,e.request);for(const s of e.request.memory.candidates){const t={...s,namespace:s.namespace??r},o=await e.memory.submitCandidate(t);if(e.emit({type:"runtime.memory.candidate.submitted",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,candidate:o.candidate,decision:o.decision,record:o.record}),"review"===o.decision.action&&e.approvals){const r=await e.approvals.create({kind:"memory_write",reason:o.decision.reason,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,subject:{candidate:o.candidate,decision:o.decision}});e.emit({type:"runtime.memory.approval.requested",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,approval:r})}}}export function createMemoryRuntimeCapability(s){return{id:"runtime.memory",beforeAdapterRun:async r=>({memory:await runMemoryRecall({memory:s.memory,emit:r.emit,request:r.request,requestId:r.requestId,sessionId:r.sessionId,agent:r.agent,workspace:r.workspace}),pluginMemories:await e({providers:s.memoryProviders,emit:r.emit,requestId:r.requestId,sessionId:r.sessionId,request:r.request,agent:r.agent,workspace:r.workspace})}),async beforeAdapterResultContract(e){emitMemoryLifecycle(s.memory,e.emit,e.requestId,e.sessionId,e.agent.id,"read-before-finalize"),await submitMemoryCandidates({memory:s.memory,approvals:s.approvals,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.workspace})},async afterAdapterResponse(e){await r({providers:s.memoryProviders,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,workspace:e.workspace,result:e.result})}}}function resolveMemoryNamespace(e,r,s){return s.memory?.namespace??`${e.root}:${r.id}`}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function resolveProgressNarrator(e){if(!1===e.options)return;const t=readProgressPolicy(e.policy);return e.options?.enabled??t.enabled?e.options?.provider??function createTemplateProgressNarrator(){const e=new Map,t=new Map;return{name:"template",narrate(r,n){var o;"runtime.request.started"===r.type&&(e.set(r.requestId,{language:(o=r.input??"",/\p{Script=Han}/u.test(o)?"zh":void 0),input:r.input}),t.delete(r.requestId));const i=function templateMessage(e,t){const r="zh"===t?.language;return"runtime.request.started"===e.type?r?`我开始处理这个请求:${summarizeText(e.input)}`:`I'm starting on this request: ${summarizeText(e.input)}`:"runtime.request.completed"===e.type?r?"我已经完成执行链,正在交付最终结果。":"I've finished the execution chain and am returning the final result.":"runtime.request.failed"===e.type?r?"执行链失败了,我会保留具体错误方便定位。":"The execution chain failed; I'm keeping the concrete error visible for diagnosis.":"runtime.request.cancelled"===e.type?r?"这个请求已取消,后续执行会停止。":"The request was cancelled, so the remaining execution will stop.":"runtime.tool.direct.started"===e.type?r?`我正在运行 ${e.toolId}。`:`I'm running ${e.toolId}.`:"runtime.tool.direct.completed"===e.type?r?`${e.toolId} 已返回结果,我会继续使用这份证据。`:`${e.toolId} returned; I'll keep using that evidence.`:"runtime.workflow.started"===e.type?r?`我正在启动 workflow ${e.workflowId}。`:`I'm starting workflow ${e.workflowId}.`:"runtime.workflow.completed"===e.type?r?`workflow ${e.workflowId} 已完成。`:`Workflow ${e.workflowId} is complete.`:"runtime.specDriven.phase.started"===e.type?r?`我正在进入 spec-driven 阶段 ${e.phaseId}。`:`I'm starting spec-driven phase ${e.phaseId}.`:"runtime.specDriven.phase.blocked"===e.type?r?`spec-driven 阶段 ${e.phaseId} 被 gate 阻塞。`:`Spec-driven phase ${e.phaseId} is blocked by a gate.`:"runtime.specDriven.phase.completed"===e.type?r?`spec-driven 阶段 ${e.phaseId} 已完成。`:`Spec-driven phase ${e.phaseId} is complete.`:"runtime.specDriven.phase.verified"===e.type?r?`spec-driven 阶段 ${e.phaseId} 已验证。`:`Spec-driven phase ${e.phaseId} is verified.`:"runtime.artifact.created"===e.type?r?"我已经保存一份运行产物。":"I've saved a runtime artifact.":"runtime.execution.contract.failed"===e.type?r?"运行证据没有满足执行契约,我会进入恢复或失败路径。":"The run evidence did not satisfy the execution contract, so I'll recover or fail explicitly.":"runtime.inventory.repair"===e.type?inventoryRepairMessage(e.status,e.diagnostic.layer,r):"runtime.skill.candidate.created"===e.type?r?`我发现一个可沉淀的 skill 候选:${e.name}。`:`I found a reusable skill candidate: ${e.name}.`:e.type.startsWith("runtime.memory.")?function memoryMessage(e,t){return"runtime.memory.lifecycle"===e.type?t?`我进入记忆阶段:${e.hook}。`:`I'm in the memory lifecycle phase: ${e.hook}.`:"runtime.memory.recall.completed"===e.type?t?`我召回了 ${e.recordIds.length} 条相关记忆。`:`I recalled ${e.recordIds.length} relevant memory records.`:"runtime.memory.candidate.submitted"===e.type?t?"我提交了一条候选记忆。":"I submitted a memory candidate.":"runtime.memory.approval.requested"===e.type?t?"我提交了记忆审批请求。":"I requested memory approval.":"runtime.memory.plugin.started"===e.type?t?`我正在运行记忆插件 ${e.provider}。`:`I'm running memory plugin ${e.provider}.`:"runtime.memory.plugin.completed"===e.type?t?`记忆插件 ${e.provider} 已完成。`:`Memory plugin ${e.provider} completed.`:"runtime.memory.plugin.failed"===e.type?t?`记忆插件 ${e.provider} 失败了;主任务会继续,不把它当成执行结果。`:`Memory plugin ${e.provider} failed; the main task will continue without treating it as the result.`:"runtime.memory.maintenance.started"===e.type?t?`我正在维护 ${e.target} 记忆。`:`I'm maintaining ${e.target} memory.`:"runtime.memory.maintenance.completed"===e.type?t?`${e.target} 记忆维护完成。`:`${e.target} memory maintenance completed.`:"runtime.memory.maintenance.failed"===e.type?t?`${e.target} 记忆维护失败。`:`${e.target} memory maintenance failed.`:void 0}(e,r):"runtime.adapter.event"===e.type?function adapterMessage(e,t){if(isRecord(e)){if("agent.handoff"===e.phase)return t?"我把请求交给上游 agent backend,让它负责规划和执行。":"I'm handing the request to the upstream agent backend for planning and execution.";if(function isToolStartEvent(e){return"deepagents.tool_execution.start"===e.eventType||"agent.tool.start"===e.phase}(e)&&"string"==typeof e.toolId)return function toolStartMessage(e,t,r){if("task"===e){const e=function readTaskTarget(e){const t=isRecord(e)?e:{};return readString(t.subagent_type)??readString(t.subagentType)}(t),n=function readDescription(e){const t=isRecord(e)?e:{};return summarizeText(readString(t.description)??readString(t.task))}(t);if(e&&n)return r?`我正在请求 task 工具委派给 ${e}:${n}`:`I'm asking the task tool to delegate to ${e}: ${n}`;if(e)return r?`我正在请求 task 工具委派给 ${e}。`:`I'm asking the task tool to delegate to ${e}.`}return r?`我正在运行 ${e} 收集证据。`:`I'm running ${e} to gather evidence.`}(e.toolId,e.args,t);if(function isToolResultEvent(e){return"deepagents.tool_execution.result"===e.eventType||"agent.tool.result"===e.phase}(e)&&"string"==typeof e.toolId)return function toolResultMessage(e,t,r,n,o){if(r)return o?`${e} 返回错误:${summarizeText(String(r))}`:`${e} returned an error: ${summarizeText(String(r))}`;const i="string"==typeof n?n:function readToolControlStatus(e){const t=function parseToolOutputRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e);return"string"==typeof t?.status?t.status:"string"==typeof t?.error?t.error:"string"==typeof e&&e.startsWith("Task delegation target is not in the workspace inventory")?"task_inventory_blocked":void 0}(t);if(i)return function toolControlMessage(e,t,r){return"duplicate_tool_call"===t?r?`${e} 重复调用已复用已有证据。`:`${e} repeated an equivalent call, so the existing evidence was reused.`:"repeated_tool_call_limit"===t?r?`${e} 出现重复调用循环,我会基于已有证据继续收敛。`:`${e} entered a repeated-call loop, so I'll continue from the evidence already collected.`:"tool_argument_error"===t||"tool_argument_validation_failed"===t?r?`${e} 参数被工具 schema 拒绝,我会让 agent 修正参数或改用合适工具。`:`${e} arguments were rejected by the tool schema; I'll have the agent repair them or choose a suitable tool.`:"task_inventory_blocked"===t?r?"task 委派目标不在当前 workspace inventory 中,已被运行时策略阻止。":"The task delegation target is not in the current workspace inventory and was blocked by runtime policy.":r?`${e} 返回运行时控制状态:${t}。`:`${e} returned runtime control status: ${t}.`}(e,i,o);if("task"===e)return o?"委派任务已返回结果,我会基于这些证据继续推进。":"The delegated task returned; I'll keep going with that evidence.";const a=function summarizeToolOutput(e){if("string"==typeof e)return summarizeText(e);if(isRecord(e)){if("string"==typeof e.status)return summarizeText(e.status);if("string"==typeof e.summary)return summarizeText(e.summary)}}(t);return o?`${e} 已返回${a?`:${a}`:",我会继续判断下一步。"}`:`${e} returned${a?`: ${a}`:"; I'll decide the next step from here."}`}(e.toolId,e.output,e.error,e.controlStatus,t);if("agent.langgraph.invoke"===e.phase)return t?"我正在调用 workflow backend。":"I'm invoking the workflow backend.";if("agent.node.completed"===e.phase&&"string"==typeof e.nodeId)return t?`节点 ${e.nodeId} 已完成。`:`Node ${e.nodeId} is complete.`;if("inventory.repair"===e.phase&&"string"==typeof e.status){const r=isRecord(e.diagnostic)?e.diagnostic:{};return inventoryRepairMessage(e.status,readString(r.layer)??"selection",t)}}}(e.event,r):void 0}(r,e.get(r.requestId));if(i&&i!==t.get(r.requestId))return t.set(r.requestId,i),"runtime.request.failed"!==r.type&&"runtime.request.cancelled"!==r.type||(e.delete(r.requestId),t.delete(r.requestId)),function pruneRequestState(e,t){for(;e.size>200;){const r=e.keys().next().value;if(!r)break;e.delete(r),t.delete(r)}}(e,t),{message:i,style:n.style,model:n.model}}}}():void 0}export function createProgressNarrationEvent(e){if(!e.narrator||"runtime.progress.narration"===e.source.type)return;const t=readProgressPolicy(e.policy),r=!1===e.options?void 0:e.options,n=e.narrator.narrate(e.source,{style:r?.style??t.style,model:r?.model??t.model});return function isPromiseLike(e){return isRecord(e)&&"function"==typeof e.then}(n)?n.then(t=>toNarrationEvent(e.source,e.narrator,t)):toNarrationEvent(e.source,e.narrator,n)}export function createProgressNarrationCapability(e){const t=resolveProgressNarrator(e);if(t)return{id:"runtime.progress.narration",onEvent(r,n){try{const o=createProgressNarrationEvent({source:r,narrator:t,options:e.options,policy:e.policy});!function isRuntimeEventPromise(e){return isRecord(e)&&"function"==typeof e.then}(o)?o&&n(o):o.then(e=>{e&&n(e)}).catch(()=>{})}catch{return}}}}function toNarrationEvent(e,t,r){if(r?.message.trim())return{type:"runtime.progress.narration",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,message:r.message,provider:t.name,sourceEventTypes:r.sourceEventTypes??[e.type],sourceEventIds:r.sourceEventIds??(e.eventId?[e.eventId]:void 0),model:r.model,style:r.style}}function inventoryRepairMessage(e,t,r){return"repaired"===e?r?`${t} 选择已按 workspace inventory 修正。`:`${t} selection was repaired against the workspace inventory.`:r?`${t} 选择不在 workspace inventory 中,已被阻止。`:`${t} selection was blocked because it is outside the workspace inventory.`}function summarizeText(e){const t=e?.replace(/\s+/gu," ").trim();return t?t.length>120?`${t.slice(0,117)}...`:t:""}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readProgressPolicy(e){const t=isRecord(e?.progress)?e.progress:{},r=isRecord(t.narration)?t.narration:{};return{enabled:"boolean"==typeof r.enabled?r.enabled:void 0,style:"string"==typeof r.style?r.style:void 0,model:"string"==typeof r.model?r.model:void 0}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
1
|
+
export function resolveProgressNarrator(e){if(!1===e.options)return;const t=readProgressPolicy(e.policy);return e.options?.enabled??t.enabled?e.options?.provider??function createTemplateProgressNarrator(){const e=new Map,t=new Map;return{name:"template",narrate(r,n){var o;"runtime.request.started"===r.type&&(e.set(r.requestId,{language:(o=r.input??"",/\p{Script=Han}/u.test(o)?"zh":void 0),input:r.input}),t.delete(r.requestId));const i=function templateMessage(e,t){const r="zh"===t?.language;return"runtime.request.started"===e.type?r?`我开始处理这个请求:${summarizeText(e.input)}`:`I'm starting on this request: ${summarizeText(e.input)}`:"runtime.request.completed"===e.type?r?"我已经完成执行链,正在交付最终结果。":"I've finished the execution chain and am returning the final result.":"runtime.request.failed"===e.type?r?"执行链失败了,我会保留具体错误方便定位。":"The execution chain failed; I'm keeping the concrete error visible for diagnosis.":"runtime.request.cancelled"===e.type?r?"这个请求已取消,后续执行会停止。":"The request was cancelled, so the remaining execution will stop.":"runtime.tool.direct.started"===e.type?r?`我正在运行 ${e.toolId}。`:`I'm running ${e.toolId}.`:"runtime.tool.direct.completed"===e.type?r?`${e.toolId} 已返回结果,我会继续使用这份证据。`:`${e.toolId} returned; I'll keep using that evidence.`:"runtime.workflow.started"===e.type?r?`我正在启动 workflow ${e.workflowId}。`:`I'm starting workflow ${e.workflowId}.`:"runtime.workflow.completed"===e.type?r?`workflow ${e.workflowId} 已完成。`:`Workflow ${e.workflowId} is complete.`:"runtime.specDriven.phase.started"===e.type?r?`我正在进入 spec-driven 阶段 ${e.phaseId}。`:`I'm starting spec-driven phase ${e.phaseId}.`:"runtime.specDriven.phase.blocked"===e.type?r?`spec-driven 阶段 ${e.phaseId} 被 gate 阻塞。`:`Spec-driven phase ${e.phaseId} is blocked by a gate.`:"runtime.specDriven.phase.completed"===e.type?r?`spec-driven 阶段 ${e.phaseId} 已完成。`:`Spec-driven phase ${e.phaseId} is complete.`:"runtime.specDriven.phase.verified"===e.type?r?`spec-driven 阶段 ${e.phaseId} 已验证。`:`Spec-driven phase ${e.phaseId} is verified.`:"runtime.artifact.created"===e.type?r?"我已经保存一份运行产物。":"I've saved a runtime artifact.":"runtime.execution.contract.failed"===e.type?r?"运行证据没有满足执行契约,我会进入恢复或失败路径。":"The run evidence did not satisfy the execution contract, so I'll recover or fail explicitly.":"runtime.repair.started"===e.type?repairMessage(e.layer,"started",r):"runtime.repair.completed"===e.type?repairMessage(e.layer,e.outcome,r):"runtime.inventory.repair"===e.type?inventoryRepairMessage(e.status,e.diagnostic.layer,r):"runtime.skill.candidate.created"===e.type?r?`我发现一个可沉淀的 skill 候选:${e.name}。`:`I found a reusable skill candidate: ${e.name}.`:e.type.startsWith("runtime.memory.")?function memoryMessage(e,t){return"runtime.memory.lifecycle"===e.type?t?`我进入记忆阶段:${e.hook}。`:`I'm in the memory lifecycle phase: ${e.hook}.`:"runtime.memory.recall.completed"===e.type?t?`我召回了 ${e.recordIds.length} 条相关记忆。`:`I recalled ${e.recordIds.length} relevant memory records.`:"runtime.memory.candidate.submitted"===e.type?t?"我提交了一条候选记忆。":"I submitted a memory candidate.":"runtime.memory.approval.requested"===e.type?t?"我提交了记忆审批请求。":"I requested memory approval.":"runtime.memory.plugin.started"===e.type?t?`我正在运行记忆插件 ${e.provider}。`:`I'm running memory plugin ${e.provider}.`:"runtime.memory.plugin.completed"===e.type?t?`记忆插件 ${e.provider} 已完成。`:`Memory plugin ${e.provider} completed.`:"runtime.memory.plugin.failed"===e.type?t?`记忆插件 ${e.provider} 失败了;主任务会继续,不把它当成执行结果。`:`Memory plugin ${e.provider} failed; the main task will continue without treating it as the result.`:"runtime.memory.maintenance.started"===e.type?t?`我正在维护 ${e.target} 记忆。`:`I'm maintaining ${e.target} memory.`:"runtime.memory.maintenance.completed"===e.type?t?`${e.target} 记忆维护完成。`:`${e.target} memory maintenance completed.`:"runtime.memory.maintenance.failed"===e.type?t?`${e.target} 记忆维护失败。`:`${e.target} memory maintenance failed.`:void 0}(e,r):"runtime.adapter.event"===e.type?function adapterMessage(e,t){if(isRecord(e)){if("agent.handoff"===e.phase)return t?"我把请求交给上游 agent backend,让它负责规划和执行。":"I'm handing the request to the upstream agent backend for planning and execution.";if(function isToolStartEvent(e){return"deepagents.tool_execution.start"===e.eventType||"agent.tool.start"===e.phase}(e)&&"string"==typeof e.toolId)return function toolStartMessage(e,t,r){if("task"===e){const e=function readTaskTarget(e){const t=isRecord(e)?e:{};return readString(t.subagent_type)??readString(t.subagentType)}(t),n=function readDescription(e){const t=isRecord(e)?e:{};return summarizeText(readString(t.description)??readString(t.task))}(t);if(e&&n)return r?`我正在请求 task 工具委派给 ${e}:${n}`:`I'm asking the task tool to delegate to ${e}: ${n}`;if(e)return r?`我正在请求 task 工具委派给 ${e}。`:`I'm asking the task tool to delegate to ${e}.`}return r?`我正在运行 ${e} 收集证据。`:`I'm running ${e} to gather evidence.`}(e.toolId,e.args,t);if(function isToolResultEvent(e){return"deepagents.tool_execution.result"===e.eventType||"agent.tool.result"===e.phase}(e)&&"string"==typeof e.toolId)return function toolResultMessage(e,t,r,n,o){if(r)return o?`${e} 返回错误:${summarizeText(String(r))}`:`${e} returned an error: ${summarizeText(String(r))}`;const i="string"==typeof n?n:function readToolControlStatus(e){const t=function parseToolOutputRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e);return"string"==typeof t?.status?t.status:"string"==typeof t?.error?t.error:"string"==typeof e&&e.startsWith("Task delegation target is not in the workspace inventory")?"task_inventory_blocked":void 0}(t);if(i)return function toolControlMessage(e,t,r){return"duplicate_tool_call"===t?r?`${e} 重复调用已复用已有证据。`:`${e} repeated an equivalent call, so the existing evidence was reused.`:"repeated_tool_call_limit"===t?r?`${e} 出现重复调用循环,我会基于已有证据继续收敛。`:`${e} entered a repeated-call loop, so I'll continue from the evidence already collected.`:"tool_argument_error"===t||"tool_argument_validation_failed"===t?r?`${e} 参数被工具 schema 拒绝,我会让 agent 修正参数或改用合适工具。`:`${e} arguments were rejected by the tool schema; I'll have the agent repair them or choose a suitable tool.`:"task_inventory_blocked"===t?r?"task 委派目标不在当前 workspace inventory 中,已被运行时策略阻止。":"The task delegation target is not in the current workspace inventory and was blocked by runtime policy.":r?`${e} 返回运行时控制状态:${t}。`:`${e} returned runtime control status: ${t}.`}(e,i,o);if("task"===e)return o?"委派任务已返回结果,我会基于这些证据继续推进。":"The delegated task returned; I'll keep going with that evidence.";const a=function summarizeToolOutput(e){if("string"==typeof e)return summarizeText(e);if(isRecord(e)){if("string"==typeof e.status)return summarizeText(e.status);if("string"==typeof e.summary)return summarizeText(e.summary)}}(t);return o?`${e} 已返回${a?`:${a}`:",我会继续判断下一步。"}`:`${e} returned${a?`: ${a}`:"; I'll decide the next step from here."}`}(e.toolId,e.output,e.error,e.controlStatus,t);if("agent.langgraph.invoke"===e.phase)return t?"我正在调用 workflow backend。":"I'm invoking the workflow backend.";if("agent.node.completed"===e.phase&&"string"==typeof e.nodeId)return t?`节点 ${e.nodeId} 已完成。`:`Node ${e.nodeId} is complete.`;if("inventory.repair"===e.phase&&"string"==typeof e.status){const r=isRecord(e.diagnostic)?e.diagnostic:{};return inventoryRepairMessage(e.status,readString(r.layer)??"selection",t)}}}(e.event,r):void 0}(r,e.get(r.requestId));if(i&&i!==t.get(r.requestId))return t.set(r.requestId,i),"runtime.request.failed"!==r.type&&"runtime.request.cancelled"!==r.type||(e.delete(r.requestId),t.delete(r.requestId)),function pruneRequestState(e,t){for(;e.size>200;){const r=e.keys().next().value;if(!r)break;e.delete(r),t.delete(r)}}(e,t),{message:i,style:n.style,model:n.model}}}}():void 0}export function createProgressNarrationEvent(e){if(!e.narrator||"runtime.progress.narration"===e.source.type)return;const t=readProgressPolicy(e.policy),r=!1===e.options?void 0:e.options,n=e.narrator.narrate(e.source,{style:r?.style??t.style,model:r?.model??t.model});return function isPromiseLike(e){return isRecord(e)&&"function"==typeof e.then}(n)?n.then(t=>toNarrationEvent(e.source,e.narrator,t)):toNarrationEvent(e.source,e.narrator,n)}export function createProgressNarrationCapability(e){const t=resolveProgressNarrator(e);if(t)return{id:"runtime.progress.narration",onEvent(r,n){try{const o=createProgressNarrationEvent({source:r,narrator:t,options:e.options,policy:e.policy});!function isRuntimeEventPromise(e){return isRecord(e)&&"function"==typeof e.then}(o)?o&&n(o):o.then(e=>{e&&n(e)}).catch(()=>{})}catch{return}}}}function toNarrationEvent(e,t,r){if(r?.message.trim())return{type:"runtime.progress.narration",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,message:r.message,provider:t.name,sourceEventTypes:r.sourceEventTypes??[e.type],sourceEventIds:r.sourceEventIds??(e.eventId?[e.eventId]:void 0),model:r.model,style:r.style}}function inventoryRepairMessage(e,t,r){return"repaired"===e?r?`${t} 选择已按 workspace inventory 修正。`:`${t} selection was repaired against the workspace inventory.`:r?`${t} 选择不在 workspace inventory 中,已被阻止。`:`${t} selection was blocked because it is outside the workspace inventory.`}function repairMessage(e,t,r){return r?"started"===t?`runtime 正在执行 ${e} repair。`:"synthesized"===t?`runtime 已通过 ${e} repair 合成可交付结果。`:"blocked"===t?`runtime 已阻止 ${e} repair 的不可靠输出。`:`runtime 已完成 ${e} repair。`:"started"===t?`Runtime is starting ${e} repair.`:"synthesized"===t?`Runtime synthesized a deliverable result through ${e} repair.`:"blocked"===t?`Runtime blocked unreliable output during ${e} repair.`:`Runtime completed ${e} repair.`}function summarizeText(e){const t=e?.replace(/\s+/gu," ").trim();return t?t.length>120?`${t.slice(0,117)}...`:t:""}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}function readProgressPolicy(e){const t=isRecord(e?.progress)?e.progress:{},r=isRecord(t.narration)?t.narration:{};return{enabled:"boolean"==typeof r.enabled?r.enabled:void 0,style:"string"==typeof r.style?r.style:void 0,model:"string"==typeof r.model?r.model:void 0}}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}
|
|
@@ -0,0 +1,12 @@
|
|
|
1
|
+
import type { RuntimeEvent, RuntimeOutput, RuntimeRequest, RuntimeStore, WorkspaceAgent } from "../../types.js";
|
|
2
|
+
export declare function recoverAdapterResultOutput(input: {
|
|
3
|
+
request: RuntimeRequest;
|
|
4
|
+
result: RuntimeOutput;
|
|
5
|
+
recoveryPolicy: unknown;
|
|
6
|
+
store: RuntimeStore;
|
|
7
|
+
emit: (event: RuntimeEvent) => void;
|
|
8
|
+
requestId: string;
|
|
9
|
+
sessionId: string;
|
|
10
|
+
agent: WorkspaceAgent;
|
|
11
|
+
runAdapter: (request: RuntimeRequest) => Promise<RuntimeOutput>;
|
|
12
|
+
}): Promise<RuntimeOutput>;
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
import{assertNoRawToolCallOutput as e,assertNoToolExecutionErrorOutput as t,buildEvidenceSynthesisOutput as r,buildResultRecoveryRequest as o,containsRawToolCallOutput as l,rawToolCallFailureMessage as a,toolCallRecoveryEnabled as u}from"../../recovery/tool-call.js";export async function recoverAdapterResultOutput(s){let i=s.result,n=s.request;const c=function resultRecoveryAttempts(e){const t="object"!=typeof e||null===e||Array.isArray(e)?void 0:e.recovery,r="object"!=typeof t||null===t||Array.isArray(t)?void 0:t.toolCall,o="object"!=typeof r||null===r||Array.isArray(r)?void 0:r.maxResultRecoveryAttempts;return"number"==typeof o&&Number.isInteger(o)&&o>0?o:3}(s.recoveryPolicy);let y=0;for(let e=0;e<c;e+=1){const t=s.store.getRun(s.requestId)?.events??[],r=o({request:n,output:i.text,events:t.slice(y),availableToolIds:s.agent.tools,policy:s.recoveryPolicy});if(!r)break;n=r,y=s.store.getRun(s.requestId)?.events.length??0,emitRepair(s,"runtime.repair.started","result_output",e+1,"recoverable_result_output"),i=await s.runAdapter(r),emitRepair(s,"runtime.repair.completed","result_output",e+1,"recoverable_result_output","retried")}return function finalizeRecoveredOutput(o,s){if(!u(o.recoveryPolicy))return s;let i=!1;l(s.text,o.recoveryPolicy)&&function rawToolCallFailureReturnsMessage(e){return"message"===("object"!=typeof e?.toolCallRecovery||null===e.toolCallRecovery||Array.isArray(e.toolCallRecovery)?{}:e.toolCallRecovery).onFailure}(o.request.metadata)&&(s={...s,text:a(),metadata:{...s.metadata,toolCallRecovery:{failed:!0,reason:"raw_tool_call_output"}}},emitRepair(o,"runtime.repair.completed","result_output",void 0,"raw_tool_call_output","blocked"));const n=r({request:o.request,output:s.text,events:o.store.getRun(o.requestId)?.events??[],policy:o.recoveryPolicy});return n&&(i=!0,s={...s,text:n,metadata:{...s.metadata,toolCallRecovery:{synthesized:!0,reason:"raw_tool_call_output_with_evidence"}}},emitRepair(o,"runtime.repair.completed","evidence_synthesis",void 0,"raw_tool_call_output_with_evidence","synthesized")),i||(e(s.text,o.recoveryPolicy),t(s.text,o.recoveryPolicy)),s}(s,i)}function emitRepair(e,t,r,o,l,a){const u={requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:r,attempt:o,reason:l};e.emit("runtime.repair.started"===t?{type:t,...u}:{type:t,...u,outcome:a??"retried"})}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{
|
|
1
|
+
import{randomUUID as e}from"node:crypto";import{assertExecutionContract as t}from"./execution-contract.js";import{buildAdapterErrorRecoveryPrompt as r,buildExecutionContractRecoveryRequest as a,isRecoverableAdapterError as s}from"./recovery/tool-call.js";import{recoverQualityReview as n,resolveQualityPolicy as o}from"./quality/index.js";import{recoverAdapterResultOutput as i}from"./runtime/recovery/adapter-result.js";import{completeRun as u,failRun as c}from"./runtime/completion.js";import{runDirectToolCall as p}from"./runtime/direct-tool-call.js";import{createApprovalGatedToolGateway as d}from"./runtime/governance/approval-gate.js";import{createSandboxedToolGateway as m}from"./runtime/governance/sandbox.js";import{createRuntimeInspectionMethods as l}from"./runtime/inspection/methods.js";import{createRuntimeCapabilityRegistry as w,normalizeAdapterResult as f}from"./runtime/capabilities.js";import{createMemoryRuntimeCapability as g}from"./runtime/memory.js";import{createInMemoryRuntimeStore as I}from"./runtime/persistence/stores.js";import{createProgressNarrationCapability as y}from"./runtime/progress-narration.js";import{repairRuntimeSelection as q}from"./runtime/selection-repair.js";import{createLangSmithTracingCapability as R}from"./runtime/tracing/langsmith.js";import{createToolFailureTracker as k}from"./runtime/tool-failure.js";import{runWorkflowRequest as v}from"./workflows/runtime.js";export function createStableHarnessRuntime(t){const f=new Set,b=t.store??I(),A=w([g(t),y({options:t.progressNarration,policy:t.workspace.runtime}),R({policy:t.workspace.runtime,store:b,options:t.langSmithTracing}),...t.capabilities??[]]),emitBase=t=>{const r=function enrichRuntimeEvent(t){return{...t,eventId:t.eventId??e(),emittedAt:t.emittedAt??(new Date).toISOString()}}(t);b.appendEvent(r);for(const e of f)e(r)},emit=e=>{emitBase(e),A.emitSideEffects(e,emitBase)},C=m({gateway:d({gateway:t.toolGateway,approvals:t.approvals,workspace:t.workspace,emit:emit}),workspace:t.workspace,sandbox:t.sandbox,emit:emit}),h={...t,toolGateway:C},x=k(function readToolFailurePolicy(e){if("object"!=typeof e||null===e||Array.isArray(e))return;const t=e.failurePolicy;return"object"!=typeof t||null===t||Array.isArray(t)?void 0:t}(t.workspace.runtime.toolGateway));return{request:async t=>async function runRuntimeRequest(t){const d=t.request.requestId??e(),m=t.request.sessionId??e(),l=[],{agent:w,adapter:f}=await async function resolveExecution(e,t,r){const a=t.agentId?await async function resolveRequestedAgentId(e,t,r){if(e.agents.has(t))return t;const a=await q({id:t,candidates:[...e.agents.values()].map(e=>({id:e.id,description:e.description})),trace:{...r,agentId:t,layer:"agent",owner:"stable_runtime_policy"}});return a.ok?a.id:t}(e.workspace,t.agentId,r):function resolveRoutedAgentId(e,t){for(const r of e.runtime.routes??[])if(routeMatches(r,t))return r.agentId;return e.runtime.defaultAgentId}(e.workspace,t.input),s=e.workspace.agents.get(a);if(!s)throw new Error(`Agent ${a} is not defined in the workspace`);if(t.toolCall||t.workflow)return{agent:s,adapter:void 0};const n=e.adapters.find(e=>e.canRun(s));if(!n)throw new Error(`No runtime adapter can run backend ${s.backend} for agent ${s.id}`);return{agent:s,adapter:n}}(t.input,t.request,{requestId:d,sessionId:m,emit:e=>l.push(e)});t.store.createRun(function createRunRecord(e,t,r,a){return{requestId:t,sessionId:r,agentId:a.id,input:e.input,state:"running",parentRunId:e.parentRunId,metadata:e.metadata,artifacts:[],startedAt:(new Date).toISOString(),events:[]}}(t.request,d,m,w)),l.forEach(t.emit),t.emit({type:"runtime.request.started",requestId:d,sessionId:m,agentId:w.id,input:t.request.input});try{if(t.request.workflow){const e=await v({workspace:t.input.workspace,adapters:t.input.workflowAdapters??[],toolGateway:t.input.toolGateway,request:{input:t.request.input,...t.request.workflow},requestId:d,sessionId:m,agentId:w.id,emit:t.emit});return u({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}if(t.request.toolCall){const e=await p({gateway:t.input.toolGateway,workspace:t.input.workspace,emit:t.emit,request:t.request,requestId:d,sessionId:m,agent:w,toolFailureTracker:t.toolFailureTracker});return u({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,result:e,artifacts:t.input.artifacts})}return await async function runAdapterRequest(e){if(!e.adapter)throw new Error(`No runtime adapter can run backend ${e.agent.backend} for agent ${e.agent.id}`);const t=e.adapter,c=await e.capabilities.beforeAdapterRun(createCapabilityContext(e)),p=c.memory,d=c.pluginMemories??[],m=e.input.workspace.runtime,l=o(e.input.workspace.runtime,e.agent),w=new Map;let f;try{f=await runAdapterOnce(e,t,e.request,p,d,w)}catch(a){if(!s(a,m))throw a;e.emit(repairStarted(e,"adapter_error",1,errorMessage(a))),f=await runAdapterOnce(e,t,r(e.request,a,m),p,d,w),e.emit(repairCompleted(e,"adapter_error","retried",1,errorMessage(a)))}f=await i({...e,request:e.request,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),e.request,f,l),await e.capabilities.beforeAdapterResultContract({...createCapabilityContext(e),result:f});try{assertRequestExecutionContract(e)}catch(r){const s=a({request:e.request,events:e.store.getRun(e.requestId)?.events??[],policy:m});if(!s)throw r;e.emit(repairStarted(e,"execution_contract",1,errorMessage(r))),f=await runAdapterOnce(e,t,s,p,d,w),f=await i({...e,request:s,result:f,recoveryPolicy:m,runAdapter:r=>runAdapterOnce(e,t,r,p,d,w)}),f=await n(createQualityRuntimeInput(e,p,d,w),s,f,l),assertRequestExecutionContract(e),e.emit(repairCompleted(e,"execution_contract","retried",1,errorMessage(r)))}const g=u({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,result:f,artifacts:e.input.artifacts});return await e.capabilities.afterAdapterResponse({...createCapabilityContext(e),result:f,response:g}),g}({...t,adapter:f,requestId:d,sessionId:m,agent:w})}catch(e){return c({store:t.store,emit:t.emit,requestId:d,sessionId:m,agent:w,error:e})}}({input:h,capabilities:A,store:b,emit:emit,request:t,toolFailureTracker:x}),subscribe:e=>(f.add(e),()=>f.delete(e)),...l({workspace:t.workspace,store:b,artifacts:t.artifacts,approvals:t.approvals,emit:emit}),cancel(e,t){const r=b.getRun(e);r&&"running"===r.state&&(b.updateRun(e,{state:"cancelled",completedAt:(new Date).toISOString()}),emit({type:"runtime.request.cancelled",requestId:e,sessionId:r.sessionId,agentId:r.agentId,reason:t}))},async stop(){await A.stop(),f.clear()}}}function createCapabilityContext(e){return{workspace:e.input.workspace,store:e.store,emit:e.emit,request:e.request,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent}}function createQualityRuntimeInput(e,t,r,a){return{workspace:e.input.workspace,agent:e.agent,request:e.request,requestId:e.requestId,sessionId:e.sessionId,events:e.store.getRun(e.requestId)?.events??[],emit:e.emit,getEvents:()=>e.store.getRun(e.requestId)?.events??[],runAdapter:s=>runAdapterOnce(e,e.adapter,s,t,r,a),reviewModel:e.input.qualityReviewModel,memory:t,pluginMemories:r}}function assertRequestExecutionContract(e){t({store:e.store,emit:e.emit,requestId:e.requestId,sessionId:e.sessionId,agent:e.agent,metadata:e.request.metadata})}async function runAdapterOnce(e,t,r,a,s,n){return f(await t.run({workspace:e.input.workspace,agent:e.agent,request:r,requestId:e.requestId,sessionId:e.sessionId,memory:a,pluginMemories:s,toolGateway:e.input.toolGateway,toolFailureTracker:e.input.toolFailureTracker,requestState:n,getEvents:()=>e.store.getRun(e.requestId)?.events??[],emit:e.emit}))}function repairStarted(e,t,r,a){return{type:"runtime.repair.started",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,attempt:r,reason:a}}function repairCompleted(e,t,r,a,s){return{type:"runtime.repair.completed",requestId:e.requestId,sessionId:e.sessionId,agentId:e.agent.id,layer:t,outcome:r,attempt:a,reason:s}}function errorMessage(e){return e instanceof Error?e.message:String(e)}function routeMatches(e,t){if(e.pattern)try{if(new RegExp(e.pattern,"iu").test(t))return!0}catch{return!1}const r=t.toLowerCase();return(e.keywords??[]).some(e=>r.includes(e.toLowerCase()))}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
export function createDelegationTraceProjection(e,t={}){return{traceType:"delegation",traceLabel:e,...t}}export function createPlanTraceProjection(e,t={}){return{traceType:"plan",traceLabel:e,...t}}export function projectRuntimeTrace(e){return e.events.map(projectEvent).filter(isTraceEntry)}export function projectRuntimeTraceSpans(e){const t=function createSpanBuilder(e){const t=`run:${e.requestId}`,r=[],o=new Map;return{ensureRoot(){if(o.has(t))return;const n={spanId:t,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,kind:"run",name:e.agentId,status:(a=e.state,"completed"===a?"completed":"failed"===a?"failed":"cancelled"===a?"blocked":"running"),startedAt:e.startedAt,completedAt:e.completedAt,startEventIndex:0,...e.parentRunId?{parentSpanId:`run:${e.parentRunId}`}:{},events:[]};var a;r.push(n),o.set(t,n)},markRoot(e,r,n,a){const i=o.get(t);i&&(addEvent(i,e,r),i.status=n,i.attributes=merge(i.attributes,a),"running"!==n&&close(i,e,r))},start(e,n,a,i,s,d){const p=createSpan(`${t}/${e}:${s}`,t,n,a,i,s,d);r.push(p),o.set(e,p)},complete(e,n,a,i){const s=o.get(e)??createSpan(`${t}/${e}:${a}`,t,"adapter",e,n,a);return o.has(e)||r.push(s),addEvent(s,n,a),s.attributes=merge(s.attributes,i),close(s,n,a),o.delete(e),s},fail(e,t,r,o){this.complete(e,t,r,o).status="failed"},event(e,o,n,a,i){const s=createSpan(`${t}/event:${a}`,t,e,o,n,a,i);s.status=function readBlockedStatus(e){return e.type.endsWith(".blocked")||e.type.includes(".approval.")?"blocked":void 0}(n)??"event",close(s,n,a),r.push(s)},closeRoot(){const r=o.get(t);r&&e.completedAt&&(r.completedAt=e.completedAt)},spans:()=>r}}(e);return t.ensureRoot(),e.events.forEach((e,r)=>function projectSpanEvent(e,t,r){return t.type.startsWith("runtime.request.")?function projectRequestSpanEvent(e,t,r){return"runtime.request.started"===t.type?e.markRoot(t,r,"running",{input:t.input}):"runtime.request.completed"===t.type?e.markRoot(t,r,"completed",{output:t.output}):"runtime.request.failed"===t.type?e.markRoot(t,r,"failed",{error:t.error}):"runtime.request.cancelled"===t.type?e.markRoot(t,r,"blocked",{reason:t.reason}):"runtime.execution.contract.failed"===t.type?projectSingleSpan(e,t,r,"quality",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):void 0}(e,t,r):"runtime.tool.direct.started"===t.type?e.start(`tool:${t.toolId}`,"tool",t.toolId,t,r,{toolId:t.toolId}):"runtime.tool.direct.completed"===t.type?e.complete(`tool:${t.toolId}`,t,r,{toolId:t.toolId,output:t.output}):"runtime.workflow.started"===t.type?e.start(`workflow:${t.workflowId}`,"workflow",t.workflowId,t,r,{workflowId:t.workflowId,adapter:t.adapter}):"runtime.workflow.completed"===t.type?e.complete(`workflow:${t.workflowId}`,t,r,{workflowId:t.workflowId,adapter:t.adapter}):t.type.startsWith("runtime.approval.")||t.type.startsWith("runtime.memory.approval.")?projectSingleSpan(e,t,r,"approval",t.type):t.type.startsWith("runtime.specDriven.phase.")?projectSingleSpan(e,t,r,"spec",function readPhaseName(e,t){return"phaseId"in e&&"string"==typeof e.phaseId?e.phaseId:t}(t,"phase")):t.type.startsWith("runtime.memory.")?projectSingleSpan(e,t,r,"memory",t.type):t.type.startsWith("runtime.quality.")?projectSingleSpan(e,t,r,"quality",t.type):"runtime.artifact.created"===t.type?projectSingleSpan(e,t,r,"artifact",t.artifact.id,{artifact:t.artifact}):"runtime.progress.narration"===t.type?projectSingleSpan(e,t,r,"progress",t.message,{provider:t.provider}):"runtime.adapter.event"===t.type?function projectAdapterSpanEvent(e,t,r){const o=isRecord(t.event)?t.event:void 0,n=readString(o?.phase)??"runtime.adapter.event",a=readTraceType(o?.traceType),i=readString(o?.traceLabel);return"delegation"===a&&i?.endsWith(".start")?e.start(delegationKey(o),"delegation",readString(o?.subagentType)??i,t,r,o):"delegation"===a&&i?.endsWith(".completed")?e.complete(delegationKey(o),t,r,o):"plan"===a&&i?projectSingleSpan(e,t,r,"plan",i,o):function isToolStartEvent(e){return"deepagents.tool_execution.start"===e?.eventType||"agent.tool.start"===e?.phase}(o)?e.start(`agent-tool:${readString(o?.toolId)??"unknown"}`,"tool",readString(o?.toolId)??n,t,r,o):function isToolResultEvent(e){return"deepagents.tool_execution.result"===e?.eventType||"agent.tool.result"===e?.phase}(o)?e.complete(`agent-tool:${readString(o?.toolId)??"unknown"}`,t,r,o):projectSingleSpan(e,t,r,"adapter",n,o)}(e,t,r):"runtime.inventory.repair"===t.type?projectSingleSpan(e,t,r,"adapter","runtime.inventory.repair",{status:t.status,...t.diagnostic}):"runtime.sandbox.decision"===t.type?projectSingleSpan(e,t,r,"tool",`sandbox:${t.toolId}`,{toolId:t.toolId,...t.decision}):"runtime.tool.failure"===t.type?e.fail(`tool:${t.toolId}`,t,r,{toolId:t.toolId,...t.failure}):"runtime.tool.circuit.opened"===t.type?projectSingleSpan(e,t,r,"tool",`circuit:${t.toolId}`,{toolId:t.toolId,reason:t.reason}):void 0}(t,e,r)),t.closeRoot(),t.spans()}export function projectEvent(e){return"runtime.request.started"===e.type||"runtime.request.completed"===e.type||"runtime.request.failed"===e.type?base(e,"request",e.type):"runtime.request.cancelled"===e.type?base(e,"request",e.type,{reason:e.reason}):"runtime.execution.contract.failed"===e.type?base(e,"request",e.type,{reason:e.reason,missingEvidenceTools:e.missingEvidenceTools}):"runtime.inventory.repair"===e.type?base(e,"adapter","runtime.inventory.repair",{status:e.status,...e.diagnostic}):"runtime.tool.direct.started"===e.type?base(e,"tool","runtime.tool.direct.started",{toolId:e.toolId}):"runtime.tool.direct.completed"===e.type?base(e,"tool","runtime.tool.direct.completed",{toolId:e.toolId}):"runtime.sandbox.decision"===e.type?base(e,"tool","runtime.sandbox.decision",{toolId:e.toolId,...e.decision}):"runtime.tool.failure"===e.type?base(e,"tool","runtime.tool.failure",{toolId:e.toolId,...e.failure}):"runtime.tool.circuit.opened"===e.type?base(e,"tool","runtime.tool.circuit.opened",{toolId:e.toolId,reason:e.reason}):"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?base(e,"workflow",e.type,{workflowId:e.workflowId,adapter:e.adapter}):function isSpecDrivenPhaseEvent(e){return e.type.startsWith("runtime.specDriven.phase.")}(e)?base(e,"spec",e.type,{phaseId:e.phaseId,..."workflowId"in e&&e.workflowId?{workflowId:e.workflowId}:{},..."reason"in e?{reason:e.reason}:{},..."artifact"in e&&e.artifact?{artifact:e.artifact}:{}}):"runtime.adapter.event"===e.type?function adapterTrace(e){const t=e.event;if(isRecord(t)&&"string"==typeof t.phase){const r=function semanticAdapterTrace(e,t){if("inventory.repair"===t.phase)return base(e,"adapter","runtime.inventory.repair",{status:t.status,...isRecord(t.diagnostic)?t.diagnostic:{}});const r=readTraceType(t.traceType),o=readString(t.traceLabel);return r&&o?base(e,r,o,t):void 0}(e,t);return r||base(e,"adapter",t.phase.startsWith("agent.")?t.phase:`adapter.${t.phase}`,t)}return base(e,"adapter","runtime.adapter.event",{event:t})}(e):"runtime.artifact.created"===e.type?base(e,"artifact","runtime.artifact.created",{artifact:e.artifact}):e.type.startsWith("runtime.memory.")?base(e,"memory",e.type):"runtime.progress.narration"===e.type?base(e,"progress",e.type,{message:e.message,provider:e.provider,sourceEventTypes:e.sourceEventTypes}):void 0}export function readPlanTodos(e){const t=function readPlanRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e),r=function readTodosArray(e){const t=isRecord(e?.args)?e.args:void 0;return Array.isArray(e?.todos)?e.todos:Array.isArray(t?.todos)?t.todos:[]}(t);return r.map(readTodo).filter(isPlanTodoItem)}function readTodo(e){if(isRecord(e)&&"string"==typeof e.content)return{content:e.content,status:"string"==typeof e.status?e.status:"pending"}}function isPlanTodoItem(e){return void 0!==e}function base(e,t,r,o){return{type:t,label:r,agentId:e.agentId,requestId:e.requestId,detail:o}}function isTraceEntry(e){return void 0!==e}function projectSingleSpan(e,t,r,o,n,a){return e.event(o,n,t,r,a)}function delegationKey(e){return`delegation:${readString(e?.subagentType)??readString(e?.toolId)??"task"}`}function createSpan(e,t,r,o,n,a,i){const s={spanId:e,parentSpanId:t,requestId:n.requestId,sessionId:n.sessionId,agentId:n.agentId,kind:r,name:o,status:"running",startedAt:n.emittedAt,startEventIndex:a,attributes:i,events:[]};return addEvent(s,n,a),s}function addEvent(e,t,r){e.events.push({index:r,eventId:t.eventId??`${t.requestId}:${r}`,type:t.type,emittedAt:t.emittedAt})}function close(e,t,r){e.status="failed"===e.status||"blocked"===e.status?e.status:"completed",e.completedAt=t.emittedAt,e.endEventIndex=r,e.durationMs=function durationMs(e,t){if(!e||!t)return;const r=Date.parse(t)-Date.parse(e);return Number.isFinite(r)&&r>=0?r:void 0}(e.startedAt,e.completedAt)}function merge(e,t){return t?{...e,...t}:e}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readTraceType(e){const t=readString(e);return"request"===t||"tool"===t||"workflow"===t||"spec"===t||"adapter"===t||"memory"===t||"artifact"===t||"progress"===t||"plan"===t||"delegation"===t?t:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
|
|
1
|
+
export function createDelegationTraceProjection(e,t={}){return{traceType:"delegation",traceLabel:e,...t}}export function createPlanTraceProjection(e,t={}){return{traceType:"plan",traceLabel:e,...t}}export function projectRuntimeTrace(e){return e.events.map(projectEvent).filter(isTraceEntry)}export function projectRuntimeTraceSpans(e){const t=function createSpanBuilder(e){const t=`run:${e.requestId}`,r=[],o=new Map;return{ensureRoot(){if(o.has(t))return;const n={spanId:t,requestId:e.requestId,sessionId:e.sessionId,agentId:e.agentId,kind:"run",name:e.agentId,status:(a=e.state,"completed"===a?"completed":"failed"===a?"failed":"cancelled"===a?"blocked":"running"),startedAt:e.startedAt,completedAt:e.completedAt,startEventIndex:0,...e.parentRunId?{parentSpanId:`run:${e.parentRunId}`}:{},events:[]};var a;r.push(n),o.set(t,n)},markRoot(e,r,n,a){const i=o.get(t);i&&(addEvent(i,e,r),i.status=n,i.attributes=merge(i.attributes,a),"running"!==n&&close(i,e,r))},start(e,n,a,i,s,d){const p=createSpan(`${t}/${e}:${s}`,t,n,a,i,s,d);r.push(p),o.set(e,p)},complete(e,n,a,i){const s=o.get(e)??createSpan(`${t}/${e}:${a}`,t,"adapter",e,n,a);return o.has(e)||r.push(s),addEvent(s,n,a),s.attributes=merge(s.attributes,i),close(s,n,a),o.delete(e),s},fail(e,t,r,o){this.complete(e,t,r,o).status="failed"},event(e,o,n,a,i){const s=createSpan(`${t}/event:${a}`,t,e,o,n,a,i);s.status=function readBlockedStatus(e){return e.type.endsWith(".blocked")||e.type.includes(".approval.")?"blocked":void 0}(n)??"event",close(s,n,a),r.push(s)},closeRoot(){const r=o.get(t);r&&e.completedAt&&(r.completedAt=e.completedAt)},spans:()=>r}}(e);return t.ensureRoot(),e.events.forEach((e,r)=>function projectSpanEvent(e,t,r){return t.type.startsWith("runtime.request.")?function projectRequestSpanEvent(e,t,r){return"runtime.request.started"===t.type?e.markRoot(t,r,"running",{input:t.input}):"runtime.request.completed"===t.type?e.markRoot(t,r,"completed",{output:t.output}):"runtime.request.failed"===t.type?e.markRoot(t,r,"failed",{error:t.error}):"runtime.request.cancelled"===t.type?e.markRoot(t,r,"blocked",{reason:t.reason}):"runtime.execution.contract.failed"===t.type?projectSingleSpan(e,t,r,"quality",t.type,{reason:t.reason,missingEvidenceTools:t.missingEvidenceTools}):void 0}(e,t,r):"runtime.tool.direct.started"===t.type?e.start(`tool:${t.toolId}`,"tool",t.toolId,t,r,{toolId:t.toolId}):"runtime.tool.direct.completed"===t.type?e.complete(`tool:${t.toolId}`,t,r,{toolId:t.toolId,output:t.output}):"runtime.workflow.started"===t.type?e.start(`workflow:${t.workflowId}`,"workflow",t.workflowId,t,r,{workflowId:t.workflowId,adapter:t.adapter}):"runtime.workflow.completed"===t.type?e.complete(`workflow:${t.workflowId}`,t,r,{workflowId:t.workflowId,adapter:t.adapter}):t.type.startsWith("runtime.approval.")||t.type.startsWith("runtime.memory.approval.")?projectSingleSpan(e,t,r,"approval",t.type):t.type.startsWith("runtime.specDriven.phase.")?projectSingleSpan(e,t,r,"spec",function readPhaseName(e,t){return"phaseId"in e&&"string"==typeof e.phaseId?e.phaseId:t}(t,"phase")):t.type.startsWith("runtime.memory.")?projectSingleSpan(e,t,r,"memory",t.type):t.type.startsWith("runtime.quality.")?projectSingleSpan(e,t,r,"quality",t.type):t.type.startsWith("runtime.repair.")?projectSingleSpan(e,t,r,"adapter",t.type):"runtime.artifact.created"===t.type?projectSingleSpan(e,t,r,"artifact",t.artifact.id,{artifact:t.artifact}):"runtime.progress.narration"===t.type?projectSingleSpan(e,t,r,"progress",t.message,{provider:t.provider}):"runtime.adapter.event"===t.type?function projectAdapterSpanEvent(e,t,r){const o=isRecord(t.event)?t.event:void 0,n=readString(o?.phase)??"runtime.adapter.event",a=readTraceType(o?.traceType),i=readString(o?.traceLabel);return"delegation"===a&&i?.endsWith(".start")?e.start(delegationKey(o),"delegation",readString(o?.subagentType)??i,t,r,o):"delegation"===a&&i?.endsWith(".completed")?e.complete(delegationKey(o),t,r,o):"plan"===a&&i?projectSingleSpan(e,t,r,"plan",i,o):function isToolStartEvent(e){return"deepagents.tool_execution.start"===e?.eventType||"agent.tool.start"===e?.phase}(o)?e.start(`agent-tool:${readString(o?.toolId)??"unknown"}`,"tool",readString(o?.toolId)??n,t,r,o):function isToolResultEvent(e){return"deepagents.tool_execution.result"===e?.eventType||"agent.tool.result"===e?.phase}(o)?e.complete(`agent-tool:${readString(o?.toolId)??"unknown"}`,t,r,o):projectSingleSpan(e,t,r,"adapter",n,o)}(e,t,r):"runtime.inventory.repair"===t.type?projectSingleSpan(e,t,r,"adapter","runtime.inventory.repair",{status:t.status,...t.diagnostic}):"runtime.sandbox.decision"===t.type?projectSingleSpan(e,t,r,"tool",`sandbox:${t.toolId}`,{toolId:t.toolId,...t.decision}):"runtime.tool.failure"===t.type?e.fail(`tool:${t.toolId}`,t,r,{toolId:t.toolId,...t.failure}):"runtime.tool.circuit.opened"===t.type?projectSingleSpan(e,t,r,"tool",`circuit:${t.toolId}`,{toolId:t.toolId,reason:t.reason}):void 0}(t,e,r)),t.closeRoot(),t.spans()}export function projectEvent(e){return"runtime.request.started"===e.type||"runtime.request.completed"===e.type||"runtime.request.failed"===e.type?base(e,"request",e.type):"runtime.request.cancelled"===e.type?base(e,"request",e.type,{reason:e.reason}):"runtime.execution.contract.failed"===e.type?base(e,"request",e.type,{reason:e.reason,missingEvidenceTools:e.missingEvidenceTools}):"runtime.inventory.repair"===e.type?base(e,"adapter","runtime.inventory.repair",{status:e.status,...e.diagnostic}):"runtime.repair.started"===e.type||"runtime.repair.completed"===e.type?base(e,"adapter",e.type,{layer:e.layer,..."outcome"in e?{outcome:e.outcome}:{},..."attempt"in e?{attempt:e.attempt}:{},..."reason"in e?{reason:e.reason}:{}}):"runtime.tool.direct.started"===e.type?base(e,"tool","runtime.tool.direct.started",{toolId:e.toolId}):"runtime.tool.direct.completed"===e.type?base(e,"tool","runtime.tool.direct.completed",{toolId:e.toolId}):"runtime.sandbox.decision"===e.type?base(e,"tool","runtime.sandbox.decision",{toolId:e.toolId,...e.decision}):"runtime.tool.failure"===e.type?base(e,"tool","runtime.tool.failure",{toolId:e.toolId,...e.failure}):"runtime.tool.circuit.opened"===e.type?base(e,"tool","runtime.tool.circuit.opened",{toolId:e.toolId,reason:e.reason}):"runtime.workflow.started"===e.type||"runtime.workflow.completed"===e.type?base(e,"workflow",e.type,{workflowId:e.workflowId,adapter:e.adapter}):function isSpecDrivenPhaseEvent(e){return e.type.startsWith("runtime.specDriven.phase.")}(e)?base(e,"spec",e.type,{phaseId:e.phaseId,..."workflowId"in e&&e.workflowId?{workflowId:e.workflowId}:{},..."reason"in e?{reason:e.reason}:{},..."artifact"in e&&e.artifact?{artifact:e.artifact}:{}}):"runtime.adapter.event"===e.type?function adapterTrace(e){const t=e.event;if(isRecord(t)&&"string"==typeof t.phase){const r=function semanticAdapterTrace(e,t){if("inventory.repair"===t.phase)return base(e,"adapter","runtime.inventory.repair",{status:t.status,...isRecord(t.diagnostic)?t.diagnostic:{}});const r=readTraceType(t.traceType),o=readString(t.traceLabel);return r&&o?base(e,r,o,t):void 0}(e,t);return r||base(e,"adapter",t.phase.startsWith("agent.")?t.phase:`adapter.${t.phase}`,t)}return base(e,"adapter","runtime.adapter.event",{event:t})}(e):"runtime.artifact.created"===e.type?base(e,"artifact","runtime.artifact.created",{artifact:e.artifact}):e.type.startsWith("runtime.memory.")?base(e,"memory",e.type):"runtime.progress.narration"===e.type?base(e,"progress",e.type,{message:e.message,provider:e.provider,sourceEventTypes:e.sourceEventTypes}):void 0}export function readPlanTodos(e){const t=function readPlanRecord(e){if(isRecord(e))return e;if("string"==typeof e)try{const t=JSON.parse(e);return isRecord(t)?t:void 0}catch{return}}(e),r=function readTodosArray(e){const t=isRecord(e?.args)?e.args:void 0;return Array.isArray(e?.todos)?e.todos:Array.isArray(t?.todos)?t.todos:[]}(t);return r.map(readTodo).filter(isPlanTodoItem)}function readTodo(e){if(isRecord(e)&&"string"==typeof e.content)return{content:e.content,status:"string"==typeof e.status?e.status:"pending"}}function isPlanTodoItem(e){return void 0!==e}function base(e,t,r,o){return{type:t,label:r,agentId:e.agentId,requestId:e.requestId,detail:o}}function isTraceEntry(e){return void 0!==e}function projectSingleSpan(e,t,r,o,n,a){return e.event(o,n,t,r,a)}function delegationKey(e){return`delegation:${readString(e?.subagentType)??readString(e?.toolId)??"task"}`}function createSpan(e,t,r,o,n,a,i){const s={spanId:e,parentSpanId:t,requestId:n.requestId,sessionId:n.sessionId,agentId:n.agentId,kind:r,name:o,status:"running",startedAt:n.emittedAt,startEventIndex:a,attributes:i,events:[]};return addEvent(s,n,a),s}function addEvent(e,t,r){e.events.push({index:r,eventId:t.eventId??`${t.requestId}:${r}`,type:t.type,emittedAt:t.emittedAt})}function close(e,t,r){e.status="failed"===e.status||"blocked"===e.status?e.status:"completed",e.completedAt=t.emittedAt,e.endEventIndex=r,e.durationMs=function durationMs(e,t){if(!e||!t)return;const r=Date.parse(t)-Date.parse(e);return Number.isFinite(r)&&r>=0?r:void 0}(e.startedAt,e.completedAt)}function merge(e,t){return t?{...e,...t}:e}function isRecord(e){return"object"==typeof e&&null!==e&&!Array.isArray(e)}function readTraceType(e){const t=readString(e);return"request"===t||"tool"===t||"workflow"===t||"spec"===t||"adapter"===t||"memory"===t||"artifact"===t||"progress"===t||"plan"===t||"delegation"===t?t:void 0}function readString(e){return"string"==typeof e&&e.trim()?e:void 0}
|