@ponythewhite/base-context 1.0.9 → 1.0.11

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (80) hide show
  1. package/CHANGELOG.md +19 -0
  2. package/dist/base-context-runtime/pyproject.toml +1 -1
  3. package/dist/base-context-runtime/uv.lock +1 -1
  4. package/dist/build-info.json +1 -1
  5. package/dist/bundle/{bundled-modules-5JRM6P4T.js → bundled-modules-PEFT72QN.js} +2 -2
  6. package/dist/bundle/{chunk-VVI3UKGR.js → chunk-JZHGOOFM.js} +87 -57
  7. package/dist/bundle/{chunk-NEHLB7JV.js → chunk-TOOVREMP.js} +596 -102
  8. package/dist/bundle/{cli-main-YUDBEYE2.js → cli-main-BRXGYTGK.js} +2 -2
  9. package/dist/bundle/cli.js +1 -1
  10. package/dist/bundle/{main-ZLGGAAGU.js → main-POUXGEL6.js} +2 -2
  11. package/dist/core/agent-session.d.ts +0 -1
  12. package/dist/core/agent-session.d.ts.map +1 -1
  13. package/dist/core/agent-session.js +85 -45
  14. package/dist/core/agent-session.js.map +1 -1
  15. package/dist/core/canonical-context.d.ts +19 -3
  16. package/dist/core/canonical-context.d.ts.map +1 -1
  17. package/dist/core/canonical-context.js +245 -39
  18. package/dist/core/canonical-context.js.map +1 -1
  19. package/dist/core/context-epoch-copy.d.ts +1 -1
  20. package/dist/core/context-epoch-copy.d.ts.map +1 -1
  21. package/dist/core/context-epoch-copy.js +18 -7
  22. package/dist/core/context-epoch-copy.js.map +1 -1
  23. package/dist/core/context-epoch.d.ts +18 -3
  24. package/dist/core/context-epoch.d.ts.map +1 -1
  25. package/dist/core/context-epoch.js +13 -2
  26. package/dist/core/context-epoch.js.map +1 -1
  27. package/dist/core/context-tree.d.ts +1 -1
  28. package/dist/core/context-tree.d.ts.map +1 -1
  29. package/dist/core/context-tree.js +98 -8
  30. package/dist/core/context-tree.js.map +1 -1
  31. package/dist/core/history-index-worker.d.ts.map +1 -1
  32. package/dist/core/history-index-worker.js +59 -6
  33. package/dist/core/history-index-worker.js.map +1 -1
  34. package/dist/core/history-index.d.ts +17 -0
  35. package/dist/core/history-index.d.ts.map +1 -1
  36. package/dist/core/history-index.js +22 -0
  37. package/dist/core/history-index.js.map +1 -1
  38. package/dist/core/inference-coordinator.d.ts.map +1 -1
  39. package/dist/core/inference-coordinator.js +5 -1
  40. package/dist/core/inference-coordinator.js.map +1 -1
  41. package/dist/core/public-context.d.ts.map +1 -1
  42. package/dist/core/public-context.js +20 -8
  43. package/dist/core/public-context.js.map +1 -1
  44. package/dist/core/request-view-selection.d.ts +2 -1
  45. package/dist/core/request-view-selection.d.ts.map +1 -1
  46. package/dist/core/request-view-selection.js +29 -2
  47. package/dist/core/request-view-selection.js.map +1 -1
  48. package/dist/core/session-fork-messages.d.ts +5 -0
  49. package/dist/core/session-fork-messages.d.ts.map +1 -1
  50. package/dist/core/session-fork-messages.js +44 -0
  51. package/dist/core/session-fork-messages.js.map +1 -1
  52. package/dist/core/session-history-index.d.ts +5 -0
  53. package/dist/core/session-history-index.d.ts.map +1 -1
  54. package/dist/core/session-history-index.js +7 -0
  55. package/dist/core/session-history-index.js.map +1 -1
  56. package/dist/core/session-manager.d.ts +2 -0
  57. package/dist/core/session-manager.d.ts.map +1 -1
  58. package/dist/core/session-manager.js +155 -13
  59. package/dist/core/session-manager.js.map +1 -1
  60. package/dist/core/session-tree.d.ts +9 -0
  61. package/dist/core/session-tree.d.ts.map +1 -1
  62. package/dist/core/session-tree.js +71 -11
  63. package/dist/core/session-tree.js.map +1 -1
  64. package/dist/modes/agent-connection/in-process-agent-connection.d.ts.map +1 -1
  65. package/dist/modes/agent-connection/in-process-agent-connection.js +4 -4
  66. package/dist/modes/agent-connection/in-process-agent-connection.js.map +1 -1
  67. package/dist/modes/daemon/daemon-mode.d.ts.map +1 -1
  68. package/dist/modes/daemon/daemon-mode.js +19 -34
  69. package/dist/modes/daemon/daemon-mode.js.map +1 -1
  70. package/dist/modes/daemon/daemon-socket.d.ts +5 -0
  71. package/dist/modes/daemon/daemon-socket.d.ts.map +1 -1
  72. package/dist/modes/daemon/daemon-socket.js +19 -0
  73. package/dist/modes/daemon/daemon-socket.js.map +1 -1
  74. package/dist/modes/daemon/daemon-supervisor.d.ts.map +1 -1
  75. package/dist/modes/daemon/daemon-supervisor.js +6 -7
  76. package/dist/modes/daemon/daemon-supervisor.js.map +1 -1
  77. package/dist/modes/daemon/daemon-worker-client.d.ts.map +1 -1
  78. package/dist/modes/daemon/daemon-worker-client.js +5 -5
  79. package/dist/modes/daemon/daemon-worker-client.js.map +1 -1
  80. package/package.json +4 -4
@@ -6,6 +6,15 @@ export declare const DEFAULT_SESSION_TREE_LIMITS: Readonly<SessionHistoryReadLim
6
6
  export declare function buildSessionTreeFlatNodes(entries: readonly SessionEntry[]): SessionTreeFlatNode[];
7
7
  /** Extracted getTree policy: source-order roots and timestamp-ordered children. */
8
8
  export declare function buildSessionTreeFromFlatNodes(flatNodes: readonly SessionTreeFlatNode[]): SessionTreeNode[];
9
+ /** UI projection limits cover visible entries, not excluded request/tool-intent bodies. */
10
+ export declare function readVisibleSessionTreeFlatNodes(manager: ReadonlySessionManager, limits?: SessionHistoryReadLimits): Promise<{
11
+ flatNodes: SessionTreeFlatNode[];
12
+ leafId: string | null;
13
+ }>;
14
+ export declare function readVisibleSessionTree(manager: ReadonlySessionManager, limits?: SessionHistoryReadLimits): Promise<{
15
+ tree: SessionTreeNode[];
16
+ leafId: string | null;
17
+ }>;
9
18
  /** Complete or refuse. Never widen a branch read or return a last-N tree. */
10
19
  export declare function readSessionTreeFlatNodes(manager: ReadonlySessionManager, limits?: SessionHistoryReadLimits): Promise<{
11
20
  flatNodes: SessionTreeFlatNode[];
@@ -1 +1 @@
1
- {"version":3,"file":"session-tree.d.ts","sourceRoot":"","sources":["../../src/core/session-tree.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvH,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,wBAAwB,CAGzE,CAAC;AAEH,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,mBAAmB,EAAE,CA+BjG;AAED,mFAAmF;AACnF,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,SAAS,mBAAmB,EAAE,GAAG,eAAe,EAAE,CAqB1G;AAED,6EAA6E;AAC7E,wBAAsB,wBAAwB,CAC7C,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GAAE,wBAAsD,GAC5D,OAAO,CAAC;IAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CA4BtE;AAED,wBAAsB,eAAe,CACpC,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GAAE,wBAAsD,GAC5D,OAAO,CAAC;IAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAG7D","sourcesContent":["import type { SessionHistoryReadLimits } from \"./session-history-index.js\";\nimport type { ReadonlySessionManager, SessionEntry, SessionTreeFlatNode, SessionTreeNode } from \"./session-manager.js\";\nimport { cloneUsage } from \"./usage.js\";\n\n/** Whole-source limits, including entries hidden from the visible tree. */\nexport const DEFAULT_SESSION_TREE_LIMITS: Readonly<SessionHistoryReadLimits> = Object.freeze({\n\tmaxEntries: 16_384,\n\tmaxSourceBytes: 64 * 1024 * 1024,\n});\n\n/** SessionManager's existing label and hidden-parent policy, on a complete bounded source. */\nexport function buildSessionTreeFlatNodes(entries: readonly SessionEntry[]): SessionTreeFlatNode[] {\n\tconst byId = new Map(entries.map((entry) => [entry.id, entry]));\n\tconst labelsById = new Map<string, string>();\n\tconst labelTimestampsById = new Map<string, string>();\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"label\") continue;\n\t\tif (entry.label) {\n\t\t\tlabelsById.set(entry.targetId, entry.label);\n\t\t\tlabelTimestampsById.set(entry.targetId, entry.timestamp);\n\t\t} else {\n\t\t\tlabelsById.delete(entry.targetId);\n\t\t\tlabelTimestampsById.delete(entry.targetId);\n\t\t}\n\t}\n\treturn entries\n\t\t.filter(\n\t\t\t(entry): entry is SessionTreeFlatNode[\"entry\"] => entry.type !== \"tool_intent\" && entry.type !== \"request\",\n\t\t)\n\t\t.map((entry) => {\n\t\t\tlet parentId = entry.parentId;\n\t\t\tlet parent = parentId ? byId.get(parentId) : undefined;\n\t\t\twhile (parent?.type === \"tool_intent\" || parent?.type === \"request\") {\n\t\t\t\tparentId = parent.parentId;\n\t\t\t\tparent = parentId ? byId.get(parentId) : undefined;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tentry: parentId === entry.parentId ? entry : { ...entry, parentId },\n\t\t\t\tlabel: labelsById.get(entry.id),\n\t\t\t\tlabelTimestamp: labelTimestampsById.get(entry.id),\n\t\t\t};\n\t\t});\n}\n\n/** Extracted getTree policy: source-order roots and timestamp-ordered children. */\nexport function buildSessionTreeFromFlatNodes(flatNodes: readonly SessionTreeFlatNode[]): SessionTreeNode[] {\n\tconst nodeMap = new Map<string, SessionTreeNode>();\n\tconst roots: SessionTreeNode[] = [];\n\tfor (const flatNode of flatNodes) nodeMap.set(flatNode.entry.id, { ...flatNode, children: [] });\n\tfor (const flatNode of flatNodes) {\n\t\tconst entry = flatNode.entry;\n\t\tconst node = nodeMap.get(entry.id)!;\n\t\tif (entry.parentId === null || entry.parentId === entry.id) roots.push(node);\n\t\telse {\n\t\t\tconst parent = nodeMap.get(entry.parentId);\n\t\t\tif (parent) parent.children.push(node);\n\t\t\telse roots.push(node);\n\t\t}\n\t}\n\tconst stack: SessionTreeNode[] = [...roots];\n\twhile (stack.length > 0) {\n\t\tconst node = stack.pop()!;\n\t\tnode.children.sort((a, b) => new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime());\n\t\tstack.push(...node.children);\n\t}\n\treturn roots;\n}\n\n/** Complete or refuse. Never widen a branch read or return a last-N tree. */\nexport async function readSessionTreeFlatNodes(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ flatNodes: SessionTreeFlatNode[]; leafId: string | null }> {\n\tconst capturedLimits = { ...limits };\n\tlet entries: SessionEntry[];\n\tlet leafId: string | null;\n\tif (manager.supportsCapturedHistoryReads()) {\n\t\tconst history = await manager.materializeSourceHistory(capturedLimits);\n\t\tentries = history.entries.map(({ entry }) => entry);\n\t\tleafId = history.source.leafId;\n\t\t// Preserve the Manager's resolved usage overlays on detached canonical entries.\n\t\tconst assistants = new Map(\n\t\t\tentries\n\t\t\t\t.filter((entry) => entry.type === \"message\" && entry.message.role === \"assistant\")\n\t\t\t\t.map((entry) => [entry.id, entry]),\n\t\t);\n\t\tfor (const entry of entries) {\n\t\t\tif (entry.type !== \"child_usage_attributed\") continue;\n\t\t\tconst target = assistants.get(entry.targetId);\n\t\t\tif (target?.type === \"message\" && target.message.role === \"assistant\")\n\t\t\t\ttarget.message.usage = cloneUsage(entry.aggregateUsage);\n\t\t}\n\t} else {\n\t\t// Explicit readonly/legacy/in-memory views keep their captured resident data.\n\t\t// Their byte limit counts serialized header/entry JSON, not canonical frames.\n\t\tconst history = manager.materializeResidentHistory(capturedLimits);\n\t\tentries = history.entries;\n\t\tleafId = history.leafId;\n\t}\n\treturn { flatNodes: buildSessionTreeFlatNodes(entries), leafId };\n}\n\nexport async function readSessionTree(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ tree: SessionTreeNode[]; leafId: string | null }> {\n\tconst { flatNodes, leafId } = await readSessionTreeFlatNodes(manager, limits);\n\treturn { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };\n}\n"]}
1
+ {"version":3,"file":"session-tree.d.ts","sourceRoot":"","sources":["../../src/core/session-tree.ts"],"names":[],"mappings":"AACA,OAAO,KAAK,EAAE,wBAAwB,EAAE,MAAM,4BAA4B,CAAC;AAC3E,OAAO,KAAK,EAAE,sBAAsB,EAAE,YAAY,EAAE,mBAAmB,EAAE,eAAe,EAAE,MAAM,sBAAsB,CAAC;AAGvH,2EAA2E;AAC3E,eAAO,MAAM,2BAA2B,EAAE,QAAQ,CAAC,wBAAwB,CAGzE,CAAC;AAEH,8FAA8F;AAC9F,wBAAgB,yBAAyB,CAAC,OAAO,EAAE,SAAS,YAAY,EAAE,GAAG,mBAAmB,EAAE,CA+BjG;AAED,mFAAmF;AACnF,wBAAgB,6BAA6B,CAAC,SAAS,EAAE,SAAS,mBAAmB,EAAE,GAAG,eAAe,EAAE,CAqB1G;AAgBD,2FAA2F;AAC3F,wBAAsB,+BAA+B,CACpD,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GAAE,wBAAsD,GAC5D,OAAO,CAAC;IAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAgDtE;AAED,wBAAsB,sBAAsB,CAC3C,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GAAE,wBAAsD,GAC5D,OAAO,CAAC;IAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAG7D;AAED,6EAA6E;AAC7E,wBAAsB,wBAAwB,CAC7C,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GAAE,wBAAsD,GAC5D,OAAO,CAAC;IAAE,SAAS,EAAE,mBAAmB,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAiBtE;AAED,wBAAsB,eAAe,CACpC,OAAO,EAAE,sBAAsB,EAC/B,MAAM,GAAE,wBAAsD,GAC5D,OAAO,CAAC;IAAE,IAAI,EAAE,eAAe,EAAE,CAAC;IAAC,MAAM,EAAE,MAAM,GAAG,IAAI,CAAA;CAAE,CAAC,CAG7D","sourcesContent":["import { stringifyBoundedJson } from \"./bounded-json.js\";\nimport type { SessionHistoryReadLimits } from \"./session-history-index.js\";\nimport type { ReadonlySessionManager, SessionEntry, SessionTreeFlatNode, SessionTreeNode } from \"./session-manager.js\";\nimport { cloneUsage } from \"./usage.js\";\n\n/** Whole-source limits, including entries hidden from the visible tree. */\nexport const DEFAULT_SESSION_TREE_LIMITS: Readonly<SessionHistoryReadLimits> = Object.freeze({\n\tmaxEntries: 16_384,\n\tmaxSourceBytes: 64 * 1024 * 1024,\n});\n\n/** SessionManager's existing label and hidden-parent policy, on a complete bounded source. */\nexport function buildSessionTreeFlatNodes(entries: readonly SessionEntry[]): SessionTreeFlatNode[] {\n\tconst byId = new Map(entries.map((entry) => [entry.id, entry]));\n\tconst labelsById = new Map<string, string>();\n\tconst labelTimestampsById = new Map<string, string>();\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"label\") continue;\n\t\tif (entry.label) {\n\t\t\tlabelsById.set(entry.targetId, entry.label);\n\t\t\tlabelTimestampsById.set(entry.targetId, entry.timestamp);\n\t\t} else {\n\t\t\tlabelsById.delete(entry.targetId);\n\t\t\tlabelTimestampsById.delete(entry.targetId);\n\t\t}\n\t}\n\treturn entries\n\t\t.filter(\n\t\t\t(entry): entry is SessionTreeFlatNode[\"entry\"] => entry.type !== \"tool_intent\" && entry.type !== \"request\",\n\t\t)\n\t\t.map((entry) => {\n\t\t\tlet parentId = entry.parentId;\n\t\t\tlet parent = parentId ? byId.get(parentId) : undefined;\n\t\t\twhile (parent?.type === \"tool_intent\" || parent?.type === \"request\") {\n\t\t\t\tparentId = parent.parentId;\n\t\t\t\tparent = parentId ? byId.get(parentId) : undefined;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tentry: parentId === entry.parentId ? entry : { ...entry, parentId },\n\t\t\t\tlabel: labelsById.get(entry.id),\n\t\t\t\tlabelTimestamp: labelTimestampsById.get(entry.id),\n\t\t\t};\n\t\t});\n}\n\n/** Extracted getTree policy: source-order roots and timestamp-ordered children. */\nexport function buildSessionTreeFromFlatNodes(flatNodes: readonly SessionTreeFlatNode[]): SessionTreeNode[] {\n\tconst nodeMap = new Map<string, SessionTreeNode>();\n\tconst roots: SessionTreeNode[] = [];\n\tfor (const flatNode of flatNodes) nodeMap.set(flatNode.entry.id, { ...flatNode, children: [] });\n\tfor (const flatNode of flatNodes) {\n\t\tconst entry = flatNode.entry;\n\t\tconst node = nodeMap.get(entry.id)!;\n\t\tif (entry.parentId === null || entry.parentId === entry.id) roots.push(node);\n\t\telse {\n\t\t\tconst parent = nodeMap.get(entry.parentId);\n\t\t\tif (parent) parent.children.push(node);\n\t\t\telse roots.push(node);\n\t\t}\n\t}\n\tconst stack: SessionTreeNode[] = [...roots];\n\twhile (stack.length > 0) {\n\t\tconst node = stack.pop()!;\n\t\tnode.children.sort((a, b) => new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime());\n\t\tstack.push(...node.children);\n\t}\n\treturn roots;\n}\n\nfunction applyTreeUsageOverlays(entries: SessionEntry[]): void {\n\tconst assistants = new Map(\n\t\tentries\n\t\t\t.filter((entry) => entry.type === \"message\" && entry.message.role === \"assistant\")\n\t\t\t.map((entry) => [entry.id, entry]),\n\t);\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"child_usage_attributed\") continue;\n\t\tconst target = assistants.get(entry.targetId);\n\t\tif (target?.type === \"message\" && target.message.role === \"assistant\")\n\t\t\ttarget.message.usage = cloneUsage(entry.aggregateUsage);\n\t}\n}\n\n/** UI projection limits cover visible entries, not excluded request/tool-intent bodies. */\nexport async function readVisibleSessionTreeFlatNodes(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ flatNodes: SessionTreeFlatNode[]; leafId: string | null }> {\n\tconst { maxEntries, maxSourceBytes } = limits;\n\tif (\n\t\t!Number.isSafeInteger(maxEntries) ||\n\t\tmaxEntries <= 0 ||\n\t\t!Number.isSafeInteger(maxSourceBytes) ||\n\t\tmaxSourceBytes <= 0\n\t)\n\t\tthrow new Error(\"Invalid history materialization limits\");\n\tif (!manager.supportsCapturedHistoryReads())\n\t\treturn readSessionTreeFlatNodes(manager, { maxEntries, maxSourceBytes });\n\treturn manager.readSourceHistory(async (history) => {\n\t\tconst entries: SessionEntry[] = [];\n\t\tconst visibleIds = new Set<string>();\n\t\tlet sourceBytes = 0;\n\t\tlet after = 0;\n\t\tfor (;;) {\n\t\t\tconst page = await history.page(after);\n\t\t\tif (page.indexedThrough < history.source.sourceSequence)\n\t\t\t\tthrow new Error(\"Captured history has incomplete index coverage\");\n\t\t\tfor (const ref of page.events) {\n\t\t\t\tif (ref.kind === \"request\" || ref.kind === \"tool_intent\") continue;\n\t\t\t\tif (entries.length >= maxEntries) throw new Error(\"History entry budget exceeded\");\n\t\t\t\tif (sourceBytes + ref.locator.length > maxSourceBytes)\n\t\t\t\t\tthrow new Error(\"History source byte budget exceeded\");\n\t\t\t\tconst hydrated = await history.hydrateEntry(ref.id, maxSourceBytes - sourceBytes);\n\t\t\t\tif (!hydrated) throw new Error(\"Session tree entry source is unavailable\");\n\t\t\t\tsourceBytes += ref.locator.length;\n\t\t\t\tlet parentId = ref.parentId;\n\t\t\t\t// Resolve excluded parent chains as metadata; never retain or hydrate their bodies.\n\t\t\t\twhile (parentId !== null && !visibleIds.has(parentId)) {\n\t\t\t\t\tconst parent = await history.get(parentId);\n\t\t\t\t\tif (!parent || (parent.kind !== \"request\" && parent.kind !== \"tool_intent\")) break;\n\t\t\t\t\tparentId = parent.parentId;\n\t\t\t\t}\n\t\t\t\thydrated.entry.parentId = parentId;\n\t\t\t\tentries.push(hydrated.entry);\n\t\t\t\tvisibleIds.add(ref.id);\n\t\t\t}\n\t\t\tif (page.nextAfter === null) break;\n\t\t\tafter = page.nextAfter;\n\t\t}\n\t\tapplyTreeUsageOverlays(entries);\n\t\tconst result = { flatNodes: buildSessionTreeFlatNodes(entries), leafId: history.source.leafId };\n\t\t// Labels and resolved usage are also part of the bounded visible response.\n\t\tstringifyBoundedJson(result, maxSourceBytes);\n\t\treturn result;\n\t});\n}\n\nexport async function readVisibleSessionTree(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ tree: SessionTreeNode[]; leafId: string | null }> {\n\tconst { flatNodes, leafId } = await readVisibleSessionTreeFlatNodes(manager, limits);\n\treturn { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };\n}\n\n/** Complete or refuse. Never widen a branch read or return a last-N tree. */\nexport async function readSessionTreeFlatNodes(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ flatNodes: SessionTreeFlatNode[]; leafId: string | null }> {\n\tconst capturedLimits = { ...limits };\n\tlet entries: SessionEntry[];\n\tlet leafId: string | null;\n\tif (manager.supportsCapturedHistoryReads()) {\n\t\tconst history = await manager.materializeSourceHistory(capturedLimits);\n\t\tentries = history.entries.map(({ entry }) => entry);\n\t\tleafId = history.source.leafId;\n\t\tapplyTreeUsageOverlays(entries);\n\t} else {\n\t\t// Explicit readonly/legacy/in-memory views keep their captured resident data.\n\t\t// Their byte limit counts serialized header/entry JSON, not canonical frames.\n\t\tconst history = manager.materializeResidentHistory(capturedLimits);\n\t\tentries = history.entries;\n\t\tleafId = history.leafId;\n\t}\n\treturn { flatNodes: buildSessionTreeFlatNodes(entries), leafId };\n}\n\nexport async function readSessionTree(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ tree: SessionTreeNode[]; leafId: string | null }> {\n\tconst { flatNodes, leafId } = await readSessionTreeFlatNodes(manager, limits);\n\treturn { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };\n}\n"]}
@@ -1,3 +1,4 @@
1
+ import { stringifyBoundedJson } from "./bounded-json.js";
1
2
  import { cloneUsage } from "./usage.js";
2
3
  /** Whole-source limits, including entries hidden from the visible tree. */
3
4
  export const DEFAULT_SESSION_TREE_LIMITS = Object.freeze({
@@ -64,6 +65,75 @@ export function buildSessionTreeFromFlatNodes(flatNodes) {
64
65
  }
65
66
  return roots;
66
67
  }
68
+ function applyTreeUsageOverlays(entries) {
69
+ const assistants = new Map(entries
70
+ .filter((entry) => entry.type === "message" && entry.message.role === "assistant")
71
+ .map((entry) => [entry.id, entry]));
72
+ for (const entry of entries) {
73
+ if (entry.type !== "child_usage_attributed")
74
+ continue;
75
+ const target = assistants.get(entry.targetId);
76
+ if (target?.type === "message" && target.message.role === "assistant")
77
+ target.message.usage = cloneUsage(entry.aggregateUsage);
78
+ }
79
+ }
80
+ /** UI projection limits cover visible entries, not excluded request/tool-intent bodies. */
81
+ export async function readVisibleSessionTreeFlatNodes(manager, limits = DEFAULT_SESSION_TREE_LIMITS) {
82
+ const { maxEntries, maxSourceBytes } = limits;
83
+ if (!Number.isSafeInteger(maxEntries) ||
84
+ maxEntries <= 0 ||
85
+ !Number.isSafeInteger(maxSourceBytes) ||
86
+ maxSourceBytes <= 0)
87
+ throw new Error("Invalid history materialization limits");
88
+ if (!manager.supportsCapturedHistoryReads())
89
+ return readSessionTreeFlatNodes(manager, { maxEntries, maxSourceBytes });
90
+ return manager.readSourceHistory(async (history) => {
91
+ const entries = [];
92
+ const visibleIds = new Set();
93
+ let sourceBytes = 0;
94
+ let after = 0;
95
+ for (;;) {
96
+ const page = await history.page(after);
97
+ if (page.indexedThrough < history.source.sourceSequence)
98
+ throw new Error("Captured history has incomplete index coverage");
99
+ for (const ref of page.events) {
100
+ if (ref.kind === "request" || ref.kind === "tool_intent")
101
+ continue;
102
+ if (entries.length >= maxEntries)
103
+ throw new Error("History entry budget exceeded");
104
+ if (sourceBytes + ref.locator.length > maxSourceBytes)
105
+ throw new Error("History source byte budget exceeded");
106
+ const hydrated = await history.hydrateEntry(ref.id, maxSourceBytes - sourceBytes);
107
+ if (!hydrated)
108
+ throw new Error("Session tree entry source is unavailable");
109
+ sourceBytes += ref.locator.length;
110
+ let parentId = ref.parentId;
111
+ // Resolve excluded parent chains as metadata; never retain or hydrate their bodies.
112
+ while (parentId !== null && !visibleIds.has(parentId)) {
113
+ const parent = await history.get(parentId);
114
+ if (!parent || (parent.kind !== "request" && parent.kind !== "tool_intent"))
115
+ break;
116
+ parentId = parent.parentId;
117
+ }
118
+ hydrated.entry.parentId = parentId;
119
+ entries.push(hydrated.entry);
120
+ visibleIds.add(ref.id);
121
+ }
122
+ if (page.nextAfter === null)
123
+ break;
124
+ after = page.nextAfter;
125
+ }
126
+ applyTreeUsageOverlays(entries);
127
+ const result = { flatNodes: buildSessionTreeFlatNodes(entries), leafId: history.source.leafId };
128
+ // Labels and resolved usage are also part of the bounded visible response.
129
+ stringifyBoundedJson(result, maxSourceBytes);
130
+ return result;
131
+ });
132
+ }
133
+ export async function readVisibleSessionTree(manager, limits = DEFAULT_SESSION_TREE_LIMITS) {
134
+ const { flatNodes, leafId } = await readVisibleSessionTreeFlatNodes(manager, limits);
135
+ return { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };
136
+ }
67
137
  /** Complete or refuse. Never widen a branch read or return a last-N tree. */
68
138
  export async function readSessionTreeFlatNodes(manager, limits = DEFAULT_SESSION_TREE_LIMITS) {
69
139
  const capturedLimits = { ...limits };
@@ -73,17 +143,7 @@ export async function readSessionTreeFlatNodes(manager, limits = DEFAULT_SESSION
73
143
  const history = await manager.materializeSourceHistory(capturedLimits);
74
144
  entries = history.entries.map(({ entry }) => entry);
75
145
  leafId = history.source.leafId;
76
- // Preserve the Manager's resolved usage overlays on detached canonical entries.
77
- const assistants = new Map(entries
78
- .filter((entry) => entry.type === "message" && entry.message.role === "assistant")
79
- .map((entry) => [entry.id, entry]));
80
- for (const entry of entries) {
81
- if (entry.type !== "child_usage_attributed")
82
- continue;
83
- const target = assistants.get(entry.targetId);
84
- if (target?.type === "message" && target.message.role === "assistant")
85
- target.message.usage = cloneUsage(entry.aggregateUsage);
86
- }
146
+ applyTreeUsageOverlays(entries);
87
147
  }
88
148
  else {
89
149
  // Explicit readonly/legacy/in-memory views keep their captured resident data.
@@ -1 +1 @@
1
- {"version":3,"file":"session-tree.js","sourceRoot":"","sources":["../../src/core/session-tree.ts"],"names":[],"mappings":"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","sourcesContent":["import type { SessionHistoryReadLimits } from \"./session-history-index.js\";\nimport type { ReadonlySessionManager, SessionEntry, SessionTreeFlatNode, SessionTreeNode } from \"./session-manager.js\";\nimport { cloneUsage } from \"./usage.js\";\n\n/** Whole-source limits, including entries hidden from the visible tree. */\nexport const DEFAULT_SESSION_TREE_LIMITS: Readonly<SessionHistoryReadLimits> = Object.freeze({\n\tmaxEntries: 16_384,\n\tmaxSourceBytes: 64 * 1024 * 1024,\n});\n\n/** SessionManager's existing label and hidden-parent policy, on a complete bounded source. */\nexport function buildSessionTreeFlatNodes(entries: readonly SessionEntry[]): SessionTreeFlatNode[] {\n\tconst byId = new Map(entries.map((entry) => [entry.id, entry]));\n\tconst labelsById = new Map<string, string>();\n\tconst labelTimestampsById = new Map<string, string>();\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"label\") continue;\n\t\tif (entry.label) {\n\t\t\tlabelsById.set(entry.targetId, entry.label);\n\t\t\tlabelTimestampsById.set(entry.targetId, entry.timestamp);\n\t\t} else {\n\t\t\tlabelsById.delete(entry.targetId);\n\t\t\tlabelTimestampsById.delete(entry.targetId);\n\t\t}\n\t}\n\treturn entries\n\t\t.filter(\n\t\t\t(entry): entry is SessionTreeFlatNode[\"entry\"] => entry.type !== \"tool_intent\" && entry.type !== \"request\",\n\t\t)\n\t\t.map((entry) => {\n\t\t\tlet parentId = entry.parentId;\n\t\t\tlet parent = parentId ? byId.get(parentId) : undefined;\n\t\t\twhile (parent?.type === \"tool_intent\" || parent?.type === \"request\") {\n\t\t\t\tparentId = parent.parentId;\n\t\t\t\tparent = parentId ? byId.get(parentId) : undefined;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tentry: parentId === entry.parentId ? entry : { ...entry, parentId },\n\t\t\t\tlabel: labelsById.get(entry.id),\n\t\t\t\tlabelTimestamp: labelTimestampsById.get(entry.id),\n\t\t\t};\n\t\t});\n}\n\n/** Extracted getTree policy: source-order roots and timestamp-ordered children. */\nexport function buildSessionTreeFromFlatNodes(flatNodes: readonly SessionTreeFlatNode[]): SessionTreeNode[] {\n\tconst nodeMap = new Map<string, SessionTreeNode>();\n\tconst roots: SessionTreeNode[] = [];\n\tfor (const flatNode of flatNodes) nodeMap.set(flatNode.entry.id, { ...flatNode, children: [] });\n\tfor (const flatNode of flatNodes) {\n\t\tconst entry = flatNode.entry;\n\t\tconst node = nodeMap.get(entry.id)!;\n\t\tif (entry.parentId === null || entry.parentId === entry.id) roots.push(node);\n\t\telse {\n\t\t\tconst parent = nodeMap.get(entry.parentId);\n\t\t\tif (parent) parent.children.push(node);\n\t\t\telse roots.push(node);\n\t\t}\n\t}\n\tconst stack: SessionTreeNode[] = [...roots];\n\twhile (stack.length > 0) {\n\t\tconst node = stack.pop()!;\n\t\tnode.children.sort((a, b) => new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime());\n\t\tstack.push(...node.children);\n\t}\n\treturn roots;\n}\n\n/** Complete or refuse. Never widen a branch read or return a last-N tree. */\nexport async function readSessionTreeFlatNodes(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ flatNodes: SessionTreeFlatNode[]; leafId: string | null }> {\n\tconst capturedLimits = { ...limits };\n\tlet entries: SessionEntry[];\n\tlet leafId: string | null;\n\tif (manager.supportsCapturedHistoryReads()) {\n\t\tconst history = await manager.materializeSourceHistory(capturedLimits);\n\t\tentries = history.entries.map(({ entry }) => entry);\n\t\tleafId = history.source.leafId;\n\t\t// Preserve the Manager's resolved usage overlays on detached canonical entries.\n\t\tconst assistants = new Map(\n\t\t\tentries\n\t\t\t\t.filter((entry) => entry.type === \"message\" && entry.message.role === \"assistant\")\n\t\t\t\t.map((entry) => [entry.id, entry]),\n\t\t);\n\t\tfor (const entry of entries) {\n\t\t\tif (entry.type !== \"child_usage_attributed\") continue;\n\t\t\tconst target = assistants.get(entry.targetId);\n\t\t\tif (target?.type === \"message\" && target.message.role === \"assistant\")\n\t\t\t\ttarget.message.usage = cloneUsage(entry.aggregateUsage);\n\t\t}\n\t} else {\n\t\t// Explicit readonly/legacy/in-memory views keep their captured resident data.\n\t\t// Their byte limit counts serialized header/entry JSON, not canonical frames.\n\t\tconst history = manager.materializeResidentHistory(capturedLimits);\n\t\tentries = history.entries;\n\t\tleafId = history.leafId;\n\t}\n\treturn { flatNodes: buildSessionTreeFlatNodes(entries), leafId };\n}\n\nexport async function readSessionTree(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ tree: SessionTreeNode[]; leafId: string | null }> {\n\tconst { flatNodes, leafId } = await readSessionTreeFlatNodes(manager, limits);\n\treturn { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };\n}\n"]}
1
+ {"version":3,"file":"session-tree.js","sourceRoot":"","sources":["../../src/core/session-tree.ts"],"names":[],"mappings":"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","sourcesContent":["import { stringifyBoundedJson } from \"./bounded-json.js\";\nimport type { SessionHistoryReadLimits } from \"./session-history-index.js\";\nimport type { ReadonlySessionManager, SessionEntry, SessionTreeFlatNode, SessionTreeNode } from \"./session-manager.js\";\nimport { cloneUsage } from \"./usage.js\";\n\n/** Whole-source limits, including entries hidden from the visible tree. */\nexport const DEFAULT_SESSION_TREE_LIMITS: Readonly<SessionHistoryReadLimits> = Object.freeze({\n\tmaxEntries: 16_384,\n\tmaxSourceBytes: 64 * 1024 * 1024,\n});\n\n/** SessionManager's existing label and hidden-parent policy, on a complete bounded source. */\nexport function buildSessionTreeFlatNodes(entries: readonly SessionEntry[]): SessionTreeFlatNode[] {\n\tconst byId = new Map(entries.map((entry) => [entry.id, entry]));\n\tconst labelsById = new Map<string, string>();\n\tconst labelTimestampsById = new Map<string, string>();\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"label\") continue;\n\t\tif (entry.label) {\n\t\t\tlabelsById.set(entry.targetId, entry.label);\n\t\t\tlabelTimestampsById.set(entry.targetId, entry.timestamp);\n\t\t} else {\n\t\t\tlabelsById.delete(entry.targetId);\n\t\t\tlabelTimestampsById.delete(entry.targetId);\n\t\t}\n\t}\n\treturn entries\n\t\t.filter(\n\t\t\t(entry): entry is SessionTreeFlatNode[\"entry\"] => entry.type !== \"tool_intent\" && entry.type !== \"request\",\n\t\t)\n\t\t.map((entry) => {\n\t\t\tlet parentId = entry.parentId;\n\t\t\tlet parent = parentId ? byId.get(parentId) : undefined;\n\t\t\twhile (parent?.type === \"tool_intent\" || parent?.type === \"request\") {\n\t\t\t\tparentId = parent.parentId;\n\t\t\t\tparent = parentId ? byId.get(parentId) : undefined;\n\t\t\t}\n\t\t\treturn {\n\t\t\t\tentry: parentId === entry.parentId ? entry : { ...entry, parentId },\n\t\t\t\tlabel: labelsById.get(entry.id),\n\t\t\t\tlabelTimestamp: labelTimestampsById.get(entry.id),\n\t\t\t};\n\t\t});\n}\n\n/** Extracted getTree policy: source-order roots and timestamp-ordered children. */\nexport function buildSessionTreeFromFlatNodes(flatNodes: readonly SessionTreeFlatNode[]): SessionTreeNode[] {\n\tconst nodeMap = new Map<string, SessionTreeNode>();\n\tconst roots: SessionTreeNode[] = [];\n\tfor (const flatNode of flatNodes) nodeMap.set(flatNode.entry.id, { ...flatNode, children: [] });\n\tfor (const flatNode of flatNodes) {\n\t\tconst entry = flatNode.entry;\n\t\tconst node = nodeMap.get(entry.id)!;\n\t\tif (entry.parentId === null || entry.parentId === entry.id) roots.push(node);\n\t\telse {\n\t\t\tconst parent = nodeMap.get(entry.parentId);\n\t\t\tif (parent) parent.children.push(node);\n\t\t\telse roots.push(node);\n\t\t}\n\t}\n\tconst stack: SessionTreeNode[] = [...roots];\n\twhile (stack.length > 0) {\n\t\tconst node = stack.pop()!;\n\t\tnode.children.sort((a, b) => new Date(a.entry.timestamp).getTime() - new Date(b.entry.timestamp).getTime());\n\t\tstack.push(...node.children);\n\t}\n\treturn roots;\n}\n\nfunction applyTreeUsageOverlays(entries: SessionEntry[]): void {\n\tconst assistants = new Map(\n\t\tentries\n\t\t\t.filter((entry) => entry.type === \"message\" && entry.message.role === \"assistant\")\n\t\t\t.map((entry) => [entry.id, entry]),\n\t);\n\tfor (const entry of entries) {\n\t\tif (entry.type !== \"child_usage_attributed\") continue;\n\t\tconst target = assistants.get(entry.targetId);\n\t\tif (target?.type === \"message\" && target.message.role === \"assistant\")\n\t\t\ttarget.message.usage = cloneUsage(entry.aggregateUsage);\n\t}\n}\n\n/** UI projection limits cover visible entries, not excluded request/tool-intent bodies. */\nexport async function readVisibleSessionTreeFlatNodes(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ flatNodes: SessionTreeFlatNode[]; leafId: string | null }> {\n\tconst { maxEntries, maxSourceBytes } = limits;\n\tif (\n\t\t!Number.isSafeInteger(maxEntries) ||\n\t\tmaxEntries <= 0 ||\n\t\t!Number.isSafeInteger(maxSourceBytes) ||\n\t\tmaxSourceBytes <= 0\n\t)\n\t\tthrow new Error(\"Invalid history materialization limits\");\n\tif (!manager.supportsCapturedHistoryReads())\n\t\treturn readSessionTreeFlatNodes(manager, { maxEntries, maxSourceBytes });\n\treturn manager.readSourceHistory(async (history) => {\n\t\tconst entries: SessionEntry[] = [];\n\t\tconst visibleIds = new Set<string>();\n\t\tlet sourceBytes = 0;\n\t\tlet after = 0;\n\t\tfor (;;) {\n\t\t\tconst page = await history.page(after);\n\t\t\tif (page.indexedThrough < history.source.sourceSequence)\n\t\t\t\tthrow new Error(\"Captured history has incomplete index coverage\");\n\t\t\tfor (const ref of page.events) {\n\t\t\t\tif (ref.kind === \"request\" || ref.kind === \"tool_intent\") continue;\n\t\t\t\tif (entries.length >= maxEntries) throw new Error(\"History entry budget exceeded\");\n\t\t\t\tif (sourceBytes + ref.locator.length > maxSourceBytes)\n\t\t\t\t\tthrow new Error(\"History source byte budget exceeded\");\n\t\t\t\tconst hydrated = await history.hydrateEntry(ref.id, maxSourceBytes - sourceBytes);\n\t\t\t\tif (!hydrated) throw new Error(\"Session tree entry source is unavailable\");\n\t\t\t\tsourceBytes += ref.locator.length;\n\t\t\t\tlet parentId = ref.parentId;\n\t\t\t\t// Resolve excluded parent chains as metadata; never retain or hydrate their bodies.\n\t\t\t\twhile (parentId !== null && !visibleIds.has(parentId)) {\n\t\t\t\t\tconst parent = await history.get(parentId);\n\t\t\t\t\tif (!parent || (parent.kind !== \"request\" && parent.kind !== \"tool_intent\")) break;\n\t\t\t\t\tparentId = parent.parentId;\n\t\t\t\t}\n\t\t\t\thydrated.entry.parentId = parentId;\n\t\t\t\tentries.push(hydrated.entry);\n\t\t\t\tvisibleIds.add(ref.id);\n\t\t\t}\n\t\t\tif (page.nextAfter === null) break;\n\t\t\tafter = page.nextAfter;\n\t\t}\n\t\tapplyTreeUsageOverlays(entries);\n\t\tconst result = { flatNodes: buildSessionTreeFlatNodes(entries), leafId: history.source.leafId };\n\t\t// Labels and resolved usage are also part of the bounded visible response.\n\t\tstringifyBoundedJson(result, maxSourceBytes);\n\t\treturn result;\n\t});\n}\n\nexport async function readVisibleSessionTree(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ tree: SessionTreeNode[]; leafId: string | null }> {\n\tconst { flatNodes, leafId } = await readVisibleSessionTreeFlatNodes(manager, limits);\n\treturn { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };\n}\n\n/** Complete or refuse. Never widen a branch read or return a last-N tree. */\nexport async function readSessionTreeFlatNodes(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ flatNodes: SessionTreeFlatNode[]; leafId: string | null }> {\n\tconst capturedLimits = { ...limits };\n\tlet entries: SessionEntry[];\n\tlet leafId: string | null;\n\tif (manager.supportsCapturedHistoryReads()) {\n\t\tconst history = await manager.materializeSourceHistory(capturedLimits);\n\t\tentries = history.entries.map(({ entry }) => entry);\n\t\tleafId = history.source.leafId;\n\t\tapplyTreeUsageOverlays(entries);\n\t} else {\n\t\t// Explicit readonly/legacy/in-memory views keep their captured resident data.\n\t\t// Their byte limit counts serialized header/entry JSON, not canonical frames.\n\t\tconst history = manager.materializeResidentHistory(capturedLimits);\n\t\tentries = history.entries;\n\t\tleafId = history.leafId;\n\t}\n\treturn { flatNodes: buildSessionTreeFlatNodes(entries), leafId };\n}\n\nexport async function readSessionTree(\n\tmanager: ReadonlySessionManager,\n\tlimits: SessionHistoryReadLimits = DEFAULT_SESSION_TREE_LIMITS,\n): Promise<{ tree: SessionTreeNode[]; leafId: string | null }> {\n\tconst { flatNodes, leafId } = await readSessionTreeFlatNodes(manager, limits);\n\treturn { tree: buildSessionTreeFromFlatNodes(flatNodes), leafId };\n}\n"]}
@@ -1 +1 @@
1
- {"version":3,"file":"in-process-agent-connection.d.ts","sourceRoot":"","sources":["../../../src/modes/agent-connection/in-process-agent-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from \"node:path\";\nimport { type AgentMessage, AgentOutputLimitError, type ThinkingLevel } from \"@ponythewhite/base-context-agent\";\nimport type { ImageContent, ServiceTier, Transport } from \"@ponythewhite/base-context-ai\";\nimport type { AgentSessionMessageReceipt, AgentSessionMessageSafetyStatus } from \"../../core/agent-messages.js\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.js\";\nimport type { AgentAutonomousStatus } from \"../../core/autonomous.js\";\nimport type { BashResult } from \"../../core/bash-executor.js\";\nimport type { CompactionResult } from \"../../core/compaction/index.js\";\nimport type { ContextTreeNode } from \"../../core/context-tree.js\";\nimport type {\n\tAgentCronJob,\n\tAgentHeartbeatDeliveryMode,\n\tAgentHeartbeatManagementAction,\n\tAgentHeartbeatUpdateAction,\n} from \"../../core/cron-jobs.js\";\nimport type { ExtensionUIContext } from \"../../core/extensions/types.js\";\nimport type { AcpMcpServerConfig } from \"../../core/mcp/acp-mcp-types.js\";\nimport type { RefinementResult } from \"../../core/refinement/index.js\";\nimport { type DeleteSessionFileResult, deleteSessionFile } from \"../../core/session-file-actions.js\";\nimport { readUserMessagesForForking } from \"../../core/session-fork-messages.js\";\nimport { SessionManager } from \"../../core/session-manager.js\";\nimport type { SessionStats } from \"../../core/session-stats.js\";\nimport { readSessionTree } from \"../../core/session-tree.js\";\nimport { type SideQuestionRun, startSideQuestion } from \"../../core/side-question.js\";\nimport { waitForHeadlessCompletion } from \"../headless-completion.js\";\nimport {\n\tcreateAgentConnectionCommands,\n\tcreateAgentConnectionResourceSnapshot,\n\tcreateAgentConnectionSnapshot,\n\tcreateAgentConnectionState,\n} from \"./snapshot.js\";\nimport { createAgentConnectionToolDefinition } from \"./tool-definition.js\";\nimport type {\n\tAgentConnection,\n\tAgentConnectionBeforeSessionInvalidateListener,\n\tAgentConnectionEvent,\n\tAgentConnectionEventListener,\n\tAgentConnectionExecuteBashOptions,\n\tAgentConnectionExtensionUiResponse,\n\tAgentConnectionForkOptions,\n\tAgentConnectionHeadlessCompletionOptions,\n\tAgentConnectionHeartbeat,\n\tAgentConnectionModel,\n\tAgentConnectionModelCatalog,\n\tAgentConnectionModelCycleResult,\n\tAgentConnectionNavigateTreeOptions,\n\tAgentConnectionNavigateTreeResult,\n\tAgentConnectionNewSessionOptions,\n\tAgentConnectionPromptOptions,\n\tAgentConnectionQueuedMessageLane,\n\tAgentConnectionQueuedMessageMutation,\n\tAgentConnectionQueuedMessageMutationStatus,\n\tAgentConnectionQueueMode,\n\tAgentConnectionQueueState,\n\tAgentConnectionResourceSnapshot,\n\tAgentConnectionRlmChildAgentSnapshot,\n\tAgentConnectionSavedSessionInfo,\n\tAgentConnectionSavedSessionScope,\n\tAgentConnectionScopedModel,\n\tAgentConnectionSessionContext,\n\tAgentConnectionSessionHeader,\n\tAgentConnectionSessionInputPause,\n\tAgentConnectionSessionListCallbacks,\n\tAgentConnectionSessionTreeNode,\n\tAgentConnectionSessionWatcher,\n\tAgentConnectionSideQuestionTurn,\n\tAgentConnectionSlashCommand,\n\tAgentConnectionSnapshot,\n\tAgentConnectionState,\n\tAgentConnectionSwitchSessionOptions,\n\tAgentConnectionToolDefinition,\n\tAgentConnectionUserMessage,\n} from \"./types.js\";\n\nexport interface InProcessHeadlessExtensionOptions {\n\tuiContext?: ExtensionUIContext;\n\tshutdownHandler?: () => void;\n}\n\nexport class InProcessAgentConnection implements AgentConnection {\n\tprivate readonly listeners = new Set<AgentConnectionEventListener>();\n\tprivate readonly beforeSessionInvalidateListeners = new Set<AgentConnectionBeforeSessionInvalidateListener>();\n\tprivate readonly sideQuestionRuns = new Map<string, SideQuestionRun>();\n\tprivate readonly sessionInputPauses = new Map<string, AgentConnectionSessionInputPause>();\n\tprivate headlessExtensionOptions: InProcessHeadlessExtensionOptions | undefined;\n\tprivate unsubscribeSessionEvents: (() => void) | undefined;\n\n\tconstructor(private readonly runtimeHost: AgentSessionRuntime) {\n\t\tthis.bindCurrentSessionEvents();\n\t\tif (typeof this.runtimeHost.setBeforeSessionInvalidate === \"function\") {\n\t\t\tthis.runtimeHost.setBeforeSessionInvalidate(() => {\n\t\t\t\tthis.abortAllSideQuestions();\n\t\t\t\tfor (const listener of [...this.beforeSessionInvalidateListeners]) {\n\t\t\t\t\tlistener();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.runtimeHost.setRebindSession(async () => {\n\t\t\tthis.bindCurrentSessionEvents();\n\t\t\tif (this.headlessExtensionOptions) {\n\t\t\t\tawait this.bindCurrentSessionExtensions();\n\t\t\t}\n\t\t\tconst state = createAgentConnectionState(this.runtimeHost);\n\t\t\tconst messages = [...this.runtimeHost.session.messages];\n\t\t\tawait this.emit({\n\t\t\t\ttype: \"session_replaced\",\n\t\t\t\tstate: await state,\n\t\t\t\tmessages,\n\t\t\t});\n\t\t});\n\t}\n\n\tasync bindHeadlessExtensions(options: InProcessHeadlessExtensionOptions = {}): Promise<void> {\n\t\tthis.headlessExtensionOptions = options;\n\t\tawait this.bindCurrentSessionExtensions();\n\t}\n\n\tsupportsAcpMcpServers(): boolean {\n\t\treturn true;\n\t}\n\n\tasync replaceAcpMcpServers(servers: readonly AcpMcpServerConfig[], ownerId: string): Promise<void> {\n\t\tthis.runtimeHost.session.replaceAcpMcpServers(servers, ownerId);\n\t}\n\n\tasync releaseAcpMcpServers(ownerId: string, serverNames: readonly string[]): Promise<void> {\n\t\tawait this.runtimeHost.session.releaseAcpMcpServers(ownerId, serverNames);\n\t}\n\n\tsubscribe(listener: AgentConnectionEventListener): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\tonBeforeSessionInvalidate(listener: AgentConnectionBeforeSessionInvalidateListener): () => void {\n\t\tthis.beforeSessionInvalidateListeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.beforeSessionInvalidateListeners.delete(listener);\n\t\t};\n\t}\n\n\tasync getState(): Promise<AgentConnectionState> {\n\t\treturn createAgentConnectionState(this.runtimeHost);\n\t}\n\n\tasync getInitialSnapshot(): Promise<AgentConnectionSnapshot> {\n\t\treturn createAgentConnectionSnapshot(this.runtimeHost);\n\t}\n\n\tasync getRlmChildSnapshots(): Promise<AgentConnectionRlmChildAgentSnapshot[]> {\n\t\treturn this.session.getRlmChildSnapshots();\n\t}\n\n\tasync getMessages(): Promise<AgentMessage[]> {\n\t\treturn this.session.state.messages;\n\t}\n\n\tasync getSessionHeader(): Promise<AgentConnectionSessionHeader | undefined> {\n\t\treturn this.session.sessionManager.getHeader() ?? undefined;\n\t}\n\n\tasync getCommands(): Promise<AgentConnectionSlashCommand[]> {\n\t\treturn createAgentConnectionCommands(this.session);\n\t}\n\n\tasync getResourceSnapshot(): Promise<AgentConnectionResourceSnapshot> {\n\t\treturn createAgentConnectionResourceSnapshot(this.session);\n\t}\n\n\tasync getAvailableModels(): Promise<AgentConnectionModel[]> {\n\t\treturn this.session.modelRegistry.refreshAvailableModels();\n\t}\n\n\tasync getModelCatalog(): Promise<AgentConnectionModelCatalog> {\n\t\treturn this.session.modelRegistry.refreshModelCatalog();\n\t}\n\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\treturn this.session.getSessionStats();\n\t}\n\n\tasync getContextTree(): Promise<ContextTreeNode> {\n\t\treturn this.session.getContextTree();\n\t}\n\n\tasync getSessionContext(): Promise<AgentConnectionSessionContext> {\n\t\treturn this.session.buildSessionContext();\n\t}\n\n\tasync getSessionTree(): Promise<{ tree: AgentConnectionSessionTreeNode[]; leafId: string | null }> {\n\t\treturn readSessionTree(this.session.sessionManager);\n\t}\n\n\tasync listSavedSessions(\n\t\tscope: AgentConnectionSavedSessionScope,\n\t\tcallbacks?: AgentConnectionSessionListCallbacks,\n\t): Promise<AgentConnectionSavedSessionInfo[]> {\n\t\t// In-memory managers hold \"\" for \"no explicit session dir\"; pass undefined so\n\t\t// list()/listAll() fall back to the default directories instead of scanning \"\".\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir() || undefined;\n\t\tif (scope === \"current\") {\n\t\t\treturn SessionManager.list(this.session.sessionManager.getCwd(), sessionDir, callbacks);\n\t\t}\n\t\treturn SessionManager.listAll(callbacks, sessionDir);\n\t}\n\n\tasync getQueue(): Promise<AgentConnectionQueueState> {\n\t\treturn {\n\t\t\tsteering: [...this.session.getSteeringMessagePreviews()],\n\t\t\tfollowUp: [...this.session.getFollowUpMessagePreviews()],\n\t\t};\n\t}\n\n\tasync mutateQueuedMessage(\n\t\tlane: AgentConnectionQueuedMessageLane,\n\t\tindex: number,\n\t\texpectedText: string,\n\t\tmutation: AgentConnectionQueuedMessageMutation,\n\t): Promise<AgentConnectionQueuedMessageMutationStatus> {\n\t\treturn this.session.mutateQueuedMessage(lane, index, expectedText, mutation);\n\t}\n\n\tasync clearQueue(): Promise<AgentConnectionQueueState> {\n\t\treturn this.session.clearQueue();\n\t}\n\n\tasync abortAndClearQueue(): Promise<AgentConnectionQueueState> {\n\t\tconst queue = this.session.clearQueue();\n\t\tthis.session.requestAbort();\n\t\treturn queue;\n\t}\n\n\tasync acquireSessionInputPause(leaseKey: string): Promise<AgentConnectionSessionInputPause> {\n\t\tconst existing = this.sessionInputPauses.get(leaseKey);\n\t\tif (existing) return existing;\n\t\tconst pause = this.session.acquireSessionInputPause();\n\t\tlet released = false;\n\t\tconst lease: AgentConnectionSessionInputPause = {\n\t\t\trelease: async () => {\n\t\t\t\tif (released) return;\n\t\t\t\tpause.release();\n\t\t\t\treleased = true;\n\t\t\t\tif (this.sessionInputPauses.get(leaseKey) === lease) this.sessionInputPauses.delete(leaseKey);\n\t\t\t},\n\t\t};\n\t\tthis.sessionInputPauses.set(leaseKey, lease);\n\t\treturn lease;\n\t}\n\n\tasync listCronJobs(_options: { includeInactive?: boolean } = {}): Promise<AgentCronJob[]> {\n\t\treturn [];\n\t}\n\n\tasync listHeartbeats(): Promise<AgentConnectionHeartbeat[]> {\n\t\treturn [];\n\t}\n\n\tasync manageHeartbeat(\n\t\t_activeSessionId: string,\n\t\t_jobId: string,\n\t\t_action: AgentHeartbeatManagementAction,\n\t): Promise<AgentCronJob> {\n\t\tthrow new Error(\"Heartbeats require daemon mode\");\n\t}\n\n\tasync addCronJob(_schedule: string, _prompt: string): Promise<AgentCronJob> {\n\t\tthrow new Error(\"Cron jobs require daemon mode\");\n\t}\n\n\tasync cancelCronJob(_jobId: string): Promise<AgentCronJob> {\n\t\tthrow new Error(\"Cron jobs require daemon mode\");\n\t}\n\n\tasync getHeartbeat(): Promise<AgentCronJob | undefined> {\n\t\treturn undefined;\n\t}\n\n\tasync setHeartbeat(\n\t\t_schedule: string,\n\t\t_instruction: string,\n\t\t_deliveryMode?: AgentHeartbeatDeliveryMode,\n\t): Promise<AgentCronJob> {\n\t\tthrow new Error(\"Heartbeats require daemon mode\");\n\t}\n\n\tasync updateHeartbeat(_action: AgentHeartbeatUpdateAction): Promise<AgentCronJob | undefined> {\n\t\tthrow new Error(\"Heartbeats require daemon mode\");\n\t}\n\n\tasync sendAgentMessage(_targetActiveSessionId: string, _message: string): Promise<AgentSessionMessageReceipt> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync getAgentMessageStatus(): Promise<AgentSessionMessageSafetyStatus> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync pauseAgentMessages(): Promise<AgentSessionMessageSafetyStatus> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync resumeAgentMessages(): Promise<AgentSessionMessageSafetyStatus> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync clearAgentMessages(): Promise<number> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync getUserMessagesForForking(): Promise<AgentConnectionUserMessage[]> {\n\t\treturn readUserMessagesForForking(this.session.sessionManager);\n\t}\n\n\tasync getLastAssistantText(): Promise<string | undefined> {\n\t\treturn this.session.getLastAssistantText();\n\t}\n\n\tasync getSystemPrompt(): Promise<string> {\n\t\treturn this.session.systemPrompt;\n\t}\n\n\tasync getToolDefinition(name: string): Promise<AgentConnectionToolDefinition | undefined> {\n\t\treturn createAgentConnectionToolDefinition(this.session.getToolDefinition(name));\n\t}\n\n\tasync setSessionEntryLabel(entryId: string, label: string | undefined): Promise<void> {\n\t\tawait this.session.sessionManager.appendLabelChange(entryId, label);\n\t}\n\n\tasync respondToExtensionUiRequest(_requestId: string, _response: AgentConnectionExtensionUiResponse): Promise<void> {\n\t\t// In-process extension UI requests are handled directly by InteractiveMode.\n\t}\n\n\tasync prompt(message: string, options?: AgentConnectionPromptOptions): Promise<void> {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tlet settled = false;\n\t\t\tlet accepted = false;\n\t\t\tconst resolveOnce = () => {\n\t\t\t\tif (!settled) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst rejectOnce = (error: unknown) => {\n\t\t\t\tif (!settled) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst prompt = this.session.prompt(message, {\n\t\t\t\t...(options?.images ? { images: options.images } : {}),\n\t\t\t\t...(options?.streamingBehavior ? { streamingBehavior: options.streamingBehavior, resumeIfIdle: true } : {}),\n\t\t\t\t...(options?.queueIfBusy !== undefined ? { queueIfBusy: options.queueIfBusy } : {}),\n\t\t\t\t...(options?.source ? { source: options.source } : {}),\n\t\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t\t\tpreflightResult: (success) => {\n\t\t\t\t\tif (success) {\n\t\t\t\t\t\taccepted = true;\n\t\t\t\t\t\tresolveOnce();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\tvoid prompt.then(\n\t\t\t\t() => {\n\t\t\t\t\tif (accepted) resolveOnce();\n\t\t\t\t\telse rejectOnce(new Error(\"Prompt was not accepted by the session.\"));\n\t\t\t\t},\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tif (!accepted) rejectOnce(error);\n\t\t\t\t\t// Output-limit refusals already have their own refusal-only agent_end.\n\t\t\t\t\telse if (!(error instanceof AgentOutputLimitError)) {\n\t\t\t\t\t\tvoid this.emit({\n\t\t\t\t\t\t\ttype: \"extension_error\",\n\t\t\t\t\t\t\textensionPath: \"<session-input>\",\n\t\t\t\t\t\t\tevent: \"prompt_completion\",\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync promptAndWait(message: string, options?: AgentConnectionPromptOptions): Promise<void> {\n\t\tawait this.session.promptAndWait(message, {\n\t\t\t...(options?.images ? { images: options.images } : {}),\n\t\t\t...(options?.streamingBehavior ? { streamingBehavior: options.streamingBehavior, resumeIfIdle: true } : {}),\n\t\t\t...(options?.queueIfBusy !== undefined ? { queueIfBusy: options.queueIfBusy } : {}),\n\t\t\t...(options?.source ? { source: options.source } : {}),\n\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t});\n\t}\n\n\tasync startSideQuestion(\n\t\tid: string,\n\t\tquestion: string,\n\t\tpreviousTurns?: AgentConnectionSideQuestionTurn[],\n\t): Promise<void> {\n\t\tif (this.sideQuestionRuns.has(id)) {\n\t\t\tthrow new Error(`Side question already exists: ${id}`);\n\t\t}\n\t\tconst run = startSideQuestion(\n\t\t\tthis.session.agent,\n\t\t\tid,\n\t\t\tquestion,\n\t\t\t(event) => this.emit({ type: \"side_question_event\", event }),\n\t\t\tpreviousTurns,\n\t\t);\n\t\tthis.sideQuestionRuns.set(id, run);\n\t\tconst removeRun = () => {\n\t\t\tthis.sideQuestionRuns.delete(id);\n\t\t};\n\t\tvoid run.done.then(removeRun, removeRun);\n\t}\n\n\tasync abortSideQuestion(id: string): Promise<boolean> {\n\t\tconst run = this.sideQuestionRuns.get(id);\n\t\tif (!run) {\n\t\t\treturn false;\n\t\t}\n\t\trun.abort();\n\t\treturn true;\n\t}\n\n\tasync steer(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.session.steer(message, images, { resumeIfIdle: true });\n\t}\n\n\tasync followUp(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.session.followUp(message, images, { resumeIfIdle: true });\n\t}\n\n\tasync abort(): Promise<void> {\n\t\tthis.session.requestAbort();\n\t}\n\n\tasync cancelRlmChild(childId: string): Promise<boolean> {\n\t\treturn this.session.cancelRlmChildRun(childId);\n\t}\n\n\tasync waitForIdle(): Promise<void> {\n\t\tawait this.session.waitForIdle();\n\t}\n\n\tasync waitForHeadlessCompletion(options?: AgentConnectionHeadlessCompletionOptions): Promise<AgentAutonomousStatus> {\n\t\treturn waitForHeadlessCompletion(this.session, options);\n\t}\n\n\tasync executeBash(command: string, options?: AgentConnectionExecuteBashOptions): Promise<void> {\n\t\tawait this.session.runUserBash(command, options);\n\t}\n\n\tasync executeBashAndWait(command: string): Promise<BashResult> {\n\t\treturn this.session.executeBash(command);\n\t}\n\n\tasync abortBash(): Promise<void> {\n\t\tthis.session.abortBash();\n\t}\n\n\tasync setModel(provider: string, modelId: string): Promise<AgentConnectionModel> {\n\t\tconst availableModels = await this.session.modelRegistry.refreshAvailableModels();\n\t\tconst model = availableModels.find((candidate) => {\n\t\t\treturn candidate.provider === provider && candidate.id === modelId;\n\t\t});\n\t\tif (!model) {\n\t\t\tthrow new Error(`Model not found: ${provider}/${modelId}`);\n\t\t}\n\t\tawait this.session.setModel(model);\n\t\treturn model;\n\t}\n\n\tasync cycleModel(\n\t\tdirection: \"forward\" | \"backward\" = \"forward\",\n\t): Promise<AgentConnectionModelCycleResult | undefined> {\n\t\treturn this.session.cycleModel(direction);\n\t}\n\n\tasync setScopedModels(scopedModels: AgentConnectionScopedModel[]): Promise<void> {\n\t\tthis.session.setScopedModels(scopedModels);\n\t}\n\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tawait this.session.setThinkingLevel(level);\n\t}\n\n\tasync setServiceTier(serviceTier: ServiceTier): Promise<void> {\n\t\tawait this.session.setServiceTier(serviceTier);\n\t}\n\n\tasync cycleThinkingLevel(): Promise<ThinkingLevel | undefined> {\n\t\treturn this.session.cycleThinkingLevel();\n\t}\n\n\tasync setTransport(transport: Transport): Promise<void> {\n\t\tthis.session.settingsManager.setTransport(transport);\n\t\tthis.session.agent.transport = transport;\n\t}\n\n\tasync setSteeringMode(mode: AgentConnectionQueueMode): Promise<void> {\n\t\tthis.session.setSteeringMode(mode);\n\t}\n\n\tasync setFollowUpMode(mode: AgentConnectionQueueMode): Promise<void> {\n\t\tthis.session.setFollowUpMode(mode);\n\t}\n\n\tasync setAutoCompactionEnabled(enabled: boolean): Promise<void> {\n\t\tthis.session.setAutoCompactionEnabled(enabled);\n\t}\n\n\tasync setAutoRetryEnabled(enabled: boolean): Promise<void> {\n\t\tthis.session.setAutoRetryEnabled(enabled);\n\t}\n\n\tasync compact(customInstructions?: string): Promise<CompactionResult> {\n\t\treturn this.session.compact(customInstructions);\n\t}\n\n\tasync refine(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean } = {},\n\t): Promise<RefinementResult> {\n\t\treturn this.session.refine(options);\n\t}\n\n\tasync abortCompaction(): Promise<void> {\n\t\tthis.session.abortCompaction();\n\t}\n\n\tasync abortBranchSummary(): Promise<void> {\n\t\tthis.session.abortBranchSummary();\n\t}\n\n\tasync abortRetry(): Promise<void> {\n\t\tthis.session.abortRetry();\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tawait this.session.reload();\n\t}\n\n\tasync newSession(options?: AgentConnectionNewSessionOptions): Promise<{ cancelled: boolean }> {\n\t\treturn this.runtimeHost.newSession(options);\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: AgentConnectionSwitchSessionOptions,\n\t): Promise<{ cancelled: boolean }> {\n\t\treturn this.runtimeHost.switchSession(sessionPath, options);\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: AgentConnectionForkOptions,\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\treturn this.runtimeHost.fork(entryId, options);\n\t}\n\n\tasync navigateTree(\n\t\ttargetId: string,\n\t\toptions?: AgentConnectionNavigateTreeOptions,\n\t): Promise<AgentConnectionNavigateTreeResult> {\n\t\treturn this.session.navigateTree(targetId, options);\n\t}\n\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\treturn this.runtimeHost.importFromJsonl(inputPath, cwdOverride);\n\t}\n\n\tasync exportToHtml(outputPath?: string): Promise<string> {\n\t\treturn this.session.exportToHtml(outputPath);\n\t}\n\n\tasync exportToJsonl(outputPath?: string): Promise<string> {\n\t\treturn this.session.exportToJsonl(outputPath);\n\t}\n\n\tasync setSessionName(name: string): Promise<void> {\n\t\tconst trimmedName = name.trim();\n\t\tif (!trimmedName) {\n\t\t\tthrow new Error(\"Session name cannot be empty\");\n\t\t}\n\t\tawait this.session.setSessionName(trimmedName);\n\t}\n\n\tasync getRlmMaxSubagentsStatus() {\n\t\treturn this.session.getRlmMaxSubagentsStatus();\n\t}\n\n\tasync setRlmMaxSubagents(maxSubagents: number) {\n\t\treturn this.session.setRlmMaxSubagents(maxSubagents);\n\t}\n\n\tasync getRlmMaxDepthStatus() {\n\t\treturn this.session.getRlmMaxDepthStatus();\n\t}\n\n\tasync setRlmMaxDepth(maxDepth: number, options?: { global?: boolean }) {\n\t\treturn this.session.setRlmMaxDepth(maxDepth, options);\n\t}\n\n\tasync renameSavedSession(sessionPath: string, name: string): Promise<void> {\n\t\tconst trimmedName = name.trim();\n\t\tif (!trimmedName) {\n\t\t\tthrow new Error(\"Session name cannot be empty\");\n\t\t}\n\t\tconst currentSessionFile = this.session.sessionFile;\n\t\tif (currentSessionFile && resolve(currentSessionFile) === resolve(sessionPath)) {\n\t\t\tawait this.session.setSessionName(trimmedName);\n\t\t\treturn;\n\t\t}\n\t\tconst manager = await SessionManager.open(sessionPath);\n\t\ttry {\n\t\t\tawait manager.appendSessionInfo(trimmedName);\n\t\t} finally {\n\t\t\tawait manager.close();\n\t\t}\n\t}\n\n\tasync deleteSavedSession(sessionPath: string): Promise<DeleteSessionFileResult> {\n\t\treturn deleteSessionFile(sessionPath);\n\t}\n\n\tasync watchSession(childId: string): Promise<AgentConnectionSessionWatcher | undefined> {\n\t\tconst child = this.session.getRlmChildSession(childId);\n\t\tif (!child) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst unsubscribes = new Set<() => void>();\n\t\treturn {\n\t\t\tgetMessages: async () => child.messages,\n\t\t\tgetCommands: async () => createAgentConnectionCommands(child),\n\t\t\tsubscribe: (listener) => {\n\t\t\t\tconst unsubscribe = child.subscribe((event) => void listener({ type: \"session_event\", event }));\n\t\t\t\tunsubscribes.add(unsubscribe);\n\t\t\t\treturn () => {\n\t\t\t\t\tunsubscribes.delete(unsubscribe);\n\t\t\t\t\tunsubscribe();\n\t\t\t\t};\n\t\t\t},\n\t\t\tgetToolDefinition: async (name) => createAgentConnectionToolDefinition(child.getToolDefinition(name)),\n\t\t\tclose: async () => {\n\t\t\t\tfor (const unsubscribe of unsubscribes) {\n\t\t\t\t\tunsubscribe();\n\t\t\t\t}\n\t\t\t\tunsubscribes.clear();\n\t\t\t},\n\t\t};\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tthis.abortAllSideQuestions();\n\t\tawait Promise.allSettled([...this.sessionInputPauses.values()].map((pause) => pause.release()));\n\t\tthis.sessionInputPauses.clear();\n\t\tthis.unsubscribeSessionEvents?.();\n\t\tthis.unsubscribeSessionEvents = undefined;\n\t\tif (typeof this.runtimeHost.setBeforeSessionInvalidate === \"function\") {\n\t\t\tthis.runtimeHost.setBeforeSessionInvalidate(undefined);\n\t\t}\n\t\tthis.runtimeHost.setRebindSession(undefined);\n\t\tawait this.runtimeHost.dispose();\n\t}\n\n\tprivate get session() {\n\t\treturn this.runtimeHost.session;\n\t}\n\n\tprivate bindCurrentSessionEvents(): void {\n\t\tthis.unsubscribeSessionEvents?.();\n\t\tthis.unsubscribeSessionEvents = this.session.subscribe((event) => {\n\t\t\tvoid this.emit({ type: \"session_event\", event });\n\t\t});\n\t}\n\n\tprivate async bindCurrentSessionExtensions(): Promise<void> {\n\t\tconst session = this.session;\n\t\tawait session.bindExtensions({\n\t\t\tuiContext: this.headlessExtensionOptions?.uiContext,\n\t\t\tcommandContextActions: {\n\t\t\t\twaitForIdle: () => session.waitForIdle(),\n\t\t\t\tnewSession: (options) => this.runtimeHost.newSession(options),\n\t\t\t\tfork: async (entryId, options) => {\n\t\t\t\t\tconst result = await this.runtimeHost.fork(entryId, options);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tnavigateTree: async (targetId, options) => {\n\t\t\t\t\tconst result = await session.navigateTree(targetId, options);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tswitchSession: (sessionPath, options) => this.runtimeHost.switchSession(sessionPath, options),\n\t\t\t\treload: () => session.reload(),\n\t\t\t},\n\t\t\tshutdownHandler: this.headlessExtensionOptions?.shutdownHandler,\n\t\t\tonError: (error) => {\n\t\t\t\tvoid this.emit({\n\t\t\t\t\ttype: \"extension_error\",\n\t\t\t\t\textensionPath: error.extensionPath,\n\t\t\t\t\tevent: error.event,\n\t\t\t\t\terror: error.error,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate abortAllSideQuestions(): void {\n\t\tfor (const run of this.sideQuestionRuns.values()) {\n\t\t\trun.abort();\n\t\t}\n\t\tthis.sideQuestionRuns.clear();\n\t}\n\n\tprivate async emit(event: AgentConnectionEvent): Promise<void> {\n\t\tfor (const listener of [...this.listeners]) {\n\t\t\tawait listener(event);\n\t\t}\n\t}\n}\n"]}
1
+ {"version":3,"file":"in-process-agent-connection.d.ts","sourceRoot":"","sources":["../../../src/modes/agent-connection/in-process-agent-connection.ts"],"names":[],"mappings":"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","sourcesContent":["import { resolve } from \"node:path\";\nimport { type AgentMessage, AgentOutputLimitError, type ThinkingLevel } from \"@ponythewhite/base-context-agent\";\nimport type { ImageContent, ServiceTier, Transport } from \"@ponythewhite/base-context-ai\";\nimport type { AgentSessionMessageReceipt, AgentSessionMessageSafetyStatus } from \"../../core/agent-messages.js\";\nimport type { AgentSessionRuntime } from \"../../core/agent-session-runtime.js\";\nimport type { AgentAutonomousStatus } from \"../../core/autonomous.js\";\nimport type { BashResult } from \"../../core/bash-executor.js\";\nimport type { CompactionResult } from \"../../core/compaction/index.js\";\nimport type { ContextTreeNode } from \"../../core/context-tree.js\";\nimport type {\n\tAgentCronJob,\n\tAgentHeartbeatDeliveryMode,\n\tAgentHeartbeatManagementAction,\n\tAgentHeartbeatUpdateAction,\n} from \"../../core/cron-jobs.js\";\nimport type { ExtensionUIContext } from \"../../core/extensions/types.js\";\nimport type { AcpMcpServerConfig } from \"../../core/mcp/acp-mcp-types.js\";\nimport type { RefinementResult } from \"../../core/refinement/index.js\";\nimport { type DeleteSessionFileResult, deleteSessionFile } from \"../../core/session-file-actions.js\";\nimport { readVisibleUserMessagesForForking } from \"../../core/session-fork-messages.js\";\nimport { SessionManager } from \"../../core/session-manager.js\";\nimport type { SessionStats } from \"../../core/session-stats.js\";\nimport { readVisibleSessionTree } from \"../../core/session-tree.js\";\nimport { type SideQuestionRun, startSideQuestion } from \"../../core/side-question.js\";\nimport { waitForHeadlessCompletion } from \"../headless-completion.js\";\nimport {\n\tcreateAgentConnectionCommands,\n\tcreateAgentConnectionResourceSnapshot,\n\tcreateAgentConnectionSnapshot,\n\tcreateAgentConnectionState,\n} from \"./snapshot.js\";\nimport { createAgentConnectionToolDefinition } from \"./tool-definition.js\";\nimport type {\n\tAgentConnection,\n\tAgentConnectionBeforeSessionInvalidateListener,\n\tAgentConnectionEvent,\n\tAgentConnectionEventListener,\n\tAgentConnectionExecuteBashOptions,\n\tAgentConnectionExtensionUiResponse,\n\tAgentConnectionForkOptions,\n\tAgentConnectionHeadlessCompletionOptions,\n\tAgentConnectionHeartbeat,\n\tAgentConnectionModel,\n\tAgentConnectionModelCatalog,\n\tAgentConnectionModelCycleResult,\n\tAgentConnectionNavigateTreeOptions,\n\tAgentConnectionNavigateTreeResult,\n\tAgentConnectionNewSessionOptions,\n\tAgentConnectionPromptOptions,\n\tAgentConnectionQueuedMessageLane,\n\tAgentConnectionQueuedMessageMutation,\n\tAgentConnectionQueuedMessageMutationStatus,\n\tAgentConnectionQueueMode,\n\tAgentConnectionQueueState,\n\tAgentConnectionResourceSnapshot,\n\tAgentConnectionRlmChildAgentSnapshot,\n\tAgentConnectionSavedSessionInfo,\n\tAgentConnectionSavedSessionScope,\n\tAgentConnectionScopedModel,\n\tAgentConnectionSessionContext,\n\tAgentConnectionSessionHeader,\n\tAgentConnectionSessionInputPause,\n\tAgentConnectionSessionListCallbacks,\n\tAgentConnectionSessionTreeNode,\n\tAgentConnectionSessionWatcher,\n\tAgentConnectionSideQuestionTurn,\n\tAgentConnectionSlashCommand,\n\tAgentConnectionSnapshot,\n\tAgentConnectionState,\n\tAgentConnectionSwitchSessionOptions,\n\tAgentConnectionToolDefinition,\n\tAgentConnectionUserMessage,\n} from \"./types.js\";\n\nexport interface InProcessHeadlessExtensionOptions {\n\tuiContext?: ExtensionUIContext;\n\tshutdownHandler?: () => void;\n}\n\nexport class InProcessAgentConnection implements AgentConnection {\n\tprivate readonly listeners = new Set<AgentConnectionEventListener>();\n\tprivate readonly beforeSessionInvalidateListeners = new Set<AgentConnectionBeforeSessionInvalidateListener>();\n\tprivate readonly sideQuestionRuns = new Map<string, SideQuestionRun>();\n\tprivate readonly sessionInputPauses = new Map<string, AgentConnectionSessionInputPause>();\n\tprivate headlessExtensionOptions: InProcessHeadlessExtensionOptions | undefined;\n\tprivate unsubscribeSessionEvents: (() => void) | undefined;\n\n\tconstructor(private readonly runtimeHost: AgentSessionRuntime) {\n\t\tthis.bindCurrentSessionEvents();\n\t\tif (typeof this.runtimeHost.setBeforeSessionInvalidate === \"function\") {\n\t\t\tthis.runtimeHost.setBeforeSessionInvalidate(() => {\n\t\t\t\tthis.abortAllSideQuestions();\n\t\t\t\tfor (const listener of [...this.beforeSessionInvalidateListeners]) {\n\t\t\t\t\tlistener();\n\t\t\t\t}\n\t\t\t});\n\t\t}\n\t\tthis.runtimeHost.setRebindSession(async () => {\n\t\t\tthis.bindCurrentSessionEvents();\n\t\t\tif (this.headlessExtensionOptions) {\n\t\t\t\tawait this.bindCurrentSessionExtensions();\n\t\t\t}\n\t\t\tconst state = createAgentConnectionState(this.runtimeHost);\n\t\t\tconst messages = [...this.runtimeHost.session.messages];\n\t\t\tawait this.emit({\n\t\t\t\ttype: \"session_replaced\",\n\t\t\t\tstate: await state,\n\t\t\t\tmessages,\n\t\t\t});\n\t\t});\n\t}\n\n\tasync bindHeadlessExtensions(options: InProcessHeadlessExtensionOptions = {}): Promise<void> {\n\t\tthis.headlessExtensionOptions = options;\n\t\tawait this.bindCurrentSessionExtensions();\n\t}\n\n\tsupportsAcpMcpServers(): boolean {\n\t\treturn true;\n\t}\n\n\tasync replaceAcpMcpServers(servers: readonly AcpMcpServerConfig[], ownerId: string): Promise<void> {\n\t\tthis.runtimeHost.session.replaceAcpMcpServers(servers, ownerId);\n\t}\n\n\tasync releaseAcpMcpServers(ownerId: string, serverNames: readonly string[]): Promise<void> {\n\t\tawait this.runtimeHost.session.releaseAcpMcpServers(ownerId, serverNames);\n\t}\n\n\tsubscribe(listener: AgentConnectionEventListener): () => void {\n\t\tthis.listeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.listeners.delete(listener);\n\t\t};\n\t}\n\n\tonBeforeSessionInvalidate(listener: AgentConnectionBeforeSessionInvalidateListener): () => void {\n\t\tthis.beforeSessionInvalidateListeners.add(listener);\n\t\treturn () => {\n\t\t\tthis.beforeSessionInvalidateListeners.delete(listener);\n\t\t};\n\t}\n\n\tasync getState(): Promise<AgentConnectionState> {\n\t\treturn createAgentConnectionState(this.runtimeHost);\n\t}\n\n\tasync getInitialSnapshot(): Promise<AgentConnectionSnapshot> {\n\t\treturn createAgentConnectionSnapshot(this.runtimeHost);\n\t}\n\n\tasync getRlmChildSnapshots(): Promise<AgentConnectionRlmChildAgentSnapshot[]> {\n\t\treturn this.session.getRlmChildSnapshots();\n\t}\n\n\tasync getMessages(): Promise<AgentMessage[]> {\n\t\treturn this.session.state.messages;\n\t}\n\n\tasync getSessionHeader(): Promise<AgentConnectionSessionHeader | undefined> {\n\t\treturn this.session.sessionManager.getHeader() ?? undefined;\n\t}\n\n\tasync getCommands(): Promise<AgentConnectionSlashCommand[]> {\n\t\treturn createAgentConnectionCommands(this.session);\n\t}\n\n\tasync getResourceSnapshot(): Promise<AgentConnectionResourceSnapshot> {\n\t\treturn createAgentConnectionResourceSnapshot(this.session);\n\t}\n\n\tasync getAvailableModels(): Promise<AgentConnectionModel[]> {\n\t\treturn this.session.modelRegistry.refreshAvailableModels();\n\t}\n\n\tasync getModelCatalog(): Promise<AgentConnectionModelCatalog> {\n\t\treturn this.session.modelRegistry.refreshModelCatalog();\n\t}\n\n\tasync getSessionStats(): Promise<SessionStats> {\n\t\treturn this.session.getSessionStats();\n\t}\n\n\tasync getContextTree(): Promise<ContextTreeNode> {\n\t\treturn this.session.getContextTree();\n\t}\n\n\tasync getSessionContext(): Promise<AgentConnectionSessionContext> {\n\t\treturn this.session.buildSessionContext();\n\t}\n\n\tasync getSessionTree(): Promise<{ tree: AgentConnectionSessionTreeNode[]; leafId: string | null }> {\n\t\treturn readVisibleSessionTree(this.session.sessionManager);\n\t}\n\n\tasync listSavedSessions(\n\t\tscope: AgentConnectionSavedSessionScope,\n\t\tcallbacks?: AgentConnectionSessionListCallbacks,\n\t): Promise<AgentConnectionSavedSessionInfo[]> {\n\t\t// In-memory managers hold \"\" for \"no explicit session dir\"; pass undefined so\n\t\t// list()/listAll() fall back to the default directories instead of scanning \"\".\n\t\tconst sessionDir = this.session.sessionManager.getSessionDir() || undefined;\n\t\tif (scope === \"current\") {\n\t\t\treturn SessionManager.list(this.session.sessionManager.getCwd(), sessionDir, callbacks);\n\t\t}\n\t\treturn SessionManager.listAll(callbacks, sessionDir);\n\t}\n\n\tasync getQueue(): Promise<AgentConnectionQueueState> {\n\t\treturn {\n\t\t\tsteering: [...this.session.getSteeringMessagePreviews()],\n\t\t\tfollowUp: [...this.session.getFollowUpMessagePreviews()],\n\t\t};\n\t}\n\n\tasync mutateQueuedMessage(\n\t\tlane: AgentConnectionQueuedMessageLane,\n\t\tindex: number,\n\t\texpectedText: string,\n\t\tmutation: AgentConnectionQueuedMessageMutation,\n\t): Promise<AgentConnectionQueuedMessageMutationStatus> {\n\t\treturn this.session.mutateQueuedMessage(lane, index, expectedText, mutation);\n\t}\n\n\tasync clearQueue(): Promise<AgentConnectionQueueState> {\n\t\treturn this.session.clearQueue();\n\t}\n\n\tasync abortAndClearQueue(): Promise<AgentConnectionQueueState> {\n\t\tconst queue = this.session.clearQueue();\n\t\tthis.session.requestAbort();\n\t\treturn queue;\n\t}\n\n\tasync acquireSessionInputPause(leaseKey: string): Promise<AgentConnectionSessionInputPause> {\n\t\tconst existing = this.sessionInputPauses.get(leaseKey);\n\t\tif (existing) return existing;\n\t\tconst pause = this.session.acquireSessionInputPause();\n\t\tlet released = false;\n\t\tconst lease: AgentConnectionSessionInputPause = {\n\t\t\trelease: async () => {\n\t\t\t\tif (released) return;\n\t\t\t\tpause.release();\n\t\t\t\treleased = true;\n\t\t\t\tif (this.sessionInputPauses.get(leaseKey) === lease) this.sessionInputPauses.delete(leaseKey);\n\t\t\t},\n\t\t};\n\t\tthis.sessionInputPauses.set(leaseKey, lease);\n\t\treturn lease;\n\t}\n\n\tasync listCronJobs(_options: { includeInactive?: boolean } = {}): Promise<AgentCronJob[]> {\n\t\treturn [];\n\t}\n\n\tasync listHeartbeats(): Promise<AgentConnectionHeartbeat[]> {\n\t\treturn [];\n\t}\n\n\tasync manageHeartbeat(\n\t\t_activeSessionId: string,\n\t\t_jobId: string,\n\t\t_action: AgentHeartbeatManagementAction,\n\t): Promise<AgentCronJob> {\n\t\tthrow new Error(\"Heartbeats require daemon mode\");\n\t}\n\n\tasync addCronJob(_schedule: string, _prompt: string): Promise<AgentCronJob> {\n\t\tthrow new Error(\"Cron jobs require daemon mode\");\n\t}\n\n\tasync cancelCronJob(_jobId: string): Promise<AgentCronJob> {\n\t\tthrow new Error(\"Cron jobs require daemon mode\");\n\t}\n\n\tasync getHeartbeat(): Promise<AgentCronJob | undefined> {\n\t\treturn undefined;\n\t}\n\n\tasync setHeartbeat(\n\t\t_schedule: string,\n\t\t_instruction: string,\n\t\t_deliveryMode?: AgentHeartbeatDeliveryMode,\n\t): Promise<AgentCronJob> {\n\t\tthrow new Error(\"Heartbeats require daemon mode\");\n\t}\n\n\tasync updateHeartbeat(_action: AgentHeartbeatUpdateAction): Promise<AgentCronJob | undefined> {\n\t\tthrow new Error(\"Heartbeats require daemon mode\");\n\t}\n\n\tasync sendAgentMessage(_targetActiveSessionId: string, _message: string): Promise<AgentSessionMessageReceipt> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync getAgentMessageStatus(): Promise<AgentSessionMessageSafetyStatus> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync pauseAgentMessages(): Promise<AgentSessionMessageSafetyStatus> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync resumeAgentMessages(): Promise<AgentSessionMessageSafetyStatus> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync clearAgentMessages(): Promise<number> {\n\t\tthrow new Error(\"Agent messaging requires daemon mode\");\n\t}\n\n\tasync getUserMessagesForForking(): Promise<AgentConnectionUserMessage[]> {\n\t\treturn readVisibleUserMessagesForForking(this.session.sessionManager);\n\t}\n\n\tasync getLastAssistantText(): Promise<string | undefined> {\n\t\treturn this.session.getLastAssistantText();\n\t}\n\n\tasync getSystemPrompt(): Promise<string> {\n\t\treturn this.session.systemPrompt;\n\t}\n\n\tasync getToolDefinition(name: string): Promise<AgentConnectionToolDefinition | undefined> {\n\t\treturn createAgentConnectionToolDefinition(this.session.getToolDefinition(name));\n\t}\n\n\tasync setSessionEntryLabel(entryId: string, label: string | undefined): Promise<void> {\n\t\tawait this.session.sessionManager.appendLabelChange(entryId, label);\n\t}\n\n\tasync respondToExtensionUiRequest(_requestId: string, _response: AgentConnectionExtensionUiResponse): Promise<void> {\n\t\t// In-process extension UI requests are handled directly by InteractiveMode.\n\t}\n\n\tasync prompt(message: string, options?: AgentConnectionPromptOptions): Promise<void> {\n\t\tawait new Promise<void>((resolve, reject) => {\n\t\t\tlet settled = false;\n\t\t\tlet accepted = false;\n\t\t\tconst resolveOnce = () => {\n\t\t\t\tif (!settled) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\tresolve();\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst rejectOnce = (error: unknown) => {\n\t\t\t\tif (!settled) {\n\t\t\t\t\tsettled = true;\n\t\t\t\t\treject(error);\n\t\t\t\t}\n\t\t\t};\n\t\t\tconst prompt = this.session.prompt(message, {\n\t\t\t\t...(options?.images ? { images: options.images } : {}),\n\t\t\t\t...(options?.streamingBehavior ? { streamingBehavior: options.streamingBehavior, resumeIfIdle: true } : {}),\n\t\t\t\t...(options?.queueIfBusy !== undefined ? { queueIfBusy: options.queueIfBusy } : {}),\n\t\t\t\t...(options?.source ? { source: options.source } : {}),\n\t\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t\t\tpreflightResult: (success) => {\n\t\t\t\t\tif (success) {\n\t\t\t\t\t\taccepted = true;\n\t\t\t\t\t\tresolveOnce();\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t});\n\t\t\tvoid prompt.then(\n\t\t\t\t() => {\n\t\t\t\t\tif (accepted) resolveOnce();\n\t\t\t\t\telse rejectOnce(new Error(\"Prompt was not accepted by the session.\"));\n\t\t\t\t},\n\t\t\t\t(error: unknown) => {\n\t\t\t\t\tif (!accepted) rejectOnce(error);\n\t\t\t\t\t// Output-limit refusals already have their own refusal-only agent_end.\n\t\t\t\t\telse if (!(error instanceof AgentOutputLimitError)) {\n\t\t\t\t\t\tvoid this.emit({\n\t\t\t\t\t\t\ttype: \"extension_error\",\n\t\t\t\t\t\t\textensionPath: \"<session-input>\",\n\t\t\t\t\t\t\tevent: \"prompt_completion\",\n\t\t\t\t\t\t\terror: error instanceof Error ? error.message : String(error),\n\t\t\t\t\t\t});\n\t\t\t\t\t}\n\t\t\t\t},\n\t\t\t);\n\t\t});\n\t}\n\n\tasync promptAndWait(message: string, options?: AgentConnectionPromptOptions): Promise<void> {\n\t\tawait this.session.promptAndWait(message, {\n\t\t\t...(options?.images ? { images: options.images } : {}),\n\t\t\t...(options?.streamingBehavior ? { streamingBehavior: options.streamingBehavior, resumeIfIdle: true } : {}),\n\t\t\t...(options?.queueIfBusy !== undefined ? { queueIfBusy: options.queueIfBusy } : {}),\n\t\t\t...(options?.source ? { source: options.source } : {}),\n\t\t\t...(options?.signal ? { signal: options.signal } : {}),\n\t\t});\n\t}\n\n\tasync startSideQuestion(\n\t\tid: string,\n\t\tquestion: string,\n\t\tpreviousTurns?: AgentConnectionSideQuestionTurn[],\n\t): Promise<void> {\n\t\tif (this.sideQuestionRuns.has(id)) {\n\t\t\tthrow new Error(`Side question already exists: ${id}`);\n\t\t}\n\t\tconst run = startSideQuestion(\n\t\t\tthis.session.agent,\n\t\t\tid,\n\t\t\tquestion,\n\t\t\t(event) => this.emit({ type: \"side_question_event\", event }),\n\t\t\tpreviousTurns,\n\t\t);\n\t\tthis.sideQuestionRuns.set(id, run);\n\t\tconst removeRun = () => {\n\t\t\tthis.sideQuestionRuns.delete(id);\n\t\t};\n\t\tvoid run.done.then(removeRun, removeRun);\n\t}\n\n\tasync abortSideQuestion(id: string): Promise<boolean> {\n\t\tconst run = this.sideQuestionRuns.get(id);\n\t\tif (!run) {\n\t\t\treturn false;\n\t\t}\n\t\trun.abort();\n\t\treturn true;\n\t}\n\n\tasync steer(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.session.steer(message, images, { resumeIfIdle: true });\n\t}\n\n\tasync followUp(message: string, images?: ImageContent[]): Promise<void> {\n\t\tawait this.session.followUp(message, images, { resumeIfIdle: true });\n\t}\n\n\tasync abort(): Promise<void> {\n\t\tthis.session.requestAbort();\n\t}\n\n\tasync cancelRlmChild(childId: string): Promise<boolean> {\n\t\treturn this.session.cancelRlmChildRun(childId);\n\t}\n\n\tasync waitForIdle(): Promise<void> {\n\t\tawait this.session.waitForIdle();\n\t}\n\n\tasync waitForHeadlessCompletion(options?: AgentConnectionHeadlessCompletionOptions): Promise<AgentAutonomousStatus> {\n\t\treturn waitForHeadlessCompletion(this.session, options);\n\t}\n\n\tasync executeBash(command: string, options?: AgentConnectionExecuteBashOptions): Promise<void> {\n\t\tawait this.session.runUserBash(command, options);\n\t}\n\n\tasync executeBashAndWait(command: string): Promise<BashResult> {\n\t\treturn this.session.executeBash(command);\n\t}\n\n\tasync abortBash(): Promise<void> {\n\t\tthis.session.abortBash();\n\t}\n\n\tasync setModel(provider: string, modelId: string): Promise<AgentConnectionModel> {\n\t\tconst availableModels = await this.session.modelRegistry.refreshAvailableModels();\n\t\tconst model = availableModels.find((candidate) => {\n\t\t\treturn candidate.provider === provider && candidate.id === modelId;\n\t\t});\n\t\tif (!model) {\n\t\t\tthrow new Error(`Model not found: ${provider}/${modelId}`);\n\t\t}\n\t\tawait this.session.setModel(model);\n\t\treturn model;\n\t}\n\n\tasync cycleModel(\n\t\tdirection: \"forward\" | \"backward\" = \"forward\",\n\t): Promise<AgentConnectionModelCycleResult | undefined> {\n\t\treturn this.session.cycleModel(direction);\n\t}\n\n\tasync setScopedModels(scopedModels: AgentConnectionScopedModel[]): Promise<void> {\n\t\tthis.session.setScopedModels(scopedModels);\n\t}\n\n\tasync setThinkingLevel(level: ThinkingLevel): Promise<void> {\n\t\tawait this.session.setThinkingLevel(level);\n\t}\n\n\tasync setServiceTier(serviceTier: ServiceTier): Promise<void> {\n\t\tawait this.session.setServiceTier(serviceTier);\n\t}\n\n\tasync cycleThinkingLevel(): Promise<ThinkingLevel | undefined> {\n\t\treturn this.session.cycleThinkingLevel();\n\t}\n\n\tasync setTransport(transport: Transport): Promise<void> {\n\t\tthis.session.settingsManager.setTransport(transport);\n\t\tthis.session.agent.transport = transport;\n\t}\n\n\tasync setSteeringMode(mode: AgentConnectionQueueMode): Promise<void> {\n\t\tthis.session.setSteeringMode(mode);\n\t}\n\n\tasync setFollowUpMode(mode: AgentConnectionQueueMode): Promise<void> {\n\t\tthis.session.setFollowUpMode(mode);\n\t}\n\n\tasync setAutoCompactionEnabled(enabled: boolean): Promise<void> {\n\t\tthis.session.setAutoCompactionEnabled(enabled);\n\t}\n\n\tasync setAutoRetryEnabled(enabled: boolean): Promise<void> {\n\t\tthis.session.setAutoRetryEnabled(enabled);\n\t}\n\n\tasync compact(customInstructions?: string): Promise<CompactionResult> {\n\t\treturn this.session.compact(customInstructions);\n\t}\n\n\tasync refine(\n\t\toptions: { instructions?: string; rollbackId?: string; global?: boolean } = {},\n\t): Promise<RefinementResult> {\n\t\treturn this.session.refine(options);\n\t}\n\n\tasync abortCompaction(): Promise<void> {\n\t\tthis.session.abortCompaction();\n\t}\n\n\tasync abortBranchSummary(): Promise<void> {\n\t\tthis.session.abortBranchSummary();\n\t}\n\n\tasync abortRetry(): Promise<void> {\n\t\tthis.session.abortRetry();\n\t}\n\n\tasync reload(): Promise<void> {\n\t\tawait this.session.reload();\n\t}\n\n\tasync newSession(options?: AgentConnectionNewSessionOptions): Promise<{ cancelled: boolean }> {\n\t\treturn this.runtimeHost.newSession(options);\n\t}\n\n\tasync switchSession(\n\t\tsessionPath: string,\n\t\toptions?: AgentConnectionSwitchSessionOptions,\n\t): Promise<{ cancelled: boolean }> {\n\t\treturn this.runtimeHost.switchSession(sessionPath, options);\n\t}\n\n\tasync fork(\n\t\tentryId: string,\n\t\toptions?: AgentConnectionForkOptions,\n\t): Promise<{ cancelled: boolean; selectedText?: string }> {\n\t\treturn this.runtimeHost.fork(entryId, options);\n\t}\n\n\tasync navigateTree(\n\t\ttargetId: string,\n\t\toptions?: AgentConnectionNavigateTreeOptions,\n\t): Promise<AgentConnectionNavigateTreeResult> {\n\t\treturn this.session.navigateTree(targetId, options);\n\t}\n\n\tasync importFromJsonl(inputPath: string, cwdOverride?: string): Promise<{ cancelled: boolean }> {\n\t\treturn this.runtimeHost.importFromJsonl(inputPath, cwdOverride);\n\t}\n\n\tasync exportToHtml(outputPath?: string): Promise<string> {\n\t\treturn this.session.exportToHtml(outputPath);\n\t}\n\n\tasync exportToJsonl(outputPath?: string): Promise<string> {\n\t\treturn this.session.exportToJsonl(outputPath);\n\t}\n\n\tasync setSessionName(name: string): Promise<void> {\n\t\tconst trimmedName = name.trim();\n\t\tif (!trimmedName) {\n\t\t\tthrow new Error(\"Session name cannot be empty\");\n\t\t}\n\t\tawait this.session.setSessionName(trimmedName);\n\t}\n\n\tasync getRlmMaxSubagentsStatus() {\n\t\treturn this.session.getRlmMaxSubagentsStatus();\n\t}\n\n\tasync setRlmMaxSubagents(maxSubagents: number) {\n\t\treturn this.session.setRlmMaxSubagents(maxSubagents);\n\t}\n\n\tasync getRlmMaxDepthStatus() {\n\t\treturn this.session.getRlmMaxDepthStatus();\n\t}\n\n\tasync setRlmMaxDepth(maxDepth: number, options?: { global?: boolean }) {\n\t\treturn this.session.setRlmMaxDepth(maxDepth, options);\n\t}\n\n\tasync renameSavedSession(sessionPath: string, name: string): Promise<void> {\n\t\tconst trimmedName = name.trim();\n\t\tif (!trimmedName) {\n\t\t\tthrow new Error(\"Session name cannot be empty\");\n\t\t}\n\t\tconst currentSessionFile = this.session.sessionFile;\n\t\tif (currentSessionFile && resolve(currentSessionFile) === resolve(sessionPath)) {\n\t\t\tawait this.session.setSessionName(trimmedName);\n\t\t\treturn;\n\t\t}\n\t\tconst manager = await SessionManager.open(sessionPath);\n\t\ttry {\n\t\t\tawait manager.appendSessionInfo(trimmedName);\n\t\t} finally {\n\t\t\tawait manager.close();\n\t\t}\n\t}\n\n\tasync deleteSavedSession(sessionPath: string): Promise<DeleteSessionFileResult> {\n\t\treturn deleteSessionFile(sessionPath);\n\t}\n\n\tasync watchSession(childId: string): Promise<AgentConnectionSessionWatcher | undefined> {\n\t\tconst child = this.session.getRlmChildSession(childId);\n\t\tif (!child) {\n\t\t\treturn undefined;\n\t\t}\n\t\tconst unsubscribes = new Set<() => void>();\n\t\treturn {\n\t\t\tgetMessages: async () => child.messages,\n\t\t\tgetCommands: async () => createAgentConnectionCommands(child),\n\t\t\tsubscribe: (listener) => {\n\t\t\t\tconst unsubscribe = child.subscribe((event) => void listener({ type: \"session_event\", event }));\n\t\t\t\tunsubscribes.add(unsubscribe);\n\t\t\t\treturn () => {\n\t\t\t\t\tunsubscribes.delete(unsubscribe);\n\t\t\t\t\tunsubscribe();\n\t\t\t\t};\n\t\t\t},\n\t\t\tgetToolDefinition: async (name) => createAgentConnectionToolDefinition(child.getToolDefinition(name)),\n\t\t\tclose: async () => {\n\t\t\t\tfor (const unsubscribe of unsubscribes) {\n\t\t\t\t\tunsubscribe();\n\t\t\t\t}\n\t\t\t\tunsubscribes.clear();\n\t\t\t},\n\t\t};\n\t}\n\n\tasync dispose(): Promise<void> {\n\t\tthis.abortAllSideQuestions();\n\t\tawait Promise.allSettled([...this.sessionInputPauses.values()].map((pause) => pause.release()));\n\t\tthis.sessionInputPauses.clear();\n\t\tthis.unsubscribeSessionEvents?.();\n\t\tthis.unsubscribeSessionEvents = undefined;\n\t\tif (typeof this.runtimeHost.setBeforeSessionInvalidate === \"function\") {\n\t\t\tthis.runtimeHost.setBeforeSessionInvalidate(undefined);\n\t\t}\n\t\tthis.runtimeHost.setRebindSession(undefined);\n\t\tawait this.runtimeHost.dispose();\n\t}\n\n\tprivate get session() {\n\t\treturn this.runtimeHost.session;\n\t}\n\n\tprivate bindCurrentSessionEvents(): void {\n\t\tthis.unsubscribeSessionEvents?.();\n\t\tthis.unsubscribeSessionEvents = this.session.subscribe((event) => {\n\t\t\tvoid this.emit({ type: \"session_event\", event });\n\t\t});\n\t}\n\n\tprivate async bindCurrentSessionExtensions(): Promise<void> {\n\t\tconst session = this.session;\n\t\tawait session.bindExtensions({\n\t\t\tuiContext: this.headlessExtensionOptions?.uiContext,\n\t\t\tcommandContextActions: {\n\t\t\t\twaitForIdle: () => session.waitForIdle(),\n\t\t\t\tnewSession: (options) => this.runtimeHost.newSession(options),\n\t\t\t\tfork: async (entryId, options) => {\n\t\t\t\t\tconst result = await this.runtimeHost.fork(entryId, options);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tnavigateTree: async (targetId, options) => {\n\t\t\t\t\tconst result = await session.navigateTree(targetId, options);\n\t\t\t\t\treturn { cancelled: result.cancelled };\n\t\t\t\t},\n\t\t\t\tswitchSession: (sessionPath, options) => this.runtimeHost.switchSession(sessionPath, options),\n\t\t\t\treload: () => session.reload(),\n\t\t\t},\n\t\t\tshutdownHandler: this.headlessExtensionOptions?.shutdownHandler,\n\t\t\tonError: (error) => {\n\t\t\t\tvoid this.emit({\n\t\t\t\t\ttype: \"extension_error\",\n\t\t\t\t\textensionPath: error.extensionPath,\n\t\t\t\t\tevent: error.event,\n\t\t\t\t\terror: error.error,\n\t\t\t\t});\n\t\t\t},\n\t\t});\n\t}\n\n\tprivate abortAllSideQuestions(): void {\n\t\tfor (const run of this.sideQuestionRuns.values()) {\n\t\t\trun.abort();\n\t\t}\n\t\tthis.sideQuestionRuns.clear();\n\t}\n\n\tprivate async emit(event: AgentConnectionEvent): Promise<void> {\n\t\tfor (const listener of [...this.listeners]) {\n\t\t\tawait listener(event);\n\t\t}\n\t}\n}\n"]}
@@ -1,9 +1,9 @@
1
1
  import { resolve } from "node:path";
2
2
  import { AgentOutputLimitError } from "@ponythewhite/base-context-agent";
3
3
  import { deleteSessionFile } from "../../core/session-file-actions.js";
4
- import { readUserMessagesForForking } from "../../core/session-fork-messages.js";
4
+ import { readVisibleUserMessagesForForking } from "../../core/session-fork-messages.js";
5
5
  import { SessionManager } from "../../core/session-manager.js";
6
- import { readSessionTree } from "../../core/session-tree.js";
6
+ import { readVisibleSessionTree } from "../../core/session-tree.js";
7
7
  import { startSideQuestion } from "../../core/side-question.js";
8
8
  import { waitForHeadlessCompletion } from "../headless-completion.js";
9
9
  import { createAgentConnectionCommands, createAgentConnectionResourceSnapshot, createAgentConnectionSnapshot, createAgentConnectionState, } from "./snapshot.js";
@@ -103,7 +103,7 @@ export class InProcessAgentConnection {
103
103
  return this.session.buildSessionContext();
104
104
  }
105
105
  async getSessionTree() {
106
- return readSessionTree(this.session.sessionManager);
106
+ return readVisibleSessionTree(this.session.sessionManager);
107
107
  }
108
108
  async listSavedSessions(scope, callbacks) {
109
109
  // In-memory managers hold "" for "no explicit session dir"; pass undefined so
@@ -190,7 +190,7 @@ export class InProcessAgentConnection {
190
190
  throw new Error("Agent messaging requires daemon mode");
191
191
  }
192
192
  async getUserMessagesForForking() {
193
- return readUserMessagesForForking(this.session.sessionManager);
193
+ return readVisibleUserMessagesForForking(this.session.sessionManager);
194
194
  }
195
195
  async getLastAssistantText() {
196
196
  return this.session.getLastAssistantText();