@sema-agent/core 7.52.0 → 7.53.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/CHANGELOG.md +194 -0
- package/README.md +3 -1
- package/dist/agents/cross-session-envelope.d.ts +8 -0
- package/dist/agents/cross-session-envelope.js +6 -0
- package/dist/agents/cross-session-judge.d.ts +21 -1
- package/dist/agents/cross-session-judge.js +8 -0
- package/dist/agents/cross-session-ref.d.ts +5 -0
- package/dist/agents/cross-session-ref.js +1 -0
- package/dist/agents/org-delivery-gate.d.ts +122 -0
- package/dist/agents/org-delivery-gate.js +69 -0
- package/dist/agents/peer-held-queue.d.ts +9 -4
- package/dist/agents/peer-held-queue.js +6 -5
- package/dist/agents/peer-session-drain.d.ts +35 -5
- package/dist/agents/peer-session-drain.js +271 -180
- package/dist/agents/read-inbox-tool.d.ts +7 -0
- package/dist/agents/read-inbox-tool.js +5 -1
- package/dist/agents/subagent.d.ts +3 -0
- package/dist/agents/subagent.js +99 -72
- package/dist/agents/tool-filter.d.ts +18 -0
- package/dist/agents/tool-filter.js +6 -0
- package/dist/brain/anthropic.d.ts +6 -1
- package/dist/brain/anthropic.js +4 -4
- package/dist/brain/model-presets.js +2 -1
- package/dist/brain/route-adjudicator.d.ts +6 -0
- package/dist/brain/routing.d.ts +24 -1
- package/dist/brain/routing.js +54 -19
- package/dist/brain/timeout.js +5 -4
- package/dist/core/a2a.d.ts +5 -2
- package/dist/core/a2a.js +30 -13
- package/dist/core/allow-entry.d.ts +2 -1
- package/dist/core/allow-entry.js +2 -2
- package/dist/core/auto-compaction.d.ts +57 -0
- package/dist/core/auto-compaction.js +28 -2
- package/dist/core/checkpoint-store.d.ts +29 -20
- package/dist/core/checkpoint-store.js +3 -3
- package/dist/core/compliance.js +3 -1
- package/dist/core/effective-path-target.d.ts +25 -6
- package/dist/core/effective-path-target.js +24 -2
- package/dist/core/engine-notice.d.ts +13 -2
- package/dist/core/gate-fold.js +3 -2
- package/dist/core/gate-lanes.js +11 -13
- package/dist/core/gate-outcome.d.ts +11 -6
- package/dist/core/governance-codes.d.ts +3 -1
- package/dist/core/governance-codes.js +3 -0
- package/dist/core/hands-band-screen.d.ts +7 -0
- package/dist/core/hands-band-screen.js +32 -0
- package/dist/core/hooks.d.ts +7 -5
- package/dist/core/hooks.js +5 -3
- package/dist/core/locked-config.d.ts +84 -32
- package/dist/core/locked-config.js +128 -42
- package/dist/core/mcp-probe.js +1 -1
- package/dist/core/mcp-server-spec.d.ts +88 -10
- package/dist/core/mcp-server-spec.js +183 -33
- package/dist/core/mcp.d.ts +21 -14
- package/dist/core/mcp.js +55 -51
- package/dist/core/memory-engine/engine.d.ts +14 -19
- package/dist/core/memory-engine/engine.js +7 -5
- package/dist/core/mode-policy.d.ts +3 -18
- package/dist/core/mode-policy.js +2 -16
- package/dist/core/mods/kernel/dispatch.js +13 -15
- package/dist/core/mods/kernel/events.d.ts +9 -6
- package/dist/core/mods/kernel/events.js +2 -2
- package/dist/core/mods/kernel/receive.d.ts +39 -10
- package/dist/core/mods/kernel/receive.js +119 -54
- package/dist/core/mods/kernel/site-rules.d.ts +80 -15
- package/dist/core/mods/kernel/site-rules.js +232 -40
- package/dist/core/mods/stations.d.ts +0 -6
- package/dist/core/mods/stations.js +0 -7
- package/dist/core/mounted-mcp.d.ts +57 -0
- package/dist/core/mounted-mcp.js +71 -2
- package/dist/core/own-property-receipt.d.ts +13 -0
- package/dist/core/own-property-receipt.js +3 -1
- package/dist/core/parent-spec-seat.d.ts +2 -2
- package/dist/core/permission-rule-model.d.ts +58 -9
- package/dist/core/permission-rule-model.js +81 -7
- package/dist/core/permission-rule-org.d.ts +163 -33
- package/dist/core/permission-rule-org.js +205 -71
- package/dist/core/permission-rules.d.ts +7 -1
- package/dist/core/permission-rules.js +37 -8
- package/dist/core/retention.js +7 -2
- package/dist/core/retired-keys.d.ts +8 -2
- package/dist/core/retired-keys.js +12 -1
- package/dist/core/roles.js +60 -10
- package/dist/core/rule-lane-reads.js +1 -1
- package/dist/core/runner/contracts.d.ts +1 -0
- package/dist/core/runner/gate-exit.js +4 -3
- package/dist/core/runner/mcp-redial.d.ts +52 -10
- package/dist/core/runner/mcp-redial.js +38 -9
- package/dist/core/runner/permission-rule-lanes.d.ts +5 -2
- package/dist/core/runner/permission-rule-lanes.js +22 -10
- package/dist/core/runner/person-path-rows.d.ts +3 -1
- package/dist/core/runner/person-path-rows.js +2 -2
- package/dist/core/runner/prepare-config-doors.d.ts +48 -2
- package/dist/core/runner/prepare-config-doors.js +161 -145
- package/dist/core/runner/prepare-defer-classify.js +4 -7
- package/dist/core/runner/prepare-delegation-surface.d.ts +2 -2
- package/dist/core/runner/prepare-delegation-surface.js +7 -5
- package/dist/core/runner/prepare-hands-readface.d.ts +1 -1
- package/dist/core/runner/prepare-hands-readface.js +2 -1
- package/dist/core/runner/prepare-inherited-gate.js +2 -2
- package/dist/core/runner/prepare-listings.d.ts +1 -1
- package/dist/core/runner/prepare-listings.js +4 -2
- package/dist/core/runner/prepare-memory-engine-session.d.ts +0 -6
- package/dist/core/runner/prepare-memory-engine-session.js +19 -6
- package/dist/core/runner/prepare-memory.d.ts +3 -2
- package/dist/core/runner/prepare-memory.js +6 -2
- package/dist/core/runner/prepare-offload-wrappers.d.ts +4 -4
- package/dist/core/runner/prepare-offload-wrappers.js +2 -1
- package/dist/core/runner/prepare-policy-chain.d.ts +1 -1
- package/dist/core/runner/prepare-policy-chain.js +12 -12
- package/dist/core/runner/prepare-project-context.d.ts +1 -1
- package/dist/core/runner/prepare-project-context.js +6 -4
- package/dist/core/runner/prepare-prompt-assembly.d.ts +1 -1
- package/dist/core/runner/prepare-prompt-assembly.js +20 -16
- package/dist/core/runner/prepare-prompt-inputs.d.ts +12 -6
- package/dist/core/runner/prepare-prompt-inputs.js +6 -3
- package/dist/core/runner/prepare-protocol-tools.d.ts +7 -5
- package/dist/core/runner/prepare-protocol-tools.js +19 -12
- package/dist/core/runner/prepare-question-face.d.ts +4 -2
- package/dist/core/runner/prepare-question-face.js +4 -3
- package/dist/core/runner/prepare-task.js +10 -10
- package/dist/core/runner/prepare-wiring-manifest.d.ts +8 -3
- package/dist/core/runner/prepare-wiring-manifest.js +8 -5
- package/dist/core/runner/resume-admission.d.ts +4 -1
- package/dist/core/runner/resume-admission.js +7 -5
- package/dist/core/runner/resume-internals-and-config.d.ts +3 -3
- package/dist/core/runner/resume-internals-and-config.js +3 -8
- package/dist/core/runner/retired-runner-deps.d.ts +5 -6
- package/dist/core/runner/retired-runner-deps.js +1 -4
- package/dist/core/runner/run-leg.js +42 -12
- package/dist/core/runner/run-recovery-lanes.js +5 -3
- package/dist/core/runner/run-terminal-adoption.js +6 -5
- package/dist/core/runner/run-turn-boundary.js +9 -3
- package/dist/core/runner/runtask.js +1 -1
- package/dist/core/runner/skills-seat.d.ts +15 -0
- package/dist/core/runner/skills-seat.js +57 -0
- package/dist/core/runner/sub-agent-deny-lists.d.ts +13 -11
- package/dist/core/runner/sub-agent-deny-lists.js +7 -5
- package/dist/core/runner/synthetic-tools.d.ts +5 -2
- package/dist/core/runner/synthetic-tools.js +2 -12
- package/dist/core/runner-deps.d.ts +29 -14
- package/dist/core/session-policy-store.d.ts +19 -0
- package/dist/core/session-policy-store.js +22 -2
- package/dist/core/store-contracts/mailbox-store-contract.js +13 -0
- package/dist/core/task-event.d.ts +38 -2
- package/dist/core/task-notification.js +2 -2
- package/dist/core/task-spec.d.ts +1 -1
- package/dist/core/tool-policy.d.ts +3 -0
- package/dist/core/tool-policy.js +10 -4
- package/dist/core/types.d.ts +2 -2
- package/dist/core/types.js +1 -1
- package/dist/core/untrusted-text.d.ts +16 -0
- package/dist/core/untrusted-text.js +7 -2
- package/dist/core/user-attachment.d.ts +13 -2
- package/dist/core/user-attachment.js +47 -41
- package/dist/core/wiring-manifest.d.ts +4 -2
- package/dist/engine/harness/agent-harness.js +2 -1
- package/dist/engine/harness/types.d.ts +3 -0
- package/dist/engine/loop/agent-loop.d.ts +12 -1
- package/dist/engine/loop/agent-loop.js +17 -5
- package/dist/engine/loop/types.d.ts +7 -1
- package/dist/index.d.ts +15 -9
- package/dist/index.js +12 -6
- package/dist/internal/harness.d.ts +1 -0
- package/dist/internal/harness.js +1 -0
- package/dist/orchestration/goal.d.ts +24 -1
- package/dist/orchestration/goal.js +3 -2
- package/dist/prompt-assembly/artifact-store.d.ts +44 -9
- package/dist/prompt-assembly/artifact-store.js +38 -12
- package/dist/prompt-assembly/artifact.d.ts +12 -11
- package/dist/prompt-assembly/artifact.js +52 -21
- package/dist/prompt-assembly/assemble.d.ts +2 -0
- package/dist/prompt-assembly/assemble.js +2 -1
- package/dist/prompt-assembly/catalog/index.js +2 -1
- package/dist/prompt-assembly/catalog/memory.d.ts +13 -0
- package/dist/prompt-assembly/catalog/memory.js +6 -0
- package/dist/prompt-assembly/catalog/schema.d.ts +16 -2
- package/dist/prompt-assembly/composer.d.ts +2 -0
- package/dist/prompt-assembly/composer.js +1 -1
- package/dist/prompt-assembly/overlay.d.ts +21 -11
- package/dist/prompt-assembly/overlay.js +55 -17
- package/dist/prompt-assembly/select.d.ts +21 -6
- package/dist/prompt-assembly/select.js +39 -2
- package/dist/prompts/default.d.ts +0 -11
- package/dist/prompts/default.js +0 -3
- package/dist/stores/file/permission-rule-store.d.ts +1 -1
- package/dist/stores/file/permission-rule-store.js +2 -1
- package/dist/tools/artifact/artifact-tool.js +4 -3
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +65 -5
- package/wire-changes/core@7.53.0.json +1946 -0
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { classifyToolContentOrigin, contentOriginPollutes, delegationCallIsExternal } from "../memory-engine/content-origin.js";
|
|
2
|
-
import { mountedMcpPoolRows } from "../mounted-mcp.js";
|
|
2
|
+
import { mountedMcpPoolRows, toolNamesOfServer } from "../mounted-mcp.js";
|
|
3
3
|
import { narrowContentSafety, readCardAttestation } from "../memory-engine/delegation-provenance.js";
|
|
4
4
|
import { recordSyncUnattestable, sessionSettlements } from "../memory-engine/delegation-settlement.js";
|
|
5
5
|
import { protocolOf } from "../protocol-table.js";
|
|
@@ -7,9 +7,10 @@ import { deliverEngineNotice } from "../types.js";
|
|
|
7
7
|
import { inlineUntrusted } from "../untrusted-text.js";
|
|
8
8
|
import { fileArgPath } from "../tool-registry.js";
|
|
9
9
|
import { RosterBuilder } from "../tool-roster.js";
|
|
10
|
+
import { isNotStartedDelegationResult } from "../../agents/subagent.js";
|
|
10
11
|
import { thrownText } from "../thrown-value.js";
|
|
11
12
|
export function prepareMemoryEngineSession(input) {
|
|
12
|
-
const { memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight,
|
|
13
|
+
const { memoryEngineSession, internals, memoryDelegationEvidence, externalContentTargetActive, lockedPreflight, mountedMcp, sessionId, runId, deps, provenanceForChildrenRef, delegationSettlementRef, spec, envHandToolNames, roster, contentOriginWrapRef } = input;
|
|
13
14
|
const tools = roster.tools;
|
|
14
15
|
const delegationProvenanceChannel = internals?.delegationProvenance;
|
|
15
16
|
if (memoryEngineSession !== undefined || delegationProvenanceChannel !== undefined) {
|
|
@@ -22,7 +23,7 @@ export function prepareMemoryEngineSession(input) {
|
|
|
22
23
|
provenanceForChildrenRef.current = { trustedTools: [...trustedTools], execIsExternalContent };
|
|
23
24
|
announceDeclaredMcpContentClasses({
|
|
24
25
|
entries: lockedPreflight.mcp,
|
|
25
|
-
|
|
26
|
+
mountedNames: roster.tools.map((t) => t.name),
|
|
26
27
|
execIsExternalContent,
|
|
27
28
|
sessionId,
|
|
28
29
|
runId,
|
|
@@ -133,6 +134,9 @@ export function prepareMemoryEngineSession(input) {
|
|
|
133
134
|
isPolluting: poolToolPollutes,
|
|
134
135
|
});
|
|
135
136
|
const result = await inner(toolCallId, params, signal, onUpdate);
|
|
137
|
+
const delivery = delegationDeliveryOf(result);
|
|
138
|
+
if (delivery === "none")
|
|
139
|
+
return result;
|
|
136
140
|
const att = readCardAttestation(result?.details);
|
|
137
141
|
if (att === "external") {
|
|
138
142
|
mark(`tool "${t.name}" returned the output of a delegated agent that invoked an external-content-class tool at runtime` +
|
|
@@ -141,8 +145,11 @@ export function prepareMemoryEngineSession(input) {
|
|
|
141
145
|
}
|
|
142
146
|
else if (att !== "clean") {
|
|
143
147
|
if (external) {
|
|
144
|
-
const staticFaceReason =
|
|
145
|
-
|
|
148
|
+
const staticFaceReason = (delivery === "launched"
|
|
149
|
+
? `tool "${t.name}" launched a background delegated agent whose tool face can reach external content`
|
|
150
|
+
: `tool "${t.name}" returned the output of a delegated agent whose tool face can reach external content`) +
|
|
151
|
+
(typeof requested === "string" ? ` (subagent_type "${requested}")` : " (no subagent_type named — classified fail-closed)") +
|
|
152
|
+
(delivery === "launched" ? " — its output enters this session when it finishes" : "");
|
|
146
153
|
if (!delegationEvidenceAttestedOnly) {
|
|
147
154
|
mark(staticFaceReason, "static");
|
|
148
155
|
}
|
|
@@ -207,13 +214,19 @@ export function prepareMemoryEngineSession(input) {
|
|
|
207
214
|
}
|
|
208
215
|
return { armed: memoryEngineSession !== undefined || delegationProvenanceChannel !== undefined };
|
|
209
216
|
}
|
|
217
|
+
function delegationDeliveryOf(result) {
|
|
218
|
+
if (isNotStartedDelegationResult(result))
|
|
219
|
+
return "none";
|
|
220
|
+
const details = typeof result === "object" && result !== null ? result.details : undefined;
|
|
221
|
+
return typeof details === "object" && details !== null && details.status === "async_launched" ? "launched" : "report";
|
|
222
|
+
}
|
|
210
223
|
function announceDeclaredMcpContentClasses(args) {
|
|
211
224
|
for (const entry of args.entries ?? []) {
|
|
212
225
|
const declaredClass = entry.contentOrigin;
|
|
213
226
|
if (declaredClass === undefined)
|
|
214
227
|
continue;
|
|
215
228
|
const server = inlineUntrusted(String(entry.name), 160);
|
|
216
|
-
const toolCount = args.
|
|
229
|
+
const toolCount = toolNamesOfServer(args.mountedNames, entry.name).length;
|
|
217
230
|
const resourceFaceCaveat = " (Not covered: the cross-server resource faces — ListMcpResourcesTool/ReadMcpResourceTool/ReadMcpResourceDirTool — stay externally classified and still mark.)";
|
|
218
231
|
const posture = declaredClass === "local"
|
|
219
232
|
? `this server's mounted tools' invocations will not mark this session's memory as externally exposed.${resourceFaceCaveat}`
|
|
@@ -208,11 +208,12 @@ export interface PrepareMemoryResult {
|
|
|
208
208
|
* BEFORE it). It performs the one destructive read this phase has — `inject()` drains the announcement queue —
|
|
209
209
|
* so a hands-phase refusal cannot consume announcements a later prepare should deliver, and it takes the
|
|
210
210
|
* roster-wide persistence verdict the driver can only read off the MOUNTED roster (`rosterCanPersist`: the
|
|
211
|
-
* `
|
|
212
|
-
*
|
|
211
|
+
* `memoryPersistenceCapable` declaration when set, else the store-path inference over the assembled tools) and
|
|
212
|
+
* `isSubagent` (a non-fork delegated child — no user conversation, no not-mounted notice). Call once per prepare.
|
|
213
213
|
*/
|
|
214
214
|
composeInjection: (facts: {
|
|
215
215
|
rosterCanPersist: boolean;
|
|
216
|
+
isSubagent: boolean;
|
|
216
217
|
}) => MemoryInjectionComposition;
|
|
217
218
|
/**
|
|
218
219
|
* The FROZEN org-admission verdict of this prepare: every org scope the task actually mounts
|
|
@@ -6,7 +6,7 @@ import { classifyScopePlanes, derivePersonalControlDir, derivePersonalMemoryDir,
|
|
|
6
6
|
import { memoryProjectScopeAbsentNotice, normalizeMemorySpec } from "../memory.js";
|
|
7
7
|
import { deriveSupersededSet } from "../memory-engine/consolidation.js";
|
|
8
8
|
import { shadowNamesOf } from "../memory-engine/shadowing.js";
|
|
9
|
-
import { MEMORY_ANNOUNCEMENT_CAPTURE_OPTOUT_CODA, MEMORY_ANNOUNCEMENT_READONLY_CODA,
|
|
9
|
+
import { MEMORY_ANNOUNCEMENT_CAPTURE_OPTOUT_CODA, MEMORY_ANNOUNCEMENT_READONLY_CODA, MEMORY_CAPTURE_OPTOUT_NOTICE, MEMORY_PREFERENCE_DISCIPLINE, MEMORY_READONLY_NOTICE, MemoryEngine, entryFileHeadCarriesOrigin, memoryCaptureOptedOutNotice, memoryCaptureOptOutUnpersistedNotice, memoryConsolidationRecommendedNotice, memoryHarvestQuarantinedNotice, memoryHoldNotices, memoryRecallDisciplineSegment, memoryRestoreWithheldNotice, memorySessionPollutedNotice, memoryUnavailableNotice, pollutionContainmentCounts, } from "../memory-engine/engine.js";
|
|
10
10
|
import { adjudicateCaptureOptOut, captureOptOutDeniedError, captureOptOutUnpersistedError } from "./memory-capture-optout.js";
|
|
11
11
|
import { readSessionCaptureOptOut } from "../memory-engine/layout.js";
|
|
12
12
|
import { sessionIncarnationResolver } from "../memory-engine/session-incarnation.js";
|
|
@@ -14,6 +14,7 @@ import { createMemoryEngineTools } from "../memory-engine/tools.js";
|
|
|
14
14
|
import { assertScopeContractPlacement, parseScopeKey, resolveProjectId } from "../memory-engine/scope-contract.js";
|
|
15
15
|
import { FileMemoryEngineBackend } from "../memory-engine/file-backend.js";
|
|
16
16
|
import { writableRootOf } from "../memory-engine/types.js";
|
|
17
|
+
import { catalogText } from "../../prompt-assembly/catalog/index.js";
|
|
17
18
|
import { asThrownError, thrownText } from "../thrown-value.js";
|
|
18
19
|
let undeclaredCapturePostureAnnounced = false;
|
|
19
20
|
export async function prepareMemory(input) {
|
|
@@ -781,7 +782,7 @@ export async function prepareMemory(input) {
|
|
|
781
782
|
blockBody = [MEMORY_CAPTURE_OPTOUT_NOTICE, injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
|
|
782
783
|
}
|
|
783
784
|
else if (captureIndeterminate && facts.rosterCanPersist) {
|
|
784
|
-
blockBody = [
|
|
785
|
+
blockBody = [memoryUnavailableNotice({ what: "capture-record-unreadable", notesReadable: true }), injection.index, injection.announceBlock].filter((s) => Boolean(s && s.trim())).join("\n\n");
|
|
785
786
|
}
|
|
786
787
|
else if (!facts.rosterCanPersist && injection.instruction === "" && injection.readOnlyNotice === undefined) {
|
|
787
788
|
blockBody = blockBody.trim() ? `${MEMORY_READONLY_NOTICE}\n\n${blockBody}` : MEMORY_READONLY_NOTICE;
|
|
@@ -817,6 +818,9 @@ export async function prepareMemory(input) {
|
|
|
817
818
|
if (memoryBlock !== undefined && injection.indexSeed !== undefined && facts.rosterCanPersist && !captureOptedOut && !captureIndeterminate)
|
|
818
819
|
seedFiles = [injection.indexSeed];
|
|
819
820
|
}
|
|
821
|
+
else if (!facts.rosterCanPersist && !facts.isSubagent) {
|
|
822
|
+
memoryBlock = effectiveMemoryScopes?.reason === "mount-failed" ? memoryUnavailableNotice({ what: "mount-failed", notesReadable: false }) : catalogText("core/memory.no-persistent-store");
|
|
823
|
+
}
|
|
820
824
|
return {
|
|
821
825
|
memoryBlock,
|
|
822
826
|
...(recallDisciplineSegment !== undefined ? { recallDisciplineSegment } : {}),
|
|
@@ -20,10 +20,10 @@ import type { ToolSelector } from "../tool-face.js";
|
|
|
20
20
|
export interface PrepareOffloadWrappersInput {
|
|
21
21
|
/** borrowed-readonly — the REBOUND spec (the config-doors result); read for the per-task coarse
|
|
22
22
|
* offload knob only. */
|
|
23
|
-
spec: Pick<TaskSpec, "toolResultThresholdChars">;
|
|
24
|
-
/** borrowed-readonly — the leg's compiled selector: an offloaded result is read back through the
|
|
25
|
-
* does not
|
|
26
|
-
* sends the model to a tool it does not have is a dead end. */
|
|
23
|
+
spec: Pick<TaskSpec, "toolResultThresholdChars" | "excludeAllTools">;
|
|
24
|
+
/** borrowed-readonly — the leg's compiled selector, read through the valve (`valveLeaves`): an offloaded result is read back through the
|
|
25
|
+
* reader tool, so a leg whose valve does not leave the reader (a sub-agent whose lists leave it out, a deployment that excludes it, a
|
|
26
|
+
* run whose whole face is switched off) offloads nothing — a preview that sends the model to a tool it does not have is a dead end. */
|
|
27
27
|
selector: Pick<ToolSelector, "admits">;
|
|
28
28
|
/** borrowed-readonly — the deployment's coarse offload knob and its injected store (used AS-IS when
|
|
29
29
|
* present; a Runner-shared instance is viewed per task, see the body). */
|
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, InMemoryToolResultStore, OFFLOAD_TOOL_NAME, RunnerSharedToolResultStore, ScopedToolResultStore, withToolResultOffload, } from "../tool-result-store.js";
|
|
2
2
|
import { faceOf } from "../tool-roster.js";
|
|
3
|
+
import { valveLeaves } from "../../agents/tool-filter.js";
|
|
3
4
|
const FIRST_PARTY_OFFLOAD_THRESHOLD_CHARS = 50_000;
|
|
4
5
|
export function prepareOffloadWrappers(input) {
|
|
5
6
|
const { spec, deps, resume, offloadScope, sessionId, selector } = input;
|
|
@@ -21,7 +22,7 @@ export function prepareOffloadWrappers(input) {
|
|
|
21
22
|
};
|
|
22
23
|
const explicitGlobalThreshold = spec.toolResultThresholdChars ?? deps.toolResultThresholdChars;
|
|
23
24
|
const offloadThreshold = explicitGlobalThreshold ?? DEFAULT_TOOL_RESULT_THRESHOLD_CHARS;
|
|
24
|
-
const offloadEnabled = Number.isFinite(offloadThreshold) && offloadThreshold > 0 && selector
|
|
25
|
+
const offloadEnabled = Number.isFinite(offloadThreshold) && offloadThreshold > 0 && valveLeaves(spec, selector)({ name: OFFLOAD_TOOL_NAME });
|
|
25
26
|
const rawOffloadStore = offloadEnabled ? (deps.toolResultStore ?? new InMemoryToolResultStore()) : undefined;
|
|
26
27
|
const offloadStore = rawOffloadStore instanceof RunnerSharedToolResultStore
|
|
27
28
|
? new ScopedToolResultStore(rawOffloadStore, offloadScope)
|
|
@@ -46,7 +46,7 @@ export interface PreparePolicyChainInput {
|
|
|
46
46
|
/** borrowed-readonly — the REBOUND spec. Read: `sessionId` / `principal` (the session-rule read and the lanes' identity),
|
|
47
47
|
* `durableApproval` / `checkpointStore` (the mandate-park facility test and the sandbox arming's park prerequisites), `taskId` (the late-ask observer's detail),
|
|
48
48
|
* `tools` (the names the caller mounted, for the name audit). Never mutated. */
|
|
49
|
-
spec: Pick<TaskSpec, "sessionId" | "principal" | "durableApproval" | "taskId" | "checkpointStore" | "tools">;
|
|
49
|
+
spec: Pick<TaskSpec, "sessionId" | "principal" | "durableApproval" | "taskId" | "checkpointStore" | "tools" | "excludeAllTools">;
|
|
50
50
|
/** borrowed-readonly — the deployment seats: `sessionPolicyStore` (the rule reads),
|
|
51
51
|
* `permissionRuleStore` / `localOwnerRules` (the lanes and the offer factory), `onError` / `onNotice` (the advisories,
|
|
52
52
|
* the refusal disclosures, the late-ask observer), `tracer` (the admission and rule-store frames), `checkpointStore` (the park facility). Receiver preserved;
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import { withArgsReading } from "../effective-path-target.js";
|
|
1
|
+
import { argsAsTheToolReads, withArgsReading } from "../effective-path-target.js";
|
|
2
2
|
import { policyAskClassOf } from "../ask-class.js";
|
|
3
3
|
import { ASK_USER_QUESTION_TOOL_NAME } from "../ask-question.js";
|
|
4
4
|
import { classifierUnavailableSeat } from "./classifier-ladder.js";
|
|
@@ -6,7 +6,8 @@ import { resolveCheckpointStore } from "../checkpoint-store.js";
|
|
|
6
6
|
import { chainJudges, inheritedToolChecks, screeningInstallationsOf, standsInFor } from "../mods/stations.js";
|
|
7
7
|
import { isNamespacedCoveringRuleName, namespacedRuleNameCovers } from "../permission-rules.js";
|
|
8
8
|
import { isIsolated } from "../remote-env.js";
|
|
9
|
-
import {
|
|
9
|
+
import { deliverEngineNotice } from "../engine-notice.js";
|
|
10
|
+
import { earlierGrammarNotice } from "../session-policy-store.js";
|
|
10
11
|
import { attest, attestationOf, checkToolPolicyProjection, combinePolicies, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, durableParkOptInDeclared, isLiveApproverSeat, mergeAttestation, refuseOutOfContractDecision, resolveAsk, toolPolicyNameSets, withAttestation, wrapToolPolicy } from "../tool-policy.js";
|
|
11
12
|
import { judgeRuleToolName, mountedToolNames } from "../tool-name-aliases.js";
|
|
12
13
|
import { approvalCardMemberOf } from "../tool-roster.js";
|
|
@@ -15,6 +16,7 @@ import { emitTrace } from "../trace.js";
|
|
|
15
16
|
import { skillGrantBindingMembers } from "../skill-grant.js";
|
|
16
17
|
import { SKILL_TOOL_NAME } from "./synthetic-tools.js";
|
|
17
18
|
import { delegationPoolReading } from "./sub-agent-deny-lists.js";
|
|
19
|
+
import { valveLeaves } from "../../agents/tool-filter.js";
|
|
18
20
|
import { autoStrippedRule, cardDisclosureOf, nearMissSpellingOf, rootFacingToolNames } from "../allow-entry.js";
|
|
19
21
|
import { arbitrateByMode, askClassMembersOf, askFaceOf, askMandateMember } from "../ask-origin.js";
|
|
20
22
|
import { createModeGatePolicy, mountedToolDeclaresReadOnly } from "../mode-policy.js";
|
|
@@ -46,7 +48,7 @@ export async function preparePolicyChain(input) {
|
|
|
46
48
|
const known = mountedToolNames(tools);
|
|
47
49
|
for (const t of harnessTools)
|
|
48
50
|
known.add(t.name);
|
|
49
|
-
const pool = delegationPoolReading(spec.tools ?? [], selector);
|
|
51
|
+
const pool = delegationPoolReading(spec.tools ?? [], valveLeaves(spec, selector));
|
|
50
52
|
const callerNames = mountedToolNames(spec.tools ?? []);
|
|
51
53
|
const rootFacing = rootFacingToolNames([...known, ...callerNames, ...pool.names]);
|
|
52
54
|
const unmatched = new Set();
|
|
@@ -119,7 +121,7 @@ export async function preparePolicyChain(input) {
|
|
|
119
121
|
catch {
|
|
120
122
|
}
|
|
121
123
|
};
|
|
122
|
-
const announceEarlierGrammar = (rulesSessionId) => (entries, field, grammar) => deps.
|
|
124
|
+
const announceEarlierGrammar = (rulesSessionId) => (entries, field, grammar) => deliverEngineNotice(deps.onNotice, earlierGrammarNotice({ rulesSessionId, sessionId, entries, field, grammar }));
|
|
123
125
|
let sessionRulePolicy;
|
|
124
126
|
if (deps.sessionPolicyStore && spec.sessionId) {
|
|
125
127
|
const store = deps.sessionPolicyStore;
|
|
@@ -343,7 +345,7 @@ export async function preparePolicyChain(input) {
|
|
|
343
345
|
const recheckApprovedEdit = async (pol, onAskOf, creq, edit, approved, csignal, ancestorAutoMode) => {
|
|
344
346
|
const ancestorDecider = ancestorAutoMode?.decider;
|
|
345
347
|
const ancestorTracker = ancestorAutoMode?.denialTracking;
|
|
346
|
-
let editArgs = edit;
|
|
348
|
+
let editArgs = argsAsTheToolReads(creq, edit);
|
|
347
349
|
let settledBy = approved;
|
|
348
350
|
const onApproval = (d) => withAttestation(d, mergeAttestation(creq, attestationOf(settledBy, creq), attestationOf(d, creq), "answer"));
|
|
349
351
|
const vetoed = onApproval;
|
|
@@ -356,8 +358,7 @@ export async function preparePolicyChain(input) {
|
|
|
356
358
|
}
|
|
357
359
|
let re;
|
|
358
360
|
try {
|
|
359
|
-
|
|
360
|
-
re = refuseOutOfContractDecision(await pol.check(editReq !== undefined ? await editReq : { ...creq, args: editArgs }, csignal ?? abortController.signal));
|
|
361
|
+
re = refuseOutOfContractDecision(await pol.check(await withArgsReading(creq, editArgs, csignal ?? abortController.signal), csignal ?? abortController.signal));
|
|
361
362
|
}
|
|
362
363
|
catch (err) {
|
|
363
364
|
reportPolicyThrow(notifyOwnHookCrash, "an inherited parent policy's re-check of the approved edit", creq, err, csignal ?? abortController.signal);
|
|
@@ -373,7 +374,7 @@ export async function preparePolicyChain(input) {
|
|
|
373
374
|
return onApproval(withAttestation({ action: "allow", updatedInput: re.updatedInput !== undefined ? re.updatedInput : editArgs, ...(stated !== undefined ? { decisionReason: stated } : {}) }, re.attestation));
|
|
374
375
|
}
|
|
375
376
|
if (re.updatedInput !== undefined)
|
|
376
|
-
editArgs = re.updatedInput;
|
|
377
|
+
editArgs = argsAsTheToolReads(creq, re.updatedInput);
|
|
377
378
|
const judged = await judgeInheritedClassifier({ liveMode: () => permissionMode.current, autoMode: ancestorAutoMode, ask: re, req: { ...creq, args: editArgs }, signal: csignal ?? abortController.signal, subject: "the approved edit", allowRewrite: editArgs, facts: inheritedStationFacts(creq), unavailableSeat: classifierUnavailableSeat({ station: "ancestor", ...(ancestorDecider?.timeoutMs !== undefined ? { budgetMs: ancestorDecider.timeoutMs } : {}), route: frozenApproverRoute(onAskOf), onNotice: deps.onNotice, sessionId, runId }) });
|
|
378
379
|
if (judged.kind === "allow") {
|
|
379
380
|
return onApproval(judged.result);
|
|
@@ -408,7 +409,7 @@ export async function preparePolicyChain(input) {
|
|
|
408
409
|
settledBy = rr;
|
|
409
410
|
if (rr.updatedInput === undefined)
|
|
410
411
|
return onApproval({ action: "allow", updatedInput: editArgs, decisionReason: "mode" });
|
|
411
|
-
editArgs = rr.updatedInput;
|
|
412
|
+
editArgs = argsAsTheToolReads(creq, rr.updatedInput);
|
|
412
413
|
}
|
|
413
414
|
};
|
|
414
415
|
const settleInstallationAsk = async (pc, decision, creq, csignal) => {
|
|
@@ -427,7 +428,7 @@ export async function preparePolicyChain(input) {
|
|
|
427
428
|
return settledAs(decision);
|
|
428
429
|
return settledAs(mandateUnreconstructibleDeny(creq));
|
|
429
430
|
}
|
|
430
|
-
const presentedArgs = decision.updatedInput !== undefined ? decision.updatedInput : creq.args;
|
|
431
|
+
const presentedArgs = decision.updatedInput !== undefined ? argsAsTheToolReads(creq, decision.updatedInput) : creq.args;
|
|
431
432
|
const judged = await judgeInheritedClassifier({ liveMode: () => permissionMode.current, autoMode: pc.autoMode, ask: decision, req: { ...creq, args: presentedArgs }, signal: csignal ?? abortController.signal, subject: "this call", allowRewrite: decision.updatedInput, facts: inheritedStationFacts(creq), unavailableSeat: classifierUnavailableSeat({ station: "ancestor", ...(pc.autoMode?.decider.timeoutMs !== undefined ? { budgetMs: pc.autoMode.decider.timeoutMs } : {}), route: frozenApproverRoute(pc.onAsk), onNotice: deps.onNotice, sessionId, runId }) });
|
|
432
433
|
if (judged.kind === "allow")
|
|
433
434
|
return settledAs(judged.result);
|
|
@@ -635,8 +636,7 @@ export async function preparePolicyChain(input) {
|
|
|
635
636
|
}
|
|
636
637
|
}
|
|
637
638
|
const recheckLayers = [...recheckPrefix, ...postEmitterSameInstanceAdapters];
|
|
638
|
-
const
|
|
639
|
-
const finalReq = finalRead !== undefined ? await finalRead : { ...req, args: decision.updatedInput };
|
|
639
|
+
const finalReq = await withArgsReading(req, decision.updatedInput, signal);
|
|
640
640
|
let asked;
|
|
641
641
|
let revalidated;
|
|
642
642
|
let restated;
|
|
@@ -14,7 +14,7 @@ export interface PrepareProjectContextInput {
|
|
|
14
14
|
/** borrowed-readonly — the REBOUND spec (`spec′`). Read: `sessionId` (phase derivation + the
|
|
15
15
|
* continuation projections), `skills` (the roster), `userInvokedSkills` (the person's invoked skills — their
|
|
16
16
|
* rows are written here), `principal` (the shared-memory tools' trusted identity). Never mutated. */
|
|
17
|
-
spec: Pick<TaskSpec, "sessionId" | "skills" | "userInvokedSkills" | "principal">;
|
|
17
|
+
spec: Pick<TaskSpec, "sessionId" | "skills" | "userInvokedSkills" | "principal" | "excludeAllTools">;
|
|
18
18
|
/** borrowed-readonly — trusted internals: `agentName` (seam ctx), `inheritedSkillGrants` (the parent's captured
|
|
19
19
|
* skill grant rows, seeded as `inherited`), `inheritedAllowedTools` (the parent's request entries, seeded as this leg's
|
|
20
20
|
* own). `undefined` on a standalone prepare. */
|
|
@@ -13,10 +13,12 @@ import { SKILL_CONTENT_MAX_CHARS, SKILL_TOOL_NAME, createSkillTool, normalizeSki
|
|
|
13
13
|
import { skillLoadReading } from "./skill-base-dir.js";
|
|
14
14
|
import { RosterBuilder } from "../tool-roster.js";
|
|
15
15
|
import { mountedToolNames } from "../tool-name-aliases.js";
|
|
16
|
+
import { valveLeaves } from "../../agents/tool-filter.js";
|
|
16
17
|
import { asThrownError } from "../thrown-value.js";
|
|
17
18
|
export async function prepareProjectContext(input) {
|
|
18
19
|
const { deps, spec, internals, session, sessionId, runId, hostTaskId, taskRootFinal, handsEnabled, delegation, seedContextFiles, memoryBlockFromEngine, skillGrants, allowedTools, allowedToolTables, roster, toolFaceSnapshot, onceLedger, memoryTools, memoryEngineSession, memorySearchToolsPlanned, memoryPairExcludedName, memoryPairOccupiedName, resume, skillListingBudget } = input;
|
|
19
20
|
const tools = roster.tools;
|
|
21
|
+
const leaves = valveLeaves(spec, toolFaceSnapshot.selector);
|
|
20
22
|
let memoryBlock = memoryBlockFromEngine;
|
|
21
23
|
let instructionSources;
|
|
22
24
|
let projectInstructionContent;
|
|
@@ -115,11 +117,11 @@ export async function prepareProjectContext(input) {
|
|
|
115
117
|
for (const alias of t.aliases ?? [])
|
|
116
118
|
mountedNameDomain.add(alias);
|
|
117
119
|
}
|
|
118
|
-
const excludedName = SHARED_MEMORY_TOOL_NAMES.find((n) => !
|
|
120
|
+
const excludedName = SHARED_MEMORY_TOOL_NAMES.find((n) => !leaves({ name: n }));
|
|
119
121
|
const occupiedName = SHARED_MEMORY_TOOL_NAMES.find((n) => mountedNameDomain.has(n));
|
|
120
122
|
if (excludedName !== undefined || occupiedName !== undefined) {
|
|
121
123
|
announceMemoryNotMounted(onceLedger, sessionId, "shared", SHARED_MEMORY_TOOL_NAMES, excludedName !== undefined
|
|
122
|
-
? `the run's tool
|
|
124
|
+
? `the run's tool face (allowTools / excludeTools / excludeAllTools) does not admit "${excludedName}"`
|
|
123
125
|
: `this task already declares a tool named "${occupiedName}" (the built-in yields to it)`);
|
|
124
126
|
}
|
|
125
127
|
else {
|
|
@@ -137,10 +139,10 @@ export async function prepareProjectContext(input) {
|
|
|
137
139
|
}
|
|
138
140
|
else if (memoryEngineSession !== undefined && !memorySearchToolsPlanned) {
|
|
139
141
|
announceMemoryNotMounted(onceLedger, sessionId, "engine", MEMORY_ENGINE_TOOL_NAMES, memoryPairExcludedName !== undefined
|
|
140
|
-
? `the run's tool
|
|
142
|
+
? `the run's tool face (allowTools / excludeTools / excludeAllTools) does not admit "${memoryPairExcludedName}"`
|
|
141
143
|
: `this task already declares a tool named "${memoryPairOccupiedName}" (the built-in yields to it)`);
|
|
142
144
|
}
|
|
143
|
-
const skillsListing = skillSpecs.length > 0
|
|
145
|
+
const skillsListing = skillSpecs.length > 0 && leaves({ name: SKILL_TOOL_NAME })
|
|
144
146
|
? {
|
|
145
147
|
entries: skillSpecs.map((s) => ({
|
|
146
148
|
name: s.name,
|
|
@@ -31,7 +31,7 @@ export interface PreparePromptAssemblyInput {
|
|
|
31
31
|
readonly role?: HostRole;
|
|
32
32
|
readonly form?: HostForm;
|
|
33
33
|
};
|
|
34
|
-
/** borrowed-readonly — the
|
|
34
|
+
/** borrowed-readonly — the run's binding (`TaskSpec.promptBinding`, validated), or undefined: a selector value. */
|
|
35
35
|
binding: string | undefined;
|
|
36
36
|
/** borrowed-readonly — the leg's mods bus: `prompt.compose` collects the deploy and task seats' overlays. */
|
|
37
37
|
modBus: LegModBus;
|
|
@@ -1,12 +1,13 @@
|
|
|
1
1
|
import { createHash } from "node:crypto";
|
|
2
2
|
import { SEND_MESSAGE_TOOL_NAME } from "../../agents/send-message-tool.js";
|
|
3
3
|
import { assemblePrompt } from "../../prompt-assembly/assemble.js";
|
|
4
|
-
import { adoptCenter, centerOverlaysOf } from "../../prompt-assembly/artifact.js";
|
|
4
|
+
import { adoptCenter, centerOverlaysOf, verifyPromptArtifactBody } from "../../prompt-assembly/artifact.js";
|
|
5
|
+
import { refusalClause, storedArtifactLine } from "../../prompt-assembly/artifact-store.js";
|
|
5
6
|
import { catalogDigestOf, digestOf, prepareEpochRecord } from "../../prompt-assembly/epoch.js";
|
|
6
7
|
import { rendererVector } from "../../prompt-assembly/renderers.js";
|
|
7
8
|
import { SEMA_DEFAULT_CATALOG } from "../../prompt-assembly/catalog/index.js";
|
|
8
9
|
import { describeCatalog } from "../../prompt-assembly/explain.js";
|
|
9
|
-
import { selectorsOf } from "../../prompt-assembly/select.js";
|
|
10
|
+
import { selectorRecordOf, selectorsOf } from "../../prompt-assembly/select.js";
|
|
10
11
|
import { auditToolCollisions, projectToolManifest } from "../../prompt-assembly/tool-catalog.js";
|
|
11
12
|
import { buildEnvironmentContext } from "../../prompts/default.js";
|
|
12
13
|
import { raisePromptCompose } from "../mods/stations.js";
|
|
@@ -31,13 +32,21 @@ export async function preparePromptAssembly(input) {
|
|
|
31
32
|
const stored = await session.getPromptEpoch();
|
|
32
33
|
let centerAdoption;
|
|
33
34
|
{
|
|
34
|
-
const failUnavailable = (what) => {
|
|
35
|
-
|
|
35
|
+
const failUnavailable = (what, refusal) => {
|
|
36
|
+
const why = refusal !== undefined ? `the source's copy is ${refusalClause(refusal)}` : `artifact source miss / not verifiable here${deps.promptSource === undefined ? "; RunnerDeps.promptSource is not configured" : ""}`;
|
|
37
|
+
throw Object.assign(new Error(`prompt snapshot unavailable: ${what} (${why}) — refusing to recompose a hybrid prompt`), { code: "prompt.snapshot_unavailable" });
|
|
36
38
|
};
|
|
37
39
|
const resolvePinned = async (digest, sourceRevision, via) => {
|
|
38
|
-
const
|
|
40
|
+
const told = {};
|
|
41
|
+
const art = await deps.promptSource?.get(digest, (r) => void (told.current = r));
|
|
39
42
|
const adopted = art !== undefined ? adoptCenter(art, sourceRevision) : undefined;
|
|
40
|
-
|
|
43
|
+
if (adopted !== undefined)
|
|
44
|
+
return adopted;
|
|
45
|
+
const checked = art !== undefined ? verifyPromptArtifactBody(art) : undefined;
|
|
46
|
+
const refusal = told.current ?? (checked !== undefined && !checked.ok ? { code: checked.code, reason: checked.reason } : undefined);
|
|
47
|
+
if (refusal !== undefined)
|
|
48
|
+
deps.onError?.(new Error(storedArtifactLine(digest, refusal, `the session fails prompt.snapshot_unavailable (a hybrid prompt is never recomposed)`)), { phase: "prompt-constitution", sessionId });
|
|
49
|
+
return failUnavailable(`${via} center prompt artifact ${digest.slice(0, 23)}… has no verified resolvable copy`, refusal);
|
|
41
50
|
};
|
|
42
51
|
const pinned = stored?.kind === "pin" ? stored.descriptor : undefined;
|
|
43
52
|
const retiredCenterPin = stored?.kind === "legacy" && stored.centerPinned;
|
|
@@ -76,14 +85,8 @@ export async function preparePromptAssembly(input) {
|
|
|
76
85
|
promptProfile,
|
|
77
86
|
fableMitigations,
|
|
78
87
|
};
|
|
79
|
-
const
|
|
80
|
-
const
|
|
81
|
-
...(binding !== undefined ? { binding } : {}),
|
|
82
|
-
traits: [...selectors.traits].sort(),
|
|
83
|
-
host: { role: selectors.host.role, form: selectors.host.form },
|
|
84
|
-
facts: { ...selectors.facts },
|
|
85
|
-
};
|
|
86
|
-
const centerOverlays = centerOverlaysOf(centerAdoption, binding);
|
|
88
|
+
const selectorRecord = selectorRecordOf(selectorsOf(facts, host, binding));
|
|
89
|
+
const centerOverlays = centerOverlaysOf(centerAdoption);
|
|
87
90
|
const lowerAdds = new Map();
|
|
88
91
|
for (const { overlay } of [...sugar, ...centerOverlays])
|
|
89
92
|
if (overlay.op === "add")
|
|
@@ -91,16 +94,17 @@ export async function preparePromptAssembly(input) {
|
|
|
91
94
|
const composed = await raisePromptCompose(modBus, {
|
|
92
95
|
model: model.id,
|
|
93
96
|
catalog: describeCatalog().sections,
|
|
94
|
-
selectors:
|
|
97
|
+
selectors: selectorRecord,
|
|
95
98
|
}, { lowerAdds, ...(input.signal !== undefined ? { signal: input.signal } : {}) });
|
|
96
99
|
for (const w of composed.warnings)
|
|
97
100
|
deps.onError?.(new Error(w), { phase: "prompt-constitution", sessionId });
|
|
98
101
|
const taskOverlays = [...sugar, ...composed.task];
|
|
99
102
|
const buildAssembleInputs = (center) => ({
|
|
100
103
|
taskOverlays,
|
|
101
|
-
centerOverlays: centerOverlaysOf(center
|
|
104
|
+
centerOverlays: centerOverlaysOf(center),
|
|
102
105
|
deployOverlays: composed.deploy,
|
|
103
106
|
host,
|
|
107
|
+
...(binding !== undefined ? { binding } : {}),
|
|
104
108
|
tools,
|
|
105
109
|
facts,
|
|
106
110
|
...(envFacts.cwd !== undefined ? { workspaceFolder: envFacts.cwd } : {}),
|
|
@@ -27,6 +27,7 @@ import type { SourcedOverlay } from "../../prompt-assembly/overlay.js";
|
|
|
27
27
|
import type { ContainmentFace } from "../../tools/fs/index.js";
|
|
28
28
|
import type { LockedPreflight } from "../locked-config.js";
|
|
29
29
|
import type { MaterializedMcp } from "../mcp.js";
|
|
30
|
+
import type { RosterBuilder } from "../tool-roster.js";
|
|
30
31
|
import type { ResolvedRole } from "../roles.js";
|
|
31
32
|
import type { RunnerDeps, TaskSpec } from "../types.js";
|
|
32
33
|
import type { SessionTreeEntry } from "../../internal/harness-types.js";
|
|
@@ -37,8 +38,8 @@ import { type ContextWindowOverlay } from "../context-settings.js";
|
|
|
37
38
|
export interface PreparePromptInputsInput {
|
|
38
39
|
/** borrowed-readonly — the REBOUND spec (`spec′`). Read: `systemPrompt` / `appendSystemPrompt` (handed whole to the
|
|
39
40
|
* request-body sugar), `clientContext` (zone, email), `envFacts` (the deployment's sandbox + resume facts),
|
|
40
|
-
* `compaction` (the within-task flag). Never mutated. */
|
|
41
|
-
spec: Pick<TaskSpec, "systemPrompt" | "appendSystemPrompt" | "clientContext" | "envFacts" | "compaction">;
|
|
41
|
+
* `compaction` (the within-task flag), `excludeAllTools` (the valve's whole-face switch). Never mutated. */
|
|
42
|
+
spec: Pick<TaskSpec, "systemPrompt" | "appendSystemPrompt" | "clientContext" | "envFacts" | "compaction" | "excludeAllTools">;
|
|
42
43
|
/** borrowed-readonly — deployment deps: `onError` (the operator lane: fail-closed advisory, cwd misalignment,
|
|
43
44
|
* git-lane degrade), `modelKnowledgeCutoffs`. Receiver preserved (`deps.onError?.(…)`). */
|
|
44
45
|
deps: Pick<RunnerDeps, "onError" | "modelKnowledgeCutoffs">;
|
|
@@ -61,8 +62,9 @@ export interface PreparePromptInputsInput {
|
|
|
61
62
|
resolvedReadFace: ContainmentFace | undefined;
|
|
62
63
|
/** borrowed-readonly — the resolved write face (the open-writes flag + the structured env fact). */
|
|
63
64
|
resolvedWriteFace: ContainmentFace | undefined;
|
|
64
|
-
/** borrowed-readonly — the frozen tool face;
|
|
65
|
-
|
|
65
|
+
/** borrowed-readonly — the frozen tool face; `defer` (the Workflow short-pointer flag) and `selector` (with the spec's whole-face
|
|
66
|
+
* switch, the valve's reading that decides which servers' instructions are taught). */
|
|
67
|
+
toolFaceSnapshot: Pick<ToolFaceSnapshot, "defer" | "selector">;
|
|
66
68
|
/** borrowed-readonly — the resolved prompt profile (rides the flags to the legacy ctx). */
|
|
67
69
|
promptProfile: "simple" | "classic";
|
|
68
70
|
/** borrowed-readonly — the fable-mitigations profile axis (rides the flags with the profile). */
|
|
@@ -81,8 +83,12 @@ export interface PreparePromptInputsInput {
|
|
|
81
83
|
};
|
|
82
84
|
/** borrowed-readonly — the resolved role; only its `systemPrompt` preset is read (second source). */
|
|
83
85
|
resolvedRole: Pick<ResolvedRole, "systemPrompt">;
|
|
84
|
-
/** borrowed-
|
|
85
|
-
|
|
86
|
+
/** borrowed-mutable — the materialized MCP roster; `serverInstructions` (the disposed entries) and `tools` (each server's listing: did it list
|
|
87
|
+
* any tool) are read, and the instructions lane's ledger is stated: the block is what the model is told at the run's start. */
|
|
88
|
+
mcp: Pick<MaterializedMcp, "serverInstructions" | "tools" | "instructionsDelta">;
|
|
89
|
+
/** borrowed-readonly — the run's roster as the protocol-tools phase mounted it (the deployment's overlay applied, the valve not yet):
|
|
90
|
+
* the tools the teaching answer reads, with the valve's predicate. */
|
|
91
|
+
roster: Pick<RosterBuilder, "tools">;
|
|
86
92
|
/** borrowed-readonly — the resolved model (id for the env line + the cutoff lookup). */
|
|
87
93
|
model: Model;
|
|
88
94
|
/** borrowed-readonly — the run's external-content-target fold (the single-source disclosure fact). */
|
|
@@ -1,5 +1,7 @@
|
|
|
1
1
|
import { formatLocalDate, isValidTimeZone } from "../../prompts/default.js";
|
|
2
2
|
import { sugarOverlays } from "../../prompt-assembly/sugar.js";
|
|
3
|
+
import { valveLeaves } from "../../agents/tool-filter.js";
|
|
4
|
+
import { instructionsTaught, toldAtStart } from "../mounted-mcp.js";
|
|
3
5
|
import { isIsolated } from "../remote-env.js";
|
|
4
6
|
import { readDateAnchor } from "./announce-once-ledger.js";
|
|
5
7
|
import { probeGitStatusLane } from "./git-status-frame.js";
|
|
@@ -31,9 +33,10 @@ export async function preparePromptInputs(input) {
|
|
|
31
33
|
isSubagent: delegation.isNonForkChild,
|
|
32
34
|
};
|
|
33
35
|
const sugar = sugarOverlays({ spec, resolvedRole, ...(internals !== undefined ? { internals } : {}) });
|
|
34
|
-
const
|
|
35
|
-
|
|
36
|
-
|
|
36
|
+
const valveLeft = valveLeaves(spec, toolFaceSnapshot.selector);
|
|
37
|
+
const taught = mcp.serverInstructions.filter((entry) => instructionsTaught(valveLeft, entry.server, input.roster.tools, mcp.tools));
|
|
38
|
+
toldAtStart(mcp.instructionsDelta, new Set(taught.map((entry) => entry.server)));
|
|
39
|
+
const mcpInstructionsBlock = taught.length ? `# MCP Server Instructions\n${taught.map(renderMcpInstructionsEntry).join("\n\n")}` : undefined;
|
|
37
40
|
const userTz = spec.clientContext?.timeZone;
|
|
38
41
|
const tzValid = userTz !== undefined && isValidTimeZone(userTz);
|
|
39
42
|
const dateAnchor = await readDateAnchor(session);
|
|
@@ -32,12 +32,14 @@ import type { AnnounceOnceSink, IrreversibilityTier, Prepared, RollbackStack, To
|
|
|
32
32
|
import { RosterBuilder, type ToolRosterDeltaSeat } from "../tool-roster.js";
|
|
33
33
|
import type { LegModBus } from "../mods/stations.js";
|
|
34
34
|
export interface PrepareProtocolToolsInput {
|
|
35
|
-
/** borrowed-readonly — the frozen preflight;
|
|
36
|
-
*
|
|
37
|
-
|
|
35
|
+
/** borrowed-readonly — the frozen preflight; `mcp` (the declared server entries: the materialize input, the RefreshMcpTools
|
|
36
|
+
* mount predicate, and whether a real client was acquired) and `a2a` (the declared peers the door judged: the materialize
|
|
37
|
+
* input and whether a handle was acquired) are read. */
|
|
38
|
+
lockedPreflight: Pick<LockedPreflight, "mcp" | "a2a">;
|
|
38
39
|
/** borrowed-readonly — the REBOUND spec. Read: `principal` (the MCP header / the A2A identity), `tools`
|
|
39
|
-
* (the caller names both reserved-name guards check against), `
|
|
40
|
-
|
|
40
|
+
* (the caller names both reserved-name guards check against), `excludeAllTools` (the valve's whole-face switch: the live roster lane's
|
|
41
|
+
* reading, and the first-dial gate). */
|
|
42
|
+
spec: Pick<TaskSpec, "principal" | "tools" | "excludeAllTools">;
|
|
41
43
|
/** borrowed-readonly — the deployment seats the materializers and their operator faces read: `onElicit`
|
|
42
44
|
* and `mcpImageResizer` ride into the MCP intake; `onError` takes the A2A warnings (no ledger — a peer is
|
|
43
45
|
* re-read every prepare); `mcpRevocations` + `onNotice` make the revocation wiring. */
|
|
@@ -1,6 +1,8 @@
|
|
|
1
1
|
import { Type } from "typebox";
|
|
2
2
|
import { materializeMcpTools } from "../mcp.js";
|
|
3
|
-
import { applyMcpRosterDelta, commitMcpRosterChanges, redialMcpServer } from "./mcp-redial.js";
|
|
3
|
+
import { applyMcpRosterDelta, commitMcpRosterChanges, redialMcpServer, rosterHolding, settledOnRoster } from "./mcp-redial.js";
|
|
4
|
+
import { valveLeaves, valveLeavesPeer } from "../../agents/tool-filter.js";
|
|
5
|
+
import { resourceFacesLeft } from "../mounted-mcp.js";
|
|
4
6
|
import { materializeA2aTools } from "../a2a.js";
|
|
5
7
|
import { deliverEngineNotice } from "../types.js";
|
|
6
8
|
import { RosterBuilder } from "../tool-roster.js";
|
|
@@ -24,8 +26,11 @@ export async function prepareProtocolTools(input) {
|
|
|
24
26
|
if (overPeer !== undefined) {
|
|
25
27
|
throw Object.assign(new Error(`MCP server name ${JSON.stringify(overPeer.name.slice(0, 40) + "…")} is ${overPeer.name.length} characters; a peer rides every roster row of its tools and the roster's bound on a name is ${TOOL_WIRE_NAME_MAX_CHARS}.`), { code: "config.tool_name_too_long" });
|
|
26
28
|
}
|
|
29
|
+
const serverReached = valveLeavesPeer(spec, toolFaceSnapshot.selector);
|
|
30
|
+
const leaves = valveLeaves(spec, toolFaceSnapshot.selector);
|
|
31
|
+
const resourcesReached = resourceFacesLeft(leaves);
|
|
27
32
|
const mcp = lockedPreflight.mcp?.length
|
|
28
|
-
? await materializeMcpTools(lockedPreflight.mcp, spec.principal, deps.onElicit, deps.mcpImageResizer, { reminderMark, counts: reminderDisclosureCounts }, mcpRevocationWiring(deps, runId), mcpPool === undefined ? undefined : { pool: mcpPool.pool, ownsPool: mcpPool.owned }, sectionDisposerOf(input.modBus, abortController.signal))
|
|
33
|
+
? await materializeMcpTools(lockedPreflight.mcp, spec.principal, deps.onElicit, deps.mcpImageResizer, { reminderMark, counts: reminderDisclosureCounts }, mcpRevocationWiring(deps, runId), mcpPool === undefined ? undefined : { pool: mcpPool.pool, ownsPool: mcpPool.owned }, sectionDisposerOf(input.modBus, abortController.signal), (entry) => resourcesReached || serverReached(mintNamespacePrefix(MCP_NAMESPACE, entry.name)))
|
|
29
34
|
:
|
|
30
35
|
{ tools: [], toolAxes: [], warnings: [], serverInstructions: [], instructionsDelta: { pendingAdds: [], pendingRemovals: [] }, droppedTools: [], statuses: [], refresh: async () => [], reconnect: async (server) => ({ server, prefix: mintNamespacePrefix(MCP_NAMESPACE, server), outcome: "not_declared", reason: "this task declared no MCP servers", toolCount: 0, added: [], removed: [] }), dispose: async () => { } };
|
|
31
36
|
if (lockedPreflight.mcp?.length)
|
|
@@ -69,7 +74,7 @@ export async function prepareProtocolTools(input) {
|
|
|
69
74
|
const rebuildHarnessToolsRef = {};
|
|
70
75
|
const contentOriginWrapRef = {};
|
|
71
76
|
const toolCallGateArmedRef = { armed: false };
|
|
72
|
-
const rosterApply = { toolFaceSnapshot, withFaces, remoteToolOffload, foldProtocolAxes: (axes, label) => foldProtocolAxes(axes, label), toolEffects, axisExplicitNegatives, roster };
|
|
77
|
+
const rosterApply = { spec, toolFaceSnapshot, withFaces, remoteToolOffload, foldProtocolAxes: (axes, label) => foldProtocolAxes(axes, label), toolEffects, axisExplicitNegatives, roster, declared: lockedPreflight.mcp ?? [], instructionsDelta: mcp.instructionsDelta };
|
|
73
78
|
const rosterCommit = { rebuildHarnessToolsRef, rosterSeat, toolCallGateArmedRef, irreversibleTools, egressTools };
|
|
74
79
|
const redialInput = { ...rosterApply, ...rosterCommit, mcp, deps, sessionId, runId, irreversibilityTier };
|
|
75
80
|
const mcpRedial = lockedPreflight.mcp?.length ? (server) => redialMcpServer(redialInput, server) : undefined;
|
|
@@ -88,14 +93,17 @@ export async function prepareProtocolTools(input) {
|
|
|
88
93
|
const lines = [];
|
|
89
94
|
let changed = false;
|
|
90
95
|
let anyActiveFailure = false;
|
|
96
|
+
const reported = [];
|
|
91
97
|
for (const r of results) {
|
|
92
98
|
if (r.tools === undefined) {
|
|
99
|
+
reported.push(settledOnRoster(r, rosterHolding(rosterApply, r.server), roster));
|
|
93
100
|
lines.push(`${r.server}: ${r.status}${r.error !== undefined ? ` (${r.error})` : ""}`);
|
|
94
101
|
if (r.status === "failed")
|
|
95
102
|
anyActiveFailure = true;
|
|
96
103
|
continue;
|
|
97
104
|
}
|
|
98
|
-
const applied = applyMcpRosterDelta(rosterApply, { server: r.server, prefix: r.prefix, tools: r.tools, axes: r.axes ?? [], dropped: r.dropped ?? [] });
|
|
105
|
+
const applied = applyMcpRosterDelta(rosterApply, { server: r.server, prefix: r.prefix, tools: r.tools, axes: r.axes ?? [], dropped: r.dropped ?? [], ...(r.instructions !== undefined ? { instructions: r.instructions } : {}) });
|
|
106
|
+
reported.push(settledOnRoster(r, applied, roster));
|
|
99
107
|
if (!applied.applied) {
|
|
100
108
|
lines.push(`${r.server}: failed (${applied.foldError})`);
|
|
101
109
|
anyActiveFailure = true;
|
|
@@ -103,16 +111,15 @@ export async function prepareProtocolTools(input) {
|
|
|
103
111
|
}
|
|
104
112
|
changed = true;
|
|
105
113
|
const detail = [];
|
|
106
|
-
|
|
107
|
-
|
|
108
|
-
|
|
109
|
-
|
|
110
|
-
detail.push(`removed: ${r.removed.join(", ")}`);
|
|
114
|
+
if (applied.added.length > 0)
|
|
115
|
+
detail.push(`added: ${applied.added.join(", ")}`);
|
|
116
|
+
if (applied.removed.length > 0)
|
|
117
|
+
detail.push(`removed: ${applied.removed.join(", ")}`);
|
|
111
118
|
if (applied.excluded.length > 0)
|
|
112
119
|
detail.push(`excluded by deployment config (not mounted): ${applied.excluded.join(", ")}`);
|
|
113
120
|
if ((r.dropped?.length ?? 0) > 0)
|
|
114
121
|
detail.push(`dropped: ${r.dropped.map((d) => `${d.tool} (${d.reason.length > 90 ? `${d.reason.slice(0, 90)}…` : d.reason})`).join("; ")}`);
|
|
115
|
-
lines.push(`${r.server}: refreshed — ${applied.
|
|
122
|
+
lines.push(`${r.server}: refreshed — ${applied.mounted.length} tool${applied.mounted.length === 1 ? "" : "s"}${detail.length > 0 ? ` (${detail.join("; ")})` : ""}`);
|
|
116
123
|
}
|
|
117
124
|
if (changed) {
|
|
118
125
|
const ungated = await commitMcpRosterChanges(rosterCommit);
|
|
@@ -122,7 +129,7 @@ export async function prepareProtocolTools(input) {
|
|
|
122
129
|
const text = lines.length === 0 ? "No connected MCP servers to refresh." : lines.join("\n");
|
|
123
130
|
return {
|
|
124
131
|
content: [{ type: "text", text }],
|
|
125
|
-
details: { results },
|
|
132
|
+
details: { results: reported },
|
|
126
133
|
terminate: false,
|
|
127
134
|
...(anyActiveFailure && !changed ? { isError: true } : {}),
|
|
128
135
|
};
|
|
@@ -157,7 +164,7 @@ export async function prepareProtocolTools(input) {
|
|
|
157
164
|
}
|
|
158
165
|
};
|
|
159
166
|
foldProtocolAxes(mcp.toolAxes, "MCP");
|
|
160
|
-
const a2aDeclared =
|
|
167
|
+
const a2aDeclared = lockedPreflight.a2a;
|
|
161
168
|
const a2a = a2aDeclared
|
|
162
169
|
? await materializeA2aTools(a2aDeclared, spec.principal, abortController.signal)
|
|
163
170
|
: { tools: [], toolAxes: [], warnings: [], statuses: [], refresh: async () => [], dispose: async () => { } };
|