@earendil-works/pi-durable 1.1.0 → 1.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (216) hide show
  1. package/CHANGELOG.md +55 -0
  2. package/README.md +164 -11
  3. package/dist/codemode/codemode.d.ts +173 -0
  4. package/dist/codemode/codemode.d.ts.map +1 -0
  5. package/dist/codemode/codemode.js +886 -0
  6. package/dist/codemode/codemode.js.map +1 -0
  7. package/dist/codemode/describe.d.ts +38 -0
  8. package/dist/codemode/describe.d.ts.map +1 -0
  9. package/dist/codemode/describe.js +119 -0
  10. package/dist/codemode/describe.js.map +1 -0
  11. package/dist/codemode/index.d.ts +3 -0
  12. package/dist/codemode/index.d.ts.map +1 -0
  13. package/dist/codemode/index.js +3 -0
  14. package/dist/codemode/index.js.map +1 -0
  15. package/dist/codemode/models.d.ts +28 -0
  16. package/dist/codemode/models.d.ts.map +1 -0
  17. package/dist/codemode/models.js +231 -0
  18. package/dist/codemode/models.js.map +1 -0
  19. package/dist/codemode/output.d.ts +41 -0
  20. package/dist/codemode/output.d.ts.map +1 -0
  21. package/dist/codemode/output.js +167 -0
  22. package/dist/codemode/output.js.map +1 -0
  23. package/dist/env/index.d.ts +43 -0
  24. package/dist/env/index.d.ts.map +1 -1
  25. package/dist/env/index.js.map +1 -1
  26. package/dist/errors.d.ts +20 -3
  27. package/dist/errors.d.ts.map +1 -1
  28. package/dist/errors.js +34 -5
  29. package/dist/errors.js.map +1 -1
  30. package/dist/harness/agent.d.ts +5 -2
  31. package/dist/harness/agent.d.ts.map +1 -1
  32. package/dist/harness/agent.js +69 -25
  33. package/dist/harness/agent.js.map +1 -1
  34. package/dist/harness/compaction.d.ts +6 -1
  35. package/dist/harness/compaction.d.ts.map +1 -1
  36. package/dist/harness/compaction.js +10 -7
  37. package/dist/harness/compaction.js.map +1 -1
  38. package/dist/harness/context.d.ts +5 -0
  39. package/dist/harness/context.d.ts.map +1 -1
  40. package/dist/harness/context.js +46 -12
  41. package/dist/harness/context.js.map +1 -1
  42. package/dist/harness/events.d.ts +35 -15
  43. package/dist/harness/events.d.ts.map +1 -1
  44. package/dist/harness/events.js +77 -23
  45. package/dist/harness/events.js.map +1 -1
  46. package/dist/harness/generation.d.ts +2 -0
  47. package/dist/harness/generation.d.ts.map +1 -1
  48. package/dist/harness/generation.js +31 -8
  49. package/dist/harness/generation.js.map +1 -1
  50. package/dist/harness/harness.d.ts +7 -0
  51. package/dist/harness/harness.d.ts.map +1 -1
  52. package/dist/harness/harness.js +53 -26
  53. package/dist/harness/harness.js.map +1 -1
  54. package/dist/harness/inbox.d.ts +16 -4
  55. package/dist/harness/inbox.d.ts.map +1 -1
  56. package/dist/harness/inbox.js +26 -3
  57. package/dist/harness/inbox.js.map +1 -1
  58. package/dist/harness/live.d.ts +74 -17
  59. package/dist/harness/live.d.ts.map +1 -1
  60. package/dist/harness/live.js +66 -14
  61. package/dist/harness/live.js.map +1 -1
  62. package/dist/harness/scheduler.d.ts +18 -5
  63. package/dist/harness/scheduler.d.ts.map +1 -1
  64. package/dist/harness/scheduler.js +696 -163
  65. package/dist/harness/scheduler.js.map +1 -1
  66. package/dist/harness/submissions.d.ts +7 -4
  67. package/dist/harness/submissions.d.ts.map +1 -1
  68. package/dist/harness/submissions.js +32 -13
  69. package/dist/harness/submissions.js.map +1 -1
  70. package/dist/harness/task-graph.d.ts +1 -1
  71. package/dist/harness/task-graph.d.ts.map +1 -1
  72. package/dist/harness/task-graph.js +15 -10
  73. package/dist/harness/task-graph.js.map +1 -1
  74. package/dist/harness/tool.d.ts +45 -5
  75. package/dist/harness/tool.d.ts.map +1 -1
  76. package/dist/harness/tool.js +378 -63
  77. package/dist/harness/tool.js.map +1 -1
  78. package/dist/harness/types.d.ts +153 -13
  79. package/dist/harness/types.d.ts.map +1 -1
  80. package/dist/harness/types.js.map +1 -1
  81. package/dist/harness/util.d.ts +6 -1
  82. package/dist/harness/util.d.ts.map +1 -1
  83. package/dist/harness/util.js +5 -2
  84. package/dist/harness/util.js.map +1 -1
  85. package/dist/harness/view.d.ts +6 -2
  86. package/dist/harness/view.d.ts.map +1 -1
  87. package/dist/harness/view.js +22 -12
  88. package/dist/harness/view.js.map +1 -1
  89. package/dist/images/cloudflare.d.ts +4 -0
  90. package/dist/images/cloudflare.d.ts.map +1 -0
  91. package/dist/images/cloudflare.js +9 -0
  92. package/dist/images/cloudflare.js.map +1 -0
  93. package/dist/images/exif.d.ts +3 -0
  94. package/dist/images/exif.d.ts.map +1 -0
  95. package/dist/images/exif.js +71 -0
  96. package/dist/images/exif.js.map +1 -0
  97. package/dist/images/index.d.ts +18 -0
  98. package/dist/images/index.d.ts.map +1 -0
  99. package/dist/images/index.js +125 -0
  100. package/dist/images/index.js.map +1 -0
  101. package/dist/images/node-worker.d.ts +17 -0
  102. package/dist/images/node-worker.d.ts.map +1 -0
  103. package/dist/images/node-worker.js +16 -0
  104. package/dist/images/node-worker.js.map +1 -0
  105. package/dist/images/node.d.ts +21 -0
  106. package/dist/images/node.d.ts.map +1 -0
  107. package/dist/images/node.js +121 -0
  108. package/dist/images/node.js.map +1 -0
  109. package/dist/index.d.ts +6 -6
  110. package/dist/index.d.ts.map +1 -1
  111. package/dist/index.js +3 -3
  112. package/dist/index.js.map +1 -1
  113. package/dist/search.d.ts +13 -0
  114. package/dist/search.d.ts.map +1 -0
  115. package/dist/search.js +85 -0
  116. package/dist/search.js.map +1 -0
  117. package/dist/session/observation.d.ts +10 -3
  118. package/dist/session/observation.d.ts.map +1 -1
  119. package/dist/session/observation.js +24 -34
  120. package/dist/session/observation.js.map +1 -1
  121. package/dist/session/session.d.ts +68 -5
  122. package/dist/session/session.d.ts.map +1 -1
  123. package/dist/session/session.js +461 -49
  124. package/dist/session/session.js.map +1 -1
  125. package/dist/session/transaction.d.ts.map +1 -1
  126. package/dist/session/transaction.js +1 -0
  127. package/dist/session/transaction.js.map +1 -1
  128. package/dist/storage/jsonl/storage.d.ts +4 -0
  129. package/dist/storage/jsonl/storage.d.ts.map +1 -1
  130. package/dist/storage/jsonl/storage.js +2 -1
  131. package/dist/storage/jsonl/storage.js.map +1 -1
  132. package/dist/storage/memory.d.ts.map +1 -1
  133. package/dist/storage/memory.js +8 -10
  134. package/dist/storage/memory.js.map +1 -1
  135. package/dist/storage/scan.d.ts.map +1 -1
  136. package/dist/storage/scan.js +5 -4
  137. package/dist/storage/scan.js.map +1 -1
  138. package/dist/storage/sqlite/cloudflare.d.ts +17 -5
  139. package/dist/storage/sqlite/cloudflare.d.ts.map +1 -1
  140. package/dist/storage/sqlite/cloudflare.js +57 -21
  141. package/dist/storage/sqlite/cloudflare.js.map +1 -1
  142. package/dist/storage/sqlite/index.d.ts +1 -1
  143. package/dist/storage/sqlite/index.d.ts.map +1 -1
  144. package/dist/storage/sqlite/index.js.map +1 -1
  145. package/dist/storage/sqlite/migrations.d.ts +5 -1
  146. package/dist/storage/sqlite/migrations.d.ts.map +1 -1
  147. package/dist/storage/sqlite/migrations.js +94 -84
  148. package/dist/storage/sqlite/migrations.js.map +1 -1
  149. package/dist/storage/sqlite/node.d.ts +6 -4
  150. package/dist/storage/sqlite/node.d.ts.map +1 -1
  151. package/dist/storage/sqlite/node.js +6 -2
  152. package/dist/storage/sqlite/node.js.map +1 -1
  153. package/dist/storage/sqlite/schema.d.ts +47 -0
  154. package/dist/storage/sqlite/schema.d.ts.map +1 -0
  155. package/dist/storage/sqlite/schema.js +57 -0
  156. package/dist/storage/sqlite/schema.js.map +1 -0
  157. package/dist/storage/sqlite/storage.d.ts +9 -1
  158. package/dist/storage/sqlite/storage.d.ts.map +1 -1
  159. package/dist/storage/sqlite/storage.js +56 -55
  160. package/dist/storage/sqlite/storage.js.map +1 -1
  161. package/dist/testing/env-conformance.d.ts.map +1 -1
  162. package/dist/testing/env-conformance.js +100 -0
  163. package/dist/testing/env-conformance.js.map +1 -1
  164. package/dist/testing/runner.d.ts +1 -1
  165. package/dist/testing/runner.d.ts.map +1 -1
  166. package/dist/testing/runner.js.map +1 -1
  167. package/dist/testing/storage-conformance.d.ts.map +1 -1
  168. package/dist/testing/storage-conformance.js +3 -2
  169. package/dist/testing/storage-conformance.js.map +1 -1
  170. package/dist/testing/types.d.ts +2 -0
  171. package/dist/testing/types.d.ts.map +1 -1
  172. package/dist/testing/types.js.map +1 -1
  173. package/dist/tool-search/index.d.ts +2 -0
  174. package/dist/tool-search/index.d.ts.map +1 -0
  175. package/dist/tool-search/index.js +2 -0
  176. package/dist/tool-search/index.js.map +1 -0
  177. package/dist/tool-search/tool-search.d.ts +23 -0
  178. package/dist/tool-search/tool-search.d.ts.map +1 -0
  179. package/dist/tool-search/tool-search.js +84 -0
  180. package/dist/tool-search/tool-search.js.map +1 -0
  181. package/dist/tools/bash.d.ts +10 -2
  182. package/dist/tools/bash.d.ts.map +1 -1
  183. package/dist/tools/bash.js +27 -9
  184. package/dist/tools/bash.js.map +1 -1
  185. package/dist/tools/edit.js +1 -1
  186. package/dist/tools/edit.js.map +1 -1
  187. package/dist/tools/image-processor.d.ts +50 -0
  188. package/dist/tools/image-processor.d.ts.map +1 -0
  189. package/dist/tools/image-processor.js +20 -0
  190. package/dist/tools/image-processor.js.map +1 -0
  191. package/dist/tools/image.d.ts +8 -0
  192. package/dist/tools/image.d.ts.map +1 -1
  193. package/dist/tools/image.js +47 -0
  194. package/dist/tools/image.js.map +1 -1
  195. package/dist/tools/index.d.ts +25 -2
  196. package/dist/tools/index.d.ts.map +1 -1
  197. package/dist/tools/index.js +13 -5
  198. package/dist/tools/index.js.map +1 -1
  199. package/dist/tools/read.d.ts +10 -2
  200. package/dist/tools/read.d.ts.map +1 -1
  201. package/dist/tools/read.js +88 -29
  202. package/dist/tools/read.js.map +1 -1
  203. package/dist/tools/write.js +1 -1
  204. package/dist/tools/write.js.map +1 -1
  205. package/dist/truncate.d.ts +3 -2
  206. package/dist/truncate.d.ts.map +1 -1
  207. package/dist/truncate.js +4 -34
  208. package/dist/truncate.js.map +1 -1
  209. package/dist/types.d.ts +59 -5
  210. package/dist/types.d.ts.map +1 -1
  211. package/dist/types.js.map +1 -1
  212. package/package.json +43 -4
  213. package/dist/harness/output.d.ts +0 -69
  214. package/dist/harness/output.d.ts.map +0 -1
  215. package/dist/harness/output.js +0 -318
  216. package/dist/harness/output.js.map +0 -1
@@ -1 +1 @@
1
- {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../src/harness/compaction.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, Draft } from \"@earendil-works/chord\";\nimport type { AssistantMessage, Message, ModelThinkingLevel, SimpleStreamOptions } from \"@earendil-works/pi-ai\";\nimport { calculateContextTokens, estimateMessageTokens } from \"@earendil-works/pi-ai/utils/estimate\";\nimport { isRetryableAssistantError, retryDelayMs } from \"@earendil-works/pi-ai/utils/retry\";\nimport { CompactionEntry } from \"../entries.ts\";\nimport { defineTask } from \"../tasks.ts\";\nimport type {\n\tConversationId,\n\tEntryDraft,\n\tEntryId,\n\tNextTaskState,\n\tRunningTask,\n\tTaskId,\n\tTaskRuntime,\n\tTx,\n} from \"../types.ts\";\nimport { orderToolResults } from \"./context.ts\";\nimport { addCompactionStatus, compactionStatus, LiveDoc, type LiveState, removeCompactionStatus } from \"./live.ts\";\nimport { ensureProviderSessionId } from \"./provider.ts\";\nimport { admitSubmission } from \"./submissions.ts\";\nimport type {\n\tCompactionHooks,\n\tCompactionReason,\n\tCompactionResult,\n\tContextView,\n\tConversationStreamOptions,\n\tModelRef,\n} from \"./types.ts\";\nimport { recordUsage } from \"./usage.ts\";\n\nexport type CompactionInput = { reason: CompactionReason; instructions?: string };\n\n/** The pinned summarization request. */\nexport type SummaryRequest = {\n\tattempt: number;\n\tmodel: ModelRef;\n\tthinkingLevel: ModelThinkingLevel;\n\tstreamOptions: ConversationStreamOptions;\n\tmaxTokens: number;\n\t/** Newest entry of the context the range was selected from. */\n\ttail: EntryId;\n\t/** First entry kept verbatim; the summary's `head`. */\n\tfirstKept: EntryId;\n};\n\nexport type CompactionCheckpoint =\n\t| { phase: \"select\" }\n\t| ({ phase: \"summarize\" } & SummaryRequest)\n\t| ({ phase: \"retry\"; until: number } & SummaryRequest);\n\ntype Runtime = TaskRuntime<CompactionInput, CompactionCheckpoint, CompactionResult, CompactionHooks>;\ntype Next = NextTaskState<CompactionCheckpoint, CompactionResult>;\n\n/** Longest tool result text a serialized summary source keeps. */\nconst TOOL_RESULT_MAX_CHARS = 2000;\n\nconst SUMMARY_PREFIX =\n\t\"The conversation history before this point was compacted into the following summary:\\n\\n<summary>\\n\";\nconst SUMMARY_SUFFIX = \"\\n</summary>\";\n\nconst SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`;\n\nconst SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work. If the conversation starts with an earlier summary, preserve its information and fold the newer messages into it.\n\nUse this EXACT format:\n\n## Goal\n[What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned by user]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Current work]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Ordered list of what should happen next]\n\n## Critical Context\n- [Any data, examples, or references needed to continue]\n- [Or \"(none)\" if not applicable]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`;\n\n/**\n * Built-in compaction task (spec §8.7): select an old prefix of the model context, summarize it, and place a summary\n * entry whose `head` is the first kept entry. A compaction the generation owns blocks it and appends directly; a\n * conversation-owned one places its summary through a write submission.\n */\nexport const CompactionTask = defineTask<CompactionInput, CompactionCheckpoint, CompactionResult, CompactionHooks>({\n\tname: \"pi.compaction\",\n\tversion: 1,\n\tinitial: () => ({ phase: \"select\" }),\n\tphases: {\n\t\tselect: async (task, runtime, context) => {\n\t\t\tconst { conversationId } = runtime;\n\t\t\tconst agent = await runtime.agent(context);\n\t\t\tconst settings = runtime.settings;\n\t\t\tconst ref = agent.model;\n\t\t\tconst model = ref === undefined ? undefined : runtime.models.getModel(ref.provider, ref.modelId);\n\t\t\tif (ref === undefined || model === undefined) return failNoModel(runtime, ref, context);\n\t\t\tconst policy = settings.compaction;\n\t\t\tconst view = await runtime.context(conversationId, context);\n\t\t\tconst cut = selectCut(view, policy.keepRecentTokens);\n\t\t\tif (cut === undefined) return complete(runtime, context);\n\t\t\tconst firstKept = view.entries[cut]!.id;\n\t\t\tconst { reason, instructions } = task.input;\n\t\t\tconst compaction = {\n\t\t\t\treason,\n\t\t\t\tentries: view.entries.slice(0, cut),\n\t\t\t\tmessages: summarizedMessages(view, cut),\n\t\t\t\tfirstKept,\n\t\t\t\t...(instructions === undefined ? {} : { instructions }),\n\t\t\t};\n\t\t\tlet decision: { readonly decline: true } | { readonly summary: string } | undefined;\n\t\t\tawait runtime.hooks.each(\"beforeCompact\", async (hook) => {\n\t\t\t\tif (decision === undefined) decision = await hook(compaction, runtime, context);\n\t\t\t});\n\t\t\tif (decision !== undefined && \"decline\" in decision) return complete(runtime, context);\n\t\t\tif (decision !== undefined) return place(runtime, firstKept, decision.summary, context);\n\t\t\tconst request: SummaryRequest = {\n\t\t\t\tattempt: 1,\n\t\t\t\tmodel: ref,\n\t\t\t\tthinkingLevel: agent.thinkingLevel,\n\t\t\t\tstreamOptions: settings.stream,\n\t\t\t\tmaxTokens: Math.min(\n\t\t\t\t\tMath.floor(0.8 * policy.reserveTokens),\n\t\t\t\t\tmodel.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY,\n\t\t\t\t),\n\t\t\t\ttail: view.entries.reduce((tail, entry) => (entry.id > tail ? entry.id : tail), firstKept),\n\t\t\t\tfirstKept,\n\t\t\t};\n\t\t\tawait runtime.commit(() => ({ status: \"running\", checkpoint: { phase: \"summarize\", ...request } }), context);\n\t\t},\n\t\tsummarize: async (task, runtime, context) => {\n\t\t\tconst { phase: _, ...request } = task.state.checkpoint;\n\t\t\tconst { model: ref, thinkingLevel, streamOptions, maxTokens, tail, firstKept, attempt } = request;\n\t\t\tconst model = runtime.models.getModel(ref.provider, ref.modelId);\n\t\t\tif (model === undefined) return failNoModel(runtime, ref, context);\n\t\t\t// The context at `tail` is immutable, so this is the range `select` chose.\n\t\t\tconst view = await runtime.context(runtime.conversationId, context, { at: tail });\n\t\t\tconst cut = view.entries.findIndex((entry) => entry.id === firstKept);\n\t\t\tconst now = runtime.now();\n\t\t\tconst messages: Message[] = [\n\t\t\t\t{ role: \"system\", content: SUMMARIZATION_SYSTEM_PROMPT, timestamp: now },\n\t\t\t\t{\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [{ type: \"text\", text: summaryPrompt(summarizedMessages(view, cut), task.input.instructions) }],\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t},\n\t\t\t];\n\t\t\tconst { deferred: _deferred, ...forwarded } = streamOptions;\n\t\t\tconst options: SimpleStreamOptions = {\n\t\t\t\t...forwarded,\n\t\t\t\tcacheRetention: \"none\",\n\t\t\t\tmaxTokens,\n\t\t\t\tsignal: runtime.signal,\n\t\t\t\tsessionId: await ensureProviderSessionId(runtime, context),\n\t\t\t\t...(thinkingLevel === \"off\" ? {} : { reasoning: thinkingLevel }),\n\t\t\t};\n\t\t\tconst message = await runtime.models.completeSimple(model, { messages }, options);\n\t\t\t// An abort mark or close: the abort invocation or the reopened task handles the committed state.\n\t\t\truntime.signal.throwIfAborted();\n\t\t\tconst summary = summaryText(message);\n\t\t\tconst policy = runtime.settings.retry;\n\t\t\tconst retry =\n\t\t\t\tmessage.stopReason === \"error\" &&\n\t\t\t\tisRetryableAssistantError(message) &&\n\t\t\t\tpolicy.enabled &&\n\t\t\t\tattempt <= policy.maxRetries;\n\t\t\tconst until = retry ? runtime.now() + retryDelayMs(policy, attempt) : 0;\n\t\t\tawait runtime.commit(async (tx, current): Promise<Next> => {\n\t\t\t\tawait recordUsage(\n\t\t\t\t\ttx,\n\t\t\t\t\truntime.conversationId,\n\t\t\t\t\t\"models\",\n\t\t\t\t\t`${message.provider}/${message.model}`,\n\t\t\t\t\tmessage.usage,\n\t\t\t\t);\n\t\t\t\tconst live = await tx.doc(LiveDoc, runtime.conversationId);\n\t\t\t\tif (summary !== undefined) return placeSummary(tx, runtime, current, live, firstKept, summary);\n\t\t\t\tif (retry) {\n\t\t\t\t\tconst status = compactionStatus(live, runtime.taskId);\n\t\t\t\t\tif (status !== undefined) status.retry = { at: until, error: message.errorMessage ?? \"\" };\n\t\t\t\t\treturn { status: \"running\", checkpoint: { phase: \"retry\", ...request, until } };\n\t\t\t\t}\n\t\t\t\tremoveCompactionStatus(live, runtime.taskId);\n\t\t\t\tconst text = summaryFailure(message);\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"terminal\",\n\t\t\t\t\toutcome: { status: \"failed\", error: { message: text, detail: { reason: \"model_error\" } } },\n\t\t\t\t};\n\t\t\t}, context);\n\t\t},\n\t\tretry: async (task, runtime, context) => {\n\t\t\tconst { phase: _, until, ...request } = task.state.checkpoint;\n\t\t\tawait runtime.sleep(until, context);\n\t\t\tconst attempt = request.attempt + 1;\n\t\t\tawait runtime.commit(async (tx) => {\n\t\t\t\tconst status = compactionStatus(await tx.doc(LiveDoc, runtime.conversationId), runtime.taskId);\n\t\t\t\tif (status !== undefined) {\n\t\t\t\t\tstatus.attempt = attempt;\n\t\t\t\t\tdelete status.retry;\n\t\t\t\t}\n\t\t\t\treturn { status: \"running\", checkpoint: { phase: \"summarize\", ...request, attempt } };\n\t\t\t}, context);\n\t\t},\n\t},\n\tabort: async (_task, runtime, context) => {\n\t\tawait runtime.commit(async (tx) => {\n\t\t\tremoveCompactionStatus(await tx.doc(LiveDoc, runtime.conversationId), runtime.taskId);\n\t\t\treturn { status: \"terminal\", outcome: { status: \"aborted\" } };\n\t\t}, context);\n\t},\n});\n\n/**\n * Create a compaction task with its status in this commit. `owner` is the generation that waits for it (a blocking\n * compaction); without one it is conversation-owned, and `background` unless it is manual.\n */\nexport async function createCompaction(\n\ttx: Tx,\n\tconversationId: ConversationId,\n\tinput: CompactionInput,\n\towner?: TaskId,\n): Promise<TaskId<CompactionResult>> {\n\tconst ownership =\n\t\towner === undefined ? ({ kind: \"conversation\" } as const) : { kind: \"task\" as const, taskId: owner };\n\tconst background = owner === undefined && input.reason !== \"manual\";\n\tconst taskId = await tx.createTask(CompactionTask, input, { ownership, conversationId, background });\n\tconst status = { taskId, reason: input.reason, blocking: owner !== undefined, attempt: 1 };\n\taddCompactionStatus(await tx.doc(LiveDoc, conversationId), status);\n\treturn taskId;\n}\n\n/**\n * Index in `view.entries` of the first entry a summary keeps, or `undefined` when there is nothing to compact\n * (spec §8.7). Walks back from the tail until `keepRecentTokens` are kept, then cuts at the first candidate at or after\n * that entry: an entry whose contribution starts with a user or assistant message, never a tool result, and never a\n * user entry that a result of the preceding assistant's calls still follows.\n */\nexport function selectCut(view: ContextView, keepRecentTokens: number): number | undefined {\n\tconst { contributions } = view;\n\tconst start = view.head === undefined ? 0 : 1;\n\tconst candidates: number[] = [];\n\tfor (let index = start; index < contributions.length; index++) {\n\t\tif (isCandidate(contributions, index)) candidates.push(index);\n\t}\n\tlet kept = 0;\n\tlet cut: number | undefined;\n\tfor (let index = contributions.length - 1; index >= start; index--) {\n\t\tfor (const message of contributions[index]!) kept += estimateMessageTokens(message);\n\t\tif (kept < keepRecentTokens) continue;\n\t\tcut = candidates.find((candidate) => candidate >= index) ?? candidates.at(-1);\n\t\tbreak;\n\t}\n\tif (cut === undefined) return undefined;\n\tfor (let index = start; index < cut; index++) if (contributions[index]!.length > 0) return cut;\n\treturn undefined;\n}\n\nfunction isCandidate(contributions: ContextView[\"contributions\"], index: number): boolean {\n\tconst first = contributions[index]![0];\n\tif (first?.role === \"assistant\") return true;\n\tif (first?.role !== \"user\") return false;\n\t// A result of the preceding assistant's calls that follows this entry, before the next assistant, belongs before it.\n\tlet calls: ReadonlySet<string> = new Set();\n\tfor (let before = index - 1; before >= 0; before--) {\n\t\tconst assistant = contributions[before]!.findLast((message) => message.role === \"assistant\");\n\t\tif (assistant === undefined) continue;\n\t\tcalls = new Set(assistant.content.flatMap((content) => (content.type === \"toolCall\" ? [content.id] : [])));\n\t\tbreak;\n\t}\n\tif (calls.size === 0) return true;\n\tfor (let after = index; after < contributions.length; after++) {\n\t\tfor (const [position, message] of contributions[after]!.entries()) {\n\t\t\tif (message.role === \"assistant\" && (after > index || position > 0)) return true;\n\t\t\tif (message.role === \"toolResult\" && calls.has(message.toolCallId)) return false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/** Model messages of the entries before `cut`: the head marker first, ordered like model context (spec §2.1). */\nexport function summarizedMessages(view: ContextView, cut: number): Message[] {\n\treturn orderToolResults(view.contributions.slice(0, cut).flat());\n}\n\n/**\n * Size of a request over `view` followed by `extra` (spec §8.3): the usage of the newest assistant appended after the\n * head marker, whose request included the marker, plus estimates of the messages after it; without one, estimates of\n * every message.\n */\nexport function estimateContext(view: ContextView, extra: readonly Message[]): number {\n\tlet measured: AssistantMessage | undefined;\n\tconst after = view.head?.id ?? Number.NEGATIVE_INFINITY;\n\tfor (let index = view.entries.length - 1; index >= 0 && measured === undefined; index--) {\n\t\tif (view.entries[index]!.id <= after) continue;\n\t\tmeasured = view.contributions[index]!.findLast(\n\t\t\t(message): message is AssistantMessage =>\n\t\t\t\tmessage.role === \"assistant\" && calculateContextTokens(message.usage) > 0,\n\t\t);\n\t}\n\tconst from = measured === undefined ? 0 : view.messages.lastIndexOf(measured) + 1;\n\tlet tokens = measured === undefined ? 0 : calculateContextTokens(measured.usage);\n\tfor (const message of view.messages.slice(from)) tokens += estimateMessageTokens(message);\n\tfor (const message of extra) tokens += estimateMessageTokens(message);\n\treturn tokens;\n}\n\n/** The summary of a clean `stop` with text and no tool call; anything else is not a summary. */\nfunction summaryText(message: AssistantMessage): string | undefined {\n\tif (message.stopReason !== \"stop\" || message.content.some((content) => content.type === \"toolCall\"))\n\t\treturn undefined;\n\tconst text = message.content\n\t\t.flatMap((content) => (content.type === \"text\" ? [content.text] : []))\n\t\t.join(\"\\n\")\n\t\t.trim();\n\treturn text.length === 0 ? undefined : text;\n}\n\nfunction summaryFailure(message: AssistantMessage): string {\n\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\treturn `Summarization failed: ${message.errorMessage ?? message.stopReason}`;\n\t}\n\tif (message.stopReason === \"length\") return \"Summarization hit the token limit; the summary is incomplete\";\n\tif (message.content.some((content) => content.type === \"toolCall\")) return \"Summarization attempted to call a tool\";\n\treturn \"Summarization produced no text\";\n}\n\n/** The summarizer's user message: the serialized conversation, the prompt, and any instructions. */\nfunction summaryPrompt(messages: readonly Message[], instructions: string | undefined): string {\n\tconst focus = instructions === undefined ? \"\" : `\\n\\nAdditional focus: ${instructions}`;\n\treturn `<conversation>\\n${serializeConversation(messages)}\\n</conversation>\\n\\n${SUMMARIZATION_PROMPT}${focus}`;\n}\n\n/** Messages as plain text, so the summarizer reads a transcript instead of continuing it. System messages are omitted. */\nexport function serializeConversation(messages: readonly Message[]): string {\n\tconst parts: string[] = [];\n\tfor (const message of messages) {\n\t\tif (message.role === \"user\") {\n\t\t\tconst text = contentText(message.content);\n\t\t\tif (text.length > 0) parts.push(`[User]: ${text}`);\n\t\t} else if (message.role === \"assistant\") {\n\t\t\tconst thinking = message.content.flatMap((content) => (content.type === \"thinking\" ? [content.thinking] : []));\n\t\t\tconst text = message.content.flatMap((content) => (content.type === \"text\" ? [content.text] : []));\n\t\t\tconst calls = message.content.flatMap((content) =>\n\t\t\t\tcontent.type === \"toolCall\"\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t`${content.name}(${Object.entries(content.arguments)\n\t\t\t\t\t\t\t\t.map(([key, value]) => `${key}=${JSON.stringify(value)}`)\n\t\t\t\t\t\t\t\t.join(\", \")})`,\n\t\t\t\t\t\t]\n\t\t\t\t\t: [],\n\t\t\t);\n\t\t\tif (thinking.length > 0) parts.push(`[Assistant thinking]: ${thinking.join(\"\\n\")}`);\n\t\t\tif (text.length > 0) parts.push(`[Assistant]: ${text.join(\"\\n\")}`);\n\t\t\tif (calls.length > 0) parts.push(`[Assistant tool calls]: ${calls.join(\"; \")}`);\n\t\t} else if (message.role === \"toolResult\") {\n\t\t\tconst text = contentText(message.content);\n\t\t\tif (text.length > 0) parts.push(`[Tool result]: ${truncate(text, TOOL_RESULT_MAX_CHARS)}`);\n\t\t}\n\t}\n\treturn parts.join(\"\\n\\n\");\n}\n\nfunction contentText(content: string | readonly { readonly type: string; readonly text?: string }[]): string {\n\tif (typeof content === \"string\") return content;\n\treturn content\n\t\t.flatMap((block) => (block.type === \"text\" && block.text !== undefined ? [block.text] : []))\n\t\t.join(\"\\n\");\n}\n\nfunction truncate(text: string, maxChars: number): string {\n\tif (text.length <= maxChars) return text;\n\treturn `${text.slice(0, maxChars)}\\n\\n[... ${text.length - maxChars} more characters truncated]`;\n}\n\n/** Place a summary supplied by a hook in its own commit. */\nasync function place(runtime: Runtime, firstKept: EntryId, summary: string, context: Context): Promise<void> {\n\tawait runtime.commit(\n\t\tasync (tx, current) =>\n\t\t\tplaceSummary(tx, runtime, current, await tx.doc(LiveDoc, runtime.conversationId), firstKept, summary),\n\t\tcontext,\n\t);\n}\n\n/**\n * Place the summary entry and complete (spec §8.7). A blocking compaction, owned by its generation, appends it: the\n * generation holds the run and waits. A conversation-owned one admits it as a write submission, placed at once when\n * idle, otherwise at the next boundary, or settled `stale`.\n * REMINDER: nothing else may append to a busy conversation, so every non-blocking summary goes through admission.\n */\nasync function placeSummary(\n\ttx: Tx,\n\truntime: Runtime,\n\tcurrent: RunningTask<CompactionInput, CompactionCheckpoint, CompactionResult>,\n\tlive: Draft<LiveState>,\n\tfirstKept: EntryId,\n\tsummary: string,\n): Promise<Next> {\n\tremoveCompactionStatus(live, runtime.taskId);\n\tconst text = `${SUMMARY_PREFIX}${summary}${SUMMARY_SUFFIX}`;\n\tconst entry = {\n\t\tkind: CompactionEntry.kind,\n\t\thead: firstKept,\n\t\tmodel: [{ role: \"user\", content: [{ type: \"text\", text }], timestamp: runtime.now() }],\n\t\tdata: { reason: current.input.reason },\n\t} satisfies EntryDraft;\n\tconst result: CompactionResult =\n\t\tcurrent.owner === undefined\n\t\t\t? {\n\t\t\t\t\tsubmissionId: await admitSubmission(\n\t\t\t\t\t\ttx,\n\t\t\t\t\t\truntime.conversationId,\n\t\t\t\t\t\t{ type: \"write\", requestId: `compaction:${runtime.taskId}`, entry },\n\t\t\t\t\t\truntime.now(),\n\t\t\t\t\t\truntime.settings,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t: { entryId: (await tx.appendEntry(runtime.conversationId, entry)).id };\n\treturn { status: \"terminal\", outcome: { status: \"completed\", result } };\n}\n\n/** Remove the status and complete without a summary. */\nasync function complete(runtime: Runtime, context: Context): Promise<void> {\n\tawait runtime.commit(async (tx) => {\n\t\tremoveCompactionStatus(await tx.doc(LiveDoc, runtime.conversationId), runtime.taskId);\n\t\treturn { status: \"terminal\", outcome: { status: \"completed\", result: {} } };\n\t}, context);\n}\n\nasync function failNoModel(runtime: Runtime, ref: ModelRef | undefined, context: Context): Promise<void> {\n\tconst message =\n\t\tref === undefined ? \"No model is configured\" : `Model ${ref.provider}/${ref.modelId} is not available`;\n\tawait runtime.commit(async (tx) => {\n\t\tremoveCompactionStatus(await tx.doc(LiveDoc, runtime.conversationId), runtime.taskId);\n\t\treturn { status: \"terminal\", outcome: { status: \"failed\", error: { message, detail: { reason: \"no_model\" } } } };\n\t}, context);\n}\n"]}
1
+ {"version":3,"file":"compaction.js","sourceRoot":"","sources":["../../src/harness/compaction.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, Draft } from \"@earendil-works/chord\";\nimport type { AssistantMessage, Message, ModelThinkingLevel, SimpleStreamOptions } from \"@earendil-works/pi-ai\";\nimport { calculateContextTokens, estimateMessageTokens } from \"@earendil-works/pi-ai/utils/estimate\";\nimport { isRetryableAssistantError, retryDelayMs } from \"@earendil-works/pi-ai/utils/retry\";\nimport { CompactionEntry } from \"../entries.ts\";\nimport { defineTask } from \"../tasks.ts\";\nimport type {\n\tConversationId,\n\tEntryDraft,\n\tEntryId,\n\tNextTaskState,\n\tRunningTask,\n\tTaskId,\n\tTaskRuntime,\n\tTx,\n} from \"../types.ts\";\nimport { orderToolResults } from \"./context.ts\";\nimport {\n\taddCompactionStatus,\n\tcompactionStatus,\n\tfailCompactionStatus,\n\tLiveDoc,\n\ttype LiveState,\n\tremoveCompactionStatus,\n} from \"./live.ts\";\nimport { ensureProviderSessionId } from \"./provider.ts\";\nimport { admitSubmission } from \"./submissions.ts\";\nimport type {\n\tCompactionHooks,\n\tCompactionReason,\n\tCompactionResult,\n\tContextView,\n\tConversationStreamOptions,\n\tModelRef,\n} from \"./types.ts\";\nimport { recordUsage } from \"./usage.ts\";\n\nexport type CompactionInput = { reason: CompactionReason; instructions?: string };\n\n/** The pinned summarization request. */\nexport type SummaryRequest = {\n\tattempt: number;\n\tmodel: ModelRef;\n\tthinkingLevel: ModelThinkingLevel;\n\tstreamOptions: ConversationStreamOptions;\n\tmaxTokens: number;\n\t/** Newest entry of the context the range was selected from. */\n\ttail: EntryId;\n\t/** First entry kept verbatim; the summary's `head`. */\n\tfirstKept: EntryId;\n};\n\nexport type CompactionCheckpoint =\n\t| { phase: \"select\" }\n\t| ({ phase: \"summarize\" } & SummaryRequest)\n\t| ({ phase: \"retry\"; until: number } & SummaryRequest);\n\ntype Runtime = TaskRuntime<CompactionInput, CompactionCheckpoint, CompactionResult, CompactionHooks>;\ntype Next = NextTaskState<CompactionCheckpoint, CompactionResult>;\n\n/** Longest tool result text a serialized summary source keeps. */\nconst TOOL_RESULT_MAX_CHARS = 2000;\n\nconst SUMMARY_PREFIX =\n\t\"The conversation history before this point was compacted into the following summary:\\n\\n<summary>\\n\";\nconst SUMMARY_SUFFIX = \"\\n</summary>\";\n\nconst SUMMARIZATION_SYSTEM_PROMPT = `You are a context summarization assistant. Your task is to read a conversation between a user and an AI assistant, then produce a structured summary following the exact format specified.\n\nDo NOT continue the conversation. Do NOT respond to any questions in the conversation. ONLY output the structured summary.`;\n\nconst SUMMARIZATION_PROMPT = `The messages above are a conversation to summarize. Create a structured context checkpoint summary that another LLM will use to continue the work. If the conversation starts with an earlier summary, preserve its information and fold the newer messages into it.\n\nUse this EXACT format:\n\n## Goal\n[What is the user trying to accomplish? Can be multiple items if the session covers different tasks.]\n\n## Constraints & Preferences\n- [Any constraints, preferences, or requirements mentioned by user]\n- [Or \"(none)\" if none were mentioned]\n\n## Progress\n### Done\n- [x] [Completed tasks/changes]\n\n### In Progress\n- [ ] [Current work]\n\n### Blocked\n- [Issues preventing progress, if any]\n\n## Key Decisions\n- **[Decision]**: [Brief rationale]\n\n## Next Steps\n1. [Ordered list of what should happen next]\n\n## Critical Context\n- [Any data, examples, or references needed to continue]\n- [Or \"(none)\" if not applicable]\n\nKeep each section concise. Preserve exact file paths, function names, and error messages.`;\n\n/**\n * Built-in compaction task (spec §8.7): select an old prefix of the model context, summarize it, and place a summary\n * entry whose `head` is the first kept entry. A compaction the generation owns blocks it and appends directly; a\n * conversation-owned one places its summary through a write submission.\n */\nexport const CompactionTask = defineTask<CompactionInput, CompactionCheckpoint, CompactionResult, CompactionHooks>({\n\tname: \"pi.compaction\",\n\tversion: 1,\n\tinitial: () => ({ phase: \"select\" }),\n\tphases: {\n\t\tselect: async (task, runtime, context) => {\n\t\t\tconst { conversationId } = runtime;\n\t\t\tconst agent = await runtime.agent(context);\n\t\t\tconst settings = runtime.settings;\n\t\t\tconst ref = agent.model;\n\t\t\tconst model = ref === undefined ? undefined : runtime.models.getModel(ref.provider, ref.modelId);\n\t\t\tif (ref === undefined || model === undefined) return failNoModel(runtime, ref, context);\n\t\t\tconst policy = settings.compaction;\n\t\t\tconst view = await runtime.context(conversationId, context);\n\t\t\tconst cut = selectCut(view, policy.keepRecentTokens);\n\t\t\tif (cut === undefined) return complete(runtime, context);\n\t\t\tconst firstKept = view.entries[cut]!.id;\n\t\t\tconst { reason, instructions } = task.input;\n\t\t\tconst compaction = {\n\t\t\t\treason,\n\t\t\t\tentries: view.entries.slice(0, cut),\n\t\t\t\tmessages: summarizedMessages(view, cut),\n\t\t\t\tfirstKept,\n\t\t\t\t...(instructions === undefined ? {} : { instructions }),\n\t\t\t};\n\t\t\tlet decision: { readonly decline: true } | { readonly summary: string } | undefined;\n\t\t\tawait runtime.hooks.each(\"beforeCompact\", async (hook) => {\n\t\t\t\tif (decision === undefined) decision = await hook(compaction, runtime, context);\n\t\t\t});\n\t\t\tif (decision !== undefined && \"decline\" in decision) return complete(runtime, context);\n\t\t\tif (decision !== undefined) return place(runtime, firstKept, decision.summary, context);\n\t\t\tconst request: SummaryRequest = {\n\t\t\t\tattempt: 1,\n\t\t\t\tmodel: ref,\n\t\t\t\tthinkingLevel: agent.thinkingLevel,\n\t\t\t\tstreamOptions: settings.stream,\n\t\t\t\tmaxTokens: Math.min(\n\t\t\t\t\tMath.floor(0.8 * policy.reserveTokens),\n\t\t\t\t\tmodel.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY,\n\t\t\t\t),\n\t\t\t\ttail: view.entries.reduce((tail, entry) => (entry.id > tail ? entry.id : tail), firstKept),\n\t\t\t\tfirstKept,\n\t\t\t};\n\t\t\tawait runtime.commit(() => ({ status: \"running\", checkpoint: { phase: \"summarize\", ...request } }), context);\n\t\t},\n\t\tsummarize: async (task, runtime, context) => {\n\t\t\tconst { phase: _, ...request } = task.state.checkpoint;\n\t\t\tconst { model: ref, thinkingLevel, streamOptions, maxTokens, tail, firstKept, attempt } = request;\n\t\t\tconst model = runtime.models.getModel(ref.provider, ref.modelId);\n\t\t\tif (model === undefined) return failNoModel(runtime, ref, context);\n\t\t\t// The context at `tail` is immutable, so this is the range `select` chose.\n\t\t\tconst view = await runtime.context(runtime.conversationId, context, { at: tail });\n\t\t\tconst cut = view.entries.findIndex((entry) => entry.id === firstKept);\n\t\t\tconst now = runtime.now();\n\t\t\tconst messages: Message[] = [\n\t\t\t\t{ role: \"system\", content: SUMMARIZATION_SYSTEM_PROMPT, timestamp: now },\n\t\t\t\t{\n\t\t\t\t\trole: \"user\",\n\t\t\t\t\tcontent: [{ type: \"text\", text: summaryPrompt(summarizedMessages(view, cut), task.input.instructions) }],\n\t\t\t\t\ttimestamp: now,\n\t\t\t\t},\n\t\t\t];\n\t\t\tconst { deferred: _deferred, ...forwarded } = streamOptions;\n\t\t\tconst options: SimpleStreamOptions = {\n\t\t\t\t...forwarded,\n\t\t\t\tcacheRetention: \"none\",\n\t\t\t\tmaxTokens,\n\t\t\t\tsignal: runtime.signal,\n\t\t\t\tsessionId: await ensureProviderSessionId(runtime, context),\n\t\t\t\t...(thinkingLevel === \"off\" ? {} : { reasoning: thinkingLevel }),\n\t\t\t};\n\t\t\tconst message = await runtime.models.completeSimple(model, { messages }, options);\n\t\t\t// An abort mark or close: the abort invocation or the reopened task handles the committed state.\n\t\t\truntime.signal.throwIfAborted();\n\t\t\tconst summary = summaryText(message);\n\t\t\tconst policy = runtime.settings.retry;\n\t\t\tconst retry =\n\t\t\t\tmessage.stopReason === \"error\" &&\n\t\t\t\tisRetryableAssistantError(message) &&\n\t\t\t\tpolicy.enabled &&\n\t\t\t\tattempt <= policy.maxRetries;\n\t\t\tconst until = retry ? runtime.now() + retryDelayMs(policy, attempt) : 0;\n\t\t\tawait runtime.commit(async (tx, current): Promise<Next> => {\n\t\t\t\tawait recordUsage(\n\t\t\t\t\ttx,\n\t\t\t\t\truntime.conversationId,\n\t\t\t\t\t\"models\",\n\t\t\t\t\t`${message.provider}/${message.model}`,\n\t\t\t\t\tmessage.usage,\n\t\t\t\t);\n\t\t\t\tconst live = await tx.doc(LiveDoc, runtime.conversationId);\n\t\t\t\tif (summary !== undefined) return placeSummary(tx, runtime, current, live, firstKept, summary);\n\t\t\t\tif (retry) {\n\t\t\t\t\tconst status = compactionStatus(live, runtime.taskId);\n\t\t\t\t\tif (status !== undefined) status.retry = { at: until, error: message.errorMessage ?? \"\" };\n\t\t\t\t\treturn { status: \"running\", checkpoint: { phase: \"retry\", ...request, until } };\n\t\t\t\t}\n\t\t\t\tconst text = summaryFailure(message);\n\t\t\t\tfailCompactionStatus(live, runtime.taskId, text);\n\t\t\t\treturn {\n\t\t\t\t\tstatus: \"terminal\",\n\t\t\t\t\toutcome: { status: \"failed\", error: { message: text, detail: { reason: \"model_error\" } } },\n\t\t\t\t};\n\t\t\t}, context);\n\t\t},\n\t\tretry: async (task, runtime, context) => {\n\t\t\tconst { phase: _, until, ...request } = task.state.checkpoint;\n\t\t\tawait runtime.sleep(until, context);\n\t\t\tconst attempt = request.attempt + 1;\n\t\t\tawait runtime.commit(async (tx) => {\n\t\t\t\tconst status = compactionStatus(await tx.doc(LiveDoc, runtime.conversationId), runtime.taskId);\n\t\t\t\tif (status !== undefined) {\n\t\t\t\t\tstatus.attempt = attempt;\n\t\t\t\t\tdelete status.retry;\n\t\t\t\t}\n\t\t\t\treturn { status: \"running\", checkpoint: { phase: \"summarize\", ...request, attempt } };\n\t\t\t}, context);\n\t\t},\n\t},\n\tabort: async (_task, runtime, context) => {\n\t\tawait runtime.commit(async (tx) => {\n\t\t\tremoveCompactionStatus(await tx.doc(LiveDoc, runtime.conversationId), runtime.taskId);\n\t\t\treturn { status: \"terminal\", outcome: { status: \"aborted\" } };\n\t\t}, context);\n\t},\n});\n\n/**\n * Create a compaction task with its status in this commit. `owner` is the generation that waits for it (a blocking\n * compaction); without one it is conversation-owned, and `background` unless it is manual.\n */\nexport async function createCompaction(\n\ttx: Tx,\n\tconversationId: ConversationId,\n\tinput: CompactionInput,\n\towner?: TaskId,\n): Promise<TaskId<CompactionResult>> {\n\tconst ownership =\n\t\towner === undefined ? ({ kind: \"conversation\" } as const) : { kind: \"task\" as const, taskId: owner };\n\tconst background = owner === undefined && input.reason !== \"manual\";\n\tconst taskId = await tx.createTask(CompactionTask, input, { ownership, conversationId, background });\n\tconst status = { taskId, reason: input.reason, blocking: owner !== undefined, attempt: 1 };\n\taddCompactionStatus(await tx.doc(LiveDoc, conversationId), status);\n\treturn taskId;\n}\n\n/**\n * Index in `view.entries` of the first entry a summary keeps, or `undefined` when there is nothing to compact\n * (spec §8.7). Walks back from the tail until `keepRecentTokens` are kept, then cuts at the first candidate at or after\n * that entry: an entry whose contribution starts with a user or assistant message, never a tool result, and never a\n * user entry that a result of the preceding assistant's calls still follows.\n */\nexport function selectCut(view: ContextView, keepRecentTokens: number): number | undefined {\n\tconst { contributions } = view;\n\tconst start = view.head === undefined ? 0 : 1;\n\tconst candidates: number[] = [];\n\tfor (let index = start; index < contributions.length; index++) {\n\t\tif (isCandidate(contributions, index)) candidates.push(index);\n\t}\n\tlet kept = 0;\n\tlet cut: number | undefined;\n\tfor (let index = contributions.length - 1; index >= start; index--) {\n\t\tfor (const message of contributions[index]!) kept += estimateMessageTokens(message);\n\t\tif (kept < keepRecentTokens) continue;\n\t\tcut = candidates.find((candidate) => candidate >= index) ?? candidates.at(-1);\n\t\tbreak;\n\t}\n\tif (cut === undefined) return undefined;\n\tfor (let index = start; index < cut; index++) if (contributions[index]!.length > 0) return cut;\n\treturn undefined;\n}\n\nfunction isCandidate(contributions: ContextView[\"contributions\"], index: number): boolean {\n\tconst first = contributions[index]![0];\n\tif (first?.role === \"assistant\") return true;\n\tif (first?.role !== \"user\") return false;\n\t// A result of the preceding assistant's calls that follows this entry, before the next assistant, belongs before it.\n\tlet calls: ReadonlySet<string> = new Set();\n\tfor (let before = index - 1; before >= 0; before--) {\n\t\tconst assistant = contributions[before]!.findLast((message) => message.role === \"assistant\");\n\t\tif (assistant === undefined) continue;\n\t\tcalls = new Set(assistant.content.flatMap((content) => (content.type === \"toolCall\" ? [content.id] : [])));\n\t\tbreak;\n\t}\n\tif (calls.size === 0) return true;\n\tfor (let after = index; after < contributions.length; after++) {\n\t\tfor (const [position, message] of contributions[after]!.entries()) {\n\t\t\tif (message.role === \"assistant\" && (after > index || position > 0)) return true;\n\t\t\tif (message.role === \"toolResult\" && calls.has(message.toolCallId)) return false;\n\t\t}\n\t}\n\treturn true;\n}\n\n/** Model messages of the entries before `cut`: the head marker first, ordered like model context (spec §2.1). */\nexport function summarizedMessages(view: ContextView, cut: number): Message[] {\n\treturn orderToolResults(view.contributions.slice(0, cut).flat());\n}\n\n/**\n * Size of a request over `view` followed by `extra` (spec §8.3): the usage of the newest assistant appended after the\n * head marker, whose request included the marker, plus estimates of the messages after it; without one, estimates of\n * every message.\n */\nexport function estimateContext(view: ContextView, extra: readonly Message[]): number {\n\tlet measured: AssistantMessage | undefined;\n\tconst after = view.head?.id ?? Number.NEGATIVE_INFINITY;\n\tfor (let index = view.entries.length - 1; index >= 0 && measured === undefined; index--) {\n\t\tif (view.entries[index]!.id <= after) continue;\n\t\tmeasured = view.contributions[index]!.findLast(\n\t\t\t(message): message is AssistantMessage =>\n\t\t\t\tmessage.role === \"assistant\" && calculateContextTokens(message.usage) > 0,\n\t\t);\n\t}\n\tconst from = measured === undefined ? 0 : view.messages.lastIndexOf(measured) + 1;\n\tlet tokens = measured === undefined ? 0 : calculateContextTokens(measured.usage);\n\tfor (const message of view.messages.slice(from)) tokens += estimateMessageTokens(message);\n\tfor (const message of extra) tokens += estimateMessageTokens(message);\n\treturn tokens;\n}\n\n/** The summary of a clean `stop` with text and no tool call; anything else is not a summary. */\nfunction summaryText(message: AssistantMessage): string | undefined {\n\tif (message.stopReason !== \"stop\" || message.content.some((content) => content.type === \"toolCall\"))\n\t\treturn undefined;\n\tconst text = message.content\n\t\t.flatMap((content) => (content.type === \"text\" ? [content.text] : []))\n\t\t.join(\"\\n\")\n\t\t.trim();\n\treturn text.length === 0 ? undefined : text;\n}\n\nfunction summaryFailure(message: AssistantMessage): string {\n\tif (message.stopReason === \"error\" || message.stopReason === \"aborted\") {\n\t\treturn `Summarization failed: ${message.errorMessage ?? message.stopReason}`;\n\t}\n\tif (message.stopReason === \"length\") return \"Summarization hit the token limit; the summary is incomplete\";\n\tif (message.content.some((content) => content.type === \"toolCall\")) return \"Summarization attempted to call a tool\";\n\treturn \"Summarization produced no text\";\n}\n\n/** The summarizer's user message: the serialized conversation, the prompt, and any instructions. */\nfunction summaryPrompt(messages: readonly Message[], instructions: string | undefined): string {\n\tconst focus = instructions === undefined ? \"\" : `\\n\\nAdditional focus: ${instructions}`;\n\treturn `<conversation>\\n${serializeConversation(messages)}\\n</conversation>\\n\\n${SUMMARIZATION_PROMPT}${focus}`;\n}\n\n/**\n * Messages as plain text, so the summarizer reads a transcript instead of continuing it. System messages are omitted.\n * Thinking is omitted too: providers return summaries of the real reasoning, and replayed thinking is often not part of\n * the live context (a block that does not match its request is dropped), so including it can make the request larger\n * than the context it summarizes. Visible text, tool calls, and tool results record what happened.\n */\nexport function serializeConversation(messages: readonly Message[]): string {\n\tconst parts: string[] = [];\n\tfor (const message of messages) {\n\t\tif (message.role === \"user\") {\n\t\t\tconst text = contentText(message.content);\n\t\t\tif (text.length > 0) parts.push(`[User]: ${text}`);\n\t\t} else if (message.role === \"assistant\") {\n\t\t\tconst text = message.content.flatMap((content) => (content.type === \"text\" ? [content.text] : []));\n\t\t\tconst calls = message.content.flatMap((content) =>\n\t\t\t\tcontent.type === \"toolCall\"\n\t\t\t\t\t? [\n\t\t\t\t\t\t\t`${content.name}(${Object.entries(content.arguments)\n\t\t\t\t\t\t\t\t.map(([key, value]) => `${key}=${JSON.stringify(value)}`)\n\t\t\t\t\t\t\t\t.join(\", \")})`,\n\t\t\t\t\t\t]\n\t\t\t\t\t: [],\n\t\t\t);\n\t\t\tif (text.length > 0) parts.push(`[Assistant]: ${text.join(\"\\n\")}`);\n\t\t\tif (calls.length > 0) parts.push(`[Assistant tool calls]: ${calls.join(\"; \")}`);\n\t\t} else if (message.role === \"toolResult\") {\n\t\t\tconst text = contentText(message.content);\n\t\t\tif (text.length > 0) parts.push(`[Tool result]: ${truncate(text, TOOL_RESULT_MAX_CHARS)}`);\n\t\t}\n\t}\n\treturn parts.join(\"\\n\\n\");\n}\n\nfunction contentText(content: string | readonly { readonly type: string; readonly text?: string }[]): string {\n\tif (typeof content === \"string\") return content;\n\treturn content\n\t\t.flatMap((block) => (block.type === \"text\" && block.text !== undefined ? [block.text] : []))\n\t\t.join(\"\\n\");\n}\n\nfunction truncate(text: string, maxChars: number): string {\n\tif (text.length <= maxChars) return text;\n\treturn `${text.slice(0, maxChars)}\\n\\n[... ${text.length - maxChars} more characters truncated]`;\n}\n\n/** Place a summary supplied by a hook in its own commit. */\nasync function place(runtime: Runtime, firstKept: EntryId, summary: string, context: Context): Promise<void> {\n\tawait runtime.commit(\n\t\tasync (tx, current) =>\n\t\t\tplaceSummary(tx, runtime, current, await tx.doc(LiveDoc, runtime.conversationId), firstKept, summary),\n\t\tcontext,\n\t);\n}\n\n/**\n * Place the summary entry and complete (spec §8.7). A blocking compaction, owned by its generation, appends it: the\n * generation holds the run and waits. A conversation-owned one admits it as a write submission, placed at once when\n * idle, otherwise at the next boundary, or settled `stale`.\n * REMINDER: nothing else may append to a busy conversation, so every non-blocking summary goes through admission.\n */\nasync function placeSummary(\n\ttx: Tx,\n\truntime: Runtime,\n\tcurrent: RunningTask<CompactionInput, CompactionCheckpoint, CompactionResult>,\n\tlive: Draft<LiveState>,\n\tfirstKept: EntryId,\n\tsummary: string,\n): Promise<Next> {\n\tremoveCompactionStatus(live, runtime.taskId);\n\tdelete live.compactionFailure;\n\tconst text = `${SUMMARY_PREFIX}${summary}${SUMMARY_SUFFIX}`;\n\tconst entry = {\n\t\tkind: CompactionEntry.kind,\n\t\thead: firstKept,\n\t\tmodel: [{ role: \"user\", content: [{ type: \"text\", text }], timestamp: runtime.now() }],\n\t\tdata: { reason: current.input.reason },\n\t} satisfies EntryDraft;\n\tconst result: CompactionResult =\n\t\tcurrent.owner === undefined\n\t\t\t? {\n\t\t\t\t\tsubmissionId: await admitSubmission(\n\t\t\t\t\t\ttx,\n\t\t\t\t\t\truntime.conversationId,\n\t\t\t\t\t\t{ type: \"write\", requestId: `compaction:${runtime.taskId}`, entry },\n\t\t\t\t\t\truntime.now(),\n\t\t\t\t\t\truntime.settings,\n\t\t\t\t\t),\n\t\t\t\t}\n\t\t\t: { entryId: (await tx.appendEntry(runtime.conversationId, entry)).id };\n\treturn { status: \"terminal\", outcome: { status: \"completed\", result } };\n}\n\n/** Remove the status and complete without a summary. */\nasync function complete(runtime: Runtime, context: Context): Promise<void> {\n\tawait runtime.commit(async (tx) => {\n\t\tremoveCompactionStatus(await tx.doc(LiveDoc, runtime.conversationId), runtime.taskId);\n\t\treturn { status: \"terminal\", outcome: { status: \"completed\", result: {} } };\n\t}, context);\n}\n\nasync function failNoModel(runtime: Runtime, ref: ModelRef | undefined, context: Context): Promise<void> {\n\tconst message =\n\t\tref === undefined ? \"No model is configured\" : `Model ${ref.provider}/${ref.modelId} is not available`;\n\tawait runtime.commit(async (tx) => {\n\t\tfailCompactionStatus(await tx.doc(LiveDoc, runtime.conversationId), runtime.taskId, message);\n\t\treturn { status: \"terminal\", outcome: { status: \"failed\", error: { message, detail: { reason: \"no_model\" } } } };\n\t}, context);\n}\n"]}
@@ -34,7 +34,11 @@ export type ContextRange = {
34
34
  readonly settled: readonly Message[];
35
35
  /** Contributed messages from the last assistant message on, before tool result ordering. */
36
36
  readonly open: readonly Message[];
37
+ /** The baseline's system message; see `findBaseline()`. */
38
+ readonly baseline: Baseline;
37
39
  };
40
+ /** A baseline's system message, `null` when the range cannot have one, or `undefined` while a later entry may be one. */
41
+ type Baseline = Message | null | undefined;
38
42
  /**
39
43
  * `readContext()` that reuses `previous`, an earlier range of the same conversation: with the same head marker, only
40
44
  * entries after its tail are scanned. Returns the view and the range to pass to the next read. A range outlives the
@@ -60,4 +64,5 @@ export declare function activeEntries(storage: Storage, conversationId: Conversa
60
64
  * the next assistant; a missing result is synthesized and unmatched results are dropped.
61
65
  */
62
66
  export declare function orderToolResults(messages: readonly Message[]): Message[];
67
+ export {};
63
68
  //# sourceMappingURL=context.d.ts.map
@@ -1 +1 @@
1
- {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/harness/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAoB,OAAO,EAA+B,MAAM,uBAAuB,CAAC;AAEpG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAe,cAAc,EAAU,OAAO,EAAc,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAClH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,iFAAiF;AACjF,MAAM,MAAM,aAAa,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IACtE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,EAChB,EAAE,CAAC,EAAE,OAAO,GACV,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAYpC;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;IACrC,4FAA4F;IAC5F,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;CAClC,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,OAAO,GAAG,SAAS,EACvB,QAAQ,EAAE,YAAY,GAAG,SAAS,GAChC,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,CAAA;CAAE,CAAC,CA6BnF;AAED,0GAA0G;AAC1G,wBAAsB,WAAW,CAChC,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,EAChB,EAAE,CAAC,EAAE,OAAO,GACV,OAAO,CAAC,WAAW,CAAC,CAGtB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAClC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,WAAW,CAAC,CAGtB;AAqFD,qFAAqF;AACrF,wBAAsB,aAAa,CAClC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAGjC;AA8BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,EAAE,CAsBxE"}
1
+ {"version":3,"file":"context.d.ts","sourceRoot":"","sources":["../../src/harness/context.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAoB,OAAO,EAA+B,MAAM,uBAAuB,CAAC;AAGpG,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AACzD,OAAO,KAAK,EAAe,cAAc,EAAU,OAAO,EAAc,WAAW,EAAE,OAAO,EAAE,MAAM,aAAa,CAAC;AAClH,OAAO,KAAK,EAAE,WAAW,EAAE,MAAM,YAAY,CAAC;AAM9C,iFAAiF;AACjF,MAAM,MAAM,aAAa,GAAG;IAC3B,QAAQ,CAAC,IAAI,EAAE,CAAC,WAAW,GAAG;QAAE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAA;KAAE,CAAC,GAAG,SAAS,CAAC;IACtE,QAAQ,CAAC,IAAI,EAAE,OAAO,CAAC;CACvB,CAAC;AAEF;;;;GAIG;AACH,wBAAsB,oBAAoB,CACzC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,EAChB,EAAE,CAAC,EAAE,OAAO,GACV,OAAO,CAAC,aAAa,GAAG,SAAS,CAAC,CAYpC;AAED;;;;GAIG;AACH,MAAM,MAAM,YAAY,GAAG;IAC1B,QAAQ,CAAC,MAAM,EAAE,aAAa,CAAC;IAC/B,QAAQ,CAAC,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IACzC,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAC3B,yCAAyC;IACzC,QAAQ,CAAC,MAAM,EAAE,WAAW,CAAC,OAAO,CAAC,CAAC;IACtC;;;OAGG;IACH,QAAQ,CAAC,OAAO,EAAE,SAAS,OAAO,EAAE,CAAC;IACrC,4FAA4F;IAC5F,QAAQ,CAAC,IAAI,EAAE,SAAS,OAAO,EAAE,CAAC;IAClC,2DAA2D;IAC3D,QAAQ,CAAC,QAAQ,EAAE,QAAQ,CAAC;CAC5B,CAAC;AAEF,yHAAyH;AACzH,KAAK,QAAQ,GAAG,OAAO,GAAG,IAAI,GAAG,SAAS,CAAC;AAE3C;;;;GAIG;AACH,wBAAsB,eAAe,CACpC,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,EAChB,EAAE,EAAE,OAAO,GAAG,SAAS,EACvB,QAAQ,EAAE,YAAY,GAAG,SAAS,GAChC,OAAO,CAAC;IAAE,QAAQ,CAAC,IAAI,EAAE,WAAW,CAAC;IAAC,QAAQ,CAAC,KAAK,EAAE,YAAY,GAAG,SAAS,CAAA;CAAE,CAAC,CA6BnF;AAED,0GAA0G;AAC1G,wBAAsB,WAAW,CAChC,OAAO,EAAE,WAAW,EACpB,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,EAChB,EAAE,CAAC,EAAE,OAAO,GACV,OAAO,CAAC,WAAW,CAAC,CAGtB;AAED;;;;;GAKG;AACH,wBAAsB,aAAa,CAClC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,WAAW,CAAC,CAGtB;AAuHD,qFAAqF;AACrF,wBAAsB,aAAa,CAClC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,MAAM,EAAE,aAAa,GAAG,SAAS,EACjC,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,SAAS,WAAW,EAAE,CAAC,CAGjC;AA8BD;;;GAGG;AACH,wBAAgB,gBAAgB,CAAC,QAAQ,EAAE,SAAS,OAAO,EAAE,GAAG,OAAO,EAAE,CAsBxE"}
@@ -1,3 +1,4 @@
1
+ import { SystemEntry } from "../entries.js";
1
2
  import { idFromNumber } from "../ids.js";
2
3
  const SCAN_PAGE_SIZE = 256;
3
4
  const EXCLUDED_STOP_REASONS = new Set(["aborted", "error", "deferred"]);
@@ -87,9 +88,10 @@ function deriveRange(bounds, entries) {
87
88
  const active = selectActive(bounds.head, entries);
88
89
  const contributions = active.map((entry) => contribute(entry, edits.get(entry.id)));
89
90
  const { settled, open } = settle([], contributions.flat());
90
- const messages = leadWithSystem([...settled, ...orderToolResults(open)]);
91
+ const baseline = findBaseline(bounds.head, active);
92
+ const messages = leadWithSystem([...settled, ...orderToolResults(open)], baseline);
91
93
  const view = { head: bounds.head, entries: active, contributions, messages };
92
- return { bounds, entries, view, edited: new Set(edits.keys()), settled, open };
94
+ return { bounds, entries, view, edited: new Set(edits.keys()), settled, open, baseline };
93
95
  }
94
96
  /**
95
97
  * `previous` extended by the entries `added` after its tail under the same head marker: only their contributions and
@@ -102,25 +104,57 @@ function extendRange(previous, bounds, added) {
102
104
  }
103
105
  const contributions = added.map((entry) => contribute(entry, undefined));
104
106
  const { settled, open } = settle(previous.settled, [...previous.open, ...contributions.flat()]);
107
+ const baseline = previous.baseline !== undefined ? previous.baseline : findBaseline(bounds.head, added);
105
108
  const view = {
106
109
  head: bounds.head,
107
110
  entries: [...previous.view.entries, ...added],
108
111
  contributions: [...previous.view.contributions, ...contributions],
109
- messages: leadWithSystem([...settled, ...orderToolResults(open)]),
112
+ messages: leadWithSystem([...settled, ...orderToolResults(open)], baseline),
110
113
  };
111
- return { bounds, entries, view, edited: previous.edited, settled, open };
114
+ return { bounds, entries, view, edited: previous.edited, settled, open, baseline };
112
115
  }
113
116
  /**
114
- * Move a system message that only user messages precede to the front. A run's input is committed before generation
115
- * renders the system prompt, so a transcript, or the range after a compaction or reset, starts with user messages
116
- * followed by the baseline system message. Providers treat only a leading system message as the initial prompt and tool
117
- * set; without it, a later tool change rewrites the request's tool list and invalidates the whole prompt cache.
117
+ * The baseline among `entries`, oldest first: the system message of the first `pi.system` entry after the head
118
+ * marker, or of the transcript without one, when generation wrote it with every section and tool in effect. After a
119
+ * head marker it always does, and omits the retained `pi.system` entries. Without one it does when it saw no system
120
+ * message before, which holds unless an earlier entry carries one, even if an edit omits it later. An edit that targets
121
+ * the baseline contributes other messages, or none, so none leads; a later entry does not take its place.
118
122
  */
119
- function leadWithSystem(messages) {
120
- const index = messages.findIndex((message) => message.role !== "user");
121
- if (index <= 0 || messages[index].role !== "system")
123
+ function findBaseline(head, entries) {
124
+ for (const entry of entries) {
125
+ if (head !== undefined && entry.id <= head.id)
126
+ continue;
127
+ if (SystemEntry.is(entry))
128
+ return entry.model?.find((message) => message.role === "system") ?? null;
129
+ if (head === undefined && carriesSystemMessage(entry))
130
+ return null;
131
+ }
132
+ return undefined;
133
+ }
134
+ /** Whether an entry's own messages, or the replacement messages of its edits, include a system message. */
135
+ function carriesSystemMessage(entry) {
136
+ const isSystem = (message) => message.role === "system";
137
+ return ((entry.model?.some(isSystem) ?? false) ||
138
+ (entry.edits?.some((edit) => edit.action === "replace" && edit.messages.some(isSystem)) ?? false));
139
+ }
140
+ /**
141
+ * Move the first system message to the front when only user messages precede it, or when it is the baseline's. A run's
142
+ * input is committed before generation renders the system prompt, so a transcript starts with the input followed by
143
+ * the baseline, and the range after a compaction with the kept history, assistant messages included. Providers treat
144
+ * only a leading system message as the initial prompt and tool set; without it, a later tool change rewrites the
145
+ * request's tool list and invalidates the whole prompt cache. Only the first system message moves, so replaying
146
+ * system messages in order gives the same sections and tools. Any other system message, before an assistant message,
147
+ * stays where it was committed: moving it would change what it means to the model.
148
+ */
149
+ function leadWithSystem(messages, baseline) {
150
+ const index = messages.findIndex((message) => message.role === "system");
151
+ if (index <= 0)
122
152
  return messages;
123
- return [messages[index], ...messages.slice(0, index), ...messages.slice(index + 1)];
153
+ const system = messages[index];
154
+ if (system !== baseline && messages.slice(0, index).some((message) => message.role !== "user")) {
155
+ return messages;
156
+ }
157
+ return [system, ...messages.slice(0, index), ...messages.slice(index + 1)];
124
158
  }
125
159
  /** One active entry's model messages after its edit and excluded stop reasons, before tool result ordering. */
126
160
  function contribute(entry, edit) {
@@ -1 +1 @@
1
- {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/harness/context.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport type { AssistantMessage, Message, ToolCall, ToolResultMessage } from \"@earendil-works/pi-ai\";\nimport { idFromNumber } from \"../ids.ts\";\nimport type { SessionImpl } from \"../session/session.ts\";\nimport type { ContextEdit, ConversationId, Cursor, EntryId, EntryQuery, EntryRecord, Storage } from \"../types.ts\";\nimport type { ContextView } from \"./types.ts\";\n\nconst SCAN_PAGE_SIZE = 256;\nconst EXCLUDED_STOP_REASONS: ReadonlySet<AssistantMessage[\"stopReason\"]> = new Set([\"aborted\", \"error\", \"deferred\"]);\nconst MISSING_RESULT_TEXT = \"Tool result unavailable: history ends before this call completed.\";\n\n/** Head marker and newest visible entry that fix one committed context range. */\nexport type ContextBounds = {\n\treadonly head: (EntryRecord & { readonly head: EntryId }) | undefined;\n\treadonly tail: EntryId;\n};\n\n/**\n * Capture the bounds of the current context, or of the context cut off at the visible entry `at`, with two O(1)\n * reads. Run this on the Session line; entries at or below the tail are immutable, so `deriveContext()` can then scan\n * them off the line.\n */\nexport async function captureContextBounds(\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tcontext: Context,\n\tat?: EntryId,\n): Promise<ContextBounds | undefined> {\n\tlet tail: EntryId | undefined;\n\tif (at === undefined) {\n\t\ttail = (await storage.scanEntries({ conversationId }, 1, undefined, context)).items[0]?.id;\n\t\tif (tail === undefined) return undefined;\n\t} else {\n\t\tif ((await storage.entry(conversationId, at, context)) === undefined) {\n\t\t\tthrow new Error(`Entry ${at} is not visible from conversation ${conversationId}`);\n\t\t}\n\t\ttail = at;\n\t}\n\treturn { head: await storage.findLatestHeadMarker(conversationId, tail, context), tail };\n}\n\n/**\n * One context read: the visible entries it scanned, from the head marker's head, or transcript start, through\n * `bounds.tail`, oldest first, and the view derived from them. Entries at or below the tail never change, so a later\n * read with the same head marker extends both.\n */\nexport type ContextRange = {\n\treadonly bounds: ContextBounds;\n\treadonly entries: readonly EntryRecord[];\n\treadonly view: ContextView;\n\t/** Targets of the edits in `entries`. */\n\treadonly edited: ReadonlySet<EntryId>;\n\t/**\n\t * `view.messages` from the contributed messages before the last assistant message. Tool results are ordered within\n\t * the messages up to the next assistant message, so later entries cannot change these.\n\t */\n\treadonly settled: readonly Message[];\n\t/** Contributed messages from the last assistant message on, before tool result ordering. */\n\treadonly open: readonly Message[];\n};\n\n/**\n * `readContext()` that reuses `previous`, an earlier range of the same conversation: with the same head marker, only\n * entries after its tail are scanned. Returns the view and the range to pass to the next read. A range outlives the\n * read, so its entries are frozen like `MemoryStorage` records, and the returned view has its own arrays.\n */\nexport async function readContextFrom(\n\tsession: SessionImpl,\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tcontext: Context,\n\tat: EntryId | undefined,\n\tprevious: ContextRange | undefined,\n): Promise<{ readonly view: ContextView; readonly range: ContextRange | undefined }> {\n\tconst bounds = await session.readOnLine(() => captureContextBounds(storage, conversationId, context, at));\n\tif (bounds === undefined) return { view: emptyView(), range: undefined };\n\tfreezeJson(bounds.head);\n\tlet range: ContextRange;\n\tif (previous === undefined || previous.bounds.head?.id !== bounds.head?.id) {\n\t\trange = deriveRange(bounds, freezeJson(await scanRange(storage, conversationId, rangeQuery(bounds), context)));\n\t} else if (bounds.tail === previous.bounds.tail) {\n\t\trange = previous;\n\t} else if (bounds.tail < previous.bounds.tail) {\n\t\trange = deriveRange(\n\t\t\tbounds,\n\t\t\tprevious.entries.filter((entry) => entry.id <= bounds.tail),\n\t\t);\n\t} else {\n\t\tconst minEntryId = idFromNumber<EntryId>(previous.bounds.tail + 1);\n\t\tconst added = await scanRange(storage, conversationId, { minEntryId, maxEntryId: bounds.tail }, context);\n\t\trange = extendRange(previous, bounds, freezeJson(added));\n\t}\n\tconst { view } = range;\n\treturn {\n\t\tview: {\n\t\t\t...view,\n\t\t\tentries: [...view.entries],\n\t\t\tcontributions: [...view.contributions],\n\t\t\tmessages: [...view.messages],\n\t\t},\n\t\trange,\n\t};\n}\n\n/** Committed context of one conversation: bounds captured on the Session line, entries derived off it. */\nexport async function readContext(\n\tsession: SessionImpl,\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tcontext: Context,\n\tat?: EntryId,\n): Promise<ContextView> {\n\tconst bounds = await session.readOnLine(() => captureContextBounds(storage, conversationId, context, at));\n\treturn deriveContext(storage, conversationId, bounds, context);\n}\n\n/**\n * Derive the active transcript and model context of one conversation within captured bounds.\n *\n * H = newest visible head marker; the range runs from `H.head` (or transcript start) through the tail. Per target,\n * the newest edit in the range wins. Context entries are H followed by the range's non-head entries.\n */\nexport async function deriveContext(\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tbounds: ContextBounds | undefined,\n\tcontext: Context,\n): Promise<ContextView> {\n\tif (bounds === undefined) return emptyView();\n\treturn deriveRange(bounds, await scanRange(storage, conversationId, rangeQuery(bounds), context)).view;\n}\n\nfunction emptyView(): ContextView {\n\treturn { head: undefined, entries: [], contributions: [], messages: [] };\n}\n\n/** Derive the context view from the entries scanned within `bounds`. */\nfunction deriveRange(bounds: ContextBounds, entries: readonly EntryRecord[]): ContextRange {\n\tconst edits = new Map<EntryId, ContextEdit>();\n\t// Edits of every entry in the range count, including older head markers that `selectActive()` drops.\n\tfor (const entry of entries) for (const edit of entry.edits ?? []) edits.set(edit.target, edit);\n\tconst active = selectActive(bounds.head, entries);\n\tconst contributions = active.map((entry) => contribute(entry, edits.get(entry.id)));\n\tconst { settled, open } = settle([], contributions.flat());\n\tconst messages = leadWithSystem([...settled, ...orderToolResults(open)]);\n\tconst view = { head: bounds.head, entries: active, contributions, messages };\n\treturn { bounds, entries, view, edited: new Set(edits.keys()), settled, open };\n}\n\n/**\n * `previous` extended by the entries `added` after its tail under the same head marker: only their contributions and\n * the open messages are derived. An added edit can change an earlier entry, so it derives the whole range again.\n */\nfunction extendRange(previous: ContextRange, bounds: ContextBounds, added: readonly EntryRecord[]): ContextRange {\n\tconst entries = [...previous.entries, ...added];\n\tif (added.some((entry) => entry.edits !== undefined || entry.head !== undefined || previous.edited.has(entry.id))) {\n\t\treturn deriveRange(bounds, entries);\n\t}\n\tconst contributions = added.map((entry) => contribute(entry, undefined));\n\tconst { settled, open } = settle(previous.settled, [...previous.open, ...contributions.flat()]);\n\tconst view = {\n\t\thead: bounds.head,\n\t\tentries: [...previous.view.entries, ...added],\n\t\tcontributions: [...previous.view.contributions, ...contributions],\n\t\tmessages: leadWithSystem([...settled, ...orderToolResults(open)]),\n\t};\n\treturn { bounds, entries, view, edited: previous.edited, settled, open };\n}\n\n/**\n * Move a system message that only user messages precede to the front. A run's input is committed before generation\n * renders the system prompt, so a transcript, or the range after a compaction or reset, starts with user messages\n * followed by the baseline system message. Providers treat only a leading system message as the initial prompt and tool\n * set; without it, a later tool change rewrites the request's tool list and invalidates the whole prompt cache.\n */\nfunction leadWithSystem(messages: Message[]): Message[] {\n\tconst index = messages.findIndex((message) => message.role !== \"user\");\n\tif (index <= 0 || messages[index]!.role !== \"system\") return messages;\n\treturn [messages[index]!, ...messages.slice(0, index), ...messages.slice(index + 1)];\n}\n\n/** One active entry's model messages after its edit and excluded stop reasons, before tool result ordering. */\nfunction contribute(entry: EntryRecord, edit: ContextEdit | undefined): readonly Message[] {\n\tif (edit?.action === \"omit\") return Object.freeze([]);\n\tconst contributed = edit?.action === \"replace\" ? edit.messages : (entry.model ?? []);\n\treturn Object.freeze(\n\t\tcontributed.filter((message) => message.role !== \"assistant\" || !EXCLUDED_STOP_REASONS.has(message.stopReason)),\n\t);\n}\n\n/** Objects `freezeJson()` froze with everything in them. `Object.isFrozen()` holds for shallow freezes too. */\nconst deeplyFrozen = new WeakSet<object>();\n\n/** Freeze a JSON value and everything in it. */\nfunction freezeJson<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || deeplyFrozen.has(value)) return value;\n\tfor (const child of Object.values(value)) freezeJson(child);\n\tObject.freeze(value);\n\tdeeplyFrozen.add(value);\n\treturn value;\n}\n\n/**\n * Move the ordered messages before the last assistant message of `open` to `settled`. `orderToolResults()` of a\n * sequence equals the concatenation over its parts when each later part starts with an assistant message.\n */\nfunction settle(\n\tsettled: readonly Message[],\n\topen: readonly Message[],\n): { readonly settled: readonly Message[]; readonly open: readonly Message[] } {\n\tconst last = open.findLastIndex((message) => message.role === \"assistant\");\n\tif (last <= 0) return { settled, open };\n\treturn { settled: [...settled, ...orderToolResults(open.slice(0, last))], open: open.slice(last) };\n}\n\n/** The raw active entries within captured bounds, without deriving model context. */\nexport async function activeEntries(\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tbounds: ContextBounds | undefined,\n\tcontext: Context,\n): Promise<readonly EntryRecord[]> {\n\tif (bounds === undefined) return [];\n\treturn selectActive(bounds.head, await scanRange(storage, conversationId, rangeQuery(bounds), context));\n}\n\n/** The visible range of `bounds`: from the head marker's head, or transcript start, through the tail. */\nfunction rangeQuery(bounds: ContextBounds): Omit<EntryQuery, \"conversationId\"> {\n\tconst head = bounds.head;\n\treturn head === undefined ? { maxEntryId: bounds.tail } : { minEntryId: head.head, maxEntryId: bounds.tail };\n}\n\n/** Visible entries within `range`, oldest first. */\nasync function scanRange(\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\trange: Omit<EntryQuery, \"conversationId\">,\n\tcontext: Context,\n): Promise<EntryRecord[]> {\n\tconst entries: EntryRecord[] = [];\n\tlet cursor: Cursor | undefined;\n\tdo {\n\t\tconst page = await storage.scanEntries({ conversationId, ...range }, SCAN_PAGE_SIZE, cursor, context);\n\t\tentries.push(...page.items);\n\t\tcursor = page.next;\n\t} while (cursor !== undefined);\n\treturn entries.reverse();\n}\n\n/** The head marker followed by the range's non-head entries, or the whole range without a marker. */\nfunction selectActive(head: ContextBounds[\"head\"], range: readonly EntryRecord[]): readonly EntryRecord[] {\n\treturn head === undefined ? range : [head, ...range.filter((entry) => entry.head === undefined)];\n}\n\n/**\n * Place each assistant's tool results directly after it in call order. Results are taken from the messages before\n * the next assistant; a missing result is synthesized and unmatched results are dropped.\n */\nexport function orderToolResults(messages: readonly Message[]): Message[] {\n\tconst ordered: Message[] = [];\n\tfor (let index = 0; index < messages.length; index++) {\n\t\tconst message = messages[index]!;\n\t\tif (message.role === \"toolResult\") continue;\n\t\tordered.push(message);\n\t\tif (message.role !== \"assistant\") continue;\n\t\tconst calls = message.content.filter((content): content is ToolCall => content.type === \"toolCall\");\n\t\tif (calls.length === 0) continue;\n\t\tconst results = new Map<string, number>();\n\t\tfor (let next = index + 1; next < messages.length && messages[next]!.role !== \"assistant\"; next++) {\n\t\t\tconst candidate = messages[next]!;\n\t\t\tif (candidate.role === \"toolResult\" && !results.has(candidate.toolCallId)) {\n\t\t\t\tresults.set(candidate.toolCallId, next);\n\t\t\t}\n\t\t}\n\t\tfor (const call of calls) {\n\t\t\tconst resultIndex = results.get(call.id);\n\t\t\tordered.push(resultIndex === undefined ? missingResult(call, message.timestamp) : messages[resultIndex]!);\n\t\t}\n\t}\n\treturn ordered;\n}\n\nfunction missingResult(call: ToolCall, timestamp: number): ToolResultMessage {\n\treturn freezeJson({\n\t\trole: \"toolResult\",\n\t\ttoolCallId: call.id,\n\t\ttoolName: call.name,\n\t\tcontent: [{ type: \"text\", text: MISSING_RESULT_TEXT }],\n\t\tisError: true,\n\t\tdetails: { reason: \"missing_result\" },\n\t\ttimestamp,\n\t});\n}\n"]}
1
+ {"version":3,"file":"context.js","sourceRoot":"","sources":["../../src/harness/context.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context } from \"@earendil-works/chord\";\nimport type { AssistantMessage, Message, ToolCall, ToolResultMessage } from \"@earendil-works/pi-ai\";\nimport { SystemEntry } from \"../entries.ts\";\nimport { idFromNumber } from \"../ids.ts\";\nimport type { SessionImpl } from \"../session/session.ts\";\nimport type { ContextEdit, ConversationId, Cursor, EntryId, EntryQuery, EntryRecord, Storage } from \"../types.ts\";\nimport type { ContextView } from \"./types.ts\";\n\nconst SCAN_PAGE_SIZE = 256;\nconst EXCLUDED_STOP_REASONS: ReadonlySet<AssistantMessage[\"stopReason\"]> = new Set([\"aborted\", \"error\", \"deferred\"]);\nconst MISSING_RESULT_TEXT = \"Tool result unavailable: history ends before this call completed.\";\n\n/** Head marker and newest visible entry that fix one committed context range. */\nexport type ContextBounds = {\n\treadonly head: (EntryRecord & { readonly head: EntryId }) | undefined;\n\treadonly tail: EntryId;\n};\n\n/**\n * Capture the bounds of the current context, or of the context cut off at the visible entry `at`, with two O(1)\n * reads. Run this on the Session line; entries at or below the tail are immutable, so `deriveContext()` can then scan\n * them off the line.\n */\nexport async function captureContextBounds(\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tcontext: Context,\n\tat?: EntryId,\n): Promise<ContextBounds | undefined> {\n\tlet tail: EntryId | undefined;\n\tif (at === undefined) {\n\t\ttail = (await storage.scanEntries({ conversationId }, 1, undefined, context)).items[0]?.id;\n\t\tif (tail === undefined) return undefined;\n\t} else {\n\t\tif ((await storage.entry(conversationId, at, context)) === undefined) {\n\t\t\tthrow new Error(`Entry ${at} is not visible from conversation ${conversationId}`);\n\t\t}\n\t\ttail = at;\n\t}\n\treturn { head: await storage.findLatestHeadMarker(conversationId, tail, context), tail };\n}\n\n/**\n * One context read: the visible entries it scanned, from the head marker's head, or transcript start, through\n * `bounds.tail`, oldest first, and the view derived from them. Entries at or below the tail never change, so a later\n * read with the same head marker extends both.\n */\nexport type ContextRange = {\n\treadonly bounds: ContextBounds;\n\treadonly entries: readonly EntryRecord[];\n\treadonly view: ContextView;\n\t/** Targets of the edits in `entries`. */\n\treadonly edited: ReadonlySet<EntryId>;\n\t/**\n\t * `view.messages` from the contributed messages before the last assistant message. Tool results are ordered within\n\t * the messages up to the next assistant message, so later entries cannot change these.\n\t */\n\treadonly settled: readonly Message[];\n\t/** Contributed messages from the last assistant message on, before tool result ordering. */\n\treadonly open: readonly Message[];\n\t/** The baseline's system message; see `findBaseline()`. */\n\treadonly baseline: Baseline;\n};\n\n/** A baseline's system message, `null` when the range cannot have one, or `undefined` while a later entry may be one. */\ntype Baseline = Message | null | undefined;\n\n/**\n * `readContext()` that reuses `previous`, an earlier range of the same conversation: with the same head marker, only\n * entries after its tail are scanned. Returns the view and the range to pass to the next read. A range outlives the\n * read, so its entries are frozen like `MemoryStorage` records, and the returned view has its own arrays.\n */\nexport async function readContextFrom(\n\tsession: SessionImpl,\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tcontext: Context,\n\tat: EntryId | undefined,\n\tprevious: ContextRange | undefined,\n): Promise<{ readonly view: ContextView; readonly range: ContextRange | undefined }> {\n\tconst bounds = await session.readOnLine(() => captureContextBounds(storage, conversationId, context, at));\n\tif (bounds === undefined) return { view: emptyView(), range: undefined };\n\tfreezeJson(bounds.head);\n\tlet range: ContextRange;\n\tif (previous === undefined || previous.bounds.head?.id !== bounds.head?.id) {\n\t\trange = deriveRange(bounds, freezeJson(await scanRange(storage, conversationId, rangeQuery(bounds), context)));\n\t} else if (bounds.tail === previous.bounds.tail) {\n\t\trange = previous;\n\t} else if (bounds.tail < previous.bounds.tail) {\n\t\trange = deriveRange(\n\t\t\tbounds,\n\t\t\tprevious.entries.filter((entry) => entry.id <= bounds.tail),\n\t\t);\n\t} else {\n\t\tconst minEntryId = idFromNumber<EntryId>(previous.bounds.tail + 1);\n\t\tconst added = await scanRange(storage, conversationId, { minEntryId, maxEntryId: bounds.tail }, context);\n\t\trange = extendRange(previous, bounds, freezeJson(added));\n\t}\n\tconst { view } = range;\n\treturn {\n\t\tview: {\n\t\t\t...view,\n\t\t\tentries: [...view.entries],\n\t\t\tcontributions: [...view.contributions],\n\t\t\tmessages: [...view.messages],\n\t\t},\n\t\trange,\n\t};\n}\n\n/** Committed context of one conversation: bounds captured on the Session line, entries derived off it. */\nexport async function readContext(\n\tsession: SessionImpl,\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tcontext: Context,\n\tat?: EntryId,\n): Promise<ContextView> {\n\tconst bounds = await session.readOnLine(() => captureContextBounds(storage, conversationId, context, at));\n\treturn deriveContext(storage, conversationId, bounds, context);\n}\n\n/**\n * Derive the active transcript and model context of one conversation within captured bounds.\n *\n * H = newest visible head marker; the range runs from `H.head` (or transcript start) through the tail. Per target,\n * the newest edit in the range wins. Context entries are H followed by the range's non-head entries.\n */\nexport async function deriveContext(\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tbounds: ContextBounds | undefined,\n\tcontext: Context,\n): Promise<ContextView> {\n\tif (bounds === undefined) return emptyView();\n\treturn deriveRange(bounds, await scanRange(storage, conversationId, rangeQuery(bounds), context)).view;\n}\n\nfunction emptyView(): ContextView {\n\treturn { head: undefined, entries: [], contributions: [], messages: [] };\n}\n\n/** Derive the context view from the entries scanned within `bounds`. */\nfunction deriveRange(bounds: ContextBounds, entries: readonly EntryRecord[]): ContextRange {\n\tconst edits = new Map<EntryId, ContextEdit>();\n\t// Edits of every entry in the range count, including older head markers that `selectActive()` drops.\n\tfor (const entry of entries) for (const edit of entry.edits ?? []) edits.set(edit.target, edit);\n\tconst active = selectActive(bounds.head, entries);\n\tconst contributions = active.map((entry) => contribute(entry, edits.get(entry.id)));\n\tconst { settled, open } = settle([], contributions.flat());\n\tconst baseline = findBaseline(bounds.head, active);\n\tconst messages = leadWithSystem([...settled, ...orderToolResults(open)], baseline);\n\tconst view = { head: bounds.head, entries: active, contributions, messages };\n\treturn { bounds, entries, view, edited: new Set(edits.keys()), settled, open, baseline };\n}\n\n/**\n * `previous` extended by the entries `added` after its tail under the same head marker: only their contributions and\n * the open messages are derived. An added edit can change an earlier entry, so it derives the whole range again.\n */\nfunction extendRange(previous: ContextRange, bounds: ContextBounds, added: readonly EntryRecord[]): ContextRange {\n\tconst entries = [...previous.entries, ...added];\n\tif (added.some((entry) => entry.edits !== undefined || entry.head !== undefined || previous.edited.has(entry.id))) {\n\t\treturn deriveRange(bounds, entries);\n\t}\n\tconst contributions = added.map((entry) => contribute(entry, undefined));\n\tconst { settled, open } = settle(previous.settled, [...previous.open, ...contributions.flat()]);\n\tconst baseline = previous.baseline !== undefined ? previous.baseline : findBaseline(bounds.head, added);\n\tconst view = {\n\t\thead: bounds.head,\n\t\tentries: [...previous.view.entries, ...added],\n\t\tcontributions: [...previous.view.contributions, ...contributions],\n\t\tmessages: leadWithSystem([...settled, ...orderToolResults(open)], baseline),\n\t};\n\treturn { bounds, entries, view, edited: previous.edited, settled, open, baseline };\n}\n\n/**\n * The baseline among `entries`, oldest first: the system message of the first `pi.system` entry after the head\n * marker, or of the transcript without one, when generation wrote it with every section and tool in effect. After a\n * head marker it always does, and omits the retained `pi.system` entries. Without one it does when it saw no system\n * message before, which holds unless an earlier entry carries one, even if an edit omits it later. An edit that targets\n * the baseline contributes other messages, or none, so none leads; a later entry does not take its place.\n */\nfunction findBaseline(head: ContextBounds[\"head\"], entries: readonly EntryRecord[]): Baseline {\n\tfor (const entry of entries) {\n\t\tif (head !== undefined && entry.id <= head.id) continue;\n\t\tif (SystemEntry.is(entry)) return entry.model?.find((message) => message.role === \"system\") ?? null;\n\t\tif (head === undefined && carriesSystemMessage(entry)) return null;\n\t}\n\treturn undefined;\n}\n\n/** Whether an entry's own messages, or the replacement messages of its edits, include a system message. */\nfunction carriesSystemMessage(entry: EntryRecord): boolean {\n\tconst isSystem = (message: Message) => message.role === \"system\";\n\treturn (\n\t\t(entry.model?.some(isSystem) ?? false) ||\n\t\t(entry.edits?.some((edit) => edit.action === \"replace\" && edit.messages.some(isSystem)) ?? false)\n\t);\n}\n\n/**\n * Move the first system message to the front when only user messages precede it, or when it is the baseline's. A run's\n * input is committed before generation renders the system prompt, so a transcript starts with the input followed by\n * the baseline, and the range after a compaction with the kept history, assistant messages included. Providers treat\n * only a leading system message as the initial prompt and tool set; without it, a later tool change rewrites the\n * request's tool list and invalidates the whole prompt cache. Only the first system message moves, so replaying\n * system messages in order gives the same sections and tools. Any other system message, before an assistant message,\n * stays where it was committed: moving it would change what it means to the model.\n */\nfunction leadWithSystem(messages: Message[], baseline: Baseline): Message[] {\n\tconst index = messages.findIndex((message) => message.role === \"system\");\n\tif (index <= 0) return messages;\n\tconst system = messages[index]!;\n\tif (system !== baseline && messages.slice(0, index).some((message) => message.role !== \"user\")) {\n\t\treturn messages;\n\t}\n\treturn [system, ...messages.slice(0, index), ...messages.slice(index + 1)];\n}\n\n/** One active entry's model messages after its edit and excluded stop reasons, before tool result ordering. */\nfunction contribute(entry: EntryRecord, edit: ContextEdit | undefined): readonly Message[] {\n\tif (edit?.action === \"omit\") return Object.freeze([]);\n\tconst contributed = edit?.action === \"replace\" ? edit.messages : (entry.model ?? []);\n\treturn Object.freeze(\n\t\tcontributed.filter((message) => message.role !== \"assistant\" || !EXCLUDED_STOP_REASONS.has(message.stopReason)),\n\t);\n}\n\n/** Objects `freezeJson()` froze with everything in them. `Object.isFrozen()` holds for shallow freezes too. */\nconst deeplyFrozen = new WeakSet<object>();\n\n/** Freeze a JSON value and everything in it. */\nfunction freezeJson<T>(value: T): T {\n\tif (value === null || typeof value !== \"object\" || deeplyFrozen.has(value)) return value;\n\tfor (const child of Object.values(value)) freezeJson(child);\n\tObject.freeze(value);\n\tdeeplyFrozen.add(value);\n\treturn value;\n}\n\n/**\n * Move the ordered messages before the last assistant message of `open` to `settled`. `orderToolResults()` of a\n * sequence equals the concatenation over its parts when each later part starts with an assistant message.\n */\nfunction settle(\n\tsettled: readonly Message[],\n\topen: readonly Message[],\n): { readonly settled: readonly Message[]; readonly open: readonly Message[] } {\n\tconst last = open.findLastIndex((message) => message.role === \"assistant\");\n\tif (last <= 0) return { settled, open };\n\treturn { settled: [...settled, ...orderToolResults(open.slice(0, last))], open: open.slice(last) };\n}\n\n/** The raw active entries within captured bounds, without deriving model context. */\nexport async function activeEntries(\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\tbounds: ContextBounds | undefined,\n\tcontext: Context,\n): Promise<readonly EntryRecord[]> {\n\tif (bounds === undefined) return [];\n\treturn selectActive(bounds.head, await scanRange(storage, conversationId, rangeQuery(bounds), context));\n}\n\n/** The visible range of `bounds`: from the head marker's head, or transcript start, through the tail. */\nfunction rangeQuery(bounds: ContextBounds): Omit<EntryQuery, \"conversationId\"> {\n\tconst head = bounds.head;\n\treturn head === undefined ? { maxEntryId: bounds.tail } : { minEntryId: head.head, maxEntryId: bounds.tail };\n}\n\n/** Visible entries within `range`, oldest first. */\nasync function scanRange(\n\tstorage: Storage,\n\tconversationId: ConversationId,\n\trange: Omit<EntryQuery, \"conversationId\">,\n\tcontext: Context,\n): Promise<EntryRecord[]> {\n\tconst entries: EntryRecord[] = [];\n\tlet cursor: Cursor | undefined;\n\tdo {\n\t\tconst page = await storage.scanEntries({ conversationId, ...range }, SCAN_PAGE_SIZE, cursor, context);\n\t\tentries.push(...page.items);\n\t\tcursor = page.next;\n\t} while (cursor !== undefined);\n\treturn entries.reverse();\n}\n\n/** The head marker followed by the range's non-head entries, or the whole range without a marker. */\nfunction selectActive(head: ContextBounds[\"head\"], range: readonly EntryRecord[]): readonly EntryRecord[] {\n\treturn head === undefined ? range : [head, ...range.filter((entry) => entry.head === undefined)];\n}\n\n/**\n * Place each assistant's tool results directly after it in call order. Results are taken from the messages before\n * the next assistant; a missing result is synthesized and unmatched results are dropped.\n */\nexport function orderToolResults(messages: readonly Message[]): Message[] {\n\tconst ordered: Message[] = [];\n\tfor (let index = 0; index < messages.length; index++) {\n\t\tconst message = messages[index]!;\n\t\tif (message.role === \"toolResult\") continue;\n\t\tordered.push(message);\n\t\tif (message.role !== \"assistant\") continue;\n\t\tconst calls = message.content.filter((content): content is ToolCall => content.type === \"toolCall\");\n\t\tif (calls.length === 0) continue;\n\t\tconst results = new Map<string, number>();\n\t\tfor (let next = index + 1; next < messages.length && messages[next]!.role !== \"assistant\"; next++) {\n\t\t\tconst candidate = messages[next]!;\n\t\t\tif (candidate.role === \"toolResult\" && !results.has(candidate.toolCallId)) {\n\t\t\t\tresults.set(candidate.toolCallId, next);\n\t\t\t}\n\t\t}\n\t\tfor (const call of calls) {\n\t\t\tconst resultIndex = results.get(call.id);\n\t\t\tordered.push(resultIndex === undefined ? missingResult(call, message.timestamp) : messages[resultIndex]!);\n\t\t}\n\t}\n\treturn ordered;\n}\n\nfunction missingResult(call: ToolCall, timestamp: number): ToolResultMessage {\n\treturn freezeJson({\n\t\trole: \"toolResult\",\n\t\ttoolCallId: call.id,\n\t\ttoolName: call.name,\n\t\tcontent: [{ type: \"text\", text: MISSING_RESULT_TEXT }],\n\t\tisError: true,\n\t\tdetails: { reason: \"missing_result\" },\n\t\ttimestamp,\n\t});\n}\n"]}
@@ -2,8 +2,8 @@ import type { Context, JsonValue } from "@earendil-works/chord";
2
2
  import type { AssistantMessage, Message, Usage } from "@earendil-works/pi-ai";
3
3
  import type { ConversationId, EntryRecord, JsonObject, SubmissionId, SubmissionRecord, TaskId, WatchEnd } from "../types.ts";
4
4
  import type { InboxItem } from "./inbox.ts";
5
- import type { CompactionStatus, ToolSlot } from "./live.ts";
6
- import type { AgentState, CompactionReason, Harness, ToolDiagnostic } from "./types.ts";
5
+ import type { CompactionFailure, CompactionStatus, NestedToolSlot, ToolSlot } from "./live.ts";
6
+ import type { AgentState, CompactionReason, Harness, NestedToolExecutionResult, ToolDiagnostic } from "./types.ts";
7
7
  import { type UsageState } from "./usage.ts";
8
8
  type Block = AssistantMessage["content"][number];
9
9
  type QueuedItem = {
@@ -51,8 +51,12 @@ export type SnapshotEvent = {
51
51
  };
52
52
  };
53
53
  tools: readonly ToolSlot[];
54
+ /** `pi.live.nestedTools`: nested calls of running tool calls. */
55
+ nestedTools: readonly NestedToolSlot[];
54
56
  /** `pi.live.compactions`: live compactions with their attempt and retry backoff. */
55
57
  compactions: readonly CompactionStatus[];
58
+ /** `pi.live.compactionFailure`: the newest compaction failure since a compaction last produced a summary. */
59
+ compactionFailure?: CompactionFailure;
56
60
  inbox: readonly QueuedItem[];
57
61
  /** `pi.agent`; `{}` when absent. */
58
62
  agent: AgentState;
@@ -81,15 +85,11 @@ export type AgentEvent = SnapshotEvent | {
81
85
  } | {
82
86
  type: "message_end";
83
87
  entry: EntryRecord;
84
- } | {
88
+ } | ({
85
89
  type: "tool_execution_start";
86
- toolCallId: string;
87
- toolName: string;
88
90
  args: JsonObject;
89
- } | {
91
+ } & ToolEventCall) | ({
90
92
  type: "tool_execution_update";
91
- toolCallId: string;
92
- toolName: string;
93
93
  /** A front trim and then an append of the retained window, or its replacement. */
94
94
  output?: {
95
95
  trimStart?: number;
@@ -99,14 +99,17 @@ export type AgentEvent = SnapshotEvent | {
99
99
  };
100
100
  details?: JsonValue;
101
101
  diagnostics?: readonly ToolDiagnostic[];
102
- }
103
- /** `entry` is absent when the tool task faulted or was orphaned. */
104
- | {
102
+ } & ToolEventCall)
103
+ /**
104
+ * A model-issued call ends with its result `entry`, a nested call with its `result`. Both are absent when the tool
105
+ * task faulted or was orphaned, or when the call's slot left `pi.live` unfinished: its run ended, or its parent
106
+ * settled first.
107
+ */
108
+ | ({
105
109
  type: "tool_execution_end";
106
- toolCallId: string;
107
- toolName: string;
108
110
  entry?: EntryRecord;
109
- } | {
111
+ result?: NestedToolExecutionResult;
112
+ } & ToolEventCall) | {
110
113
  type: "inbox_update";
111
114
  items: readonly QueuedItem[];
112
115
  } | {
@@ -143,11 +146,28 @@ export type AgentEvent = SnapshotEvent | {
143
146
  reason: CompactionReason;
144
147
  blocking: boolean;
145
148
  }
146
- /** The task's receipt tells whether it produced a summary; the summary entry has its own events. */
149
+ /**
150
+ * The task's receipt tells whether it produced a summary; the summary entry has its own events. `error` is set when
151
+ * the compaction failed, faulted, or was orphaned, as in `pi.live.compactionFailure`.
152
+ */
147
153
  | {
148
154
  type: "compaction_end";
149
155
  taskId: TaskId;
150
156
  reason: CompactionReason;
157
+ error?: string;
158
+ };
159
+ /**
160
+ * Which call a tool event is about. `toolCallId` is the call's ID in the transcript and in tool events: the provider's
161
+ * ID for a model-issued call, `<parent call ID>/<key>` for a nested one. Match events by it; do not parse it. `taskId`
162
+ * is the call's tool task, absent for a call that never got one (not offered, or not started in a sequential round).
163
+ * A nested call also names the call that made it, by call ID and by tool task.
164
+ */
165
+ export type ToolEventCall = {
166
+ toolCallId: string;
167
+ toolName: string;
168
+ taskId?: TaskId;
169
+ parentToolCallId?: string;
170
+ parentTaskId?: TaskId;
151
171
  };
152
172
  /** Serialized stream of one conversation's event batches, one per commit. */
153
173
  export interface AgentEventStream {
@@ -1 +1 @@
1
- {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/harness/events.ts"],"names":[],"mappings":"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"}
1
+ {"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/harness/events.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAEhE,OAAO,KAAK,EAAE,gBAAgB,EAAE,OAAO,EAAE,KAAK,EAAE,MAAM,uBAAuB,CAAC;AAE9E,OAAO,KAAK,EAGX,cAAc,EACd,WAAW,EACX,UAAU,EACV,YAAY,EACZ,gBAAgB,EAChB,MAAM,EACN,QAAQ,EACR,MAAM,aAAa,CAAC;AAErB,OAAO,KAAK,EAAE,SAAS,EAAc,MAAM,YAAY,CAAC;AACxD,OAAO,KAAK,EAAE,iBAAiB,EAAE,gBAAgB,EAAa,cAAc,EAAE,QAAQ,EAAE,MAAM,WAAW,CAAC;AAE1G,OAAO,KAAK,EAAE,UAAU,EAAE,gBAAgB,EAAE,OAAO,EAAE,yBAAyB,EAAE,cAAc,EAAE,MAAM,YAAY,CAAC;AACnH,OAAO,EAAY,KAAK,UAAU,EAAE,MAAM,YAAY,CAAC;AAIvD,KAAK,KAAK,GAAG,gBAAgB,CAAC,SAAS,CAAC,CAAC,MAAM,CAAC,CAAC;AACjD,KAAK,UAAU,GAAG;IAAE,EAAE,EAAE,YAAY,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC,MAAM,CAAC,CAAA;CAAE,CAAC;AAEhE,+EAA+E;AAC/E,MAAM,MAAM,aAAa,GACtB;IAAE,IAAI,EAAE,YAAY,GAAG,gBAAgB,GAAG,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GAChG;IAAE,IAAI,EAAE,YAAY,GAAG,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GAC9E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,SAAS,CAAC,MAAM,GAAG,MAAM,CAAC,EAAE,CAAC;IAAC,KAAK,EAAE,MAAM,CAAA;CAAE,GACnG;IAAE,IAAI,EAAE,OAAO,CAAC;IAAC,YAAY,EAAE,MAAM,CAAC;IAAC,KAAK,EAAE,KAAK,CAAA;CAAE,GACrD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,OAAO,EAAE,gBAAgB,CAAA;CAAE,CAAC;AAElD,MAAM,MAAM,aAAa,GAAG;IAC3B,IAAI,EAAE,UAAU,CAAC;IACjB,OAAO,EAAE,SAAS,WAAW,EAAE,CAAC;IAChC,GAAG,CAAC,EAAE;QAAE,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;KAAE,CAAC;IAC1C,0FAA0F;IAC1F,UAAU,CAAC,EAAE;QACZ,OAAO,EAAE,MAAM,CAAC;QAChB,OAAO,CAAC,EAAE,gBAAgB,CAAC;QAC3B,KAAK,CAAC,EAAE;YAAE,EAAE,EAAE,MAAM,CAAC;YAAC,KAAK,EAAE,MAAM,CAAA;SAAE,CAAC;QACtC,QAAQ,CAAC,EAAE;YAAE,MAAM,EAAE,MAAM,CAAA;SAAE,CAAC;KAC9B,CAAC;IACF,KAAK,EAAE,SAAS,QAAQ,EAAE,CAAC;IAC3B,iEAAiE;IACjE,WAAW,EAAE,SAAS,cAAc,EAAE,CAAC;IACvC,oFAAoF;IACpF,WAAW,EAAE,SAAS,gBAAgB,EAAE,CAAC;IACzC,6GAA6G;IAC7G,iBAAiB,CAAC,EAAE,iBAAiB,CAAC;IACtC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAC;IAC7B,oCAAoC;IACpC,KAAK,EAAE,UAAU,CAAC;IAClB,KAAK,EAAE,UAAU,CAAC;CAClB,CAAC;AAEF,2FAA2F;AAC3F,MAAM,MAAM,UAAU,GACnB,aAAa,GACb;IAAE,IAAI,EAAE,WAAW,CAAC;IAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,SAAS,CAAC;IAAC,MAAM,EAAE,SAAS,YAAY,EAAE,CAAA;CAAE,GACpD;IAAE,IAAI,EAAE,YAAY,CAAA;CAAE,GACtB;IAAE,IAAI,EAAE,UAAU,CAAA;CAAE,GACpB;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,OAAO,EAAE,OAAO,CAAA;CAAE;AAC7C,kFAAkF;GAChF;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,KAAK,CAAC;IAAC,OAAO,EAAE,SAAS,aAAa,EAAE,CAAA;CAAE,GAC3E;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GAC3C,CAAC;IAAE,IAAI,EAAE,sBAAsB,CAAC;IAAC,IAAI,EAAE,UAAU,CAAA;CAAE,GAAG,aAAa,CAAC,GACpE,CAAC;IACD,IAAI,EAAE,uBAAuB,CAAC;IAC9B,kFAAkF;IAClF,MAAM,CAAC,EAAE;QAAE,SAAS,CAAC,EAAE,MAAM,CAAC;QAAC,MAAM,CAAC,EAAE,MAAM,CAAA;KAAE,GAAG;QAAE,GAAG,EAAE,MAAM,CAAA;KAAE,CAAC;IACnE,OAAO,CAAC,EAAE,SAAS,CAAC;IACpB,WAAW,CAAC,EAAE,SAAS,cAAc,EAAE,CAAC;CACvC,GAAG,aAAa,CAAC;AACpB;;;;GAIG;GACD,CAAC;IAAE,IAAI,EAAE,oBAAoB,CAAC;IAAC,KAAK,CAAC,EAAE,WAAW,CAAC;IAAC,MAAM,CAAC,EAAE,yBAAyB,CAAA;CAAE,GAAG,aAAa,CAAC,GACzG;IAAE,IAAI,EAAE,cAAc,CAAC;IAAC,KAAK,EAAE,SAAS,UAAU,EAAE,CAAA;CAAE,GACtD;IAAE,IAAI,EAAE,YAAY,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAA;CAAE,GAChD;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAC;IAAC,EAAE,EAAE,MAAM,CAAC;IAAC,YAAY,EAAE,MAAM,CAAA;CAAE,GAC/E;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GAC3C;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,MAAM,EAAE,MAAM,CAAA;CAAE,GACzC;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,KAAK,EAAE,WAAW,CAAA;CAAE,GAC9C;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,eAAe,CAAC;IAAC,KAAK,EAAE,UAAU,CAAA;CAAE,GAC5C;IAAE,IAAI,EAAE,aAAa,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,IAAI,EAAE,MAAM,CAAC;IAAC,OAAO,EAAE,MAAM,CAAA;CAAE,GACtE;IAAE,IAAI,EAAE,kBAAkB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,QAAQ,EAAE,OAAO,CAAA;CAAE;AAC3F;;;GAGG;GACD;IAAE,IAAI,EAAE,gBAAgB,CAAC;IAAC,MAAM,EAAE,MAAM,CAAC;IAAC,MAAM,EAAE,gBAAgB,CAAC;IAAC,KAAK,CAAC,EAAE,MAAM,CAAA;CAAE,CAAC;AAExF;;;;;GAKG;AACH,MAAM,MAAM,aAAa,GAAG;IAC3B,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,CAAC,EAAE,MAAM,CAAC;IAChB,gBAAgB,CAAC,EAAE,MAAM,CAAC;IAC1B,YAAY,CAAC,EAAE,MAAM,CAAC;CACtB,CAAC;AAEF,6EAA6E;AAC7E,MAAM,WAAW,gBAAgB;IAChC,0CAA0C;IAC1C,QAAQ,CAAC,QAAQ,EAAE,aAAa,CAAC;IACjC,KAAK,CAAC,QAAQ,EAAE,CAAC,MAAM,EAAE,SAAS,UAAU,EAAE,EAAE,OAAO,EAAE,OAAO,KAAK,OAAO,CAAC,IAAI,CAAC,GAAG,IAAI,CAAC;IAC1F,IAAI,IAAI,OAAO,CAAC,QAAQ,CAAC,CAAC;IAC1B,QAAQ,CAAC,MAAM,EAAE,OAAO,CAAC,QAAQ,CAAC,CAAC;CACnC;AAwCD;;;GAGG;AACH,wBAAsB,WAAW,CAChC,OAAO,EAAE,OAAO,EAChB,cAAc,EAAE,cAAc,EAC9B,OAAO,EAAE,OAAO,GACd,OAAO,CAAC,gBAAgB,CAAC,CA4C3B"}