@sema-agent/core 2.0.1 → 2.2.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.
Files changed (71) hide show
  1. package/dist/agents/observer.d.ts +14 -0
  2. package/dist/agents/observer.js +66 -12
  3. package/dist/agents/send-message-tool.js +164 -88
  4. package/dist/agents/subagent.d.ts +11 -4
  5. package/dist/agents/subagent.js +166 -62
  6. package/dist/core/context-edit.js +16 -3
  7. package/dist/core/file-snapshot-store.js +10 -1
  8. package/dist/core/memory-engine/dual-root.js +2 -0
  9. package/dist/core/memory-engine/engine.d.ts +4 -0
  10. package/dist/core/memory-engine/engine.js +6 -1
  11. package/dist/core/runner/prepare-memory.d.ts +4 -0
  12. package/dist/core/runner/prepare-memory.js +4 -1
  13. package/dist/core/runner/prepare-task.d.ts +9 -2
  14. package/dist/core/runner/prepare-task.js +68 -13
  15. package/dist/core/runner/runtask.js +919 -865
  16. package/dist/core/runner/synthetic-tools.d.ts +1 -0
  17. package/dist/core/runner/synthetic-tools.js +18 -15
  18. package/dist/core/runner/turn-attachments.d.ts +27 -3
  19. package/dist/core/runner/turn-attachments.js +101 -12
  20. package/dist/core/task-registry-agent.d.ts +9 -1
  21. package/dist/core/task-registry-agent.js +23 -2
  22. package/dist/core/task-registry-monitor.js +79 -24
  23. package/dist/core/task-registry-shared.d.ts +13 -1
  24. package/dist/core/task-registry-shared.js +21 -0
  25. package/dist/core/task-registry.d.ts +2 -0
  26. package/dist/core/task-registry.js +24 -26
  27. package/dist/core/tool-result-budget.js +2 -2
  28. package/dist/core/tool-result-store.d.ts +2 -0
  29. package/dist/core/tool-result-store.js +27 -2
  30. package/dist/core/types.d.ts +4 -2
  31. package/dist/core/workflow-journal-store.d.ts +13 -0
  32. package/dist/engine/session/import-validate.js +29 -0
  33. package/dist/engine/session/memory-repo.js +5 -0
  34. package/dist/index.d.ts +1 -1
  35. package/dist/index.js +1 -1
  36. package/dist/orchestration/workflow-size-guideline.d.ts +6 -1
  37. package/dist/orchestration/workflow-size-guideline.js +19 -9
  38. package/dist/orchestration/workflow.d.ts +1 -0
  39. package/dist/orchestration/workflow.js +44 -1
  40. package/dist/prompt-assembly/assemble.js +3 -7
  41. package/dist/prompt-assembly/event-registry.js +1 -1
  42. package/dist/prompt-assembly/packs/sema-default.js +8 -5
  43. package/dist/prompts/coordinator.d.ts +1 -1
  44. package/dist/prompts/coordinator.js +45 -0
  45. package/dist/prompts/default.d.ts +4 -5
  46. package/dist/prompts/default.js +16 -18
  47. package/dist/prompts/simple-sections.d.ts +3 -1
  48. package/dist/prompts/simple-sections.js +11 -1
  49. package/dist/stores/cc/task-list-store.js +3 -3
  50. package/dist/stores/file/memory-store.d.ts +3 -0
  51. package/dist/stores/file/memory-store.js +39 -12
  52. package/dist/stores/file/tool-result-store.js +16 -2
  53. package/dist/stores/file/workflow-journal-store.d.ts +23 -0
  54. package/dist/stores/file/workflow-journal-store.js +140 -3
  55. package/dist/tools/fs/bash-readonly-classifier.js +21 -2
  56. package/dist/tools/fs/fs-bash.d.ts +1 -0
  57. package/dist/tools/fs/fs-bash.js +10 -3
  58. package/dist/tools/fs/fs-read.js +12 -12
  59. package/dist/tools/fs/fs-search-tools.js +42 -7
  60. package/dist/tools/fs/fs-write.js +18 -6
  61. package/dist/tools/fs/index.d.ts +1 -0
  62. package/dist/tools/fs/index.js +2 -1
  63. package/dist/tools/fs/safety.d.ts +4 -0
  64. package/dist/tools/fs/safety.js +113 -10
  65. package/dist/tools/fs/search.d.ts +1 -0
  66. package/dist/tools/fs/search.js +23 -3
  67. package/dist/tools/monitor.js +1 -1
  68. package/dist/tools/task-list.d.ts +1 -0
  69. package/dist/tools/task-list.js +13 -2
  70. package/dist/tools/web.js +36 -6
  71. package/package.json +3 -2
@@ -12,12 +12,16 @@ import { materializeMcpTools } from "../mcp.js";
12
12
  import { Type } from "typebox";
13
13
  import { brainToRuntime } from "../runtime.js";
14
14
  import { StoredSession, isSessionConflict, hasSessionFork } from "../session.js";
15
- import { createAgentTranscriptTool, createSendMessageTool, createSubagentWorktreeHelper, forkGovernanceDenial, AGENT_TRANSCRIPT_TOOL_NAME, SEND_MESSAGE_TOOL_NAME, SubagentRetainLedger } from "../../agents/subagent.js";
15
+ import { createSubagentWorktreeHelper, forkGovernanceDenial } from "../../agents/subagent.js";
16
+ import { createAgentTranscriptTool, AGENT_TRANSCRIPT_TOOL_NAME } from "../../agents/agent-transcript-tool.js";
17
+ import { createSendMessageTool, SEND_MESSAGE_TOOL_NAME } from "../../agents/send-message-tool.js";
18
+ import { SubagentRetainLedger } from "../../agents/retain-ledger.js";
16
19
  import { combinePolicies, createTranscriptIntegrityPolicy, createUnverifiableDeletePolicy, resolveAsk, toolPolicyNameSets } from "../tool-policy.js";
17
20
  import { ActiveSkillScope, createActiveSkillScopePolicy } from "./active-skill-scope.js";
18
21
  import { computeCallCap, createCallCapRef, softExecDeadlineMs, toolCutDeadlineMs, WALLTIME_STALL_CONNECT_MS, WALLTIME_STALL_FIRST_TOKEN_MS, WALLTIME_STALL_IDLE_MS } from "./call-cap.js";
19
22
  import { createCutKillRegistry } from "./cut-kill.js";
20
- import { CHANGED_FILES_MTIME_EPS_MS, renderAgentListingDelta } from "./turn-attachments.js";
23
+ import { CHANGED_FILES_MTIME_EPS_MS, fenceMcpServerInstructions, renderAgentListingDelta } from "./turn-attachments.js";
24
+ import { inlineUntrusted } from "../untrusted-text.js";
21
25
  import { emitTrace } from "../trace.js";
22
26
  import { createSessionRulePolicy } from "./session-rule-policy.js";
23
27
  import { cloneObserverInput, formatHookFeedback, runToolGate } from "../hooks.js";
@@ -27,7 +31,7 @@ import { reservedCollisions, reservedFor } from "../../brain/request-params.js";
27
31
  import { defineTool } from "../tools.js";
28
32
  import { canonicalToolName } from "../tool-name-aliases.js";
29
33
  import { pathToUri } from "../lsp-protocol.js";
30
- import { DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, firstPartyOffloadPolicy, InMemoryToolResultStore, RunnerSharedToolResultStore, ScopedToolResultStore, isVolatileOffloadStore, OFFLOAD_TOOL_NAME, createReadToolResultTool, withToolResultOffload, } from "../tool-result-store.js";
34
+ import { DEFAULT_TOOL_RESULT_THRESHOLD_CHARS, buildToolResultRef, firstPartyOffloadPolicy, InMemoryToolResultStore, RunnerSharedToolResultStore, ScopedToolResultStore, isVolatileOffloadStore, OFFLOAD_TOOL_NAME, createReadToolResultTool, withToolResultOffload, } from "../tool-result-store.js";
31
35
  import { OUTPUT_TOOL_NAME, REPORT_FINDINGS_TOOL_NAME, SKILL_CONTENT_MAX_CHARS, SKILL_TOOL_NAME, createOutputTool, createReportBlockedTool, createReportFindingsTool, createSkillTool, normalizeSkills } from "./synthetic-tools.js";
32
36
  import { compileOutputSchema } from "./strict-output-schema.js";
33
37
  import { TOOL_SEARCH_NAME, buildDeferredRegistry, classifyDeferred, extractDiscoveredToolNames, createPlaceholderTool, createToolSearchTool, } from "./tool-disclosure.js";
@@ -89,6 +93,9 @@ export function resolveModelPromptTraits(model, spec, internals) {
89
93
  fableMitigations: isFableFamilyModelId(model.id),
90
94
  };
91
95
  }
96
+ function isDelegatedNonForkChild(internals) {
97
+ return internals?.isDelegatedChild === true && internals?.insideFork !== true;
98
+ }
92
99
  export function batchContextAt(messages, currentId) {
93
100
  let batch = [];
94
101
  for (const m of messages) {
@@ -738,6 +745,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
738
745
  model: harnessRef.current?.getModel(),
739
746
  thinkingLevel: harnessRef.current?.getThinkingLevel(),
740
747
  principal: spec.principal,
748
+ oneShot: spec.oneShot,
741
749
  clientContext: spec.clientContext,
742
750
  excludeTools: toolFaceSnapshot.exclude,
743
751
  deferTools: toolFaceSnapshot.defer,
@@ -1160,6 +1168,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1160
1168
  taskRegistry: defaultTaskRegistry,
1161
1169
  taskOwner: hostTaskId,
1162
1170
  taskScope,
1171
+ oneShot: spec.oneShot,
1163
1172
  ...(sessionId !== undefined ? { sessionId } : {}),
1164
1173
  ...(internals?.onTaskNotification !== undefined ? { taskNotification: internals.onTaskNotification } : {}),
1165
1174
  ...(internals?.detachHub !== undefined ? { detachHub: internals.detachHub } : {}),
@@ -1208,7 +1217,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1208
1217
  if (backgroundTaskToolsActive || workflowToolsActive) {
1209
1218
  toolEffects.set("TaskOutput", "read");
1210
1219
  toolEffects.set("TaskStop", "write");
1211
- tools.push(firstPartyOffload(createTaskOutputTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore, notificationWired: internals?.onTaskNotification !== undefined, ...(callCapRef ? { deadlineMs: () => toolCutDeadlineMs(callCapRef, Date.now()) } : {}) })), firstPartyOffload(createTaskStopTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore })));
1220
+ tools.push(firstPartyOffload(createTaskOutputTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore, notificationWired: internals?.onTaskNotification !== undefined, oneShot: spec.oneShot, ...(callCapRef ? { deadlineMs: () => toolCutDeadlineMs(callCapRef, Date.now()) } : {}) })), firstPartyOffload(createTaskStopTool({ registry: defaultTaskRegistry, owner: hostTaskId, scope: taskScope, sessionId, workflowStore: deps.workflowRunStore, agentStore: deps.backgroundAgentStore })));
1212
1221
  if (runnerSelf && !(spec.tools ?? []).some((t) => t.name === SEND_MESSAGE_TOOL_NAME)) {
1213
1222
  const delegationForRevive = (spec.tools ?? []).find((t) => t.agentListing !== undefined);
1214
1223
  const reviveSpawn = delegationForRevive !== undefined && deps.backgroundAgentStore !== undefined && deps.mailboxStore !== undefined
@@ -1362,8 +1371,16 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1362
1371
  .catch(() => undefined);
1363
1372
  }
1364
1373
  : undefined;
1365
- const { memoryEngineSession, memoryBlock: memoryBlockFromEngine } = await prepareMemory({ spec, deps, sessionId, taskRootPath, memoryWriteGateRef });
1374
+ const { memoryEngineSession, memoryBlock: memoryBlockFromEngine, seedFiles: memorySeedFiles } = await prepareMemory({ spec, deps, sessionId, taskRootPath, memoryWriteGateRef });
1366
1375
  let memoryBlock = memoryBlockFromEngine;
1376
+ if (memorySeedFiles?.length && seedContextFiles) {
1377
+ try {
1378
+ await seedContextFiles(memorySeedFiles);
1379
+ }
1380
+ catch (err) {
1381
+ deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "config", sessionId });
1382
+ }
1383
+ }
1367
1384
  let instructionSources;
1368
1385
  if (deps.loadProjectMemory) {
1369
1386
  let projectMemoryPhase = spec.sessionId ? "resume" : "fresh";
@@ -1393,7 +1410,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1393
1410
  loaded = await Promise.resolve(deps.loadProjectMemory({
1394
1411
  cwd: taskRootPath,
1395
1412
  handsEnabled,
1396
- isSubagent: internals?.parentTaskId !== undefined,
1413
+ isSubagent: isDelegatedNonForkChild(internals),
1397
1414
  ...(internals?.agentName ? { agentName: internals.agentName } : {}),
1398
1415
  sessionId,
1399
1416
  phase: projectMemoryPhase,
@@ -1420,6 +1437,10 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1420
1437
  memoryBlock = memoryBlock ? `${memoryBlock}\n\n${projectBlock}` : projectBlock;
1421
1438
  }
1422
1439
  }
1440
+ const declaredSkillRank = new Map();
1441
+ for (const s of spec.skills ?? [])
1442
+ if (!declaredSkillRank.has(s.name))
1443
+ declaredSkillRank.set(s.name, declaredSkillRank.size);
1423
1444
  const skillSpecs = normalizeSkills(spec.skills ?? []).filter((s) => {
1424
1445
  if (s.content.length <= SKILL_CONTENT_MAX_CHARS)
1425
1446
  return true;
@@ -1445,6 +1466,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1445
1466
  name: s.name,
1446
1467
  description: s.description,
1447
1468
  ...(s.files !== undefined ? { files: s.files.map((f) => ({ path: f.path })) } : {}),
1469
+ ...(declaredSkillRank.get(s.name) !== undefined ? { declaredRank: declaredSkillRank.get(s.name) } : {}),
1448
1470
  })),
1449
1471
  seedAnnounced: resume !== undefined || spec.sessionId !== undefined,
1450
1472
  }
@@ -1473,12 +1495,12 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1473
1495
  awarenessEnabled: thinking !== undefined && ULTRA_REASONING_TIERS.has(thinking),
1474
1496
  worktreeIsolated: internals?.isolation === "worktree" && ownedEnv !== undefined,
1475
1497
  withinTaskCompactionEnabled: (spec.compaction?.enabled ?? true) && (spec.compaction?.withinTask ?? true),
1476
- isSubagent: internals?.isDelegatedChild === true && internals?.insideFork !== true,
1498
+ isSubagent: isDelegatedNonForkChild(internals),
1477
1499
  };
1478
1500
  const userSystemPrompt = spec.systemPrompt ?? resolvedRole.systemPrompt ?? internals?.defaultSystemPrompt;
1479
1501
  const userAppendSystemPrompt = spec.appendSystemPrompt;
1480
1502
  const mcpInstructionsBlock = mcp.serverInstructions.length
1481
- ? `# MCP Server Instructions\n${mcp.serverInstructions.map((s) => `## ${s.server}\n${s.text}`).join("\n\n")}`
1503
+ ? `# MCP Server Instructions\n${mcp.serverInstructions.map((s) => fenceMcpServerInstructions(s.server, s.text)).join("\n\n")}`
1482
1504
  : undefined;
1483
1505
  const userTz = spec.clientContext?.timeZone;
1484
1506
  const tzValid = userTz !== undefined && isValidTimeZone(userTz);
@@ -1760,7 +1782,13 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1760
1782
  }
1761
1783
  const turnSnapshotRef = {};
1762
1784
  let harnessTools = tools;
1785
+ const failedMcpServers = mcp.statuses
1786
+ .filter((s) => s.status === "failed")
1787
+ .map((s) => ({ name: inlineUntrusted(s.name, 160), ...(s.error !== undefined ? { error: inlineUntrusted(s.error, 240) } : {}) }));
1763
1788
  let toolsDeltaRef;
1789
+ if (deferred.size > 0 || failedMcpServers.length > 0) {
1790
+ toolsDeltaRef = { pending: [], pendingRemoved: [], pendingReadded: [], pendingFailed: failedMcpServers };
1791
+ }
1764
1792
  const listingRideRef = {};
1765
1793
  if (deferred.size > 0) {
1766
1794
  if (deferred.has(TOOL_SEARCH_NAME) || tools.some((t) => t.name === TOOL_SEARCH_NAME)) {
@@ -1787,7 +1815,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1787
1815
  return list;
1788
1816
  };
1789
1817
  const announcedTools = new Set(activeTools);
1790
- toolsDeltaRef = { pending: [] };
1818
+ const withdrawnTools = new Set();
1791
1819
  const deltaRef = toolsDeltaRef;
1792
1820
  const rematerialize = async (active) => {
1793
1821
  const list = buildToolList(active);
@@ -1795,10 +1823,23 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1795
1823
  if (fpRef.current)
1796
1824
  fpRef.current.tools = toolsToFingerprintInputs(list);
1797
1825
  turnSnapshotRef.current?.refreshTools(toolsToFingerprintInputs(list));
1826
+ const live = new Set(list.map((t) => t.name));
1827
+ for (const n of [...announcedTools]) {
1828
+ if (!live.has(n)) {
1829
+ announcedTools.delete(n);
1830
+ withdrawnTools.add(n);
1831
+ deltaRef.pendingRemoved.push(n);
1832
+ }
1833
+ }
1798
1834
  for (const n of active) {
1835
+ if (!live.has(n))
1836
+ continue;
1799
1837
  if (!announcedTools.has(n)) {
1800
1838
  announcedTools.add(n);
1801
- deltaRef.pending.push(n);
1839
+ if (withdrawnTools.delete(n))
1840
+ deltaRef.pendingReadded.push(n);
1841
+ else
1842
+ deltaRef.pending.push(n);
1802
1843
  }
1803
1844
  }
1804
1845
  };
@@ -2351,7 +2392,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
2351
2392
  : foldedPolicy;
2352
2393
  const hooks = spec.hooks ?? deps.hooks;
2353
2394
  const onAsk = spec.onAsk ?? deps.onAsk;
2354
- const handWriteTools = handsEnabled
2395
+ const handWriteTools = handsEnabled && spec.handsReadOnly !== true
2355
2396
  ? Object.keys(HAND_TOOL_EFFECTS).filter((name) => {
2356
2397
  const eff = HAND_TOOL_EFFECTS[name];
2357
2398
  return eff === "write" || eff === "idempotent";
@@ -3035,7 +3076,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
3035
3076
  ? {
3036
3077
  offload: {
3037
3078
  persist: (toolCallId, fullText) => {
3038
- const ref = `tr_${sessionId}_${toolCallId}`;
3079
+ const ref = buildToolResultRef(sessionId, toolCallId);
3039
3080
  void offloadStore.put(ref, fullText);
3040
3081
  return ref;
3041
3082
  },
@@ -3136,15 +3177,29 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
3136
3177
  const onCompactionApplied = handsEnabled && readFileStateForCheckpoint
3137
3178
  ? (attachedComplete, preserveReadState) => applyCompactionToReadFileState(readFileStateForCheckpoint, attachedComplete, preserveReadState)
3138
3179
  : undefined;
3180
+ const changedFilesReadDenied = denyNarrowingPolicy === undefined
3181
+ ? undefined
3182
+ : async (path) => {
3183
+ try {
3184
+ const d = await denyNarrowingPolicy.check({ toolName: "Read", args: { file_path: path }, toolCallId: "changed-files-visibility-probe" }, abortController.signal);
3185
+ return d.action === "deny";
3186
+ }
3187
+ catch {
3188
+ return false;
3189
+ }
3190
+ };
3139
3191
  const detectExternalChanges = handsEnabled && readFileStateForCheckpoint
3140
3192
  ? async (maxFiles) => {
3141
3193
  const candidates = [...readFileStateForCheckpoint.entries()]
3142
3194
  .filter(([, e]) => e.lastReadAt !== undefined)
3195
+ .filter(([, e]) => e.truncated !== true)
3143
3196
  .sort((a, b) => (b[1].lastReadAt ?? 0) - (a[1].lastReadAt ?? 0))
3144
3197
  .slice(0, Math.max(0, maxFiles));
3145
3198
  const changed = [];
3146
3199
  const evicted = [];
3147
3200
  for (const [path, entry] of candidates) {
3201
+ if (changedFilesReadDenied !== undefined && (await changedFilesReadDenied(path)))
3202
+ continue;
3148
3203
  try {
3149
3204
  const info = await executionEnv.fileInfo(path, abortController.signal);
3150
3205
  if (!info.ok) {
@@ -3218,7 +3273,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
3218
3273
  : undefined;
3219
3274
  overheadState.promptChars = systemPrompt.length;
3220
3275
  const preparedHolder = {};
3221
- const buildPrepared = () => ({ harness, session, sessionId, taskRootPath, model, thinking, compModel, mcp: mcp, blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, nestedStats, cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), releaseSignal, cacheBreakDetector, cacheFingerprint, promptManifest, epochDeclaredSections, activeTools, ownedEnv, suspendRef, reviewRef, reviewRequestRef, suspendLoopRef, suspendForResource, ...(callCapRef ? { callCapRef } : {}), ...(cutKills ? { cutKills } : {}), ...(callCapRef ? { callIssuedAtRef } : {}), suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolEffects, promptOverheadTokens, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit } } : {}), planModeRef, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, listBackgroundTasks, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
3276
+ const buildPrepared = () => ({ harness, session, sessionId, taskRootPath, model, thinking, compModel, mcp: mcp, blockedRef, outputRef, abortController, conflictRef, blockedToolCalls, nestedStats, cwdRef: handsCwdRef, ...(worktreeSessionRef !== undefined ? { worktreeSessionRef } : {}), ...(workspaceStateSettle !== undefined ? { workspaceStateSettle } : {}), denyNarrowingPolicy, ...(basePolicyForResumeEdit !== undefined ? { basePolicyForResumeEdit } : {}), releaseSignal, cacheBreakDetector, cacheFingerprint, promptManifest, epochDeclaredSections, activeTools, ...(deferred.size > 0 ? { deferredToolNames: deferred } : {}), ownedEnv, suspendRef, reviewRef, reviewRequestRef, suspendLoopRef, suspendForResource, ...(callCapRef ? { callCapRef } : {}), ...(cutKills ? { cutKills } : {}), ...(callCapRef ? { callIssuedAtRef } : {}), suspendForReview, resourceLedger: priorLedger, liveSpendRef, humanReviewRef, now, tools, toolEffects, promptOverheadTokens, readTaskFile, recentlyReadFiles, normalizeAttachmentPath, isDedupStubResult, ...(onCompactionApplied ? { onCompactionApplied } : {}), compactionReuseRef, trimPressureRef, ...(memoryEngineSession ? { memoryEngineSession } : {}), ...(subagentRetain ? { subagentRetain } : {}), ...(lspDiagnostics && nudgeLspOnEdit ? { lspDiagnostics: { registry: lspDiagnostics, nudge: nudgeLspOnEdit } } : {}), planModeRef, ...(dateChange ? { dateChange } : {}), ...(instructionSources ? { instructionSources } : {}), ...(detectExternalChanges ? { detectExternalChanges } : {}), ...(toolsDeltaRef ? { toolsDeltaRef } : {}), ...(agentListing ? { agentListing } : {}), ...(skillsListing ? { skillsListing } : {}), announcedListingsRef, listBackgroundTasks, ...(turnSnapshotRef.current !== undefined ? { turnSnapshot: turnSnapshotRef.current } : {}), ...(centerCompactionCandidate !== undefined ? { centerCompactionCandidate } : {}) });
3222
3277
  const prepared = buildPrepared();
3223
3278
  preparedHolder.current = prepared;
3224
3279
  return prepared;