@tangle-network/agent-runtime 0.126.0 → 0.128.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +2 -2
- package/dist/agent.d.ts +1 -1
- package/dist/agent.js +2 -2
- package/dist/{environment-provider-PM9PeW_J.d.ts → environment-provider-CUFsyymu.d.ts} +7 -1
- package/dist/environment-provider.d.ts +1 -1
- package/dist/{index-EdjCQBV9.d.ts → index-BhZhQw77.d.ts} +198 -20
- package/dist/{index-DIV33AF5.d.ts → index-BhuzfG2r.d.ts} +3 -3
- package/dist/{index-D_M4d1_B.d.ts → index-DLM0W1h1.d.ts} +5 -5
- package/dist/index.d.ts +5 -5
- package/dist/index.js +5 -5
- package/dist/index.js.map +1 -1
- package/dist/intelligence.d.ts +1 -1
- package/dist/kernel.d.ts +3 -3
- package/dist/kernel.js +3 -3
- package/dist/{knowledge-EnuEqm_Y.js → knowledge-DF63xPr4.js} +2 -2
- package/dist/{knowledge-EnuEqm_Y.js.map → knowledge-DF63xPr4.js.map} +1 -1
- package/dist/knowledge.d.ts +1 -1
- package/dist/knowledge.js +1 -1
- package/dist/{loop-runner-bin-qwT_4F5I.js → loop-runner-bin-CWqOpCEw.js} +3 -3
- package/dist/{loop-runner-bin-qwT_4F5I.js.map → loop-runner-bin-CWqOpCEw.js.map} +1 -1
- package/dist/{loop-runner-bin-Bo29_fiD.d.ts → loop-runner-bin-Ckp_9tmD.d.ts} +3 -3
- package/dist/loop-runner-bin.d.ts +1 -1
- package/dist/loop-runner-bin.js +1 -1
- package/dist/mcp/bin.js +1 -1
- package/dist/mcp/index.d.ts +3 -7
- package/dist/mcp/index.js +3 -3
- package/dist/{openai-tools-Bp1KSkP6.js → openai-tools-D3XfrrQ6.js} +2 -2
- package/dist/{openai-tools-Bp1KSkP6.js.map → openai-tools-D3XfrrQ6.js.map} +1 -1
- package/dist/primeintellect/index.d.ts +1 -1
- package/dist/{runtime-BzXz7OjS.js → runtime-5uDVVfER.js} +362 -11
- package/dist/runtime-5uDVVfER.js.map +1 -0
- package/dist/{supervise-Ds8FtyI9.js → supervise-CsTKbH9R.js} +100 -18
- package/dist/supervise-CsTKbH9R.js.map +1 -0
- package/dist/testing.js +8 -8
- package/package.json +1 -1
- package/skills/agent-graphs/IMPROVE.md +58 -0
- package/skills/agent-graphs/SKILL.md +140 -0
- package/skills/agent-graphs/cases/artifact-mission-release-notes.json +10 -0
- package/skills/agent-graphs/cases/audited-single-writer.json +9 -0
- package/skills/agent-graphs/cases/cap-as-stop-mistake.json +8 -0
- package/skills/agent-graphs/cases/floor-trap-pi.json +11 -0
- package/skills/agent-graphs/cases/mission-in-deliverable.json +8 -0
- package/skills/agent-graphs/cases/review-pipeline.json +14 -0
- package/skills/agent-graphs/cases/runtime-discovered-fanout.json +8 -0
- package/skills/agent-graphs/cases/single-agent-suffices.json +7 -0
- package/skills/agent-graphs/cases/steer-heavy-drafting.json +9 -0
- package/skills/agent-graphs/cases/unmeasured-harness.json +9 -0
- package/skills/agent-graphs/generations/gen1-baseline.json +248 -0
- package/skills/agent-graphs/generations/gen2.json +375 -0
- package/skills/agent-graphs/generations/gen3.json +702 -0
- package/skills/build-with-agent-runtime/SKILL.md +1 -0
- package/dist/runtime-BzXz7OjS.js.map +0 -1
- package/dist/supervise-Ds8FtyI9.js.map +0 -1
|
@@ -1,16 +1,17 @@
|
|
|
1
1
|
import { n as AnalystError, r as BackendTransportError, s as PlannerError, u as ValidationError } from "./errors-DEAvWQPy.js";
|
|
2
2
|
import { i as normalizeBackendStreamEvent, o as newRuntimeSession, s as nowIso } from "./backends-CiOCyRHb.js";
|
|
3
|
-
import { i as InMemorySpawnJournal, r as InMemoryResultBlobStore, v as isTraceAnalysisStore } from "./spawn-journal-DsZKDqeh.js";
|
|
3
|
+
import { i as InMemorySpawnJournal, r as InMemoryResultBlobStore, v as isTraceAnalysisStore, x as contentAddress } from "./spawn-journal-DsZKDqeh.js";
|
|
4
4
|
import { a as randomSuffix, c as stringifySafe, f as zeroTokenUsage, r as isAbortError, s as sleep, t as addTokenUsage } from "./util-MVgdwuIS.js";
|
|
5
5
|
import { i as redactProtectedValue, r as redactProtectedReason } from "./protected-redaction--F3v1oo8.js";
|
|
6
|
-
import { _t as routerChatWithUsage, bt as runBrainLoop, en as isHarnessNativeModel, et as rollingDispatch, ht as routerBrain, l as withDriverExecutor, m as settledToIteration, n as createSupervisor } from "./supervisor-DpjO0Gmy.js";
|
|
6
|
+
import { $t as concreteProfileModel, Qt as concreteModelId, _t as routerChatWithUsage, bt as runBrainLoop, ct as attestRuntimeOwnedExecutor, dt as newExecutionAttemptId, en as isHarnessNativeModel, et as rollingDispatch, ht as routerBrain, l as withDriverExecutor, m as settledToIteration, n as createSupervisor } from "./supervisor-DpjO0Gmy.js";
|
|
7
7
|
import { C as observe, O as strategyAuthorMethod, b as sample, v as refine, x as sampleThenRefine, y as runAgentic } from "./structural-rollout-zY0oqQzO.js";
|
|
8
8
|
import { i as notifyRuntimeHookEvent, t as composeRuntimeHooks } from "./runtime-hooks-C7iJOWm3.js";
|
|
9
9
|
import { a as notifySandboxEventObserver, i as mapSandboxToolEvent, r as mapSandboxEvent, t as createSandboxToolPartState } from "./sandbox-events-Yhd1GYWl.js";
|
|
10
|
-
import {
|
|
10
|
+
import { $t as kernelPromptRegistry, Ct as mergeAbortSignals, Ft as createSandboxLineage, It as probeSandboxCapabilities, Nt as defaultSelectWinner, Ot as createPushTraceSource, Pt as runAgentRounds, Qt as formatPromptHandle, St as createExecutorRegistry, Tt as createWorktreeCliExecutor, Ut as canonicalizeAuthoredProfile, n as supervise, r as workerFromBackend, rn as gateOnDeliverable, wt as taskToPrompt, xt as createExecutor } from "./supervise-CsTKbH9R.js";
|
|
11
11
|
import { CODING_HARNESSES, InMemoryTraceStore, OUTPUT_VALUE, benjaminiHochberg, buildTrajectory, computeFindingId as computeFindingId$1, confidenceInterval, expandProfileAxes, harnessAxisOf, makeFinding as makeFinding$1, pairedBootstrap, paretoFrontier, scoreKnowledgeReadiness, wilcoxonSignedRank, wilson } from "@tangle-network/agent-eval";
|
|
12
12
|
import { heldoutSignificance, runProfileMatrix } from "@tangle-network/agent-eval/campaign";
|
|
13
13
|
import { agentProfileSchema, canonicalCandidateDigest, validateAgentProfileSecurity } from "@tangle-network/agent-interface";
|
|
14
|
+
import { randomUUID } from "node:crypto";
|
|
14
15
|
import { mkdir, readFile, writeFile } from "node:fs/promises";
|
|
15
16
|
import { appendFileSync, chmodSync, constants, copyFileSync, existsSync, lstatSync, mkdirSync, mkdtempSync, readFileSync, readlinkSync, rmSync, symlinkSync, writeFileSync } from "node:fs";
|
|
16
17
|
import { dirname, isAbsolute, join, relative, resolve, sep } from "node:path";
|
|
@@ -4593,6 +4594,333 @@ function deriveTurnSignal(callerSignal, timeoutMs) {
|
|
|
4593
4594
|
};
|
|
4594
4595
|
}
|
|
4595
4596
|
//#endregion
|
|
4597
|
+
//#region src/runtime/supervise/chat-transport-executor.ts
|
|
4598
|
+
/**
|
|
4599
|
+
* The chat-transport leaf executor: a worker whose runtime is a plain OpenAI-compatible
|
|
4600
|
+
* `/v1/chat/completions` transport — the worker IS a model conversation, not a sandboxed process
|
|
4601
|
+
* (#721). Tool calls are optional (none, or a caller-provided tool table executed on this host).
|
|
4602
|
+
* A chat worker gets everything real workers get through the open `Executor` port: node pinning,
|
|
4603
|
+
* conserved spend, settle/verdict, journal + edge ledger.
|
|
4604
|
+
*
|
|
4605
|
+
* Module home: a standalone leaf-executor module beside `worktree-cli-executor.ts` — a direct
|
|
4606
|
+
* `(options) → Executor` constructor, NOT a `createExecutor` backend variant. The reason is
|
|
4607
|
+
* continuity: `workerFromBackend` (the backend-as-data path every `ExecutorConfig` rides) creates
|
|
4608
|
+
* a fresh executor per spawn with no session re-attachment and deliberately FAILS LOUD on a
|
|
4609
|
+
* `continuity: 'resume'` spawn; the documented resume consumer is a session-owning
|
|
4610
|
+
* `makeWorkerAgent` seam. {@link chatWorkerSeam} is that seam, and this module ships both halves
|
|
4611
|
+
* together so no caller re-derives the resume wiring.
|
|
4612
|
+
*
|
|
4613
|
+
* Transport shape: NON-streaming, one buffered POST per turn — the simplest honest choice.
|
|
4614
|
+
* A streaming executor cannot mark an unmetered turn today (`UsageEvent`'s `tokens` variant has
|
|
4615
|
+
* no `tokensKnown: false` twin — see the documented limitation in `./types`), while the one-shot
|
|
4616
|
+
* path returns a whole `Spend` that carries both markers. Honesty wins over liveness here.
|
|
4617
|
+
*
|
|
4618
|
+
* Metering: tokens come from the transport's `usage` fields; a turn without usage marks
|
|
4619
|
+
* `tokensKnown: false`. Dollars come ONLY from the response's own cost fields (`usage.cost` /
|
|
4620
|
+
* `usage.cost_usd`, the cli-bridge and OpenRouter conventions); a turn without one marks
|
|
4621
|
+
* `usdKnown: false`. NEVER estimated from a local price table — this executor speaks to arbitrary
|
|
4622
|
+
* OpenAI-compatible endpoints whose models a local table cannot price, and a silent estimate is a
|
|
4623
|
+
* fabricated measurement.
|
|
4624
|
+
*
|
|
4625
|
+
* @experimental
|
|
4626
|
+
*/
|
|
4627
|
+
/** The default transport: POST `${url}/chat/completions` with an optional bearer. Fail-loud on
|
|
4628
|
+
* any non-2xx — the status and body head become the settle reason. */
|
|
4629
|
+
function chatCompletionsTransport(opts) {
|
|
4630
|
+
if (typeof opts.url !== "string" || opts.url.length === 0) throw new ValidationError("chatCompletionsTransport: url required");
|
|
4631
|
+
const endpoint = `${opts.url.replace(/\/$/, "")}/chat/completions`;
|
|
4632
|
+
return async (body, signal) => {
|
|
4633
|
+
const res = await fetch(endpoint, {
|
|
4634
|
+
method: "POST",
|
|
4635
|
+
headers: {
|
|
4636
|
+
"content-type": "application/json",
|
|
4637
|
+
...opts.bearer ? { authorization: `Bearer ${opts.bearer}` } : {}
|
|
4638
|
+
},
|
|
4639
|
+
body: JSON.stringify(body),
|
|
4640
|
+
...signal ? { signal } : {}
|
|
4641
|
+
});
|
|
4642
|
+
if (!res.ok) throw new ValidationError(`chat transport ${res.status}: ${(await res.text()).slice(0, 200)}`);
|
|
4643
|
+
return res.json();
|
|
4644
|
+
};
|
|
4645
|
+
}
|
|
4646
|
+
/** In-memory `ChatSessionStore`. Entries are detached copies — a caller mutating a saved array
|
|
4647
|
+
* cannot corrupt a recorded session. */
|
|
4648
|
+
function createChatSessionStore() {
|
|
4649
|
+
const sessions = /* @__PURE__ */ new Map();
|
|
4650
|
+
return {
|
|
4651
|
+
load: (workerId) => sessions.get(workerId),
|
|
4652
|
+
save: (workerId, messages) => {
|
|
4653
|
+
sessions.set(workerId, structuredClone(messages));
|
|
4654
|
+
}
|
|
4655
|
+
};
|
|
4656
|
+
}
|
|
4657
|
+
const CHAT_TRANSPORT_RUNTIME = "chat-transport";
|
|
4658
|
+
/**
|
|
4659
|
+
* Build the chat-transport `Executor`: one `execute` = one conversation SHOT — seed (fresh system
|
|
4660
|
+
* prompt, or the resumed session's recorded history) + the task as the next user message, then
|
|
4661
|
+
* loop completion → host tool calls → tool messages until the model answers without a tool call
|
|
4662
|
+
* (or the turn cap). Settles with the final assistant text as `out`.
|
|
4663
|
+
*
|
|
4664
|
+
* Fail-loud contract: transport failures (non-2xx, network faults, malformed completions) throw
|
|
4665
|
+
* `ValidationError`, which the scope settles as an INFRA failure (`Settled.down.infra`) — never a
|
|
4666
|
+
* fake success. The accumulated conversation is still recorded before the throw when a store is
|
|
4667
|
+
* configured, because the inference HAPPENED and a resume may continue a failed session (the
|
|
4668
|
+
* kernel deliberately allows resume-after-failure; the seam decides).
|
|
4669
|
+
*/
|
|
4670
|
+
function chatTransportExecutor(opts) {
|
|
4671
|
+
const model = concreteModelId(opts.model);
|
|
4672
|
+
if (!model) throw new ValidationError("chatTransportExecutor: model required");
|
|
4673
|
+
if (!opts.complete && (typeof opts.url !== "string" || opts.url.length === 0)) throw new ValidationError("chatTransportExecutor: url required (or inject `complete`)");
|
|
4674
|
+
for (const tool of opts.tools ?? []) if (typeof tool.spec?.function?.name !== "string" || typeof tool.execute !== "function") throw new ValidationError("chatTransportExecutor: every tools entry needs spec.function.name + execute");
|
|
4675
|
+
const maxTurns = opts.maxTurnsPerShot ?? 200;
|
|
4676
|
+
if (!Number.isInteger(maxTurns) || maxTurns < 1) throw new ValidationError("chatTransportExecutor: maxTurnsPerShot must be a positive integer");
|
|
4677
|
+
if (opts.maxTokens !== void 0 && (!Number.isInteger(opts.maxTokens) || opts.maxTokens < 1)) throw new ValidationError("chatTransportExecutor: maxTokens must be a positive integer");
|
|
4678
|
+
let seed;
|
|
4679
|
+
if (opts.resume) {
|
|
4680
|
+
if (!opts.sessions) throw new ValidationError("chatTransportExecutor: a 'resume' spawn needs `sessions` — the store holding the conversation this shot continues");
|
|
4681
|
+
const prior = opts.sessions.load(opts.resume.ofWorker);
|
|
4682
|
+
if (prior === void 0) throw new ValidationError(`chatTransportExecutor: no recorded conversation for worker '${opts.resume.ofWorker}' — the session store holds only conversations recorded by this process (the kernel’s process-local resume boundary)`);
|
|
4683
|
+
seed = structuredClone(prior);
|
|
4684
|
+
} else seed = opts.system !== void 0 && opts.system.length > 0 ? [{
|
|
4685
|
+
role: "system",
|
|
4686
|
+
content: opts.system
|
|
4687
|
+
}] : [];
|
|
4688
|
+
const transport = opts.complete ?? chatCompletionsTransport({
|
|
4689
|
+
url: opts.url,
|
|
4690
|
+
...opts.bearer ? { bearer: opts.bearer } : {}
|
|
4691
|
+
});
|
|
4692
|
+
const toolSpecs = (opts.tools ?? []).map((tool) => tool.spec);
|
|
4693
|
+
const toolByName = new Map((opts.tools ?? []).map((tool) => [tool.spec.function.name, tool]));
|
|
4694
|
+
const controller = new AbortController();
|
|
4695
|
+
let artifact;
|
|
4696
|
+
let executed = false;
|
|
4697
|
+
const executionId = opts.sessionKey ?? `chat-session-${randomUUID()}`;
|
|
4698
|
+
const attemptId = opts.attemptId ?? newExecutionAttemptId(executionId);
|
|
4699
|
+
const executor = {
|
|
4700
|
+
runtime: CHAT_TRANSPORT_RUNTIME,
|
|
4701
|
+
async execute(task, signal) {
|
|
4702
|
+
if (executed) throw new ValidationError("chatTransportExecutor: execute() called twice on one instance");
|
|
4703
|
+
executed = true;
|
|
4704
|
+
const started = Date.now();
|
|
4705
|
+
const messages = seed;
|
|
4706
|
+
messages.push({
|
|
4707
|
+
role: "user",
|
|
4708
|
+
content: taskToPrompt(task)
|
|
4709
|
+
});
|
|
4710
|
+
const linked = mergeAbortSignals(signal, controller.signal);
|
|
4711
|
+
const tokens = zeroTokenUsage();
|
|
4712
|
+
let tokensKnown = true;
|
|
4713
|
+
let usd = 0;
|
|
4714
|
+
let usdKnown = true;
|
|
4715
|
+
let turns = 0;
|
|
4716
|
+
let lastText = "";
|
|
4717
|
+
try {
|
|
4718
|
+
for (let t = 0; t < maxTurns; t += 1) {
|
|
4719
|
+
const body = {
|
|
4720
|
+
model,
|
|
4721
|
+
messages,
|
|
4722
|
+
...toolSpecs.length > 0 ? {
|
|
4723
|
+
tools: toolSpecs,
|
|
4724
|
+
tool_choice: "auto"
|
|
4725
|
+
} : {},
|
|
4726
|
+
...opts.temperature !== void 0 ? { temperature: opts.temperature } : {},
|
|
4727
|
+
...opts.maxTokens !== void 0 ? { max_tokens: opts.maxTokens } : {}
|
|
4728
|
+
};
|
|
4729
|
+
let raw;
|
|
4730
|
+
try {
|
|
4731
|
+
raw = await transport(body, linked);
|
|
4732
|
+
} catch (cause) {
|
|
4733
|
+
if (cause instanceof Error && cause.name === "AbortError") throw cause;
|
|
4734
|
+
if (cause instanceof ValidationError) throw cause;
|
|
4735
|
+
throw new ValidationError(`chatTransportExecutor: transport failed: ${cause instanceof Error ? cause.message : String(cause)}`);
|
|
4736
|
+
}
|
|
4737
|
+
turns += 1;
|
|
4738
|
+
const data = raw;
|
|
4739
|
+
const usage = data?.usage;
|
|
4740
|
+
if (usage && typeof usage.prompt_tokens === "number" && typeof usage.completion_tokens === "number") {
|
|
4741
|
+
tokens.input += usage.prompt_tokens;
|
|
4742
|
+
tokens.output += usage.completion_tokens;
|
|
4743
|
+
} else tokensKnown = false;
|
|
4744
|
+
const turnCost = typeof usage?.cost === "number" ? usage.cost : typeof usage?.cost_usd === "number" ? usage.cost_usd : void 0;
|
|
4745
|
+
if (turnCost !== void 0) usd += turnCost;
|
|
4746
|
+
else usdKnown = false;
|
|
4747
|
+
const msg = data?.choices?.[0]?.message;
|
|
4748
|
+
if (msg === void 0) throw new ValidationError("chatTransportExecutor: transport returned no choices[0].message");
|
|
4749
|
+
if (typeof msg.content === "string" && msg.content.length > 0) lastText = msg.content;
|
|
4750
|
+
const toolCalls = msg.tool_calls ?? [];
|
|
4751
|
+
if (toolCalls.length === 0 || toolSpecs.length === 0) {
|
|
4752
|
+
messages.push({
|
|
4753
|
+
role: "assistant",
|
|
4754
|
+
content: msg.content ?? ""
|
|
4755
|
+
});
|
|
4756
|
+
break;
|
|
4757
|
+
}
|
|
4758
|
+
messages.push({
|
|
4759
|
+
role: "assistant",
|
|
4760
|
+
content: msg.content ?? "",
|
|
4761
|
+
tool_calls: toolCalls.map((tc, i) => ({
|
|
4762
|
+
id: tc.id ?? `call_${i}`,
|
|
4763
|
+
type: "function",
|
|
4764
|
+
function: {
|
|
4765
|
+
name: tc.function?.name ?? "",
|
|
4766
|
+
arguments: tc.function?.arguments ?? "{}"
|
|
4767
|
+
}
|
|
4768
|
+
}))
|
|
4769
|
+
});
|
|
4770
|
+
for (let i = 0; i < toolCalls.length; i += 1) {
|
|
4771
|
+
const tc = toolCalls[i];
|
|
4772
|
+
const id = tc?.id ?? `call_${i}`;
|
|
4773
|
+
const name = tc?.function?.name ?? "";
|
|
4774
|
+
const tool = toolByName.get(name);
|
|
4775
|
+
if (!tool) {
|
|
4776
|
+
messages.push({
|
|
4777
|
+
role: "tool",
|
|
4778
|
+
tool_call_id: id,
|
|
4779
|
+
content: `error: unknown tool '${name}'`
|
|
4780
|
+
});
|
|
4781
|
+
continue;
|
|
4782
|
+
}
|
|
4783
|
+
let args;
|
|
4784
|
+
try {
|
|
4785
|
+
args = JSON.parse(tc?.function?.arguments ?? "{}");
|
|
4786
|
+
} catch {
|
|
4787
|
+
messages.push({
|
|
4788
|
+
role: "tool",
|
|
4789
|
+
tool_call_id: id,
|
|
4790
|
+
content: "error: tool arguments were not valid JSON"
|
|
4791
|
+
});
|
|
4792
|
+
continue;
|
|
4793
|
+
}
|
|
4794
|
+
let result;
|
|
4795
|
+
try {
|
|
4796
|
+
result = await tool.execute(args, task);
|
|
4797
|
+
} catch (cause) {
|
|
4798
|
+
result = `error: ${cause instanceof Error ? cause.message : String(cause)}`;
|
|
4799
|
+
}
|
|
4800
|
+
messages.push({
|
|
4801
|
+
role: "tool",
|
|
4802
|
+
tool_call_id: id,
|
|
4803
|
+
content: result
|
|
4804
|
+
});
|
|
4805
|
+
}
|
|
4806
|
+
}
|
|
4807
|
+
} finally {
|
|
4808
|
+
if (opts.sessions && opts.sessionKey !== void 0) opts.sessions.save(opts.sessionKey, messages);
|
|
4809
|
+
}
|
|
4810
|
+
const spent = {
|
|
4811
|
+
iterations: turns,
|
|
4812
|
+
tokens,
|
|
4813
|
+
...tokensKnown ? {} : { tokensKnown: false },
|
|
4814
|
+
usd,
|
|
4815
|
+
...usdKnown ? {} : { usdKnown: false },
|
|
4816
|
+
ms: Date.now() - started
|
|
4817
|
+
};
|
|
4818
|
+
artifact = {
|
|
4819
|
+
outRef: contentAddress({
|
|
4820
|
+
kind: "chat-transport",
|
|
4821
|
+
model,
|
|
4822
|
+
content: lastText,
|
|
4823
|
+
turns
|
|
4824
|
+
}),
|
|
4825
|
+
out: lastText,
|
|
4826
|
+
spent
|
|
4827
|
+
};
|
|
4828
|
+
return artifact;
|
|
4829
|
+
},
|
|
4830
|
+
teardown(_grace) {
|
|
4831
|
+
controller.abort();
|
|
4832
|
+
return Promise.resolve({ destroyed: true });
|
|
4833
|
+
},
|
|
4834
|
+
resultArtifact() {
|
|
4835
|
+
if (!artifact) throw new ValidationError("chatTransportExecutor: resultArtifact() read before execute()");
|
|
4836
|
+
return {
|
|
4837
|
+
...artifact,
|
|
4838
|
+
spent: artifact.spent
|
|
4839
|
+
};
|
|
4840
|
+
}
|
|
4841
|
+
};
|
|
4842
|
+
if (opts.profile === void 0) return executor;
|
|
4843
|
+
return attestRuntimeOwnedExecutor(executor, {
|
|
4844
|
+
effectiveProfile: opts.profile,
|
|
4845
|
+
backend: "chat-transport",
|
|
4846
|
+
model: {
|
|
4847
|
+
status: "known",
|
|
4848
|
+
id: model
|
|
4849
|
+
},
|
|
4850
|
+
execution: {
|
|
4851
|
+
kind: "session",
|
|
4852
|
+
id: executionId
|
|
4853
|
+
},
|
|
4854
|
+
materializer: "chat-transport-conversation",
|
|
4855
|
+
plan: {
|
|
4856
|
+
kind: "openai-chat-conversation",
|
|
4857
|
+
model,
|
|
4858
|
+
maxTurnsPerShot: maxTurns,
|
|
4859
|
+
tools: toolSpecs,
|
|
4860
|
+
resumeOf: opts.resume?.ofWorker ?? null
|
|
4861
|
+
}
|
|
4862
|
+
}, {
|
|
4863
|
+
attemptId,
|
|
4864
|
+
binding: {
|
|
4865
|
+
endpoint: opts.complete ? "injected-transport" : opts.url,
|
|
4866
|
+
model,
|
|
4867
|
+
sessionKey: opts.sessionKey ?? null
|
|
4868
|
+
},
|
|
4869
|
+
descriptor: {
|
|
4870
|
+
kind: "chat-transport-session",
|
|
4871
|
+
transport: opts.complete ? "injected" : "http",
|
|
4872
|
+
backend: "chat-transport"
|
|
4873
|
+
}
|
|
4874
|
+
});
|
|
4875
|
+
}
|
|
4876
|
+
/**
|
|
4877
|
+
* The `makeWorkerAgent` seam over {@link chatTransportExecutor} — the continuity consumer
|
|
4878
|
+
* `workerFromBackend` refuses to be. Every spawn becomes one conversation shot: the spawned
|
|
4879
|
+
* profile's system prompt + instructions (which is where a graph's delegates directive lands)
|
|
4880
|
+
* seed a fresh session, and a `'resume'` spawn re-attaches by loading `resume.ofWorker`'s
|
|
4881
|
+
* recorded message list from the seam's session store. Conversations are recorded under the
|
|
4882
|
+
* kernel node id, which is exactly what a later `resume.ofWorker` names.
|
|
4883
|
+
*/
|
|
4884
|
+
function chatWorkerSeam(opts) {
|
|
4885
|
+
if (!opts.complete && (typeof opts.url !== "string" || opts.url.length === 0)) throw new ValidationError("chatWorkerSeam: url required (or inject `complete`)");
|
|
4886
|
+
const sessions = opts.sessions ?? createChatSessionStore();
|
|
4887
|
+
return (rawProfile, spawnContext) => {
|
|
4888
|
+
const parsed = agentProfileSchema.safeParse(canonicalizeAuthoredProfile(rawProfile));
|
|
4889
|
+
if (!parsed.success) throw new ValidationError(`chatWorkerSeam: invalid AgentProfile: ${parsed.error.message}`);
|
|
4890
|
+
const profile = parsed.data;
|
|
4891
|
+
const model = concreteProfileModel(profile) ?? concreteModelId(opts.model);
|
|
4892
|
+
if (!model) throw new ValidationError("chatWorkerSeam: no model — set ChatWorkerSeamOptions.model or AgentProfile.model.default");
|
|
4893
|
+
const system = [profile.prompt?.systemPrompt, ...profile.prompt?.instructions ?? []].filter((line) => typeof line === "string" && line.trim().length > 0).join("\n");
|
|
4894
|
+
return {
|
|
4895
|
+
name: profile.name ?? "chat-worker",
|
|
4896
|
+
act: async () => void 0,
|
|
4897
|
+
executorSpec: {
|
|
4898
|
+
profile,
|
|
4899
|
+
harness: null,
|
|
4900
|
+
executorFactory: (executorSpec, ctx) => {
|
|
4901
|
+
const executor = chatTransportExecutor({
|
|
4902
|
+
url: opts.url,
|
|
4903
|
+
...opts.bearer !== void 0 ? { bearer: opts.bearer } : {},
|
|
4904
|
+
model,
|
|
4905
|
+
...system.length > 0 ? { system } : {},
|
|
4906
|
+
...opts.tools !== void 0 ? { tools: opts.tools } : {},
|
|
4907
|
+
...opts.temperature !== void 0 ? { temperature: opts.temperature } : {},
|
|
4908
|
+
...opts.maxTokens !== void 0 ? { maxTokens: opts.maxTokens } : {},
|
|
4909
|
+
...opts.maxTurnsPerShot !== void 0 ? { maxTurnsPerShot: opts.maxTurnsPerShot } : {},
|
|
4910
|
+
...opts.complete !== void 0 ? { complete: opts.complete } : {},
|
|
4911
|
+
sessions,
|
|
4912
|
+
...ctx.node?.nodeId !== void 0 ? { sessionKey: ctx.node.nodeId } : {},
|
|
4913
|
+
...spawnContext?.resume !== void 0 ? { resume: spawnContext.resume } : {},
|
|
4914
|
+
profile: executorSpec.profile,
|
|
4915
|
+
...ctx.node?.attemptId !== void 0 ? { attemptId: ctx.node.attemptId } : {}
|
|
4916
|
+
});
|
|
4917
|
+
return opts.deliverable ? gateOnDeliverable(executor, opts.deliverable) : executor;
|
|
4918
|
+
}
|
|
4919
|
+
}
|
|
4920
|
+
};
|
|
4921
|
+
};
|
|
4922
|
+
}
|
|
4923
|
+
//#endregion
|
|
4596
4924
|
//#region src/runtime/supervise/graph.ts
|
|
4597
4925
|
/**
|
|
4598
4926
|
*
|
|
@@ -4607,8 +4935,8 @@ function deriveTurnSignal(callerSignal, timeoutMs) {
|
|
|
4607
4935
|
* NOT A SECOND SCHEDULER. `runGraph` is an interpretation layer over what already runs:
|
|
4608
4936
|
* `supervise()` is the execution core — the same `supervisorAgent`/`driverAgent` machinery,
|
|
4609
4937
|
* `makeWorkerAgent` seam, conserved-pool budget, and deliverable-gated settlement every
|
|
4610
|
-
* supervised run uses. (`
|
|
4611
|
-
*
|
|
4938
|
+
* supervised run uses. (`runAgentRounds` is deliberately NOT the substrate here.) What the graph
|
|
4939
|
+
* layer ADDS is exactly what a bespoke driver loop never
|
|
4612
4940
|
* had:
|
|
4613
4941
|
*
|
|
4614
4942
|
* 1. **Node pinning** — a spawn names a node (`profile.name` = node id) and the node's canonical
|
|
@@ -4623,6 +4951,12 @@ function deriveTurnSignal(callerSignal, timeoutMs) {
|
|
|
4623
4951
|
* edge is a versioned optimization target, never prose hardcoded in a builder function.
|
|
4624
4952
|
* 4. **Per-edge traversal caps** — the cyclic-graph backstop. A delegates edge whose cap is
|
|
4625
4953
|
* exhausted REFUSES further traversals (fail loud), so a cycle cannot spin the pool dry.
|
|
4954
|
+
* 5. **Continuity as data** — a delegates edge may declare `continuity: 'resume'`, so each spawn
|
|
4955
|
+
* after the node's first re-attaches to its latest SETTLED session (the spawn context hands
|
|
4956
|
+
* the executor seam `resume: { ofWorker, sequence }`; the kernel keeps identity, ordering,
|
|
4957
|
+
* ledger truth, and the one conserved pool). Every ledger row states how its hop continued:
|
|
4958
|
+
* `'fresh' | 'resume'` for spawns, `'steer'` for mid-run deliveries — fresh respawns, session
|
|
4959
|
+
* resumes, and live steers are all plain data, each a ledgered fact.
|
|
4626
4960
|
*
|
|
4627
4961
|
* ORACLES ARE ENVIRONMENT, NEVER WORKERS. Graders/verifiers must not be spawnable in the graph —
|
|
4628
4962
|
* a delegates edge to them leaks the rubric. An `analyzes` edge names its analyst in one of two
|
|
@@ -4682,6 +5016,7 @@ function validateGraph(graph, registry, analysts) {
|
|
|
4682
5016
|
requireNode(edge.from, edgeId(edge));
|
|
4683
5017
|
requireNode(edge.to, edgeId(edge));
|
|
4684
5018
|
if (edge.from === edge.to) throw new ValidationError(`runGraph: ${edgeId(edge)} delegates to itself — the driver↔worker cycle is the settle-return loop, not a self-edge`);
|
|
5019
|
+
if (edge.continuity !== void 0 && edge.continuity !== "fresh" && edge.continuity !== "resume") throw new ValidationError(`runGraph: ${edgeId(edge)} has invalid continuity ${JSON.stringify(edge.continuity)} — a delegates edge's continuity is 'fresh' or 'resume'`);
|
|
4685
5020
|
}
|
|
4686
5021
|
const delegatedTo = new Set(delegates.map((edge) => edge.to));
|
|
4687
5022
|
const roots = [...new Set(delegates.map((edge) => edge.from))].filter((id) => !delegatedTo.has(id));
|
|
@@ -4691,6 +5026,7 @@ function validateGraph(graph, registry, analysts) {
|
|
|
4691
5026
|
const analystIds = /* @__PURE__ */ new Set();
|
|
4692
5027
|
const analystNodes = /* @__PURE__ */ new Map();
|
|
4693
5028
|
for (const edge of analyzes) {
|
|
5029
|
+
if (edge.continuity !== void 0) throw new ValidationError(`runGraph: ${edgeId(edge)} carries continuity — analysts are spawned by the analyst machinery (every analyst run is a fresh session over settled evidence), so continuity is a delegates-edge axis only`);
|
|
4694
5030
|
if (analystIds.has(edge.analyst)) throw new ValidationError(`runGraph: two analyzes edges share analyst '${edge.analyst}' — one analyzes edge per analyst lens (traversals are ledgered by analyst id; a second edge would silently absorb the first's). Register the lens under a second id for a second edge.`);
|
|
4695
5031
|
analystIds.add(edge.analyst);
|
|
4696
5032
|
const analystNode = byId.get(edge.analyst);
|
|
@@ -4703,7 +5039,10 @@ function validateGraph(graph, registry, analysts) {
|
|
|
4703
5039
|
} else if (!analysts) throw new ValidationError(`runGraph: ${edgeId(edge)} analyst '${edge.analyst}' is not a graph node, and no RunGraphOptions.analysts registry was provided to resolve it as a lens`);
|
|
4704
5040
|
else if (!inRegistry) throw new ValidationError(`runGraph: ${edgeId(edge)} analyst '${edge.analyst}' is neither a graph node nor in the analysts registry (known lenses: ${analysts.kinds.map((kind) => kind.id).join(", ") || "none"})`);
|
|
4705
5041
|
if (edge.over.length === 0) throw new ValidationError(`runGraph: ${edgeId(edge)} must analyze at least one node`);
|
|
4706
|
-
for (const over of edge.over)
|
|
5042
|
+
for (const over of edge.over) {
|
|
5043
|
+
requireNode(over, edgeId(edge));
|
|
5044
|
+
if (over === root.id) throw new ValidationError(`runGraph: ${edgeId(edge)} analyzes the ROOT — analysts observe settled workers, and the root never settles as one, so this edge would silently never fire; list delegates-target nodes only`);
|
|
5045
|
+
}
|
|
4707
5046
|
requireNode(edge.to, edgeId(edge));
|
|
4708
5047
|
}
|
|
4709
5048
|
for (const edge of analyzes) for (const over of edge.over) if (analystNodes.has(over)) throw new ValidationError(`runGraph: ${edgeId(edge)} analyzes '${over}', which is an analyst node — an analyst run settles as a finding, never as a worker, so this edge would silently never fire; analyst nodes are not analyzable`);
|
|
@@ -4769,6 +5108,7 @@ function runGraph(graph, opts) {
|
|
|
4769
5108
|
},
|
|
4770
5109
|
traversal: entry.traversal,
|
|
4771
5110
|
outcome: entry.outcome,
|
|
5111
|
+
continuity: entry.continuity,
|
|
4772
5112
|
bytes: entry.bytes,
|
|
4773
5113
|
...entry.reason !== void 0 ? { reason: entry.reason } : {},
|
|
4774
5114
|
seq: ledgerSeq++,
|
|
@@ -4803,7 +5143,9 @@ function runGraph(graph, opts) {
|
|
|
4803
5143
|
const edge = delegatesByWorker.get(node.id);
|
|
4804
5144
|
const id = edgeId(edge);
|
|
4805
5145
|
const cap = edge.maxTraversals ?? 32;
|
|
4806
|
-
|
|
5146
|
+
const used = traversalCounts.get(id) ?? 0;
|
|
5147
|
+
const spawnContinuity = spawnContext?.continuity ?? "fresh";
|
|
5148
|
+
if (used >= cap) {
|
|
4807
5149
|
exhausted.add(id);
|
|
4808
5150
|
exhaustedDelegates.add(id);
|
|
4809
5151
|
record({
|
|
@@ -4813,6 +5155,7 @@ function runGraph(graph, opts) {
|
|
|
4813
5155
|
to: edge.to,
|
|
4814
5156
|
directive: formatPromptHandle(edge.directive),
|
|
4815
5157
|
outcome: "unpropagated",
|
|
5158
|
+
continuity: spawnContinuity,
|
|
4816
5159
|
bytes: 0,
|
|
4817
5160
|
reason: `traversal-cap-exhausted (max ${cap})`
|
|
4818
5161
|
}, true);
|
|
@@ -4828,6 +5171,7 @@ function runGraph(graph, opts) {
|
|
|
4828
5171
|
to: edge.to,
|
|
4829
5172
|
directive: formatPromptHandle(edge.directive),
|
|
4830
5173
|
outcome: bytes === 0 ? "empty" : "delivered",
|
|
5174
|
+
continuity: spawnContinuity,
|
|
4831
5175
|
bytes,
|
|
4832
5176
|
...bytes === 0 ? { reason: "no directive text and no task payload" } : {}
|
|
4833
5177
|
}, false);
|
|
@@ -4862,14 +5206,18 @@ function runGraph(graph, opts) {
|
|
|
4862
5206
|
};
|
|
4863
5207
|
});
|
|
4864
5208
|
const driverAnalyzesBriefs = analyzes.filter((edge) => edge.to === root.id).map((edge) => analystNodes.has(edge.analyst) ? `Findings from analyst '${edge.analyst}' (a tool-equipped analyst agent node, over: ${edge.over.join(", ")}) will arrive as finding events.` : `Findings from analyst '${edge.analyst}' (over: ${edge.over.join(", ")}) will arrive as finding events.\n${registry.resolve(edge.directive).text}`);
|
|
5209
|
+
const continuityByProfile = {};
|
|
5210
|
+
for (const [nodeId, edge] of delegatesByWorker) if (edge.continuity !== void 0) continuityByProfile[nodeId] = edge.continuity;
|
|
4865
5211
|
const graphBrief = [
|
|
4866
5212
|
"AGENT GRAPH: you are the driver node of a fixed topology. You may spawn ONLY these worker",
|
|
4867
5213
|
"nodes, by EXACT name (spawn_agent with profile: { name: '<node id>' }; the node's full",
|
|
4868
5214
|
"profile is pinned by the graph — any other profile fields you author are ignored):",
|
|
4869
5215
|
...[...workers.values()].map((node) => {
|
|
4870
|
-
const
|
|
5216
|
+
const edge = delegatesByWorker.get(node.id);
|
|
5217
|
+
const cap = edge.maxTraversals ?? 32;
|
|
4871
5218
|
const description = typeof node.profile.description === "string" && node.profile.description.length > 0 ? ` — ${node.profile.description}` : "";
|
|
4872
|
-
|
|
5219
|
+
const continuityNote = edge.continuity === "resume" ? "; continuity: resume — each spawn after the first re-attaches to this node's latest settled session (spawn again to continue it; steer while it is live)" : "";
|
|
5220
|
+
return `- '${node.id}'${description} (delegation cap: ${cap} traversals${continuityNote})`;
|
|
4873
5221
|
}),
|
|
4874
5222
|
...driverAnalyzesBriefs.length > 0 ? ["", ...driverAnalyzesBriefs] : []
|
|
4875
5223
|
].join("\n");
|
|
@@ -4904,6 +5252,7 @@ function runGraph(graph, opts) {
|
|
|
4904
5252
|
to: edge.to,
|
|
4905
5253
|
directive: formatPromptHandle(edge.directive),
|
|
4906
5254
|
outcome: capped ? "unpropagated" : outcome,
|
|
5255
|
+
continuity: "steer",
|
|
4907
5256
|
bytes,
|
|
4908
5257
|
...capped ? { reason: `traversal-cap-exhausted (max ${edge.maxTraversals ?? 32})` } : reason !== void 0 ? { reason } : {},
|
|
4909
5258
|
...workerId !== void 0 ? { workerId } : {}
|
|
@@ -4942,6 +5291,7 @@ function runGraph(graph, opts) {
|
|
|
4942
5291
|
to: edge.to,
|
|
4943
5292
|
directive: formatPromptHandle(edge.directive),
|
|
4944
5293
|
outcome: !down.delivered ? "unpropagated" : stripped ? "stripped" : "delivered",
|
|
5294
|
+
continuity: "steer",
|
|
4945
5295
|
bytes: byteLength(down.instruction),
|
|
4946
5296
|
...!down.delivered ? { reason: down.outcome } : stripped ? { reason: `authorization narrowed ${stripped.composedBytes} composed bytes` } : {},
|
|
4947
5297
|
workerId: down.toWorker
|
|
@@ -4977,6 +5327,7 @@ function runGraph(graph, opts) {
|
|
|
4977
5327
|
analyzeOnSettle: routes,
|
|
4978
5328
|
...opts.analysts ? { analysts: opts.analysts } : {}
|
|
4979
5329
|
} : {},
|
|
5330
|
+
...Object.keys(continuityByProfile).length > 0 ? { continuityByProfile } : {},
|
|
4980
5331
|
...opts.watchWorkers ? { watchWorkers: opts.watchWorkers } : {},
|
|
4981
5332
|
...opts.router ? { router: opts.router } : {},
|
|
4982
5333
|
...opts.brain ? { brain: opts.brain } : {},
|
|
@@ -6150,6 +6501,6 @@ function tail(s) {
|
|
|
6150
6501
|
return s.slice(-400);
|
|
6151
6502
|
}
|
|
6152
6503
|
//#endregion
|
|
6153
|
-
export {
|
|
6504
|
+
export { renderCorpusToInstructions as $, collectAgentTurn as A, auditIntent as At, openSandboxRun as B, resolveSecretEnv as Bt, GraphEdgeCapError as C, stopSentinel as Ct, chatTransportExecutor as D, renderLeaderboardMarkdown as Dt, chatCompletionsTransport as E, renderLeaderboardHtml as Et, selectChampion as F, createMcpEnvironment as Ft, trajectoryReport as G, runBenchmark as H, assertStrategyContract as I, sanitizeMcpToolSchema as It, builtinShapes as J, definePersona as K, authorStrategy as L, envKeyProvider as Lt, discriminatingMeans as M, McpSpawnFault as Mt, pickChampion as N, connectStdioMcp as Nt, chatWorkerSeam as O, renderLeaderboardSvg as Ot, runStrategyEvolution as P, materializeLocalMcp as Pt, InMemoryCorpus as Q, strategyAuthorContract as R, mcpSecretEnvMetadataKey as Rt, runCoderChecks as S, sentinelCompletion as St, runGraph as T, pairwiseSignificance as Tt, promotionGate as U, printBenchmarkReport as V, secretEnvOfMcpServer as Vt, equalKOnCost as W, registerShape as X, createShapeRegistry as Y, FileCorpus as Z, settledWorkerOut as _, inlineSandboxClient as _t, localShell as a, selectValidWinner as at, analyzeTrace as b, completionAuthorizes as bt, createVerifierEnvironment as c, assertTraceDerivedFindings as ct, worktreeFanout as d, registryScopeAnalyst as dt, fanout as et, EVIDENCE_MAX_CHARS as f, inProcessSandboxClient as ft, composeWorkerEvidence as g, localSandboxClient as gt, closingWorkerNote as h, resolveSandboxClient as ht, jjWorkspace as i, pipeline as it, streamAgentTurn as j, defaultAuditorInstruction as jt, createChatSessionStore as k, renderPairwiseMarkdown as kt, failuresAnalyst as l, buildSteerContext as lt, VERIFY_TAIL_CHARS as m, defineLeaderboard as mt, makeFinding$1 as n, loopUntil as nt, runInWorkspace as o, verify as ot, NOTE_MAX_CHARS as p, harvestCorpus as pt, runPersonified as q, gitWorkspace as r, panel as rt, createWaterfallCollector as s, widen as st, computeFindingId$1 as t, flatWidenGate as tt, superviseSurface as u, createScopeAnalyst as ut, copyUntrackedIntoClone as v, loopCampaignDispatch as vt, defaultEdgeTraversalCap as w, leaderboard as wt, patchDelivered as x, deterministicCompletion as xt, withUntrackedArtifacts as y, loopDispatch as yt, SandboxRunAbortError as z, resolveMcpServerLaunch as zt };
|
|
6154
6505
|
|
|
6155
|
-
//# sourceMappingURL=runtime-
|
|
6506
|
+
//# sourceMappingURL=runtime-5uDVVfER.js.map
|