@wrongstack/core 0.9.20 → 0.10.2
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/README.md +37 -33
- package/dist/{agent-bridge-Dti3KXGk.d.ts → agent-bridge-DBBGP5O4.d.ts} +1 -1
- package/dist/{agent-subagent-runner-U-rs7kk7.d.ts → agent-subagent-runner-KwufTWwn.d.ts} +3 -3
- package/dist/{compactor-D7X96RLZ.d.ts → compactor-D1RHFRmF.d.ts} +1 -1
- package/dist/{config-CLXMDOSs.d.ts → config-CJXBka2r.d.ts} +38 -2
- package/dist/{context-zkZeILpr.d.ts → context-7u93AcGD.d.ts} +94 -0
- package/dist/coordination/index.d.ts +12 -12
- package/dist/coordination/index.js +130 -58
- package/dist/coordination/index.js.map +1 -1
- package/dist/{default-config-Uzla85H-.d.ts → default-config-DEXI4jsl.d.ts} +10 -1
- package/dist/defaults/index.d.ts +24 -24
- package/dist/defaults/index.js +611 -95
- package/dist/defaults/index.js.map +1 -1
- package/dist/{events-DH-9r-_C.d.ts → events-Bw1K5E6K.d.ts} +8 -1
- package/dist/execution/index.d.ts +18 -15
- package/dist/execution/index.js +309 -61
- package/dist/execution/index.js.map +1 -1
- package/dist/extension/index.d.ts +6 -6
- package/dist/extension/index.js.map +1 -1
- package/dist/goal-store-BeRsj7YX.d.ts +188 -0
- package/dist/{index-CFO9QmJo.d.ts → index-DIt5TIaF.d.ts} +8 -8
- package/dist/{index-BIHJ4uII.d.ts → index-DgQWnZxP.d.ts} +5 -5
- package/dist/index.d.ts +56 -35
- package/dist/index.js +742 -203
- package/dist/index.js.map +1 -1
- package/dist/infrastructure/index.d.ts +6 -6
- package/dist/kernel/index.d.ts +9 -9
- package/dist/kernel/index.js +57 -8
- package/dist/kernel/index.js.map +1 -1
- package/dist/{mcp-servers-DkESgh0G.d.ts → mcp-servers-BgINZzuo.d.ts} +3 -3
- package/dist/models/index.d.ts +3 -3
- package/dist/models/index.js +163 -10
- package/dist/models/index.js.map +1 -1
- package/dist/models-registry-gwMAo6E3.d.ts +86 -0
- package/dist/{multi-agent-DNp6lAzg.d.ts → multi-agent-C1O8EFzb.d.ts} +45 -4
- package/dist/{multi-agent-coordinator-CAhsegPz.d.ts → multi-agent-coordinator-DoVSBFNx.d.ts} +2 -2
- package/dist/{null-fleet-bus-Dnl19vmf.d.ts → null-fleet-bus-T-s3JaOt.d.ts} +8 -6
- package/dist/observability/index.d.ts +2 -2
- package/dist/{path-resolver-CHiBL0DD.d.ts → path-resolver-BfyK-I7w.d.ts} +2 -2
- package/dist/{permission-H35s9Evv.d.ts → permission-B6sldrSp.d.ts} +1 -1
- package/dist/{permission-policy-CT-nRmTn.d.ts → permission-policy-CtNscWOA.d.ts} +10 -9
- package/dist/{plan-templates-Bs8iRwi6.d.ts → plan-templates-BWs6Je7j.d.ts} +8 -8
- package/dist/{provider-runner-BZdDrWrS.d.ts → provider-runner-BmPe2RuU.d.ts} +3 -3
- package/dist/{retry-policy-J9N_PM40.d.ts → retry-policy-KF18W4dg.d.ts} +1 -1
- package/dist/sdd/index.d.ts +8 -8
- package/dist/sdd/index.js +130 -58
- package/dist/sdd/index.js.map +1 -1
- package/dist/security/index.d.ts +65 -4
- package/dist/security/index.js +67 -19
- package/dist/security/index.js.map +1 -1
- package/dist/{selector-CFTh3Z6p.d.ts → selector-DmXxpFyM.d.ts} +1 -1
- package/dist/{session-reader-C7JJlxOw.d.ts → session-reader-CCSBfQmd.d.ts} +1 -1
- package/dist/storage/index.d.ts +7 -7
- package/dist/storage/index.js +125 -6
- package/dist/storage/index.js.map +1 -1
- package/dist/{system-prompt-CneIxVip.d.ts → system-prompt-CM6zOhd2.d.ts} +19 -1
- package/dist/{tool-executor-flTuxsqO.d.ts → tool-executor-D7RxLtg4.d.ts} +4 -4
- package/dist/types/index.d.ts +16 -16
- package/dist/types/index.js +344 -14
- package/dist/types/index.js.map +1 -1
- package/dist/utils/index.d.ts +23 -3
- package/dist/utils/index.js +66 -1
- package/dist/utils/index.js.map +1 -1
- package/dist/{wstack-paths-BCgmTNlG.d.ts → wstack-paths-eMXnY1_X.d.ts} +8 -0
- package/package.json +1 -1
- package/dist/goal-store-C7jcumEh.d.ts +0 -96
- package/dist/models-registry-OG_30xqZ.d.ts +0 -46
package/dist/index.js
CHANGED
|
@@ -142,8 +142,10 @@ var ERROR_CODES = {
|
|
|
142
142
|
// Container / Registry
|
|
143
143
|
CONTAINER_TOKEN_ALREADY_BOUND: "CONTAINER_TOKEN_ALREADY_BOUND",
|
|
144
144
|
CONTAINER_TOKEN_NOT_BOUND: "CONTAINER_TOKEN_NOT_BOUND",
|
|
145
|
+
CONTAINER_CIRCULAR_DEPENDENCY: "CONTAINER_CIRCULAR_DEPENDENCY",
|
|
145
146
|
REGISTRY_DUPLICATE: "REGISTRY_DUPLICATE",
|
|
146
147
|
REGISTRY_NOT_FOUND: "REGISTRY_NOT_FOUND",
|
|
148
|
+
REGISTRY_INVALID: "REGISTRY_INVALID",
|
|
147
149
|
// File system
|
|
148
150
|
FS_READ_FAILED: "FS_READ_FAILED",
|
|
149
151
|
FS_WRITE_FAILED: "FS_WRITE_FAILED",
|
|
@@ -306,6 +308,16 @@ function isFsError(err) {
|
|
|
306
308
|
// src/kernel/container.ts
|
|
307
309
|
var Container = class {
|
|
308
310
|
entries = /* @__PURE__ */ new Map();
|
|
311
|
+
/**
|
|
312
|
+
* Tokens currently mid-resolve. Tracked so we can detect circular
|
|
313
|
+
* dependencies (A → B → A) and throw a structured error instead of
|
|
314
|
+
* overflowing the call stack with "Maximum call stack size exceeded".
|
|
315
|
+
*
|
|
316
|
+
* Not a memoization cache — the per-entry `cache` field is the source
|
|
317
|
+
* of truth for "have I built this before?". This set only lives for
|
|
318
|
+
* the duration of a single resolve call.
|
|
319
|
+
*/
|
|
320
|
+
resolving = /* @__PURE__ */ new Set();
|
|
309
321
|
bind(token, factory, opts = {}) {
|
|
310
322
|
if (this.entries.has(token)) {
|
|
311
323
|
throw new WrongStackError({
|
|
@@ -366,14 +378,43 @@ var Container = class {
|
|
|
366
378
|
if (entry.singleton && entry.cache !== void 0) {
|
|
367
379
|
return entry.cache;
|
|
368
380
|
}
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
381
|
+
if (this.resolving.has(token)) {
|
|
382
|
+
const cycle = this.describeCycle(token);
|
|
383
|
+
throw new WrongStackError({
|
|
384
|
+
message: `Container: circular dependency detected \u2014 ${cycle}`,
|
|
385
|
+
code: ERROR_CODES.CONTAINER_CIRCULAR_DEPENDENCY,
|
|
386
|
+
subsystem: "container",
|
|
387
|
+
context: { token: token.description, cycle }
|
|
388
|
+
});
|
|
389
|
+
}
|
|
390
|
+
this.resolving.add(token);
|
|
391
|
+
try {
|
|
392
|
+
let value = entry.factory(this);
|
|
393
|
+
for (const d of entry.decorators) {
|
|
394
|
+
value = d(value, this);
|
|
395
|
+
}
|
|
396
|
+
if (entry.singleton) {
|
|
397
|
+
entry.cache = value;
|
|
398
|
+
}
|
|
399
|
+
return value;
|
|
400
|
+
} finally {
|
|
401
|
+
this.resolving.delete(token);
|
|
372
402
|
}
|
|
373
|
-
|
|
374
|
-
|
|
403
|
+
}
|
|
404
|
+
/**
|
|
405
|
+
* Build a human-readable description of the dependency cycle that
|
|
406
|
+
* caused the resolution to re-enter. Lists the tokens in the order
|
|
407
|
+
* they were entered, then appends the re-entered token to close the
|
|
408
|
+
* loop. Falls back to a generic message if the resolving set is
|
|
409
|
+
* somehow empty (shouldn't happen, but defensive).
|
|
410
|
+
*/
|
|
411
|
+
describeCycle(reentry) {
|
|
412
|
+
const descs = [];
|
|
413
|
+
for (const t2 of this.resolving) {
|
|
414
|
+
descs.push(t2.description ?? "unknown");
|
|
375
415
|
}
|
|
376
|
-
|
|
416
|
+
descs.push(reentry.description ?? "unknown");
|
|
417
|
+
return descs.join(" \u2192 ");
|
|
377
418
|
}
|
|
378
419
|
has(token) {
|
|
379
420
|
return this.entries.has(token);
|
|
@@ -644,7 +685,8 @@ var EventBus = class {
|
|
|
644
685
|
}
|
|
645
686
|
if (this.wildcards.length > 0) {
|
|
646
687
|
const name = event;
|
|
647
|
-
|
|
688
|
+
const snapshot = this.wildcards.slice();
|
|
689
|
+
for (const { match, fn } of snapshot) {
|
|
648
690
|
if (!match(name)) continue;
|
|
649
691
|
try {
|
|
650
692
|
fn(name, payload);
|
|
@@ -715,11 +757,19 @@ var ScopedEventBus = class extends EventBus {
|
|
|
715
757
|
* Uses EventBus's public API directly to avoid triggering our own `on()`
|
|
716
758
|
* override (which would consume a key slot for the wrapper, then orphan
|
|
717
759
|
* our registration entry under a different key).
|
|
760
|
+
*
|
|
761
|
+
* When the wrapper fires, it cleans up BOTH the underlying EventBus
|
|
762
|
+
* listener AND the tracking entry — so `scopedListenerCount` returns to
|
|
763
|
+
* its pre-`once()` value without requiring the caller to invoke the
|
|
764
|
+
* returned unsubscribe. The returned `unsub` is still safe to call
|
|
765
|
+
* after auto-removal (its delete is a no-op and its off() finds
|
|
766
|
+
* nothing to remove).
|
|
718
767
|
*/
|
|
719
768
|
once(event, fn) {
|
|
720
769
|
const key = this.nextKey++;
|
|
721
770
|
const wrapper = (payload) => {
|
|
722
771
|
EventBus.prototype.off.call(this, event, wrapper);
|
|
772
|
+
this.registrations.delete(key);
|
|
723
773
|
fn(payload);
|
|
724
774
|
};
|
|
725
775
|
EventBus.prototype.on.call(this, event, wrapper);
|
|
@@ -1024,6 +1074,14 @@ var DEFAULT_CONTEXT_CONFIG = Object.freeze({
|
|
|
1024
1074
|
var DEFAULT_AUTONOMY_CONFIG = Object.freeze({
|
|
1025
1075
|
autoProceedDelayMs: 45e3
|
|
1026
1076
|
});
|
|
1077
|
+
var DEFAULT_SESSION_LOGGING_CONFIG = Object.freeze({
|
|
1078
|
+
auditLevel: "standard",
|
|
1079
|
+
sampling: {
|
|
1080
|
+
toolProgress: {
|
|
1081
|
+
sampleRate: 8
|
|
1082
|
+
}
|
|
1083
|
+
}
|
|
1084
|
+
});
|
|
1027
1085
|
|
|
1028
1086
|
// src/types/secret-vault.ts
|
|
1029
1087
|
var ENCRYPTED_PREFIX = "enc:v1:";
|
|
@@ -2140,6 +2198,71 @@ var DefaultSecretScrubber = class {
|
|
|
2140
2198
|
|
|
2141
2199
|
// src/models/models-registry.ts
|
|
2142
2200
|
init_atomic_write();
|
|
2201
|
+
|
|
2202
|
+
// src/utils/merge-models-payload.ts
|
|
2203
|
+
function mergeModelsPayload(base, overlay) {
|
|
2204
|
+
const out = {};
|
|
2205
|
+
for (const [id, provider] of Object.entries(base)) {
|
|
2206
|
+
out[id] = cloneProvider(provider);
|
|
2207
|
+
}
|
|
2208
|
+
for (const [id, ovProvider] of Object.entries(overlay)) {
|
|
2209
|
+
const existing = out[id];
|
|
2210
|
+
out[id] = existing ? mergeProvider(existing, ovProvider) : cloneProvider(ovProvider);
|
|
2211
|
+
}
|
|
2212
|
+
return out;
|
|
2213
|
+
}
|
|
2214
|
+
function mergeProvider(base, overlay) {
|
|
2215
|
+
const models = {};
|
|
2216
|
+
for (const [mid, m] of Object.entries(base.models ?? {})) {
|
|
2217
|
+
models[mid] = { ...m };
|
|
2218
|
+
}
|
|
2219
|
+
for (const [mid, ovModel] of Object.entries(overlay.models ?? {})) {
|
|
2220
|
+
const existing = models[mid];
|
|
2221
|
+
models[mid] = existing ? mergeModel(existing, ovModel) : { ...ovModel };
|
|
2222
|
+
}
|
|
2223
|
+
return {
|
|
2224
|
+
...base,
|
|
2225
|
+
// Overlay scalar fields win when explicitly provided; otherwise keep base.
|
|
2226
|
+
...stripUndefined({
|
|
2227
|
+
id: overlay.id,
|
|
2228
|
+
name: overlay.name,
|
|
2229
|
+
npm: overlay.npm,
|
|
2230
|
+
api: overlay.api,
|
|
2231
|
+
env: overlay.env,
|
|
2232
|
+
doc: overlay.doc
|
|
2233
|
+
}),
|
|
2234
|
+
models
|
|
2235
|
+
};
|
|
2236
|
+
}
|
|
2237
|
+
function mergeModel(base, overlay) {
|
|
2238
|
+
const merged = { ...base, ...overlay };
|
|
2239
|
+
if (base.limit || overlay.limit) {
|
|
2240
|
+
merged.limit = { ...base.limit, ...overlay.limit };
|
|
2241
|
+
}
|
|
2242
|
+
if (base.cost || overlay.cost) {
|
|
2243
|
+
merged.cost = { ...base.cost, ...overlay.cost };
|
|
2244
|
+
}
|
|
2245
|
+
if (base.modalities || overlay.modalities) {
|
|
2246
|
+
merged.modalities = { ...base.modalities, ...overlay.modalities };
|
|
2247
|
+
}
|
|
2248
|
+
return merged;
|
|
2249
|
+
}
|
|
2250
|
+
function cloneProvider(p) {
|
|
2251
|
+
const models = {};
|
|
2252
|
+
for (const [mid, m] of Object.entries(p.models ?? {})) {
|
|
2253
|
+
models[mid] = { ...m };
|
|
2254
|
+
}
|
|
2255
|
+
return { ...p, models };
|
|
2256
|
+
}
|
|
2257
|
+
function stripUndefined(obj) {
|
|
2258
|
+
const out = {};
|
|
2259
|
+
for (const [k, v] of Object.entries(obj)) {
|
|
2260
|
+
if (v !== void 0) out[k] = v;
|
|
2261
|
+
}
|
|
2262
|
+
return out;
|
|
2263
|
+
}
|
|
2264
|
+
|
|
2265
|
+
// src/models/models-registry.ts
|
|
2143
2266
|
var DEFAULT_URL = "https://models.dev/api.json";
|
|
2144
2267
|
var DEFAULT_TTL_SECONDS = 24 * 3600;
|
|
2145
2268
|
var FAMILY_BY_NPM = {
|
|
@@ -2167,7 +2290,10 @@ function classifyFamily(npm) {
|
|
|
2167
2290
|
return FAMILY_BY_NPM[npm] ?? "unsupported";
|
|
2168
2291
|
}
|
|
2169
2292
|
var DefaultModelsRegistry = class {
|
|
2293
|
+
/** Merged (base + overlay) payload — what every reader sees. */
|
|
2170
2294
|
payload;
|
|
2295
|
+
/** Memoised overlay payload (in-memory / fetched / file). */
|
|
2296
|
+
overlayPayload;
|
|
2171
2297
|
fetchedAt;
|
|
2172
2298
|
cacheFile;
|
|
2173
2299
|
url;
|
|
@@ -2175,6 +2301,10 @@ var DefaultModelsRegistry = class {
|
|
|
2175
2301
|
fetchImpl;
|
|
2176
2302
|
seed;
|
|
2177
2303
|
maxStaleAgeMs;
|
|
2304
|
+
overlay;
|
|
2305
|
+
overlayUrl;
|
|
2306
|
+
overlayFile;
|
|
2307
|
+
overlayCacheFile;
|
|
2178
2308
|
constructor(opts) {
|
|
2179
2309
|
this.cacheFile = opts.cacheFile;
|
|
2180
2310
|
this.url = opts.url ?? DEFAULT_URL;
|
|
@@ -2183,6 +2313,10 @@ var DefaultModelsRegistry = class {
|
|
|
2183
2313
|
this.seed = opts.seed;
|
|
2184
2314
|
const maxStaleSeconds = opts.maxStaleAgeSeconds ?? 7 * 24 * 3600;
|
|
2185
2315
|
this.maxStaleAgeMs = maxStaleSeconds * 1e3;
|
|
2316
|
+
this.overlay = opts.overlay;
|
|
2317
|
+
this.overlayUrl = opts.overlayUrl;
|
|
2318
|
+
this.overlayFile = opts.overlayFile;
|
|
2319
|
+
this.overlayCacheFile = opts.overlayCacheFile ?? (opts.overlayUrl ? path6.join(path6.dirname(opts.cacheFile), "models-overlay-cache.json") : void 0);
|
|
2186
2320
|
}
|
|
2187
2321
|
async load(opts = {}) {
|
|
2188
2322
|
if (this.payload && !opts.force) return this.payload;
|
|
@@ -2191,27 +2325,45 @@ var DefaultModelsRegistry = class {
|
|
|
2191
2325
|
this.fetchedAt = /* @__PURE__ */ new Date();
|
|
2192
2326
|
return this.payload;
|
|
2193
2327
|
}
|
|
2328
|
+
const overlay = await this.loadOverlay(opts);
|
|
2329
|
+
const base = await this.loadBase(opts, Object.keys(overlay).length > 0);
|
|
2330
|
+
this.payload = mergeModelsPayload(base, overlay);
|
|
2331
|
+
return this.payload;
|
|
2332
|
+
}
|
|
2333
|
+
/**
|
|
2334
|
+
* Load the models.dev base payload: fresh cache → network → stale cache.
|
|
2335
|
+
* On total failure, degrade to `{}` (so a non-empty overlay still drives
|
|
2336
|
+
* the catalog) rather than throwing — unless there's no curated overlay to
|
|
2337
|
+
* fall back on, in which case the original error propagates so pure-
|
|
2338
|
+
* models.dev setups still surface the problem.
|
|
2339
|
+
*/
|
|
2340
|
+
async loadBase(opts = {}, overlayAvailable = false) {
|
|
2194
2341
|
if (!opts.force) {
|
|
2195
|
-
const cached = await this.
|
|
2342
|
+
const cached = await this.readCacheAt(this.cacheFile);
|
|
2196
2343
|
if (cached && this.isFresh(cached.fetchedAt)) {
|
|
2197
|
-
this.payload = cached.payload;
|
|
2198
2344
|
this.fetchedAt = new Date(cached.fetchedAt);
|
|
2199
2345
|
return cached.payload;
|
|
2200
2346
|
}
|
|
2201
2347
|
}
|
|
2202
2348
|
try {
|
|
2203
|
-
return await this.
|
|
2349
|
+
return await this.refreshBase();
|
|
2204
2350
|
} catch (err) {
|
|
2205
|
-
const cached = await this.
|
|
2351
|
+
const cached = await this.readCacheAt(this.cacheFile);
|
|
2206
2352
|
if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) {
|
|
2207
|
-
this.payload = cached.payload;
|
|
2208
2353
|
this.fetchedAt = new Date(cached.fetchedAt);
|
|
2209
2354
|
return cached.payload;
|
|
2210
2355
|
}
|
|
2356
|
+
if (overlayAvailable) {
|
|
2357
|
+
console.warn(
|
|
2358
|
+
`ModelsRegistry: models.dev unavailable (${err instanceof Error ? err.message : String(err)}); serving curated overlay only.`
|
|
2359
|
+
);
|
|
2360
|
+
return {};
|
|
2361
|
+
}
|
|
2211
2362
|
throw err;
|
|
2212
2363
|
}
|
|
2213
2364
|
}
|
|
2214
|
-
|
|
2365
|
+
/** Fetch + cache the models.dev base. Throws on failure (used by `refresh`). */
|
|
2366
|
+
async refreshBase() {
|
|
2215
2367
|
const res = await this.fetchImpl(this.url, {
|
|
2216
2368
|
method: "GET",
|
|
2217
2369
|
headers: { accept: "application/json" }
|
|
@@ -2220,7 +2372,6 @@ var DefaultModelsRegistry = class {
|
|
|
2220
2372
|
throw new Error(`ModelsRegistry: HTTP ${res.status} fetching ${this.url}`);
|
|
2221
2373
|
}
|
|
2222
2374
|
const json = await res.json();
|
|
2223
|
-
this.payload = json;
|
|
2224
2375
|
this.fetchedAt = /* @__PURE__ */ new Date();
|
|
2225
2376
|
const envelope = {
|
|
2226
2377
|
fetchedAt: this.fetchedAt.toISOString(),
|
|
@@ -2230,6 +2381,68 @@ var DefaultModelsRegistry = class {
|
|
|
2230
2381
|
await atomicWrite(this.cacheFile, JSON.stringify(envelope));
|
|
2231
2382
|
return json;
|
|
2232
2383
|
}
|
|
2384
|
+
/**
|
|
2385
|
+
* Resolve the curated overlay, memoised. Order: in-memory `overlay` →
|
|
2386
|
+
* fetched `overlayUrl` (cached, same TTL/stale rules) → `overlayFile` on
|
|
2387
|
+
* disk. Never throws — a missing/broken overlay yields `{}`.
|
|
2388
|
+
*/
|
|
2389
|
+
async loadOverlay(opts = {}) {
|
|
2390
|
+
if (this.overlayPayload && !opts.force) return this.overlayPayload;
|
|
2391
|
+
if (this.overlay) {
|
|
2392
|
+
this.overlayPayload = this.overlay;
|
|
2393
|
+
return this.overlayPayload;
|
|
2394
|
+
}
|
|
2395
|
+
const fetched = await this.loadOverlayFromUrl(opts);
|
|
2396
|
+
if (fetched) {
|
|
2397
|
+
this.overlayPayload = fetched;
|
|
2398
|
+
return fetched;
|
|
2399
|
+
}
|
|
2400
|
+
const fromFile = await this.readOverlayFile();
|
|
2401
|
+
this.overlayPayload = fromFile ?? {};
|
|
2402
|
+
return this.overlayPayload;
|
|
2403
|
+
}
|
|
2404
|
+
async loadOverlayFromUrl(opts) {
|
|
2405
|
+
if (!this.overlayUrl || !this.overlayCacheFile) return void 0;
|
|
2406
|
+
if (!opts.force) {
|
|
2407
|
+
const cached = await this.readCacheAt(this.overlayCacheFile);
|
|
2408
|
+
if (cached && this.isFresh(cached.fetchedAt)) return cached.payload;
|
|
2409
|
+
}
|
|
2410
|
+
try {
|
|
2411
|
+
const res = await this.fetchImpl(this.overlayUrl, {
|
|
2412
|
+
method: "GET",
|
|
2413
|
+
headers: { accept: "application/json" }
|
|
2414
|
+
});
|
|
2415
|
+
if (!res.ok) throw new Error(`HTTP ${res.status}`);
|
|
2416
|
+
const json = await res.json();
|
|
2417
|
+
const envelope = {
|
|
2418
|
+
fetchedAt: (/* @__PURE__ */ new Date()).toISOString(),
|
|
2419
|
+
url: this.overlayUrl,
|
|
2420
|
+
payload: json
|
|
2421
|
+
};
|
|
2422
|
+
await atomicWrite(this.overlayCacheFile, JSON.stringify(envelope)).catch(() => {
|
|
2423
|
+
});
|
|
2424
|
+
return json;
|
|
2425
|
+
} catch {
|
|
2426
|
+
const cached = await this.readCacheAt(this.overlayCacheFile);
|
|
2427
|
+
if (cached && this.isWithinMaxStaleAge(cached.fetchedAt)) return cached.payload;
|
|
2428
|
+
return void 0;
|
|
2429
|
+
}
|
|
2430
|
+
}
|
|
2431
|
+
async readOverlayFile() {
|
|
2432
|
+
if (!this.overlayFile) return void 0;
|
|
2433
|
+
try {
|
|
2434
|
+
const raw = await fsp2.readFile(this.overlayFile, "utf8");
|
|
2435
|
+
return JSON.parse(raw);
|
|
2436
|
+
} catch {
|
|
2437
|
+
return void 0;
|
|
2438
|
+
}
|
|
2439
|
+
}
|
|
2440
|
+
async refresh() {
|
|
2441
|
+
const base = await this.refreshBase();
|
|
2442
|
+
const overlay = await this.loadOverlay({ force: true });
|
|
2443
|
+
this.payload = mergeModelsPayload(base, overlay);
|
|
2444
|
+
return this.payload;
|
|
2445
|
+
}
|
|
2233
2446
|
async listProviders() {
|
|
2234
2447
|
const payload = await this.load();
|
|
2235
2448
|
return Object.values(payload).map((p) => this.resolveProvider(p));
|
|
@@ -2270,7 +2483,7 @@ var DefaultModelsRegistry = class {
|
|
|
2270
2483
|
}
|
|
2271
2484
|
async ageSeconds() {
|
|
2272
2485
|
if (!this.fetchedAt) {
|
|
2273
|
-
const cached = await this.
|
|
2486
|
+
const cached = await this.readCacheAt(this.cacheFile);
|
|
2274
2487
|
if (!cached) return Number.POSITIVE_INFINITY;
|
|
2275
2488
|
return (Date.now() - new Date(cached.fetchedAt).getTime()) / 1e3;
|
|
2276
2489
|
}
|
|
@@ -2294,9 +2507,9 @@ var DefaultModelsRegistry = class {
|
|
|
2294
2507
|
isWithinMaxStaleAge(fetchedAtIso) {
|
|
2295
2508
|
return Date.now() - new Date(fetchedAtIso).getTime() < this.maxStaleAgeMs;
|
|
2296
2509
|
}
|
|
2297
|
-
async
|
|
2510
|
+
async readCacheAt(file) {
|
|
2298
2511
|
try {
|
|
2299
|
-
const raw = await fsp2.readFile(
|
|
2512
|
+
const raw = await fsp2.readFile(file, "utf8");
|
|
2300
2513
|
return JSON.parse(raw);
|
|
2301
2514
|
} catch {
|
|
2302
2515
|
return void 0;
|
|
@@ -2868,6 +3081,141 @@ function topologicalSort(graph) {
|
|
|
2868
3081
|
return result;
|
|
2869
3082
|
}
|
|
2870
3083
|
|
|
3084
|
+
// src/security/capabilities.ts
|
|
3085
|
+
var ToolCapabilities = {
|
|
3086
|
+
/** Can execute arbitrary commands in the user's shell (the `bash` tool). */
|
|
3087
|
+
SHELL_ARBITRARY: "shell.arbitrary",
|
|
3088
|
+
/** Can write / modify / delete files inside the project. */
|
|
3089
|
+
FS_WRITE: "fs.write",
|
|
3090
|
+
/** Can write files outside the current project root (very high risk). */
|
|
3091
|
+
FS_WRITE_OUTSIDE_PROJECT: "fs.write.outside-project",
|
|
3092
|
+
/** Proxies tools from external MCP servers (unknown capability). */
|
|
3093
|
+
MCP_PROXY: "mcp.proxy",
|
|
3094
|
+
/** Can spawn or manage subagents / multi-agent tasks. */
|
|
3095
|
+
SUBAGENT_SPAWN: "subagent.spawn",
|
|
3096
|
+
/** Can mutate global or session configuration / trust state. */
|
|
3097
|
+
CONFIG_MUTATE: "config.mutate",
|
|
3098
|
+
/** Can install packages or run package managers with side effects. */
|
|
3099
|
+
PACKAGE_INSTALL: "package.install"
|
|
3100
|
+
};
|
|
3101
|
+
var DANGEROUS_FOR_SUBAGENTS = [
|
|
3102
|
+
ToolCapabilities.SHELL_ARBITRARY,
|
|
3103
|
+
ToolCapabilities.FS_WRITE,
|
|
3104
|
+
ToolCapabilities.FS_WRITE_OUTSIDE_PROJECT,
|
|
3105
|
+
ToolCapabilities.MCP_PROXY,
|
|
3106
|
+
ToolCapabilities.SUBAGENT_SPAWN,
|
|
3107
|
+
ToolCapabilities.CONFIG_MUTATE,
|
|
3108
|
+
ToolCapabilities.PACKAGE_INSTALL
|
|
3109
|
+
];
|
|
3110
|
+
function hasDangerousCapabilityForSubagents(toolOrCaps) {
|
|
3111
|
+
if (!toolOrCaps) return false;
|
|
3112
|
+
const input = toolOrCaps;
|
|
3113
|
+
const caps = Array.isArray(input) ? input : input?.capabilities ?? [];
|
|
3114
|
+
return caps.some((c) => DANGEROUS_FOR_SUBAGENTS.includes(c));
|
|
3115
|
+
}
|
|
3116
|
+
function getDangerousCapabilities(toolOrCaps) {
|
|
3117
|
+
if (!toolOrCaps) return [];
|
|
3118
|
+
const input = toolOrCaps;
|
|
3119
|
+
const caps = Array.isArray(input) ? input : input?.capabilities ?? [];
|
|
3120
|
+
return caps.filter(
|
|
3121
|
+
(c) => DANGEROUS_FOR_SUBAGENTS.includes(c)
|
|
3122
|
+
);
|
|
3123
|
+
}
|
|
3124
|
+
|
|
3125
|
+
// src/utils/json-schema-validate.ts
|
|
3126
|
+
function validateAgainstSchema(value, schema) {
|
|
3127
|
+
const errors = [];
|
|
3128
|
+
walk2(value, schema, "", errors);
|
|
3129
|
+
return { ok: errors.length === 0, errors };
|
|
3130
|
+
}
|
|
3131
|
+
function walk2(value, schema, path35, errors) {
|
|
3132
|
+
if (schema.enum !== void 0) {
|
|
3133
|
+
if (!schema.enum.some((e) => deepEqual(e, value))) {
|
|
3134
|
+
errors.push({
|
|
3135
|
+
path: path35 || "<root>",
|
|
3136
|
+
message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
|
|
3137
|
+
});
|
|
3138
|
+
return;
|
|
3139
|
+
}
|
|
3140
|
+
}
|
|
3141
|
+
if (typeof schema.type === "string") {
|
|
3142
|
+
if (!checkType(value, schema.type)) {
|
|
3143
|
+
errors.push({
|
|
3144
|
+
path: path35 || "<root>",
|
|
3145
|
+
message: `expected ${schema.type}, got ${describeType(value)}`
|
|
3146
|
+
});
|
|
3147
|
+
return;
|
|
3148
|
+
}
|
|
3149
|
+
}
|
|
3150
|
+
if (schema.type === "object" && isPlainObject(value)) {
|
|
3151
|
+
const obj = value;
|
|
3152
|
+
for (const req of schema.required ?? []) {
|
|
3153
|
+
if (!(req in obj)) {
|
|
3154
|
+
errors.push({ path: joinPath(path35, req), message: "required property missing" });
|
|
3155
|
+
}
|
|
3156
|
+
}
|
|
3157
|
+
if (schema.properties) {
|
|
3158
|
+
for (const [key, subSchema] of Object.entries(schema.properties)) {
|
|
3159
|
+
if (key in obj) {
|
|
3160
|
+
walk2(obj[key], subSchema, joinPath(path35, key), errors);
|
|
3161
|
+
}
|
|
3162
|
+
}
|
|
3163
|
+
}
|
|
3164
|
+
}
|
|
3165
|
+
if (schema.type === "array" && Array.isArray(value) && schema.items) {
|
|
3166
|
+
value.forEach((item, i) => walk2(item, schema.items, `${path35}[${i}]`, errors));
|
|
3167
|
+
}
|
|
3168
|
+
}
|
|
3169
|
+
function checkType(value, type) {
|
|
3170
|
+
switch (type) {
|
|
3171
|
+
case "string":
|
|
3172
|
+
return typeof value === "string";
|
|
3173
|
+
case "number":
|
|
3174
|
+
return typeof value === "number" && !Number.isNaN(value);
|
|
3175
|
+
case "integer":
|
|
3176
|
+
return typeof value === "number" && Number.isInteger(value);
|
|
3177
|
+
case "boolean":
|
|
3178
|
+
return typeof value === "boolean";
|
|
3179
|
+
case "null":
|
|
3180
|
+
return value === null;
|
|
3181
|
+
case "array":
|
|
3182
|
+
return Array.isArray(value);
|
|
3183
|
+
case "object":
|
|
3184
|
+
return isPlainObject(value);
|
|
3185
|
+
default:
|
|
3186
|
+
return true;
|
|
3187
|
+
}
|
|
3188
|
+
}
|
|
3189
|
+
function isPlainObject(v) {
|
|
3190
|
+
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
3191
|
+
}
|
|
3192
|
+
function describeType(v) {
|
|
3193
|
+
if (v === null) return "null";
|
|
3194
|
+
if (Array.isArray(v)) return "array";
|
|
3195
|
+
return typeof v;
|
|
3196
|
+
}
|
|
3197
|
+
function joinPath(parent, key) {
|
|
3198
|
+
if (!parent) return key;
|
|
3199
|
+
return `${parent}.${key}`;
|
|
3200
|
+
}
|
|
3201
|
+
function deepEqual(a, b) {
|
|
3202
|
+
if (a === b) return true;
|
|
3203
|
+
if (typeof a !== typeof b) return false;
|
|
3204
|
+
if (a === null || b === null) return a === b;
|
|
3205
|
+
if (Array.isArray(a) && Array.isArray(b)) {
|
|
3206
|
+
return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
|
|
3207
|
+
}
|
|
3208
|
+
if (typeof a === "object" && typeof b === "object") {
|
|
3209
|
+
const ak = Object.keys(a);
|
|
3210
|
+
const bk = Object.keys(b);
|
|
3211
|
+
if (ak.length !== bk.length) return false;
|
|
3212
|
+
return ak.every(
|
|
3213
|
+
(k) => deepEqual(a[k], b[k])
|
|
3214
|
+
);
|
|
3215
|
+
}
|
|
3216
|
+
return false;
|
|
3217
|
+
}
|
|
3218
|
+
|
|
2871
3219
|
// src/utils/tool-output-serializer.ts
|
|
2872
3220
|
function createToolOutputSerializer(opts = {}) {
|
|
2873
3221
|
const capBytes = opts.perIterationOutputCapBytes ?? 1e5;
|
|
@@ -2949,18 +3297,45 @@ var ToolExecutor = class {
|
|
|
2949
3297
|
budget = this.decrementBudget(result, budget);
|
|
2950
3298
|
return { result, tool, durationMs: Date.now() - start };
|
|
2951
3299
|
}
|
|
3300
|
+
const validation = validateAgainstSchema(use.input, tool.inputSchema);
|
|
3301
|
+
if (!validation.ok) {
|
|
3302
|
+
const errorDetails = validation.errors.map((e) => ` - ${e.path || "input"}: ${e.message}`).join("\n");
|
|
3303
|
+
const result = {
|
|
3304
|
+
type: "tool_result",
|
|
3305
|
+
tool_use_id: use.id,
|
|
3306
|
+
content: `Invalid arguments for tool "${tool.name}".
|
|
3307
|
+
|
|
3308
|
+
Validation errors:
|
|
3309
|
+
${errorDetails}
|
|
3310
|
+
|
|
3311
|
+
Please call the tool again with arguments that match its inputSchema. You can use the "tool-help" tool with name="${tool.name}" to see the exact expected schema.`,
|
|
3312
|
+
is_error: true
|
|
3313
|
+
};
|
|
3314
|
+
budget = this.decrementBudget(result, budget);
|
|
3315
|
+
return { result, tool, durationMs: Date.now() - start };
|
|
3316
|
+
}
|
|
3317
|
+
const toolDangerousCaps = getDangerousCapabilities(tool);
|
|
3318
|
+
if (toolDangerousCaps.length > 0) {
|
|
3319
|
+
if (this.opts.events) ;
|
|
3320
|
+
}
|
|
2952
3321
|
if (hasMalformedArguments(use.input)) {
|
|
2953
3322
|
const result = this.malformedInputResult(use, extractMalformedRaw(use.input));
|
|
2954
3323
|
budget = this.decrementBudget(result, budget);
|
|
2955
3324
|
return { result, tool, durationMs: Date.now() - start };
|
|
2956
3325
|
}
|
|
2957
3326
|
const decision = await this.opts.permissionPolicy.evaluate(tool, use.input, ctx);
|
|
2958
|
-
|
|
3327
|
+
let effectivePermission = decision.permission;
|
|
3328
|
+
const policy = this.opts.permissionPolicy;
|
|
3329
|
+
const yolo = policy.getYolo?.() === true || policy.getForceAllYolo?.() === true;
|
|
3330
|
+
if (toolDangerousCaps.length > 0 && effectivePermission === "auto" && !yolo) {
|
|
3331
|
+
effectivePermission = "confirm";
|
|
3332
|
+
}
|
|
3333
|
+
if (effectivePermission === "deny") {
|
|
2959
3334
|
const result = this.deniedResult(use, decision.reason);
|
|
2960
3335
|
budget = this.decrementBudget(result, budget);
|
|
2961
3336
|
return { result, tool, durationMs: Date.now() - start };
|
|
2962
3337
|
}
|
|
2963
|
-
if (
|
|
3338
|
+
if (effectivePermission === "confirm") {
|
|
2964
3339
|
if (this.opts.confirmAwaiter) {
|
|
2965
3340
|
const choice = await this.opts.confirmAwaiter(tool, use.input, use.id, tool.name);
|
|
2966
3341
|
if (choice !== "yes" && choice !== "always") {
|
|
@@ -2985,10 +3360,13 @@ var ToolExecutor = class {
|
|
|
2985
3360
|
return { result: pending, tool, durationMs: Date.now() - start };
|
|
2986
3361
|
}
|
|
2987
3362
|
}
|
|
3363
|
+
const toolCapsForAudit = hasDangerousCapabilityForSubagents(tool) ? tool.capabilities ?? [] : [];
|
|
2988
3364
|
const span = this.opts.tracer?.startSpan(`tool.${tool.name}`, {
|
|
2989
3365
|
"tool.name": tool.name,
|
|
2990
3366
|
"tool.mutating": tool.mutating,
|
|
2991
|
-
"tool.permission": tool.permission
|
|
3367
|
+
"tool.permission": tool.permission,
|
|
3368
|
+
"tool.capabilities": JSON.stringify(tool.capabilities ?? []),
|
|
3369
|
+
"tool.has_dangerous_capabilities": toolCapsForAudit.length > 0
|
|
2992
3370
|
});
|
|
2993
3371
|
try {
|
|
2994
3372
|
const result = await this.executeTool(tool, use, ctx, budget);
|
|
@@ -3931,9 +4309,11 @@ function resolveWstackPaths(opts) {
|
|
|
3931
4309
|
globalPrompts: path6.join(globalRoot, "prompts"),
|
|
3932
4310
|
cacheDir: path6.join(globalRoot, "cache"),
|
|
3933
4311
|
modelsCache: path6.join(globalRoot, "cache", "models.dev.json"),
|
|
4312
|
+
modelsOverlayCache: path6.join(globalRoot, "cache", "models-overlay.json"),
|
|
3934
4313
|
historyFile: path6.join(globalRoot, "history"),
|
|
3935
4314
|
logFile: path6.join(globalRoot, "logs", "wrongstack.log"),
|
|
3936
4315
|
projectDir,
|
|
4316
|
+
projectCodebaseIndex: path6.join(projectDir, "codebase-index"),
|
|
3937
4317
|
projectMemory: path6.join(projectDir, "memory.md"),
|
|
3938
4318
|
projectSessions: path6.join(projectDir, "sessions"),
|
|
3939
4319
|
projectTrust: path6.join(projectDir, "trust.json"),
|
|
@@ -4042,100 +4422,6 @@ function buildChildEnv(optsOrSessionId) {
|
|
|
4042
4422
|
return out;
|
|
4043
4423
|
}
|
|
4044
4424
|
|
|
4045
|
-
// src/utils/json-schema-validate.ts
|
|
4046
|
-
function validateAgainstSchema(value, schema) {
|
|
4047
|
-
const errors = [];
|
|
4048
|
-
walk2(value, schema, "", errors);
|
|
4049
|
-
return { ok: errors.length === 0, errors };
|
|
4050
|
-
}
|
|
4051
|
-
function walk2(value, schema, path35, errors) {
|
|
4052
|
-
if (schema.enum !== void 0) {
|
|
4053
|
-
if (!schema.enum.some((e) => deepEqual(e, value))) {
|
|
4054
|
-
errors.push({
|
|
4055
|
-
path: path35 || "<root>",
|
|
4056
|
-
message: `expected one of ${JSON.stringify(schema.enum)}, got ${JSON.stringify(value)}`
|
|
4057
|
-
});
|
|
4058
|
-
return;
|
|
4059
|
-
}
|
|
4060
|
-
}
|
|
4061
|
-
if (typeof schema.type === "string") {
|
|
4062
|
-
if (!checkType(value, schema.type)) {
|
|
4063
|
-
errors.push({
|
|
4064
|
-
path: path35 || "<root>",
|
|
4065
|
-
message: `expected ${schema.type}, got ${describeType(value)}`
|
|
4066
|
-
});
|
|
4067
|
-
return;
|
|
4068
|
-
}
|
|
4069
|
-
}
|
|
4070
|
-
if (schema.type === "object" && isPlainObject(value)) {
|
|
4071
|
-
const obj = value;
|
|
4072
|
-
for (const req of schema.required ?? []) {
|
|
4073
|
-
if (!(req in obj)) {
|
|
4074
|
-
errors.push({ path: joinPath(path35, req), message: "required property missing" });
|
|
4075
|
-
}
|
|
4076
|
-
}
|
|
4077
|
-
if (schema.properties) {
|
|
4078
|
-
for (const [key, subSchema] of Object.entries(schema.properties)) {
|
|
4079
|
-
if (key in obj) {
|
|
4080
|
-
walk2(obj[key], subSchema, joinPath(path35, key), errors);
|
|
4081
|
-
}
|
|
4082
|
-
}
|
|
4083
|
-
}
|
|
4084
|
-
}
|
|
4085
|
-
if (schema.type === "array" && Array.isArray(value) && schema.items) {
|
|
4086
|
-
value.forEach((item, i) => walk2(item, schema.items, `${path35}[${i}]`, errors));
|
|
4087
|
-
}
|
|
4088
|
-
}
|
|
4089
|
-
function checkType(value, type) {
|
|
4090
|
-
switch (type) {
|
|
4091
|
-
case "string":
|
|
4092
|
-
return typeof value === "string";
|
|
4093
|
-
case "number":
|
|
4094
|
-
return typeof value === "number" && !Number.isNaN(value);
|
|
4095
|
-
case "integer":
|
|
4096
|
-
return typeof value === "number" && Number.isInteger(value);
|
|
4097
|
-
case "boolean":
|
|
4098
|
-
return typeof value === "boolean";
|
|
4099
|
-
case "null":
|
|
4100
|
-
return value === null;
|
|
4101
|
-
case "array":
|
|
4102
|
-
return Array.isArray(value);
|
|
4103
|
-
case "object":
|
|
4104
|
-
return isPlainObject(value);
|
|
4105
|
-
default:
|
|
4106
|
-
return true;
|
|
4107
|
-
}
|
|
4108
|
-
}
|
|
4109
|
-
function isPlainObject(v) {
|
|
4110
|
-
return typeof v === "object" && v !== null && !Array.isArray(v);
|
|
4111
|
-
}
|
|
4112
|
-
function describeType(v) {
|
|
4113
|
-
if (v === null) return "null";
|
|
4114
|
-
if (Array.isArray(v)) return "array";
|
|
4115
|
-
return typeof v;
|
|
4116
|
-
}
|
|
4117
|
-
function joinPath(parent, key) {
|
|
4118
|
-
if (!parent) return key;
|
|
4119
|
-
return `${parent}.${key}`;
|
|
4120
|
-
}
|
|
4121
|
-
function deepEqual(a, b) {
|
|
4122
|
-
if (a === b) return true;
|
|
4123
|
-
if (typeof a !== typeof b) return false;
|
|
4124
|
-
if (a === null || b === null) return a === b;
|
|
4125
|
-
if (Array.isArray(a) && Array.isArray(b)) {
|
|
4126
|
-
return a.length === b.length && a.every((v, i) => deepEqual(v, b[i]));
|
|
4127
|
-
}
|
|
4128
|
-
if (typeof a === "object" && typeof b === "object") {
|
|
4129
|
-
const ak = Object.keys(a);
|
|
4130
|
-
const bk = Object.keys(b);
|
|
4131
|
-
if (ak.length !== bk.length) return false;
|
|
4132
|
-
return ak.every(
|
|
4133
|
-
(k) => deepEqual(a[k], b[k])
|
|
4134
|
-
);
|
|
4135
|
-
}
|
|
4136
|
-
return false;
|
|
4137
|
-
}
|
|
4138
|
-
|
|
4139
4425
|
// src/utils/json-repair.ts
|
|
4140
4426
|
function completePartialObject(s) {
|
|
4141
4427
|
if (!s.trim().startsWith("{")) return s;
|
|
@@ -4830,7 +5116,7 @@ function isPersistedQueueItem(v) {
|
|
|
4830
5116
|
// src/storage/attachment-store.ts
|
|
4831
5117
|
init_atomic_write();
|
|
4832
5118
|
var DEFAULT_SPOOL_THRESHOLD = 256 * 1024;
|
|
4833
|
-
var PLACEHOLDER_RE = /\[(pasted|image|file) #(\d+)\]/g;
|
|
5119
|
+
var PLACEHOLDER_RE = /\[(pasted|image|file) #(\d+)[^\]]*\]|\[file:([^\]]+)\]/g;
|
|
4834
5120
|
var DefaultAttachmentStore = class {
|
|
4835
5121
|
items = /* @__PURE__ */ new Map();
|
|
4836
5122
|
refs = [];
|
|
@@ -4884,9 +5170,15 @@ var DefaultAttachmentStore = class {
|
|
|
4884
5170
|
const idx = m.index ?? 0;
|
|
4885
5171
|
const before = text.slice(lastIndex, idx);
|
|
4886
5172
|
if (before) blocks.push({ type: "text", text: before });
|
|
4887
|
-
|
|
4888
|
-
|
|
4889
|
-
|
|
5173
|
+
let ref;
|
|
5174
|
+
if (m[3] !== void 0) {
|
|
5175
|
+
const wantPath = m[3];
|
|
5176
|
+
ref = findLast(this.refs, (r) => r.kind === "file" && refPath(r) === wantPath);
|
|
5177
|
+
} else {
|
|
5178
|
+
const kind = prefixToKind(m[1]);
|
|
5179
|
+
const seq = Number(m[2]);
|
|
5180
|
+
ref = this.refs.find((r) => r.kind === kind && r.seq === seq);
|
|
5181
|
+
}
|
|
4890
5182
|
const att = ref ? this.items.get(ref.id) : void 0;
|
|
4891
5183
|
if (!att) {
|
|
4892
5184
|
blocks.push({ type: "text", text: m[0] });
|
|
@@ -4939,6 +5231,15 @@ function prefixToKind(prefix) {
|
|
|
4939
5231
|
if (prefix === "image") return "image";
|
|
4940
5232
|
return "file";
|
|
4941
5233
|
}
|
|
5234
|
+
function refPath(ref) {
|
|
5235
|
+
return ref.meta.filename ?? ref.meta.label;
|
|
5236
|
+
}
|
|
5237
|
+
function findLast(arr, pred) {
|
|
5238
|
+
for (let i = arr.length - 1; i >= 0; i--) {
|
|
5239
|
+
if (pred(arr[i])) return arr[i];
|
|
5240
|
+
}
|
|
5241
|
+
return void 0;
|
|
5242
|
+
}
|
|
4942
5243
|
function mergeAdjacentText(blocks) {
|
|
4943
5244
|
const out = [];
|
|
4944
5245
|
for (const b of blocks) {
|
|
@@ -5266,7 +5567,8 @@ var BEHAVIOR_DEFAULTS = {
|
|
|
5266
5567
|
memory: true,
|
|
5267
5568
|
modelsRegistry: true,
|
|
5268
5569
|
skills: true
|
|
5269
|
-
}
|
|
5570
|
+
},
|
|
5571
|
+
session: { ...DEFAULT_SESSION_LOGGING_CONFIG }
|
|
5270
5572
|
};
|
|
5271
5573
|
var ENV_MAP = {
|
|
5272
5574
|
WRONGSTACK_PROVIDER: (c, v) => {
|
|
@@ -5774,6 +6076,101 @@ var SessionAnalyzer = class {
|
|
|
5774
6076
|
}
|
|
5775
6077
|
};
|
|
5776
6078
|
|
|
6079
|
+
// src/storage/session-event-bridge.ts
|
|
6080
|
+
var CORE_RECONSTRUCT_EVENTS = /* @__PURE__ */ new Set([
|
|
6081
|
+
"session_start",
|
|
6082
|
+
"session_resumed",
|
|
6083
|
+
"user_input",
|
|
6084
|
+
"llm_response",
|
|
6085
|
+
"tool_result",
|
|
6086
|
+
"checkpoint",
|
|
6087
|
+
"file_snapshot",
|
|
6088
|
+
"rewound",
|
|
6089
|
+
"in_flight_start",
|
|
6090
|
+
"in_flight_end",
|
|
6091
|
+
"session_end"
|
|
6092
|
+
]);
|
|
6093
|
+
var STANDARD_AUDIT_EVENTS = /* @__PURE__ */ new Set([
|
|
6094
|
+
"llm_request",
|
|
6095
|
+
"tool_use",
|
|
6096
|
+
"tool_call_start",
|
|
6097
|
+
"tool_call_end",
|
|
6098
|
+
"compaction",
|
|
6099
|
+
"error",
|
|
6100
|
+
"message_truncated",
|
|
6101
|
+
"provider_retry",
|
|
6102
|
+
"provider_error"
|
|
6103
|
+
]);
|
|
6104
|
+
var FULL_ONLY_EVENTS = /* @__PURE__ */ new Set([
|
|
6105
|
+
"tool_progress"
|
|
6106
|
+
]);
|
|
6107
|
+
function isAllowed(type, level) {
|
|
6108
|
+
if (CORE_RECONSTRUCT_EVENTS.has(type)) return true;
|
|
6109
|
+
if (level === "minimal") return false;
|
|
6110
|
+
if (STANDARD_AUDIT_EVENTS.has(type)) return true;
|
|
6111
|
+
if (level === "standard") return false;
|
|
6112
|
+
if (FULL_ONLY_EVENTS.has(type)) {
|
|
6113
|
+
return level === "full";
|
|
6114
|
+
}
|
|
6115
|
+
return true;
|
|
6116
|
+
}
|
|
6117
|
+
function createSessionEventBridge(writer, level = "standard", options = {}) {
|
|
6118
|
+
const normalizedLevel = level ?? "standard";
|
|
6119
|
+
const progressCounters = /* @__PURE__ */ new Map();
|
|
6120
|
+
const toolProgressConfig = options.sampling?.toolProgress ?? {};
|
|
6121
|
+
const TOOL_PROGRESS_SAMPLE_RATE = toolProgressConfig.sampleRate ?? 8;
|
|
6122
|
+
function shouldSample(event) {
|
|
6123
|
+
if (event.type !== "tool_progress") return true;
|
|
6124
|
+
const progEvent = event;
|
|
6125
|
+
const innerType = progEvent.event?.type;
|
|
6126
|
+
if (innerType === "warning" || innerType === "metric" || innerType === "file_changed") {
|
|
6127
|
+
return true;
|
|
6128
|
+
}
|
|
6129
|
+
if (innerType === "log" || innerType === "partial_output") {
|
|
6130
|
+
const key = progEvent.id || progEvent.name;
|
|
6131
|
+
const count = (progressCounters.get(key) || 0) + 1;
|
|
6132
|
+
progressCounters.set(key, count);
|
|
6133
|
+
return count === 1 || count % TOOL_PROGRESS_SAMPLE_RATE === 0;
|
|
6134
|
+
}
|
|
6135
|
+
return true;
|
|
6136
|
+
}
|
|
6137
|
+
return {
|
|
6138
|
+
level: normalizedLevel,
|
|
6139
|
+
allows(type) {
|
|
6140
|
+
return isAllowed(type, normalizedLevel);
|
|
6141
|
+
},
|
|
6142
|
+
async append(event) {
|
|
6143
|
+
if (!writer) return;
|
|
6144
|
+
if (!isAllowed(event.type, normalizedLevel)) return;
|
|
6145
|
+
if (!shouldSample(event)) return;
|
|
6146
|
+
try {
|
|
6147
|
+
await writer.append(event);
|
|
6148
|
+
} catch (err) {
|
|
6149
|
+
}
|
|
6150
|
+
}
|
|
6151
|
+
};
|
|
6152
|
+
}
|
|
6153
|
+
function resolveAuditLevel(cfg) {
|
|
6154
|
+
const raw = cfg?.session?.auditLevel;
|
|
6155
|
+
if (raw === "minimal" || raw === "standard" || raw === "full") {
|
|
6156
|
+
return raw;
|
|
6157
|
+
}
|
|
6158
|
+
return "standard";
|
|
6159
|
+
}
|
|
6160
|
+
function resolveSessionLoggingConfig(cfg) {
|
|
6161
|
+
const session = cfg?.session ?? {};
|
|
6162
|
+
const auditLevel = resolveAuditLevel(cfg);
|
|
6163
|
+
const toolProgressSampleRate = session.sampling?.toolProgress?.sampleRate ?? 8;
|
|
6164
|
+
return {
|
|
6165
|
+
auditLevel,
|
|
6166
|
+
sampling: {
|
|
6167
|
+
toolProgress: {
|
|
6168
|
+
sampleRate: Math.max(1, Math.floor(toolProgressSampleRate))
|
|
6169
|
+
}
|
|
6170
|
+
}
|
|
6171
|
+
};
|
|
6172
|
+
}
|
|
6173
|
+
|
|
5777
6174
|
// src/storage/todos-checkpoint.ts
|
|
5778
6175
|
init_atomic_write();
|
|
5779
6176
|
async function loadTodosCheckpoint(filePath) {
|
|
@@ -6262,8 +6659,6 @@ var DirectorStateCheckpoint = class {
|
|
|
6262
6659
|
}
|
|
6263
6660
|
}
|
|
6264
6661
|
};
|
|
6265
|
-
|
|
6266
|
-
// src/security/permission-policy.ts
|
|
6267
6662
|
init_atomic_write();
|
|
6268
6663
|
var DefaultPermissionPolicy = class {
|
|
6269
6664
|
policy = {};
|
|
@@ -6504,31 +6899,21 @@ var DefaultPermissionPolicy = class {
|
|
|
6504
6899
|
};
|
|
6505
6900
|
var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
|
|
6506
6901
|
/**
|
|
6507
|
-
*
|
|
6508
|
-
*
|
|
6509
|
-
* and cannot answer prompts, but inherited authorization does not
|
|
6510
|
-
* imply blanket permission for destructive or privilege-escalating
|
|
6511
|
-
* operations. These tools remain at their declared `permission`
|
|
6512
|
-
* level so the leader must explicitly allow them per-spawn.
|
|
6902
|
+
* Legacy name-based denylist.
|
|
6903
|
+
* @deprecated Prefer declaring `capabilities` on the Tool and using capability-based checks.
|
|
6513
6904
|
*/
|
|
6514
|
-
static
|
|
6905
|
+
static LEGACY_NAME_DENY = /* @__PURE__ */ new Set([
|
|
6515
6906
|
"bash",
|
|
6516
|
-
// arbitrary shell — use exec for constrained shell
|
|
6517
6907
|
"write",
|
|
6518
|
-
// arbitrary file write
|
|
6519
6908
|
"edit",
|
|
6520
|
-
// arbitrary in-project file modification (equivalent to write)
|
|
6521
6909
|
"replace",
|
|
6522
|
-
// arbitrary multi-file find/replace (equivalent to write)
|
|
6523
6910
|
"scaffold",
|
|
6524
|
-
// arbitrary file generation outside project root
|
|
6525
6911
|
"patch",
|
|
6526
|
-
// arbitrary diff application
|
|
6527
6912
|
"install",
|
|
6528
|
-
// installs from arbitrary package sources
|
|
6529
6913
|
"exec"
|
|
6530
|
-
// restricted shell but with arbitrary command args
|
|
6531
6914
|
]);
|
|
6915
|
+
// Note: hasDangerousCapabilityForSubagents is now the shared helper from capabilities.ts
|
|
6916
|
+
// The old private method was removed in favor of the centralized utility.
|
|
6532
6917
|
/**
|
|
6533
6918
|
* Tools from MCP servers (`mcp__<server>__<tool>`) are external code of
|
|
6534
6919
|
* unknown capability — they may wrap a shell or filesystem. They are
|
|
@@ -6539,12 +6924,16 @@ var AutoApprovePermissionPolicy = class _AutoApprovePermissionPolicy {
|
|
|
6539
6924
|
return name.startsWith("mcp__");
|
|
6540
6925
|
}
|
|
6541
6926
|
async evaluate(tool) {
|
|
6542
|
-
const
|
|
6543
|
-
|
|
6927
|
+
const hasDangerousCap = hasDangerousCapabilityForSubagents(tool);
|
|
6928
|
+
const legacyNameBlock = _AutoApprovePermissionPolicy.LEGACY_NAME_DENY.has(tool.name);
|
|
6929
|
+
const isMcp = _AutoApprovePermissionPolicy.isMcpTool(tool.name);
|
|
6930
|
+
const blocked = tool.permission === "deny" || hasDangerousCap || legacyNameBlock || isMcp;
|
|
6931
|
+
if (blocked) {
|
|
6932
|
+
const reason = hasDangerousCap ? `tool declares dangerous capability (${tool.capabilities?.join(", ")}) \u2014 not auto-approved for subagents` : legacyNameBlock || isMcp ? `tool ${tool.name} is not auto-approved for subagents \u2014 ask the leader to allow it explicitly` : "tool default deny";
|
|
6544
6933
|
return {
|
|
6545
6934
|
permission: "deny",
|
|
6546
6935
|
source: "subagent_guard",
|
|
6547
|
-
reason
|
|
6936
|
+
reason
|
|
6548
6937
|
};
|
|
6549
6938
|
}
|
|
6550
6939
|
return { permission: "auto", source: "yolo" };
|
|
@@ -7676,6 +8065,7 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
|
|
|
7676
8065
|
events;
|
|
7677
8066
|
failureMode;
|
|
7678
8067
|
policyProvider;
|
|
8068
|
+
sessionBridge;
|
|
7679
8069
|
/**
|
|
7680
8070
|
* Once a compaction attempt reduces nothing (preserveK protects everything,
|
|
7681
8071
|
* no oversized tool_results remain to elide), retrying on every iteration
|
|
@@ -7712,6 +8102,7 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
|
|
|
7712
8102
|
this.events = opts.events;
|
|
7713
8103
|
this.failureMode = opts.failureMode ?? "throw_on_hard";
|
|
7714
8104
|
this.policyProvider = opts.policyProvider;
|
|
8105
|
+
this.sessionBridge = opts.sessionBridge;
|
|
7715
8106
|
}
|
|
7716
8107
|
/** Allow callers (e.g. model-switch in WebUI) to update the context window
|
|
7717
8108
|
* denominator when the active model changes. */
|
|
@@ -7775,6 +8166,15 @@ var AutoCompactionMiddleware = class _AutoCompactionMiddleware {
|
|
|
7775
8166
|
report,
|
|
7776
8167
|
aggressive
|
|
7777
8168
|
});
|
|
8169
|
+
await this.sessionBridge?.append({
|
|
8170
|
+
type: "compaction",
|
|
8171
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
8172
|
+
before: report.before,
|
|
8173
|
+
after: report.after,
|
|
8174
|
+
level: pressure.level,
|
|
8175
|
+
aggressive,
|
|
8176
|
+
reductions: report.reductions?.map((r) => ({ phase: r.phase, saved: r.saved }))
|
|
8177
|
+
});
|
|
7778
8178
|
ctx.clearFileTracking();
|
|
7779
8179
|
} catch (err) {
|
|
7780
8180
|
const error = err instanceof Error ? err : new Error(String(err));
|
|
@@ -8686,6 +9086,13 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
8686
9086
|
tokenOutput = 0;
|
|
8687
9087
|
costUsd = 0;
|
|
8688
9088
|
startTime = null;
|
|
9089
|
+
/**
|
|
9090
|
+
* Timestamp of the most recent activity (iteration / tool call / token
|
|
9091
|
+
* usage / streamed progress). Drives the idle timeout — reset by
|
|
9092
|
+
* `markActivity()`. Initialised to `start()` time so a never-active agent
|
|
9093
|
+
* still eventually trips its idle window.
|
|
9094
|
+
*/
|
|
9095
|
+
lastActivityTime = null;
|
|
8689
9096
|
_onThreshold;
|
|
8690
9097
|
/**
|
|
8691
9098
|
* Hard cap on how long `_negotiateExtension` waits for the coordinator to
|
|
@@ -8729,6 +9136,24 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
8729
9136
|
}
|
|
8730
9137
|
start() {
|
|
8731
9138
|
this.startTime = Date.now();
|
|
9139
|
+
this.lastActivityTime = this.startTime;
|
|
9140
|
+
}
|
|
9141
|
+
/**
|
|
9142
|
+
* Reset the idle clock. Called on any sign of forward progress —
|
|
9143
|
+
* iterations, tool calls, token usage, and streamed tool/text progress —
|
|
9144
|
+
* so a long-but-productive subagent never trips its `idleTimeoutMs`.
|
|
9145
|
+
*/
|
|
9146
|
+
markActivity() {
|
|
9147
|
+
this.lastActivityTime = Date.now();
|
|
9148
|
+
}
|
|
9149
|
+
/**
|
|
9150
|
+
* Milliseconds since the last activity signal. Returns 0 before `start()`
|
|
9151
|
+
* (nothing to measure yet). Used by the coordinator watchdog to decide
|
|
9152
|
+
* whether to re-arm (still active) or reap (genuinely idle).
|
|
9153
|
+
*/
|
|
9154
|
+
idleMs() {
|
|
9155
|
+
const since = this.lastActivityTime ?? this.startTime;
|
|
9156
|
+
return since === null ? 0 : Date.now() - since;
|
|
8732
9157
|
}
|
|
8733
9158
|
/** Returns true if we're within 10% of any limit — useful for pre-flight checks. */
|
|
8734
9159
|
isNearLimit() {
|
|
@@ -8776,8 +9201,13 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
8776
9201
|
if (this.limits.maxCostUsd !== void 0 && this.costUsd > this.limits.maxCostUsd) {
|
|
8777
9202
|
exceeded.push({ kind: "cost", used: this.costUsd, limit: this.limits.maxCostUsd });
|
|
8778
9203
|
}
|
|
8779
|
-
if (elapsedMs !== void 0
|
|
8780
|
-
|
|
9204
|
+
if (elapsedMs !== void 0) {
|
|
9205
|
+
const idle = this.idleMs();
|
|
9206
|
+
if (this.limits.idleTimeoutMs !== void 0 && idle > this.limits.idleTimeoutMs) {
|
|
9207
|
+
exceeded.push({ kind: "timeout", used: idle, limit: this.limits.idleTimeoutMs });
|
|
9208
|
+
} else if (this.limits.timeoutMs !== void 0 && elapsedMs > this.limits.timeoutMs) {
|
|
9209
|
+
exceeded.push({ kind: "timeout", used: elapsedMs, limit: this.limits.timeoutMs });
|
|
9210
|
+
}
|
|
8781
9211
|
}
|
|
8782
9212
|
if (exceeded.length === 0) return [];
|
|
8783
9213
|
if (!this._onThreshold) {
|
|
@@ -8882,6 +9312,9 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
8882
9312
|
if (ext.timeoutMs !== void 0) {
|
|
8883
9313
|
this.limits.timeoutMs = ext.timeoutMs;
|
|
8884
9314
|
}
|
|
9315
|
+
if (ext.idleTimeoutMs !== void 0) {
|
|
9316
|
+
this.limits.idleTimeoutMs = ext.idleTimeoutMs;
|
|
9317
|
+
}
|
|
8885
9318
|
return decision;
|
|
8886
9319
|
} finally {
|
|
8887
9320
|
this._pendingNegotiations.delete(kind);
|
|
@@ -8889,16 +9322,19 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
8889
9322
|
}
|
|
8890
9323
|
recordIteration() {
|
|
8891
9324
|
this.iterations++;
|
|
9325
|
+
this.markActivity();
|
|
8892
9326
|
void this.checkLimits();
|
|
8893
9327
|
}
|
|
8894
9328
|
recordToolCall() {
|
|
8895
9329
|
this.toolCalls++;
|
|
9330
|
+
this.markActivity();
|
|
8896
9331
|
void this.checkLimits();
|
|
8897
9332
|
}
|
|
8898
9333
|
recordUsage(usage, costUsd = 0) {
|
|
8899
9334
|
this.tokenInput += usage.input;
|
|
8900
9335
|
this.tokenOutput += usage.output;
|
|
8901
9336
|
this.costUsd += costUsd;
|
|
9337
|
+
this.markActivity();
|
|
8902
9338
|
void this.checkLimits();
|
|
8903
9339
|
}
|
|
8904
9340
|
/**
|
|
@@ -8913,15 +9349,22 @@ var SubagentBudget = class _SubagentBudget {
|
|
|
8913
9349
|
* - `mode === 'auto'` + listener → throw `BudgetExceededError` (timeout is not extendable)
|
|
8914
9350
|
*/
|
|
8915
9351
|
checkTimeout() {
|
|
8916
|
-
if (this.startTime === null
|
|
9352
|
+
if (this.startTime === null) return;
|
|
9353
|
+
const { timeoutMs, idleTimeoutMs } = this.limits;
|
|
9354
|
+
if (timeoutMs === void 0 && idleTimeoutMs === void 0) return;
|
|
8917
9355
|
const elapsed = Date.now() - this.startTime;
|
|
8918
|
-
|
|
9356
|
+
const wallTripped = timeoutMs !== void 0 && elapsed > timeoutMs;
|
|
9357
|
+
const idleTripped = idleTimeoutMs !== void 0 && this.idleMs() > idleTimeoutMs;
|
|
9358
|
+
if (!wallTripped && !idleTripped) return;
|
|
8919
9359
|
void this.checkLimits(elapsed);
|
|
8920
9360
|
}
|
|
8921
|
-
/** Returns true if a timeout has occurred without throwing.
|
|
9361
|
+
/** Returns true if a wall-clock or idle timeout has occurred without throwing. */
|
|
8922
9362
|
isTimedOut() {
|
|
8923
|
-
if (this.startTime === null
|
|
8924
|
-
|
|
9363
|
+
if (this.startTime === null) return false;
|
|
9364
|
+
const { timeoutMs, idleTimeoutMs } = this.limits;
|
|
9365
|
+
if (timeoutMs !== void 0 && Date.now() - this.startTime > timeoutMs) return true;
|
|
9366
|
+
if (idleTimeoutMs !== void 0 && this.idleMs() > idleTimeoutMs) return true;
|
|
9367
|
+
return false;
|
|
8925
9368
|
}
|
|
8926
9369
|
usage() {
|
|
8927
9370
|
return {
|
|
@@ -9028,6 +9471,7 @@ function makeAgentSubagentRunner(opts) {
|
|
|
9028
9471
|
// Cheap: O(1) per progress event, and the budget short-circuits
|
|
9029
9472
|
// when timeoutMs is unset (most subagents have one set anyway).
|
|
9030
9473
|
events.on("tool.progress", () => {
|
|
9474
|
+
ctx.budget.markActivity();
|
|
9031
9475
|
try {
|
|
9032
9476
|
ctx.budget.checkTimeout();
|
|
9033
9477
|
} catch (e) {
|
|
@@ -9044,6 +9488,7 @@ function makeAgentSubagentRunner(opts) {
|
|
|
9044
9488
|
currentToolName = e.name;
|
|
9045
9489
|
}),
|
|
9046
9490
|
events.on("provider.text_delta", (e) => {
|
|
9491
|
+
ctx.budget.markActivity();
|
|
9047
9492
|
streamingTextAcc = (streamingTextAcc + e.text).slice(-200);
|
|
9048
9493
|
})
|
|
9049
9494
|
);
|
|
@@ -11613,6 +12058,7 @@ var FLEET_ROSTER = {
|
|
|
11613
12058
|
ALL_AGENT_DEFINITIONS.map((d) => [d.config.role, d.config])
|
|
11614
12059
|
)
|
|
11615
12060
|
};
|
|
12061
|
+
var DEFAULT_IDLE_TIMEOUT_MS = 15 * 60 * 1e3;
|
|
11616
12062
|
var FLEET_ROSTER_BUDGETS = {
|
|
11617
12063
|
"audit-log": { timeoutMs: 7.5 * 60 * 60 * 1e3, maxIterations: 5e3, maxToolCalls: 15e3 },
|
|
11618
12064
|
"bug-hunter": { timeoutMs: 10 * 60 * 60 * 1e3, maxIterations: 8e3, maxToolCalls: 2e4 },
|
|
@@ -11624,7 +12070,7 @@ var FLEET_ROSTER_BUDGETS = {
|
|
|
11624
12070
|
)
|
|
11625
12071
|
};
|
|
11626
12072
|
var GENERIC_SUBAGENT_BUDGET = {
|
|
11627
|
-
|
|
12073
|
+
idleTimeoutMs: DEFAULT_IDLE_TIMEOUT_MS,
|
|
11628
12074
|
maxIterations: 5e3,
|
|
11629
12075
|
maxToolCalls: 15e3
|
|
11630
12076
|
};
|
|
@@ -11634,7 +12080,13 @@ function applyRosterBudget(cfg) {
|
|
|
11634
12080
|
if (!defaultBudget) return cfg;
|
|
11635
12081
|
return {
|
|
11636
12082
|
...cfg,
|
|
11637
|
-
|
|
12083
|
+
// Wall-clock cap is opt-in only: forward an explicit `cfg.timeoutMs`, but
|
|
12084
|
+
// do NOT impose the roster's historical multi-hour wall-clock default — it
|
|
12085
|
+
// killed agents that were still actively working. Reaping is idle-based.
|
|
12086
|
+
timeoutMs: cfg.timeoutMs,
|
|
12087
|
+
// Idle window is the default reaper. Resets on activity, so a long-but-
|
|
12088
|
+
// productive run is never killed; only a genuine stall is reaped.
|
|
12089
|
+
idleTimeoutMs: cfg.idleTimeoutMs ?? defaultBudget.idleTimeoutMs ?? DEFAULT_IDLE_TIMEOUT_MS,
|
|
11638
12090
|
maxIterations: cfg.maxIterations ?? defaultBudget.maxIterations,
|
|
11639
12091
|
maxToolCalls: cfg.maxToolCalls ?? defaultBudget.maxToolCalls,
|
|
11640
12092
|
maxTokens: cfg.maxTokens ?? defaultBudget.maxTokens,
|
|
@@ -12196,13 +12648,17 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
12196
12648
|
const rawMaxTokens = subagent.config.maxTokens;
|
|
12197
12649
|
const rawMaxCostUsd = subagent.config.maxCostUsd;
|
|
12198
12650
|
const rawTimeoutMs = subagent.config.timeoutMs;
|
|
12651
|
+
const rawIdleTimeoutMs = subagent.config.idleTimeoutMs;
|
|
12199
12652
|
const configWithRosterDefaults = applyRosterBudget(subagent.config);
|
|
12200
12653
|
const budget = new SubagentBudget({
|
|
12201
12654
|
maxIterations: rawMaxIterations ?? this.config.defaultBudget?.maxIterations ?? configWithRosterDefaults.maxIterations,
|
|
12202
12655
|
maxToolCalls: rawMaxToolCalls ?? this.config.defaultBudget?.maxToolCalls ?? configWithRosterDefaults.maxToolCalls,
|
|
12203
12656
|
maxTokens: rawMaxTokens ?? this.config.defaultBudget?.maxTokens ?? configWithRosterDefaults.maxTokens,
|
|
12204
12657
|
maxCostUsd: rawMaxCostUsd ?? this.config.defaultBudget?.maxCostUsd ?? configWithRosterDefaults.maxCostUsd,
|
|
12205
|
-
|
|
12658
|
+
// Wall-clock cap is opt-in (explicit config / defaultBudget only); the
|
|
12659
|
+
// roster no longer supplies one. Idle is the default reaper.
|
|
12660
|
+
timeoutMs: rawTimeoutMs ?? this.config.defaultBudget?.timeoutMs ?? configWithRosterDefaults.timeoutMs,
|
|
12661
|
+
idleTimeoutMs: rawIdleTimeoutMs ?? this.config.defaultBudget?.idleTimeoutMs ?? configWithRosterDefaults.idleTimeoutMs
|
|
12206
12662
|
});
|
|
12207
12663
|
subagent.activeBudget = budget;
|
|
12208
12664
|
if (!this.runner) {
|
|
@@ -12249,63 +12705,79 @@ var DefaultMultiAgentCoordinator = class extends EventEmitter {
|
|
|
12249
12705
|
}
|
|
12250
12706
|
async executeWithTimeout(runner, task, ctx, budget) {
|
|
12251
12707
|
const initialTimeoutMs = budget.limits.timeoutMs;
|
|
12252
|
-
|
|
12708
|
+
const idleLimitMs = budget.limits.idleTimeoutMs;
|
|
12709
|
+
if (initialTimeoutMs === void 0 && idleLimitMs === void 0) {
|
|
12710
|
+
return runner(task, ctx);
|
|
12711
|
+
}
|
|
12253
12712
|
const start = Date.now();
|
|
12254
12713
|
let timer = null;
|
|
12255
12714
|
const timeoutPromise = new Promise((_, reject) => {
|
|
12256
12715
|
const armFor = (ms) => {
|
|
12257
12716
|
if (timer) clearTimeout(timer);
|
|
12258
|
-
timer = setTimeout(
|
|
12259
|
-
|
|
12260
|
-
|
|
12261
|
-
|
|
12262
|
-
|
|
12263
|
-
|
|
12717
|
+
timer = setTimeout(onTick, Math.max(0, ms));
|
|
12718
|
+
};
|
|
12719
|
+
const scheduleNext = () => {
|
|
12720
|
+
const wallRemaining = initialTimeoutMs === void 0 ? Number.POSITIVE_INFINITY : (budget.limits.timeoutMs ?? initialTimeoutMs) - (Date.now() - start);
|
|
12721
|
+
const idleRemaining = idleLimitMs === void 0 ? Number.POSITIVE_INFINITY : (budget.limits.idleTimeoutMs ?? idleLimitMs) - budget.idleMs();
|
|
12722
|
+
armFor(Math.max(25, Math.min(wallRemaining, idleRemaining)));
|
|
12723
|
+
};
|
|
12724
|
+
const onTick = async () => {
|
|
12725
|
+
const elapsed = Date.now() - start;
|
|
12726
|
+
const wallLimit = initialTimeoutMs === void 0 ? void 0 : budget.limits.timeoutMs ?? initialTimeoutMs;
|
|
12727
|
+
const idleLimit = idleLimitMs === void 0 ? void 0 : budget.limits.idleTimeoutMs ?? idleLimitMs;
|
|
12728
|
+
const wallExceeded = wallLimit !== void 0 && elapsed >= wallLimit;
|
|
12729
|
+
const idleExceeded = idleLimit !== void 0 && budget.idleMs() >= idleLimit;
|
|
12730
|
+
if (idleExceeded && !wallExceeded) {
|
|
12731
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
12732
|
+
reject(new BudgetExceededError("timeout", idleLimit, budget.idleMs()));
|
|
12733
|
+
return;
|
|
12734
|
+
}
|
|
12735
|
+
if (!wallExceeded) {
|
|
12736
|
+
scheduleNext();
|
|
12737
|
+
return;
|
|
12738
|
+
}
|
|
12739
|
+
const limit = wallLimit;
|
|
12740
|
+
if (!budget.onThreshold) {
|
|
12741
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
12742
|
+
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
12743
|
+
return;
|
|
12744
|
+
}
|
|
12745
|
+
try {
|
|
12746
|
+
const result = budget.onThreshold({
|
|
12747
|
+
kind: "timeout",
|
|
12748
|
+
used: elapsed,
|
|
12749
|
+
limit,
|
|
12750
|
+
requestDecision: () => new Promise((resolveDecision) => {
|
|
12751
|
+
budget._events?.emit("budget.threshold_reached", {
|
|
12752
|
+
kind: "timeout",
|
|
12753
|
+
used: elapsed,
|
|
12754
|
+
limit,
|
|
12755
|
+
timeoutMs: 6e4,
|
|
12756
|
+
extend: (extra) => resolveDecision({ extend: extra }),
|
|
12757
|
+
deny: () => resolveDecision("stop")
|
|
12758
|
+
});
|
|
12759
|
+
})
|
|
12760
|
+
});
|
|
12761
|
+
const decision = typeof result === "string" ? result : await result;
|
|
12762
|
+
if (decision === "continue" || decision === "throw" || decision === "stop") {
|
|
12763
|
+
armFor(Math.max(1e3, limit));
|
|
12264
12764
|
return;
|
|
12265
12765
|
}
|
|
12266
|
-
|
|
12267
|
-
|
|
12268
|
-
|
|
12269
|
-
|
|
12270
|
-
limit,
|
|
12271
|
-
requestDecision: () => new Promise((resolveDecision) => {
|
|
12272
|
-
budget._events?.emit("budget.threshold_reached", {
|
|
12273
|
-
kind: "timeout",
|
|
12274
|
-
used: elapsed,
|
|
12275
|
-
limit,
|
|
12276
|
-
timeoutMs: 6e4,
|
|
12277
|
-
extend: (extra) => resolveDecision({ extend: extra }),
|
|
12278
|
-
deny: () => resolveDecision("stop")
|
|
12279
|
-
});
|
|
12280
|
-
})
|
|
12281
|
-
});
|
|
12282
|
-
const decision = typeof result === "string" ? result : await result;
|
|
12283
|
-
if (decision === "continue") {
|
|
12284
|
-
armFor(Math.max(1e3, limit));
|
|
12285
|
-
return;
|
|
12286
|
-
}
|
|
12287
|
-
if (decision === "throw" || decision === "stop") {
|
|
12288
|
-
armFor(Math.max(1e3, limit));
|
|
12289
|
-
return;
|
|
12290
|
-
}
|
|
12291
|
-
if (decision.extend.timeoutMs !== void 0) {
|
|
12292
|
-
budget.limits.timeoutMs = decision.extend.timeoutMs;
|
|
12293
|
-
const newLimit = decision.extend.timeoutMs;
|
|
12294
|
-
const remaining = Math.max(1e3, newLimit - elapsed);
|
|
12295
|
-
armFor(remaining);
|
|
12296
|
-
return;
|
|
12297
|
-
}
|
|
12298
|
-
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
12299
|
-
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
12300
|
-
} catch (err) {
|
|
12301
|
-
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
12302
|
-
reject(
|
|
12303
|
-
err instanceof BudgetExceededError ? err : new BudgetExceededError("timeout", limit, elapsed)
|
|
12304
|
-
);
|
|
12766
|
+
if (decision.extend.timeoutMs !== void 0) {
|
|
12767
|
+
budget.limits.timeoutMs = decision.extend.timeoutMs;
|
|
12768
|
+
scheduleNext();
|
|
12769
|
+
return;
|
|
12305
12770
|
}
|
|
12306
|
-
|
|
12771
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
12772
|
+
reject(new BudgetExceededError("timeout", limit, elapsed));
|
|
12773
|
+
} catch (err) {
|
|
12774
|
+
this.subagents.get(ctx.subagentId)?.abortController.abort();
|
|
12775
|
+
reject(
|
|
12776
|
+
err instanceof BudgetExceededError ? err : new BudgetExceededError("timeout", limit, elapsed)
|
|
12777
|
+
);
|
|
12778
|
+
}
|
|
12307
12779
|
};
|
|
12308
|
-
|
|
12780
|
+
scheduleNext();
|
|
12309
12781
|
});
|
|
12310
12782
|
try {
|
|
12311
12783
|
return await Promise.race([runner(task, ctx), timeoutPromise]);
|
|
@@ -19343,16 +19815,16 @@ var allServers = () => ({
|
|
|
19343
19815
|
function parseSkillRef(input) {
|
|
19344
19816
|
const trimmed = input.trim().replace(/^https?:\/\/github\.com\//, "").replace(/\.git$/, "");
|
|
19345
19817
|
const atIdx = trimmed.indexOf("@");
|
|
19346
|
-
let
|
|
19818
|
+
let refPath2;
|
|
19347
19819
|
let ref;
|
|
19348
19820
|
if (atIdx > 0) {
|
|
19349
|
-
|
|
19821
|
+
refPath2 = trimmed.slice(0, atIdx);
|
|
19350
19822
|
ref = trimmed.slice(atIdx + 1);
|
|
19351
19823
|
} else {
|
|
19352
|
-
|
|
19824
|
+
refPath2 = trimmed;
|
|
19353
19825
|
ref = "main";
|
|
19354
19826
|
}
|
|
19355
|
-
const parts =
|
|
19827
|
+
const parts = refPath2.split("/").filter(Boolean);
|
|
19356
19828
|
if (parts.length < 2) {
|
|
19357
19829
|
throw new Error(`Invalid skill reference "${input}". Expected format: user/repo or user/repo@ref`);
|
|
19358
19830
|
}
|
|
@@ -23917,6 +24389,15 @@ var Agent = class {
|
|
|
23917
24389
|
this.events.emit("iteration.started", { ctx: this.ctx, index: i });
|
|
23918
24390
|
this.injectPendingBtwNotes();
|
|
23919
24391
|
const req = await this.buildAndRunRequestPipeline(opts);
|
|
24392
|
+
await this.ctx.session.append({
|
|
24393
|
+
type: "llm_request",
|
|
24394
|
+
ts: (/* @__PURE__ */ new Date()).toISOString(),
|
|
24395
|
+
model: req.model,
|
|
24396
|
+
messageCount: req.messages.length,
|
|
24397
|
+
estimatedInputTokens: estimateRequestTokens(req.messages, req.system, req.tools ?? []).total,
|
|
24398
|
+
toolCount: (req.tools ?? []).length
|
|
24399
|
+
}).catch(() => {
|
|
24400
|
+
});
|
|
23920
24401
|
let res;
|
|
23921
24402
|
try {
|
|
23922
24403
|
res = await customRunner(this.ctx, req);
|
|
@@ -24126,6 +24607,7 @@ var Agent = class {
|
|
|
24126
24607
|
this.executionStrategy
|
|
24127
24608
|
);
|
|
24128
24609
|
const useById = new Map(selectedToolUses.map((u) => [u.id, u]));
|
|
24610
|
+
const resultsForMessage = [];
|
|
24129
24611
|
for (const { result, tool, durationMs } of outputs) {
|
|
24130
24612
|
if (result.type === "tool_confirm_pending") {
|
|
24131
24613
|
const decision = await this.waitForConfirm({
|
|
@@ -24210,8 +24692,10 @@ var Agent = class {
|
|
|
24210
24692
|
});
|
|
24211
24693
|
}
|
|
24212
24694
|
}
|
|
24695
|
+
resultsForMessage.push(reRunResult.result);
|
|
24213
24696
|
continue;
|
|
24214
24697
|
}
|
|
24698
|
+
resultsForMessage.push(result);
|
|
24215
24699
|
const use = useById.get(result.tool_use_id);
|
|
24216
24700
|
if (!use) continue;
|
|
24217
24701
|
await this.pipelines.toolCall.run({
|
|
@@ -24244,7 +24728,7 @@ var Agent = class {
|
|
|
24244
24728
|
}
|
|
24245
24729
|
this.ctx.state.appendMessage({
|
|
24246
24730
|
role: "user",
|
|
24247
|
-
content:
|
|
24731
|
+
content: resultsForMessage
|
|
24248
24732
|
});
|
|
24249
24733
|
await this.extensions.runAfterToolExecution(this.ctx, outputs);
|
|
24250
24734
|
}
|
|
@@ -24609,6 +25093,50 @@ var InputBuilder = class {
|
|
|
24609
25093
|
this.refs.push(ref);
|
|
24610
25094
|
return placeholder;
|
|
24611
25095
|
}
|
|
25096
|
+
/**
|
|
25097
|
+
* Register-only variant of `appendPaste`. Always stores the paste and
|
|
25098
|
+
* returns the inline `[pasted #N, L lines]` token WITHOUT mutating
|
|
25099
|
+
* `display` — the caller (TUI) owns its own editable buffer as the single
|
|
25100
|
+
* source of truth, inserts the token there, and expands the buffer at
|
|
25101
|
+
* submit. The collapse decision is the caller's (it gates this call); use
|
|
25102
|
+
* `wouldCollapse()` for that.
|
|
25103
|
+
*/
|
|
25104
|
+
async registerPaste(text) {
|
|
25105
|
+
const ref = await this.store.add({
|
|
25106
|
+
kind: "text",
|
|
25107
|
+
data: text,
|
|
25108
|
+
meta: { label: paragraphLabel(text) }
|
|
25109
|
+
});
|
|
25110
|
+
this.refs.push(ref);
|
|
25111
|
+
const lines = text.split("\n").length;
|
|
25112
|
+
return `[pasted #${ref.seq}, ${lines} lines]`;
|
|
25113
|
+
}
|
|
25114
|
+
/**
|
|
25115
|
+
* Register-only variant of `appendImage` — see `registerPaste`. Returns a
|
|
25116
|
+
* seq-keyed `[image #N, LABEL]` token; does not touch `display`.
|
|
25117
|
+
*/
|
|
25118
|
+
async registerImage(dataBase64, mediaType) {
|
|
25119
|
+
const label = `${mediaType.split("/")[1]?.toUpperCase() ?? "IMG"}`;
|
|
25120
|
+
const ref = await this.store.add({
|
|
25121
|
+
kind: "image",
|
|
25122
|
+
data: dataBase64,
|
|
25123
|
+
meta: { mediaType, label }
|
|
25124
|
+
});
|
|
25125
|
+
this.refs.push(ref);
|
|
25126
|
+
return `[image #${ref.seq}, ${label}]`;
|
|
25127
|
+
}
|
|
25128
|
+
/**
|
|
25129
|
+
* Register-only variant of `appendFile` — see `registerPaste`. Returns a
|
|
25130
|
+
* path-keyed `[file:<path>]` token (resolved by path at expand time); does
|
|
25131
|
+
* not touch `display`. The path is read from `meta.filename` (falling back
|
|
25132
|
+
* to `meta.label`).
|
|
25133
|
+
*/
|
|
25134
|
+
async registerFile(input) {
|
|
25135
|
+
const ref = await this.store.add({ ...input, kind: "file" });
|
|
25136
|
+
this.refs.push(ref);
|
|
25137
|
+
const path35 = ref.meta.filename ?? ref.meta.label ?? String(ref.seq);
|
|
25138
|
+
return `[file:${path35}]`;
|
|
25139
|
+
}
|
|
24612
25140
|
/**
|
|
24613
25141
|
* Whether `appendPaste(text)` would collapse the text to a placeholder
|
|
24614
25142
|
* (rather than inlining it). Lets a frontend decide where to route a paste
|
|
@@ -25091,6 +25619,14 @@ var ToolRegistry = class _ToolRegistry {
|
|
|
25091
25619
|
context: { tool: tool.name }
|
|
25092
25620
|
});
|
|
25093
25621
|
}
|
|
25622
|
+
if (!tool.inputSchema || typeof tool.inputSchema !== "object") {
|
|
25623
|
+
throw new WrongStackError({
|
|
25624
|
+
message: `Tool "${tool.name}" has an invalid or missing inputSchema`,
|
|
25625
|
+
code: ERROR_CODES.REGISTRY_INVALID,
|
|
25626
|
+
subsystem: "container",
|
|
25627
|
+
context: { tool: tool.name }
|
|
25628
|
+
});
|
|
25629
|
+
}
|
|
25094
25630
|
this.tools.set(tool.name, { tool, owner });
|
|
25095
25631
|
}
|
|
25096
25632
|
/**
|
|
@@ -25100,6 +25636,9 @@ var ToolRegistry = class _ToolRegistry {
|
|
|
25100
25636
|
*/
|
|
25101
25637
|
tryRegister(tool, owner = "core") {
|
|
25102
25638
|
if (this.tools.has(tool.name)) return false;
|
|
25639
|
+
if (!tool.inputSchema || typeof tool.inputSchema !== "object") {
|
|
25640
|
+
return false;
|
|
25641
|
+
}
|
|
25103
25642
|
this.tools.set(tool.name, { tool, owner });
|
|
25104
25643
|
return true;
|
|
25105
25644
|
}
|
|
@@ -28591,6 +29130,6 @@ ${formatPlan(updated)}`
|
|
|
28591
29130
|
};
|
|
28592
29131
|
}
|
|
28593
29132
|
|
|
28594
|
-
export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, hashRequest, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, pendingBtwCount, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveContextWindowPolicy, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, slackServer, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
|
|
29133
|
+
export { ACP_AGENTS, AGENTS_BY_PHASE, AGENT_CATALOG, AISpecBuilder, ALL_AGENT_DEFINITIONS, ALL_FLEET_AGENTS, ALL_SYNC_CATEGORIES, AUDIT_LOG_AGENT, Agent, AgentError, AnnotationsStore, AutoApprovePermissionPolicy, AutoCompactionMiddleware, AutoExecutor, AutoPhasePlanner, AutoPhaseRunner, AutonomousRunner, BUG_HUNTER_AGENT, BudgetExceededError, CONTEXT_WINDOW_MODES, CORE_RECONSTRUCT_EVENTS, CheckpointManager, CloudSync, CollaborationBus, ConfigError, ConfigMigrationError, Container, Context, ConversationState, DEFAULT_AUTONOMY_CONFIG, DEFAULT_CONFIG_MIGRATIONS, DEFAULT_CONTEXT_CONFIG, DEFAULT_CONTEXT_WINDOW_MODE_ID, DEFAULT_DIRECTOR_PREAMBLE, DEFAULT_DISPATCH_ROLE, DEFAULT_MAX_ITERATIONS, DEFAULT_MODES, DEFAULT_RECOVERY_STRATEGIES, DEFAULT_SESSION_LOGGING_CONFIG, DEFAULT_SPEC_TEMPLATE, DEFAULT_SUBAGENT_BASELINE, DEFAULT_TOOLS_CONFIG, DefaultAttachmentStore, DefaultConfigLoader, DefaultConfigStore, DefaultErrorHandler, DefaultHealthRegistry, DefaultLogger, DefaultMemoryStore, DefaultModeStore, DefaultModelsRegistry, DefaultMultiAgentCoordinator, DefaultPathResolver, DefaultPermissionPolicy, DefaultPluginAPI, DefaultPromptStore, DefaultProviderRunner, DefaultRetryPolicy, DefaultSecretScrubber, DefaultSecretVault, DefaultSessionReader, DefaultSessionRewinder, DefaultSessionStore, DefaultSkillLoader, DefaultSystemPromptBuilder, DefaultTaskStore, DefaultTokenCounter, Director, DirectorStateCheckpoint, DoneConditionChecker, ERROR_CODES, EternalAutonomyEngine, EventBus, ExtensionRegistry, FLEET_ROSTER, FLEET_ROSTER_BUDGETS, FLEET_ROSTER_WITHACP, FleetBus, FleetCostCapError, FleetManager, FleetSpawnBudgetError, FleetUsageAggregator, FsError, GitignoreUpdater, HybridCompactor, InMemoryAgentBridge, InMemoryBridgeTransport, InMemoryMetricsSink, InputBuilder, IntelligentCompactor, KERNEL_API_VERSION, LAYER_1_IDENTITY, LLMSelector, MAX_JOURNAL_ENTRIES, NULL_FLEET_BUS, NoopMetricsSink, NoopTracer, OTelTracer, PROMETHEUS_CONTENT_TYPE, ParallelEternalEngine, PhaseGraphBuilder, PhaseOrchestrator, PhaseStore, Pipeline, PluginError, ProviderError, ProviderRegistry, QueueStore, REFACTOR_PLANNER_AGENT, RecoveryLock, ReplayLogStore, ReplayProviderRunner, ReportGenerator, RunController, SECURITY_SCANNER_AGENT, SPEC_TEMPLATES, STANDARD_AUDIT_EVENTS, ScopedEventBus, SddParallelRun, SddTaskDecomposer, SecurityScanner, SecurityScannerOrchestrator, SelectiveCompactor, SessionAnalyzer, SessionError, SessionRecovery, SkillGenerator, SkillInstaller, SkillManifestStore, SlashCommandRegistry, SpecDrivenDev, SpecParser, SpecStore, SpecVersioning, SubagentBudget, TOKENS, TaskFlow, TaskGenerator, TaskGraphStore, TaskTracker, TechStackDetector, ToolAuditLog, ToolError, ToolExecutor, ToolRegistry, WorktreeManager, WrongStackError, addPlanItem, allServers, analyzeCriticalPath, appendJournal, applyRosterBudget, asBlocks, asText, assertSafePath, atomicWrite, attachAutoExtend, attachPlanCheckpoint, attachTodosCheckpoint, awsServer, blockServer, braveSearchServer, buildBtwBlock, buildChildEnv, buildGoalPreamble, buildOtlpMetricsRequest, buildOtlpTracesRequest, buildRecoveryStrategies, classifyFamily, clearPlan, collabInjectMiddleware, collabPauseMiddleware, color, compileGlob, compileUserRegex, completePartialObject, composeDirectorPrompt, composeSubagentPrompt, computeTaskProgress, consumeBtwNotes, context7Server, contextManagerTool, createAutoExecutor, createAutoPhaseFromTaskGraph, createContextManagerTool, createDefaultPipelines, createDelegateTool, createGitPlugin, createMcpControlTool, createMessage, createObservabilityPlugin, createPlanPlugin, createPromptsPlugin, createSecurityPlugin, createSecuritySlashCommand, createSessionEventBridge, createSkillsPlugin, createSyncPlugin, createToolOutputSerializer, decryptConfigSecrets, defaultGitignoreUpdater, defaultOrchestrator, defaultReportGenerator, defaultSecurityScanner, defaultSkillGenerator, defaultTechStackDetector, deriveTodosFromPlanItem, detectNewlineStyle, dispatchAgent, downloadGitHubTarball, emptyGoal, emptyPlan, encryptConfigSecrets, ensureDir, estimateRequestTokens, estimateTextTokens, estimateToolDefTokens, estimateToolInputTokens, estimateToolResultTokens, everArtServer, extractRunEnv, filesystemServer, findCriticalPath, formatContextWindowModeList, formatGoal, formatPlan, formatPlanTemplates, formatTodosList, getAgentDefinition, getContextWindowMode, getPlanTemplate, getTemplate, githubServer, goalFilePath, googleMapsServer, hashRequest, isAgentError, isConfigError, isContextWindowModeId, isFsError, isImageBlock, isPluginError, isSessionError, isTextBlock, isThinkingBlock, isToolError, isToolResultBlock, isToolUseBlock, isWrongStackError, listContextWindowModes, listPlanTemplates, listTemplates, loadDirectorState, loadGoal, loadPlan, loadPlugins, loadProjectModes, loadTodosCheckpoint, loadUserModes, makeAgentSubagentRunner, makeAskTool, makeAssignTool, makeAutonomyPromptContributor, makeAwaitTasksTool, makeCollabDebugTool, makeContinueToNextIterationTool, makeDirectorSessionFactory, makeFleetEmitTool, makeFleetHealthTool, makeFleetSessionTool, makeFleetStatusTool, makeFleetUsageTool, makeLLMClassifier, makeRollUpTool, makeSpawnTool, makeTerminateTool, matchAny, matchGlob, mergeModelsPayload, migratePlaintextSecrets, miniMaxVisionServer, normalizeToLf, parseContinueDirective, parseSkillRef, pendingBtwCount, projectHash, removePlanItem, renderProgress, renderPrometheus, renderSpecAnalysis, renderTaskGraph, renderTaskList, repairToolUseAdjacency, resolveAuditLevel, resolveContextWindowPolicy, resolveSessionLoggingConfig, resolveWstackPaths, rewriteConfigEncrypted, rosterSummaryFromConfigs, runConfigMigrations, runProviderWithRetry, safeParse, safeStringify, sanitizeJsonString, saveGoal, savePlan, saveTodosCheckpoint, scoreAgents, securitySlashCommand, sentinelServer, setBtwNote, setPlanItemStatus, slackServer, stableStringify, startMetricsServer, startOtlpMetricsExporter, startOtlpTraceExporter, stripAnsi, summarizeUsage, templateToMarkdown, toStyle, toWrongStackError, topologicalSort, unifiedDiff, unloadPlugins, validateAgainstSchema, wireMetricsToEvents, wrapAsState, zaiVisionServer };
|
|
28595
29134
|
//# sourceMappingURL=index.js.map
|
|
28596
29135
|
//# sourceMappingURL=index.js.map
|