@sema-agent/core 5.36.0 → 5.38.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 +124 -0
- package/dist/agents/subagent.d.ts +10 -0
- package/dist/agents/subagent.js +6 -0
- package/dist/agents/teacher.js +3 -0
- package/dist/agents/team.d.ts +7 -1
- package/dist/agents/team.js +11 -9
- package/dist/agents/verify.js +3 -0
- package/dist/core/auto-mode-prompt-assets.d.ts +5 -3
- package/dist/core/auto-mode-prompt-assets.js +1 -1
- package/dist/core/checkpoint-store.d.ts +26 -1
- package/dist/core/governance-codes.js +4 -0
- package/dist/core/hooks.d.ts +129 -2
- package/dist/core/hooks.js +20 -3
- package/dist/core/memory-engine/engine.d.ts +142 -0
- package/dist/core/memory-engine/engine.js +264 -2
- package/dist/core/memory-engine/file-backend.d.ts +490 -16
- package/dist/core/memory-engine/file-backend.js +1099 -36
- package/dist/core/memory-engine/index.d.ts +2 -2
- package/dist/core/memory-engine/index.js +1 -1
- package/dist/core/memory-engine/layout.d.ts +42 -2
- package/dist/core/memory-engine/layout.js +76 -12
- package/dist/core/memory-engine/memory-backend-contract.d.ts +13 -0
- package/dist/core/memory-engine/memory-backend-contract.js +89 -0
- package/dist/core/protocol-table.d.ts +4 -4
- package/dist/core/runner/assemble-result.d.ts +5 -0
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/prepare-config-doors.d.ts +17 -0
- package/dist/core/runner/prepare-config-doors.js +33 -2
- package/dist/core/runner/prepare-memory.d.ts +11 -1
- package/dist/core/runner/prepare-memory.js +48 -2
- package/dist/core/runner/prepare-task.d.ts +22 -2
- package/dist/core/runner/prepare-task.js +125 -42
- package/dist/core/runner/runtask.js +50 -11
- package/dist/core/tool-model-gate.d.ts +125 -0
- package/dist/core/tool-model-gate.js +303 -0
- package/dist/core/tool-policy.d.ts +1 -1
- package/dist/core/types.d.ts +284 -1
- package/dist/core/types.js +21 -0
- package/dist/core/untrusted-text.d.ts +1 -1
- package/dist/index.d.ts +5 -4
- package/dist/index.js +3 -2
- package/dist/orchestration/builtin-workflows.d.ts +68 -6
- package/dist/orchestration/builtin-workflows.js +26 -9
- package/dist/orchestration/run-workflow-tool.d.ts +10 -1
- package/dist/orchestration/run-workflow-tool.js +70 -27
- package/dist/orchestration/workflow-script-store.d.ts +8 -3
- package/dist/prompts/coordinator.d.ts +4 -1
- package/dist/prompts/coordinator.js +8 -0
- package/dist/prompts/default.d.ts +14 -4
- package/dist/prompts/default.js +2 -1
- package/dist/scenarios/full-body.d.ts +5 -0
- package/dist/scenarios/full-body.js +8 -4
- package/dist/tools/fs/fs-shared.d.ts +3 -2
- package/dist/tools/fs/fs-shared.js +19 -9
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +24 -1
|
@@ -12,12 +12,16 @@ export async function prepareMemory(input) {
|
|
|
12
12
|
const memorySpec = normalizeMemorySpec(spec.memory);
|
|
13
13
|
let admittedOrgScopes = [];
|
|
14
14
|
let ownOrgVerdict;
|
|
15
|
+
const deploymentScopeSet = new Set(deps.deploymentMemoryScopes ?? []);
|
|
16
|
+
const scopeOriginsSnapshot = memorySpec?.scopeOrigins !== undefined ? { ...memorySpec.scopeOrigins } : undefined;
|
|
17
|
+
if (memorySpec && scopeOriginsSnapshot !== undefined)
|
|
18
|
+
memorySpec.scopeOrigins = scopeOriginsSnapshot;
|
|
15
19
|
if (memorySpec && memorySpec.enabled && deps.memoryBackend) {
|
|
16
20
|
const outcome = await admitMemoryScopes({
|
|
17
21
|
memorySpec,
|
|
18
22
|
principal: spec.principal,
|
|
19
23
|
admission: deps.memoryScopeAdmission,
|
|
20
|
-
deploymentScopes:
|
|
24
|
+
deploymentScopes: deploymentScopeSet,
|
|
21
25
|
orgMemoryDenied: admissionCtx.orgMemoryDenied,
|
|
22
26
|
complianceDegraded: admissionCtx.complianceDegraded,
|
|
23
27
|
parentAdmittedOrgScopes: admissionCtx.parentAdmittedOrgScopes,
|
|
@@ -38,6 +42,15 @@ export async function prepareMemory(input) {
|
|
|
38
42
|
const useMemoryEngine = Boolean(memorySpec && memorySpec.enabled && deps.memoryBackend);
|
|
39
43
|
let memoryEngineSession;
|
|
40
44
|
let memoryTools;
|
|
45
|
+
let effectiveMemoryScopes;
|
|
46
|
+
const originOf = (scope) => scopeOriginsSnapshot !== undefined
|
|
47
|
+
? scopeOriginsSnapshot[scope] === "deployment"
|
|
48
|
+
? "deployment"
|
|
49
|
+
: "request"
|
|
50
|
+
: deploymentScopeSet.has(scope)
|
|
51
|
+
? "deployment"
|
|
52
|
+
: "request";
|
|
53
|
+
const materializedResidue = [];
|
|
41
54
|
if (useMemoryEngine && memorySpec) {
|
|
42
55
|
try {
|
|
43
56
|
const backend = deps.memoryBackend;
|
|
@@ -133,6 +146,12 @@ export async function prepareMemory(input) {
|
|
|
133
146
|
b)
|
|
134
147
|
: (b.retrievalView?.() ?? b);
|
|
135
148
|
const planeScopes = (scopes, write) => [...new Set([...scopes, ...(write !== null ? [write] : [])])];
|
|
149
|
+
const mountedScopeRows = (dual
|
|
150
|
+
? [
|
|
151
|
+
...planeScopes(planes.project, planes.writePlane === "project" ? memorySpec.writeScope : null),
|
|
152
|
+
...planeScopes(planes.personal, planes.writePlane === "personal" ? memorySpec.writeScope : null),
|
|
153
|
+
]
|
|
154
|
+
: planeScopes(memorySpec.scopes, memorySpec.writeScope)).map((scope) => ({ scope, origin: originOf(scope) }));
|
|
136
155
|
const pollutedOpts = (engine) => {
|
|
137
156
|
const rec = engine.sessionPollution(sessionId);
|
|
138
157
|
return rec !== undefined ? { polluted: { reason: rec.reason } } : {};
|
|
@@ -179,7 +198,9 @@ export async function prepareMemory(input) {
|
|
|
179
198
|
const personalEngine = personal.engine;
|
|
180
199
|
const p = planes;
|
|
181
200
|
const projectHandle = await projectEngine.materialize(p.project, p.writePlane === "project" ? memorySpec.writeScope : null, { adoptionRestricted });
|
|
201
|
+
materializedResidue.push(...planeScopes(p.project, p.writePlane === "project" ? memorySpec.writeScope : null));
|
|
182
202
|
const personalHandle = await personalEngine.materialize(p.personal, p.writePlane === "personal" ? memorySpec.writeScope : null, { adoptionRestricted });
|
|
203
|
+
materializedResidue.push(...planeScopes(p.personal, p.writePlane === "personal" ? memorySpec.writeScope : null));
|
|
183
204
|
const writeIsPersonal = p.writePlane === "personal";
|
|
184
205
|
writeEngine = writeIsPersonal ? personalEngine : projectEngine;
|
|
185
206
|
writeHandle = writeIsPersonal ? personalHandle : projectHandle;
|
|
@@ -222,6 +243,7 @@ export async function prepareMemory(input) {
|
|
|
222
243
|
const personal = createPersonalEngine(choosePersonalBackend());
|
|
223
244
|
const personalEngine = personal.engine;
|
|
224
245
|
const handle = await personalEngine.materialize(memorySpec.scopes, memorySpec.writeScope, { adoptionRestricted });
|
|
246
|
+
materializedResidue.push(...planeScopes(memorySpec.scopes, memorySpec.writeScope));
|
|
225
247
|
writeEngine = personalEngine;
|
|
226
248
|
writeHandle = handle;
|
|
227
249
|
injectFn = () => personalEngine.inject(handle, { writeToolMounted: input.writeToolsMounted });
|
|
@@ -243,6 +265,7 @@ export async function prepareMemory(input) {
|
|
|
243
265
|
onIncident: onEngineIncident,
|
|
244
266
|
});
|
|
245
267
|
const handle = await engine.materialize(memorySpec.scopes, memorySpec.writeScope, { adoptionRestricted });
|
|
268
|
+
materializedResidue.push(...planeScopes(memorySpec.scopes, memorySpec.writeScope));
|
|
246
269
|
writeEngine = engine;
|
|
247
270
|
writeHandle = handle;
|
|
248
271
|
injectFn = () => engine.inject(handle, { writeToolMounted: input.writeToolsMounted });
|
|
@@ -311,6 +334,12 @@ export async function prepareMemory(input) {
|
|
|
311
334
|
execIsExternalContent: memorySpec.execIsExternalContent === true,
|
|
312
335
|
},
|
|
313
336
|
};
|
|
337
|
+
effectiveMemoryScopes = {
|
|
338
|
+
state: "mounted",
|
|
339
|
+
contract: memorySpec.scopeContract === "v2" ? "v2" : "legacy",
|
|
340
|
+
scopes: mountedScopeRows,
|
|
341
|
+
writeScope: memorySpec.writeScope,
|
|
342
|
+
};
|
|
314
343
|
if (input.memorySearchToolsPlanned)
|
|
315
344
|
memoryTools = createMemoryEngineTools({ planes: toolPlanes });
|
|
316
345
|
}
|
|
@@ -322,6 +351,16 @@ export async function prepareMemory(input) {
|
|
|
322
351
|
throw err;
|
|
323
352
|
}
|
|
324
353
|
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "memory", sessionId });
|
|
354
|
+
if (effectiveMemoryScopes === undefined) {
|
|
355
|
+
effectiveMemoryScopes = {
|
|
356
|
+
state: "memoryless",
|
|
357
|
+
reason: "mount-failed",
|
|
358
|
+
contract: memorySpec.scopeContract === "v2" ? "v2" : "legacy",
|
|
359
|
+
scopes: [],
|
|
360
|
+
writeScope: null,
|
|
361
|
+
...(materializedResidue.length > 0 ? { materializedResidue: [...new Set(materializedResidue)] } : {}),
|
|
362
|
+
};
|
|
363
|
+
}
|
|
325
364
|
}
|
|
326
365
|
}
|
|
327
366
|
let memoryBlock;
|
|
@@ -359,5 +398,12 @@ export async function prepareMemory(input) {
|
|
|
359
398
|
if (memoryBlock !== undefined && injection.indexSeed !== undefined && input.rosterCanPersist)
|
|
360
399
|
seedFiles = [injection.indexSeed];
|
|
361
400
|
}
|
|
362
|
-
|
|
401
|
+
if (effectiveMemoryScopes === undefined) {
|
|
402
|
+
effectiveMemoryScopes = memorySpec
|
|
403
|
+
? memorySpec.enabled
|
|
404
|
+
? { state: "memoryless", reason: "no-backend", contract: memorySpec.scopeContract === "v2" ? "v2" : "legacy", scopes: [], writeScope: null }
|
|
405
|
+
: { state: "none", reason: "disabled", scopes: [], writeScope: null }
|
|
406
|
+
: { state: "none", reason: "no-spec", scopes: [], writeScope: null };
|
|
407
|
+
}
|
|
408
|
+
return { memoryEngineSession, memoryBlock, admittedOrgScopes, ownOrgVerdict, effectiveMemoryScopes, ...(memoryTools !== undefined ? { memoryTools } : {}), ...(seedFiles !== undefined ? { seedFiles } : {}) };
|
|
363
409
|
}
|
|
@@ -11,7 +11,7 @@ import { SubagentRetainLedger } from "../../agents/retain-ledger.js";
|
|
|
11
11
|
import type { OnAsk, ToolCallRequest, ToolPolicy } from "../tool-policy.js";
|
|
12
12
|
import { type ActiveSkillFrame } from "./active-skill-scope.js";
|
|
13
13
|
import type { SessionPermissionRules } from "../session-policy-store.js";
|
|
14
|
-
import { type Hooks, type OrgGateVerdict } from "../hooks.js";
|
|
14
|
+
import { type Hooks, type HookInvocationIdentity, type OrgGateVerdict } from "../hooks.js";
|
|
15
15
|
import type { RecoveredOrphan } from "../session-reconcile.js";
|
|
16
16
|
import { CacheBreakDetector, type ToolFingerprintInput } from "../cache-break-detector.js";
|
|
17
17
|
import { type BrainCallGuardrailRef } from "../../brain/timeout.js";
|
|
@@ -29,8 +29,14 @@ import { type WiringManifest } from "../wiring-manifest.js";
|
|
|
29
29
|
import type { ActiveWorktreeSession, AgentMessage, AgentTool, ExecutionEnv } from "../../internal/harness.js";
|
|
30
30
|
import type { NestedUsageAccum, RunnerDeps, TaskEvent, TaskResult, TaskSpec, ToolActivity, ToolEffect } from "../types.js";
|
|
31
31
|
import type { RepairBundle } from "../../agents/repair-loop.js";
|
|
32
|
-
/** Test seam (mirrors `
|
|
32
|
+
/** Test seam (mirrors `__resetToolModelGateAnnouncements`): never called by production code.
|
|
33
|
+
* Re-arms BOTH arms (a WeakMap has no clear — it is re-minted). */
|
|
33
34
|
export declare function __resetMaterializeEnvAnnouncements(): void;
|
|
35
|
+
/** Test seam (mirrors `__resetMaterializeEnvAnnouncements`): never called by production code.
|
|
36
|
+
* Re-arms BOTH arms (a WeakMap has no clear — it is re-minted). Deliberately UNLIKE the read-face
|
|
37
|
+
* seam below (console latch only): tests here legitimately reuse ONE sink across prepares to pin
|
|
38
|
+
* the per-sink dedup itself, so the seam must be able to re-arm a still-referenced sink. */
|
|
39
|
+
export declare function __resetToolModelGateAnnouncements(): void;
|
|
34
40
|
/** Test seam (mirrors `__resetMalformedNoticeSeatAnnouncement`): never called by production code.
|
|
35
41
|
* Deliberately asymmetric — it resets only the console latch: the WeakSet arm needs no seam
|
|
36
42
|
* because a test resets it by minting a fresh sink function (identity IS the ledger key), while
|
|
@@ -205,6 +211,11 @@ export interface Prepared {
|
|
|
205
211
|
* excluded), echoed on `TaskResult.effectiveReadDenyPatterns`. Present iff non-empty; a defensive
|
|
206
212
|
* copy (the wide-scope working array stays the engine's own). */
|
|
207
213
|
effectiveReadDenyPatterns?: readonly import("../../tools/fs/read-deny.js").NormalizedReadDenyEntry[];
|
|
214
|
+
/** design/178 v2 §2.3 (件①) — the memory-visibility observation prepareMemory minted (echoed on
|
|
215
|
+
* `TaskResult.effectiveMemoryScopes`). Always present on a completed prepare (the memory-less
|
|
216
|
+
* states are their own values); the seat is optional only so a Prepared shape without the phase
|
|
217
|
+
* cannot fabricate one. */
|
|
218
|
+
effectiveMemoryScopes?: import("../types.js").EffectiveMemoryScopes;
|
|
208
219
|
/** design/99 §E13 — the per-task logical cwd ref when a real shell is mounted (else undefined). The Runner
|
|
209
220
|
* reads `cwdRef.current` after each tool to detect a `cd` move and emit `workspace_changed`. */
|
|
210
221
|
cwdRef?: CwdRef;
|
|
@@ -274,6 +285,15 @@ export interface Prepared {
|
|
|
274
285
|
* model/tool interaction. Host/operator plane — never enters model context.
|
|
275
286
|
*/
|
|
276
287
|
wiringManifest: WiringManifest;
|
|
288
|
+
/**
|
|
289
|
+
* #281 件A — this leg's frozen identity envelope, minted ONCE in prepare beside the wiring
|
|
290
|
+
* manifest (same leg derivation, one mint — {@link mintHookInvocationIdentity}). Every hook
|
|
291
|
+
* station runtask drives (stop/stopFailure/userPromptSubmit/postToolBatch, the compaction
|
|
292
|
+
* wrapper) and the 件B delegation-lifecycle observer read THIS object; prepare's own stations
|
|
293
|
+
* (the tool gate, the post-tool contexts) close over the same const. Always present — a prepared
|
|
294
|
+
* leg always knows its identity.
|
|
295
|
+
*/
|
|
296
|
+
hookIdentity: HookInvocationIdentity;
|
|
277
297
|
promptManifest: {
|
|
278
298
|
constitution: "core" | "replaced" | "provider-assembled";
|
|
279
299
|
blocks: Array<{
|
|
@@ -29,7 +29,7 @@ import { inlineUntrusted } from "../untrusted-text.js";
|
|
|
29
29
|
import { policyAskClassOf } from "../ask-class.js";
|
|
30
30
|
import { emitTrace } from "../trace.js";
|
|
31
31
|
import { createSessionRulePolicy } from "./session-rule-policy.js";
|
|
32
|
-
import { cloneObserverInput, createHookEnvCapabilities, createPreToolUseConstraintPolicy, formatHookFeedback, persistedRuleMandateOf, runToolGate } from "../hooks.js";
|
|
32
|
+
import { cloneObserverInput, createHookEnvCapabilities, createPreToolUseConstraintPolicy, formatHookFeedback, mintHookInvocationIdentity, persistedRuleMandateOf, runToolGate } from "../hooks.js";
|
|
33
33
|
import { orgRuleVerdictFor } from "../permission-rule-org.js";
|
|
34
34
|
import { CacheBreakDetector, toolsToFingerprintInputs } from "../cache-break-detector.js";
|
|
35
35
|
import { reservedCollisions, reservedFor } from "../../brain/request-params.js";
|
|
@@ -92,13 +92,104 @@ import { countElicitOptIns, deriveWiringManifest, resolveAskSeamForm, resolveDec
|
|
|
92
92
|
import { durableParkGapFor } from "../park-selfcheck.js";
|
|
93
93
|
import { GLOBAL_USAGE_KEY, usageRetryAfterMs } from "../usage-window-store.js";
|
|
94
94
|
import { deliverEngineNotice } from "../types.js";
|
|
95
|
-
|
|
95
|
+
let announcedMaterializeEnvBySink = new WeakMap();
|
|
96
|
+
const announcedMaterializeEnvConsole = new Set();
|
|
97
|
+
function materializeEnvLedger(onNotice) {
|
|
98
|
+
if (typeof onNotice !== "function")
|
|
99
|
+
return announcedMaterializeEnvConsole;
|
|
100
|
+
let lines = announcedMaterializeEnvBySink.get(onNotice);
|
|
101
|
+
if (lines === undefined) {
|
|
102
|
+
lines = new Set();
|
|
103
|
+
announcedMaterializeEnvBySink.set(onNotice, lines);
|
|
104
|
+
}
|
|
105
|
+
return lines;
|
|
106
|
+
}
|
|
96
107
|
export function __resetMaterializeEnvAnnouncements() {
|
|
97
|
-
|
|
108
|
+
announcedMaterializeEnvBySink = new WeakMap();
|
|
109
|
+
announcedMaterializeEnvConsole.clear();
|
|
98
110
|
}
|
|
99
111
|
function emitMaterializeEnvNotice(onNotice, message, detail) {
|
|
112
|
+
const ledger = materializeEnvLedger(onNotice);
|
|
113
|
+
if (ledger.has(message))
|
|
114
|
+
return;
|
|
115
|
+
ledger.add(message);
|
|
100
116
|
deliverEngineNotice(onNotice, { code: "config.materialize_env_discarded", message, detail });
|
|
101
117
|
}
|
|
118
|
+
function warnCompactionWindowHazard(tracer, spec, model, compModel, hostTaskId) {
|
|
119
|
+
if (compModel === undefined)
|
|
120
|
+
return;
|
|
121
|
+
const compWindow = compModel.contextTokens ?? compModel.contextWindow;
|
|
122
|
+
const mainWindow = model.autoCompactTokens ?? model.contextTokens ?? model.contextWindow;
|
|
123
|
+
if (compWindow > 0 && mainWindow > 0 && compWindow < mainWindow) {
|
|
124
|
+
const merged = { ...DEFAULT_COMPACTION_SETTINGS, ...spec.compaction };
|
|
125
|
+
const sanitized = sanitizeCompactionSettings(merged, mainWindow);
|
|
126
|
+
const tolerance = sanitized.clampTolerance ?? DEFAULT_CLAMP_TOLERANCE;
|
|
127
|
+
const headroom = Math.max(0, compWindow - Math.max(Math.floor(0.8 * summaryOutputBudgetTokens(compModel, sanitized)), 2048) - 512);
|
|
128
|
+
emitTrace(tracer, () => ({
|
|
129
|
+
kind: "compaction.window_config_warning",
|
|
130
|
+
version: 1,
|
|
131
|
+
taskId: hostTaskId,
|
|
132
|
+
compactionModelWindow: compWindow,
|
|
133
|
+
mainModelWindow: mainWindow,
|
|
134
|
+
...(tolerance < 1 ? { fallbackAt: Math.floor(headroom / (1 - tolerance)) } : {}),
|
|
135
|
+
ts: Date.now(),
|
|
136
|
+
}));
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
let announcedToolModelGateBySink = new WeakMap();
|
|
140
|
+
const announcedToolModelGateConsole = new Set();
|
|
141
|
+
function toolModelGateLedger(onNotice) {
|
|
142
|
+
if (typeof onNotice !== "function")
|
|
143
|
+
return announcedToolModelGateConsole;
|
|
144
|
+
let lines = announcedToolModelGateBySink.get(onNotice);
|
|
145
|
+
if (lines === undefined) {
|
|
146
|
+
lines = new Set();
|
|
147
|
+
announcedToolModelGateBySink.set(onNotice, lines);
|
|
148
|
+
}
|
|
149
|
+
return lines;
|
|
150
|
+
}
|
|
151
|
+
export function __resetToolModelGateAnnouncements() {
|
|
152
|
+
announcedToolModelGateBySink = new WeakMap();
|
|
153
|
+
announcedToolModelGateConsole.clear();
|
|
154
|
+
}
|
|
155
|
+
function announceToolModelGate(onNotice, modelId, gate) {
|
|
156
|
+
const ledger = toolModelGateLedger(onNotice);
|
|
157
|
+
for (const [gateClass, removed] of gate.removedByClass) {
|
|
158
|
+
const line = `Model gate: default-mounted tool(s) ${removed.map((n) => JSON.stringify(n)).join(", ")} (class ${JSON.stringify(gateClass)}) ` +
|
|
159
|
+
`were not mounted for model ${JSON.stringify(modelId)} — the gate table marks this model as managing multi-step work without the scaffold. ` +
|
|
160
|
+
`Explicitly composed tools are exempt; restore via TaskSpec.restoreGatedTools, SEMA_TOOL_MODEL_GATE=off, or RunnerDeps.toolModelGate: false.`;
|
|
161
|
+
if (!ledger.has(line)) {
|
|
162
|
+
ledger.add(line);
|
|
163
|
+
deliverEngineNotice(onNotice, {
|
|
164
|
+
code: "config.tool_model_gate_removed",
|
|
165
|
+
message: line,
|
|
166
|
+
detail: {
|
|
167
|
+
modelId,
|
|
168
|
+
gateClass,
|
|
169
|
+
removed: [...removed],
|
|
170
|
+
restore: { spec: "TaskSpec.restoreGatedTools", env: "SEMA_TOOL_MODEL_GATE=off", deps: "RunnerDeps.toolModelGate: false" },
|
|
171
|
+
},
|
|
172
|
+
});
|
|
173
|
+
}
|
|
174
|
+
}
|
|
175
|
+
for (const gateClass of gate.unknownClasses) {
|
|
176
|
+
const line = `ToolSpec.modelGate names gate class ${JSON.stringify(gateClass)}, which no row of the merged gate table defines — the tag is inert ` +
|
|
177
|
+
`(fail-open: the tool stays mounted). Fix the tag, or define the class via RunnerDeps.toolModelGate.classes.`;
|
|
178
|
+
if (!ledger.has(line)) {
|
|
179
|
+
ledger.add(line);
|
|
180
|
+
deliverEngineNotice(onNotice, { code: "config.tool_model_gate_unknown_class", message: line, detail: { gateClass } });
|
|
181
|
+
}
|
|
182
|
+
}
|
|
183
|
+
if (gate.discardedEnvRaw !== undefined) {
|
|
184
|
+
const line = `SEMA_TOOL_MODEL_GATE=${JSON.stringify(gate.discardedEnvRaw)} is not in the closed set (on|1|true|off|0|false, case-insensitive) — ` +
|
|
185
|
+
`not in force on this task (nothing the model gate would remove), but a task where the gate WOULD trim a default-mounted tool ` +
|
|
186
|
+
`will refuse to prepare under it (config.tool_model_gate_env_invalid). Fix or unset the flag.`;
|
|
187
|
+
if (!ledger.has(line)) {
|
|
188
|
+
ledger.add(line);
|
|
189
|
+
deliverEngineNotice(onNotice, { code: "config.tool_model_gate_env_invalid", message: line, detail: { raw: gate.discardedEnvRaw } });
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
}
|
|
102
193
|
const readFaceClampAnnouncedSinks = new WeakSet();
|
|
103
194
|
let readFaceClampConsoleAnnounced = false;
|
|
104
195
|
export function __resetReadFaceClampAnnouncement() {
|
|
@@ -153,8 +244,9 @@ export { rebaseWorkspacePath, rebaseWorkspacePathAcross } from "./prepare-worksp
|
|
|
153
244
|
function hasConversationContent(branch) {
|
|
154
245
|
return branch.some((e) => e.type === "message" || e.type === "custom_message" || e.type === "compaction");
|
|
155
246
|
}
|
|
156
|
-
function
|
|
157
|
-
|
|
247
|
+
function effectiveDelegationFacts(internals, seedIsDelegatedChild) {
|
|
248
|
+
const isDelegatedChild = internals?.isDelegatedChild !== undefined ? internals.isDelegatedChild === true : seedIsDelegatedChild === true;
|
|
249
|
+
return { isDelegatedChild, isNonForkChild: isDelegatedChild && internals?.insideFork !== true };
|
|
158
250
|
}
|
|
159
251
|
export function batchContextAt(messages, currentId) {
|
|
160
252
|
let batch = [];
|
|
@@ -238,6 +330,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
238
330
|
const doors = prepareConfigDoors({ spec, deps, sessions, resume, internals });
|
|
239
331
|
spec = doors.spec;
|
|
240
332
|
const { toolFaceSnapshot, promptProfile, lockedPreflight, resolvedInteractionPosture, resolvedRole, model, thinking, compModel, fableMitigations, usageWindows, brainCallGuardrailRef, brainCallGuardrailMs } = doors;
|
|
333
|
+
announceToolModelGate(deps.onNotice, model.id, doors.modelGate);
|
|
241
334
|
const { toolEffects, egressTools, irreversibleTools, irreversibilityTier, axisExplicitNegatives, reversibilityProbes, ownToolNames } = prepareSafetyScan({ spec, deps });
|
|
242
335
|
let shellGatedBash = false;
|
|
243
336
|
let shellGatedMonitor = false;
|
|
@@ -249,25 +342,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
249
342
|
const { acquired, session, conflictRef, wakeRecovered, resumeAtBeforeParentId } = await prepareAcquireReconcile({ sessions, spec, resume, toolEffects, ...(() => { const g = durableParkGapFor(deps, spec); return g !== undefined ? { durableParkGap: g } : {}; })() });
|
|
250
343
|
const sessionId = acquired.sessionId;
|
|
251
344
|
const hostTaskId = spec.taskId ?? sessionId;
|
|
252
|
-
|
|
253
|
-
|
|
254
|
-
const mainWindow = model.autoCompactTokens ?? model.contextTokens ?? model.contextWindow;
|
|
255
|
-
if (compWindow > 0 && mainWindow > 0 && compWindow < mainWindow) {
|
|
256
|
-
const merged = { ...DEFAULT_COMPACTION_SETTINGS, ...spec.compaction };
|
|
257
|
-
const sanitized = sanitizeCompactionSettings(merged, mainWindow);
|
|
258
|
-
const tolerance = sanitized.clampTolerance ?? DEFAULT_CLAMP_TOLERANCE;
|
|
259
|
-
const headroom = Math.max(0, compWindow - Math.max(Math.floor(0.8 * summaryOutputBudgetTokens(compModel, sanitized)), 2048) - 512);
|
|
260
|
-
emitTrace(deps.tracer, () => ({
|
|
261
|
-
kind: "compaction.window_config_warning",
|
|
262
|
-
version: 1,
|
|
263
|
-
taskId: hostTaskId,
|
|
264
|
-
compactionModelWindow: compWindow,
|
|
265
|
-
mainModelWindow: mainWindow,
|
|
266
|
-
...(tolerance < 1 ? { fallbackAt: Math.floor(headroom / (1 - tolerance)) } : {}),
|
|
267
|
-
ts: Date.now(),
|
|
268
|
-
}));
|
|
269
|
-
}
|
|
270
|
-
}
|
|
345
|
+
const delegation = effectiveDelegationFacts(internals, resume?.seed.isDelegatedChild);
|
|
346
|
+
warnCompactionWindowHazard(deps.tracer, spec, model, compModel, hostTaskId);
|
|
271
347
|
const taskScope = internals?.registryScope ?? spec.principal ?? "default";
|
|
272
348
|
internals?.peerSelfRef?.addAxis("s", sessionId);
|
|
273
349
|
internals?.peerSelfRef?.addAxis("t", hostTaskId);
|
|
@@ -705,6 +781,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
705
781
|
excludeTools: toolFaceSnapshot.exclude,
|
|
706
782
|
deferTools: toolFaceSnapshot.defer,
|
|
707
783
|
alwaysLoadTools: toolFaceSnapshot.alwaysLoad,
|
|
784
|
+
...(toolFaceSnapshot.restoreGated !== undefined ? { restoreGatedTools: toolFaceSnapshot.restoreGated } : {}),
|
|
708
785
|
promptProfile,
|
|
709
786
|
...(spec.additionalDirectories !== undefined ? { additionalDirectories: Object.freeze([...spec.additionalDirectories]) } : {}),
|
|
710
787
|
...(spec.additionalReadDirectories !== undefined ? { additionalReadDirectories: Object.freeze([...spec.additionalReadDirectories]) } : {}),
|
|
@@ -876,6 +953,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
876
953
|
parentExcludeTools: toolFaceSnapshot.exclude,
|
|
877
954
|
parentDeferTools: toolFaceSnapshot.defer,
|
|
878
955
|
parentAlwaysLoadTools: toolFaceSnapshot.alwaysLoad,
|
|
956
|
+
...(toolFaceSnapshot.restoreGated !== undefined ? { parentRestoreGatedTools: toolFaceSnapshot.restoreGated } : {}),
|
|
879
957
|
parentPromptProfile: promptProfile,
|
|
880
958
|
models: deps.models,
|
|
881
959
|
agents: deps.agents,
|
|
@@ -1555,7 +1633,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1555
1633
|
const memoryPairExcludedName = MEMORY_ENGINE_TOOL_NAMES.find((n) => (toolFaceSnapshot.exclude ?? []).includes(n));
|
|
1556
1634
|
const memoryPairOccupiedName = MEMORY_ENGINE_TOOL_NAMES.find((n) => memoryPairNameDomain.has(n));
|
|
1557
1635
|
const memorySearchToolsPlanned = memoryPairExcludedName === undefined && memoryPairOccupiedName === undefined;
|
|
1558
|
-
const { memoryEngineSession, memoryBlock: memoryBlockFromEngine, memoryTools, seedFiles: memorySeedFiles, admittedOrgScopes: memoryAdmittedOrgScopes, ownOrgVerdict: memoryOwnOrgVerdict, } = await prepareMemory({
|
|
1636
|
+
const { memoryEngineSession, memoryBlock: memoryBlockFromEngine, memoryTools, seedFiles: memorySeedFiles, admittedOrgScopes: memoryAdmittedOrgScopes, ownOrgVerdict: memoryOwnOrgVerdict, effectiveMemoryScopes: memoryEffectiveScopes, } = await prepareMemory({
|
|
1559
1637
|
spec,
|
|
1560
1638
|
deps,
|
|
1561
1639
|
sessionId,
|
|
@@ -1581,7 +1659,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1581
1659
|
orgMemoryDenied: complianceDenies.has("org_memory_mount"),
|
|
1582
1660
|
complianceDegraded,
|
|
1583
1661
|
parentAdmittedOrgScopes: foldAdmissionFreeze({
|
|
1584
|
-
delegated:
|
|
1662
|
+
delegated: delegation.isDelegatedChild ||
|
|
1585
1663
|
internals?.inheritedGate !== undefined ||
|
|
1586
1664
|
(resume?.seed.inheritedGate !== undefined &&
|
|
1587
1665
|
(resume.seed.inheritedGate.ancestorRules !== undefined ||
|
|
@@ -1650,7 +1728,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1650
1728
|
loaded = await Promise.resolve(deps.loadProjectMemory({
|
|
1651
1729
|
cwd: taskRootFinal,
|
|
1652
1730
|
handsEnabled,
|
|
1653
|
-
isSubagent:
|
|
1731
|
+
isSubagent: delegation.isNonForkChild,
|
|
1654
1732
|
...(internals?.agentName ? { agentName: internals.agentName } : {}),
|
|
1655
1733
|
sessionId,
|
|
1656
1734
|
phase: projectMemoryPhase,
|
|
@@ -1775,7 +1853,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1775
1853
|
awarenessEnabled: thinking !== undefined && ULTRA_REASONING_TIERS.has(thinking),
|
|
1776
1854
|
worktreeIsolated: internals?.isolation === "worktree" && ownedEnv !== undefined,
|
|
1777
1855
|
withinTaskCompactionEnabled: (spec.compaction?.enabled ?? true) && (spec.compaction?.withinTask ?? true),
|
|
1778
|
-
isSubagent:
|
|
1856
|
+
isSubagent: delegation.isNonForkChild,
|
|
1779
1857
|
};
|
|
1780
1858
|
const userSystemPrompt = spec.systemPrompt ?? resolvedRole.systemPrompt ?? internals?.defaultSystemPrompt;
|
|
1781
1859
|
const userAppendSystemPrompt = spec.appendSystemPrompt;
|
|
@@ -2209,10 +2287,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2209
2287
|
const raw = process.env.SEMA_TOOL_MATERIALIZE_STRATEGY;
|
|
2210
2288
|
if (raw !== undefined && raw !== "swap" && raw !== "static" && deferred.size === 0) {
|
|
2211
2289
|
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.`;
|
|
2212
|
-
|
|
2213
|
-
announcedMaterializeEnv.add(line);
|
|
2214
|
-
emitMaterializeEnvNotice(deps.onNotice, line, { raw });
|
|
2215
|
-
}
|
|
2290
|
+
emitMaterializeEnvNotice(deps.onNotice, line, { raw });
|
|
2216
2291
|
}
|
|
2217
2292
|
}
|
|
2218
2293
|
if (deferred.size > 0) {
|
|
@@ -2231,10 +2306,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2231
2306
|
}
|
|
2232
2307
|
if (envStrategyInvalid) {
|
|
2233
2308
|
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.`;
|
|
2234
|
-
|
|
2235
|
-
announcedMaterializeEnv.add(line);
|
|
2236
|
-
emitMaterializeEnvNotice(deps.onNotice, line, { raw: rawEnvStrategy, specStrategy: spec.toolMaterializeStrategy });
|
|
2237
|
-
}
|
|
2309
|
+
emitMaterializeEnvNotice(deps.onNotice, line, { raw: rawEnvStrategy, specStrategy: spec.toolMaterializeStrategy });
|
|
2238
2310
|
}
|
|
2239
2311
|
const envStrategy = envStrategyInvalid ? undefined : rawEnvStrategy;
|
|
2240
2312
|
const requestedStrategy = spec.toolMaterializeStrategy ?? envStrategy ?? "swap";
|
|
@@ -2785,7 +2857,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2785
2857
|
...((internals?.explicitAgentName ?? internals?.agentName) !== undefined
|
|
2786
2858
|
? { sourceAgentName: internals?.explicitAgentName ?? internals?.agentName }
|
|
2787
2859
|
: {}),
|
|
2788
|
-
...(
|
|
2860
|
+
...(delegation.isDelegatedChild ? { isDelegatedChild: true } : {}),
|
|
2789
2861
|
});
|
|
2790
2862
|
const riskAxesOf = (toolName) => {
|
|
2791
2863
|
const tier = irreversibilityTier.get(toolName);
|
|
@@ -3347,6 +3419,15 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3347
3419
|
retentionPolicyWired: deps.retentionPolicy !== undefined,
|
|
3348
3420
|
});
|
|
3349
3421
|
const parkLaneArmed = wiringManifest.parkLane.effective === true;
|
|
3422
|
+
const hookIdentity = mintHookInvocationIdentity({
|
|
3423
|
+
sessionId,
|
|
3424
|
+
taskId: spec.taskId ?? sessionId,
|
|
3425
|
+
legKind: wiringManifest.leg.kind,
|
|
3426
|
+
isDelegatedChild: delegation.isDelegatedChild,
|
|
3427
|
+
...(internals?.insideFork === true ? { insideFork: true } : {}),
|
|
3428
|
+
...(internals?.agentName !== undefined ? { agentName: internals.agentName } : {}),
|
|
3429
|
+
...(internals?.parentToolCallId !== undefined ? { parentToolCallId: internals.parentToolCallId } : {}),
|
|
3430
|
+
});
|
|
3350
3431
|
const hookContextConsumerWired = hooks?.preToolUse !== undefined || hooks?.postToolUse !== undefined || hooks?.postToolUseFailure !== undefined;
|
|
3351
3432
|
const hookEnvFace = hookContextConsumerWired && (ownedEnv ?? deps.executionEnv) != null ? createHookEnvCapabilities(executionEnv) : undefined;
|
|
3352
3433
|
if (effectivePolicy || hooks?.preToolUse || egressTools.size > 0 || irreversibleTools.size > 0 || resourceSuspendEligible || platformSuspendArmed || spec.enablePlanMode === true) {
|
|
@@ -3556,6 +3637,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3556
3637
|
: undefined,
|
|
3557
3638
|
gitAnnouncement: gitStatusRef.announced !== undefined ? { ...gitStatusRef.announced } : undefined,
|
|
3558
3639
|
delegationProvenance: internals?.delegationProvenance !== undefined ? { ...internals.delegationProvenance.ref.current } : undefined,
|
|
3640
|
+
isDelegatedChild: hookIdentity.isDelegatedChild ? true : undefined,
|
|
3559
3641
|
});
|
|
3560
3642
|
const commitSuspendSaga = async (token, cp, remoteEnv, remoteHandle) => {
|
|
3561
3643
|
if (!checkpointStore)
|
|
@@ -4155,7 +4237,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4155
4237
|
if (blockedTracked)
|
|
4156
4238
|
blockedToolCalls.add(e.toolCallId);
|
|
4157
4239
|
if (notifyPermissionDenied) {
|
|
4158
|
-
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: complianceDeny, source: "safety" });
|
|
4240
|
+
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: complianceDeny, source: "safety", identity: hookIdentity });
|
|
4159
4241
|
}
|
|
4160
4242
|
return { block: true, reason: formatHookFeedback(complianceDeny), preToolContext: [] };
|
|
4161
4243
|
}
|
|
@@ -4166,7 +4248,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4166
4248
|
const planDenyReason = `Plan mode is active — "${e.toolName}" is a write/mutating tool and is read-only-blocked. ` +
|
|
4167
4249
|
`Research with read-only tools, then call ${PRESENT_PLAN_TOOL_NAME} with your plan to get it approved before acting.`;
|
|
4168
4250
|
if (notifyPermissionDenied) {
|
|
4169
|
-
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: planDenyReason, source: "planMode" });
|
|
4251
|
+
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: planDenyReason, source: "planMode", identity: hookIdentity });
|
|
4170
4252
|
}
|
|
4171
4253
|
return {
|
|
4172
4254
|
block: true,
|
|
@@ -4179,6 +4261,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4179
4261
|
result = await runToolGate({
|
|
4180
4262
|
onNotifyError: (f) => emitTrace(deps.tracer, () => ({ kind: "observer.notify_failed", version: 1, taskId: spec.taskId ?? sessionId, site: f.site, message: f.error.message, ts: Date.now() })),
|
|
4181
4263
|
event: e,
|
|
4264
|
+
identity: hookIdentity,
|
|
4182
4265
|
preToolUse: ownGatePreToolUse,
|
|
4183
4266
|
...(hookEnvFace !== undefined ? { hookEnv: hookEnvFace } : {}),
|
|
4184
4267
|
adjudicate,
|
|
@@ -4291,7 +4374,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4291
4374
|
isInterrupt: abortController.signal.aborted || spec.signal?.aborted === true,
|
|
4292
4375
|
content: e.content.map((c) => ({ ...c })),
|
|
4293
4376
|
details: clonedDetails,
|
|
4294
|
-
}, { toolCallId: e.toolCallId, toolName: e.toolName, ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}) });
|
|
4377
|
+
}, { toolCallId: e.toolCallId, toolName: e.toolName, ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}), identity: hookIdentity });
|
|
4295
4378
|
if (patch?.additionalContext) {
|
|
4296
4379
|
content = [...content, { type: "text", text: formatHookFeedback(patch.additionalContext) }];
|
|
4297
4380
|
changed = true;
|
|
@@ -4299,7 +4382,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4299
4382
|
}
|
|
4300
4383
|
}
|
|
4301
4384
|
else if (hooks?.postToolUse) {
|
|
4302
|
-
const patch = await hooks.postToolUse(e.toolName, e.input, { content: e.content, details: e.details, isError: e.isError }, { toolCallId: e.toolCallId, toolName: e.toolName, ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}) });
|
|
4385
|
+
const patch = await hooks.postToolUse(e.toolName, e.input, { content: e.content, details: e.details, isError: e.isError }, { toolCallId: e.toolCallId, toolName: e.toolName, ...(hookEnvFace !== undefined ? { env: hookEnvFace } : {}), identity: hookIdentity });
|
|
4303
4386
|
if (patch?.updatedOutput) {
|
|
4304
4387
|
content = patch.updatedOutput;
|
|
4305
4388
|
changed = true;
|
|
@@ -4586,7 +4669,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
4586
4669
|
const effectiveReadFaceObserved = carrierReadFace();
|
|
4587
4670
|
const effectiveReadDenyObserved = readDenyAdditionsNormalized.length > 0 ? readDenyAdditionsNormalized.map((e) => ({ ...e })) : undefined;
|
|
4588
4671
|
const preparedHolder = {};
|
|
4589
|
-
const buildPrepared = () => ({ harness, session, sessionId, taskRootPath: taskRootFinal, model, thinking, compModel, mcp: mcp, ...(a2a !== undefined && a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, approvalSettlement, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, suspendRef, suspendProgressRef, reviewRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, brainCallGuardrailRef, suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, gitStatusRef, listBackgroundTasks, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
|
|
4672
|
+
const buildPrepared = () => ({ harness, session, sessionId, taskRootPath: taskRootFinal, model, thinking, compModel, mcp: mcp, ...(a2a !== undefined && a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, approvalSettlement, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), ...(effectiveReadFaceObserved !== undefined ? { effectiveReadFace: effectiveReadFaceObserved } : {}), ...(effectiveReadDenyObserved !== undefined ? { effectiveReadDenyPatterns: effectiveReadDenyObserved } : {}), effectiveMemoryScopes: memoryEffectiveScopes, cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), ...(permissionRuleOrgLane !== undefined ? { permissionRuleOrg: permissionRuleOrgLane } : {}), releaseSignal, settleContentAskBindings, cacheBreakDetector, cacheFingerprint, wiringManifest, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, deferDirectCall, ...(staticFaceForRef.current !== undefined ? { staticFaceFor: staticFaceForRef.current } : {}), ownedEnv, suspendRef, suspendProgressRef, reviewRef, remoteEnvFailures, reviewRequestRef, suspendLoopRef, suspendForResource, ...(suspendForPlatformLimit !== undefined ? { suspendForPlatformLimit } : {}), ...(envLifetimeSuspendAt !== undefined ? { envLifetimeSuspendAt } : {}), ...(usageGovernance !== undefined ? { usageGovernance } : {}), callIssuedAtRef, brainCallGuardrailRef, suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolEffects, wakeRecovered, promptOverheadTokens, lastBrainContext, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit, runIdent: lspRunIdent } } : {}), planModeRef, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(workflowSizeGuideline ? { workflowSizeGuideline } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, gitStatusRef, listBackgroundTasks, hookIdentity, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
|
|
4590
4673
|
const prepared = buildPrepared();
|
|
4591
4674
|
preparedHolder.current = prepared;
|
|
4592
4675
|
return prepared;
|