@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.
@@ -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-2R3XTLE2.js";
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-Q2N6B5JN.js";
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
- return deleteDurableFile(this.gateway, filePath);
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 (file.endsWith("-files.json") || file.endsWith("-files.json.bak") || file.endsWith("-files.json.prev")) {
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
- const sessionIds = await this.list();
2406
- const metadata = [];
2407
- for (const id of sessionIds) {
2408
- const meta = await this.getMetadata(id);
2409
- if (meta) {
2410
- metadata.push(meta);
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 metadata.sort((a, b) => b.updatedAt - a.updatedAt);
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
- console.warn(`[SessionManager] Session not found: ${sessionId}`);
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 isRecord(value) {
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) => isRecord(block) && block.type === "text").map((block) => String(block.text || "")).join("");
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 (!isRecord(result)) return void 0;
7651
+ if (!isRecord2(result)) return void 0;
7363
7652
  const content = Array.isArray(result.content) ? result.content : [];
7364
- const text = content.filter((item) => isRecord(item) && item.type === "text").map((item) => String(item.text || "")).join("\n").trim();
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 (!isRecord(result) || !isRecord(result.details)) return void 0;
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 (!isRecord(attempt)) return attempt;
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 (!isRecord(entry)) return entry;
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 (!isRecord(entry)) return entry;
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 (!isRecord(attempt)) return attempt;
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 (!isRecord(message)) return typeof message;
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(isRecord).map((block) => String(block.type || "unknown")).slice(0, 10);
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 (isRecord(value) && typeof value.count === "number" && !Array.isArray(value)) return value;
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 (!isRecord(result)) continue;
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 (!isRecord(block)) continue;
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 (!isRecord(block) || !("arguments" in block)) continue;
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 (!isRecord(message)) continue;
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 (isRecord(block) && typeof block.name === "string" && toolNames.length < 20) {
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 (!isRecord(value)) return typeof value;
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 (!isRecord(value)) return typeof value;
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 (!isRecord(meta)) return meta;
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" && isRecord(value)) {
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(isRecord).map((entry) => ({
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" || !isRecord(result)) return [];
7676
- const details = isRecord(result.details) ? result.details : void 0;
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(isRecord).map((task) => {
7679
- const plan = isRecord(task.plan) ? task.plan : void 0;
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 = isRecord(meta) ? meta : {};
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 = isRecord2(block.input) ? block.input : void 0;
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 = isRecord2(block.content) && typeof block.content.error_code === "string" ? block.content.error_code : "unknown";
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 isRecord2(value) {
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 (!isRecord2(value)) return;
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 (!isRecord2(value)) return;
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 = isRecord2(response) ? response : {};
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 = isRecord2(response) ? response : {};
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 = isRecord2(choices[0]) ? choices[0] : {};
8616
- const message = isRecord2(firstChoice.message) ? firstChoice.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 isRecord3(value) {
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 isRecord3(result.details) ? result.details : {};
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,