@sema-agent/core 5.65.0 → 6.0.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 (159) hide show
  1. package/CHANGELOG.md +46 -0
  2. package/dist/agents/subagent.d.ts +2 -2
  3. package/dist/agents/subagent.js +11 -0
  4. package/dist/agents/verify.d.ts +1 -1
  5. package/dist/brain/anthropic.js +1 -1
  6. package/dist/brain/errors.d.ts +29 -0
  7. package/dist/brain/errors.js +20 -0
  8. package/dist/brain/open-responses.js +2 -2
  9. package/dist/brain/route-adjudicator.d.ts +8 -1
  10. package/dist/brain/route-adjudicator.js +1 -0
  11. package/dist/brain/status-sink.js +12 -1
  12. package/dist/brain/stream-engine.js +17 -6
  13. package/dist/core/auto-compaction.d.ts +26 -0
  14. package/dist/core/auto-compaction.js +7 -2
  15. package/dist/core/auto-mode-arming.d.ts +138 -0
  16. package/dist/core/auto-mode-arming.js +181 -0
  17. package/dist/core/auto-mode-defaults.d.ts +13 -0
  18. package/dist/core/auto-mode-defaults.js +5 -0
  19. package/dist/core/auto-mode-prompt.d.ts +14 -3
  20. package/dist/core/auto-mode-prompt.js +10 -7
  21. package/dist/core/auto-mode-rebuild.d.ts +75 -0
  22. package/dist/core/auto-mode-rebuild.js +41 -0
  23. package/dist/core/auto-mode.d.ts +15 -0
  24. package/dist/core/auto-mode.js +4 -2
  25. package/dist/core/checkpoint-store.d.ts +18 -0
  26. package/dist/core/context-edit.d.ts +47 -5
  27. package/dist/core/context-guard.d.ts +1 -1
  28. package/dist/core/file-history-retention.d.ts +106 -0
  29. package/dist/core/file-history-retention.js +36 -0
  30. package/dist/core/file-history-store.d.ts +768 -0
  31. package/dist/core/file-history-store.js +880 -0
  32. package/dist/core/governance-codes.d.ts +2 -1
  33. package/dist/core/governance-codes.js +14 -0
  34. package/dist/core/hooks.d.ts +39 -7
  35. package/dist/core/hooks.js +38 -21
  36. package/dist/core/lsp.d.ts +2 -2
  37. package/dist/core/mcp.d.ts +29 -7
  38. package/dist/core/memory-engine/consolidation-driver.d.ts +11 -0
  39. package/dist/core/memory-engine/consolidation-driver.js +71 -4
  40. package/dist/core/memory-engine/consolidation.d.ts +25 -2
  41. package/dist/core/memory-engine/consolidation.js +4 -1
  42. package/dist/core/memory-engine/distiller.d.ts +84 -1
  43. package/dist/core/memory-engine/distiller.js +68 -0
  44. package/dist/core/memory-engine/dual-root.js +3 -0
  45. package/dist/core/memory-engine/engine.d.ts +328 -15
  46. package/dist/core/memory-engine/engine.js +355 -29
  47. package/dist/core/memory-engine/file-backend.d.ts +30 -0
  48. package/dist/core/memory-engine/file-backend.js +14 -13
  49. package/dist/core/memory-engine/frontmatter.d.ts +22 -1
  50. package/dist/core/memory-engine/frontmatter.js +3 -0
  51. package/dist/core/memory-engine/header-hints.d.ts +5 -0
  52. package/dist/core/memory-engine/index.d.ts +5 -4
  53. package/dist/core/memory-engine/index.js +5 -4
  54. package/dist/core/memory-engine/layout.d.ts +88 -2
  55. package/dist/core/memory-engine/layout.js +112 -3
  56. package/dist/core/memory-engine/provenance-wording.d.ts +7 -0
  57. package/dist/core/memory-engine/provenance-wording.js +3 -0
  58. package/dist/core/memory-engine/tools.d.ts +89 -8
  59. package/dist/core/memory-engine/tools.js +263 -22
  60. package/dist/core/memory-engine/types.d.ts +64 -1
  61. package/dist/core/memory-recall.d.ts +6 -0
  62. package/dist/core/memory.d.ts +27 -1
  63. package/dist/core/memory.js +16 -2
  64. package/dist/core/permission-rule-consent.d.ts +20 -0
  65. package/dist/core/permission-rule-consent.js +12 -3
  66. package/dist/core/permission-rule-model.d.ts +67 -7
  67. package/dist/core/permission-rule-model.js +53 -7
  68. package/dist/core/permission-rule-store.js +15 -10
  69. package/dist/core/permission-rule-sync.js +15 -11
  70. package/dist/core/retention-policy.d.ts +9 -0
  71. package/dist/core/retention-policy.js +5 -2
  72. package/dist/core/retention.d.ts +13 -2
  73. package/dist/core/runner/assemble-result.d.ts +19 -1
  74. package/dist/core/runner/assemble-result.js +17 -2
  75. package/dist/core/runner/compaction-call-options.d.ts +93 -0
  76. package/dist/core/runner/compaction-call-options.js +3 -0
  77. package/dist/core/runner/memory-capture-optout.d.ts +80 -0
  78. package/dist/core/runner/memory-capture-optout.js +53 -0
  79. package/dist/core/runner/prepare-config-doors.d.ts +5 -0
  80. package/dist/core/runner/prepare-config-doors.js +16 -0
  81. package/dist/core/runner/prepare-hands-readface.d.ts +110 -5
  82. package/dist/core/runner/prepare-hands-readface.js +99 -7
  83. package/dist/core/runner/prepare-memory.d.ts +88 -0
  84. package/dist/core/runner/prepare-memory.js +305 -24
  85. package/dist/core/runner/prepare-task.d.ts +141 -1
  86. package/dist/core/runner/prepare-task.js +443 -79
  87. package/dist/core/runner/runtask.d.ts +9 -20
  88. package/dist/core/runner/runtask.js +133 -96
  89. package/dist/core/runner/session-file-state-replay.d.ts +18 -10
  90. package/dist/core/runner/session-file-state-replay.js +52 -1
  91. package/dist/core/runner/tool-disclosure.js +2 -1
  92. package/dist/core/runner/turn-attachments.d.ts +22 -12
  93. package/dist/core/session-store.d.ts +1 -1
  94. package/dist/core/session-store.js +6 -1
  95. package/dist/core/session.d.ts +34 -1
  96. package/dist/core/store-contracts/file-history-store-contract.d.ts +3 -0
  97. package/dist/core/store-contracts/file-history-store-contract.js +720 -0
  98. package/dist/core/task-registry-shared.js +11 -1
  99. package/dist/core/tool-errors.js +1 -0
  100. package/dist/core/tool-policy.d.ts +172 -1
  101. package/dist/core/tool-policy.js +32 -1
  102. package/dist/core/tool-result-store.js +2 -1
  103. package/dist/core/trace.d.ts +24 -0
  104. package/dist/core/types.d.ts +784 -89
  105. package/dist/core/types.js +4 -3
  106. package/dist/core/untrusted-text.d.ts +1 -1
  107. package/dist/core/untrusted-text.js +8 -0
  108. package/dist/core/workflow-run-store-contract.js +6 -2
  109. package/dist/core/workflow-run-store.d.ts +4 -1
  110. package/dist/engine/compaction/compaction.d.ts +88 -10
  111. package/dist/engine/compaction/compaction.js +109 -30
  112. package/dist/engine/execution-env/node-execution-env.d.ts +9 -1
  113. package/dist/engine/execution-env/node-execution-env.js +28 -0
  114. package/dist/engine/harness/agent-harness.d.ts +52 -1
  115. package/dist/engine/harness/agent-harness.js +36 -1
  116. package/dist/engine/harness/types.d.ts +26 -1
  117. package/dist/engine/llm/types.d.ts +50 -4
  118. package/dist/engine/loop/agent-loop.d.ts +5 -1
  119. package/dist/engine/loop/agent-loop.js +25 -0
  120. package/dist/engine/loop/types.d.ts +19 -0
  121. package/dist/engine/lsp/node-lsp-manager.d.ts +1 -1
  122. package/dist/engine/session/session.js +1 -1
  123. package/dist/index.d.ts +18 -8
  124. package/dist/index.js +14 -6
  125. package/dist/orchestration/run-workflow-tool.d.ts +20 -2
  126. package/dist/orchestration/run-workflow-tool.js +22 -3
  127. package/dist/orchestration/workflow-governance.d.ts +59 -1
  128. package/dist/orchestration/workflow-governance.js +61 -8
  129. package/dist/orchestration/workflow-meta.d.ts +4 -2
  130. package/dist/orchestration/workflow-primitives.js +56 -13
  131. package/dist/orchestration/workflow-types.d.ts +78 -2
  132. package/dist/orchestration/workflow.d.ts +20 -0
  133. package/dist/orchestration/workflow.js +163 -14
  134. package/dist/prompt-assembly/event-registry.js +1 -1
  135. package/dist/prompts/default.d.ts +7 -7
  136. package/dist/stores/file/file-history-store.d.ts +368 -0
  137. package/dist/stores/file/file-history-store.js +1248 -0
  138. package/dist/stores/file/index.d.ts +22 -13
  139. package/dist/stores/file/index.js +4 -4
  140. package/dist/stores/file/permission-rule-store.js +1 -0
  141. package/dist/stores/file/strategy-store.d.ts +3 -3
  142. package/dist/tools/fs/bash-readonly-classifier.d.ts +87 -3
  143. package/dist/tools/fs/bash-readonly-classifier.js +106 -4
  144. package/dist/tools/fs/fs-bash.js +9 -5
  145. package/dist/tools/fs/fs-shared.d.ts +52 -1
  146. package/dist/tools/fs/fs-shared.js +14 -0
  147. package/dist/tools/fs/fs-write.d.ts +5 -5
  148. package/dist/tools/fs/fs-write.js +71 -14
  149. package/dist/tools/fs/index.d.ts +6 -1
  150. package/dist/tools/fs/index.js +1 -1
  151. package/dist/tools/web.js +2 -1
  152. package/package.json +5 -1
  153. package/test/export-surface.snapshot.json +155 -23
  154. package/dist/core/file-snapshot-store.d.ts +0 -165
  155. package/dist/core/file-snapshot-store.js +0 -259
  156. package/dist/core/store-contracts/file-snapshot-store-contract.d.ts +0 -13
  157. package/dist/core/store-contracts/file-snapshot-store-contract.js +0 -134
  158. package/dist/stores/file/file-snapshot-store.d.ts +0 -58
  159. package/dist/stores/file/file-snapshot-store.js +0 -353
@@ -1,353 +0,0 @@
1
- import { createHash } from "node:crypto";
2
- import { existsSync, readdirSync, readFileSync, rmSync } from "node:fs";
3
- import { join } from "node:path";
4
- import { applyManifest, captureManifest, DEFAULT_SNAPSHOT_BOUNDS, } from "../../core/file-snapshot-store.js";
5
- import { canonicalStoreKey, ensureDir, sanitizePathComponent, sanitizeScope, writeThenLink } from "./fs-atomic.js";
6
- import { assertAdoptionBootGate } from "./adoption/marker.js";
7
- const sharedInFlight = new Map();
8
- function containSinkThenable(r) {
9
- if (typeof r?.then === "function") {
10
- r.then(undefined, () => {
11
- });
12
- }
13
- }
14
- export class FileFileSnapshotStore {
15
- base;
16
- blobsDir;
17
- manifestsDir;
18
- get inFlight() {
19
- let t = sharedInFlight.get(this.inFlightKey);
20
- if (t === undefined) {
21
- t = new Map();
22
- sharedInFlight.set(this.inFlightKey, t);
23
- }
24
- return t;
25
- }
26
- inFlightKey;
27
- bounds;
28
- onCorruptRead;
29
- constructor(root, bounds, opts) {
30
- assertAdoptionBootGate(root, "FileFileSnapshotStore");
31
- this.base = join(root, "file-snapshots");
32
- this.blobsDir = join(this.base, "blobs");
33
- this.manifestsDir = join(this.base, "manifests");
34
- ensureDir(this.blobsDir);
35
- ensureDir(this.manifestsDir);
36
- this.inFlightKey = canonicalStoreKey(this.base);
37
- this.bounds = {
38
- maxFiles: bounds?.maxFiles ?? DEFAULT_SNAPSHOT_BOUNDS.maxFiles,
39
- maxBytes: bounds?.maxBytes ?? DEFAULT_SNAPSHOT_BOUNDS.maxBytes,
40
- ignoreDirs: new Set(bounds?.ignoreDirs ?? DEFAULT_SNAPSHOT_BOUNDS.ignoreDirs),
41
- };
42
- this.onCorruptRead = opts?.onCorruptRead;
43
- }
44
- disclose(path, reason) {
45
- try {
46
- containSinkThenable(this.onCorruptRead?.({ path, reason }));
47
- }
48
- catch {
49
- }
50
- }
51
- scopeDir(scope) {
52
- return join(this.manifestsDir, sanitizeScope(scope));
53
- }
54
- manifestPath(scope, key) {
55
- return join(this.scopeDir(scope), `${sanitizePathComponent(key)}.json`);
56
- }
57
- tryManifestPath(scope, key) {
58
- try {
59
- return this.manifestPath(scope, key);
60
- }
61
- catch {
62
- return null;
63
- }
64
- }
65
- blobPath(hash) {
66
- return join(this.blobsDir, sanitizePathComponent(hash));
67
- }
68
- readManifest(path) {
69
- let raw;
70
- try {
71
- raw = readFileSync(path, "utf8");
72
- }
73
- catch (err) {
74
- if (err.code === "ENOENT")
75
- return null;
76
- throw err;
77
- }
78
- try {
79
- const parsed = JSON.parse(raw);
80
- if (Array.isArray(parsed))
81
- return new Map(parsed);
82
- this.disclose(path, "manifest is not a pair array — read as no snapshot");
83
- return null;
84
- }
85
- catch {
86
- this.disclose(path, "unparseable manifest JSON (torn/zero-byte write?) — read as no snapshot");
87
- return null;
88
- }
89
- }
90
- async snapshot(scope, key, env, root, signal) {
91
- const mpath = this.tryManifestPath(scope, key);
92
- if (!mpath)
93
- return { ok: false, error: { code: "restore_failed", message: `unsafe snapshot key ${JSON.stringify(key)}` } };
94
- if (this.inFlight.has(mpath))
95
- return { ok: true };
96
- if (this.readManifest(mpath) !== null)
97
- return { ok: true };
98
- if (existsSync(mpath)) {
99
- try {
100
- rmSync(mpath, { force: true });
101
- }
102
- catch {
103
- }
104
- }
105
- const written = new Set();
106
- this.inFlight.set(mpath, written);
107
- try {
108
- const captured = await captureManifest(env, root, this.bounds, signal, (hash, bytes) => {
109
- written.add(hash);
110
- try {
111
- writeThenLink(this.blobPath(hash), bytes);
112
- }
113
- catch (err) {
114
- if (err.code !== "EEXIST")
115
- throw err;
116
- }
117
- });
118
- if (!captured.ok)
119
- return captured;
120
- ensureDir(this.scopeDir(scope));
121
- writeThenLink(mpath, JSON.stringify([...captured.value]));
122
- return { ok: true };
123
- }
124
- catch (err) {
125
- if (err.code === "EEXIST")
126
- return { ok: true };
127
- return { ok: false, error: { code: "restore_failed", message: `snapshot persist failed: ${err.message}` } };
128
- }
129
- finally {
130
- this.inFlight.delete(mpath);
131
- }
132
- }
133
- async restore(scope, key, env, root, signal) {
134
- const mpath = this.tryManifestPath(scope, key);
135
- const manifest = mpath ? this.readManifest(mpath) : null;
136
- if (!manifest)
137
- return { ok: false, error: { code: "not_found", message: `no snapshot for key ${key}` } };
138
- return applyManifest(env, root, this.bounds, signal, manifest, (hash) => {
139
- try {
140
- return readFileSync(this.blobPath(hash));
141
- }
142
- catch (err) {
143
- return undefined;
144
- }
145
- });
146
- }
147
- async listKeys(scope) {
148
- const dir = this.scopeDir(scope);
149
- let entries;
150
- try {
151
- entries = readdirSync(dir);
152
- }
153
- catch (err) {
154
- if (err.code === "ENOENT")
155
- return [];
156
- this.disclose(dir, `manifest scope directory unreadable (${err.code ?? "unknown"}) — listed as no keys`);
157
- return [];
158
- }
159
- return entries
160
- .filter((f) => f.endsWith(".json"))
161
- .filter((f) => this.readManifest(join(dir, f)) !== null)
162
- .map((f) => f.slice(0, -".json".length));
163
- }
164
- async has(scope, key) {
165
- const mpath = this.tryManifestPath(scope, key);
166
- return mpath !== null && this.readManifest(mpath) !== null;
167
- }
168
- async exportManifest(scope, key) {
169
- const mpath = this.tryManifestPath(scope, key);
170
- return mpath ? this.readManifest(mpath) : null;
171
- }
172
- async getBlob(hash) {
173
- try {
174
- return readFileSync(this.blobPath(hash));
175
- }
176
- catch {
177
- return undefined;
178
- }
179
- }
180
- async putBlob(hash, bytes) {
181
- if (createHash("sha256").update(bytes).digest("hex") !== hash) {
182
- return { ok: false, error: { code: "read_failed", message: `blob bytes fail content-address integrity for ${hash}` } };
183
- }
184
- try {
185
- writeThenLink(this.blobPath(hash), bytes);
186
- }
187
- catch (err) {
188
- if (err.code === "EEXIST")
189
- return { ok: true };
190
- return { ok: false, error: { code: "restore_failed", message: `putBlob persist failed: ${err.message}` } };
191
- }
192
- return { ok: true };
193
- }
194
- async importManifest(scope, key, manifest, srcGetBlob) {
195
- const mpath = this.tryManifestPath(scope, key);
196
- if (!mpath)
197
- return { ok: false, error: { code: "restore_failed", message: `unsafe snapshot key ${JSON.stringify(key)}` } };
198
- if (this.inFlight.has(mpath))
199
- return { ok: true };
200
- if (this.readManifest(mpath) !== null)
201
- return { ok: true };
202
- if (existsSync(mpath)) {
203
- try {
204
- rmSync(mpath, { force: true });
205
- }
206
- catch {
207
- }
208
- }
209
- const written = new Set();
210
- this.inFlight.set(mpath, written);
211
- try {
212
- for (const hash of new Set(manifest.values())) {
213
- written.add(hash);
214
- let bpath;
215
- try {
216
- bpath = this.blobPath(hash);
217
- }
218
- catch {
219
- return { ok: false, error: { code: "read_failed", message: `unsafe blob hash ${JSON.stringify(hash)}` } };
220
- }
221
- if (existsSync(bpath))
222
- continue;
223
- let bytes;
224
- try {
225
- bytes = await srcGetBlob(hash);
226
- }
227
- catch (err) {
228
- return { ok: false, error: { code: "read_failed", message: `source blob ${hash} fetch failed: ${err.message}` } };
229
- }
230
- if (!bytes)
231
- return { ok: false, error: { code: "read_failed", message: `missing source blob ${hash}` } };
232
- if (createHash("sha256").update(bytes).digest("hex") !== hash) {
233
- return { ok: false, error: { code: "read_failed", message: `source blob ${hash} fails content-address integrity` } };
234
- }
235
- try {
236
- writeThenLink(bpath, bytes);
237
- }
238
- catch (err) {
239
- if (err.code !== "EEXIST")
240
- throw err;
241
- }
242
- }
243
- ensureDir(this.scopeDir(scope));
244
- writeThenLink(mpath, JSON.stringify([...manifest]));
245
- return { ok: true };
246
- }
247
- catch (err) {
248
- if (err.code === "EEXIST")
249
- return { ok: true };
250
- return { ok: false, error: { code: "restore_failed", message: `import persist failed: ${err.message}` } };
251
- }
252
- finally {
253
- this.inFlight.delete(mpath);
254
- }
255
- }
256
- async reap(scope, keepKeys) {
257
- const keep = new Set(keepKeys);
258
- const dir = this.scopeDir(scope);
259
- let removed = 0;
260
- let entries;
261
- try {
262
- entries = readdirSync(dir);
263
- }
264
- catch (err) {
265
- if (err.code === "ENOENT")
266
- entries = [];
267
- else {
268
- entries = [];
269
- this.disclose(dir, `manifest scope directory unreadable (${err.code ?? "unknown"}) — the manifest-deletion pass was skipped`);
270
- }
271
- }
272
- for (const file of entries) {
273
- if (!file.endsWith(".json"))
274
- continue;
275
- const key = file.slice(0, -".json".length);
276
- if (!keep.has(key)) {
277
- if (safeRm(join(dir, file)))
278
- removed++;
279
- }
280
- }
281
- const live = new Set();
282
- for (const hs of this.inFlight.values())
283
- for (const h of hs)
284
- live.add(h);
285
- let complete = true;
286
- let scopeDirs;
287
- try {
288
- scopeDirs = readdirSync(this.manifestsDir);
289
- }
290
- catch (err) {
291
- if (err.code === "ENOENT")
292
- scopeDirs = [];
293
- else {
294
- this.disclose(this.manifestsDir, `manifest root unreadable (${err.code ?? "unknown"}) — blob GC aborted, every blob kept`);
295
- return removed;
296
- }
297
- }
298
- for (const scopeName of scopeDirs) {
299
- const sdir = join(this.manifestsDir, scopeName);
300
- let files;
301
- try {
302
- files = readdirSync(sdir);
303
- }
304
- catch (err) {
305
- if (err.code === "ENOENT")
306
- continue;
307
- complete = false;
308
- this.disclose(sdir, `manifest scope directory unreadable (${err.code ?? "unknown"}) — blob GC aborted, every blob kept`);
309
- break;
310
- }
311
- for (const file of files) {
312
- if (!file.endsWith(".json"))
313
- continue;
314
- const m = this.readManifest(join(sdir, file));
315
- if (!m) {
316
- complete = false;
317
- this.disclose(join(sdir, file), "manifest unreadable during the live-set scan — blob GC aborted, every blob kept");
318
- break;
319
- }
320
- for (const h of m.values())
321
- live.add(h);
322
- }
323
- if (!complete)
324
- break;
325
- }
326
- if (!complete)
327
- return removed;
328
- let blobs;
329
- try {
330
- blobs = readdirSync(this.blobsDir);
331
- }
332
- catch (err) {
333
- if (err.code !== "ENOENT") {
334
- this.disclose(this.blobsDir, `blob directory unreadable (${err.code ?? "unknown"}) — blob GC skipped, every blob kept`);
335
- }
336
- return removed;
337
- }
338
- for (const blob of blobs) {
339
- if (!live.has(blob))
340
- safeRm(join(this.blobsDir, blob));
341
- }
342
- return removed;
343
- }
344
- }
345
- function safeRm(path) {
346
- try {
347
- rmSync(path, { force: true });
348
- return true;
349
- }
350
- catch {
351
- return false;
352
- }
353
- }