@tangle-network/agent-runtime 0.44.0 → 0.45.0
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 +95 -203
- package/dist/agent.d.ts +5 -4
- package/dist/agent.js +5 -7
- package/dist/agent.js.map +1 -1
- package/dist/analyst-loop.d.ts +65 -4
- package/dist/analyst-loop.js +6 -1
- package/dist/audit.d.ts +93 -0
- package/dist/audit.js +312 -0
- package/dist/audit.js.map +1 -0
- package/dist/chunk-4B6U4CVQ.js +15 -0
- package/dist/chunk-4B6U4CVQ.js.map +1 -0
- package/dist/chunk-FK53TXOP.js +603 -0
- package/dist/chunk-FK53TXOP.js.map +1 -0
- package/dist/{chunk-SKUZZCHE.js → chunk-IJ6FGOPO.js} +5 -5
- package/dist/chunk-IJ6FGOPO.js.map +1 -0
- package/dist/{chunk-HVYOHJHK.js → chunk-IJGS6J7X.js} +2 -2
- package/dist/chunk-IJGS6J7X.js.map +1 -0
- package/dist/chunk-KEWO4KI6.js +3599 -0
- package/dist/chunk-KEWO4KI6.js.map +1 -0
- package/dist/{chunk-NRZOXCJK.js → chunk-KSMX62JF.js} +2 -2
- package/dist/{chunk-GFKVVRQ7.js → chunk-NYN5RTLP.js} +11 -10
- package/dist/chunk-NYN5RTLP.js.map +1 -0
- package/dist/chunk-PRX45WE2.js +264 -0
- package/dist/chunk-PRX45WE2.js.map +1 -0
- package/dist/{chunk-3HMHSN22.js → chunk-QR4UUC5P.js} +6 -6
- package/dist/chunk-QR4UUC5P.js.map +1 -0
- package/dist/chunk-WIR4HOOJ.js +27 -0
- package/dist/chunk-WIR4HOOJ.js.map +1 -0
- package/dist/{chunk-KDMRUD2P.js → chunk-Z2QXVBA6.js} +296 -8
- package/dist/chunk-Z2QXVBA6.js.map +1 -0
- package/dist/coder-CczgMqFx.d.ts +114 -0
- package/dist/dynamic-BvllHV6M.d.ts +221 -0
- package/dist/{improvement-adapter-BC4HhuAR.d.ts → improvement-adapter-CWegd3vw.d.ts} +1 -1
- package/dist/improvement.d.ts +2 -3
- package/dist/improvement.js +0 -5
- package/dist/improvement.js.map +1 -1
- package/dist/index.d.ts +123 -10
- package/dist/index.js +398 -10
- package/dist/index.js.map +1 -1
- package/dist/{kb-gate-D0ZIhFOU.d.ts → kb-gate-D9GBocLN.d.ts} +82 -5
- package/dist/{loop-runner-bin-BLMa8He3.d.ts → loop-runner-bin-CPrCoKqC.d.ts} +14 -10
- package/dist/loop-runner-bin.d.ts +9 -7
- package/dist/loop-runner-bin.js +6 -8
- package/dist/loops.d.ts +7 -393
- package/dist/loops.js +94 -25
- package/dist/mcp/bin.js +7 -7
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +284 -11
- package/dist/mcp/index.js +341 -9
- package/dist/mcp/index.js.map +1 -1
- package/dist/{otel-export-wFDmmurL.d.ts → otel-export-Dy2DyUCU.d.ts} +1 -1
- package/dist/profiles.d.ts +385 -86
- package/dist/profiles.js +549 -4
- package/dist/profiles.js.map +1 -1
- package/dist/{run-loop-C4L1Sted.d.ts → run-loop--hSoIknW.d.ts} +35 -12
- package/dist/runtime-hooks-C7JwKb9E.d.ts +70 -0
- package/dist/runtime.d.ts +1860 -0
- package/dist/runtime.js +114 -0
- package/dist/runtime.js.map +1 -0
- package/dist/substrate-CUgk7F7s.d.ts +77 -0
- package/dist/topology.d.ts +73 -0
- package/dist/topology.js +111 -0
- package/dist/topology.js.map +1 -0
- package/dist/types-1HbsFa7H.d.ts +438 -0
- package/dist/{types-p8dWBIXL.d.ts → types-BtRLF2U3.d.ts} +1 -1
- package/dist/{types-DbJzz2uf.d.ts → types-DdzkffAm.d.ts} +95 -1
- package/dist/workflow.d.ts +3 -2
- package/dist/workflow.js +4 -5
- package/dist/workflow.js.map +1 -1
- package/package.json +26 -6
- package/skills/agent-runtime-adoption/SKILL.md +29 -26
- package/dist/chunk-3HMHSN22.js.map +0 -1
- package/dist/chunk-GFKVVRQ7.js.map +0 -1
- package/dist/chunk-HVYOHJHK.js.map +0 -1
- package/dist/chunk-KDMRUD2P.js.map +0 -1
- package/dist/chunk-PY6NMZYX.js +0 -52
- package/dist/chunk-PY6NMZYX.js.map +0 -1
- package/dist/chunk-S7JXV32P.js +0 -947
- package/dist/chunk-S7JXV32P.js.map +0 -1
- package/dist/chunk-SKUZZCHE.js.map +0 -1
- package/dist/chunk-SQSCRJ7U.js +0 -65
- package/dist/chunk-SQSCRJ7U.js.map +0 -1
- package/dist/chunk-VOX6Z3II.js +0 -90
- package/dist/chunk-VOX6Z3II.js.map +0 -1
- package/dist/chunk-XBUG326M.js +0 -261
- package/dist/chunk-XBUG326M.js.map +0 -1
- package/dist/dynamic-wUgp6UKs.d.ts +0 -108
- package/dist/optimize-prompt-D-urF2wW.d.ts +0 -129
- /package/dist/{chunk-NRZOXCJK.js.map → chunk-KSMX62JF.js.map} +0 -0
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@tangle-network/agent-runtime",
|
|
3
|
-
"version": "0.
|
|
4
|
-
"description": "
|
|
3
|
+
"version": "0.45.0",
|
|
4
|
+
"description": "Shared task-lifecycle skeleton for agents: a recursive loop kernel for chat turns, one-shot tasks, and multi-attempt loops, with trace capture and eval-gated self-improvement. Domain behavior lives in adapters; scoring and ship-gates in @tangle-network/agent-eval.",
|
|
5
5
|
"homepage": "https://github.com/tangle-network/agent-runtime#readme",
|
|
6
6
|
"repository": {
|
|
7
7
|
"type": "git",
|
|
@@ -39,11 +39,21 @@
|
|
|
39
39
|
"import": "./dist/agent.js",
|
|
40
40
|
"default": "./dist/agent.js"
|
|
41
41
|
},
|
|
42
|
+
"./runtime": {
|
|
43
|
+
"types": "./dist/runtime.d.ts",
|
|
44
|
+
"import": "./dist/runtime.js",
|
|
45
|
+
"default": "./dist/runtime.js"
|
|
46
|
+
},
|
|
42
47
|
"./loops": {
|
|
43
48
|
"types": "./dist/loops.d.ts",
|
|
44
49
|
"import": "./dist/loops.js",
|
|
45
50
|
"default": "./dist/loops.js"
|
|
46
51
|
},
|
|
52
|
+
"./topology": {
|
|
53
|
+
"types": "./dist/topology.d.ts",
|
|
54
|
+
"import": "./dist/topology.js",
|
|
55
|
+
"default": "./dist/topology.js"
|
|
56
|
+
},
|
|
47
57
|
"./workflow": {
|
|
48
58
|
"types": "./dist/workflow.d.ts",
|
|
49
59
|
"import": "./dist/workflow.js",
|
|
@@ -54,6 +64,11 @@
|
|
|
54
64
|
"import": "./dist/profiles.js",
|
|
55
65
|
"default": "./dist/profiles.js"
|
|
56
66
|
},
|
|
67
|
+
"./audit": {
|
|
68
|
+
"types": "./dist/audit.d.ts",
|
|
69
|
+
"import": "./dist/audit.js",
|
|
70
|
+
"default": "./dist/audit.js"
|
|
71
|
+
},
|
|
57
72
|
"./mcp": {
|
|
58
73
|
"types": "./dist/mcp/index.d.ts",
|
|
59
74
|
"import": "./dist/mcp/index.js",
|
|
@@ -81,14 +96,15 @@
|
|
|
81
96
|
"lint": "biome check src tests examples",
|
|
82
97
|
"lint:fix": "biome check --write src tests examples",
|
|
83
98
|
"typecheck": "tsc --noEmit",
|
|
99
|
+
"typecheck:examples": "tsc --noEmit -p tsconfig.examples.json",
|
|
84
100
|
"verify:package": "node scripts/verify-package-exports.mjs"
|
|
85
101
|
},
|
|
86
|
-
"dependencies": {},
|
|
87
102
|
"devDependencies": {
|
|
88
103
|
"@biomejs/biome": "^2.4.0",
|
|
89
|
-
"@tangle-network/agent-eval": "^0.
|
|
104
|
+
"@tangle-network/agent-eval": "^0.83.0",
|
|
90
105
|
"@tangle-network/sandbox": "^0.4.0",
|
|
91
106
|
"@types/node": "^25.6.0",
|
|
107
|
+
"playwright": "^1.40.0",
|
|
92
108
|
"tsup": "^8.0.0",
|
|
93
109
|
"typescript": "^5.7.0",
|
|
94
110
|
"vitest": "^3.0.0"
|
|
@@ -108,9 +124,10 @@
|
|
|
108
124
|
"license": "MIT",
|
|
109
125
|
"packageManager": "pnpm@10.28.0",
|
|
110
126
|
"peerDependencies": {
|
|
111
|
-
"@tangle-network/agent-eval": ">=0.
|
|
127
|
+
"@tangle-network/agent-eval": ">=0.83.0 <1.0.0",
|
|
112
128
|
"@tangle-network/agent-knowledge": ">=1.3.0 <2.0.0",
|
|
113
|
-
"@tangle-network/sandbox": ">=0.1.2 <0.5.0"
|
|
129
|
+
"@tangle-network/sandbox": ">=0.1.2 <0.5.0",
|
|
130
|
+
"playwright": "^1.40.0"
|
|
114
131
|
},
|
|
115
132
|
"peerDependenciesMeta": {
|
|
116
133
|
"@tangle-network/agent-knowledge": {
|
|
@@ -118,6 +135,9 @@
|
|
|
118
135
|
},
|
|
119
136
|
"@tangle-network/sandbox": {
|
|
120
137
|
"optional": true
|
|
138
|
+
},
|
|
139
|
+
"playwright": {
|
|
140
|
+
"optional": true
|
|
121
141
|
}
|
|
122
142
|
}
|
|
123
143
|
}
|
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
---
|
|
2
2
|
name: agent-runtime-adoption
|
|
3
|
-
description: Adopt @tangle-network/agent-runtime in a product — the driven-loop kernel (runLoop), topology drivers (refine / fanout-vote / dynamic agent-authored), the loopDispatch campaign bridge, MCP delegation, and
|
|
3
|
+
description: Adopt @tangle-network/agent-runtime in a product — the driven-loop kernel (runLoop), topology drivers (refine / fanout-vote / dynamic agent-authored), the loopDispatch campaign bridge, MCP delegation, and the code-surface improvementDriver for agent-eval's selfImprove (the optimization entry point). Self-contained; needs only the published package + @tangle-network/agent-eval. Use when wiring runLoop, choosing a topology driver, optimizing a system/planner prompt or code surface, or exposing delegation tools.
|
|
4
4
|
---
|
|
5
5
|
|
|
6
6
|
# agent-runtime adoption — driven loops, topology drivers, prompt optimization
|
|
@@ -106,30 +106,34 @@ const dispatch = loopCampaignDispatch({
|
|
|
106
106
|
|
|
107
107
|
`loopDispatch` is the `runProfileMatrix` variant (profile is an axis).
|
|
108
108
|
|
|
109
|
-
## Identity-gated
|
|
109
|
+
## Identity-gated optimization — agent-eval's `selfImprove`
|
|
110
110
|
|
|
111
|
-
`@tangle-network/agent-
|
|
112
|
-
agent-
|
|
113
|
-
|
|
114
|
-
|
|
115
|
-
|
|
116
|
-
|
|
117
|
-
|
|
118
|
-
|
|
111
|
+
The optimization entry point is **`selfImprove`** (`@tangle-network/agent-eval/contract`),
|
|
112
|
+
NOT agent-runtime — agent-runtime contributes the code-surface `improvementDriver`
|
|
113
|
+
(`/improvement`, the git-worktree path) you pass to it as `driver` to optimize CODE
|
|
114
|
+
instead of a string. `selfImprove` optimizes any text/config surface (system /
|
|
115
|
+
planner / judge rubric) and is **identity-gated by construction**: it runs evals,
|
|
116
|
+
proposes candidates (default driver `gepaDriver`), and a held-out gate ships a winner
|
|
117
|
+
only if it beats the baseline. `result.winner.surface` is the **baseline unless
|
|
118
|
+
`result.gateDecision === 'ship'`** — so registering a surface for optimization can
|
|
119
|
+
never regress it; it only improves when held-out data earns it.
|
|
119
120
|
|
|
120
121
|
```ts
|
|
121
|
-
import {
|
|
122
|
-
const
|
|
123
|
-
|
|
124
|
-
|
|
125
|
-
scenarios,
|
|
126
|
-
|
|
127
|
-
|
|
122
|
+
import { selfImprove } from '@tangle-network/agent-eval/contract'
|
|
123
|
+
const result = await selfImprove({
|
|
124
|
+
baselineSurface: CURRENT_SYSTEM_PROMPT,
|
|
125
|
+
agent: (surface, scenario, ctx) => runYourThing(surface, scenario), // sandbox / runLoop / direct call
|
|
126
|
+
scenarios,
|
|
127
|
+
judge,
|
|
128
|
+
budget: { holdoutScenarios, generations: 3, populationSize: 2 },
|
|
129
|
+
llm: { baseUrl, apiKey, model: REFLECTION_MODEL }, // drives the default gepaDriver
|
|
130
|
+
// driver? — pass agent-runtime's improvementDriver to optimize CODE (worktree) instead of a string
|
|
131
|
+
// gate? — defaults to a held-out gate; pass defaultProductionGate for red-team hardening
|
|
128
132
|
})
|
|
129
|
-
// use
|
|
133
|
+
// use result.winner.surface unconditionally: it's the baseline until a candidate genuinely wins
|
|
130
134
|
```
|
|
131
135
|
|
|
132
|
-
###
|
|
136
|
+
### selfImprove gotchas — read before wiring
|
|
133
137
|
|
|
134
138
|
- **`gepaDriver` mutates TEXT only**, and its only structural guard is `##` H2
|
|
135
139
|
headings (`preserveSections`) + `maxSentenceEdits`. Make load-bearing sections
|
|
@@ -137,12 +141,11 @@ const { prompt, improved, decision, delta } = await optimizePrompt({
|
|
|
137
141
|
GEPA optimizes the prose, never the envelope/contract.
|
|
138
142
|
- **Scenarios must be domain-real.** Derive them from the surface's own traces /
|
|
139
143
|
ground truth, not from unrelated corpora. Cross-domain examples are noise.
|
|
140
|
-
- **Extend, don't fork.** If the product already wires `
|
|
141
|
-
(e.g. for a main-agent prompt), add the new surface as
|
|
142
|
-
harness rather than bolting on a second optimizer.
|
|
143
|
-
- `
|
|
144
|
-
|
|
145
|
-
real activity.
|
|
144
|
+
- **Extend, don't fork.** If the product already wires `selfImprove` /
|
|
145
|
+
`runImprovementLoop` (e.g. for a main-agent prompt), add the new surface as
|
|
146
|
+
another target in that harness rather than bolting on a second optimizer.
|
|
147
|
+
- `agent` is the only domain seam — the optimizer never assumes how a surface
|
|
148
|
+
runs. Report cost via `ctx.cost` inside it so the integrity guard sees real activity.
|
|
146
149
|
- A live run needs a real backend (`TANGLE_API_KEY` / router, or local
|
|
147
150
|
cli-bridge) and real spend; it is not free.
|
|
148
151
|
|
|
@@ -161,7 +164,7 @@ Mount it on a production `AgentProfile.mcp`; do not re-implement delegation.
|
|
|
161
164
|
`loops/types.ts:Driver` only when none fit — never fork the kernel.
|
|
162
165
|
- [ ] `runLoop` is bridged to campaigns via `loopDispatch` / `loopCampaignDispatch`
|
|
163
166
|
(usage + trace auto-forwarded), not a hand-rolled ExecCtx.
|
|
164
|
-
- [ ] Every optimizable prompt is registered through `
|
|
167
|
+
- [ ] Every optimizable prompt is registered through `selfImprove` (or the
|
|
165
168
|
product's existing `runImprovementLoop`), identity-gated on a held-out set.
|
|
166
169
|
- [ ] Boundaries fail loud: no `null` sandbox client, no silent adapter return,
|
|
167
170
|
no unguarded planner envelope.
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/profiles/coder.ts"],"sourcesContent":["/**\n * @experimental\n *\n * `coderProfile` — opinionated preset for code-modification tasks.\n *\n * The agent is told to:\n * - work on a fresh branch inside the sandbox workspace\n * - keep the patch minimal (under `maxDiffLines`)\n * - avoid `forbiddenPaths`\n * - run `testCmd` and `typecheckCmd`\n * - emit a final JSON result the output adapter parses\n *\n * The profile is stateless and agent-agnostic — `harness` selects the\n * sandbox-SDK backend (`claude-code`, `codex`, `opencode/*`). For\n * heterogeneous fanout, use `multiHarnessCoderFanout`.\n */\n\nimport type { AgentProfile, SandboxEvent } from '@tangle-network/sandbox'\nimport { createFanoutVoteDriver } from '../loops/drivers/fanout-vote'\nimport type { AgentRunSpec, DefaultVerdict, Driver, OutputAdapter, Validator } from '../loops/types'\n\nconst DEFAULT_MAX_DIFF_LINES = 400\n\n/** @experimental */\nexport interface CoderTask {\n /** What the agent must accomplish. Free-form prose. */\n goal: string\n /** Absolute path inside the sandbox where the repo lives. */\n repoRoot: string\n /** Default `main`. The branch the agent diffs against. */\n baseBranch?: string\n /** Default `pnpm test --run`. */\n testCmd?: string\n /** Default `pnpm typecheck`. */\n typecheckCmd?: string\n /** Files the agent may inspect for context. Surfaced verbatim in the prompt. */\n contextFiles?: string[]\n /**\n * Paths the agent must not touch. Validator hard-fails on any match.\n * Use glob-free literal path prefixes for unambiguous enforcement.\n */\n forbiddenPaths?: string[]\n /** Default 400. Hard cap; validator hard-fails when exceeded. */\n maxDiffLines?: number\n}\n\n/** @experimental */\nexport interface CoderOutput {\n /** Branch the agent wrote the patch on. */\n branch: string\n /** Unified diff (`git diff <base>..HEAD`). */\n patch: string\n testResult: { passed: boolean; output: string }\n typecheckResult: { passed: boolean; output: string }\n diffStats: { filesChanged: number; insertions: number; deletions: number }\n /** Optional reviewer commentary surfaced by the agent. */\n reviewerNotes?: string\n}\n\n/** @experimental */\nexport interface CoderProfileOptions {\n /** Sandbox-SDK backend.type. Default `'claude-code'`. */\n harness?: string\n /** Default model id passed in `AgentProfile.model.default`. */\n model?: string\n /** Custom system prompt replacement. Default = built-in coder preset. */\n systemPrompt?: string\n /** Stable name for `AgentRunSpec.name`. Default = `coder-${harness}`. */\n name?: string\n}\n\n/**\n * Build a coder preset.\n *\n * `validator` enforces test + typecheck + a 400-line default diff cap. For\n * per-task `forbiddenPaths` / `maxDiffLines` enforcement, pass `task` here\n * — the returned validator closes over its constraints. Without a task\n * the validator falls back to the default cap and skips path enforcement.\n *\n * @experimental\n */\nexport function coderProfile(options: CoderProfileOptions & { task?: CoderTask } = {}): {\n profile: AgentProfile\n taskToPrompt: (task: CoderTask) => string\n output: OutputAdapter<CoderOutput>\n validator: Validator<CoderOutput>\n agentRunSpec: AgentRunSpec<CoderTask>\n} {\n const harness = options.harness ?? 'claude-code'\n const name = options.name ?? `coder-${harness}`\n const systemPrompt = options.systemPrompt ?? DEFAULT_CODER_SYSTEM_PROMPT\n const profile: AgentProfile = {\n name,\n description: 'Code-modification agent. Minimal-diff worktree-based coder.',\n prompt: { systemPrompt },\n model: options.model ? { default: options.model } : undefined,\n tools: { git: true, fs: true, shell: true, test_runner: true },\n metadata: { backendType: harness, role: 'coder' },\n }\n const output: OutputAdapter<CoderOutput> = { parse: parseCoderEvents }\n const validator: Validator<CoderOutput> = options.task\n ? createCoderValidator(options.task)\n : createCoderValidator({\n goal: '',\n repoRoot: '',\n forbiddenPaths: [],\n maxDiffLines: DEFAULT_MAX_DIFF_LINES,\n })\n const agentRunSpec: AgentRunSpec<CoderTask> = {\n name,\n profile,\n taskToPrompt: formatCoderPrompt,\n }\n return { profile, taskToPrompt: formatCoderPrompt, output, validator, agentRunSpec }\n}\n\n/** @experimental */\nexport interface MultiHarnessCoderFanoutOptions {\n /**\n * Sandbox-SDK backend.type identifiers, one per parallel agent. Default:\n * `['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']`.\n */\n harnesses?: string[]\n /** Optional per-harness model override. Indexed parallel to `harnesses`. */\n models?: (string | undefined)[]\n}\n\n/** @experimental */\nexport function multiHarnessCoderFanout(options: MultiHarnessCoderFanoutOptions = {}): {\n agentRuns: AgentRunSpec<CoderTask>[]\n output: OutputAdapter<CoderOutput>\n validator: Validator<CoderOutput>\n driver: Driver<CoderTask, CoderOutput, 'pick-winner' | 'fail'>\n} {\n const harnesses =\n options.harnesses && options.harnesses.length > 0\n ? options.harnesses\n : ['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']\n const models = options.models ?? []\n const agentRuns = harnesses.map((harness, i) => {\n const { agentRunSpec } = coderProfile({ harness, model: models[i] })\n return agentRunSpec\n })\n const { output, validator } = coderProfile()\n const driver = createFanoutVoteDriver<CoderTask, CoderOutput>({ n: harnesses.length })\n return { agentRuns, output, validator, driver }\n}\n\nconst DEFAULT_CODER_SYSTEM_PROMPT = [\n 'You are a coder agent operating inside an isolated sandbox workspace.',\n 'Your job is to deliver a minimal, correct patch for the user-supplied goal.',\n '',\n 'Hard rules:',\n ' 1. Work on a fresh branch off the supplied base. Do not mutate the base branch.',\n ' 2. Never touch a forbidden path. The user will list them explicitly.',\n ' 3. Keep the diff under the max-diff cap. Prefer the smallest change that ships.',\n ' 4. Run the supplied test and typecheck commands before declaring done.',\n ' 5. If either command fails, fix the cause — do not weaken the test or hide the error.',\n '',\n 'When you finish, emit a single final structured message of the shape:',\n ' ```json',\n ' { \"branch\": \"<branch-name>\",',\n ' \"patch\": \"<unified-diff>\",',\n ' \"testResult\": { \"passed\": <bool>, \"output\": \"<stdout/stderr>\" },',\n ' \"typecheckResult\": { \"passed\": <bool>, \"output\": \"<stdout/stderr>\" },',\n ' \"diffStats\": { \"filesChanged\": <int>, \"insertions\": <int>, \"deletions\": <int> },',\n ' \"reviewerNotes\": \"<optional commentary>\" }',\n ' ```',\n].join('\\n')\n\nfunction formatCoderPrompt(task: CoderTask): string {\n const base = task.baseBranch ?? 'main'\n const testCmd = task.testCmd ?? 'pnpm test --run'\n const typecheckCmd = task.typecheckCmd ?? 'pnpm typecheck'\n const maxDiff = task.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES\n const forbidden = task.forbiddenPaths?.length ? task.forbiddenPaths.join(', ') : '(none)'\n const context = task.contextFiles?.length\n ? task.contextFiles.map((f) => ` - ${f}`).join('\\n')\n : ' (none)'\n return [\n `Goal: ${task.goal}`,\n `Repo: ${task.repoRoot}`,\n `Base branch: ${base}`,\n `Run tests with: ${testCmd}`,\n `Run typecheck with: ${typecheckCmd}`,\n `Forbidden paths: ${forbidden}`,\n `Max diff lines: ${maxDiff}`,\n 'Context files:',\n context,\n '',\n 'Produce a minimal patch on a fresh branch. Run tests and typecheck before',\n 'returning. Emit the final JSON result block exactly as instructed.',\n ].join('\\n')\n}\n\n/**\n * Walk the event stream and return the last structured `coder.result` payload.\n *\n * The agent is instructed to emit a JSON block; in practice the sandbox SDK\n * lifts the structured payload onto `data.result` of a `result` / `final`\n * event. When the event stream does not contain a structured result, the\n * adapter scans text deltas for a fenced JSON block matching the expected\n * keys. Both shapes converge on `CoderOutput`.\n */\nfunction parseCoderEvents(events: SandboxEvent[]): CoderOutput {\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const type = String(event.type ?? '')\n const data = isRecord(event.data) ? event.data : {}\n if (type === 'result' || type === 'final' || type === 'coder.result') {\n const direct = coerceCoderOutput(data.result ?? data.output ?? data)\n if (direct) return direct\n }\n }\n // Fallback: scan text deltas in reverse for a fenced JSON block.\n for (let i = events.length - 1; i >= 0; i -= 1) {\n const event = events[i]\n if (!event) continue\n const data = isRecord(event.data) ? event.data : {}\n const text = pickString(data.text) ?? pickString(data.delta)\n if (!text) continue\n const fenced = extractFencedJson(text)\n if (!fenced) continue\n const coerced = coerceCoderOutput(fenced)\n if (coerced) return coerced\n }\n return {\n branch: '',\n patch: '',\n testResult: { passed: false, output: '' },\n typecheckResult: { passed: false, output: '' },\n diffStats: { filesChanged: 0, insertions: 0, deletions: 0 },\n }\n}\n\n/**\n * Build a validator that closes over a specific `CoderTask`'s constraints.\n *\n * Checks in order:\n * 1. Forbidden-path: any `+++` / `---` header in the patch matching a\n * path prefix in `task.forbiddenPaths` fails hard.\n * 2. Diff size: line count above `task.maxDiffLines` (default 400) fails\n * hard; below cap, the score shrinks linearly.\n * 3. Tests: `output.testResult.passed` must be `true`.\n * 4. Typecheck: `output.typecheckResult.passed` must be `true`.\n *\n * Aggregate score: `0.5 * tests + 0.3 * typecheck + 0.2 * (1 - diffLines/maxDiff)`.\n * `valid` is the conjunction of all four.\n *\n * @experimental\n */\n/**\n * Default-on safety floor (folded from the ai-trading-blueprint delegation\n * MCP): a coder patch that touches a credential-shaped path is rejected\n * regardless of `forbiddenPaths` config. Catches `.env`, private keys,\n * keystores, wallets, and the common secret/credential JSON files.\n */\nconst SECRET_PATH_RE =\n /(^|\\/)(\\.env(\\.|$)|.*\\.(pem|key|p12|pfx|keystore|wallet)|id_rsa|id_ed25519|secrets?\\.json|credentials?\\.json)$/i\n\nexport function createCoderValidator(task: CoderTask): Validator<CoderOutput> {\n const maxDiff = task.maxDiffLines ?? DEFAULT_MAX_DIFF_LINES\n const forbidden = task.forbiddenPaths ?? []\n return {\n async validate(output) {\n const scores: Record<string, number> = {}\n const notes: string[] = []\n let pass = true\n\n const touched = touchedPathsFromPatch(output.patch)\n\n // No-op rejection: an empty patch can trivially \"pass\" tests/typecheck\n // (nothing changed) yet does no work — never a valid coder result.\n if (touched.length === 0 || output.patch.trim().length === 0) {\n pass = false\n scores.nonEmpty = 0\n notes.push('empty patch — no files changed')\n } else {\n scores.nonEmpty = 1\n }\n\n // Secret-path floor: always-on, independent of `forbiddenPaths`.\n const touchedSecrets = touched.filter((p) => SECRET_PATH_RE.test(p))\n if (touchedSecrets.length > 0) {\n pass = false\n scores.noSecrets = 0\n notes.push(`touched secret-shaped paths: ${touchedSecrets.join(', ')}`)\n } else {\n scores.noSecrets = 1\n }\n\n const touchedForbidden = forbidden.filter((path) => {\n const prefix = path.endsWith('/') ? path : `${path}/`\n const exact = prefix.slice(0, -1)\n return touched.some((p) => p === exact || p.startsWith(prefix))\n })\n if (touchedForbidden.length > 0) {\n pass = false\n scores.forbiddenPath = 0\n notes.push(`touched forbidden paths: ${touchedForbidden.join(', ')}`)\n } else {\n scores.forbiddenPath = 1\n }\n\n const diffLines = countDiffLines(output.patch)\n if (diffLines > maxDiff) {\n pass = false\n scores.diffSize = 0\n notes.push(`diff ${diffLines} lines exceeds cap ${maxDiff}`)\n } else {\n scores.diffSize = maxDiff === 0 ? 0 : Math.max(0, 1 - diffLines / maxDiff)\n }\n\n scores.tests = output.testResult.passed ? 1 : 0\n scores.typecheck = output.typecheckResult.passed ? 1 : 0\n if (!output.testResult.passed) {\n pass = false\n notes.push('tests failed')\n }\n if (!output.typecheckResult.passed) {\n pass = false\n notes.push('typecheck failed')\n }\n\n const score = 0.5 * scores.tests + 0.3 * scores.typecheck + 0.2 * scores.diffSize\n const verdict: DefaultVerdict = {\n valid: pass,\n score: Number.isFinite(score) ? score : 0,\n scores,\n }\n if (notes.length > 0) verdict.notes = notes.join('; ')\n return verdict\n },\n }\n}\n\nfunction touchedPathsFromPatch(patch: string): string[] {\n const out = new Set<string>()\n for (const line of patch.split(/\\r?\\n/)) {\n if (line.startsWith('+++ ') || line.startsWith('--- ')) {\n const rest = line.slice(4).trim()\n if (rest === '/dev/null') continue\n const stripped = rest.startsWith('a/') || rest.startsWith('b/') ? rest.slice(2) : rest\n out.add(stripped)\n }\n }\n return [...out]\n}\n\nfunction countDiffLines(patch: string): number {\n let count = 0\n for (const line of patch.split(/\\r?\\n/)) {\n if (\n (line.startsWith('+') || line.startsWith('-')) &&\n !line.startsWith('+++') &&\n !line.startsWith('---')\n ) {\n count += 1\n }\n }\n return count\n}\n\nfunction isRecord(value: unknown): value is Record<string, unknown> {\n return value !== null && typeof value === 'object' && !Array.isArray(value)\n}\n\nfunction pickString(value: unknown): string | undefined {\n return typeof value === 'string' && value.length > 0 ? value : undefined\n}\n\nfunction extractFencedJson(text: string): unknown | undefined {\n const match = text.match(/```(?:json)?\\s*([\\s\\S]*?)```/i)\n if (!match) return undefined\n const body = (match[1] ?? '').trim()\n if (!body) return undefined\n try {\n return JSON.parse(body)\n } catch {\n return undefined\n }\n}\n\nfunction coerceCoderOutput(value: unknown): CoderOutput | undefined {\n if (!isRecord(value)) return undefined\n const branch = pickString(value.branch)\n const patch = pickString(value.patch) ?? ''\n if (branch === undefined) return undefined\n const testResult = coerceCmdResult(value.testResult)\n const typecheckResult = coerceCmdResult(value.typecheckResult)\n const diffStats = coerceDiffStats(value.diffStats)\n return {\n branch,\n patch,\n testResult,\n typecheckResult,\n diffStats,\n reviewerNotes: pickString(value.reviewerNotes),\n }\n}\n\nfunction coerceCmdResult(value: unknown): { passed: boolean; output: string } {\n if (!isRecord(value)) return { passed: false, output: '' }\n return {\n passed: value.passed === true,\n output: pickString(value.output) ?? '',\n }\n}\n\nfunction coerceDiffStats(value: unknown): {\n filesChanged: number\n insertions: number\n deletions: number\n} {\n if (!isRecord(value)) return { filesChanged: 0, insertions: 0, deletions: 0 }\n return {\n filesChanged: toFiniteInt(value.filesChanged),\n insertions: toFiniteInt(value.insertions),\n deletions: toFiniteInt(value.deletions),\n }\n}\n\nfunction toFiniteInt(value: unknown): number {\n if (typeof value !== 'number') return 0\n if (!Number.isFinite(value)) return 0\n return Math.max(0, Math.trunc(value))\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/loop-runner.ts","../src/loop-runner-bin.ts"],"sourcesContent":["/**\n * @experimental\n *\n * `runDelegatedLoop` — the configured delegated loop-runner.\n *\n * One typed entrypoint a worker agent (or a scheduled routine) calls to run a\n * disciplined loop in a chosen MODE, over agent-runtime's hardened engines:\n *\n * code → build-in-a-loop via the coder delegate (no-op + secret floor,\n * optional reviewer gate, winner-selection)\n * review → code mode with a REQUIRED reviewer (the gate is the point)\n * research → research-in-a-loop with valid-only KB growth (createKbGate)\n * audit → analyze trace/run data → findings (runAnalystLoop, caller-wired)\n * self-improve → identity-gated prompt optimization (optimizePrompt, caller-wired)\n * dynamic → agent-authored topology (runLoop + createDynamicDriver)\n *\n * It is intentionally a thin façade: the value is that EVERY product reuses the\n * one hardened engine instead of forking delegation logic. The dispatcher owns\n * mode routing, timing, fail-loud on an unregistered mode, and a uniform result\n * shape; each mode's engine is a pre-configured runner in the registry (build it\n * with the factories below, or inject your own / a stub).\n */\n\nimport type { Scenario } from '@tangle-network/agent-eval/campaign'\nimport { runAnalystLoop } from './analyst-loop'\nimport type { RunAnalystLoopOpts, RunAnalystLoopResult } from './analyst-loop/types'\nimport { ConfigError } from './errors'\nimport {\n type OptimizePromptOptions,\n type OptimizePromptResult,\n optimizePrompt,\n} from './improvement/optimize-prompt'\nimport {\n type AgentRunSpec,\n createDynamicDriver,\n type DynamicDecision,\n type LoopResult,\n type LoopSandboxClient,\n type OutputAdapter,\n runLoop,\n type TopologyPlanner,\n type Validator,\n} from './loops'\nimport {\n type CoderReviewer,\n type CoderWinnerSelection,\n createDefaultCoderDelegate,\n type DelegateRunCtx,\n} from './mcp/delegates'\nimport { type CreateKbGateOptions, createKbGate, type FactCandidate } from './mcp/kb-gate'\nimport type { DelegateCodeArgs } from './mcp/types'\nimport type { CoderOutput } from './profiles/coder'\n\n/** @experimental Every delegated-loop mode, for validation + CLI surfaces. */\nexport const DELEGATED_LOOP_MODES = [\n 'code',\n 'review',\n 'research',\n 'audit',\n 'self-improve',\n 'dynamic',\n] as const\n\n/** @experimental */\nexport type DelegatedLoopMode = (typeof DELEGATED_LOOP_MODES)[number]\n\n/** @experimental Type guard for an untrusted mode string (CLI / config input). */\nexport function isDelegatedLoopMode(value: unknown): value is DelegatedLoopMode {\n return typeof value === 'string' && (DELEGATED_LOOP_MODES as readonly string[]).includes(value)\n}\n\n/** @experimental A pre-configured loop for one mode. Returns the mode's raw\n * output; the dispatcher wraps it in a {@link DelegatedLoopResult}. */\nexport type DelegatedLoopRunner<T = unknown> = (signal: AbortSignal) => Promise<T>\n\n/** @experimental Mode → configured runner. Partial: only register the modes a\n * given product/routine actually uses. */\nexport type DelegatedLoopRegistry = Partial<Record<DelegatedLoopMode, DelegatedLoopRunner>>\n\n/** @experimental Uniform result — never throws from a registered runner; a\n * thrown engine becomes `{ ok: false, error }` so a routine can record + move on. */\nexport interface DelegatedLoopResult<T = unknown> {\n mode: DelegatedLoopMode\n ok: boolean\n output?: T\n error?: string\n durationMs: number\n}\n\n/** @experimental */\nexport interface RunDelegatedLoopOptions {\n signal?: AbortSignal\n /** Clock override for deterministic tests. */\n now?: () => number\n}\n\n/**\n * @experimental\n *\n * Dispatch a configured loop by mode. Fails loud (throws `ConfigError`) when no\n * runner is registered for the mode — a routine pointed at an unwired mode is a\n * config bug, not a silent no-op. A runner that throws is captured as\n * `{ ok: false }` so unattended runs record the failure rather than crash.\n */\nexport async function runDelegatedLoop<T = unknown>(\n mode: DelegatedLoopMode,\n registry: DelegatedLoopRegistry,\n options: RunDelegatedLoopOptions = {},\n): Promise<DelegatedLoopResult<T>> {\n const runner = registry[mode] as DelegatedLoopRunner<T> | undefined\n if (!runner) {\n throw new ConfigError(\n `runDelegatedLoop: no runner registered for mode '${mode}' (registered: ${\n Object.keys(registry).join(', ') || 'none'\n })`,\n )\n }\n const now = options.now ?? Date.now\n const signal = options.signal ?? new AbortController().signal\n const start = now()\n try {\n const output = await runner(signal)\n return { mode, ok: true, output, durationMs: now() - start }\n } catch (err) {\n return {\n mode,\n ok: false,\n error: err instanceof Error ? err.message : String(err),\n durationMs: now() - start,\n }\n }\n}\n\n/** @experimental Options for the default `code`/`review` runner. */\nexport interface CoderLoopRunnerOptions {\n sandboxClient: LoopSandboxClient\n /** What to build — the delegate args (goal, repoRoot, variants, config, …). */\n args: DelegateCodeArgs\n /** Adversarial reviewer. REQUIRED for `review` mode (see `reviewLoopRunner`). */\n reviewer?: CoderReviewer\n /** Winner-selection strategy. Default `highest-score`. */\n winnerSelection?: CoderWinnerSelection\n /** Harnesses for `variants > 1` fanout. */\n fanoutHarnesses?: string[]\n}\n\n/** @experimental Build a `code`-mode runner over the hardened coder delegate. */\nexport function coderLoopRunner(options: CoderLoopRunnerOptions): DelegatedLoopRunner<CoderOutput> {\n const delegate = createDefaultCoderDelegate({\n sandboxClient: options.sandboxClient,\n ...(options.reviewer ? { reviewer: options.reviewer } : {}),\n ...(options.winnerSelection ? { winnerSelection: options.winnerSelection } : {}),\n ...(options.fanoutHarnesses ? { fanoutHarnesses: options.fanoutHarnesses } : {}),\n })\n return async (signal) => {\n const ctx: DelegateRunCtx = { signal, report: () => {} }\n return delegate(options.args, ctx)\n }\n}\n\n/**\n * @experimental\n *\n * `review` mode = `code` with a REQUIRED reviewer. The gate is the whole point,\n * so the type forces a reviewer (a \"review loop\" with no reviewer is a code loop).\n */\nexport function reviewLoopRunner(\n options: CoderLoopRunnerOptions & { reviewer: CoderReviewer },\n): DelegatedLoopRunner<CoderOutput> {\n return coderLoopRunner(options)\n}\n\n/** @experimental Options for the default `dynamic` runner. */\nexport interface DynamicLoopRunnerOptions<Task, Output> {\n sandboxClient: LoopSandboxClient\n /** The agent-authored topology planner (e.g. `createSandboxPlanner(...)`). */\n planner: TopologyPlanner<Task, Output>\n task: Task\n output: OutputAdapter<Output>\n validator?: Validator<Output>\n /** Exactly one of `agentRun` / `agentRuns` (runLoop validates). */\n agentRun?: AgentRunSpec<Task>\n agentRuns?: AgentRunSpec<Task>[]\n maxIterations?: number\n maxFanout?: number\n}\n\n/** @experimental `dynamic` mode — agent-authored topology over `runLoop`. */\nexport function dynamicLoopRunner<Task, Output>(\n o: DynamicLoopRunnerOptions<Task, Output>,\n): DelegatedLoopRunner<LoopResult<Task, Output, DynamicDecision>> {\n return async (signal) =>\n runLoop<Task, Output, DynamicDecision>({\n driver: createDynamicDriver<Task, Output>({\n planner: o.planner,\n ...(o.maxIterations !== undefined ? { maxIterations: o.maxIterations } : {}),\n ...(o.maxFanout !== undefined ? { maxFanout: o.maxFanout } : {}),\n }),\n ...(o.agentRun ? { agentRun: o.agentRun } : {}),\n ...(o.agentRuns ? { agentRuns: o.agentRuns } : {}),\n output: o.output,\n ...(o.validator ? { validator: o.validator } : {}),\n task: o.task,\n ctx: { sandboxClient: o.sandboxClient, signal },\n ...(o.maxIterations !== undefined ? { maxIterations: o.maxIterations } : {}),\n })\n}\n\n/** @experimental A fact rejected at the KB gate — surfaced, never dropped. */\nexport interface VetoedFact {\n candidate: FactCandidate\n vetoedBy?: string\n reason?: string\n}\n\n/** @experimental */\nexport interface ResearchLoopResult {\n /** Facts that passed the fail-closed gate — safe to write to the KB. */\n accepted: FactCandidate[]\n /** Facts the gate vetoed in the final round — escalate, do not silently drop. */\n vetoed: VetoedFact[]\n /** Research rounds actually run. */\n rounds: number\n}\n\n/** @experimental Options for the default `research` runner. */\nexport interface ResearchLoopRunnerOptions {\n /**\n * The research engine (the consumer's web/doc searcher + extractor). Called\n * each round with the prior round's vetoes so it can re-research the gaps.\n * Returns fact candidates carrying their grounding (`verbatimPassage` +\n * `sourceText`).\n */\n research: (round: number, vetoed: VetoedFact[]) => Promise<FactCandidate[]>\n /** Gate config (extra judges, self-artifact kinds, …). The floor is always on. */\n gate?: CreateKbGateOptions\n /** Max research rounds (correct-on-veto remediation). Default 1. */\n maxRounds?: number\n}\n\n/**\n * @experimental `research` mode — research-in-a-loop with valid-only KB growth.\n *\n * Each round: research → gate every candidate (fail-closed; passage MUST be in\n * the source) → accept the clean ones → re-research the vetoed ones next round,\n * up to `maxRounds`. Vetoed facts in the final round are RETURNED (escalate,\n * never silently dropped) so the caller audits vs retries.\n */\nexport function researchLoopRunner(\n o: ResearchLoopRunnerOptions,\n): DelegatedLoopRunner<ResearchLoopResult> {\n const gate = createKbGate(o.gate)\n const maxRounds = Math.max(1, Math.trunc(o.maxRounds ?? 1))\n return async (signal) => {\n const accepted: FactCandidate[] = []\n let vetoed: VetoedFact[] = []\n let rounds = 0\n for (let round = 0; round < maxRounds; round += 1) {\n if (signal.aborted) break\n rounds += 1\n const candidates = await o.research(round, vetoed)\n if (candidates.length === 0) break\n vetoed = []\n for (const c of candidates) {\n const v = await gate(c)\n if (v.accepted) accepted.push(c)\n else vetoed.push({ candidate: c, vetoedBy: v.vetoedBy, reason: v.reason })\n }\n if (vetoed.length === 0) break\n }\n return { accepted, vetoed, rounds }\n }\n}\n\n/** @experimental `self-improve` mode — identity-gated prompt optimization. */\nexport function selfImproveLoopRunner<TScenario extends Scenario, TArtifact>(\n options: OptimizePromptOptions<TScenario, TArtifact>,\n): DelegatedLoopRunner<OptimizePromptResult<TArtifact, TScenario>> {\n return async () => optimizePrompt<TScenario, TArtifact>(options)\n}\n\n/** @experimental `audit` mode — analyst loop over captured trace/run data. */\nexport function auditLoopRunner<TProposal = unknown, TEdit = unknown>(\n options: RunAnalystLoopOpts,\n): DelegatedLoopRunner<RunAnalystLoopResult<TProposal, TEdit>> {\n return async () => runAnalystLoop<TProposal, TEdit>(options)\n}\n","#!/usr/bin/env node\n/**\n * @experimental\n *\n * `agent-runtime-loop` — the schedulable entrypoint for the configured\n * delegated loop-runner. A cron job / routine / Makefile target invokes:\n *\n * agent-runtime-loop --mode research --config ./loops.config.js\n *\n * The config module wires the registry (with full access to env / creds —\n * which is why the deps live there, not in this generic bin). It must default-\n * export a `DelegatedLoopRegistry`, or a `() => DelegatedLoopRegistry | Promise<…>`.\n * The bin runs the selected mode, prints the `DelegatedLoopResult` as JSON, and\n * exits 0 on `ok`, 1 on a recorded failure, 2 on a usage/config error.\n */\n\nimport {\n DELEGATED_LOOP_MODES,\n type DelegatedLoopMode,\n type DelegatedLoopRegistry,\n type DelegatedLoopResult,\n isDelegatedLoopMode,\n runDelegatedLoop,\n} from './loop-runner'\n\n/** @experimental Parsed CLI invocation. */\nexport interface LoopRunnerCliArgs {\n mode: string\n /** Loads the registry — the bin wires this from `--config`; tests inject a stub. */\n loadRegistry: () => Promise<DelegatedLoopRegistry> | DelegatedLoopRegistry\n now?: () => number\n}\n\n/** @experimental */\nexport interface LoopRunnerCliResult {\n exitCode: number\n result?: DelegatedLoopResult\n error?: string\n}\n\n/**\n * @experimental\n *\n * Pure CLI core (no process / argv / IO) so it's unit-testable: validate the\n * mode, load the registry, dispatch, map to an exit code (0 ok / 1 failed /\n * 2 usage). Exported for embedding in custom runners + tests.\n */\nexport async function runLoopRunnerCli(args: LoopRunnerCliArgs): Promise<LoopRunnerCliResult> {\n if (!isDelegatedLoopMode(args.mode)) {\n return {\n exitCode: 2,\n error: `unknown mode '${args.mode}' (expected one of: ${DELEGATED_LOOP_MODES.join(', ')})`,\n }\n }\n let registry: DelegatedLoopRegistry\n try {\n registry = await args.loadRegistry()\n } catch (err) {\n return { exitCode: 2, error: `failed to load registry: ${errMsg(err)}` }\n }\n if (!registry[args.mode]) {\n return {\n exitCode: 2,\n error: `config registers no runner for mode '${args.mode}' (registered: ${\n Object.keys(registry).join(', ') || 'none'\n })`,\n }\n }\n // runDelegatedLoop throws only on a missing runner (guarded above); a failing\n // engine is captured as { ok: false } → exit 1, not a crash.\n const result = await runDelegatedLoop(args.mode as DelegatedLoopMode, registry, {\n ...(args.now ? { now: args.now } : {}),\n })\n return { exitCode: result.ok ? 0 : 1, result }\n}\n\n/** Parse `--mode X --config Y` from an argv tail (`process.argv.slice(2)`). */\nexport function parseLoopRunnerArgv(argv: string[]): { mode?: string; config?: string } {\n const out: { mode?: string; config?: string } = {}\n for (let i = 0; i < argv.length; i += 1) {\n const a = argv[i]\n if (a === '--mode') out.mode = argv[++i]\n else if (a === '--config') out.config = argv[++i]\n else if (a?.startsWith('--mode=')) out.mode = a.slice('--mode='.length)\n else if (a?.startsWith('--config=')) out.config = a.slice('--config='.length)\n }\n return out\n}\n\n/** Normalize a config module's default export → a registry. */\nfunction resolveRegistry(mod: unknown): DelegatedLoopRegistry {\n const def = (mod as { default?: unknown })?.default ?? mod\n const value = typeof def === 'function' ? (def as () => unknown)() : def\n return value as DelegatedLoopRegistry\n}\n\nfunction errMsg(err: unknown): string {\n return err instanceof Error ? err.message : String(err)\n}\n\n/** The argv → IO → exit shell. Kept thin; logic lives in `runLoopRunnerCli`. */\nasync function main(): Promise<void> {\n const { mode, config } = parseLoopRunnerArgv(process.argv.slice(2))\n if (!mode || !config) {\n process.stderr.write(\n 'usage: agent-runtime-loop --mode <mode> --config <module>\\n' +\n ` modes: ${DELEGATED_LOOP_MODES.join(' | ')}\\n` +\n ' config: a JS/TS module default-exporting a DelegatedLoopRegistry (or a factory)\\n',\n )\n process.exit(2)\n }\n const { pathToFileURL } = await import('node:url')\n const { resolve } = await import('node:path')\n const cli = await runLoopRunnerCli({\n mode,\n loadRegistry: async () => resolveRegistry(await import(pathToFileURL(resolve(config)).href)),\n })\n process.stdout.write(`${JSON.stringify(cli.result ?? { error: cli.error }, null, 2)}\\n`)\n if (cli.error) process.stderr.write(`${cli.error}\\n`)\n process.exit(cli.exitCode)\n}\n\n// Run only when executed as the bin — never when imported for the testable\n// core, and never when bundled into a runtime that has no `process.argv`\n// (e.g. Cloudflare Workers, where `process` is a shim without `argv`). Reading\n// `process.argv[1]` directly would throw at module load there; `process.argv?.`\n// keeps the guard a no-op instead of crashing the Worker on startup.\nconst invokedScript = typeof process !== 'undefined' ? process.argv?.[1] : undefined\nif (invokedScript && /loop-runner-bin\\.(js|ts|mjs)$/.test(invokedScript)) {\n void main()\n}\n"],"mappings":"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","names":[]}
|
|
@@ -1 +0,0 @@
|
|
|
1
|
-
{"version":3,"sources":["../src/mcp/task-queue.ts","../src/mcp/tools/delegate-code.ts","../src/mcp/feedback-store.ts","../src/mcp/tools/delegate-feedback.ts","../src/mcp/tools/delegate-research.ts","../src/mcp/tools/delegation-history.ts","../src/mcp/tools/delegation-status.ts","../src/otel-export.ts"],"sourcesContent":["/**\n * @experimental\n *\n * In-memory state for async MCP delegations. State machine:\n *\n * pending → running → completed | failed\n * ↘ cancelled (from any non-terminal state via cancel())\n *\n * Each `submit` returns a `taskId` immediately and kicks the work off in the\n * background. The work function receives an `AbortSignal` the queue fires\n * when `cancel(taskId)` is called. The queue does NOT supervise runtime\n * timeouts — the underlying `runLoop` driver / sandbox imposes those.\n *\n * Idempotency: callers may supply an `idempotencyKey` (hash of the input).\n * A duplicate `submit` with a known key returns the existing task instead of\n * starting a new one. Mutated input → different key → different task.\n *\n * Persistent state (sqlite) is a Phase 2 follow-up. The README documents the\n * in-memory limitation explicitly so consumers know a worker restart drops\n * pending delegations.\n */\n\nimport type {\n DelegateCodeArgs,\n DelegateResearchArgs,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusResult,\n} from './types'\n\n/** @experimental */\nexport interface DelegationRecord {\n taskId: string\n profile: DelegationProfile\n namespace?: string\n args: DelegateCodeArgs | DelegateResearchArgs\n status: DelegationStatus\n progress?: DelegationProgress\n result?: DelegationResultPayload\n error?: DelegationError\n costUsd?: number\n startedAt: string\n completedAt?: string\n /** Sha-prefix hash of the canonical input — used for idempotency lookup. */\n idempotencyKey?: string\n /** Feedback events keyed by this delegation's taskId. */\n feedback: DelegationFeedbackSnapshot[]\n}\n\n/** @experimental */\nexport interface SubmitInput<Args extends DelegateCodeArgs | DelegateResearchArgs> {\n profile: DelegationProfile\n args: Args\n namespace?: string\n idempotencyKey?: string\n /**\n * Runs the underlying delegation. The queue passes a fresh `AbortSignal`\n * and a `report` channel for incremental progress updates. The function\n * MUST resolve with the typed `DelegationResultPayload['output']`; the\n * queue wraps it with the profile tag.\n */\n run: (ctx: {\n signal: AbortSignal\n report(progress: DelegationProgress): void\n }) => Promise<DelegationResultPayload['output']>\n}\n\n/** @experimental */\nexport interface SubmitOutput {\n taskId: string\n /** True when a prior matching `idempotencyKey` returned an existing record. */\n reused: boolean\n}\n\n/** @experimental */\nexport interface DelegationTaskQueueOptions {\n /** ID generator override; default `randomTaskId`. */\n generateId?: () => string\n /** Clock override; default `() => new Date().toISOString()`. */\n now?: () => string\n}\n\n/** @experimental */\nexport class DelegationTaskQueue {\n private readonly records = new Map<string, DelegationRecord>()\n private readonly controllers = new Map<string, AbortController>()\n private readonly byIdempotencyKey = new Map<string, string>()\n private readonly generateId: () => string\n private readonly now: () => string\n\n constructor(options: DelegationTaskQueueOptions = {}) {\n this.generateId = options.generateId ?? randomTaskId\n this.now = options.now ?? (() => new Date().toISOString())\n }\n\n /**\n * Kick off a delegation in the background. Returns immediately. The\n * `taskId` is queryable via `status` once this method returns.\n */\n submit<Args extends DelegateCodeArgs | DelegateResearchArgs>(\n input: SubmitInput<Args>,\n ): SubmitOutput {\n if (input.idempotencyKey) {\n const existing = this.byIdempotencyKey.get(input.idempotencyKey)\n if (existing && this.records.has(existing)) {\n return { taskId: existing, reused: true }\n }\n }\n const taskId = this.generateId()\n const controller = new AbortController()\n const record: DelegationRecord = {\n taskId,\n profile: input.profile,\n namespace: input.namespace,\n args: input.args,\n status: 'pending',\n startedAt: this.now(),\n feedback: [],\n idempotencyKey: input.idempotencyKey,\n }\n this.records.set(taskId, record)\n this.controllers.set(taskId, controller)\n if (input.idempotencyKey) this.byIdempotencyKey.set(input.idempotencyKey, taskId)\n\n // Fire-and-forget the run function. Errors flow into the record so the\n // status poll surfaces them; the promise itself is intentionally\n // unobserved by the queue.\n queueMicrotask(() => {\n this.execute(taskId, input, controller)\n })\n\n return { taskId, reused: false }\n }\n\n /**\n * Snapshot the current state of a delegation. Returns `undefined` for\n * unknown ids so callers can distinguish missing from terminal.\n */\n status(taskId: string): DelegationStatusResult | undefined {\n const record = this.records.get(taskId)\n if (!record) return undefined\n return toStatusResult(record)\n }\n\n /**\n * Abort an in-flight delegation. Returns `false` if the task is unknown\n * or already terminal. The underlying `run` function MUST honor the\n * abort signal for the cancel to take effect; the queue marks the\n * record `cancelled` regardless so a misbehaving runner cannot pin the\n * UI on `running` forever.\n */\n cancel(taskId: string): boolean {\n const record = this.records.get(taskId)\n if (!record) return false\n if (isTerminal(record.status)) return false\n const controller = this.controllers.get(taskId)\n controller?.abort()\n record.status = 'cancelled'\n record.completedAt = this.now()\n record.error = { message: 'cancelled by caller', kind: 'CancelledError' }\n return true\n }\n\n /**\n * Append a feedback event to the matching delegation. Returns `false`\n * when `ref` does not name a known taskId — the caller should still\n * record the feedback through a different surface (artifact/outcome\n * kinds are not queue-bound).\n */\n attachFeedback(taskId: string, snapshot: DelegationFeedbackSnapshot): boolean {\n const record = this.records.get(taskId)\n if (!record) return false\n record.feedback.push(snapshot)\n return true\n }\n\n /**\n * Query the recorded delegations. Returns entries newest-first (by\n * `startedAt`), truncated to `limit`.\n */\n history(args: DelegationHistoryArgs = {}): DelegationHistoryEntry[] {\n const limit = clampLimit(args.limit)\n const since = args.since ? Date.parse(args.since) : Number.NEGATIVE_INFINITY\n const out: DelegationHistoryEntry[] = []\n for (const record of this.records.values()) {\n if (args.namespace && record.namespace !== args.namespace) continue\n if (args.profile && record.profile !== args.profile) continue\n if (Number.isFinite(since) && Date.parse(record.startedAt) < since) continue\n out.push(toHistoryEntry(record))\n }\n out.sort((a, b) => b.startedAt.localeCompare(a.startedAt))\n return out.slice(0, limit)\n }\n\n /** Test-only — number of in-flight (non-terminal) records. */\n inflightCount(): number {\n let n = 0\n for (const record of this.records.values()) {\n if (!isTerminal(record.status)) n += 1\n }\n return n\n }\n\n private async execute<Args extends DelegateCodeArgs | DelegateResearchArgs>(\n taskId: string,\n input: SubmitInput<Args>,\n controller: AbortController,\n ): Promise<void> {\n const record = this.records.get(taskId)\n if (!record) return\n record.status = 'running'\n try {\n const output = await input.run({\n signal: controller.signal,\n report: (progress) => {\n if (record.status === 'running') record.progress = progress\n },\n })\n // `cancel()` may have flipped the status to `cancelled` while the\n // run promise was pending. Read the field through a widening\n // helper so the narrowed `'running'` type from the assignment\n // above does not exclude that case at compile time.\n if (currentStatus(record) === 'cancelled') return\n record.status = 'completed'\n record.completedAt = this.now()\n record.result = { profile: input.profile, output } as DelegationResultPayload\n } catch (err) {\n if (currentStatus(record) === 'cancelled') return\n record.status = 'failed'\n record.completedAt = this.now()\n record.error = errorToShape(err)\n } finally {\n this.controllers.delete(taskId)\n }\n }\n}\n\nfunction isTerminal(status: DelegationStatus): boolean {\n return status === 'completed' || status === 'failed' || status === 'cancelled'\n}\n\nfunction currentStatus(record: DelegationRecord): DelegationStatus {\n return record.status\n}\n\nfunction clampLimit(raw: number | undefined): number {\n if (!Number.isFinite(raw)) return 50\n const n = Math.trunc(raw as number)\n if (n <= 0) return 50\n return Math.min(n, 500)\n}\n\nfunction toStatusResult(record: DelegationRecord): DelegationStatusResult {\n const out: DelegationStatusResult = {\n taskId: record.taskId,\n profile: record.profile,\n status: record.status,\n startedAt: record.startedAt,\n }\n if (record.progress) out.progress = record.progress\n if (record.result) out.result = record.result\n if (record.error) out.error = record.error\n if (record.costUsd !== undefined) out.costUsd = record.costUsd\n if (record.completedAt) out.completedAt = record.completedAt\n return out\n}\n\nfunction toHistoryEntry(record: DelegationRecord): DelegationHistoryEntry {\n const entry: DelegationHistoryEntry = {\n taskId: record.taskId,\n profile: record.profile,\n args: record.args,\n status: record.status,\n startedAt: record.startedAt,\n }\n if (record.namespace) entry.namespace = record.namespace\n if (record.completedAt) entry.completedAt = record.completedAt\n if (record.costUsd !== undefined) entry.costUsd = record.costUsd\n if (record.feedback.length > 0) entry.feedback = [...record.feedback]\n return entry\n}\n\nfunction errorToShape(err: unknown): DelegationError {\n if (err instanceof Error) {\n return { message: err.message, kind: err.name || 'Error' }\n }\n return { message: String(err), kind: 'NonError' }\n}\n\nfunction randomTaskId(): string {\n // Caller-stable id: `dlg-${timestamp}-${random}`. The timestamp portion\n // makes lexicographic sort match chronological order in history queries\n // even when the system clock skews under the second.\n const t = Date.now().toString(36)\n const r = Math.random().toString(36).slice(2, 10)\n return `dlg-${t}-${r}`\n}\n\n/**\n * Best-effort stable hash for use as `idempotencyKey`. Not cryptographic;\n * collisions only affect dedupe, never correctness.\n *\n * @experimental\n */\nexport function hashIdempotencyInput(value: unknown): string {\n let str: string\n try {\n str = JSON.stringify(canonicalize(value))\n } catch {\n str = String(value)\n }\n // FNV-1a 32-bit\n let h = 0x811c9dc5\n for (let i = 0; i < str.length; i += 1) {\n h ^= str.charCodeAt(i)\n h = Math.imul(h, 0x01000193)\n }\n return (h >>> 0).toString(16).padStart(8, '0')\n}\n\nfunction canonicalize(value: unknown): unknown {\n if (value === null || typeof value !== 'object') return value\n if (Array.isArray(value)) return value.map(canonicalize)\n const entries = Object.entries(value as Record<string, unknown>)\n .filter(([, v]) => v !== undefined)\n .sort(([a], [b]) => a.localeCompare(b))\n const out: Record<string, unknown> = {}\n for (const [k, v] of entries) out[k] = canonicalize(v)\n return out\n}\n\n// Re-exports re-used by the feedback-store + handler glue. Kept local so\n// consumers of the queue don't have to import from `./types` separately.\nexport type {\n DelegateCodeArgs,\n DelegateCodeResult,\n DelegateFeedbackArgs,\n DelegateFeedbackResult,\n DelegateResearchArgs,\n DelegateResearchResult,\n DelegationError,\n DelegationFeedbackSnapshot,\n DelegationHistoryArgs,\n DelegationHistoryEntry,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationProgress,\n DelegationResultPayload,\n DelegationStatus,\n DelegationStatusArgs,\n DelegationStatusResult,\n} from './types'\n","/**\n * @experimental\n *\n * `delegate_code` MCP tool — async kickoff. The handler validates the\n * input, computes an idempotency key over the canonical fields, hands\n * the task to the queue, and returns `{ taskId, estimatedDurationMs }`.\n */\n\nimport type { CoderDelegate } from '../delegates'\nimport {\n type DelegateCodeArgs,\n type DelegateCodeResult,\n type DelegationTaskQueue,\n hashIdempotencyInput,\n} from '../task-queue'\n\n/** @experimental */\nexport const DELEGATE_CODE_TOOL_NAME = 'delegate_code'\n\n/** @experimental */\nexport const DELEGATE_CODE_DESCRIPTION = [\n 'Delegate a coding task to specialist coder agents that produce a validated patch.',\n '',\n 'Use when: you need code written, fixed, refactored, or extended to satisfy a',\n 'user goal that touches a real repository. The coder runs in an isolated',\n 'sandbox, opens a fresh branch, keeps the diff minimal, runs the supplied',\n 'test + typecheck commands, and emits a unified-diff patch.',\n '',\n 'Returns immediately with a taskId. Poll delegation_status to retrieve the',\n 'patch + validator verdict (typically minutes-to-hours, longer for large',\n 'changes). Identical inputs return the same taskId — safe to retry.',\n '',\n 'When variants > 1, multiple coder harnesses (claude-code, codex, opencode)',\n 'attempt the task in parallel and the highest-scoring patch wins (smallest',\n 'passing diff). Use variants for high-stakes changes; single variant for',\n 'routine ones.',\n '',\n 'Capability scope: the coder cannot modify paths outside repoRoot and cannot',\n 'touch paths in config.forbiddenPaths. The validator hard-fails on a',\n 'forbidden-path violation, diff above config.maxDiffLines, test failure, or',\n 'typecheck failure — none of those make it past the gate.',\n].join('\\n')\n\n/** @experimental */\nexport const DELEGATE_CODE_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n goal: {\n type: 'string',\n description: 'Natural-language description of what the coder must accomplish.',\n },\n repoRoot: {\n type: 'string',\n description: 'Absolute path inside the sandbox where the repo lives.',\n },\n contextHint: {\n type: 'string',\n description: 'Optional free-form context the coder sees in the prompt prelude.',\n },\n variants: {\n type: 'integer',\n minimum: 1,\n maximum: 8,\n description: 'Number of parallel coder harnesses. Default 1.',\n },\n config: {\n type: 'object',\n properties: {\n testCmd: { type: 'string' },\n typecheckCmd: { type: 'string' },\n forbiddenPaths: { type: 'array', items: { type: 'string' } },\n maxDiffLines: { type: 'integer', minimum: 1 },\n },\n additionalProperties: false,\n },\n namespace: {\n type: 'string',\n description: 'Multi-tenant scope (customer-id, workspace-id).',\n },\n },\n required: ['goal', 'repoRoot'],\n additionalProperties: false,\n} as const\n\nconst SINGLE_VARIANT_ESTIMATE_MS = 6 * 60 * 1000 // 6 minutes — single coder\nconst FANOUT_PER_VARIANT_ESTIMATE_MS = 8 * 60 * 1000 // 8 minutes — fanout\n\n/** @experimental */\nexport function validateDelegateCodeArgs(raw: unknown): DelegateCodeArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_code: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const goal = value.goal\n if (typeof goal !== 'string' || goal.trim().length === 0) {\n throw new TypeError('delegate_code: `goal` must be a non-empty string')\n }\n const repoRoot = value.repoRoot\n if (typeof repoRoot !== 'string' || repoRoot.trim().length === 0) {\n throw new TypeError('delegate_code: `repoRoot` must be a non-empty string')\n }\n const args: DelegateCodeArgs = { goal: goal.trim(), repoRoot: repoRoot.trim() }\n if (typeof value.contextHint === 'string') args.contextHint = value.contextHint\n if (value.variants !== undefined) {\n const variants = Number(value.variants)\n if (!Number.isFinite(variants) || variants < 1 || variants > 8) {\n throw new RangeError('delegate_code: `variants` must be an integer in [1, 8]')\n }\n args.variants = Math.trunc(variants)\n }\n if (value.config !== undefined) {\n args.config = validateConfig(value.config)\n }\n if (typeof value.namespace === 'string') args.namespace = value.namespace\n return args\n}\n\nfunction validateConfig(raw: unknown): DelegateCodeArgs['config'] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_code: `config` must be an object')\n }\n const value = raw as Record<string, unknown>\n const out: NonNullable<DelegateCodeArgs['config']> = {}\n if (value.testCmd !== undefined) {\n if (typeof value.testCmd !== 'string') {\n throw new TypeError('delegate_code: `config.testCmd` must be a string')\n }\n out.testCmd = value.testCmd\n }\n if (value.typecheckCmd !== undefined) {\n if (typeof value.typecheckCmd !== 'string') {\n throw new TypeError('delegate_code: `config.typecheckCmd` must be a string')\n }\n out.typecheckCmd = value.typecheckCmd\n }\n if (value.forbiddenPaths !== undefined) {\n if (!Array.isArray(value.forbiddenPaths)) {\n throw new TypeError('delegate_code: `config.forbiddenPaths` must be a string array')\n }\n out.forbiddenPaths = value.forbiddenPaths.map((entry, i) => {\n if (typeof entry !== 'string') {\n throw new TypeError(`delegate_code: forbiddenPaths[${i}] must be a string`)\n }\n return entry\n })\n }\n if (value.maxDiffLines !== undefined) {\n const n = Number(value.maxDiffLines)\n if (!Number.isFinite(n) || n < 1) {\n throw new RangeError('delegate_code: `config.maxDiffLines` must be a positive integer')\n }\n out.maxDiffLines = Math.trunc(n)\n }\n return out\n}\n\n/** @experimental */\nexport interface DelegateCodeHandlerOptions {\n queue: DelegationTaskQueue\n delegate: CoderDelegate\n /** Override the duration hint. */\n estimateDurationMs?: (args: DelegateCodeArgs) => number\n}\n\n/** @experimental */\nexport function createDelegateCodeHandler(\n options: DelegateCodeHandlerOptions,\n): (raw: unknown) => Promise<DelegateCodeResult> {\n const estimateDurationMs = options.estimateDurationMs ?? defaultEstimate\n return async (raw) => {\n const args = validateDelegateCodeArgs(raw)\n const idempotencyKey = hashIdempotencyInput({\n profile: 'coder',\n goal: args.goal,\n repoRoot: args.repoRoot,\n contextHint: args.contextHint,\n variants: args.variants ?? 1,\n config: args.config,\n namespace: args.namespace,\n })\n const submitted = options.queue.submit<DelegateCodeArgs>({\n profile: 'coder',\n args,\n namespace: args.namespace,\n idempotencyKey,\n run: async (ctx) => options.delegate(args, ctx),\n })\n return {\n taskId: submitted.taskId,\n estimatedDurationMs: estimateDurationMs(args),\n }\n }\n}\n\nfunction defaultEstimate(args: DelegateCodeArgs): number {\n const variants = Math.max(1, args.variants ?? 1)\n if (variants === 1) return SINGLE_VARIANT_ESTIMATE_MS\n return FANOUT_PER_VARIANT_ESTIMATE_MS\n}\n","/**\n * @experimental\n *\n * Feedback persistence surface for the MCP layer.\n *\n * The substrate cannot import `@tangle-network/agent-knowledge` (it would\n * induce a dependency cycle), so the store is an abstract interface. The\n * default implementation is in-memory; consumers wire their own adapter\n * (a real KbStore-backed sink, an HTTP relay to gtm-agent's knowledge\n * service, etc.) via `createMcpServer({ feedbackStore })`.\n *\n * Feedback events are append-only: every rating is a new event with a\n * fresh id, even when the same delegation is rated multiple times. The\n * caller decides how to roll up scores downstream.\n */\n\nimport type { DelegateFeedbackArgs, DelegationFeedbackSnapshot } from './types'\n\n/** @experimental */\nexport interface FeedbackEvent {\n id: string\n refersTo: DelegateFeedbackArgs['refersTo']\n rating: DelegateFeedbackArgs['rating']\n by: DelegateFeedbackArgs['by']\n capturedAt: string\n namespace?: string\n}\n\n/** @experimental */\nexport interface FeedbackStore {\n /** Append a new event. Never dedupes — every rating is its own event. */\n put(event: FeedbackEvent): Promise<void>\n /**\n * List events filtered by `namespace`. When `namespace` is omitted, list\n * across all namespaces. Returns events in insertion order.\n */\n list(filter?: { namespace?: string; refersToRef?: string }): Promise<FeedbackEvent[]>\n}\n\n/** @experimental */\nexport class InMemoryFeedbackStore implements FeedbackStore {\n private readonly events: FeedbackEvent[] = []\n\n async put(event: FeedbackEvent): Promise<void> {\n this.events.push({ ...event })\n }\n\n async list(filter: { namespace?: string; refersToRef?: string } = {}): Promise<FeedbackEvent[]> {\n let out = this.events\n if (filter.namespace !== undefined) {\n out = out.filter((event) => event.namespace === filter.namespace)\n }\n if (filter.refersToRef !== undefined) {\n out = out.filter((event) => event.refersTo.ref === filter.refersToRef)\n }\n return out.map((event) => ({ ...event }))\n }\n}\n\n/**\n * Project a `FeedbackEvent` down to the snapshot shape carried on\n * `delegation_history` entries.\n *\n * @experimental\n */\nexport function eventToSnapshot(event: FeedbackEvent): DelegationFeedbackSnapshot {\n const snap: DelegationFeedbackSnapshot = {\n id: event.id,\n score: event.rating.score,\n by: event.by,\n notes: event.rating.notes,\n capturedAt: event.capturedAt,\n }\n if (event.rating.label) snap.label = event.rating.label\n return snap\n}\n","/**\n * @experimental\n *\n * `delegate_feedback` MCP tool — synchronous record of agent / user /\n * downstream-judge feedback on a delegation, artifact, or outcome.\n *\n * The store is append-only. Every rating is its own event; no dedupe.\n * When `refersTo.kind === 'delegation'`, the snapshot is also attached\n * to the matching queue record so `delegation_history` surfaces it\n * inline without a join.\n */\n\nimport type { FeedbackStore } from '../feedback-store'\nimport { eventToSnapshot } from '../feedback-store'\nimport type { DelegationTaskQueue } from '../task-queue'\nimport type {\n DelegateFeedbackArgs,\n DelegateFeedbackResult,\n FeedbackRating,\n FeedbackRefersTo,\n} from '../types'\n\n/** @experimental */\nexport const DELEGATE_FEEDBACK_TOOL_NAME = 'delegate_feedback'\n\n/** @experimental */\nexport const DELEGATE_FEEDBACK_DESCRIPTION = [\n 'Record feedback on a delegation, artifact, or outcome. Synchronous — the',\n 'event is durably stored when this call returns.',\n '',\n 'Use when: you (the agent), the user, or a downstream judge has formed an',\n 'opinion about a piece of work and want it persisted for calibration,',\n 'pricing, or future routing. Every call is a new event — multiple ratings',\n 'on the same target are expected and never deduped.',\n '',\n '`refersTo.kind`:',\n ' - \"delegation\": ref is a taskId returned by delegate_code/delegate_research',\n ' - \"artifact\": ref is a URI/path/git-sha — anything you can dereference',\n ' - \"outcome\": ref is a free-form description of a downstream result',\n '',\n '`by`:',\n ' - \"agent\": the agent itself rated the work',\n ' - \"user\": the human user rated it',\n ' - \"downstream-judge\": an automated evaluator emitted the rating',\n '',\n 'When ref names a known taskId, the rating is also attached to the',\n 'delegation record so delegation_history surfaces it inline.',\n].join('\\n')\n\n/** @experimental */\nexport const DELEGATE_FEEDBACK_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n refersTo: {\n type: 'object',\n properties: {\n kind: { type: 'string', enum: ['delegation', 'artifact', 'outcome'] },\n ref: { type: 'string' },\n },\n required: ['kind', 'ref'],\n additionalProperties: false,\n },\n rating: {\n type: 'object',\n properties: {\n score: { type: 'number', minimum: 0, maximum: 1 },\n label: { type: 'string', enum: ['good', 'bad', 'neutral', 'mixed'] },\n notes: { type: 'string' },\n },\n required: ['score', 'notes'],\n additionalProperties: false,\n },\n by: { type: 'string', enum: ['agent', 'user', 'downstream-judge'] },\n capturedAt: { type: 'string' },\n namespace: { type: 'string' },\n },\n required: ['refersTo', 'rating', 'by'],\n additionalProperties: false,\n} as const\n\n/** @experimental */\nexport function validateDelegateFeedbackArgs(raw: unknown): DelegateFeedbackArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const refersTo = validateRefersTo(value.refersTo)\n const rating = validateRating(value.rating)\n const by = value.by\n if (by !== 'agent' && by !== 'user' && by !== 'downstream-judge') {\n throw new TypeError(\n 'delegate_feedback: `by` must be one of \"agent\" | \"user\" | \"downstream-judge\"',\n )\n }\n const args: DelegateFeedbackArgs = { refersTo, rating, by }\n if (value.capturedAt !== undefined) {\n if (typeof value.capturedAt !== 'string' || Number.isNaN(Date.parse(value.capturedAt))) {\n throw new TypeError('delegate_feedback: `capturedAt` must be an ISO datetime')\n }\n args.capturedAt = value.capturedAt\n }\n if (typeof value.namespace === 'string') args.namespace = value.namespace\n return args\n}\n\nfunction validateRefersTo(raw: unknown): FeedbackRefersTo {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: `refersTo` must be an object')\n }\n const value = raw as Record<string, unknown>\n const kind = value.kind\n if (kind !== 'delegation' && kind !== 'artifact' && kind !== 'outcome') {\n throw new TypeError(\n 'delegate_feedback: `refersTo.kind` must be one of \"delegation\" | \"artifact\" | \"outcome\"',\n )\n }\n const ref = value.ref\n if (typeof ref !== 'string' || ref.trim().length === 0) {\n throw new TypeError('delegate_feedback: `refersTo.ref` must be a non-empty string')\n }\n return { kind, ref: ref.trim() }\n}\n\nfunction validateRating(raw: unknown): FeedbackRating {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_feedback: `rating` must be an object')\n }\n const value = raw as Record<string, unknown>\n const score = Number(value.score)\n if (!Number.isFinite(score) || score < 0 || score > 1) {\n throw new RangeError('delegate_feedback: `rating.score` must be a number in [0, 1]')\n }\n const notes = value.notes\n if (typeof notes !== 'string') {\n throw new TypeError('delegate_feedback: `rating.notes` must be a string')\n }\n const rating: FeedbackRating = { score, notes }\n const label = value.label\n if (label !== undefined) {\n if (label !== 'good' && label !== 'bad' && label !== 'neutral' && label !== 'mixed') {\n throw new TypeError(\n 'delegate_feedback: `rating.label` must be one of \"good\" | \"bad\" | \"neutral\" | \"mixed\"',\n )\n }\n rating.label = label\n }\n return rating\n}\n\n/** @experimental */\nexport interface DelegateFeedbackHandlerOptions {\n queue: DelegationTaskQueue\n store: FeedbackStore\n generateId?: () => string\n now?: () => string\n}\n\n/** @experimental */\nexport function createDelegateFeedbackHandler(\n options: DelegateFeedbackHandlerOptions,\n): (raw: unknown) => Promise<DelegateFeedbackResult> {\n const generateId = options.generateId ?? randomFeedbackId\n const now = options.now ?? (() => new Date().toISOString())\n return async (raw) => {\n const args = validateDelegateFeedbackArgs(raw)\n const id = generateId()\n const event = {\n id,\n refersTo: args.refersTo,\n rating: args.rating,\n by: args.by,\n capturedAt: args.capturedAt ?? now(),\n namespace: args.namespace,\n }\n await options.store.put(event)\n if (args.refersTo.kind === 'delegation') {\n options.queue.attachFeedback(args.refersTo.ref, eventToSnapshot(event))\n }\n return { recorded: true, id }\n }\n}\n\nfunction randomFeedbackId(): string {\n const t = Date.now().toString(36)\n const r = Math.random().toString(36).slice(2, 10)\n return `fbk-${t}-${r}`\n}\n","/**\n * @experimental\n *\n * `delegate_research` MCP tool — async kickoff for source-grounded\n * research tasks. Same async semantics as `delegate_code`: returns a\n * taskId immediately, idempotent on canonical inputs.\n *\n * The handler does not import a researcher profile directly — consumers\n * inject a `ResearcherDelegate` via `createMcpServer({ researcherDelegate })`.\n * The substrate cannot depend on `@tangle-network/agent-knowledge`\n * without inducing a dependency cycle.\n */\n\nimport type { ResearcherDelegate } from '../delegates'\nimport {\n type DelegateResearchArgs,\n type DelegateResearchResult,\n type DelegationTaskQueue,\n hashIdempotencyInput,\n} from '../task-queue'\nimport type { ResearchSource } from '../types'\n\n/** @experimental */\nexport const DELEGATE_RESEARCH_TOOL_NAME = 'delegate_research'\n\n/** @experimental */\nexport const DELEGATE_RESEARCH_DESCRIPTION = [\n 'Delegate a research question to specialist researcher agents that produce',\n 'source-grounded, evidence-bearing knowledge items.',\n '',\n 'Use when: you need to answer a factual question with external evidence —',\n 'audience research, competitive intelligence, recency-bound web searches,',\n 'corpus / docs lookups. The researcher emits items[] with provenance, a',\n 'citations[] index, and proposedWrites[] you decide whether to persist.',\n '',\n 'Returns immediately with a taskId. Poll delegation_status to retrieve the',\n 'items + verdict. Identical inputs return the same taskId — safe to retry.',\n '',\n 'When variants > 1, multiple researcher harnesses run in parallel and the',\n 'highest-scoring valid output wins (citation density × source diversity ×',\n 'recency match × gap coverage). Use variants when answers might disagree.',\n '',\n 'Multi-tenant isolation: every item carries `namespace`. The validator',\n 'hard-fails when any item is scoped outside `namespace`. Never pass another',\n \"tenant's namespace.\",\n].join('\\n')\n\nconst VALID_SOURCES: readonly ResearchSource[] = ['web', 'corpus', 'twitter', 'github', 'docs']\n\n/** @experimental */\nexport const DELEGATE_RESEARCH_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n question: {\n type: 'string',\n description: 'The research question to answer.',\n },\n namespace: {\n type: 'string',\n description: 'Multi-tenant scope (customer-id, workspace-id). REQUIRED.',\n },\n scope: { type: 'string', description: 'Bound, e.g. \"audience for cpg-founder ICP\".' },\n sources: {\n type: 'array',\n items: { type: 'string', enum: [...VALID_SOURCES] },\n },\n variants: { type: 'integer', minimum: 1, maximum: 8 },\n config: {\n type: 'object',\n properties: {\n recencyWindow: {\n type: 'object',\n properties: {\n since: { type: 'string', description: 'ISO datetime' },\n until: { type: 'string', description: 'ISO datetime' },\n },\n additionalProperties: false,\n },\n maxItems: { type: 'integer', minimum: 1 },\n minConfidence: { type: 'number', minimum: 0, maximum: 1 },\n },\n additionalProperties: false,\n },\n },\n required: ['question', 'namespace'],\n additionalProperties: false,\n} as const\n\nconst SINGLE_VARIANT_ESTIMATE_MS = 4 * 60 * 1000\nconst FANOUT_PER_VARIANT_ESTIMATE_MS = 6 * 60 * 1000\n\n/** @experimental */\nexport function validateDelegateResearchArgs(raw: unknown): DelegateResearchArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_research: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const question = value.question\n if (typeof question !== 'string' || question.trim().length === 0) {\n throw new TypeError('delegate_research: `question` must be a non-empty string')\n }\n const namespace = value.namespace\n if (typeof namespace !== 'string' || namespace.trim().length === 0) {\n throw new TypeError('delegate_research: `namespace` is required')\n }\n const args: DelegateResearchArgs = { question: question.trim(), namespace: namespace.trim() }\n if (typeof value.scope === 'string') args.scope = value.scope\n if (value.sources !== undefined) {\n if (!Array.isArray(value.sources)) {\n throw new TypeError('delegate_research: `sources` must be a string array')\n }\n const sources: ResearchSource[] = value.sources.map((src, i) => {\n if (typeof src !== 'string' || !VALID_SOURCES.includes(src as ResearchSource)) {\n throw new TypeError(\n `delegate_research: sources[${i}] must be one of ${VALID_SOURCES.join('|')}`,\n )\n }\n return src as ResearchSource\n })\n args.sources = sources\n }\n if (value.variants !== undefined) {\n const variants = Number(value.variants)\n if (!Number.isFinite(variants) || variants < 1 || variants > 8) {\n throw new RangeError('delegate_research: `variants` must be an integer in [1, 8]')\n }\n args.variants = Math.trunc(variants)\n }\n if (value.config !== undefined) {\n args.config = validateConfig(value.config)\n }\n return args\n}\n\nfunction validateConfig(raw: unknown): DelegateResearchArgs['config'] {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegate_research: `config` must be an object')\n }\n const value = raw as Record<string, unknown>\n const out: NonNullable<DelegateResearchArgs['config']> = {}\n if (value.recencyWindow !== undefined) {\n if (value.recencyWindow === null || typeof value.recencyWindow !== 'object') {\n throw new TypeError('delegate_research: `config.recencyWindow` must be an object')\n }\n const window = value.recencyWindow as Record<string, unknown>\n const windowOut: NonNullable<NonNullable<DelegateResearchArgs['config']>['recencyWindow']> = {}\n if (window.since !== undefined) {\n if (typeof window.since !== 'string' || Number.isNaN(Date.parse(window.since))) {\n throw new TypeError('delegate_research: `recencyWindow.since` must be an ISO datetime')\n }\n windowOut.since = window.since\n }\n if (window.until !== undefined) {\n if (typeof window.until !== 'string' || Number.isNaN(Date.parse(window.until))) {\n throw new TypeError('delegate_research: `recencyWindow.until` must be an ISO datetime')\n }\n windowOut.until = window.until\n }\n out.recencyWindow = windowOut\n }\n if (value.maxItems !== undefined) {\n const n = Number(value.maxItems)\n if (!Number.isFinite(n) || n < 1) {\n throw new RangeError('delegate_research: `config.maxItems` must be a positive integer')\n }\n out.maxItems = Math.trunc(n)\n }\n if (value.minConfidence !== undefined) {\n const n = Number(value.minConfidence)\n if (!Number.isFinite(n) || n < 0 || n > 1) {\n throw new RangeError('delegate_research: `config.minConfidence` must be in [0, 1]')\n }\n out.minConfidence = n\n }\n return out\n}\n\n/** @experimental */\nexport interface DelegateResearchHandlerOptions {\n queue: DelegationTaskQueue\n delegate: ResearcherDelegate\n estimateDurationMs?: (args: DelegateResearchArgs) => number\n}\n\n/** @experimental */\nexport function createDelegateResearchHandler(\n options: DelegateResearchHandlerOptions,\n): (raw: unknown) => Promise<DelegateResearchResult> {\n const estimateDurationMs = options.estimateDurationMs ?? defaultEstimate\n return async (raw) => {\n const args = validateDelegateResearchArgs(raw)\n const idempotencyKey = hashIdempotencyInput({\n profile: 'researcher',\n question: args.question,\n namespace: args.namespace,\n scope: args.scope,\n sources: args.sources,\n variants: args.variants ?? 1,\n config: args.config,\n })\n const submitted = options.queue.submit<DelegateResearchArgs>({\n profile: 'researcher',\n args,\n namespace: args.namespace,\n idempotencyKey,\n run: async (ctx) => options.delegate(args, ctx),\n })\n return {\n taskId: submitted.taskId,\n estimatedDurationMs: estimateDurationMs(args),\n }\n }\n}\n\nfunction defaultEstimate(args: DelegateResearchArgs): number {\n const variants = Math.max(1, args.variants ?? 1)\n if (variants === 1) return SINGLE_VARIANT_ESTIMATE_MS\n return FANOUT_PER_VARIANT_ESTIMATE_MS\n}\n","/**\n * @experimental\n *\n * `delegation_history` MCP tool — synchronous read of past delegations.\n * The agent uses this for self-introspection — \"have I delegated this\n * kind of task before? did it work?\" — and calibration.\n */\n\nimport type {\n DelegationHistoryArgs,\n DelegationHistoryResult,\n DelegationProfile,\n DelegationTaskQueue,\n} from '../task-queue'\n\n/** @experimental */\nexport const DELEGATION_HISTORY_TOOL_NAME = 'delegation_history'\n\n/** @experimental */\nexport const DELEGATION_HISTORY_DESCRIPTION = [\n 'Read past delegations newest-first. Each entry carries the original',\n 'arguments, current status, cost, and any feedback attached via',\n 'delegate_feedback.',\n '',\n 'Use when: you want to introspect prior decisions — \"have I asked this',\n 'question before?',\n 'did the last patch land?',\n \"what's the historical\",\n 'success rate of coder delegations on this repo?\". Feed the results back',\n 'into your own routing and calibration.',\n '',\n 'Filters: `namespace` (multi-tenant scope), `profile` (\"coder\" | \"researcher\"),',\n '`since` (ISO date — only delegations started at-or-after). `limit` defaults',\n 'to 50, capped at 500.',\n].join('\\n')\n\n/** @experimental */\nexport const DELEGATION_HISTORY_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n namespace: { type: 'string' },\n profile: { type: 'string', enum: ['coder', 'researcher'] },\n since: { type: 'string', description: 'ISO datetime — earliest startedAt to include.' },\n limit: { type: 'integer', minimum: 1, maximum: 500 },\n },\n additionalProperties: false,\n} as const\n\n/** @experimental */\nexport function validateDelegationHistoryArgs(raw: unknown): DelegationHistoryArgs {\n if (raw === undefined || raw === null) return {}\n if (typeof raw !== 'object') {\n throw new TypeError('delegation_history: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const out: DelegationHistoryArgs = {}\n if (value.namespace !== undefined) {\n if (typeof value.namespace !== 'string') {\n throw new TypeError('delegation_history: `namespace` must be a string')\n }\n out.namespace = value.namespace\n }\n if (value.profile !== undefined) {\n if (value.profile !== 'coder' && value.profile !== 'researcher') {\n throw new TypeError('delegation_history: `profile` must be \"coder\" or \"researcher\"')\n }\n out.profile = value.profile as DelegationProfile\n }\n if (value.since !== undefined) {\n if (typeof value.since !== 'string' || Number.isNaN(Date.parse(value.since))) {\n throw new TypeError('delegation_history: `since` must be an ISO datetime')\n }\n out.since = value.since\n }\n if (value.limit !== undefined) {\n const n = Number(value.limit)\n if (!Number.isFinite(n) || n < 1 || n > 500) {\n throw new RangeError('delegation_history: `limit` must be an integer in [1, 500]')\n }\n out.limit = Math.trunc(n)\n }\n return out\n}\n\n/** @experimental */\nexport interface DelegationHistoryHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** @experimental */\nexport function createDelegationHistoryHandler(\n options: DelegationHistoryHandlerOptions,\n): (raw: unknown) => Promise<DelegationHistoryResult> {\n return async (raw) => {\n const args = validateDelegationHistoryArgs(raw)\n return { delegations: options.queue.history(args) }\n }\n}\n","/**\n * @experimental\n *\n * `delegation_status` MCP tool — synchronous poll. Returns the current\n * state machine + optional progress + final result (when terminal).\n */\n\nimport { NotFoundError } from '../../errors'\nimport type {\n DelegationStatusArgs,\n DelegationStatusResult,\n DelegationTaskQueue,\n} from '../task-queue'\n\n/** @experimental */\nexport const DELEGATION_STATUS_TOOL_NAME = 'delegation_status'\n\n/** @experimental */\nexport const DELEGATION_STATUS_DESCRIPTION = [\n 'Poll the status of an async delegation. Returns the current state',\n '(pending | running | completed | failed | cancelled), optional progress,',\n 'and the final result when status === \"completed\".',\n '',\n 'Use when: you previously called delegate_code or delegate_research and',\n \"need to know whether the work is done. The agent's right rhythm is to\",\n 'call this every minute or two while waiting; do not busy-poll.',\n '',\n 'For a completed coder task, `result.output` is a CoderOutput with branch,',\n 'patch, test/typecheck results, and diff stats. For a completed research',\n 'task, `result.output` is the items + citations + proposedWrites bundle.',\n '',\n 'Throws NotFoundError when taskId is unknown — never silently returns',\n '`pending` for a typo.',\n].join('\\n')\n\n/** @experimental */\nexport const DELEGATION_STATUS_INPUT_SCHEMA = {\n type: 'object',\n properties: {\n taskId: { type: 'string', description: 'Returned by delegate_code / delegate_research.' },\n },\n required: ['taskId'],\n additionalProperties: false,\n} as const\n\n/** @experimental */\nexport function validateDelegationStatusArgs(raw: unknown): DelegationStatusArgs {\n if (raw === null || typeof raw !== 'object') {\n throw new TypeError('delegation_status: arguments must be an object')\n }\n const value = raw as Record<string, unknown>\n const taskId = value.taskId\n if (typeof taskId !== 'string' || taskId.trim().length === 0) {\n throw new TypeError('delegation_status: `taskId` must be a non-empty string')\n }\n return { taskId: taskId.trim() }\n}\n\n/** @experimental */\nexport interface DelegationStatusHandlerOptions {\n queue: DelegationTaskQueue\n}\n\n/** @experimental */\nexport function createDelegationStatusHandler(\n options: DelegationStatusHandlerOptions,\n): (raw: unknown) => Promise<DelegationStatusResult> {\n return async (raw) => {\n const args = validateDelegationStatusArgs(raw)\n const status = options.queue.status(args.taskId)\n if (!status) {\n throw new NotFoundError(`delegation_status: unknown taskId \"${args.taskId}\"`)\n }\n return status\n }\n}\n","/**\n * OTEL span exporter — streams LoopTraceEvents to an OTLP/HTTP collector.\n *\n * Reads OTEL_EXPORTER_OTLP_ENDPOINT + OTEL_EXPORTER_OTLP_HEADERS from env\n * when no explicit config is given. Keeps the runtime dep-free from\n * @opentelemetry/sdk-trace-base — minimal OTLP/JSON serializer.\n *\n * The exporter accepts both raw OtelSpan objects and LoopTraceEvents\n * (which get converted to OTLP spans automatically).\n */\n\nexport interface OtelExportConfig {\n /** OTLP endpoint. Reads OTEL_EXPORTER_OTLP_ENDPOINT env by default. */\n endpoint?: string\n /** OTLP headers. Reads OTEL_EXPORTER_OTLP_HEADERS env by default. */\n headers?: Record<string, string>\n /** Batch size before flush. Default 64. */\n batchSize?: number\n /** Flush interval ms. Default 5000. */\n flushIntervalMs?: number\n /** Resource attributes stamped on every export. */\n resourceAttributes?: Record<string, string | number | boolean>\n /** Service name. Default 'agent-runtime'. */\n serviceName?: string\n}\n\nexport interface OtelExporter {\n /** Export a span. */\n exportSpan(span: OtelSpan): void\n /** Force flush pending spans. */\n flush(): Promise<void>\n /** Shutdown cleanly. */\n shutdown(): Promise<void>\n}\n\nexport interface OtelSpan {\n traceId: string\n spanId: string\n parentSpanId?: string\n name: string\n kind?: number\n startTimeUnixNano: string\n endTimeUnixNano: string\n attributes?: OtelAttribute[]\n status?: { code: number; message?: string }\n}\n\nexport interface OtelAttribute {\n key: string\n value: { stringValue?: string; intValue?: string; doubleValue?: number; boolValue?: boolean }\n}\n\ninterface OtlpResourceSpans {\n resource: { attributes: OtelAttribute[] }\n scopeSpans: Array<{ scope: { name: string; version: string }; spans: OtelSpan[] }>\n}\n\ninterface OtlpExport {\n resourceSpans: OtlpResourceSpans[]\n}\n\nconst SCOPE = { name: '@tangle-network/agent-runtime', version: '0.33.0' }\n\n/**\n * Current (non-deprecated) OpenTelemetry GenAI semantic-convention keys.\n * Registry: https://opentelemetry.io/docs/specs/semconv/registry/attributes/gen-ai/\n * NB: `gen_ai.system` / `gen_ai.usage.prompt_tokens` / `completion_tokens` are\n * DEPRECATED — do not emit them. We use `provider.name` + `input/output_tokens`.\n */\nconst GEN_AI = {\n operation: 'gen_ai.operation.name',\n agentName: 'gen_ai.agent.name',\n conversationId: 'gen_ai.conversation.id',\n inputTokens: 'gen_ai.usage.input_tokens',\n outputTokens: 'gen_ai.usage.output_tokens',\n} as const\n\n/**\n * Create an OTEL exporter. Returns undefined when no endpoint is configured.\n */\nexport function createOtelExporter(config?: OtelExportConfig): OtelExporter | undefined {\n const resolvedEndpoint =\n config?.endpoint ??\n (typeof process !== 'undefined' ? process.env.OTEL_EXPORTER_OTLP_ENDPOINT : undefined)\n if (!resolvedEndpoint) return undefined\n const endpoint: string = resolvedEndpoint\n\n const headers = config?.headers ?? parseHeadersFromEnv()\n const batchSize = config?.batchSize ?? 64\n const flushIntervalMs = config?.flushIntervalMs ?? 5000\n const serviceName = config?.serviceName ?? 'agent-runtime'\n const resourceAttrs = config?.resourceAttributes ?? {}\n\n const pending: OtelSpan[] = []\n let timer: ReturnType<typeof setInterval> | undefined\n let stopped = false\n\n const exporter: OtelExporter = {\n exportSpan(span: OtelSpan): void {\n if (stopped) return\n pending.push(span)\n if (pending.length >= batchSize) {\n void doFlush()\n }\n },\n\n async flush(): Promise<void> {\n await doFlush()\n },\n\n async shutdown(): Promise<void> {\n stopped = true\n if (timer !== undefined) {\n clearInterval(timer)\n timer = undefined\n }\n await doFlush()\n },\n }\n\n timer = setInterval(() => {\n if (pending.length > 0) void doFlush()\n }, flushIntervalMs)\n if (typeof timer === 'object' && 'unref' in timer) {\n ;(timer as NodeJS.Timeout).unref()\n }\n\n async function doFlush(): Promise<void> {\n if (pending.length === 0) return\n const batch = pending.splice(0)\n const body: OtlpExport = {\n resourceSpans: [\n {\n resource: {\n attributes: toAttributes({\n 'service.name': serviceName,\n ...resourceAttrs,\n }),\n },\n scopeSpans: [{ scope: SCOPE, spans: batch }],\n },\n ],\n }\n const url = `${endpoint.replace(/\\/+$/, '')}/v1/traces`\n try {\n await fetch(url, {\n method: 'POST',\n headers: { 'content-type': 'application/json', ...headers },\n body: JSON.stringify(body),\n })\n } catch {\n // Best-effort — telemetry export must not crash the runtime.\n }\n }\n\n return exporter\n}\n\n/**\n * Convert a LoopTraceEvent into an OtelSpan for export.\n */\nexport function loopEventToOtelSpan(\n event: {\n kind: string\n runId: string\n timestamp: number\n payload: object\n },\n traceId: string,\n parentSpanId?: string,\n): OtelSpan {\n const spanId = generateSpanId()\n const attrs: Record<string, string | number | boolean> = {\n 'loop.event_kind': event.kind,\n 'loop.run_id': event.runId,\n }\n for (const [k, v] of Object.entries(event.payload)) {\n if (typeof v === 'string' || typeof v === 'number' || typeof v === 'boolean') {\n attrs[`loop.${k}`] = v\n }\n }\n const ts = msToNs(event.timestamp)\n return {\n traceId: padTraceId(traceId),\n spanId,\n parentSpanId: parentSpanId ? padSpanId(parentSpanId) : undefined,\n name: event.kind,\n kind: 1,\n startTimeUnixNano: ts,\n endTimeUnixNano: ts,\n attributes: toAttributes(attrs),\n status: { code: 1 },\n }\n}\n\n/**\n * Build a nested, real-duration OTLP span tree for ONE loop run from its full\n * ordered `LoopTraceEvent` stream. Unlike `loopEventToOtelSpan` (one flat,\n * zero-duration span per event), this reconstructs the topology hierarchy a\n * GenAI trace viewer renders natively:\n *\n * loop (invoke_workflow)\n * └─ loop.round[k] (invoke_workflow) ← tangle.loop.move.{kind,width,rationale}\n * ├─ loop.iteration[i] (invoke_agent) ← gen_ai.agent.name + usage + verdict + placement\n * └─ …\n *\n * Attributes follow the current GenAI semconv (`gen_ai.*`) where they apply and\n * a namespaced `tangle.loop.*` / `tangle.cost.usd` extension for topology /\n * verdict / placement / cost (not yet standardized). Pure: feed it a buffered\n * per-runId event array (e.g. flushed on `loop.ended`) and export the result.\n */\nexport function buildLoopOtelSpans(\n events: ReadonlyArray<{ kind: string; runId: string; timestamp: number; payload: object }>,\n traceId: string,\n rootParentSpanId?: string,\n): OtelSpan[] {\n if (events.length === 0) return []\n const tid = padTraceId(traceId)\n const out: OtelSpan[] = []\n const num = (v: unknown): number | undefined =>\n typeof v === 'number' && Number.isFinite(v) ? v : undefined\n const str = (v: unknown): string | undefined =>\n typeof v === 'string' && v.length > 0 ? v : undefined\n const rec = (v: unknown): Record<string, unknown> =>\n v && typeof v === 'object' ? (v as Record<string, unknown>) : {}\n\n const started = events.find((e) => e.kind === 'loop.started')\n const ended = events.find((e) => e.kind === 'loop.ended')\n const runId = events[0]?.runId ?? ''\n const rootStart = started?.timestamp ?? events[0]!.timestamp\n const rootEnd = ended?.timestamp ?? events[events.length - 1]!.timestamp\n const rootId = generateSpanId()\n\n const make = (\n spanId: string,\n parentSpanId: string | undefined,\n name: string,\n startMs: number,\n endMs: number,\n attrs: Record<string, string | number | boolean>,\n statusCode = 1,\n ): OtelSpan => ({\n traceId: tid,\n spanId,\n parentSpanId: parentSpanId ? padSpanId(parentSpanId) : undefined,\n name,\n kind: 1,\n startTimeUnixNano: msToNs(startMs),\n endTimeUnixNano: msToNs(endMs),\n attributes: toAttributes(attrs),\n status: { code: statusCode },\n })\n\n // root\n const sp = rec(started?.payload)\n const rootAttrs: Record<string, string | number | boolean> = {\n [GEN_AI.operation]: 'invoke_workflow',\n [GEN_AI.conversationId]: runId,\n 'tangle.loop.driver': str(sp.driver) ?? 'driver',\n }\n if (Array.isArray(sp.agentRunNames) && sp.agentRunNames.length > 0) {\n rootAttrs['tangle.loop.agents'] = sp.agentRunNames.map(String).join(',')\n }\n if (ended) {\n const ep = rec(ended.payload)\n const win = num(ep.winnerIterationIndex)\n if (win !== undefined) rootAttrs['tangle.loop.winner.iteration_index'] = win\n const cost = num(ep.totalCostUsd)\n if (cost !== undefined) rootAttrs['tangle.cost.usd'] = cost\n const dur = num(ep.durationMs)\n if (dur !== undefined) rootAttrs['tangle.loop.duration_ms'] = dur\n const iters = num(ep.iterations)\n if (iters !== undefined) rootAttrs['tangle.loop.iterations'] = iters\n }\n out.push(make(rootId, rootParentSpanId, 'loop', rootStart, rootEnd, rootAttrs))\n\n // rounds + iterations\n const iterStartTs = new Map<number, number>()\n const placementByIdx = new Map<number, Record<string, string>>()\n let currentRoundId: string | undefined\n let pendingRound:\n | { id: string; start: number; attrs: Record<string, string | number | boolean> }\n | undefined\n const flushRound = (endMs: number) => {\n if (!pendingRound) return\n out.push(\n make(pendingRound.id, rootId, 'loop.round', pendingRound.start, endMs, pendingRound.attrs),\n )\n pendingRound = undefined\n }\n\n for (const e of events) {\n const p = rec(e.payload)\n switch (e.kind) {\n case 'loop.plan': {\n flushRound(e.timestamp)\n const id = generateSpanId()\n const roundIdx = num(p.roundIndex) ?? 0\n const attrs: Record<string, string | number | boolean> = {\n [GEN_AI.operation]: 'invoke_workflow',\n 'tangle.loop.round.index': roundIdx,\n 'tangle.loop.move.kind': str(p.moveKind) ?? 'unknown',\n 'tangle.loop.move.round': roundIdx,\n 'tangle.loop.move.width': num(p.plannedCount) ?? 0,\n }\n const r = str(p.rationale)\n if (r) attrs['tangle.loop.move.rationale'] = r\n const parent = num(p.parentIndex)\n if (parent !== undefined) attrs['tangle.loop.move.parent_index'] = parent\n if (Array.isArray(p.childIndices) && p.childIndices.length > 0) {\n attrs['tangle.loop.move.child_indices'] = p.childIndices.map(String).join(',')\n }\n pendingRound = { id, start: e.timestamp, attrs }\n currentRoundId = id\n break\n }\n case 'loop.iteration.started': {\n const idx = num(p.iterationIndex)\n if (idx !== undefined) iterStartTs.set(idx, e.timestamp)\n break\n }\n case 'loop.iteration.dispatch': {\n const idx = num(p.iterationIndex)\n if (idx === undefined) break\n const place: Record<string, string> = {}\n const kind = str(p.placement)\n if (kind) place['tangle.loop.placement.kind'] = kind\n const sid = str(p.sandboxId)\n if (sid) place['tangle.sandbox.id'] = sid\n const fid = str(p.fleetId)\n if (fid) place['tangle.fleet.id'] = fid\n const mid = str(p.machineId)\n if (mid) place['tangle.machine.id'] = mid\n placementByIdx.set(idx, place)\n break\n }\n case 'loop.iteration.ended': {\n const idx = num(p.iterationIndex) ?? 0\n const start = iterStartTs.get(idx) ?? e.timestamp\n const err = str(p.error)\n const attrs: Record<string, string | number | boolean> = {\n [GEN_AI.operation]: 'invoke_agent',\n 'tangle.loop.iteration.index': idx,\n }\n const agent = str(p.agentRunName)\n if (agent) attrs[GEN_AI.agentName] = agent\n const tu = rec(p.tokenUsage)\n const inTok = num(tu.input)\n if (inTok !== undefined) attrs[GEN_AI.inputTokens] = inTok\n const outTok = num(tu.output)\n if (outTok !== undefined) attrs[GEN_AI.outputTokens] = outTok\n const cost = num(p.costUsd)\n if (cost !== undefined) attrs['tangle.cost.usd'] = cost\n const verdict = rec(p.verdict)\n if (typeof verdict.valid === 'boolean') attrs['tangle.loop.verdict.valid'] = verdict.valid\n const score = num(verdict.score)\n if (score !== undefined) attrs['tangle.loop.verdict.score'] = score\n if (err) attrs['tangle.loop.error'] = err\n const gid = num(p.groupId)\n if (gid !== undefined) attrs['tangle.loop.iteration.group_id'] = gid\n const par = num(p.parentIndex)\n if (par !== undefined) attrs['tangle.loop.iteration.parent_index'] = par\n const dur = num(p.durationMs)\n if (dur !== undefined) attrs['tangle.loop.iteration.duration_ms'] = dur\n const preview = str(p.outputPreview)\n if (preview) attrs['tangle.loop.iteration.output_preview'] = preview\n Object.assign(attrs, placementByIdx.get(idx) ?? {})\n out.push(\n make(\n generateSpanId(),\n currentRoundId ?? rootId,\n 'loop.iteration',\n start,\n e.timestamp,\n attrs,\n err ? 2 : 1,\n ),\n )\n break\n }\n case 'loop.decision': {\n if (pendingRound) {\n const dec = str(p.decision)\n if (dec) pendingRound.attrs['tangle.loop.decision'] = dec\n flushRound(e.timestamp)\n }\n currentRoundId = undefined\n break\n }\n }\n }\n flushRound(rootEnd)\n return out\n}\n\nfunction parseHeadersFromEnv(): Record<string, string> {\n if (typeof process === 'undefined') return {}\n const raw = process.env.OTEL_EXPORTER_OTLP_HEADERS\n if (!raw) return {}\n const out: Record<string, string> = {}\n for (const pair of raw.split(',')) {\n const eq = pair.indexOf('=')\n if (eq < 0) continue\n const key = pair.slice(0, eq).trim()\n const value = pair.slice(eq + 1).trim()\n if (key) out[key] = value\n }\n return out\n}\n\nfunction toAttributes(record: Record<string, string | number | boolean>): OtelAttribute[] {\n return Object.entries(record).map(([key, value]) => ({\n key,\n value:\n typeof value === 'number'\n ? Number.isInteger(value)\n ? { intValue: value.toString() }\n : { doubleValue: value }\n : typeof value === 'boolean'\n ? { boolValue: value }\n : { stringValue: value },\n }))\n}\n\nfunction msToNs(ms: number): string {\n return (BigInt(Math.floor(ms)) * 1_000_000n).toString()\n}\n\nfunction padSpanId(id: string): string {\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 16).padEnd(16, '0')\n}\n\nfunction padTraceId(id: string): string {\n const cleaned = id.replace(/-/g, '')\n return cleaned.slice(0, 32).padEnd(32, '0')\n}\n\nfunction generateSpanId(): string {\n const bytes = new Uint8Array(8)\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 8; i++) bytes[i] = Math.floor(Math.random() * 256)\n }\n return Array.from(bytes)\n .map((b) => b.toString(16).padStart(2, '0'))\n .join('')\n}\n\n// ─── Eval-run ingest (self-improvement provenance) ───────────────────────────\n//\n// Tangle Intelligence has a first-class, non-trace record for self-improvement\n// runs: POST /v1/ingest/eval-runs (\"Mode D\"). Each generation carries a\n// `surfaceHash` (the proposed-change identity) + arbitrary `surface` provenance;\n// a later `gate-decided` event re-emits the same `runId` (idempotent upsert) with\n// a real `gateDecision` + `holdoutLift`, so proposal→verdict is one diffable\n// record. This is how a consumer's RSI loop records WHAT it changed, WHY, from\n// which evidence — the audit trail behind agentic self-improvement.\n\n/** Wire version the eval-runs ingest enforces (X-Tangle-Wire-Version + body). */\nexport const INTELLIGENCE_WIRE_VERSION = '2026-05-26.v1'\n\nexport interface EvalRunGeneration {\n /** 0-based ordinal of this generation within the run (required by ingest). */\n index: number\n /** Identity of the proposed surface change (content-addressed hash). */\n surfaceHash: string\n /** Arbitrary provenance for this generation (rationale, evidence, source). */\n surface?: unknown\n /** Per-scenario results; empty until the generation is measured. */\n cells?: unknown[]\n /** Mean composite score (0 when unmeasured — pair with labels.measured). */\n compositeMean: number\n costUsd: number\n durationMs: number\n}\n\nexport interface EvalRunEvent {\n runId: string\n runDir: string\n /** ISO timestamp. */\n timestamp: string\n status:\n | 'started'\n | 'baseline-complete'\n | 'generation-complete'\n | 'gate-decided'\n | 'finished'\n | 'errored'\n labels?: Record<string, string>\n baseline?: EvalRunGeneration\n generations?: EvalRunGeneration[]\n gateDecision?: 'ship' | 'hold' | 'need_more_work' | 'model_ceiling' | 'arch_ceiling'\n holdoutLift?: number\n totalCostUsd: number\n totalDurationMs: number\n errorMessage?: string\n}\n\nexport interface EvalRunsExportConfig {\n /** Bearer key — tenant is resolved server-side from it. Reads TANGLE_API_KEY. */\n apiKey?: string\n /** Intelligence base. Reads INTELLIGENCE_BASE env, else prod. */\n base?: string\n /** Idempotency-Key header (e.g. the runId) — safe retries + upsert. */\n idempotencyKey?: string\n}\n\nexport interface EvalRunsExportResult {\n ok: boolean\n status: number\n accepted: number\n rejected: Array<{ index: number; reason: string }>\n}\n\nconst DEFAULT_INTELLIGENCE_BASE = 'https://intelligence.tangle.tools'\n\n/**\n * Ship self-improvement eval-run events to Tangle Intelligence. Unlike the\n * best-effort span exporter, this RESOLVES with the ingest verdict (accepted /\n * rejected per event) so a consumer's loop can assert its provenance landed.\n * Throws only on a missing key or network failure.\n */\nexport async function exportEvalRuns(\n events: EvalRunEvent[],\n config?: EvalRunsExportConfig,\n): Promise<EvalRunsExportResult> {\n if (events.length === 0) return { ok: true, status: 0, accepted: 0, rejected: [] }\n const apiKey =\n config?.apiKey ?? (typeof process !== 'undefined' ? process.env.TANGLE_API_KEY : undefined)\n if (!apiKey)\n throw new Error('exportEvalRuns: apiKey required (pass config.apiKey or set TANGLE_API_KEY)')\n const base =\n config?.base ??\n (typeof process !== 'undefined' ? process.env.INTELLIGENCE_BASE : undefined) ??\n DEFAULT_INTELLIGENCE_BASE\n const url = `${base.replace(/\\/+$/, '')}/v1/ingest/eval-runs`\n const res = await fetch(url, {\n method: 'POST',\n headers: {\n 'content-type': 'application/json',\n authorization: `Bearer ${apiKey}`,\n 'X-Tangle-Wire-Version': INTELLIGENCE_WIRE_VERSION,\n ...(config?.idempotencyKey ? { 'Idempotency-Key': config.idempotencyKey } : {}),\n },\n body: JSON.stringify({ wireVersion: INTELLIGENCE_WIRE_VERSION, events }),\n })\n let parsed: { accepted?: number; rejected?: Array<{ index: number; reason: string }> } = {}\n try {\n parsed = (await res.json()) as typeof parsed\n } catch {\n // non-JSON body (e.g. 5xx HTML) — leave parsed empty\n }\n return {\n ok: res.ok,\n status: res.status,\n accepted: parsed.accepted ?? (res.ok ? events.length : 0),\n rejected: parsed.rejected ?? [],\n }\n}\n"],"mappings":"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","names":["SINGLE_VARIANT_ESTIMATE_MS","FANOUT_PER_VARIANT_ESTIMATE_MS","validateConfig","defaultEstimate"]}
|