@sema-agent/core 5.16.0 → 5.17.0-pre.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 (38) hide show
  1. package/CHANGELOG.md +118 -0
  2. package/dist/agents/peer-admission.d.ts +58 -0
  3. package/dist/agents/peer-admission.js +175 -0
  4. package/dist/agents/retain-ledger.d.ts +1 -1
  5. package/dist/agents/retain-ledger.js +9 -1
  6. package/dist/agents/send-message-tool.d.ts +8 -0
  7. package/dist/agents/send-message-tool.js +171 -21
  8. package/dist/agents/subagent.d.ts +5 -0
  9. package/dist/agents/subagent.js +21 -3
  10. package/dist/core/ask-question.js +10 -0
  11. package/dist/core/mailbox-store.d.ts +2 -0
  12. package/dist/core/mailbox-store.js +2 -2
  13. package/dist/core/runner/prepare-task.d.ts +3 -0
  14. package/dist/core/runner/prepare-task.js +92 -25
  15. package/dist/core/runner/runtask.js +10 -0
  16. package/dist/core/shared-memory/contract.d.ts +17 -0
  17. package/dist/core/shared-memory/contract.js +138 -0
  18. package/dist/core/shared-memory/normalize.d.ts +73 -0
  19. package/dist/core/shared-memory/normalize.js +259 -0
  20. package/dist/core/shared-memory/tools.d.ts +7 -0
  21. package/dist/core/shared-memory/tools.js +289 -0
  22. package/dist/core/shared-memory/types.d.ts +95 -0
  23. package/dist/core/shared-memory/types.js +18 -0
  24. package/dist/core/task-notification.d.ts +3 -0
  25. package/dist/core/task-registry-agent.d.ts +1 -1
  26. package/dist/core/task-registry-agent.js +1 -1
  27. package/dist/core/task-registry.d.ts +1 -1
  28. package/dist/core/task-registry.js +2 -0
  29. package/dist/core/types.d.ts +7 -0
  30. package/dist/core/untrusted-text.d.ts +1 -0
  31. package/dist/core/untrusted-text.js +10 -0
  32. package/dist/engine/harness/agent-harness.d.ts +1 -0
  33. package/dist/engine/harness/agent-harness.js +21 -2
  34. package/dist/index.d.ts +3 -0
  35. package/dist/index.js +3 -0
  36. package/dist/stores/cc/mailbox-store.js +4 -0
  37. package/dist/stores/file/mailbox-store.js +2 -2
  38. package/package.json +1 -1
@@ -120,7 +120,7 @@ export declare function deliverToRunningAgentLane(core: DurableAgentCore, id: st
120
120
  disposition: "queued" | "parked" | "pending";
121
121
  } | {
122
122
  ok: false;
123
- reason: "not_found" | "not_running" | "no_channel";
123
+ reason: "not_found" | "not_running" | "no_channel" | "queue_full";
124
124
  }>;
125
125
  export declare function runningBackgroundAgentLabelsLane(core: DurableAgentCore, access: TaskAccess): string[];
126
126
  export declare function runningAgentFooterLane(core: DurableAgentCore, access: TaskAccess): {
@@ -1102,7 +1102,7 @@ export async function deliverToRunningAgentLane(core, id, access, notification,
1102
1102
  return { ok: false, reason: "no_channel" };
1103
1103
  const q = (handle.preAttachQueue ??= []);
1104
1104
  if (q.length >= 8)
1105
- return { ok: false, reason: "no_channel" };
1105
+ return { ok: false, reason: "queue_full" };
1106
1106
  return bounded(new Promise((resolve) => {
1107
1107
  q.push([notification, opts, resolve]);
1108
1108
  }), { ok: true, disposition: "pending" });
@@ -195,7 +195,7 @@ export declare class TaskRegistry {
195
195
  disposition: "queued" | "parked" | "pending";
196
196
  } | {
197
197
  ok: false;
198
- reason: "not_found" | "not_running" | "no_channel";
198
+ reason: "not_found" | "not_running" | "no_channel" | "queue_full";
199
199
  }>;
200
200
  runningBackgroundAgentLabels(access: TaskAccess): string[];
201
201
  private pollBackgroundAgent;
@@ -957,6 +957,8 @@ The durable record is still marked running (last update ${new Date(row.updatedAt
957
957
  for (const [id, handle] of this.handles) {
958
958
  if (handle.status === "running" || handle.status === "pending")
959
959
  continue;
960
+ if (this.claimingHandles.has(id) || this.reapingHandles.has(id))
961
+ continue;
960
962
  if (now - handle.updatedAt < terminalTtlMs)
961
963
  continue;
962
964
  this.handles.delete(id);
@@ -90,8 +90,13 @@ export interface ToolExecuteContext {
90
90
  outcome: import("./checkpoint-store.js").ResumeOutcome;
91
91
  inheritedGate?: import("./runner/prepare-task.js").InheritedGate;
92
92
  };
93
+ peerSeed?: {
94
+ hopChain: string[];
95
+ };
93
96
  };
94
97
  spawnedAgentName?: string;
98
+ peerSelfRef?: import("../agents/peer-admission.js").PeerSelfRef;
99
+ peerInboundChainRef?: import("../agents/peer-admission.js").PeerInboundChainRef;
95
100
  roster?: import("../agents/roster-store.js").RosterStore;
96
101
  hostSessionFork?: () => Promise<{
97
102
  sessionId: string;
@@ -792,6 +797,7 @@ export interface RunnerDeps {
792
797
  workflowRunStore?: import("./workflow-run-store.js").WorkflowRunStore;
793
798
  backgroundAgentStore?: import("./background-agent-store.js").BackgroundAgentStore;
794
799
  mailboxStore?: import("./mailbox-store.js").MailboxStore;
800
+ peerAdmission?: Partial<import("../agents/peer-admission.js").PeerAdmissionConfig>;
795
801
  usageWindows?: readonly import("./usage-window-store.js").UsageWindow[];
796
802
  usageWindowStore?: import("./usage-window-store.js").UsageWindowStore;
797
803
  workflowJournalStore?: import("./workflow-journal-store.js").WorkflowJournalStore;
@@ -802,6 +808,7 @@ export interface RunnerDeps {
802
808
  brainCallGuardrailMs?: import("../brain/timeout.js").BrainCallGuardrailKnob;
803
809
  now?: () => number;
804
810
  memoryBackend?: import("./memory-engine/types.js").MemoryBackend;
811
+ sharedMemoryStores?: import("./shared-memory/types.js").SharedMemoryStoreProvider;
805
812
  memoryEngineDir?: string;
806
813
  onMemoryHarvestReport?: (report: import("./memory-engine/types.js").HarvestReport, info: {
807
814
  sessionId: string;
@@ -23,5 +23,6 @@ export declare function cutEngineSegments(text: string, segments: unknown): {
23
23
  };
24
24
  export declare function flattenableUserText(content: unknown): string | undefined;
25
25
  export declare function defuseFenceMarkers(body: string): string;
26
+ export declare function defuseControlChars(text: string): string;
26
27
  export declare function inlineUntrusted(text: string, maxLen?: number): string;
27
28
  export declare function delimitUntrusted(label: string, text: string, maxBody?: number): string;
@@ -87,6 +87,16 @@ export function flattenableUserText(content) {
87
87
  export function defuseFenceMarkers(body) {
88
88
  return body.replace(/<{3,}|>{3,}/g, (run) => run.match(/.{1,2}/g).join(ZWSP));
89
89
  }
90
+ const REPLACEMENT = "�";
91
+ export function defuseControlChars(text) {
92
+ let out = "";
93
+ for (const ch of text.replace(/\r\n?/g, "\n")) {
94
+ const cp = ch.codePointAt(0) ?? 0;
95
+ const control = cp !== 9 && cp !== 10 && (cp < 32 || (cp >= 127 && cp <= 159));
96
+ out += control ? REPLACEMENT : ch;
97
+ }
98
+ return out;
99
+ }
90
100
  const LABEL_MAX = 160;
91
101
  export function inlineUntrusted(text, maxLen = LABEL_MAX) {
92
102
  const oneLine = text.replace(/[\s\u0000-\u001f\u007f\u0085]+/g, " ").trim();
@@ -36,6 +36,7 @@ export declare class AgentHarness<TSkill extends Skill = Skill, TPromptTemplate
36
36
  private model;
37
37
  private thinkingLevel;
38
38
  onUndrainedEngineNotes?: (payloads: unknown[]) => void;
39
+ onEngineNoteConsumed?: (payload: unknown) => void;
39
40
  recoverUndrainedEngineNotes(): void;
40
41
  private sweepUndrainedEngineNotes;
41
42
  private systemPrompt;
@@ -158,6 +158,7 @@ export class AgentHarness {
158
158
  model;
159
159
  thinkingLevel;
160
160
  onUndrainedEngineNotes;
161
+ onEngineNoteConsumed;
161
162
  recoverUndrainedEngineNotes() {
162
163
  this.sweepUndrainedEngineNotes([this.nextTurnQueue, this.steerQueue, this.followUpQueue]);
163
164
  }
@@ -438,8 +439,17 @@ export class AgentHarness {
438
439
  }
439
440
  try {
440
441
  await this.emitQueueUpdate();
441
- for (const m of messages)
442
+ for (const m of messages) {
443
+ const payload = engineNotePayloads.get(m);
444
+ if (payload !== undefined) {
445
+ try {
446
+ this.onEngineNoteConsumed?.(payload);
447
+ }
448
+ catch {
449
+ }
450
+ }
442
451
  engineNotePayloads.delete(m);
452
+ }
443
453
  return messages;
444
454
  }
445
455
  catch (error) {
@@ -648,8 +658,17 @@ export class AgentHarness {
648
658
  this.nextTurnQueue.unshift(...queuedMessages);
649
659
  throw normalizeHookError(error);
650
660
  }
651
- for (const m of queuedMessages)
661
+ for (const m of queuedMessages) {
662
+ const payload = engineNotePayloads.get(m);
663
+ if (payload !== undefined) {
664
+ try {
665
+ this.onEngineNoteConsumed?.(payload);
666
+ }
667
+ catch {
668
+ }
669
+ }
652
670
  engineNotePayloads.delete(m);
671
+ }
653
672
  messages = [...queuedMessages, messages[0]];
654
673
  }
655
674
  const beforeResult = await this.emitHook({
package/dist/index.d.ts CHANGED
@@ -129,6 +129,8 @@ export { createPermissionRulePolicy, validatePermissionRules, parsePermissionRul
129
129
  export { formatHookFeedback, runToolGate, createHookEnvCapabilities, type Hooks, type HookToolContext, type HookEnvCapabilities, type HookToolOutput, type PreToolUseResult, type PostToolUseResult, type UserPromptSubmitResult, type HookToolFailure, type PostToolUseFailureResult, type PostToolBatchCall, type PostToolBatchResult, type PreCompactContext, type PreCompactResult, type PostCompactContext, type StopFailureContext, type PermissionDeniedPayload, type PermissionDeniedSource, } from "./core/hooks.js";
130
130
  export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, type NormalizedMemorySpec, type MemorySpecInput, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, type Embedder, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, type UtilityGate, type MemoryStore, type MemoryVectorMode, type ScoredMemory, type MemoryNoteHeader, type MemoryNoteRecord, type MemoryNoteType, type StructuredNoteInput, } from "./core/memory.js";
131
131
  export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, type MemoryBackendContractHooks, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, type MemoryAnnouncement, type ScanFinding, type MemoryEngineOptions, type MemoryInjection, type MemoryBackend, type MemoryEntry, type MemoryEntryFrontmatter, type MemoryEntryHeader, type ScoredMemoryEntry, type NotePatch, type PatchReport, type MaterializedFile, type MemorySessionHandle, type HarvestReport, type HarvestRejection, type HarvestRejectionCode, type ParsedEntryFile, type ScannedEntryFile, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, type ParsedScopeKey, migrateScope, type MigrateScopeReport, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, type RemoteMemoryFile, type RemoteMemoryBaseline, type RemoteMaterialization, type RemoteHarvestResult, type InboundEntryFinding, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, type MemorySyncCursor, type MemorySyncConflict, type MemorySyncPlan, type RecallSource, syncMemoryScope, type MemorySyncTransport, type MemorySyncRequestBody, type MemorySyncResponseBody, type MemorySyncClientConflict, type SyncMemoryScopeOptions, type MemorySyncClientResult, } from "./core/memory-engine/index.js";
132
+ export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, type SharedMemoryStoreProvider, type SharedMemoryStoreReader, type SharedMemoryStoreInfo, type SharedMemoryDocumentEntry, type SharedMemorySnapshot, type SharedMemoryRequestContext, type MemoryListDetails, type MemoryReadDetails, } from "./core/shared-memory/types.js";
133
+ export { sharedMemoryStoreContract, type SharedMemoryFixture, type SharedMemoryStoreContractHooks, } from "./core/shared-memory/contract.js";
132
134
  export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.js";
133
135
  export { encodeSurfacedKey, buildManifestText, validateSelectedIds, composeSelectiveBody, formatMemoryAge, resolveLinkedIds, RECALL_CAVEAT, DEFAULT_MAX_SELECTED, DEFAULT_MAX_LINKED, type MemorySelector, type MemorySelectRequest, type SelectiveRecallOptions, type SelectiveRecallResult, type LayeredRecallOptions, type LayeredRecallResult, type ScopedNoteHeader, type ScopedNoteRecord, } from "./core/memory-recall.js";
134
136
  export { runMemoryConsolidation, CONSOLIDATION_SYSTEM_PROMPT, DEFAULT_CONSOLIDATION_BAND, DEFAULT_CONSOLIDATION_SEARCH_LIMIT, DEFAULT_CONSOLIDATION_MAX_NOTES, DEFAULT_CONSOLIDATION_TIMEOUT_SEC, normalizeForExactMatch, type ConsolidationParams, type ConsolidationStats, type ConsolidationNote, type ConsolidationLLM, } from "./core/runner/memory-consolidation.js";
@@ -195,6 +197,7 @@ export { COORDINATOR_ROLE_PROMPT, TEAMMATE_COMMUNICATION_ADDENDUM, TEAMMATE_TASK
195
197
  export { createSubagentTool, FORK_SUBAGENT_TYPE, GENERAL_PURPOSE_SUBAGENT_TYPE, agentWhenToUseText, FORK_DIRECTIVE_FRAME, SUBAGENT_SYSTEM_NOTE, type SubagentToolOptions, type SubagentSpawnContext, type SubagentSteerHandle, type SubagentStep, type SubagentEditedFile, } from "./agents/subagent.js";
196
198
  export { getSessionRetainLedger, releaseSessionRetainLedger, } from "./agents/retain-ledger.js";
197
199
  export { createSendMessageTool, SEND_MESSAGE_TOOL_NAME, type SendMessageToolOptions } from "./agents/send-message-tool.js";
200
+ export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerAdmissionConfig, PEER_ADMISSION_DEFAULTS, PEER_HOP_CHAIN_WINDOW, PEER_MESSAGE_NOTICE, createPeerSelfRef, createPeerInboundChainRef, peerAxisToken, appendHopToken, type PeerAdmission, type PeerAdmissionConfig, type PeerAdmissionOptions, type PeerAdmissionRequest, type PeerAdmissionVerdict, type PeerAdmissionRefusal, type PeerRefusalCode, type PeerAxisTag, type PeerIdentity, type PeerSelfRef, type PeerInboundChainRef, } from "./agents/peer-admission.js";
198
201
  export { createAgentTranscriptTool, AGENT_TRANSCRIPT_TOOL_NAME, type AgentTranscriptToolOptions, } from "./agents/agent-transcript-tool.js";
199
202
  export { defineAgent } from "./agents/agent-definition.js";
200
203
  export { builtinAgentDefinitions, BUILTIN_READONLY_DENY_TOOLS, EXPLORE_WHEN_TO_USE, EXPLORE_WHEN_TO_USE_LEAN, PLAN_WHEN_TO_USE, EXPLORE_SYSTEM_PROMPT, PLAN_SYSTEM_PROMPT, } from "./agents/builtin-agents.js";
package/dist/index.js CHANGED
@@ -114,6 +114,8 @@ export { createPermissionRulePolicy, validatePermissionRules, parsePermissionRul
114
114
  export { formatHookFeedback, runToolGate, createHookEnvCapabilities, } from "./core/hooks.js";
115
115
  export { InMemoryMemoryStore, composeMemoryBlock, composeLayeredMemoryBlock, normalizeMemorySpec, supportsConsolidation, supportsPeriodicConsolidation, firstSentence, expandLexicalTerms, lexicalSearchMatch, classifyPromotable, enforcePromotableWriteGate, guardedMemoryStore, MemoryGateError, detectSecret, enforceSecretWriteGate, enforceStructuredNoteSecretGate, } from "./core/memory.js";
116
116
  export { MemoryEngine, FileMemoryEngineBackend, memoryBackendContract, assertMemoryBackendSearchEquivalence, buildMemoryInstruction, truncateIndex, scanEntryFiles, deriveRepoKey, deriveRepoMemoryDir, deriveControlPlaneDir, deriveRepoControlPlaneDir, resolveMemoryEngineRoot, scopeDirName, ControlPlaneCorruptError, parseEntryFile, serializeEntryFile, computeEntryRev, entryFromFile, MEMORY_INSTRUCTION_TEMPLATE, MEMORY_INDEX_FILENAME, MEMORY_INDEX_MAX_LINES, MEMORY_INDEX_MAX_BYTES, STUB_ARCHIVED_LINE, DEFAULT_MAX_MEMORY_FILES, DEFAULT_MAX_ENTRY_DEPTH, DEFAULT_HARVEST_DEADLINE_MS, DEFAULT_HARVEST_FILE_BUDGET, MASS_DELETION_FUSE_RATIO, scanMemoryWrite, scanMemoryFileName, scanRemediation, MEMORY_FILENAME_SEGMENT_RE, renderAnnouncements, enqueueMemoryAnnouncement, drainMemoryAnnouncements, peekMemoryAnnouncements, bumpScanFuse, scanFuseCount, clearScanFuse, ANNOUNCEMENTS_FILE, MEMORY_ANNOUNCEMENTS_MAX, SCAN_FUSE_FILE, SCAN_FUSE_THRESHOLD, SCOPE_SEGMENT_MAX_ENCODED, PROJECT_MARKER_PATH, encodeScopeSegment, decodeScopeSegment, parseScopeKey, formatUserScope, formatOrgScope, formatProjScope, formatUserProjScope, isPersonalScope, assertScopeContractPlacement, formatProjectMarker, parseProjectMarker, resolveProjectId, PROJECT_ID_REGEX, migrateScope, materializeEntriesToFiles, harvestFilesToPatches, projectionsToWriteBack, screenInboundEntries, REMOTE_HARVEST_PER_FILE_BYTES, REMOTE_MASS_DELETION_FUSE_RATIO, deriveProjectMemoryDir, deriveProjectControlDir, recordProjectIdHint, lookupProjectIdHint, PROJECT_ID_HINTS_FILE, reconcileMemoryEntries, nextSyncBaseline, mergeRecallHits, syncMemoryScope, } from "./core/memory-engine/index.js";
117
+ export { SHARED_MEMORY_READ_CAP_BYTES, SHARED_MEMORY_LIST_PAGE_SIZE, SharedMemoryStoreError, } from "./core/shared-memory/types.js";
118
+ export { sharedMemoryStoreContract, } from "./core/shared-memory/contract.js";
117
119
  export { termSet, jaccardDistance, cosineDistance } from "./core/memory-vector.js";
118
120
  export { encodeSurfacedKey, buildManifestText, validateSelectedIds, composeSelectiveBody, formatMemoryAge, resolveLinkedIds, RECALL_CAVEAT, DEFAULT_MAX_SELECTED, DEFAULT_MAX_LINKED, } from "./core/memory-recall.js";
119
121
  export { runMemoryConsolidation, CONSOLIDATION_SYSTEM_PROMPT, DEFAULT_CONSOLIDATION_BAND, DEFAULT_CONSOLIDATION_SEARCH_LIMIT, DEFAULT_CONSOLIDATION_MAX_NOTES, DEFAULT_CONSOLIDATION_TIMEOUT_SEC, normalizeForExactMatch, } from "./core/runner/memory-consolidation.js";
@@ -177,6 +179,7 @@ export { COORDINATOR_ROLE_PROMPT, TEAMMATE_COMMUNICATION_ADDENDUM, TEAMMATE_TASK
177
179
  export { createSubagentTool, FORK_SUBAGENT_TYPE, GENERAL_PURPOSE_SUBAGENT_TYPE, agentWhenToUseText, FORK_DIRECTIVE_FRAME, SUBAGENT_SYSTEM_NOTE, } from "./agents/subagent.js";
178
180
  export { getSessionRetainLedger, releaseSessionRetainLedger, } from "./agents/retain-ledger.js";
179
181
  export { createSendMessageTool, SEND_MESSAGE_TOOL_NAME } from "./agents/send-message-tool.js";
182
+ export { createPeerAdmission, peerAdmissionFor, judgePeerAdmission, resolvePeerAdmissionConfig, PEER_ADMISSION_DEFAULTS, PEER_HOP_CHAIN_WINDOW, PEER_MESSAGE_NOTICE, createPeerSelfRef, createPeerInboundChainRef, peerAxisToken, appendHopToken, } from "./agents/peer-admission.js";
180
183
  export { createAgentTranscriptTool, AGENT_TRANSCRIPT_TOOL_NAME, } from "./agents/agent-transcript-tool.js";
181
184
  export { defineAgent } from "./agents/agent-definition.js";
182
185
  export { builtinAgentDefinitions, BUILTIN_READONLY_DENY_TOOLS, EXPLORE_WHEN_TO_USE, EXPLORE_WHEN_TO_USE_LEAN, PLAN_WHEN_TO_USE, EXPLORE_SYSTEM_PROMPT, PLAN_SYSTEM_PROMPT, } from "./agents/builtin-agents.js";
@@ -149,6 +149,7 @@ export function createCcFileMailboxStore(opts) {
149
149
  msgV: 1,
150
150
  msg_id: randomUUID(),
151
151
  read: false,
152
+ ...(msg.hopChain !== undefined ? { hopChain: [...msg.hopChain] } : {}),
152
153
  });
153
154
  saveBox(path, box);
154
155
  return box.length;
@@ -174,6 +175,9 @@ export function createCcFileMailboxStore(opts) {
174
175
  ...(typeof e.from === "string" ? { from: e.from } : {}),
175
176
  content: typeof e.text === "string" ? e.text : "",
176
177
  sentAt: typeof e.timestamp === "string" ? Date.parse(e.timestamp) || 0 : 0,
178
+ ...(Array.isArray(e.hopChain) && e.hopChain.every((h) => typeof h === "string")
179
+ ? { hopChain: e.hopChain.filter((h) => typeof h === "string") }
180
+ : {}),
177
181
  }));
178
182
  if (pending.length === 0)
179
183
  return Promise.resolve(null);
@@ -116,7 +116,7 @@ export class FileMailboxStore {
116
116
  return withPathLock(this.lockKey(scope, handle), () => {
117
117
  const b = this.load(scope, handle);
118
118
  const seq = b.nextSeq;
119
- const m = { seq, ...(msg.from !== undefined ? { from: msg.from } : {}), content: msg.content, sentAt: msg.sentAt };
119
+ const m = { seq, ...(msg.from !== undefined ? { from: msg.from } : {}), content: msg.content, sentAt: msg.sentAt, ...(msg.hopChain !== undefined ? { hopChain: [...msg.hopChain] } : {}) };
120
120
  this.commit(b, this.boxPath(scope, handle), { t: "append", m });
121
121
  return seq;
122
122
  });
@@ -130,7 +130,7 @@ export class FileMailboxStore {
130
130
  return null;
131
131
  const maxSeq = b.messages[b.messages.length - 1].seq;
132
132
  this.commit(b, this.boxPath(scope, handle), { t: "lease", owner, expiresAt: now + ttlMs, maxSeq });
133
- return { messages: b.messages.map((m) => ({ ...m })), maxSeq };
133
+ return { messages: b.messages.map((m) => ({ ...m, ...(m.hopChain !== undefined ? { hopChain: [...m.hopChain] } : {}) })), maxSeq };
134
134
  });
135
135
  }
136
136
  async ack(scope, handle, owner, upToSeq) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@sema-agent/core",
3
- "version": "5.16.0",
3
+ "version": "5.17.0-pre.0",
4
4
  "description": "Stateless, task-oriented AI agent core",
5
5
  "type": "module",
6
6
  "license": "BUSL-1.1",