@tangle-network/agent-runtime 0.35.0 → 0.37.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/dist/{chunk-5QVVET72.js → chunk-3HMHSN22.js} +17 -1
- package/dist/chunk-3HMHSN22.js.map +1 -0
- package/dist/{chunk-TT3IHIQT.js → chunk-M65QJD35.js} +5 -161
- package/dist/chunk-M65QJD35.js.map +1 -0
- package/dist/{chunk-7ZECSZ3C.js → chunk-T3GJBKHA.js} +2 -2
- package/dist/{chunk-HSX6PFZR.js → chunk-V6GURW4W.js} +209 -1
- package/dist/chunk-V6GURW4W.js.map +1 -0
- package/dist/index.d.ts +86 -3
- package/dist/index.js +50 -2
- package/dist/index.js.map +1 -1
- package/dist/loops.d.ts +2 -3
- package/dist/mcp/bin.js +5 -4
- package/dist/mcp/bin.js.map +1 -1
- package/dist/mcp/index.d.ts +81 -328
- package/dist/mcp/index.js +64 -7
- package/dist/mcp/index.js.map +1 -1
- package/dist/otel-export-DgFMwsVy.d.ts +552 -0
- package/dist/profiles.d.ts +1 -18
- package/dist/profiles.js +1 -1
- package/dist/{types-DrXVR2Fu.d.ts → types-CmTjKLyB.d.ts} +137 -3
- package/package.json +1 -1
- package/dist/chunk-5QVVET72.js.map +0 -1
- package/dist/chunk-HSX6PFZR.js.map +0 -1
- package/dist/chunk-TT3IHIQT.js.map +0 -1
- package/dist/otel-export-xgf4J6bo.d.ts +0 -191
- package/dist/runtime-run-B8VIiOhI.d.ts +0 -137
- /package/dist/{chunk-7ZECSZ3C.js.map → chunk-T3GJBKHA.js.map} +0 -0
package/dist/loops.d.ts
CHANGED
|
@@ -1,11 +1,10 @@
|
|
|
1
1
|
import { AgentProfile, SandboxEvent } from '@tangle-network/sandbox';
|
|
2
2
|
export { AgentProfile, CreateSandboxOptions, SandboxEvent, SandboxInstance } from '@tangle-network/sandbox';
|
|
3
|
-
import { I as Iteration, D as Driver, L as LoopSandboxClient, A as AgentRunSpec, O as OutputAdapter, V as Validator, E as ExecCtx, a as LoopWinner, b as LoopResult } from './types-
|
|
4
|
-
export { c as LoopDecisionPayload, d as LoopEndedPayload, e as LoopIterationDispatchPayload, f as LoopIterationEndedPayload, g as LoopIterationStartedPayload, h as LoopPlanDescription, i as LoopPlanPayload, j as LoopSandboxPlacement, k as LoopStartedPayload, l as LoopTokenUsage, m as LoopTraceEmitter, n as LoopTraceEvent, o as ValidationCtx } from './types-
|
|
3
|
+
import { I as Iteration, D as Driver, L as LoopSandboxClient, A as AgentRunSpec, O as OutputAdapter, V as Validator, E as ExecCtx, a as LoopWinner, b as LoopResult } from './types-CmTjKLyB.js';
|
|
4
|
+
export { c as LoopDecisionPayload, d as LoopEndedPayload, e as LoopIterationDispatchPayload, f as LoopIterationEndedPayload, g as LoopIterationStartedPayload, h as LoopPlanDescription, i as LoopPlanPayload, j as LoopSandboxPlacement, k as LoopStartedPayload, l as LoopTokenUsage, m as LoopTraceEmitter, n as LoopTraceEvent, o as ValidationCtx } from './types-CmTjKLyB.js';
|
|
5
5
|
import { DefaultVerdict, AgentProfile as AgentProfile$1 } from '@tangle-network/agent-eval';
|
|
6
6
|
export { DefaultVerdict } from '@tangle-network/agent-eval';
|
|
7
7
|
import { Scenario, DispatchFn, ProfileDispatchFn } from '@tangle-network/agent-eval/campaign';
|
|
8
|
-
import './runtime-run-B8VIiOhI.js';
|
|
9
8
|
import './types-CsCCryln.js';
|
|
10
9
|
|
|
11
10
|
/**
|
package/dist/mcp/bin.js
CHANGED
|
@@ -1,15 +1,16 @@
|
|
|
1
1
|
#!/usr/bin/env node
|
|
2
2
|
import {
|
|
3
|
-
createDefaultCoderDelegate,
|
|
4
3
|
createMcpServer,
|
|
5
4
|
detectExecutor
|
|
6
|
-
} from "../chunk-
|
|
7
|
-
import
|
|
5
|
+
} from "../chunk-M65QJD35.js";
|
|
6
|
+
import {
|
|
7
|
+
createDefaultCoderDelegate
|
|
8
|
+
} from "../chunk-V6GURW4W.js";
|
|
8
9
|
import "../chunk-GLR25NG7.js";
|
|
9
10
|
import {
|
|
10
11
|
runLoop
|
|
11
12
|
} from "../chunk-7JBDJQLO.js";
|
|
12
|
-
import "../chunk-
|
|
13
|
+
import "../chunk-3HMHSN22.js";
|
|
13
14
|
import "../chunk-PY6NMZYX.js";
|
|
14
15
|
import "../chunk-SQSCRJ7U.js";
|
|
15
16
|
import "../chunk-DGUM43GV.js";
|
package/dist/mcp/bin.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"sources":["../../src/mcp/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * @experimental\n *\n * `agent-runtime-mcp` — stdio MCP server entry point.\n *\n * Spins up a server with the default coder delegate (wired against the\n * real `@tangle-network/sandbox` client) and, when the optional\n * `@tangle-network/agent-knowledge` peer is installed, a researcher\n * delegate against `multiHarnessResearcherFanout`.\n *\n * Environment variables:\n * TANGLE_API_KEY required — passed to `new Sandbox({ apiKey })`\n * SANDBOX_BASE_URL optional — sandbox-SDK base URL override\n * TANGLE_FLEET_ID optional — when set, delegations dispatch\n * INTO this fleet's shared workspace instead\n * of creating sibling sandboxes. Set by the\n * parent sandbox when launching this MCP\n * server so worker diffs land on the caller's\n * filesystem with no cross-sandbox boundary.\n * TANGLE_FLEET_EXCLUDE_MACHINES optional — comma-separated machine ids to\n * skip during fleet-mode round-robin\n * (typically the coordinator machine this\n * MCP server is running on).\n * MCP_MAX_CONCURRENT_SANDBOXES default 4 — kernel maxConcurrency cap\n * MCP_CODER_FANOUT_HARNESSES comma-separated harness ids to use for variants > 1\n * MCP_DISABLE_CODER set to `1` to omit `delegate_code`\n * MCP_DISABLE_RESEARCHER set to `1` to omit `delegate_research` even when peer is present\n */\n\nimport type { LoopSandboxClient } from '../loops'\nimport { runLoop } from '../loops'\nimport { detectExecutor } from './bin-helpers'\nimport { createDefaultCoderDelegate, type ResearcherDelegate } from './delegates'\nimport type { DelegationExecutor } from './executor'\nimport { createMcpServer } from './server'\nimport type { ResearchOutputShape } from './types'\n\nasync function main(): Promise<void> {\n const fanoutHarnesses = parseHarnesses(process.env.MCP_CODER_FANOUT_HARNESSES)\n const maxConcurrency = parseConcurrency(process.env.MCP_MAX_CONCURRENT_SANDBOXES)\n const wantCoder = !process.env.MCP_DISABLE_CODER\n const wantResearcher = !process.env.MCP_DISABLE_RESEARCHER\n const fleetId = parseFleetId(process.env.TANGLE_FLEET_ID)\n\n // Skip the sandbox client load entirely when no profile delegate needs it —\n // the feedback + status + history tools are queue-bound and require no\n // sandbox. Useful for tooling that mounts the MCP server purely for\n // self-introspection.\n const needsSandbox = wantCoder || wantResearcher\n let sandboxClient: LoopSandboxClient | undefined\n let executor: DelegationExecutor | undefined\n if (needsSandbox) {\n const apiKey = process.env.TANGLE_API_KEY\n if (!apiKey && !process.env.AGENT_RUNTIME_MCP_ALLOW_NO_KEY) {\n process.stderr.write(\n 'agent-runtime-mcp: TANGLE_API_KEY is required. Set AGENT_RUNTIME_MCP_ALLOW_NO_KEY=1 to run without it for diagnostics, or MCP_DISABLE_CODER=1 MCP_DISABLE_RESEARCHER=1 to run the queue-only subset.\\n',\n )\n process.exit(2)\n }\n // Fleet mode against a diagnostic stub is meaningless — the stub can't\n // resolve a real fleet handle. Refuse rather than silently degrading,\n // otherwise a fleet-mounted MCP would behave differently than configured.\n if (fleetId && !apiKey) {\n process.stderr.write(\n 'agent-runtime-mcp: TANGLE_FLEET_ID was set but TANGLE_API_KEY is missing; cannot resolve fleet handle. Provide an api key or unset TANGLE_FLEET_ID.\\n',\n )\n process.exit(2)\n }\n sandboxClient = await loadSandboxClient(apiKey)\n executor = await detectExecutor({ sandboxClient })\n if (fleetId) {\n process.stderr.write(`agent-runtime-mcp: fleet-aware delegation: fleetId=${fleetId}\\n`)\n }\n process.stderr.write(`agent-runtime-mcp: delegation placement → ${executor.describe()}\\n`)\n }\n\n const coderDelegate =\n wantCoder && executor\n ? createDefaultCoderDelegate({\n executor,\n fanoutHarnesses,\n maxConcurrency,\n })\n : undefined\n\n const researcherDelegate =\n wantResearcher && executor\n ? await loadResearcherDelegate(executor.client, maxConcurrency)\n : undefined\n\n const server = createMcpServer({ coderDelegate, researcherDelegate })\n\n process.on('SIGINT', () => {\n server.stop()\n process.exit(0)\n })\n process.on('SIGTERM', () => {\n server.stop()\n process.exit(0)\n })\n\n await server.serve()\n}\n\nasync function loadSandboxClient(apiKey: string | undefined): Promise<LoopSandboxClient> {\n // Diagnostic mode: AGENT_RUNTIME_MCP_ALLOW_NO_KEY=1 enables tools/list + the\n // queue-bound tools (status / history / feedback) without sandbox creds.\n // Coder + researcher delegations require a real client; the stub fails loud\n // at create() so the agent observes the cause instead of silent success.\n if (!apiKey) {\n return {\n async create() {\n throw new Error(\n 'agent-runtime-mcp: TANGLE_API_KEY is unset; coder/researcher delegations are disabled in diagnostic mode. Set TANGLE_API_KEY or use MCP_DISABLE_CODER=1 MCP_DISABLE_RESEARCHER=1 to remove the unsupported tools from the tool list.',\n )\n },\n } satisfies LoopSandboxClient\n }\n // Dynamic import keeps the bin importable in environments that haven't\n // installed `@tangle-network/sandbox` yet (the runtime package lists it\n // as a peer dep, not a hard dep).\n const mod = await import('@tangle-network/sandbox').catch((err) => {\n process.stderr.write(\n `agent-runtime-mcp: failed to load @tangle-network/sandbox (${err.message}); install the peer dependency\\n`,\n )\n process.exit(2)\n })\n const SandboxCtor = (mod as { Sandbox?: new (config: unknown) => LoopSandboxClient }).Sandbox\n if (!SandboxCtor) {\n process.stderr.write(\n 'agent-runtime-mcp: @tangle-network/sandbox does not export Sandbox; cannot construct client\\n',\n )\n process.exit(2)\n }\n const baseUrl = process.env.SANDBOX_BASE_URL\n return new SandboxCtor({\n apiKey,\n ...(baseUrl ? { baseUrl } : {}),\n })\n}\n\ninterface ResearcherProfilePreset {\n agentRunSpec: Parameters<typeof runLoop>[0]['agentRun'] extends infer T ? NonNullable<T> : never\n output: Parameters<typeof runLoop>[0]['output']\n validator: Parameters<typeof runLoop>[0]['validator']\n}\n\ninterface ResearcherFanoutPreset {\n agentRuns: NonNullable<Parameters<typeof runLoop>[0]['agentRuns']>\n output: Parameters<typeof runLoop>[0]['output']\n validator: Parameters<typeof runLoop>[0]['validator']\n driver: Parameters<typeof runLoop>[0]['driver']\n}\n\nasync function loadResearcherDelegate(\n sandboxClient: LoopSandboxClient,\n maxConcurrency: number,\n): Promise<ResearcherDelegate | undefined> {\n // Optional peer — when `@tangle-network/agent-knowledge` isn't installed,\n // we silently omit the researcher tool from the advertisement. The\n // dynamic-import path is resolved at runtime; TypeScript cannot see the\n // peer, so we type the module structurally rather than via its own\n // declaration file.\n const profilesSpecifier = '@tangle-network/agent-knowledge/profiles'\n const mod = await import(profilesSpecifier).catch(() => undefined)\n if (!mod) return undefined\n type SingleFactory = (opts: { task: unknown }) => ResearcherProfilePreset\n type FanoutFactory = (opts: { task: unknown }) => ResearcherFanoutPreset\n const fanoutFactory = (mod as { multiHarnessResearcherFanout?: FanoutFactory })\n .multiHarnessResearcherFanout\n const singleFactory = (mod as { researcherProfile?: SingleFactory }).researcherProfile\n if (!fanoutFactory || !singleFactory) return undefined\n\n return async (args, ctx) => {\n const task = {\n question: args.question,\n knowledgeNamespace: args.namespace,\n scope: args.scope,\n sources: args.sources,\n recencyWindow: args.config?.recencyWindow\n ? {\n since: args.config.recencyWindow.since\n ? new Date(args.config.recencyWindow.since)\n : undefined,\n until: args.config.recencyWindow.until\n ? new Date(args.config.recencyWindow.until)\n : undefined,\n }\n : undefined,\n maxItems: args.config?.maxItems,\n minConfidence: args.config?.minConfidence,\n }\n const variants = Math.max(1, Math.trunc(args.variants ?? 1))\n ctx.report({ iteration: 0, phase: 'starting' })\n if (variants <= 1) {\n const preset = singleFactory({ task })\n const result = await runLoop({\n driver: {\n name: 'mcp-researcher-single',\n async plan(t, history) {\n return history.length === 0 ? [t] : []\n },\n decide(history) {\n return history.length > 0 ? 'pick-winner' : 'fail'\n },\n },\n agentRun: preset.agentRunSpec,\n output: preset.output,\n validator: preset.validator,\n task,\n ctx: { sandboxClient, signal: ctx.signal },\n maxIterations: 1,\n maxConcurrency,\n })\n const output = result.winner?.output\n if (!output) throw new Error('researcher delegate produced no winner')\n ctx.report({ iteration: 1, phase: 'completed' })\n return output as ResearchOutputShape\n }\n const fanout = fanoutFactory({ task })\n const result = await runLoop({\n driver: fanout.driver,\n agentRuns: fanout.agentRuns.slice(0, variants),\n output: fanout.output,\n validator: fanout.validator,\n task,\n ctx: { sandboxClient, signal: ctx.signal },\n maxIterations: variants,\n maxConcurrency: Math.min(maxConcurrency, variants),\n })\n const output = result.winner?.output\n if (!output) throw new Error('researcher delegate fanout produced no winner')\n ctx.report({ iteration: result.iterations.length, phase: 'completed' })\n return output as ResearchOutputShape\n }\n}\n\nfunction parseHarnesses(raw: string | undefined): string[] | undefined {\n if (!raw) return undefined\n const list = raw\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean)\n return list.length > 0 ? list : undefined\n}\n\nfunction parseFleetId(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nfunction parseConcurrency(raw: string | undefined): number {\n if (!raw) return 4\n const n = Number(raw)\n if (!Number.isFinite(n) || n < 1) return 4\n return Math.min(Math.trunc(n), 32)\n}\n\nmain().catch((err) => {\n process.stderr.write(`agent-runtime-mcp: ${err instanceof Error ? err.stack : String(err)}\\n`)\n process.exit(1)\n})\n"],"mappings":"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","names":["result","output"]}
|
|
1
|
+
{"version":3,"sources":["../../src/mcp/bin.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * @experimental\n *\n * `agent-runtime-mcp` — stdio MCP server entry point.\n *\n * Spins up a server with the default coder delegate (wired against the\n * real `@tangle-network/sandbox` client) and, when the optional\n * `@tangle-network/agent-knowledge` peer is installed, a researcher\n * delegate against `multiHarnessResearcherFanout`.\n *\n * Environment variables:\n * TANGLE_API_KEY required — passed to `new Sandbox({ apiKey })`\n * SANDBOX_BASE_URL optional — sandbox-SDK base URL override\n * TANGLE_FLEET_ID optional — when set, delegations dispatch\n * INTO this fleet's shared workspace instead\n * of creating sibling sandboxes. Set by the\n * parent sandbox when launching this MCP\n * server so worker diffs land on the caller's\n * filesystem with no cross-sandbox boundary.\n * TANGLE_FLEET_EXCLUDE_MACHINES optional — comma-separated machine ids to\n * skip during fleet-mode round-robin\n * (typically the coordinator machine this\n * MCP server is running on).\n * MCP_MAX_CONCURRENT_SANDBOXES default 4 — kernel maxConcurrency cap\n * MCP_CODER_FANOUT_HARNESSES comma-separated harness ids to use for variants > 1\n * MCP_DISABLE_CODER set to `1` to omit `delegate_code`\n * MCP_DISABLE_RESEARCHER set to `1` to omit `delegate_research` even when peer is present\n */\n\nimport type { LoopSandboxClient } from '../loops'\nimport { runLoop } from '../loops'\nimport { detectExecutor } from './bin-helpers'\nimport { createDefaultCoderDelegate, type ResearcherDelegate } from './delegates'\nimport type { DelegationExecutor } from './executor'\nimport { createMcpServer } from './server'\nimport type { ResearchOutputShape } from './types'\n\nasync function main(): Promise<void> {\n const fanoutHarnesses = parseHarnesses(process.env.MCP_CODER_FANOUT_HARNESSES)\n const maxConcurrency = parseConcurrency(process.env.MCP_MAX_CONCURRENT_SANDBOXES)\n const wantCoder = !process.env.MCP_DISABLE_CODER\n const wantResearcher = !process.env.MCP_DISABLE_RESEARCHER\n const fleetId = parseFleetId(process.env.TANGLE_FLEET_ID)\n\n // Skip the sandbox client load entirely when no profile delegate needs it —\n // the feedback + status + history tools are queue-bound and require no\n // sandbox. Useful for tooling that mounts the MCP server purely for\n // self-introspection.\n const needsSandbox = wantCoder || wantResearcher\n let sandboxClient: LoopSandboxClient | undefined\n let executor: DelegationExecutor | undefined\n if (needsSandbox) {\n const apiKey = process.env.TANGLE_API_KEY\n if (!apiKey && !process.env.AGENT_RUNTIME_MCP_ALLOW_NO_KEY) {\n process.stderr.write(\n 'agent-runtime-mcp: TANGLE_API_KEY is required. Set AGENT_RUNTIME_MCP_ALLOW_NO_KEY=1 to run without it for diagnostics, or MCP_DISABLE_CODER=1 MCP_DISABLE_RESEARCHER=1 to run the queue-only subset.\\n',\n )\n process.exit(2)\n }\n // Fleet mode against a diagnostic stub is meaningless — the stub can't\n // resolve a real fleet handle. Refuse rather than silently degrading,\n // otherwise a fleet-mounted MCP would behave differently than configured.\n if (fleetId && !apiKey) {\n process.stderr.write(\n 'agent-runtime-mcp: TANGLE_FLEET_ID was set but TANGLE_API_KEY is missing; cannot resolve fleet handle. Provide an api key or unset TANGLE_FLEET_ID.\\n',\n )\n process.exit(2)\n }\n sandboxClient = await loadSandboxClient(apiKey)\n executor = await detectExecutor({ sandboxClient })\n if (fleetId) {\n process.stderr.write(`agent-runtime-mcp: fleet-aware delegation: fleetId=${fleetId}\\n`)\n }\n process.stderr.write(`agent-runtime-mcp: delegation placement → ${executor.describe()}\\n`)\n }\n\n const coderDelegate =\n wantCoder && executor\n ? createDefaultCoderDelegate({\n executor,\n fanoutHarnesses,\n maxConcurrency,\n })\n : undefined\n\n const researcherDelegate =\n wantResearcher && executor\n ? await loadResearcherDelegate(executor.client, maxConcurrency)\n : undefined\n\n const server = createMcpServer({ coderDelegate, researcherDelegate })\n\n process.on('SIGINT', () => {\n server.stop()\n process.exit(0)\n })\n process.on('SIGTERM', () => {\n server.stop()\n process.exit(0)\n })\n\n await server.serve()\n}\n\nasync function loadSandboxClient(apiKey: string | undefined): Promise<LoopSandboxClient> {\n // Diagnostic mode: AGENT_RUNTIME_MCP_ALLOW_NO_KEY=1 enables tools/list + the\n // queue-bound tools (status / history / feedback) without sandbox creds.\n // Coder + researcher delegations require a real client; the stub fails loud\n // at create() so the agent observes the cause instead of silent success.\n if (!apiKey) {\n return {\n async create() {\n throw new Error(\n 'agent-runtime-mcp: TANGLE_API_KEY is unset; coder/researcher delegations are disabled in diagnostic mode. Set TANGLE_API_KEY or use MCP_DISABLE_CODER=1 MCP_DISABLE_RESEARCHER=1 to remove the unsupported tools from the tool list.',\n )\n },\n } satisfies LoopSandboxClient\n }\n // Dynamic import keeps the bin importable in environments that haven't\n // installed `@tangle-network/sandbox` yet (the runtime package lists it\n // as a peer dep, not a hard dep).\n const mod = await import('@tangle-network/sandbox').catch((err) => {\n process.stderr.write(\n `agent-runtime-mcp: failed to load @tangle-network/sandbox (${err.message}); install the peer dependency\\n`,\n )\n process.exit(2)\n })\n const SandboxCtor = (mod as { Sandbox?: new (config: unknown) => LoopSandboxClient }).Sandbox\n if (!SandboxCtor) {\n process.stderr.write(\n 'agent-runtime-mcp: @tangle-network/sandbox does not export Sandbox; cannot construct client\\n',\n )\n process.exit(2)\n }\n const baseUrl = process.env.SANDBOX_BASE_URL\n return new SandboxCtor({\n apiKey,\n ...(baseUrl ? { baseUrl } : {}),\n })\n}\n\ninterface ResearcherProfilePreset {\n agentRunSpec: Parameters<typeof runLoop>[0]['agentRun'] extends infer T ? NonNullable<T> : never\n output: Parameters<typeof runLoop>[0]['output']\n validator: Parameters<typeof runLoop>[0]['validator']\n}\n\ninterface ResearcherFanoutPreset {\n agentRuns: NonNullable<Parameters<typeof runLoop>[0]['agentRuns']>\n output: Parameters<typeof runLoop>[0]['output']\n validator: Parameters<typeof runLoop>[0]['validator']\n driver: Parameters<typeof runLoop>[0]['driver']\n}\n\nasync function loadResearcherDelegate(\n sandboxClient: LoopSandboxClient,\n maxConcurrency: number,\n): Promise<ResearcherDelegate | undefined> {\n // Optional peer — when `@tangle-network/agent-knowledge` isn't installed,\n // we silently omit the researcher tool from the advertisement. The\n // dynamic-import path is resolved at runtime; TypeScript cannot see the\n // peer, so we type the module structurally rather than via its own\n // declaration file.\n const profilesSpecifier = '@tangle-network/agent-knowledge/profiles'\n const mod = await import(profilesSpecifier).catch(() => undefined)\n if (!mod) return undefined\n type SingleFactory = (opts: { task: unknown }) => ResearcherProfilePreset\n type FanoutFactory = (opts: { task: unknown }) => ResearcherFanoutPreset\n const fanoutFactory = (mod as { multiHarnessResearcherFanout?: FanoutFactory })\n .multiHarnessResearcherFanout\n const singleFactory = (mod as { researcherProfile?: SingleFactory }).researcherProfile\n if (!fanoutFactory || !singleFactory) return undefined\n\n return async (args, ctx) => {\n const task = {\n question: args.question,\n knowledgeNamespace: args.namespace,\n scope: args.scope,\n sources: args.sources,\n recencyWindow: args.config?.recencyWindow\n ? {\n since: args.config.recencyWindow.since\n ? new Date(args.config.recencyWindow.since)\n : undefined,\n until: args.config.recencyWindow.until\n ? new Date(args.config.recencyWindow.until)\n : undefined,\n }\n : undefined,\n maxItems: args.config?.maxItems,\n minConfidence: args.config?.minConfidence,\n }\n const variants = Math.max(1, Math.trunc(args.variants ?? 1))\n ctx.report({ iteration: 0, phase: 'starting' })\n if (variants <= 1) {\n const preset = singleFactory({ task })\n const result = await runLoop({\n driver: {\n name: 'mcp-researcher-single',\n async plan(t, history) {\n return history.length === 0 ? [t] : []\n },\n decide(history) {\n return history.length > 0 ? 'pick-winner' : 'fail'\n },\n },\n agentRun: preset.agentRunSpec,\n output: preset.output,\n validator: preset.validator,\n task,\n ctx: { sandboxClient, signal: ctx.signal },\n maxIterations: 1,\n maxConcurrency,\n })\n const output = result.winner?.output\n if (!output) throw new Error('researcher delegate produced no winner')\n ctx.report({ iteration: 1, phase: 'completed' })\n return output as ResearchOutputShape\n }\n const fanout = fanoutFactory({ task })\n const result = await runLoop({\n driver: fanout.driver,\n agentRuns: fanout.agentRuns.slice(0, variants),\n output: fanout.output,\n validator: fanout.validator,\n task,\n ctx: { sandboxClient, signal: ctx.signal },\n maxIterations: variants,\n maxConcurrency: Math.min(maxConcurrency, variants),\n })\n const output = result.winner?.output\n if (!output) throw new Error('researcher delegate fanout produced no winner')\n ctx.report({ iteration: result.iterations.length, phase: 'completed' })\n return output as ResearchOutputShape\n }\n}\n\nfunction parseHarnesses(raw: string | undefined): string[] | undefined {\n if (!raw) return undefined\n const list = raw\n .split(',')\n .map((entry) => entry.trim())\n .filter(Boolean)\n return list.length > 0 ? list : undefined\n}\n\nfunction parseFleetId(raw: string | undefined): string | undefined {\n if (typeof raw !== 'string') return undefined\n const trimmed = raw.trim()\n return trimmed.length > 0 ? trimmed : undefined\n}\n\nfunction parseConcurrency(raw: string | undefined): number {\n if (!raw) return 4\n const n = Number(raw)\n if (!Number.isFinite(n) || n < 1) return 4\n return Math.min(Math.trunc(n), 32)\n}\n\nmain().catch((err) => {\n process.stderr.write(`agent-runtime-mcp: ${err instanceof Error ? err.stack : String(err)}\\n`)\n process.exit(1)\n})\n"],"mappings":";;;;;;;;;;;;;;;;;;AAuCA,eAAe,OAAsB;AACnC,QAAM,kBAAkB,eAAe,QAAQ,IAAI,0BAA0B;AAC7E,QAAM,iBAAiB,iBAAiB,QAAQ,IAAI,4BAA4B;AAChF,QAAM,YAAY,CAAC,QAAQ,IAAI;AAC/B,QAAM,iBAAiB,CAAC,QAAQ,IAAI;AACpC,QAAM,UAAU,aAAa,QAAQ,IAAI,eAAe;AAMxD,QAAM,eAAe,aAAa;AAClC,MAAI;AACJ,MAAI;AACJ,MAAI,cAAc;AAChB,UAAM,SAAS,QAAQ,IAAI;AAC3B,QAAI,CAAC,UAAU,CAAC,QAAQ,IAAI,gCAAgC;AAC1D,cAAQ,OAAO;AAAA,QACb;AAAA,MACF;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AAIA,QAAI,WAAW,CAAC,QAAQ;AACtB,cAAQ,OAAO;AAAA,QACb;AAAA,MACF;AACA,cAAQ,KAAK,CAAC;AAAA,IAChB;AACA,oBAAgB,MAAM,kBAAkB,MAAM;AAC9C,eAAW,MAAM,eAAe,EAAE,cAAc,CAAC;AACjD,QAAI,SAAS;AACX,cAAQ,OAAO,MAAM,sDAAsD,OAAO;AAAA,CAAI;AAAA,IACxF;AACA,YAAQ,OAAO,MAAM,kDAA6C,SAAS,SAAS,CAAC;AAAA,CAAI;AAAA,EAC3F;AAEA,QAAM,gBACJ,aAAa,WACT,2BAA2B;AAAA,IACzB;AAAA,IACA;AAAA,IACA;AAAA,EACF,CAAC,IACD;AAEN,QAAM,qBACJ,kBAAkB,WACd,MAAM,uBAAuB,SAAS,QAAQ,cAAc,IAC5D;AAEN,QAAM,SAAS,gBAAgB,EAAE,eAAe,mBAAmB,CAAC;AAEpE,UAAQ,GAAG,UAAU,MAAM;AACzB,WAAO,KAAK;AACZ,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACD,UAAQ,GAAG,WAAW,MAAM;AAC1B,WAAO,KAAK;AACZ,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AAED,QAAM,OAAO,MAAM;AACrB;AAEA,eAAe,kBAAkB,QAAwD;AAKvF,MAAI,CAAC,QAAQ;AACX,WAAO;AAAA,MACL,MAAM,SAAS;AACb,cAAM,IAAI;AAAA,UACR;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAIA,QAAM,MAAM,MAAM,OAAO,yBAAyB,EAAE,MAAM,CAAC,QAAQ;AACjE,YAAQ,OAAO;AAAA,MACb,8DAA8D,IAAI,OAAO;AAAA;AAAA,IAC3E;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB,CAAC;AACD,QAAM,cAAe,IAAiE;AACtF,MAAI,CAAC,aAAa;AAChB,YAAQ,OAAO;AAAA,MACb;AAAA,IACF;AACA,YAAQ,KAAK,CAAC;AAAA,EAChB;AACA,QAAM,UAAU,QAAQ,IAAI;AAC5B,SAAO,IAAI,YAAY;AAAA,IACrB;AAAA,IACA,GAAI,UAAU,EAAE,QAAQ,IAAI,CAAC;AAAA,EAC/B,CAAC;AACH;AAeA,eAAe,uBACb,eACA,gBACyC;AAMzC,QAAM,oBAAoB;AAC1B,QAAM,MAAM,MAAM,OAAO,mBAAmB,MAAM,MAAM,MAAS;AACjE,MAAI,CAAC,IAAK,QAAO;AAGjB,QAAM,gBAAiB,IACpB;AACH,QAAM,gBAAiB,IAA8C;AACrE,MAAI,CAAC,iBAAiB,CAAC,cAAe,QAAO;AAE7C,SAAO,OAAO,MAAM,QAAQ;AAC1B,UAAM,OAAO;AAAA,MACX,UAAU,KAAK;AAAA,MACf,oBAAoB,KAAK;AAAA,MACzB,OAAO,KAAK;AAAA,MACZ,SAAS,KAAK;AAAA,MACd,eAAe,KAAK,QAAQ,gBACxB;AAAA,QACE,OAAO,KAAK,OAAO,cAAc,QAC7B,IAAI,KAAK,KAAK,OAAO,cAAc,KAAK,IACxC;AAAA,QACJ,OAAO,KAAK,OAAO,cAAc,QAC7B,IAAI,KAAK,KAAK,OAAO,cAAc,KAAK,IACxC;AAAA,MACN,IACA;AAAA,MACJ,UAAU,KAAK,QAAQ;AAAA,MACvB,eAAe,KAAK,QAAQ;AAAA,IAC9B;AACA,UAAM,WAAW,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,YAAY,CAAC,CAAC;AAC3D,QAAI,OAAO,EAAE,WAAW,GAAG,OAAO,WAAW,CAAC;AAC9C,QAAI,YAAY,GAAG;AACjB,YAAM,SAAS,cAAc,EAAE,KAAK,CAAC;AACrC,YAAMA,UAAS,MAAM,QAAQ;AAAA,QAC3B,QAAQ;AAAA,UACN,MAAM;AAAA,UACN,MAAM,KAAK,GAAG,SAAS;AACrB,mBAAO,QAAQ,WAAW,IAAI,CAAC,CAAC,IAAI,CAAC;AAAA,UACvC;AAAA,UACA,OAAO,SAAS;AACd,mBAAO,QAAQ,SAAS,IAAI,gBAAgB;AAAA,UAC9C;AAAA,QACF;AAAA,QACA,UAAU,OAAO;AAAA,QACjB,QAAQ,OAAO;AAAA,QACf,WAAW,OAAO;AAAA,QAClB;AAAA,QACA,KAAK,EAAE,eAAe,QAAQ,IAAI,OAAO;AAAA,QACzC,eAAe;AAAA,QACf;AAAA,MACF,CAAC;AACD,YAAMC,UAASD,QAAO,QAAQ;AAC9B,UAAI,CAACC,QAAQ,OAAM,IAAI,MAAM,wCAAwC;AACrE,UAAI,OAAO,EAAE,WAAW,GAAG,OAAO,YAAY,CAAC;AAC/C,aAAOA;AAAA,IACT;AACA,UAAM,SAAS,cAAc,EAAE,KAAK,CAAC;AACrC,UAAM,SAAS,MAAM,QAAQ;AAAA,MAC3B,QAAQ,OAAO;AAAA,MACf,WAAW,OAAO,UAAU,MAAM,GAAG,QAAQ;AAAA,MAC7C,QAAQ,OAAO;AAAA,MACf,WAAW,OAAO;AAAA,MAClB;AAAA,MACA,KAAK,EAAE,eAAe,QAAQ,IAAI,OAAO;AAAA,MACzC,eAAe;AAAA,MACf,gBAAgB,KAAK,IAAI,gBAAgB,QAAQ;AAAA,IACnD,CAAC;AACD,UAAM,SAAS,OAAO,QAAQ;AAC9B,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,+CAA+C;AAC5E,QAAI,OAAO,EAAE,WAAW,OAAO,WAAW,QAAQ,OAAO,YAAY,CAAC;AACtE,WAAO;AAAA,EACT;AACF;AAEA,SAAS,eAAe,KAA+C;AACrE,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,OAAO,IACV,MAAM,GAAG,EACT,IAAI,CAAC,UAAU,MAAM,KAAK,CAAC,EAC3B,OAAO,OAAO;AACjB,SAAO,KAAK,SAAS,IAAI,OAAO;AAClC;AAEA,SAAS,aAAa,KAA6C;AACjE,MAAI,OAAO,QAAQ,SAAU,QAAO;AACpC,QAAM,UAAU,IAAI,KAAK;AACzB,SAAO,QAAQ,SAAS,IAAI,UAAU;AACxC;AAEA,SAAS,iBAAiB,KAAiC;AACzD,MAAI,CAAC,IAAK,QAAO;AACjB,QAAM,IAAI,OAAO,GAAG;AACpB,MAAI,CAAC,OAAO,SAAS,CAAC,KAAK,IAAI,EAAG,QAAO;AACzC,SAAO,KAAK,IAAI,KAAK,MAAM,CAAC,GAAG,EAAE;AACnC;AAEA,KAAK,EAAE,MAAM,CAAC,QAAQ;AACpB,UAAQ,OAAO,MAAM,sBAAsB,eAAe,QAAQ,IAAI,QAAQ,OAAO,GAAG,CAAC;AAAA,CAAI;AAC7F,UAAQ,KAAK,CAAC;AAChB,CAAC;","names":["result","output"]}
|
package/dist/mcp/index.d.ts
CHANGED
|
@@ -1,100 +1,14 @@
|
|
|
1
|
-
import { L as LoopSandboxClient, j as LoopSandboxPlacement, m as LoopTraceEmitter } from '../types-
|
|
2
|
-
import {
|
|
3
|
-
|
|
1
|
+
import { L as LoopSandboxClient, j as LoopSandboxPlacement, m as LoopTraceEmitter } from '../types-CmTjKLyB.js';
|
|
2
|
+
import { F as FleetHandle, D as DelegationExecutor, a as DelegateFeedbackArgs, b as DelegationFeedbackSnapshot, c as DelegationProfile, d as DelegateCodeArgs, e as DelegateResearchArgs, f as DelegationStatus, g as DelegationProgress, h as DelegationResultPayload, i as DelegationError, j as DelegationStatusResult, k as DelegationHistoryArgs, l as DelegationHistoryEntry, C as CoderDelegate, R as ResearcherDelegate, m as DelegateCodeResult, n as DelegateFeedbackResult, o as ResearchSource, p as DelegateResearchResult, q as DelegationHistoryResult, r as DelegationStatusArgs, O as OtelExporter } from '../otel-export-DgFMwsVy.js';
|
|
3
|
+
export { s as CoderReview, t as CoderReviewer, u as CoderWinnerSelection, v as CreateDefaultCoderDelegateOptions, w as DelegateCodeConfig, x as DelegateResearchConfig, y as DelegateRunCtx, z as FeedbackRating, A as FeedbackRefersTo, B as FleetWorkspaceExecutorOptions, E as ResearchOutputShape, S as SiblingSandboxExecutorOptions, G as createDefaultCoderDelegate, H as createFleetWorkspaceExecutor, I as createSiblingSandboxExecutor, J as mcpToolsForRuntimeMcp, K as mcpToolsForRuntimeMcpSubset } from '../otel-export-DgFMwsVy.js';
|
|
4
4
|
import { L as LocalHarness, r as runLocalHarness } from '../local-harness-KrdFTY5R.js';
|
|
5
5
|
export { a as LocalHarnessResult, R as RunLocalHarnessOptions } from '../local-harness-KrdFTY5R.js';
|
|
6
|
-
import { O as OtelExporter } from '../otel-export-xgf4J6bo.js';
|
|
7
|
-
export { m as mcpToolsForRuntimeMcp, a as mcpToolsForRuntimeMcpSubset } from '../otel-export-xgf4J6bo.js';
|
|
8
6
|
import '@tangle-network/agent-eval';
|
|
9
|
-
import '
|
|
7
|
+
import '@tangle-network/sandbox';
|
|
10
8
|
import '../types-CsCCryln.js';
|
|
9
|
+
import '../profiles.js';
|
|
11
10
|
import 'node:child_process';
|
|
12
11
|
|
|
13
|
-
/**
|
|
14
|
-
* @experimental
|
|
15
|
-
*
|
|
16
|
-
* Delegation executors — the layer between MCP delegates and the sandbox
|
|
17
|
-
* substrate. Each executor exposes a {@link LoopSandboxClient} the kernel
|
|
18
|
-
* consumes plus a placement tag so the trace pipeline can correlate workers
|
|
19
|
-
* with their physical placement.
|
|
20
|
-
*
|
|
21
|
-
* Two implementations ship in-box:
|
|
22
|
-
*
|
|
23
|
-
* - {@link createSiblingSandboxExecutor} — every delegation spawns a fresh
|
|
24
|
-
* sandbox sibling to the caller. Default when the MCP server runs as a
|
|
25
|
-
* standalone CLI mounted outside a fleet.
|
|
26
|
-
*
|
|
27
|
-
* - {@link createFleetWorkspaceExecutor} — delegations dispatch onto machines
|
|
28
|
-
* in the caller's existing fleet so worker diffs land directly on the
|
|
29
|
-
* caller's filesystem (the fleet's shared workspace). Selected when the
|
|
30
|
-
* parent sandbox passes `TANGLE_FLEET_ID` into the MCP server's env.
|
|
31
|
-
*/
|
|
32
|
-
|
|
33
|
-
/** @experimental */
|
|
34
|
-
interface DelegationExecutor {
|
|
35
|
-
/** Sandbox client the kernel calls. Returned with `describePlacement` set. */
|
|
36
|
-
readonly client: LoopSandboxClient;
|
|
37
|
-
/** Best-effort one-liner used in stderr boot logs and diagnostics. */
|
|
38
|
-
describe(): string;
|
|
39
|
-
}
|
|
40
|
-
/** @experimental */
|
|
41
|
-
interface SiblingSandboxExecutorOptions {
|
|
42
|
-
client: LoopSandboxClient;
|
|
43
|
-
}
|
|
44
|
-
/**
|
|
45
|
-
* Wrap a raw sandbox SDK client so the kernel emits
|
|
46
|
-
* `loop.iteration.dispatch` events with `{ placement: 'sibling', sandboxId }`.
|
|
47
|
-
*
|
|
48
|
-
* The returned client `.create()` delegates to the underlying client; the
|
|
49
|
-
* only added behavior is a `describePlacement` tag the kernel reads.
|
|
50
|
-
*
|
|
51
|
-
* @experimental
|
|
52
|
-
*/
|
|
53
|
-
declare function createSiblingSandboxExecutor(options: SiblingSandboxExecutorOptions): DelegationExecutor;
|
|
54
|
-
/**
|
|
55
|
-
* Minimal `SandboxFleet` surface the fleet executor calls. Declared
|
|
56
|
-
* structurally so tests can pass an in-memory stub without instantiating the
|
|
57
|
-
* sandbox SDK.
|
|
58
|
-
*
|
|
59
|
-
* @experimental
|
|
60
|
-
*/
|
|
61
|
-
interface FleetHandle {
|
|
62
|
-
readonly fleetId: string;
|
|
63
|
-
/** Machine ids in dispatch-eligible order. The executor round-robins. */
|
|
64
|
-
readonly ids: ReadonlyArray<string>;
|
|
65
|
-
/** Resolve a machine id to its `SandboxInstance` — that machine is mounted
|
|
66
|
-
* on the fleet's shared workspace, so any diff the worker writes lands on
|
|
67
|
-
* every other fleet machine's filesystem too. */
|
|
68
|
-
sandbox(machineId: string): Promise<SandboxInstance>;
|
|
69
|
-
}
|
|
70
|
-
/** @experimental */
|
|
71
|
-
interface FleetWorkspaceExecutorOptions {
|
|
72
|
-
fleet: FleetHandle;
|
|
73
|
-
/**
|
|
74
|
-
* Override the machine-selection policy. Default = round-robin across
|
|
75
|
-
* `fleet.ids`, skipping the optional `excludeMachineIds` set (typically the
|
|
76
|
-
* coordinator machine the MCP server is running on).
|
|
77
|
-
*/
|
|
78
|
-
selectMachine?: (call: {
|
|
79
|
-
callIndex: number;
|
|
80
|
-
ids: ReadonlyArray<string>;
|
|
81
|
-
}) => string;
|
|
82
|
-
/**
|
|
83
|
-
* Machine ids to skip during default round-robin. Set to the caller's own
|
|
84
|
-
* machineId so workers don't compete with the orchestrator on the same VM.
|
|
85
|
-
*/
|
|
86
|
-
excludeMachineIds?: ReadonlyArray<string>;
|
|
87
|
-
}
|
|
88
|
-
/**
|
|
89
|
-
* Build an executor that resolves each delegated iteration to an existing
|
|
90
|
-
* machine in `fleet`. The fleet's shared-workspace policy means the worker
|
|
91
|
-
* machine sees the caller's filesystem — diffs land in-place with no
|
|
92
|
-
* cross-sandbox copy step.
|
|
93
|
-
*
|
|
94
|
-
* @experimental
|
|
95
|
-
*/
|
|
96
|
-
declare function createFleetWorkspaceExecutor(options: FleetWorkspaceExecutorOptions): DelegationExecutor;
|
|
97
|
-
|
|
98
12
|
/**
|
|
99
13
|
* @experimental
|
|
100
14
|
*
|
|
@@ -131,242 +45,6 @@ interface DetectExecutorArgs {
|
|
|
131
45
|
*/
|
|
132
46
|
declare function detectExecutor(args: DetectExecutorArgs): Promise<DelegationExecutor>;
|
|
133
47
|
|
|
134
|
-
/**
|
|
135
|
-
* @experimental
|
|
136
|
-
*
|
|
137
|
-
* MCP delegation tool surface — the typed inputs/outputs the product agent
|
|
138
|
-
* sees over the wire. These types are the contract; the JSON schemas under
|
|
139
|
-
* `tools/*` mirror them for the MCP `tools/list` advertisement.
|
|
140
|
-
*
|
|
141
|
-
* Async semantics: `delegate_code` + `delegate_research` return a `taskId`
|
|
142
|
-
* immediately. The product agent polls `delegation_status` until the task
|
|
143
|
-
* transitions to `completed` | `failed` | `cancelled`. `delegate_feedback`
|
|
144
|
-
* + `delegation_history` are synchronous reads / writes against the local
|
|
145
|
-
* task queue + feedback store.
|
|
146
|
-
*/
|
|
147
|
-
|
|
148
|
-
/** @experimental */
|
|
149
|
-
type DelegationProfile = 'coder' | 'researcher';
|
|
150
|
-
/** @experimental */
|
|
151
|
-
type DelegationStatus = 'pending' | 'running' | 'completed' | 'failed' | 'cancelled';
|
|
152
|
-
/**
|
|
153
|
-
* Minimal `CoderTask` overrides exposed over the MCP wire. The full
|
|
154
|
-
* `CoderTask` carries fields the kernel synthesizes from `goal` +
|
|
155
|
-
* `repoRoot` — the agent only edits the few that materially gate
|
|
156
|
-
* validator behavior.
|
|
157
|
-
*
|
|
158
|
-
* @experimental
|
|
159
|
-
*/
|
|
160
|
-
interface DelegateCodeConfig {
|
|
161
|
-
testCmd?: string;
|
|
162
|
-
typecheckCmd?: string;
|
|
163
|
-
forbiddenPaths?: string[];
|
|
164
|
-
maxDiffLines?: number;
|
|
165
|
-
}
|
|
166
|
-
/** @experimental */
|
|
167
|
-
interface DelegateCodeArgs {
|
|
168
|
-
/** Natural-language description of what the coder must accomplish. */
|
|
169
|
-
goal: string;
|
|
170
|
-
/** Absolute path inside the sandbox where the repo lives. */
|
|
171
|
-
repoRoot: string;
|
|
172
|
-
/** Optional free-form context the agent surfaces in the prompt prelude. */
|
|
173
|
-
contextHint?: string;
|
|
174
|
-
/**
|
|
175
|
-
* When > 1, dispatches `multiHarnessCoderFanout` across N harnesses
|
|
176
|
-
* (claude-code, codex, opencode-glm) and picks the highest-scoring
|
|
177
|
-
* passing patch. Default 1.
|
|
178
|
-
*/
|
|
179
|
-
variants?: number;
|
|
180
|
-
/** Validator + prompt overrides the agent knows for this repo. */
|
|
181
|
-
config?: DelegateCodeConfig;
|
|
182
|
-
/** Multi-tenant scope (customer-id, workspace-id). */
|
|
183
|
-
namespace?: string;
|
|
184
|
-
}
|
|
185
|
-
/** @experimental */
|
|
186
|
-
interface DelegateCodeResult {
|
|
187
|
-
taskId: string;
|
|
188
|
-
/** Best-effort hint — coder loops can take minutes-to-hours. */
|
|
189
|
-
estimatedDurationMs?: number;
|
|
190
|
-
}
|
|
191
|
-
/** @experimental */
|
|
192
|
-
type ResearchSource = 'web' | 'corpus' | 'twitter' | 'github' | 'docs';
|
|
193
|
-
/** @experimental */
|
|
194
|
-
interface DelegateResearchConfig {
|
|
195
|
-
recencyWindow?: {
|
|
196
|
-
since?: string;
|
|
197
|
-
until?: string;
|
|
198
|
-
};
|
|
199
|
-
maxItems?: number;
|
|
200
|
-
minConfidence?: number;
|
|
201
|
-
}
|
|
202
|
-
/** @experimental */
|
|
203
|
-
interface DelegateResearchArgs {
|
|
204
|
-
question: string;
|
|
205
|
-
namespace: string;
|
|
206
|
-
scope?: string;
|
|
207
|
-
sources?: ResearchSource[];
|
|
208
|
-
variants?: number;
|
|
209
|
-
config?: DelegateResearchConfig;
|
|
210
|
-
}
|
|
211
|
-
/** @experimental */
|
|
212
|
-
interface DelegateResearchResult {
|
|
213
|
-
taskId: string;
|
|
214
|
-
estimatedDurationMs?: number;
|
|
215
|
-
}
|
|
216
|
-
/** @experimental */
|
|
217
|
-
interface FeedbackRefersTo {
|
|
218
|
-
kind: 'delegation' | 'artifact' | 'outcome';
|
|
219
|
-
/** For `'delegation'`, this is the taskId. */
|
|
220
|
-
ref: string;
|
|
221
|
-
}
|
|
222
|
-
/** @experimental */
|
|
223
|
-
interface FeedbackRating {
|
|
224
|
-
/** [0, 1]. */
|
|
225
|
-
score: number;
|
|
226
|
-
label?: 'good' | 'bad' | 'neutral' | 'mixed';
|
|
227
|
-
notes: string;
|
|
228
|
-
}
|
|
229
|
-
/** @experimental */
|
|
230
|
-
interface DelegateFeedbackArgs {
|
|
231
|
-
refersTo: FeedbackRefersTo;
|
|
232
|
-
rating: FeedbackRating;
|
|
233
|
-
by: 'agent' | 'user' | 'downstream-judge';
|
|
234
|
-
/** ISO timestamp; defaults to server clock when omitted. */
|
|
235
|
-
capturedAt?: string;
|
|
236
|
-
namespace?: string;
|
|
237
|
-
}
|
|
238
|
-
/** @experimental */
|
|
239
|
-
interface DelegateFeedbackResult {
|
|
240
|
-
recorded: true;
|
|
241
|
-
id: string;
|
|
242
|
-
}
|
|
243
|
-
/** @experimental */
|
|
244
|
-
interface DelegationStatusArgs {
|
|
245
|
-
taskId: string;
|
|
246
|
-
}
|
|
247
|
-
/** @experimental */
|
|
248
|
-
interface DelegationProgress {
|
|
249
|
-
iteration: number;
|
|
250
|
-
phase: string;
|
|
251
|
-
}
|
|
252
|
-
/** @experimental */
|
|
253
|
-
interface DelegationError {
|
|
254
|
-
message: string;
|
|
255
|
-
kind: string;
|
|
256
|
-
}
|
|
257
|
-
/**
|
|
258
|
-
* Polymorphic `result` field: `CoderOutput` when the underlying profile
|
|
259
|
-
* is `'coder'`, a structurally-typed research output when `'researcher'`.
|
|
260
|
-
* The MCP wire carries it as JSON either way.
|
|
261
|
-
*
|
|
262
|
-
* @experimental
|
|
263
|
-
*/
|
|
264
|
-
type DelegationResultPayload = {
|
|
265
|
-
profile: 'coder';
|
|
266
|
-
output: CoderOutput;
|
|
267
|
-
} | {
|
|
268
|
-
profile: 'researcher';
|
|
269
|
-
output: ResearchOutputShape;
|
|
270
|
-
};
|
|
271
|
-
/**
|
|
272
|
-
* Loose shape of a research output over the wire — the substrate cannot
|
|
273
|
-
* import the `ResearchOutput` type from agent-knowledge without inducing
|
|
274
|
-
* a dependency cycle, so the MCP layer treats it structurally.
|
|
275
|
-
*
|
|
276
|
-
* @experimental
|
|
277
|
-
*/
|
|
278
|
-
interface ResearchOutputShape {
|
|
279
|
-
items: unknown[];
|
|
280
|
-
citations: unknown[];
|
|
281
|
-
proposedWrites: unknown[];
|
|
282
|
-
gaps?: string[];
|
|
283
|
-
notes?: string;
|
|
284
|
-
[key: string]: unknown;
|
|
285
|
-
}
|
|
286
|
-
/** @experimental */
|
|
287
|
-
interface DelegationStatusResult {
|
|
288
|
-
taskId: string;
|
|
289
|
-
profile: DelegationProfile;
|
|
290
|
-
status: DelegationStatus;
|
|
291
|
-
progress?: DelegationProgress;
|
|
292
|
-
result?: DelegationResultPayload;
|
|
293
|
-
error?: DelegationError;
|
|
294
|
-
costUsd?: number;
|
|
295
|
-
startedAt: string;
|
|
296
|
-
completedAt?: string;
|
|
297
|
-
}
|
|
298
|
-
/** @experimental */
|
|
299
|
-
interface DelegationHistoryArgs {
|
|
300
|
-
namespace?: string;
|
|
301
|
-
profile?: DelegationProfile;
|
|
302
|
-
/** ISO date — only delegations started at-or-after `since` are returned. */
|
|
303
|
-
since?: string;
|
|
304
|
-
/** Default 50. Hard cap 500. */
|
|
305
|
-
limit?: number;
|
|
306
|
-
}
|
|
307
|
-
/** @experimental */
|
|
308
|
-
interface DelegationFeedbackSnapshot {
|
|
309
|
-
id: string;
|
|
310
|
-
score: number;
|
|
311
|
-
label?: FeedbackRating['label'];
|
|
312
|
-
by: DelegateFeedbackArgs['by'];
|
|
313
|
-
notes: string;
|
|
314
|
-
capturedAt: string;
|
|
315
|
-
}
|
|
316
|
-
/** @experimental */
|
|
317
|
-
interface DelegationHistoryEntry {
|
|
318
|
-
taskId: string;
|
|
319
|
-
profile: DelegationProfile;
|
|
320
|
-
namespace?: string;
|
|
321
|
-
args: DelegateCodeArgs | DelegateResearchArgs;
|
|
322
|
-
status: DelegationStatus;
|
|
323
|
-
feedback?: DelegationFeedbackSnapshot[];
|
|
324
|
-
costUsd?: number;
|
|
325
|
-
startedAt: string;
|
|
326
|
-
completedAt?: string;
|
|
327
|
-
}
|
|
328
|
-
/** @experimental */
|
|
329
|
-
interface DelegationHistoryResult {
|
|
330
|
-
delegations: DelegationHistoryEntry[];
|
|
331
|
-
}
|
|
332
|
-
|
|
333
|
-
/** @experimental */
|
|
334
|
-
interface DelegateRunCtx {
|
|
335
|
-
signal: AbortSignal;
|
|
336
|
-
report(progress: DelegationProgress): void;
|
|
337
|
-
}
|
|
338
|
-
/** @experimental */
|
|
339
|
-
type CoderDelegate = (args: DelegateCodeArgs, ctx: DelegateRunCtx) => Promise<CoderOutput>;
|
|
340
|
-
/** @experimental */
|
|
341
|
-
type ResearcherDelegate = (args: DelegateResearchArgs, ctx: DelegateRunCtx) => Promise<ResearchOutputShape>;
|
|
342
|
-
/** @experimental */
|
|
343
|
-
interface CreateDefaultCoderDelegateOptions {
|
|
344
|
-
/**
|
|
345
|
-
* Execution placement. Pass a {@link DelegationExecutor} (sibling or fleet)
|
|
346
|
-
* to control where worker iterations land. `sandboxClient` is a
|
|
347
|
-
* convenience shorthand that wraps the client in a sibling executor — pass
|
|
348
|
-
* one or the other, not both.
|
|
349
|
-
*/
|
|
350
|
-
executor?: DelegationExecutor;
|
|
351
|
-
/**
|
|
352
|
-
* Convenience shorthand for sibling placement. Equivalent to
|
|
353
|
-
* `executor: createSiblingSandboxExecutor({ client: sandboxClient })`.
|
|
354
|
-
*/
|
|
355
|
-
sandboxClient?: LoopSandboxClient;
|
|
356
|
-
/** Default `['claude-code', 'codex', 'opencode/zai-coding-plan/glm-5.1']` when variants > 1. */
|
|
357
|
-
fanoutHarnesses?: string[];
|
|
358
|
-
/** Hard cap on the kernel's per-batch concurrency. Default 4. */
|
|
359
|
-
maxConcurrency?: number;
|
|
360
|
-
}
|
|
361
|
-
/**
|
|
362
|
-
* Build a coder delegate that drives `runLoop` against the project's
|
|
363
|
-
* sandbox client + coder profile. When `args.variants > 1` it switches
|
|
364
|
-
* to the multi-harness fanout topology.
|
|
365
|
-
*
|
|
366
|
-
* @experimental
|
|
367
|
-
*/
|
|
368
|
-
declare function createDefaultCoderDelegate(options: CreateDefaultCoderDelegateOptions): CoderDelegate;
|
|
369
|
-
|
|
370
48
|
/**
|
|
371
49
|
* @experimental
|
|
372
50
|
*
|
|
@@ -607,6 +285,81 @@ interface InProcessExecutorDescribePlacement extends LoopSandboxPlacement {
|
|
|
607
285
|
*/
|
|
608
286
|
declare function createInProcessExecutor(options: InProcessExecutorOptions): DelegationExecutor;
|
|
609
287
|
|
|
288
|
+
/**
|
|
289
|
+
* @experimental
|
|
290
|
+
*
|
|
291
|
+
* `createKbGate` — the valid-only knowledge-base growth gate, distilled from
|
|
292
|
+
* physim's KB-research subsystem. A research-in-a-loop delegate (or any KB
|
|
293
|
+
* writer) runs candidate facts through this before persisting, so the KB grows
|
|
294
|
+
* with ONLY grounded facts — hallucinated, unsourced, or laundered claims are
|
|
295
|
+
* vetoed at the gate.
|
|
296
|
+
*
|
|
297
|
+
* Fail-closed by construction: every judge must `accept`; the FIRST veto wins
|
|
298
|
+
* and the fact is rejected. The non-negotiable floor (always on, can't be
|
|
299
|
+
* disabled) is the **passage-present guard** — a fact's `verbatimPassage` MUST
|
|
300
|
+
* literally appear in its `sourceText`. That single check kills the dominant
|
|
301
|
+
* failure mode (a confident claim decoupled from any real source).
|
|
302
|
+
*
|
|
303
|
+
* Pure + dependency-free: it operates on fact candidates, not on a store, so it
|
|
304
|
+
* composes with `@tangle-network/agent-knowledge` or any persistence layer
|
|
305
|
+
* without importing it. The remediation policy (correct-on-veto vs
|
|
306
|
+
* escalate-as-unverified) is the caller's — this returns the verdict; it never
|
|
307
|
+
* drops a fact silently.
|
|
308
|
+
*/
|
|
309
|
+
/** @experimental A fact proposed for the KB, with its grounding. */
|
|
310
|
+
interface FactCandidate {
|
|
311
|
+
/** The atomic claim text. */
|
|
312
|
+
claim: string;
|
|
313
|
+
/** Optional extracted value (number or string) the claim asserts. */
|
|
314
|
+
value?: string | number;
|
|
315
|
+
/** Verbatim span lifted from the source that backs the claim. */
|
|
316
|
+
verbatimPassage: string;
|
|
317
|
+
/** The raw source text the passage must be grounded in. */
|
|
318
|
+
sourceText: string;
|
|
319
|
+
/** Where the fact claims to come from — checked for circular/self citations. */
|
|
320
|
+
citation?: string;
|
|
321
|
+
}
|
|
322
|
+
/** @experimental */
|
|
323
|
+
interface FactJudgeVerdict {
|
|
324
|
+
accept: boolean;
|
|
325
|
+
reason?: string;
|
|
326
|
+
}
|
|
327
|
+
/** @experimental A pluggable fact validator. Throw is NOT allowed — return a
|
|
328
|
+
* verdict; a thrown judge is a programmer error, not a veto. */
|
|
329
|
+
interface FactJudge {
|
|
330
|
+
name: string;
|
|
331
|
+
judge(candidate: FactCandidate): FactJudgeVerdict | Promise<FactJudgeVerdict>;
|
|
332
|
+
}
|
|
333
|
+
/** @experimental */
|
|
334
|
+
interface KbGateResult {
|
|
335
|
+
accepted: boolean;
|
|
336
|
+
/** Name of the judge that vetoed; undefined when accepted. */
|
|
337
|
+
vetoedBy?: string;
|
|
338
|
+
reason?: string;
|
|
339
|
+
}
|
|
340
|
+
/** @experimental */
|
|
341
|
+
interface CreateKbGateOptions {
|
|
342
|
+
/** Extra judges appended after the built-in floor (e.g. an LLM judge). */
|
|
343
|
+
judges?: FactJudge[];
|
|
344
|
+
/** Minimum verbatim-passage length. Default 12 — kills empty/stub passages. */
|
|
345
|
+
minPassageChars?: number;
|
|
346
|
+
/**
|
|
347
|
+
* Citation tokens that denote a SELF-generated artifact (e.g. `'spec'`,
|
|
348
|
+
* `'cad_params'`, `'requirements'`). A citation naming one is circular
|
|
349
|
+
* (laundering) — the fact cites a derived artifact, not a real source.
|
|
350
|
+
* Default `[]` (no circular check unless the consumer declares its kinds).
|
|
351
|
+
*/
|
|
352
|
+
selfArtifactKinds?: string[];
|
|
353
|
+
}
|
|
354
|
+
/**
|
|
355
|
+
* @experimental
|
|
356
|
+
*
|
|
357
|
+
* Build a fail-closed KB gate. The returned function runs the built-in floor
|
|
358
|
+
* (passage-non-empty → passage-present → value-in-passage → no-circular-citation)
|
|
359
|
+
* then any consumer judges, returning on the first veto.
|
|
360
|
+
*/
|
|
361
|
+
declare function createKbGate(options?: CreateKbGateOptions): (candidate: FactCandidate) => Promise<KbGateResult>;
|
|
362
|
+
|
|
610
363
|
/**
|
|
611
364
|
* @experimental
|
|
612
365
|
*
|
|
@@ -1194,4 +947,4 @@ declare function createPropagatingTraceEmitter(ctx: TraceContext): {
|
|
|
1194
947
|
*/
|
|
1195
948
|
declare function traceContextToEnv(ctx: TraceContext): Record<string, string>;
|
|
1196
949
|
|
|
1197
|
-
export {
|
|
950
|
+
export { CoderDelegate, type CreateKbGateOptions, type CreateWorktreeOptions, DELEGATE_CODE_DESCRIPTION, DELEGATE_CODE_INPUT_SCHEMA, DELEGATE_CODE_TOOL_NAME, DELEGATE_FEEDBACK_DESCRIPTION, DELEGATE_FEEDBACK_INPUT_SCHEMA, DELEGATE_FEEDBACK_TOOL_NAME, DELEGATE_RESEARCH_DESCRIPTION, DELEGATE_RESEARCH_INPUT_SCHEMA, DELEGATE_RESEARCH_TOOL_NAME, DELEGATION_HISTORY_DESCRIPTION, DELEGATION_HISTORY_INPUT_SCHEMA, DELEGATION_HISTORY_TOOL_NAME, DELEGATION_STATUS_DESCRIPTION, DELEGATION_STATUS_INPUT_SCHEMA, DELEGATION_STATUS_TOOL_NAME, DelegateCodeArgs, DelegateCodeResult, DelegateFeedbackArgs, DelegateFeedbackResult, DelegateResearchArgs, DelegateResearchResult, DelegationError, DelegationExecutor, DelegationFeedbackSnapshot, DelegationHistoryArgs, DelegationHistoryEntry, DelegationHistoryResult, DelegationProfile, DelegationProgress, type DelegationRecord, DelegationResultPayload, DelegationStatus, DelegationStatusArgs, DelegationStatusResult, DelegationTaskQueue, type DelegationTaskQueueOptions, type DetectExecutorArgs, type DiffOptions, type DiffResult, type FactCandidate, type FactJudge, type FactJudgeVerdict, type FeedbackEvent, type FeedbackStore, FleetHandle, type GitRunner, InMemoryFeedbackStore, type InProcessExecutorDescribePlacement, type InProcessExecutorOptions, type JsonRpcMessage, type JsonRpcResponse, type KbGateResult, LocalHarness, type McpServer, type McpServerOptions, type McpToolDescriptor, type McpTransport, type RemoveWorktreeOptions, ResearchSource, ResearcherDelegate, type SubmitInput, type SubmitOutput, type TraceContext, type WorktreeHandle, captureWorktreeDiff, createDelegateCodeHandler, createDelegateFeedbackHandler, createDelegateResearchHandler, createDelegationHistoryHandler, createDelegationStatusHandler, createInProcessExecutor, createInProcessTransport, createKbGate, createMcpServer, createPropagatingTraceEmitter, createWorktree, detectExecutor, eventToSnapshot, hashIdempotencyInput, readTraceContextFromEnv, removeWorktree, runLocalHarness, traceContextToEnv, validateDelegateCodeArgs, validateDelegateFeedbackArgs, validateDelegateResearchArgs, validateDelegationHistoryArgs, validateDelegationStatusArgs };
|
package/dist/mcp/index.js
CHANGED
|
@@ -1,21 +1,18 @@
|
|
|
1
1
|
import {
|
|
2
2
|
captureWorktreeDiff,
|
|
3
|
-
createDefaultCoderDelegate,
|
|
4
|
-
createFleetWorkspaceExecutor,
|
|
5
3
|
createInProcessExecutor,
|
|
6
4
|
createInProcessTransport,
|
|
7
5
|
createMcpServer,
|
|
8
|
-
createSiblingSandboxExecutor,
|
|
9
6
|
createWorktree,
|
|
10
7
|
detectExecutor,
|
|
11
8
|
removeWorktree
|
|
12
|
-
} from "../chunk-
|
|
9
|
+
} from "../chunk-M65QJD35.js";
|
|
13
10
|
import {
|
|
14
11
|
buildLoopOtelSpans,
|
|
15
12
|
createOtelExporter,
|
|
16
13
|
mcpToolsForRuntimeMcp,
|
|
17
14
|
mcpToolsForRuntimeMcpSubset
|
|
18
|
-
} from "../chunk-
|
|
15
|
+
} from "../chunk-T3GJBKHA.js";
|
|
19
16
|
import {
|
|
20
17
|
DELEGATE_CODE_DESCRIPTION,
|
|
21
18
|
DELEGATE_CODE_INPUT_SCHEMA,
|
|
@@ -34,11 +31,14 @@ import {
|
|
|
34
31
|
DELEGATION_STATUS_TOOL_NAME,
|
|
35
32
|
DelegationTaskQueue,
|
|
36
33
|
InMemoryFeedbackStore,
|
|
34
|
+
createDefaultCoderDelegate,
|
|
37
35
|
createDelegateCodeHandler,
|
|
38
36
|
createDelegateFeedbackHandler,
|
|
39
37
|
createDelegateResearchHandler,
|
|
40
38
|
createDelegationHistoryHandler,
|
|
41
39
|
createDelegationStatusHandler,
|
|
40
|
+
createFleetWorkspaceExecutor,
|
|
41
|
+
createSiblingSandboxExecutor,
|
|
42
42
|
eventToSnapshot,
|
|
43
43
|
hashIdempotencyInput,
|
|
44
44
|
validateDelegateCodeArgs,
|
|
@@ -46,16 +46,72 @@ import {
|
|
|
46
46
|
validateDelegateResearchArgs,
|
|
47
47
|
validateDelegationHistoryArgs,
|
|
48
48
|
validateDelegationStatusArgs
|
|
49
|
-
} from "../chunk-
|
|
49
|
+
} from "../chunk-V6GURW4W.js";
|
|
50
50
|
import {
|
|
51
51
|
runLocalHarness
|
|
52
52
|
} from "../chunk-GLR25NG7.js";
|
|
53
53
|
import "../chunk-7JBDJQLO.js";
|
|
54
|
-
import "../chunk-
|
|
54
|
+
import "../chunk-3HMHSN22.js";
|
|
55
55
|
import "../chunk-PY6NMZYX.js";
|
|
56
56
|
import "../chunk-SQSCRJ7U.js";
|
|
57
57
|
import "../chunk-DGUM43GV.js";
|
|
58
58
|
|
|
59
|
+
// src/mcp/kb-gate.ts
|
|
60
|
+
var norm = (s) => s.toLowerCase().replace(/\s+/g, " ").trim();
|
|
61
|
+
function valueAppears(value, passageNorm) {
|
|
62
|
+
if (passageNorm.includes(norm(String(value)))) return true;
|
|
63
|
+
if (typeof value !== "number" || !Number.isFinite(value)) return false;
|
|
64
|
+
const forms = [value.toLocaleString("en-US")];
|
|
65
|
+
if (Math.abs(value) >= 1e9) forms.push(`${trimZero(value / 1e9)} billion`);
|
|
66
|
+
if (Math.abs(value) >= 1e6) forms.push(`${trimZero(value / 1e6)} million`);
|
|
67
|
+
return forms.some((f) => passageNorm.includes(norm(f)));
|
|
68
|
+
}
|
|
69
|
+
function trimZero(n) {
|
|
70
|
+
return Number.isInteger(n) ? String(n) : String(Number(n.toFixed(2)));
|
|
71
|
+
}
|
|
72
|
+
function builtinJudges(minPassageChars, selfArtifactKinds) {
|
|
73
|
+
const kinds = selfArtifactKinds.map((k) => k.toLowerCase());
|
|
74
|
+
return [
|
|
75
|
+
{
|
|
76
|
+
name: "passage-non-empty",
|
|
77
|
+
judge: (c) => c.verbatimPassage.trim().length >= minPassageChars ? { accept: true } : { accept: false, reason: `passage shorter than ${minPassageChars} chars` }
|
|
78
|
+
},
|
|
79
|
+
{
|
|
80
|
+
// THE anti-hallucination floor — the passage must literally be in the source.
|
|
81
|
+
name: "passage-present",
|
|
82
|
+
judge: (c) => norm(c.sourceText).includes(norm(c.verbatimPassage)) ? { accept: true } : { accept: false, reason: "verbatim passage not found in source (unbacked fact)" }
|
|
83
|
+
},
|
|
84
|
+
{
|
|
85
|
+
name: "value-in-passage",
|
|
86
|
+
judge: (c) => c.value === void 0 || valueAppears(c.value, norm(c.verbatimPassage)) ? { accept: true } : { accept: false, reason: `value ${JSON.stringify(c.value)} not present in passage` }
|
|
87
|
+
},
|
|
88
|
+
{
|
|
89
|
+
name: "no-circular-citation",
|
|
90
|
+
judge: (c) => {
|
|
91
|
+
if (!c.citation || kinds.length === 0) return { accept: true };
|
|
92
|
+
const cite = c.citation.toLowerCase();
|
|
93
|
+
const hit = kinds.find((k) => cite.includes(k));
|
|
94
|
+
return hit ? { accept: false, reason: `circular citation to self-generated artifact "${hit}"` } : { accept: true };
|
|
95
|
+
}
|
|
96
|
+
}
|
|
97
|
+
];
|
|
98
|
+
}
|
|
99
|
+
function createKbGate(options = {}) {
|
|
100
|
+
const judges = [
|
|
101
|
+
...builtinJudges(options.minPassageChars ?? 12, options.selfArtifactKinds ?? []),
|
|
102
|
+
...options.judges ?? []
|
|
103
|
+
];
|
|
104
|
+
return async (candidate) => {
|
|
105
|
+
for (const j of judges) {
|
|
106
|
+
const verdict = await j.judge(candidate);
|
|
107
|
+
if (!verdict.accept) {
|
|
108
|
+
return { accepted: false, vetoedBy: j.name, reason: verdict.reason };
|
|
109
|
+
}
|
|
110
|
+
}
|
|
111
|
+
return { accepted: true };
|
|
112
|
+
};
|
|
113
|
+
}
|
|
114
|
+
|
|
59
115
|
// src/mcp/trace-propagation.ts
|
|
60
116
|
function readTraceContextFromEnv() {
|
|
61
117
|
const traceId = process.env.TRACE_ID || generateTraceId();
|
|
@@ -124,6 +180,7 @@ export {
|
|
|
124
180
|
createFleetWorkspaceExecutor,
|
|
125
181
|
createInProcessExecutor,
|
|
126
182
|
createInProcessTransport,
|
|
183
|
+
createKbGate,
|
|
127
184
|
createMcpServer,
|
|
128
185
|
createPropagatingTraceEmitter,
|
|
129
186
|
createSiblingSandboxExecutor,
|