@sema-agent/core 2.0.0 → 2.1.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 (46) hide show
  1. package/dist/agents/observer.js +8 -3
  2. package/dist/agents/send-message-tool.js +112 -81
  3. package/dist/agents/subagent.d.ts +10 -4
  4. package/dist/agents/subagent.js +103 -53
  5. package/dist/core/memory-engine/dual-root.js +2 -0
  6. package/dist/core/memory-engine/engine.d.ts +4 -0
  7. package/dist/core/memory-engine/engine.js +6 -1
  8. package/dist/core/runner/prepare-memory.d.ts +4 -0
  9. package/dist/core/runner/prepare-memory.js +4 -1
  10. package/dist/core/runner/prepare-task.d.ts +8 -2
  11. package/dist/core/runner/prepare-task.js +39 -8
  12. package/dist/core/runner/runtask.js +910 -865
  13. package/dist/core/runner/turn-attachments.d.ts +15 -1
  14. package/dist/core/runner/turn-attachments.js +68 -9
  15. package/dist/core/tool-result-budget.js +2 -2
  16. package/dist/core/tool-result-store.d.ts +2 -0
  17. package/dist/core/tool-result-store.js +27 -2
  18. package/dist/core/tools.js +1 -0
  19. package/dist/core/types.d.ts +1 -1
  20. package/dist/core/workflow-journal-store.d.ts +13 -0
  21. package/dist/engine/loop/agent-loop.d.ts +1 -1
  22. package/dist/engine/loop/agent-loop.js +10 -9
  23. package/dist/engine/session/import-validate.js +29 -0
  24. package/dist/orchestration/workflow.js +28 -1
  25. package/dist/prompt-assembly/event-registry.js +1 -1
  26. package/dist/stores/cc/task-list-store.js +3 -3
  27. package/dist/stores/file/mailbox-store.js +33 -2
  28. package/dist/stores/file/memory-store.d.ts +3 -0
  29. package/dist/stores/file/memory-store.js +39 -12
  30. package/dist/stores/file/tool-result-store.js +16 -2
  31. package/dist/stores/file/workflow-journal-store.d.ts +17 -0
  32. package/dist/stores/file/workflow-journal-store.js +102 -2
  33. package/dist/tools/fs/bash-readonly-classifier.js +1 -1
  34. package/dist/tools/fs/fs-read.js +2 -2
  35. package/dist/tools/fs/fs-search-tools.js +3 -1
  36. package/dist/tools/fs/fs-shared.d.ts +2 -1
  37. package/dist/tools/fs/fs-shared.js +7 -3
  38. package/dist/tools/fs/fs-write.js +9 -11
  39. package/dist/tools/fs/safety.d.ts +3 -0
  40. package/dist/tools/fs/safety.js +20 -7
  41. package/dist/tools/fs/search.d.ts +1 -0
  42. package/dist/tools/fs/search.js +21 -3
  43. package/dist/tools/task-list.d.ts +1 -0
  44. package/dist/tools/task-list.js +13 -2
  45. package/dist/tools/web.js +79 -11
  46. package/package.json +1 -1
@@ -178,6 +178,7 @@ export async function prepareMemory(input) {
178
178
  }
179
179
  }
180
180
  let memoryBlock;
181
+ let seedFiles;
181
182
  if (memorySpec && memorySpec.enabled && !useMemoryEngine) {
182
183
  const detail = "TaskSpec.memory is enabled but RunnerDeps.memoryBackend is not configured; memory is inactive for this task (the legacy memoryStore fallback was retired in design/138 S4 and the dep was removed in design/157 B19).";
183
184
  deps.onError?.(new Error(detail), { phase: "config", sessionId });
@@ -186,6 +187,8 @@ export async function prepareMemory(input) {
186
187
  const injection = memoryEngineSession.inject();
187
188
  if (injection.block.trim())
188
189
  memoryBlock = injection.block;
190
+ if (memoryBlock !== undefined && injection.indexSeed !== undefined)
191
+ seedFiles = [injection.indexSeed];
189
192
  }
190
- return { memoryEngineSession, memoryBlock };
193
+ return { memoryEngineSession, memoryBlock, ...(seedFiles !== undefined ? { seedFiles } : {}) };
191
194
  }
@@ -4,7 +4,7 @@ import { type MaterializedMcp } from "../mcp.js";
4
4
  import type { HarvestReport, MemorySessionHandle } from "../memory-engine/types.js";
5
5
  import { StoredSession } from "../session.js";
6
6
  import type { SessionStore } from "../session.js";
7
- import { SubagentRetainLedger } from "../../agents/subagent.js";
7
+ import { SubagentRetainLedger } from "../../agents/retain-ledger.js";
8
8
  import type { OnAsk, ToolPolicy } from "../tool-policy.js";
9
9
  import { type ActiveSkillFrame } from "./active-skill-scope.js";
10
10
  import { type CutKillRegistry } from "./cut-kill.js";
@@ -207,6 +207,12 @@ export interface Prepared {
207
207
  }>;
208
208
  toolsDeltaRef?: {
209
209
  pending: string[];
210
+ pendingRemoved: string[];
211
+ pendingReadded: string[];
212
+ pendingFailed: Array<{
213
+ name: string;
214
+ error?: string;
215
+ }>;
210
216
  };
211
217
  agentListing?: {
212
218
  entries: ReadonlyArray<{
@@ -311,7 +317,7 @@ export interface RunInternals {
311
317
  parentNotify?: (notification: TaskNotificationPayload, opts?: {
312
318
  priority?: import("../task-notification.js").SystemInjectionPriority;
313
319
  }) => void;
314
- parentRetainLedger?: import("../../agents/subagent.js").SubagentRetainLedger;
320
+ parentRetainLedger?: import("../../agents/retain-ledger.js").SubagentRetainLedger;
315
321
  onNotifyInjectorReady?: (inject: (notification: TaskNotificationPayload, opts?: {
316
322
  priority?: import("../task-notification.js").SystemInjectionPriority;
317
323
  }) => Promise<"queued" | "parked" | "dropped_duplicate">) => void;
@@ -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";
@@ -1362,8 +1366,16 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1362
1366
  .catch(() => undefined);
1363
1367
  }
1364
1368
  : undefined;
1365
- const { memoryEngineSession, memoryBlock: memoryBlockFromEngine } = await prepareMemory({ spec, deps, sessionId, taskRootPath, memoryWriteGateRef });
1369
+ const { memoryEngineSession, memoryBlock: memoryBlockFromEngine, seedFiles: memorySeedFiles } = await prepareMemory({ spec, deps, sessionId, taskRootPath, memoryWriteGateRef });
1366
1370
  let memoryBlock = memoryBlockFromEngine;
1371
+ if (memorySeedFiles?.length && seedContextFiles) {
1372
+ try {
1373
+ await seedContextFiles(memorySeedFiles);
1374
+ }
1375
+ catch (err) {
1376
+ deps.onError?.(err instanceof Error ? err : new Error(String(err)), { phase: "config", sessionId });
1377
+ }
1378
+ }
1367
1379
  let instructionSources;
1368
1380
  if (deps.loadProjectMemory) {
1369
1381
  let projectMemoryPhase = spec.sessionId ? "resume" : "fresh";
@@ -1478,7 +1490,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1478
1490
  const userSystemPrompt = spec.systemPrompt ?? resolvedRole.systemPrompt ?? internals?.defaultSystemPrompt;
1479
1491
  const userAppendSystemPrompt = spec.appendSystemPrompt;
1480
1492
  const mcpInstructionsBlock = mcp.serverInstructions.length
1481
- ? `# MCP Server Instructions\n${mcp.serverInstructions.map((s) => `## ${s.server}\n${s.text}`).join("\n\n")}`
1493
+ ? `# MCP Server Instructions\n${mcp.serverInstructions.map((s) => fenceMcpServerInstructions(s.server, s.text)).join("\n\n")}`
1482
1494
  : undefined;
1483
1495
  const userTz = spec.clientContext?.timeZone;
1484
1496
  const tzValid = userTz !== undefined && isValidTimeZone(userTz);
@@ -1760,7 +1772,13 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1760
1772
  }
1761
1773
  const turnSnapshotRef = {};
1762
1774
  let harnessTools = tools;
1775
+ const failedMcpServers = mcp.statuses
1776
+ .filter((s) => s.status === "failed")
1777
+ .map((s) => ({ name: inlineUntrusted(s.name, 160), ...(s.error !== undefined ? { error: inlineUntrusted(s.error, 240) } : {}) }));
1763
1778
  let toolsDeltaRef;
1779
+ if (deferred.size > 0 || failedMcpServers.length > 0) {
1780
+ toolsDeltaRef = { pending: [], pendingRemoved: [], pendingReadded: [], pendingFailed: failedMcpServers };
1781
+ }
1764
1782
  const listingRideRef = {};
1765
1783
  if (deferred.size > 0) {
1766
1784
  if (deferred.has(TOOL_SEARCH_NAME) || tools.some((t) => t.name === TOOL_SEARCH_NAME)) {
@@ -1787,7 +1805,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1787
1805
  return list;
1788
1806
  };
1789
1807
  const announcedTools = new Set(activeTools);
1790
- toolsDeltaRef = { pending: [] };
1808
+ const withdrawnTools = new Set();
1791
1809
  const deltaRef = toolsDeltaRef;
1792
1810
  const rematerialize = async (active) => {
1793
1811
  const list = buildToolList(active);
@@ -1795,10 +1813,23 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
1795
1813
  if (fpRef.current)
1796
1814
  fpRef.current.tools = toolsToFingerprintInputs(list);
1797
1815
  turnSnapshotRef.current?.refreshTools(toolsToFingerprintInputs(list));
1816
+ const live = new Set(list.map((t) => t.name));
1817
+ for (const n of [...announcedTools]) {
1818
+ if (!live.has(n)) {
1819
+ announcedTools.delete(n);
1820
+ withdrawnTools.add(n);
1821
+ deltaRef.pendingRemoved.push(n);
1822
+ }
1823
+ }
1798
1824
  for (const n of active) {
1825
+ if (!live.has(n))
1826
+ continue;
1799
1827
  if (!announcedTools.has(n)) {
1800
1828
  announcedTools.add(n);
1801
- deltaRef.pending.push(n);
1829
+ if (withdrawnTools.delete(n))
1830
+ deltaRef.pendingReadded.push(n);
1831
+ else
1832
+ deltaRef.pending.push(n);
1802
1833
  }
1803
1834
  }
1804
1835
  };
@@ -3035,7 +3066,7 @@ export async function prepareTask(spec, deps, sessions, resume, internals, runne
3035
3066
  ? {
3036
3067
  offload: {
3037
3068
  persist: (toolCallId, fullText) => {
3038
- const ref = `tr_${sessionId}_${toolCallId}`;
3069
+ const ref = buildToolResultRef(sessionId, toolCallId);
3039
3070
  void offloadStore.put(ref, fullText);
3040
3071
  return ref;
3041
3072
  },