@sema-agent/core 5.48.0 → 5.50.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 +112 -0
- package/dist/agents/agent-transcript-tool.d.ts +1 -1
- package/dist/agents/agent-transcript-tool.js +1 -1
- package/dist/agents/roster-store.js +4 -1
- package/dist/agents/send-message-tool.d.ts +2 -2
- package/dist/agents/send-message-tool.js +2 -2
- package/dist/agents/subagent.d.ts +6 -0
- package/dist/agents/subagent.js +126 -1
- package/dist/agents/teacher.d.ts +25 -1
- package/dist/agents/teacher.js +89 -13
- package/dist/brain/anthropic.js +11 -20
- package/dist/brain/open-responses.js +6 -14
- package/dist/brain/openai.js +6 -18
- package/dist/brain/reasoning.d.ts +100 -8
- package/dist/brain/reasoning.js +39 -15
- package/dist/brain/request-params.d.ts +37 -1
- package/dist/brain/request-params.js +40 -2
- package/dist/core/background-agent-store.d.ts +1 -1
- package/dist/core/background-agent-store.js +5 -4
- package/dist/core/mcp.d.ts +7 -1
- package/dist/core/mcp.js +64 -8
- package/dist/core/memory-engine/delegation-settlement.d.ts +27 -0
- package/dist/core/memory-engine/delegation-settlement.js +31 -4
- package/dist/core/memory-engine/dual-root.js +11 -0
- package/dist/core/memory-engine/engine.d.ts +36 -2
- package/dist/core/memory-engine/engine.js +354 -38
- package/dist/core/memory-engine/layout.d.ts +43 -0
- package/dist/core/memory-engine/layout.js +59 -0
- package/dist/core/memory-engine/memory-backend-contract.js +120 -0
- package/dist/core/memory-engine/origin-clearance.d.ts +19 -0
- package/dist/core/memory-engine/origin-clearance.js +10 -0
- package/dist/core/memory-engine/provenance-wording.d.ts +15 -1
- package/dist/core/memory-engine/provenance-wording.js +1 -0
- package/dist/core/memory-engine/tools.js +6 -4
- package/dist/core/memory-engine/types.d.ts +13 -1
- package/dist/core/runner/prepare-task.js +22 -8
- package/dist/core/runner/runtask.d.ts +26 -1
- package/dist/core/runner/runtask.js +18 -2
- package/dist/core/strategy-store.d.ts +180 -3
- package/dist/core/strategy-store.js +172 -23
- package/dist/core/task-registry-agent.js +6 -0
- package/dist/core/types.d.ts +24 -1
- package/dist/index.d.ts +2 -2
- package/dist/index.js +2 -2
- package/dist/orchestration/run-workflow-tool.d.ts +12 -0
- package/dist/orchestration/run-workflow-tool.js +1 -1
- package/dist/orchestration/workflow-governance.d.ts +27 -0
- package/dist/orchestration/workflow-governance.js +13 -0
- package/dist/orchestration/workflow-primitives.d.ts +8 -1
- package/dist/orchestration/workflow-primitives.js +11 -3
- package/dist/stores/file/file-snapshot-store.js +7 -1
- package/dist/stores/file/index.d.ts +8 -0
- package/dist/stores/file/index.js +12 -0
- package/dist/stores/file/session-policy-store.d.ts +0 -13
- package/dist/stores/file/session-policy-store.js +7 -1
- package/dist/stores/file/session-store.d.ts +4 -1
- package/dist/stores/file/session-store.js +7 -1
- package/dist/stores/file/strategy-store.d.ts +97 -0
- package/dist/stores/file/strategy-store.js +340 -0
- package/package.json +1 -1
- package/test/export-surface.snapshot.json +8 -1
|
@@ -0,0 +1,340 @@
|
|
|
1
|
+
import { accessSync, constants as FS, lstatSync, mkdirSync, readFileSync, readdirSync, renameSync, statSync, unlinkSync } from "node:fs";
|
|
2
|
+
import { join } from "node:path";
|
|
3
|
+
import { createHash } from "node:crypto";
|
|
4
|
+
import { atomicWriteFile } from "./fs-atomic.js";
|
|
5
|
+
import { createSafeNotifier, observeThenableRejection } from "../../core/safe-notify.js";
|
|
6
|
+
import { MAX_STRATEGY_INJECTION_TOTAL_BYTES, MAX_STRATEGY_TEXT_BYTES, compileStrategyQuery, resolveCapacityCap, resolveFindLimit, scoreStoredStrategy, storedStrategyShapeIssue, strategyDedupKey, validateStrategyForWrite, } from "../../core/strategy-store.js";
|
|
7
|
+
function configRefusal(message, code) {
|
|
8
|
+
const e = new Error(message);
|
|
9
|
+
e.code = code;
|
|
10
|
+
return e;
|
|
11
|
+
}
|
|
12
|
+
const SCOPE_SLUG_MAX = 40;
|
|
13
|
+
const READ_FILE_CAP_FACTOR = 4;
|
|
14
|
+
const STALE_TEMP_MS = 60 * 60 * 1000;
|
|
15
|
+
const MAX_ENTRY_FILE_BYTES = 65536;
|
|
16
|
+
const FILE_RE = /^([A-Za-z0-9_-]{1,64})\.json$/;
|
|
17
|
+
export class FileStrategyStore {
|
|
18
|
+
root;
|
|
19
|
+
maxPerScope;
|
|
20
|
+
onIncident;
|
|
21
|
+
warnedOps = new Set();
|
|
22
|
+
sinkNotifier = createSafeNotifier();
|
|
23
|
+
sweptTemps = new Set();
|
|
24
|
+
constructor(opts) {
|
|
25
|
+
this.maxPerScope = resolveCapacityCap("maxPerScope", opts.maxPerScope ?? 100);
|
|
26
|
+
this.onIncident = opts.onIncident;
|
|
27
|
+
const root = opts.root;
|
|
28
|
+
if (typeof root !== "string" || root.length === 0) {
|
|
29
|
+
throw configRefusal("FileStrategyStore: root must be a non-empty path", "config.strategy_root_invalid");
|
|
30
|
+
}
|
|
31
|
+
try {
|
|
32
|
+
mkdirSync(root, { recursive: true, mode: 0o700 });
|
|
33
|
+
}
|
|
34
|
+
catch (err) {
|
|
35
|
+
throw configRefusal(`FileStrategyStore: cannot create root ${root}: ${String(err.message ?? err)}`, "config.strategy_root_invalid");
|
|
36
|
+
}
|
|
37
|
+
let st;
|
|
38
|
+
try {
|
|
39
|
+
st = statSync(root);
|
|
40
|
+
}
|
|
41
|
+
catch (err) {
|
|
42
|
+
throw configRefusal(`FileStrategyStore: cannot stat root ${root}: ${String(err.message ?? err)}`, "config.strategy_root_invalid");
|
|
43
|
+
}
|
|
44
|
+
if (!st.isDirectory()) {
|
|
45
|
+
throw configRefusal(`FileStrategyStore: root ${root} exists and is not a directory`, "config.strategy_root_invalid");
|
|
46
|
+
}
|
|
47
|
+
try {
|
|
48
|
+
accessSync(root, FS.W_OK);
|
|
49
|
+
}
|
|
50
|
+
catch {
|
|
51
|
+
throw configRefusal(`FileStrategyStore: root ${root} is not writable`, "config.strategy_root_invalid");
|
|
52
|
+
}
|
|
53
|
+
this.root = root;
|
|
54
|
+
}
|
|
55
|
+
scopeDirName(scope) {
|
|
56
|
+
const slug = scope
|
|
57
|
+
.toLowerCase()
|
|
58
|
+
.replace(/[^a-z0-9-]+/g, "-")
|
|
59
|
+
.replace(/^-+|-+$/g, "")
|
|
60
|
+
.slice(0, SCOPE_SLUG_MAX);
|
|
61
|
+
const h = createHash("sha256").update(scope, "utf8").digest("hex").slice(0, 24);
|
|
62
|
+
return `${slug || "s"}-${h}`;
|
|
63
|
+
}
|
|
64
|
+
scopeDirPath(scope) {
|
|
65
|
+
return join(this.root, this.scopeDirName(scope));
|
|
66
|
+
}
|
|
67
|
+
assertScopeDirSafe(dir) {
|
|
68
|
+
let st;
|
|
69
|
+
try {
|
|
70
|
+
st = lstatSync(dir);
|
|
71
|
+
}
|
|
72
|
+
catch (err) {
|
|
73
|
+
if (err.code === "ENOENT")
|
|
74
|
+
return;
|
|
75
|
+
throw err;
|
|
76
|
+
}
|
|
77
|
+
if (st.isSymbolicLink() || !st.isDirectory()) {
|
|
78
|
+
const e = new Error(`FileStrategyStore: scope directory ${dir} is not a plain directory (symlink or non-dir refused)`);
|
|
79
|
+
e.code = "strategy.scope_dir_invalid";
|
|
80
|
+
throw e;
|
|
81
|
+
}
|
|
82
|
+
}
|
|
83
|
+
incident(i) {
|
|
84
|
+
const sink = this.onIncident;
|
|
85
|
+
if (sink !== undefined) {
|
|
86
|
+
const site = `FileStrategyStore.onIncident.${i.op}`;
|
|
87
|
+
this.sinkNotifier.notify(() => observeThenableRejection(sink(i), this.sinkNotifier, site), site);
|
|
88
|
+
return;
|
|
89
|
+
}
|
|
90
|
+
if (!this.warnedOps.has(i.op)) {
|
|
91
|
+
this.warnedOps.add(i.op);
|
|
92
|
+
console.warn(`FileStrategyStore ${i.op} incident: ${i.error}${i.path !== undefined ? ` (${i.path})` : ""}`);
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
sweepStaleTemps(dir) {
|
|
96
|
+
if (this.sweptTemps.has(dir))
|
|
97
|
+
return;
|
|
98
|
+
this.sweptTemps.add(dir);
|
|
99
|
+
let names;
|
|
100
|
+
try {
|
|
101
|
+
names = readdirSync(dir);
|
|
102
|
+
}
|
|
103
|
+
catch {
|
|
104
|
+
return;
|
|
105
|
+
}
|
|
106
|
+
const cutoff = Date.now() - STALE_TEMP_MS;
|
|
107
|
+
for (const name of names) {
|
|
108
|
+
if (!name.endsWith(".tmp"))
|
|
109
|
+
continue;
|
|
110
|
+
const p = join(dir, name);
|
|
111
|
+
try {
|
|
112
|
+
if (statSync(p).mtimeMs < cutoff)
|
|
113
|
+
unlinkSync(p);
|
|
114
|
+
}
|
|
115
|
+
catch {
|
|
116
|
+
}
|
|
117
|
+
}
|
|
118
|
+
}
|
|
119
|
+
loadScope(scope, dir, readCap) {
|
|
120
|
+
let names;
|
|
121
|
+
try {
|
|
122
|
+
names = readdirSync(dir);
|
|
123
|
+
}
|
|
124
|
+
catch (err) {
|
|
125
|
+
if (err.code === "ENOENT")
|
|
126
|
+
return [];
|
|
127
|
+
throw err;
|
|
128
|
+
}
|
|
129
|
+
let candidates = names.filter((n) => FILE_RE.test(n)).sort();
|
|
130
|
+
if (Number.isFinite(readCap) && candidates.length > readCap) {
|
|
131
|
+
this.incident({
|
|
132
|
+
op: "find",
|
|
133
|
+
error: `scope directory holds ${candidates.length} entry files, over the ${readCap} read cap — parsing the first ${readCap} only (an external writer likely inflated this directory)`,
|
|
134
|
+
path: dir,
|
|
135
|
+
});
|
|
136
|
+
candidates = candidates.slice(0, readCap);
|
|
137
|
+
}
|
|
138
|
+
const out = [];
|
|
139
|
+
for (const name of candidates) {
|
|
140
|
+
const p = join(dir, name);
|
|
141
|
+
let fst;
|
|
142
|
+
try {
|
|
143
|
+
fst = lstatSync(p);
|
|
144
|
+
}
|
|
145
|
+
catch (err) {
|
|
146
|
+
if (err.code === "ENOENT")
|
|
147
|
+
continue;
|
|
148
|
+
this.incident({ op: "find", error: `unstat-able entry skipped: ${String(err.message ?? err)}`, path: p });
|
|
149
|
+
continue;
|
|
150
|
+
}
|
|
151
|
+
if (!fst.isFile()) {
|
|
152
|
+
this.incident({ op: "find", error: "non-regular entry skipped (symlink or special file refused)", path: p });
|
|
153
|
+
continue;
|
|
154
|
+
}
|
|
155
|
+
if (fst.size > MAX_ENTRY_FILE_BYTES) {
|
|
156
|
+
this.quarantine(p, `entry file is ${fst.size} bytes, over the ${MAX_ENTRY_FILE_BYTES} read bound`);
|
|
157
|
+
continue;
|
|
158
|
+
}
|
|
159
|
+
let raw;
|
|
160
|
+
try {
|
|
161
|
+
raw = readFileSync(p, "utf8");
|
|
162
|
+
}
|
|
163
|
+
catch (err) {
|
|
164
|
+
if (err.code === "ENOENT")
|
|
165
|
+
continue;
|
|
166
|
+
this.incident({ op: "find", error: `unreadable entry skipped: ${String(err.message ?? err)}`, path: p });
|
|
167
|
+
continue;
|
|
168
|
+
}
|
|
169
|
+
let parsed;
|
|
170
|
+
try {
|
|
171
|
+
parsed = JSON.parse(raw);
|
|
172
|
+
}
|
|
173
|
+
catch {
|
|
174
|
+
this.quarantine(p, "unparseable JSON");
|
|
175
|
+
continue;
|
|
176
|
+
}
|
|
177
|
+
if (parsed === null || typeof parsed !== "object" || Array.isArray(parsed)) {
|
|
178
|
+
this.quarantine(p, "top-level JSON value is not an object");
|
|
179
|
+
continue;
|
|
180
|
+
}
|
|
181
|
+
const rec = parsed;
|
|
182
|
+
if (rec.v !== 1) {
|
|
183
|
+
this.incident({ op: "parse", error: `unknown schema version ${String(rec.v)} — entry skipped, file left in place`, path: p });
|
|
184
|
+
continue;
|
|
185
|
+
}
|
|
186
|
+
const { v: _v, ...candidate } = rec;
|
|
187
|
+
const issue = storedStrategyShapeIssue(candidate);
|
|
188
|
+
if (issue !== null) {
|
|
189
|
+
this.quarantine(p, issue);
|
|
190
|
+
continue;
|
|
191
|
+
}
|
|
192
|
+
const entry = candidate;
|
|
193
|
+
const fileId = FILE_RE.exec(name)[1];
|
|
194
|
+
if (entry.scope !== scope || entry.id !== fileId) {
|
|
195
|
+
this.incident({
|
|
196
|
+
op: "find",
|
|
197
|
+
error: `entry skipped: scope/id mismatch (file claims scope ${JSON.stringify(entry.scope)}, id ${JSON.stringify(entry.id)})`,
|
|
198
|
+
id: fileId,
|
|
199
|
+
path: p,
|
|
200
|
+
});
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
out.push({ entry, path: p });
|
|
204
|
+
}
|
|
205
|
+
const byKey = new Map();
|
|
206
|
+
for (const le of out) {
|
|
207
|
+
const key = strategyDedupKey(le.entry);
|
|
208
|
+
const prev = byKey.get(key);
|
|
209
|
+
if (prev === undefined || scoreStoredStrategy(le.entry) > scoreStoredStrategy(prev.entry))
|
|
210
|
+
byKey.set(key, le);
|
|
211
|
+
}
|
|
212
|
+
return [...byKey.values()];
|
|
213
|
+
}
|
|
214
|
+
quarantine(p, reason) {
|
|
215
|
+
try {
|
|
216
|
+
renameSync(p, `${p}.bad`);
|
|
217
|
+
this.incident({ op: "parse", error: `corrupt entry quarantined (${reason})`, path: p });
|
|
218
|
+
}
|
|
219
|
+
catch (err) {
|
|
220
|
+
this.incident({ op: "parse", error: `corrupt entry skipped (${reason}); quarantine rename failed: ${String(err.message ?? err)}`, path: p });
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
writeEntry(dir, path, entry) {
|
|
224
|
+
const record = {
|
|
225
|
+
v: 1,
|
|
226
|
+
id: entry.id,
|
|
227
|
+
problem: entry.problem,
|
|
228
|
+
strategy: entry.strategy,
|
|
229
|
+
confidence: entry.confidence,
|
|
230
|
+
scope: entry.scope,
|
|
231
|
+
ts: entry.ts,
|
|
232
|
+
...(entry.teacherModel !== undefined ? { teacherModel: entry.teacherModel } : {}),
|
|
233
|
+
...(entry.signature !== undefined ? { signature: entry.signature } : {}),
|
|
234
|
+
...(entry.origin !== undefined ? { origin: entry.origin } : {}),
|
|
235
|
+
};
|
|
236
|
+
const bytes = JSON.stringify(record);
|
|
237
|
+
if (Buffer.byteLength(bytes, "utf8") > MAX_ENTRY_FILE_BYTES) {
|
|
238
|
+
const e = new Error(`FileStrategyStore: entry serializes over the ${MAX_ENTRY_FILE_BYTES}-byte read bound (JSON escaping expanded it past the field caps) — refusing a write the read side would quarantine`);
|
|
239
|
+
e.code = "strategy.entry_invalid";
|
|
240
|
+
throw e;
|
|
241
|
+
}
|
|
242
|
+
atomicWriteFile(dir, path, bytes);
|
|
243
|
+
}
|
|
244
|
+
save(s) {
|
|
245
|
+
validateStrategyForWrite(s);
|
|
246
|
+
const dir = this.scopeDirPath(s.scope);
|
|
247
|
+
this.assertScopeDirSafe(dir);
|
|
248
|
+
mkdirSync(dir, { recursive: true, mode: 0o700 });
|
|
249
|
+
this.sweepStaleTemps(dir);
|
|
250
|
+
const existing = this.loadScope(s.scope, dir, this.retrievalReadCap());
|
|
251
|
+
const key = strategyDedupKey(s);
|
|
252
|
+
const dup = existing.find((le) => strategyDedupKey(le.entry) === key);
|
|
253
|
+
let all;
|
|
254
|
+
if (dup !== undefined) {
|
|
255
|
+
const refreshed = {
|
|
256
|
+
...dup.entry,
|
|
257
|
+
...(s.confidence >= dup.entry.confidence ? { confidence: s.confidence, ts: s.ts } : {}),
|
|
258
|
+
...(s.teacherModel !== undefined ? { teacherModel: s.teacherModel } : {}),
|
|
259
|
+
};
|
|
260
|
+
this.writeEntry(dir, dup.path, refreshed);
|
|
261
|
+
dup.entry = refreshed;
|
|
262
|
+
all = existing;
|
|
263
|
+
}
|
|
264
|
+
else {
|
|
265
|
+
const p = join(dir, `${s.id}.json`);
|
|
266
|
+
const byId = existing.find((le) => le.entry.id === s.id);
|
|
267
|
+
this.writeEntry(dir, p, s);
|
|
268
|
+
if (byId !== undefined) {
|
|
269
|
+
byId.entry = s;
|
|
270
|
+
all = existing;
|
|
271
|
+
}
|
|
272
|
+
else {
|
|
273
|
+
all = [...existing, { entry: s, path: p }];
|
|
274
|
+
}
|
|
275
|
+
}
|
|
276
|
+
if (all.length > this.maxPerScope) {
|
|
277
|
+
this.evict(all, this.maxPerScope);
|
|
278
|
+
}
|
|
279
|
+
}
|
|
280
|
+
evict(all, keep) {
|
|
281
|
+
const sorted = [...all].sort((a, b) => scoreStoredStrategy(b.entry) - scoreStoredStrategy(a.entry));
|
|
282
|
+
for (const le of sorted.slice(keep)) {
|
|
283
|
+
try {
|
|
284
|
+
unlinkSync(le.path);
|
|
285
|
+
}
|
|
286
|
+
catch (err) {
|
|
287
|
+
if (err.code === "ENOENT")
|
|
288
|
+
continue;
|
|
289
|
+
this.incident({ op: "evict", error: String(err.message ?? err), id: le.entry.id, path: le.path });
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
find(scope, query, limit) {
|
|
294
|
+
const cap = resolveFindLimit(limit);
|
|
295
|
+
const dir = this.scopeDirPath(scope);
|
|
296
|
+
this.assertScopeDirSafe(dir);
|
|
297
|
+
const matches = compileStrategyQuery(query);
|
|
298
|
+
if (matches === null)
|
|
299
|
+
return [];
|
|
300
|
+
const ranked = this.loadScope(scope, dir, this.retrievalReadCap())
|
|
301
|
+
.map((le) => le.entry)
|
|
302
|
+
.filter((e) => matches(e.problem))
|
|
303
|
+
.sort((a, b) => scoreStoredStrategy(b) - scoreStoredStrategy(a))
|
|
304
|
+
.slice(0, cap);
|
|
305
|
+
let bytes = 0;
|
|
306
|
+
for (let i = 0; i < ranked.length; i++) {
|
|
307
|
+
bytes += Buffer.byteLength(ranked[i].strategy, "utf8");
|
|
308
|
+
if (bytes > MAX_STRATEGY_INJECTION_TOTAL_BYTES) {
|
|
309
|
+
this.incident({
|
|
310
|
+
op: "find",
|
|
311
|
+
error: `result truncated at ${i} of ${ranked.length} entries — combined strategy text exceeded ${MAX_STRATEGY_INJECTION_TOTAL_BYTES} bytes (per-entry cap ${MAX_STRATEGY_TEXT_BYTES})`,
|
|
312
|
+
});
|
|
313
|
+
return ranked.slice(0, i);
|
|
314
|
+
}
|
|
315
|
+
}
|
|
316
|
+
return ranked;
|
|
317
|
+
}
|
|
318
|
+
retrievalReadCap() {
|
|
319
|
+
return this.maxPerScope * READ_FILE_CAP_FACTOR;
|
|
320
|
+
}
|
|
321
|
+
prune(scope, maxSize) {
|
|
322
|
+
const n = resolveCapacityCap("maxSize", maxSize);
|
|
323
|
+
const dir = this.scopeDirPath(scope);
|
|
324
|
+
this.assertScopeDirSafe(dir);
|
|
325
|
+
const all = this.loadScope(scope, dir, Number.POSITIVE_INFINITY);
|
|
326
|
+
if (all.length > n)
|
|
327
|
+
this.evict(all, n);
|
|
328
|
+
}
|
|
329
|
+
scopeUsage(scope) {
|
|
330
|
+
const dir = this.scopeDirPath(scope);
|
|
331
|
+
this.assertScopeDirSafe(dir);
|
|
332
|
+
return { used: this.loadScope(scope, dir, Number.POSITIVE_INFINITY).length, capacity: this.maxPerScope };
|
|
333
|
+
}
|
|
334
|
+
hasStrategy(scope, entry) {
|
|
335
|
+
const dir = this.scopeDirPath(scope);
|
|
336
|
+
this.assertScopeDirSafe(dir);
|
|
337
|
+
const key = strategyDedupKey(entry);
|
|
338
|
+
return this.loadScope(scope, dir, this.retrievalReadCap()).some((le) => strategyDedupKey(le.entry) === key);
|
|
339
|
+
}
|
|
340
|
+
}
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"_comment": "design/87 L3 — frozen public export surface of src/index.ts (name -> kind). DO NOT edit by hand to silence a red test. A removed/changed entry = a SemVer-BREAKING change; bump MAJOR and update this fixture in the SAME commit (design/87 §4.2 / §5.2). Regenerate via REGEN in test/export-surface.test.ts.",
|
|
3
|
-
"count":
|
|
3
|
+
"count": 1646,
|
|
4
4
|
"exports": {
|
|
5
5
|
"A2ATaskState": "type",
|
|
6
6
|
"A2ATaskStateReversal": "type",
|
|
@@ -317,6 +317,8 @@
|
|
|
317
317
|
"FileStorageBackend": "class",
|
|
318
318
|
"FileStorageBackendOptions": "interface",
|
|
319
319
|
"FileStorageCorruptReadInfo": "interface",
|
|
320
|
+
"FileStrategyStore": "class",
|
|
321
|
+
"FileStrategyStoreOptions": "interface",
|
|
320
322
|
"FileToolResultStore": "class",
|
|
321
323
|
"FileUsageWindowStore": "class",
|
|
322
324
|
"FileWorkflowJournalStore": "class",
|
|
@@ -866,6 +868,8 @@
|
|
|
866
868
|
"SecretEnvFindingKind": "type",
|
|
867
869
|
"SecretRef": "interface",
|
|
868
870
|
"SectionRenderInputs": "interface",
|
|
871
|
+
"SeedStrategiesReport": "interface",
|
|
872
|
+
"SeedStrategyEntry": "type",
|
|
869
873
|
"SelectiveRecallOptions": "interface",
|
|
870
874
|
"SelectiveRecallResult": "type",
|
|
871
875
|
"SemaTaskHandle": "interface",
|
|
@@ -929,7 +933,9 @@
|
|
|
929
933
|
"StoredSession": "class",
|
|
930
934
|
"StoredSessionRules": "interface",
|
|
931
935
|
"StoredStrategy": "interface",
|
|
936
|
+
"StrategyOrigin": "type",
|
|
932
937
|
"StrategyStore": "interface",
|
|
938
|
+
"StrategyStoreIncident": "interface",
|
|
933
939
|
"StreamFn": "type",
|
|
934
940
|
"StreamingImportValidator": "class",
|
|
935
941
|
"StrictControlPlaneLedger": "type",
|
|
@@ -1571,6 +1577,7 @@
|
|
|
1571
1577
|
"screenInboundEntries": "function",
|
|
1572
1578
|
"screenRuleSyncState": "function",
|
|
1573
1579
|
"scrubSecretEnv": "function",
|
|
1580
|
+
"seedStrategies": "function",
|
|
1574
1581
|
"selectModel": "function",
|
|
1575
1582
|
"selectModelOrThrow": "function",
|
|
1576
1583
|
"selfOrchestrationFailClosedReason": "function",
|