@sema-agent/core 7.5.0 → 7.5.2
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/CHANGELOG.md +44 -0
- package/dist/core/auto-mode.d.ts +9 -0
- package/dist/core/auto-mode.js +11 -0
- package/dist/core/checkpoint-store.js +5 -1
- package/dist/core/protocol-table.d.ts +5 -0
- package/dist/core/protocol-table.js +1 -0
- package/dist/core/runner/abort-race.d.ts +41 -0
- package/dist/core/runner/abort-race.js +38 -0
- package/dist/core/runner/checkpoint-scope.d.ts +44 -0
- package/dist/core/runner/checkpoint-scope.js +7 -0
- package/dist/core/runner/compaction-call-options.d.ts +1 -1
- package/dist/core/runner/content-ask-bindings.d.ts +27 -0
- package/dist/core/runner/content-ask-bindings.js +1 -0
- package/dist/core/runner/contracts.d.ts +1990 -0
- package/dist/core/runner/contracts.js +1 -0
- package/dist/core/runner/denial-limit-arms.d.ts +24 -1
- package/dist/core/runner/denial-limit-arms.js +21 -0
- package/dist/core/runner/derived-route-fallback.d.ts +34 -0
- package/dist/core/runner/derived-route-fallback.js +16 -0
- package/dist/core/runner/inherited-ask-grants.d.ts +46 -0
- package/dist/core/runner/inherited-ask-grants.js +29 -0
- package/dist/core/runner/park-commit.d.ts +108 -0
- package/dist/core/runner/park-commit.js +32 -0
- package/dist/core/runner/{prepare-permission-rules.d.ts → permission-rule-lanes.d.ts} +109 -3
- package/dist/core/runner/{prepare-permission-rules.js → permission-rule-lanes.js} +47 -1
- package/dist/core/runner/prepare-acquire-reconcile.d.ts +1 -1
- package/dist/core/runner/prepare-ask-lane.d.ts +110 -0
- package/dist/core/runner/prepare-ask-lane.js +133 -0
- package/dist/core/runner/prepare-boundary-parks.d.ts +105 -0
- package/dist/core/runner/prepare-boundary-parks.js +169 -0
- package/dist/core/runner/prepare-caps-and-workflow.d.ts +170 -0
- package/dist/core/runner/prepare-caps-and-workflow.js +255 -0
- package/dist/core/runner/prepare-config-doors.d.ts +2 -10
- package/dist/core/runner/prepare-context-lane.d.ts +119 -0
- package/dist/core/runner/prepare-context-lane.js +230 -0
- package/dist/core/runner/prepare-defer-classify.d.ts +86 -0
- package/dist/core/runner/prepare-defer-classify.js +107 -0
- package/dist/core/runner/prepare-delegation-surface.d.ts +104 -0
- package/dist/core/runner/prepare-delegation-surface.js +144 -0
- package/dist/core/runner/prepare-execution-env.d.ts +54 -0
- package/dist/core/runner/prepare-execution-env.js +86 -0
- package/dist/core/runner/prepare-file-history.d.ts +95 -0
- package/dist/core/runner/prepare-file-history.js +383 -0
- package/dist/core/runner/prepare-gate-stations.d.ts +177 -0
- package/dist/core/runner/prepare-gate-stations.js +290 -0
- package/dist/core/runner/prepare-hands-readface.d.ts +9 -11
- package/dist/core/runner/prepare-hands-readface.js +1 -1
- package/dist/core/runner/prepare-inherited-gate.d.ts +268 -0
- package/dist/core/runner/prepare-inherited-gate.js +266 -0
- package/dist/core/runner/prepare-listings.d.ts +77 -0
- package/dist/core/runner/prepare-listings.js +76 -0
- package/dist/core/runner/prepare-lsp.d.ts +55 -0
- package/dist/core/runner/prepare-lsp.js +27 -0
- package/dist/core/runner/prepare-memory-engine-session.d.ts +84 -0
- package/dist/core/runner/prepare-memory-engine-session.js +233 -0
- package/dist/core/runner/prepare-memory.d.ts +1 -1
- package/dist/core/runner/prepare-offload-wrappers.d.ts +62 -0
- package/dist/core/runner/prepare-offload-wrappers.js +45 -0
- package/dist/core/runner/prepare-park-ask.d.ts +164 -0
- package/dist/core/runner/prepare-park-ask.js +377 -0
- package/dist/core/runner/prepare-policy-chain.d.ts +208 -0
- package/dist/core/runner/prepare-policy-chain.js +584 -0
- package/dist/core/runner/prepare-project-context.d.ts +119 -0
- package/dist/core/runner/prepare-project-context.js +148 -0
- package/dist/core/runner/prepare-prompt-assembly.d.ts +95 -0
- package/dist/core/runner/prepare-prompt-assembly.js +162 -0
- package/dist/core/runner/prepare-prompt-inputs.d.ts +119 -0
- package/dist/core/runner/prepare-prompt-inputs.js +141 -0
- package/dist/core/runner/prepare-protocol-tools.d.ts +91 -0
- package/dist/core/runner/prepare-protocol-tools.js +179 -0
- package/dist/core/runner/prepare-question-face.d.ts +101 -0
- package/dist/core/runner/prepare-question-face.js +84 -0
- package/dist/core/runner/prepare-run-refs.d.ts +89 -0
- package/dist/core/runner/prepare-run-refs.js +39 -0
- package/dist/core/runner/prepare-safety-scan.d.ts +3 -7
- package/dist/core/runner/prepare-safety-scan.js +1 -2
- package/dist/core/runner/prepare-suspend-saga.d.ts +170 -0
- package/dist/core/runner/prepare-suspend-saga.js +308 -0
- package/dist/core/runner/prepare-task.d.ts +14 -1976
- package/dist/core/runner/prepare-task.js +182 -5162
- package/dist/core/runner/prepare-tool-disclosure-mount.d.ts +111 -0
- package/dist/core/runner/prepare-tool-disclosure-mount.js +219 -0
- package/dist/core/runner/prepare-turn-wiring.d.ts +154 -0
- package/dist/core/runner/prepare-turn-wiring.js +201 -0
- package/dist/core/runner/prepare-wiring-manifest.d.ts +192 -0
- package/dist/core/runner/prepare-wiring-manifest.js +247 -0
- package/dist/core/runner/prepare-workspace-restore.d.ts +3 -56
- package/dist/core/runner/prepare-workspace-restore.js +4 -38
- package/dist/core/runner/prompt-hash-salt.d.ts +1 -0
- package/dist/core/runner/prompt-hash-salt.js +2 -0
- package/dist/core/runner/remote-env-retry.d.ts +29 -0
- package/dist/core/runner/remote-env-retry.js +16 -0
- package/dist/core/runner/rollback-stack.d.ts +32 -0
- package/dist/core/runner/rollback-stack.js +30 -0
- package/dist/core/runner/runtask.js +1 -1
- package/dist/core/runner/workspace-path.d.ts +33 -0
- package/dist/core/runner/workspace-path.js +22 -0
- package/dist/core/session.d.ts +12 -0
- package/dist/core/session.js +3 -0
- package/dist/core/tool-policy.d.ts +16 -0
- package/dist/core/tool-policy.js +3 -0
- package/dist/core/types.d.ts +2 -2
- package/dist/core/write-protect.js +3 -2
- package/package.json +6 -2
- /package/dist/core/runner/{prepare-announce-once.d.ts → announce-once-ledger.d.ts} +0 -0
- /package/dist/core/runner/{prepare-announce-once.js → announce-once-ledger.js} +0 -0
|
@@ -0,0 +1,111 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* design/390 §1.2 M14 — prepareTask's TOOL-DISCLOSURE-MOUNT phase, verbatim from the driver: the deferred registry
|
|
3
|
+
* and its placeholders, the ToolSearch mount with its serialized activation section, the materialize strategy's
|
|
4
|
+
* two-layer resolution (spec over the env channel, the safety interlock, the loud arms for a discarded env value), the
|
|
5
|
+
* per-tool static exemption with its monotone ledger, the activation seed from the transcript / compaction snapshots /
|
|
6
|
+
* checkpoint, the callable-names accessor the offload preview and ToolSearch share, the delta ref with its failed-server
|
|
7
|
+
* arm, and the RefreshMcpTools rebuild seam's two arms. The env-channel announce ledger (per sink, per line) moved with
|
|
8
|
+
* the segment — only this phase announces through it. The interface is the dependency list the segment had implicitly
|
|
9
|
+
* (design/238 R-1).
|
|
10
|
+
*
|
|
11
|
+
* ASYNC PHASE: with deferred names present the segment awaits the session's context and branch (the activation seed),
|
|
12
|
+
* exactly where the driver awaited them; with nothing deferred the body has no await of its own. The phase adds no yield
|
|
13
|
+
* BEFORE the first of those awaits (the reserved-name refusal, the env screen and the registry build run synchronously
|
|
14
|
+
* as they did). Read-stability of the host handles for the call: {@link RunInternals} (`@contract prepare.deps-read-stable`).
|
|
15
|
+
*
|
|
16
|
+
* The roster is READ here, never written (the writer table is on {@link Prepared.tools}); `harnessTools` is the derived
|
|
17
|
+
* list the harness is built from, and the placeholders live only in it.
|
|
18
|
+
*/
|
|
19
|
+
import type { AgentHarness, AgentTool } from "../../internal/harness.js";
|
|
20
|
+
import { type ToolFingerprintInput } from "../cache-break-detector.js";
|
|
21
|
+
import type { MaterializedMcp, McpServerStatus } from "../mcp.js";
|
|
22
|
+
import type { StoredSession } from "../session.js";
|
|
23
|
+
import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
24
|
+
import type { Prepared, PrepareResume } from "./contracts.js";
|
|
25
|
+
export interface PrepareToolDisclosureMountInput {
|
|
26
|
+
/** borrowed-readonly — the REBOUND spec. Read: `toolMaterializeStrategy` (the requested strategy, spec wins) and
|
|
27
|
+
* `deferSelfResolve` (the direct-call lane, the interlock). Never mutated. */
|
|
28
|
+
spec: Pick<TaskSpec, "toolMaterializeStrategy" | "deferSelfResolve">;
|
|
29
|
+
/** borrowed-readonly — the deployment seats: only `onNotice` (the env-channel discard announcements). */
|
|
30
|
+
deps: Pick<RunnerDeps, "onNotice">;
|
|
31
|
+
/** borrowed-readonly — the acquired session: `buildContext` and `getBranch` seed the activation set (deferred names only). */
|
|
32
|
+
session: Pick<StoredSession, "buildContext" | "getBranch">;
|
|
33
|
+
/** borrowed-readonly — the resume leg, or undefined: `seed.activeTools` is the authoritative activation reseed. */
|
|
34
|
+
resume: Pick<PrepareResume, "seed"> | undefined;
|
|
35
|
+
/** borrowed-readonly — the deferred classification (post-exclusion names): read for size, membership and iteration. */
|
|
36
|
+
deferred: ReadonlySet<string>;
|
|
37
|
+
/** borrowed-readonly — the run's shared roster (`Prepared.tools`): READ here — the registry build, the reserved-name
|
|
38
|
+
* check, the live resolution the placeholders and the static face perform at call time. Never written by this phase. */
|
|
39
|
+
tools: AgentTool[];
|
|
40
|
+
/** borrowed-readonly — the once-per-session ledger's failed-server projection (current failures minus the pairs this
|
|
41
|
+
* session already announced). */
|
|
42
|
+
onceLedger: {
|
|
43
|
+
mcpFailuresToAnnounce(statuses: ReadonlyArray<McpServerStatus>): Array<{
|
|
44
|
+
name: string;
|
|
45
|
+
error?: string;
|
|
46
|
+
}>;
|
|
47
|
+
};
|
|
48
|
+
/** borrowed-readonly — the materialized MCP handle; only `statuses` (the failed-server arm's source). */
|
|
49
|
+
mcp: Pick<MaterializedMcp, "statuses">;
|
|
50
|
+
/** borrowed-mutable — the assembled-prompt manifest (`Prepared.promptManifest`). Writer here: ONE assignment of
|
|
51
|
+
* `toolDisclosure` (deferred names only). */
|
|
52
|
+
promptManifest: Prepared["promptManifest"];
|
|
53
|
+
/** borrowed-mutable — the offload preview's reachability accessor seat. Writer here: `current` ← the callable-names
|
|
54
|
+
* accessor (deferred names only); the offload wrappers read it at each offload. */
|
|
55
|
+
offloadReachableToolsRef: {
|
|
56
|
+
current?: () => ReadonlySet<string>;
|
|
57
|
+
};
|
|
58
|
+
/** borrowed-readonly — the content-origin wrap seat; both rebuild arms CALL `current` at run time, never write it. */
|
|
59
|
+
contentOriginWrapRef: {
|
|
60
|
+
current?: () => void;
|
|
61
|
+
};
|
|
62
|
+
/** borrowed-mutable — the RefreshMcpTools rebuild seam. Writer here: `current` ← the deferred arm's rematerialize or the
|
|
63
|
+
* default arm's bare setTools (exactly one of the two, decided by `deferred.size`). */
|
|
64
|
+
rebuildHarnessToolsRef: {
|
|
65
|
+
current?: () => Promise<void>;
|
|
66
|
+
};
|
|
67
|
+
/** borrowed-readonly — the harness seat; the rebuild arms and the direct-call lane read `current` at run time. */
|
|
68
|
+
harnessRef: {
|
|
69
|
+
current?: AgentHarness;
|
|
70
|
+
};
|
|
71
|
+
}
|
|
72
|
+
export interface PrepareToolDisclosureMountResult {
|
|
73
|
+
/** owned — the activation set (`Prepared.activeTools`): seeded here; ToolSearch and the direct lane add at run time. */
|
|
74
|
+
activeTools: Set<string>;
|
|
75
|
+
/** borrowed-mutable — the cache-fingerprint seat. Writer: the driver, once, when the fingerprint is built; the rebuild
|
|
76
|
+
* arms refresh its `tools` at run time. */
|
|
77
|
+
fpRef: {
|
|
78
|
+
current?: {
|
|
79
|
+
systemPrompt: string;
|
|
80
|
+
tools: ToolFingerprintInput[];
|
|
81
|
+
};
|
|
82
|
+
};
|
|
83
|
+
/** borrowed-mutable — the turn-snapshot identity seat. Writer: the driver's turn wiring, once; the rebuild arms call
|
|
84
|
+
* `refreshTools` on it at run time. */
|
|
85
|
+
turnSnapshotRef: {
|
|
86
|
+
current?: import("../../prompt-assembly/turn-snapshot.js").TurnPromptSnapshot;
|
|
87
|
+
};
|
|
88
|
+
/** owned — the list the harness is built from: the roster with placeholders in the deferred slots plus ToolSearch (or the
|
|
89
|
+
* roster itself when nothing is deferred). */
|
|
90
|
+
harnessTools: AgentTool[];
|
|
91
|
+
/** owned — the boundary delta ref (`Prepared.toolsDeltaRef`), minted when anything is deferred OR a server failed. */
|
|
92
|
+
toolsDeltaRef: Prepared["toolsDeltaRef"];
|
|
93
|
+
/** owned — the effective strategy (`Prepared.toolMaterializeStatic`). */
|
|
94
|
+
toolMaterializeStatic: boolean;
|
|
95
|
+
/** owned — the direct-call lane's presence (`Prepared.deferDirectCall`). */
|
|
96
|
+
deferDirectCall: boolean;
|
|
97
|
+
/** owned — the per-tool static exemption seat (`Prepared.staticFaceFor` reads its `current`). */
|
|
98
|
+
staticFaceForRef: {
|
|
99
|
+
current?: (name: string) => boolean;
|
|
100
|
+
};
|
|
101
|
+
/** borrowed-mutable — the listing-ride seam: the ToolSearch tool and the direct lane call `current` at run time. Writer:
|
|
102
|
+
* the listings phase, once, after the roster face is classified. */
|
|
103
|
+
listingRideRef: {
|
|
104
|
+
current?: (newly: readonly string[]) => string | undefined;
|
|
105
|
+
};
|
|
106
|
+
}
|
|
107
|
+
/** Test seam (mirrors `__resetToolModelGateAnnouncements`): never called by production code.
|
|
108
|
+
* Re-arms BOTH arms (a WeakMap has no clear — it is re-minted). */
|
|
109
|
+
export declare function __resetMaterializeEnvAnnouncements(): void;
|
|
110
|
+
/** The M14 phase body — prepareTask's tool-disclosure-mount stretch, verbatim (see the module header). */
|
|
111
|
+
export declare function prepareToolDisclosureMount(input: PrepareToolDisclosureMountInput): Promise<PrepareToolDisclosureMountResult>;
|
|
@@ -0,0 +1,219 @@
|
|
|
1
|
+
import { readCompactionActiveTools } from "../../internal/harness.js";
|
|
2
|
+
import { toolsToFingerprintInputs } from "../cache-break-detector.js";
|
|
3
|
+
import { deliverEngineNotice } from "../types.js";
|
|
4
|
+
import { TOOL_SEARCH_NAME, buildDeferredRegistry, extractDiscoveredToolNames, createPlaceholderTool, createToolSearchTool, staticSchemaRenderable } from "./tool-disclosure.js";
|
|
5
|
+
let announcedMaterializeEnvBySink = new WeakMap();
|
|
6
|
+
const announcedMaterializeEnvConsole = new Set();
|
|
7
|
+
function materializeEnvLedger(onNotice) {
|
|
8
|
+
if (typeof onNotice !== "function")
|
|
9
|
+
return announcedMaterializeEnvConsole;
|
|
10
|
+
let lines = announcedMaterializeEnvBySink.get(onNotice);
|
|
11
|
+
if (lines === undefined) {
|
|
12
|
+
lines = new Set();
|
|
13
|
+
announcedMaterializeEnvBySink.set(onNotice, lines);
|
|
14
|
+
}
|
|
15
|
+
return lines;
|
|
16
|
+
}
|
|
17
|
+
export function __resetMaterializeEnvAnnouncements() {
|
|
18
|
+
announcedMaterializeEnvBySink = new WeakMap();
|
|
19
|
+
announcedMaterializeEnvConsole.clear();
|
|
20
|
+
}
|
|
21
|
+
function emitMaterializeEnvNotice(onNotice, message, detail) {
|
|
22
|
+
const ledger = materializeEnvLedger(onNotice);
|
|
23
|
+
if (ledger.has(message))
|
|
24
|
+
return;
|
|
25
|
+
ledger.add(message);
|
|
26
|
+
deliverEngineNotice(onNotice, { code: "config.materialize_env_discarded", message, detail });
|
|
27
|
+
}
|
|
28
|
+
export async function prepareToolDisclosureMount(input) {
|
|
29
|
+
const { spec, deps, session, resume, deferred, tools, onceLedger, mcp, promptManifest, offloadReachableToolsRef, contentOriginWrapRef, rebuildHarnessToolsRef, harnessRef } = input;
|
|
30
|
+
const activeTools = new Set();
|
|
31
|
+
const fpRef = {};
|
|
32
|
+
const turnSnapshotRef = {};
|
|
33
|
+
let harnessTools = tools;
|
|
34
|
+
const failedMcpServers = onceLedger.mcpFailuresToAnnounce(mcp.statuses);
|
|
35
|
+
let toolsDeltaRef;
|
|
36
|
+
let toolMaterializeStatic = false;
|
|
37
|
+
let deferDirectCall = false;
|
|
38
|
+
const staticFaceForRef = {};
|
|
39
|
+
if (deferred.size > 0 || failedMcpServers.length > 0) {
|
|
40
|
+
toolsDeltaRef = { pending: [], pendingRemoved: [], pendingReadded: [], pendingFailed: failedMcpServers };
|
|
41
|
+
}
|
|
42
|
+
const listingRideRef = {};
|
|
43
|
+
{
|
|
44
|
+
const raw = process.env.SEMA_TOOL_MATERIALIZE_STRATEGY;
|
|
45
|
+
if (raw !== undefined && raw !== "swap" && raw !== "static" && deferred.size === 0) {
|
|
46
|
+
const line = `SEMA_TOOL_MATERIALIZE_STRATEGY=${JSON.stringify(raw)} is not "swap" or "static" — inert on this task (no deferred tools), but a deferring task WITHOUT an explicit spec strategy will refuse to prepare under it (an explicit legal spec outranks and discards it, loudly). Fix or unset the flag.`;
|
|
47
|
+
emitMaterializeEnvNotice(deps.onNotice, line, { raw });
|
|
48
|
+
}
|
|
49
|
+
}
|
|
50
|
+
if (deferred.size > 0) {
|
|
51
|
+
if (deferred.has(TOOL_SEARCH_NAME) || tools.some((t) => t.name === TOOL_SEARCH_NAME)) {
|
|
52
|
+
const e = new Error(`Tool name "${TOOL_SEARCH_NAME}" is reserved when deferred tools are present.`);
|
|
53
|
+
e.code = "config.reserved_tool_name";
|
|
54
|
+
throw e;
|
|
55
|
+
}
|
|
56
|
+
const registry = buildDeferredRegistry(deferred, tools);
|
|
57
|
+
const rawEnvStrategy = process.env.SEMA_TOOL_MATERIALIZE_STRATEGY;
|
|
58
|
+
const envStrategyInvalid = rawEnvStrategy !== undefined && rawEnvStrategy !== "swap" && rawEnvStrategy !== "static";
|
|
59
|
+
if (envStrategyInvalid && spec.toolMaterializeStrategy === undefined) {
|
|
60
|
+
const e = new Error(`SEMA_TOOL_MATERIALIZE_STRATEGY must be "swap" or "static" (got ${JSON.stringify(rawEnvStrategy)}).`);
|
|
61
|
+
e.code = "config.tool_materialize_invalid";
|
|
62
|
+
throw e;
|
|
63
|
+
}
|
|
64
|
+
if (envStrategyInvalid) {
|
|
65
|
+
const line = `SEMA_TOOL_MATERIALIZE_STRATEGY=${JSON.stringify(rawEnvStrategy)} was ignored — not "swap" or "static", and the task spec pins toolMaterializeStrategy=${JSON.stringify(spec.toolMaterializeStrategy)} which outranks it. Fix or unset the env flag.`;
|
|
66
|
+
emitMaterializeEnvNotice(deps.onNotice, line, { raw: rawEnvStrategy, specStrategy: spec.toolMaterializeStrategy });
|
|
67
|
+
}
|
|
68
|
+
const envStrategy = envStrategyInvalid ? undefined : rawEnvStrategy;
|
|
69
|
+
const requestedStrategy = spec.toolMaterializeStrategy ?? envStrategy ?? "swap";
|
|
70
|
+
const laneDegrade = requestedStrategy === "static" && spec.deferSelfResolve === false;
|
|
71
|
+
const materializeStatic = requestedStrategy === "static" && !laneDegrade;
|
|
72
|
+
toolMaterializeStatic = materializeStatic;
|
|
73
|
+
deferDirectCall = spec.deferSelfResolve !== false;
|
|
74
|
+
promptManifest.toolDisclosure = {
|
|
75
|
+
deferredTools: deferred.size,
|
|
76
|
+
strategy: materializeStatic ? "static" : "swap",
|
|
77
|
+
source: laneDegrade ? "degraded_no_direct_lane" : spec.toolMaterializeStrategy !== undefined ? "spec" : envStrategy !== undefined ? "env" : "default",
|
|
78
|
+
};
|
|
79
|
+
const everExempt = new Set();
|
|
80
|
+
const staticFaceFor = (name) => {
|
|
81
|
+
if (!materializeStatic)
|
|
82
|
+
return false;
|
|
83
|
+
if (everExempt.has(name))
|
|
84
|
+
return false;
|
|
85
|
+
if (staticSchemaRenderable(tools.find((t) => t.name === name)?.parameters))
|
|
86
|
+
return true;
|
|
87
|
+
everExempt.add(name);
|
|
88
|
+
return false;
|
|
89
|
+
};
|
|
90
|
+
staticFaceForRef.current = staticFaceFor;
|
|
91
|
+
let activationChain = Promise.resolve();
|
|
92
|
+
const serializeActivation = (section) => {
|
|
93
|
+
const p = activationChain.then(section);
|
|
94
|
+
activationChain = p.then(() => undefined, () => undefined);
|
|
95
|
+
return p;
|
|
96
|
+
};
|
|
97
|
+
const directCallFor = (name) => {
|
|
98
|
+
if (spec.deferSelfResolve === false)
|
|
99
|
+
return undefined;
|
|
100
|
+
const executionMode = tools.find((t) => t.name === name)?.executionMode;
|
|
101
|
+
return {
|
|
102
|
+
resolveReal: () => {
|
|
103
|
+
const real = tools.find((t) => t.name === name);
|
|
104
|
+
if (real === undefined)
|
|
105
|
+
return undefined;
|
|
106
|
+
return {
|
|
107
|
+
parameters: real.parameters,
|
|
108
|
+
invoke: (toolCallId, params, signal, onUpdate) => real.execute(toolCallId, params, signal, onUpdate),
|
|
109
|
+
};
|
|
110
|
+
},
|
|
111
|
+
...(executionMode !== undefined ? { executionMode } : {}),
|
|
112
|
+
staticFace: () => staticFaceFor(name),
|
|
113
|
+
activate: async () => serializeActivation(async () => {
|
|
114
|
+
if (activeTools.has(name))
|
|
115
|
+
return undefined;
|
|
116
|
+
activeTools.add(name);
|
|
117
|
+
try {
|
|
118
|
+
await rematerialize(activeTools);
|
|
119
|
+
}
|
|
120
|
+
catch (e) {
|
|
121
|
+
activeTools.delete(name);
|
|
122
|
+
throw e;
|
|
123
|
+
}
|
|
124
|
+
return listingRideRef.current?.([name]);
|
|
125
|
+
}),
|
|
126
|
+
};
|
|
127
|
+
};
|
|
128
|
+
const placeholders = new Map([...registry.values()].map((i) => [i.name, createPlaceholderTool(i, directCallFor(i.name))]));
|
|
129
|
+
const { messages } = await session.buildContext();
|
|
130
|
+
for (const n of extractDiscoveredToolNames(messages, registry)) {
|
|
131
|
+
if (deferred.has(n))
|
|
132
|
+
activeTools.add(n);
|
|
133
|
+
}
|
|
134
|
+
for (const entry of await session.getBranch()) {
|
|
135
|
+
if (entry.type !== "compaction" || entry.fromHook === true)
|
|
136
|
+
continue;
|
|
137
|
+
for (const n of readCompactionActiveTools(entry.details)) {
|
|
138
|
+
if (deferred.has(n))
|
|
139
|
+
activeTools.add(n);
|
|
140
|
+
}
|
|
141
|
+
}
|
|
142
|
+
if (resume) {
|
|
143
|
+
for (const n of resume.seed.activeTools)
|
|
144
|
+
if (deferred.has(n))
|
|
145
|
+
activeTools.add(n);
|
|
146
|
+
}
|
|
147
|
+
const callableToolNames = () => {
|
|
148
|
+
const s = new Set(tools.map((t) => t.name));
|
|
149
|
+
for (const n of deferred)
|
|
150
|
+
if (!activeTools.has(n))
|
|
151
|
+
s.delete(n);
|
|
152
|
+
s.add(TOOL_SEARCH_NAME);
|
|
153
|
+
return s;
|
|
154
|
+
};
|
|
155
|
+
offloadReachableToolsRef.current = callableToolNames;
|
|
156
|
+
let toolSearch;
|
|
157
|
+
const buildToolList = (active) => {
|
|
158
|
+
const list = tools.map((t) => (deferred.has(t.name) && (staticFaceFor(t.name) || !active.has(t.name)) ? placeholders.get(t.name) : t));
|
|
159
|
+
list.push(toolSearch);
|
|
160
|
+
return list;
|
|
161
|
+
};
|
|
162
|
+
const announcedTools = new Set(activeTools);
|
|
163
|
+
const withdrawnTools = new Set();
|
|
164
|
+
const deltaRef = toolsDeltaRef;
|
|
165
|
+
const rematerialize = async (active) => {
|
|
166
|
+
contentOriginWrapRef.current?.();
|
|
167
|
+
const list = buildToolList(active);
|
|
168
|
+
await harnessRef.current.setTools(list, list.map((t) => t.name));
|
|
169
|
+
if (fpRef.current)
|
|
170
|
+
fpRef.current.tools = toolsToFingerprintInputs(list);
|
|
171
|
+
turnSnapshotRef.current?.refreshTools(toolsToFingerprintInputs(list));
|
|
172
|
+
const live = new Set(list.map((t) => t.name));
|
|
173
|
+
for (const n of [...announcedTools]) {
|
|
174
|
+
if (!live.has(n)) {
|
|
175
|
+
announcedTools.delete(n);
|
|
176
|
+
withdrawnTools.add(n);
|
|
177
|
+
deltaRef.pendingRemoved.push(n);
|
|
178
|
+
}
|
|
179
|
+
}
|
|
180
|
+
for (const n of active) {
|
|
181
|
+
if (!live.has(n))
|
|
182
|
+
continue;
|
|
183
|
+
if (!announcedTools.has(n)) {
|
|
184
|
+
announcedTools.add(n);
|
|
185
|
+
if (withdrawnTools.delete(n))
|
|
186
|
+
deltaRef.pendingReadded.push(n);
|
|
187
|
+
else
|
|
188
|
+
deltaRef.pending.push(n);
|
|
189
|
+
}
|
|
190
|
+
}
|
|
191
|
+
};
|
|
192
|
+
rebuildHarnessToolsRef.current = () => rematerialize(activeTools);
|
|
193
|
+
toolSearch = createToolSearchTool({
|
|
194
|
+
registry,
|
|
195
|
+
active: activeTools,
|
|
196
|
+
rematerialize,
|
|
197
|
+
listingRide: (newly) => listingRideRef.current?.(newly),
|
|
198
|
+
mountedNames: callableToolNames,
|
|
199
|
+
directCallEnabled: spec.deferSelfResolve !== false,
|
|
200
|
+
isMounted: (name) => tools.some((t) => t.name === name),
|
|
201
|
+
...(materializeStatic
|
|
202
|
+
? { staticSchemaFor: (name) => (staticFaceFor(name) ? tools.find((t) => t.name === name)?.parameters : undefined) }
|
|
203
|
+
: {}),
|
|
204
|
+
serializeActivation,
|
|
205
|
+
});
|
|
206
|
+
harnessTools = buildToolList(activeTools);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
rebuildHarnessToolsRef.current = async () => {
|
|
210
|
+
contentOriginWrapRef.current?.();
|
|
211
|
+
const list = [...tools];
|
|
212
|
+
await harnessRef.current.setTools(list, list.map((t) => t.name));
|
|
213
|
+
if (fpRef.current)
|
|
214
|
+
fpRef.current.tools = toolsToFingerprintInputs(list);
|
|
215
|
+
turnSnapshotRef.current?.refreshTools(toolsToFingerprintInputs(list));
|
|
216
|
+
};
|
|
217
|
+
}
|
|
218
|
+
return { activeTools, fpRef, turnSnapshotRef, harnessTools, toolsDeltaRef, toolMaterializeStatic, deferDirectCall, staticFaceForRef, listingRideRef };
|
|
219
|
+
}
|
|
@@ -0,0 +1,154 @@
|
|
|
1
|
+
import type { AgentHarness, AgentTool, ExecutionEnv, ThinkingLevel } from "../../internal/harness.js";
|
|
2
|
+
import type { Model } from "../../internal/llm.js";
|
|
3
|
+
import { type AssembledPrompt, type AssembleInputs } from "../../prompt-assembly/assemble.js";
|
|
4
|
+
import { type PromptEpochArtifact } from "../../prompt-assembly/artifact.js";
|
|
5
|
+
import type { EpochDeclaredSections } from "../../prompt-assembly/epoch.js";
|
|
6
|
+
import { type TurnPromptSnapshot } from "../../prompt-assembly/turn-snapshot.js";
|
|
7
|
+
import type { PromptTextDeclaration } from "../../prompts/default.js";
|
|
8
|
+
import { CacheBreakDetector, type ToolFingerprintInput } from "../cache-break-detector.js";
|
|
9
|
+
import { type ToolPolicy } from "../tool-policy.js";
|
|
10
|
+
import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
11
|
+
import type { CwdRef } from "../../tools/fs/fs-shared.js";
|
|
12
|
+
import { type ReadFace } from "../../tools/fs/index.js";
|
|
13
|
+
import type { ReadDenyMatcher } from "../../tools/fs/read-deny.js";
|
|
14
|
+
import { type ReadFileState } from "../../tools/fs/safety.js";
|
|
15
|
+
import type { Prepared } from "./contracts.js";
|
|
16
|
+
export interface PrepareTurnWiringInput {
|
|
17
|
+
/** borrowed-readonly — the deployment seats: `cacheBreakDetection` (the detector knob), `onError` (the attachment-skip
|
|
18
|
+
* degraded line), `promptSource` (the center candidate's state and current artifact). Receiver preserved. */
|
|
19
|
+
deps: Pick<RunnerDeps, "cacheBreakDetection" | "onError" | "promptSource">;
|
|
20
|
+
/** borrowed-mutable — the LIVE system prompt (the prompt-assembly phase's accessor cell). Read: the fingerprint, the
|
|
21
|
+
* snapshot's stable text, the overhead term. Writer here: the center candidate's `apply` (the boundary swap). */
|
|
22
|
+
systemPromptSeat: {
|
|
23
|
+
current: string;
|
|
24
|
+
};
|
|
25
|
+
/** borrowed-readonly — the FINAL wire tool list (the fingerprint's and the snapshot's tool wire, the overhead sum). */
|
|
26
|
+
harnessTools: ReadonlyArray<AgentTool>;
|
|
27
|
+
/** borrowed-mutable — the fingerprint ref the tool-disclosure phase minted. Writers: THIS phase seeds `current`; the
|
|
28
|
+
* candidate's `apply` rewrites `current.systemPrompt`; the disclosure phase's rebuild seam refreshes `current.tools`. */
|
|
29
|
+
fpRef: {
|
|
30
|
+
current?: {
|
|
31
|
+
systemPrompt: string;
|
|
32
|
+
tools: ToolFingerprintInput[];
|
|
33
|
+
};
|
|
34
|
+
};
|
|
35
|
+
/** borrowed-readonly — the task model: `provider` / `id` / `maxTokens` / `api` (the snapshot's identity elements). */
|
|
36
|
+
model: Pick<Model, "provider" | "id" | "maxTokens" | "api">;
|
|
37
|
+
/** borrowed-readonly — the resolved epoch's artifact digest (the snapshot's identity element). */
|
|
38
|
+
epochArtifactDigestForSnapshot: string;
|
|
39
|
+
/** borrowed-readonly — the resolved prompt profile (a snapshot element). */
|
|
40
|
+
promptProfile: "simple" | "classic";
|
|
41
|
+
/** borrowed-readonly — the fable mitigations switch (a snapshot element). */
|
|
42
|
+
fableMitigations: boolean;
|
|
43
|
+
/** borrowed-readonly — the assembled prompt's physical block face, or undefined (the snapshot's layout groups). */
|
|
44
|
+
systemBlocks: AssembledPrompt["systemBlocks"];
|
|
45
|
+
/** borrowed-readonly — the resolved thinking level, or undefined (a snapshot element). */
|
|
46
|
+
thinking: ThinkingLevel | undefined;
|
|
47
|
+
/** borrowed-readonly — the REBOUND spec; only `outputSchema` (presence) and `taskId` (the snapshot's identity). */
|
|
48
|
+
spec: Pick<TaskSpec, "outputSchema" | "taskId">;
|
|
49
|
+
/** borrowed-readonly — the acquired session id (the snapshot; the attachment-skip attribution). */
|
|
50
|
+
sessionId: string;
|
|
51
|
+
/** borrowed-mutable — the snapshot ref the tool-disclosure phase minted. Writers: THIS phase seeds `current`; the candidate's
|
|
52
|
+
* `apply` calls `refreshStableSystem`; the disclosure phase's rebuild seam calls `refreshTools`; the run loop assigns
|
|
53
|
+
* `current.onChange` (the snapshot-changed trace emitter) once Prepared is built. */
|
|
54
|
+
turnSnapshotRef: {
|
|
55
|
+
current?: TurnPromptSnapshot;
|
|
56
|
+
};
|
|
57
|
+
/** borrowed-mutable — the composition manifest (`Prepared.promptManifest`). Writer here: the identity/lowering BACKFILL
|
|
58
|
+
* (the snapshot needs the final wire list, which exists only now). */
|
|
59
|
+
promptManifest: Prepared["promptManifest"];
|
|
60
|
+
/** borrowed-readonly — the model's structural coefficient (the context lane's), the overhead term's coordinate. */
|
|
61
|
+
charsPerToken: number;
|
|
62
|
+
/** borrowed-readonly — whether an execution env is wired (every reader exists only then). */
|
|
63
|
+
handsEnabled: boolean;
|
|
64
|
+
/** borrowed-readonly — the run's resolved env (the readers read and stat through it). */
|
|
65
|
+
executionEnv: ExecutionEnv;
|
|
66
|
+
/** borrowed-readonly — the canonical attachment root, or undefined (the readers' containment fence). */
|
|
67
|
+
attachmentRootCanonical: string | undefined;
|
|
68
|
+
/** borrowed-readonly — the canonical extra write roots (the fence's root set). */
|
|
69
|
+
additionalRootsCanonical: ReadonlyArray<string>;
|
|
70
|
+
/** borrowed-readonly — the canonical extra read roots (the fence's root set). */
|
|
71
|
+
additionalReadRootsCanonical: ReadonlyArray<string>;
|
|
72
|
+
/** borrowed-readonly — the compiled read-deny judge, or undefined (the reader's withheld arm). */
|
|
73
|
+
readDenyMatcher: ReadDenyMatcher | undefined;
|
|
74
|
+
/** borrowed-readonly — the resolved read face, or undefined (the fence's ninth argument). */
|
|
75
|
+
resolvedReadFace: ReadFace | undefined;
|
|
76
|
+
/** borrowed-readonly — the tracked-cwd seat, read per call by the kept-tail normalizer (never written here). */
|
|
77
|
+
handsCwdRef: CwdRef | undefined;
|
|
78
|
+
/** borrowed-mutable — the live read-file state, or undefined. Writers here, at RUN time: `detectExternalChanges` evicts a
|
|
79
|
+
* not-found entry; `onCompactionApplied` applies a landed compaction to it. The hands phase mints it. */
|
|
80
|
+
readFileStateForCheckpoint: ReadFileState | undefined;
|
|
81
|
+
/** borrowed-readonly — the deny-narrowing fold, or undefined (the changed-files deny door's authority). */
|
|
82
|
+
denyNarrowingPolicy: ToolPolicy | undefined;
|
|
83
|
+
/** borrowed-readonly — the run's abort controller; only `signal` (the deny door's and the stat's signal). */
|
|
84
|
+
abortController: Pick<AbortController, "signal">;
|
|
85
|
+
/** borrowed-readonly — the per-task identity (the background listing's owner). */
|
|
86
|
+
hostTaskId: string;
|
|
87
|
+
/** borrowed-readonly — the registry scope the background listing reads under. */
|
|
88
|
+
taskScope: string;
|
|
89
|
+
/** borrowed-readonly — the prompt-assembly phase's re-invokable assemble-inputs builder (the candidate re-assembles). */
|
|
90
|
+
buildAssembleInputs: (centerDecls?: PromptTextDeclaration[]) => AssembleInputs;
|
|
91
|
+
/** borrowed-mutable — the LIVE center adoption (the prompt-assembly phase's accessor cell). Read: the candidate's arming and
|
|
92
|
+
* same-artifact test. Writer here: the candidate's `apply` (the boundary swap / the explicit-disable rollback). */
|
|
93
|
+
centerAdoptionRef: {
|
|
94
|
+
current: {
|
|
95
|
+
artifact: PromptEpochArtifact;
|
|
96
|
+
sourceRevision?: string;
|
|
97
|
+
} | undefined;
|
|
98
|
+
};
|
|
99
|
+
/** borrowed-readonly — the harness ref (the candidate's `apply` calls `setSystemPrompt` on the current harness). */
|
|
100
|
+
harnessRef: {
|
|
101
|
+
current?: AgentHarness;
|
|
102
|
+
};
|
|
103
|
+
/** borrowed-readonly — the provider-declared sections in the epoch shape (the candidate's declared-sections TYPE). */
|
|
104
|
+
epochDeclaredSections: EpochDeclaredSections;
|
|
105
|
+
/** borrowed-readonly — the ONE carrier-face expression both delegation mounts consume (the observation seat). */
|
|
106
|
+
carrierReadFace: () => ReadFace | undefined;
|
|
107
|
+
/** borrowed-readonly — the normalized deny additions (the observation seat copies them). */
|
|
108
|
+
readDenyAdditionsNormalized: ReadonlyArray<{
|
|
109
|
+
pattern: string;
|
|
110
|
+
caseSensitive: boolean;
|
|
111
|
+
}>;
|
|
112
|
+
/** borrowed-mutable — the holder of the built Prepared. Writer: the DRIVER fills `current` right after `buildPrepared()`;
|
|
113
|
+
* the candidate's `apply` then writes `current.epochDeclaredSections` and `current.promptOverheadTokens` at a boundary. */
|
|
114
|
+
preparedHolder: {
|
|
115
|
+
current?: Prepared;
|
|
116
|
+
};
|
|
117
|
+
}
|
|
118
|
+
export interface PrepareTurnWiringResult {
|
|
119
|
+
/** owned — the two-phase cache-break detector (`Prepared.cacheBreakDetector`), or undefined when the knob is off. */
|
|
120
|
+
cacheBreakDetector: CacheBreakDetector | undefined;
|
|
121
|
+
/** borrowed-mutable — the prefix fingerprint (`Prepared.cacheFingerprint`; the same object `fpRef.current` holds), or
|
|
122
|
+
* undefined. Writers after this phase: the candidate's `apply` (systemPrompt), the disclosure rebuild seam (tools). */
|
|
123
|
+
cacheFingerprint: {
|
|
124
|
+
systemPrompt: string;
|
|
125
|
+
tools: ToolFingerprintInput[];
|
|
126
|
+
} | undefined;
|
|
127
|
+
/** owned — the fixed prompt-overhead term in the compaction trigger's coordinate (`Prepared.promptOverheadTokens`). */
|
|
128
|
+
promptOverheadTokens: number;
|
|
129
|
+
/** owned — the fenced working-file reader, or undefined without hands (`Prepared.readTaskFile`). */
|
|
130
|
+
readTaskFile: Prepared["readTaskFile"];
|
|
131
|
+
/** owned — the kept-tail path normalizer, or undefined without hands. */
|
|
132
|
+
normalizeAttachmentPath: Prepared["normalizeAttachmentPath"];
|
|
133
|
+
/** owned — the Read tool's dedup-stub predicate, or undefined without hands. */
|
|
134
|
+
isDedupStubResult: Prepared["isDedupStubResult"];
|
|
135
|
+
/** owned — the most-recently-read files projection, or undefined without read state. */
|
|
136
|
+
recentlyReadFiles: Prepared["recentlyReadFiles"];
|
|
137
|
+
/** owned — the landed-compaction read-state hook, or undefined without read state. */
|
|
138
|
+
onCompactionApplied: Prepared["onCompactionApplied"];
|
|
139
|
+
/** owned — the boundary-time changed-files scan, or undefined without read state. */
|
|
140
|
+
detectExternalChanges: Prepared["detectExternalChanges"];
|
|
141
|
+
/** owned — the post-compact background-task listing (`Prepared.listBackgroundTasks`). */
|
|
142
|
+
listBackgroundTasks: Prepared["listBackgroundTasks"];
|
|
143
|
+
/** owned — the compaction-boundary center adoption candidate, or undefined (no source, or no adoption). */
|
|
144
|
+
centerCompactionCandidate: Prepared["centerCompactionCandidate"];
|
|
145
|
+
/** owned — the effective read face observed for the result seats (`Prepared.effectiveReadFace`), or undefined. */
|
|
146
|
+
effectiveReadFaceObserved: ReadFace | undefined;
|
|
147
|
+
/** owned — the effective read-deny patterns observed (fresh copies), or undefined when none. */
|
|
148
|
+
effectiveReadDenyObserved: Array<{
|
|
149
|
+
pattern: string;
|
|
150
|
+
caseSensitive: boolean;
|
|
151
|
+
}> | undefined;
|
|
152
|
+
}
|
|
153
|
+
/** The M22 phase body — prepareTask's turn-wiring stretch, verbatim (see the module header). */
|
|
154
|
+
export declare function prepareTurnWiring(input: PrepareTurnWiringInput): PrepareTurnWiringResult;
|