@cydm/pie 1.0.19 → 1.0.20
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/dist/builtin/extensions/ask-user/index.js +3 -3
- package/dist/builtin/extensions/plan-mode/index.js +3 -3
- package/dist/builtin/extensions/subagent/index.js +4 -4
- package/dist/builtin/extensions/todo/index.js +3 -3
- package/dist/chunks/{chunk-2R3XTLE2.js → chunk-L5BJNCNG.js} +1 -1
- package/dist/chunks/{chunk-GZVSE44O.js → chunk-NHR6EBM2.js} +345 -54
- package/dist/chunks/{chunk-Q2N6B5JN.js → chunk-VESPMEDG.js} +40 -0
- package/dist/chunks/{chunk-KZ54RSWP.js → chunk-ZYOTRKU7.js} +3 -2
- package/dist/chunks/{src-7UV3KKGU.js → src-2FHZO63Y.js} +2 -2
- package/dist/chunks/{test-stream-PP63L7MK.js → test-stream-UW74PA6T.js} +1 -1
- package/dist/cli.js +721 -230
- package/package.json +4 -3
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { createRequire as __createRequire } from "node:module"; const require = __createRequire(import.meta.url);
|
|
2
2
|
import {
|
|
3
3
|
Agent
|
|
4
|
-
} from "./chunk-
|
|
4
|
+
} from "./chunk-L5BJNCNG.js";
|
|
5
5
|
import {
|
|
6
6
|
FileSystemGateway,
|
|
7
7
|
Type,
|
|
@@ -11,7 +11,7 @@ import {
|
|
|
11
11
|
getPlatformConfig,
|
|
12
12
|
hashText,
|
|
13
13
|
streamSimple
|
|
14
|
-
} from "./chunk-
|
|
14
|
+
} from "./chunk-VESPMEDG.js";
|
|
15
15
|
import {
|
|
16
16
|
__require
|
|
17
17
|
} from "./chunk-TG2EQLX2.js";
|
|
@@ -2071,6 +2071,15 @@ function candidatePriority(role) {
|
|
|
2071
2071
|
return 1;
|
|
2072
2072
|
}
|
|
2073
2073
|
function chooseBestCandidate(candidates) {
|
|
2074
|
+
const main = candidates.find((candidate) => candidate.role === "main");
|
|
2075
|
+
if (main) {
|
|
2076
|
+
const backup = candidates.find((candidate) => candidate.role === "backup");
|
|
2077
|
+
const previous = candidates.find((candidate) => candidate.role === "previous");
|
|
2078
|
+
if (backup && previous && backup.content !== main.content && previous.content === main.content && backup.updatedAt >= main.updatedAt) {
|
|
2079
|
+
return backup;
|
|
2080
|
+
}
|
|
2081
|
+
return main;
|
|
2082
|
+
}
|
|
2074
2083
|
return [...candidates].sort((a, b) => {
|
|
2075
2084
|
const updatedAtDiff = b.updatedAt - a.updatedAt;
|
|
2076
2085
|
if (updatedAtDiff !== 0) return updatedAtDiff;
|
|
@@ -2159,6 +2168,8 @@ function deleteDurableFile(gateway, filePath) {
|
|
|
2159
2168
|
|
|
2160
2169
|
// ../../packages/agent-framework/src/session/store.ts
|
|
2161
2170
|
var SESSION_VERSION = 2;
|
|
2171
|
+
var METADATA_INDEX_VERSION = 3;
|
|
2172
|
+
var METADATA_FAST_READ_BYTES = 64 * 1024;
|
|
2162
2173
|
function isSessionEntry(value) {
|
|
2163
2174
|
return !!value && typeof value === "object" && "id" in value && "type" in value;
|
|
2164
2175
|
}
|
|
@@ -2181,6 +2192,60 @@ function normalizeEntriesInput(entriesOrMessages) {
|
|
|
2181
2192
|
}
|
|
2182
2193
|
return entries;
|
|
2183
2194
|
}
|
|
2195
|
+
function extractJsonObjectProperty(content, propertyName) {
|
|
2196
|
+
const propertyIndex = content.indexOf(`"${propertyName}"`);
|
|
2197
|
+
if (propertyIndex < 0) return null;
|
|
2198
|
+
const colonIndex = content.indexOf(":", propertyIndex + propertyName.length + 2);
|
|
2199
|
+
if (colonIndex < 0) return null;
|
|
2200
|
+
let index = colonIndex + 1;
|
|
2201
|
+
while (index < content.length && /\s/.test(content[index])) index += 1;
|
|
2202
|
+
if (content[index] !== "{") return null;
|
|
2203
|
+
let depth = 0;
|
|
2204
|
+
let inString = false;
|
|
2205
|
+
let escaping = false;
|
|
2206
|
+
for (let cursor = index; cursor < content.length; cursor += 1) {
|
|
2207
|
+
const char = content[cursor];
|
|
2208
|
+
if (inString) {
|
|
2209
|
+
if (escaping) {
|
|
2210
|
+
escaping = false;
|
|
2211
|
+
} else if (char === "\\") {
|
|
2212
|
+
escaping = true;
|
|
2213
|
+
} else if (char === '"') {
|
|
2214
|
+
inString = false;
|
|
2215
|
+
}
|
|
2216
|
+
continue;
|
|
2217
|
+
}
|
|
2218
|
+
if (char === '"') {
|
|
2219
|
+
inString = true;
|
|
2220
|
+
continue;
|
|
2221
|
+
}
|
|
2222
|
+
if (char === "{") {
|
|
2223
|
+
depth += 1;
|
|
2224
|
+
} else if (char === "}") {
|
|
2225
|
+
depth -= 1;
|
|
2226
|
+
if (depth === 0) {
|
|
2227
|
+
return content.slice(index, cursor + 1);
|
|
2228
|
+
}
|
|
2229
|
+
}
|
|
2230
|
+
}
|
|
2231
|
+
return null;
|
|
2232
|
+
}
|
|
2233
|
+
function parseMetadataOnly(content) {
|
|
2234
|
+
const metadataText = extractJsonObjectProperty(content, "metadata");
|
|
2235
|
+
if (!metadataText) return null;
|
|
2236
|
+
const parsed = JSON.parse(metadataText);
|
|
2237
|
+
if (!parsed || typeof parsed !== "object" || Array.isArray(parsed)) return null;
|
|
2238
|
+
const metadata = parsed;
|
|
2239
|
+
if (typeof metadata.id !== "string" || typeof metadata.name !== "string" || typeof metadata.createdAt !== "number" || typeof metadata.updatedAt !== "number" || typeof metadata.entryCount !== "number" || typeof metadata.messageCount !== "number") {
|
|
2240
|
+
return null;
|
|
2241
|
+
}
|
|
2242
|
+
return metadata;
|
|
2243
|
+
}
|
|
2244
|
+
function durableRolePriority(role) {
|
|
2245
|
+
if (role === "main") return 3;
|
|
2246
|
+
if (role === "backup") return 2;
|
|
2247
|
+
return 1;
|
|
2248
|
+
}
|
|
2184
2249
|
var LEGACY_VERSION = 1;
|
|
2185
2250
|
function getDefaultSessionsDir() {
|
|
2186
2251
|
return getPlatformConfig().sessionsPath;
|
|
@@ -2246,6 +2311,9 @@ var FileSessionStore = class {
|
|
|
2246
2311
|
const safeId = sessionId.replace(/[^a-zA-Z0-9_-]/g, "_");
|
|
2247
2312
|
return this.gateway.join(this.sessionsDir, `${safeId}.json`);
|
|
2248
2313
|
}
|
|
2314
|
+
getMetadataIndexPath() {
|
|
2315
|
+
return this.gateway.join(this.sessionsDir, ".metadata-index.json");
|
|
2316
|
+
}
|
|
2249
2317
|
normalizeLoadedData(data) {
|
|
2250
2318
|
if (data.version === LEGACY_VERSION || !data.version) {
|
|
2251
2319
|
return { data: migrateV1ToV2(data), shouldPersist: true };
|
|
@@ -2280,6 +2348,8 @@ var FileSessionStore = class {
|
|
|
2280
2348
|
const normalizedEntries = normalizeEntriesInput(entries);
|
|
2281
2349
|
const now = Date.now();
|
|
2282
2350
|
const existing = await this.load(sessionId);
|
|
2351
|
+
const requestedUpdatedAt = metadata?.updatedAt ?? now;
|
|
2352
|
+
const updatedAt = Math.max(requestedUpdatedAt, existing?.metadata.updatedAt ?? 0);
|
|
2283
2353
|
const messageCount = normalizedEntries.filter((e) => e.type === "message" && e.message).length;
|
|
2284
2354
|
const rootEntry = normalizedEntries.find((e) => e.parentId === null);
|
|
2285
2355
|
const activeEntryId = metadata?.activeEntryId ?? existing?.metadata.activeEntryId ?? normalizedEntries[normalizedEntries.length - 1]?.id ?? null;
|
|
@@ -2289,13 +2359,13 @@ var FileSessionStore = class {
|
|
|
2289
2359
|
id: sessionId,
|
|
2290
2360
|
name: metadata?.name ?? existing?.metadata.name ?? `Session ${sessionId.slice(0, 8)}`,
|
|
2291
2361
|
createdAt: existing?.metadata.createdAt ?? now,
|
|
2292
|
-
updatedAt: now,
|
|
2293
2362
|
entryCount: normalizedEntries.length,
|
|
2294
2363
|
messageCount,
|
|
2295
2364
|
activeEntryId: activeEntryId ?? rootEntry?.id ?? null,
|
|
2296
2365
|
rootEntryId: rootEntry?.id ?? null,
|
|
2297
2366
|
tags: metadata?.tags ?? existing?.metadata.tags,
|
|
2298
|
-
...metadata
|
|
2367
|
+
...metadata,
|
|
2368
|
+
updatedAt
|
|
2299
2369
|
},
|
|
2300
2370
|
entries: normalizedEntries,
|
|
2301
2371
|
messages: flattenTreeToMessages(normalizedEntries, activeEntryId ?? null)
|
|
@@ -2307,6 +2377,7 @@ var FileSessionStore = class {
|
|
|
2307
2377
|
filePath,
|
|
2308
2378
|
parse: (content, path3) => this.parseSessionContent(content, path3)
|
|
2309
2379
|
}, json);
|
|
2380
|
+
this.upsertMetadataIndexBestEffort(sessionData.metadata);
|
|
2310
2381
|
}
|
|
2311
2382
|
/**
|
|
2312
2383
|
* Legacy save method for backward compatibility
|
|
@@ -2362,7 +2433,9 @@ var FileSessionStore = class {
|
|
|
2362
2433
|
async delete(sessionId) {
|
|
2363
2434
|
const filePath = this.getSessionPath(sessionId);
|
|
2364
2435
|
try {
|
|
2365
|
-
|
|
2436
|
+
const deleted = deleteDurableFile(this.gateway, filePath);
|
|
2437
|
+
if (deleted) this.removeMetadataIndexEntryBestEffort(sessionId);
|
|
2438
|
+
return deleted;
|
|
2366
2439
|
} catch (e) {
|
|
2367
2440
|
console.error(`[SessionStore] Failed to delete session: ${sessionId}`, e);
|
|
2368
2441
|
return false;
|
|
@@ -2379,13 +2452,16 @@ var FileSessionStore = class {
|
|
|
2379
2452
|
* List all session IDs
|
|
2380
2453
|
*/
|
|
2381
2454
|
async list() {
|
|
2455
|
+
return this.listSessionIdsSync();
|
|
2456
|
+
}
|
|
2457
|
+
listSessionIdsSync() {
|
|
2382
2458
|
if (!this.gateway.exists(this.sessionsDir)) {
|
|
2383
2459
|
return [];
|
|
2384
2460
|
}
|
|
2385
2461
|
const files = this.gateway.readdir(this.sessionsDir);
|
|
2386
2462
|
const sessionIds = /* @__PURE__ */ new Set();
|
|
2387
2463
|
for (const file of files) {
|
|
2388
|
-
if (
|
|
2464
|
+
if (isSessionSidecarFile(file)) {
|
|
2389
2465
|
continue;
|
|
2390
2466
|
}
|
|
2391
2467
|
if (file.endsWith(".json")) {
|
|
@@ -2402,24 +2478,235 @@ var FileSessionStore = class {
|
|
|
2402
2478
|
* List all session metadata
|
|
2403
2479
|
*/
|
|
2404
2480
|
async listMetadata() {
|
|
2405
|
-
|
|
2406
|
-
|
|
2407
|
-
|
|
2408
|
-
|
|
2409
|
-
|
|
2410
|
-
|
|
2411
|
-
|
|
2481
|
+
return await this.listMetadataIndexed();
|
|
2482
|
+
}
|
|
2483
|
+
async listMetadataPage(input) {
|
|
2484
|
+
const limit = Math.max(0, input.limit);
|
|
2485
|
+
if (limit === 0) return { metadata: [], hasMore: false };
|
|
2486
|
+
const result = [];
|
|
2487
|
+
for (const metadata of await this.listMetadataIndexed()) {
|
|
2488
|
+
if (input.after && compareMetadataListPosition(metadata, input.after) <= 0) continue;
|
|
2489
|
+
if (input.filter && !input.filter(metadata)) continue;
|
|
2490
|
+
result.push(metadata);
|
|
2491
|
+
if (result.length > limit) break;
|
|
2412
2492
|
}
|
|
2413
|
-
return
|
|
2493
|
+
return {
|
|
2494
|
+
metadata: result.slice(0, limit),
|
|
2495
|
+
hasMore: result.length > limit
|
|
2496
|
+
};
|
|
2414
2497
|
}
|
|
2415
2498
|
/**
|
|
2416
2499
|
* Get session metadata without loading full entries
|
|
2417
2500
|
*/
|
|
2418
2501
|
async getMetadata(sessionId) {
|
|
2502
|
+
const fastMetadata = this.getMetadataFast(sessionId);
|
|
2503
|
+
if (fastMetadata) return fastMetadata;
|
|
2419
2504
|
const data = await this.load(sessionId);
|
|
2420
2505
|
return data?.metadata ?? null;
|
|
2421
2506
|
}
|
|
2507
|
+
getMetadataFast(sessionId) {
|
|
2508
|
+
const paths = durableFilePaths(this.getSessionPath(sessionId));
|
|
2509
|
+
const candidates = [];
|
|
2510
|
+
for (const [role, path3] of [
|
|
2511
|
+
["main", paths.main],
|
|
2512
|
+
["backup", paths.backup],
|
|
2513
|
+
["previous", paths.previous]
|
|
2514
|
+
]) {
|
|
2515
|
+
try {
|
|
2516
|
+
if (!this.gateway.exists(path3)) continue;
|
|
2517
|
+
const metadata = this.readMetadataOnlyFast(path3);
|
|
2518
|
+
if (metadata) candidates.push({ metadata, role });
|
|
2519
|
+
} catch {
|
|
2520
|
+
}
|
|
2521
|
+
}
|
|
2522
|
+
if (candidates.length === 0) return null;
|
|
2523
|
+
return chooseBestMetadataCandidate(candidates).metadata;
|
|
2524
|
+
}
|
|
2525
|
+
readMetadataOnlyFast(path3) {
|
|
2526
|
+
const fileSize = this.gateway.getFileSize(path3);
|
|
2527
|
+
if (fileSize <= METADATA_FAST_READ_BYTES) {
|
|
2528
|
+
return parseMetadataOnly(this.gateway.readFile(path3, "utf-8"));
|
|
2529
|
+
}
|
|
2530
|
+
const head = this.gateway.readFileHead(path3, METADATA_FAST_READ_BYTES, "utf-8");
|
|
2531
|
+
const metadata = parseMetadataOnly(head);
|
|
2532
|
+
if (metadata) return metadata;
|
|
2533
|
+
return parseMetadataOnly(this.gateway.readFile(path3, "utf-8"));
|
|
2534
|
+
}
|
|
2535
|
+
async listMetadataIndexed() {
|
|
2536
|
+
const sessionIds = await this.list();
|
|
2537
|
+
const sessionIdSet = new Set(sessionIds);
|
|
2538
|
+
const index = this.readMetadataIndexBestEffort();
|
|
2539
|
+
if (index && this.metadataIndexMatchesSessionFiles(index, sessionIdSet)) {
|
|
2540
|
+
return sortMetadata(index.sessions.map((entry) => entry.metadata).filter((metadata2) => sessionIdSet.has(metadata2.id)));
|
|
2541
|
+
}
|
|
2542
|
+
const metadata = [];
|
|
2543
|
+
for (const id of sessionIds) {
|
|
2544
|
+
const meta = await this.getMetadata(id);
|
|
2545
|
+
if (meta) metadata.push(meta);
|
|
2546
|
+
}
|
|
2547
|
+
const sorted = sortMetadata(metadata);
|
|
2548
|
+
this.writeMetadataIndexBestEffort(sorted);
|
|
2549
|
+
return sorted;
|
|
2550
|
+
}
|
|
2551
|
+
readMetadataIndexBestEffort() {
|
|
2552
|
+
try {
|
|
2553
|
+
if (!this.gateway.exists(this.getMetadataIndexPath())) return null;
|
|
2554
|
+
const parsed = JSON.parse(this.gateway.readFile(this.getMetadataIndexPath(), "utf-8"));
|
|
2555
|
+
if (!isRecord(parsed) || parsed.v !== METADATA_INDEX_VERSION || !Array.isArray(parsed.sessions)) return null;
|
|
2556
|
+
const sessions = parsed.sessions.filter(isMetadataIndexEntry);
|
|
2557
|
+
if (sessions.length !== parsed.sessions.length) return null;
|
|
2558
|
+
return {
|
|
2559
|
+
v: METADATA_INDEX_VERSION,
|
|
2560
|
+
sessions,
|
|
2561
|
+
updatedAt: typeof parsed.updatedAt === "number" ? parsed.updatedAt : 0
|
|
2562
|
+
};
|
|
2563
|
+
} catch {
|
|
2564
|
+
return null;
|
|
2565
|
+
}
|
|
2566
|
+
}
|
|
2567
|
+
writeMetadataIndexBestEffort(sessions) {
|
|
2568
|
+
try {
|
|
2569
|
+
this.gateway.writeFile(this.getMetadataIndexPath(), JSON.stringify({
|
|
2570
|
+
v: METADATA_INDEX_VERSION,
|
|
2571
|
+
updatedAt: Date.now(),
|
|
2572
|
+
sessions: sortMetadata(sessions).map((metadata) => ({
|
|
2573
|
+
metadata,
|
|
2574
|
+
files: this.sessionFileSignature(metadata.id)
|
|
2575
|
+
}))
|
|
2576
|
+
}, null, 2));
|
|
2577
|
+
} catch {
|
|
2578
|
+
}
|
|
2579
|
+
}
|
|
2580
|
+
upsertMetadataIndexBestEffort(metadata) {
|
|
2581
|
+
const current = this.readMetadataIndexBestEffort();
|
|
2582
|
+
if (current && !this.metadataIndexCanAcceptUpsert(current, metadata.id)) {
|
|
2583
|
+
this.removeMetadataIndexFileBestEffort();
|
|
2584
|
+
return;
|
|
2585
|
+
}
|
|
2586
|
+
const next = (current?.sessions.map((entry) => entry.metadata) ?? []).filter((item) => item.id !== metadata.id);
|
|
2587
|
+
next.push(metadata);
|
|
2588
|
+
this.writeMetadataIndexBestEffort(next);
|
|
2589
|
+
}
|
|
2590
|
+
removeMetadataIndexEntryBestEffort(sessionId) {
|
|
2591
|
+
const current = this.readMetadataIndexBestEffort();
|
|
2592
|
+
if (!current) return;
|
|
2593
|
+
if (!this.metadataIndexCanRemoveSession(current, sessionId)) {
|
|
2594
|
+
this.removeMetadataIndexFileBestEffort();
|
|
2595
|
+
return;
|
|
2596
|
+
}
|
|
2597
|
+
this.writeMetadataIndexBestEffort(current.sessions.map((entry) => entry.metadata).filter((item) => item.id !== sessionId));
|
|
2598
|
+
}
|
|
2599
|
+
removeMetadataIndexFileBestEffort() {
|
|
2600
|
+
try {
|
|
2601
|
+
if (this.gateway.exists(this.getMetadataIndexPath())) this.gateway.deleteFile(this.getMetadataIndexPath());
|
|
2602
|
+
} catch {
|
|
2603
|
+
}
|
|
2604
|
+
}
|
|
2605
|
+
metadataIndexCanAcceptUpsert(index, upsertedSessionId) {
|
|
2606
|
+
const sessionIds = new Set(this.listSessionIdsSync());
|
|
2607
|
+
const indexedIds = new Set(index.sessions.map((entry) => entry.metadata.id));
|
|
2608
|
+
if (indexedIds.size !== index.sessions.length) return false;
|
|
2609
|
+
for (const id of sessionIds) {
|
|
2610
|
+
if (id !== upsertedSessionId && !indexedIds.has(id)) return false;
|
|
2611
|
+
}
|
|
2612
|
+
for (const entry of index.sessions) {
|
|
2613
|
+
const id = entry.metadata.id;
|
|
2614
|
+
if (id !== upsertedSessionId && !sessionIds.has(id)) return false;
|
|
2615
|
+
if (id !== upsertedSessionId && !sessionFileSignaturesEqual(entry.files, this.sessionFileSignature(id))) return false;
|
|
2616
|
+
}
|
|
2617
|
+
return true;
|
|
2618
|
+
}
|
|
2619
|
+
metadataIndexCanRemoveSession(index, removedSessionId) {
|
|
2620
|
+
const sessionIds = new Set(this.listSessionIdsSync());
|
|
2621
|
+
return index.sessions.every(
|
|
2622
|
+
(entry) => entry.metadata.id === removedSessionId || sessionIds.has(entry.metadata.id) && sessionFileSignaturesEqual(entry.files, this.sessionFileSignature(entry.metadata.id))
|
|
2623
|
+
);
|
|
2624
|
+
}
|
|
2625
|
+
metadataIndexMatchesSessionFiles(index, sessionIds) {
|
|
2626
|
+
if (index.sessions.length !== sessionIds.size) return false;
|
|
2627
|
+
const indexedIds = new Set(index.sessions.map((entry) => entry.metadata.id));
|
|
2628
|
+
if (indexedIds.size !== index.sessions.length) return false;
|
|
2629
|
+
for (const id of sessionIds) {
|
|
2630
|
+
if (!indexedIds.has(id)) return false;
|
|
2631
|
+
}
|
|
2632
|
+
return index.sessions.every((entry) => sessionFileSignaturesEqual(entry.files, this.sessionFileSignature(entry.metadata.id)));
|
|
2633
|
+
}
|
|
2634
|
+
sessionFileSignature(sessionId) {
|
|
2635
|
+
const paths = durableFilePaths(this.getSessionPath(sessionId));
|
|
2636
|
+
return {
|
|
2637
|
+
...this.gateway.exists(paths.main) ? { main: this.fileSignature(paths.main) } : {},
|
|
2638
|
+
...this.gateway.exists(paths.backup) ? { backup: this.fileSignature(paths.backup) } : {},
|
|
2639
|
+
...this.gateway.exists(paths.previous) ? { previous: this.fileSignature(paths.previous) } : {}
|
|
2640
|
+
};
|
|
2641
|
+
}
|
|
2642
|
+
fileSignature(path3) {
|
|
2643
|
+
return {
|
|
2644
|
+
size: this.gateway.getFileSize(path3),
|
|
2645
|
+
modifiedAt: this.gateway.getModifiedTime(path3)
|
|
2646
|
+
};
|
|
2647
|
+
}
|
|
2422
2648
|
};
|
|
2649
|
+
function isSessionSidecarFile(file) {
|
|
2650
|
+
return file === ".metadata-index.json" || file.endsWith(".trace.json") || file.endsWith(".trace.json.bak") || file.endsWith(".trace.json.prev") || file.endsWith("-files.json") || file.endsWith("-files.json.bak") || file.endsWith("-files.json.prev");
|
|
2651
|
+
}
|
|
2652
|
+
function sortMetadata(metadata) {
|
|
2653
|
+
return [...metadata].sort((a, b) => b.updatedAt - a.updatedAt || a.id.localeCompare(b.id));
|
|
2654
|
+
}
|
|
2655
|
+
function chooseBestMetadataCandidate(candidates) {
|
|
2656
|
+
const main = candidates.find((candidate) => candidate.role === "main");
|
|
2657
|
+
if (main) {
|
|
2658
|
+
const backup = candidates.find((candidate) => candidate.role === "backup");
|
|
2659
|
+
const previous = candidates.find((candidate) => candidate.role === "previous");
|
|
2660
|
+
if (backup && previous && !metadataObjectsEqual(backup.metadata, main.metadata) && metadataObjectsEqual(previous.metadata, main.metadata) && backup.metadata.updatedAt >= main.metadata.updatedAt) {
|
|
2661
|
+
return backup;
|
|
2662
|
+
}
|
|
2663
|
+
return main;
|
|
2664
|
+
}
|
|
2665
|
+
return [...candidates].sort((left, right) => {
|
|
2666
|
+
const updatedAtDiff = right.metadata.updatedAt - left.metadata.updatedAt;
|
|
2667
|
+
if (updatedAtDiff !== 0) return updatedAtDiff;
|
|
2668
|
+
return durableRolePriority(right.role) - durableRolePriority(left.role);
|
|
2669
|
+
})[0];
|
|
2670
|
+
}
|
|
2671
|
+
function metadataObjectsEqual(left, right) {
|
|
2672
|
+
return stableJson(left) === stableJson(right);
|
|
2673
|
+
}
|
|
2674
|
+
function stableJson(value) {
|
|
2675
|
+
if (Array.isArray(value)) {
|
|
2676
|
+
return `[${value.map((item) => stableJson(item)).join(",")}]`;
|
|
2677
|
+
}
|
|
2678
|
+
if (isRecord(value)) {
|
|
2679
|
+
return `{${Object.keys(value).sort().map((key) => `${JSON.stringify(key)}:${stableJson(value[key])}`).join(",")}}`;
|
|
2680
|
+
}
|
|
2681
|
+
return JSON.stringify(value);
|
|
2682
|
+
}
|
|
2683
|
+
function compareMetadataListPosition(metadata, boundary) {
|
|
2684
|
+
const updatedAtDiff = boundary.updatedAt - metadata.updatedAt;
|
|
2685
|
+
if (updatedAtDiff !== 0) return updatedAtDiff;
|
|
2686
|
+
return metadata.id.localeCompare(boundary.id);
|
|
2687
|
+
}
|
|
2688
|
+
function isSessionMetadata(value) {
|
|
2689
|
+
if (!isRecord(value)) return false;
|
|
2690
|
+
return typeof value.id === "string" && typeof value.name === "string" && typeof value.createdAt === "number" && typeof value.updatedAt === "number" && typeof value.entryCount === "number" && typeof value.messageCount === "number";
|
|
2691
|
+
}
|
|
2692
|
+
function isMetadataIndexEntry(value) {
|
|
2693
|
+
if (!isRecord(value) || !isSessionMetadata(value.metadata) || !isRecord(value.files)) return false;
|
|
2694
|
+
return optionalFileSignature(value.files.main) && optionalFileSignature(value.files.backup) && optionalFileSignature(value.files.previous);
|
|
2695
|
+
}
|
|
2696
|
+
function optionalFileSignature(value) {
|
|
2697
|
+
if (value === void 0) return true;
|
|
2698
|
+
return isRecord(value) && typeof value.size === "number" && Number.isFinite(value.size) && typeof value.modifiedAt === "number" && Number.isFinite(value.modifiedAt);
|
|
2699
|
+
}
|
|
2700
|
+
function sessionFileSignaturesEqual(left, right) {
|
|
2701
|
+
return fileSignaturesEqual(left.main, right.main) && fileSignaturesEqual(left.backup, right.backup) && fileSignaturesEqual(left.previous, right.previous);
|
|
2702
|
+
}
|
|
2703
|
+
function fileSignaturesEqual(left, right) {
|
|
2704
|
+
if (!left || !right) return left === right;
|
|
2705
|
+
return left.size === right.size && left.modifiedAt === right.modifiedAt;
|
|
2706
|
+
}
|
|
2707
|
+
function isRecord(value) {
|
|
2708
|
+
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
2709
|
+
}
|
|
2423
2710
|
|
|
2424
2711
|
// ../../packages/agent-framework/src/session/manager.ts
|
|
2425
2712
|
function generateSessionId() {
|
|
@@ -2508,10 +2795,12 @@ var SessionManager = class {
|
|
|
2508
2795
|
/**
|
|
2509
2796
|
* Load an existing session
|
|
2510
2797
|
*/
|
|
2511
|
-
async loadSession(sessionId) {
|
|
2798
|
+
async loadSession(sessionId, options) {
|
|
2512
2799
|
const data = await this.store.load(sessionId);
|
|
2513
2800
|
if (!data) {
|
|
2514
|
-
|
|
2801
|
+
if (options?.warnIfMissing !== false) {
|
|
2802
|
+
console.warn(`[SessionManager] Session not found: ${sessionId}`);
|
|
2803
|
+
}
|
|
2515
2804
|
return false;
|
|
2516
2805
|
}
|
|
2517
2806
|
if (!data.entries) {
|
|
@@ -7350,23 +7639,23 @@ async function understandFileWithModel(deps, request) {
|
|
|
7350
7639
|
}
|
|
7351
7640
|
|
|
7352
7641
|
// ../../packages/shared-headless-capabilities/src/session-trace.ts
|
|
7353
|
-
function
|
|
7642
|
+
function isRecord2(value) {
|
|
7354
7643
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
7355
7644
|
}
|
|
7356
7645
|
function getTextFromMessageContent(content) {
|
|
7357
7646
|
if (typeof content === "string") return content;
|
|
7358
7647
|
if (!Array.isArray(content)) return "";
|
|
7359
|
-
return content.filter((block) =>
|
|
7648
|
+
return content.filter((block) => isRecord2(block) && block.type === "text").map((block) => String(block.text || "")).join("");
|
|
7360
7649
|
}
|
|
7361
7650
|
function summarizeToolResult(result) {
|
|
7362
|
-
if (!
|
|
7651
|
+
if (!isRecord2(result)) return void 0;
|
|
7363
7652
|
const content = Array.isArray(result.content) ? result.content : [];
|
|
7364
|
-
const text = content.filter((item) =>
|
|
7653
|
+
const text = content.filter((item) => isRecord2(item) && item.type === "text").map((item) => String(item.text || "")).join("\n").trim();
|
|
7365
7654
|
if (!text) return void 0;
|
|
7366
7655
|
return text.length > 500 ? `${text.slice(0, 500)}...` : text;
|
|
7367
7656
|
}
|
|
7368
7657
|
function summarizeToolResultDetails(result) {
|
|
7369
|
-
if (!
|
|
7658
|
+
if (!isRecord2(result) || !isRecord2(result.details)) return void 0;
|
|
7370
7659
|
const details = result.details;
|
|
7371
7660
|
const keys = [
|
|
7372
7661
|
"providerMode",
|
|
@@ -7401,7 +7690,7 @@ function summarizeToolResultDetails(result) {
|
|
|
7401
7690
|
const value = details[key];
|
|
7402
7691
|
if (key === "attempts" && Array.isArray(value)) {
|
|
7403
7692
|
summary[key] = value.slice(-5).map((attempt) => {
|
|
7404
|
-
if (!
|
|
7693
|
+
if (!isRecord2(attempt)) return attempt;
|
|
7405
7694
|
return {
|
|
7406
7695
|
provider: attempt.provider,
|
|
7407
7696
|
modelId: attempt.modelId,
|
|
@@ -7419,7 +7708,7 @@ function summarizeToolResultDetails(result) {
|
|
|
7419
7708
|
summary[key] = {
|
|
7420
7709
|
count: value.length,
|
|
7421
7710
|
items: value.slice(0, 5).map((entry) => {
|
|
7422
|
-
if (!
|
|
7711
|
+
if (!isRecord2(entry)) return entry;
|
|
7423
7712
|
return {
|
|
7424
7713
|
url: entry.finalUrl || entry.url,
|
|
7425
7714
|
title: entry.title,
|
|
@@ -7435,7 +7724,7 @@ function summarizeToolResultDetails(result) {
|
|
|
7435
7724
|
}
|
|
7436
7725
|
if (key === "providerHealth" && Array.isArray(value)) {
|
|
7437
7726
|
summary[key] = value.slice(0, 5).map((entry) => {
|
|
7438
|
-
if (!
|
|
7727
|
+
if (!isRecord2(entry)) return entry;
|
|
7439
7728
|
return {
|
|
7440
7729
|
routeKey: entry.routeKey,
|
|
7441
7730
|
attempts: entry.attempts,
|
|
@@ -7450,7 +7739,7 @@ function summarizeToolResultDetails(result) {
|
|
|
7450
7739
|
}
|
|
7451
7740
|
if (key === "providerAttempts" && Array.isArray(value)) {
|
|
7452
7741
|
summary[key] = value.slice(-5).map((attempt) => {
|
|
7453
|
-
if (!
|
|
7742
|
+
if (!isRecord2(attempt)) return attempt;
|
|
7454
7743
|
return {
|
|
7455
7744
|
provider: attempt.provider,
|
|
7456
7745
|
modelId: attempt.modelId,
|
|
@@ -7482,10 +7771,10 @@ function summarizeString(value, maxLength = 300) {
|
|
|
7482
7771
|
return value.length > maxLength ? `${value.slice(0, maxLength)}...` : value;
|
|
7483
7772
|
}
|
|
7484
7773
|
function summarizeMessage(message) {
|
|
7485
|
-
if (!
|
|
7774
|
+
if (!isRecord2(message)) return typeof message;
|
|
7486
7775
|
if ("contentBlocks" in message && !("content" in message)) return message;
|
|
7487
7776
|
const content = Array.isArray(message.content) ? message.content : [];
|
|
7488
|
-
const blockTypes = content.filter(
|
|
7777
|
+
const blockTypes = content.filter(isRecord2).map((block) => String(block.type || "unknown")).slice(0, 10);
|
|
7489
7778
|
const text = getTextFromMessageContent(content);
|
|
7490
7779
|
return {
|
|
7491
7780
|
role: message.role,
|
|
@@ -7497,12 +7786,12 @@ function summarizeMessage(message) {
|
|
|
7497
7786
|
};
|
|
7498
7787
|
}
|
|
7499
7788
|
function summarizeToolResults(value) {
|
|
7500
|
-
if (
|
|
7789
|
+
if (isRecord2(value) && typeof value.count === "number" && !Array.isArray(value)) return value;
|
|
7501
7790
|
if (!Array.isArray(value)) return typeof value;
|
|
7502
7791
|
let errors = 0;
|
|
7503
7792
|
const toolNames = [];
|
|
7504
7793
|
for (const result of value) {
|
|
7505
|
-
if (!
|
|
7794
|
+
if (!isRecord2(result)) continue;
|
|
7506
7795
|
if (result.isError === true) errors++;
|
|
7507
7796
|
const toolName = typeof result.toolName === "string" ? result.toolName : typeof result.name === "string" ? result.name : void 0;
|
|
7508
7797
|
if (toolName && toolNames.length < 10) toolNames.push(toolName);
|
|
@@ -7514,7 +7803,7 @@ function collectTextLength(content) {
|
|
|
7514
7803
|
if (!Array.isArray(content)) return 0;
|
|
7515
7804
|
let length = 0;
|
|
7516
7805
|
for (const block of content) {
|
|
7517
|
-
if (!
|
|
7806
|
+
if (!isRecord2(block)) continue;
|
|
7518
7807
|
if (typeof block.text === "string") length += block.text.length;
|
|
7519
7808
|
}
|
|
7520
7809
|
return length;
|
|
@@ -7523,7 +7812,7 @@ function collectArgumentLength(content) {
|
|
|
7523
7812
|
if (!Array.isArray(content)) return 0;
|
|
7524
7813
|
let length = 0;
|
|
7525
7814
|
for (const block of content) {
|
|
7526
|
-
if (!
|
|
7815
|
+
if (!isRecord2(block) || !("arguments" in block)) continue;
|
|
7527
7816
|
if (typeof block.arguments === "string") {
|
|
7528
7817
|
length += block.arguments.length;
|
|
7529
7818
|
continue;
|
|
@@ -7546,7 +7835,7 @@ function summarizeMessages(value) {
|
|
|
7546
7835
|
let textLength = 0;
|
|
7547
7836
|
let argumentLength = 0;
|
|
7548
7837
|
for (const message of value) {
|
|
7549
|
-
if (!
|
|
7838
|
+
if (!isRecord2(message)) continue;
|
|
7550
7839
|
const role = typeof message.role === "string" ? message.role : void 0;
|
|
7551
7840
|
if (role && roles.length < 20) roles.push(role);
|
|
7552
7841
|
if (typeof message.stopReason === "string" && stopReasons.length < 20) stopReasons.push(message.stopReason);
|
|
@@ -7557,7 +7846,7 @@ function summarizeMessages(value) {
|
|
|
7557
7846
|
textLength += collectTextLength(message.content);
|
|
7558
7847
|
argumentLength += collectArgumentLength(message.content);
|
|
7559
7848
|
for (const block of content) {
|
|
7560
|
-
if (
|
|
7849
|
+
if (isRecord2(block) && typeof block.name === "string" && toolNames.length < 20) {
|
|
7561
7850
|
toolNames.push(block.name);
|
|
7562
7851
|
}
|
|
7563
7852
|
}
|
|
@@ -7574,7 +7863,7 @@ function summarizeMessages(value) {
|
|
|
7574
7863
|
};
|
|
7575
7864
|
}
|
|
7576
7865
|
function summarizeFailure(value) {
|
|
7577
|
-
if (!
|
|
7866
|
+
if (!isRecord2(value)) return typeof value;
|
|
7578
7867
|
return {
|
|
7579
7868
|
kind: value.kind,
|
|
7580
7869
|
retryable: value.retryable,
|
|
@@ -7585,7 +7874,7 @@ function summarizeFailure(value) {
|
|
|
7585
7874
|
};
|
|
7586
7875
|
}
|
|
7587
7876
|
function summarizeRuntimeEvent(value) {
|
|
7588
|
-
if (!
|
|
7877
|
+
if (!isRecord2(value)) return typeof value;
|
|
7589
7878
|
const summary = {
|
|
7590
7879
|
type: value.type
|
|
7591
7880
|
};
|
|
@@ -7618,7 +7907,7 @@ function recomputeRuntimeSummaryFromTimeline(events) {
|
|
|
7618
7907
|
return summary;
|
|
7619
7908
|
}
|
|
7620
7909
|
function summarizeMeta(meta) {
|
|
7621
|
-
if (!
|
|
7910
|
+
if (!isRecord2(meta)) return meta;
|
|
7622
7911
|
const summary = {};
|
|
7623
7912
|
for (const [key, value] of Object.entries(meta)) {
|
|
7624
7913
|
if (key === "messages" || key === "queuedInputs" || key === "result") {
|
|
@@ -7645,7 +7934,7 @@ function summarizeMeta(meta) {
|
|
|
7645
7934
|
summary[key] = summarizeRuntimeEvent(value);
|
|
7646
7935
|
continue;
|
|
7647
7936
|
}
|
|
7648
|
-
if (key === "queuedInput" &&
|
|
7937
|
+
if (key === "queuedInput" && isRecord2(value)) {
|
|
7649
7938
|
summary[key] = {
|
|
7650
7939
|
mode: value.mode,
|
|
7651
7940
|
source: value.source,
|
|
@@ -7665,18 +7954,18 @@ function toStringArray(value) {
|
|
|
7665
7954
|
}
|
|
7666
7955
|
function summarizeExcludedTools(value) {
|
|
7667
7956
|
if (!Array.isArray(value)) return void 0;
|
|
7668
|
-
const entries = value.filter(
|
|
7957
|
+
const entries = value.filter(isRecord2).map((entry) => ({
|
|
7669
7958
|
name: String(entry.name || ""),
|
|
7670
7959
|
reason: String(entry.reason || "")
|
|
7671
7960
|
})).filter((entry) => entry.name);
|
|
7672
7961
|
return entries.length > 0 ? entries : void 0;
|
|
7673
7962
|
}
|
|
7674
7963
|
function extractSubagentSummaries(toolCallId, toolName, result) {
|
|
7675
|
-
if (toolName !== "spawn_subagents_parallel" || !
|
|
7676
|
-
const details =
|
|
7964
|
+
if (toolName !== "spawn_subagents_parallel" || !isRecord2(result)) return [];
|
|
7965
|
+
const details = isRecord2(result.details) ? result.details : void 0;
|
|
7677
7966
|
const tasks = Array.isArray(details?.tasks) ? details.tasks : [];
|
|
7678
|
-
return tasks.filter(
|
|
7679
|
-
const plan =
|
|
7967
|
+
return tasks.filter(isRecord2).map((task) => {
|
|
7968
|
+
const plan = isRecord2(task.plan) ? task.plan : void 0;
|
|
7680
7969
|
const evidence = Array.isArray(task.evidence) ? task.evidence : [];
|
|
7681
7970
|
const confidenceSignals = Array.isArray(task.confidenceSignals) ? task.confidenceSignals : [];
|
|
7682
7971
|
const runtimeEvidence = Array.isArray(task.runtimeEvidence) ? task.runtimeEvidence : [];
|
|
@@ -7703,7 +7992,7 @@ function extractSubagentSummaries(toolCallId, toolName, result) {
|
|
|
7703
7992
|
}
|
|
7704
7993
|
function timelineEventFromTraceEvent(type, meta) {
|
|
7705
7994
|
const normalizedType = type.startsWith("runtime:") ? type.slice("runtime:".length) : type;
|
|
7706
|
-
const data =
|
|
7995
|
+
const data = isRecord2(meta) ? meta : {};
|
|
7707
7996
|
const detail = summarizeMeta(meta);
|
|
7708
7997
|
if (normalizedType === "assistant_update" || normalizedType === "dispatch_settled" || normalizedType === "wait_for_idle_settled") {
|
|
7709
7998
|
return null;
|
|
@@ -8499,14 +8788,14 @@ function extractAnthropicContent(content, originalQuery) {
|
|
|
8499
8788
|
results.push(makeTextSegment(block.text));
|
|
8500
8789
|
}
|
|
8501
8790
|
if (block?.type === "server_tool_use") {
|
|
8502
|
-
const input =
|
|
8791
|
+
const input = isRecord3(block.input) ? block.input : void 0;
|
|
8503
8792
|
if (typeof input?.query === "string" && input.query.trim()) {
|
|
8504
8793
|
actualQueries.push(input.query.trim());
|
|
8505
8794
|
}
|
|
8506
8795
|
}
|
|
8507
8796
|
if (block?.type === "web_search_tool_result") {
|
|
8508
8797
|
if (!Array.isArray(block.content)) {
|
|
8509
|
-
const errorCode =
|
|
8798
|
+
const errorCode = isRecord3(block.content) && typeof block.content.error_code === "string" ? block.content.error_code : "unknown";
|
|
8510
8799
|
results.push({
|
|
8511
8800
|
type: "error",
|
|
8512
8801
|
toolUseId: typeof block.tool_use_id === "string" ? block.tool_use_id : void 0,
|
|
@@ -8550,7 +8839,7 @@ function collectUrlStrings(text, sources) {
|
|
|
8550
8839
|
function resolveResponsesEndpoint(baseUrl) {
|
|
8551
8840
|
return `${baseUrl.replace(/\/+$/, "")}/responses`;
|
|
8552
8841
|
}
|
|
8553
|
-
function
|
|
8842
|
+
function isRecord3(value) {
|
|
8554
8843
|
return typeof value === "object" && value !== null;
|
|
8555
8844
|
}
|
|
8556
8845
|
function collectUrlCitations(value, sources) {
|
|
@@ -8558,7 +8847,7 @@ function collectUrlCitations(value, sources) {
|
|
|
8558
8847
|
for (const item of value) collectUrlCitations(item, sources);
|
|
8559
8848
|
return;
|
|
8560
8849
|
}
|
|
8561
|
-
if (!
|
|
8850
|
+
if (!isRecord3(value)) return;
|
|
8562
8851
|
if (value.type === "url_citation" && typeof value.url === "string") {
|
|
8563
8852
|
sources.push(sourceFromUrl(value.url, typeof value.title === "string" ? value.title : void 0));
|
|
8564
8853
|
}
|
|
@@ -8577,7 +8866,7 @@ function collectOutputText(value, chunks) {
|
|
|
8577
8866
|
for (const item of value) collectOutputText(item, chunks);
|
|
8578
8867
|
return;
|
|
8579
8868
|
}
|
|
8580
|
-
if (!
|
|
8869
|
+
if (!isRecord3(value)) return;
|
|
8581
8870
|
if (value.type === "output_text" && typeof value.text === "string") {
|
|
8582
8871
|
chunks.push(value.text);
|
|
8583
8872
|
return;
|
|
@@ -8591,7 +8880,7 @@ function collectOutputText(value, chunks) {
|
|
|
8591
8880
|
}
|
|
8592
8881
|
}
|
|
8593
8882
|
function extractOpenAIResponsesContent(response, originalQuery) {
|
|
8594
|
-
const body =
|
|
8883
|
+
const body = isRecord3(response) ? response : {};
|
|
8595
8884
|
const sources = [];
|
|
8596
8885
|
collectUrlCitations(body.output, sources);
|
|
8597
8886
|
if (typeof body.output_text === "string" && body.output_text.trim()) {
|
|
@@ -8608,12 +8897,12 @@ function extractOpenAIResponsesContent(response, originalQuery) {
|
|
|
8608
8897
|
return { text, sources: uniqueSources(sources), results: text ? [makeTextSegment(text)] : [], actualQueries: [originalQuery] };
|
|
8609
8898
|
}
|
|
8610
8899
|
function extractChatCompletionsContent(response, originalQuery) {
|
|
8611
|
-
const body =
|
|
8900
|
+
const body = isRecord3(response) ? response : {};
|
|
8612
8901
|
const sources = [];
|
|
8613
8902
|
collectUrlCitations(body, sources);
|
|
8614
8903
|
const choices = Array.isArray(body.choices) ? body.choices : [];
|
|
8615
|
-
const firstChoice =
|
|
8616
|
-
const message =
|
|
8904
|
+
const firstChoice = isRecord3(choices[0]) ? choices[0] : {};
|
|
8905
|
+
const message = isRecord3(firstChoice.message) ? firstChoice.message : {};
|
|
8617
8906
|
const content = typeof message.content === "string" ? message.content : "";
|
|
8618
8907
|
if (content) {
|
|
8619
8908
|
collectUrlStrings(content, sources);
|
|
@@ -9425,7 +9714,7 @@ var webResearchSchema = Type.Object({
|
|
|
9425
9714
|
var DEFAULT_WEB_RESEARCH_SEARCH_ATTEMPT_TIMEOUT_MS = 45e3;
|
|
9426
9715
|
var DEFAULT_WEB_RESEARCH_FETCH_ATTEMPT_TIMEOUT_MS = 3e4;
|
|
9427
9716
|
var DEFAULT_WEB_RESEARCH_BROWSER_ATTEMPT_TIMEOUT_MS = 45e3;
|
|
9428
|
-
function
|
|
9717
|
+
function isRecord4(value) {
|
|
9429
9718
|
return !!value && typeof value === "object" && !Array.isArray(value);
|
|
9430
9719
|
}
|
|
9431
9720
|
function textFromResult(result) {
|
|
@@ -9639,7 +9928,7 @@ function updateProviderHealth(current, attempts) {
|
|
|
9639
9928
|
return [...byKey.values()].sort((a, b) => b.updatedAt - a.updatedAt).slice(0, 20);
|
|
9640
9929
|
}
|
|
9641
9930
|
function contentDetails(result) {
|
|
9642
|
-
return
|
|
9931
|
+
return isRecord4(result.details) ? result.details : {};
|
|
9643
9932
|
}
|
|
9644
9933
|
function excerpt(text, max = 1400) {
|
|
9645
9934
|
const clean = text.replace(/\s+/g, " ").trim();
|
|
@@ -10265,6 +10554,8 @@ export {
|
|
|
10265
10554
|
getAutoCompactTokenLimit,
|
|
10266
10555
|
findFirstKeptEntryId,
|
|
10267
10556
|
createCompactionSummary,
|
|
10557
|
+
generateEntryId,
|
|
10558
|
+
FileSessionStore,
|
|
10268
10559
|
createSessionManager,
|
|
10269
10560
|
AgentSessionController,
|
|
10270
10561
|
registerInteractionHandler,
|