@earendil-works/pi-durable 0.99.2 → 1.0.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.
- package/CHANGELOG.md +7 -0
- package/README.md +196 -74
- package/dist/env/index.d.ts +5 -0
- package/dist/env/index.d.ts.map +1 -1
- package/dist/env/index.js.map +1 -1
- package/dist/env/node.d.ts +2 -0
- package/dist/env/node.d.ts.map +1 -1
- package/dist/env/node.js +2 -0
- package/dist/env/node.js.map +1 -1
- package/dist/harness/agent.d.ts +31 -0
- package/dist/harness/agent.d.ts.map +1 -0
- package/dist/harness/agent.js +209 -0
- package/dist/harness/agent.js.map +1 -0
- package/dist/harness/compaction.d.ts.map +1 -1
- package/dist/harness/compaction.js +8 -11
- package/dist/harness/compaction.js.map +1 -1
- package/dist/harness/define.d.ts +18 -0
- package/dist/harness/define.d.ts.map +1 -0
- package/dist/harness/define.js +25 -0
- package/dist/harness/define.js.map +1 -0
- package/dist/harness/events.d.ts +5 -5
- package/dist/harness/events.d.ts.map +1 -1
- package/dist/harness/events.js +6 -6
- package/dist/harness/events.js.map +1 -1
- package/dist/harness/generation.d.ts +2 -4
- package/dist/harness/generation.d.ts.map +1 -1
- package/dist/harness/generation.js +39 -43
- package/dist/harness/generation.js.map +1 -1
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/harness.js +68 -154
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/inbox.d.ts +4 -2
- package/dist/harness/inbox.d.ts.map +1 -1
- package/dist/harness/inbox.js +3 -5
- package/dist/harness/inbox.js.map +1 -1
- package/dist/harness/prompt.d.ts +1 -3
- package/dist/harness/prompt.d.ts.map +1 -1
- package/dist/harness/prompt.js +1 -11
- package/dist/harness/prompt.js.map +1 -1
- package/dist/harness/registry.d.ts +2 -3
- package/dist/harness/registry.d.ts.map +1 -1
- package/dist/harness/registry.js +66 -283
- package/dist/harness/registry.js.map +1 -1
- package/dist/harness/scheduler.d.ts +7 -2
- package/dist/harness/scheduler.d.ts.map +1 -1
- package/dist/harness/scheduler.js +41 -27
- package/dist/harness/scheduler.js.map +1 -1
- package/dist/harness/submissions.d.ts +4 -4
- package/dist/harness/submissions.d.ts.map +1 -1
- package/dist/harness/submissions.js +7 -4
- package/dist/harness/submissions.js.map +1 -1
- package/dist/harness/task-graph.d.ts +49 -0
- package/dist/harness/task-graph.d.ts.map +1 -0
- package/dist/harness/task-graph.js +163 -0
- package/dist/harness/task-graph.js.map +1 -0
- package/dist/harness/tool.d.ts +1 -1
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +9 -6
- package/dist/harness/tool.js.map +1 -1
- package/dist/harness/types.d.ts +171 -140
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/view.d.ts +1 -1
- package/dist/harness/view.d.ts.map +1 -1
- package/dist/harness/view.js +2 -7
- package/dist/harness/view.js.map +1 -1
- package/dist/index.d.ts +4 -2
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +2 -1
- package/dist/index.js.map +1 -1
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +5 -1
- package/dist/session/session.js.map +1 -1
- package/dist/session/transaction.d.ts +2 -2
- package/dist/session/transaction.d.ts.map +1 -1
- package/dist/session/transaction.js +7 -4
- package/dist/session/transaction.js.map +1 -1
- package/dist/storage/sqlite/database.d.ts +26 -19
- package/dist/storage/sqlite/database.d.ts.map +1 -1
- package/dist/storage/sqlite/database.js.map +1 -1
- package/dist/storage/sqlite/index.d.ts +1 -1
- package/dist/storage/sqlite/index.d.ts.map +1 -1
- package/dist/storage/sqlite/index.js.map +1 -1
- package/dist/storage/sqlite/migrations.js +6 -6
- package/dist/storage/sqlite/migrations.js.map +1 -1
- package/dist/storage/sqlite/node.d.ts +23 -7
- package/dist/storage/sqlite/node.d.ts.map +1 -1
- package/dist/storage/sqlite/node.js +129 -47
- package/dist/storage/sqlite/node.js.map +1 -1
- package/dist/storage/sqlite/storage.d.ts +12 -0
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js +121 -129
- package/dist/storage/sqlite/storage.js.map +1 -1
- package/dist/tools/bash.d.ts +1 -1
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +3 -2
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.d.ts +3 -3
- package/dist/tools/edit.d.ts.map +1 -1
- package/dist/tools/edit.js +5 -4
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/file-mutation-queue.d.ts +5 -1
- package/dist/tools/file-mutation-queue.d.ts.map +1 -1
- package/dist/tools/file-mutation-queue.js +39 -33
- package/dist/tools/file-mutation-queue.js.map +1 -1
- package/dist/tools/index.d.ts +18 -0
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +10 -0
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/read.d.ts +3 -3
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +4 -3
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/write.d.ts +1 -1
- package/dist/tools/write.d.ts.map +1 -1
- package/dist/tools/write.js +3 -2
- package/dist/tools/write.js.map +1 -1
- package/dist/types.d.ts +15 -4
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +25 -15
- package/dist/harness/config.d.ts +0 -29
- package/dist/harness/config.d.ts.map +0 -1
- package/dist/harness/config.js +0 -24
- package/dist/harness/config.js.map +0 -1
- package/docs/chord-delta-findings.md +0 -358
- package/docs/pico-v5-chord-usage.md +0 -373
- package/docs/pico-v5-handoff.md +0 -861
- package/docs/pico-v5.md +0 -4174
|
@@ -2,7 +2,6 @@ import { calculateContextTokens, estimateMessageTokens } from "@earendil-works/p
|
|
|
2
2
|
import { isRetryableAssistantError, retryDelayMs } from "@earendil-works/pi-ai/utils/retry";
|
|
3
3
|
import { CompactionEntry } from "../entries.js";
|
|
4
4
|
import { defineTask } from "../tasks.js";
|
|
5
|
-
import { ConversationConfig, DEFAULT_COMPACTION_POLICY, DEFAULT_RETRY_POLICY } from "./config.js";
|
|
6
5
|
import { orderToolResults } from "./context.js";
|
|
7
6
|
import { addCompactionStatus, compactionStatus, LiveDoc, removeCompactionStatus } from "./live.js";
|
|
8
7
|
import { admitSubmission } from "./submissions.js";
|
|
@@ -58,13 +57,13 @@ export const CompactionTask = defineTask({
|
|
|
58
57
|
phases: {
|
|
59
58
|
select: async (task, runtime, context) => {
|
|
60
59
|
const { conversationId } = runtime;
|
|
61
|
-
const
|
|
62
|
-
|
|
63
|
-
const ref =
|
|
60
|
+
const agent = await runtime.agent(context);
|
|
61
|
+
const settings = runtime.settings;
|
|
62
|
+
const ref = agent.model;
|
|
64
63
|
const model = ref === undefined ? undefined : runtime.models.getModel(ref.provider, ref.modelId);
|
|
65
64
|
if (ref === undefined || model === undefined)
|
|
66
65
|
return failNoModel(runtime, ref, context);
|
|
67
|
-
const policy =
|
|
66
|
+
const policy = settings.compaction;
|
|
68
67
|
const view = await runtime.context(conversationId, context);
|
|
69
68
|
const cut = selectCut(view, policy.keepRecentTokens);
|
|
70
69
|
if (cut === undefined)
|
|
@@ -90,8 +89,8 @@ export const CompactionTask = defineTask({
|
|
|
90
89
|
const request = {
|
|
91
90
|
attempt: 1,
|
|
92
91
|
model: ref,
|
|
93
|
-
thinkingLevel:
|
|
94
|
-
streamOptions:
|
|
92
|
+
thinkingLevel: agent.thinkingLevel,
|
|
93
|
+
streamOptions: settings.stream,
|
|
95
94
|
maxTokens: Math.min(Math.floor(0.8 * policy.reserveTokens), model.maxTokens > 0 ? model.maxTokens : Number.POSITIVE_INFINITY),
|
|
96
95
|
tail: view.entries.reduce((tail, entry) => (entry.id > tail ? entry.id : tail), firstKept),
|
|
97
96
|
firstKept,
|
|
@@ -128,8 +127,7 @@ export const CompactionTask = defineTask({
|
|
|
128
127
|
// An abort mark or close: the abort invocation or the reopened task handles the committed state.
|
|
129
128
|
runtime.signal.throwIfAborted();
|
|
130
129
|
const summary = summaryText(message);
|
|
131
|
-
const policy =
|
|
132
|
-
DEFAULT_RETRY_POLICY;
|
|
130
|
+
const policy = runtime.settings.retry;
|
|
133
131
|
const retry = message.stopReason === "error" &&
|
|
134
132
|
isRetryableAssistantError(message) &&
|
|
135
133
|
policy.enabled &&
|
|
@@ -362,8 +360,7 @@ async function placeSummary(tx, runtime, current, live, firstKept, summary) {
|
|
|
362
360
|
};
|
|
363
361
|
const result = current.owner === undefined
|
|
364
362
|
? {
|
|
365
|
-
|
|
366
|
-
submissionId: await admitSubmission(tx, runtime.conversationId, { type: "write", requestId: `compaction:${runtime.taskId}`, entry }, runtime.now()),
|
|
363
|
+
submissionId: await admitSubmission(tx, runtime.conversationId, { type: "write", requestId: `compaction:${runtime.taskId}`, entry }, runtime.now(), runtime.settings),
|
|
367
364
|
}
|
|
368
365
|
: { entryId: (await tx.appendEntry(runtime.conversationId, entry)).id };
|
|
369
366
|
return { status: "terminal", outcome: { status: "completed", result } };
|
|
@@ -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 type { Transaction } from \"../session/transaction.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 { ConversationConfig, DEFAULT_COMPACTION_POLICY, DEFAULT_RETRY_POLICY } from \"./config.ts\";\nimport { orderToolResults } from \"./context.ts\";\nimport { addCompactionStatus, compactionStatus, LiveDoc, type LiveState, removeCompactionStatus } from \"./live.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 config =\n\t\t\t\t(await runtime.snapshot(ConversationConfig, conversationId, context)) ??\n\t\t\t\tConversationConfig.definition.initial();\n\t\t\tconst ref = config.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 = config.compaction ?? DEFAULT_COMPACTION_POLICY;\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: config.thinkingLevel,\n\t\t\t\tstreamOptions: config.streamOptions ?? {},\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, 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\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 =\n\t\t\t\t(await runtime.snapshot(ConversationConfig, runtime.conversationId, context))?.retry ??\n\t\t\t\tDEFAULT_RETRY_POLICY;\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\t// The scheduler commits runtime changes through a Session transaction, which admission needs.\n\t\t\t\t\tsubmissionId: await admitSubmission(\n\t\t\t\t\t\ttx as Transaction,\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),\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 { addCompactionStatus, compactionStatus, LiveDoc, type LiveState, removeCompactionStatus } from \"./live.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, 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\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"]}
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
import type { JsonValue } from "@earendil-works/chord";
|
|
2
|
+
import type { TSchema } from "@earendil-works/pi-ai";
|
|
3
|
+
import type { AnyTask, Extension, HookRegistration, HooksOf, PromptSection, ToolRegistration, Wrap } from "./types.ts";
|
|
4
|
+
/** Identity function that types an extension. */
|
|
5
|
+
export declare function defineExtension<Tool extends ToolRegistration = ToolRegistration>(extension: Extension<Tool>): Extension<Tool>;
|
|
6
|
+
/** Identity function that types a tool: `args` from `parameters`, details from what it reports. */
|
|
7
|
+
export declare function defineTool<TParameters extends TSchema, TDetails extends JsonValue = JsonValue>(tool: ToolRegistration<TParameters, TDetails>): ToolRegistration<TParameters, TDetails>;
|
|
8
|
+
/** A prompt section; tagged unless `tag` is false. */
|
|
9
|
+
export declare function section<Tool extends ToolRegistration = ToolRegistration>(key: string, render: PromptSection<Tool>["render"], options?: {
|
|
10
|
+
readonly tag?: boolean;
|
|
11
|
+
}): PromptSection<Tool>;
|
|
12
|
+
/** Hook handlers for tasks with `task`'s name. */
|
|
13
|
+
export declare function hook<K extends AnyTask>(task: K, handlers: Partial<HooksOf<K>>): HookRegistration;
|
|
14
|
+
/** Wrap the tool named like `tool` wherever the wrapping extension is selected. */
|
|
15
|
+
export declare function wrapTool<Tool extends ToolRegistration>(tool: Tool, wrapper: (tool: Tool) => Tool): Wrap<Tool>;
|
|
16
|
+
/** Wrap the section `key` wherever the wrapping extension is selected. */
|
|
17
|
+
export declare function wrapSection<Tool extends ToolRegistration = ToolRegistration>(key: string, wrapper: (section: PromptSection<Tool>) => PromptSection<Tool>): Wrap<Tool>;
|
|
18
|
+
//# sourceMappingURL=define.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.d.ts","sourceRoot":"","sources":["../../src/harness/define.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AACvD,OAAO,KAAK,EAAE,OAAO,EAAE,MAAM,uBAAuB,CAAC;AACrD,OAAO,KAAK,EAAE,OAAO,EAAE,SAAS,EAAE,gBAAgB,EAAE,OAAO,EAAE,aAAa,EAAE,gBAAgB,EAAE,IAAI,EAAE,MAAM,YAAY,CAAC;AAEvH,iDAAiD;AACjD,wBAAgB,eAAe,CAAC,IAAI,SAAS,gBAAgB,GAAG,gBAAgB,EAC/E,SAAS,EAAE,SAAS,CAAC,IAAI,CAAC,GACxB,SAAS,CAAC,IAAI,CAAC,CAEjB;AAED,mGAAmG;AACnG,wBAAgB,UAAU,CAAC,WAAW,SAAS,OAAO,EAAE,QAAQ,SAAS,SAAS,GAAG,SAAS,EAC7F,IAAI,EAAE,gBAAgB,CAAC,WAAW,EAAE,QAAQ,CAAC,GAC3C,gBAAgB,CAAC,WAAW,EAAE,QAAQ,CAAC,CAEzC;AAED,sDAAsD;AACtD,wBAAgB,OAAO,CAAC,IAAI,SAAS,gBAAgB,GAAG,gBAAgB,EACvE,GAAG,EAAE,MAAM,EACX,MAAM,EAAE,aAAa,CAAC,IAAI,CAAC,CAAC,QAAQ,CAAC,EACrC,OAAO,CAAC,EAAE;IAAE,QAAQ,CAAC,GAAG,CAAC,EAAE,OAAO,CAAA;CAAE,GAClC,aAAa,CAAC,IAAI,CAAC,CAErB;AAED,kDAAkD;AAClD,wBAAgB,IAAI,CAAC,CAAC,SAAS,OAAO,EAAE,IAAI,EAAE,CAAC,EAAE,QAAQ,EAAE,OAAO,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,GAAG,gBAAgB,CAEhG;AAED,mFAAmF;AACnF,wBAAgB,QAAQ,CAAC,IAAI,SAAS,gBAAgB,EAAE,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC,IAAI,EAAE,IAAI,KAAK,IAAI,GAAG,IAAI,CAAC,IAAI,CAAC,CAE7G;AAED,0EAA0E;AAC1E,wBAAgB,WAAW,CAAC,IAAI,SAAS,gBAAgB,GAAG,gBAAgB,EAC3E,GAAG,EAAE,MAAM,EACX,OAAO,EAAE,CAAC,OAAO,EAAE,aAAa,CAAC,IAAI,CAAC,KAAK,aAAa,CAAC,IAAI,CAAC,GAC5D,IAAI,CAAC,IAAI,CAAC,CAEZ"}
|
|
@@ -0,0 +1,25 @@
|
|
|
1
|
+
/** Identity function that types an extension. */
|
|
2
|
+
export function defineExtension(extension) {
|
|
3
|
+
return extension;
|
|
4
|
+
}
|
|
5
|
+
/** Identity function that types a tool: `args` from `parameters`, details from what it reports. */
|
|
6
|
+
export function defineTool(tool) {
|
|
7
|
+
return tool;
|
|
8
|
+
}
|
|
9
|
+
/** A prompt section; tagged unless `tag` is false. */
|
|
10
|
+
export function section(key, render, options) {
|
|
11
|
+
return options?.tag === undefined ? { key, render } : { key, render, tag: options.tag };
|
|
12
|
+
}
|
|
13
|
+
/** Hook handlers for tasks with `task`'s name. */
|
|
14
|
+
export function hook(task, handlers) {
|
|
15
|
+
return { task: task.definition.name, handlers };
|
|
16
|
+
}
|
|
17
|
+
/** Wrap the tool named like `tool` wherever the wrapping extension is selected. */
|
|
18
|
+
export function wrapTool(tool, wrapper) {
|
|
19
|
+
return { tool: tool.name, wrap: wrapper };
|
|
20
|
+
}
|
|
21
|
+
/** Wrap the section `key` wherever the wrapping extension is selected. */
|
|
22
|
+
export function wrapSection(key, wrapper) {
|
|
23
|
+
return { section: key, wrap: wrapper };
|
|
24
|
+
}
|
|
25
|
+
//# sourceMappingURL=define.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"define.js","sourceRoot":"","sources":["../../src/harness/define.ts"],"names":[],"mappings":"AAIA,iDAAiD;AACjD,MAAM,UAAU,eAAe,CAC9B,SAA0B;IAE1B,OAAO,SAAS,CAAC;AAClB,CAAC;AAED,mGAAmG;AACnG,MAAM,UAAU,UAAU,CACzB,IAA6C;IAE7C,OAAO,IAAI,CAAC;AACb,CAAC;AAED,sDAAsD;AACtD,MAAM,UAAU,OAAO,CACtB,GAAW,EACX,MAAqC,EACrC,OAAoC;IAEpC,OAAO,OAAO,EAAE,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,CAAC,CAAC,CAAC,EAAE,GAAG,EAAE,MAAM,EAAE,GAAG,EAAE,OAAO,CAAC,GAAG,EAAE,CAAC;AACzF,CAAC;AAED,kDAAkD;AAClD,MAAM,UAAU,IAAI,CAAoB,IAAO,EAAE,QAA6B;IAC7E,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,UAAU,CAAC,IAAI,EAAE,QAAQ,EAAE,CAAC;AACjD,CAAC;AAED,mFAAmF;AACnF,MAAM,UAAU,QAAQ,CAAgC,IAAU,EAAE,OAA6B;IAChG,OAAO,EAAE,IAAI,EAAE,IAAI,CAAC,IAAI,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AAC3C,CAAC;AAED,0EAA0E;AAC1E,MAAM,UAAU,WAAW,CAC1B,GAAW,EACX,OAA8D;IAE9D,OAAO,EAAE,OAAO,EAAE,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,CAAC;AACxC,CAAC","sourcesContent":["import type { JsonValue } from \"@earendil-works/chord\";\nimport type { TSchema } from \"@earendil-works/pi-ai\";\nimport type { AnyTask, Extension, HookRegistration, HooksOf, PromptSection, ToolRegistration, Wrap } from \"./types.ts\";\n\n/** Identity function that types an extension. */\nexport function defineExtension<Tool extends ToolRegistration = ToolRegistration>(\n\textension: Extension<Tool>,\n): Extension<Tool> {\n\treturn extension;\n}\n\n/** Identity function that types a tool: `args` from `parameters`, details from what it reports. */\nexport function defineTool<TParameters extends TSchema, TDetails extends JsonValue = JsonValue>(\n\ttool: ToolRegistration<TParameters, TDetails>,\n): ToolRegistration<TParameters, TDetails> {\n\treturn tool;\n}\n\n/** A prompt section; tagged unless `tag` is false. */\nexport function section<Tool extends ToolRegistration = ToolRegistration>(\n\tkey: string,\n\trender: PromptSection<Tool>[\"render\"],\n\toptions?: { readonly tag?: boolean },\n): PromptSection<Tool> {\n\treturn options?.tag === undefined ? { key, render } : { key, render, tag: options.tag };\n}\n\n/** Hook handlers for tasks with `task`'s name. */\nexport function hook<K extends AnyTask>(task: K, handlers: Partial<HooksOf<K>>): HookRegistration {\n\treturn { task: task.definition.name, handlers };\n}\n\n/** Wrap the tool named like `tool` wherever the wrapping extension is selected. */\nexport function wrapTool<Tool extends ToolRegistration>(tool: Tool, wrapper: (tool: Tool) => Tool): Wrap<Tool> {\n\treturn { tool: tool.name, wrap: wrapper };\n}\n\n/** Wrap the section `key` wherever the wrapping extension is selected. */\nexport function wrapSection<Tool extends ToolRegistration = ToolRegistration>(\n\tkey: string,\n\twrapper: (section: PromptSection<Tool>) => PromptSection<Tool>,\n): Wrap<Tool> {\n\treturn { section: key, wrap: wrapper };\n}\n"]}
|
package/dist/harness/events.d.ts
CHANGED
|
@@ -1,10 +1,9 @@
|
|
|
1
1
|
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
|
-
import { type ConversationConfigState } from "./config.ts";
|
|
5
4
|
import type { InboxItem } from "./inbox.ts";
|
|
6
5
|
import type { CompactionStatus, ToolSlot } from "./live.ts";
|
|
7
|
-
import type { CompactionReason, Harness, ToolDiagnostic } from "./types.ts";
|
|
6
|
+
import type { AgentState, CompactionReason, Harness, ToolDiagnostic } from "./types.ts";
|
|
8
7
|
import { type UsageState } from "./usage.ts";
|
|
9
8
|
type Block = AssistantMessage["content"][number];
|
|
10
9
|
type QueuedItem = {
|
|
@@ -55,7 +54,8 @@ export type SnapshotEvent = {
|
|
|
55
54
|
/** `pi.live.compactions`: live compactions with their attempt and retry backoff. */
|
|
56
55
|
compactions: readonly CompactionStatus[];
|
|
57
56
|
inbox: readonly QueuedItem[];
|
|
58
|
-
|
|
57
|
+
/** `pi.agent`; `{}` when absent. */
|
|
58
|
+
agent: AgentState;
|
|
59
59
|
usage: UsageState;
|
|
60
60
|
};
|
|
61
61
|
/** Experimental agent event, shaped like the coding agent's session events (spec §9.4). */
|
|
@@ -127,8 +127,8 @@ export type AgentEvent = SnapshotEvent | {
|
|
|
127
127
|
type: "entry_appended";
|
|
128
128
|
entry: EntryRecord;
|
|
129
129
|
} | {
|
|
130
|
-
type: "
|
|
131
|
-
|
|
130
|
+
type: "agent_changed";
|
|
131
|
+
agent: AgentState;
|
|
132
132
|
} | {
|
|
133
133
|
type: "usage_changed";
|
|
134
134
|
usage: UsageState;
|
|
@@ -1 +1 @@
|
|
|
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;
|
|
1
|
+
{"version":3,"file":"events.d.ts","sourceRoot":"","sources":["../../src/harness/events.ts"],"names":[],"mappings":"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"}
|
package/dist/harness/events.js
CHANGED
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { CommittedWatch } from "../session/observation.js";
|
|
2
|
-
import {
|
|
2
|
+
import { AgentDoc } from "./agent.js";
|
|
3
3
|
import { UsageDoc } from "./usage.js";
|
|
4
4
|
import { scanAll } from "./util.js";
|
|
5
5
|
import { conversationViews } from "./view.js";
|
|
@@ -7,12 +7,12 @@ function parts(view) {
|
|
|
7
7
|
return {
|
|
8
8
|
live: (view.docs["pi.live"] ?? {}),
|
|
9
9
|
inbox: view.docs["pi.inbox"],
|
|
10
|
-
|
|
10
|
+
agent: view.docs["pi.agent"],
|
|
11
11
|
usage: view.docs["pi.usage"],
|
|
12
12
|
};
|
|
13
13
|
}
|
|
14
14
|
function snapshotOf(view) {
|
|
15
|
-
const { live, inbox,
|
|
15
|
+
const { live, inbox, agent, usage } = parts(view);
|
|
16
16
|
return {
|
|
17
17
|
type: "snapshot",
|
|
18
18
|
entries: view.entries,
|
|
@@ -21,7 +21,7 @@ function snapshotOf(view) {
|
|
|
21
21
|
tools: live.tools ?? [],
|
|
22
22
|
compactions: live.compactions ?? [],
|
|
23
23
|
inbox: queued(inbox),
|
|
24
|
-
|
|
24
|
+
agent: agent ?? AgentDoc.definition.initial(),
|
|
25
25
|
usage: usage ?? UsageDoc.definition.initial(),
|
|
26
26
|
};
|
|
27
27
|
}
|
|
@@ -220,8 +220,8 @@ function translate(conversationId, before, after, viewOps, publication, held) {
|
|
|
220
220
|
if (now.inbox !== was.inbox)
|
|
221
221
|
events.push({ type: "inbox_update", items: queued(now.inbox) });
|
|
222
222
|
// A retired document reads as its initial value, as in a snapshot.
|
|
223
|
-
if (now.
|
|
224
|
-
events.push({ type: "
|
|
223
|
+
if (now.agent !== was.agent) {
|
|
224
|
+
events.push({ type: "agent_changed", agent: now.agent ?? AgentDoc.definition.initial() });
|
|
225
225
|
}
|
|
226
226
|
if (now.usage !== was.usage)
|
|
227
227
|
events.push({ type: "usage_changed", usage: now.usage ?? UsageDoc.definition.initial() });
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/harness/events.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@earendil-works/chord\";\nimport type { Op, Path } from \"@earendil-works/chord/delta\";\nimport type { AssistantMessage, Message, Usage } from \"@earendil-works/pi-ai\";\nimport { CommittedWatch } from \"../session/observation.ts\";\nimport type {\n\tCommitChange,\n\tCommitPublication,\n\tConversationId,\n\tEntryRecord,\n\tJsonObject,\n\tSubmissionId,\n\tSubmissionRecord,\n\tTaskId,\n\tWatchEnd,\n} from \"../types.ts\";\nimport { ConversationConfig, type ConversationConfigState } from \"./config.ts\";\nimport type { InboxItem, InboxState } from \"./inbox.ts\";\nimport type { CompactionStatus, LiveState, ToolSlot } from \"./live.ts\";\nimport type { CompactionReason, Harness, ToolDiagnostic } from \"./types.ts\";\nimport { UsageDoc, type UsageState } from \"./usage.ts\";\nimport { scanAll } from \"./util.ts\";\nimport { type ConversationView, conversationViews } from \"./view.ts\";\n\ntype Block = AssistantMessage[\"content\"][number];\ntype QueuedItem = { id: SubmissionId; mode: InboxItem[\"mode\"] };\n\n/** One change to the in-flight assistant message, relative to that message. */\nexport type MessageChange =\n\t| { type: \"text_start\" | \"thinking_start\" | \"toolcall_start\"; contentIndex: number; block: Block }\n\t| { type: \"text_delta\" | \"thinking_delta\"; contentIndex: number; delta: string }\n\t| { type: \"toolcall_delta\"; contentIndex: number; path: readonly (string | number)[]; delta: string }\n\t| { type: \"block\"; contentIndex: number; block: Block }\n\t| { type: \"message\"; message: AssistantMessage };\n\nexport type SnapshotEvent = {\n\ttype: \"snapshot\";\n\tentries: readonly EntryRecord[];\n\trun?: { inputs: readonly SubmissionId[] };\n\t/** Current generation attempt: its in-flight partial, retry backoff, or deferred poll. */\n\tgeneration?: {\n\t\tattempt: number;\n\t\tmessage?: AssistantMessage;\n\t\tretry?: { at: number; error: string };\n\t\tdeferred?: { pollAt: number };\n\t};\n\ttools: readonly ToolSlot[];\n\t/** `pi.live.compactions`: live compactions with their attempt and retry backoff. */\n\tcompactions: readonly CompactionStatus[];\n\tinbox: readonly QueuedItem[];\n\tconfig: ConversationConfigState;\n\tusage: UsageState;\n};\n\n/** Experimental agent event, shaped like the coding agent's session events (spec §9.4). */\nexport type AgentEvent =\n\t| SnapshotEvent\n\t| { type: \"run_start\"; inputs: readonly SubmissionId[] }\n\t| { type: \"run_end\"; inputs: readonly SubmissionId[] }\n\t| { type: \"turn_start\" }\n\t| { type: \"turn_end\" }\n\t| { type: \"message_start\"; message: Message }\n\t/** `usage` is the partial's current usage, as in the coding agent's JSON mode. */\n\t| { type: \"message_update\"; usage: Usage; changes: readonly MessageChange[] }\n\t| { type: \"message_end\"; entry: EntryRecord }\n\t| { type: \"tool_execution_start\"; toolCallId: string; toolName: string; args: JsonObject }\n\t| {\n\t\t\ttype: \"tool_execution_update\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t\t\t/** A front trim and then an append of the retained window, or its replacement. */\n\t\t\toutput?: { trimStart?: number; append?: string } | { set: string };\n\t\t\tdetails?: JsonValue;\n\t\t\tdiagnostics?: readonly ToolDiagnostic[];\n\t }\n\t/** `entry` is absent when the tool task faulted or was orphaned. */\n\t| { type: \"tool_execution_end\"; toolCallId: string; toolName: string; entry?: EntryRecord }\n\t| { type: \"inbox_update\"; items: readonly QueuedItem[] }\n\t| { type: \"submission\"; record: SubmissionRecord }\n\t| { type: \"auto_retry_start\"; attempt: number; at: number; errorMessage: string }\n\t| { type: \"auto_retry_end\"; attempt: number }\n\t| { type: \"deferred_poll\"; pollAt: number }\n\t| { type: \"entry_appended\"; entry: EntryRecord }\n\t| { type: \"config_changed\"; config: ConversationConfigState }\n\t| { type: \"usage_changed\"; usage: UsageState }\n\t| { type: \"task_failed\"; taskId: TaskId; kind: string; message: string }\n\t| { type: \"compaction_start\"; taskId: TaskId; reason: CompactionReason; blocking: boolean }\n\t/** The task's receipt tells whether it produced a summary; the summary entry has its own events. */\n\t| { type: \"compaction_end\"; taskId: TaskId; reason: CompactionReason };\n\n/** Serialized stream of one conversation's event batches, one per commit. */\nexport interface AgentEventStream {\n\t/** The `snapshot` event at attachment. */\n\treadonly snapshot: SnapshotEvent;\n\tstart(listener: (events: readonly AgentEvent[], context: Context) => Promise<void>): void;\n\tstop(): Promise<WatchEnd>;\n\treadonly closed: Promise<WatchEnd>;\n}\n\n/** The typed parts of a view the events read. */\ntype Parts = {\n\tlive: LiveState;\n\tinbox: InboxState | undefined;\n\tconfig: ConversationConfigState | undefined;\n\tusage: UsageState | undefined;\n};\n\nfunction parts(view: ConversationView): Parts {\n\treturn {\n\t\tlive: (view.docs[\"pi.live\"] ?? {}) as LiveState,\n\t\tinbox: view.docs[\"pi.inbox\"] as InboxState | undefined,\n\t\tconfig: view.docs[\"pi.conversation.config\"] as ConversationConfigState | undefined,\n\t\tusage: view.docs[\"pi.usage\"] as UsageState | undefined,\n\t};\n}\n\nfunction snapshotOf(view: ConversationView): SnapshotEvent {\n\tconst { live, inbox, config, usage } = parts(view);\n\treturn {\n\t\ttype: \"snapshot\",\n\t\tentries: view.entries,\n\t\t...(live.run === undefined ? {} : { run: { inputs: live.run.inputs } }),\n\t\t...(live.generation === undefined ? {} : { generation: live.generation as SnapshotEvent[\"generation\"] }),\n\t\ttools: live.tools ?? [],\n\t\tcompactions: live.compactions ?? [],\n\t\tinbox: queued(inbox),\n\t\tconfig: config ?? ConversationConfig.definition.initial(),\n\t\tusage: usage ?? UsageDoc.definition.initial(),\n\t};\n}\n\nfunction queued(inbox: InboxState | undefined): QueuedItem[] {\n\treturn (inbox?.items ?? []).map((item) => ({ id: item.id, mode: item.mode }));\n}\n\n/**\n * Experimental: attach to one conversation's agent events (spec §9.4). The snapshot and the registration for later\n * commits are captured atomically on the Session line; overflow replaces undelivered batches with one snapshot.\n */\nexport async function watchEvents(\n\tharness: Harness,\n\tconversationId: ConversationId,\n\tcontext: Context,\n): Promise<AgentEventStream> {\n\tlet watch!: CommittedWatch<readonly AgentEvent[]>;\n\tlet snapshot!: SnapshotEvent;\n\tawait conversationViews(harness).attach(\n\t\tconversationId,\n\t\tasync (initial, release, storage) => {\n\t\t\t// Generations whose held outcome already ended their turn, read on the line with the snapshot.\n\t\t\tconst query = { conversationId, kind: \"pi.generation\", status: \"completing\" } as const;\n\t\t\tconst completing = await scanAll((cursor) => storage.scanTasks(query, 100, cursor, context));\n\t\t\tconst held = new Set<TaskId>(completing.map((record) => record.id));\n\t\t\tlet current = initial;\n\t\t\tsnapshot = snapshotOf(initial);\n\t\t\t// Batches are the watch's values; an overflow delivers a snapshot of the newest view instead.\n\t\t\twatch = new CommittedWatch<readonly AgentEvent[]>([], release, () => [snapshotOf(current)]);\n\t\t\treturn {\n\t\t\t\tpublication: (before, after, ops, publication, commitContext) => {\n\t\t\t\t\tcurrent = after;\n\t\t\t\t\tconst events = translate(conversationId, before, after, ops, publication, held);\n\t\t\t\t\tif (events.length > 0) watch.advance(events, [], commitContext);\n\t\t\t\t},\n\t\t\t\tcloseSession: () => watch.closeSession(),\n\t\t\t};\n\t\t},\n\t\tcontext,\n\t);\n\t// Like a watch, the acquisition context governs the stream's lifetime.\n\tconst signal = context.abortSignal;\n\tif (signal?.aborted) {\n\t\twatch.cancel();\n\t\tthrow signal.reason;\n\t}\n\tif (signal !== undefined) watch.observeCancellation(signal);\n\treturn {\n\t\tsnapshot,\n\t\tstart: (listener) => watch.start((events, _ops, deliveryContext) => listener(events, deliveryContext)),\n\t\tstop: () => watch.stop(),\n\t\tclosed: watch.closed,\n\t};\n}\n\ntype TaskChange = Extract<CommitChange, { type: \"task\" }>;\n\n/** The tool result for `callId` among `entries`. */\nfunction resultOf(entries: readonly EntryRecord[], callId: string): EntryRecord | undefined {\n\treturn entries.find((entry) => {\n\t\tconst message = entry.model?.[0];\n\t\treturn message?.role === \"toolResult\" && message.toolCallId === callId;\n\t});\n}\n\n/** Every event one publication causes, in the order of spec §9.4. */\nfunction translate(\n\tconversationId: ConversationId,\n\tbefore: ConversationView,\n\tafter: ConversationView,\n\tviewOps: readonly Op[],\n\tpublication: CommitPublication,\n\theld: Set<TaskId>,\n): AgentEvent[] {\n\tconst entries: EntryRecord[] = [];\n\tconst tasks = new Map<TaskId, TaskChange[\"value\"]>();\n\tconst submissions: SubmissionRecord[] = [];\n\tfor (const change of publication.changes) {\n\t\tif (change.type === \"entry\" && change.value.conversationId === conversationId) entries.push(change.value);\n\t\tif (change.type === \"task\" && change.value.conversationId === conversationId)\n\t\t\ttasks.set(change.value.id, change.value);\n\t\tif (change.type === \"submission\" && change.value.conversationId === conversationId) {\n\t\t\tsubmissions.push(change.value);\n\t\t}\n\t}\n\tif (viewOps.length === 0 && entries.length === 0 && tasks.size === 0 && submissions.length === 0) return [];\n\t// Entries are appended in ID order; submission records are published in the order the commit first touched them.\n\tsubmissions.sort((a, b) => a.id - b.id);\n\tconst was = parts(before);\n\tconst now = parts(after);\n\tconst events: AgentEvent[] = [];\n\n\t// Progress: tool starts, the in-flight message, tool updates, retry and deferred state.\n\tconst slotsBefore = new Map((was.live.tools ?? []).map((slot) => [slot.callId, slot]));\n\tconst slots = now.live.tools ?? [];\n\tfor (const slot of slots) {\n\t\tif (slot.status !== \"running\" || slotsBefore.get(slot.callId)?.status === \"running\") continue;\n\t\tconst checkpoint = slot.taskId === undefined ? undefined : tasks.get(slot.taskId)?.state.checkpoint;\n\t\tconst args = (checkpoint as { arguments?: JsonObject } | undefined)?.arguments ?? {};\n\t\tevents.push({ type: \"tool_execution_start\", toolCallId: slot.callId, toolName: slot.name, args });\n\t}\n\tconst partialBefore = was.live.generation?.message as AssistantMessage | undefined;\n\tconst partial = now.live.generation?.message as AssistantMessage | undefined;\n\tif (partial !== undefined && partialBefore === undefined) events.push({ type: \"message_start\", message: partial });\n\telse if (partial !== undefined && partial !== partialBefore) {\n\t\tevents.push({ type: \"message_update\", usage: partial.usage, changes: messageChanges(viewOps, partial) });\n\t}\n\tfor (const [index, slot] of slots.entries()) {\n\t\tconst previous = slotsBefore.get(slot.callId);\n\t\tif (slot.status !== \"running\" || previous?.status !== \"running\") continue;\n\t\tconst update = toolUpdate(viewOps, index, slot, previous);\n\t\tif (update === undefined) continue;\n\t\tevents.push({ type: \"tool_execution_update\", toolCallId: slot.callId, toolName: slot.name, ...update });\n\t}\n\tconst generation = now.live.generation;\n\tconst generationBefore = was.live.generation;\n\tif (generation?.retry !== undefined && generationBefore?.retry === undefined) {\n\t\tconst { at, error } = generation.retry;\n\t\tevents.push({ type: \"auto_retry_start\", attempt: generation.attempt, at, errorMessage: error });\n\t}\n\tif (generationBefore?.retry !== undefined && generation?.retry === undefined) {\n\t\tevents.push({ type: \"auto_retry_end\", attempt: generationBefore.attempt });\n\t}\n\tif (generation?.deferred !== undefined && generation.deferred.pollAt !== generationBefore?.deferred?.pollAt) {\n\t\tevents.push({ type: \"deferred_poll\", pollAt: generation.deferred.pollAt });\n\t}\n\n\t// Tools that end in this commit: a slot that becomes done, one created done (a call not offered), or an unfinished\n\t// one that vanishes because its run ended. A done slot that vanishes ended earlier.\n\tconst toolEnds: Extract<AgentEvent, { type: \"tool_execution_end\" }>[] = [];\n\tconst endTool = (callId: string, name: string, entryId: number | undefined): void => {\n\t\tconst entry = entries.find((candidate) => candidate.id === entryId);\n\t\ttoolEnds.push({\n\t\t\ttype: \"tool_execution_end\",\n\t\t\ttoolCallId: callId,\n\t\t\ttoolName: name,\n\t\t\t...(entry === undefined ? {} : { entry }),\n\t\t});\n\t};\n\tfor (const previous of slotsBefore.values()) {\n\t\tif (previous.status === \"done\") continue;\n\t\tconst slot = slots.find((candidate) => candidate.callId === previous.callId);\n\t\tif (slot?.status === \"done\") endTool(previous.callId, previous.name, slot.entry);\n\t\t// A slot whose run ended in this commit may have had its result appended with it, as for unstarted calls.\n\t\telse if (slot === undefined) endTool(previous.callId, previous.name, resultOf(entries, previous.callId)?.id);\n\t}\n\tfor (const slot of slots) {\n\t\tif (slot.status === \"done\" && !slotsBefore.has(slot.callId)) endTool(slot.callId, slot.name, slot.entry);\n\t}\n\n\t// Entries in append order; a tool's end directly precedes its result's message, as in the coding agent.\n\tlet assistantAppended = false;\n\tfor (const entry of entries) {\n\t\tevents.push(...toolEnds.filter((end) => end.entry === entry));\n\t\tconst message = entry.model?.[0];\n\t\tif (message === undefined) {\n\t\t\tevents.push({ type: \"entry_appended\", entry });\n\t\t\tcontinue;\n\t\t}\n\t\t// A streamed answer already started with its first partial.\n\t\tconst streamed = message.role === \"assistant\" && partialBefore !== undefined && !assistantAppended;\n\t\tif (message.role === \"assistant\") assistantAppended = true;\n\t\tif (!streamed) events.push({ type: \"message_start\", message });\n\t\tevents.push({ type: \"message_end\", entry });\n\t}\n\t// Ends without a result entry: a faulted or orphaned tool, or one whose run ended.\n\tevents.push(...toolEnds.filter((end) => end.entry === undefined));\n\n\t// Compaction ends, task failures, then turn and run ends.\n\tconst compactionsBefore = was.live.compactions ?? [];\n\tconst compactions = now.live.compactions ?? [];\n\tfor (const { taskId, reason } of compactionsBefore) {\n\t\tif (!compactions.some((status) => status.taskId === taskId)) {\n\t\t\tevents.push({ type: \"compaction_end\", taskId, reason });\n\t\t}\n\t}\n\t// A generation's turn ends when its outcome is committed: at a `completing` hold or at terminal, whichever comes\n\t// first, so a successor created at the hold starts after it.\n\tlet turnEnded = false;\n\tfor (const task of tasks.values()) {\n\t\tconst status = task.state.status;\n\t\tif (task.kind === \"pi.generation\" && status === \"completing\" && !held.has(task.id)) {\n\t\t\theld.add(task.id);\n\t\t\tturnEnded = true;\n\t\t}\n\t\tif (status !== \"terminal\") continue;\n\t\tif (task.kind === \"pi.generation\" && !held.delete(task.id)) turnEnded = true;\n\t\tconst outcome = task.state.outcome;\n\t\tif (outcome.status === \"faulted\" || outcome.status === \"orphaned\") {\n\t\t\tconst message = outcome.status === \"faulted\" ? outcome.error.message : outcome.reason;\n\t\t\tevents.push({ type: \"task_failed\", taskId: task.id, kind: task.kind, message });\n\t\t}\n\t}\n\tif (turnEnded) events.push({ type: \"turn_end\" });\n\tconst run = now.live.run;\n\tconst runBefore = was.live.run;\n\tconst runChanged = run?.inputs[0] !== runBefore?.inputs[0];\n\tif (runBefore !== undefined && runChanged) events.push({ type: \"run_end\", inputs: runBefore.inputs });\n\n\t// Submissions, document state, then what began.\n\tfor (const record of submissions) events.push({ type: \"submission\", record });\n\tif (now.inbox !== was.inbox) events.push({ type: \"inbox_update\", items: queued(now.inbox) });\n\t// A retired document reads as its initial value, as in a snapshot.\n\tif (now.config !== was.config) {\n\t\tevents.push({ type: \"config_changed\", config: now.config ?? ConversationConfig.definition.initial() });\n\t}\n\tif (now.usage !== was.usage)\n\t\tevents.push({ type: \"usage_changed\", usage: now.usage ?? UsageDoc.definition.initial() });\n\tfor (const { taskId, reason, blocking } of compactions) {\n\t\tif (!compactionsBefore.some((status) => status.taskId === taskId)) {\n\t\t\tevents.push({ type: \"compaction_start\", taskId, reason, blocking });\n\t\t}\n\t}\n\tif (run !== undefined && runChanged) events.push({ type: \"run_start\", inputs: run.inputs });\n\tif (run !== undefined && run.taskId !== runBefore?.taskId && tasks.get(run.taskId)?.kind === \"pi.generation\") {\n\t\tevents.push({ type: \"turn_start\" });\n\t}\n\treturn events;\n}\n\nconst PARTIAL_PATH = [\"docs\", \"pi.live\", \"generation\", \"message\"];\n\n/** Translate the view operations on the in-flight message into message changes (spec §9.4). */\nfunction messageChanges(viewOps: readonly Op[], message: AssistantMessage): MessageChange[] {\n\tconst changes: MessageChange[] = [];\n\t// A block sent whole already holds every later change to it in this batch.\n\tconst whole = new Set<number>();\n\tfor (const op of viewOps) {\n\t\t// View operations never replace the root.\n\t\tconst path = op[1] as Path;\n\t\tif (!startsWith(path, PARTIAL_PATH)) {\n\t\t\t// The whole message or generation was replaced.\n\t\t\tif (startsWith(PARTIAL_PATH, path)) return [{ type: \"message\", message }];\n\t\t\tcontinue;\n\t\t}\n\t\tconst rest = path.slice(PARTIAL_PATH.length);\n\t\tif (rest[0] === \"usage\") continue;\n\t\tif (rest[0] !== \"content\") return [{ type: \"message\", message }];\n\t\tif (rest.length === 1) {\n\t\t\tif (op[0] !== \"p\" || op[3] !== 0) return [{ type: \"message\", message }];\n\t\t\tfor (const [offset, block] of (op[4] as unknown as Block[]).entries()) {\n\t\t\t\tconst type =\n\t\t\t\t\tblock.type === \"text\" ? \"text_start\" : block.type === \"thinking\" ? \"thinking_start\" : \"toolcall_start\";\n\t\t\t\tchanges.push({ type, contentIndex: op[2] + offset, block });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tconst contentIndex = rest[1] as number;\n\t\tconst field = rest[2];\n\t\tif (whole.has(contentIndex)) continue;\n\t\tif (op[0] === \"a\" && rest.length === 3 && (field === \"text\" || field === \"thinking\")) {\n\t\t\tchanges.push({ type: field === \"text\" ? \"text_delta\" : \"thinking_delta\", contentIndex, delta: op[2] });\n\t\t} else if (op[0] === \"a\" && field === \"arguments\") {\n\t\t\tchanges.push({ type: \"toolcall_delta\", contentIndex, path: rest.slice(3), delta: op[2] });\n\t\t} else {\n\t\t\twhole.add(contentIndex);\n\t\t\tchanges.push({ type: \"block\", contentIndex, block: message.content[contentIndex]! });\n\t\t}\n\t}\n\treturn changes;\n}\n\n/** Output, details, and diagnostics changes of a running slot, from the view operations on it. */\nfunction toolUpdate(\n\tviewOps: readonly Op[],\n\tindex: number,\n\tslot: ToolSlot,\n\tprevious: ToolSlot,\n): Omit<Extract<AgentEvent, { type: \"tool_execution_update\" }>, \"type\" | \"toolCallId\" | \"toolName\"> | undefined {\n\tconst outputPath = [\"docs\", \"pi.live\", \"tools\", index, \"output\"];\n\tlet trimStart = 0;\n\tlet append = \"\";\n\tlet set = false;\n\tfor (const op of viewOps) {\n\t\tif (!startsWith(op[1] as Path, outputPath)) continue;\n\t\tif (op[0] === \"t\") trimStart += op[2];\n\t\telse if (op[0] === \"a\") append += op[2];\n\t\telse set = true;\n\t}\n\tlet output: { trimStart?: number; append?: string } | { set: string } | undefined;\n\tif (set || (slot.output !== previous.output && trimStart === 0 && append === \"\"))\n\t\toutput = { set: slot.output ?? \"\" };\n\telse if (trimStart > 0 || append !== \"\") {\n\t\toutput = { ...(trimStart > 0 ? { trimStart } : {}), ...(append === \"\" ? {} : { append }) };\n\t}\n\t// A safe replay clears a running slot's progress: removed details send `null`, removed diagnostics `[]`.\n\tconst update = {\n\t\t...(output === undefined ? {} : { output }),\n\t\t...(slot.details === previous.details ? {} : { details: slot.details ?? null }),\n\t\t...(slot.diagnostics === previous.diagnostics ? {} : { diagnostics: slot.diagnostics ?? [] }),\n\t};\n\treturn Object.keys(update).length === 0 ? undefined : update;\n}\n\nfunction startsWith(path: Path, prefix: readonly (string | number)[]): boolean {\n\treturn prefix.length <= path.length && prefix.every((segment, index) => path[index] === segment);\n}\n"]}
|
|
1
|
+
{"version":3,"file":"events.js","sourceRoot":"","sources":["../../src/harness/events.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Context, JsonValue } from \"@earendil-works/chord\";\nimport type { Op, Path } from \"@earendil-works/chord/delta\";\nimport type { AssistantMessage, Message, Usage } from \"@earendil-works/pi-ai\";\nimport { CommittedWatch } from \"../session/observation.ts\";\nimport type {\n\tCommitChange,\n\tCommitPublication,\n\tConversationId,\n\tEntryRecord,\n\tJsonObject,\n\tSubmissionId,\n\tSubmissionRecord,\n\tTaskId,\n\tWatchEnd,\n} from \"../types.ts\";\nimport { AgentDoc } from \"./agent.ts\";\nimport type { InboxItem, InboxState } from \"./inbox.ts\";\nimport type { CompactionStatus, LiveState, ToolSlot } from \"./live.ts\";\nimport type { AgentState, CompactionReason, Harness, ToolDiagnostic } from \"./types.ts\";\nimport { UsageDoc, type UsageState } from \"./usage.ts\";\nimport { scanAll } from \"./util.ts\";\nimport { type ConversationView, conversationViews } from \"./view.ts\";\n\ntype Block = AssistantMessage[\"content\"][number];\ntype QueuedItem = { id: SubmissionId; mode: InboxItem[\"mode\"] };\n\n/** One change to the in-flight assistant message, relative to that message. */\nexport type MessageChange =\n\t| { type: \"text_start\" | \"thinking_start\" | \"toolcall_start\"; contentIndex: number; block: Block }\n\t| { type: \"text_delta\" | \"thinking_delta\"; contentIndex: number; delta: string }\n\t| { type: \"toolcall_delta\"; contentIndex: number; path: readonly (string | number)[]; delta: string }\n\t| { type: \"block\"; contentIndex: number; block: Block }\n\t| { type: \"message\"; message: AssistantMessage };\n\nexport type SnapshotEvent = {\n\ttype: \"snapshot\";\n\tentries: readonly EntryRecord[];\n\trun?: { inputs: readonly SubmissionId[] };\n\t/** Current generation attempt: its in-flight partial, retry backoff, or deferred poll. */\n\tgeneration?: {\n\t\tattempt: number;\n\t\tmessage?: AssistantMessage;\n\t\tretry?: { at: number; error: string };\n\t\tdeferred?: { pollAt: number };\n\t};\n\ttools: readonly ToolSlot[];\n\t/** `pi.live.compactions`: live compactions with their attempt and retry backoff. */\n\tcompactions: readonly CompactionStatus[];\n\tinbox: readonly QueuedItem[];\n\t/** `pi.agent`; `{}` when absent. */\n\tagent: AgentState;\n\tusage: UsageState;\n};\n\n/** Experimental agent event, shaped like the coding agent's session events (spec §9.4). */\nexport type AgentEvent =\n\t| SnapshotEvent\n\t| { type: \"run_start\"; inputs: readonly SubmissionId[] }\n\t| { type: \"run_end\"; inputs: readonly SubmissionId[] }\n\t| { type: \"turn_start\" }\n\t| { type: \"turn_end\" }\n\t| { type: \"message_start\"; message: Message }\n\t/** `usage` is the partial's current usage, as in the coding agent's JSON mode. */\n\t| { type: \"message_update\"; usage: Usage; changes: readonly MessageChange[] }\n\t| { type: \"message_end\"; entry: EntryRecord }\n\t| { type: \"tool_execution_start\"; toolCallId: string; toolName: string; args: JsonObject }\n\t| {\n\t\t\ttype: \"tool_execution_update\";\n\t\t\ttoolCallId: string;\n\t\t\ttoolName: string;\n\t\t\t/** A front trim and then an append of the retained window, or its replacement. */\n\t\t\toutput?: { trimStart?: number; append?: string } | { set: string };\n\t\t\tdetails?: JsonValue;\n\t\t\tdiagnostics?: readonly ToolDiagnostic[];\n\t }\n\t/** `entry` is absent when the tool task faulted or was orphaned. */\n\t| { type: \"tool_execution_end\"; toolCallId: string; toolName: string; entry?: EntryRecord }\n\t| { type: \"inbox_update\"; items: readonly QueuedItem[] }\n\t| { type: \"submission\"; record: SubmissionRecord }\n\t| { type: \"auto_retry_start\"; attempt: number; at: number; errorMessage: string }\n\t| { type: \"auto_retry_end\"; attempt: number }\n\t| { type: \"deferred_poll\"; pollAt: number }\n\t| { type: \"entry_appended\"; entry: EntryRecord }\n\t| { type: \"agent_changed\"; agent: AgentState }\n\t| { type: \"usage_changed\"; usage: UsageState }\n\t| { type: \"task_failed\"; taskId: TaskId; kind: string; message: string }\n\t| { type: \"compaction_start\"; taskId: TaskId; reason: CompactionReason; blocking: boolean }\n\t/** The task's receipt tells whether it produced a summary; the summary entry has its own events. */\n\t| { type: \"compaction_end\"; taskId: TaskId; reason: CompactionReason };\n\n/** Serialized stream of one conversation's event batches, one per commit. */\nexport interface AgentEventStream {\n\t/** The `snapshot` event at attachment. */\n\treadonly snapshot: SnapshotEvent;\n\tstart(listener: (events: readonly AgentEvent[], context: Context) => Promise<void>): void;\n\tstop(): Promise<WatchEnd>;\n\treadonly closed: Promise<WatchEnd>;\n}\n\n/** The typed parts of a view the events read. */\ntype Parts = {\n\tlive: LiveState;\n\tinbox: InboxState | undefined;\n\tagent: AgentState | undefined;\n\tusage: UsageState | undefined;\n};\n\nfunction parts(view: ConversationView): Parts {\n\treturn {\n\t\tlive: (view.docs[\"pi.live\"] ?? {}) as LiveState,\n\t\tinbox: view.docs[\"pi.inbox\"] as InboxState | undefined,\n\t\tagent: view.docs[\"pi.agent\"] as AgentState | undefined,\n\t\tusage: view.docs[\"pi.usage\"] as UsageState | undefined,\n\t};\n}\n\nfunction snapshotOf(view: ConversationView): SnapshotEvent {\n\tconst { live, inbox, agent, usage } = parts(view);\n\treturn {\n\t\ttype: \"snapshot\",\n\t\tentries: view.entries,\n\t\t...(live.run === undefined ? {} : { run: { inputs: live.run.inputs } }),\n\t\t...(live.generation === undefined ? {} : { generation: live.generation as SnapshotEvent[\"generation\"] }),\n\t\ttools: live.tools ?? [],\n\t\tcompactions: live.compactions ?? [],\n\t\tinbox: queued(inbox),\n\t\tagent: agent ?? AgentDoc.definition.initial(),\n\t\tusage: usage ?? UsageDoc.definition.initial(),\n\t};\n}\n\nfunction queued(inbox: InboxState | undefined): QueuedItem[] {\n\treturn (inbox?.items ?? []).map((item) => ({ id: item.id, mode: item.mode }));\n}\n\n/**\n * Experimental: attach to one conversation's agent events (spec §9.4). The snapshot and the registration for later\n * commits are captured atomically on the Session line; overflow replaces undelivered batches with one snapshot.\n */\nexport async function watchEvents(\n\tharness: Harness,\n\tconversationId: ConversationId,\n\tcontext: Context,\n): Promise<AgentEventStream> {\n\tlet watch!: CommittedWatch<readonly AgentEvent[]>;\n\tlet snapshot!: SnapshotEvent;\n\tawait conversationViews(harness).attach(\n\t\tconversationId,\n\t\tasync (initial, release, storage) => {\n\t\t\t// Generations whose held outcome already ended their turn, read on the line with the snapshot.\n\t\t\tconst query = { conversationId, kind: \"pi.generation\", status: \"completing\" } as const;\n\t\t\tconst completing = await scanAll((cursor) => storage.scanTasks(query, 100, cursor, context));\n\t\t\tconst held = new Set<TaskId>(completing.map((record) => record.id));\n\t\t\tlet current = initial;\n\t\t\tsnapshot = snapshotOf(initial);\n\t\t\t// Batches are the watch's values; an overflow delivers a snapshot of the newest view instead.\n\t\t\twatch = new CommittedWatch<readonly AgentEvent[]>([], release, () => [snapshotOf(current)]);\n\t\t\treturn {\n\t\t\t\tpublication: (before, after, ops, publication, commitContext) => {\n\t\t\t\t\tcurrent = after;\n\t\t\t\t\tconst events = translate(conversationId, before, after, ops, publication, held);\n\t\t\t\t\tif (events.length > 0) watch.advance(events, [], commitContext);\n\t\t\t\t},\n\t\t\t\tcloseSession: () => watch.closeSession(),\n\t\t\t};\n\t\t},\n\t\tcontext,\n\t);\n\t// Like a watch, the acquisition context governs the stream's lifetime.\n\tconst signal = context.abortSignal;\n\tif (signal?.aborted) {\n\t\twatch.cancel();\n\t\tthrow signal.reason;\n\t}\n\tif (signal !== undefined) watch.observeCancellation(signal);\n\treturn {\n\t\tsnapshot,\n\t\tstart: (listener) => watch.start((events, _ops, deliveryContext) => listener(events, deliveryContext)),\n\t\tstop: () => watch.stop(),\n\t\tclosed: watch.closed,\n\t};\n}\n\ntype TaskChange = Extract<CommitChange, { type: \"task\" }>;\n\n/** The tool result for `callId` among `entries`. */\nfunction resultOf(entries: readonly EntryRecord[], callId: string): EntryRecord | undefined {\n\treturn entries.find((entry) => {\n\t\tconst message = entry.model?.[0];\n\t\treturn message?.role === \"toolResult\" && message.toolCallId === callId;\n\t});\n}\n\n/** Every event one publication causes, in the order of spec §9.4. */\nfunction translate(\n\tconversationId: ConversationId,\n\tbefore: ConversationView,\n\tafter: ConversationView,\n\tviewOps: readonly Op[],\n\tpublication: CommitPublication,\n\theld: Set<TaskId>,\n): AgentEvent[] {\n\tconst entries: EntryRecord[] = [];\n\tconst tasks = new Map<TaskId, TaskChange[\"value\"]>();\n\tconst submissions: SubmissionRecord[] = [];\n\tfor (const change of publication.changes) {\n\t\tif (change.type === \"entry\" && change.value.conversationId === conversationId) entries.push(change.value);\n\t\tif (change.type === \"task\" && change.value.conversationId === conversationId)\n\t\t\ttasks.set(change.value.id, change.value);\n\t\tif (change.type === \"submission\" && change.value.conversationId === conversationId) {\n\t\t\tsubmissions.push(change.value);\n\t\t}\n\t}\n\tif (viewOps.length === 0 && entries.length === 0 && tasks.size === 0 && submissions.length === 0) return [];\n\t// Entries are appended in ID order; submission records are published in the order the commit first touched them.\n\tsubmissions.sort((a, b) => a.id - b.id);\n\tconst was = parts(before);\n\tconst now = parts(after);\n\tconst events: AgentEvent[] = [];\n\n\t// Progress: tool starts, the in-flight message, tool updates, retry and deferred state.\n\tconst slotsBefore = new Map((was.live.tools ?? []).map((slot) => [slot.callId, slot]));\n\tconst slots = now.live.tools ?? [];\n\tfor (const slot of slots) {\n\t\tif (slot.status !== \"running\" || slotsBefore.get(slot.callId)?.status === \"running\") continue;\n\t\tconst checkpoint = slot.taskId === undefined ? undefined : tasks.get(slot.taskId)?.state.checkpoint;\n\t\tconst args = (checkpoint as { arguments?: JsonObject } | undefined)?.arguments ?? {};\n\t\tevents.push({ type: \"tool_execution_start\", toolCallId: slot.callId, toolName: slot.name, args });\n\t}\n\tconst partialBefore = was.live.generation?.message as AssistantMessage | undefined;\n\tconst partial = now.live.generation?.message as AssistantMessage | undefined;\n\tif (partial !== undefined && partialBefore === undefined) events.push({ type: \"message_start\", message: partial });\n\telse if (partial !== undefined && partial !== partialBefore) {\n\t\tevents.push({ type: \"message_update\", usage: partial.usage, changes: messageChanges(viewOps, partial) });\n\t}\n\tfor (const [index, slot] of slots.entries()) {\n\t\tconst previous = slotsBefore.get(slot.callId);\n\t\tif (slot.status !== \"running\" || previous?.status !== \"running\") continue;\n\t\tconst update = toolUpdate(viewOps, index, slot, previous);\n\t\tif (update === undefined) continue;\n\t\tevents.push({ type: \"tool_execution_update\", toolCallId: slot.callId, toolName: slot.name, ...update });\n\t}\n\tconst generation = now.live.generation;\n\tconst generationBefore = was.live.generation;\n\tif (generation?.retry !== undefined && generationBefore?.retry === undefined) {\n\t\tconst { at, error } = generation.retry;\n\t\tevents.push({ type: \"auto_retry_start\", attempt: generation.attempt, at, errorMessage: error });\n\t}\n\tif (generationBefore?.retry !== undefined && generation?.retry === undefined) {\n\t\tevents.push({ type: \"auto_retry_end\", attempt: generationBefore.attempt });\n\t}\n\tif (generation?.deferred !== undefined && generation.deferred.pollAt !== generationBefore?.deferred?.pollAt) {\n\t\tevents.push({ type: \"deferred_poll\", pollAt: generation.deferred.pollAt });\n\t}\n\n\t// Tools that end in this commit: a slot that becomes done, one created done (a call not offered), or an unfinished\n\t// one that vanishes because its run ended. A done slot that vanishes ended earlier.\n\tconst toolEnds: Extract<AgentEvent, { type: \"tool_execution_end\" }>[] = [];\n\tconst endTool = (callId: string, name: string, entryId: number | undefined): void => {\n\t\tconst entry = entries.find((candidate) => candidate.id === entryId);\n\t\ttoolEnds.push({\n\t\t\ttype: \"tool_execution_end\",\n\t\t\ttoolCallId: callId,\n\t\t\ttoolName: name,\n\t\t\t...(entry === undefined ? {} : { entry }),\n\t\t});\n\t};\n\tfor (const previous of slotsBefore.values()) {\n\t\tif (previous.status === \"done\") continue;\n\t\tconst slot = slots.find((candidate) => candidate.callId === previous.callId);\n\t\tif (slot?.status === \"done\") endTool(previous.callId, previous.name, slot.entry);\n\t\t// A slot whose run ended in this commit may have had its result appended with it, as for unstarted calls.\n\t\telse if (slot === undefined) endTool(previous.callId, previous.name, resultOf(entries, previous.callId)?.id);\n\t}\n\tfor (const slot of slots) {\n\t\tif (slot.status === \"done\" && !slotsBefore.has(slot.callId)) endTool(slot.callId, slot.name, slot.entry);\n\t}\n\n\t// Entries in append order; a tool's end directly precedes its result's message, as in the coding agent.\n\tlet assistantAppended = false;\n\tfor (const entry of entries) {\n\t\tevents.push(...toolEnds.filter((end) => end.entry === entry));\n\t\tconst message = entry.model?.[0];\n\t\tif (message === undefined) {\n\t\t\tevents.push({ type: \"entry_appended\", entry });\n\t\t\tcontinue;\n\t\t}\n\t\t// A streamed answer already started with its first partial.\n\t\tconst streamed = message.role === \"assistant\" && partialBefore !== undefined && !assistantAppended;\n\t\tif (message.role === \"assistant\") assistantAppended = true;\n\t\tif (!streamed) events.push({ type: \"message_start\", message });\n\t\tevents.push({ type: \"message_end\", entry });\n\t}\n\t// Ends without a result entry: a faulted or orphaned tool, or one whose run ended.\n\tevents.push(...toolEnds.filter((end) => end.entry === undefined));\n\n\t// Compaction ends, task failures, then turn and run ends.\n\tconst compactionsBefore = was.live.compactions ?? [];\n\tconst compactions = now.live.compactions ?? [];\n\tfor (const { taskId, reason } of compactionsBefore) {\n\t\tif (!compactions.some((status) => status.taskId === taskId)) {\n\t\t\tevents.push({ type: \"compaction_end\", taskId, reason });\n\t\t}\n\t}\n\t// A generation's turn ends when its outcome is committed: at a `completing` hold or at terminal, whichever comes\n\t// first, so a successor created at the hold starts after it.\n\tlet turnEnded = false;\n\tfor (const task of tasks.values()) {\n\t\tconst status = task.state.status;\n\t\tif (task.kind === \"pi.generation\" && status === \"completing\" && !held.has(task.id)) {\n\t\t\theld.add(task.id);\n\t\t\tturnEnded = true;\n\t\t}\n\t\tif (status !== \"terminal\") continue;\n\t\tif (task.kind === \"pi.generation\" && !held.delete(task.id)) turnEnded = true;\n\t\tconst outcome = task.state.outcome;\n\t\tif (outcome.status === \"faulted\" || outcome.status === \"orphaned\") {\n\t\t\tconst message = outcome.status === \"faulted\" ? outcome.error.message : outcome.reason;\n\t\t\tevents.push({ type: \"task_failed\", taskId: task.id, kind: task.kind, message });\n\t\t}\n\t}\n\tif (turnEnded) events.push({ type: \"turn_end\" });\n\tconst run = now.live.run;\n\tconst runBefore = was.live.run;\n\tconst runChanged = run?.inputs[0] !== runBefore?.inputs[0];\n\tif (runBefore !== undefined && runChanged) events.push({ type: \"run_end\", inputs: runBefore.inputs });\n\n\t// Submissions, document state, then what began.\n\tfor (const record of submissions) events.push({ type: \"submission\", record });\n\tif (now.inbox !== was.inbox) events.push({ type: \"inbox_update\", items: queued(now.inbox) });\n\t// A retired document reads as its initial value, as in a snapshot.\n\tif (now.agent !== was.agent) {\n\t\tevents.push({ type: \"agent_changed\", agent: now.agent ?? AgentDoc.definition.initial() });\n\t}\n\tif (now.usage !== was.usage)\n\t\tevents.push({ type: \"usage_changed\", usage: now.usage ?? UsageDoc.definition.initial() });\n\tfor (const { taskId, reason, blocking } of compactions) {\n\t\tif (!compactionsBefore.some((status) => status.taskId === taskId)) {\n\t\t\tevents.push({ type: \"compaction_start\", taskId, reason, blocking });\n\t\t}\n\t}\n\tif (run !== undefined && runChanged) events.push({ type: \"run_start\", inputs: run.inputs });\n\tif (run !== undefined && run.taskId !== runBefore?.taskId && tasks.get(run.taskId)?.kind === \"pi.generation\") {\n\t\tevents.push({ type: \"turn_start\" });\n\t}\n\treturn events;\n}\n\nconst PARTIAL_PATH = [\"docs\", \"pi.live\", \"generation\", \"message\"];\n\n/** Translate the view operations on the in-flight message into message changes (spec §9.4). */\nfunction messageChanges(viewOps: readonly Op[], message: AssistantMessage): MessageChange[] {\n\tconst changes: MessageChange[] = [];\n\t// A block sent whole already holds every later change to it in this batch.\n\tconst whole = new Set<number>();\n\tfor (const op of viewOps) {\n\t\t// View operations never replace the root.\n\t\tconst path = op[1] as Path;\n\t\tif (!startsWith(path, PARTIAL_PATH)) {\n\t\t\t// The whole message or generation was replaced.\n\t\t\tif (startsWith(PARTIAL_PATH, path)) return [{ type: \"message\", message }];\n\t\t\tcontinue;\n\t\t}\n\t\tconst rest = path.slice(PARTIAL_PATH.length);\n\t\tif (rest[0] === \"usage\") continue;\n\t\tif (rest[0] !== \"content\") return [{ type: \"message\", message }];\n\t\tif (rest.length === 1) {\n\t\t\tif (op[0] !== \"p\" || op[3] !== 0) return [{ type: \"message\", message }];\n\t\t\tfor (const [offset, block] of (op[4] as unknown as Block[]).entries()) {\n\t\t\t\tconst type =\n\t\t\t\t\tblock.type === \"text\" ? \"text_start\" : block.type === \"thinking\" ? \"thinking_start\" : \"toolcall_start\";\n\t\t\t\tchanges.push({ type, contentIndex: op[2] + offset, block });\n\t\t\t}\n\t\t\tcontinue;\n\t\t}\n\t\tconst contentIndex = rest[1] as number;\n\t\tconst field = rest[2];\n\t\tif (whole.has(contentIndex)) continue;\n\t\tif (op[0] === \"a\" && rest.length === 3 && (field === \"text\" || field === \"thinking\")) {\n\t\t\tchanges.push({ type: field === \"text\" ? \"text_delta\" : \"thinking_delta\", contentIndex, delta: op[2] });\n\t\t} else if (op[0] === \"a\" && field === \"arguments\") {\n\t\t\tchanges.push({ type: \"toolcall_delta\", contentIndex, path: rest.slice(3), delta: op[2] });\n\t\t} else {\n\t\t\twhole.add(contentIndex);\n\t\t\tchanges.push({ type: \"block\", contentIndex, block: message.content[contentIndex]! });\n\t\t}\n\t}\n\treturn changes;\n}\n\n/** Output, details, and diagnostics changes of a running slot, from the view operations on it. */\nfunction toolUpdate(\n\tviewOps: readonly Op[],\n\tindex: number,\n\tslot: ToolSlot,\n\tprevious: ToolSlot,\n): Omit<Extract<AgentEvent, { type: \"tool_execution_update\" }>, \"type\" | \"toolCallId\" | \"toolName\"> | undefined {\n\tconst outputPath = [\"docs\", \"pi.live\", \"tools\", index, \"output\"];\n\tlet trimStart = 0;\n\tlet append = \"\";\n\tlet set = false;\n\tfor (const op of viewOps) {\n\t\tif (!startsWith(op[1] as Path, outputPath)) continue;\n\t\tif (op[0] === \"t\") trimStart += op[2];\n\t\telse if (op[0] === \"a\") append += op[2];\n\t\telse set = true;\n\t}\n\tlet output: { trimStart?: number; append?: string } | { set: string } | undefined;\n\tif (set || (slot.output !== previous.output && trimStart === 0 && append === \"\"))\n\t\toutput = { set: slot.output ?? \"\" };\n\telse if (trimStart > 0 || append !== \"\") {\n\t\toutput = { ...(trimStart > 0 ? { trimStart } : {}), ...(append === \"\" ? {} : { append }) };\n\t}\n\t// A safe replay clears a running slot's progress: removed details send `null`, removed diagnostics `[]`.\n\tconst update = {\n\t\t...(output === undefined ? {} : { output }),\n\t\t...(slot.details === previous.details ? {} : { details: slot.details ?? null }),\n\t\t...(slot.diagnostics === previous.diagnostics ? {} : { diagnostics: slot.diagnostics ?? [] }),\n\t};\n\treturn Object.keys(update).length === 0 ? undefined : update;\n}\n\nfunction startsWith(path: Path, prefix: readonly (string | number)[]): boolean {\n\treturn prefix.length <= path.length && prefix.every((segment, index) => path[index] === segment);\n}\n"]}
|