@tangle-network/agent-runtime 0.38.0 → 0.39.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.
Files changed (35) hide show
  1. package/dist/{chunk-Z523NPJK.js → chunk-7ZECSZ3C.js} +2 -59
  2. package/dist/chunk-7ZECSZ3C.js.map +1 -0
  3. package/dist/chunk-AXWGLYSF.js +201 -0
  4. package/dist/chunk-AXWGLYSF.js.map +1 -0
  5. package/dist/chunk-FNMGYYSS.js +60 -0
  6. package/dist/chunk-FNMGYYSS.js.map +1 -0
  7. package/dist/{chunk-V6GURW4W.js → chunk-HSX6PFZR.js} +1 -209
  8. package/dist/chunk-HSX6PFZR.js.map +1 -0
  9. package/dist/{chunk-M65QJD35.js → chunk-PK5DYSNO.js} +5 -3
  10. package/dist/{chunk-M65QJD35.js.map → chunk-PK5DYSNO.js.map} +1 -1
  11. package/dist/chunk-VLXRXMTF.js +212 -0
  12. package/dist/chunk-VLXRXMTF.js.map +1 -0
  13. package/dist/{dynamic-DeOPeeAw.d.ts → dynamic-DcrwVGuV.d.ts} +1 -1
  14. package/dist/improvement.d.ts +1 -1
  15. package/dist/index.d.ts +10 -147
  16. package/dist/index.js +23 -99
  17. package/dist/index.js.map +1 -1
  18. package/dist/{otel-export-CNmeg_7B.d.ts → kb-gate-YdPNEagq.d.ts} +2 -191
  19. package/dist/loop-runner-bin-DgZj0zfJ.d.ts +192 -0
  20. package/dist/loop-runner-bin.d.ts +12 -0
  21. package/dist/loop-runner-bin.js +19 -0
  22. package/dist/loop-runner-bin.js.map +1 -0
  23. package/dist/loops.d.ts +4 -4
  24. package/dist/mcp/bin.js +3 -2
  25. package/dist/mcp/bin.js.map +1 -1
  26. package/dist/mcp/index.d.ts +5 -3
  27. package/dist/mcp/index.js +11 -7
  28. package/dist/mcp/index.js.map +1 -1
  29. package/dist/{optimize-prompt-cmH9wZdH.d.ts → optimize-prompt-D-urF2wW.d.ts} +1 -1
  30. package/dist/otel-export-xgf4J6bo.d.ts +191 -0
  31. package/dist/profiles.d.ts +1 -1
  32. package/dist/{types-CmkQl8qE.d.ts → types-B9O7l-ij.d.ts} +1 -1
  33. package/package.json +3 -2
  34. package/dist/chunk-V6GURW4W.js.map +0 -1
  35. package/dist/chunk-Z523NPJK.js.map +0 -1
@@ -1,7 +1,6 @@
1
1
  import { CoderOutput, CoderTask } from './profiles.js';
2
- import { L as LoopSandboxClient } from './types-CmkQl8qE.js';
2
+ import { L as LoopSandboxClient } from './types-B9O7l-ij.js';
3
3
  import { SandboxInstance } from '@tangle-network/sandbox';
4
- import { O as OpenAIChatTool } from './types-CsCCryln.js';
5
4
 
6
5
  /**
7
6
  * @experimental
@@ -436,192 +435,4 @@ interface CreateKbGateOptions {
436
435
  */
437
436
  declare function createKbGate(options?: CreateKbGateOptions): (candidate: FactCandidate) => Promise<KbGateResult>;
438
437
 
439
- /**
440
- * @experimental
441
- *
442
- * OpenAI Chat Completions `tools[]` projection of the 5 agent-runtime MCP
443
- * delegation tools.
444
- *
445
- * Use when configuring `createOpenAICompatibleBackend({ tools: ... })` so the
446
- * model can call `delegate_code`, `delegate_research`, `delegate_feedback`,
447
- * `delegation_status`, and `delegation_history` through the OpenAI-compat
448
- * transport (tcloud, OpenRouter, OpenAI direct, cli-bridge). The runtime
449
- * surfaces tool calls as `tool_call` stream events — execution is the
450
- * caller's responsibility (typically the parent sandbox runtime's MCP
451
- * mount).
452
- *
453
- * Sandbox-SDK callers do NOT need this helper: the sandbox runtime mounts
454
- * MCP servers natively and the in-sandbox harness discovers tools via the
455
- * runtime, not via an OpenAI tools array.
456
- *
457
- * Tool name + description + JSON-schema are pulled from the canonical
458
- * `DELEGATE_*` constants exported by `./tools/*` so the projection cannot
459
- * drift from the server's own validators.
460
- */
461
-
462
- /**
463
- * @experimental
464
- *
465
- * Returns the 5 delegation tools projected into OpenAI Chat Completions
466
- * `tools[]` shape. The order is stable: `delegate_code`,
467
- * `delegate_research`, `delegate_feedback`, `delegation_status`,
468
- * `delegation_history`.
469
- */
470
- declare function mcpToolsForRuntimeMcp(): OpenAIChatTool[];
471
- /**
472
- * @experimental
473
- *
474
- * Subset filter — return only the projected tools whose `function.name`
475
- * appears in `names`. Useful for curated mounts (e.g. only the queue-bound
476
- * delegation tools, omitting `delegate_feedback`). Unknown names are
477
- * silently ignored; pass an empty array to get an empty result.
478
- */
479
- declare function mcpToolsForRuntimeMcpSubset(names: ReadonlyArray<string>): OpenAIChatTool[];
480
-
481
- /**
482
- * OTEL span exporter — streams LoopTraceEvents to an OTLP/HTTP collector.
483
- *
484
- * Reads OTEL_EXPORTER_OTLP_ENDPOINT + OTEL_EXPORTER_OTLP_HEADERS from env
485
- * when no explicit config is given. Keeps the runtime dep-free from
486
- * @opentelemetry/sdk-trace-base — minimal OTLP/JSON serializer.
487
- *
488
- * The exporter accepts both raw OtelSpan objects and LoopTraceEvents
489
- * (which get converted to OTLP spans automatically).
490
- */
491
- interface OtelExportConfig {
492
- /** OTLP endpoint. Reads OTEL_EXPORTER_OTLP_ENDPOINT env by default. */
493
- endpoint?: string;
494
- /** OTLP headers. Reads OTEL_EXPORTER_OTLP_HEADERS env by default. */
495
- headers?: Record<string, string>;
496
- /** Batch size before flush. Default 64. */
497
- batchSize?: number;
498
- /** Flush interval ms. Default 5000. */
499
- flushIntervalMs?: number;
500
- /** Resource attributes stamped on every export. */
501
- resourceAttributes?: Record<string, string | number | boolean>;
502
- /** Service name. Default 'agent-runtime'. */
503
- serviceName?: string;
504
- }
505
- interface OtelExporter {
506
- /** Export a span. */
507
- exportSpan(span: OtelSpan): void;
508
- /** Force flush pending spans. */
509
- flush(): Promise<void>;
510
- /** Shutdown cleanly. */
511
- shutdown(): Promise<void>;
512
- }
513
- interface OtelSpan {
514
- traceId: string;
515
- spanId: string;
516
- parentSpanId?: string;
517
- name: string;
518
- kind?: number;
519
- startTimeUnixNano: string;
520
- endTimeUnixNano: string;
521
- attributes?: OtelAttribute[];
522
- status?: {
523
- code: number;
524
- message?: string;
525
- };
526
- }
527
- interface OtelAttribute {
528
- key: string;
529
- value: {
530
- stringValue?: string;
531
- intValue?: string;
532
- doubleValue?: number;
533
- boolValue?: boolean;
534
- };
535
- }
536
- /**
537
- * Create an OTEL exporter. Returns undefined when no endpoint is configured.
538
- */
539
- declare function createOtelExporter(config?: OtelExportConfig): OtelExporter | undefined;
540
- /**
541
- * Convert a LoopTraceEvent into an OtelSpan for export.
542
- */
543
- declare function loopEventToOtelSpan(event: {
544
- kind: string;
545
- runId: string;
546
- timestamp: number;
547
- payload: object;
548
- }, traceId: string, parentSpanId?: string): OtelSpan;
549
- /**
550
- * Build a nested, real-duration OTLP span tree for ONE loop run from its full
551
- * ordered `LoopTraceEvent` stream. Unlike `loopEventToOtelSpan` (one flat,
552
- * zero-duration span per event), this reconstructs the topology hierarchy a
553
- * GenAI trace viewer renders natively:
554
- *
555
- * loop (invoke_workflow)
556
- * └─ loop.round[k] (invoke_workflow) ← tangle.loop.move.{kind,width,rationale}
557
- * ├─ loop.iteration[i] (invoke_agent) ← gen_ai.agent.name + usage + verdict + placement
558
- * └─ …
559
- *
560
- * Attributes follow the current GenAI semconv (`gen_ai.*`) where they apply and
561
- * a namespaced `tangle.loop.*` / `tangle.cost.usd` extension for topology /
562
- * verdict / placement / cost (not yet standardized). Pure: feed it a buffered
563
- * per-runId event array (e.g. flushed on `loop.ended`) and export the result.
564
- */
565
- declare function buildLoopOtelSpans(events: ReadonlyArray<{
566
- kind: string;
567
- runId: string;
568
- timestamp: number;
569
- payload: object;
570
- }>, traceId: string, rootParentSpanId?: string): OtelSpan[];
571
- /** Wire version the eval-runs ingest enforces (X-Tangle-Wire-Version + body). */
572
- declare const INTELLIGENCE_WIRE_VERSION = "2026-05-26.v1";
573
- interface EvalRunGeneration {
574
- /** 0-based ordinal of this generation within the run (required by ingest). */
575
- index: number;
576
- /** Identity of the proposed surface change (content-addressed hash). */
577
- surfaceHash: string;
578
- /** Arbitrary provenance for this generation (rationale, evidence, source). */
579
- surface?: unknown;
580
- /** Per-scenario results; empty until the generation is measured. */
581
- cells?: unknown[];
582
- /** Mean composite score (0 when unmeasured — pair with labels.measured). */
583
- compositeMean: number;
584
- costUsd: number;
585
- durationMs: number;
586
- }
587
- interface EvalRunEvent {
588
- runId: string;
589
- runDir: string;
590
- /** ISO timestamp. */
591
- timestamp: string;
592
- status: 'started' | 'baseline-complete' | 'generation-complete' | 'gate-decided' | 'finished' | 'errored';
593
- labels?: Record<string, string>;
594
- baseline?: EvalRunGeneration;
595
- generations?: EvalRunGeneration[];
596
- gateDecision?: 'ship' | 'hold' | 'need_more_work' | 'model_ceiling' | 'arch_ceiling';
597
- holdoutLift?: number;
598
- totalCostUsd: number;
599
- totalDurationMs: number;
600
- errorMessage?: string;
601
- }
602
- interface EvalRunsExportConfig {
603
- /** Bearer key — tenant is resolved server-side from it. Reads TANGLE_API_KEY. */
604
- apiKey?: string;
605
- /** Intelligence base. Reads INTELLIGENCE_BASE env, else prod. */
606
- base?: string;
607
- /** Idempotency-Key header (e.g. the runId) — safe retries + upsert. */
608
- idempotencyKey?: string;
609
- }
610
- interface EvalRunsExportResult {
611
- ok: boolean;
612
- status: number;
613
- accepted: number;
614
- rejected: Array<{
615
- index: number;
616
- reason: string;
617
- }>;
618
- }
619
- /**
620
- * Ship self-improvement eval-run events to Tangle Intelligence. Unlike the
621
- * best-effort span exporter, this RESOLVES with the ingest verdict (accepted /
622
- * rejected per event) so a consumer's loop can assert its provenance landed.
623
- * Throws only on a missing key or network failure.
624
- */
625
- declare function exportEvalRuns(events: EvalRunEvent[], config?: EvalRunsExportConfig): Promise<EvalRunsExportResult>;
626
-
627
- export { type OtelSpan as $, type FactCandidate as A, type FactJudge as B, type CoderDelegate as C, type DelegationExecutor as D, type FactJudgeVerdict as E, type FleetHandle as F, type FeedbackRating as G, type FeedbackRefersTo as H, type FleetWorkspaceExecutorOptions as I, type ResearchOutputShape as J, type KbGateResult as K, createDefaultCoderDelegate as L, createFleetWorkspaceExecutor as M, createKbGate as N, type OtelExporter as O, createSiblingSandboxExecutor as P, mcpToolsForRuntimeMcp as Q, type ResearcherDelegate as R, type SiblingSandboxExecutorOptions as S, mcpToolsForRuntimeMcpSubset as T, type EvalRunEvent as U, type EvalRunGeneration as V, type EvalRunsExportConfig as W, type EvalRunsExportResult as X, INTELLIGENCE_WIRE_VERSION as Y, type OtelAttribute as Z, type OtelExportConfig as _, type DelegateFeedbackArgs as a, buildLoopOtelSpans as a0, createOtelExporter as a1, exportEvalRuns as a2, loopEventToOtelSpan as a3, type DelegationFeedbackSnapshot as b, type DelegationProfile as c, type DelegateCodeArgs as d, type DelegateResearchArgs as e, type DelegationStatus as f, type DelegationProgress as g, type DelegationResultPayload as h, type DelegationError as i, type DelegationStatusResult as j, type DelegationHistoryArgs as k, type DelegationHistoryEntry as l, type DelegateCodeResult as m, type DelegateFeedbackResult as n, type ResearchSource as o, type DelegateResearchResult as p, type DelegationHistoryResult as q, type DelegationStatusArgs as r, type CoderReview as s, type CoderReviewer as t, type CoderWinnerSelection as u, type CreateDefaultCoderDelegateOptions as v, type CreateKbGateOptions as w, type DelegateCodeConfig as x, type DelegateResearchConfig as y, type DelegateRunCtx as z };
438
+ export { type DelegateRunCtx as A, type FactJudge as B, type CoderReviewer as C, type DelegateCodeArgs as D, type FactJudgeVerdict as E, type FactCandidate as F, type FeedbackRating as G, type FeedbackRefersTo as H, type FleetWorkspaceExecutorOptions as I, type ResearchOutputShape as J, type KbGateResult as K, createDefaultCoderDelegate as L, createFleetWorkspaceExecutor as M, createKbGate as N, createSiblingSandboxExecutor as O, type ResearcherDelegate as R, type SiblingSandboxExecutorOptions as S, type CoderWinnerSelection as a, type CreateKbGateOptions as b, type FleetHandle as c, type DelegationExecutor as d, type DelegateFeedbackArgs as e, type DelegationFeedbackSnapshot as f, type DelegationProfile as g, type DelegateResearchArgs as h, type DelegationStatus as i, type DelegationProgress as j, type DelegationResultPayload as k, type DelegationError as l, type DelegationStatusResult as m, type DelegationHistoryArgs as n, type DelegationHistoryEntry as o, type CoderDelegate as p, type DelegateCodeResult as q, type DelegateFeedbackResult as r, type ResearchSource as s, type DelegateResearchResult as t, type DelegationHistoryResult as u, type DelegationStatusArgs as v, type CoderReview as w, type CreateDefaultCoderDelegateOptions as x, type DelegateCodeConfig as y, type DelegateResearchConfig as z };
@@ -0,0 +1,192 @@
1
+ import { Scenario } from '@tangle-network/agent-eval/campaign';
2
+ import { R as RunAnalystLoopOpts, a as RunAnalystLoopResult } from './types-p8dWBIXL.js';
3
+ import { O as OptimizePromptOptions, a as OptimizePromptResult } from './optimize-prompt-D-urF2wW.js';
4
+ import { T as TopologyPlanner, D as DynamicDecision } from './dynamic-DcrwVGuV.js';
5
+ import { L as LoopSandboxClient, O as OutputAdapter, V as Validator, A as AgentRunSpec, a as LoopResult } from './types-B9O7l-ij.js';
6
+ import { D as DelegateCodeArgs, C as CoderReviewer, a as CoderWinnerSelection, F as FactCandidate, b as CreateKbGateOptions } from './kb-gate-YdPNEagq.js';
7
+ import { CoderOutput } from './profiles.js';
8
+
9
+ /**
10
+ * @experimental
11
+ *
12
+ * `runDelegatedLoop` — the configured delegated loop-runner.
13
+ *
14
+ * One typed entrypoint a worker agent (or a scheduled routine) calls to run a
15
+ * disciplined loop in a chosen MODE, over agent-runtime's hardened engines:
16
+ *
17
+ * code → build-in-a-loop via the coder delegate (no-op + secret floor,
18
+ * optional reviewer gate, winner-selection)
19
+ * review → code mode with a REQUIRED reviewer (the gate is the point)
20
+ * research → research-in-a-loop with valid-only KB growth (createKbGate)
21
+ * audit → analyze trace/run data → findings (runAnalystLoop, caller-wired)
22
+ * self-improve → identity-gated prompt optimization (optimizePrompt, caller-wired)
23
+ * dynamic → agent-authored topology (runLoop + createDynamicDriver)
24
+ *
25
+ * It is intentionally a thin façade: the value is that EVERY product reuses the
26
+ * one hardened engine instead of forking delegation logic. The dispatcher owns
27
+ * mode routing, timing, fail-loud on an unregistered mode, and a uniform result
28
+ * shape; each mode's engine is a pre-configured runner in the registry (build it
29
+ * with the factories below, or inject your own / a stub).
30
+ */
31
+
32
+ /** @experimental Every delegated-loop mode, for validation + CLI surfaces. */
33
+ declare const DELEGATED_LOOP_MODES: readonly ["code", "review", "research", "audit", "self-improve", "dynamic"];
34
+ /** @experimental */
35
+ type DelegatedLoopMode = (typeof DELEGATED_LOOP_MODES)[number];
36
+ /** @experimental Type guard for an untrusted mode string (CLI / config input). */
37
+ declare function isDelegatedLoopMode(value: unknown): value is DelegatedLoopMode;
38
+ /** @experimental A pre-configured loop for one mode. Returns the mode's raw
39
+ * output; the dispatcher wraps it in a {@link DelegatedLoopResult}. */
40
+ type DelegatedLoopRunner<T = unknown> = (signal: AbortSignal) => Promise<T>;
41
+ /** @experimental Mode → configured runner. Partial: only register the modes a
42
+ * given product/routine actually uses. */
43
+ type DelegatedLoopRegistry = Partial<Record<DelegatedLoopMode, DelegatedLoopRunner>>;
44
+ /** @experimental Uniform result — never throws from a registered runner; a
45
+ * thrown engine becomes `{ ok: false, error }` so a routine can record + move on. */
46
+ interface DelegatedLoopResult<T = unknown> {
47
+ mode: DelegatedLoopMode;
48
+ ok: boolean;
49
+ output?: T;
50
+ error?: string;
51
+ durationMs: number;
52
+ }
53
+ /** @experimental */
54
+ interface RunDelegatedLoopOptions {
55
+ signal?: AbortSignal;
56
+ /** Clock override for deterministic tests. */
57
+ now?: () => number;
58
+ }
59
+ /**
60
+ * @experimental
61
+ *
62
+ * Dispatch a configured loop by mode. Fails loud (throws `ConfigError`) when no
63
+ * runner is registered for the mode — a routine pointed at an unwired mode is a
64
+ * config bug, not a silent no-op. A runner that throws is captured as
65
+ * `{ ok: false }` so unattended runs record the failure rather than crash.
66
+ */
67
+ declare function runDelegatedLoop<T = unknown>(mode: DelegatedLoopMode, registry: DelegatedLoopRegistry, options?: RunDelegatedLoopOptions): Promise<DelegatedLoopResult<T>>;
68
+ /** @experimental Options for the default `code`/`review` runner. */
69
+ interface CoderLoopRunnerOptions {
70
+ sandboxClient: LoopSandboxClient;
71
+ /** What to build — the delegate args (goal, repoRoot, variants, config, …). */
72
+ args: DelegateCodeArgs;
73
+ /** Adversarial reviewer. REQUIRED for `review` mode (see `reviewLoopRunner`). */
74
+ reviewer?: CoderReviewer;
75
+ /** Winner-selection strategy. Default `highest-score`. */
76
+ winnerSelection?: CoderWinnerSelection;
77
+ /** Harnesses for `variants > 1` fanout. */
78
+ fanoutHarnesses?: string[];
79
+ }
80
+ /** @experimental Build a `code`-mode runner over the hardened coder delegate. */
81
+ declare function coderLoopRunner(options: CoderLoopRunnerOptions): DelegatedLoopRunner<CoderOutput>;
82
+ /**
83
+ * @experimental
84
+ *
85
+ * `review` mode = `code` with a REQUIRED reviewer. The gate is the whole point,
86
+ * so the type forces a reviewer (a "review loop" with no reviewer is a code loop).
87
+ */
88
+ declare function reviewLoopRunner(options: CoderLoopRunnerOptions & {
89
+ reviewer: CoderReviewer;
90
+ }): DelegatedLoopRunner<CoderOutput>;
91
+ /** @experimental Options for the default `dynamic` runner. */
92
+ interface DynamicLoopRunnerOptions<Task, Output> {
93
+ sandboxClient: LoopSandboxClient;
94
+ /** The agent-authored topology planner (e.g. `createSandboxPlanner(...)`). */
95
+ planner: TopologyPlanner<Task, Output>;
96
+ task: Task;
97
+ output: OutputAdapter<Output>;
98
+ validator?: Validator<Output>;
99
+ /** Exactly one of `agentRun` / `agentRuns` (runLoop validates). */
100
+ agentRun?: AgentRunSpec<Task>;
101
+ agentRuns?: AgentRunSpec<Task>[];
102
+ maxIterations?: number;
103
+ maxFanout?: number;
104
+ }
105
+ /** @experimental `dynamic` mode — agent-authored topology over `runLoop`. */
106
+ declare function dynamicLoopRunner<Task, Output>(o: DynamicLoopRunnerOptions<Task, Output>): DelegatedLoopRunner<LoopResult<Task, Output, DynamicDecision>>;
107
+ /** @experimental A fact rejected at the KB gate — surfaced, never dropped. */
108
+ interface VetoedFact {
109
+ candidate: FactCandidate;
110
+ vetoedBy?: string;
111
+ reason?: string;
112
+ }
113
+ /** @experimental */
114
+ interface ResearchLoopResult {
115
+ /** Facts that passed the fail-closed gate — safe to write to the KB. */
116
+ accepted: FactCandidate[];
117
+ /** Facts the gate vetoed in the final round — escalate, do not silently drop. */
118
+ vetoed: VetoedFact[];
119
+ /** Research rounds actually run. */
120
+ rounds: number;
121
+ }
122
+ /** @experimental Options for the default `research` runner. */
123
+ interface ResearchLoopRunnerOptions {
124
+ /**
125
+ * The research engine (the consumer's web/doc searcher + extractor). Called
126
+ * each round with the prior round's vetoes so it can re-research the gaps.
127
+ * Returns fact candidates carrying their grounding (`verbatimPassage` +
128
+ * `sourceText`).
129
+ */
130
+ research: (round: number, vetoed: VetoedFact[]) => Promise<FactCandidate[]>;
131
+ /** Gate config (extra judges, self-artifact kinds, …). The floor is always on. */
132
+ gate?: CreateKbGateOptions;
133
+ /** Max research rounds (correct-on-veto remediation). Default 1. */
134
+ maxRounds?: number;
135
+ }
136
+ /**
137
+ * @experimental `research` mode — research-in-a-loop with valid-only KB growth.
138
+ *
139
+ * Each round: research → gate every candidate (fail-closed; passage MUST be in
140
+ * the source) → accept the clean ones → re-research the vetoed ones next round,
141
+ * up to `maxRounds`. Vetoed facts in the final round are RETURNED (escalate,
142
+ * never silently dropped) so the caller audits vs retries.
143
+ */
144
+ declare function researchLoopRunner(o: ResearchLoopRunnerOptions): DelegatedLoopRunner<ResearchLoopResult>;
145
+ /** @experimental `self-improve` mode — identity-gated prompt optimization. */
146
+ declare function selfImproveLoopRunner<TScenario extends Scenario, TArtifact>(options: OptimizePromptOptions<TScenario, TArtifact>): DelegatedLoopRunner<OptimizePromptResult<TArtifact, TScenario>>;
147
+ /** @experimental `audit` mode — analyst loop over captured trace/run data. */
148
+ declare function auditLoopRunner<TProposal = unknown, TEdit = unknown>(options: RunAnalystLoopOpts): DelegatedLoopRunner<RunAnalystLoopResult<TProposal, TEdit>>;
149
+
150
+ /**
151
+ * @experimental
152
+ *
153
+ * `agent-runtime-loop` — the schedulable entrypoint for the configured
154
+ * delegated loop-runner. A cron job / routine / Makefile target invokes:
155
+ *
156
+ * agent-runtime-loop --mode research --config ./loops.config.js
157
+ *
158
+ * The config module wires the registry (with full access to env / creds —
159
+ * which is why the deps live there, not in this generic bin). It must default-
160
+ * export a `DelegatedLoopRegistry`, or a `() => DelegatedLoopRegistry | Promise<…>`.
161
+ * The bin runs the selected mode, prints the `DelegatedLoopResult` as JSON, and
162
+ * exits 0 on `ok`, 1 on a recorded failure, 2 on a usage/config error.
163
+ */
164
+
165
+ /** @experimental Parsed CLI invocation. */
166
+ interface LoopRunnerCliArgs {
167
+ mode: string;
168
+ /** Loads the registry — the bin wires this from `--config`; tests inject a stub. */
169
+ loadRegistry: () => Promise<DelegatedLoopRegistry> | DelegatedLoopRegistry;
170
+ now?: () => number;
171
+ }
172
+ /** @experimental */
173
+ interface LoopRunnerCliResult {
174
+ exitCode: number;
175
+ result?: DelegatedLoopResult;
176
+ error?: string;
177
+ }
178
+ /**
179
+ * @experimental
180
+ *
181
+ * Pure CLI core (no process / argv / IO) so it's unit-testable: validate the
182
+ * mode, load the registry, dispatch, map to an exit code (0 ok / 1 failed /
183
+ * 2 usage). Exported for embedding in custom runners + tests.
184
+ */
185
+ declare function runLoopRunnerCli(args: LoopRunnerCliArgs): Promise<LoopRunnerCliResult>;
186
+ /** Parse `--mode X --config Y` from an argv tail (`process.argv.slice(2)`). */
187
+ declare function parseLoopRunnerArgv(argv: string[]): {
188
+ mode?: string;
189
+ config?: string;
190
+ };
191
+
192
+ export { type CoderLoopRunnerOptions as C, DELEGATED_LOOP_MODES as D, type LoopRunnerCliArgs as L, type ResearchLoopResult as R, type VetoedFact as V, type DelegatedLoopMode as a, type DelegatedLoopRegistry as b, type DelegatedLoopResult as c, type DelegatedLoopRunner as d, type DynamicLoopRunnerOptions as e, type LoopRunnerCliResult as f, type ResearchLoopRunnerOptions as g, type RunDelegatedLoopOptions as h, auditLoopRunner as i, coderLoopRunner as j, dynamicLoopRunner as k, isDelegatedLoopMode as l, reviewLoopRunner as m, runDelegatedLoop as n, runLoopRunnerCli as o, parseLoopRunnerArgv as p, researchLoopRunner as r, selfImproveLoopRunner as s };
@@ -0,0 +1,12 @@
1
+ #!/usr/bin/env node
2
+ export { L as LoopRunnerCliArgs, f as LoopRunnerCliResult, p as parseLoopRunnerArgv, o as runLoopRunnerCli } from './loop-runner-bin-DgZj0zfJ.js';
3
+ import '@tangle-network/agent-eval/campaign';
4
+ import './types-p8dWBIXL.js';
5
+ import '@tangle-network/agent-eval';
6
+ import './optimize-prompt-D-urF2wW.js';
7
+ import './dynamic-DcrwVGuV.js';
8
+ import './types-B9O7l-ij.js';
9
+ import '@tangle-network/sandbox';
10
+ import './types-CsCCryln.js';
11
+ import './kb-gate-YdPNEagq.js';
12
+ import './profiles.js';
@@ -0,0 +1,19 @@
1
+ #!/usr/bin/env node
2
+ import {
3
+ parseLoopRunnerArgv,
4
+ runLoopRunnerCli
5
+ } from "./chunk-AXWGLYSF.js";
6
+ import "./chunk-XBUG326M.js";
7
+ import "./chunk-VOX6Z3II.js";
8
+ import "./chunk-FNMGYYSS.js";
9
+ import "./chunk-VLXRXMTF.js";
10
+ import "./chunk-7JBDJQLO.js";
11
+ import "./chunk-3HMHSN22.js";
12
+ import "./chunk-PY6NMZYX.js";
13
+ import "./chunk-SQSCRJ7U.js";
14
+ import "./chunk-DGUM43GV.js";
15
+ export {
16
+ parseLoopRunnerArgv,
17
+ runLoopRunnerCli
18
+ };
19
+ //# sourceMappingURL=loop-runner-bin.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":[],"sourcesContent":[],"mappings":"","names":[]}
package/dist/loops.d.ts CHANGED
@@ -1,9 +1,9 @@
1
1
  import { AgentProfile, SandboxEvent } from '@tangle-network/sandbox';
2
2
  export { AgentProfile, CreateSandboxOptions, SandboxEvent, SandboxInstance } from '@tangle-network/sandbox';
3
- import { P as PlannerContext, T as TopologyPlanner } from './dynamic-DeOPeeAw.js';
4
- export { C as CreateDynamicDriverOptions, D as DynamicDecision, a as TopologyMove, c as createDynamicDriver, s as summarizeHistory } from './dynamic-DeOPeeAw.js';
5
- import { D as Driver, I as Iteration, L as LoopSandboxClient, A as AgentRunSpec, O as OutputAdapter, V as Validator, E as ExecCtx, a as LoopWinner, b as LoopResult } from './types-CmkQl8qE.js';
6
- 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-CmkQl8qE.js';
3
+ import { P as PlannerContext, T as TopologyPlanner } from './dynamic-DcrwVGuV.js';
4
+ export { C as CreateDynamicDriverOptions, D as DynamicDecision, a as TopologyMove, c as createDynamicDriver, s as summarizeHistory } from './dynamic-DcrwVGuV.js';
5
+ import { D as Driver, I as Iteration, L as LoopSandboxClient, A as AgentRunSpec, O as OutputAdapter, V as Validator, E as ExecCtx, b as LoopWinner, a as LoopResult } from './types-B9O7l-ij.js';
6
+ 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-B9O7l-ij.js';
7
7
  import { DefaultVerdict, AgentProfile as AgentProfile$1 } from '@tangle-network/agent-eval';
8
8
  export { DefaultVerdict } from '@tangle-network/agent-eval';
9
9
  import { Scenario, DispatchFn, ProfileDispatchFn } from '@tangle-network/agent-eval/campaign';
package/dist/mcp/bin.js CHANGED
@@ -2,10 +2,11 @@
2
2
  import {
3
3
  createMcpServer,
4
4
  detectExecutor
5
- } from "../chunk-M65QJD35.js";
5
+ } from "../chunk-PK5DYSNO.js";
6
+ import "../chunk-HSX6PFZR.js";
6
7
  import {
7
8
  createDefaultCoderDelegate
8
- } from "../chunk-V6GURW4W.js";
9
+ } from "../chunk-VLXRXMTF.js";
9
10
  import "../chunk-GLR25NG7.js";
10
11
  import {
11
12
  runLoop
@@ -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":";;;;;;;;;;;;;;;;;;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"]}
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,8 +1,10 @@
1
- import { L as LoopSandboxClient, j as LoopSandboxPlacement, m as LoopTraceEmitter } from '../types-CmkQl8qE.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-CNmeg_7B.js';
3
- export { s as CoderReview, t as CoderReviewer, u as CoderWinnerSelection, v as CreateDefaultCoderDelegateOptions, w as CreateKbGateOptions, x as DelegateCodeConfig, y as DelegateResearchConfig, z as DelegateRunCtx, A as FactCandidate, B as FactJudge, E as FactJudgeVerdict, G as FeedbackRating, H as FeedbackRefersTo, I as FleetWorkspaceExecutorOptions, K as KbGateResult, J as ResearchOutputShape, S as SiblingSandboxExecutorOptions, L as createDefaultCoderDelegate, M as createFleetWorkspaceExecutor, N as createKbGate, P as createSiblingSandboxExecutor, Q as mcpToolsForRuntimeMcp, T as mcpToolsForRuntimeMcpSubset } from '../otel-export-CNmeg_7B.js';
1
+ import { L as LoopSandboxClient, j as LoopSandboxPlacement, m as LoopTraceEmitter } from '../types-B9O7l-ij.js';
2
+ import { c as FleetHandle, d as DelegationExecutor, e as DelegateFeedbackArgs, f as DelegationFeedbackSnapshot, g as DelegationProfile, D as DelegateCodeArgs, h as DelegateResearchArgs, i as DelegationStatus, j as DelegationProgress, k as DelegationResultPayload, l as DelegationError, m as DelegationStatusResult, n as DelegationHistoryArgs, o as DelegationHistoryEntry, p as CoderDelegate, R as ResearcherDelegate, q as DelegateCodeResult, r as DelegateFeedbackResult, s as ResearchSource, t as DelegateResearchResult, u as DelegationHistoryResult, v as DelegationStatusArgs } from '../kb-gate-YdPNEagq.js';
3
+ export { w as CoderReview, C as CoderReviewer, a as CoderWinnerSelection, x as CreateDefaultCoderDelegateOptions, b as CreateKbGateOptions, y as DelegateCodeConfig, z as DelegateResearchConfig, A as DelegateRunCtx, F as FactCandidate, B as FactJudge, E as FactJudgeVerdict, G as FeedbackRating, H as FeedbackRefersTo, I as FleetWorkspaceExecutorOptions, K as KbGateResult, J as ResearchOutputShape, S as SiblingSandboxExecutorOptions, L as createDefaultCoderDelegate, M as createFleetWorkspaceExecutor, N as createKbGate, O as createSiblingSandboxExecutor } from '../kb-gate-YdPNEagq.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';
6
8
  import '@tangle-network/agent-eval';
7
9
  import '@tangle-network/sandbox';
8
10
  import '../types-CsCCryln.js';
package/dist/mcp/index.js CHANGED
@@ -6,14 +6,13 @@ import {
6
6
  createWorktree,
7
7
  detectExecutor,
8
8
  removeWorktree
9
- } from "../chunk-M65QJD35.js";
9
+ } from "../chunk-PK5DYSNO.js";
10
10
  import {
11
11
  buildLoopOtelSpans,
12
- createKbGate,
13
12
  createOtelExporter,
14
13
  mcpToolsForRuntimeMcp,
15
14
  mcpToolsForRuntimeMcpSubset
16
- } from "../chunk-Z523NPJK.js";
15
+ } from "../chunk-7ZECSZ3C.js";
17
16
  import {
18
17
  DELEGATE_CODE_DESCRIPTION,
19
18
  DELEGATE_CODE_INPUT_SCHEMA,
@@ -32,14 +31,11 @@ import {
32
31
  DELEGATION_STATUS_TOOL_NAME,
33
32
  DelegationTaskQueue,
34
33
  InMemoryFeedbackStore,
35
- createDefaultCoderDelegate,
36
34
  createDelegateCodeHandler,
37
35
  createDelegateFeedbackHandler,
38
36
  createDelegateResearchHandler,
39
37
  createDelegationHistoryHandler,
40
38
  createDelegationStatusHandler,
41
- createFleetWorkspaceExecutor,
42
- createSiblingSandboxExecutor,
43
39
  eventToSnapshot,
44
40
  hashIdempotencyInput,
45
41
  validateDelegateCodeArgs,
@@ -47,7 +43,15 @@ import {
47
43
  validateDelegateResearchArgs,
48
44
  validateDelegationHistoryArgs,
49
45
  validateDelegationStatusArgs
50
- } from "../chunk-V6GURW4W.js";
46
+ } from "../chunk-HSX6PFZR.js";
47
+ import {
48
+ createKbGate
49
+ } from "../chunk-FNMGYYSS.js";
50
+ import {
51
+ createDefaultCoderDelegate,
52
+ createFleetWorkspaceExecutor,
53
+ createSiblingSandboxExecutor
54
+ } from "../chunk-VLXRXMTF.js";
51
55
  import {
52
56
  runLocalHarness
53
57
  } from "../chunk-GLR25NG7.js";
@@ -1 +1 @@
1
- {"version":3,"sources":["../../src/mcp/trace-propagation.ts"],"sourcesContent":["/**\n * @experimental\n *\n * Trace context propagation for MCP subprocess.\n *\n * When the MCP server is launched as a child process by a sandbox harness,\n * the parent passes trace context via environment variables:\n *\n * TRACE_ID=<current-run-trace-id>\n * PARENT_SPAN_ID=<span-that-dispatched-the-delegation>\n *\n * The MCP server reads these at startup and uses them as the root of its\n * internal trace tree. All spans emitted by `runLoop` invocations inside\n * the MCP are children of the parent's delegation span.\n *\n * When these env vars are absent, the MCP generates a fresh trace root —\n * the server operates standalone without trace joining.\n */\n\nimport type { LoopTraceEmitter, LoopTraceEvent } from '../loops/types'\nimport type { OtelExporter } from '../otel-export'\nimport { buildLoopOtelSpans, createOtelExporter } from '../otel-export'\n\nexport interface TraceContext {\n /** Trace id inherited from the parent process, or a fresh one. */\n traceId: string\n /** Parent span id from the delegation that launched this MCP server. */\n parentSpanId?: string\n}\n\n/**\n * Read trace context from the process environment.\n * Returns a context with inherited ids or a freshly generated root.\n */\nexport function readTraceContextFromEnv(): TraceContext {\n const traceId = process.env.TRACE_ID || generateTraceId()\n const parentSpanId = process.env.PARENT_SPAN_ID || undefined\n return { traceId, parentSpanId }\n}\n\n/**\n * Create a LoopTraceEmitter that:\n * 1. Parents all spans under the inherited PARENT_SPAN_ID.\n * 2. Exports spans to OTEL when OTEL_EXPORTER_OTLP_ENDPOINT is set.\n *\n * Returns both the emitter and the optional exporter handle for shutdown.\n */\nexport function createPropagatingTraceEmitter(ctx: TraceContext): {\n emitter: LoopTraceEmitter\n exporter: OtelExporter | undefined\n context: TraceContext\n} {\n const exporter = createOtelExporter()\n\n // Buffer events per loop run, then emit the full nested span tree on\n // `loop.ended` so the topology hierarchy (loop → round → branch) reaches the\n // OTLP collector — not a flat list of zero-duration point spans. A run that\n // never reaches `loop.ended` (hard abort) drops its buffer; acceptable for\n // the short-lived MCP subprocess.\n const buffers = new Map<string, LoopTraceEvent[]>()\n\n const emitter: LoopTraceEmitter = {\n emit(event: LoopTraceEvent) {\n if (!exporter) return\n const buf = buffers.get(event.runId)\n if (buf) buf.push(event)\n else buffers.set(event.runId, [event])\n if (event.kind === 'loop.ended') {\n const events = buffers.get(event.runId) ?? [event]\n buffers.delete(event.runId)\n for (const span of buildLoopOtelSpans(events, ctx.traceId, ctx.parentSpanId)) {\n exporter.exportSpan(span)\n }\n }\n },\n }\n\n return { emitter, exporter, context: ctx }\n}\n\n/**\n * Build env vars to pass to a child MCP subprocess so it inherits the\n * current trace context.\n */\nexport function traceContextToEnv(ctx: TraceContext): Record<string, string> {\n const env: Record<string, string> = { TRACE_ID: ctx.traceId }\n if (ctx.parentSpanId) env.PARENT_SPAN_ID = ctx.parentSpanId\n return env\n}\n\nfunction generateTraceId(): string {\n const bytes = new Uint8Array(16)\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 16; 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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCO,SAAS,0BAAwC;AACtD,QAAM,UAAU,QAAQ,IAAI,YAAY,gBAAgB;AACxD,QAAM,eAAe,QAAQ,IAAI,kBAAkB;AACnD,SAAO,EAAE,SAAS,aAAa;AACjC;AASO,SAAS,8BAA8B,KAI5C;AACA,QAAM,WAAW,mBAAmB;AAOpC,QAAM,UAAU,oBAAI,IAA8B;AAElD,QAAM,UAA4B;AAAA,IAChC,KAAK,OAAuB;AAC1B,UAAI,CAAC,SAAU;AACf,YAAM,MAAM,QAAQ,IAAI,MAAM,KAAK;AACnC,UAAI,IAAK,KAAI,KAAK,KAAK;AAAA,UAClB,SAAQ,IAAI,MAAM,OAAO,CAAC,KAAK,CAAC;AACrC,UAAI,MAAM,SAAS,cAAc;AAC/B,cAAM,SAAS,QAAQ,IAAI,MAAM,KAAK,KAAK,CAAC,KAAK;AACjD,gBAAQ,OAAO,MAAM,KAAK;AAC1B,mBAAW,QAAQ,mBAAmB,QAAQ,IAAI,SAAS,IAAI,YAAY,GAAG;AAC5E,mBAAS,WAAW,IAAI;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,UAAU,SAAS,IAAI;AAC3C;AAMO,SAAS,kBAAkB,KAA2C;AAC3E,QAAM,MAA8B,EAAE,UAAU,IAAI,QAAQ;AAC5D,MAAI,IAAI,aAAc,KAAI,iBAAiB,IAAI;AAC/C,SAAO;AACT;AAEA,SAAS,kBAA0B;AACjC,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,MAAI,OAAO,WAAW,QAAQ,oBAAoB,YAAY;AAC5D,eAAW,OAAO,gBAAgB,KAAK;AAAA,EACzC,OAAO;AACL,aAAS,IAAI,GAAG,IAAI,IAAI,IAAK,OAAM,CAAC,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG;AAAA,EACxE;AACA,SAAO,MAAM,KAAK,KAAK,EACpB,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACZ;","names":[]}
1
+ {"version":3,"sources":["../../src/mcp/trace-propagation.ts"],"sourcesContent":["/**\n * @experimental\n *\n * Trace context propagation for MCP subprocess.\n *\n * When the MCP server is launched as a child process by a sandbox harness,\n * the parent passes trace context via environment variables:\n *\n * TRACE_ID=<current-run-trace-id>\n * PARENT_SPAN_ID=<span-that-dispatched-the-delegation>\n *\n * The MCP server reads these at startup and uses them as the root of its\n * internal trace tree. All spans emitted by `runLoop` invocations inside\n * the MCP are children of the parent's delegation span.\n *\n * When these env vars are absent, the MCP generates a fresh trace root —\n * the server operates standalone without trace joining.\n */\n\nimport type { LoopTraceEmitter, LoopTraceEvent } from '../loops/types'\nimport type { OtelExporter } from '../otel-export'\nimport { buildLoopOtelSpans, createOtelExporter } from '../otel-export'\n\nexport interface TraceContext {\n /** Trace id inherited from the parent process, or a fresh one. */\n traceId: string\n /** Parent span id from the delegation that launched this MCP server. */\n parentSpanId?: string\n}\n\n/**\n * Read trace context from the process environment.\n * Returns a context with inherited ids or a freshly generated root.\n */\nexport function readTraceContextFromEnv(): TraceContext {\n const traceId = process.env.TRACE_ID || generateTraceId()\n const parentSpanId = process.env.PARENT_SPAN_ID || undefined\n return { traceId, parentSpanId }\n}\n\n/**\n * Create a LoopTraceEmitter that:\n * 1. Parents all spans under the inherited PARENT_SPAN_ID.\n * 2. Exports spans to OTEL when OTEL_EXPORTER_OTLP_ENDPOINT is set.\n *\n * Returns both the emitter and the optional exporter handle for shutdown.\n */\nexport function createPropagatingTraceEmitter(ctx: TraceContext): {\n emitter: LoopTraceEmitter\n exporter: OtelExporter | undefined\n context: TraceContext\n} {\n const exporter = createOtelExporter()\n\n // Buffer events per loop run, then emit the full nested span tree on\n // `loop.ended` so the topology hierarchy (loop → round → branch) reaches the\n // OTLP collector — not a flat list of zero-duration point spans. A run that\n // never reaches `loop.ended` (hard abort) drops its buffer; acceptable for\n // the short-lived MCP subprocess.\n const buffers = new Map<string, LoopTraceEvent[]>()\n\n const emitter: LoopTraceEmitter = {\n emit(event: LoopTraceEvent) {\n if (!exporter) return\n const buf = buffers.get(event.runId)\n if (buf) buf.push(event)\n else buffers.set(event.runId, [event])\n if (event.kind === 'loop.ended') {\n const events = buffers.get(event.runId) ?? [event]\n buffers.delete(event.runId)\n for (const span of buildLoopOtelSpans(events, ctx.traceId, ctx.parentSpanId)) {\n exporter.exportSpan(span)\n }\n }\n },\n }\n\n return { emitter, exporter, context: ctx }\n}\n\n/**\n * Build env vars to pass to a child MCP subprocess so it inherits the\n * current trace context.\n */\nexport function traceContextToEnv(ctx: TraceContext): Record<string, string> {\n const env: Record<string, string> = { TRACE_ID: ctx.traceId }\n if (ctx.parentSpanId) env.PARENT_SPAN_ID = ctx.parentSpanId\n return env\n}\n\nfunction generateTraceId(): string {\n const bytes = new Uint8Array(16)\n if (typeof globalThis.crypto?.getRandomValues === 'function') {\n globalThis.crypto.getRandomValues(bytes)\n } else {\n for (let i = 0; i < 16; 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"],"mappings":";;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCO,SAAS,0BAAwC;AACtD,QAAM,UAAU,QAAQ,IAAI,YAAY,gBAAgB;AACxD,QAAM,eAAe,QAAQ,IAAI,kBAAkB;AACnD,SAAO,EAAE,SAAS,aAAa;AACjC;AASO,SAAS,8BAA8B,KAI5C;AACA,QAAM,WAAW,mBAAmB;AAOpC,QAAM,UAAU,oBAAI,IAA8B;AAElD,QAAM,UAA4B;AAAA,IAChC,KAAK,OAAuB;AAC1B,UAAI,CAAC,SAAU;AACf,YAAM,MAAM,QAAQ,IAAI,MAAM,KAAK;AACnC,UAAI,IAAK,KAAI,KAAK,KAAK;AAAA,UAClB,SAAQ,IAAI,MAAM,OAAO,CAAC,KAAK,CAAC;AACrC,UAAI,MAAM,SAAS,cAAc;AAC/B,cAAM,SAAS,QAAQ,IAAI,MAAM,KAAK,KAAK,CAAC,KAAK;AACjD,gBAAQ,OAAO,MAAM,KAAK;AAC1B,mBAAW,QAAQ,mBAAmB,QAAQ,IAAI,SAAS,IAAI,YAAY,GAAG;AAC5E,mBAAS,WAAW,IAAI;AAAA,QAC1B;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,SAAO,EAAE,SAAS,UAAU,SAAS,IAAI;AAC3C;AAMO,SAAS,kBAAkB,KAA2C;AAC3E,QAAM,MAA8B,EAAE,UAAU,IAAI,QAAQ;AAC5D,MAAI,IAAI,aAAc,KAAI,iBAAiB,IAAI;AAC/C,SAAO;AACT;AAEA,SAAS,kBAA0B;AACjC,QAAM,QAAQ,IAAI,WAAW,EAAE;AAC/B,MAAI,OAAO,WAAW,QAAQ,oBAAoB,YAAY;AAC5D,eAAW,OAAO,gBAAgB,KAAK;AAAA,EACzC,OAAO;AACL,aAAS,IAAI,GAAG,IAAI,IAAI,IAAK,OAAM,CAAC,IAAI,KAAK,MAAM,KAAK,OAAO,IAAI,GAAG;AAAA,EACxE;AACA,SAAO,MAAM,KAAK,KAAK,EACpB,IAAI,CAAC,MAAM,EAAE,SAAS,EAAE,EAAE,SAAS,GAAG,GAAG,CAAC,EAC1C,KAAK,EAAE;AACZ;","names":[]}
@@ -126,4 +126,4 @@ interface OptimizePromptResult<TArtifact, TScenario extends Scenario> {
126
126
  /** @experimental */
127
127
  declare function optimizePrompt<TScenario extends Scenario, TArtifact>(opts: OptimizePromptOptions<TScenario, TArtifact>): Promise<OptimizePromptResult<TArtifact, TScenario>>;
128
128
 
129
- export { type OptimizePromptOptions as O, type OptimizePromptReflection as a, type OptimizePromptResult as b, optimizePrompt as o };
129
+ export { type OptimizePromptOptions as O, type OptimizePromptResult as a, type OptimizePromptReflection as b, optimizePrompt as o };