@sema-agent/core 5.11.0 → 5.13.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 +52 -0
- package/dist/agents/subagent.js +4 -2
- package/dist/core/auto-compaction.d.ts +12 -1
- package/dist/core/auto-compaction.js +3 -1
- package/dist/core/checkpoint-store.d.ts +8 -1
- package/dist/core/checkpoint-store.js +3 -1
- package/dist/core/compliance.d.ts +11 -0
- package/dist/core/compliance.js +34 -0
- package/dist/core/exec-gate.js +12 -1
- package/dist/core/governance-codes.d.ts +12 -0
- package/dist/core/governance-codes.js +24 -0
- package/dist/core/locked-config.d.ts +27 -0
- package/dist/core/locked-config.js +42 -0
- package/dist/core/memory-admission.d.ts +47 -0
- package/dist/core/memory-admission.js +156 -0
- package/dist/core/memory.d.ts +2 -0
- package/dist/core/memory.js +3 -2
- package/dist/core/retention.d.ts +36 -0
- package/dist/core/retention.js +31 -0
- package/dist/core/runner/assemble-result.js +1 -1
- package/dist/core/runner/compaction-call-options.d.ts +13 -1
- package/dist/core/runner/compaction-call-options.js +85 -0
- package/dist/core/runner/prepare-memory.d.ts +9 -0
- package/dist/core/runner/prepare-memory.js +28 -2
- package/dist/core/runner/prepare-task.d.ts +4 -0
- package/dist/core/runner/prepare-task.js +183 -26
- package/dist/core/runner/runtask.js +101 -47
- package/dist/core/runner/turn-attachments.js +3 -1
- package/dist/core/session-store.d.ts +1 -0
- package/dist/core/session-store.js +1 -0
- package/dist/core/tool-result-store.d.ts +2 -0
- package/dist/core/tool-result-store.js +1 -0
- package/dist/core/types.d.ts +12 -2
- package/dist/engine/compaction/compaction.d.ts +11 -2
- package/dist/engine/compaction/compaction.js +87 -9
- package/dist/engine/harness/agent-harness.js +11 -1
- package/dist/engine/llm/validation.js +11 -1
- package/dist/index.d.ts +7 -2
- package/dist/index.js +6 -1
- package/dist/prompt-assembly/event-registry.js +1 -1
- package/package.json +1 -1
|
@@ -4,6 +4,7 @@ import { resolve as resolveFsPath } from "node:path";
|
|
|
4
4
|
import { AgentHarness, DEFAULT_CHARS_PER_TOKEN, DEFAULT_CLAMP_TOLERANCE, DEFAULT_COMPACTION_SETTINGS, estimateContextTokens, readCompactionActiveTools, summaryOutputBudgetTokens } from "../../internal/harness.js";
|
|
5
5
|
const PROMPT_HASH_SALT = randomBytes(16);
|
|
6
6
|
import { sanitizeCompactionSettings } from "../auto-compaction.js";
|
|
7
|
+
import { projectStaleToolResults, resolveStaleToolResultOffload } from "./compaction-call-options.js";
|
|
7
8
|
import { createAutoModeDecider } from "../auto-mode.js";
|
|
8
9
|
import { buildAutoModePrompt, renderAutoModeAction, renderAutoModeWindow } from "../auto-mode-prompt.js";
|
|
9
10
|
import { resolveModel, resolveTaskModel, roleModelIfSet } from "../roles.js";
|
|
@@ -37,6 +38,10 @@ import { OUTPUT_TOOL_NAME, REPORT_FINDINGS_TOOL_NAME, SKILL_CONTENT_MAX_CHARS, S
|
|
|
37
38
|
import { compileOutputSchema } from "./strict-output-schema.js";
|
|
38
39
|
import { TOOL_SEARCH_NAME, buildDeferredRegistry, classifyDeferred, extractDiscoveredToolNames, createPlaceholderTool, createToolSearchTool, } from "./tool-disclosure.js";
|
|
39
40
|
import { composeMemoryBlock } from "../memory.js";
|
|
41
|
+
import { preflightLockedConfig } from "../locked-config.js";
|
|
42
|
+
import { COMPLIANCE_CAPABILITIES, WEB_FETCH_TOOL_NAME, complianceCallDenial, resolveComplianceDenies } from "../compliance.js";
|
|
43
|
+
import { assertRetentionCapability } from "../retention.js";
|
|
44
|
+
import { foldAdmissionFreeze } from "../memory-admission.js";
|
|
40
45
|
import { prepareMemory } from "./prepare-memory.js";
|
|
41
46
|
import { defaultPromptProvider, buildEnvironmentContext, buildGitSnapshot, formatLocalDate, isValidTimeZone, PROJECT_CONTEXT_FRAMING } from "../../prompts/default.js";
|
|
42
47
|
import { assemblePrompt } from "../../prompt-assembly/assemble.js";
|
|
@@ -68,7 +73,7 @@ import { resolveWorkflowSizeGuideline } from "../../orchestration/workflow-size-
|
|
|
68
73
|
import { createLspTool, gitCheckIgnoreFilter, resolveLspPath } from "../lsp.js";
|
|
69
74
|
import { resolveKey } from "../../tools/fs/safety.js";
|
|
70
75
|
import { wholeFileRecordsFromTranscript } from "./session-file-state-replay.js";
|
|
71
|
-
import { BINDING_CHECKPOINT_VERSION, mintCheckpointToken, RESOURCE_CHECKPOINT_VERSION, TOKEN_CHECKPOINT_VERSION, buildRiskDescriptor, debitLedger, remainingBudgetMicroUsd, } from "../checkpoint-store.js";
|
|
76
|
+
import { BINDING_CHECKPOINT_VERSION, mintCheckpointToken, ORG_ADMISSION_CHECKPOINT_VERSION, RESOURCE_CHECKPOINT_VERSION, TOKEN_CHECKPOINT_VERSION, buildRiskDescriptor, debitLedger, remainingBudgetMicroUsd, } from "../checkpoint-store.js";
|
|
72
77
|
import { boundInputHashOf } from "../canonical-json.js";
|
|
73
78
|
import { GLOBAL_USAGE_KEY, resolveUsageWindows, usageRetryAfterMs } from "../usage-window-store.js";
|
|
74
79
|
const RECONCILE_MAX_RETRIES = 3;
|
|
@@ -336,6 +341,16 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
336
341
|
e.code = "config.empty_objective";
|
|
337
342
|
throw e;
|
|
338
343
|
}
|
|
344
|
+
const lockedPreflight = preflightLockedConfig(spec, deps);
|
|
345
|
+
assertRetentionCapability({
|
|
346
|
+
policy: deps.retentionPolicy,
|
|
347
|
+
locked: lockedPreflight.lockedKeys.has("retentionPolicy"),
|
|
348
|
+
stores: [
|
|
349
|
+
{ name: "sessionStore", store: sessions },
|
|
350
|
+
{ name: "checkpointStore", store: resolveCheckpointStore(spec, deps) },
|
|
351
|
+
{ name: "toolResultStore", store: deps.toolResultStore },
|
|
352
|
+
],
|
|
353
|
+
});
|
|
339
354
|
resolveTaskLimits(spec.limits);
|
|
340
355
|
if (spec.resourceSuspend !== undefined) {
|
|
341
356
|
const rsus = spec.resourceSuspend;
|
|
@@ -939,9 +954,24 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
939
954
|
? liveShellGate
|
|
940
955
|
: seedShellGate;
|
|
941
956
|
const inheritedParentConstraints = liveInheritedGate?.parentConstraints;
|
|
957
|
+
const liveAdmittedOrg = liveInheritedGate?.admittedOrgScopes;
|
|
958
|
+
const seedAdmittedOrg = seedInheritedGate?.admittedOrgScopes;
|
|
959
|
+
const inheritedAdmittedOrgScopes = liveAdmittedOrg === undefined ? seedAdmittedOrg : seedAdmittedOrg === undefined ? liveAdmittedOrg : liveAdmittedOrg.filter((s) => seedAdmittedOrg.includes(s));
|
|
960
|
+
const inheritedOrgGoverned = liveInheritedGate?.orgAdmissionGoverned === true || seedInheritedGate?.orgAdmissionGoverned === true;
|
|
961
|
+
const priorOwnOrgVerdict = resume?.seed.inheritedGate?.ownAdmittedOrgScopes !== undefined
|
|
962
|
+
? { scopes: resume.seed.inheritedGate.ownAdmittedOrgScopes, writeScope: resume.seed.inheritedGate.ownAdmittedOrgWriteScope ?? null }
|
|
963
|
+
: undefined;
|
|
964
|
+
const orgGovernedProvenance = deps.memoryScopeAdmission !== undefined ||
|
|
965
|
+
(deps.deploymentMemoryScopes !== undefined && deps.deploymentMemoryScopes.length > 0) ||
|
|
966
|
+
deps.compliancePostureResolver !== undefined ||
|
|
967
|
+
inheritedOrgGoverned ||
|
|
968
|
+
priorOwnOrgVerdict !== undefined;
|
|
942
969
|
const specShellGate = spec.shellGate ?? "off";
|
|
943
970
|
const effectiveShellGate = inheritedShellGate !== undefined && shellGateRank[inheritedShellGate] > shellGateRank[specShellGate] ? inheritedShellGate : specShellGate;
|
|
944
971
|
const ownSessionRulesRef = {};
|
|
972
|
+
const memoryAdmittedOrgScopesRef = { current: [] };
|
|
973
|
+
const ownOrgVerdictRef = { current: undefined };
|
|
974
|
+
const orgAdmissionCheckpointState = () => inheritedAdmittedOrgScopes !== undefined || ownOrgVerdictRef.current !== undefined || orgGovernedProvenance;
|
|
945
975
|
const frozenOnAsk = spec.onAsk ?? deps.onAsk;
|
|
946
976
|
const frozenOnQuestion = spec.onQuestion ?? deps.onQuestion;
|
|
947
977
|
const inheritedGateForChildren = () => {
|
|
@@ -949,7 +979,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
949
979
|
...(inheritedAncestorRules ?? []),
|
|
950
980
|
...(ownSessionRulesRef.current !== undefined ? [ownSessionRulesRef.current] : []),
|
|
951
981
|
];
|
|
952
|
-
const ownCallerPolicy =
|
|
982
|
+
const ownCallerPolicy = lockedPreflight.toolPolicy;
|
|
953
983
|
const durableMandate = runtimeCaps?.forceDurableGate === true || (spec.durableApproval !== undefined && frozenOnAsk === undefined);
|
|
954
984
|
const parentConstraints = [
|
|
955
985
|
...(inheritedParentConstraints ?? []),
|
|
@@ -967,6 +997,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
967
997
|
...(ancestorRules.length > 0 ? { ancestorRules } : {}),
|
|
968
998
|
...(effectiveShellGate !== "off" ? { shellGate: effectiveShellGate } : {}),
|
|
969
999
|
...(parentConstraints.length > 0 ? { parentConstraints } : {}),
|
|
1000
|
+
admittedOrgScopes: memoryAdmittedOrgScopesRef.current,
|
|
1001
|
+
...(orgGovernedProvenance ? { orgAdmissionGoverned: true } : {}),
|
|
970
1002
|
};
|
|
971
1003
|
};
|
|
972
1004
|
let agentForkDenial;
|
|
@@ -1071,6 +1103,39 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1071
1103
|
runtimeCaps = { allowWorkflows: false, allowFork: false };
|
|
1072
1104
|
}
|
|
1073
1105
|
}
|
|
1106
|
+
let complianceDenies = new Set();
|
|
1107
|
+
let complianceDegraded = false;
|
|
1108
|
+
if (deps.compliancePostureResolver) {
|
|
1109
|
+
try {
|
|
1110
|
+
const posture = (await deps.compliancePostureResolver(spec.principal)) ?? undefined;
|
|
1111
|
+
if (posture !== undefined)
|
|
1112
|
+
complianceDenies = resolveComplianceDenies(posture);
|
|
1113
|
+
}
|
|
1114
|
+
catch (err) {
|
|
1115
|
+
deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "config", sessionId });
|
|
1116
|
+
complianceDenies = new Set(COMPLIANCE_CAPABILITIES);
|
|
1117
|
+
complianceDegraded = true;
|
|
1118
|
+
}
|
|
1119
|
+
const complianceRefuse = (capability, requested) => {
|
|
1120
|
+
const e = new Error(`${requested} is denied for this principal by the compliance posture (capability "${capability}"` +
|
|
1121
|
+
`${complianceDegraded ? "; the posture resolver is currently failing, so every managed capability is denied fail-closed" : ""}) — ` +
|
|
1122
|
+
`the task is refused rather than silently narrowed.`);
|
|
1123
|
+
e.code = complianceDegraded ? "config.compliance_required" : "config.compliance_denied";
|
|
1124
|
+
throw e;
|
|
1125
|
+
};
|
|
1126
|
+
if (complianceDenies.has("mcp_servers") && lockedPreflight.mcp?.length) {
|
|
1127
|
+
complianceRefuse("mcp_servers", "TaskSpec.mcp (MCP server materialization)");
|
|
1128
|
+
}
|
|
1129
|
+
if (complianceDenies.has("workflows") && spec.selfOrchestration === true) {
|
|
1130
|
+
complianceRefuse("workflows", "TaskSpec.selfOrchestration (workflow self-orchestration)");
|
|
1131
|
+
}
|
|
1132
|
+
if (complianceDenies.has("web_fetch")) {
|
|
1133
|
+
const webTool = (spec.tools ?? []).find((t) => t.name === WEB_FETCH_TOOL_NAME || (t.aliases ?? []).includes(WEB_FETCH_TOOL_NAME));
|
|
1134
|
+
if (webTool !== undefined) {
|
|
1135
|
+
complianceRefuse("web_fetch", `TaskSpec.tools["${webTool.name}"] (the WebFetch tool face)`);
|
|
1136
|
+
}
|
|
1137
|
+
}
|
|
1138
|
+
}
|
|
1074
1139
|
agentForkDenial = forkGovernanceDenial(spec.enableFork, runtimeCaps?.allowFork);
|
|
1075
1140
|
observersActive = runtimeCaps?.allowObservers === true;
|
|
1076
1141
|
if (runtimeCaps?.autoMode === true && deps.autoMode !== undefined) {
|
|
@@ -1219,8 +1284,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1219
1284
|
}
|
|
1220
1285
|
tools.push(createOutputTool(outputRef, spec.outputSchema, compiled.strict ? compiled.modelSchema : undefined));
|
|
1221
1286
|
}
|
|
1222
|
-
mcp =
|
|
1223
|
-
? await materializeMcpTools(
|
|
1287
|
+
mcp = lockedPreflight.mcp?.length
|
|
1288
|
+
? await materializeMcpTools(lockedPreflight.mcp, spec.principal, deps.onElicit, deps.mcpImageResizer)
|
|
1224
1289
|
: { tools: [], toolAxes: [], warnings: [], serverInstructions: [], instructionsDelta: { pendingAdds: [], pendingRemovals: [] }, droppedTools: [], statuses: [], refresh: async () => [], dispose: async () => { } };
|
|
1225
1290
|
for (const w of mcp.warnings)
|
|
1226
1291
|
deps.onError?.(w, { phase: "mcp", sessionId });
|
|
@@ -1240,7 +1305,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1240
1305
|
tools.push(...mcp.tools.map((t) => remoteToolOffload(t)));
|
|
1241
1306
|
const rebuildHarnessToolsRef = {};
|
|
1242
1307
|
const toolCallGateArmedRef = { armed: false };
|
|
1243
|
-
if (
|
|
1308
|
+
if (lockedPreflight.mcp?.length) {
|
|
1244
1309
|
tools.push({
|
|
1245
1310
|
name: "RefreshMcpTools",
|
|
1246
1311
|
label: "RefreshMcpTools",
|
|
@@ -1631,7 +1696,31 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1631
1696
|
.catch(() => undefined);
|
|
1632
1697
|
}
|
|
1633
1698
|
: undefined;
|
|
1634
|
-
const { memoryEngineSession, memoryBlock: memoryBlockFromEngine, seedFiles: memorySeedFiles } = await prepareMemory({
|
|
1699
|
+
const { memoryEngineSession, memoryBlock: memoryBlockFromEngine, seedFiles: memorySeedFiles, admittedOrgScopes: memoryAdmittedOrgScopes, ownOrgVerdict: memoryOwnOrgVerdict, } = await prepareMemory({
|
|
1700
|
+
spec,
|
|
1701
|
+
deps,
|
|
1702
|
+
sessionId,
|
|
1703
|
+
taskRootPath,
|
|
1704
|
+
memoryWriteGateRef,
|
|
1705
|
+
admissionCtx: {
|
|
1706
|
+
orgMemoryDenied: complianceDenies.has("org_memory_mount"),
|
|
1707
|
+
complianceDegraded,
|
|
1708
|
+
parentAdmittedOrgScopes: foldAdmissionFreeze({
|
|
1709
|
+
delegated: internals?.isDelegatedChild === true ||
|
|
1710
|
+
internals?.inheritedGate !== undefined ||
|
|
1711
|
+
(resume?.seed.inheritedGate !== undefined &&
|
|
1712
|
+
(resume.seed.inheritedGate.ancestorRules !== undefined ||
|
|
1713
|
+
resume.seed.inheritedGate.shellGate !== undefined ||
|
|
1714
|
+
resume.seed.inheritedGate.admittedOrgScopes !== undefined ||
|
|
1715
|
+
resume.seed.inheritedGate.requiresParentConstraint)),
|
|
1716
|
+
inherited: inheritedAdmittedOrgScopes,
|
|
1717
|
+
}),
|
|
1718
|
+
priorOwnVerdict: priorOwnOrgVerdict,
|
|
1719
|
+
governedProvenance: orgGovernedProvenance,
|
|
1720
|
+
},
|
|
1721
|
+
});
|
|
1722
|
+
memoryAdmittedOrgScopesRef.current = memoryAdmittedOrgScopes;
|
|
1723
|
+
ownOrgVerdictRef.current = memoryOwnOrgVerdict ?? priorOwnOrgVerdict;
|
|
1635
1724
|
let memoryBlock = memoryBlockFromEngine;
|
|
1636
1725
|
if (memorySeedFiles?.length && seedContextFiles) {
|
|
1637
1726
|
try {
|
|
@@ -1736,7 +1825,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
1736
1825
|
{ entries: [], seedAnnounced: true }
|
|
1737
1826
|
: undefined;
|
|
1738
1827
|
const provider = spec.promptProvider ?? deps.promptProvider ?? defaultPromptProvider;
|
|
1739
|
-
const promptPolicyEnabled = Boolean(
|
|
1828
|
+
const promptPolicyEnabled = Boolean(lockedPreflight.toolPolicy);
|
|
1740
1829
|
const promptHooks = spec.hooks ?? deps.hooks;
|
|
1741
1830
|
const promptHooksEnabled = Boolean(promptHooks?.preToolUse || promptHooks?.postToolUse);
|
|
1742
1831
|
const failClosedReason = selfOrchestrationFailClosedReason(spec, deps);
|
|
@@ -2275,6 +2364,34 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2275
2364
|
const dateChange = renderWithDate
|
|
2276
2365
|
? { legDate: envFacts.date, today: () => formatLocalDate(new Date(), tzValid ? userTz : undefined) }
|
|
2277
2366
|
: undefined;
|
|
2367
|
+
const lastBrainContextRef = {};
|
|
2368
|
+
const requestLossyRef = { current: false };
|
|
2369
|
+
const staleOffloadWrittenRefs = new Set();
|
|
2370
|
+
const lastBrainContext = () => lastBrainContextRef.current;
|
|
2371
|
+
const recordBrainContext = (servedModelId, c) => {
|
|
2372
|
+
if (requestLossyRef.current) {
|
|
2373
|
+
lastBrainContextRef.current = undefined;
|
|
2374
|
+
return;
|
|
2375
|
+
}
|
|
2376
|
+
lastBrainContextRef.current = {
|
|
2377
|
+
...(c.systemPrompt !== undefined ? { systemPrompt: c.systemPrompt } : {}),
|
|
2378
|
+
...(c.systemBlocks !== undefined ? { systemBlocks: [...c.systemBlocks] } : {}),
|
|
2379
|
+
messages: [...c.messages],
|
|
2380
|
+
...(c.tools !== undefined ? { tools: [...c.tools] } : {}),
|
|
2381
|
+
modelId: servedModelId,
|
|
2382
|
+
};
|
|
2383
|
+
};
|
|
2384
|
+
const staleOffloadCfg = resolveStaleToolResultOffload(spec.compaction?.staleToolResultOffload);
|
|
2385
|
+
if (staleOffloadCfg !== undefined && offloadStore === undefined) {
|
|
2386
|
+
deps.onError?.(new Error("compaction.staleToolResultOffload is set but the tool-result offload store is disabled (toolResultThresholdChars ≤ 0/∞) — the knob is inert this run; re-enable offloading or drop the knob"), { phase: "config", sessionId });
|
|
2387
|
+
}
|
|
2388
|
+
const staleOffload = staleOffloadCfg !== undefined && offloadStore !== undefined ? { cfg: staleOffloadCfg, store: offloadStore } : undefined;
|
|
2389
|
+
const guardedBrain = brainCallGuardrailMs === undefined
|
|
2390
|
+
? deps.brain
|
|
2391
|
+
: {
|
|
2392
|
+
...deps.brain,
|
|
2393
|
+
stream: withBrainCallGuardrail((m, c, o) => deps.brain.stream(m, c, o), brainCallGuardrailMs, brainCallGuardrailRef),
|
|
2394
|
+
};
|
|
2278
2395
|
const harness = new AgentHarness({
|
|
2279
2396
|
abortResultDetails: () => suspendRef.token !== undefined || reviewRef.token !== undefined ? { code: "gate.parked" } : undefined,
|
|
2280
2397
|
...(spec.limits?.maxOutputTokens !== undefined && spec.limits.maxOutputTokens > 0
|
|
@@ -2299,7 +2416,6 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2299
2416
|
}));
|
|
2300
2417
|
},
|
|
2301
2418
|
...(spec.streamingToolExecution === true ? { streamingToolExecution: true } : {}),
|
|
2302
|
-
followUpMode: "all",
|
|
2303
2419
|
env: executionEnv,
|
|
2304
2420
|
session,
|
|
2305
2421
|
tools: harnessTools,
|
|
@@ -2308,12 +2424,20 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2308
2424
|
systemPrompt,
|
|
2309
2425
|
...(assembled.systemBlocks ? { systemBlocks: assembled.systemBlocks } : {}),
|
|
2310
2426
|
getApiKeyAndHeaders: spec.getApiKeyAndHeaders,
|
|
2311
|
-
runtime: brainToRuntime(
|
|
2312
|
-
|
|
2313
|
-
: {
|
|
2314
|
-
|
|
2315
|
-
|
|
2316
|
-
|
|
2427
|
+
runtime: brainToRuntime({
|
|
2428
|
+
...guardedBrain,
|
|
2429
|
+
stream: (m, c, o) => {
|
|
2430
|
+
if (staleOffload === undefined) {
|
|
2431
|
+
recordBrainContext(m.id, c);
|
|
2432
|
+
return guardedBrain.stream(m, c, o);
|
|
2433
|
+
}
|
|
2434
|
+
return (async () => {
|
|
2435
|
+
const projected = await projectStaleToolResults(c, staleOffload.cfg, staleOffload.store, sessionId, staleOffloadWrittenRefs);
|
|
2436
|
+
recordBrainContext(m.id, projected);
|
|
2437
|
+
return await guardedBrain.stream(m, projected, o);
|
|
2438
|
+
})();
|
|
2439
|
+
},
|
|
2440
|
+
}),
|
|
2317
2441
|
});
|
|
2318
2442
|
harnessRef.current = harness;
|
|
2319
2443
|
let releaseSignal = () => undefined;
|
|
@@ -2331,7 +2455,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2331
2455
|
releaseSignal = () => sig.removeEventListener("abort", onExternalAbort);
|
|
2332
2456
|
}
|
|
2333
2457
|
}
|
|
2334
|
-
const policy =
|
|
2458
|
+
const policy = lockedPreflight.toolPolicy;
|
|
2335
2459
|
const auditPolicyNames = (auditee) => {
|
|
2336
2460
|
const nameGroups = toolPolicyNameSets(auditee);
|
|
2337
2461
|
if (nameGroups.length > 0) {
|
|
@@ -2419,7 +2543,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2419
2543
|
for (const layer of narrowingLayers)
|
|
2420
2544
|
auditPolicyNames(layer);
|
|
2421
2545
|
const denyNarrowingPolicy = narrowingLayers.length === 0 ? undefined : narrowingLayers.length === 1 ? narrowingLayers[0] : combinePolicies(...narrowingLayers);
|
|
2422
|
-
const basePolicyForResumeEdit =
|
|
2546
|
+
const basePolicyForResumeEdit = lockedPreflight.toolPolicy;
|
|
2423
2547
|
const sameInstanceAncestorCount = policy === undefined ? 0 : (inheritedParentConstraints ?? []).reduce((n, pc) => (pc.policy === policy ? n + 1 : n), 0);
|
|
2424
2548
|
const sharedFirstDecision = new Map();
|
|
2425
2549
|
const SHARED_FIRST_DECISION_CAP = 256;
|
|
@@ -2957,10 +3081,20 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
2957
3081
|
inheritedGate: (() => {
|
|
2958
3082
|
const requiresParentConstraint = (inheritedParentConstraints?.length ?? 0) > 0 || seedInheritedGate?.requiresParentConstraint === true;
|
|
2959
3083
|
const parentConstraintCount = (inheritedParentConstraints?.length ?? 0) > 0 ? inheritedParentConstraints.length : seedInheritedGate?.parentConstraintCount;
|
|
2960
|
-
return inheritedAncestorRules !== undefined ||
|
|
3084
|
+
return inheritedAncestorRules !== undefined ||
|
|
3085
|
+
inheritedShellGate !== undefined ||
|
|
3086
|
+
inheritedAdmittedOrgScopes !== undefined ||
|
|
3087
|
+
ownOrgVerdictRef.current !== undefined ||
|
|
3088
|
+
orgGovernedProvenance ||
|
|
3089
|
+
requiresParentConstraint
|
|
2961
3090
|
? {
|
|
2962
3091
|
...(inheritedAncestorRules !== undefined ? { ancestorRules: structuredClone(inheritedAncestorRules) } : {}),
|
|
2963
3092
|
...(inheritedShellGate !== undefined ? { shellGate: inheritedShellGate } : {}),
|
|
3093
|
+
...(inheritedAdmittedOrgScopes !== undefined ? { admittedOrgScopes: [...inheritedAdmittedOrgScopes] } : {}),
|
|
3094
|
+
...(ownOrgVerdictRef.current !== undefined
|
|
3095
|
+
? { ownAdmittedOrgScopes: [...ownOrgVerdictRef.current.scopes], ownAdmittedOrgWriteScope: ownOrgVerdictRef.current.writeScope }
|
|
3096
|
+
: {}),
|
|
3097
|
+
...(orgGovernedProvenance ? { orgAdmissionGoverned: true } : {}),
|
|
2964
3098
|
requiresParentConstraint,
|
|
2965
3099
|
...(requiresParentConstraint && parentConstraintCount !== undefined ? { parentConstraintCount } : {}),
|
|
2966
3100
|
}
|
|
@@ -3075,7 +3209,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3075
3209
|
const mintedAt = Date.now();
|
|
3076
3210
|
const cp = {
|
|
3077
3211
|
token,
|
|
3078
|
-
version: resourceLedgerOut.totalTokens !== undefined ? TOKEN_CHECKPOINT_VERSION : RESOURCE_CHECKPOINT_VERSION,
|
|
3212
|
+
version: orgAdmissionCheckpointState() ? ORG_ADMISSION_CHECKPOINT_VERSION : resourceLedgerOut.totalTokens !== undefined ? TOKEN_CHECKPOINT_VERSION : RESOURCE_CHECKPOINT_VERSION,
|
|
3079
3213
|
scope,
|
|
3080
3214
|
sessionId,
|
|
3081
3215
|
leafId,
|
|
@@ -3157,7 +3291,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3157
3291
|
const mintedAt = Date.now();
|
|
3158
3292
|
const cp = {
|
|
3159
3293
|
token,
|
|
3160
|
-
version: reviewLedger.totalTokens !== undefined ? TOKEN_CHECKPOINT_VERSION : BINDING_CHECKPOINT_VERSION,
|
|
3294
|
+
version: orgAdmissionCheckpointState() ? ORG_ADMISSION_CHECKPOINT_VERSION : reviewLedger.totalTokens !== undefined ? TOKEN_CHECKPOINT_VERSION : BINDING_CHECKPOINT_VERSION,
|
|
3161
3295
|
scope,
|
|
3162
3296
|
sessionId,
|
|
3163
3297
|
leafId,
|
|
@@ -3193,8 +3327,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3193
3327
|
: undefined;
|
|
3194
3328
|
const suspendAsk = checkpointStore && (durableApproval || irreversibleTools.size > 0 || egressTools.size > 0)
|
|
3195
3329
|
? async (req, postHookArgs, safety, approverUnavailable) => {
|
|
3196
|
-
if (
|
|
3197
|
-
onAsk !== undefined &&
|
|
3330
|
+
if (onAsk !== undefined &&
|
|
3198
3331
|
runtimeCaps?.forceDurableGate !== true &&
|
|
3199
3332
|
approverUnavailable !== true &&
|
|
3200
3333
|
req.toolName !== ASK_USER_QUESTION_TOOL_NAME &&
|
|
@@ -3283,7 +3416,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3283
3416
|
const mintedAt = Date.now();
|
|
3284
3417
|
cp = {
|
|
3285
3418
|
token,
|
|
3286
|
-
version: approvalLedger.totalTokens !== undefined ? TOKEN_CHECKPOINT_VERSION : BINDING_CHECKPOINT_VERSION,
|
|
3419
|
+
version: orgAdmissionCheckpointState() ? ORG_ADMISSION_CHECKPOINT_VERSION : approvalLedger.totalTokens !== undefined ? TOKEN_CHECKPOINT_VERSION : BINDING_CHECKPOINT_VERSION,
|
|
3287
3420
|
scope,
|
|
3288
3421
|
sessionId,
|
|
3289
3422
|
leafId,
|
|
@@ -3344,11 +3477,28 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3344
3477
|
if (eff !== undefined && !toolEffects.has(t.name))
|
|
3345
3478
|
toolEffects.set(t.name, eff);
|
|
3346
3479
|
}
|
|
3347
|
-
toolCallGateArmedRef.armed =
|
|
3480
|
+
toolCallGateArmedRef.armed =
|
|
3481
|
+
effectivePolicy !== undefined ||
|
|
3482
|
+
hooks?.preToolUse !== undefined ||
|
|
3483
|
+
egressTools.size > 0 ||
|
|
3484
|
+
irreversibleTools.size > 0 ||
|
|
3485
|
+
spec.enablePlanMode === true ||
|
|
3486
|
+
complianceDenies.has("web_fetch");
|
|
3348
3487
|
if (toolCallGateArmedRef.armed) {
|
|
3349
3488
|
harness.on("tool_call", async (e) => {
|
|
3350
3489
|
blockedToolCalls.delete(e.toolCallId);
|
|
3351
3490
|
inheritedAskGrants.delete(e.toolCallId);
|
|
3491
|
+
{
|
|
3492
|
+
const complianceDeny = complianceCallDenial(complianceDenies, e.toolName);
|
|
3493
|
+
if (complianceDeny !== undefined) {
|
|
3494
|
+
if (blockedTracked)
|
|
3495
|
+
blockedToolCalls.add(e.toolCallId);
|
|
3496
|
+
if (notifyPermissionDenied) {
|
|
3497
|
+
await notifyPermissionDenied({ toolName: e.toolName, input: cloneObserverInput(e.input), toolCallId: e.toolCallId, reason: complianceDeny, source: "safety" });
|
|
3498
|
+
}
|
|
3499
|
+
return { block: true, reason: formatHookFeedback(complianceDeny), preToolContext: [] };
|
|
3500
|
+
}
|
|
3501
|
+
}
|
|
3352
3502
|
if (planModeRef.active && (toolEffects.get(e.toolName) ?? "write") !== "read") {
|
|
3353
3503
|
if (blockedTracked)
|
|
3354
3504
|
blockedToolCalls.add(e.toolCallId);
|
|
@@ -3486,7 +3636,8 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3486
3636
|
: {}),
|
|
3487
3637
|
});
|
|
3488
3638
|
let trimmed = trimToBudget(edited, guardAt, estimateContextTokens(edited, charsPerToken).tokens, charsPerToken);
|
|
3489
|
-
|
|
3639
|
+
const trimDroppedMessages = trimmed.length < edited.length;
|
|
3640
|
+
if (trimDroppedMessages) {
|
|
3490
3641
|
trimPressureRef.droppedMessages = true;
|
|
3491
3642
|
const droppedCount = edited.length - trimmed.length;
|
|
3492
3643
|
trimmed = insertTrimNotice(trimmed);
|
|
@@ -3509,6 +3660,12 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3509
3660
|
catch {
|
|
3510
3661
|
}
|
|
3511
3662
|
}
|
|
3663
|
+
requestLossyRef.current =
|
|
3664
|
+
capped !== healed ||
|
|
3665
|
+
mediaCapped !== capped ||
|
|
3666
|
+
edited !== mediaCapped ||
|
|
3667
|
+
trimDroppedMessages ||
|
|
3668
|
+
swept.dropped.length > 0;
|
|
3512
3669
|
return { messages: swept.messages };
|
|
3513
3670
|
});
|
|
3514
3671
|
const cacheBreakDetector = deps.cacheBreakDetection === false ? undefined : new CacheBreakDetector();
|
|
@@ -3622,7 +3779,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3622
3779
|
: undefined;
|
|
3623
3780
|
const listBackgroundTasks = () => defaultTaskRegistry
|
|
3624
3781
|
.list({ owner: hostTaskId, scope: taskScope, sessionId })
|
|
3625
|
-
.filter((t) => t.status === "pending" || t.status === "running")
|
|
3782
|
+
.filter((t) => t.status === "pending" || t.status === "running" || t.status === "parked")
|
|
3626
3783
|
.map((t) => ({ id: t.task_id, ...(t.description !== undefined ? { description: t.description } : {}), status: t.status }));
|
|
3627
3784
|
const overheadState = { promptChars: 0 };
|
|
3628
3785
|
const centerCompactionCandidate = deps.promptSource !== undefined && centerAdoption !== undefined
|
|
@@ -3674,7 +3831,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
|
|
|
3674
3831
|
: undefined;
|
|
3675
3832
|
overheadState.promptChars = systemPrompt.length;
|
|
3676
3833
|
const preparedHolder = {};
|
|
3677
|
-
const buildPrepared = () => ({ harness, session, sessionId, taskRootPath, model, thinking, compModel, mcp: mcp, ...(a2a !== undefined && a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), releaseSignal, cacheBreakDetector, cacheFingerprint, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, 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, 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, listBackgroundTasks, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
|
|
3834
|
+
const buildPrepared = () => ({ harness, session, sessionId, taskRootPath, model, thinking, compModel, mcp: mcp, ...(a2a !== undefined && a2a.tools.length > 0 ? { a2a } : {}), blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, nestedStats, ...(rewindNotes.length > 0 ? { rewindNotes } : {}), cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), releaseSignal, cacheBreakDetector, cacheFingerprint, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), toolMaterializeStatic, 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, listBackgroundTasks, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
|
|
3678
3835
|
const prepared = buildPrepared();
|
|
3679
3836
|
preparedHolder.current = prepared;
|
|
3680
3837
|
return prepared;
|