@earendil-works/pi-durable 1.1.0 → 1.2.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 +40 -0
- package/README.md +147 -11
- package/dist/codemode/codemode.d.ts +173 -0
- package/dist/codemode/codemode.d.ts.map +1 -0
- package/dist/codemode/codemode.js +886 -0
- package/dist/codemode/codemode.js.map +1 -0
- package/dist/codemode/describe.d.ts +38 -0
- package/dist/codemode/describe.d.ts.map +1 -0
- package/dist/codemode/describe.js +119 -0
- package/dist/codemode/describe.js.map +1 -0
- package/dist/codemode/index.d.ts +3 -0
- package/dist/codemode/index.d.ts.map +1 -0
- package/dist/codemode/index.js +3 -0
- package/dist/codemode/index.js.map +1 -0
- package/dist/codemode/models.d.ts +28 -0
- package/dist/codemode/models.d.ts.map +1 -0
- package/dist/codemode/models.js +231 -0
- package/dist/codemode/models.js.map +1 -0
- package/dist/codemode/output.d.ts +41 -0
- package/dist/codemode/output.d.ts.map +1 -0
- package/dist/codemode/output.js +167 -0
- package/dist/codemode/output.js.map +1 -0
- package/dist/env/index.d.ts +42 -0
- package/dist/env/index.d.ts.map +1 -1
- package/dist/env/index.js.map +1 -1
- package/dist/errors.d.ts +20 -3
- package/dist/errors.d.ts.map +1 -1
- package/dist/errors.js +34 -5
- package/dist/errors.js.map +1 -1
- package/dist/harness/agent.d.ts +5 -2
- package/dist/harness/agent.d.ts.map +1 -1
- package/dist/harness/agent.js +69 -25
- package/dist/harness/agent.js.map +1 -1
- package/dist/harness/compaction.d.ts +6 -1
- package/dist/harness/compaction.d.ts.map +1 -1
- package/dist/harness/compaction.js +10 -7
- package/dist/harness/compaction.js.map +1 -1
- package/dist/harness/events.d.ts +35 -15
- package/dist/harness/events.d.ts.map +1 -1
- package/dist/harness/events.js +77 -23
- package/dist/harness/events.js.map +1 -1
- package/dist/harness/generation.d.ts +2 -0
- package/dist/harness/generation.d.ts.map +1 -1
- package/dist/harness/generation.js +31 -8
- package/dist/harness/generation.js.map +1 -1
- package/dist/harness/harness.d.ts +7 -0
- package/dist/harness/harness.d.ts.map +1 -1
- package/dist/harness/harness.js +53 -26
- package/dist/harness/harness.js.map +1 -1
- package/dist/harness/inbox.d.ts +16 -4
- package/dist/harness/inbox.d.ts.map +1 -1
- package/dist/harness/inbox.js +26 -3
- package/dist/harness/inbox.js.map +1 -1
- package/dist/harness/live.d.ts +74 -17
- package/dist/harness/live.d.ts.map +1 -1
- package/dist/harness/live.js +66 -14
- package/dist/harness/live.js.map +1 -1
- package/dist/harness/scheduler.d.ts +18 -5
- package/dist/harness/scheduler.d.ts.map +1 -1
- package/dist/harness/scheduler.js +696 -163
- package/dist/harness/scheduler.js.map +1 -1
- package/dist/harness/submissions.d.ts +7 -4
- package/dist/harness/submissions.d.ts.map +1 -1
- package/dist/harness/submissions.js +32 -13
- package/dist/harness/submissions.js.map +1 -1
- package/dist/harness/task-graph.d.ts +1 -1
- package/dist/harness/task-graph.d.ts.map +1 -1
- package/dist/harness/task-graph.js +15 -10
- package/dist/harness/task-graph.js.map +1 -1
- package/dist/harness/tool.d.ts +45 -5
- package/dist/harness/tool.d.ts.map +1 -1
- package/dist/harness/tool.js +377 -62
- package/dist/harness/tool.js.map +1 -1
- package/dist/harness/types.d.ts +153 -13
- package/dist/harness/types.d.ts.map +1 -1
- package/dist/harness/types.js.map +1 -1
- package/dist/harness/util.d.ts +6 -1
- package/dist/harness/util.d.ts.map +1 -1
- package/dist/harness/util.js +5 -2
- package/dist/harness/util.js.map +1 -1
- package/dist/harness/view.d.ts +6 -2
- package/dist/harness/view.d.ts.map +1 -1
- package/dist/harness/view.js +22 -12
- package/dist/harness/view.js.map +1 -1
- package/dist/images/cloudflare.d.ts +4 -0
- package/dist/images/cloudflare.d.ts.map +1 -0
- package/dist/images/cloudflare.js +9 -0
- package/dist/images/cloudflare.js.map +1 -0
- package/dist/images/exif.d.ts +3 -0
- package/dist/images/exif.d.ts.map +1 -0
- package/dist/images/exif.js +71 -0
- package/dist/images/exif.js.map +1 -0
- package/dist/images/index.d.ts +18 -0
- package/dist/images/index.d.ts.map +1 -0
- package/dist/images/index.js +125 -0
- package/dist/images/index.js.map +1 -0
- package/dist/images/node-worker.d.ts +17 -0
- package/dist/images/node-worker.d.ts.map +1 -0
- package/dist/images/node-worker.js +16 -0
- package/dist/images/node-worker.js.map +1 -0
- package/dist/images/node.d.ts +21 -0
- package/dist/images/node.d.ts.map +1 -0
- package/dist/images/node.js +121 -0
- package/dist/images/node.js.map +1 -0
- package/dist/index.d.ts +6 -6
- package/dist/index.d.ts.map +1 -1
- package/dist/index.js +3 -3
- package/dist/index.js.map +1 -1
- package/dist/search.d.ts +13 -0
- package/dist/search.d.ts.map +1 -0
- package/dist/search.js +85 -0
- package/dist/search.js.map +1 -0
- package/dist/session/observation.d.ts +10 -3
- package/dist/session/observation.d.ts.map +1 -1
- package/dist/session/observation.js +24 -34
- package/dist/session/observation.js.map +1 -1
- package/dist/session/session.d.ts +68 -5
- package/dist/session/session.d.ts.map +1 -1
- package/dist/session/session.js +461 -49
- package/dist/session/session.js.map +1 -1
- package/dist/session/transaction.d.ts.map +1 -1
- package/dist/session/transaction.js +1 -0
- package/dist/session/transaction.js.map +1 -1
- package/dist/storage/jsonl/storage.d.ts +4 -0
- package/dist/storage/jsonl/storage.d.ts.map +1 -1
- package/dist/storage/jsonl/storage.js +2 -1
- package/dist/storage/jsonl/storage.js.map +1 -1
- package/dist/storage/memory.d.ts.map +1 -1
- package/dist/storage/memory.js +8 -10
- package/dist/storage/memory.js.map +1 -1
- package/dist/storage/scan.d.ts.map +1 -1
- package/dist/storage/scan.js +5 -4
- package/dist/storage/scan.js.map +1 -1
- package/dist/storage/sqlite/storage.d.ts.map +1 -1
- package/dist/storage/sqlite/storage.js +10 -12
- package/dist/storage/sqlite/storage.js.map +1 -1
- package/dist/testing/env-conformance.d.ts.map +1 -1
- package/dist/testing/env-conformance.js +100 -0
- package/dist/testing/env-conformance.js.map +1 -1
- package/dist/testing/runner.d.ts +1 -1
- package/dist/testing/runner.d.ts.map +1 -1
- package/dist/testing/runner.js.map +1 -1
- package/dist/testing/storage-conformance.d.ts.map +1 -1
- package/dist/testing/storage-conformance.js +3 -2
- package/dist/testing/storage-conformance.js.map +1 -1
- package/dist/testing/types.d.ts +2 -0
- package/dist/testing/types.d.ts.map +1 -1
- package/dist/testing/types.js.map +1 -1
- package/dist/tool-search/index.d.ts +2 -0
- package/dist/tool-search/index.d.ts.map +1 -0
- package/dist/tool-search/index.js +2 -0
- package/dist/tool-search/index.js.map +1 -0
- package/dist/tool-search/tool-search.d.ts +23 -0
- package/dist/tool-search/tool-search.d.ts.map +1 -0
- package/dist/tool-search/tool-search.js +84 -0
- package/dist/tool-search/tool-search.js.map +1 -0
- package/dist/tools/bash.d.ts +10 -2
- package/dist/tools/bash.d.ts.map +1 -1
- package/dist/tools/bash.js +27 -9
- package/dist/tools/bash.js.map +1 -1
- package/dist/tools/edit.js +1 -1
- package/dist/tools/edit.js.map +1 -1
- package/dist/tools/image-processor.d.ts +47 -0
- package/dist/tools/image-processor.d.ts.map +1 -0
- package/dist/tools/image-processor.js +30 -0
- package/dist/tools/image-processor.js.map +1 -0
- package/dist/tools/image.d.ts +8 -0
- package/dist/tools/image.d.ts.map +1 -1
- package/dist/tools/image.js +47 -0
- package/dist/tools/image.js.map +1 -1
- package/dist/tools/index.d.ts +25 -2
- package/dist/tools/index.d.ts.map +1 -1
- package/dist/tools/index.js +13 -5
- package/dist/tools/index.js.map +1 -1
- package/dist/tools/read.d.ts +10 -2
- package/dist/tools/read.d.ts.map +1 -1
- package/dist/tools/read.js +87 -28
- package/dist/tools/read.js.map +1 -1
- package/dist/tools/write.js +1 -1
- package/dist/tools/write.js.map +1 -1
- package/dist/types.d.ts +59 -5
- package/dist/types.d.ts.map +1 -1
- package/dist/types.js.map +1 -1
- package/package.json +43 -4
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/harness/harness.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AttachedReplicatedState, Context, JsonValue } from \"@earendil-works/chord\";\nimport { withAbortSignal, withoutAbortSignal } from \"@earendil-works/chord/context\";\nimport { ResetEntry } from \"../entries.ts\";\nimport type { ExecutionEnv } from \"../env/index.ts\";\nimport { SessionImpl } from \"../session/session.ts\";\nimport type { Transaction } from \"../session/transaction.ts\";\nimport type {\n\tConversationId,\n\tConversationOwnership,\n\tConversationRecord,\n\tCursor,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tPage,\n\tStorage,\n\tSubmissionId,\n\tTaskId,\n\tTaskRecord,\n\tTx,\n} from \"../types.ts\";\nimport { ROOT_CONVERSATION_ID } from \"../types.ts\";\nimport { AgentDoc, configure, createAgent, resolveAgent, resolveSettings } from \"./agent.ts\";\nimport { createCompaction } from \"./compaction.ts\";\nimport { readContext } from \"./context.ts\";\nimport { InboxDoc, withdrawQueuedInputs } from \"./inbox.ts\";\nimport { LiveDoc, settleSchedulerOutcome } from \"./live.ts\";\nimport { ProviderDoc } from \"./provider.ts\";\nimport { BUILTIN_TASKS } from \"./registry.ts\";\nimport { type InvocationBinding, TaskScheduler } from \"./scheduler.ts\";\nimport { Submissions } from \"./submissions.ts\";\nimport { type TaskGraph, TaskGraphView, type TaskGraphWatch } from \"./task-graph.ts\";\nimport type {\n\tAgent,\n\tAgentChange,\n\tCompactionResult,\n\tContextView,\n\tConversation,\n\tConversationAbortOptions,\n\tConversationCreateOptions,\n\tConversationHandle,\n\tConversationInit,\n\tConversationWatch,\n\tHarnessInspection,\n\tHarnessOptions,\n\tHarness as HarnessType,\n\tRegistrySnapshot,\n\tSettledTask,\n\tSubmission,\n\tSubmissionDraft,\n\tToolRegistration,\n} from \"./types.ts\";\nimport { addUsageState, UsageDoc, type UsageState } from \"./usage.ts\";\nimport { scanAll } from \"./util.ts\";\nimport { type ConversationView, ConversationViews } from \"./view.ts\";\n\nconst SCAN_PAGE_SIZE = 256;\n\ntype CreateTarget =\n\t| { readonly kind: \"root\" }\n\t| { readonly kind: \"independent\"; readonly ownership: ConversationOwnership }\n\t| {\n\t\t\treadonly kind: \"fork\";\n\t\t\treadonly parentId: ConversationId;\n\t\t\treadonly at: EntryId;\n\t\t\treadonly ownership: ConversationOwnership;\n\t };\n\n/** What the conveniences apply in the creating commit, after the creation hook. */\ntype CreateOptions = { readonly agent?: AgentChange; readonly init?: ConversationInit };\n\n/** Harness-private services used by Conversation handles. */\ntype ConversationHost<Tool extends ToolRegistration> = {\n\treadonly harness: HarnessImpl<Tool>;\n\treadonly storage: Storage;\n\treadonly tasks: TaskScheduler;\n\treadonly submissions: Submissions;\n\treadonly views: ConversationViews;\n\treadonly now: () => number;\n\tcreate(target: CreateTarget, options: CreateOptions, context: Context): Promise<Conversation>;\n};\n\nclass ConversationImpl<Tool extends ToolRegistration> implements Conversation {\n\treadonly id: ConversationId;\n\treadonly #host: ConversationHost<Tool>;\n\n\tconstructor(id: ConversationId, host: ConversationHost<Tool>) {\n\t\tthis.id = id;\n\t\tthis.#host = host;\n\t}\n\n\tagent(context: Context): Promise<Agent> {\n\t\treturn this.#host.harness.resolveAgent(this.id, undefined, context);\n\t}\n\n\tconfigure(change: AgentChange, context: Context): Promise<void> {\n\t\treturn this.#host.harness.commitWith((tx) => configure(tx, this.id, change), context);\n\t}\n\n\tsubmit(submission: SubmissionDraft, context: Context): Promise<Submission> {\n\t\treturn this.#host.submissions.submit(this.id, submission, context);\n\t}\n\n\tcompact(instructions: string | undefined, context: Context): Promise<TaskId<CompactionResult>> {\n\t\tthis.#host.tasks.resume();\n\t\tconst input = { reason: \"manual\", ...(instructions === undefined ? {} : { instructions }) } as const;\n\t\treturn this.#host.harness.commitWith((tx) => createCompaction(tx, this.id, input), context);\n\t}\n\n\tasync reset(handoff: string | undefined, context: Context): Promise<void> {\n\t\tconst model =\n\t\t\thandoff === undefined\n\t\t\t\t? {}\n\t\t\t\t: { model: [{ role: \"user\", content: handoff, timestamp: this.#host.now() } as const] };\n\t\tconst entry = { kind: ResetEntry.kind, head: \"self\", ...model } as const;\n\t\tawait this.#host.submissions.submit(this.id, { type: \"write\", entry }, context);\n\t}\n\n\tcommit<T>(change: (tx: Tx) => T | Promise<T>, context: Context): Promise<T> {\n\t\treturn this.#host.harness.commitWith(change, context, { conversationId: this.id });\n\t}\n\n\tcontext(context: Context, options?: { readonly at?: EntryId }): Promise<ContextView> {\n\t\treturn readContext(this.#host.harness, this.#host.storage, this.id, context, options?.at);\n\t}\n\n\tentries(\n\t\tquery: Omit<EntryQuery, \"conversationId\">,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\tcontext: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tconst bounded: EntryQuery = {\n\t\t\tconversationId: this.id,\n\t\t\t...(query.minEntryId === undefined ? {} : { minEntryId: query.minEntryId }),\n\t\t\t...(query.maxEntryId === undefined ? {} : { maxEntryId: query.maxEntryId }),\n\t\t\t...(query.order === undefined ? {} : { order: query.order }),\n\t\t};\n\t\treturn this.#host.harness.readOnLine(() => this.#host.storage.scanEntries(bounded, limit, cursor, context));\n\t}\n\n\tfork(at: EntryId, options: ConversationCreateOptions, context: Context): Promise<Conversation> {\n\t\treturn this.#host.create({ kind: \"fork\", parentId: this.id, at, ownership: options.ownership }, options, context);\n\t}\n\n\tabort(context: Context, options?: ConversationAbortOptions): Promise<void> {\n\t\tthis.#host.tasks.resume();\n\t\treturn this.#host.tasks.abortConversation(this.id, options?.background === true, context);\n\t}\n\n\twaitForIdle(context: Context): Promise<void> {\n\t\tthis.#host.tasks.resume();\n\t\treturn this.#host.tasks.waitForIdle(this.id, context);\n\t}\n\n\tviewState(context: Context): Promise<AttachedReplicatedState<ConversationView>> {\n\t\treturn this.#host.views.state(this.id, context);\n\t}\n\n\twatch(context: Context): Promise<ConversationWatch> {\n\t\treturn this.#host.views.watch(this.id, context);\n\t}\n}\n\n/** Session kernel extended with conversation handles and a registry. */\nclass HarnessImpl<Tool extends ToolRegistration> extends SessionImpl implements HarnessType {\n\treadonly #storage: Storage;\n\treadonly #options: HarnessOptions<Tool>;\n\treadonly #report: (error: unknown) => void;\n\treadonly #host: ConversationHost<Tool>;\n\treadonly #tasks: TaskScheduler;\n\treadonly #submissions: Submissions;\n\treadonly #taskGraph: TaskGraphView;\n\t#closed = false;\n\n\tconstructor(storage: Storage, options: HarnessOptions<Tool>, context: Context) {\n\t\tsuper(storage, options.now);\n\t\tthis.#storage = storage;\n\t\tthis.#options = options;\n\t\tthis.#report = options.onReport ?? (() => {});\n\t\tconst now = options.now ?? Date.now;\n\t\tconst settings = () => resolveSettings(options.settings);\n\t\tthis.#tasks = new TaskScheduler({\n\t\t\tsession: this,\n\t\t\tstorage,\n\t\t\tregistry: options.registry,\n\t\t\tmodels: options.models,\n\t\t\tagent: (id, snapshot, callContext) => this.resolveAgent(id, snapshot as RegistrySnapshot<Tool>, callContext),\n\t\t\tsettings,\n\t\t\tenv: (id, callContext) => this.buildEnv(id, callContext),\n\t\t\tnow,\n\t\t\treport: this.#report,\n\t\t\tsettleOutcome: settleSchedulerOutcome,\n\t\t\twithdrawInputs: withdrawQueuedInputs,\n\t\t\tconversation: async (id, binding, callContext) => {\n\t\t\t\tconst record = await this.readOnLine(() => storage.conversation(id, callContext));\n\t\t\t\treturn record === undefined ? undefined : boundConversation(id, binding, this.#submissions, this.#tasks);\n\t\t\t},\n\t\t\tcontext: withoutAbortSignal(context),\n\t\t});\n\t\tthis.#submissions = new Submissions(this, storage, now, settings, () => this.#tasks.resume());\n\t\tthis.#taskGraph = new TaskGraphView(this, storage);\n\t\tthis.#host = {\n\t\t\tharness: this,\n\t\t\tstorage,\n\t\t\ttasks: this.#tasks,\n\t\t\tsubmissions: this.#submissions,\n\t\t\tviews: new ConversationViews(this, storage),\n\t\t\tnow,\n\t\t\tcreate: (target, createOptions, context) => this.#create(target, createOptions, context),\n\t\t};\n\t}\n\n\t/** Resolve a conversation's committed `pi.agent` against `snapshot`, or the current one, and the current settings. */\n\tasync resolveAgent(\n\t\tid: ConversationId,\n\t\tsnapshot: RegistrySnapshot<Tool> | undefined,\n\t\tcontext: Context,\n\t): Promise<Agent<Tool>> {\n\t\tconst registry = snapshot ?? this.#options.registry.snapshot();\n\t\tconst state = await this.snapshot(AgentDoc, id, context);\n\t\treturn resolveAgent(state, registry, resolveSettings(this.#options.settings), this.#report);\n\t}\n\n\t/** Build a conversation's environment from its current `cwd`; `undefined` without an `env` option. */\n\tasync buildEnv(id: ConversationId, context: Context): Promise<ExecutionEnv | undefined> {\n\t\tconst build = this.#options.env;\n\t\tif (build === undefined) return undefined;\n\t\tconst cwd = (await this.snapshot(AgentDoc, id, context))?.cwd;\n\t\treturn build({ conversationId: id, ...(cwd === undefined ? {} : { cwd }), read: this }, context);\n\t}\n\n\t/** Reconcile surviving `running` tasks to `pending`; part of open. */\n\topenTasks(context: Context): Promise<void> {\n\t\treturn this.#tasks.open(context);\n\t}\n\n\tresume(): void {\n\t\tthis.#assertOpen();\n\t\tthis.#tasks.resume();\n\t}\n\n\tgetTask<R>(id: TaskId<R>, context: Context): Promise<TaskRecord<JsonValue, JsonValue, R> | undefined> {\n\t\treturn this.readOnLine(() => this.#storage.task(id, context)) as Promise<\n\t\t\tTaskRecord<JsonValue, JsonValue, R> | undefined\n\t\t>;\n\t}\n\n\tinspect(context: Context): Promise<HarnessInspection> {\n\t\treturn this.readOnLine(async () => {\n\t\t\tconst { scheduling, tasks } = await this.#tasks.inspect(this.#options.registry.snapshot());\n\t\t\tconst scan = (status: \"queued\" | \"placed\") =>\n\t\t\t\tscanAll((cursor) => this.#storage.scanSubmissions({ status }, SCAN_PAGE_SIZE, cursor, context));\n\t\t\tconst submissions = [...(await scan(\"queued\")), ...(await scan(\"placed\"))].sort((a, b) => a.id - b.id);\n\t\t\treturn { scheduling, tasks, submissions };\n\t\t});\n\t}\n\n\tsubmission(id: SubmissionId, context: Context): Promise<Submission | undefined> {\n\t\treturn this.#submissions.get(id, context);\n\t}\n\n\tabortSubmission(\n\t\tid: SubmissionId,\n\t\tcontext: Context,\n\t\tconversationId?: ConversationId,\n\t): Promise<\"aborted\" | \"already_placed\" | \"settled\" | \"not_found\"> {\n\t\treturn this.#submissions.abort(id, context, conversationId);\n\t}\n\n\tabortTask(id: TaskId, context: Context): Promise<\"marked\" | \"terminal\"> {\n\t\treturn this.#tasks.abort(id, context);\n\t}\n\n\twaitForTask<R>(id: TaskId<R>, context: Context): Promise<SettledTask<R>> {\n\t\tthis.#tasks.resume();\n\t\treturn this.#tasks.waitForTask(id, context) as Promise<SettledTask<R>>;\n\t}\n\n\twaitForIdle(context: Context): Promise<void> {\n\t\tthis.#tasks.resume();\n\t\treturn this.#tasks.waitForIdle(undefined, context);\n\t}\n\n\t/** Sum every conversation's committed `pi.usage`. Each document is read at its own point; totals only grow. */\n\tasync usage(context: Context): Promise<UsageState> {\n\t\tconst conversations = await this.readOnLine(() =>\n\t\t\tscanAll((cursor) => this.#storage.scanConversations({}, SCAN_PAGE_SIZE, cursor, context)),\n\t\t);\n\t\tconst total = UsageDoc.definition.initial();\n\t\tfor (const { id } of conversations) {\n\t\t\tconst state = await this.snapshot(UsageDoc, id, context);\n\t\t\tif (state !== undefined) addUsageState(total, state);\n\t\t}\n\t\treturn total;\n\t}\n\n\ttaskGraph(context: Context): Promise<AttachedReplicatedState<TaskGraph>> {\n\t\treturn this.#taskGraph.state(context);\n\t}\n\n\twatchTaskGraph(context: Context): Promise<TaskGraphWatch> {\n\t\treturn this.#taskGraph.watch(context);\n\t}\n\n\troot(\n\t\tcontext: Context,\n\t\toptions?: { readonly agent?: AgentChange; readonly init?: ConversationInit },\n\t): Promise<Conversation> {\n\t\treturn this.#create({ kind: \"root\" }, options ?? {}, context);\n\t}\n\n\tasync conversation(id: ConversationId, context: Context): Promise<Conversation | undefined> {\n\t\tthis.#assertOpen();\n\t\tconst record = await this.readOnLine(() => this.#storage.conversation(id, context));\n\t\treturn record === undefined ? undefined : new ConversationImpl(record.id, this.#host);\n\t}\n\n\tcreateConversation(options: ConversationCreateOptions, context: Context): Promise<Conversation> {\n\t\treturn this.#create({ kind: \"independent\", ownership: options.ownership }, options, context);\n\t}\n\n\toverride close(context: Context): Promise<void> {\n\t\tthis.#closed = true;\n\t\treturn super.close(context);\n\t}\n\n\t/** Join task invocations after admission is sealed and before Storage closes; writes no task outcome. */\n\tprotected override beforeClose(): Promise<void> {\n\t\treturn this.#tasks.join();\n\t}\n\n\tasync #create(target: CreateTarget, options: CreateOptions, context: Context): Promise<Conversation> {\n\t\tthis.#assertOpen();\n\t\tconst id = await this.commitWith(async (tx) => {\n\t\t\tif (target.kind === \"root\" && (await tx.conversation(ROOT_CONVERSATION_ID)) !== undefined) {\n\t\t\t\treturn ROOT_CONVERSATION_ID;\n\t\t\t}\n\t\t\tconst record =\n\t\t\t\ttarget.kind === \"root\"\n\t\t\t\t\t? await tx.createRootConversation()\n\t\t\t\t\t: target.kind === \"fork\"\n\t\t\t\t\t\t? await tx.forkConversation(target.parentId, target.at, { ownership: target.ownership })\n\t\t\t\t\t\t: await tx.createConversation({ ownership: target.ownership });\n\t\t\tif (options.agent !== undefined) await configure(tx, record.id, options.agent);\n\t\t\tif (options.init !== undefined) await options.init(tx, record.id);\n\t\t\treturn record.id;\n\t\t}, context);\n\t\treturn new ConversationImpl(id, this.#host);\n\t}\n\n\t/**\n\t * The built-in creation hook, in every commit that creates or forks a conversation: empty `pi.live`, `pi.inbox`, and\n\t * `pi.usage`, a fresh `pi.provider`, the conversation's `pi.agent` (see `createAgent()`), then\n\t * `HarnessOptions.conversationCreated`.\n\t */\n\tprotected override async conversationCreated(tx: Transaction, record: ConversationRecord): Promise<void> {\n\t\tawait tx.doc(LiveDoc, record.id);\n\t\tawait tx.doc(InboxDoc, record.id);\n\t\tawait tx.doc(UsageDoc, record.id);\n\t\tawait tx.doc(ProviderDoc, record.id);\n\t\tawait createAgent(tx, record);\n\t\tawait this.#options.conversationCreated?.(tx, record);\n\t}\n\n\t#assertOpen(): void {\n\t\tif (this.#closed) throw new Error(\"Harness is closed\");\n\t}\n}\n\n/**\n * Invocation-bound handle for tasks and tools. Every operation, and every operation of a submission it returns, first\n * checks the invocation and runs under its signal, so it rejects once the invocation ends; admitted work stays durable.\n */\nfunction boundConversation(\n\tid: ConversationId,\n\tbinding: InvocationBinding,\n\tsubmissions: Submissions,\n\ttasks: TaskScheduler,\n): ConversationHandle {\n\tconst bind = (context: Context): Context => withAbortSignal(binding.signal, context);\n\tconst bound = <T>(operation: (context: Context) => Promise<T>) => {\n\t\treturn async (context: Context): Promise<T> => {\n\t\t\tbinding.check();\n\t\t\treturn operation(bind(context));\n\t\t};\n\t};\n\treturn {\n\t\tid,\n\t\tsubmit: async (draft, context) => {\n\t\t\tbinding.check();\n\t\t\tconst submission = await submissions.submit(id, draft, bind(context));\n\t\t\treturn {\n\t\t\t\tid: submission.id,\n\t\t\t\tstatus: bound((callContext) => submission.status(callContext)),\n\t\t\t\twait: bound((callContext) => submission.wait(callContext)),\n\t\t\t\tabort: bound((callContext) => submission.abort(callContext)),\n\t\t\t};\n\t\t},\n\t\tabort: async (context, options) => {\n\t\t\tbinding.check();\n\t\t\treturn tasks.abortConversation(id, options?.background === true, bind(context));\n\t\t},\n\t\twaitForIdle: bound((callContext) => tasks.waitForIdle(id, callContext)),\n\t};\n}\n\n/** Durable agent harness over one Session. */\nexport type Harness = HarnessType;\n\nexport const Harness = {\n\t/** Open a Harness over storage. The registry may keep changing while the Harness runs. */\n\tasync open<Tool extends ToolRegistration>(\n\t\tstorage: Storage,\n\t\toptions: HarnessOptions<Tool>,\n\t\tcontext: Context,\n\t): Promise<Harness> {\n\t\tcontext.abortSignal?.throwIfAborted();\n\t\tconst snapshot = options.registry.snapshot();\n\t\tconst missing = BUILTIN_TASKS.filter((task) => snapshot.task(task.definition.name) === undefined);\n\t\tif (missing.length > 0) {\n\t\t\tconst names = missing.map((task) => task.definition.name).join(\", \");\n\t\t\tthrow new Error(`Registry lacks built-in tasks ${names}; create it with createRegistry()`);\n\t\t}\n\t\tconst harness = new HarnessImpl(storage, options, context);\n\t\ttry {\n\t\t\tawait harness.openTasks(context);\n\t\t} catch (error) {\n\t\t\t// The caller's context may be what failed open: close without it, and rethrow the open error.\n\t\t\tawait harness\n\t\t\t\t.close(withoutAbortSignal(context))\n\t\t\t\t.catch((closeError: unknown) => options.onReport?.(closeError));\n\t\t\tthrow error;\n\t\t}\n\t\treturn harness;\n\t},\n};\n"]}
|
|
1
|
+
{"version":3,"file":"harness.js","sourceRoot":"","sources":["../../src/harness/harness.ts"],"names":[],"mappings":"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","sourcesContent":["import type { AttachedReplicatedState, Context, JsonValue } from \"@earendil-works/chord\";\nimport { withAbortSignal, withoutAbortSignal } from \"@earendil-works/chord/context\";\nimport { ResetEntry } from \"../entries.ts\";\nimport type { ExecutionEnv } from \"../env/index.ts\";\nimport { contained, SessionImpl } from \"../session/session.ts\";\nimport type { Transaction } from \"../session/transaction.ts\";\nimport type {\n\tConversationId,\n\tConversationOwnership,\n\tConversationRecord,\n\tCursor,\n\tEntryId,\n\tEntryQuery,\n\tEntryRecord,\n\tPage,\n\tStorage,\n\tSubmissionId,\n\tTaskId,\n\tTaskRecord,\n\tTx,\n} from \"../types.ts\";\nimport { ROOT_CONVERSATION_ID } from \"../types.ts\";\nimport { AgentDoc, configure, createAgent, resolveAgent, resolveSettings } from \"./agent.ts\";\nimport { createCompaction } from \"./compaction.ts\";\nimport { readContext } from \"./context.ts\";\nimport { InboxDoc, withdrawQueuedInputs } from \"./inbox.ts\";\nimport { LiveDoc, settleSchedulerOutcome } from \"./live.ts\";\nimport { ProviderDoc } from \"./provider.ts\";\nimport { BUILTIN_TASKS } from \"./registry.ts\";\nimport { type InvocationBinding, TaskScheduler } from \"./scheduler.ts\";\nimport { Submissions } from \"./submissions.ts\";\nimport { type TaskGraph, TaskGraphView, type TaskGraphWatch } from \"./task-graph.ts\";\nimport type {\n\tAgent,\n\tAgentChange,\n\tCompactionResult,\n\tContextView,\n\tConversation,\n\tConversationAbortOptions,\n\tConversationCreateOptions,\n\tConversationHandle,\n\tConversationInit,\n\tConversationWatch,\n\tHarnessInspection,\n\tHarnessOptions,\n\tHarness as HarnessType,\n\tRegistrySnapshot,\n\tSettledTask,\n\tSubmission,\n\tSubmissionDraft,\n\tToolRegistration,\n} from \"./types.ts\";\nimport { addUsageState, UsageDoc, type UsageState } from \"./usage.ts\";\nimport { scanAll } from \"./util.ts\";\nimport { type ConversationView, ConversationViews } from \"./view.ts\";\n\nconst SCAN_PAGE_SIZE = 256;\n\ntype CreateTarget =\n\t| { readonly kind: \"root\" }\n\t| { readonly kind: \"independent\"; readonly ownership: ConversationOwnership }\n\t| {\n\t\t\treadonly kind: \"fork\";\n\t\t\treadonly parentId: ConversationId;\n\t\t\treadonly at: EntryId;\n\t\t\treadonly ownership: ConversationOwnership;\n\t };\n\n/** What the conveniences apply in the creating commit, after the creation hook. */\ntype CreateOptions = { readonly agent?: AgentChange; readonly init?: ConversationInit };\n\n/** Harness-private services used by Conversation handles. */\ntype ConversationHost<Tool extends ToolRegistration> = {\n\treadonly harness: HarnessImpl<Tool>;\n\treadonly storage: Storage;\n\treadonly tasks: TaskScheduler;\n\treadonly submissions: Submissions;\n\treadonly views: ConversationViews;\n\treadonly now: () => number;\n\tcreate(target: CreateTarget, options: CreateOptions, context: Context): Promise<Conversation>;\n};\n\n/** Key of the Harness's internal index-size getter, for tests. */\nexport const SCHEDULER_INDEX_SIZES = Symbol.for(\"pi-durable.schedulerIndexSizes\");\n\nclass ConversationImpl<Tool extends ToolRegistration> implements Conversation {\n\treadonly id: ConversationId;\n\treadonly #host: ConversationHost<Tool>;\n\n\tconstructor(id: ConversationId, host: ConversationHost<Tool>) {\n\t\tthis.id = id;\n\t\tthis.#host = host;\n\t}\n\n\tagent(context: Context): Promise<Agent> {\n\t\treturn this.#host.harness.resolveAgent(this.id, undefined, context);\n\t}\n\n\tconfigure(change: AgentChange, context: Context): Promise<void> {\n\t\treturn this.#host.harness.commitWith((tx) => configure(tx, this.id, change), context);\n\t}\n\n\tsubmit(submission: SubmissionDraft, context: Context): Promise<Submission> {\n\t\treturn this.#host.submissions.submit(this.id, submission, context);\n\t}\n\n\tcompact(instructions: string | undefined, context: Context): Promise<TaskId<CompactionResult>> {\n\t\tthis.#host.tasks.resume();\n\t\tconst input = { reason: \"manual\", ...(instructions === undefined ? {} : { instructions }) } as const;\n\t\treturn this.#host.harness.commitWith((tx) => createCompaction(tx, this.id, input), context);\n\t}\n\n\tasync reset(handoff: string | undefined, context: Context): Promise<void> {\n\t\tconst model =\n\t\t\thandoff === undefined\n\t\t\t\t? {}\n\t\t\t\t: { model: [{ role: \"user\", content: handoff, timestamp: this.#host.now() } as const] };\n\t\tconst entry = { kind: ResetEntry.kind, head: \"self\", ...model } as const;\n\t\tawait this.#host.submissions.submit(this.id, { type: \"write\", entry }, context);\n\t}\n\n\tcommit<T>(change: (tx: Tx) => T | Promise<T>, context: Context): Promise<T> {\n\t\treturn this.#host.harness.commitWith(change, context, { conversationId: this.id });\n\t}\n\n\tcontext(context: Context, options?: { readonly at?: EntryId }): Promise<ContextView> {\n\t\treturn readContext(this.#host.harness, this.#host.storage, this.id, context, options?.at);\n\t}\n\n\tentries(\n\t\tquery: Omit<EntryQuery, \"conversationId\">,\n\t\tlimit: number,\n\t\tcursor: Cursor | undefined,\n\t\tcontext: Context,\n\t): Promise<Page<EntryRecord, Cursor>> {\n\t\tconst bounded: EntryQuery = {\n\t\t\tconversationId: this.id,\n\t\t\t...(query.minEntryId === undefined ? {} : { minEntryId: query.minEntryId }),\n\t\t\t...(query.maxEntryId === undefined ? {} : { maxEntryId: query.maxEntryId }),\n\t\t\t...(query.order === undefined ? {} : { order: query.order }),\n\t\t};\n\t\treturn this.#host.harness.readOnLine(() => this.#host.storage.scanEntries(bounded, limit, cursor, context));\n\t}\n\n\tfork(at: EntryId, options: ConversationCreateOptions, context: Context): Promise<Conversation> {\n\t\treturn this.#host.create({ kind: \"fork\", parentId: this.id, at, ownership: options.ownership }, options, context);\n\t}\n\n\tabort(context: Context, options?: ConversationAbortOptions): Promise<void> {\n\t\tthis.#host.tasks.resume();\n\t\treturn this.#host.tasks.abortConversation(this.id, options?.background === true, context);\n\t}\n\n\twaitForIdle(context: Context): Promise<void> {\n\t\tthis.#host.tasks.resume();\n\t\treturn this.#host.tasks.waitForIdle(this.id, context);\n\t}\n\n\tviewState(context: Context): Promise<AttachedReplicatedState<ConversationView>> {\n\t\treturn this.#host.views.state(this.id, context);\n\t}\n\n\twatch(context: Context): Promise<ConversationWatch> {\n\t\treturn this.#host.views.watch(this.id, context);\n\t}\n}\n\n/** Session kernel extended with conversation handles and a registry. */\nclass HarnessImpl<Tool extends ToolRegistration> extends SessionImpl implements HarnessType {\n\treadonly #options: HarnessOptions<Tool>;\n\treadonly #report: (error: unknown) => void;\n\treadonly #host: ConversationHost<Tool>;\n\treadonly #tasks: TaskScheduler;\n\treadonly #submissions: Submissions;\n\treadonly #taskGraph: TaskGraphView;\n\n\tconstructor(rawStorage: Storage, options: HarnessOptions<Tool>, context: Context) {\n\t\tconst report = safeReport(options.onReport);\n\t\tconst now = safeNow(options.now, report);\n\t\t// Read at each use, as all settings are, but only this field: it is read on every commit.\n\t\tsuper(rawStorage, now, () => options.settings?.documentRetentionMs);\n\t\t// Every component reads and writes through the Session's failure guard: `rawStorage` serves only `super()`.\n\t\tconst storage = this.storage;\n\t\tthis.#options = options;\n\t\tthis.#report = report;\n\t\tconst settings = () => resolveSettings(options.settings);\n\t\tthis.#tasks = new TaskScheduler({\n\t\t\tsession: this,\n\t\t\tstorage,\n\t\t\tregistry: options.registry,\n\t\t\tmodels: options.models,\n\t\t\tagent: (id, snapshot, callContext) => this.resolveAgent(id, snapshot as RegistrySnapshot<Tool>, callContext),\n\t\t\tsettings,\n\t\t\tenv: (id, callContext) => this.buildEnv(id, callContext),\n\t\t\tnow,\n\t\t\treport: this.#report,\n\t\t\tsettleOutcome: settleSchedulerOutcome,\n\t\t\twithdrawInputs: withdrawQueuedInputs,\n\t\t\tconversation: async (id, binding, callContext) => {\n\t\t\t\tconst record = await this.readOnLine(() => storage.conversation(id, callContext));\n\t\t\t\treturn record === undefined ? undefined : boundConversation(id, binding, this.#submissions, this.#tasks);\n\t\t\t},\n\t\t\tcontext: withoutAbortSignal(context),\n\t\t});\n\t\tthis.#submissions = new Submissions(this, storage, now, settings, () => this.#tasks.resume());\n\t\tthis.#taskGraph = new TaskGraphView(this, storage);\n\t\tthis.#host = {\n\t\t\tharness: this,\n\t\t\tstorage,\n\t\t\ttasks: this.#tasks,\n\t\t\tsubmissions: this.#submissions,\n\t\t\tviews: new ConversationViews(this, storage),\n\t\t\tnow,\n\t\t\tcreate: (target, createOptions, context) => this.#create(target, createOptions, context),\n\t\t};\n\t}\n\n\t/** Resolve a conversation's committed `pi.agent` against `snapshot`, or the current one, and the current settings. */\n\tasync resolveAgent(\n\t\tid: ConversationId,\n\t\tsnapshot: RegistrySnapshot<Tool> | undefined,\n\t\tcontext: Context,\n\t): Promise<Agent<Tool>> {\n\t\tconst registry = snapshot ?? this.#options.registry.snapshot();\n\t\tconst state = await this.snapshot(AgentDoc, id, context);\n\t\treturn resolveAgent(state, registry, resolveSettings(this.#options.settings), this.#report);\n\t}\n\n\t/** Build a conversation's environment from its current `cwd`; `undefined` without an `env` option. */\n\tasync buildEnv(id: ConversationId, context: Context): Promise<ExecutionEnv | undefined> {\n\t\tconst build = this.#options.env;\n\t\tif (build === undefined) return undefined;\n\t\tconst cwd = (await this.snapshot(AgentDoc, id, context))?.cwd;\n\t\treturn build({ conversationId: id, ...(cwd === undefined ? {} : { cwd }), read: this }, context);\n\t}\n\n\t/** Reconcile surviving `running` tasks to `pending`; part of open. */\n\topenTasks(context: Context): Promise<void> {\n\t\treturn this.#tasks.open(context);\n\t}\n\n\tresume(): void {\n\t\tthis.assertUsable();\n\t\tthis.#tasks.resume();\n\t}\n\n\tgetTask<R>(id: TaskId<R>, context: Context): Promise<TaskRecord<JsonValue, JsonValue, R> | undefined> {\n\t\treturn this.readOnLine(() => this.storage.task(id, context)) as Promise<\n\t\t\tTaskRecord<JsonValue, JsonValue, R> | undefined\n\t\t>;\n\t}\n\n\t/** Internal, for tests: sizes of the scheduler's ownership indexes. */\n\tget [SCHEDULER_INDEX_SIZES](): TaskScheduler[\"indexSizes\"] {\n\t\treturn this.#tasks.indexSizes;\n\t}\n\n\tinspect(context: Context): Promise<HarnessInspection> {\n\t\treturn this.readOnLine(async () => {\n\t\t\tconst { scheduling, tasks } = await this.#tasks.inspect(this.#options.registry.snapshot());\n\t\t\tconst scan = (status: \"queued\" | \"placed\") =>\n\t\t\t\tscanAll((cursor) => this.storage.scanSubmissions({ status }, SCAN_PAGE_SIZE, cursor, context));\n\t\t\tconst submissions = [...(await scan(\"queued\")), ...(await scan(\"placed\"))].sort((a, b) => a.id - b.id);\n\t\t\treturn { scheduling, tasks, submissions };\n\t\t});\n\t}\n\n\tsubmission(id: SubmissionId, context: Context): Promise<Submission | undefined> {\n\t\treturn this.#submissions.get(id, context);\n\t}\n\n\tabortSubmission(\n\t\tid: SubmissionId,\n\t\tcontext: Context,\n\t\tconversationId?: ConversationId,\n\t): Promise<\"aborted\" | \"already_placed\" | \"settled\" | \"not_found\"> {\n\t\treturn this.#submissions.abort(id, context, conversationId);\n\t}\n\n\tabortTask(id: TaskId, context: Context): Promise<\"marked\" | \"terminal\"> {\n\t\treturn this.#tasks.abort(id, context);\n\t}\n\n\twaitForTask<R>(id: TaskId<R>, context: Context): Promise<SettledTask<R>> {\n\t\tthis.#tasks.resume();\n\t\treturn this.#tasks.waitForTask(id, context) as Promise<SettledTask<R>>;\n\t}\n\n\twaitForIdle(context: Context): Promise<void> {\n\t\tthis.#tasks.resume();\n\t\treturn this.#tasks.waitForIdle(undefined, context);\n\t}\n\n\t/** Sum every conversation's committed `pi.usage`. Each document is read at its own point; totals only grow. */\n\tasync usage(context: Context): Promise<UsageState> {\n\t\tconst conversations = await this.readOnLine(() =>\n\t\t\tscanAll((cursor) => this.storage.scanConversations({}, SCAN_PAGE_SIZE, cursor, context)),\n\t\t);\n\t\tconst total = UsageDoc.definition.initial();\n\t\tfor (const { id } of conversations) {\n\t\t\tconst state = await this.snapshot(UsageDoc, id, context);\n\t\t\tif (state !== undefined) addUsageState(total, state);\n\t\t}\n\t\treturn total;\n\t}\n\n\ttaskGraph(context: Context): Promise<AttachedReplicatedState<TaskGraph>> {\n\t\treturn this.#taskGraph.state(context);\n\t}\n\n\twatchTaskGraph(context: Context): Promise<TaskGraphWatch> {\n\t\treturn this.#taskGraph.watch(context);\n\t}\n\n\troot(\n\t\tcontext: Context,\n\t\toptions?: { readonly agent?: AgentChange; readonly init?: ConversationInit },\n\t): Promise<Conversation> {\n\t\treturn this.#create({ kind: \"root\" }, options ?? {}, context);\n\t}\n\n\tasync conversation(id: ConversationId, context: Context): Promise<Conversation | undefined> {\n\t\tthis.assertUsable();\n\t\tconst record = await this.readOnLine(() => this.storage.conversation(id, context));\n\t\treturn record === undefined ? undefined : new ConversationImpl(record.id, this.#host);\n\t}\n\n\tcreateConversation(options: ConversationCreateOptions, context: Context): Promise<Conversation> {\n\t\treturn this.#create({ kind: \"independent\", ownership: options.ownership }, options, context);\n\t}\n\n\toverride report(error: unknown): void {\n\t\tthis.#report(error);\n\t}\n\n\t/** Signal and join task invocations after the close listeners and before Storage closes; writes no task outcome. */\n\tprotected override beforeClose(): Promise<void> {\n\t\treturn this.#tasks.join();\n\t}\n\n\tasync #create(target: CreateTarget, options: CreateOptions, context: Context): Promise<Conversation> {\n\t\tthis.assertUsable();\n\t\tconst id = await this.commitWith(async (tx) => {\n\t\t\tif (target.kind === \"root\" && (await tx.conversation(ROOT_CONVERSATION_ID)) !== undefined) {\n\t\t\t\treturn ROOT_CONVERSATION_ID;\n\t\t\t}\n\t\t\tconst record =\n\t\t\t\ttarget.kind === \"root\"\n\t\t\t\t\t? await tx.createRootConversation()\n\t\t\t\t\t: target.kind === \"fork\"\n\t\t\t\t\t\t? await tx.forkConversation(target.parentId, target.at, { ownership: target.ownership })\n\t\t\t\t\t\t: await tx.createConversation({ ownership: target.ownership });\n\t\t\tif (options.agent !== undefined) await configure(tx, record.id, options.agent);\n\t\t\tif (options.init !== undefined) await options.init(tx, record.id);\n\t\t\treturn record.id;\n\t\t}, context);\n\t\treturn new ConversationImpl(id, this.#host);\n\t}\n\n\t/**\n\t * The built-in creation hook, in every commit that creates or forks a conversation: empty `pi.live`, `pi.inbox`, and\n\t * `pi.usage`, a fresh `pi.provider`, the conversation's `pi.agent` (see `createAgent()`), then\n\t * `HarnessOptions.conversationCreated`.\n\t */\n\tprotected override async conversationCreated(tx: Transaction, record: ConversationRecord): Promise<void> {\n\t\tawait tx.doc(LiveDoc, record.id);\n\t\tawait tx.doc(InboxDoc, record.id);\n\t\tawait tx.doc(UsageDoc, record.id);\n\t\tawait tx.doc(ProviderDoc, record.id);\n\t\tawait createAgent(tx, record);\n\t\tawait this.#options.conversationCreated?.(tx, record);\n\t}\n}\n\n/** `onReport` that cannot fail: it is the last place an error goes, so its own throw or rejection is dropped. */\nfunction safeReport(onReport: ((error: unknown) => void) | undefined): (error: unknown) => void {\n\treturn (error) =>\n\t\tcontained(\n\t\t\t() => onReport?.(error),\n\t\t\t() => {},\n\t\t);\n}\n\n/**\n * The host clock, falling back to `Date.now` when it throws: a broken clock must not stop commits. The first throw is\n * reported; the clock is read in every task change, so later ones are not.\n */\nexport function safeNow(now: (() => number) | undefined, report: (error: unknown) => void): () => number {\n\tif (now === undefined) return Date.now;\n\tlet reported = false;\n\treturn () => {\n\t\ttry {\n\t\t\treturn now();\n\t\t} catch (error) {\n\t\t\t// Set first: a report handler that reads the clock again must not report again.\n\t\t\tif (!reported) {\n\t\t\t\treported = true;\n\t\t\t\treport(error);\n\t\t\t}\n\t\t\treturn Date.now();\n\t\t}\n\t};\n}\n\n/**\n * Invocation-bound handle for tasks and tools. Every operation, and every operation of a submission it returns, first\n * checks the invocation and runs under its signal, so it rejects once the invocation ends; admitted work stays durable.\n */\nfunction boundConversation(\n\tid: ConversationId,\n\tbinding: InvocationBinding,\n\tsubmissions: Submissions,\n\ttasks: TaskScheduler,\n): ConversationHandle {\n\tconst bind = (context: Context): Context => withAbortSignal(binding.signal, context);\n\tconst bound = <T>(operation: (context: Context) => Promise<T>) => {\n\t\treturn async (context: Context): Promise<T> => {\n\t\t\tbinding.check();\n\t\t\treturn operation(bind(context));\n\t\t};\n\t};\n\treturn {\n\t\tid,\n\t\tsubmit: async (draft, context) => {\n\t\t\tbinding.check();\n\t\t\tconst submission = await submissions.submit(id, draft, bind(context));\n\t\t\treturn {\n\t\t\t\tid: submission.id,\n\t\t\t\tstatus: bound((callContext) => submission.status(callContext)),\n\t\t\t\twait: bound((callContext) => submission.wait(callContext)),\n\t\t\t\tabort: bound((callContext) => submission.abort(callContext)),\n\t\t\t};\n\t\t},\n\t\tabort: async (context, options) => {\n\t\t\tbinding.check();\n\t\t\treturn tasks.abortConversation(id, options?.background === true, bind(context));\n\t\t},\n\t\twaitForIdle: bound((callContext) => tasks.waitForIdle(id, callContext)),\n\t};\n}\n\n/** Durable agent harness over one Session. */\nexport type Harness = HarnessType;\n\nexport const Harness = {\n\t/** Open a Harness over storage. The registry may keep changing while the Harness runs. */\n\tasync open<Tool extends ToolRegistration>(\n\t\tstorage: Storage,\n\t\toptions: HarnessOptions<Tool>,\n\t\tcontext: Context,\n\t): Promise<Harness> {\n\t\tcontext.abortSignal?.throwIfAborted();\n\t\tconst snapshot = options.registry.snapshot();\n\t\tconst missing = BUILTIN_TASKS.filter((task) => snapshot.task(task.definition.name) === undefined);\n\t\tif (missing.length > 0) {\n\t\t\tconst names = missing.map((task) => task.definition.name).join(\", \");\n\t\t\tthrow new Error(`Registry lacks built-in tasks ${names}; create it with createRegistry()`);\n\t\t}\n\t\tconst harness = new HarnessImpl(storage, options, context);\n\t\ttry {\n\t\t\tawait harness.openTasks(context);\n\t\t} catch (error) {\n\t\t\t// The caller's context may be what failed open: close without it, and rethrow the open error.\n\t\t\t// A failing Storage close fails the Session, which reports it.\n\t\t\tawait harness.close(withoutAbortSignal(context)).catch(() => {});\n\t\t\tthrow error;\n\t\t}\n\t\treturn harness;\n\t},\n};\n"]}
|
package/dist/harness/inbox.d.ts
CHANGED
|
@@ -1,11 +1,12 @@
|
|
|
1
|
-
import type
|
|
2
|
-
import type { ConversationId, EntryDraft, EntryId, JsonObject, SubmissionId, Tx } from "../types.ts";
|
|
3
|
-
import type { QueueMode, Settings, UserInput } from "./types.ts";
|
|
4
|
-
/** A queued submission: user input for a run, or
|
|
1
|
+
import { type Draft, type JsonRepresentation } from "@earendil-works/chord";
|
|
2
|
+
import type { ConversationId, EntryDraft, EntryId, EntryRecord, JsonObject, SubmissionId, Tx } from "../types.ts";
|
|
3
|
+
import type { InputEntry, QueueMode, Settings, UserInput } from "./types.ts";
|
|
4
|
+
/** A queued submission: user input for a run, with the entry it is placed as when not `pi.user`, or an entry write. */
|
|
5
5
|
export type InboxItem = {
|
|
6
6
|
id: SubmissionId;
|
|
7
7
|
mode: "steer" | "followUp";
|
|
8
8
|
content: JsonRepresentation<UserInput>;
|
|
9
|
+
entry?: JsonRepresentation<InputEntry>;
|
|
9
10
|
}
|
|
10
11
|
/** `entry` is an `EntryDraft`, stored as plain JSON. */
|
|
11
12
|
| {
|
|
@@ -47,6 +48,17 @@ export declare function prepareBoundary(tx: Tx, conversationId: ConversationId,
|
|
|
47
48
|
* stale items are removed positionally.
|
|
48
49
|
*/
|
|
49
50
|
export declare function applyBoundary(tx: Tx, boundary: Boundary, at: "postTools" | "final", now: number): Promise<BoundaryResult>;
|
|
51
|
+
/** Append the entry an input is placed as: `entry`'s kind and data, or `pi.user`, with the user message of `content`. */
|
|
52
|
+
export declare function appendInput(tx: Tx, conversationId: ConversationId, content: UserInput, entry: InputEntry | undefined, now: number): Promise<EntryRecord>;
|
|
53
|
+
/** The kind and data of an input's entry as strict JSON, without other fields an untyped caller might pass. */
|
|
54
|
+
export declare function pickInputEntry({ kind, data }: InputEntry): JsonRepresentation<InputEntry>;
|
|
55
|
+
/**
|
|
56
|
+
* Whether a write is display-only: it has no `model`, `head`, or `edits` (present counts, even if empty), so it changes
|
|
57
|
+
* nothing the model sees and needs no boundary.
|
|
58
|
+
*/
|
|
59
|
+
export declare function isDisplayOnly(entry: EntryDraft): boolean;
|
|
60
|
+
/** Whether a reset (`head: "self"` write) is queued; entries appended before it leave the active range when it lands. */
|
|
61
|
+
export declare function hasQueuedReset(items: readonly InboxItem[]): boolean;
|
|
50
62
|
/** Whether a head write targets an entry before the active range, so placing it would bring back cut history. */
|
|
51
63
|
export declare function isStale(boundary: Boundary, entry: EntryDraft): boolean;
|
|
52
64
|
/** Remove a withdrawn submission's item; the caller settles the submission. */
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/harness/inbox.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,
|
|
1
|
+
{"version":3,"file":"inbox.d.ts","sourceRoot":"","sources":["../../src/harness/inbox.ts"],"names":[],"mappings":"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"}
|
package/dist/harness/inbox.js
CHANGED
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { copyJson } from "@earendil-works/chord";
|
|
1
2
|
import { defineDoc } from "../documents.js";
|
|
2
3
|
import { UserEntry } from "../entries.js";
|
|
3
4
|
export const InboxDoc = defineDoc({
|
|
@@ -34,7 +35,7 @@ export async function prepareBoundary(tx, conversationId, modes) {
|
|
|
34
35
|
export async function applyBoundary(tx, boundary, at, now) {
|
|
35
36
|
const { conversationId, inbox } = boundary;
|
|
36
37
|
const items = inbox.items;
|
|
37
|
-
const reset = items
|
|
38
|
+
const reset = hasQueuedReset(items);
|
|
38
39
|
const final = at === "final" || reset;
|
|
39
40
|
const pick = (mode, queueMode) => {
|
|
40
41
|
const indexes = items.flatMap((item, index) => (item.mode === mode ? [index] : []));
|
|
@@ -59,8 +60,7 @@ export async function applyBoundary(tx, boundary, at, now) {
|
|
|
59
60
|
const placed = [];
|
|
60
61
|
for (const index of users) {
|
|
61
62
|
const item = items[index];
|
|
62
|
-
const
|
|
63
|
-
const entry = await tx.appendEntry(UserEntry, conversationId, { model: [message] });
|
|
63
|
+
const entry = await appendInput(tx, conversationId, item.content, item.entry, now);
|
|
64
64
|
tx.placeSubmission(item.id, entry.id);
|
|
65
65
|
placed.push(item.id);
|
|
66
66
|
}
|
|
@@ -69,6 +69,29 @@ export async function applyBoundary(tx, boundary, at, now) {
|
|
|
69
69
|
items.splice(index, 1);
|
|
70
70
|
return { users: placed, reset };
|
|
71
71
|
}
|
|
72
|
+
/** Append the entry an input is placed as: `entry`'s kind and data, or `pi.user`, with the user message of `content`. */
|
|
73
|
+
export function appendInput(tx, conversationId, content, entry, now) {
|
|
74
|
+
const message = { role: "user", content, timestamp: now };
|
|
75
|
+
if (entry === undefined)
|
|
76
|
+
return tx.appendEntry(UserEntry, conversationId, { model: [message] });
|
|
77
|
+
return tx.appendEntry(conversationId, { ...pickInputEntry(entry), model: [message] });
|
|
78
|
+
}
|
|
79
|
+
/** The kind and data of an input's entry as strict JSON, without other fields an untyped caller might pass. */
|
|
80
|
+
export function pickInputEntry({ kind, data }) {
|
|
81
|
+
const picked = data === undefined ? { kind } : { kind, data };
|
|
82
|
+
return copyJson(picked, { omitUndefinedProperties: true });
|
|
83
|
+
}
|
|
84
|
+
/**
|
|
85
|
+
* Whether a write is display-only: it has no `model`, `head`, or `edits` (present counts, even if empty), so it changes
|
|
86
|
+
* nothing the model sees and needs no boundary.
|
|
87
|
+
*/
|
|
88
|
+
export function isDisplayOnly(entry) {
|
|
89
|
+
return entry.model === undefined && entry.head === undefined && entry.edits === undefined;
|
|
90
|
+
}
|
|
91
|
+
/** Whether a reset (`head: "self"` write) is queued; entries appended before it leave the active range when it lands. */
|
|
92
|
+
export function hasQueuedReset(items) {
|
|
93
|
+
return items.some((item) => item.mode === "write" && item.entry.head === "self");
|
|
94
|
+
}
|
|
72
95
|
/** Whether a head write targets an entry before the active range, so placing it would bring back cut history. */
|
|
73
96
|
export function isStale(boundary, entry) {
|
|
74
97
|
return typeof entry.head === "number" && boundary.head !== undefined && entry.head < boundary.head;
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/harness/inbox.ts"],"names":[],"mappings":"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","sourcesContent":["import type { Draft, JsonRepresentation } from \"@earendil-works/chord\";\nimport { defineDoc } from \"../documents.ts\";\nimport { UserEntry } from \"../entries.ts\";\nimport type { ConversationId, EntryDraft, EntryId, JsonObject, SubmissionId, Tx } from \"../types.ts\";\nimport type { QueueMode, Settings, UserInput } from \"./types.ts\";\n\n/** A queued submission: user input for a run, or a passive entry write. */\nexport type InboxItem =\n\t| { id: SubmissionId; mode: \"steer\" | \"followUp\"; content: JsonRepresentation<UserInput> }\n\t/** `entry` is an `EntryDraft`, stored as plain JSON. */\n\t| { id: SubmissionId; mode: \"write\"; entry: JsonObject };\n\n/** Built-in queue of one conversation's submissions waiting for a boundary, in ID order. */\nexport type InboxState = { items: InboxItem[] };\n\nexport const InboxDoc = defineDoc<InboxState>({\n\tkind: \"pi.inbox\",\n\tversion: 1,\n\tscope: \"conversation\",\n\thistory: \"latest\",\n\tfork: \"initial\",\n\tinitial: () => ({ items: [] }),\n\tcheckpointWhen: (value) => value.items.length === 0,\n});\n\n/** The settings a boundary reads, on the Session line. */\nexport type QueueModes = Pick<Settings, \"steeringMode\" | \"followUpMode\">;\n\n/** What a boundary reads before the commit's first table write, and the newest head it has seen so far. */\nexport type Boundary = {\n\treadonly conversationId: ConversationId;\n\treadonly inbox: Draft<InboxState>;\n\treadonly steeringMode: QueueMode;\n\treadonly followUpMode: QueueMode;\n\t/** Start of the active range, the newest head marker's `head`; advanced by heads written in this commit. */\n\thead: EntryId | undefined;\n};\n\n/** Selected user items, in ID order, and whether a `head: \"self\"` write (a reset) was placed. */\nexport type BoundaryResult = { readonly users: SubmissionId[]; readonly reset: boolean };\n\n/**\n * Read what a boundary needs. Table reads must precede the commit's first table write, so callers prepare the\n * boundary at the start of their commit.\n */\nexport async function prepareBoundary(tx: Tx, conversationId: ConversationId, modes: QueueModes): Promise<Boundary> {\n\tconst head = (await tx.latestHeadMarker(conversationId))?.head;\n\tconst inbox = await tx.doc(InboxDoc, conversationId);\n\treturn {\n\t\tconversationId,\n\t\tinbox,\n\t\tsteeringMode: modes.steeringMode,\n\t\tfollowUpMode: modes.followUpMode,\n\t\thead,\n\t};\n}\n\n/**\n * Place the queued items a boundary selects (spec §6): every write, the first or all steers, and at `final` the first\n * or all follow-ups. A selected reset turns a `postTools` boundary into `final`. Writes are placed first and user\n * items after them, each in ID order, so user items queued before a reset run in the new context. A write whose head\n * targets an entry before the active range, including a range started earlier in this commit, is stale. Selected and\n * stale items are removed positionally.\n */\nexport async function applyBoundary(\n\ttx: Tx,\n\tboundary: Boundary,\n\tat: \"postTools\" | \"final\",\n\tnow: number,\n): Promise<BoundaryResult> {\n\tconst { conversationId, inbox } = boundary;\n\tconst items = inbox.items;\n\tconst reset = items.some((item) => item.mode === \"write\" && item.entry.head === \"self\");\n\tconst final = at === \"final\" || reset;\n\tconst pick = (mode: \"steer\" | \"followUp\", queueMode: QueueMode): number[] => {\n\t\tconst indexes = items.flatMap((item, index) => (item.mode === mode ? [index] : []));\n\t\treturn queueMode === \"all\" ? indexes : indexes.slice(0, 1);\n\t};\n\tconst writes = items.flatMap((item, index) => (item.mode === \"write\" ? [index] : []));\n\tconst users = [...pick(\"steer\", boundary.steeringMode), ...(final ? pick(\"followUp\", boundary.followUpMode) : [])];\n\tusers.sort((a, b) => a - b);\n\n\t// `appendEntry()` copies the drafts' values; the items are removed only afterwards.\n\tfor (const index of writes) {\n\t\tconst item = items[index] as Draft<Extract<InboxItem, { mode: \"write\" }>>;\n\t\tconst draft = item.entry as unknown as EntryDraft;\n\t\tif (isStale(boundary, draft)) {\n\t\t\ttx.settleSubmission(item.id, { status: \"unanswered\", reason: \"stale\" });\n\t\t\tcontinue;\n\t\t}\n\t\tconst entry = await tx.appendEntry(conversationId, draft);\n\t\tif (draft.head !== undefined) boundary.head = draft.head === \"self\" ? entry.id : draft.head;\n\t\ttx.placeSubmission(item.id, entry.id);\n\t}\n\tconst placed: SubmissionId[] = [];\n\tfor (const index of users) {\n\t\tconst item = items[index] as Draft<Extract<InboxItem, { mode: \"steer\" | \"followUp\" }>>;\n\t\tconst message = { role: \"user\", content: item.content as UserInput, timestamp: now } as const;\n\t\tconst entry = await tx.appendEntry(UserEntry, conversationId, { model: [message] });\n\t\ttx.placeSubmission(item.id, entry.id);\n\t\tplaced.push(item.id);\n\t}\n\tconst removed = [...writes, ...users].sort((a, b) => b - a);\n\tfor (const index of removed) items.splice(index, 1);\n\treturn { users: placed, reset };\n}\n\n/** Whether a head write targets an entry before the active range, so placing it would bring back cut history. */\nexport function isStale(boundary: Boundary, entry: EntryDraft): boolean {\n\treturn typeof entry.head === \"number\" && boundary.head !== undefined && entry.head < boundary.head;\n}\n\n/** Remove a withdrawn submission's item; the caller settles the submission. */\nexport async function removeInboxItem(tx: Tx, conversationId: ConversationId, id: SubmissionId): Promise<void> {\n\tconst items = (await tx.doc(InboxDoc, conversationId)).items;\n\tconst index = items.findIndex((item) => item.id === id);\n\tif (index >= 0) items.splice(index, 1);\n}\n\n/**\n * Withdraw every queued input of a conversation, as `Conversation.abort()` and abort cascades do: each settles\n * `unanswered` with `aborted` and leaves the inbox; queued writes stay for later placement.\n */\nexport async function withdrawQueuedInputs(tx: Tx, conversationId: ConversationId): Promise<void> {\n\tconst items = (await tx.doc(InboxDoc, conversationId)).items;\n\tfor (let index = items.length - 1; index >= 0; index--) {\n\t\tconst item = items[index]!;\n\t\tif (item.mode === \"write\") continue;\n\t\ttx.settleSubmission(item.id, { status: \"unanswered\", reason: \"aborted\" });\n\t\titems.splice(index, 1);\n\t}\n}\n"]}
|
|
1
|
+
{"version":3,"file":"inbox.js","sourceRoot":"","sources":["../../src/harness/inbox.ts"],"names":[],"mappings":"AAAA,OAAO,EAAE,QAAQ,EAAuC,MAAM,uBAAuB,CAAC;AACtF,OAAO,EAAE,SAAS,EAAE,MAAM,iBAAiB,CAAC;AAC5C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAkB1C,MAAM,CAAC,MAAM,QAAQ,GAAG,SAAS,CAAa;IAC7C,IAAI,EAAE,UAAU;IAChB,OAAO,EAAE,CAAC;IACV,KAAK,EAAE,cAAc;IACrB,OAAO,EAAE,QAAQ;IACjB,IAAI,EAAE,SAAS;IACf,OAAO,EAAE,GAAG,EAAE,CAAC,CAAC,EAAE,KAAK,EAAE,EAAE,EAAE,CAAC;IAC9B,cAAc,EAAE,CAAC,KAAK,EAAE,EAAE,CAAC,KAAK,CAAC,KAAK,CAAC,MAAM,KAAK,CAAC;CACnD,CAAC,CAAC;AAkBH;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAM,EAAE,cAA8B,EAAE,KAAiB;IAC9F,MAAM,IAAI,GAAG,CAAC,MAAM,EAAE,CAAC,gBAAgB,CAAC,cAAc,CAAC,CAAC,EAAE,IAAI,CAAC;IAC/D,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC;IACrD,OAAO;QACN,cAAc;QACd,KAAK;QACL,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,YAAY,EAAE,KAAK,CAAC,YAAY;QAChC,IAAI;KACJ,CAAC;AACH,CAAC;AAED;;;;;;GAMG;AACH,MAAM,CAAC,KAAK,UAAU,aAAa,CAClC,EAAM,EACN,QAAkB,EAClB,EAAyB,EACzB,GAAW;IAEX,MAAM,EAAE,cAAc,EAAE,KAAK,EAAE,GAAG,QAAQ,CAAC;IAC3C,MAAM,KAAK,GAAG,KAAK,CAAC,KAAK,CAAC;IAC1B,MAAM,KAAK,GAAG,cAAc,CAAC,KAAK,CAAC,CAAC;IACpC,MAAM,KAAK,GAAG,EAAE,KAAK,OAAO,IAAI,KAAK,CAAC;IACtC,MAAM,IAAI,GAAG,CAAC,IAA0B,EAAE,SAAoB,EAAY,EAAE;QAC3E,MAAM,OAAO,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,IAAI,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;QACpF,OAAO,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,OAAO,CAAC,KAAK,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IAC5D,CAAC,CAAC;IACF,MAAM,MAAM,GAAG,KAAK,CAAC,OAAO,CAAC,CAAC,IAAI,EAAE,KAAK,EAAE,EAAE,CAAC,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,CAAC,CAAC,CAAC,CAAC,KAAK,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACtF,MAAM,KAAK,GAAG,CAAC,GAAG,IAAI,CAAC,OAAO,EAAE,QAAQ,CAAC,YAAY,CAAC,EAAE,GAAG,CAAC,KAAK,CAAC,CAAC,CAAC,IAAI,CAAC,UAAU,EAAE,QAAQ,CAAC,YAAY,CAAC,CAAC,CAAC,CAAC,EAAE,CAAC,CAAC,CAAC;IACnH,KAAK,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAE5B,oFAAoF;IACpF,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC5B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAiD,CAAC;QAC1E,MAAM,KAAK,GAAG,IAAI,CAAC,KAA8B,CAAC;QAClD,IAAI,OAAO,CAAC,QAAQ,EAAE,KAAK,CAAC,EAAE,CAAC;YAC9B,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,OAAO,EAAE,CAAC,CAAC;YACxE,SAAS;QACV,CAAC;QACD,MAAM,KAAK,GAAG,MAAM,EAAE,CAAC,WAAW,CAAC,cAAc,EAAE,KAAK,CAAC,CAAC;QAC1D,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS;YAAE,QAAQ,CAAC,IAAI,GAAG,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,EAAE,CAAC,CAAC,CAAC,KAAK,CAAC,IAAI,CAAC;QAC5F,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;IACvC,CAAC;IACD,MAAM,MAAM,GAAmB,EAAE,CAAC;IAClC,KAAK,MAAM,KAAK,IAAI,KAAK,EAAE,CAAC;QAC3B,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAA8D,CAAC;QACvF,MAAM,KAAK,GAAG,MAAM,WAAW,CAAC,EAAE,EAAE,cAAc,EAAE,IAAI,CAAC,OAAoB,EAAE,IAAI,CAAC,KAAmB,EAAE,GAAG,CAAC,CAAC;QAC9G,EAAE,CAAC,eAAe,CAAC,IAAI,CAAC,EAAE,EAAE,KAAK,CAAC,EAAE,CAAC,CAAC;QACtC,MAAM,CAAC,IAAI,CAAC,IAAI,CAAC,EAAE,CAAC,CAAC;IACtB,CAAC;IACD,MAAM,OAAO,GAAG,CAAC,GAAG,MAAM,EAAE,GAAG,KAAK,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,EAAE,CAAC,EAAE,EAAE,CAAC,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5D,KAAK,MAAM,KAAK,IAAI,OAAO;QAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACpD,OAAO,EAAE,KAAK,EAAE,MAAM,EAAE,KAAK,EAAE,CAAC;AACjC,CAAC;AAED,yHAAyH;AACzH,MAAM,UAAU,WAAW,CAC1B,EAAM,EACN,cAA8B,EAC9B,OAAkB,EAClB,KAA6B,EAC7B,GAAW;IAEX,MAAM,OAAO,GAAG,EAAE,IAAI,EAAE,MAAM,EAAE,OAAO,EAAE,SAAS,EAAE,GAAG,EAAW,CAAC;IACnE,IAAI,KAAK,KAAK,SAAS;QAAE,OAAO,EAAE,CAAC,WAAW,CAAC,SAAS,EAAE,cAAc,EAAE,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;IAChG,OAAO,EAAE,CAAC,WAAW,CAAC,cAAc,EAAE,EAAE,GAAG,cAAc,CAAC,KAAK,CAAC,EAAE,KAAK,EAAE,CAAC,OAAO,CAAC,EAAE,CAAC,CAAC;AACvF,CAAC;AAED,+GAA+G;AAC/G,MAAM,UAAU,cAAc,CAAC,EAAE,IAAI,EAAE,IAAI,EAAc;IACxD,MAAM,MAAM,GAAG,IAAI,KAAK,SAAS,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,CAAC,CAAC,CAAC,EAAE,IAAI,EAAE,IAAI,EAAE,CAAC;IAC9D,OAAO,QAAQ,CAAC,MAAM,EAAE,EAAE,uBAAuB,EAAE,IAAI,EAAE,CAAmC,CAAC;AAC9F,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,KAAiB;IAC9C,OAAO,KAAK,CAAC,KAAK,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,KAAK,KAAK,SAAS,CAAC;AAC3F,CAAC;AAED,yHAAyH;AACzH,MAAM,UAAU,cAAc,CAAC,KAA2B;IACzD,OAAO,KAAK,CAAC,IAAI,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,IAAI,KAAK,OAAO,IAAI,IAAI,CAAC,KAAK,CAAC,IAAI,KAAK,MAAM,CAAC,CAAC;AAClF,CAAC;AAED,iHAAiH;AACjH,MAAM,UAAU,OAAO,CAAC,QAAkB,EAAE,KAAiB;IAC5D,OAAO,OAAO,KAAK,CAAC,IAAI,KAAK,QAAQ,IAAI,QAAQ,CAAC,IAAI,KAAK,SAAS,IAAI,KAAK,CAAC,IAAI,GAAG,QAAQ,CAAC,IAAI,CAAC;AACpG,CAAC;AAED,+EAA+E;AAC/E,MAAM,CAAC,KAAK,UAAU,eAAe,CAAC,EAAM,EAAE,cAA8B,EAAE,EAAgB;IAC7F,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7D,MAAM,KAAK,GAAG,KAAK,CAAC,SAAS,CAAC,CAAC,IAAI,EAAE,EAAE,CAAC,IAAI,CAAC,EAAE,KAAK,EAAE,CAAC,CAAC;IACxD,IAAI,KAAK,IAAI,CAAC;QAAE,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;AACxC,CAAC;AAED;;;GAGG;AACH,MAAM,CAAC,KAAK,UAAU,oBAAoB,CAAC,EAAM,EAAE,cAA8B;IAChF,MAAM,KAAK,GAAG,CAAC,MAAM,EAAE,CAAC,GAAG,CAAC,QAAQ,EAAE,cAAc,CAAC,CAAC,CAAC,KAAK,CAAC;IAC7D,KAAK,IAAI,KAAK,GAAG,KAAK,CAAC,MAAM,GAAG,CAAC,EAAE,KAAK,IAAI,CAAC,EAAE,KAAK,EAAE,EAAE,CAAC;QACxD,MAAM,IAAI,GAAG,KAAK,CAAC,KAAK,CAAE,CAAC;QAC3B,IAAI,IAAI,CAAC,IAAI,KAAK,OAAO;YAAE,SAAS;QACpC,EAAE,CAAC,gBAAgB,CAAC,IAAI,CAAC,EAAE,EAAE,EAAE,MAAM,EAAE,YAAY,EAAE,MAAM,EAAE,SAAS,EAAE,CAAC,CAAC;QAC1E,KAAK,CAAC,MAAM,CAAC,KAAK,EAAE,CAAC,CAAC,CAAC;IACxB,CAAC;AACF,CAAC","sourcesContent":["import { copyJson, type Draft, type JsonRepresentation } from \"@earendil-works/chord\";\nimport { defineDoc } from \"../documents.ts\";\nimport { UserEntry } from \"../entries.ts\";\nimport type { ConversationId, EntryDraft, EntryId, EntryRecord, JsonObject, SubmissionId, Tx } from \"../types.ts\";\nimport type { InputEntry, QueueMode, Settings, UserInput } from \"./types.ts\";\n\n/** A queued submission: user input for a run, with the entry it is placed as when not `pi.user`, or an entry write. */\nexport type InboxItem =\n\t| {\n\t\t\tid: SubmissionId;\n\t\t\tmode: \"steer\" | \"followUp\";\n\t\t\tcontent: JsonRepresentation<UserInput>;\n\t\t\tentry?: JsonRepresentation<InputEntry>;\n\t }\n\t/** `entry` is an `EntryDraft`, stored as plain JSON. */\n\t| { id: SubmissionId; mode: \"write\"; entry: JsonObject };\n\n/** Built-in queue of one conversation's submissions waiting for a boundary, in ID order. */\nexport type InboxState = { items: InboxItem[] };\n\nexport const InboxDoc = defineDoc<InboxState>({\n\tkind: \"pi.inbox\",\n\tversion: 1,\n\tscope: \"conversation\",\n\thistory: \"latest\",\n\tfork: \"initial\",\n\tinitial: () => ({ items: [] }),\n\tcheckpointWhen: (value) => value.items.length === 0,\n});\n\n/** The settings a boundary reads, on the Session line. */\nexport type QueueModes = Pick<Settings, \"steeringMode\" | \"followUpMode\">;\n\n/** What a boundary reads before the commit's first table write, and the newest head it has seen so far. */\nexport type Boundary = {\n\treadonly conversationId: ConversationId;\n\treadonly inbox: Draft<InboxState>;\n\treadonly steeringMode: QueueMode;\n\treadonly followUpMode: QueueMode;\n\t/** Start of the active range, the newest head marker's `head`; advanced by heads written in this commit. */\n\thead: EntryId | undefined;\n};\n\n/** Selected user items, in ID order, and whether a `head: \"self\"` write (a reset) was placed. */\nexport type BoundaryResult = { readonly users: SubmissionId[]; readonly reset: boolean };\n\n/**\n * Read what a boundary needs. Table reads must precede the commit's first table write, so callers prepare the\n * boundary at the start of their commit.\n */\nexport async function prepareBoundary(tx: Tx, conversationId: ConversationId, modes: QueueModes): Promise<Boundary> {\n\tconst head = (await tx.latestHeadMarker(conversationId))?.head;\n\tconst inbox = await tx.doc(InboxDoc, conversationId);\n\treturn {\n\t\tconversationId,\n\t\tinbox,\n\t\tsteeringMode: modes.steeringMode,\n\t\tfollowUpMode: modes.followUpMode,\n\t\thead,\n\t};\n}\n\n/**\n * Place the queued items a boundary selects (spec §6): every write, the first or all steers, and at `final` the first\n * or all follow-ups. A selected reset turns a `postTools` boundary into `final`. Writes are placed first and user\n * items after them, each in ID order, so user items queued before a reset run in the new context. A write whose head\n * targets an entry before the active range, including a range started earlier in this commit, is stale. Selected and\n * stale items are removed positionally.\n */\nexport async function applyBoundary(\n\ttx: Tx,\n\tboundary: Boundary,\n\tat: \"postTools\" | \"final\",\n\tnow: number,\n): Promise<BoundaryResult> {\n\tconst { conversationId, inbox } = boundary;\n\tconst items = inbox.items;\n\tconst reset = hasQueuedReset(items);\n\tconst final = at === \"final\" || reset;\n\tconst pick = (mode: \"steer\" | \"followUp\", queueMode: QueueMode): number[] => {\n\t\tconst indexes = items.flatMap((item, index) => (item.mode === mode ? [index] : []));\n\t\treturn queueMode === \"all\" ? indexes : indexes.slice(0, 1);\n\t};\n\tconst writes = items.flatMap((item, index) => (item.mode === \"write\" ? [index] : []));\n\tconst users = [...pick(\"steer\", boundary.steeringMode), ...(final ? pick(\"followUp\", boundary.followUpMode) : [])];\n\tusers.sort((a, b) => a - b);\n\n\t// `appendEntry()` copies the drafts' values; the items are removed only afterwards.\n\tfor (const index of writes) {\n\t\tconst item = items[index] as Draft<Extract<InboxItem, { mode: \"write\" }>>;\n\t\tconst draft = item.entry as unknown as EntryDraft;\n\t\tif (isStale(boundary, draft)) {\n\t\t\ttx.settleSubmission(item.id, { status: \"unanswered\", reason: \"stale\" });\n\t\t\tcontinue;\n\t\t}\n\t\tconst entry = await tx.appendEntry(conversationId, draft);\n\t\tif (draft.head !== undefined) boundary.head = draft.head === \"self\" ? entry.id : draft.head;\n\t\ttx.placeSubmission(item.id, entry.id);\n\t}\n\tconst placed: SubmissionId[] = [];\n\tfor (const index of users) {\n\t\tconst item = items[index] as Draft<Extract<InboxItem, { mode: \"steer\" | \"followUp\" }>>;\n\t\tconst entry = await appendInput(tx, conversationId, item.content as UserInput, item.entry as InputEntry, now);\n\t\ttx.placeSubmission(item.id, entry.id);\n\t\tplaced.push(item.id);\n\t}\n\tconst removed = [...writes, ...users].sort((a, b) => b - a);\n\tfor (const index of removed) items.splice(index, 1);\n\treturn { users: placed, reset };\n}\n\n/** Append the entry an input is placed as: `entry`'s kind and data, or `pi.user`, with the user message of `content`. */\nexport function appendInput(\n\ttx: Tx,\n\tconversationId: ConversationId,\n\tcontent: UserInput,\n\tentry: InputEntry | undefined,\n\tnow: number,\n): Promise<EntryRecord> {\n\tconst message = { role: \"user\", content, timestamp: now } as const;\n\tif (entry === undefined) return tx.appendEntry(UserEntry, conversationId, { model: [message] });\n\treturn tx.appendEntry(conversationId, { ...pickInputEntry(entry), model: [message] });\n}\n\n/** The kind and data of an input's entry as strict JSON, without other fields an untyped caller might pass. */\nexport function pickInputEntry({ kind, data }: InputEntry): JsonRepresentation<InputEntry> {\n\tconst picked = data === undefined ? { kind } : { kind, data };\n\treturn copyJson(picked, { omitUndefinedProperties: true }) as JsonRepresentation<InputEntry>;\n}\n\n/**\n * Whether a write is display-only: it has no `model`, `head`, or `edits` (present counts, even if empty), so it changes\n * nothing the model sees and needs no boundary.\n */\nexport function isDisplayOnly(entry: EntryDraft): boolean {\n\treturn entry.model === undefined && entry.head === undefined && entry.edits === undefined;\n}\n\n/** Whether a reset (`head: \"self\"` write) is queued; entries appended before it leave the active range when it lands. */\nexport function hasQueuedReset(items: readonly InboxItem[]): boolean {\n\treturn items.some((item) => item.mode === \"write\" && item.entry.head === \"self\");\n}\n\n/** Whether a head write targets an entry before the active range, so placing it would bring back cut history. */\nexport function isStale(boundary: Boundary, entry: EntryDraft): boolean {\n\treturn typeof entry.head === \"number\" && boundary.head !== undefined && entry.head < boundary.head;\n}\n\n/** Remove a withdrawn submission's item; the caller settles the submission. */\nexport async function removeInboxItem(tx: Tx, conversationId: ConversationId, id: SubmissionId): Promise<void> {\n\tconst items = (await tx.doc(InboxDoc, conversationId)).items;\n\tconst index = items.findIndex((item) => item.id === id);\n\tif (index >= 0) items.splice(index, 1);\n}\n\n/**\n * Withdraw every queued input of a conversation, as `Conversation.abort()` and abort cascades do: each settles\n * `unanswered` with `aborted` and leaves the inbox; queued writes stay for later placement.\n */\nexport async function withdrawQueuedInputs(tx: Tx, conversationId: ConversationId): Promise<void> {\n\tconst items = (await tx.doc(InboxDoc, conversationId)).items;\n\tfor (let index = items.length - 1; index >= 0; index--) {\n\t\tconst item = items[index]!;\n\t\tif (item.mode === \"write\") continue;\n\t\ttx.settleSubmission(item.id, { status: \"unanswered\", reason: \"aborted\" });\n\t\titems.splice(index, 1);\n\t}\n}\n"]}
|
package/dist/harness/live.d.ts
CHANGED
|
@@ -1,18 +1,13 @@
|
|
|
1
1
|
import type { Draft, JsonRepresentation, JsonValue } from "@earendil-works/chord";
|
|
2
|
-
import type { AssistantMessage } from "@earendil-works/pi-ai";
|
|
2
|
+
import type { AssistantMessage, Usage } from "@earendil-works/pi-ai";
|
|
3
3
|
import type { Transaction } from "../session/transaction.ts";
|
|
4
|
-
import type { EntryId, SubmissionId, SubmissionSettlement, TaskId, TaskRecord, Tx } from "../types.ts";
|
|
4
|
+
import type { EntryId, JsonObject, SubmissionId, SubmissionSettlement, TaskId, TaskRecord, Tx } from "../types.ts";
|
|
5
5
|
import type { SchedulerOutcome } from "./scheduler.ts";
|
|
6
6
|
import type { CompactionReason, CompactionResult, ToolDiagnostic } from "./types.ts";
|
|
7
|
-
/**
|
|
8
|
-
|
|
7
|
+
/** What a running tool call publishes, shared by model-issued and nested calls. */
|
|
8
|
+
type SlotProgress = {
|
|
9
9
|
callId: string;
|
|
10
10
|
name: string;
|
|
11
|
-
/**
|
|
12
|
-
* Absent for a call not started yet (sequential round) and for a call its request did not offer, which starts `done`
|
|
13
|
-
* with the `entry` generation wrote.
|
|
14
|
-
*/
|
|
15
|
-
taskId?: TaskId;
|
|
16
11
|
status: "pending" | "running" | "done";
|
|
17
12
|
/** Retained running output and what the bounds dropped. */
|
|
18
13
|
output?: string;
|
|
@@ -22,9 +17,41 @@ export type ToolSlot = {
|
|
|
22
17
|
details?: JsonValue;
|
|
23
18
|
/** Diagnostics recorded through `api.diagnostic()`. */
|
|
24
19
|
diagnostics?: ToolDiagnostic[];
|
|
20
|
+
};
|
|
21
|
+
/** Presentation of one tool call of the current round. */
|
|
22
|
+
export type ToolSlot = SlotProgress & {
|
|
23
|
+
/**
|
|
24
|
+
* Absent for a call not started yet (sequential round) and for a call its request did not offer, which starts `done`
|
|
25
|
+
* with the `entry` generation wrote.
|
|
26
|
+
*/
|
|
27
|
+
taskId?: TaskId;
|
|
25
28
|
/** Result entry once done; absent when the tool task faulted or was orphaned. */
|
|
26
29
|
entry?: EntryId;
|
|
27
30
|
};
|
|
31
|
+
/**
|
|
32
|
+
* Presentation of one nested call: a call a running tool made through `executeTool()`. `callId` is
|
|
33
|
+
* `<parentCallId>/<key>`, the call's ID in tool events and unique because keys contain no `/`. The Harness relates
|
|
34
|
+
* slots by task ID: `taskId` is the call's tool task, `parentTaskId` the calling one, model-issued or nested.
|
|
35
|
+
*/
|
|
36
|
+
export type NestedToolSlot = SlotProgress & {
|
|
37
|
+
parentCallId: string;
|
|
38
|
+
parentTaskId: TaskId;
|
|
39
|
+
taskId: TaskId;
|
|
40
|
+
/**
|
|
41
|
+
* What the call was made with, replaced by the arguments it runs with, after repair, `beforeTool`, and coercion,
|
|
42
|
+
* once it starts executing. A model-issued call's arguments are in its assistant entry instead.
|
|
43
|
+
*/
|
|
44
|
+
arguments: JsonObject;
|
|
45
|
+
/** Once done: how the call ended, for a status line. The result itself is in the caller's `NestedCallDoc`. */
|
|
46
|
+
summary?: NestedToolSummary;
|
|
47
|
+
};
|
|
48
|
+
/** How a nested call ended: an error flag, its execution time, its spend, and up to 500 characters of error text. */
|
|
49
|
+
export type NestedToolSummary = {
|
|
50
|
+
isError: boolean;
|
|
51
|
+
durationMs?: number;
|
|
52
|
+
usage?: JsonRepresentation<Usage>;
|
|
53
|
+
error?: string;
|
|
54
|
+
};
|
|
28
55
|
/** Presentation of one live compaction task (spec §8.7). */
|
|
29
56
|
export type CompactionStatus = {
|
|
30
57
|
taskId: TaskId<CompactionResult>;
|
|
@@ -38,6 +65,13 @@ export type CompactionStatus = {
|
|
|
38
65
|
error: string;
|
|
39
66
|
};
|
|
40
67
|
};
|
|
68
|
+
/** The newest compaction that failed since a compaction last produced a summary (spec §8.7). */
|
|
69
|
+
export type CompactionFailure = {
|
|
70
|
+
taskId: TaskId<CompactionResult>;
|
|
71
|
+
reason: CompactionReason;
|
|
72
|
+
/** The failed or faulted outcome's error message, or why the scheduler orphaned the task. */
|
|
73
|
+
error: string;
|
|
74
|
+
};
|
|
41
75
|
/** Built-in live conversation state: run control and presentation of the current generation and tool round. */
|
|
42
76
|
export type LiveState = {
|
|
43
77
|
/** Run control: the task that settles the run's inputs, and those inputs; present exactly while busy. */
|
|
@@ -62,13 +96,23 @@ export type LiveState = {
|
|
|
62
96
|
};
|
|
63
97
|
/** The current tool round in call order, from the tool-calling answer until the generation's `tools` phase ends it. */
|
|
64
98
|
tools?: ToolSlot[];
|
|
99
|
+
/**
|
|
100
|
+
* Nested calls of running tool calls, in creation order, so a parent precedes its children and task IDs ascend. A
|
|
101
|
+
* call's nested slots are removed when the call settles.
|
|
102
|
+
*/
|
|
103
|
+
nestedTools?: NestedToolSlot[];
|
|
65
104
|
/** Live compaction tasks in task ID order; absent when none. */
|
|
66
105
|
compactions?: CompactionStatus[];
|
|
106
|
+
/**
|
|
107
|
+
* The newest compaction failure, so a client can show it after the task ended. A compaction that produces a summary
|
|
108
|
+
* removes it; one that is aborted or finds nothing to compact leaves it.
|
|
109
|
+
*/
|
|
110
|
+
compactionFailure?: CompactionFailure;
|
|
67
111
|
};
|
|
68
112
|
export declare const LiveDoc: import("../types.ts").ConversationDocToken<LiveState>;
|
|
69
113
|
/**
|
|
70
|
-
* End the run owned by `taskId`: settle each of its inputs and remove `run`. Always removes `generation
|
|
71
|
-
* whose presentation belongs to the ending run.
|
|
114
|
+
* End the run owned by `taskId`: settle each of its inputs and remove `run`. Always removes `generation`, `tools`, and
|
|
115
|
+
* `nestedTools`, whose presentation belongs to the ending run.
|
|
72
116
|
*/
|
|
73
117
|
export declare function endRun(tx: Tx, live: Draft<LiveState>, taskId: TaskId, settlement: SubmissionSettlement): void;
|
|
74
118
|
/** Add the status of a compaction task created in this commit; statuses stay in task ID order. */
|
|
@@ -77,16 +121,28 @@ export declare function addCompactionStatus(live: Draft<LiveState>, status: Comp
|
|
|
77
121
|
export declare function compactionStatus(live: Draft<LiveState>, taskId: TaskId): Draft<CompactionStatus> | undefined;
|
|
78
122
|
/** Remove the status of compaction task `taskId`, and the list once empty. */
|
|
79
123
|
export declare function removeCompactionStatus(live: Draft<LiveState>, taskId: TaskId): void;
|
|
80
|
-
/**
|
|
81
|
-
export declare function
|
|
82
|
-
/**
|
|
83
|
-
|
|
124
|
+
/** Remove the status of compaction task `taskId` and record that it failed with `error`. */
|
|
125
|
+
export declare function failCompactionStatus(live: Draft<LiveState>, taskId: TaskId, error: string): void;
|
|
126
|
+
/**
|
|
127
|
+
* The slot of tool task `taskId`, model-issued or nested, if `pi.live` still lists it. Nested slots are found by binary
|
|
128
|
+
* search: a tool may make thousands of nested calls, each of which looks up its slot in several commits, and every
|
|
129
|
+
* element a search reads costs a node in the draft's change tracker. Their task IDs ascend: each slot is appended in
|
|
130
|
+
* the commit that creates its task, task IDs ascend in commit order, and removal keeps the order.
|
|
131
|
+
*/
|
|
132
|
+
export declare function toolSlot(live: Draft<LiveState>, taskId: TaskId): Draft<ToolSlot | NestedToolSlot> | undefined;
|
|
133
|
+
/**
|
|
134
|
+
* Mark a slot done and clear its running output; the caller sets a model-issued call's result `entry`, or a nested
|
|
135
|
+
* call's `summary`. Neither is set when the task faulted or was orphaned.
|
|
136
|
+
*/
|
|
137
|
+
export declare function finishSlot(slot: Draft<ToolSlot | NestedToolSlot>): void;
|
|
138
|
+
/** Remove the nested slots below tool task `taskId`, transitively; the list holds parents before their children. */
|
|
139
|
+
export declare function removeNestedSlots(live: Draft<LiveState>, taskId: TaskId): void;
|
|
84
140
|
/** Remove what a tool published while running; its result entry or a rerun replaces it. */
|
|
85
|
-
export declare function clearProgress(slot: Draft<
|
|
141
|
+
export declare function clearProgress(slot: Draft<SlotProgress>): void;
|
|
86
142
|
/**
|
|
87
143
|
* Harness cleanup for a terminal outcome the scheduler writes itself (`faulted` or `orphaned`). A run task ends its
|
|
88
144
|
* run; a tool task's slot is marked done without an entry, and context derivation synthesizes the missing result; a
|
|
89
|
-
* compaction task's status is removed.
|
|
145
|
+
* compaction task's status is removed and its failure recorded.
|
|
90
146
|
* Ignores other kinds so it never creates `pi.live` elsewhere. The scheduler calls this without knowing task kinds;
|
|
91
147
|
* the Harness passes it in (spec §5.4).
|
|
92
148
|
* REMINDER: a committed generation partial becomes an aborted assistant entry here, exactly as in the generation abort
|
|
@@ -96,4 +152,5 @@ export declare function clearProgress(slot: Draft<ToolSlot>): void;
|
|
|
96
152
|
* uncertain storage failure poisons the Session instead and writes no outcome.
|
|
97
153
|
*/
|
|
98
154
|
export declare function settleSchedulerOutcome(tx: Transaction, record: TaskRecord<JsonValue, JsonValue, JsonValue>, outcome: SchedulerOutcome): Promise<void>;
|
|
155
|
+
export {};
|
|
99
156
|
//# sourceMappingURL=live.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/harness/live.ts"],"names":[],"mappings":"AAAA,OAAO,KAAK,EAAE,KAAK,EAAE,kBAAkB,EAAE,SAAS,EAAE,MAAM,uBAAuB,CAAC;AAClF,OAAO,KAAK,EAAE,gBAAgB,EAAE,MAAM,uBAAuB,CAAC;
|
|
1
|
+
{"version":3,"file":"live.d.ts","sourceRoot":"","sources":["../../src/harness/live.ts"],"names":[],"mappings":"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"}
|
package/dist/harness/live.js
CHANGED
|
@@ -10,16 +10,19 @@ export const LiveDoc = defineDoc({
|
|
|
10
10
|
// REMINDER: a complete base whenever nothing runs (spec §8.2): no generation and no running tool slot. That holds
|
|
11
11
|
// while idle, in the commit handing a generation over to its tool round, and between tools, so the delta chain
|
|
12
12
|
// spans at most one generation or the overlapping execution of one round's tools. A slot holds output only while
|
|
13
|
-
// running, so every base is small
|
|
14
|
-
|
|
13
|
+
// running, so every base is small; a nested call's result lives in its caller's task documents, never here. Do not
|
|
14
|
+
// add a delta-count bound; the tool output benchmark checks this rule.
|
|
15
|
+
checkpointWhen: (value) => value.generation === undefined &&
|
|
16
|
+
!(value.tools ?? []).some((slot) => slot.status === "running") &&
|
|
17
|
+
!(value.nestedTools ?? []).some((slot) => slot.status === "running"),
|
|
15
18
|
});
|
|
16
19
|
/** Built-in task kinds that can own `pi.live.run`. */
|
|
17
20
|
const RUN_TASK_KINDS = new Set(["pi.generation"]);
|
|
18
21
|
const TOOL_TASK_KIND = "pi.tool";
|
|
19
22
|
const COMPACTION_TASK_KIND = "pi.compaction";
|
|
20
23
|
/**
|
|
21
|
-
* End the run owned by `taskId`: settle each of its inputs and remove `run`. Always removes `generation
|
|
22
|
-
* whose presentation belongs to the ending run.
|
|
24
|
+
* End the run owned by `taskId`: settle each of its inputs and remove `run`. Always removes `generation`, `tools`, and
|
|
25
|
+
* `nestedTools`, whose presentation belongs to the ending run.
|
|
23
26
|
*/
|
|
24
27
|
export function endRun(tx, live, taskId, settlement) {
|
|
25
28
|
if (live.run?.taskId === taskId) {
|
|
@@ -29,6 +32,7 @@ export function endRun(tx, live, taskId, settlement) {
|
|
|
29
32
|
}
|
|
30
33
|
delete live.generation;
|
|
31
34
|
delete live.tools;
|
|
35
|
+
delete live.nestedTools;
|
|
32
36
|
}
|
|
33
37
|
/** Add the status of a compaction task created in this commit; statuses stay in task ID order. */
|
|
34
38
|
export function addCompactionStatus(live, status) {
|
|
@@ -50,17 +54,62 @@ export function removeCompactionStatus(live, taskId) {
|
|
|
50
54
|
if (statuses.length === 0)
|
|
51
55
|
delete live.compactions;
|
|
52
56
|
}
|
|
53
|
-
/**
|
|
57
|
+
/** Remove the status of compaction task `taskId` and record that it failed with `error`. */
|
|
58
|
+
export function failCompactionStatus(live, taskId, error) {
|
|
59
|
+
const status = compactionStatus(live, taskId);
|
|
60
|
+
if (status !== undefined)
|
|
61
|
+
live.compactionFailure = { taskId: status.taskId, reason: status.reason, error };
|
|
62
|
+
removeCompactionStatus(live, taskId);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* The slot of tool task `taskId`, model-issued or nested, if `pi.live` still lists it. Nested slots are found by binary
|
|
66
|
+
* search: a tool may make thousands of nested calls, each of which looks up its slot in several commits, and every
|
|
67
|
+
* element a search reads costs a node in the draft's change tracker. Their task IDs ascend: each slot is appended in
|
|
68
|
+
* the commit that creates its task, task IDs ascend in commit order, and removal keeps the order.
|
|
69
|
+
*/
|
|
54
70
|
export function toolSlot(live, taskId) {
|
|
55
|
-
|
|
71
|
+
const slot = live.tools?.find((each) => each.taskId === taskId);
|
|
72
|
+
if (slot !== undefined || live.nestedTools === undefined)
|
|
73
|
+
return slot;
|
|
74
|
+
const nested = live.nestedTools;
|
|
75
|
+
let low = 0;
|
|
76
|
+
let high = nested.length - 1;
|
|
77
|
+
while (low <= high) {
|
|
78
|
+
const middle = (low + high) >>> 1;
|
|
79
|
+
const candidate = nested[middle];
|
|
80
|
+
if (candidate.taskId === taskId)
|
|
81
|
+
return candidate;
|
|
82
|
+
if (candidate.taskId < taskId)
|
|
83
|
+
low = middle + 1;
|
|
84
|
+
else
|
|
85
|
+
high = middle - 1;
|
|
86
|
+
}
|
|
87
|
+
return undefined;
|
|
56
88
|
}
|
|
57
|
-
/**
|
|
58
|
-
|
|
89
|
+
/**
|
|
90
|
+
* Mark a slot done and clear its running output; the caller sets a model-issued call's result `entry`, or a nested
|
|
91
|
+
* call's `summary`. Neither is set when the task faulted or was orphaned.
|
|
92
|
+
*/
|
|
93
|
+
export function finishSlot(slot) {
|
|
59
94
|
slot.status = "done";
|
|
60
|
-
if (entry !== undefined)
|
|
61
|
-
slot.entry = entry;
|
|
62
95
|
clearProgress(slot);
|
|
63
96
|
}
|
|
97
|
+
/** Remove the nested slots below tool task `taskId`, transitively; the list holds parents before their children. */
|
|
98
|
+
export function removeNestedSlots(live, taskId) {
|
|
99
|
+
const nested = live.nestedTools;
|
|
100
|
+
if (nested === undefined)
|
|
101
|
+
return;
|
|
102
|
+
const removed = new Set([taskId]);
|
|
103
|
+
for (const slot of nested)
|
|
104
|
+
if (removed.has(slot.parentTaskId))
|
|
105
|
+
removed.add(slot.taskId);
|
|
106
|
+
for (let index = nested.length - 1; index >= 0; index--) {
|
|
107
|
+
if (removed.has(nested[index].parentTaskId))
|
|
108
|
+
nested.splice(index, 1);
|
|
109
|
+
}
|
|
110
|
+
if (nested.length === 0)
|
|
111
|
+
delete live.nestedTools;
|
|
112
|
+
}
|
|
64
113
|
/** Remove what a tool published while running; its result entry or a rerun replaces it. */
|
|
65
114
|
export function clearProgress(slot) {
|
|
66
115
|
delete slot.output;
|
|
@@ -72,7 +121,7 @@ export function clearProgress(slot) {
|
|
|
72
121
|
/**
|
|
73
122
|
* Harness cleanup for a terminal outcome the scheduler writes itself (`faulted` or `orphaned`). A run task ends its
|
|
74
123
|
* run; a tool task's slot is marked done without an entry, and context derivation synthesizes the missing result; a
|
|
75
|
-
* compaction task's status is removed.
|
|
124
|
+
* compaction task's status is removed and its failure recorded.
|
|
76
125
|
* Ignores other kinds so it never creates `pi.live` elsewhere. The scheduler calls this without knowing task kinds;
|
|
77
126
|
* the Harness passes it in (spec §5.4).
|
|
78
127
|
* REMINDER: a committed generation partial becomes an aborted assistant entry here, exactly as in the generation abort
|
|
@@ -83,13 +132,16 @@ export function clearProgress(slot) {
|
|
|
83
132
|
*/
|
|
84
133
|
export async function settleSchedulerOutcome(tx, record, outcome) {
|
|
85
134
|
if (record.kind === TOOL_TASK_KIND) {
|
|
86
|
-
const
|
|
135
|
+
const live = await tx.doc(LiveDoc, record.conversationId);
|
|
136
|
+
const slot = toolSlot(live, record.id);
|
|
87
137
|
if (slot !== undefined)
|
|
88
|
-
finishSlot(slot
|
|
138
|
+
finishSlot(slot);
|
|
139
|
+
removeNestedSlots(live, record.id);
|
|
89
140
|
return;
|
|
90
141
|
}
|
|
91
142
|
if (record.kind === COMPACTION_TASK_KIND) {
|
|
92
|
-
|
|
143
|
+
const error = outcome.status === "faulted" ? outcome.error.message : outcome.reason;
|
|
144
|
+
failCompactionStatus(await tx.doc(LiveDoc, record.conversationId), record.id, error);
|
|
93
145
|
return;
|
|
94
146
|
}
|
|
95
147
|
if (!RUN_TASK_KINDS.has(record.kind))
|