@orkestrel/agent 0.0.32 → 0.0.33
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/dist/src/core/index.cjs +122 -30
- package/dist/src/core/index.cjs.map +1 -1
- package/dist/src/core/index.d.cts +24 -24
- package/dist/src/core/index.d.ts +24 -24
- package/dist/src/core/index.js +123 -31
- package/dist/src/core/index.js.map +1 -1
- package/package.json +22 -22
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.js","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/shapers.ts","../../../src/core/contracts.ts","../../../src/core/cloners.ts","../../../src/core/helpers.ts","../../../src/core/validators.ts","../../../src/core/providers/constants.ts","../../../src/core/providers/errors.ts","../../../src/core/providers/shapers.ts","../../../src/core/providers/contracts.ts","../../../src/core/providers/helpers.ts","../../../src/core/providers/RelayStream.ts","../../../src/core/providers/ThinkSplitter.ts","../../../src/core/providers/AgentProvider.ts","../../../src/core/providers/RelayProvider.ts","../../../src/core/providers/AgentJudge.ts","../../../src/core/providers/validators.ts","../../../src/core/providers/SystemOneJudge.ts","../../../src/core/providers/factories.ts","../../../src/core/conversations/constants.ts","../../../src/core/conversations/errors.ts","../../../src/core/conversations/validators.ts","../../../src/core/conversations/helpers.ts","../../../src/core/conversations/JudgmentManager.ts","../../../src/core/conversations/Conversation.ts","../../../src/core/conversations/ConversationManager.ts","../../../src/core/conversations/stores/MemoryConversationStore.ts","../../../src/core/conversations/stores/DatabaseConversationStore.ts","../../../src/core/conversations/factories.ts","../../../src/core/contexts/constants.ts","../../../src/core/contexts/instructions/Instruction.ts","../../../src/core/contexts/instructions/InstructionManager.ts","../../../src/core/contexts/helpers.ts","../../../src/core/contexts/scopes/Scope.ts","../../../src/core/contexts/scopes/ScopeManager.ts","../../../src/core/contexts/AgentContext.ts","../../../src/core/contexts/factories.ts","../../../src/core/agents/constants.ts","../../../src/core/agents/errors.ts","../../../src/core/agents/Channel.ts","../../../src/core/agents/helpers.ts","../../../src/core/agents/Agent.ts","../../../src/core/agents/AgentFanout.ts","../../../src/core/agents/Authority.ts","../../../src/core/agents/AgentRegistry.ts","../../../src/core/agents/factories.ts","../../../src/core/ledgers/constants.ts","../../../src/core/ledgers/errors.ts","../../../src/core/ledgers/helpers.ts","../../../src/core/ledgers/Classifier.ts","../../../src/core/ledgers/validators.ts","../../../src/core/ledgers/Gauge.ts","../../../src/core/ledgers/LedgerPass.ts","../../../src/core/ledgers/LedgerRequest.ts","../../../src/core/ledgers/Ledger.ts","../../../src/core/ledgers/factories.ts"],"sourcesContent":["/**\n * Lists the roles a conversation message can play, in the order the wire contract names them —\n * the one list the {@link import('./types.js').MessageRole} union derives from, the message\n * guard tests membership against, and the message shape passes to its literal contract.\n */\nexport const MESSAGE_ROLES = Object.freeze(['system', 'user', 'assistant', 'tool'] as const)\n","import type { JudgeResult } from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/**\n * Reports a judge call cancelled by the caller's signal or its deadline, carrying the\n * {@link JudgeResult} merged from the calls that completed before the cancel and the\n * machine-readable `code` `'ABORT'`.\n *\n * @remarks\n * `partial` keeps the answers and the usage of every completed call, so usage reported by\n * completed calls is retained; a cancel before the first call carries an empty partial. `cause` holds the failure the\n * cancel superseded when a throw raced the abort, and is undefined when the cancel was the only\n * failure.\n */\nexport class JudgeAbortError extends Error {\n\t/** Names the machine-readable condition — `'ABORT'`: a judge call cancelled mid-flight. */\n\treadonly code = 'ABORT' as const\n\treadonly partial: JudgeResult\n\n\tconstructor(partial: JudgeResult, options?: ErrorOptions) {\n\t\tsuper('judge call aborted', options)\n\t\tthis.name = 'JudgeAbortError'\n\t\tthis.partial = partial\n\t}\n}\n\n/**\n * Narrows a caught value to a {@link JudgeAbortError} through `instanceof`, so a `catch` can\n * recover its `partial` result.\n *\n * @param value - The caught value\n * @returns True if the value is a {@link JudgeAbortError}; false otherwise\n * @example\n * ```ts\n * isJudgeAbortError(new JudgeAbortError({ model: 'tev1:0.8b', answers: {} })) // true\n * ```\n */\nexport function isJudgeAbortError(value: unknown): value is JudgeAbortError {\n\treturn isInstance(value, JudgeAbortError)\n}\n","import type { ContractShape } from '@orkestrel/contract'\nimport { MESSAGE_ROLES } from './constants.js'\nimport {\n\tarrayShape,\n\tjsonShape,\n\tliteralShape,\n\tobjectShape,\n\toptionalShape,\n\trecordShape,\n\tstringShape,\n} from '@orkestrel/contract'\n\n/**\n * Describes a tool call's JSON wire projection.\n *\n * @remarks\n * The wire is strictly narrower than the domain: non-JSON arguments are refused.\n * Calls carry only id, name, and arguments; execution context stays local.\n * The guard refuses every extra member; the contract parser drops extra members.\n */\nexport const toolCallShape = objectShape({\n\tid: stringShape(),\n\tname: stringShape(),\n\targuments: recordShape(jsonShape()),\n}) satisfies ContractShape\n\n/**\n * Describes a conversation message's JSON wire projection.\n *\n * @remarks\n * The wire is strictly narrower than Message: non-JSON call arguments are refused,\n * and execution context stays local. The guard refuses extra members; the parser drops them.\n */\nexport const messageShape = objectShape({\n\tid: stringShape(),\n\trole: literalShape(MESSAGE_ROLES),\n\tcontent: stringShape(),\n\tcalls: optionalShape(arrayShape(toolCallShape)),\n\tcall: optionalShape(stringShape()),\n\timages: optionalShape(arrayShape(stringShape())),\n\tthinking: optionalShape(stringShape()),\n}) satisfies ContractShape\n","import { createContract } from '@orkestrel/contract'\nimport { messageShape } from './shapers.js'\n\n/** Validates and projects conversation messages at a JSON wire boundary. */\nexport const messageContract = createContract(messageShape)\n","import { attempt, parseJSON } from '@orkestrel/contract'\n\n/**\n * Owns a value by serializing it to JSON and parsing the text, so the copy shares nothing with its source.\n *\n * @remarks\n * A value that JSON cannot carry, such as a cycle or a bigint, and a value that serializes to\n * nothing, such as a function, both return undefined, so a guard over the result refuses them.\n * A proxied value serializes through its traps, where a structured clone refuses it.\n *\n * @param value - The value to own\n * @returns The owned JSON copy, or undefined when the value is not JSON\n * @example\n * ```ts\n * copyJSON({ state: 'A ticket.' }) // { state: 'A ticket.' }\n * copyJSON(() => 1) // undefined\n * ```\n */\nexport function copyJSON(value: unknown): unknown {\n\tconst text = attempt(() => JSON.stringify(value))\n\tif (!text.success || typeof text.value !== 'string') return undefined\n\treturn parseJSON(text.value)\n}\n","import type { JudgeQuestion, Judgment, Message, ThinkingReplay } from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport { attempt, isFiniteNumber } from '@orkestrel/contract'\n\n/**\n * Filters a list of members by a {@link import('./contexts/index.js').ScopeInterface} allow-list of keys —\n * `undefined` passes everything, `[]` passes nothing, and a non-empty list passes the listed keys\n * alone, order preserved. The pure, total set-membership primitive the context's build step and\n * the agent loop's tool-advertise step apply a scope through.\n *\n * @remarks\n * Varies by the allow-list's shape, so a `Scope` category expresses \"all /\n * none / only these\":\n * - `undefined` ⇒ no constraint — every member passes (returned unchanged).\n * - `[]` (empty) ⇒ none pass (no key is in an empty set).\n * - a non-empty list ⇒ only members whose `key(member)` is in the list pass.\n *\n * Preserves the members' order. Keys are matched by a `Set` for membership.\n *\n * @typeParam T - The member type being filtered\n * @param allow - The allow-list of keys (`undefined` ⇒ all, `[]` ⇒ none, else only-listed)\n * @param members - The members to filter (returned unchanged when `allow` is `undefined`)\n * @param key - Extracts the key a member is matched on (for example an instruction's `name`)\n * @returns The members that pass the allow-list, in their original order\n *\n * @example\n * ```ts\n * const members = [{ name: 'refunds' }, { name: 'billing' }]\n * filterAllowList(undefined, members, (member) => member.name) // [{ name: 'refunds' }, { name: 'billing' }]\n * filterAllowList([], members, (member) => member.name) // []\n * filterAllowList(['billing'], members, (member) => member.name) // [{ name: 'billing' }]\n * ```\n */\nexport function filterAllowList<T>(\n\tallow: readonly string[] | undefined,\n\tmembers: readonly T[],\n\tkey: (member: T) => string,\n): readonly T[] {\n\tif (allow === undefined) return members\n\tif (allow.length === 0) return []\n\tconst set = new Set(allow)\n\treturn members.filter((member) => set.has(key(member)))\n}\n\n/**\n * Joins the reasoning a run's provider calls separated from the answer — the first call\n * seeds the accumulation, a later call appends blank-line separated so each turn's reasoning\n * stays readable.\n *\n * @remarks\n * Pure and total. `running` is `undefined` until a call surfaces reasoning, so the first join\n * returns `next` verbatim. Each call's non-empty thinking is recorded on the assistant message\n * that call appends. The joined result also includes thinking from calls that appended no\n * message, such as an aborted call. Only recorded thinking can return to a provider,\n * as its `replay` policy allows. Thinking stays out of `content`.\n *\n * @param running - The reasoning accumulated so far (`undefined` before the first)\n * @param next - This call's separated reasoning\n * @returns The joined reasoning\n *\n * @example\n * ```ts\n * joinThinking(undefined, 'first') // 'first'\n * joinThinking('', 'x') // 'x'\n * joinThinking('first', 'second') // 'first\\n\\nsecond'\n * ```\n */\nexport function joinThinking(running: string | undefined, next: string): string {\n\tif (running === undefined || running.length === 0) return next\n\treturn next.length === 0 ? running : `${running}\\n\\n${next}`\n}\n\n/**\n * Applies a {@link ThinkingReplay} policy to a conversation, returning the messages a provider\n * sends with only the assistant thinking the policy allows.\n *\n * @remarks\n * Pure and total. `'all'` returns the input array itself. `'none'` drops `thinking` from every\n * message that carries it. `'turn'` drops it from every message at or before the last `user`\n * message and keeps it after, the turn in progress; with no `user` message every message counts\n * as inside the turn. A message without `thinking`, or one that keeps it, is the same object;\n * a message that loses it is a copy without that member, so no `undefined` member is written.\n *\n * @param messages - The conversation to project (left unchanged)\n * @param replay - The policy naming which thinking stays\n * @returns The messages with the policy applied\n *\n * @example\n * ```ts\n * const messages = [\n * \t{ id: '1', role: 'user', content: 'Plan the trip' },\n * \t{ id: '2', role: 'assistant', content: 'Booked', thinking: 'Compare fares first' },\n * ]\n * stripThinking(messages, 'none') // [{ id: '1', ... }, { id: '2', role: 'assistant', content: 'Booked' }]\n * stripThinking(messages, 'turn') // the thinking on '2' stays: it follows the last user message\n * ```\n */\nexport function stripThinking(\n\tmessages: readonly Message[],\n\treplay: ThinkingReplay,\n): readonly Message[] {\n\tif (replay === 'all') return messages\n\tconst last =\n\t\treplay === 'none' ? messages.length - 1 : messages.findLastIndex((one) => one.role === 'user')\n\treturn messages.map((message, index) => {\n\t\tif (message.thinking === undefined || index > last) return message\n\t\tconst { thinking: _thinking, ...rest } = message\n\t\treturn rest\n\t})\n}\n\n/**\n * Sanitizes one reported token count into a non-negative integer — a non-finite or\n * non-positive value becomes `0`, and a positive fractional value floors down.\n *\n * @param value - The token count to sanitize\n * @returns The floored count, or `0` when the value is non-finite or non-positive\n * @example\n * ```ts\n * sanitizeToken(12.7) // 12\n * sanitizeToken(-1) // 0\n * sanitizeToken(Number.NaN) // 0\n * ```\n */\nexport function sanitizeToken(value: number): number {\n\treturn isFiniteNumber(value) && value > 0 ? Math.floor(value) : 0\n}\n\n/**\n * Sanitizes a {@link TokenUsage} into non-negative integers — the guard an agent's\n * abort-usage path applies to a provider's partial usage before it is charged against a\n * budget or folded into the run total.\n *\n * @remarks\n * Per field (`prompt` / `completion` / `total`): a non-finite value (`NaN`, `+Infinity`,\n * `-Infinity`) or a negative value floors to `0`; a fractional value floors to its\n * non-negative integer part. No upper cap is applied. Total — never throws.\n *\n * @param usage - The token usage to sanitize (for example a provider's abort-partial usage)\n * @returns A new {@link TokenUsage} with every field a non-negative integer\n *\n * @example\n * ```ts\n * sanitizeUsage({ prompt: -5, completion: NaN, total: 12.7 }) // { prompt: 0, completion: 0, total: 12 }\n * ```\n */\nexport function sanitizeUsage(usage: TokenUsage): TokenUsage {\n\treturn {\n\t\tprompt: sanitizeToken(usage.prompt),\n\t\tcompletion: sanitizeToken(usage.completion),\n\t\ttotal: sanitizeToken(usage.total),\n\t}\n}\n\n/**\n * Adds two {@link TokenUsage} values field by field — the running total an agent run keeps\n * across its provider calls.\n *\n * @remarks\n * Pure and total: the first call seeds the total (`running` `undefined` returns `next`\n * unchanged), later calls accumulate. No sanitization happens here — charge a provider's\n * reported usage through {@link sanitizeUsage} first.\n *\n * @param running - The total so far (`undefined` before the first usage-bearing call)\n * @param next - This call's reported usage\n * @returns The summed usage\n *\n * @example\n * ```ts\n * sumUsage(undefined, { prompt: 2, completion: 1, total: 3 }) // { prompt: 2, completion: 1, total: 3 }\n * sumUsage({ prompt: 2, completion: 1, total: 3 }, { prompt: 1, completion: 1, total: 2 })\n * // { prompt: 3, completion: 2, total: 5 }\n * ```\n */\nexport function sumUsage(running: TokenUsage | undefined, next: TokenUsage): TokenUsage {\n\tif (running === undefined) return next\n\treturn {\n\t\tprompt: running.prompt + next.prompt,\n\t\tcompletion: running.completion + next.completion,\n\t\ttotal: running.total + next.total,\n\t}\n}\n\n/**\n * Removes each key through a single-key remover and folds the outcomes, so a batch `remove`\n * reports whether the whole batch applied.\n *\n * @remarks\n * Every key is passed to `remove` even after one is missing, so a present key still takes\n * effect (and emits) when an earlier key was absent.\n *\n * @typeParam K - The key type the remover accepts\n * @param keys - The keys to remove, in order\n * @param remove - Removes one key and returns whether it was present\n * @returns True if every key was present and removed; false otherwise (an empty list returns true)\n *\n * @example\n * ```ts\n * const stored = new Set(['refunds', 'billing'])\n * removeEntries(['refunds', 'escalations'], (key) => stored.delete(key)) // false\n * removeEntries(['billing'], (key) => stored.delete(key)) // true\n * ```\n */\nexport function removeEntries<K>(keys: readonly K[], remove: (key: K) => boolean): boolean {\n\t// `Array.from` passes a hole in `keys` to `remove` as `undefined`, as iteration does; `map` skips it.\n\treturn Array.from(keys, (key) => remove(key)).every((removed) => removed)\n}\n\n/**\n * Collects whole exchanges, joining every exchange spanned by a tool group.\n *\n * @remarks\n * A user message opens an exchange that ends before the next user message. Leading messages\n * form their own exchange. A tool group joins every exchange between its first and last member.\n *\n * @param messages - The messages in prompt order\n * @returns The exchanges in prompt order, with each message retained unchanged\n * @example\n * ```ts\n * collectExchanges([\n * \t{ id: 'greeting', role: 'assistant', content: 'Welcome.' },\n * \t{ id: 'request', role: 'user', content: 'Read the order.' },\n * ]) // a leading exchange and a request exchange\n * ```\n */\nexport function collectExchanges(messages: readonly Message[]): ReadonlyArray<readonly Message[]> {\n\tif (messages.length === 0) return []\n\tconst positions = new Map(messages.map((message, index) => [message, index]))\n\tconst spans = collectToolGroups(messages).map((group) => {\n\t\tconst spanned = group.flatMap((message) => {\n\t\t\tconst position = positions.get(message)\n\t\t\treturn position === undefined ? [] : [position]\n\t\t})\n\t\treturn {\n\t\t\tstart: spanned.reduce((least, position) => Math.min(least, position), messages.length),\n\t\t\tend: spanned.reduce((most, position) => Math.max(most, position), 0),\n\t\t}\n\t})\n\tconst starts = [\n\t\t...new Set([\n\t\t\t0,\n\t\t\t...[...messages.entries()].flatMap(([index, message]) =>\n\t\t\t\tmessage.role === 'user' ? [index] : [],\n\t\t\t),\n\t\t]),\n\t].filter((boundary) => !spans.some((span) => span.start < boundary && boundary <= span.end))\n\treturn starts.map((start, position) =>\n\t\tmessages.slice(start, starts[position + 1] ?? messages.length),\n\t)\n}\n\n/**\n * Checks whether a message carries at least one tool call.\n *\n * @remarks\n * Pure and total. An absent `calls` member and an empty list both return false, so a tool-free\n * assistant turn and a turn whose provider reported an empty call list read alike.\n *\n * @param message - The message to inspect; only its `calls` member is read\n * @returns True if `calls` holds at least one call; false otherwise\n * @example\n * ```ts\n * hasCalls({ calls: [{ id: 'order', name: 'lookup', arguments: {} }] }) // true\n * hasCalls({ calls: [] }) // false\n * hasCalls({}) // false\n * ```\n */\nexport function hasCalls(message: Pick<Message, 'calls'>): boolean {\n\treturn (message.calls?.length ?? 0) > 0\n}\n\n/**\n * Collects each assistant message that carries calls together with the tool messages that answer\n * it, then each run of tool messages that no assistant message owns.\n *\n * @remarks\n * A tool message belongs to the one assistant message whose calls hold its `call` id. Without that\n * unique owner, it belongs to the assistant message that leads its run of tool messages when that\n * leader holds the id, repeats a call id, or the tool message has no `call`. Any other tool message\n * joins the orphan run it sits in. Compaction and the stock selection each keep a group on one side\n * of their cut.\n *\n * @param messages - The messages in prompt order\n * @returns The owned groups in owner order, then the orphan runs, each in prompt order\n * @example\n * ```ts\n * collectToolGroups([\n * \t{ id: 'lookup', role: 'assistant', content: '', calls: [{ id: 'order', name: 'lookup', arguments: {} }] },\n * \t{ id: 'result', role: 'tool', content: 'LH-81660 is late', call: 'order' },\n * ]) // one group holding the lookup call and its result\n * ```\n */\nexport function collectToolGroups(messages: readonly Message[]): ReadonlyArray<readonly Message[]> {\n\tconst leaders = messages.filter((message) => message.role === 'assistant' && hasCalls(message))\n\tconst leading = new Set(leaders)\n\t// `Array.from` passes a hole in `calls` to the mapper as `undefined`, as iteration does; `map` skips it.\n\tconst owners = Map.groupBy(\n\t\tleaders.flatMap((leader) =>\n\t\t\tArray.from(leader.calls ?? [], (call) => ({ id: call.id, leader })),\n\t\t),\n\t\t(entry) => entry.id,\n\t)\n\tconst starts = [...messages.entries()].flatMap(([index, message]) =>\n\t\tmessage.role === 'tool' ? [] : [index],\n\t)\n\t// A run is one non-tool message, which leads it when it owns calls, and the tool messages after it.\n\tconst runs = [\n\t\t{ leader: undefined, tools: messages.slice(0, starts[0] ?? messages.length) },\n\t\t...starts.map((start, position) => {\n\t\t\tconst message = messages[start]\n\t\t\treturn {\n\t\t\t\tleader: message !== undefined && leading.has(message) ? message : undefined,\n\t\t\t\ttools: messages.slice(start + 1, starts[position + 1] ?? messages.length),\n\t\t\t}\n\t\t}),\n\t]\n\tconst placed = runs.map(({ leader, tools }) => {\n\t\tconst local = leader?.calls ?? []\n\t\tconst duplicate = new Set(local.map((call) => call.id)).size !== local.length\n\t\treturn tools.map((message) => {\n\t\t\tconst paired =\n\t\t\t\tleader !== undefined &&\n\t\t\t\t(duplicate || message.call === undefined || local.some((call) => call.id === message.call))\n\t\t\tconst sharing = message.call === undefined ? undefined : owners.get(message.call)\n\t\t\tconst owner = sharing?.length === 1 ? sharing[0]?.leader : paired ? leader : undefined\n\t\t\treturn { message, owner }\n\t\t})\n\t})\n\tconst owned = Map.groupBy(\n\t\tplaced.flat().filter((entry) => entry.owner !== undefined),\n\t\t(entry) => entry.owner,\n\t)\n\tconst groups = [...leading].map((leader) => [\n\t\tleader,\n\t\t...(owned.get(leader) ?? []).map((entry) => entry.message),\n\t])\n\tconst orphans = placed.flatMap((run) => {\n\t\tconst orphan = run.filter((entry) => entry.owner === undefined).map((entry) => entry.message)\n\t\treturn orphan.length > 0 ? [orphan] : []\n\t})\n\treturn [...groups, ...orphans]\n}\n\n/**\n * Renders a value as the JSON text `JSON.stringify` produces, or `undefined` when JSON cannot\n * carry the value.\n *\n * @remarks\n * Pure and total. Where `JSON.stringify` returns text, the result is the same text, property order\n * included; `canonicalStringify` from `@orkestrel/contract` sorts keys instead. A value\n * `JSON.stringify` throws on, such as a `BigInt` or a cycle, and a value it renders as nothing,\n * such as `undefined`, a function, or a symbol, return `undefined`.\n *\n * @param value - The value to render\n * @returns The JSON text, or `undefined` when the value has no JSON text\n * @example\n * ```ts\n * renderJSON({ order: 'LH-81660', late: true }) // '{\"order\":\"LH-81660\",\"late\":true}'\n * renderJSON(10n) // undefined\n * renderJSON(undefined) // undefined\n * ```\n */\nexport function renderJSON(value: unknown): string | undefined {\n\tconst outcome = attempt((): string | undefined => JSON.stringify(value))\n\treturn outcome.success ? outcome.value : undefined\n}\n\n/**\n * Matches a recorded question, ordered sources, rendered state, and judge identity by JSON text, so key order counts.\n *\n * @param judgment - The recorded judgment to compare\n * @param question - The question to ask\n * @param sources - The ordered source message ids\n * @param state - The rendered state to compare\n * @param model - The configured judge identity\n * @returns True if every identity component matches; false otherwise\n * @example\n * ```ts\n * matchesJudgment(judgment, question, ['message-a'], 'Charged twice', judge.model)\n * ```\n */\nexport function matchesJudgment(\n\tjudgment: Judgment,\n\tquestion: JudgeQuestion,\n\tsources: readonly string[],\n\tstate: string,\n\tmodel: string,\n): boolean {\n\treturn (\n\t\tjudgment.model === model &&\n\t\tjudgment.state === state &&\n\t\tjudgment.sources.length === sources.length &&\n\t\tjudgment.sources.every((id, index) => id === sources[index]) &&\n\t\tJSON.stringify(judgment.question) === JSON.stringify(question)\n\t)\n}\n","import type { JudgeEntry, JudgeQuestion } from './types.js'\nimport {\n\tarrayOf,\n\tattempt,\n\tisArray,\n\tisFiniteNumber,\n\tisJSONValue,\n\tisRecord,\n\tisString,\n\tnullableOf,\n\toptionalOf,\n} from '@orkestrel/contract'\n\n/**\n * Checks whether a value is a judge entry: a string, a JSON record, or a JSON array.\n *\n * @remarks\n * Total: a cycle, a non-JSON member, a class instance, and a hostile input return false. `null`\n * is not an entry; a criteria guard admits it where the protocol keeps it.\n *\n * @param value - The unknown entry candidate\n * @returns True if the value is a string or JSON structure the model can read; false otherwise\n * @example\n * ```ts\n * isJudgeEntry('Customer asks for a refund') // true\n * isJudgeEntry({ ticket: 4182, tags: ['billing'] }) // true\n * isJudgeEntry(null) // false\n * isJudgeEntry({ opened: new Date() }) // false\n * ```\n */\nexport function isJudgeEntry(value: unknown): value is JudgeEntry {\n\tif (isString(value)) return true\n\treturn (isRecord(value) || isArray(value)) && isJSONValue(value)\n}\n\n/**\n * Checks whether a value is a well-formed judge question of the choice, score, or noul form.\n *\n * @remarks\n * Total: a hostile input returns false. A choice needs at least 2 options and a score at least 2\n * levels, because the confidence formula divides by the candidate count; a description or a level\n * can be `null`. `instructions` and noul `criteria` are omitted when absent and never `null`.\n * Server limits on option, level, and question counts are left to the server.\n *\n * @param value - The unknown question candidate\n * @returns True if the value is a question the judge engine can send; false otherwise\n * @example\n * ```ts\n * isJudgeQuestion({ form: 'choice', criteria: { billing: null, bug: 'Software defect' } }) // true\n * isJudgeQuestion({ form: 'score', criteria: ['Cosmetic', null, 'Blocking'] }) // true\n * isJudgeQuestion({ form: 'noul', instructions: 'Is a refund owed?' }) // true\n * isJudgeQuestion({ form: 'choice', criteria: { billing: null } }) // false\n * ```\n */\nexport function isJudgeQuestion(value: unknown): value is JudgeQuestion {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { form, instructions, criteria } = value\n\t\tif (instructions !== undefined && !isJudgeEntry(instructions)) return false\n\t\tif (form === 'choice') {\n\t\t\treturn (\n\t\t\t\tisRecord(criteria) &&\n\t\t\t\tObject.keys(criteria).length >= 2 &&\n\t\t\t\tObject.values(criteria).every(nullableOf(isJudgeEntry))\n\t\t\t)\n\t\t}\n\t\tif (form === 'score') {\n\t\t\treturn arrayOf(nullableOf(isJudgeEntry))(criteria) && criteria.length >= 2\n\t\t}\n\t\tif (form !== 'noul') return false\n\t\tif (criteria === undefined) return true\n\t\tif (!isRecord(criteria)) return false\n\t\treturn optionalOf(isJudgeEntry)(criteria.true) && optionalOf(isJudgeEntry)(criteria.false)\n\t})\n\treturn checked.success && checked.value\n}\n\n/**\n * Checks whether a value is a non-negative safe integer, `-0` included.\n *\n * @remarks\n * Total: a non-number, `NaN`, an infinity, a fraction, a negative number, and an integer past\n * `Number.MAX_SAFE_INTEGER` return false. It differs from `isNonNegativeInteger` in\n * `@orkestrel/contract` at two values: that guard rejects `-0` and admits an unsafe integer such\n * as `2 ** 53`, while this guard admits `-0` and rejects `2 ** 53`.\n *\n * @param value - The unknown count or limit candidate\n * @returns True if the value is a safe integer at or above zero; false otherwise\n * @example\n * ```ts\n * isNonNegativeSafeInteger(0) // true\n * isNonNegativeSafeInteger(-0) // true\n * isNonNegativeSafeInteger(2 ** 53) // false\n * isNonNegativeSafeInteger(1.5) // false\n * ```\n */\nexport function isNonNegativeSafeInteger(value: unknown): value is number {\n\treturn isFiniteNumber(value) && Number.isSafeInteger(value) && value >= 0\n}\n","/**\n * Names the opening tag a {@link import('./ThinkSplitter.js').ThinkSplitter} recognizes as the start of\n * an in-content reasoning span — `'<think>'`, the de-facto wire convention thinking models\n * (qwen3, DeepSeek-R1 family) emit their chain-of-thought under when a daemon renders it inline\n * instead of on a separate wire field. Paired with {@link THINK_CLOSE}.\n */\nexport const THINK_OPEN = '<think>'\n\n/**\n * Names the closing tag that ends a {@link THINK_OPEN} reasoning span — `'</think>'`. A span the\n * stream never closes (the model was cut off mid-reasoning) is treated as thinking to its end,\n * and {@link import('./types.js').ThinkSplitterInterface.flush} settles it.\n */\nexport const THINK_CLOSE = '</think>'\n\n/**\n * Holds the default provider deadline in milliseconds — `120_000`, the wall-clock bound a call\n * runs under when `AgentProviderInput.timeout` is omitted, folded with the caller's signal so\n * whichever trips first cancels the call.\n */\nexport const DEFAULT_PROVIDER_TIMEOUT = 120_000\n\n/**\n * Bounds the decoded error excerpt's input in bytes — `2048`, the leading bytes of a non-OK\n * response body handed to the decoder before the read cancels the remainder, so a `ProviderError`\n * message never carries a longer excerpt.\n */\nexport const MAX_ERROR_BODY_LENGTH = 2048\n\n/**\n * Holds the default relay request limit in bytes — `1_048_576`, the byte budget a relay applies\n * to an inbound body when `RelayOptions.limit` is omitted, refusing a body that reaches it.\n */\nexport const DEFAULT_RELAY_LIMIT = 1_048_576\n\n/**\n * Names the relay's newline-delimited JSON content type — `'application/x-ndjson; charset=utf-8'`,\n * the header a relay response carries beside `cache-control: no-store`.\n */\nexport const RELAY_CONTENT_TYPE = 'application/x-ndjson; charset=utf-8'\n\n/**\n * Names the public message for an unexpected upstream relay failure — `'relay provider failed'`,\n * the fixed text every `error` frame carries, so an upstream failure's own message never reaches\n * the browser.\n */\nexport const RELAY_PROVIDER_MESSAGE = 'relay provider failed'\n\n/**\n * Names the status a relay answers when the `authorize` callback returns anything but `true` or throws —\n * `401`, carried with no body and reaching the browser as a `ProviderError` with the `HTTP` code.\n */\nexport const UNAUTHORIZED_RELAY_STATUS = 401\n\n/**\n * Names the status a relay answers when the upstream provider call cannot be constructed — `502`,\n * carried with no body after `provider.stream` was entered and threw before returning its\n * iterator.\n */\nexport const UPSTREAM_RELAY_STATUS = 502\n\n/**\n * Names the status a relay answers for a body that is missing, unreadable, or rejected by\n * `providerRequestContract` — `400`, carried with no body and reaching the browser as a\n * `ProviderError` with the `HTTP` code.\n */\nexport const INVALID_RELAY_STATUS = 400\n\n/**\n * Names the status a relay answers for a request body at or above its byte budget — `413`,\n * carried with no body and answered for an aborted inbound read as well.\n */\nexport const OVERSIZED_RELAY_STATUS = 413\n\n/** Names the System One decision endpoint shared by compatible servers. */\nexport const SYSTEM_ONE_PATH = '/v1/systemone'\n","import type {\n\tJudgeErrorCode,\n\tProviderErrorCode,\n\tProviderErrorOptions,\n\tProviderResult,\n} from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/**\n * Reports a provider stream cancelled mid-flight by its bound signal — thrown by the\n * `stream` method of a {@link ProviderInterface}, carrying the {@link ProviderResult} assembled from\n * whatever streamed before the cancel and the machine-readable `code` `'ABORT'`.\n *\n * @remarks\n * Lets a caller recover the partial content (and any tool calls / usage seen so far)\n * on cancellation: `catch` the throw, narrow with {@link isProviderAbortError}, and\n * read `partial`. `code` is the machine-readable condition (`'ABORT'` — the only one this\n * error reports), so a `catch` branches on it rather than on the message string. `cause`\n * holds the failure the cancel superseded when a throw raced the abort — the wire decoder's\n * {@link ProviderError}, say — and is undefined when the cancel was the only failure.\n */\nexport class ProviderAbortError extends Error {\n\t/** Names the machine-readable condition — `'ABORT'`: a stream cancelled mid-flight. */\n\treadonly code = 'ABORT' as const\n\treadonly partial: ProviderResult\n\n\tconstructor(partial: ProviderResult, options?: ErrorOptions) {\n\t\tsuper('provider stream aborted', options)\n\t\tthis.name = 'ProviderAbortError'\n\t\tthis.partial = partial\n\t}\n}\n\n/**\n * Narrows an unknown caught value to a {@link ProviderAbortError} through `instanceof`, so a\n * `catch` can recover its `partial` result.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns True if `value` is a {@link ProviderAbortError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tfor await (const delta of provider.stream(messages, signal)) render(delta)\n * } catch (error) {\n * \tif (isProviderAbortError(error)) keep(error.partial.content) // recover partial\n * }\n * ```\n */\nexport function isProviderAbortError(value: unknown): value is ProviderAbortError {\n\treturn isInstance(value, ProviderAbortError)\n}\n\n/**\n * Reports a coded provider failure with its HTTP status and underlying cause when available.\n *\n * @remarks\n * The provider base throws this error for a non-OK HTTP response, a missing response\n * body, or a missing settled result when strict assembly is enabled. Concrete wire\n * decoders also use it for malformed records and relayed provider failures.\n * `status` is present only for an `HTTP` failure; other codes leave it undefined.\n */\nexport class ProviderError extends Error {\n\t/** Names the machine-readable condition — `'HTTP'`: a non-OK response, including a relay refusing an oversized request with 413; `'PROTOCOL'`: a missing response body, a malformed wire record, or a strict stream with no settled result; `'PROVIDER'`: an upstream failure carried by a relay error record. */\n\treadonly code: ProviderErrorCode\n\t/** Holds the response status for an HTTP failure, or undefined for other codes. */\n\treadonly status: number | undefined\n\n\tconstructor(code: ProviderErrorCode, message: string, options?: ProviderErrorOptions) {\n\t\tsuper(message, options)\n\t\tthis.name = 'ProviderError'\n\t\tthis.code = code\n\t\tthis.status = options?.status\n\t}\n}\n\n/**\n * Narrows a caught value to the provider failure class through `instanceof`.\n *\n * @param value - The caught value\n * @returns True if the value is a provider failure; false otherwise\n * @example\n * ```ts\n * isProviderError(new ProviderError('HTTP', 'unavailable', { status: 503 })) // true\n * ```\n */\nexport function isProviderError(value: unknown): value is ProviderError {\n\treturn isInstance(value, ProviderError)\n}\n\n/**\n * Reports a coded judge failure with its HTTP status and underlying cause when available.\n *\n * @remarks\n * The judge engine throws this error for a non-OK HTTP response, a missing or unparsable\n * response body, and a request refused before inference. Concrete wire decoders also use it for\n * a response they cannot read and for a wire limit. `status` is present only for an `HTTP`\n * failure; other codes leave it undefined.\n */\nexport class JudgeError extends Error {\n\t/** Names the machine-readable condition — `'HTTP'`: a non-OK response; `'PROTOCOL'`: a missing, unparsable, or unreadable response body; `'QUESTION'`: a request refused before inference. */\n\treadonly code: JudgeErrorCode\n\t/** Holds the response status for an HTTP failure, or undefined for other codes. */\n\treadonly status: number | undefined\n\n\tconstructor(code: JudgeErrorCode, message: string, options?: ProviderErrorOptions) {\n\t\tsuper(message, options)\n\t\tthis.name = 'JudgeError'\n\t\tthis.code = code\n\t\tthis.status = options?.status\n\t}\n}\n\n/**\n * Narrows a caught value to the judge failure class through `instanceof`.\n *\n * @param value - The caught value\n * @returns True if the value is a {@link JudgeError}; false otherwise\n * @example\n * ```ts\n * isJudgeError(new JudgeError('HTTP', 'judge error: 429', { status: 429 })) // true\n * ```\n */\nexport function isJudgeError(value: unknown): value is JudgeError {\n\treturn isInstance(value, JudgeError)\n}\n","import type { ContractShape } from '@orkestrel/contract'\nimport {\n\tarrayShape,\n\tbooleanShape,\n\tjsonShape,\n\tliteralShape,\n\tnumberShape,\n\tobjectShape,\n\toptionalShape,\n\trecordShape,\n\tstringShape,\n\tunionShape,\n} from '@orkestrel/contract'\nimport { messageShape, toolCallShape } from '../shapers.js'\n\n/**\n * Describes a provider request's JSON wire projection.\n *\n * @remarks\n * The wire is strictly narrower than `ProviderRequest`: non-JSON arguments, parameters,\n * or schema members are refused. Execution context stays local; the guard refuses\n * extra members, and the parser drops them.\n */\nexport const providerRequestShape = objectShape({\n\tmessages: arrayShape(messageShape),\n\ttools: optionalShape(\n\t\tarrayShape(\n\t\t\tobjectShape({\n\t\t\t\tname: stringShape(),\n\t\t\t\tdescription: optionalShape(stringShape()),\n\t\t\t\tparameters: optionalShape(recordShape(jsonShape())),\n\t\t\t}),\n\t\t),\n\t),\n\toptions: optionalShape(\n\t\tobjectShape({\n\t\t\tthink: optionalShape(booleanShape()),\n\t\t\tschema: optionalShape(recordShape(jsonShape())),\n\t\t}),\n\t),\n}) satisfies ContractShape\n\n/**\n * Describes a provider result's JSON wire projection.\n *\n * @remarks\n * The wire is strictly narrower than `ProviderResult`: non-JSON call arguments are\n * refused. Execution context stays local; the guard refuses extra members, and the parser drops them.\n */\nexport const providerResultShape = objectShape({\n\tcontent: stringShape(),\n\tthinking: optionalShape(stringShape()),\n\ttools: optionalShape(arrayShape(toolCallShape)),\n\tusage: optionalShape(\n\t\tobjectShape({\n\t\t\tprompt: numberShape(),\n\t\t\tcompletion: numberShape(),\n\t\t\ttotal: numberShape(),\n\t\t}),\n\t),\n\ttruncated: optionalShape(booleanShape()),\n}) satisfies ContractShape\n\n/**\n * Describes the channel-discriminated JSON relay wire projection.\n *\n * @remarks\n * The wire is strictly narrower than `RelayFrame` through its `result` and `partial`\n * fields: non-JSON arguments are refused. Execution context stays local; the guard\n * refuses extra members, and the parser drops them.\n */\nexport const relayFrameShape = unionShape(\n\tobjectShape({ channel: literalShape(['content', 'thinking']), text: stringShape() }),\n\tobjectShape({ channel: literalShape(['result']), result: providerResultShape }),\n\tobjectShape({ channel: literalShape(['abort']), partial: providerResultShape }),\n\tobjectShape({ channel: literalShape(['error']), message: stringShape() }),\n) satisfies ContractShape\n","import { createContract } from '@orkestrel/contract'\nimport { providerRequestShape, providerResultShape, relayFrameShape } from './shapers.js'\n\n/** Validates and projects provider requests at a JSON wire boundary. */\nexport const providerRequestContract = createContract(providerRequestShape)\n\n/** Validates and projects provider results at a JSON wire boundary. */\nexport const providerResultContract = createContract(providerResultShape)\n\n/** Validates and projects channel-discriminated relay frames at a JSON wire boundary. */\nexport const relayFrameContract = createContract(relayFrameShape)\n","import type {\n\tFailureRead,\n\tProviderOptions,\n\tProviderRequest,\n\tProviderResult,\n\tReading,\n\tSystemOneAnswer,\n\tSystemOneQuestion,\n\tSystemOneUsage,\n\tTextRead,\n} from './types.js'\nimport type { JudgeAnswer, JudgeQuestion, JudgeResult, Refusal } from '../types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport type { ToolCall } from '@orkestrel/tool'\nimport { isTokenUsage } from '@orkestrel/budget'\nimport { attempt, boundsOf, isArray, isNumber } from '@orkestrel/contract'\nimport { JudgeError } from './errors.js'\nimport { MAX_ERROR_BODY_LENGTH } from './constants.js'\nimport { sanitizeUsage, sumUsage } from '../helpers.js'\n\n/**\n * Assembles a provider result with only populated optional fields.\n *\n * @param content - The authoritative answer\n * @param thinking - The joined reasoning\n * @param tools - The accumulated calls\n * @param usage - The reported token usage\n * @param truncated - Whether the model stopped at its own limit, or undefined when the wire did not report it\n * @returns The assembled result\n * @example\n * ```ts\n * buildProviderResult('ok', '', [], undefined, undefined) // { content: 'ok' }\n * ```\n */\nexport function buildProviderResult(\n\tcontent: string,\n\tthinking: string,\n\ttools: readonly ToolCall[],\n\tusage: TokenUsage | undefined,\n\ttruncated: boolean | undefined,\n): ProviderResult {\n\treturn {\n\t\tcontent,\n\t\t...(thinking.length === 0 ? {} : { thinking }),\n\t\t...(tools.length === 0 ? {} : { tools }),\n\t\t...(usage === undefined ? {} : { usage }),\n\t\t...(truncated === undefined ? {} : { truncated }),\n\t}\n}\n\n/**\n * Cancels a stream reader and releases its lock, swallowing a cancellation failure so the\n * caller's own outcome stands.\n *\n * @param reader - The reader to cancel and release\n * @returns A promise that settles after the lock is released\n *\n * @example\n * ```ts\n * const body = new Response('answer').body\n * if (body !== null) await releaseReader(body.getReader())\n * ```\n */\nexport async function releaseReader(\n\treader: ReadableStreamDefaultReader<Uint8Array>,\n): Promise<void> {\n\ttry {\n\t\tawait reader.cancel()\n\t} catch {\n\t\t// Preserve the caller's outcome when the source refuses cancellation.\n\t} finally {\n\t\treader.releaseLock()\n\t}\n}\n\n/**\n * Arms signal propagation to a byte reader and returns the controller that removes the listener.\n *\n * @param reader - The reader whose pending read an abort releases\n * @param signal - The optional caller signal\n * @returns The listener cleanup controller after any already-aborted cancellation settles\n * @example\n * ```ts\n * const reader = new ReadableStream<Uint8Array>().getReader()\n * const cleanup = await armReaderAbort(reader, new AbortController().signal)\n * cleanup.abort()\n * await releaseReader(reader)\n * ```\n */\nexport async function armReaderAbort(\n\treader: ReadableStreamDefaultReader<Uint8Array>,\n\tsignal: AbortSignal | undefined,\n): Promise<AbortController> {\n\tconst cleanup = new AbortController()\n\tsignal?.addEventListener(\n\t\t'abort',\n\t\t() => {\n\t\t\tvoid reader.cancel(signal.reason).catch(() => {\n\t\t\t\t// Preserve the caller's outcome when source cancellation rejects.\n\t\t\t})\n\t\t},\n\t\t{ once: true, signal: cleanup.signal },\n\t)\n\tif (signal?.aborted) {\n\t\tawait reader.cancel(signal.reason).catch(() => {\n\t\t\t// An already-aborted read retains the same cancellation contract.\n\t\t})\n\t\tcleanup.abort()\n\t}\n\treturn cleanup\n}\n\n/**\n * Reads a bounded HTTP failure excerpt and preserves an unreadable body's cause.\n *\n * @remarks\n * Both HTTP engines, the provider and the judge, translate a non-OK response here and throw\n * their own coded error from the result. When the excerpt is read and `signal` has aborted, the\n * abort is the call's outcome, so the signal's reason is thrown. When the body read fails, the\n * failure is returned as `cause` whether or not `signal` has aborted, so a read that raced the\n * abort stays recorded on the error the caller throws.\n *\n * @param response - The failed HTTP response\n * @param prefix - The error taxonomy prefix, including its trailing colon\n * @param signal - The call's combined caller and deadline signal\n * @returns The status message with any excerpt, the response status, and any body-read failure\n * @throws Thrown when the excerpt is read after `signal` aborts, with the signal's reason\n * @example\n * ```ts\n * await readFailure(new Response('unavailable', { status: 503 }), 'provider error:', new AbortController().signal)\n * // { message: 'provider error: 503 - unavailable', status: 503 }\n * ```\n */\nexport async function readFailure(\n\tresponse: Response,\n\tprefix: string,\n\tsignal: AbortSignal,\n): Promise<FailureRead> {\n\tconst status = response.status\n\tconst body = response.body\n\tif (body === null) {\n\t\tsignal.throwIfAborted()\n\t\treturn { message: `${prefix} ${status}`, status }\n\t}\n\treturn readText(body, MAX_ERROR_BODY_LENGTH, signal).then(\n\t\t(read) => {\n\t\t\tsignal.throwIfAborted()\n\t\t\treturn { message: `${prefix} ${status}${read.text === '' ? '' : ` - ${read.text}`}`, status }\n\t\t},\n\t\t(cause: unknown) => ({\n\t\t\tmessage: `${prefix} ${status} - (error body unavailable)`,\n\t\t\tstatus,\n\t\t\t...(cause === undefined ? {} : { cause }),\n\t\t}),\n\t)\n}\n\n/**\n * Reads a UTF-8 prefix of a byte stream and cancels its remainder.\n *\n * @remarks\n * The `limit` parameter bounds bytes passed to the decoder, including a partial final\n * character. An omitted limit reads to completion. A source may deliver a chunk larger\n * than the remaining limit; its unused bytes are discarded without decoding.\n * The read can overshoot by one source chunk. An abort leaves completion false.\n *\n * @param body - The readable byte stream\n * @param limit - The maximum byte prefix, or undefined for the complete stream\n * @param signal - The optional cancellation bound; abort returns the decoded prefix\n * @returns The decoded prefix and whether EOF occurred within the byte budget\n * @example\n * ```ts\n * import { readText } from '@orkestrel/agent'\n *\n * const body = new Response('answer').body\n * if (body !== null) await readText(body, 3) // { text: 'ans', complete: false }\n * ```\n */\nexport async function readText(\n\tbody: ReadableStream<Uint8Array>,\n\tlimit?: number,\n\tsignal?: AbortSignal,\n): Promise<TextRead> {\n\tconst reader = body.getReader()\n\tconst decoder = new TextDecoder()\n\ttry {\n\t\tconst cleanup = await armReaderAbort(reader, signal)\n\t\ttry {\n\t\t\t// Each step's decoded text and the byte budget left after it: the next read's budget is the\n\t\t\t// latest step's, and the text joins every step.\n\t\t\tconst steps: Array<{ readonly text: string; readonly remaining: number }> = []\n\t\t\tfor (;;) {\n\t\t\t\tconst remaining = steps.at(-1)?.remaining ?? limit ?? Infinity\n\t\t\t\tconst step = remaining > 0 && signal?.aborted !== true ? await reader.read() : undefined\n\t\t\t\tif (step === undefined || signal?.aborted === true || step.done) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttext: steps.map((one) => one.text).join('') + decoder.decode(),\n\t\t\t\t\t\tcomplete: step?.done === true && signal?.aborted !== true,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst bytes = step.value.subarray(0, remaining)\n\t\t\t\tsteps.push({\n\t\t\t\t\ttext: decoder.decode(bytes, { stream: true }),\n\t\t\t\t\tremaining: remaining - bytes.byteLength,\n\t\t\t\t})\n\t\t\t}\n\t\t} finally {\n\t\t\tcleanup.abort()\n\t\t}\n\t} finally {\n\t\tawait releaseReader(reader)\n\t}\n}\n\n/**\n * Decodes UTF-8 chunks with a final flush and releases the stream on every exit.\n *\n * @param body - The readable byte stream\n * @param signal - The optional cancellation bound; abort ends iteration without further chunks\n * @returns Decoded text chunks, including a held decoder tail\n * @example\n * ```ts\n * const body = new Response('answer').body\n * if (body !== null) for await (const chunk of readChunks(body)) render(chunk)\n * ```\n */\nexport async function* readChunks(\n\tbody: ReadableStream<Uint8Array>,\n\tsignal?: AbortSignal,\n): AsyncGenerator<string> {\n\tconst reader = body.getReader()\n\tconst decoder = new TextDecoder()\n\ttry {\n\t\tconst cleanup = await armReaderAbort(reader, signal)\n\t\ttry {\n\t\t\tif (signal?.aborted) return\n\t\t\tfor (;;) {\n\t\t\t\tconst step = await reader.read()\n\t\t\t\tif (signal?.aborted) return\n\t\t\t\tif (step.done) break\n\t\t\t\tconst chunk = decoder.decode(step.value, { stream: true })\n\t\t\t\tif (chunk.length > 0) yield chunk\n\t\t\t}\n\t\t\tconst tail = decoder.decode()\n\t\t\tif (tail.length > 0) yield tail\n\t\t} finally {\n\t\t\tcleanup.abort()\n\t\t}\n\t} finally {\n\t\tawait releaseReader(reader)\n\t}\n}\n\n/**\n * Derives the winner, its probability, the published confidence, and a score answer's expected\n * level from a judge answer's distribution.\n *\n * @remarks\n * The winner is the first strictly greatest candidate in enumeration order: an option name in\n * criteria order, a level index, or `'false'` then `'true'` for a noul, so a noul of exactly 0.5\n * names `'false'`. Confidence follows the TypeSafe formulas, whatever confidence a server sent: a\n * choice reads `(max(p) - 1/n) / (1 - 1/n)`, a noul reads `|2p - 1|` (the choice formula at\n * n = 2), and a score reads `max(0, 1 - spread / even_spread)`, where `spread` sums each level's\n * probability times its distance from the winning level and `even_spread` is the mean distance\n * from the middle level. `score` is the expected level `sum(i * p_i)` and is set only for a score\n * answer.\n *\n * @param answer - The answer whose distribution is read\n * @returns The derived measures\n * @throws JudgeError Thrown when a choice or score answer has fewer than 2 candidates\n * (code `PROTOCOL`), because the confidence formulas divide by the candidate count\n * @example\n * ```ts\n * computeReading({ form: 'choice', probabilities: { billing: 0.88, technical: 0.12, sales: 0 } })\n * // { winner: 'billing', probability: 0.88, confidence: 0.82 } to 2 decimals\n * computeReading({ form: 'score', probabilities: [0, 0.57, 0.43] })\n * // { winner: '1', probability: 0.57, confidence: 0.355, score: 1.43 } to 3 decimals\n * computeReading({ form: 'noul', noul: 0.5 }) // { winner: 'false', probability: 0.5, confidence: 0 }\n * ```\n */\nexport function computeReading(answer: JudgeAnswer): Reading {\n\tif (answer.form === 'noul') {\n\t\tconst yes = answer.noul > 0.5\n\t\treturn {\n\t\t\twinner: yes ? 'true' : 'false',\n\t\t\tprobability: yes ? answer.noul : 1 - answer.noul,\n\t\t\tconfidence: Math.abs(2 * answer.noul - 1),\n\t\t}\n\t}\n\tconst candidates: ReadonlyArray<readonly [string, number]> =\n\t\tanswer.form === 'choice'\n\t\t\t? Object.entries(answer.probabilities)\n\t\t\t: answer.probabilities.map((probability, level) => [String(level), probability])\n\tconst count = candidates.length\n\tif (count < 2) {\n\t\tthrow new JudgeError('PROTOCOL', 'judge error: an answer needs at least 2 candidates')\n\t}\n\t// The first strictly greatest candidate wins a tie. The spread visits a hole in a score\n\t// distribution as an undefined candidate, which the destructuring refuses; `reduce` skips it.\n\tconst { winner, index, probability } = [...candidates].reduce(\n\t\t(top, [name, candidate], position) =>\n\t\t\tcandidate > top.probability ? { winner: name, index: position, probability: candidate } : top,\n\t\t{ winner: '', index: 0, probability: -Infinity },\n\t)\n\tif (answer.form === 'choice') {\n\t\treturn { winner, probability, confidence: (probability - 1 / count) / (1 - 1 / count) }\n\t}\n\tconst spread = answer.probabilities.reduce(\n\t\t(sum, candidate, level) => sum + candidate * Math.abs(level - index),\n\t\t0,\n\t)\n\tconst even = answer.probabilities.reduce(\n\t\t(sum, _candidate, level) => sum + Math.abs(level - (count - 1) / 2),\n\t\t0,\n\t)\n\tconst score = answer.probabilities.reduce((sum, candidate, level) => sum + level * candidate, 0)\n\treturn { winner, probability, confidence: Math.max(0, 1 - spread / (even / count)), score }\n}\n\n/**\n * Merges the results of a judge request's calls into one result.\n *\n * @remarks\n * Pure and total. Answers and refusals are joined by question id; `refusals` is omitted when no\n * call refused a question. Each call's usage passes through {@link sanitizeUsage} and the totals\n * add through {@link sumUsage}; `usage` is omitted when no call reported one. The model is the\n * first call's, or the given model when the list is empty, as the empty partial of a cancel\n * before the first call requires.\n *\n * @param model - The judge's configured model, reported when no call completed\n * @param results - The completed calls' results in call order\n * @returns The merged result\n * @example\n * ```ts\n * buildJudgeResult('tev1:0.8b', []) // { model: 'tev1:0.8b', answers: {} }\n * buildJudgeResult('jev-latest', [\n * \t{ model: 'jev-1.13.0', answers: { urgent: { form: 'noul', noul: 0.95 } } },\n * \t{ model: 'jev-1.13.0', answers: {}, refusals: { team: { missing: ['sales'] } } },\n * ])\n * // { model: 'jev-1.13.0', answers: { urgent: ... }, refusals: { team: { missing: ['sales'] } } }\n * ```\n */\nexport function buildJudgeResult(model: string, results: readonly JudgeResult[]): JudgeResult {\n\t// The spread visits a hole in `results` as an undefined result, as iteration does; `reduce` skips it.\n\tconst calls = [...results]\n\tconst answers = calls.reduce<Readonly<Record<string, JudgeAnswer>>>(\n\t\t(merged, result) => ({ ...merged, ...result.answers }),\n\t\t{},\n\t)\n\tconst refusals = calls.reduce<Readonly<Record<string, Refusal>>>(\n\t\t(merged, result) => ({ ...merged, ...result.refusals }),\n\t\t{},\n\t)\n\tconst usage = calls.reduce<TokenUsage | undefined>(\n\t\t(total, result) =>\n\t\t\tresult.usage === undefined ? total : sumUsage(total, sanitizeUsage(result.usage)),\n\t\tundefined,\n\t)\n\treturn {\n\t\tmodel: results[0]?.model ?? model,\n\t\tanswers,\n\t\t...(Object.keys(refusals).length === 0 ? {} : { refusals }),\n\t\t...(usage === undefined ? {} : { usage }),\n\t}\n}\n\n/**\n * Builds a request's JSON headers, awaiting the caller's header hook inside the call's\n * cancellation bound.\n *\n * @remarks\n * The headers start with `Content-Type: application/json`; each entry the hook returns is set\n * over them, so the hook overrides the content type only when it returns that header. The hook\n * receives `signal` and races its abort, and the abort listener is removed on every exit. Both\n * HTTP engines, the provider and the judge, read their headers here.\n *\n * @param hook - The caller's header hook, or undefined for the JSON content type alone\n * @param signal - The call's combined caller and deadline signal\n * @returns The request headers\n * @throws Thrown when the signal aborts before the hook settles, with the signal's reason, and\n * when the hook throws or rejects, with the hook's own failure\n * @example\n * ```ts\n * const signal = new AbortController().signal\n * // API_KEY stands for the server's bearer key.\n * const headers = await buildProviderHeaders(() => ({ authorization: 'Bearer API_KEY' }), signal)\n * headers.get('authorization') // 'Bearer API_KEY'\n * headers.get('content-type') // 'application/json'\n * ```\n */\nexport async function buildProviderHeaders(\n\thook: ProviderOptions['headers'],\n\tsignal: AbortSignal,\n): Promise<Headers> {\n\tconst headers = new Headers({ 'Content-Type': 'application/json' })\n\tif (hook === undefined) return headers\n\tconst cleanup = new AbortController()\n\tconst aborted = Promise.withResolvers<never>()\n\tsignal.addEventListener('abort', () => aborted.reject(signal.reason), {\n\t\tonce: true,\n\t\tsignal: cleanup.signal,\n\t})\n\ttry {\n\t\tsignal.throwIfAborted()\n\t\tconst entries = await Promise.race([\n\t\t\tPromise.resolve().then(() => hook(signal)),\n\t\t\taborted.promise,\n\t\t])\n\t\tfor (const [key, value] of Object.entries(entries)) headers.set(key, value)\n\t\treturn headers\n\t} finally {\n\t\tcleanup.abort()\n\t}\n}\n\n/**\n * Projects a provider request onto the declared members the relay wire carries.\n *\n * @remarks\n * Each message keeps `id`, `role`, `content`, and any `calls`, `call`, `images`, and `thinking`;\n * each call keeps only `id`, `name`, and `arguments`, so a local execution context never reaches\n * the wire. Each tool keeps `name` and any `description` and `parameters`, and the options keep\n * any `think` and `schema`. An absent member stays absent. The projection shares every nested\n * value with the input rather than copying it, so the caller snapshots and validates the result;\n * a throwing getter propagates its failure.\n *\n * @param request - The domain conversation and call configuration\n * @returns The request with only the members the relay wire declares\n * @example\n * ```ts\n * requestToRelay({\n * \tmessages: [{ id: 'turn-1', role: 'user', content: 'Track BW-5512' }],\n * \toptions: { think: false },\n * })\n * // { messages: [{ id: 'turn-1', role: 'user', content: 'Track BW-5512' }], options: { think: false } }\n * ```\n */\nexport function requestToRelay(request: ProviderRequest): ProviderRequest {\n\treturn {\n\t\tmessages: request.messages.map((message) => ({\n\t\t\tid: message.id,\n\t\t\trole: message.role,\n\t\t\tcontent: message.content,\n\t\t\t...(message.calls === undefined\n\t\t\t\t? {}\n\t\t\t\t: {\n\t\t\t\t\t\tcalls: message.calls.map((call) => ({\n\t\t\t\t\t\t\tid: call.id,\n\t\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\t\targuments: call.arguments,\n\t\t\t\t\t\t})),\n\t\t\t\t\t}),\n\t\t\t...(message.call === undefined ? {} : { call: message.call }),\n\t\t\t...(message.images === undefined ? {} : { images: message.images }),\n\t\t\t...(message.thinking === undefined ? {} : { thinking: message.thinking }),\n\t\t})),\n\t\t...(request.tools === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\ttools: request.tools.map((tool) => ({\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\t...(tool.description === undefined ? {} : { description: tool.description }),\n\t\t\t\t\t\t...(tool.parameters === undefined ? {} : { parameters: tool.parameters }),\n\t\t\t\t\t})),\n\t\t\t\t}),\n\t\t...(request.options === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\toptions: {\n\t\t\t\t\t\t...(request.options.think === undefined ? {} : { think: request.options.think }),\n\t\t\t\t\t\t...(request.options.schema === undefined ? {} : { schema: request.options.schema }),\n\t\t\t\t\t},\n\t\t\t\t}),\n\t}\n}\n\n/**\n * Projects a judge question onto the System One wire while preserving omitted members.\n *\n * @param question - The domain question to send\n * @returns The wire question with `type` replacing `form`\n * @example\n * ```ts\n * questionToSystemOne({ form: 'noul' }) // { type: 'noul' }\n * ```\n */\nexport function questionToSystemOne(question: JudgeQuestion): SystemOneQuestion {\n\treturn {\n\t\ttype: question.form,\n\t\t...(question.instructions === undefined ? {} : { instructions: question.instructions }),\n\t\t...(question.criteria === undefined ? {} : { criteria: question.criteria }),\n\t}\n}\n\n/**\n * Extracts a System One distribution in question criteria order and drops server measures.\n *\n * @remarks\n * Every requested candidate must have a finite probability in [0, 1]; the helper checks each\n * requested candidate itself and reads no other member. Score maps and arrays project onto the\n * requested levels. Additional candidates are ignored, sums are unconstrained, and probabilities\n * are preserved without normalization.\n *\n * @param answer - The wire answer to decode\n * @param question - The question defining the form and candidate order\n * @returns The domain answer, or undefined for a mismatched form or a requested candidate whose\n * probability is missing, not finite, or outside [0, 1]\n * @example\n * ```ts\n * extractSystemOneAnswer({ type: 'noul', noul: 0.9 }, { form: 'noul' })\n * // { form: 'noul', noul: 0.9 }\n * ```\n */\nexport function extractSystemOneAnswer(\n\tanswer: SystemOneAnswer,\n\tquestion: JudgeQuestion,\n): JudgeAnswer | undefined {\n\tconst bounded = boundsOf(0, 1)\n\tif (answer.type === 'noul' && question.form === 'noul') {\n\t\treturn bounded(answer.noul) ? { form: 'noul', noul: answer.noul } : undefined\n\t}\n\tif (answer.type === 'choice' && question.form === 'choice') {\n\t\tconst labels = Object.keys(question.criteria)\n\t\tconst entries = labels.flatMap((label) => {\n\t\t\tconst probability = Object.hasOwn(answer.probabilities, label)\n\t\t\t\t? answer.probabilities[label]\n\t\t\t\t: undefined\n\t\t\treturn bounded(probability) ? [[label, probability] as const] : []\n\t\t})\n\t\treturn entries.length === labels.length\n\t\t\t? { form: 'choice', probabilities: Object.fromEntries(entries) }\n\t\t\t: undefined\n\t}\n\tif (answer.type !== 'score' || question.form !== 'score') return undefined\n\t// `keys()` visits a hole in the criteria list too, so a hole is a requested level.\n\tconst levels = [...question.criteria.keys()]\n\tconst probabilities = levels.flatMap((level) => {\n\t\tconst probability = Object.hasOwn(answer.probabilities, level)\n\t\t\t? isArray(answer.probabilities)\n\t\t\t\t? answer.probabilities[level]\n\t\t\t\t: answer.probabilities[String(level)]\n\t\t\t: undefined\n\t\treturn bounded(probability) ? [probability] : []\n\t})\n\treturn probabilities.length === levels.length ? { form: 'score', probabilities } : undefined\n}\n\n/**\n * Maps complete System One token counts onto validated token usage.\n *\n * @param usage - The optional wire token counts\n * @returns Token usage, or undefined for missing, null, negative, or non-finite counts\n * @example\n * ```ts\n * extractSystemOneUsage({ input_tokens: 975, output_tokens: 4 })\n * // { prompt: 975, completion: 4, total: 979 }\n * ```\n */\nexport function extractSystemOneUsage(usage: SystemOneUsage | undefined): TokenUsage | undefined {\n\tconst extracted = attempt(() => {\n\t\tif (usage === undefined) return undefined\n\t\tconst { input_tokens: prompt, output_tokens: completion } = usage\n\t\tif (!isNumber(prompt) || !isNumber(completion)) return undefined\n\t\tconst result = { prompt, completion, total: prompt + completion }\n\t\treturn isTokenUsage(result) ? result : undefined\n\t})\n\treturn extracted.success ? extracted.value : undefined\n}\n","import type { ProviderDelta, ProviderResult, RelayFrame, RelayStreamOptions } from './types.js'\nimport type { ThinkingReplay } from '../types.js'\nimport { RELAY_CONTENT_TYPE, RELAY_PROVIDER_MESSAGE } from './constants.js'\nimport { ProviderError, isProviderAbortError } from './errors.js'\nimport { relayFrameContract } from './contracts.js'\nimport { stripThinking } from '../helpers.js'\n\n/**\n * Streams a provider call as validated NDJSON frames under response backpressure.\n *\n * @remarks\n * Cancellation aborts upstream before returning its iterator. Request listeners are\n * released on settlement. Unexpected provider failures carry a fixed public message.\n * An inbound abort leaves the response body neither closed nor errored — a server runtime\n * cancels that body when the client disconnects — so a consumer that aborts the inbound\n * signal itself must cancel the body rather than keep reading it.\n *\n * @example\n * ```ts\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { RelayStream } from '@orkestrel/agent'\n *\n * export function respond(provider: ProviderInterface, signal: AbortSignal): Response {\n * \treturn new RelayStream({ provider, request: { messages: [] }, signal }).response\n * }\n * ```\n */\nexport class RelayStream {\n\treadonly #replay: ThinkingReplay\n\treadonly #upstream = new AbortController()\n\treadonly #encoder = new TextEncoder()\n\treadonly #iterator: AsyncGenerator<ProviderDelta, ProviderResult>\n\treadonly #signal: AbortSignal\n\treadonly #listener: () => void\n\treadonly #response: Response\n\t#settled = false\n\n\tconstructor(options: RelayStreamOptions) {\n\t\tthis.#replay = options.provider.replay ?? 'none'\n\t\tthis.#signal = options.signal\n\t\tthis.#listener = this.#abort.bind(this)\n\t\tif (this.#signal.aborted) this.#abortProvider()\n\t\tthis.#iterator = options.provider.stream(\n\t\t\tstripThinking(options.request.messages, this.#replay),\n\t\t\tthis.#upstream.signal,\n\t\t\toptions.request.tools,\n\t\t\toptions.request.options,\n\t\t)\n\t\tthis.#signal.addEventListener('abort', this.#listener, { once: true })\n\t\tthis.#response = new Response(\n\t\t\tnew ReadableStream<Uint8Array>({\n\t\t\t\tpull: this.#pull.bind(this),\n\t\t\t\tcancel: this.#abort.bind(this),\n\t\t\t}),\n\t\t\t{ headers: { 'content-type': RELAY_CONTENT_TYPE, 'cache-control': 'no-store' } },\n\t\t)\n\t}\n\n\t/** Exposes the pull-driven response for the provider call. */\n\tget response(): Response {\n\t\treturn this.#response\n\t}\n\n\tasync #pull(controller: ReadableStreamDefaultController<Uint8Array>): Promise<void> {\n\t\tif (this.#settled) return\n\t\ttry {\n\t\t\tconst step = await this.#iterator.next()\n\t\t\tif (this.#settled) return\n\t\t\tthis.#write(controller, step.done ? { channel: 'result', result: step.value } : step.value)\n\t\t\tif (step.done) this.#finish(controller)\n\t\t} catch (error) {\n\t\t\tif (this.#settled) return\n\t\t\tconst frame: RelayFrame = isProviderAbortError(error)\n\t\t\t\t? { channel: 'abort', partial: error.partial }\n\t\t\t\t: { channel: 'error', message: RELAY_PROVIDER_MESSAGE }\n\t\t\tthis.#write(\n\t\t\t\tcontroller,\n\t\t\t\trelayFrameContract.is(frame)\n\t\t\t\t\t? frame\n\t\t\t\t\t: { channel: 'error', message: RELAY_PROVIDER_MESSAGE },\n\t\t\t)\n\t\t\tthis.#finish(controller)\n\t\t\tthis.#abortProvider()\n\t\t\tawait this.#return()\n\t\t}\n\t}\n\n\tasync #abort(): Promise<void> {\n\t\tif (this.#settled) return\n\t\tthis.#settled = true\n\t\tthis.#abortProvider()\n\t\ttry {\n\t\t\tawait this.#return()\n\t\t} finally {\n\t\t\tthis.#release()\n\t\t}\n\t}\n\n\tasync #return(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.#iterator.return({ content: '' })\n\t\t} catch {\n\t\t\t// A settled response has no error channel for upstream cleanup failures.\n\t\t}\n\t}\n\n\t#write(controller: ReadableStreamDefaultController<Uint8Array>, frame: RelayFrame): void {\n\t\tif (!relayFrameContract.is(frame)) throw new ProviderError('PROTOCOL', 'invalid relay frame')\n\t\tcontroller.enqueue(this.#encoder.encode(`${JSON.stringify(frame)}\\n`))\n\t}\n\n\t#finish(controller: ReadableStreamDefaultController<Uint8Array>): void {\n\t\tthis.#settled = true\n\t\tthis.#release()\n\t\tcontroller.close()\n\t}\n\n\t#abortProvider(): void {\n\t\tthis.#upstream.abort(this.#signal.reason)\n\t}\n\n\t#release(): void {\n\t\tthis.#signal.removeEventListener('abort', this.#listener)\n\t}\n}\n","import type { ThinkSplitterInterface } from './types.js'\nimport { THINK_CLOSE, THINK_OPEN } from './constants.js'\n\n/**\n * Separates `<think>…</think>` spans from raw content deltas with per-stream state: text inside a\n * span accumulates on `thinking`, and text outside it returns as clean content, so a provider\n * yields the answer alone and surfaces the reasoning as\n * {@link import('./types.js').ProviderResult.thinking}. A tag split across deltas is held until\n * disambiguated, `flush()` settles the stream end, and one splitter serves one stream.\n *\n * @remarks\n * - **Cross-chunk tags.** A tag may arrive split across wire deltas (`'<thi'` then\n * `'nk>'`): any suffix of the pending text that is a strict prefix of a tag being\n * scanned for is held back (neither surfaced nor routed) until the next delta — or\n * `flush()` — disambiguates it. A held tag prefix that never completes is real\n * content; a held close-tag prefix inside a span is thinking.\n * - **The implicit leading open (the qwen3-template shape).** Some chat templates\n * pre-seed `<think>` into the prompt scaffold, so the wire stream begins\n * mid-reasoning and only a bare `</think>` appears. Before any tag event, a bare\n * close therefore reclassifies everything surfaced so far (plus the pre-close\n * pending) as thinking — `content` is corrected retroactively (the already-returned\n * prefix cannot be recalled, so `content` is the authoritative accumulation). The\n * rule is one-shot: after any tag event a bare `</think>` is plain text.\n * - **Multiple spans** accumulate onto `thinking` in stream order. A nested-looking\n * `<think>` inside an open span is thinking text (no nesting is tracked — the\n * first `</think>` closes the span), matching how the models emit it.\n * - **Unclosed span at stream end.** `flush()` routes the open span's tail (including\n * any held partial close tag) to `thinking` — a cut-off model was still reasoning.\n * - **One splitter, one stream.** State is per-stream; create a fresh instance per\n * provider call ({@link import('./factories.js').createThinkSplitter}).\n *\n * @example\n * ```ts\n * const splitter = new ThinkSplitter()\n * splitter.split('<thi') // '' (held — ambiguous)\n * splitter.split('nk>plan</think>ok') // 'ok'\n * splitter.thinking // 'plan'\n * splitter.content // 'ok'\n * splitter.flush() // '' (nothing held)\n * ```\n */\nexport class ThinkSplitter implements ThinkSplitterInterface {\n\t// The undecided tail of the stream — text not yet routed to content or thinking\n\t// (at most one partial tag's worth between calls; transiently the whole delta).\n\t#pending = ''\n\t// Whether the scanner is inside an open `<think>` span.\n\t#inside = false\n\t// Whether a tag event has occurred (an explicit open, or the one-shot implicit-open\n\t// close) — before it, a bare `</think>` closes the implicit span a chat template\n\t// pre-seeded; after it, a bare close is plain text.\n\t#opened = false\n\t#content = ''\n\t#thinking = ''\n\n\tget content(): string {\n\t\treturn this.#content\n\t}\n\n\tget thinking(): string {\n\t\treturn this.#thinking\n\t}\n\n\tsplit(delta: string): string {\n\t\tconst out = this.#scan(delta)\n\t\tthis.#content += out\n\t\treturn out\n\t}\n\n\tflush(): string {\n\t\tconst pending = this.#pending\n\t\tthis.#pending = ''\n\t\tif (this.#inside) {\n\t\t\t// An unclosed span at stream end — the tail (held partial close tag included)\n\t\t\t// is thinking: the model was cut off mid-reasoning, never mid-answer.\n\t\t\tthis.#thinking += pending\n\t\t\tthis.#inside = false\n\t\t\treturn ''\n\t\t}\n\t\t// A held partial tag that never completed was real content after all.\n\t\tthis.#content += pending\n\t\treturn pending\n\t}\n\n\t// Drive the state machine over one delta, returning the clean content it surfaces —\n\t// the wrapper folds the return into `#content`, which the implicit-open branch may\n\t// have reset a moment earlier (the reclassification).\n\t#scan(delta: string): string {\n\t\tthis.#pending += delta\n\t\treturn [...this.#surface()].join('')\n\t}\n\n\t// Walk the pending text, yielding each clean content piece in order and routing reasoning to\n\t// `#thinking`; return once the remainder is undecided and held for the next delta. A piece is\n\t// yielded only after `#opened` is set, so the reclassification below never meets one.\n\t*#surface(): Generator<string, void> {\n\t\tfor (;;) {\n\t\t\tif (this.#inside) {\n\t\t\t\tconst close = this.#pending.indexOf(THINK_CLOSE)\n\t\t\t\tif (close === -1) {\n\t\t\t\t\t// No close yet — route all but a possible partial close-tag suffix to\n\t\t\t\t\t// thinking, holding that suffix for the next delta to disambiguate.\n\t\t\t\t\tthis.#thinking += this.#hold([THINK_CLOSE])\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.#thinking += this.#pending.slice(0, close)\n\t\t\t\tthis.#pending = this.#pending.slice(close + THINK_CLOSE.length)\n\t\t\t\tthis.#inside = false\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst open = this.#pending.indexOf(THINK_OPEN)\n\t\t\tif (!this.#opened) {\n\t\t\t\t// The implicit leading open: before any tag event, a bare close (arriving\n\t\t\t\t// ahead of any explicit open) means the stream began inside a pre-seeded\n\t\t\t\t// span — everything surfaced so far was reasoning. Reclassify it.\n\t\t\t\tconst close = this.#pending.indexOf(THINK_CLOSE)\n\t\t\t\tif (close !== -1 && (open === -1 || close < open)) {\n\t\t\t\t\tthis.#thinking += this.#content + this.#pending.slice(0, close)\n\t\t\t\t\tthis.#content = ''\n\t\t\t\t\tthis.#pending = this.#pending.slice(close + THINK_CLOSE.length)\n\t\t\t\t\tthis.#opened = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (open === -1) {\n\t\t\t\t// No open tag — surface all but a possible partial tag suffix as content\n\t\t\t\t// (before any tag event a split leading close must not leak either, so the\n\t\t\t\t// close tag's prefixes are held back too).\n\t\t\t\tconst tags = this.#opened ? [THINK_OPEN] : [THINK_OPEN, THINK_CLOSE]\n\t\t\t\tyield this.#hold(tags)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.#opened = true\n\t\t\tyield this.#pending.slice(0, open)\n\t\t\tthis.#pending = this.#pending.slice(open + THINK_OPEN.length)\n\t\t\tthis.#inside = true\n\t\t}\n\t}\n\n\t// Settle the pending text against the given tags' possible partial suffixes: the\n\t// longest ambiguous suffix stays pending for the next delta; everything before it\n\t// is returned for routing.\n\t#hold(tags: readonly string[]): string {\n\t\tconst keep = Math.max(...tags.map((tag) => this.#overlap(tag)))\n\t\tconst cut = this.#pending.length - keep\n\t\tconst settled = this.#pending.slice(0, cut)\n\t\tthis.#pending = this.#pending.slice(cut)\n\t\treturn settled\n\t}\n\n\t// The length of the longest strict prefix of `tag` that suffixes the pending text —\n\t// how many trailing characters are an ambiguous partial tag and must be held back.\n\t#overlap(tag: string): number {\n\t\tconst max = Math.min(this.#pending.length, tag.length - 1)\n\t\treturn (\n\t\t\tArray.from({ length: max }, (_, index) => max - index).find((length) =>\n\t\t\t\tthis.#pending.endsWith(tag.slice(0, length)),\n\t\t\t) ?? 0\n\t\t)\n\t}\n}\n","import type {\n\tAgentProviderInput,\n\tAgentProviderInterface,\n\tProviderDelta,\n\tProviderIncrement,\n\tProviderOptions,\n\tProviderParserInterface,\n\tProviderRequest,\n\tProviderResult,\n\tProviderStreamOptions,\n\tThinkSplitterInterface,\n} from './types.js'\nimport type { Message, ThinkingReplay } from '../types.js'\nimport type { ToolDefinition } from '@orkestrel/tool'\nimport { Timeout } from '@orkestrel/timeout'\nimport { DEFAULT_PROVIDER_TIMEOUT } from './constants.js'\nimport { ProviderAbortError, ProviderError } from './errors.js'\nimport { ThinkSplitter } from './ThinkSplitter.js'\nimport { buildProviderResult, readChunks, buildProviderHeaders, readFailure } from './helpers.js'\nimport { joinThinking } from '../helpers.js'\n\n/**\n * Implements bounded HTTP streaming and result assembly behind concrete wire seams.\n *\n * @remarks\n * Every call owns its parser, splitter, deadline, and accumulation. Success bodies\n * have no size limit. A qwen3 implicit-open reclassification corrects the final\n * content while content deltas already yielded cannot be recalled. A subclass fills\n * `name`, `frame`, `encode`, `read`, and `finish`; the constructor takes the `split`\n * and `strict` switches to control reasoning separation and settled-result requirements.\n * The `replay` input names which stored thinking the agent and relay send back. Default: `'none'`.\n *\n * @example Writing a provider for a new wire\n * ```ts\n * import type {\n * \tProviderIncrement,\n * \tProviderOptions,\n * \tProviderParserInterface,\n * \tProviderRequest,\n * } from '@orkestrel/agent'\n * import { AgentProvider } from '@orkestrel/agent'\n *\n * class TextFrame implements ProviderParserInterface<string> {\n * \tparse(chunk: string): readonly string[] {\n * \t\treturn [chunk]\n * \t}\n * \tclear(): void {} // Raw text retains no framing state.\n * }\n *\n * interface TextOptions extends ProviderOptions {\n * \treadonly url: string\n * }\n *\n * class TextProvider extends AgentProvider<string> {\n * \treadonly name = 'text'\n * \tconstructor(options: TextOptions) {\n * \t\tsuper({ ...options, path: '/generate' })\n * \t}\n * \tframe(): ProviderParserInterface<string> {\n * \t\treturn new TextFrame()\n * \t}\n * \tencode(request: ProviderRequest): object {\n * \t\treturn { messages: request.messages }\n * \t}\n * \tread(record: string): ProviderIncrement {\n * \t\treturn { content: record, thinking: '', tools: [] }\n * \t}\n * \tfinish(_parser: ProviderParserInterface<string>): readonly string[] {\n * \t\treturn [] // Raw text retains no records at end of input.\n * \t}\n * }\n * ```\n */\nexport abstract class AgentProvider<\n\tTRecord = Readonly<Record<string, unknown>>,\n> implements AgentProviderInterface<TRecord> {\n\treadonly #id: string\n\treadonly #replay: ThinkingReplay\n\treadonly #url: string\n\treadonly #path: string\n\treadonly #timeout: number\n\treadonly #transport: typeof globalThis.fetch\n\treadonly #headers: ProviderOptions['headers']\n\treadonly #split: boolean\n\treadonly #strict: boolean\n\n\tconstructor(input: AgentProviderInput) {\n\t\tthis.#id = crypto.randomUUID()\n\t\tthis.#replay = input.replay ?? 'none'\n\t\tthis.#url = input.url\n\t\tthis.#path = input.path ?? ''\n\t\tthis.#timeout = input.timeout ?? DEFAULT_PROVIDER_TIMEOUT\n\t\tthis.#transport = input.fetch ?? globalThis.fetch.bind(globalThis)\n\t\tthis.#headers = input.headers\n\t\tthis.#split = input.split ?? true\n\t\tthis.#strict = input.strict ?? false\n\t}\n\n\t/** Identifies the concrete backend. */\n\tabstract readonly name: string\n\n\t/** Exposes the instance's minted UUID. */\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\t/** Names which stored assistant thinking the agent and relay send back. */\n\tget replay(): ThinkingReplay {\n\t\treturn this.#replay\n\t}\n\n\t/** Creates fresh framing state for the call. */\n\tabstract frame(): ProviderParserInterface<TRecord>\n\t/** Projects a domain request onto the concrete protocol's wire body. */\n\tabstract encode(request: ProviderRequest): object\n\t/** Decodes a framed record into a turn increment. */\n\tabstract read(record: TRecord): ProviderIncrement\n\t/** Returns any records retained at end of input. */\n\tabstract finish(parser: ProviderParserInterface<TRecord>): readonly TRecord[]\n\n\t/**\n\t * Generates a complete turn by draining the shared stream engine.\n\t *\n\t * @param messages - The conversation turns\n\t * @param signal - The caller's cancellation bound\n\t * @param tools - The advertised tool definitions\n\t * @param options - The per-call generation configuration\n\t * @returns The terminal stream result\n\t */\n\tasync generate(\n\t\tmessages: readonly Message[],\n\t\tsignal: AbortSignal,\n\t\ttools?: readonly ToolDefinition[],\n\t\toptions?: ProviderStreamOptions,\n\t): Promise<ProviderResult> {\n\t\tconst stream = this.stream(messages, signal, tools, options)\n\t\tfor (;;) {\n\t\t\tconst step = await stream.next()\n\t\t\tif (step.done) return step.value\n\t\t}\n\t}\n\n\t/**\n\t * Streams decoded deltas and returns the authoritative or assembled turn result.\n\t *\n\t * @param messages - The conversation turns\n\t * @param signal - The caller's cancellation bound\n\t * @param tools - The advertised tool definitions\n\t * @param options - The per-call generation configuration\n\t * @returns Content and native thinking deltas followed by the settled result\n\t * @throws ProviderAbortError Thrown when the combined cancellation bound fires\n\t * @throws ProviderError Thrown when the response is non-OK, the response has no body, a wire record\n\t * is malformed or carries an upstream failure, or a strict stream ends without a settled result\n\t */\n\tasync *stream(\n\t\tmessages: readonly Message[],\n\t\tsignal: AbortSignal,\n\t\ttools?: readonly ToolDefinition[],\n\t\toptions?: ProviderStreamOptions,\n\t): AsyncGenerator<ProviderDelta, ProviderResult> {\n\t\tif (signal.aborted) throw new ProviderAbortError({ content: '' })\n\t\tconst timeout = new Timeout({ ms: this.#timeout })\n\t\ttimeout.start()\n\t\tconst combined = AbortSignal.any([timeout.signal, signal])\n\t\ttry {\n\t\t\tconst parser = this.#frame(combined)\n\t\t\ttry {\n\t\t\t\treturn yield* this.#read(parser, messages, tools, options, combined)\n\t\t\t} finally {\n\t\t\t\tparser.clear()\n\t\t\t}\n\t\t} finally {\n\t\t\ttimeout.clear()\n\t\t}\n\t}\n\n\t// Creates the call's framing state; a failure that raced the cancel becomes the empty partial.\n\t#frame(combined: AbortSignal): ProviderParserInterface<TRecord> {\n\t\ttry {\n\t\t\treturn this.frame()\n\t\t} catch (error) {\n\t\t\tthrow this.#translate(error, combined, undefined, [])\n\t\t}\n\t}\n\n\t// Requests, frames, folds, and settles one call. Each decoded increment joins a local list\n\t// before its deltas are exposed, so a cancel during a yield assembles from what the body produced.\n\tasync *#read(\n\t\tparser: ProviderParserInterface<TRecord>,\n\t\tmessages: readonly Message[],\n\t\ttools: readonly ToolDefinition[] | undefined,\n\t\toptions: ProviderStreamOptions | undefined,\n\t\tcombined: AbortSignal,\n\t): AsyncGenerator<ProviderDelta, ProviderResult> {\n\t\tconst splitter = this.#split ? new ThinkSplitter() : undefined\n\t\tconst increments: ProviderIncrement[] = []\n\t\ttry {\n\t\t\tconst response = await this.#request(\n\t\t\t\t{\n\t\t\t\t\tmessages,\n\t\t\t\t\t...(tools === undefined ? {} : { tools }),\n\t\t\t\t\t...(options === undefined ? {} : { options }),\n\t\t\t\t},\n\t\t\t\tcombined,\n\t\t\t)\n\t\t\tif (response.body === null) {\n\t\t\t\tthrow new ProviderError('PROTOCOL', 'provider error: no response body')\n\t\t\t}\n\t\t\tfor await (const chunk of readChunks(response.body, combined)) {\n\t\t\t\tcombined.throwIfAborted()\n\t\t\t\tfor (const record of parser.parse(chunk)) {\n\t\t\t\t\tconst increment = this.read(record)\n\t\t\t\t\tincrements.push(increment)\n\t\t\t\t\tif (increment.result === undefined) yield* this.#emit(increment, splitter, combined)\n\t\t\t\t\tcombined.throwIfAborted()\n\t\t\t\t\tif (increment.result !== undefined) return increment.result\n\t\t\t\t}\n\t\t\t}\n\t\t\tcombined.throwIfAborted()\n\t\t\tfor (const record of this.finish(parser)) {\n\t\t\t\tconst increment = this.read(record)\n\t\t\t\tincrements.push(increment)\n\t\t\t\tif (increment.result === undefined) yield* this.#emit(increment, splitter, combined)\n\t\t\t\tcombined.throwIfAborted()\n\t\t\t\tif (increment.result !== undefined) return increment.result\n\t\t\t}\n\t\t\tconst tail = splitter?.flush() ?? ''\n\t\t\tif (tail.length > 0) yield { channel: 'content', text: tail }\n\t\t\tcombined.throwIfAborted()\n\t\t\tif (this.#strict) {\n\t\t\t\tthrow new ProviderError('PROTOCOL', 'provider error: missing settled result')\n\t\t\t}\n\t\t\treturn this.#assemble(splitter, increments)\n\t\t} catch (error) {\n\t\t\tthrow this.#translate(error, combined, splitter, increments)\n\t\t}\n\t}\n\n\t// Surfaces one increment's deltas: the split content, then — unless the call was cancelled in\n\t// between — its native thinking.\n\t*#emit(\n\t\tincrement: ProviderIncrement,\n\t\tsplitter: ThinkSplitterInterface | undefined,\n\t\tsignal: AbortSignal,\n\t): Generator<ProviderDelta> {\n\t\tconst content = splitter?.split(increment.content) ?? increment.content\n\t\tif (content.length > 0) yield { channel: 'content', text: content }\n\t\tsignal.throwIfAborted()\n\t\tif (increment.thinking.length > 0) yield { channel: 'thinking', text: increment.thinking }\n\t}\n\n\t// The error a failed call throws: a cancel becomes a ProviderAbortError carrying the partial\n\t// assembled so far (a throw that raced the cancel is its cause); any other failure is itself.\n\t#translate(\n\t\terror: unknown,\n\t\tcombined: AbortSignal,\n\t\tsplitter: ThinkSplitterInterface | undefined,\n\t\tincrements: readonly ProviderIncrement[],\n\t): unknown {\n\t\tif (!combined.aborted) return error\n\t\tsplitter?.flush()\n\t\treturn new ProviderAbortError(\n\t\t\tthis.#assemble(splitter, increments),\n\t\t\terror === combined.reason ? undefined : { cause: error },\n\t\t)\n\t}\n\n\t// Both exits assemble alike, so an aborted call's partial carries what a settled call would. A\n\t// settled-result increment replaces the fold.\n\t#assemble(\n\t\tsplitter: ThinkSplitterInterface | undefined,\n\t\tincrements: readonly ProviderIncrement[],\n\t): ProviderResult {\n\t\tconst last = increments.at(-1)\n\t\tconst folded = last?.result === undefined ? increments : [last]\n\t\treturn buildProviderResult(\n\t\t\tsplitter?.content ?? folded.map((one) => one.content).join(''),\n\t\t\tjoinThinking(splitter?.thinking, folded.map((one) => one.thinking).join('')),\n\t\t\tfolded.flatMap((one) => [...one.tools]),\n\t\t\tfolded.findLast((one) => one.usage !== undefined)?.usage,\n\t\t\tfolded.findLast((one) => one.truncated !== undefined)?.truncated,\n\t\t)\n\t}\n\n\t// Send one request and translate its HTTP failure into the shared provider taxonomy.\n\tasync #request(request: ProviderRequest, signal: AbortSignal): Promise<Response> {\n\t\tconst headers = await buildProviderHeaders(this.#headers, signal)\n\t\tsignal.throwIfAborted()\n\t\tconst response = await this.#transport(this.#url + this.#path, {\n\t\t\tmethod: 'POST',\n\t\t\theaders,\n\t\t\tbody: JSON.stringify(this.encode(request)),\n\t\t\tsignal,\n\t\t})\n\t\tif (!response.ok) {\n\t\t\tconst { message, ...options } = await readFailure(response, 'provider error:', signal)\n\t\t\tthrow new ProviderError('HTTP', message, options)\n\t\t}\n\t\treturn response\n\t}\n}\n","import type {\n\tProviderIncrement,\n\tProviderParserInterface,\n\tProviderRequest,\n\tRelayProviderOptions,\n} from './types.js'\nimport { attempt, cloneJSONValue } from '@orkestrel/contract'\nimport { AgentProvider } from './AgentProvider.js'\nimport { ProviderAbortError, ProviderError } from './errors.js'\nimport { requestToRelay } from './helpers.js'\nimport { providerRequestContract, relayFrameContract } from './contracts.js'\n\n/**\n * Carries provider calls over an authenticated NDJSON relay endpoint.\n *\n * @remarks\n * Tool execution context stays local; calls carry only `id`, `name`, and `arguments`.\n * The wire body is an owned snapshot of\n * the projection read through property descriptors, so a serializer reachable only through a\n * `get` trap or a prototype is never consulted; an own function-valued property such as a\n * `toJSON` method is a value outside JSON and is refused before fetching, with the clone's\n * failure as the refusal's `cause`. A remote abort reconstructs a `ProviderAbortError` instance\n * without aborting the\n * local signal; the `Agent` runtime treats that instance as an error unless its own bound\n * signal is aborted.\n * Content is preserved verbatim, including literal thinking tags.\n * A refusal reaches the browser as a `ProviderError` instance with the `HTTP` code and status.\n * This is the browser end alone; {@link createRelay} mounts the server end.\n * The example of {@link createRelayProvider} is the browser half of that pair.\n *\n * @example\n * ```ts\n * import type { ProviderResult } from '@orkestrel/agent'\n * import { RelayProvider } from '@orkestrel/agent'\n * // The browser application supplies this parser dependency.\n * import { createNDJSONParser } from '@orkestrel/ndjson'\n *\n * export function ask(bearer: string, signal: AbortSignal): Promise<ProviderResult> {\n * \tconst browser = new RelayProvider({\n * \t\turl: 'https://relay.example/relay',\n * \t\tparser: createNDJSONParser,\n * \t\theaders: () => ({ authorization: `Bearer ${bearer}` }),\n * \t})\n * \treturn browser.generate([{ id: 'ask', role: 'user', content: 'ping' }], signal)\n * }\n * ```\n */\nexport class RelayProvider extends AgentProvider {\n\treadonly #parser: () => ProviderParserInterface\n\n\tconstructor(options: RelayProviderOptions) {\n\t\tconst { url, timeout, fetch, headers, replay } = options\n\t\tsuper({\n\t\t\turl,\n\t\t\tsplit: false,\n\t\t\tstrict: true,\n\t\t\t...(timeout === undefined ? {} : { timeout }),\n\t\t\t...(fetch === undefined ? {} : { fetch }),\n\t\t\t...(headers === undefined ? {} : { headers }),\n\t\t\t...(replay === undefined ? {} : { replay }),\n\t\t})\n\t\tthis.#parser = options.parser\n\t}\n\n\t/** Identifies the relay backend. */\n\treadonly name = 'relay'\n\n\t/** Creates fresh framing state for each response. */\n\tframe(): ProviderParserInterface {\n\t\treturn this.#parser()\n\t}\n\n\t/**\n\t * Projects declared request fields and refuses values the JSON wire cannot carry.\n\t *\n\t * @remarks\n\t * The snapshot is taken from property descriptors, so a custom serializer a projected\n\t * value carries is ignored rather than consulted and cannot reach the wire.\n\t *\n\t * @param request - The domain conversation and call configuration\n\t * @returns The validated wire request\n\t * @throws {ProviderError} Thrown when the snapshot cannot be taken — a hostile read or a\n\t * value outside JSON — carrying that failure as its `cause`, and when the snapshot the\n\t * projection produced is not a valid wire request\n\t */\n\tencode(request: ProviderRequest): object {\n\t\tconst snapshot = attempt(() => cloneJSONValue(requestToRelay(request)))\n\t\tif (!snapshot.success) {\n\t\t\tthrow new ProviderError('PROTOCOL', 'relay request is not JSON', { cause: snapshot.error })\n\t\t}\n\t\tif (!providerRequestContract.is(snapshot.value)) {\n\t\t\tthrow new ProviderError('PROTOCOL', 'relay request is not JSON')\n\t\t}\n\t\treturn snapshot.value\n\t}\n\n\t/**\n\t * Validates a relay frame and translates its channel into the shared stream engine.\n\t *\n\t * @param record - The framed wire record\n\t * @returns A delta contribution or authoritative result\n\t * @throws {ProviderAbortError} Thrown when the frame's channel is `abort`, carrying its partial result\n\t * @throws {ProviderError} Thrown when the frame fails validation or its channel is `error`\n\t */\n\tread(record: Readonly<Record<string, unknown>>): ProviderIncrement {\n\t\tif (!relayFrameContract.is(record)) {\n\t\t\tthrow new ProviderError('PROTOCOL', 'invalid relay frame')\n\t\t}\n\t\tswitch (record.channel) {\n\t\t\tcase 'content':\n\t\t\t\treturn { content: record.text, thinking: '', tools: [] }\n\t\t\tcase 'thinking':\n\t\t\t\treturn { content: '', thinking: record.text, tools: [] }\n\t\t\tcase 'result':\n\t\t\t\treturn { content: '', thinking: '', tools: [], result: record.result }\n\t\t\tcase 'abort':\n\t\t\t\tthrow new ProviderAbortError(record.partial)\n\t\t\tcase 'error':\n\t\t\t\tthrow new ProviderError('PROVIDER', record.message)\n\t\t}\n\t}\n\n\t/**\n\t * Recovers an unterminated final frame by completing its NDJSON line.\n\t *\n\t * @param parser - The call's retained framing state\n\t * @returns Records completed by the final newline\n\t */\n\tfinish(parser: ProviderParserInterface): ReadonlyArray<Readonly<Record<string, unknown>>> {\n\t\treturn parser.parse('\\n')\n\t}\n}\n","import type { AgentJudgeInput, AgentJudgeInterface, ProviderOptions } from './types.js'\nimport type { JudgeRequest, JudgeResult } from '../types.js'\nimport { isRecord, parseJSON } from '@orkestrel/contract'\nimport { Timeout } from '@orkestrel/timeout'\nimport { DEFAULT_PROVIDER_TIMEOUT } from './constants.js'\nimport { JudgeError } from './errors.js'\nimport { copyJSON } from '../cloners.js'\nimport { JudgeAbortError } from '../errors.js'\nimport { buildJudgeResult, buildProviderHeaders, readFailure, readText } from './helpers.js'\nimport { isJudgeEntry, isJudgeQuestion } from '../validators.js'\n\n/**\n * Implements the bounded HTTP calls, validation, and result merging of a judge behind concrete\n * wire seams.\n *\n * @remarks\n * A subclass fills `name`, `encode`, and `read`; the constructor takes the `batch` switch that\n * decides whether one call carries every question or each question gets its own call in key\n * order. `ask` validates the request before any call, builds every body before the first call so\n * a wire limit refuses the request before inference, and runs the calls one after another, each\n * under its own deadline folded with the caller's signal. A cancel throws a `JudgeAbortError`\n * whose `partial` merges the calls that completed. A transport error reaches the caller unchanged.\n *\n * @example Writing a judge wire\n * ```ts\n * import type { JudgeRequest, JudgeResult } from '@orkestrel/agent'\n * import { AgentJudge, JudgeError } from '@orkestrel/agent'\n * import { isFiniteNumber, isRecord } from '@orkestrel/contract'\n *\n * // A wire whose server answers one yes/no question per call as { \"yes\": 0.93 }.\n * class YesJudge extends AgentJudge {\n * \treadonly name = 'yes'\n * \tencode(request: JudgeRequest): object {\n * \t\treturn { model: this.model, state: request.state, questions: request.questions }\n * \t}\n * \tread(value: unknown, request: JudgeRequest): JudgeResult {\n * \t\tconst [id] = Object.keys(request.questions)\n * \t\tif (id === undefined || !isRecord(value) || !isFiniteNumber(value.yes)) {\n * \t\t\tthrow new JudgeError('PROTOCOL', 'judge error: unreadable answer')\n * \t\t}\n * \t\treturn { model: this.model, answers: { [id]: { form: 'noul', noul: value.yes } } }\n * \t}\n * }\n *\n * const judge = new YesJudge({\n * \turl: 'http://localhost:8010',\n * \tpath: '/v1/yes',\n * \tmodel: 'yes-1',\n * \tbatch: false,\n * })\n * ```\n */\nexport abstract class AgentJudge implements AgentJudgeInterface {\n\treadonly #id: string\n\treadonly #url: string\n\treadonly #path: string\n\treadonly #model: string\n\treadonly #timeout: number\n\treadonly #transport: typeof globalThis.fetch\n\treadonly #headers: ProviderOptions['headers']\n\treadonly #batch: boolean\n\n\tconstructor(input: AgentJudgeInput) {\n\t\tthis.#id = crypto.randomUUID()\n\t\tthis.#url = input.url\n\t\tthis.#path = input.path ?? ''\n\t\tthis.#model = input.model\n\t\tthis.#timeout = input.timeout ?? DEFAULT_PROVIDER_TIMEOUT\n\t\tthis.#transport = input.fetch ?? globalThis.fetch.bind(globalThis)\n\t\tthis.#headers = input.headers\n\t\tthis.#batch = input.batch ?? true\n\t}\n\n\t/** Identifies the concrete wire. */\n\tabstract readonly name: string\n\n\t/** Exposes the instance's minted UUID. */\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\t/** Exposes the configured model identity. */\n\tget model(): string {\n\t\treturn this.#model\n\t}\n\n\t/** Projects one call's request onto the concrete protocol's wire body. */\n\tabstract encode(request: JudgeRequest): object\n\t/** Decodes one call's parsed response body into the answers for that call's questions. */\n\tabstract read(value: unknown, request: JudgeRequest): JudgeResult\n\n\t/**\n\t * Asks every question of the request about its state and merges the answers of every call.\n\t *\n\t * @param request - The state and the questions keyed by caller id\n\t * @param signal - The caller's cancellation bound\n\t * @returns The merged answers, refusals, and usage of every call\n\t * @throws JudgeAbortError Thrown when the caller's signal or a call's deadline fires, carrying\n\t * the merged result of the completed calls\n\t * @throws JudgeError Thrown when the question map is empty, a question or the state is malformed,\n\t * or the wire refuses the request before any call (code `QUESTION`); when a response is non-OK\n\t * (code `HTTP`); and when a response body is missing or unparsable (code `PROTOCOL`)\n\t */\n\tasync ask(request: JudgeRequest, signal: AbortSignal): Promise<JudgeResult> {\n\t\tif (signal.aborted) throw new JudgeAbortError(buildJudgeResult(this.#model, []))\n\t\t// The request is owned through JSON before validation, so a caller mutating it while a call\n\t\t// is pending cannot make `read` decode against criteria that were never sent, and a proxied\n\t\t// request (a reactive view) is owned where a structured clone would refuse it.\n\t\tconst state = copyJSON(request.state)\n\t\tif (!isJudgeEntry(state)) {\n\t\t\tthrow new JudgeError('QUESTION', 'judge error: state is not a judge entry')\n\t\t}\n\t\tconst questions = isRecord(request.questions) ? Object.entries(request.questions) : []\n\t\tif (questions.length === 0) throw new JudgeError('QUESTION', 'judge error: no questions')\n\t\tconst entries = questions.map(([id, question]) => {\n\t\t\tconst copy = copyJSON(question)\n\t\t\tif (!isJudgeQuestion(copy)) {\n\t\t\t\tthrow new JudgeError('QUESTION', `judge error: question ${id} is malformed`)\n\t\t\t}\n\t\t\treturn [id, copy] as const\n\t\t})\n\t\tconst owned: JudgeRequest = { state, questions: Object.fromEntries(entries) }\n\t\tconst parts: readonly JudgeRequest[] = this.#batch\n\t\t\t? [owned]\n\t\t\t: entries.map(([id, question]) => ({ state, questions: { [id]: question } }))\n\t\tconst calls = parts.map((part) => ({ request: part, body: JSON.stringify(this.encode(part)) }))\n\t\tconst results: JudgeResult[] = []\n\t\tfor (const call of calls) {\n\t\t\tresults.push(await this.#call(call.request, call.body, signal, results))\n\t\t}\n\t\treturn buildJudgeResult(this.#model, results)\n\t}\n\n\tasync #call(\n\t\trequest: JudgeRequest,\n\t\tbody: string,\n\t\tsignal: AbortSignal,\n\t\tcompleted: readonly JudgeResult[],\n\t): Promise<JudgeResult> {\n\t\tconst timeout = new Timeout({ ms: this.#timeout })\n\t\ttimeout.start()\n\t\tconst combined = AbortSignal.any([timeout.signal, signal])\n\t\ttry {\n\t\t\tconst headers = await buildProviderHeaders(this.#headers, combined)\n\t\t\tcombined.throwIfAborted()\n\t\t\tconst response = await this.#transport(this.#url + this.#path, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders,\n\t\t\t\tbody,\n\t\t\t\tsignal: combined,\n\t\t\t})\n\t\t\tif (!response.ok) {\n\t\t\t\tconst { message, ...options } = await readFailure(response, 'judge error:', combined)\n\t\t\t\tthrow new JudgeError('HTTP', message, options)\n\t\t\t}\n\t\t\tif (response.body === null) {\n\t\t\t\tthrow new JudgeError('PROTOCOL', 'judge error: no response body')\n\t\t\t}\n\t\t\tconst text = await readText(response.body, undefined, combined)\n\t\t\tcombined.throwIfAborted()\n\t\t\tconst value = parseJSON(text.text)\n\t\t\tif (value === undefined) throw new JudgeError('PROTOCOL', 'judge error: invalid JSON body')\n\t\t\tconst result = this.read(value, request)\n\t\t\tcombined.throwIfAborted()\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tif (combined.aborted) {\n\t\t\t\t// A throw that raced the cancel is the call's real failure, so it is recorded as the cause.\n\t\t\t\tthrow new JudgeAbortError(\n\t\t\t\t\tbuildJudgeResult(this.#model, completed),\n\t\t\t\t\terror === combined.reason ? undefined : { cause: error },\n\t\t\t\t)\n\t\t\t}\n\t\t\tthrow error\n\t\t} finally {\n\t\t\ttimeout.clear()\n\t\t}\n\t}\n}\n","import type { SystemOneAnswer, SystemOneResponse } from './types.js'\nimport {\n\tarrayOf,\n\tattempt,\n\tboundsOf,\n\tisArray,\n\tisNumber,\n\tisRecord,\n\tisString,\n\tnullableOf,\n\toptionalOf,\n} from '@orkestrel/contract'\n\n/**\n * Checks whether a value is a System One response envelope with optional model and usage.\n *\n * @remarks\n * Answers remain unknown until checked against their questions. Missing and null usage counts\n * are accepted. Extra members are ignored, and unreadable fields return false.\n *\n * @param value - The unknown response candidate\n * @returns True if the envelope fields have their wire types; false otherwise\n * @example\n * ```ts\n * isSystemOneResponse({ answers: {}, usage: { input_tokens: null } }) // true\n * ```\n */\nexport function isSystemOneResponse(value: unknown): value is SystemOneResponse {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { model, answers, usage } = value\n\t\tif (!optionalOf(isString)(model) || !isRecord(answers)) return false\n\t\tif (usage === undefined) return true\n\t\tif (!isRecord(usage)) return false\n\t\treturn (\n\t\t\toptionalOf(nullableOf(isNumber))(usage.input_tokens) &&\n\t\t\toptionalOf(nullableOf(isNumber))(usage.output_tokens)\n\t\t)\n\t})\n\treturn checked.success && checked.value\n}\n\n/**\n * Checks whether a value is a System One answer whose type and distribution the wire can read.\n *\n * @remarks\n * The guard checks `type` and the distribution the wire dereferences: the `noul` number for a\n * noul, the `probabilities` map for a choice, and the `probabilities` map or dense array for a\n * score, each probability a finite number in [0, 1]. The `choice`, `score`, `confidence`, and\n * `legend` members are carried unchecked, because the wire never reads them, so a value this\n * guard accepts can hold any value in those members. Distribution sums are not constrained;\n * values are never normalized. Hostile reads return false.\n *\n * @param value - The unknown answer candidate\n * @returns True if the type and the distribution satisfy the wire contract; false otherwise\n * @example\n * ```ts\n * isSystemOneAnswer({ type: 'noul', noul: 0.9 }) // true\n * isSystemOneAnswer({ type: 'score', probabilities: [0.2, 0.8] }) // true\n * isSystemOneAnswer({ type: 'noul', noul: 1.1 }) // false\n * ```\n */\nexport function isSystemOneAnswer(value: unknown): value is SystemOneAnswer {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { type } = value\n\t\tif (type === 'noul') return boundsOf(0, 1)(value.noul)\n\t\tif (type !== 'choice' && type !== 'score') return false\n\t\tconst { probabilities } = value\n\t\tif (type === 'score' && isArray(probabilities)) {\n\t\t\treturn arrayOf(boundsOf(0, 1))(probabilities)\n\t\t}\n\t\treturn isRecord(probabilities) && Object.values(probabilities).every(boundsOf(0, 1))\n\t})\n\treturn checked.success && checked.value\n}\n","import type { SystemOneJudgeOptions, SystemOneRequest } from './types.js'\nimport type { JudgeRequest, JudgeResult } from '../types.js'\nimport { AgentJudge } from './AgentJudge.js'\nimport { SYSTEM_ONE_PATH } from './constants.js'\nimport { extractSystemOneAnswer, extractSystemOneUsage, questionToSystemOne } from './helpers.js'\nimport { isSystemOneAnswer, isSystemOneResponse } from './validators.js'\nimport { JudgeError } from './errors.js'\n\n/**\n * Carries judge questions over the System One protocol and derives answers from server distributions.\n *\n * @remarks\n * The caller supplies the server origin and model. Every question travels in one request.\n * Server measures are ignored; the response model is preserved.\n * `headers` supplies authentication through the shared judge engine.\n * The example readings are those of the response Ollama 0.40.0 returned for that request on 2026-10-07.\n *\n * @example Asking a System One server a choice, a noul, and a score\n * ```ts\n * import { computeReading, createSystemOneJudge } from '@orkestrel/agent'\n *\n * const judge = createSystemOneJudge({ url: 'http://localhost:11434', model: 'tev1:0.8b' })\n * const result = await judge.ask(\n * \t{\n * \t\tstate: 'Our checkout has returned 500 errors since 9am. I want a refund for today.',\n * \t\tquestions: {\n * \t\t\tlabel: {\n * \t\t\t\tform: 'choice',\n * \t\t\t\tinstructions: 'Which label fits this ticket?',\n * \t\t\t\tcriteria: { billing: 'Payments and refunds', bug: 'Software errors', account: null },\n * \t\t\t},\n * \t\t\trefund: {\n * \t\t\t\tform: 'noul',\n * \t\t\t\tinstructions: 'Does the customer ask for money back?',\n * \t\t\t\tcriteria: {\n * \t\t\t\t\ttrue: 'The customer asks for a refund or for money back.',\n * \t\t\t\t\tfalse: 'The customer does not ask for money back.',\n * \t\t\t\t},\n * \t\t\t},\n * \t\t\tseverity: {\n * \t\t\t\tform: 'score',\n * \t\t\t\tinstructions: 'How severe is the reported issue?',\n * \t\t\t\tcriteria: ['Cosmetic; no impact', 'Degraded, workaround exists', 'Blocking; no workaround'],\n * \t\t\t},\n * \t\t},\n * \t},\n * \tAbortSignal.timeout(30_000),\n * )\n * const readings = Object.fromEntries(\n * \tObject.entries(result.answers).map(([id, answer]) => [id, computeReading(answer)]),\n * )\n * result.model // 'tev1:0.8b' — the model the server named\n * result.usage // { prompt: 975, completion: 4, total: 979 }\n * readings.label // { winner: 'bug', probability: 0.9691, confidence: 0.9536 } to 4 decimals\n * readings.refund // { winner: 'true', probability: 0.9979, confidence: 0.9958 } to 4 decimals\n * readings.severity // { winner: '1', probability: 0.9494, confidence: 0.9241, score: 0.9919 } to 4 decimals\n * ```\n */\nexport class SystemOneJudge extends AgentJudge {\n\tconstructor(options: SystemOneJudgeOptions) {\n\t\tsuper({ ...options, path: SYSTEM_ONE_PATH, batch: true })\n\t}\n\n\t/** Identifies the System One protocol. */\n\treadonly name = 'systemone'\n\n\t/**\n\t * Projects the state and questions onto the System One request with the configured model.\n\t *\n\t * @param request - The state and questions keyed by caller id\n\t * @returns The System One request body\n\t */\n\tencode(request: JudgeRequest): SystemOneRequest {\n\t\treturn {\n\t\t\tstate: request.state,\n\t\t\tmodel: this.model,\n\t\t\tquestions: Object.fromEntries(\n\t\t\t\tObject.entries(request.questions).map(([id, question]) => [\n\t\t\t\t\tid,\n\t\t\t\t\tquestionToSystemOne(question),\n\t\t\t\t]),\n\t\t\t),\n\t\t}\n\t}\n\n\t/**\n\t * Decodes requested System One answers and reports the server model and available usage.\n\t *\n\t * @param value - The parsed response body\n\t * @param request - The questions defining the expected answers\n\t * @returns The decoded distributions, model, and available usage\n\t * @throws JudgeError Thrown when the envelope is malformed or an answer is invalid (code `PROTOCOL`);\n\t * the message names the question id of an invalid answer\n\t */\n\tread(value: unknown, request: JudgeRequest): JudgeResult {\n\t\tif (!isSystemOneResponse(value)) {\n\t\t\tthrow new JudgeError('PROTOCOL', 'judge error: invalid System One response envelope')\n\t\t}\n\t\tconst entries = Object.entries(request.questions).map(([id, question]) => {\n\t\t\tif (!Object.hasOwn(value.answers, id)) {\n\t\t\t\tthrow new JudgeError('PROTOCOL', `judge error: question ${id} has no System One answer`)\n\t\t\t}\n\t\t\tconst wire = value.answers[id]\n\t\t\tif (!isSystemOneAnswer(wire)) {\n\t\t\t\tthrow new JudgeError(\n\t\t\t\t\t'PROTOCOL',\n\t\t\t\t\t`judge error: question ${id} has an invalid System One answer`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst answer = extractSystemOneAnswer(wire, question)\n\t\t\tif (answer === undefined) {\n\t\t\t\tthrow new JudgeError(\n\t\t\t\t\t'PROTOCOL',\n\t\t\t\t\t`judge error: question ${id} has a mismatched or incomplete System One answer`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn [id, answer] as const\n\t\t})\n\t\tconst usage = extractSystemOneUsage(value.usage)\n\t\treturn {\n\t\t\tmodel: value.model ?? this.model,\n\t\t\tanswers: Object.fromEntries(entries),\n\t\t\t...(usage === undefined ? {} : { usage }),\n\t\t}\n\t}\n}\n","import type {\n\tProviderInterface,\n\tRelayHandler,\n\tRelayOptions,\n\tRelayProviderOptions,\n\tSystemOneJudgeOptions,\n\tThinkSplitterInterface,\n} from './types.js'\nimport type { JudgeInterface } from '../types.js'\nimport { parseJSONAs } from '@orkestrel/contract'\nimport {\n\tDEFAULT_RELAY_LIMIT,\n\tINVALID_RELAY_STATUS,\n\tOVERSIZED_RELAY_STATUS,\n\tUNAUTHORIZED_RELAY_STATUS,\n\tUPSTREAM_RELAY_STATUS,\n} from './constants.js'\nimport { readText } from './helpers.js'\nimport { providerRequestContract } from './contracts.js'\nimport { RelayStream } from './RelayStream.js'\nimport { RelayProvider } from './RelayProvider.js'\nimport { ThinkSplitter } from './ThinkSplitter.js'\nimport { SystemOneJudge } from './SystemOneJudge.js'\n\n/**\n * Creates an authorized relay handler that validates a bounded JSON request before streaming.\n *\n * @remarks\n * Answers with the `401` status when authorization refuses or throws, the `400`\n * status when the body is missing, unreadable, or invalid, the `413` status when\n * the body fills its byte budget or the inbound read is aborted, and the `502`\n * status when the upstream provider call cannot be constructed. Refusals carry no body.\n *\n * @param options - The upstream provider, authorization decision, and optional byte budget\n * @returns A fetch-standard handler suitable for a router\n * @example Mounting the relay on your server\n * ```ts\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { createRelay } from '@orkestrel/agent'\n * import { createDispatcher } from '@orkestrel/router'\n * import { createServer } from '@orkestrel/server'\n *\n * declare const upstream: ProviderInterface // the server-side provider holding the credential\n * declare const bearer: string\n *\n * const handler = createRelay({\n * \tprovider: upstream,\n * \tauthorize: (request) => request.headers.get('authorization') === `Bearer ${bearer}`,\n * })\n * const dispatcher = createDispatcher({\n * \troutes: [{ method: 'POST', path: '/relay', handler }],\n * })\n *\n * export function serve(request: Request): Promise<Response> {\n * \treturn dispatcher.handle(request, undefined)\n * }\n *\n * const server = createServer({ dispatcher, state: () => undefined })\n * await server.start()\n * process.on('SIGTERM', () => server.stop()) // signal cancellation, drain, then close the listener\n * ```\n */\nexport function createRelay(options: RelayOptions): RelayHandler {\n\tconst { provider, authorize, limit } = options\n\treturn async (request) => {\n\t\ttry {\n\t\t\tif ((await authorize(request)) !== true) {\n\t\t\t\treturn new Response(undefined, { status: UNAUTHORIZED_RELAY_STATUS })\n\t\t\t}\n\t\t} catch {\n\t\t\treturn new Response(undefined, { status: UNAUTHORIZED_RELAY_STATUS })\n\t\t}\n\t\tif (request.body === null) return new Response(undefined, { status: INVALID_RELAY_STATUS })\n\t\tconst read = await readText(request.body, limit ?? DEFAULT_RELAY_LIMIT, request.signal).catch(\n\t\t\t() => undefined,\n\t\t)\n\t\tif (read === undefined) {\n\t\t\treturn new Response(undefined, {\n\t\t\t\tstatus: request.signal.aborted ? OVERSIZED_RELAY_STATUS : INVALID_RELAY_STATUS,\n\t\t\t})\n\t\t}\n\t\tif (!read.complete) return new Response(undefined, { status: OVERSIZED_RELAY_STATUS })\n\t\tconst parsed = parseJSONAs(read.text, providerRequestContract.is)\n\t\tif (parsed === undefined) return new Response(undefined, { status: INVALID_RELAY_STATUS })\n\t\ttry {\n\t\t\treturn new RelayStream({ provider, request: parsed, signal: request.signal }).response\n\t\t} catch {\n\t\t\treturn new Response(undefined, { status: UPSTREAM_RELAY_STATUS })\n\t\t}\n\t}\n}\n\n/**\n * Creates a provider that carries calls through a relay endpoint.\n *\n * @remarks\n * This is the browser end alone. {@link createRelay} mounts the server end, and its example\n * is the server half this one pairs with.\n *\n * @param options - The endpoint, parser factory, and HTTP call configuration\n * @returns The relay provider behind the shared provider interface; construct\n * {@link RelayProvider} directly to reach its wire seams\n * @example Reaching the relay from the browser\n * ```ts\n * import type { ProviderInterface, ProviderParserInterface } from '@orkestrel/agent'\n * import { createRelayProvider, ProviderError } from '@orkestrel/agent'\n * import { createAbort } from '@orkestrel/abort'\n * import { isRecord, parseJSONAs } from '@orkestrel/contract'\n *\n * class RelayFrameParser implements ProviderParserInterface {\n * \t#pending = ''\n * \tparse(chunk: string): ReadonlyArray<Readonly<Record<string, unknown>>> {\n * \t\tthis.#pending += chunk\n * \t\tconst lines = this.#pending.split(/\\r\\n|\\n/)\n * \t\tthis.#pending = lines.pop() ?? ''\n * \t\treturn lines\n * \t\t\t.filter((line) => line.trim().length > 0)\n * \t\t\t.map((line) => {\n * \t\t\t\tconst record = parseJSONAs(line, isRecord)\n * \t\t\t\tif (record === undefined) throw new ProviderError('PROTOCOL', 'invalid JSON record')\n * \t\t\t\treturn record\n * \t\t\t})\n * \t}\n * \tclear(): void {\n * \t\tthis.#pending = ''\n * \t}\n * }\n *\n * declare const bearer: string\n * const abort = createAbort()\n * const messages = [{ id: '1', role: 'user', content: 'Say hello.' }] as const\n *\n * const browser: ProviderInterface = createRelayProvider({\n * \turl: 'https://app.example/relay',\n * \tparser: () => new RelayFrameParser(),\n * \theaders: () => ({ authorization: `Bearer ${bearer}` }),\n * })\n * const result = await browser.generate(messages, abort.signal) // a ProviderResult like a local provider's\n * ```\n */\nexport function createRelayProvider(options: RelayProviderOptions): ProviderInterface {\n\treturn new RelayProvider(options)\n}\n\n/**\n * Creates a fresh stream-stateful `<think>` separator — a {@link ThinkSplitterInterface} that\n * splits a thinking model's in-content `<think>…</think>` reasoning spans away from the answer,\n * delta by delta, so a provider yields clean content alone and surfaces the accumulated\n * reasoning as {@link import('./types.js').ProviderResult.thinking}. One splitter serves one\n * stream.\n *\n * @remarks\n * Feed each raw wire delta through `split(delta)` (it returns the clean content to\n * surface — possibly `''` mid-think) and settle the stream end with `flush()` (a held\n * partial open tag that never completed returns as final content; an unclosed think\n * span lands on `thinking`). Tags split across deltas are held back until\n * disambiguated, multiple spans accumulate in order, and a nested-looking `<think>`\n * inside an open span is thinking text. One splitter serves one stream — create\n * a fresh one per provider call.\n *\n * @returns A fresh {@link ThinkSplitterInterface} (state empty, outside any span)\n *\n * @example\n * ```ts\n * import { createThinkSplitter } from '@orkestrel/agent'\n *\n * const splitter = createThinkSplitter()\n * const clean = splitter.split('<think>plan the answer</think>Here it is.')\n * clean // 'Here it is.'\n * splitter.thinking // 'plan the answer'\n * ```\n */\nexport function createThinkSplitter(): ThinkSplitterInterface {\n\treturn new ThinkSplitter()\n}\n\n/**\n * Creates a judge that sends every question through the configured System One server.\n *\n * @param options - The server origin, model, and optional transport, headers, and timeout\n * @returns The configured judge behind its shared interface\n * @example\n * ```ts\n * const judge = createSystemOneJudge({ url: 'http://localhost:11434', model: 'tev1:0.8b' })\n * ```\n */\nexport function createSystemOneJudge(options: SystemOneJudgeOptions): JudgeInterface {\n\treturn new SystemOneJudge(options)\n}\n","/**\n * Sets the default number of recent live messages the `compact()` method of a\n * {@link ConversationInterface} retains verbatim — `0`, so a manual `compact()` keeps no recent tail and folds every\n * exchange before the newest user message into one summarized section. A caller retains a recent\n * tail by passing `keep` (on\n * {@link ConversationOptions}, {@link ConversationManagerOptions}, or per-fold through\n * {@link CompactOptions}), folding at most the older `count - keep` messages, cut back to whole\n * exchanges, and leaving at least the most recent `keep` live for the next turn. Overridable everywhere `keep` is accepted.\n */\nexport const DEFAULT_CONVERSATION_KEEP = 0\n\n/**\n * Names the framing label the `view()` method of a {@link ConversationInterface} prefixes onto the\n * summary of each compacted section so a small model reads it as a condensed recap of earlier turns — the lean\n * `'[Summary of earlier messages] '` marker, never a literal assistant turn to echo or treat as\n * the live answer.\n *\n * @remarks\n * Deliberately a fixed, lean handful of tokens (a short bracketed marker) so the framing adds a\n * bounded `prefix × sections` overhead and never an open-ended blow-up — the\n * {@link ConversationInterface} no-bloat test guard pins exactly that. Kept here (beside\n * {@link DEFAULT_CONVERSATION_KEEP}) as the one tunable framing constant of the conversation\n * layer, so the wording has a single source of truth (the `view()` recap framing is distinct\n * from the cross-conversation provenance marker of `reference()`, which is rendered inline\n * because it interpolates the per-call provenance `label`).\n */\nexport const CONVERSATION_RECAP_PREFIX = '[Summary of earlier messages] '\n","import type { ConversationErrorCode } from './types.js'\nimport type { CodedErrorOptions } from '../types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/**\n * Reports a conversation with no {@link ConversationSummaryHandler} to fold its messages with, a\n * `sections` cap below `1`, a `keep` that is not a nonnegative safe integer, or a judgment or\n * judge request that JSON cannot carry — thrown by the `compact()` method of a\n * {@link ConversationInterface}, its construction, or its judgment store, carrying the\n * machine-readable `code` `'SUMMARIZER' | 'SECTIONS' | 'JUDGMENT' | 'KEEP'`.\n *\n * @remarks\n * Compaction requires a summarizer (it digests the folded slice into a section summary); a\n * conversation created without one can still store + `view()` its live tail, but a `compact()`\n * is a programmer error and throws this with `'SUMMARIZER'`.\n * A `sections` cap (on {@link import('./types.js').ConversationOptions} /\n * {@link import('./types.js').ConversationManagerOptions} /\n * {@link import('./types.js').CompactOptions}) must be `>= 1`, and cannot combine with\n * `rolling` — either is a programmer error and throws this with `'SECTIONS'`. A `keep` on the same options must be a nonnegative\n * safe integer — any other value is a programmer error and throws this with `'KEEP'`. A judgment\n * record or a judge request that JSON cannot carry, or whose copy fails its guard, is a\n * programmer error and throws this with `'JUDGMENT'`, its `context` naming the `question` id\n * where one exists. Narrow a caught value with {@link isConversationError} and branch on\n * `error.code`.\n */\nexport class ConversationError extends Error {\n\t/** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a sub-1 `sections` cap, or a cap combined with `rolling`; `'JUDGMENT'`: a judgment or judge request that is not JSON; `'KEEP'`: a `keep` that is not a nonnegative safe integer. */\n\treadonly code: ConversationErrorCode\n\t/** Holds the values that locate the failure, such as the `question` id of a malformed question, or `undefined` when none were supplied. */\n\treadonly context: Readonly<Record<string, unknown>> | undefined\n\n\t/**\n\t * Creates the error with its code, message, and optional cause and context.\n\t *\n\t * @param code - The machine-readable {@link ConversationErrorCode}\n\t * @param message - The human-readable description\n\t * @param options - The optional {@link CodedErrorOptions}; `cause` reaches `Error.cause` only when present\n\t */\n\tconstructor(code: ConversationErrorCode, message: string, options?: CodedErrorOptions) {\n\t\tsuper(message, options?.cause === undefined ? undefined : { cause: options.cause })\n\t\tthis.name = 'ConversationError'\n\t\tthis.code = code\n\t\tthis.context = options?.context\n\t}\n}\n\n/**\n * Narrows an unknown caught value to a {@link ConversationError} through `instanceof`, so a\n * `catch` can branch on its `code`.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns True if `value` is a {@link ConversationError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tawait conversation.compact()\n * } catch (error) {\n * \tif (isConversationError(error) && error.code === 'SUMMARIZER') addSummarizer()\n * }\n * ```\n */\nexport function isConversationError(value: unknown): value is ConversationError {\n\treturn isInstance(value, ConversationError)\n}\n","import type { ConversationSnapshot, Section } from './types.js'\nimport type { Judgment, Message } from '../types.js'\nimport { isTokenUsage } from '@orkestrel/budget'\nimport {\n\tarrayOf,\n\tattempt,\n\tisFiniteNumber,\n\tisRecord,\n\tisString,\n\toptionalOf,\n\tobjectOf,\n\trecordOf,\n} from '@orkestrel/contract'\nimport { isToolCall } from '@orkestrel/tool'\nimport { MESSAGE_ROLES } from '../constants.js'\nimport { isJudgeQuestion } from '../validators.js'\n\n/**\n * Checks whether a value satisfies the domain conversation-message contract.\n *\n * @remarks\n * Roles belong to MessageRole, image elements are strings, `thinking` is a string, and `call` is a string on any\n * role, as the flat Message type admits. Tool arguments may carry non-JSON values, as the\n * domain type permits; the message wire contract is narrower. Unreadable fields and hostile\n * inputs return false.\n *\n * @param value - The unknown message candidate\n * @returns True if the domain message fields are valid; false otherwise\n * @example\n * ```ts\n * isMessage({ id: '1', role: 'user', content: 'hi' }) // true\n * isMessage({ id: '1', role: 'other', content: '' }) // false\n * isMessage({ id: '1', role: 'user', content: '', images: [1] }) // false\n * isMessage({ id: '1', role: 'assistant', content: '', thinking: 1 }) // false\n * ```\n */\nexport function isMessage(value: unknown): value is Message {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { id, role, content, calls, call, images, thinking } = value\n\t\tif (!isString(id) || !isString(content)) return false\n\t\tif (!MESSAGE_ROLES.some((one) => one === role)) return false\n\t\tif (calls !== undefined && !arrayOf(isToolCall)(calls)) return false\n\t\tif (call !== undefined && !isString(call)) return false\n\t\tif (images !== undefined && !arrayOf(isString)(images)) return false\n\t\treturn thinking === undefined || isString(thinking)\n\t})\n\treturn checked.success && checked.value\n}\n\n/**\n * Checks whether a stored judgment carries a valid question and exactly one answer or refusal.\n *\n * @remarks\n * Unknown members, malformed members, and unreadable inputs return false. Answer fields follow\n * the root judge value types; this storage guard does not impose a wire's probability or\n * candidate limits. The `time`, `noul`, and probability numbers must be finite, because a stored\n * record is owned through JSON, which turns `NaN` and the infinities into `null`; so every record\n * this guard accepts hydrates through a `JudgmentManager`.\n *\n * @param value - The unknown stored record\n * @returns True if the record satisfies the judgment contract; false otherwise\n * @example\n * ```ts\n * isJudgment({ id: 'q', question: { form: 'noul' }, answer: { form: 'noul', noul: 0.9 }, model: 'judge', sources: [], state: 'text', time: 0 }) // true\n * isJudgment({ id: 'q' }) // false\n * ```\n */\nexport function isJudgment(value: unknown): value is Judgment {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { answer, refusal } = value\n\t\tif (\n\t\t\t!recordOf(\n\t\t\t\t{\n\t\t\t\t\tid: isString,\n\t\t\t\t\tquestion: isJudgeQuestion,\n\t\t\t\t\tmodel: isString,\n\t\t\t\t\tsources: arrayOf(isString),\n\t\t\t\t\tstate: isString,\n\t\t\t\t\ttime: isFiniteNumber,\n\t\t\t\t\tusage: optionalOf(isTokenUsage),\n\t\t\t\t\t...(answer === undefined ? { refusal: isRecord } : { answer: isRecord }),\n\t\t\t\t},\n\t\t\t\t['usage'],\n\t\t\t)(value)\n\t\t)\n\t\t\treturn false\n\t\tif (answer === undefined) return objectOf({ missing: arrayOf(isString) })(refusal)\n\t\tif (refusal !== undefined || !isRecord(answer)) return false\n\t\tif (answer.form === 'noul') return isFiniteNumber(answer.noul)\n\t\tif (answer.form === 'score') return arrayOf(isFiniteNumber)(answer.probabilities)\n\t\treturn (\n\t\t\tanswer.form === 'choice' &&\n\t\t\tisRecord(answer.probabilities) &&\n\t\t\tObject.values(answer.probabilities).every(isFiniteNumber)\n\t\t)\n\t})\n\treturn checked.success && checked.value\n}\n\n/**\n * Checks whether an `unknown` is structurally a {@link Section} record — a `string` `id` and\n * `summary` beside a `messages` array of valid {@link Message} records, the per-section step of\n * the {@link isConversationSnapshot} read-boundary narrow. Total, never throwing, and never an\n * assertion.\n *\n * @remarks\n * A total guard (it never throws — adversarial input, a throwing getter included, returns\n * `false`). It checks the shape of the section: a record with a `string` `id`, a `string`\n * `summary`, and a dense `messages` array every element of which is a valid {@link Message}\n * record ({@link isMessage}); a sparse `messages` array is refused. Enough to safely impose\n * the {@link Section} type at a storage boundary without a cast.\n *\n * @param value - The value to test (one element of a snapshot's `sections` array)\n * @returns True if `value` has the structural shape of a {@link Section}; false otherwise\n *\n * @example\n * ```ts\n * isSection({ id: 's', summary: 'recap', messages: [{ id: '1', role: 'user', content: 'hi' }] }) // true\n * isSection({ id: 's', summary: 'recap', messages: 'nope' }) // false\n * isSection({ id: 's', messages: [] }) // false (missing summary)\n * ```\n */\nexport function isSection(value: unknown): value is Section {\n\treturn (\n\t\tisRecord(value) &&\n\t\tobjectOf({ id: isString, summary: isString, messages: arrayOf(isMessage) })(value)\n\t)\n}\n\n/**\n * Narrows an `unknown` to a {@link ConversationSnapshot} — a `string` `id` and valid\n * `sections` and `messages` arrays; the total boundary guard for an untrusted snapshot read (a storage row a\n * {@link import('./stores/DatabaseConversationStore.js').DatabaseConversationStore}\n * reads back from its opaque JSON column, a snapshot loaded from disk), never throwing. The exact\n * analogue of {@link import('@orkestrel/workspace').isWorkspaceSnapshot}.\n *\n * @remarks\n * A total guard (it never throws — adversarial input returns `false`). It checks the shape of the\n * snapshot: a `string` `id`, a `sections` array every element of which is a valid\n * {@link Section} ({@link isSection}), a `messages` array every element of which is a\n * valid {@link Message} ({@link isMessage}), and optional valid `judgments` — enough to safely\n * impose the\n * {@link ConversationSnapshot} type at a storage boundary without a cast. The structural twin of\n * {@link import('@orkestrel/workspace').isWorkspaceSnapshot}. Unknown members are admitted, so a\n * 0.0.29 snapshot that carries a conversation `summary` passes. A malformed blob (a non-record,\n * a missing / non-string `id`, a non-array `sections` / `messages`, or any malformed\n * element) resolves `false`, so a\n * {@link import('./stores/DatabaseConversationStore.js').DatabaseConversationStore}\n * read yields `undefined` rather than a broken conversation.\n *\n * @param value - The value to test (an opaque storage read)\n * @returns True if `value` has the structural shape of a {@link ConversationSnapshot}; false otherwise\n *\n * @example\n * ```ts\n * isConversationSnapshot({ id: 'c1', sections: [], messages: [] }) // true\n * isConversationSnapshot({ id: 'c1', sections: 'nope', messages: [] }) // false\n * isConversationSnapshot({ sections: [], messages: [] }) // false (missing id)\n * ```\n */\nexport function isConversationSnapshot(value: unknown): value is ConversationSnapshot {\n\treturn (\n\t\tisRecord(value) &&\n\t\tobjectOf(\n\t\t\t{\n\t\t\t\tid: isString,\n\t\t\t\tsections: arrayOf(isSection),\n\t\t\t\tmessages: arrayOf(isMessage),\n\t\t\t\tjudgments: optionalOf(arrayOf(isJudgment)),\n\t\t\t},\n\t\t\t['judgments'],\n\t\t)(value)\n\t)\n}\n","import type { Section } from './types.js'\nimport type { JudgeRequest, JudgeResult, Judgment, JudgmentInput, Message } from '../types.js'\nimport { CONVERSATION_RECAP_PREFIX } from './constants.js'\nimport { ConversationError } from './errors.js'\nimport { isJudgment } from './validators.js'\nimport { isNonNegativeSafeInteger } from '../validators.js'\n\n/**\n * Builds records for answered or refused request keys, attaching usage only for a single question.\n *\n * @param request - The request whose question keys define record order\n * @param result - The reported answers, refusals, model, and usage\n * @param sources - The ordered source message ids\n * @param state - The rendered state read by the judge\n * @param model - The configured judge identity the records carry\n * @returns Inputs for completed question keys in request order\n * @example\n * ```ts\n * buildJudgments(request, result, ['message-a'], 'Charged twice', judge.model)\n * ```\n */\nexport function buildJudgments(\n\trequest: JudgeRequest,\n\tresult: JudgeResult,\n\tsources: readonly string[],\n\tstate: string,\n\tmodel: string,\n): readonly JudgmentInput[] {\n\tconst single = Object.keys(request.questions).length === 1\n\treturn Object.entries(request.questions).flatMap(([id, question]): readonly JudgmentInput[] => {\n\t\tconst answer = Object.hasOwn(result.answers, id) ? result.answers[id] : undefined\n\t\tconst refusal =\n\t\t\tresult.refusals !== undefined && Object.hasOwn(result.refusals, id)\n\t\t\t\t? result.refusals[id]\n\t\t\t\t: undefined\n\t\tif (answer === undefined && refusal === undefined) return []\n\t\treturn [\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tquestion,\n\t\t\t\tmodel,\n\t\t\t\tsources,\n\t\t\t\tstate,\n\t\t\t\t...(answer !== undefined ? { answer } : refusal !== undefined ? { refusal } : {}),\n\t\t\t\t...(single && result.usage !== undefined ? { usage: result.usage } : {}),\n\t\t\t},\n\t\t]\n\t})\n}\n\n/**\n * Builds the raw synthetic summary message for one compacted section — role `'assistant'`, the\n * section's stable `id`, and its `summary` verbatim as content.\n *\n * @remarks\n * Pure and total. This is the unframed form a `sections` cap merge digests when it folds the\n * oldest sections into one (a summary over their section summaries); the recap label is absent\n * from that merge input. A rolling fold instead re-reads the framed recap — see\n * {@link buildRecapMessage}.\n *\n * @param section - The compacted section to render\n * @returns The synthetic summary message\n *\n * @example\n * ```ts\n * buildSummaryMessage({ id: 's1', summary: 'recap', messages: [] })\n * // { id: 's1', role: 'assistant', content: 'recap' }\n * ```\n */\nexport function buildSummaryMessage(section: Section): Message {\n\treturn { id: section.id, role: 'assistant', content: section.summary }\n}\n\n/**\n * Builds the framed recap message for one compacted section — the same role and stable `id` as\n * {@link buildSummaryMessage}, with the content prefixed by {@link\n * import('./constants.js').CONVERSATION_RECAP_PREFIX}.\n *\n * @remarks\n * Pure and total. The prefix is what makes a small model read the message as a condensed\n * recap of earlier turns rather than a literal assistant turn to echo or answer from. It is a\n * fixed handful of tokens, so a conversation's `view()` stays lean however many sections it\n * carries.\n *\n * @param section - The compacted section to render\n * @returns The framed recap message\n *\n * @example\n * ```ts\n * buildRecapMessage({ id: 's1', summary: 'recap', messages: [] })\n * // { id: 's1', role: 'assistant', content: `${CONVERSATION_RECAP_PREFIX}recap` }\n * ```\n */\nexport function buildRecapMessage(section: Section): Message {\n\treturn {\n\t\tid: section.id,\n\t\trole: 'assistant',\n\t\tcontent: `${CONVERSATION_RECAP_PREFIX}${section.summary}`,\n\t}\n}\n\n/**\n * Returns a stored judgment record after checking it, or throws a coded error.\n *\n * @remarks\n * A stored record is the JSON copy of its input, so a proxied record is accepted and the stored\n * value is exactly what a snapshot can carry. The check is {@link isJudgment}.\n *\n * @param value - The JSON copy of a judgment record or input\n * @returns The value, narrowed to a {@link Judgment}\n * @throws ConversationError Thrown when the value is not a valid judgment record (code `'JUDGMENT'`)\n *\n * @example\n * ```ts\n * requireJudgment(copyJSON(record)) // the record, narrowed\n * requireJudgment({ id: 'refund' }) // throws ConversationError ('JUDGMENT')\n * ```\n */\nexport function requireJudgment(value: unknown): Judgment {\n\tif (!isJudgment(value)) {\n\t\tthrow new ConversationError('JUDGMENT', 'conversation error: a judgment must be a JSON record')\n\t}\n\treturn value\n}\n\n/**\n * Returns a `sections` cap after checking its lower bound, or throws a coded error.\n *\n * @remarks\n * A supplied cap must satisfy `>= 1`; fractional caps and positive infinity pass, and `NaN`\n * is refused. An absent cap leaves the sections list unbounded.\n *\n * @param cap - The cap to check, or `undefined` for no cap\n * @returns The cap unchanged, or `undefined` when none was supplied\n * @throws ConversationError Thrown when the cap does not satisfy `>= 1` (code `'SECTIONS'`, including `NaN`)\n *\n * @example\n * ```ts\n * requireSectionsCap(2) // 2\n * requireSectionsCap(undefined) // undefined\n * requireSectionsCap(0) // throws ConversationError ('SECTIONS')\n * ```\n */\nexport function requireSectionsCap(cap: number | undefined): number | undefined {\n\tif (cap !== undefined && !(cap >= 1)) {\n\t\tthrow new ConversationError('SECTIONS', 'a sections cap must be >= 1')\n\t}\n\treturn cap\n}\n\n/**\n * Returns the rolling switch after checking it does not combine with a `sections` cap, or throws a\n * coded error.\n *\n * @remarks\n * A rolling conversation keeps one section, so a cap has nothing to bound. The cap checked is the\n * effective one: inherited from a manager, configured on the conversation, or supplied to one\n * `compact()` call.\n *\n * @param rolling - Whether folds roll every prior section into one\n * @param cap - The effective `sections` cap, or `undefined` for none\n * @returns The rolling switch unchanged\n * @throws ConversationError Thrown when `rolling` is true and a cap is present (code `'SECTIONS'`)\n *\n * @example\n * ```ts\n * requireRolling(true, undefined) // true\n * requireRolling(false, 2) // false\n * requireRolling(true, 2) // throws ConversationError ('SECTIONS')\n * ```\n */\nexport function requireRolling(rolling: boolean, cap: number | undefined): boolean {\n\tif (rolling && cap !== undefined) {\n\t\tthrow new ConversationError('SECTIONS', 'rolling cannot combine with a sections cap', {\n\t\t\tcontext: { sections: cap },\n\t\t})\n\t}\n\treturn rolling\n}\n\n/**\n * Returns a retained-tail size after checking it is a nonnegative safe integer, or throws a coded\n * error.\n *\n * @remarks\n * The check is {@link import('../validators.js').isNonNegativeSafeInteger}, so `0` and `-0`\n * pass while `NaN`, a fraction, a negative, and either infinity are refused. The error's `context`\n * carries the refused value as `keep`.\n *\n * @param keep - The retained-tail size to check\n * @returns The size unchanged\n * @throws ConversationError Thrown when `keep` is not a nonnegative safe integer (code `'KEEP'`)\n *\n * @example\n * ```ts\n * requireKeep(2) // 2\n * requireKeep(1.5) // throws ConversationError ('KEEP')\n * ```\n */\nexport function requireKeep(keep: number): number {\n\tif (!isNonNegativeSafeInteger(keep)) {\n\t\tthrow new ConversationError('KEEP', 'a keep must be a nonnegative safe integer', {\n\t\t\tcontext: { keep },\n\t\t})\n\t}\n\treturn keep\n}\n\n/**\n * Settles with a promise, or rejects with the reason of a signal that aborts first, so a caller\n * is released at once even when the work behind the promise ignores the signal.\n *\n * @remarks\n * An absent signal returns `promise` itself. An already-aborted signal rejects with its reason\n * without waiting. The abort listener is removed as soon as `promise` settles. A rejection of\n * `promise` after the abort is handled here and never surfaces as unhandled.\n *\n * @param promise - The work to wait for\n * @param signal - The cancellation signal, or `undefined` for none\n * @returns A promise that settles as `promise` does, or rejects with `signal.reason` on abort\n *\n * @example\n * ```ts\n * const controller = new AbortController()\n * const raced = raceSignal(new Promise<string>(() => {}), controller.signal)\n * controller.abort(new Error('stop'))\n * await raced // rejects with the Error 'stop'\n * ```\n */\nexport function raceSignal<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n\tif (signal === undefined) return promise\n\treturn new Promise<T>((resolve, reject) => {\n\t\t// Aborting `settled` removes the abort listener once the promise settles.\n\t\tconst settled = new AbortController()\n\t\tif (signal.aborted) reject(signal.reason)\n\t\telse {\n\t\t\tsignal.addEventListener('abort', () => reject(signal.reason), {\n\t\t\t\tonce: true,\n\t\t\t\tsignal: settled.signal,\n\t\t\t})\n\t\t}\n\t\t// Settling an already-rejected race is a no-op, and this handler is what keeps a late\n\t\t// rejection of `promise` from surfacing as unhandled.\n\t\tvoid promise.then(resolve, reject).finally(() => settled.abort())\n\t})\n}\n","import type { JudgmentManagerInterface } from './types.js'\nimport type { JudgeInterface, JudgeRequest, Judgment, JudgmentInput } from '../types.js'\nimport { isArray, isRecord } from '@orkestrel/contract'\nimport { ConversationError } from './errors.js'\nimport { buildJudgments, requireJudgment } from './helpers.js'\nimport { copyJSON } from '../cloners.js'\nimport { JudgeAbortError, isJudgeAbortError } from '../errors.js'\nimport { matchesJudgment, removeEntries } from '../helpers.js'\nimport { isJudgeEntry, isJudgeQuestion } from '../validators.js'\n\n/**\n * Stores judgments in insertion order and asks a judge only for unmatched question identities.\n *\n * @remarks\n * Adding an existing key replaces it without changing its insertion position. Construction\n * restores recorded times; adding stamps the current epoch milliseconds. Caller input is owned\n * through JSON on arrival, so a proxied record or request is accepted where a structured clone\n * refuses it, and records are copied on reads, so callers cannot change the stored identity\n * through nested values.\n *\n * @example\n * ```ts\n * const judgments = new JudgmentManager()\n * const records = await judgments.resolve(judge, request, ['message-a'], signal)\n * ```\n */\nexport class JudgmentManager implements JudgmentManagerInterface {\n\treadonly #judgments: Map<string, Judgment>\n\n\t/**\n\t * Restores records without replacing their storage times.\n\t * @param judgments - The previously stored judgments to restore. Default: an empty list\n\t */\n\tconstructor(judgments: readonly Judgment[] = []) {\n\t\t// `Array.from` visits a hole in `judgments` as an undefined record, which `requireJudgment` refuses; `map` skips it.\n\t\tthis.#judgments = new Map(\n\t\t\tArray.from(judgments, (judgment) => requireJudgment(copyJSON(judgment))).map((owned) => [\n\t\t\t\towned.id,\n\t\t\t\towned,\n\t\t\t]),\n\t\t)\n\t}\n\n\tget count(): number {\n\t\treturn this.#judgments.size\n\t}\n\n\tadd(input: JudgmentInput): Judgment\n\tadd(inputs: readonly JudgmentInput[]): readonly Judgment[]\n\tadd(input: JudgmentInput | readonly JudgmentInput[]): Judgment | readonly Judgment[] {\n\t\tif (isArray(input)) return input.map((one) => this.#store(one))\n\t\treturn this.#store(input)\n\t}\n\n\tjudgment(id: string): Judgment | undefined {\n\t\tconst judgment = this.#judgments.get(id)\n\t\treturn judgment === undefined ? undefined : structuredClone(judgment)\n\t}\n\n\tjudgments(): readonly Judgment[] {\n\t\treturn structuredClone([...this.#judgments.values()])\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) return removeEntries(ids, (id) => this.#judgments.delete(id))\n\t\treturn this.#judgments.delete(ids)\n\t}\n\n\tclear(): void {\n\t\tthis.#judgments.clear()\n\t}\n\n\tasync resolve(\n\t\tjudge: JudgeInterface,\n\t\trequest: JudgeRequest,\n\t\tsources: readonly string[],\n\t\tsignal: AbortSignal,\n\t): Promise<readonly Judgment[]> {\n\t\t// The request is owned through JSON before it is compared or sent, as the judge engine owns\n\t\t// it, so a proxied request is accepted and a caller mutating it mid-flight changes nothing.\n\t\tconst state = copyJSON(request.state)\n\t\tif (!isJudgeEntry(state)) {\n\t\t\tthrow new ConversationError(\n\t\t\t\t'JUDGMENT',\n\t\t\t\t'conversation error: the judge state is not a judge entry',\n\t\t\t)\n\t\t}\n\t\tconst rendered = typeof state === 'string' ? state : JSON.stringify(state)\n\t\tconst origins = [...sources]\n\t\tconst entries = isRecord(request.questions) ? Object.entries(request.questions) : []\n\t\tconst checked = entries.map(([id, raw]) => {\n\t\t\tconst question = copyJSON(raw)\n\t\t\tif (!isJudgeQuestion(question)) {\n\t\t\t\tthrow new ConversationError('JUDGMENT', `conversation error: question ${id} is malformed`, {\n\t\t\t\t\tcontext: { question: id },\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn [id, question] as const\n\t\t})\n\t\tconst matched = new Map(\n\t\t\tchecked.flatMap(([id, question]) => {\n\t\t\t\tconst judgment = this.#judgments.get(id)\n\t\t\t\treturn judgment !== undefined &&\n\t\t\t\t\tmatchesJudgment(judgment, question, origins, rendered, judge.model)\n\t\t\t\t\t? [[id, judgment] as const]\n\t\t\t\t\t: []\n\t\t\t}),\n\t\t)\n\t\tconst pending = checked.filter(([id]) => !matched.has(id))\n\t\tconst added =\n\t\t\tpending.length === 0\n\t\t\t\t? []\n\t\t\t\t: await this.#ask(\n\t\t\t\t\t\tjudge,\n\t\t\t\t\t\t{ state, questions: Object.fromEntries(pending) },\n\t\t\t\t\t\torigins,\n\t\t\t\t\t\trendered,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t)\n\t\tconst resolved = new Map([\n\t\t\t...matched,\n\t\t\t...added.map((judgment) => [judgment.id, judgment] as const),\n\t\t])\n\t\treturn entries.flatMap(([id]) => {\n\t\t\tconst judgment = resolved.get(id)\n\t\t\treturn judgment === undefined ? [] : [structuredClone(judgment)]\n\t\t})\n\t}\n\n\t// Asks the judge for the unmatched questions and stores what it answered. An aborted ask stores\n\t// its partial answers before it rethrows, so finished work survives the cancellation.\n\tasync #ask(\n\t\tjudge: JudgeInterface,\n\t\tunmatched: JudgeRequest,\n\t\torigins: readonly string[],\n\t\trendered: string,\n\t\tsignal: AbortSignal,\n\t): Promise<readonly Judgment[]> {\n\t\tif (signal.aborted) throw new JudgeAbortError({ model: judge.model, answers: {} })\n\t\ttry {\n\t\t\tconst result = await judge.ask(unmatched, signal)\n\t\t\treturn this.add(buildJudgments(unmatched, result, origins, rendered, judge.model))\n\t\t} catch (error) {\n\t\t\tif (isJudgeAbortError(error))\n\t\t\t\tthis.add(buildJudgments(unmatched, error.partial, origins, rendered, judge.model))\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t#store(input: JudgmentInput): Judgment {\n\t\tconst copy = copyJSON(input)\n\t\tconst judgment = requireJudgment(isRecord(copy) ? { ...copy, time: Date.now() } : copy)\n\t\tthis.#judgments.set(judgment.id, judgment)\n\t\treturn structuredClone(judgment)\n\t}\n}\n","import type {\n\tCompactOptions,\n\tConversationEventMap,\n\tConversationInterface,\n\tConversationOptions,\n\tConversationReferenceOptions,\n\tConversationSnapshot,\n\tConversationSummaryHandler,\n\tJudgmentManagerInterface,\n\tSection,\n} from './types.js'\nimport type { Message, MessageInput } from '../types.js'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { collectExchanges, removeEntries, stripThinking } from '../helpers.js'\nimport { DEFAULT_CONVERSATION_KEEP } from './constants.js'\nimport { ConversationError } from './errors.js'\nimport {\n\tbuildRecapMessage,\n\tbuildSummaryMessage,\n\traceSignal,\n\trequireKeep,\n\trequireRolling,\n\trequireSectionsCap,\n} from './helpers.js'\nimport { JudgmentManager } from './JudgmentManager.js'\n\n/**\n * Represents a conversation — a live uncompacted tail of messages it owns directly above a flat\n * message store, plus compacted, summarized {@link Section} records and a `summarizable` flag,\n * with on-demand `rehydrate` and substring `search`, driven by a provider-agnostic\n * {@link ConversationSummaryHandler} seam so `core` never imports a provider. Observable through\n * its own `emitter`.\n *\n * @remarks\n * - **Live tail + sections.** The conversation owns its live tail directly — `#messages` is an\n * insertion-ordered `Map` of immutable {@link Message} records keyed by their minted id\n * (`add` / `message` / `messages` / `remove` / `clear` / `count`), exactly as a `Workspace`\n * owns its files (no separate per-value manager). `#sections` are the compacted history\n * (oldest → newest), each a summarized slice that retains its originals.\n * - **`view()`.** Each section folds to one synthetic summary message (role `'assistant'` — a\n * prior-context recap — keyed by the stable `id` of the section), then the live messages\n * verbatim. The per-section summaries are the compaction benefit.\n * - **`compact()`.** Folds the oldest `count - keep` live messages into a section (its\n * `summary` from `#summarize`), removes them from the live tail by id, and emits `compact`.\n * The fold stops before the newest user message, so the request a run serves and its turns\n * stay live. An exchange is a user message and every message after it up to the next user\n * message. Leading messages form a separate exchange, retained until the first user exchange\n * can also fold. A cut inside an exchange moves back to its start, so a fold removes whole\n * exchanges. A cut inside an assistant call group, which only a group spanning two exchanges\n * allows, moves before the group, so a tool result never stays live without its call. Returns\n * the section, or `undefined` when nothing folds. A {@link ConversationError} is thrown when no\n * `#summarize` was supplied. Calls run one at a time, a fold commits only when its messages are\n * still the live entries after the summarizer settles, and `options.signal` rejects the call\n * with its reason at once and commits nothing after the abort.\n * - **Rolling.** With `rolling`, a fold makes one summarizer call over the framed recaps of all\n * prior sections then the slice, and replaces those sections with one that retains their\n * originals then the slice. It emits `compact` once and never `collapse`, commits nothing when\n * the call throws, aborts, or the slice or prior sections changed, and cannot combine with a\n * `sections` cap (`'SECTIONS'`).\n * - **`rehydrate(id)` / `search(query)`.** `rehydrate` returns the full original messages of a\n * known section and emits its `id` through `rehydrate`, even when the list is empty. An unknown\n * id returns `undefined` without an event. The read never reinserts messages. `search` is a case-insensitive\n * substring scan of `content` across all messages (the originals of every section + the live\n * tail).\n * - **Observable.** The owned {@link emitter} ({@link ConversationEventMap}) carries\n * `compact` / `collapse` / `rehydrate`, emitted directly, strictly after the state change;\n * the emitter isolates a listener throw and routes it to its `error` handler (the `error`\n * option), so a buggy observer can never corrupt a compaction.\n *\n * @example\n * ```ts\n * const conversation = new Conversation({ summarize: async (m) => `recap of ${m.length}` })\n * conversation.add([\n * \t{ role: 'user', content: 'Hello' },\n * \t{ role: 'assistant', content: 'Hi there' },\n * \t{ role: 'user', content: 'What did I say?' },\n * ])\n * const section = await conversation.compact() // folds the first two into one summarized section\n * conversation.view() // [<recap of 2>, { role: 'user', content: 'What did I say?' }]\n * ```\n */\nexport class Conversation implements ConversationInterface {\n\treadonly #id: string\n\t// The push observation surface — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into a compaction.\n\treadonly #emitter: Emitter<ConversationEventMap>\n\t// The provider-agnostic summarizer seam — `undefined` ⇒ `compact()` throws (a conversation\n\t// can still store + view a live tail; it cannot fold).\n\treadonly #summarize: ConversationSummaryHandler | undefined\n\t// How many recent live messages a `compact()` retains verbatim (older ones fold).\n\treadonly #keep: number\n\t// The optional cap on the compacted sections list — `undefined` ⇒ unlimited. Enforced\n\t// after appending a fresh `compact()` fold: an overflow folds the oldest sections into one.\n\treadonly #cap: number | undefined\n\t// Whether a fold replaces every prior section with one that digests their recaps and the slice.\n\t// Never combined with a cap.\n\treadonly #rolling: boolean\n\t// The compacted history, oldest → newest — each summarized slice retains its originals.\n\t// Replaced on every change rather than mutated in place.\n\t#sections: readonly Section[]\n\t// The live uncompacted tail the conversation owns directly — an insertion-ordered Map of\n\t// immutable messages keyed by their minted id.\n\treadonly #messages: Map<string, Message>\n\treadonly #judgments: JudgmentManager\n\t// The folds in flight, one per `compact()` call from its start until it settles. A later call\n\t// waits on every member it finds, so an aborted waiter never releases it ahead of a fold still\n\t// running.\n\treadonly #pending = new Set<Promise<Section | undefined>>()\n\n\tconstructor(options?: ConversationOptions) {\n\t\t// A summarizer is a function and is never serialized, so it comes from options beside the\n\t\t// snapshot. Restoring is silent: nothing was edited, so no event fires.\n\t\tconst snapshot = options?.snapshot\n\t\tthis.#judgments = new JudgmentManager(snapshot?.judgments)\n\t\tthis.#id = snapshot?.id ?? options?.id ?? crypto.randomUUID()\n\t\tthis.#emitter = new Emitter<ConversationEventMap>(options)\n\t\tthis.#summarize = options?.summarize\n\t\tthis.#keep = requireKeep(options?.keep ?? DEFAULT_CONVERSATION_KEEP)\n\t\tthis.#cap = requireSectionsCap(options?.sections)\n\t\tthis.#rolling = options?.rolling ?? false\n\t\trequireRolling(this.#rolling, this.#cap)\n\t\tthis.#sections = snapshot === undefined ? [] : [...snapshot.sections]\n\t\tthis.#messages = new Map(snapshot?.messages.map((message) => [message.id, message]))\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget judgments(): JudgmentManagerInterface {\n\t\treturn this.#judgments\n\t}\n\n\tget emitter(): EmitterInterface<ConversationEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget sections(): readonly Section[] {\n\t\treturn [...this.#sections]\n\t}\n\n\tget summarizable(): boolean {\n\t\t// True exactly when a summarizer was supplied — the clean signal the automatic compaction of\n\t\t// the agent loop gates on (a non-summarizable conversation is never auto-compacted, so the\n\t\t// auto path never throws the `SUMMARIZER` ConversationError). A manual `compact()` still throws.\n\t\treturn this.#summarize !== undefined\n\t}\n\n\tget count(): number {\n\t\treturn this.#messages.size\n\t}\n\n\tadd(input: MessageInput): Message\n\tadd(inputs: readonly MessageInput[]): readonly Message[]\n\tadd(input: MessageInput | readonly MessageInput[]): Message | readonly Message[] {\n\t\tif (isArray(input)) return input.map((one) => this.#create(one))\n\t\treturn this.#create(input)\n\t}\n\n\tmessage(id: string): Message | undefined {\n\t\treturn this.#messages.get(id)\n\t}\n\n\tmessages(): readonly Message[] {\n\t\treturn [...this.#messages.values()]\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\treturn removeEntries(ids, (id) => this.#messages.delete(id))\n\t\t}\n\t\treturn this.#messages.delete(ids)\n\t}\n\n\tclear(): void {\n\t\tthis.#messages.clear()\n\t}\n\n\tview(): readonly Message[] {\n\t\t// The recap is framed (a `[Summary of earlier messages]` label prefix) so a small model reads\n\t\t// it as a condensed recap of prior turns, not as a literal assistant turn it must echo / treat\n\t\t// as the latest answer — a lean label (a handful of tokens), proven no-bloat by a test guard.\n\t\treturn [\n\t\t\t...this.#sections.map((section) => buildRecapMessage(section)),\n\t\t\t...this.#messages.values(),\n\t\t]\n\t}\n\n\tasync compact(options?: CompactOptions): Promise<Section | undefined> {\n\t\tconst summarize = this.#summarize\n\t\tif (summarize === undefined) {\n\t\t\tthrow new ConversationError(\n\t\t\t\t'SUMMARIZER',\n\t\t\t\t'cannot compact a conversation without a summarizer',\n\t\t\t)\n\t\t}\n\t\tconst cap = requireSectionsCap(options?.sections ?? this.#cap)\n\t\trequireRolling(this.#rolling, cap)\n\t\tconst keep = requireKeep(options?.keep ?? this.#keep)\n\t\tconst signal = options?.signal\n\t\tsignal?.throwIfAborted()\n\t\t// Queue behind every earlier fold, captured before this call adds its own. An earlier waiter\n\t\t// that aborts leaves the folds it waited on in the set, so a later call still waits for them.\n\t\tconst previous = this.#pending.size === 0 ? undefined : Promise.allSettled([...this.#pending])\n\t\tconst fold = this.#fold(previous, summarize, cap, keep, signal)\n\t\tthis.#pending.add(fold)\n\t\tvoid fold.then(\n\t\t\t() => this.#pending.delete(fold),\n\t\t\t() => this.#pending.delete(fold),\n\t\t)\n\t\treturn fold\n\t}\n\n\trehydrate(id: string): readonly Message[] | undefined {\n\t\tconst section = this.#sections.find((one) => one.id === id)\n\t\tif (section === undefined) return undefined\n\t\t// Emitted after resolving, because a read has no mutation for a listener to perturb.\n\t\tthis.#emitter.emit('rehydrate', id)\n\t\treturn section.messages\n\t}\n\n\tsearch(query: string): readonly Message[] {\n\t\t// Section originals (oldest → newest) come before the live tail.\n\t\tconst needle = query.toLowerCase()\n\t\tconst all = [\n\t\t\t...this.#sections.flatMap((section) => section.messages),\n\t\t\t...this.#messages.values(),\n\t\t]\n\t\treturn all.filter((message) => message.content.toLowerCase().includes(needle))\n\t}\n\n\treference(options?: ConversationReferenceOptions): string {\n\t\t// The leading marker states the block is not part of the live conversation, so a small\n\t\t// model reads the cherry-picked excerpts as foreign material it attributes to that source,\n\t\t// never as its own latest turns.\n\t\tconst label = options?.label ?? this.#id\n\t\tconst messages = options?.messages ?? []\n\t\t// `Array.from` visits a hole in `messages` as an undefined message, as iteration does; `map` skips it.\n\t\treturn [\n\t\t\t`[Reference — conversation \"${label}\" — NOT part of this conversation]`,\n\t\t\t...(messages.length > 0\n\t\t\t\t? [\n\t\t\t\t\t\t'Relevant messages:',\n\t\t\t\t\t\t...Array.from(messages, (message) => `- ${message.role}: ${message.content}`),\n\t\t\t\t\t]\n\t\t\t\t: []),\n\t\t].join('\\n')\n\t}\n\n\tsnapshot(): ConversationSnapshot {\n\t\t// The summarizer / keep are not serialized — they are live config re-supplied on hydrate\n\t\t// (a ConversationSummaryHandler is a function, not data).\n\t\treturn {\n\t\t\tid: this.#id,\n\t\t\tsections: this.sections,\n\t\t\tmessages: this.messages(),\n\t\t\t...(this.#judgments.count === 0 ? {} : { judgments: this.#judgments.judgments() }),\n\t\t}\n\t}\n\n\t// One serialized fold: wait for the earlier call, read the live tail, summarize, then commit\n\t// only what is unchanged. Every await is raced against the signal and followed by a check, so\n\t// an abort commits nothing after it.\n\tasync #fold(\n\t\tprevious: Promise<unknown> | undefined,\n\t\tsummarize: ConversationSummaryHandler,\n\t\tcap: number | undefined,\n\t\tkeep: number,\n\t\tsignal: AbortSignal | undefined,\n\t): Promise<Section | undefined> {\n\t\tif (previous !== undefined) await raceSignal(previous, signal)\n\t\tsignal?.throwIfAborted()\n\t\tconst live = [...this.#messages.values()]\n\t\t// The newest user message is the request a run serves, so it and its turns stay live.\n\t\tconst newest = live.findLastIndex((message) => message.role === 'user')\n\t\tconst first = live.findIndex((message) => message.role === 'user')\n\t\tconst wanted = Math.min(\n\t\t\tkeep <= 0 ? live.length : live.length - keep,\n\t\t\tnewest === -1 ? live.length : newest,\n\t\t)\n\t\t// A cut inside an exchange moves back to that exchange's start so a whole exchange folds or\n\t\t// stays. At most one exchange strictly contains the cut.\n\t\tconst { aligned } = collectExchanges(live).reduce(\n\t\t\t(cut, exchange) => {\n\t\t\t\tconst end = cut.start + exchange.length\n\t\t\t\treturn { start: end, aligned: cut.start < wanted && wanted < end ? cut.start : cut.aligned }\n\t\t\t},\n\t\t\t{ start: 0, aligned: wanted },\n\t\t)\n\t\t// Retain the leading context until the first user exchange can fold with it.\n\t\tconst fold = first >= 0 && aligned <= first ? 0 : aligned\n\t\tif (fold <= 0) return undefined\n\t\tconst slice = live.slice(0, fold)\n\t\t// A rolling fold digests every prior recap (framed, oldest first) ahead of the slice in one\n\t\t// call; the originals behind those recaps are never sent.\n\t\tconst prior = this.#rolling ? this.#sections : []\n\t\tconst request = [...prior.map((one) => buildRecapMessage(one)), ...stripThinking(slice, 'none')]\n\t\tconst summary = await raceSignal(summarize(request, signal), signal)\n\t\tsignal?.throwIfAborted()\n\t\t// A `remove` or `clear` while the summarizer ran changed what this fold covers, so commit\n\t\t// nothing rather than fold messages the caller dropped back into a section.\n\t\tif (!slice.every((message) => this.#messages.get(message.id) === message)) return undefined\n\t\t// The recaps the digest covers must still be the sections held, or the replacement would drop\n\t\t// a section it never summarized.\n\t\tif (\n\t\t\tthis.#rolling &&\n\t\t\t(this.#sections.length !== prior.length ||\n\t\t\t\t!prior.every((one, index) => this.#sections[index] === one))\n\t\t) {\n\t\t\treturn undefined\n\t\t}\n\t\tconst section: Section = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tsummary,\n\t\t\tmessages: this.#rolling ? [...prior.flatMap((one) => one.messages), ...slice] : slice,\n\t\t}\n\t\tfor (const message of slice) this.#messages.delete(message.id)\n\t\tthis.#sections = this.#rolling ? [section] : [...this.#sections, section]\n\t\t// Preserve the original sections if the merge fails by replacing them only after summarizing.\n\t\tif (cap !== undefined && this.#sections.length > cap) {\n\t\t\tconst overflow = this.#sections.length - cap + 1\n\t\t\tconst folded = this.#sections.slice(0, overflow)\n\t\t\tconst digest = await raceSignal(\n\t\t\t\tsummarize(\n\t\t\t\t\tfolded.map((one) => buildSummaryMessage(one)),\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\tsignal,\n\t\t\t)\n\t\t\tsignal?.throwIfAborted()\n\t\t\t// Only a fold changes `#sections`, and folds run one at a time, so the head holds here;\n\t\t\t// the check keeps a merge from ever replacing sections it did not summarize.\n\t\t\tif (!folded.every((one, index) => this.#sections[index] === one)) return undefined\n\t\t\tconst merged: Section = {\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\tsummary: digest,\n\t\t\t\tmessages: folded.flatMap((one) => one.messages),\n\t\t\t}\n\t\t\tthis.#sections = [merged, ...this.#sections.slice(overflow)]\n\t\t\tthis.#emitter.emit('collapse', merged)\n\t\t}\n\t\t// Observe the section last, so a swallowed listener throw can't perturb the fold.\n\t\tthis.#emitter.emit('compact', section)\n\t\treturn section\n\t}\n\n\t// Spread each optional only when present, so an absent optional is never stored as `undefined`.\n\t#create(input: MessageInput): Message {\n\t\tconst message: Message = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\trole: input.role,\n\t\t\tcontent: input.content,\n\t\t\t...(input.calls === undefined ? {} : { calls: input.calls }),\n\t\t\t...(input.call === undefined ? {} : { call: input.call }),\n\t\t\t...(input.images === undefined ? {} : { images: input.images }),\n\t\t\t...(input.thinking === undefined ? {} : { thinking: input.thinking }),\n\t\t}\n\t\tthis.#messages.set(message.id, message)\n\t\treturn message\n\t}\n}\n","import type {\n\tConversationInput,\n\tConversationInterface,\n\tConversationManagerInterface,\n\tConversationManagerOptions,\n\tConversationStoreInterface,\n\tConversationSummaryHandler,\n} from './types.js'\nimport { isArray } from '@orkestrel/contract'\nimport { DEFAULT_CONVERSATION_KEEP } from './constants.js'\nimport { Conversation } from './Conversation.js'\nimport { requireKeep } from './helpers.js'\nimport { removeEntries } from '../helpers.js'\n\n/**\n * Registers {@link Conversation} instances keyed by `id`, in insertion order, with an active pointer —\n * the id-keyed store over the conversation layer, the `active` / `switch` seam the\n * {@link import('../contexts/index.js').AgentContext} renders, and the durable `open` / `save`\n * store seam. Event-free (a registry, like\n * {@link import('@orkestrel/workspace').WorkspaceManager}); the observability lives on each\n * {@link Conversation}.\n *\n * @remarks\n * - **Registry.** Conversations live in an insertion-ordered `Map` keyed by `id`. `add(input?)`\n * mints a {@link Conversation} (its `id` from `input` or `crypto.randomUUID()`), flowing the\n * default `#summarize` / `#keep` of the manager in unless the `input` overrides them, and stores\n * it (an already-present `id` overwrites — last write wins). `count` is the map size,\n * `conversation(id)` looks one up, `conversations()` lists them in insertion order.\n * - **Active pointer.** `active` is the active conversation (the agent's message source the\n * context renders), `undefined` until the first `add` (which auto-activates it — a registry\n * with conversations always has one active). A subsequent `add` leaves `active` unchanged.\n * `switch(id)` re-points `active` to the conversation with `id` and returns it; an unknown `id`\n * returns `undefined` and leaves `active` unchanged (the lenient lookup style — never throws,\n * no added error code).\n * - **Removal.** `remove` drops one by id, or a batch — `true` only when every supplied id was\n * removed; removing the active conversation sets `active` to `undefined`. `clear` empties the registry\n * and sets `active` to `undefined`.\n * - **Event-free.** A purely registry store — no Emitter, no events (each conversation owns\n * its own observable `emitter`).\n *\n * @example\n * ```ts\n * const manager = new ConversationManager({ summarize: async (m) => `recap of ${m.length}` })\n * const conversation = manager.add() // auto-activates — active === conversation\n * manager.add({ id: 'scratch' }) // leaves active unchanged\n * manager.switch('scratch') // re-points active to the 'scratch' conversation\n * manager.count // 2\n * ```\n */\nexport class ConversationManager implements ConversationManagerInterface {\n\treadonly #conversations = new Map<string, ConversationInterface>()\n\t// The active conversation's id — the message source the context renders; `undefined` until the\n\t// first `add` auto-activates one (kept as an id, never a stale reference, so a re-add / removal\n\t// of that id is reflected through the live map lookup in `active`).\n\t#active: string | undefined\n\t// The default summarizer flowed into every conversation `add` creates (a per-`add` override\n\t// wins); a conversation created with neither cannot `compact` (it throws a ConversationError).\n\treadonly #summarize: ConversationSummaryHandler | undefined\n\t// The default retained-tail size flowed into every conversation `add` creates (overridable).\n\treadonly #keep: number\n\t// The default `sections` cap flowed into every conversation `add` creates (overridable); `undefined` ⇒ unlimited.\n\treadonly #sections: number | undefined\n\t// The optional durable store backing `open` / `save`; `undefined` ⇒ registry-only (both lenient).\n\treadonly #store: ConversationStoreInterface | undefined\n\n\tconstructor(options?: ConversationManagerOptions) {\n\t\tthis.#summarize = options?.summarize\n\t\tthis.#keep = requireKeep(options?.keep ?? DEFAULT_CONVERSATION_KEEP)\n\t\tthis.#sections = options?.sections\n\t\tthis.#store = options?.store\n\t}\n\n\tget count(): number {\n\t\treturn this.#conversations.size\n\t}\n\n\tget active(): ConversationInterface | undefined {\n\t\treturn this.#active === undefined ? undefined : this.#conversations.get(this.#active)\n\t}\n\n\tconversation(id: string): ConversationInterface | undefined {\n\t\treturn this.#conversations.get(id)\n\t}\n\n\tconversations(): readonly ConversationInterface[] {\n\t\treturn [...this.#conversations.values()]\n\t}\n\n\tadd(input?: ConversationInput): ConversationInterface {\n\t\t// An optional `snapshot` hydrates through the declared `ConversationOptions.snapshot` seam,\n\t\t// so the live summarize / keep ride beside it in the same options object.\n\t\tconst sections = input?.sections ?? this.#sections\n\t\tconst summarize = input?.summarize ?? this.#summarize\n\t\tconst conversation = new Conversation({\n\t\t\t...(input?.id === undefined ? {} : { id: input.id }),\n\t\t\t...(input?.on === undefined ? {} : { on: input.on }),\n\t\t\t...(input?.error === undefined ? {} : { error: input.error }),\n\t\t\t...(summarize === undefined ? {} : { summarize }),\n\t\t\tkeep: input?.keep ?? this.#keep,\n\t\t\t...(sections === undefined ? {} : { sections }),\n\t\t\t...(input?.rolling === undefined ? {} : { rolling: input.rolling }),\n\t\t\t...(input?.snapshot === undefined ? {} : { snapshot: input.snapshot }),\n\t\t})\n\t\tthis.#conversations.set(conversation.id, conversation)\n\t\t// First conversation auto-activates: a registry that holds conversations always has one active.\n\t\tif (this.#active === undefined) this.#active = conversation.id\n\t\treturn conversation\n\t}\n\n\tswitch(id: string): ConversationInterface | undefined {\n\t\t// Lenient (mirrors `conversation(id)`): an unknown id re-points nothing and returns undefined.\n\t\tconst conversation = this.#conversations.get(id)\n\t\tif (conversation === undefined) return undefined\n\t\tthis.#active = id\n\t\treturn conversation\n\t}\n\n\tasync open(id: string): Promise<ConversationInterface | undefined> {\n\t\tconst existing = this.#conversations.get(id)\n\t\tif (existing !== undefined) {\n\t\t\tthis.#active = id\n\t\t\treturn existing\n\t\t}\n\t\tif (this.#store === undefined) return undefined\n\t\tconst snapshot = await this.#store.get(id)\n\t\t// A conversation registered while the read was pending is live state; the stored snapshot\n\t\t// is older, so it must not overwrite it.\n\t\tconst registered = this.#conversations.get(id)\n\t\tif (registered !== undefined) {\n\t\t\tthis.#active = id\n\t\t\treturn registered\n\t\t}\n\t\t// A store answering with another conversation's snapshot would register and activate the\n\t\t// wrong id, so only a snapshot of `id` hydrates.\n\t\tif (snapshot === undefined || snapshot.id !== id) return undefined\n\t\t// Reuse `add` so the default summarize / keep of the manager flow into the rehydrated conversation.\n\t\tconst conversation = this.add({ snapshot })\n\t\t// Re-point `active` explicitly: `add` only auto-activates the first conversation, so an open\n\t\t// into a non-empty registry must still make the rehydrated one active.\n\t\tthis.#active = conversation.id\n\t\treturn conversation\n\t}\n\n\tasync save(id: string): Promise<boolean> {\n\t\tconst conversation = this.#conversations.get(id)\n\t\tif (this.#store === undefined || conversation === undefined) return false\n\t\tawait this.#store.set(conversation.snapshot())\n\t\treturn true\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\t// Each present id still clears `active` when it was the active conversation.\n\t\t\treturn removeEntries(ids, (id) => this.#drop(id))\n\t\t}\n\t\treturn this.#drop(ids)\n\t}\n\n\tclear(): void {\n\t\tthis.#conversations.clear()\n\t\t// An emptied registry has no active conversation.\n\t\tthis.#active = undefined\n\t}\n\n\t// Delete one conversation by id; when it was the active one, clear the active pointer (a removed\n\t// conversation can never stay active).\n\t#drop(id: string): boolean {\n\t\tconst removed = this.#conversations.delete(id)\n\t\tif (removed && this.#active === id) this.#active = undefined\n\t\treturn removed\n\t}\n}\n","import type { ConversationSnapshot, ConversationStoreInterface } from '../types.js'\n\n/**\n * Implements the {@link ConversationStoreInterface} in memory — a process-lifetime `Map` of\n * {@link ConversationSnapshot} records keyed by conversation id, the default store\n * {@link import('../factories.js').createMemoryConversationStore} builds and the default\n * backing for `open` / `save`. The exact twin of\n * {@link import('@orkestrel/workspace').MemoryWorkspaceStore}.\n *\n * @remarks\n * A plain `Map<string, ConversationSnapshot>` — the snapshot is already pure,\n * self-contained JSON, so no encoding is needed for the memory tier. Like the\n * {@link import('@orkestrel/workspace').MemoryWorkspaceStore} it twins,\n * there is no idle-TTL and no eviction: a persisted conversation lives until an explicit `delete`. A\n * durable backend (JSON / SQLite / IndexedDB) swaps in through the same interface without touching\n * the {@link import('../ConversationManager.js').ConversationManager} or the\n * {@link import('../Conversation.js').Conversation} — its driver-pluggable twin is\n * {@link import('./DatabaseConversationStore.js').DatabaseConversationStore} (the snapshot as one\n * opaque JSON column).\n *\n * - **`get` resolves the persisted snapshot for an id**, or `undefined` if none is stored.\n * - **`set` inserts / replaces under the snapshot's own `id`** (no separate id param).\n * - **`delete` drops a snapshot by id**; an absent id is a no-op (no throw).\n *\n * The public surface is exactly `get` / `set` / `delete` — no extra members (the method\n * bijection with {@link ConversationStoreInterface}). Hydration is a caller concern: a\n * {@link import('../ConversationManager.js').ConversationManager} reads a snapshot back and rebuilds\n * the live conversation through the `snapshot` option (its `open` / `save`).\n *\n * @example\n * ```ts\n * import { createConversation, createMemoryConversationStore } from '@orkestrel/agent'\n *\n * const store = createMemoryConversationStore()\n * const conversation = createConversation()\n * conversation.add({ role: 'user', content: 'hello' })\n * await store.set(conversation.snapshot()) // persist the conversation\n * const snapshot = await store.get(conversation.id)\n * await store.delete(conversation.id) // drop it\n * ```\n */\nexport class MemoryConversationStore implements ConversationStoreInterface {\n\treadonly #snapshots = new Map<string, ConversationSnapshot>()\n\n\t/**\n\t * Resolves the persisted snapshot for `id`, or `undefined` if none is stored.\n\t *\n\t * @param id - The conversation id to resolve (a {@link ConversationSnapshot.id})\n\t * @returns The persisted snapshot, or `undefined` if absent\n\t */\n\tget(id: string): Promise<ConversationSnapshot | undefined> {\n\t\treturn Promise.resolve(this.#snapshots.get(id))\n\t}\n\n\t/**\n\t * Inserts or replaces a snapshot under its own `snapshot.id` (no separate id param —\n\t * mirroring the `set` method of {@link import('@orkestrel/workspace').WorkspaceStoreInterface}).\n\t *\n\t * @param snapshot - The snapshot to store (keyed by its `id`)\n\t * @returns A promise that resolves after the snapshot is stored\n\t */\n\tset(snapshot: ConversationSnapshot): Promise<void> {\n\t\tthis.#snapshots.set(snapshot.id, snapshot)\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Drops a snapshot by id; an absent id is a no-op (no throw).\n\t *\n\t * @param id - The conversation id to drop\n\t * @returns A promise that resolves after the snapshot is dropped\n\t */\n\tdelete(id: string): Promise<void> {\n\t\t// `Map.delete` of an absent id is a no-op, so no presence check is needed.\n\t\tthis.#snapshots.delete(id)\n\t\treturn Promise.resolve()\n\t}\n}\n","import type {\n\tConversationSnapshot,\n\tConversationSnapshotRow,\n\tConversationStoreInterface,\n} from '../types.js'\nimport type { TableInterface } from '@orkestrel/database'\nimport { isConversationSnapshot } from '../validators.js'\n\n/**\n * Backs a {@link ConversationStoreInterface} with one table of the `databases` layer — a\n * conversation's durable state is a row holding the snapshot as one opaque JSON column, narrowed\n * back on `get` by {@link import('../validators.js').isConversationSnapshot}, so persistence\n * reduces to keyed point-access (`get` / `set` / `delete`) over a {@link TableInterface}. The\n * driver-pluggable twin of the plain-`Map`\n * {@link import('./MemoryConversationStore.js').MemoryConversationStore}, and the exact twin of\n * {@link import('@orkestrel/workspace').DatabaseWorkspaceStore}.\n *\n * @remarks\n * The store is driver-agnostic: it holds a single {@link TableInterface} whose backend (memory,\n * JSON, SQLite, IndexedDB) is chosen by whoever builds it (the factories), so a JSON / SQLite /\n * IndexedDB backend swaps in without touching the\n * {@link import('../ConversationManager.js').ConversationManager} or the\n * {@link import('../Conversation.js').Conversation} — the same seam as\n * {@link import('@orkestrel/workspace').DatabaseWorkspaceStore}. Default driver: memory\n * ({@link import('../factories.js').createDatabaseConversationStore} passes\n * `createMemoryDriver()`), so it also works in memory out of the box; you opt into the\n * durable plumbing by passing a JSON / SQLite / IndexedDB driver.\n *\n * The {@link ConversationSnapshot} is stored as one opaque JSON column — the table is a row of\n * `{ id; snapshot }` ({@link ConversationSnapshotRow}), the snapshot the whole JSON blob (a\n * `rawShape` column the factory builds) — exactly as `DatabaseWorkspaceStore` stores its snapshot.\n * The snapshot is already a complete, self-contained, pure-JSON payload, so storing it whole is\n * lossless and keeps the row type flat (`snapshot` reads back as `unknown`).\n *\n * - **`set(snapshot)` upserts under the snapshot's own `id`** (no separate id param) — it writes\n * the row `{ id: snapshot.id, snapshot }`.\n * - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to\n * a {@link ConversationSnapshot} ({@link import('../validators.js').isConversationSnapshot} — the\n * total guard for an untrusted storage read), or `undefined` if none is stored, the blob is\n * malformed, or the blob's own `id` is not the requested one.\n * - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).\n *\n * Unlike a session store there is no idle-TTL / eviction — a persisted conversation lives until an\n * explicit `delete`. The public surface is exactly `get` / `set` / `delete` — no extra members (the\n * method bijection with {@link ConversationStoreInterface}). Hydration stays a caller concern: a\n * {@link import('../ConversationManager.js').ConversationManager} reads a snapshot back and rebuilds\n * the live conversation through the `snapshot` option (its `open` / `save`).\n *\n * @example\n * ```ts\n * import { createConversation, createDatabaseConversationStore } from '@orkestrel/agent'\n * import { createMemoryDriver } from '@orkestrel/database'\n *\n * const store = createDatabaseConversationStore(createMemoryDriver()) // a durable driver swaps in here\n * const conversation = createConversation()\n * conversation.add({ role: 'user', content: 'hello' })\n * await store.set(conversation.snapshot()) // persist the conversation (one JSON column)\n * const snapshot = await store.get(conversation.id)\n * await store.delete(conversation.id) // drop it\n * ```\n */\nexport class DatabaseConversationStore implements ConversationStoreInterface {\n\treadonly #table: TableInterface<ConversationSnapshotRow>\n\n\t/**\n\t * Wraps a table as a conversation store.\n\t *\n\t * @param table - The {@link TableInterface} holding the snapshots — its row is the\n\t * {@link ConversationSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)\n\t */\n\tconstructor(table: TableInterface<ConversationSnapshotRow>) {\n\t\tthis.#table = table\n\t}\n\n\t/**\n\t * Resolves the persisted snapshot for `id`, narrowing the opaque JSON column back to a\n\t * `ConversationSnapshot`.\n\t *\n\t * @remarks\n\t * The column is an untrusted storage read, so a blob that fails\n\t * {@link import('../validators.js').isConversationSnapshot}, or whose own `id` is not `id`,\n\t * resolves `undefined` rather than a conversation under the wrong key.\n\t *\n\t * @param id - The conversation id to resolve (the row key)\n\t * @returns The persisted snapshot, or `undefined` when no row is stored, the blob is malformed,\n\t * or the blob names another id\n\t */\n\tasync get(id: string): Promise<ConversationSnapshot | undefined> {\n\t\tconst row = await this.#table.get(id)\n\t\tif (row === undefined) return undefined\n\t\t// The snapshot crosses back as an untrusted storage read (a structured clone / a JSON row),\n\t\t// so narrow the opaque JSON column with the total boundary guard rather than a cast;\n\t\t// a malformed blob resolves `undefined`, never a broken conversation.\n\t\tconst snapshot = row.snapshot\n\t\treturn isConversationSnapshot(snapshot) && snapshot.id === id ? snapshot : undefined\n\t}\n\n\t/**\n\t * Inserts or replaces under the snapshot's own `id` (no separate id param) — the row is\n\t * `{ id, snapshot }`.\n\t *\n\t * @param snapshot - The snapshot to store, keyed by its `id`\n\t * @returns A promise that resolves once the row is written\n\t */\n\tasync set(snapshot: ConversationSnapshot): Promise<void> {\n\t\tawait this.#table.set({ id: snapshot.id, snapshot })\n\t}\n\n\t/**\n\t * Drops a snapshot by id; an absent id is a no-op (no throw).\n\t *\n\t * @param id - The conversation id to drop\n\t * @returns A promise that resolves once the row is gone\n\t */\n\tasync delete(id: string): Promise<void> {\n\t\tawait this.#table.remove(id)\n\t}\n}\n","import type {\n\tConversationInterface,\n\tConversationManagerInterface,\n\tConversationManagerOptions,\n\tConversationOptions,\n\tConversationSnapshotRow,\n\tConversationStoreInterface,\n} from './types.js'\nimport type { DriverInterface, TableInterface } from '@orkestrel/database'\nimport { rawShape, stringShape } from '@orkestrel/contract'\nimport { createDatabase, createMemoryDriver } from '@orkestrel/database'\nimport { Conversation } from './Conversation.js'\nimport { ConversationManager } from './ConversationManager.js'\nimport { MemoryConversationStore } from './stores/MemoryConversationStore.js'\nimport { DatabaseConversationStore } from './stores/DatabaseConversationStore.js'\n\n/**\n * Creates a conversation — a {@link ConversationInterface} grouping messages above a flat\n * message store it owns directly, with compaction into summarized sections, on-demand\n * `rehydrate`, and substring `search`, driven by a provider-agnostic\n * {@link ConversationSummaryHandler} seam.\n *\n * @remarks\n * Append turns through the conversation's own `add` (the live tail it owns); `view()` is the model input\n * (each section as a summary message, then the live tail). `compact()` folds the older live\n * messages into a summarized {@link Section}, whole exchanges at a time — it requires a\n * `summarize` (without one `compact()` throws a `ConversationError`); `keep` retains a recent\n * tail (Default: `DEFAULT_CONVERSATION_KEEP`, which folds up to the newest user message).\n * `rehydrate(id)` / `search(query)` read the retained originals. Observable (`emitter` —\n * `compact` / `collapse` / `rehydrate`), wired\n * through the reserved `on` option; the emitter isolates a listener throw and routes it to\n * its `error` handler (the `error` option), so it can never corrupt a compaction.\n *\n * @param options - Optional `id` / `on` hooks + the `summarize` seam + `keep` + `sections` (see {@link ConversationOptions})\n * @returns A working {@link ConversationInterface}\n *\n * @example Conversations & compaction\n * ```ts\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { createConversation } from '@orkestrel/agent'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * // The summarizer seam — built from the provider by the runtime; core stays provider-agnostic.\n * // Append the instruction as the FINAL user turn: a chat model emits nothing when the prompt\n * // ends on an assistant turn, so a leading-system instruction is unreliable.\n * const conversation = createConversation({\n * \tsummarize: async (messages, signal) =>\n * \t\t(\n * \t\t\tawait provider.generate(\n * \t\t\t\t[\n * \t\t\t\t\t...messages,\n * \t\t\t\t\t{ id: 's', role: 'user', content: 'Summarize the conversation so far concisely.' },\n * \t\t\t\t],\n * \t\t\t\tsignal ?? AbortSignal.timeout(30_000), // the compact() call's signal, when it passed one\n * \t\t\t)\n * \t\t).content,\n * \tkeep: 2, // retain at least the 2 most recent messages verbatim on each compaction\n * })\n * conversation.add([\n * \t{ role: 'user', content: 'My name is Ada.' },\n * \t{ role: 'assistant', content: 'Nice to meet you, Ada.' },\n * \t{ role: 'user', content: 'Book a table for two at 19:00.' },\n * \t{ role: 'assistant', content: 'Booked for two at 19:00.' },\n * \t{ role: 'user', content: 'What did I say my name was?' },\n * ])\n *\n * const section = await conversation.compact() // folds the first exchange → a summarized section\n * conversation.view() // [<section summary message>, ...the retained recent exchanges] — the model input\n * conversation.search('ada') // case-insensitive across sections' originals + the live tail\n * section && conversation.rehydrate(section.id) // the section's full original messages (a pure read)\n * ```\n */\nexport function createConversation(options?: ConversationOptions): ConversationInterface {\n\treturn new Conversation(options)\n}\n\n/**\n * Creates a conversation registry — a {@link ConversationManagerInterface} holding\n * {@link ConversationInterface} instances keyed by their `id`, in insertion order, with an active pointer:\n * the id-keyed store over the conversation layer plus the `active` / `switch` seam the context\n * renders. `add` auto-activates the first conversation and flows the registry's default\n * `summarize` / `keep` into every conversation it creates.\n *\n * @remarks\n * Starts empty; `add(input?)` mints a {@link ConversationInterface} (its `id` from the input\n * or a random UUID), flowing the manager's default `summarize` / `keep` in unless the input\n * overrides them, and stores it (an already-present `id` overwrites — last write wins) — and\n * auto-activates the first one (a registry with conversations always has one `active`); a later\n * `add` leaves `active` unchanged. `switch(id)` re-points `active` (an unknown `id` returns\n * `undefined`, leaving `active` unchanged — lenient, never throws); `conversation(id)` /\n * `conversations()` look up; `remove` (one or a batch) reports `true` only when every supplied id\n * was removed and clears `active` if it was a removed one; `clear` empties it and clears `active`.\n * Event-free\n * (each conversation owns its own observable `emitter`). A conversation created with neither a\n * manager default nor a per-`add` `summarize` cannot `compact` (it throws a `ConversationError`).\n *\n * @param options - Optional default `summarize` / `keep` (see {@link ConversationManagerOptions})\n * @returns An empty {@link ConversationManagerInterface}\n *\n * @example\n * ```ts\n * import { createConversationManager } from '@orkestrel/agent'\n *\n * const conversations = createConversationManager({ summarize: async (m) => `recap of ${m.length}` })\n * const chat = conversations.add() // auto-activates — conversations.active === chat\n * chat.add({ role: 'user', content: 'Hello' })\n * ```\n */\nexport function createConversationManager(\n\toptions?: ConversationManagerOptions,\n): ConversationManagerInterface {\n\treturn new ConversationManager(options)\n}\n\n/**\n * Creates the in-memory conversation store — a {@link ConversationStoreInterface} backed by a\n * process-lifetime `Map` of {@link import('./types.js').ConversationSnapshot} records keyed by conversation\n * id, the default backing for the durable {@link ConversationManagerInterface.open} /\n * {@link ConversationManagerInterface.save} seam. The exact twin of\n * {@link import('@orkestrel/workspace').createMemoryWorkspaceStore}.\n *\n * @remarks\n * A plain `Map` (the snapshot is already pure JSON, so no encoding is needed for the memory tier),\n * the structural twin of {@link import('@orkestrel/workspace').createMemoryWorkspaceStore}.\n * `get` / `set` / `delete` are async (the\n * same shape a durable backend fits); unlike a session store there is no idle-TTL / eviction — a\n * persisted conversation lives until an explicit `delete`. Its driver-pluggable twin is\n * {@link createDatabaseConversationStore} (the snapshot as one opaque JSON column over a `databases`\n * table) — for a durable store pass it a JSON / SQLite / IndexedDB driver, and it swaps in without\n * touching the manager or the conversation. Hydration stays a manager concern: read a snapshot back\n * and rebuild the live conversation through the `snapshot` option (re-supplying the live\n * `summarize` / `keep`).\n *\n * @returns A memory-backed {@link ConversationStoreInterface}\n *\n * @example\n * ```ts\n * import { createConversationManager, createMemoryConversationStore } from '@orkestrel/agent'\n *\n * const store = createMemoryConversationStore()\n * const manager = createConversationManager({ store })\n * const conversation = manager.add()\n * conversation.add({ role: 'user', content: 'hello' })\n * await manager.save(conversation.id) // persist the conversation\n * ```\n */\nexport function createMemoryConversationStore(): ConversationStoreInterface {\n\treturn new MemoryConversationStore()\n}\n\n/**\n * Creates a {@link DatabaseConversationStore} over any {@link DriverInterface} — the durable,\n * driver-pluggable backing for the conversation persistence\n * seam, holding each snapshot as one opaque JSON column and standing as the opt-in twin of\n * {@link createMemoryConversationStore}. The exact twin of\n * {@link import('@orkestrel/workspace').createDatabaseWorkspaceStore}.\n *\n * @remarks\n * Builds a one-table database (`conversations`, keyed by `id`) over the supplied driver, the snapshot\n * held as one opaque JSON column — the column map is `{ id; snapshot }` where `snapshot` is a\n * `rawShape` (a JSON blob), exactly as\n * {@link import('@orkestrel/workspace').createDatabaseWorkspaceStore} stores its snapshot. The\n * snapshot is already a complete, self-contained, pure-JSON payload, so storing it whole is lossless\n * and keeps the row type flat (the column reads back as `unknown`, narrowed on `get` by\n * {@link import('./validators.js').isConversationSnapshot}). Default driver:\n * {@link createMemoryDriver}, so the store also works in memory out of the box; pass a server\n * `createJSONDriver` / `createSQLiteDriver` (or a browser IndexedDB driver) for a persistent one —\n * the durability is the driver's job, the store engine is shared. It swaps in behind\n * {@link ConversationStoreInterface} without touching the manager or the conversation.\n *\n * @param driver - The storage backend the snapshots persist to. Default: {@link createMemoryDriver}\n * @returns A {@link ConversationStoreInterface} over the driver\n *\n * @example\n * ```ts\n * import { createConversationManager, createDatabaseConversationStore } from '@orkestrel/agent'\n * import { createMemoryDriver } from '@orkestrel/database'\n *\n * const store = createDatabaseConversationStore(createMemoryDriver()) // a durable driver swaps in here\n * const manager = createConversationManager({ store })\n * const conversation = manager.add()\n * conversation.add({ role: 'user', content: 'hello' })\n * await manager.save(conversation.id) // persist the conversation (one JSON column)\n * ```\n */\nexport function createDatabaseConversationStore(\n\tdriver: DriverInterface = createMemoryDriver(),\n): ConversationStoreInterface {\n\t// The snapshot is stored as one opaque JSON column (`rawShape`), so the row infers flat —\n\t// `{ id: string; snapshot: unknown }` = `ConversationSnapshotRow` — and the sections/messages\n\t// snapshot shape never forces a contract `Infer`.\n\tconst columns = { id: stringShape(), snapshot: rawShape({}) }\n\tconst database = createDatabase({ driver, tables: { conversations: columns } })\n\tconst table: TableInterface<ConversationSnapshotRow> = database.table('conversations')\n\treturn new DatabaseConversationStore(table)\n}\n","/**\n * Names the section header the `build()` method of {@link import('./AgentContext.js').AgentContext}\n * renders the active workspace's text files under — `'## Workspace'`, the leading line of the dedicated\n * workspace block in the system message.\n *\n * @remarks\n * `build()` owns the workspace render (a `Workspace` / `WorkspaceManager` stays file-focused — no\n * `open` / `format` getters), so this header lives here as the contexts module's one\n * workspace-section framing constant rather than on a manager. Each workspace text file renders\n * beneath it as a fenced `` File: <path>\\n```<language>\\n<text>\\n``` `` block through\n * {@link import('./helpers.js').renderFencedFile}, and the block is placed immediately after the\n * instructions section in the system block. The workspace's image files render no section: their\n * `base64` payload attaches to the last user message.\n */\nexport const WORKSPACE_SECTION_HEADER = '## Workspace'\n","import type { InstructionInput, InstructionInterface } from '../types.js'\n\n/**\n * Represents an immutable named directive — an {@link InstructionInterface} assembled once from\n * its input (`name` / `content` and an optional `priority`), the `id` minted at\n * construction. Default: `0` for `priority`.\n *\n * @remarks\n * A thin immutable value object (mirroring {@link import('@orkestrel/tool').Tool}): the\n * constructor mints a fresh `id` (`crypto.randomUUID()`), copies the input's `name` /\n * `content`, resolves `priority` to the input's value or `0`, and carries the input's\n * per-item `override` value when supplied; otherwise that property is `undefined`.\n * Never mutated after construction. An\n * {@link import('./InstructionManager.js').InstructionManager} keys it by `name` and\n * renders it (highest `priority` first) under its section header.\n *\n * @example\n * ```ts\n * const instruction = new Instruction({ name: 'tone', content: 'Be concise.', priority: 5 })\n * instruction.priority // 5\n * ```\n */\nexport class Instruction implements InstructionInterface {\n\treadonly id: string\n\treadonly name: string\n\treadonly content: string\n\treadonly priority: number\n\treadonly override?: string\n\n\tconstructor(input: InstructionInput) {\n\t\tthis.id = crypto.randomUUID()\n\t\tthis.name = input.name\n\t\tthis.content = input.content\n\t\tthis.priority = input.priority ?? 0\n\t\tif (input.override !== undefined) this.override = input.override\n\t}\n}\n","import type {\n\tContextSectionFormat,\n\tInstructionInput,\n\tInstructionInterface,\n\tInstructionManagerEventMap,\n\tInstructionManagerInterface,\n\tInstructionManagerOptions,\n} from '../types.js'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { removeEntries } from '../../helpers.js'\nimport { Instruction } from './Instruction.js'\n\n/**\n * Registers the immutable {@link Instruction} instances a richer context assembles a directives block\n * from — keyed by `name` so adding an instruction whose name is already stored overwrites it,\n * last write wins, and listed by descending `priority`, carrying the `open` / `render` / `close` build contract and an observable `emitter`.\n *\n * @remarks\n * - **Registry.** Instructions live in an insertion-ordered `Map` keyed by `name`;\n * `add` takes one {@link InstructionInput} or a batch, mints each instruction's\n * `id`, and adding an instruction whose name is already stored overwrites it (last write wins).\n * `count` is the map size, `instruction(name)` looks one up, and `instructions()` lists them sorted by\n * descending `priority` (a stable sort, so equal priorities keep insertion order).\n * - **Build contract (the whole format cascade).** `open` is the section header a context\n * renders the instructions under, `render(instruction)` renders one instruction, and\n * `close` is the line after them. Each resolves the cascade most-specific-first: `render`\n * returns the instruction's {@link InstructionInput.override}, else the\n * `InstructionManagerOptions.format` `render`, else its `content`; `open` returns the\n * options `open`, else the built-in header; `close` returns the options `close`, else\n * `undefined`. A context reads the three and frames the section from them (see\n * {@link import('../AgentContext.js').AgentContext}).\n * - **Removal.** `remove` drops one by name, or a batch — `true` only when every supplied\n * name was removed; `clear` empties the registry.\n * - **Observable.** The owned {@link emitter} ({@link InstructionManagerEventMap})\n * carries `add` (the created instruction) / `remove` (the name) / `clear` for\n * fire-and-forget observers. Every event is emitted directly, strictly after the map\n * mutation completes; the emitter isolates a listener throw and routes it to its `error`\n * handler (the `error` option), so a buggy observer can never corrupt a mutation.\n *\n * @example\n * ```ts\n * const manager = new InstructionManager()\n * manager.add([\n * \t{ name: 'tone', content: 'Be concise.', priority: 1 },\n * \t{ name: 'safety', content: 'Refuse unsafe requests.', priority: 10 },\n * ])\n * manager.instructions().map((one) => one.name) // ['safety', 'tone'] — highest priority first\n * ```\n */\nexport class InstructionManager implements InstructionManagerInterface {\n\treadonly #instructions = new Map<string, InstructionInterface>()\n\t// The push observation surface — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into a mutation.\n\treadonly #emitter: Emitter<InstructionManagerEventMap>\n\treadonly #format: ContextSectionFormat<InstructionInterface> | undefined\n\n\tconstructor(options?: InstructionManagerOptions) {\n\t\tthis.#emitter = new Emitter<InstructionManagerEventMap>(options)\n\t\tthis.#format = options?.format\n\t}\n\n\tget emitter(): EmitterInterface<InstructionManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#instructions.size\n\t}\n\n\tget open(): string {\n\t\treturn this.#format?.open ?? '## Instructions'\n\t}\n\n\tget close(): string | undefined {\n\t\treturn this.#format?.close\n\t}\n\n\tadd(input: InstructionInput): InstructionInterface\n\tadd(inputs: readonly InstructionInput[]): readonly InstructionInterface[]\n\tadd(\n\t\tinput: InstructionInput | readonly InstructionInput[],\n\t): InstructionInterface | readonly InstructionInterface[] {\n\t\tif (isArray(input)) return input.map((one) => this.#create(one))\n\t\treturn this.#create(input)\n\t}\n\n\tinstruction(name: string): InstructionInterface | undefined {\n\t\treturn this.#instructions.get(name)\n\t}\n\n\tinstructions(): readonly InstructionInterface[] {\n\t\t// A stable descending-priority sort — Array.prototype.sort is stable, so equal\n\t\t// priorities keep their insertion order (the map's iteration order).\n\t\treturn [...this.#instructions.values()].sort((a, b) => b.priority - a.priority)\n\t}\n\n\trender(instruction: InstructionInterface): string {\n\t\treturn instruction.override ?? this.#format?.render?.(instruction) ?? instruction.content\n\t}\n\n\tremove(name: string): boolean\n\tremove(names: readonly string[]): boolean\n\tremove(names: string | readonly string[]): boolean {\n\t\tif (isArray(names)) {\n\t\t\t// Each present name still emits.\n\t\t\treturn removeEntries(names, (name) => this.#delete(name))\n\t\t}\n\t\treturn this.#delete(names)\n\t}\n\n\tclear(): void {\n\t\tthis.#instructions.clear()\n\t\t// Observe the cleared registry — after the map emptied, so a swallowed listener\n\t\t// throw can never alter the clear (no payload — `clear` is a pure signal).\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\t// Mint an immutable instruction, store it by name (overwriting a same-name one), and\n\t// emit `add` after the map mutation — so a swallowed listener throw can't perturb it.\n\t#create(input: InstructionInput): InstructionInterface {\n\t\tconst instruction = new Instruction(input)\n\t\tthis.#instructions.set(instruction.name, instruction)\n\t\tthis.#emitter.emit('add', instruction)\n\t\treturn instruction\n\t}\n\n\t// Delete one instruction, emitting `remove` only when one was actually removed (a\n\t// delete of an absent name returns `false` and emits nothing) — after the deletion.\n\t#delete(name: string): boolean {\n\t\tconst removed = this.#instructions.delete(name)\n\t\tif (removed) this.#emitter.emit('remove', name)\n\t\treturn removed\n\t}\n}\n","import type { Message } from '../types.js'\nimport type { FileInterface } from '@orkestrel/workspace'\nimport { isBinary } from '@orkestrel/workspace'\n\n/**\n * Renders a path-addressed text body as a fenced reference block — a `File: <path>` label line\n * over a language-tagged fence, the framing the\n * active-workspace text-file render of {@link import('./AgentContext.js').AgentContext} emits.\n *\n * @remarks\n * Produces `` File: <path>\\n```<language>\\n<content>\\n``` `` — the `File:` label line, then a\n * fenced code block tagged with `language`, the `content` verbatim inside. The fence is one\n * backtick longer than the longest backtick run in `content`, and never shorter than three (the\n * CommonMark rule), so file text holding a triple backtick cannot close the block early and\n * land outside it; content with no run of three or more keeps the three-backtick fence. Pure\n * string assembly, total — never throws. The one fenced-file format string for the whole\n * module — `AgentContext.build()` frames an active workspace's text files with it (each carries\n * its own `language` on its {@link import('@orkestrel/workspace').FileContent} text arm).\n *\n * @param path - The file path shown on the `File:` label line\n * @param language - The fenced-code language tag (for example `'typescript'`)\n * @param content - The file body rendered verbatim inside the fence\n * @returns The fenced reference block\n *\n * @example\n * ```ts\n * import { renderFencedFile } from '@orkestrel/agent'\n *\n * renderFencedFile('src/main.ts', 'typescript', 'const x = 1')\n * // 'File: src/main.ts\\n```typescript\\nconst x = 1\\n```'\n * ```\n */\nexport function renderFencedFile(path: string, language: string, content: string): string {\n\tconst runs = content.match(/`+/g) ?? []\n\tconst longest = runs.reduce((most, run) => Math.max(most, run.length), 0)\n\tconst fence = '`'.repeat(Math.max(3, longest + 1))\n\treturn `File: ${path}\\n${fence}${language}\\n${content}\\n${fence}`\n}\n\n/**\n * Renders one context section — the resolved `open`, each item's rendering, and the resolved\n * `close` when one exists, blank-line joined; `undefined` when the section has no items.\n *\n * @remarks\n * Pure and total. A section with no items renders nothing (`undefined`), so an empty or fully\n * scoped-out manager stays silent — its `open` / `close` appear only when the section has items.\n * An empty or absent slot is dropped before the join, so an `open: ''`, a `close: ''`, an unset\n * `close` (there is no built-in close), and an item rendered to `''` each add no blank line; a\n * section whose every slot is empty renders nothing (`undefined`).\n *\n * @typeParam T - The section item being rendered\n * @param open - The section's resolved leading text\n * @param members - The already scope-filtered items\n * @param render - Renders one item to its prompt text\n * @param close - The section's resolved trailing text, or `undefined` for none\n * @returns The rendered section, or `undefined` when there are no items or every slot is empty\n *\n * @example\n * ```ts\n * renderSection('## Instructions', [{ content: 'Be terse.' }], (one) => one.content, undefined)\n * // '## Instructions\\n\\nBe terse.'\n * renderSection('<rules>', [], (one) => one.content, '</rules>') // undefined (no items)\n * ```\n */\nexport function renderSection<T>(\n\topen: string,\n\tmembers: readonly T[],\n\trender: (member: T) => string,\n\tclose: string | undefined,\n): string | undefined {\n\tif (members.length === 0) return undefined\n\tconst lines = [open, ...members.map(render), close].flatMap((line) =>\n\t\tline === undefined || line === '' ? [] : [line],\n\t)\n\treturn lines.length === 0 ? undefined : lines.join('\\n\\n')\n}\n\n/**\n * Copies a message with image data merged onto its `images` — the message's own images first,\n * then the attached data, keeping every other field and never mutating the original.\n *\n * @remarks\n * Pure and total: the original message is never mutated. Every other field the source message\n * carries (`calls`, `call`, `thinking`) is kept as given, and an absent one stays absent,\n * mirroring the store's present-when-given convention.\n *\n * @param message - The message to copy (left unchanged)\n * @param payloads - The base64 image data to attach\n * @returns A new message carrying the merged `images`\n *\n * @example\n * ```ts\n * // IMAGE_BASE64 stands for the base64 text of one image.\n * attachImages({ id: '1', role: 'user', content: 'Describe' }, ['IMAGE_BASE64'])\n * // { id: '1', role: 'user', content: 'Describe', images: ['IMAGE_BASE64'] }\n * ```\n */\nexport function attachImages(message: Message, payloads: readonly string[]): Message {\n\treturn { ...message, images: [...(message.images ?? []), ...payloads] }\n}\n\n/**\n * Attaches image data to a conversation's last user message — the turn a vision provider reads\n * images off — as a new array with that one message replaced by its carrying copy, and unchanged\n * when there is no data or no user turn.\n *\n * @remarks\n * Pure and total: the conversation and its messages are never mutated, and the returned array\n * replaces exactly the one target message with the copy {@link attachImages} builds. Empty\n * data returns the conversation unchanged; a conversation with no user message returns it\n * unchanged too (there is nowhere to attach, and the images already rode the system block). A hole\n * in a sparse conversation is not a user message.\n *\n * @param conversation - The messages to attach into (left unchanged)\n * @param payloads - The base64 image data to attach\n * @returns The conversation with its last user message replaced by the carrying copy\n *\n * @example\n * ```ts\n * attachUserImages([{ id: '1', role: 'user', content: 'Describe' }], ['IMAGE_BASE64'])\n * // [{ id: '1', role: 'user', content: 'Describe', images: ['IMAGE_BASE64'] }]\n * ```\n */\nexport function attachUserImages(\n\tconversation: readonly Message[],\n\tpayloads: readonly string[],\n): readonly Message[] {\n\tif (payloads.length === 0) return conversation\n\tconst target = conversation.findLastIndex(\n\t\t(message: Message | undefined) => message?.role === 'user',\n\t)\n\tif (target === -1) return conversation\n\treturn conversation.map((message, index) =>\n\t\tindex === target ? attachImages(message, payloads) : message,\n\t)\n}\n\n/**\n * Collects the `base64` payload of the image files in a workspace file list — the data an agent\n * context attaches to the last user message.\n *\n * @remarks\n * Pure and total. `isBinary` narrows the tagless content to its binary arm (a total guard,\n * never an assertion), then the MIME prefix gates it to an image, so a text file and a non-image\n * binary (a PDF) are both skipped. Order follows the file list.\n *\n * @param files - The (already scope-filtered) workspace files\n * @returns The `base64` payload of each image file, in file order\n *\n * @example\n * ```ts\n * collectImageData([createFile({ path: 'a.png', content: { base64: 'IMAGE_BASE64', mime: 'image/png' } })])\n * // ['IMAGE_BASE64']\n * ```\n */\nexport function collectImageData(files: readonly FileInterface[]): readonly string[] {\n\t// The spread visits a hole in `files` as an undefined file, as iteration does; `flatMap` skips it.\n\treturn [...files].flatMap((file) =>\n\t\tisBinary(file.content) && file.content.mime.startsWith('image/') ? [file.content.base64] : [],\n\t)\n}\n\n/**\n * Intersects two scope category lists under the \"`undefined` is the universal set\" rule — a\n * fresh copy that can only tighten, and the primitive a scope narrows through.\n *\n * @remarks\n * Pure and total, and it can only tighten: `undefined` ∩ `undefined` is `undefined` (still no\n * constraint); `undefined` ∩ a list is a copy of that list (the `undefined` side imposes\n * nothing); a list ∩ a list keeps the child keys the parent also allows, so a parent-excluded\n * key can never be re-admitted. Every returned list is a fresh copy, so a later mutation of\n * either input cannot leak into the result.\n *\n * @param parent - The parent's allow-list (`undefined` ⇒ no constraint)\n * @param child - The narrowing allow-list (`undefined` ⇒ no constraint)\n * @returns The intersected allow-list, or `undefined` when neither side constrains\n *\n * @example\n * ```ts\n * intersectKeys(['read', 'write'], ['write', 'admin']) // ['write']\n * intersectKeys(undefined, ['read']) // ['read']\n * intersectKeys(undefined, undefined) // undefined\n * ```\n */\nexport function intersectKeys(\n\tparent: readonly string[] | undefined,\n\tchild: readonly string[] | undefined,\n): readonly string[] | undefined {\n\tif (parent === undefined) return child === undefined ? undefined : [...child]\n\tif (child === undefined) return [...parent]\n\tconst allowed = new Set(parent)\n\treturn child.filter((key) => allowed.has(key))\n}\n","import type { ScopeFilter, ScopeInput, ScopeInterface, SelectionHandler } from '../types.js'\nimport { intersectKeys } from '../helpers.js'\n\n/**\n * Represents a named, immutable filter over a richer context's items — an optional allow-list per\n * category (`instructions` / `tools` / `files`), each keyed by that category's identity (an\n * instruction's `name`, a tool's `name`, a workspace file's `path`) and read as an allow-list:\n * `undefined` lets everything pass, `[]` lets nothing pass, and a non-empty list passes the listed\n * keys alone. `narrow` composes a tighter child by set intersection.\n *\n * @remarks\n * - **A category list is three-way.** `undefined` ⇒ no constraint on that category (all\n * pass); `[]` ⇒ none pass; a non-empty list ⇒ only the listed keys pass. The build\n * step / loop apply this through `filterAllowList`.\n * - **Immutable.** The `id` is minted at construction; every supplied list is copied in\n * (so a later mutation of the caller's array can't leak in), and the lists are\n * `readonly`. A `Scope` is never mutated after construction — `narrow` returns a new\n * one rather than altering this one.\n * - **`narrow` is set-intersection (immutable composition).** A child scope's visible set\n * per category is the intersection of this scope's list and the config's list — but\n * `undefined` means \"no constraint\", so it acts as the universal set: intersecting\n * `undefined` with a list yields the list, and `undefined` with `undefined` stays\n * `undefined`. Narrowing can only tighten, never widen — a key excluded by a parent\n * can never be re-admitted by a child. The child keeps this scope's `name` and `select` handler.\n *\n * @example\n * ```ts\n * const scope = new Scope({ name: 'reader', tools: ['search', 'read'] })\n * // narrow intersects: tools ∩ ['read', 'write'] = ['read'] (write was never in the parent).\n * const tighter = scope.narrow({ tools: ['read', 'write'] })\n * tighter.tools // ['read']\n * // instructions had no parent constraint (undefined) → the child's list passes through.\n * tighter.narrow({ instructions: ['safety'] }).instructions // ['safety']\n * ```\n */\nexport class Scope implements ScopeInterface {\n\treadonly id: string = crypto.randomUUID()\n\treadonly name: string\n\treadonly instructions?: readonly string[]\n\treadonly tools?: readonly string[]\n\treadonly files?: readonly string[]\n\treadonly select?: SelectionHandler\n\n\tconstructor(input: ScopeInput) {\n\t\tthis.name = input.name\n\t\tif (input.select !== undefined) this.select = input.select\n\t\t// Copy each supplied list in (a later mutation of the caller's array can't leak in);\n\t\t// an omitted list stays `undefined` — the absence of a constraint.\n\t\tif (input.instructions !== undefined) this.instructions = [...input.instructions]\n\t\tif (input.tools !== undefined) this.tools = [...input.tools]\n\t\tif (input.files !== undefined) this.files = [...input.files]\n\t}\n\n\tnarrow(config: ScopeFilter): ScopeInterface {\n\t\tconst instructions = intersectKeys(this.instructions, config.instructions)\n\t\tconst tools = intersectKeys(this.tools, config.tools)\n\t\tconst files = intersectKeys(this.files, config.files)\n\t\treturn new Scope({\n\t\t\tname: this.name,\n\t\t\t...(this.select === undefined ? {} : { select: this.select }),\n\t\t\t...(instructions === undefined ? {} : { instructions }),\n\t\t\t...(tools === undefined ? {} : { tools }),\n\t\t\t...(files === undefined ? {} : { files }),\n\t\t})\n\t}\n}\n","import type {\n\tScopeInput,\n\tScopeInterface,\n\tScopeManagerEventMap,\n\tScopeManagerInterface,\n\tScopeManagerOptions,\n} from '../types.js'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { removeEntries } from '../../helpers.js'\nimport { Scope } from './Scope.js'\n\n/**\n * Registers the named filters a richer context reuses — immutable {@link Scope} instances keyed by their\n * minted `id`, in insertion order, where `add` always mints and stores rather than overwriting,\n * and an observable `emitter` reports each change.\n *\n * @remarks\n * - **Registry.** Scopes live in an insertion-ordered `Map` keyed by their minted `id`;\n * `add` mints a {@link Scope} from a {@link ScopeInput} (an `id` plus the three\n * allow-lists), stores it, and returns it. `count` is the map size, `scope(id)` looks\n * one up, and `scopes()` lists them in insertion order. (Unlike the name-keyed\n * instruction registry, a scope's key is its minted `id`, so two scopes may share a\n * `name`; `add` therefore never overwrites.)\n * - **Removal.** `remove` drops one by id, or a batch — `true` only when every supplied id\n * was removed; `clear` empties the registry.\n * - **Observable.** The owned {@link emitter} ({@link ScopeManagerEventMap}) carries\n * `add` (the added scope) / `remove` (the id) / `clear`. Every event is emitted\n * directly, strictly after the map mutation completes; the emitter isolates a listener\n * throw and routes it to its `error` handler (the `error` option), so a buggy observer can\n * never corrupt a mutation.\n *\n * @example\n * ```ts\n * const manager = new ScopeManager()\n * const reader = manager.add({ name: 'reader', tools: ['search', 'read'] })\n * manager.scope(reader.id) // the same scope\n * manager.count // 1\n * ```\n */\nexport class ScopeManager implements ScopeManagerInterface {\n\treadonly #scopes = new Map<string, ScopeInterface>()\n\t// The push observation surface — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into a mutation.\n\treadonly #emitter: Emitter<ScopeManagerEventMap>\n\n\tconstructor(options?: ScopeManagerOptions) {\n\t\tthis.#emitter = new Emitter<ScopeManagerEventMap>(options)\n\t}\n\n\tget emitter(): EmitterInterface<ScopeManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#scopes.size\n\t}\n\n\tadd(input: ScopeInput): ScopeInterface {\n\t\tconst scope = new Scope(input)\n\t\tthis.#scopes.set(scope.id, scope)\n\t\t// Observe the added scope — after the map set, so a swallowed listener throw can't\n\t\t// perturb the store the caller is about to use.\n\t\tthis.#emitter.emit('add', scope)\n\t\treturn scope\n\t}\n\n\tscope(id: string): ScopeInterface | undefined {\n\t\treturn this.#scopes.get(id)\n\t}\n\n\tscopes(): readonly ScopeInterface[] {\n\t\treturn [...this.#scopes.values()]\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\t// Each present id still emits.\n\t\t\treturn removeEntries(ids, (id) => this.#delete(id))\n\t\t}\n\t\treturn this.#delete(ids)\n\t}\n\n\tclear(): void {\n\t\tthis.#scopes.clear()\n\t\t// Observe the cleared registry — after the map emptied, so a swallowed listener\n\t\t// throw can never alter the clear (no payload — `clear` is a pure signal).\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\t// Delete one scope, emitting `remove` only when one was actually removed (a delete of\n\t// an absent id returns `false` and emits nothing) — after the deletion.\n\t#delete(id: string): boolean {\n\t\tconst removed = this.#scopes.delete(id)\n\t\tif (removed) this.#emitter.emit('remove', id)\n\t\treturn removed\n\t}\n}\n","import type {\n\tAgentContextInterface,\n\tAgentContextOptions,\n\tInstructionManagerInterface,\n\tScopeInterface,\n\tSelection,\n\tSelectionHandler,\n} from './types.js'\nimport type {\n\tConversationInterface,\n\tConversationManagerInterface,\n\tMessageManagerInterface,\n} from '../conversations/index.js'\nimport type { Message } from '../types.js'\nimport type { ToolManagerInterface } from '@orkestrel/tool'\nimport type { WorkspaceManagerInterface } from '@orkestrel/workspace'\nimport { ToolManager } from '@orkestrel/tool'\nimport { isText, WorkspaceManager } from '@orkestrel/workspace'\nimport { InstructionManager } from './instructions/InstructionManager.js'\nimport { ConversationManager } from '../conversations/index.js'\nimport { filterAllowList } from '../helpers.js'\nimport { attachUserImages, collectImageData, renderFencedFile, renderSection } from './helpers.js'\nimport { WORKSPACE_SECTION_HEADER } from './constants.js'\n\n/**\n * Assembles a provider request from the richer turn context — the optional system prompt, the\n * observable context managers (instructions / workspaces), the\n * {@link ConversationManagerInterface} message source whose active conversation is `messages`, the\n * {@link ToolManagerInterface} registry, and an active {@link ScopeInterface} changed through\n * {@link AgentContextInterface.apply}. `build()` folds the scoped managers and the active\n * workspace into one system block, then the conversation, and never reads `tools`.\n *\n * @remarks\n * - **Composition.** `system` is the optional system prompt; `instructions` / `tools` /\n * `workspaces` / `conversations` are the registries passed in `options` (bring your own), or\n * fresh empty ones when omitted (so `workspaces` is always present); `messages` is the active\n * conversation's live tail (always defined — see the following item). `scope` is the active filter —\n * `undefined` (the default) ⇒ no filtering; change it through `apply(scope)`. The structural\n * `workspaces` / `conversations` registries are fixed at construction; switch their active\n * members through their own `switch(id)` methods.\n * - **The message source — the conversation registry's active conversation.** `conversations` is a\n * {@link ConversationManagerInterface}. The constructor adds a default conversation when the\n * manager has no active one, so the dynamic `messages` getter — `this.#conversations.active` — is\n * always defined. `messages` returns the active conversation itself (it owns the live tail + the\n * message verbs directly, satisfying {@link MessageManagerInterface} structurally — the same\n * reference, no duplication), and `build()` folds that conversation's `view()` (its per-section\n * summaries + live tail) as the authoritative message inclusion — the scope does not filter the\n * conversation (it owns inclusion through compaction; scope filters only instructions / tools /\n * workspace files). Because `messages` is read dynamically, an agent switches the active\n * conversation between runs (`conversations.switch(id)`) to serve many threads (the real\n * multi-conversation pattern); switch between runs, not during a run, and use separate agents for\n * concurrent threads.\n * - **`build()` — the scoped assembly + the format cascade.** It folds, in order,\n * the system prompt then the scope-filtered instructions → the active workspace's text files\n * (each as a block: the section's `open` text, each item's rendering, then any `close` text)\n * into one leading `system` message (prepended only when at least one part exists), then\n * appends the active conversation's `view()` (the conversation owns message inclusion through\n * compaction — the scope does not filter the conversation). The instruction manager resolves\n * each `open` / item / `close` most-specific-first: `open` = manager-options-override >\n * built-in; per item = item-override > manager-options-override > built-in; `close` =\n * manager-options-override (no built-in ⇒ no closing line when unset) (see\n * {@link AgentContextInterface.build}). With no override set, each section is its built-in\n * header + items, no closing line. The active workspace's scoped-in image files' `base64` payload is attached to\n * the last user message (a vision provider reads images off a user turn); when no user message\n * exists the attachment is skipped. Built fresh each call (recomputed, never cached), so it\n * always reflects the current managers / messages / scope / active workspace; it never mutates a\n * manager or the stored messages.\n * - **The active workspace, rendered by carrier — the sole document/image context.**\n * `workspaces.active` (when set) has its {@link import('@orkestrel/workspace').FileInterface} values scope-filtered by `scope.files`,\n * then split: text files fold into a dedicated `## Workspace` system section (fenced reference\n * blocks — placed right after the instructions section), and image files' `base64` payload attaches\n * to the last user message. Active-only — never the other registered workspaces; with no active\n * workspace nothing renders for workspaces. `build()` owns this render (a `Workspace` /\n * `WorkspaceManager` stays file-focused).\n * - **Tools are structural, not in the prompt.** The registry is advertised to the provider\n * through `tools.definitions()` (scope-filtered by the loop), never serialized into the\n * message array — so the output of the `build()` method carries no tool content, scoped or not.\n * - **Event-free context; observable managers.** The context itself owns no Emitter; the\n * context managers each carry their own (the push observation surface).\n *\n * @example\n * ```ts\n * const context = new AgentContext({ system: 'You are concise.' })\n * context.instructions.add({ name: 'tone', content: 'Be terse.' })\n * context.messages.add({ role: 'user', content: 'Hi' })\n * context.build() // [{ role: 'system', content: 'You are concise.\\n\\n## Instructions\\n\\nBe terse.' }, { role: 'user', content: 'Hi' }]\n * ```\n */\nexport class AgentContext implements AgentContextInterface {\n\treadonly #system: string | undefined\n\treadonly #instructions: InstructionManagerInterface\n\t// The workspace registry whose active workspace `build()` renders by carrier (text files →\n\t// the system block, image files → the last user message). Always present (a fresh empty\n\t// manager when none was supplied). The registry is structural; switch its active workspace\n\t// through `workspaces.switch(id)`. `build()` reads `active` / its `files()` fresh each call.\n\treadonly #workspaces: WorkspaceManagerInterface\n\t// The conversation registry whose active conversation is the message source: the dynamic\n\t// `messages` getter returns `#conversations.active`, which the constructor seeds when absent, and\n\t// `build()` folds that conversation's `view()`. The registry is structural; switch its active\n\t// conversation through `conversations.switch(id)`.\n\treadonly #conversations: ConversationManagerInterface\n\treadonly #tools: ToolManagerInterface\n\t// The agent default; the active scope's `select` overrides it at each `select` call.\n\treadonly #select: SelectionHandler | undefined\n\t#scope: ScopeInterface | undefined\n\n\tconstructor(options?: AgentContextOptions) {\n\t\tthis.#system = options?.system\n\t\tthis.#instructions = options?.instructions ?? new InstructionManager()\n\t\t// Default to a fresh empty registry so `context.workspaces` is always present (mirroring\n\t\t// the always-present instruction manager); a supplied one is reused. The active workspace\n\t\t// is the sole document/image context.\n\t\tthis.#workspaces = options?.workspaces ?? new WorkspaceManager()\n\t\t// The conversation registry the message source flows from — a supplied one is reused, else a\n\t\t// fresh empty one. Seed an active conversation so `context.messages` (the active conversation's\n\t\t// live tail) is always defined: when the manager has none active, call `add()` for a default\n\t\t// (which auto-activates it). NB: `messages` is not captured here — it is computed dynamically\n\t\t// (the getter reads `#conversations.active`), so it always tracks the current active\n\t\t// conversation's live tail, no duplication.\n\t\tthis.#conversations = options?.conversations ?? new ConversationManager()\n\t\tif (this.#conversations.active === undefined) this.#conversations.add()\n\t\tthis.#tools = options?.tools ?? new ToolManager()\n\t\tthis.#select = options?.select\n\t\tthis.#scope = options?.scope\n\t}\n\n\tget system(): string | undefined {\n\t\treturn this.#system\n\t}\n\n\tget instructions(): InstructionManagerInterface {\n\t\treturn this.#instructions\n\t}\n\n\tget workspaces(): WorkspaceManagerInterface {\n\t\treturn this.#workspaces\n\t}\n\n\t// Dynamic — the active conversation itself (it owns its live tail + the message verbs directly,\n\t// like a `Workspace` owns its files), always defined: the constructor adds a default when the\n\t// registry has no active conversation. Computed on every read (never captured), so\n\t// `context.messages` always points at the current active conversation (the same reference — no\n\t// duplication) and follows a `conversations.switch(id)`. The active `Conversation` satisfies the\n\t// message-verb contract directly, so this stays a `MessageManagerInterface`. The\n\t// `#ensureConversation()` method re-seats a default if a caller's supplied manager was emptied (for\n\t// example `clear()`), so the getter is total — never undefined.\n\tget messages(): MessageManagerInterface {\n\t\treturn this.#ensureConversation()\n\t}\n\n\tget conversations(): ConversationManagerInterface {\n\t\treturn this.#conversations\n\t}\n\n\tget tools(): ToolManagerInterface {\n\t\treturn this.#tools\n\t}\n\n\tget scope(): ScopeInterface | undefined {\n\t\treturn this.#scope\n\t}\n\n\tapply(scope: ScopeInterface | undefined): void {\n\t\tthis.#scope = scope\n\t}\n\n\tselect(request: Message, signal: AbortSignal): Promise<Selection> | undefined {\n\t\t// Returning `undefined` synchronously keeps the loop's default path free of an `await`.\n\t\tconst handler = this.#scope?.select ?? this.#select\n\t\tif (handler === undefined) return undefined\n\t\treturn this.#check(handler, this.#ensureConversation(), request, signal)\n\t}\n\n\tbuild(selection?: Selection): readonly Message[] {\n\t\tconst scope = this.#scope\n\t\t// Tools reach the provider structurally. Each manager resolves its format cascade.\n\t\tconst parts: string[] = []\n\t\t// Configured by `=== undefined`, not falsiness — an explicitly supplied '' (or a\n\t\t// whitespace-only) system is opted in and prepended verbatim; a truthiness check would drop it.\n\t\tif (this.#system !== undefined) parts.push(this.#system)\n\t\tconst instructions = filterAllowList(\n\t\t\tscope?.instructions,\n\t\t\tthis.#instructions.instructions(),\n\t\t\t(one) => one.name,\n\t\t)\n\t\tconst instructed = renderSection(\n\t\t\tthis.#instructions.open,\n\t\t\tinstructions,\n\t\t\t(one) => this.#instructions.render(one),\n\t\t\tthis.#instructions.close,\n\t\t)\n\t\tif (instructed !== undefined) parts.push(instructed)\n\t\t// The active workspace is the sole document/image context. `build()` owns this render\n\t\t// because a `Workspace` / `WorkspaceManager` stays file-focused.\n\t\tconst files = filterAllowList(\n\t\t\tscope?.files,\n\t\t\tthis.#workspaces.active?.files() ?? [],\n\t\t\t(one) => one.path,\n\t\t)\n\t\tconst workspaceTexts = files.flatMap((file) =>\n\t\t\tisText(file.content)\n\t\t\t\t? [{ path: file.path, language: file.content.language, text: file.content.text }]\n\t\t\t\t: [],\n\t\t)\n\t\tconst documented = renderSection(\n\t\t\tWORKSPACE_SECTION_HEADER,\n\t\t\tworkspaceTexts,\n\t\t\t(file) => renderFencedFile(file.path, file.language, file.text),\n\t\t\tundefined,\n\t\t)\n\t\tif (documented !== undefined) parts.push(documented)\n\n\t\t// The active conversation's `view()` is authoritative (the per-section\n\t\t// summaries + the live tail) — the conversation owns message inclusion through compaction, so the\n\t\t// scope does not filter the conversation here (scope filters only the preceding instructions /\n\t\t// tools / workspace files). The active conversation is always present (the constructor adds\n\t\t// one), with `#ensureConversation()` as a total fallback if a caller emptied its supplied registry.\n\t\tconst conversation = selection?.messages ?? this.#ensureConversation().view()\n\t\t// A vision provider reads image payloads from a user turn.\n\t\tconst tail = attachUserImages(conversation, collectImageData(files))\n\n\t\t// A faulted selection's messages are `view()`, so the plan its briefing rested on is void.\n\t\tif (\n\t\t\tselection !== undefined &&\n\t\t\tselection.fault === undefined &&\n\t\t\tselection.briefing !== undefined &&\n\t\t\tselection.briefing !== ''\n\t\t) {\n\t\t\tparts.push(selection.briefing)\n\t\t}\n\n\t\tif (parts.length === 0) return tail\n\t\tconst system: Message = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\trole: 'system',\n\t\t\tcontent: parts.join('\\n\\n'),\n\t\t}\n\t\treturn [system, ...tail]\n\t}\n\n\t// Another run can append to the conversation while the handler awaits, so the view's ids are\n\t// recorded before the call (an async body runs synchronously up to its first `await`) and\n\t// compared after it; a changed view turns the handler's selection into a fault over `view()`.\n\tasync #check(\n\t\thandler: SelectionHandler,\n\t\tconversation: ConversationInterface,\n\t\trequest: Message,\n\t\tsignal: AbortSignal,\n\t): Promise<Selection> {\n\t\tconst before = conversation.view().map((message) => message.id)\n\t\tconst selection = await handler(conversation, request, signal)\n\t\tconst after = conversation.view()\n\t\tif (\n\t\t\tafter.length === before.length &&\n\t\t\tafter.every((message, index) => message.id === before[index])\n\t\t) {\n\t\t\treturn selection\n\t\t}\n\t\tconst text = `conversation ${conversation.id} changed during selection: ${before.length} messages before, ${after.length} after`\n\t\treturn {\n\t\t\tmessages: after,\n\t\t\tjudgments: selection.judgments,\n\t\t\t...(selection.usage === undefined ? {} : { usage: selection.usage }),\n\t\t\tfault:\n\t\t\t\tselection.fault === undefined\n\t\t\t\t\t? new Error(text)\n\t\t\t\t\t: new Error(text, { cause: selection.fault }),\n\t\t}\n\t}\n\n\t// A supplied registry can be emptied after construction. Re-seat a default so the message\n\t// source stays defined, preferring the active conversation an add observer may have selected.\n\t#ensureConversation(): ConversationInterface {\n\t\tif (this.#conversations.active !== undefined) return this.#conversations.active\n\t\tconst conversation = this.#conversations.add()\n\t\treturn this.#conversations.active ?? conversation\n\t}\n}\n","import type {\n\tAgentContextInterface,\n\tAgentContextOptions,\n\tInstructionInput,\n\tInstructionInterface,\n\tInstructionManagerInterface,\n\tInstructionManagerOptions,\n\tScopeInput,\n\tScopeInterface,\n\tScopeManagerInterface,\n\tScopeManagerOptions,\n} from './types.js'\nimport { Instruction } from './instructions/Instruction.js'\nimport { InstructionManager } from './instructions/InstructionManager.js'\nimport { Scope } from './scopes/Scope.js'\nimport { ScopeManager } from './scopes/ScopeManager.js'\nimport { AgentContext } from './AgentContext.js'\n\n/**\n * Creates an instruction — an immutable {@link InstructionInterface} (a named directive)\n * from its `name` / `content` and optional `priority`, the `id` minted at construction.\n *\n * @remarks\n * Only `name` / `content` are required; `priority` orders the instruction in the\n * rendered list of an {@link InstructionManagerInterface} (higher first). Default: `0`.\n * Stored immutable — never mutated after creation.\n *\n * @param input - `name` / `content` (required) and an optional `priority` (see\n * {@link InstructionInput})\n * @returns A working {@link InstructionInterface}\n *\n * @example\n * ```ts\n * import { createInstruction } from '@orkestrel/agent'\n *\n * const instruction = createInstruction({ name: 'tone', content: 'Be concise.', priority: 5 })\n * ```\n */\nexport function createInstruction(input: InstructionInput): InstructionInterface {\n\treturn new Instruction(input)\n}\n\n/**\n * Creates an instruction registry — an {@link InstructionManagerInterface} holding\n * immutable instructions keyed by `name`, listed by descending `priority`.\n *\n * @remarks\n * Starts empty; `add` (one or a batch) mints each `id` and overwrites a same-name\n * instruction (last write wins); `instructions()` lists them sorted by descending\n * `priority` (stable for ties); `open` / `render` / `close` are the build contract a richer\n * context renders an instructions block with; `remove` (one or a batch) reports `true` only\n * when every supplied name was removed; `clear` empties it. Carries an observable `emitter`\n * ({@link import('./types.js').InstructionManagerEventMap}) wired through the reserved `on`\n * option; the emitter isolates a listener throw and routes it to its `error` handler\n * (the `error` option), so it can never corrupt a mutation. An optional `format`\n * override is the manager-options level of the `AgentContext` build cascade (consulted by\n * `open` / `render` / `close`, beating the built-in; a per-item\n * `InstructionInput.override` still beats it).\n *\n * @param options - Optional `on` hooks + a `format` override (see {@link InstructionManagerOptions})\n * @returns An empty {@link InstructionManagerInterface}\n *\n * @example\n * ```ts\n * import { createInstructionManager } from '@orkestrel/agent'\n *\n * const instructions = createInstructionManager()\n * instructions.add({ name: 'tone', content: 'Be concise.', priority: 5 })\n * ```\n */\nexport function createInstructionManager(\n\toptions?: InstructionManagerOptions,\n): InstructionManagerInterface {\n\treturn new InstructionManager(options)\n}\n\n/**\n * Creates a named scope — an immutable {@link ScopeInterface} from its `name` and its\n * per-category allow-lists, the `id` minted at construction.\n *\n * @remarks\n * Each list is three-way: `undefined` ⇒ no constraint on that category (all pass), `[]` ⇒\n * none pass, a non-empty list ⇒ only the listed keys pass. `narrow(config)` composes a\n * tighter child by set-intersection (an `undefined` side imposing no constraint). Stored\n * immutable — never mutated after creation (`narrow` returns a new scope).\n *\n * @param input - `name` (required) and the optional `instructions` / `tools` / `files`\n * allow-lists (see {@link ScopeInput})\n * @returns A working {@link ScopeInterface}\n *\n * @example\n * ```ts\n * import { createScope } from '@orkestrel/agent'\n *\n * const reader = createScope({ name: 'reader', tools: ['search', 'read'] })\n * reader.narrow({ tools: ['read', 'write'] }).tools // ['read'] — intersection tightens\n * ```\n */\nexport function createScope(input: ScopeInput): ScopeInterface {\n\treturn new Scope(input)\n}\n\n/**\n * Creates a scope registry — a {@link ScopeManagerInterface} holding immutable scopes keyed\n * by their minted `id`, in insertion order.\n *\n * @remarks\n * Starts empty; `add` mints each scope's `id` and stores it (keyed by `id`, so it\n * never overwrites — two scopes may share a `name`); `scopes()` lists them in insertion order;\n * `remove` (one or a batch) reports `true` only when every supplied id was removed; `clear`\n * empties it. Carries an observable `emitter`\n * ({@link import('./types.js').ScopeManagerEventMap}) wired through the reserved `on`\n * option; the emitter isolates a listener throw and routes it to its `error` handler\n * (the `error` option), so it can never corrupt a mutation.\n *\n * @param options - Optional `on` hooks (see {@link ScopeManagerOptions})\n * @returns An empty {@link ScopeManagerInterface}\n *\n * @example\n * ```ts\n * import { createScopeManager } from '@orkestrel/agent'\n *\n * const scopes = createScopeManager()\n * const reader = scopes.add({ name: 'reader', tools: ['search'] })\n * ```\n */\nexport function createScopeManager(options?: ScopeManagerOptions): ScopeManagerInterface {\n\treturn new ScopeManager(options)\n}\n\n/**\n * Creates a richer turn context — an {@link AgentContextInterface} assembling a provider request\n * from the optional system prompt, the instruction registry, the workspace registry (the only\n * document channel), the conversation registry that is its `messages` source, the tool registry,\n * and the active scope, which `build()` folds into the next turn's input.\n *\n * @remarks\n * `system` is the optional system prompt; `tools` / `instructions` / `workspaces` are pre-built\n * managers to reuse (empty ones are created when omitted, so `context.workspaces` is always\n * present); `scope` is the initial active filter (`undefined` ⇒ no filtering, changeable afterwards\n * through `context.apply(...)`). `conversations` is the message source: a supplied manager's\n * active conversation is reused as `messages`, and a default conversation is added only when it\n * has none (a fresh registry with one default conversation is created when omitted). `build()`\n * folds the scoped instructions — plus the active workspace's scope-filtered text files (fenced) —\n * into one leading `system` message and appends the active conversation's `view()` (attaching the\n * active workspace's scope-filtered image files' `base64` payload to the last user message), built\n * fresh each call; the scope never filters the conversation. The active workspace is the sole\n * document/image context. Tools are advertised structurally (through\n * `tools.definitions()`, scope-filtered by the loop), never serialized into the prompt.\n *\n * @param options - Optional `system` / `tools` / `instructions` / `workspaces` /\n * `conversations` / `scope` / `select` (see {@link AgentContextOptions})\n * @returns A working {@link AgentContextInterface}\n *\n * @example\n * ```ts\n * import { createAgentContext } from '@orkestrel/agent'\n *\n * const context = createAgentContext({ system: 'You are concise.' })\n * context.instructions.add({ name: 'tone', content: 'Be terse.' })\n * context.messages.add({ role: 'user', content: 'Hi' })\n * context.build() // [{ role: 'system', content: 'You are concise.\\n\\n## Instructions\\n\\nBe terse.' }, { role: 'user', content: 'Hi' }]\n * ```\n */\nexport function createAgentContext(options?: AgentContextOptions): AgentContextInterface {\n\treturn new AgentContext(options)\n}\n","/**\n * Caps an {@link AgentInterface} turn's tool iterations by default — `10` context → provider →\n * tools cycles before the loop stops, so a model that keeps requesting tools can never loop\n * forever. Overridable per agent through `AgentOptions.limit`.\n */\nexport const DEFAULT_AGENT_LIMIT = 10\n\n/**\n * Names the default zone for an unmatched tool call allowed by an authority.\n */\nexport const DEFAULT_AUTHORITY_ZONE = 'default'\n\n/**\n * Estimates the role and framing overhead added to each message by {@link estimateMessages}.\n */\nexport const MESSAGE_TOKEN_OVERHEAD = 4\n\n/**\n * Names the coarse, deliberately approximate per-image token cost\n * {@link import('./helpers.js').estimateMessages} charges for each attached image — `512`, because\n * a base64 payload's length is no reliable token proxy.\n *\n * @remarks\n * A base64 image payload's length is not a reliable token proxy (a vision model's actual image\n * token cost depends on resolution / tiling, not byte size), so this is a fixed, coarse\n * per-image estimate rather than a derivation from `image.length` — a planning heuristic, not an\n * exact count.\n */\nexport const IMAGE_TOKEN_ESTIMATE = 512\n","import type { AgentErrorCode, AgentResult } from './types.js'\nimport type { CodedErrorOptions } from '../types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n// A real error type, not a sentinel. An agent job treats a partial result\n// (a job committed early from an abort / budget / timeout) as a failure by default — the\n// queue / runner handler throws this so the Queue's retries + a Runner's fail-fast\n// engage. It carries the partial AgentResult so a caller (or a `retries: 0` enqueue that\n// rejects with it) can still inspect what accumulated. The guard narrows with\n// `instanceof`, mirroring `ProviderAbortError` and `isProviderAbortError` in `providers/errors.ts`.\n\n/**\n * Reports an {@link AgentInterface} run that ended {@link AgentResult.partial} under a\n * `partial` policy of `false` (the default) — thrown by an agent-job handler (a\n * `createAgentQueue` / `createAgentRunner` job), carrying the partial {@link AgentResult} so\n * the failure stays inspectable, and the machine-readable `code` `'PARTIAL'`.\n *\n * @remarks\n * A partial result means the agent was cancelled (an external `signal` abort, a queue /\n * runner abort threaded in, a `timeout` deadline, or an exhausted token `budget`) rather\n * than finishing naturally. For a durable job that is a failure by default: throwing this\n * lets the Queue's retries re-run the job and a Runner's fail-fast abort its siblings.\n * Set `partial: true` (see `AgentQueueOptions` / `AgentRunnerOptions`) to treat a\n * partial as success instead, in which case this is never thrown. Narrow a caught value\n * with {@link isAgentJobError} to read `partial`. `code` is the machine-readable condition\n * (`'PARTIAL'` — the only one this error reports), so a `catch` branches on it rather than on\n * the message string.\n */\nexport class AgentJobError extends Error {\n\t/** Names the machine-readable condition — `'PARTIAL'`: a job that ended partial under a disallowing policy. */\n\treadonly code = 'PARTIAL' as const\n\t/** Holds the partial {@link AgentResult} the cancelled job produced. */\n\treadonly partial: AgentResult\n\n\tconstructor(message: string, partial: AgentResult) {\n\t\tsuper(message)\n\t\tthis.name = 'AgentJobError'\n\t\tthis.partial = partial\n\t}\n}\n\n/**\n * Narrows an unknown caught value to an {@link AgentJobError} through `instanceof`, so a\n * `catch` can recover its `partial` result.\n *\n * @param value - The value to test (typically a `catch` binding or a rejected enqueue)\n * @returns True if `value` is an {@link AgentJobError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tawait queue.enqueue(job) // retries: 0 → a partial rejects with the error\n * } catch (error) {\n * \tif (isAgentJobError(error)) keep(error.partial.content) // recover the partial content\n * }\n * ```\n */\nexport function isAgentJobError(value: unknown): value is AgentJobError {\n\treturn isInstance(value, AgentJobError)\n}\n\n// A real error type, not a sentinel. A run that would share an accounting instance with a live\n// run would corrupt that accounting, so `stream()` throws this synchronously, before any state\n// mutation or emit, rather than letting the runs race. Carries a machine-readable `code` so a\n// `catch` branches on `error.code`, mirroring `ConversationError` in `conversations/errors.ts`.\n\n/**\n * Reports a run sharing accounting with a live run, a `limit` that is not a nonnegative safe integer, a name absent from a registry pool, or a strict run whose request exceeds its window. Agent construction, the `stream` and `generate` methods, and registry accessors throw synchronously, before returning a handle or promise; a `'WINDOW'` refusal rejects the run's `result` instead. Await the call inside `try`/`catch` to catch it.\n *\n * @remarks\n * `'CONCURRENCY'` reports a run started while another run on the same agent is live, when the\n * agent carries a `window` (a shared context budget) or when the run's effective `budget` or\n * `allowance` is an instance a live run holds — the second run's `start()` would replace that\n * instance's signal and race its charges against the first run's. Use separate agents, or\n * distinct budget and allowance instances per run with no `window`, for concurrent runs. Its\n * `context` names the `agent` id.\n * `'LIMIT'` reports a construction or per-run `limit` that is not a nonnegative safe integer,\n * including one a rehydrated job carries into `build`. `'REGISTRY'` reports a rehydration name\n * absent from its registry pool, on `provider` / `tool` / `authority` / `scheduler` / `build`;\n * its `context` names the `category` and the `name`. `'WINDOW'` reports a `strict` run whose\n * complete provider request is still over the `window` budget, equal to its `max` included, after\n * the one permitted fold or with no fold possible; it settles the run `error` before the provider\n * is called, and its `context` holds the `agent` id, the measured `consumed`, and the window `max`.\n * Narrow a caught value with {@link isAgentError} and branch on `error.code`.\n */\nexport class AgentError extends Error {\n\t/** Names the machine-readable condition — `'CONCURRENCY'`: a run sharing accounting with a live run; `'LIMIT'`: a `limit` that is not a nonnegative safe integer; `'REGISTRY'`: a rehydration name absent from its registry pool; `'WINDOW'`: a strict run whose complete request is still over its window budget. */\n\treadonly code: AgentErrorCode\n\t/** Holds the values that locate the failure, such as the `agent` id of a refused run, or `undefined` when none were supplied. */\n\treadonly context: Readonly<Record<string, unknown>> | undefined\n\n\t/**\n\t * Creates the error with its code, message, and optional cause and context.\n\t *\n\t * @param code - The machine-readable {@link AgentErrorCode}\n\t * @param message - The human-readable description\n\t * @param options - The optional {@link CodedErrorOptions}; `cause` reaches `Error.cause` only when present\n\t */\n\tconstructor(code: AgentErrorCode, message: string, options?: CodedErrorOptions) {\n\t\tsuper(message, options?.cause === undefined ? undefined : { cause: options.cause })\n\t\tthis.name = 'AgentError'\n\t\tthis.code = code\n\t\tthis.context = options?.context\n\t}\n}\n\n/**\n * Narrows an unknown caught value to an {@link AgentError} through `instanceof`, so a `catch`\n * can branch on its `code`.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns True if `value` is an {@link AgentError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tagent.stream()\n * } catch (error) {\n * \tif (isAgentError(error) && error.code === 'CONCURRENCY') useSeparateAgents()\n * }\n * ```\n */\nexport function isAgentError(value: unknown): value is AgentError {\n\treturn isInstance(value, AgentError)\n}\n","import type { ChannelInterface } from './types.js'\n\n/**\n * Buffers chunks in a minimal unbounded async channel — the eager pump writes them in (`push`)\n * and ends it (`close` / `fail`) regardless of consumption, while a consumer reads them back live\n * through the `drain` async-iterator. Decoupling write from read is what lets a producer make\n * progress without a consumer pulling, and it is why an agent's `result` settles whether or not\n * its `events` are drained.\n *\n * @remarks\n * A waiting `drain` parks its void resolver in `#waiting`; `push` / `close` / `fail`\n * enqueue/flag, then fire and clear every parked resolver, so each parked reader wakes,\n * re-reads the shared buffer, and either takes the next chunk, returns (on `close`), throws\n * (on `fail`), or parks again when another reader took the chunk first. Taking a chunk is\n * synchronous, so each value reaches exactly one reader.\n * A `return()` issued while a read is parked waits for the next `push`, `close`, or `fail`.\n * The parked read takes a pushed value before that `return()` settles.\n *\n * @example\n * ```ts\n * import { Channel } from '@orkestrel/agent'\n *\n * const channel = new Channel<number>()\n * channel.push(1)\n * channel.close()\n * for await (const value of channel.drain()) {\n * \tvalue // 1\n * }\n * ```\n */\nexport class Channel<T> implements ChannelInterface<T> {\n\t#buffer: ReadonlyArray<{ readonly value: T }> = []\n\t#waiting: ReadonlyArray<() => void> = []\n\t#closed = false\n\t#failure: { error: unknown } | undefined\n\n\tpush(value: T): void {\n\t\tthis.#buffer = [...this.#buffer, { value }]\n\t\tthis.#signal()\n\t}\n\n\tclose(): void {\n\t\tthis.#closed = true\n\t\tthis.#signal()\n\t}\n\n\tfail(error: unknown): void {\n\t\t// First failure wins; a later close / fail can't override a recorded error.\n\t\tif (this.#failure === undefined) this.#failure = { error }\n\t\tthis.#closed = true\n\t\tthis.#signal()\n\t}\n\n\tasync *drain(): AsyncGenerator<T, void> {\n\t\tfor (;;) {\n\t\t\t// Yield everything buffered before checking for end, so a close / fail that\n\t\t\t// arrives alongside the last chunks still delivers those chunks first.\n\t\t\twhile (this.#buffer.length > 0) {\n\t\t\t\tconst [cell, ...remaining] = this.#buffer\n\t\t\t\tthis.#buffer = remaining\n\t\t\t\tif (cell !== undefined) yield cell.value\n\t\t\t}\n\t\t\tif (this.#failure !== undefined) throw this.#failure.error\n\t\t\tif (this.#closed) return\n\t\t\tawait this.#park()\n\t\t}\n\t}\n\n\t// Wake every parked reader, not one: with concurrent readers, a single woken reader would\n\t// leave the rest parked past a `close` / `fail`. The list is cleared before firing, so a\n\t// reader that re-parks arms the next wait. A `signal` with no parked reader is a no-op (the\n\t// buffer / flags are already set, so the next `drain` pass reads them without parking).\n\t#signal(): void {\n\t\tconst waiting = this.#waiting\n\t\tthis.#waiting = []\n\t\tfor (const wake of waiting) wake()\n\t}\n\n\t#park(): Promise<void> {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.#waiting = [...this.#waiting, resolve]\n\t\t})\n\t}\n}\n","import type { Message } from '../types.js'\nimport type { ProviderRequest } from '../providers/index.js'\nimport type {\n\tAgentInterface,\n\tAgentJobInput,\n\tAgentRegistryInterface,\n\tAgentResult,\n\tAgentRunResult,\n\tAgentStop,\n\tAgentTurn,\n\tMessageMeasure,\n\tRequestMeasure,\n} from './types.js'\nimport type { BudgetInterface, TokenUsage } from '@orkestrel/budget'\nimport type { JSONValue } from '@orkestrel/contract'\nimport type { QueueContext, QueueOptions } from '@orkestrel/queue'\nimport type { ToolCall, ToolResult } from '@orkestrel/tool'\nimport { isBudget, isBudgetError } from '@orkestrel/budget'\nimport {\n\tattempt,\n\tContractError,\n\tisBoolean,\n\tisFiniteNumber,\n\tisObject,\n\tisString,\n\tparseJSONValue,\n\tpreview,\n} from '@orkestrel/contract'\nimport { IMAGE_TOKEN_ESTIMATE, MESSAGE_TOKEN_OVERHEAD } from './constants.js'\nimport { AgentError, AgentJobError } from './errors.js'\nimport { hasCalls, renderJSON } from '../helpers.js'\nimport { isNonNegativeSafeInteger } from '../validators.js'\n\n/**\n * Projects an unknown value onto a fresh, exact `JSONValue` representation of an\n * {@link AgentResult} — capturing each structural field once through a total boundary,\n * accepting conforming accessors and inherited properties, preserving finite negative and\n * fractional usage counts, dropping extras, and resolving `undefined` for a malformed field, a\n * non-finite usage number, a throwing getter, or a hostile or revoked proxy.\n *\n * @remarks\n * This is a total hostile-boundary projection. Each structural field is captured once\n * through Contract's sanctioned exception boundary, so conforming accessors and inherited\n * properties are supported while a throwing getter or revoked proxy returns `undefined`.\n * Present usage counts must be finite numbers; negative and fractional values are preserved,\n * not normalized. The result is exact `{ content, thinking?, usage?, partial, stop? }`. A present\n * `stop` is read once, then its `layer`, `id`, `max`, `consumed`, `estimate`, and `usage` once each\n * in that order, `max` and `consumed` only on a `meter` or `budget` arm; the arm is rebuilt\n * exactly, omitting absent readings, and a malformed `stop` refuses the whole value. Extra input\n * properties are dropped while a fresh exact plain object is rebuilt and deep-gated through\n * {@link import('@orkestrel/contract').parseJSONValue}.\n *\n * @param value - The unknown value to project\n * @returns A fresh JSON value containing only AgentResult fields, or `undefined` when invalid\n *\n * @example\n * ```ts\n * import { agentResultToJSON } from '@orkestrel/agent'\n *\n * agentResultToJSON({ content: 'done', usage: { prompt: 2, completion: 1, total: 3 }, partial: false })\n * // { content: 'done', usage: { prompt: 2, completion: 1, total: 3 }, partial: false }\n * ```\n */\nexport function agentResultToJSON(value: unknown): JSONValue | undefined {\n\tconst captured = attempt(() => {\n\t\tif (!isObject(value)) return undefined\n\n\t\tconst content = Reflect.get(value, 'content')\n\t\tconst thinking = Reflect.get(value, 'thinking')\n\t\tconst usage = Reflect.get(value, 'usage')\n\t\tconst partial = Reflect.get(value, 'partial')\n\t\tconst stop = Reflect.get(value, 'stop')\n\t\tif (!isString(content) || !isBoolean(partial)) return undefined\n\t\tif (thinking !== undefined && !isString(thinking)) return undefined\n\t\tconst projectedUsage = usage === undefined ? undefined : tokenUsageToJSON(usage)\n\t\tif (usage !== undefined && projectedUsage === undefined) return undefined\n\t\tif (stop !== undefined && !isObject(stop)) return undefined\n\n\t\tconst layer = isObject(stop) ? Reflect.get(stop, 'layer') : undefined\n\t\tconst id = isObject(stop) ? Reflect.get(stop, 'id') : undefined\n\t\tconst ranked = layer === 'meter' || layer === 'budget'\n\t\tconst max = isObject(stop) && ranked ? Reflect.get(stop, 'max') : undefined\n\t\tconst consumed = isObject(stop) && ranked ? Reflect.get(stop, 'consumed') : undefined\n\t\tconst estimate = isObject(stop) ? Reflect.get(stop, 'estimate') : undefined\n\t\tconst spent = isObject(stop) ? Reflect.get(stop, 'usage') : undefined\n\t\tconst projectedSpent = spent === undefined ? undefined : tokenUsageToJSON(spent)\n\t\tconst readings = {\n\t\t\t...(isFiniteNumber(estimate) ? { estimate } : {}),\n\t\t\t...(projectedSpent === undefined ? {} : { usage: projectedSpent }),\n\t\t}\n\t\tconst projectedStop =\n\t\t\t!isString(id) ||\n\t\t\t(estimate !== undefined && !isFiniteNumber(estimate)) ||\n\t\t\t(spent !== undefined && projectedSpent === undefined)\n\t\t\t\t? undefined\n\t\t\t\t: ranked && isFiniteNumber(max) && isFiniteNumber(consumed)\n\t\t\t\t\t? { layer, id, max, consumed, ...readings }\n\t\t\t\t\t: layer === 'model'\n\t\t\t\t\t\t? { layer, id, ...readings }\n\t\t\t\t\t\t: undefined\n\t\tif (stop !== undefined && projectedStop === undefined) return undefined\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\t...(thinking === undefined ? {} : { thinking }),\n\t\t\t...(projectedUsage === undefined ? {} : { usage: projectedUsage }),\n\t\t\tpartial,\n\t\t\t...(projectedStop === undefined ? {} : { stop: projectedStop }),\n\t\t}\n\t})\n\n\treturn captured.success ? parseJSONValue(captured.value) : undefined\n}\n\n/**\n * Projects an unknown value onto a fresh, exact `TokenUsage` — capturing `prompt`, `completion`, and\n * `total` once each through a total boundary, preserving finite negative and fractional counts,\n * dropping extras, and resolving `undefined` for a non-object, a missing or non-finite count, a\n * throwing getter, or a hostile or revoked proxy.\n *\n * @remarks\n * The capture runs inside Contract's sanctioned exception boundary, so conforming accessors and\n * inherited properties are read while a throwing getter or a revoked proxy returns `undefined`.\n * Counts are not normalized. A caller that treats an absent usage as valid checks for `undefined`\n * before it projects, because this function refuses `undefined` like any other non-object.\n *\n * @param value - The unknown value to project\n * @returns A fresh `{ prompt, completion, total }`, or `undefined` when the value is not a finite usage triple\n *\n * @example\n * ```ts\n * import { tokenUsageToJSON } from '@orkestrel/agent'\n *\n * tokenUsageToJSON({ prompt: 2, completion: -1, total: 1.5, cached: 4 }) // { prompt: 2, completion: -1, total: 1.5 }\n * tokenUsageToJSON({ prompt: 2, completion: Infinity, total: 3 }) // undefined\n * ```\n */\nexport function tokenUsageToJSON(value: unknown): TokenUsage | undefined {\n\tconst captured = attempt(() => {\n\t\tif (!isObject(value)) return undefined\n\t\tconst prompt = Reflect.get(value, 'prompt')\n\t\tconst completion = Reflect.get(value, 'completion')\n\t\tconst total = Reflect.get(value, 'total')\n\t\treturn isFiniteNumber(prompt) && isFiniteNumber(completion) && isFiniteNumber(total)\n\t\t\t? { prompt, completion, total }\n\t\t\t: undefined\n\t})\n\treturn captured.success ? captured.value : undefined\n}\n\n/**\n * Infers which of a run's three failure layers stopped it — the meter allowance, a cost budget, or\n * the model's own token limit — and returns the stop record with the final call's readings, or\n * `undefined` when no layer stopped the run.\n *\n * @remarks\n * The layer that stopped the final provider call first wins. A model-truncated final answer whose\n * call returned unaborted is a `model` stop, even when that call's reconciled usage then exhausted a\n * budget or a cancel then landed before the run settled. Otherwise a `BudgetError` reason is a\n * `meter` stop when the allowance is exhausted, the reason is the allowance signal's own reason, its\n * context carries the allowance's `id` and `max`, and either the allowance is a separate instance or\n * the run had aborted when the call returned; any other `BudgetError` is a `budget` stop. The\n * identity test tells an allowance and a budget that share an `id` apart, and the readings test\n * tells a parent budget linked through the allowance's `signal` option apart from the allowance. An\n * external cancel, a deadline, or an `abort()` reason yields `undefined`. Two inputs still read as\n * the meter's: a charge a caller makes to the run's shared allowance from its own code while a call\n * streams, and a parent with the allowance's own `id` and `max` that aborted before `start()` when\n * the allowance then exhausts.\n *\n * @param reason - The run signal's abort reason (`undefined` while it is unaborted)\n * @param allowance - The run's meter allowance, or `undefined` for a run with no meter layer\n * @param budget - The run's cost budget, or `undefined` for an unbudgeted run\n * @param provider - The provider's trace `id`, named by a `model` stop\n * @param turn - The run's final turn record, or `undefined` when the run took no turn\n * @returns The stop record, or `undefined` when no layer stopped the run\n *\n * @example\n * ```ts\n * const allowance = createTokenBudget({ id: 'meter', max: 2 })\n * allowance.start()\n * allowance.consume({ prompt: 0, completion: 3, total: 3 })\n * inferStop(allowance.signal.reason, allowance, undefined, 'ollama', undefined)\n * // { layer: 'meter', id: 'meter', max: 2, consumed: 3 }\n * ```\n */\nexport function inferStop(\n\treason: unknown,\n\tallowance: BudgetInterface<TokenUsage> | undefined,\n\tbudget: BudgetInterface<TokenUsage> | undefined,\n\tprovider: string,\n\tturn: AgentTurn | undefined,\n): AgentStop | undefined {\n\tconst readings = {\n\t\t...(turn?.estimate === undefined ? {} : { estimate: turn.estimate }),\n\t\t...(turn?.usage === undefined ? {} : { usage: turn.usage }),\n\t}\n\tconst interrupted = turn?.interrupted === true\n\tif (!interrupted && turn?.truncated === true) return { layer: 'model', id: provider, ...readings }\n\tif (!isBudgetError(reason)) return undefined\n\tconst metered =\n\t\tallowance !== undefined &&\n\t\tallowance.exhausted &&\n\t\treason === allowance.signal.reason &&\n\t\treason.context.id === allowance.id &&\n\t\treason.context.max === allowance.max &&\n\t\t(allowance !== budget || interrupted)\n\treturn {\n\t\tlayer: metered ? 'meter' : 'budget',\n\t\tid: reason.context.id,\n\t\tmax: reason.context.max,\n\t\tconsumed: reason.context.consumed,\n\t\t...readings,\n\t}\n}\n\n/**\n * Estimates the context-token footprint of a string — the deterministic `ceil(length / 4)`\n * character heuristic {@link estimateMessages} sums over a conversation's messages (the default\n * context-budget estimator).\n *\n * @remarks\n * Approximates `ceil(length / 4)` (4 characters per token), so the same input always yields the same estimate (no model round-trip).\n * Empty text is `0`. This is a planning heuristic for reasoning about how much a turn's\n * messages cost the next request, not an exact tokenizer count — it never calls a provider,\n * so the agent layer stays provider-agnostic and synchronous where it can be.\n *\n * @param text - The text to estimate (a section summary, a message's content)\n * @returns The estimated token count (`ceil(text.length / 4)`; `0` for empty text)\n *\n * @example\n * ```ts\n * estimateTokens('') // 0\n * estimateTokens('hello') // 2 (ceil(5 / 4))\n * estimateTokens('a'.repeat(40)) // 10\n * ```\n */\nexport function estimateTokens(text: string): number {\n\treturn Math.ceil(text.length / 4)\n}\n\n/**\n * Estimates the context-token footprint of a batch of messages — each message's content plus\n * {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}, a tool-call JSON estimate, a thinking estimate, and\n * {@link import('./constants.js').IMAGE_TOKEN_ESTIMATE} for each attached image. The {@link estimateRequest} message term\n * for an agent's context budget (the\n * {@link import('./types.js').AgentOptions} `window`), a provider-independent approximation for conforming messages rather than an exact tokenizer count.\n *\n * @remarks\n * Sums, per message, {@link estimateTokens} over its `content` (the `ceil(length / 4)` character\n * heuristic) plus {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} (a fixed per-message\n * role/framing overhead) plus, when present, {@link estimateTokens} over its JSON-stringified\n * `calls` plus, when present, {@link estimateTokens} over its `thinking` plus `images.length * `{@link import('./constants.js').IMAGE_TOKEN_ESTIMATE} (a coarse,\n * deliberately-approximate per-image cost — a base64 length is not a token proxy). Deterministic\n * and provider-free — the same messages always yield the same estimate, with an empty batch `0`.\n * It is the message term of the request estimate an agent's auto-compaction context budget\n * measures; a caller wanting a sharper count supplies its own `consumer` to `createBudget`\n * instead. A `calls` list JSON cannot carry (a circular or `BigInt`\n * `ToolCall.arguments`) contributes a fixed\n * {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} (the same per-message overhead scale)\n * instead of an estimate of the (unreachable) serialized length.\n *\n * @param messages - The messages to estimate (a turn's appended assistant + tool messages)\n * @returns The summed estimated token count (`0` when empty)\n *\n * @example\n * ```ts\n * estimateMessages([]) // 0\n * estimateMessages([{ id: '1', role: 'user', content: 'hello' }]) // 6 (2 content + 4 overhead)\n * ```\n */\nexport function estimateMessages(messages: readonly Message[]): number {\n\treturn messages.reduce((sum, message) => {\n\t\tconst measure = measureMessage(message)\n\t\treturn (\n\t\t\tsum + measure.content + measure.framing + measure.calls + measure.thinking + measure.images\n\t\t)\n\t}, 0)\n}\n\n/**\n * Measures the disjoint estimate components of one message — its content, framing, rendered calls,\n * thinking, and attached images — as the same heuristic units {@link estimateMessages} sums.\n *\n * @remarks\n * The result is a structural estimate, not a tokenizer allocation. `id` and `role` are joins back to\n * the message, not token components, and a provider's template effects and the estimation error are\n * not individually attributed. `content` is `ceil(length / 4)`, `framing` is\n * {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}, `calls` is the estimate of the JSON-rendered\n * calls (`0` when the message carries none, the framing overhead when they cannot be rendered),\n * `thinking` is the estimate of the thinking (`0` when absent), and `images` is the attached image\n * count times {@link import('./constants.js').IMAGE_TOKEN_ESTIMATE}. The message is not mutated.\n *\n * @param message - The message to measure\n * @returns The message's identity and its estimate components\n *\n * @example\n * ```ts\n * measureMessage({ id: '1', role: 'user', content: 'hello' })\n * // { id: '1', role: 'user', content: 2, framing: 4, calls: 0, thinking: 0, images: 0 }\n * ```\n */\nexport function measureMessage(message: Message): MessageMeasure {\n\tconst rendered = hasCalls(message) ? renderJSON(message.calls) : ''\n\tconst calls = rendered === undefined ? MESSAGE_TOKEN_OVERHEAD : estimateTokens(rendered)\n\treturn {\n\t\tid: message.id,\n\t\trole: message.role,\n\t\tcontent: estimateTokens(message.content),\n\t\tframing: MESSAGE_TOKEN_OVERHEAD,\n\t\tcalls,\n\t\tthinking: message.thinking === undefined ? 0 : estimateTokens(message.thinking),\n\t\timages: (message.images?.length ?? 0) * IMAGE_TOKEN_ESTIMATE,\n\t}\n}\n\n/**\n * Estimates the context-token footprint of a complete provider request — its messages through\n * {@link estimateMessages}, plus the rendered advertised `tools`, plus the rendered\n * `options.schema`. The `consumer` estimator an agent's `window` budget measures every request\n * through, a provider-independent heuristic rather than an exact tokenizer count.\n *\n * @remarks\n * Adds {@link estimateTokens} over the JSON rendering of `tools` and of `options.schema` to the\n * message estimate. An absent or empty `tools` list and an absent or empty `schema` add `0`, so a\n * request that advertises neither equals {@link estimateMessages} of its messages. A value JSON\n * cannot carry contributes a fixed {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}. The\n * estimate counts JSON characters, not a provider's template: the chat template's own tokens, how\n * a provider encodes tool definitions, and the `think` flag are not counted, and no tokenizer\n * runs. A model's real prompt count can exceed it, so choose the window `max` with headroom\n * measured against the provider.\n *\n * @param request - The {@link ProviderRequest} to estimate: messages, advertised tools, call options\n * @returns The estimated token count (`0` for an empty request)\n *\n * @example\n * ```ts\n * estimateRequest({ messages: [{ id: '1', role: 'user', content: 'hello' }] }) // 6, equal to estimateMessages\n * ```\n */\nexport function estimateRequest(request: ProviderRequest): number {\n\tconst measure = measureRequest(request)\n\treturn measure.messages.reduce(\n\t\t(sum, message) =>\n\t\t\tsum + message.content + message.framing + message.calls + message.thinking + message.images,\n\t\tmeasure.tools + measure.schema,\n\t)\n}\n\n/**\n * Measures the disjoint estimate components of a complete provider request — each message through\n * {@link measureMessage}, plus the rendered advertised `tools` and `options.schema` — as the same\n * heuristic units {@link estimateRequest} sums.\n *\n * @remarks\n * The result is a structural estimate, not a tokenizer allocation; a provider's template effects, how\n * it encodes tool definitions, the `think` flag, and the estimation error are not individually\n * attributed. `messages` keeps the request's message order, duplicate ids included. `tools` and\n * `schema` are each `0` when absent or empty and the estimate of their JSON rendering otherwise, or\n * the {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} when JSON cannot carry them. The request\n * is not mutated.\n *\n * @param request - The {@link ProviderRequest} to measure: messages, advertised tools, call options\n * @returns The per-message components and the tools and schema estimates\n *\n * @example\n * ```ts\n * measureRequest({ messages: [{ id: '1', role: 'user', content: 'hello' }] })\n * // { messages: [{ id: '1', role: 'user', content: 2, framing: 4, calls: 0, thinking: 0, images: 0 }], tools: 0, schema: 0 }\n * ```\n */\nexport function measureRequest(request: ProviderRequest): RequestMeasure {\n\tconst tools = request.tools !== undefined && request.tools.length > 0 ? request.tools : undefined\n\tconst schema = request.options?.schema\n\tconst [toolsEstimate = 0, schemaEstimate = 0] = [\n\t\ttools,\n\t\tschema !== undefined && Object.keys(schema).length > 0 ? schema : undefined,\n\t].map((part) => {\n\t\tif (part === undefined) return 0\n\t\tconst rendered = renderJSON(part)\n\t\treturn rendered === undefined ? MESSAGE_TOKEN_OVERHEAD : estimateTokens(rendered)\n\t})\n\treturn {\n\t\tmessages: request.messages.map((message) => measureMessage(message)),\n\t\ttools: toolsEstimate,\n\t\tschema: schemaEstimate,\n\t}\n}\n\n/**\n * Runs one rehydrated agent and applies the partial-as-configurable-failure policy — a partial\n * run throws an {@link import('./errors.js').AgentJobError} unless the `partial` policy allows\n * it, and a natural finish resolves. The shared job-handler step `createAgentQueue` and\n * `createAgentRunner` both settle each job through, so the policy can never diverge between\n * them.\n *\n * @remarks\n * A turn that committed partial (a cancel — abort / budget / timeout) is by default a\n * failure, so it throws an {@link import('./errors.js').AgentJobError} carrying the partial\n * (the Queue's retries + a Runner's fail-fast then engage); the `partial` policy resolves\n * it as success instead. A natural finish always resolves with its result.\n *\n * @param agent - The rehydrated {@link AgentInterface} to run to its {@link AgentResult}\n * @param partial - The partial policy. If `true`, a partial result resolves as success; if\n * `false` (the default policy), a partial result throws an {@link AgentJobError}\n * @returns The agent's {@link AgentResult} (a natural finish, or a partial one under the\n * `partial` policy)\n * @throws {AgentJobError} Thrown when the run ended partial and the `partial` policy is `false`\n *\n * @example\n * ```ts\n * const result = await settleAgentJob(registry.build(input, signal), false)\n * ```\n */\nexport async function settleAgentJob(\n\tagent: AgentInterface,\n\tpartial: boolean,\n): Promise<AgentResult> {\n\tconst result = await agent.generate()\n\tif (result.partial && !partial) throw new AgentJobError('agent job ended partial', result)\n\treturn result\n}\n\n/**\n * Handles one queued agent job by rehydrating it through a registry with the queue\n * attempt's signal, then applying the shared partial-result policy.\n *\n * @param registry - The registry that rehydrates the serializable job\n * @param partial - The partial policy. If `true`, a partial result resolves; if `false`, it throws\n * @param input - The serializable agent job\n * @param context - The queue attempt whose signal bounds the agent\n * @returns The settled agent result\n *\n * @example\n * ```ts\n * const result = await handleAgentQueueJob(registry, false, input, context)\n * ```\n */\nexport function handleAgentQueueJob(\n\tregistry: AgentRegistryInterface,\n\tpartial: boolean,\n\tinput: AgentJobInput,\n\tcontext: QueueContext,\n): Promise<AgentResult> {\n\treturn settleAgentJob(registry.build(input, context.signal), partial)\n}\n\n/**\n * Assembles the settled {@link AgentResult} from a run's {@link AgentRunResult} — `thinking`,\n * `usage`, and `stop` are carried only when the run surfaced them, and the loop-internal\n * `exhausted` flag is left out.\n *\n * @remarks\n * Pure and total. An absent optional is omitted rather than stored as `undefined` (the\n * present-when-given convention the message store follows), so a settled result JSON\n * round-trips without an explicit `undefined` field. The keys follow `content`, `partial`,\n * `thinking`, `usage`, then `stop`. `exhausted` is loop bookkeeping and does not reach the public\n * result — the `exhaust` event carries it instead.\n *\n * @param outcome - The run's settled outcome\n * @returns The public {@link AgentResult}\n *\n * @example\n * ```ts\n * assembleResult({ content: 'hi', thinking: undefined, usage: undefined, partial: false, exhausted: false, stop: undefined })\n * // { content: 'hi', partial: false }\n * ```\n */\nexport function assembleResult(outcome: AgentRunResult): AgentResult {\n\treturn {\n\t\tcontent: outcome.content,\n\t\tpartial: outcome.partial,\n\t\t...(outcome.thinking === undefined ? {} : { thinking: outcome.thinking }),\n\t\t...(outcome.usage === undefined ? {} : { usage: outcome.usage }),\n\t\t...(outcome.stop === undefined ? {} : { stop: outcome.stop }),\n\t}\n}\n\n/**\n * Synthesizes the denial {@link ToolResult} an authority-blocked call is fed back with — the\n * call's `id` / `name` keyed back, carrying a denial `error` instead of a value.\n *\n * @remarks\n * Pure and total. The rule's `reason` is rendered as `denied: <reason>` when one was given,\n * else the generic `denied by authority`. There is no `value`, so the agent loop feeds it back\n * exactly like a tool error and the model can react to it.\n *\n * @param call - The denied {@link ToolCall}\n * @param reason - The rule's explanation, or `undefined` for the generic denial\n * @returns The failure-arm {@link ToolResult}\n *\n * @example\n * ```ts\n * denyCall({ id: '1', name: 'drop', arguments: {} }, 'read-only mode')\n * // { success: false, id: '1', name: 'drop', error: 'denied: read-only mode' }\n * ```\n */\nexport function denyCall(call: ToolCall, reason: string | undefined): ToolResult {\n\treturn {\n\t\tsuccess: false,\n\t\tid: call.id,\n\t\tname: call.name,\n\t\terror: reason !== undefined ? `denied: ${reason}` : 'denied by authority',\n\t}\n}\n\n/**\n * Consumes a reported usage against a budget over what was already charged, so a turn's total\n * draw is never less than the report and nothing is charged twice.\n *\n * @remarks\n * The full `prompt` count is consumed because no earlier charge covers it. Each of `completion`\n * and `total` is consumed less `charged`, floored at 0. An estimate above the report is not\n * refunded. The usage must already be sanitized: a\n * non-finite field yields a non-finite charge, which the installed `Budget` refuses by throwing\n * a `range` `ContractError`. Without a budget the call consumes nothing.\n *\n * @param budget - The budget to consume against, or `undefined` for an unmetered run\n * @param usage - The sanitized usage the provider reported\n * @param charged - The completion tokens already consumed this turn\n *\n * @example\n * ```ts\n * const budget = createBudget<TokenUsage>({ max: 1000, consumer: (usage) => usage.total })\n * chargeUsage(budget, { prompt: 20, completion: 30, total: 50 }, 10)\n * budget.consumed // 40\n * ```\n */\nexport function chargeUsage(\n\tbudget: BudgetInterface<TokenUsage> | undefined,\n\tusage: TokenUsage,\n\tcharged: number,\n): void {\n\tbudget?.consume({\n\t\tprompt: usage.prompt,\n\t\tcompletion: Math.max(0, usage.completion - charged),\n\t\ttotal: Math.max(0, usage.total - charged),\n\t})\n}\n\n/**\n * Returns a tool-iteration cap after checking it is a nonnegative safe integer, or throws a coded\n * error.\n *\n * @remarks\n * The check is {@link import('../validators.js').isNonNegativeSafeInteger}, so `0` and `-0`\n * pass while `NaN`, a fraction, a negative, and either infinity are refused. The error's `context`\n * carries the refused value as `limit`.\n *\n * @param limit - The tool-iteration cap to check\n * @returns The cap unchanged\n * @throws {AgentError} Thrown when `limit` is not a nonnegative safe integer (code `'LIMIT'`)\n *\n * @example\n * ```ts\n * requireLimit(3) // 3\n * requireLimit(1.5) // throws AgentError ('LIMIT')\n * ```\n */\nexport function requireLimit(limit: number): number {\n\tif (!isNonNegativeSafeInteger(limit)) {\n\t\tthrow new AgentError('LIMIT', 'a limit must be a nonnegative safe integer', {\n\t\t\tcontext: { limit },\n\t\t})\n\t}\n\treturn limit\n}\n\n/**\n * Returns a run's budget or allowance after checking it implements `BudgetInterface`, or throws a\n * coded error before the run starts it.\n *\n * @remarks\n * The check is `isBudget` from `@orkestrel/budget`, a total guard. `undefined` passes, because an\n * absent bound is no bound. The error's `context` carries the option path, the limit\n * `'BudgetInterface'`, and a preview of the refused value.\n *\n * @param value - The effective `budget` or `allowance`, or `undefined`\n * @param key - The option the value came from, named in the error's path\n * @returns The value unchanged\n * @throws {ContractError} Thrown when `value` is defined and does not implement `BudgetInterface` (code `'placement'`)\n *\n * @example\n * ```ts\n * requireBudget(createTokenBudget({ max: 10 }), 'budget') // the budget\n * requireBudget({ consume() {} }, 'allowance') // throws ContractError ('placement')\n * ```\n */\nexport function requireBudget(\n\tvalue: BudgetInterface<TokenUsage> | undefined,\n\tkey: 'budget' | 'allowance',\n): BudgetInterface<TokenUsage> | undefined {\n\tif (value === undefined || isBudget(value)) return value\n\tthrow new ContractError(`Agent: ${key} must implement BudgetInterface`, {\n\t\tcode: 'placement',\n\t\tcontext: { path: ['options', key], limit: 'BudgetInterface', received: preview(value) },\n\t})\n}\n\n/**\n * Renders a tool's output as the string content of its tool message.\n *\n * @remarks\n * A string passes through unchanged and `undefined` renders as `''`. Any other value renders as\n * its `JSON.stringify` text, byte for byte, when JSON can carry it. A value JSON cannot carry (a\n * `BigInt`, a cycle, a symbol, a throwing `toJSON`) renders as `String(value)`, and as `''` when\n * that conversion throws too, so a tool's output never rejects the run that dispatched it.\n *\n * @param value - The tool's output (`ToolSuccess.value`, which may be `undefined`)\n * @returns The message content\n *\n * @example\n * ```ts\n * renderToolValue('sunny') // 'sunny'\n * renderToolValue({ count: 2 }) // '{\"count\":2}'\n * renderToolValue(undefined) // ''\n * renderToolValue(10n) // '10'\n * ```\n */\nexport function renderToolValue(value: unknown): string {\n\tif (typeof value === 'string') return value\n\tif (value === undefined) return ''\n\tconst rendered = renderJSON(value)\n\tif (rendered !== undefined) return rendered\n\tconst fallback = attempt(() => String(value))\n\treturn fallback.success ? fallback.value : ''\n}\n\n/**\n * Returns a registered value or throws when its name is absent.\n * @param pool - The named values\n * @param category - The registry category named in an error\n * @param name - The requested key\n * @returns The registered value\n * @throws {AgentError} Thrown when the name is absent, with code REGISTRY and a `context` naming the `category` and the `name`.\n * @example\n * ```ts\n * requireEntry(new Map([['main', provider]]), 'provider', 'main') // provider\n * ```\n */\nexport function requireEntry<T>(pool: ReadonlyMap<string, T>, category: string, name: string): T {\n\tconst value = pool.get(name)\n\tif (value === undefined) {\n\t\tthrow new AgentError('REGISTRY', `unknown ${category}: ${name}`, {\n\t\t\tcontext: { category, name },\n\t\t})\n\t}\n\treturn value\n}\n\n/**\n * Extracts the present concurrency, retry, and deadline options for an agent job queue.\n * @param options - The queue options to project\n * @returns The present queue options, omitting absent keys\n * @example\n * ```ts\n * extractQueueOptions({ concurrency: 2 }) // { concurrency: 2 }\n * ```\n */\nexport function extractQueueOptions(\n\toptions: Pick<QueueOptions<AgentJobInput, AgentResult>, 'concurrency' | 'retries' | 'timeout'>,\n): Pick<QueueOptions<AgentJobInput, AgentResult>, 'concurrency' | 'retries' | 'timeout'> {\n\tconst { concurrency, retries, timeout } = options\n\treturn {\n\t\t...(concurrency === undefined ? {} : { concurrency }),\n\t\t...(retries === undefined ? {} : { retries }),\n\t\t...(timeout === undefined ? {} : { timeout }),\n\t}\n}\n","import type {\n\tAgentChunk,\n\tAgentEventMap,\n\tAgentInterface,\n\tAgentOptions,\n\tAgentResult,\n\tAgentRunOptions,\n\tAgentStatus,\n\tAgentStreamInterface,\n\tAgentTurn,\n\tAuthorityInterface,\n\tAgentRunResult,\n} from './types.js'\nimport type { ProviderInterface, ProviderRequest, ProviderResult } from '../providers/index.js'\nimport type { AgentContextInterface, Selection } from '../contexts/index.js'\nimport type { Section } from '../conversations/index.js'\nimport type { Message, ThinkingReplay } from '../types.js'\nimport type { AbortInterface } from '@orkestrel/abort'\nimport type { BudgetInterface, MeterInterface, TokenUsage } from '@orkestrel/budget'\nimport type { Result } from '@orkestrel/contract'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type { ToolCall, ToolManagerInterface, ToolResult } from '@orkestrel/tool'\nimport type { SchedulerInterface } from '@orkestrel/workflow'\nimport type { TimeoutInterface } from '@orkestrel/timeout'\nimport { createAbort } from '@orkestrel/abort'\nimport { createTokenMeter } from '@orkestrel/budget'\nimport { attempt } from '@orkestrel/contract'\nimport { createTimeout } from '@orkestrel/timeout'\nimport { Emitter } from '@orkestrel/emitter'\nimport { errorToMessage } from '@orkestrel/workflow'\nimport { AgentContext } from '../contexts/index.js'\nimport { DEFAULT_AGENT_LIMIT } from './constants.js'\nimport { AgentError } from './errors.js'\nimport { Channel } from './Channel.js'\nimport {\n\tassembleResult,\n\tchargeUsage,\n\tdenyCall,\n\testimateTokens,\n\tinferStop,\n\trenderToolValue,\n\trequireBudget,\n\trequireLimit,\n} from './helpers.js'\nimport { filterAllowList, sanitizeUsage, stripThinking, sumUsage } from '../helpers.js'\nimport { isProviderAbortError } from '../providers/index.js'\n\n/**\n * Composes a {@link ProviderInterface}, an {@link AgentContext}, and a\n * {@link ToolManagerInterface} into a bounded context → provider → tools → repeat turn, exposed\n * as both a one-shot `generate` and a live `stream` that share one private run — bounded by the\n * run `signal`, the `timeout`, and the `budget` folded through `AbortSignal.any`, paced by\n * `scheduler`, with tool iteration capped at `limit`.\n *\n * @remarks\n * - **One loop, two faces.** A single private async generator (`#execute`) drives the\n * whole run. `stream` drives it eagerly into a private {@link Channel} and settles `result`\n * from the outcome the generator returns, through one `.then` — so `result` settles\n * whether or not the live `events` are drained; `generate` awaits that same\n * settled `result` — so the two can never diverge.\n * - **The turn.** `#execute` builds the provider input once, then runs up to `limit` turns,\n * each appending one readonly {@link AgentTurn} record: drive `provider.stream(...)`,\n * yielding each content delta as a `token` chunk and charging its estimate to the\n * `allowance` when one is set; reconcile the turn's usage against the `budget`, before a\n * genuine provider error rejects the run too, and yield a `usage` chunk; if the model\n * requested tools, append the assistant turn, pass them to the tool manager's `execute`\n * method, yield a `tool` chunk per call, append each tool result message, and continue;\n * otherwise append the final assistant message and stop. The run's content,\n * thinking, usage, and stop derive from the turn records. Each assistant message stores its\n * call's non-empty thinking.\n * Provider calls and prompt estimates apply the provider's `replay` policy to the working\n * array; an absent policy means `'none'`.\n * - **Bounded.** Each run arms one cancel through `createAbort({ signal: AbortSignal.any([\n * …]) })` folding the external `signal`, the `timeout` deadline, and the `budget` and\n * `allowance` signals; `abort()` fires it. Any trip stops the loop and commits a partial result\n * (the `result` promise resolves, never rejects, on a cancel) — only a genuine\n * provider / tool error rejects.\n * - **Paced + capped.** The loop calls the `scheduler` object's `yield` method between turns when given; tool\n * iteration is capped at `limit`.\n * - **Two observation surfaces.** The pull {@link AgentChunk} stream carries per-token\n * deltas (+ usage/tool chunks); the push {@link emitter} ({@link AgentEventMap}) carries\n * lifecycle + usage/tool/deny moments for fire-and-forget observers. Every event is\n * emitted directly, after the relevant state transition / settle; the emitter isolates a\n * listener throw and routes it to its `error` handler (the `error` option), so a buggy\n * observer can never escape into / reorder / corrupt the settle-once loop — observation is\n * purely a side-channel.\n *\n * @example\n * ```ts\n * const agent = new Agent(provider, { system: 'You are concise.' })\n * agent.context.messages.add({ role: 'user', content: 'Say hi.' })\n * const result = await agent.generate()\n * ```\n */\nexport class Agent implements AgentInterface {\n\treadonly #id: string\n\treadonly #provider: ProviderInterface\n\treadonly #replay: ThinkingReplay\n\treadonly #context: AgentContextInterface\n\treadonly #limit: number\n\treadonly #timeoutMs: number | undefined\n\treadonly #budget: BudgetInterface<TokenUsage> | undefined\n\t// The meter layer's allowance: the budget each content delta's estimate is charged against while\n\t// a call streams. `undefined` ⇒ no meter layer; the estimate is still measured for `usage`.\n\treadonly #allowance: BudgetInterface<TokenUsage> | undefined\n\treadonly #scheduler: SchedulerInterface | undefined\n\treadonly #signal: AbortSignal | undefined\n\treadonly #authority: AuthorityInterface | undefined\n\t// The context budget that admits each provider request — its `consumer` is a token estimator\n\t// over the complete `ProviderRequest`, its `max` the context window. `#admit` re-measures the\n\t// exact request (replay-filtered messages, advertised tools, per-call options) against it before\n\t// every dispatch; `undefined` ⇒ disabled, and the loop never calls `#admit`. Reset (`clear()`)\n\t// at run entry so no stale `consumed` carries across runs / a conversation switch. Not the hard\n\t// cost `budget` ceiling — when the request reaches its `max` this compacts + continues\n\t// (non-fatal on a summarizer throw, futile-guarded) and never aborts; only `strict` refuses.\n\treadonly #window: BudgetInterface<ProviderRequest> | undefined\n\t// When true, a summarizer failure during automatic compaction rethrows (after the `fault`\n\t// event) instead of skipping compaction and continuing over-window, and a request still over\n\t// the window after the permitted fold is refused with a WINDOW error before dispatch.\n\treadonly #strict: boolean\n\t// The push observation surface — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into the loop. No\n\t// `destroy()`: the Agent holds no other teardownable resources, and an `Emitter` owns\n\t// only listener sets (no timers / handles), so it is reclaimed with the agent — there\n\t// is no leak to clear, and adding lifecycle the entity does not otherwise need is avoided.\n\treadonly #emitter: Emitter<AgentEventMap>\n\t// The label the last run settled on. `status` derives the live answer from `#runs`, so an\n\t// overlapping run can never report `done` while another is still in flight.\n\t#settled: AgentStatus = 'idle'\n\t// Every in-flight run's abort handle, mapped to the distinct budget and allowance instances that\n\t// run holds — a run adds its entry on `stream()` and its settle removes it, so `abort()` fires\n\t// every live run, not only the most recent, and the concurrency guard reads which instances are\n\t// held. Per-run, never a single shared slot a later `stream()` could clobber: `generate`/`stream`\n\t// are reusable and may overlap, and each run must cancel independently (its own `stream.abort()`\n\t// fires its own handle; `agent.abort()` fires them all).\n\treadonly #runs = new Map<AbortInterface, ReadonlyArray<BudgetInterface<TokenUsage>>>()\n\n\tconstructor(provider: ProviderInterface, options?: AgentOptions) {\n\t\tthis.#limit = requireLimit(options?.limit ?? DEFAULT_AGENT_LIMIT)\n\t\tthis.#id = crypto.randomUUID()\n\t\tthis.#provider = provider\n\t\tthis.#replay = provider.replay ?? 'none'\n\t\tthis.#context = new AgentContext({\n\t\t\t...(options?.system === undefined ? {} : { system: options.system }),\n\t\t\t...(options?.tools === undefined ? {} : { tools: options.tools }),\n\t\t\t...(options?.instructions === undefined ? {} : { instructions: options.instructions }),\n\t\t\t...(options?.workspaces === undefined ? {} : { workspaces: options.workspaces }),\n\t\t\t...(options?.scope === undefined ? {} : { scope: options.scope }),\n\t\t\t...(options?.conversations === undefined ? {} : { conversations: options.conversations }),\n\t\t\t...(options?.select === undefined ? {} : { select: options.select }),\n\t\t})\n\t\tthis.#timeoutMs = options?.timeout\n\t\tthis.#budget = options?.budget\n\t\tthis.#allowance = options?.allowance\n\t\tthis.#scheduler = options?.scheduler\n\t\tthis.#signal = options?.signal\n\t\tthis.#authority = options?.authority\n\t\tthis.#window = options?.window\n\t\tthis.#strict = options?.strict ?? false\n\t\tthis.#emitter = new Emitter<AgentEventMap>(options)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget emitter(): EmitterInterface<AgentEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget status(): AgentStatus {\n\t\t// Derived, never stored: a live run outranks any settled label, so overlapping runs can\n\t\t// never report `done` while one is still in flight, and a settled `error` is not erased\n\t\t// by a later run's `done` until that later run itself settles.\n\t\treturn this.#runs.size > 0 ? 'running' : this.#settled\n\t}\n\n\tget context(): AgentContextInterface {\n\t\treturn this.#context\n\t}\n\n\tgenerate(options?: AgentRunOptions): Promise<AgentResult> {\n\t\t// Zero loop logic of its own — start the stream (whose eager drive settles `result`\n\t\t// independently of any consumer) and await that same settled result, so `generate`\n\t\t// and `stream` can never diverge. No manual drain needed: the drive runs regardless.\n\t\treturn this.stream(options).result\n\t}\n\n\tstream(options?: AgentRunOptions): AgentStreamInterface {\n\t\t// Resolve effective per-run bounds — a per-run override wins, else the construction\n\t\t// default. `limit`, `budget`, and `allowance` also thread into `#execute` (the loop bound,\n\t\t// the reconcile, and the mid-stream meter); each budget is the same instance folded into\n\t\t// `#combineSignals`, so its trip both aborts the run and is the budget the run charges.\n\t\tconst limit = options?.limit === undefined ? this.#limit : requireLimit(options.limit)\n\t\t// Both bounds are checked before the concurrency guard and before either `start()`, so a\n\t\t// refused bound leaves the other untouched and nothing emitted.\n\t\tconst budget = requireBudget(options?.budget ?? this.#budget, 'budget')\n\t\tconst allowance = requireBudget(options?.allowance ?? this.#allowance, 'allowance')\n\t\t// The distinct accounting instances this run holds, cost budget first: an allowance that is\n\t\t// the budget itself is held, started, and folded once.\n\t\tconst held = [budget, allowance].filter(\n\t\t\t(one, index, all): one is BudgetInterface<TokenUsage> =>\n\t\t\t\tone !== undefined && all.indexOf(one) === index,\n\t\t)\n\t\t// Concurrency guard: a `window` is one context budget every run clears and measures, and a\n\t\t// budget instance carries one signal that `start()` replaces — a second live run on either\n\t\t// would race the first run's accounting or orphan its bound. Thrown synchronously, before\n\t\t// any state mutation or emit, so a sequential/awaited caller is never affected and runs\n\t\t// holding distinct budget instances with no `window` still overlap.\n\t\tif (\n\t\t\tthis.#runs.size > 0 &&\n\t\t\t(this.#window !== undefined ||\n\t\t\t\t[...this.#runs.values()].some((live) => live.some((one) => held.includes(one))))\n\t\t) {\n\t\t\tthrow new AgentError(\n\t\t\t\t'CONCURRENCY',\n\t\t\t\t'a live run on this agent holds the window or this budget or allowance instance; use separate agents or distinct instances per run',\n\t\t\t\t{ context: { agent: this.#id } },\n\t\t\t)\n\t\t}\n\t\t// The deadline is created unarmed: its signal keeps its identity when `start()` arms it, so\n\t\t// it can be composed first and armed only after nothing left can throw.\n\t\tconst timeoutMs = options?.timeout ?? this.#timeoutMs\n\t\tconst timeout = timeoutMs === undefined ? undefined : createTimeout({ ms: timeoutMs })\n\t\t// `start()` replaces each held budget's signal, so it precedes the composition that reads it.\n\t\tfor (const one of held) one.start()\n\t\t// Fold every present bound (external signal + a per-run signal + deadline + budget +\n\t\t// allowance) into one cancel the run races against; this run's own `abort()` fires this handle.\n\t\tconst signal = this.#combineSignals(timeout, budget, allowance, options?.signal)\n\t\tconst abort = createAbort(signal === undefined ? {} : { signal })\n\t\ttimeout?.start()\n\t\tthis.#runs.set(abort, held)\n\t\t// Observe the run begin — after the run joins `#runs` (which is what `status` derives\n\t\t// `running` from), so a swallowed listener throw can't perturb the state the drive is\n\t\t// about to change.\n\t\tthis.#emitter.emit('start', this.id)\n\t\tconst channel = new Channel<AgentChunk>()\n\t\tconst settled = Promise.withResolvers<AgentResult>()\n\t\t// Kick off the eager drive synchronously (not lazily on first `events` pull): it drives\n\t\t// `#execute` into the channel, and the run settles from its outcome regardless of whether\n\t\t// anyone drains `events`. The per-run `think` / `schema` preferences ride through to\n\t\t// `provider.stream`; `limit` / `budget` / `allowance` ride through as the effective run bounds.\n\t\tvoid this.#drive(\n\t\t\tabort,\n\t\t\tchannel,\n\t\t\toptions?.think,\n\t\t\toptions?.schema,\n\t\t\tlimit,\n\t\t\tbudget,\n\t\t\tallowance,\n\t\t).then(\n\t\t\t(outcome) => this.#finish(abort, timeout, channel, settled, limit, outcome),\n\t\t\t(error: unknown) => this.#fail(abort, timeout, channel, settled, error),\n\t\t)\n\t\t// An abandoned handle (neither `events` drained nor `result` awaited) must not surface an\n\t\t// unhandledRejection on a genuine error — guard the public result, where the rejection lives\n\t\t// (`#fail` rejects `settled` without re-throwing, so the drive's settle itself resolves).\n\t\t// A caller who awaits `result` still gets the rejection: `.catch` returns a derived promise, it\n\t\t// does not consume the original's rejection.\n\t\tsettled.promise.catch(() => {})\n\t\treturn {\n\t\t\tevents: this.#drainEvents(channel, abort),\n\t\t\tresult: settled.promise,\n\t\t\t// Fire this run's own handle (the closed-over `abort`), never a shared field a\n\t\t\t// later `stream()` could have replaced — so a handle's `abort()` always cancels\n\t\t\t// the run it belongs to, even when runs overlap.\n\t\t\tabort: abort.abort.bind(abort),\n\t\t}\n\t}\n\n\tabort(reason?: unknown): void {\n\t\t// Cancel every in-flight run — iterate a snapshot so a settle-driven `#runs.delete`\n\t\t// (a cancelled run unwinding) can't disturb the walk. Aborting is idempotent, so an\n\t\t// already-finished or already-cancelled handle is a harmless no-op.\n\t\tfor (const abort of [...this.#runs.keys()]) abort.abort(reason)\n\t}\n\n\t// Settles a finished or cancelled run: the deadline clears, the run leaves `#runs` (releasing its\n\t// budget instances), the channel closes, and the assembled result resolves before it is observed.\n\t// A cancel still resolves a partial, so a cancelled run emits `abort` (the cancel reason) then\n\t// `finish`; limit exhaustion is not a cancel and emits `exhaust` (the turn count) instead. Every\n\t// emit follows the resolve, so an isolated listener throw can't reorder the settle.\n\t#finish(\n\t\tabort: AbortInterface,\n\t\ttimeout: TimeoutInterface | undefined,\n\t\tchannel: Channel<AgentChunk>,\n\t\tsettled: PromiseWithResolvers<AgentResult>,\n\t\tlimit: number,\n\t\toutcome: AgentRunResult,\n\t): void {\n\t\ttimeout?.clear()\n\t\tthis.#runs.delete(abort)\n\t\tthis.#settled = 'done'\n\t\tchannel.close()\n\t\tconst result = assembleResult(outcome)\n\t\tsettled.resolve(result)\n\t\tif (outcome.exhausted) this.#emitter.emit('exhaust', limit)\n\t\telse if (outcome.partial) this.#emitter.emit('abort', abort.signal.reason)\n\t\tthis.#emitter.emit('finish', result)\n\t}\n\n\t// Settles a run a genuine (non-cancel) provider / tool error stopped: the channel fails, the\n\t// result rejects, and the failure is observed after the reject.\n\t#fail(\n\t\tabort: AbortInterface,\n\t\ttimeout: TimeoutInterface | undefined,\n\t\tchannel: Channel<AgentChunk>,\n\t\tsettled: PromiseWithResolvers<AgentResult>,\n\t\terror: unknown,\n\t): void {\n\t\ttimeout?.clear()\n\t\tthis.#runs.delete(abort)\n\t\tthis.#settled = 'error'\n\t\tchannel.fail(error)\n\t\tsettled.reject(error)\n\t\tthis.#emitter.emit('error', error)\n\t}\n\n\t// Drives `#execute` by hand, pushing each chunk into the channel, and returns the generator's\n\t// return value; a genuine provider / tool error rejects. `for await` would discard the return.\n\tasync #drive(\n\t\tabort: AbortInterface,\n\t\tchannel: Channel<AgentChunk>,\n\t\tthink: boolean | undefined,\n\t\tschema: Readonly<Record<string, unknown>> | undefined,\n\t\tlimit: number,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t\tallowance: BudgetInterface<TokenUsage> | undefined,\n\t): Promise<AgentRunResult> {\n\t\tconst run = this.#execute(abort, think, schema, limit, budget, allowance)\n\t\tfor (;;) {\n\t\t\tconst next = await run.next()\n\t\t\tif (next.done === true) return next.value\n\t\t\tchannel.push(next.value)\n\t\t}\n\t}\n\n\t// The live event stream: drain the channel the drive writes into, yielding each `AgentChunk` as it\n\t// is pushed (and throwing if the drive called `fail` on the channel). Its `return()` — fired when\n\t// a consumer exits with `break` early — fires the turn abort, so the run stops promptly: the drive\n\t// then completes the loop with `partial: true`, calls `clear` on the deadline, and settles\n\t// `result` to a non-misleading `{ partial: true }`, leaving `status` no longer `running`.\n\tasync *#drainEvents(\n\t\tchannel: Channel<AgentChunk>,\n\t\tabort: AbortInterface,\n\t): AsyncGenerator<AgentChunk, void> {\n\t\ttry {\n\t\t\tyield* channel.drain()\n\t\t} finally {\n\t\t\t// Early break (consumer stopped pulling): cancel the run so the drive unwinds and\n\t\t\t// settles partial. A natural end reaches here too with the signal already done, so\n\t\t\t// this abort is a harmless no-op then.\n\t\t\tabort.abort()\n\t\t}\n\t}\n\n\t// The core loop, shared by generate + stream. Builds the provider input once, then runs turns up\n\t// to `limit`, appending each turn's readonly record, and continues only while the latest turn\n\t// requested tools. A cancel (the bound abort) ends a turn with a `cancel` record — it never\n\t// throws; only a genuine provider / tool error propagates. Every record is local to one call, so\n\t// concurrent runs share nothing, and the settled `AgentRunResult` derives from the records.\n\t// Each turn runs in this generator, which delegates only the provider stream to `#provide`: a\n\t// delta crosses these two layers before `#drive` pushes it, and no per-turn generator settles\n\t// between a turn's chunks. Every further layer would let a consumer's early `return()` cancel the\n\t// provider a step sooner.\n\tasync *#execute(\n\t\tabort: AbortInterface,\n\t\tthink: boolean | undefined,\n\t\tschema: Readonly<Record<string, unknown>> | undefined,\n\t\tlimit: number,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t\tallowance: BudgetInterface<TokenUsage> | undefined,\n\t): AsyncGenerator<AgentChunk, AgentRunResult> {\n\t\t// Compaction can fold the request into a section, so every select site receives the object\n\t\t// captured at run entry.\n\t\tconst last = this.#context.conversations.active?.view().at(-1)\n\t\tconst request = last?.role === 'user' ? last : undefined\n\t\t// `#select` returns `undefined` when no handler is set, so the default path awaits nothing\n\t\t// before the first provider request.\n\t\tconst selecting = this.#select(request, abort, budget)\n\t\tconst entry =\n\t\t\tselecting === undefined\n\t\t\t\t? { messages: this.#context.build(), usage: undefined }\n\t\t\t\t: await selecting\n\t\tconst tools = this.#context.tools\n\t\t// The per-call options are fixed for the run, so every request carries this one snapshot;\n\t\t// absent when neither preference is set.\n\t\tconst options: ProviderRequest['options'] =\n\t\t\tthink === undefined && schema === undefined\n\t\t\t\t? undefined\n\t\t\t\t: {\n\t\t\t\t\t\t...(think === undefined ? {} : { think }),\n\t\t\t\t\t\t...(schema === undefined ? {} : { schema }),\n\t\t\t\t\t}\n\t\t// Reset `#window` at run entry so no stale `consumed` carries across runs / a conversation\n\t\t// switch. A `limit: 0` run never measures or folds, and adds no `await` when `window` is unset.\n\t\tthis.#window?.clear()\n\t\t// A cancel at the entry select site of a `limit: 0` run never reaches a turn's abort checks.\n\t\tconst cancelled = abort.signal.aborted\n\t\t// One readonly record per turn; the turn index is the list length.\n\t\tconst turns: AgentTurn[] = []\n\t\t// One turn per step: observe it, pace the boundary, admit the request, stream the provider,\n\t\t// reconcile the usage, then dispatch the requested tools or record the final answer. A cancel\n\t\t// appends a `cancel` record, which ends the loop; a genuine error throws. The section before\n\t\t// the provider call adds no `await` on the default path, so the provider's `stream()` is\n\t\t// entered in `agent.stream()`'s own call.\n\t\twhile (turns.length < limit && (turns.at(-1)?.ending ?? 'tools') === 'tools') {\n\t\t\tconst index = turns.length\n\t\t\tconst base = turns.at(-1)?.messages ?? entry.messages\n\t\t\tconst futile = turns.at(-1)?.futile ?? false\n\t\t\t// The record of a turn a cancel stopped before its provider call.\n\t\t\tconst stopped: AgentTurn = {\n\t\t\t\tcontent: '',\n\t\t\t\tthinking: undefined,\n\t\t\t\tusage: undefined,\n\t\t\t\tspent: undefined,\n\t\t\t\tmessages: base,\n\t\t\t\tending: 'cancel',\n\t\t\t\tpartial: true,\n\t\t\t\tfutile,\n\t\t\t\testimate: undefined,\n\t\t\t\tinterrupted: false,\n\t\t\t\ttruncated: false,\n\t\t\t}\n\t\t\t// Observe each turn begin (the turn index). The emitter isolates a listener throw, so it\n\t\t\t// can't perturb the turn that immediately follows.\n\t\t\tthis.#emitter.emit('turn', index)\n\t\t\t// Pace between expensive turns — never before the first. A scheduler honours the signal by\n\t\t\t// rejecting a pending yield on abort, so a cancel landing at the turn boundary surfaces here\n\t\t\t// as a throw; it stops the turn like any cancel, while a genuine scheduler fault propagates.\n\t\t\tif (index > 0) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.#scheduler?.yield({ signal: abort.signal })\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (!abort.signal.aborted) throw error\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (abort.signal.aborted) {\n\t\t\t\tturns.push(stopped)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Snapshot the allow-list before listeners can change the active scope this turn.\n\t\t\tconst names = this.#context.scope?.tools?.slice()\n\t\t\tconst advertised = filterAllowList(\n\t\t\t\tnames,\n\t\t\t\ttools.definitions(),\n\t\t\t\t(definition) => definition.name,\n\t\t\t)\n\t\t\tconst definitions = advertised.length > 0 ? advertised : undefined\n\t\t\t// Admit the request: compose it once from the replay-filtered messages and this turn's tool\n\t\t\t// and option snapshot, measure it against `#window`, and dispatch exactly the request the\n\t\t\t// window last measured (the rebuilt one after a fold). With no `window` it is composed and\n\t\t\t// dispatched with no extra `await`.\n\t\t\tconst composed = this.#compose(base, definitions, options)\n\t\t\tconst admitted =\n\t\t\t\tthis.#window === undefined\n\t\t\t\t\t? { dispatch: composed, messages: base, spent: undefined, futile }\n\t\t\t\t\t: await this.#admit(\n\t\t\t\t\t\t\tthis.#window,\n\t\t\t\t\t\t\tcomposed,\n\t\t\t\t\t\t\tbase,\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t\tindex > 0,\n\t\t\t\t\t\t\tfutile,\n\t\t\t\t\t\t\tabort,\n\t\t\t\t\t\t\tbudget,\n\t\t\t\t\t\t)\n\t\t\tif (admitted.dispatch === undefined) {\n\t\t\t\tturns.push({\n\t\t\t\t\t...stopped,\n\t\t\t\t\tmessages: admitted.messages,\n\t\t\t\t\tspent: admitted.spent,\n\t\t\t\t\tfutile: admitted.futile,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// The turn's streamed content, one entry per content delta; the meter charges only when an\n\t\t\t// allowance exists.\n\t\t\tconst streamed: string[] = []\n\t\t\tconst meter =\n\t\t\t\tallowance === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: createTokenMeter({ budget: allowance, estimator: estimateTokens })\n\t\t\tconst provided = yield* this.#provide(admitted.dispatch, abort.signal, streamed, meter)\n\t\t\tconst settled = this.#reconcile(provided, abort, streamed, admitted, meter, budget, allowance)\n\t\t\tif (!provided.success) {\n\t\t\t\tturns.push({ ...settled, ending: 'cancel', partial: true })\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst result = provided.value\n\t\t\tconst recorded = settled.thinking === undefined ? {} : { thinking: settled.thinking }\n\t\t\tif (settled.usage !== undefined) {\n\t\t\t\t// Observe this turn's usage — the result already exists; emit beside the yield.\n\t\t\t\tthis.#emitter.emit('usage', settled.usage, settled.estimate)\n\t\t\t\tyield { category: 'usage', usage: settled.usage, estimate: settled.estimate }\n\t\t\t}\n\t\t\tif (definitions === undefined) {\n\t\t\t\tfor (const call of result.tools ?? []) {\n\t\t\t\t\tthis.#emitter.emit('deny', call, 'no tool is advertised in the active scope')\n\t\t\t\t}\n\t\t\t} else if (result.tools !== undefined && result.tools.length > 0) {\n\t\t\t\tconst admittedCalls = filterAllowList(names, result.tools, (call) => call.name)\n\t\t\t\tconst authorization = this.#authorize(result.tools, admittedCalls)\n\t\t\t\tif (abort.signal.aborted) {\n\t\t\t\t\tturns.push({ ...settled, ending: 'cancel', partial: true })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst assistant = this.#context.messages.add({\n\t\t\t\t\trole: 'assistant',\n\t\t\t\t\tcontent: result.content,\n\t\t\t\t\tcalls: result.tools,\n\t\t\t\t\t...recorded,\n\t\t\t\t})\n\t\t\t\tconst results = await this.#dispatch(tools, result.tools, abort.signal, authorization)\n\t\t\t\t// Each dispatched call's tool message, appended per step of a loop that yields.\n\t\t\t\tconst replies: Message[] = []\n\t\t\t\tfor (const [position, call] of result.tools.entries()) {\n\t\t\t\t\tconst outcome = results[position]\n\t\t\t\t\tif (outcome === undefined) continue\n\t\t\t\t\t// Observe the dispatched tool + its result — beside the `tool` yield (the result\n\t\t\t\t\t// already exists). Carries the same pair the chunk carries.\n\t\t\t\t\tthis.#emitter.emit('tool', call, outcome)\n\t\t\t\t\tyield { category: 'tool', call, result: outcome }\n\t\t\t\t\t// `call` comes from the paired call rather than the result's `id`, so tool message\n\t\t\t\t\t// `position` names `calls[position]` even when a supplied tool manager returns another id.\n\t\t\t\t\treplies.push(\n\t\t\t\t\t\tthis.#context.messages.add({\n\t\t\t\t\t\t\trole: 'tool',\n\t\t\t\t\t\t\tcontent: outcome.success ? renderToolValue(outcome.value) : outcome.error,\n\t\t\t\t\t\t\tcall: call.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\t// The next turn's admission measures and folds the grown prompt, so a final answer never\n\t\t\t\t// pays for a fold. A tools turn's truncation does not end the run, so it is not recorded.\n\t\t\t\tturns.push({\n\t\t\t\t\t...settled,\n\t\t\t\t\tmessages: [...admitted.messages, assistant, ...replies],\n\t\t\t\t\tending: 'tools',\n\t\t\t\t\tpartial: true,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// No tools: this turn's content is the final answer — record it and finish.\n\t\t\tthis.#context.messages.add({ role: 'assistant', content: result.content, ...recorded })\n\t\t\tturns.push({\n\t\t\t\t...settled,\n\t\t\t\tcontent: result.content,\n\t\t\t\tending: 'answer',\n\t\t\t\tpartial: abort.signal.aborted,\n\t\t\t\ttruncated: result.truncated === true,\n\t\t\t})\n\t\t}\n\t\tconst final = turns.at(-1)\n\t\tconst thinkings = turns.flatMap((turn) => (turn.thinking === undefined ? [] : [turn.thinking]))\n\t\treturn {\n\t\t\tcontent:\n\t\t\t\tfinal?.ending === 'answer' ? final.content : turns.map((turn) => turn.content).join(''),\n\t\t\tthinking: thinkings.length === 0 ? undefined : thinkings.join('\\n\\n'),\n\t\t\t// Every turn's usage, then the entry selection's, then each rebuild's, in turn order.\n\t\t\tusage: [\n\t\t\t\t...turns.map((turn) => turn.usage),\n\t\t\t\tentry.usage,\n\t\t\t\t...turns.map((turn) => turn.spent),\n\t\t\t].reduce<TokenUsage | undefined>(\n\t\t\t\t(total, one) => (one === undefined ? total : sumUsage(total, one)),\n\t\t\t\tundefined,\n\t\t\t),\n\t\t\tpartial: final?.partial ?? cancelled,\n\t\t\t// Every allowed turn requested tools; a cancel during the last one is an `abort`, never an\n\t\t\t// `exhaust`, so the signal is read here.\n\t\t\texhausted: final?.ending === 'tools' && !abort.signal.aborted,\n\t\t\tstop: inferStop(abort.signal.reason, allowance, budget, this.#provider.id, final),\n\t\t}\n\t}\n\n\t// Settles one provider call into its turn's record fields, charges the cost budget at the one\n\t// charge site, then rethrows a genuine failure. A cancelled call's fields still describe what it\n\t// streamed; the caller adds the ending.\n\t#reconcile(\n\t\tprovided: Result<ProviderResult>,\n\t\tabort: AbortInterface,\n\t\tstreamed: readonly string[],\n\t\tadmitted: Pick<AgentTurn, 'messages' | 'spent' | 'futile'>,\n\t\tmeter: MeterInterface | undefined,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t\tallowance: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\t// Read before any reconcile: an abort seen here landed while the call ran, and a charge that\n\t\t// trips a bound below cannot turn a genuine failure into a partial.\n\t\tconst interrupted = abort.signal.aborted\n\t\t// The abort partial of an interrupted call is the only carrier of its reasoning and usage; the\n\t\t// streamed deltas already hold its content. A genuine failure contributes no usage.\n\t\tconst partial =\n\t\t\t!provided.success && interrupted && isProviderAbortError(provided.error)\n\t\t\t\t? provided.error.partial\n\t\t\t\t: undefined\n\t\tconst reasoning = provided.success ? provided.value.thinking : partial?.thinking\n\t\tconst thinking = reasoning !== undefined && reasoning.length > 0 ? reasoning : undefined\n\t\tconst content = streamed.join('')\n\t\tconst estimate = estimateTokens(content)\n\t\tconst reported = provided.success ? provided.value.usage : partial?.usage\n\t\tconst usage = reported === undefined ? undefined : sanitizeUsage(reported)\n\t\t// The one charge site for every path, a genuine failure included. The estimate is already on\n\t\t// the cost budget only when the meter charged that same instance; a call that reported no usage\n\t\t// keeps its estimate on the cost budget, unless the meter put it there.\n\t\tconst charged = allowance === budget ? (meter?.charged ?? 0) : 0\n\t\tconst billed =\n\t\t\tusage ??\n\t\t\t(allowance === budget ? undefined : { prompt: 0, completion: estimate, total: estimate })\n\t\tif (billed !== undefined) chargeUsage(budget, billed, charged)\n\t\tif (!provided.success && !interrupted) throw provided.error\n\t\treturn {\n\t\t\tcontent,\n\t\t\tthinking,\n\t\t\tusage,\n\t\t\tspent: admitted.spent,\n\t\t\tmessages: admitted.messages,\n\t\t\tfutile: admitted.futile,\n\t\t\testimate,\n\t\t\tinterrupted,\n\t\t\ttruncated: false,\n\t\t}\n\t}\n\n\t// Composes the exact request one provider dispatch sends: the working messages after the\n\t// provider's replay policy, the advertised tool definitions, and the per-call `think` / `schema`\n\t// options. Keys are omitted when undefined, so the provider receives no tools and no options\n\t// object when there are none. The request owns its messages array, a shallow copy after the\n\t// replay filter, because that filter returns the working array itself for a policy that keeps\n\t// every message. The admission step measures this object and `#provide` sends it, so the\n\t// measured and the dispatched request can never diverge.\n\t#compose(\n\t\tmessages: readonly Message[],\n\t\ttools: ProviderRequest['tools'],\n\t\toptions: ProviderRequest['options'],\n\t): ProviderRequest {\n\t\treturn {\n\t\t\tmessages: [...stripThinking(messages, this.#replay)],\n\t\t\t...(tools === undefined ? {} : { tools }),\n\t\t\t...(options === undefined ? {} : { options }),\n\t\t}\n\t}\n\n\t// Admits one request against the context `window` budget immediately before its provider\n\t// dispatch, so only called when a window is set. `clear()` then consuming the request makes\n\t// `window.consumed` its estimated footprint, and `exhausted` means it has reached `max`. A\n\t// request over the window folds the active conversation once when it is summarizable and not\n\t// latched futile, then rebuilds through selection, recomposes with the same tool and option\n\t// snapshot, and measures again; the request that measures last is the one dispatched. A\n\t// non-summarizable conversation is measured but never folded, so the auto path never throws the\n\t// `compact()` SUMMARIZER error. A cancel anywhere returns no dispatch so the run settles partial,\n\t// and wins over `strict`; otherwise `strict` refuses a request still over the window with a\n\t// WINDOW error before any dispatch, while the lenient default sends it.\n\tasync #admit(\n\t\twindow: BudgetInterface<ProviderRequest>,\n\t\tcomposed: ProviderRequest,\n\t\tmessages: readonly Message[],\n\t\trequest: Message | undefined,\n\t\tlatch: boolean,\n\t\tfutile: boolean,\n\t\tabort: AbortInterface,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\twindow.clear()\n\t\twindow.consume(composed)\n\t\tif (!window.exhausted) return { dispatch: composed, messages, spent: undefined, futile }\n\t\t// A cancelled run is about to settle, so a fold would spend summarizer time on a request no\n\t\t// provider reads; the next run's first admission folds instead.\n\t\tif (abort.signal.aborted) return { dispatch: undefined, messages, spent: undefined, futile }\n\t\tconst conversation = this.#context.conversations.active\n\t\tif (conversation?.summarizable !== true || futile) {\n\t\t\treturn { dispatch: this.#enforce(window, composed), messages, spent: undefined, futile }\n\t\t}\n\t\t// The run signal bounds the fold: `compact()` rejects with its reason on a cancel and\n\t\t// commits nothing, even when the summarizer ignores the signal.\n\t\treturn conversation.compact({ signal: abort.signal }).then(\n\t\t\t(section) => this.#refold(section, window, composed, messages, request, latch, abort, budget),\n\t\t\t(error: unknown) => this.#unfold(error, composed, messages, abort),\n\t\t)\n\t}\n\n\t// A fold that settled: a cancel wins; nothing folded latches on a later turn, where the tail had\n\t// its chance to grow, but not on the first; otherwise rebuild through selection (compaction\n\t// changed the view the handler evaluates) and measure the rebuilt request.\n\tasync #refold(\n\t\tsection: Section | undefined,\n\t\twindow: BudgetInterface<ProviderRequest>,\n\t\tcomposed: ProviderRequest,\n\t\tmessages: readonly Message[],\n\t\trequest: Message | undefined,\n\t\tlatch: boolean,\n\t\tabort: AbortInterface,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\tif (abort.signal.aborted)\n\t\t\treturn { dispatch: undefined, messages, spent: undefined, futile: false }\n\t\tif (section === undefined) {\n\t\t\treturn {\n\t\t\t\tdispatch: this.#enforce(window, composed),\n\t\t\t\tmessages,\n\t\t\t\tspent: undefined,\n\t\t\t\tfutile: latch,\n\t\t\t}\n\t\t}\n\t\tconst selecting = this.#select(request, abort, budget)\n\t\tconst rebuilt =\n\t\t\tselecting === undefined\n\t\t\t\t? { messages: this.#context.build(), usage: undefined }\n\t\t\t\t: await selecting\n\t\tif (abort.signal.aborted) {\n\t\t\treturn {\n\t\t\t\tdispatch: undefined,\n\t\t\t\tmessages: rebuilt.messages,\n\t\t\t\tspent: rebuilt.usage,\n\t\t\t\tfutile: false,\n\t\t\t}\n\t\t}\n\t\tconst dispatch = this.#compose(rebuilt.messages, composed.tools, composed.options)\n\t\twindow.clear()\n\t\twindow.consume(dispatch)\n\t\treturn {\n\t\t\tdispatch: this.#enforce(window, dispatch),\n\t\t\tmessages: rebuilt.messages,\n\t\t\tspent: rebuilt.usage,\n\t\t\tfutile: false,\n\t\t}\n\t}\n\n\t// A fold that rejected: a cancel wins over the failure it caused, as on the select path;\n\t// otherwise surface the summarizer failure observably, rethrow under `strict`, and send the\n\t// over-window request leniently.\n\t#unfold(\n\t\terror: unknown,\n\t\tcomposed: ProviderRequest,\n\t\tmessages: readonly Message[],\n\t\tabort: AbortInterface,\n\t) {\n\t\tif (abort.signal.aborted)\n\t\t\treturn { dispatch: undefined, messages, spent: undefined, futile: false }\n\t\tthis.#emitter.emit('fault', error)\n\t\tif (this.#strict) throw error\n\t\treturn { dispatch: composed, messages, spent: undefined, futile: false }\n\t}\n\n\t// Refuses, under `strict`, a request the window still measures over its max; returns it otherwise.\n\t#enforce(window: BudgetInterface<ProviderRequest>, request: ProviderRequest): ProviderRequest {\n\t\tif (this.#strict && window.exhausted) {\n\t\t\tthrow new AgentError(\n\t\t\t\t'WINDOW',\n\t\t\t\t`the request measures ${window.consumed} against a window of ${window.max} and cannot shrink`,\n\t\t\t\t{ context: { agent: this.#id, consumed: window.consumed, max: window.max } },\n\t\t\t)\n\t\t}\n\t\treturn request\n\t}\n\n\t// One select site: the handler's pending selection settled into the working messages and the\n\t// usage it spent, or `undefined` when there is no request or no handler, so the caller builds from\n\t// `view()` without an await.\n\t#select(\n\t\trequest: Message | undefined,\n\t\tabort: AbortInterface,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\tconst pending = request === undefined ? undefined : this.#context.select(request, abort.signal)\n\t\treturn pending === undefined\n\t\t\t? undefined\n\t\t\t: pending.then(\n\t\t\t\t\t(selection) => this.#adopt(selection, abort, budget),\n\t\t\t\t\t(error: unknown) => this.#reject(error, abort),\n\t\t\t\t)\n\t}\n\n\t// A resolved selection: charge its usage before the abort check, because judge calls were spent\n\t// either way and the charge can itself trip the run's bound; then build from it unless a cancel or\n\t// a strict fault intervenes. A cancelled site builds from `view()` and emits no `select`.\n\t#adopt(\n\t\tselection: Selection,\n\t\tabort: AbortInterface,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\tconst usage = selection.usage === undefined ? undefined : sanitizeUsage(selection.usage)\n\t\tif (usage !== undefined) chargeUsage(budget, usage, 0)\n\t\tif (abort.signal.aborted) return { messages: this.#context.build(), usage }\n\t\tif (selection.fault !== undefined) {\n\t\t\tthis.#emitter.emit('fault', selection.fault)\n\t\t\tif (abort.signal.aborted) return { messages: this.#context.build(), usage }\n\t\t\tif (this.#strict) throw selection.fault\n\t\t}\n\t\tconst messages = this.#context.build(selection)\n\t\tthis.#emitter.emit('select', selection)\n\t\treturn { messages, usage }\n\t}\n\n\t// A rejected selection: a fault unless cancelled, rethrown under `strict`, then the default build.\n\t#reject(error: unknown, abort: AbortInterface) {\n\t\tif (!abort.signal.aborted) {\n\t\t\tthis.#emitter.emit('fault', error)\n\t\t\t// A `fault` listener can cancel the run synchronously; the cancel then wins over `strict`.\n\t\t\tif (this.#strict && !abort.signal.aborted) throw error\n\t\t}\n\t\treturn { messages: this.#context.build(), usage: undefined }\n\t}\n\n\t// Evaluate policy and emit denials before the run's final pre-dispatch abort guard:\n\t// policy callbacks and denial listeners can cancel the run synchronously.\n\t#authorize(calls: readonly ToolCall[], admitted: readonly ToolCall[]) {\n\t\t// `entries()` visits a hole as `undefined`, as a `for…of` over the calls does.\n\t\tconst decisions = [...calls.entries()].map(([index, call]) => ({\n\t\t\tindex,\n\t\t\tcall,\n\t\t\tdenial: this.#decide(call, admitted),\n\t\t}))\n\t\treturn {\n\t\t\tallowed: new Map(\n\t\t\t\tdecisions.flatMap((one) =>\n\t\t\t\t\tone.denial === undefined ? [[one.index, one.call] as const] : [],\n\t\t\t\t),\n\t\t\t),\n\t\t\tdenials: new Map(\n\t\t\t\tdecisions.flatMap((one) =>\n\t\t\t\t\tone.denial === undefined ? [] : [[one.index, one.denial] as const],\n\t\t\t\t),\n\t\t\t),\n\t\t}\n\t}\n\n\t// Decides one call — scope, then authority — and emits `deny` with the reason of a denial.\n\t#decide(call: ToolCall, admitted: readonly ToolCall[]): ToolResult | undefined {\n\t\tif (!admitted.includes(call)) {\n\t\t\tconst reason = `${call.name} is not in the active scope`\n\t\t\tconst denial = denyCall(call, reason)\n\t\t\tthis.#emitter.emit('deny', call, reason)\n\t\t\treturn denial\n\t\t}\n\t\tconst authority = this.#authority\n\t\tif (authority === undefined) return undefined\n\t\t// A security gate must fail closed: if a policy `evaluate` throws, the call is not\n\t\t// cleared, so it must not run. Synthesize a denial (carrying the error's message)\n\t\t// instead of letting the throw reject the whole run — the tool stays unexecuted and\n\t\t// the model still receives a denial it can react to, exactly like an explicit `deny`.\n\t\tconst evaluated = attempt(() => authority.evaluate({ call }))\n\t\tif (!evaluated.success) {\n\t\t\t// The declared `@orkestrel/workflow` normalizer, so a fail-closed denial carries a\n\t\t\t// non-empty explanation the model can read: an `Error` with an empty `message`\n\t\t\t// normalizes to real text, and a throw whose stringification itself fails is caught\n\t\t\t// rather than escaping the gate and rejecting the run.\n\t\t\tconst reason = errorToMessage(evaluated.error)\n\t\t\tconst denial = denyCall(call, reason)\n\t\t\tthis.#emitter.emit('deny', call, reason)\n\t\t\treturn denial\n\t\t}\n\t\tif (evaluated.value.allowed) return undefined\n\t\tconst denial = denyCall(call, evaluated.value.reason)\n\t\tthis.#emitter.emit('deny', call, evaluated.value.reason)\n\t\treturn denial\n\t}\n\n\t// Carry cancellation into entered handlers, then merge executed results and denials\n\t// in call order. An all-denied turn costs no tool run.\n\tasync #dispatch(\n\t\ttools: ToolManagerInterface,\n\t\tcalls: readonly ToolCall[],\n\t\tsignal: AbortSignal,\n\t\tauthorization: {\n\t\t\treadonly allowed: ReadonlyMap<number, ToolCall>\n\t\t\treadonly denials: ReadonlyMap<number, ToolResult>\n\t\t},\n\t): Promise<readonly ToolResult[]> {\n\t\tconst { allowed, denials } = authorization\n\t\tconst executed = allowed.size > 0 ? await tools.execute([...allowed.values()], { signal }) : []\n\t\t// Denials and executed results never share an index.\n\t\tconst results = new Map<number, ToolResult>([\n\t\t\t...denials,\n\t\t\t...[...allowed.keys()].flatMap((index, offset) => {\n\t\t\t\tconst result = executed[offset]\n\t\t\t\treturn result === undefined ? [] : [[index, result] as const]\n\t\t\t}),\n\t\t])\n\t\treturn calls.map((call, index) => results.get(index) ?? denyCall(call, undefined))\n\t}\n\n\t// Drive one provider stream turn: read the `channel` of each {@link ProviderDelta} — a `'content'`\n\t// delta is the answer (appended to the turn's `streamed` log, charged through the meter, surfaced\n\t// as a `token` chunk, in that order); a `'thinking'` delta is live reasoning (surfaced as a `think`\n\t// chunk, never metered — reasoning is not answer content) — returning the provider's assembled\n\t// result or its failure as a Result built through the installed `attempt`, so the turn reads a\n\t// provider or meter failure from a value. It sends the composed {@link ProviderRequest}\n\t// unchanged — the messages already carry only the thinking the provider's replay policy permits\n\t// (default `'none'`), and the tools and options are the turn's snapshot, absent when there are\n\t// none. It pulls the provider itself, so no generator layer sits between a delta and the turn.\n\tasync *#provide(\n\t\trequest: ProviderRequest,\n\t\tsignal: AbortSignal,\n\t\tstreamed: string[],\n\t\tmeter: MeterInterface | undefined,\n\t): AsyncGenerator<AgentChunk, Result<ProviderResult>> {\n\t\ttry {\n\t\t\tconst generator = this.#provider.stream(\n\t\t\t\trequest.messages,\n\t\t\t\tsignal,\n\t\t\t\trequest.tools,\n\t\t\t\trequest.options,\n\t\t\t)\n\t\t\tfor (;;) {\n\t\t\t\tconst next = await generator.next()\n\t\t\t\tif (next.done === true) {\n\t\t\t\t\tconst result = next.value\n\t\t\t\t\treturn attempt(() => result)\n\t\t\t\t}\n\t\t\t\tconst delta = next.value\n\t\t\t\tif (delta.channel === 'content') {\n\t\t\t\t\tstreamed.push(delta.text)\n\t\t\t\t\tmeter?.charge(delta.text)\n\t\t\t\t\tyield { category: 'token', content: delta.text }\n\t\t\t\t} else {\n\t\t\t\t\tyield { category: 'think', content: delta.text }\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\treturn attempt((): ProviderResult => {\n\t\t\t\tthrow error\n\t\t\t})\n\t\t}\n\t}\n\n\t// The parent signal for a run's abort: the external signal, an optional per-run signal\n\t// (composed with, never replacing, the construction `signal`), the deadline, the effective\n\t// budget, and an allowance that is not the budget itself, folded through `AbortSignal.any` —\n\t// or a lone present one, or `undefined` when none. The budget precedes the allowance, so when\n\t// both are exhausted before the run the budget's reason is the run's.\n\t#combineSignals(\n\t\ttimeout: TimeoutInterface | undefined,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t\tallowance: BudgetInterface<TokenUsage> | undefined,\n\t\tsignal: AbortSignal | undefined,\n\t): AbortSignal | undefined {\n\t\tconst signals = [\n\t\t\tthis.#signal,\n\t\t\tsignal,\n\t\t\ttimeout?.signal,\n\t\t\tbudget?.signal,\n\t\t\tallowance === budget ? undefined : allowance?.signal,\n\t\t].filter((one): one is AbortSignal => one !== undefined)\n\t\tif (signals.length === 0) return undefined\n\t\tif (signals.length === 1) return signals[0]\n\t\treturn AbortSignal.any(signals)\n\t}\n}\n","import type { AgentJobInput, AgentRegistryInterface, AgentResult } from './types.js'\nimport type { ControllerInterface } from '@orkestrel/workflow'\nimport { settleAgentJob } from './helpers.js'\n\n/**\n * Executes one runner's agent jobs — spawning each unit's declared children on its first attempt\n * only, then rehydrating the unit through a registry with the controller signal and settling it\n * under the shared partial-result policy.\n *\n * @remarks\n * One instance serves one runner, because it records every unit it has fanned out. The runner\n * calls its handler once per attempt with the same unit id, so a retried attempt finds its unit\n * recorded and spawns no child again. Children are fired through the controller without being\n * awaited inline, so a bounded runner frees the parent's slot for them. `createAgentRunner`\n * creates one instance per runner and binds its `execute` method as the runner's handler.\n *\n * @example\n * ```ts\n * import type { AgentJobInput, ProviderInterface } from '@orkestrel/agent'\n * import { AgentFanout, createAgentRegistry } from '@orkestrel/agent'\n * import { createRunner } from '@orkestrel/workflow'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * const fanout = new AgentFanout(createAgentRegistry({ providers: { main: provider } }), false)\n * const runner = createRunner({ handler: fanout.execute.bind(fanout), retries: 1 })\n * const child: AgentJobInput = { provider: 'main', messages: [{ role: 'user', content: 'child' }] }\n * const parent: AgentJobInput = { ...child, messages: [{ role: 'user', content: 'parent' }], children: [child] }\n * const results = await runner.execute([parent]) // the parent's result, then the child's\n * ```\n */\nexport class AgentFanout {\n\treadonly #registry: AgentRegistryInterface\n\treadonly #partial: boolean\n\t// The ids of the units whose children this runner already spawned. Copy-on-write, and never\n\t// shrunk: a unit id stays recorded so every later attempt of that unit skips the fan-out.\n\t#spawned: ReadonlySet<string> = new Set<string>()\n\n\t/**\n\t * Creates the fan-out for one runner over a registry and a partial policy.\n\t *\n\t * @param registry - The registry that rehydrates each serializable job\n\t * @param partial - The partial policy. If `true`, a partial result resolves; if `false`, it throws an `AgentJobError`\n\t */\n\tconstructor(registry: AgentRegistryInterface, partial: boolean) {\n\t\tthis.#registry = registry\n\t\tthis.#partial = partial\n\t}\n\n\t/**\n\t * Executes one unit: spawns its declared children unless an earlier attempt of the unit already\n\t * did, then runs the rehydrated agent and settles it under the partial policy.\n\t *\n\t * @param controller - The runner controller for this unit's attempt\n\t * @returns The settled agent result of the unit\n\t * @throws {AgentJobError} Thrown when the run ended partial and the partial policy is `false`\n\t */\n\texecute(controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult> {\n\t\tconst children = controller.input.children\n\t\tif (children !== undefined && !this.#spawned.has(controller.id)) {\n\t\t\tthis.#spawned = new Set([...this.#spawned, controller.id])\n\t\t\tfor (const child of children) void controller.spawn(child)\n\t\t}\n\t\treturn settleAgentJob(this.#registry.build(controller.input, controller.signal), this.#partial)\n\t}\n}\n","import type {\n\tAuthorityContext,\n\tAuthorityDecision,\n\tAuthorityInterface,\n\tAuthorityOptions,\n\tAuthorityRule,\n} from './types.js'\nimport { DEFAULT_AUTHORITY_ZONE } from './constants.js'\n\n/**\n * Gates the agent loop's tool calls — the synchronous policy consulted before each call runs,\n * turning one {@link AuthorityContext} into an {@link AuthorityDecision} by walking the ordered\n * rules first-match-wins and falling back to a configurable default, which allows an unmatched\n * call unless its `fallback` denies.\n *\n * @remarks\n * - **Ordered, first-match-wins.** `evaluate` walks the configured rules in order and\n * returns the first whose `match(context)` is true as\n * `{ zone, allowed: rule.allowed ?? true, reason }` — a matched rule allows by\n * default and denies only when its `allowed` is explicitly `false`.\n * - **Fallback.** When no rule matches, `evaluate` returns the configured `fallback`.\n * Default: `{ zone: DEFAULT_AUTHORITY_ZONE, allowed: true }` (allow-unmatched),\n * so a rules list of denials behaves as a denylist. To make the gate deny-by-default\n * (an allowlist — only matched rules that allow get through), pass an `allowed: false`\n * `fallback`.\n * - **Consulted before each tool call.** The agent loop calls `evaluate({ call })` for\n * every {@link import('@orkestrel/tool').ToolCall} the model emits; a denied call is fed\n * back to the model as a denial {@link import('@orkestrel/tool').ToolResult} (a `tool`\n * chunk + a tool message) instead of being executed — no tool execution —\n * so the model receives the denial and can react.\n * - **Synchronous.** `evaluate` returns the verdict directly.\n * - **Event-free.** A purely functional gate — no Emitter, no events.\n *\n * @example\n * ```ts\n * // A denylist: deny the `delete` tool, allow everything else (default fallback).\n * const authority = new Authority({\n * \trules: [{ match: (c) => c.call.name === 'delete', zone: 'restricted', allowed: false }],\n * })\n * authority.evaluate({ call: { id: '1', name: 'delete', arguments: {} } }) // { zone: 'restricted', allowed: false }\n * authority.evaluate({ call: { id: '2', name: 'add', arguments: {} } }) // { zone: 'default', allowed: true }\n * ```\n */\nexport class Authority implements AuthorityInterface {\n\treadonly #rules: readonly AuthorityRule[]\n\treadonly #fallback: AuthorityDecision\n\n\tconstructor(options?: AuthorityOptions) {\n\t\tthis.#rules = options?.rules ?? []\n\t\tthis.#fallback = options?.fallback ?? { zone: DEFAULT_AUTHORITY_ZONE, allowed: true }\n\t}\n\n\tevaluate(context: AuthorityContext): AuthorityDecision {\n\t\tfor (const rule of this.#rules) {\n\t\t\tif (rule.match(context))\n\t\t\t\treturn {\n\t\t\t\t\tzone: rule.zone,\n\t\t\t\t\tallowed: rule.allowed ?? true,\n\t\t\t\t\t...(rule.reason === undefined ? {} : { reason: rule.reason }),\n\t\t\t\t}\n\t\t}\n\t\treturn this.#fallback\n\t}\n}\n","import type {\n\tAgentInterface,\n\tAgentJobInput,\n\tAgentOptions,\n\tAgentRegistryInterface,\n\tAgentRegistryOptions,\n\tAuthorityInterface,\n} from './types.js'\nimport type { ProviderInterface } from '../providers/index.js'\nimport type { ConversationStoreInterface } from '../conversations/index.js'\nimport type { ToolInterface } from '@orkestrel/tool'\nimport type { SchedulerInterface } from '@orkestrel/workflow'\nimport { createTokenBudget } from '@orkestrel/budget'\nimport { ToolManager } from '@orkestrel/tool'\nimport { Agent } from './Agent.js'\nimport { ConversationManager } from '../conversations/index.js'\nimport { requireEntry } from './helpers.js'\n\n/**\n * Makes a durable, JSON-serializable {@link AgentJobInput} runnable — holds the named pools of\n * live, non-serializable pieces (providers, tools, authorities, schedulers), throws on a name\n * absent from its pool, and its `build` method returns a seeded, signal-wired {@link Agent} from a job's names and\n * data.\n *\n * @remarks\n * - **Why it exists.** An `AgentJobInput` is serializable so it can survive a crash in a\n * Queue's store; the live objects it needs (a provider with sockets, tools / rules /\n * schedulers carrying functions) cannot serialize. The registry closes that gap:\n * construct it once with the live pools, then a queue / runner handler calls `build`\n * on each (possibly restored) job to get a ready agent.\n * - **Accessors throw on a miss.** `provider` / `tool` / `authority` / `scheduler` resolve a\n * name against their pool and throw an {@link AgentError} carrying `code: 'REGISTRY'` and\n * the message `unknown <category>: <name>` when it is absent — an unknown name in a\n * rehydrated job is a programmer / config error that must fail loudly at build time, never\n * silently resolve to `undefined` and run an agent missing a dependency.\n * - **`build` rehydrates.** Resolve the job's `provider`; assemble a fresh\n * {@link ToolManager} from the `tools` names; rebuild the token `budget` from its\n * ceiling (`createTokenBudget({ max })`); resolve the optional `authority` /\n * `scheduler` names; construct the {@link Agent} with `system` / `limit` / `timeout` /\n * the threaded `signal`; seed its context with the job's `messages`; return it. The\n * `signal` is the queue attempt's / runner unit's cancel, so a bounded abort propagates\n * into the agent (which commits a partial — the job's `partial` policy then\n * decides success vs. retry). A job `limit` that is not a nonnegative safe integer throws an\n * {@link AgentError} carrying `code: 'LIMIT'` from the agent's construction.\n * - **Event-free.** A pure resolver — no Emitter, no events.\n *\n * @example\n * ```ts\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * const registry = new AgentRegistry({ providers: { main: provider } })\n * const agent = registry.build({ provider: 'main', messages: [{ role: 'user', content: 'Say ok.' }] })\n * const result = await agent.generate()\n * ```\n */\nexport class AgentRegistry implements AgentRegistryInterface {\n\treadonly #providers: ReadonlyMap<string, ProviderInterface>\n\treadonly #tools: ReadonlyMap<string, ToolInterface>\n\treadonly #authorities: ReadonlyMap<string, AuthorityInterface>\n\treadonly #schedulers: ReadonlyMap<string, SchedulerInterface>\n\treadonly #store: ConversationStoreInterface | undefined\n\n\tconstructor(options: AgentRegistryOptions) {\n\t\tthis.#providers = new Map(Object.entries(options.providers))\n\t\tthis.#tools = new Map(Object.entries(options.tools ?? {}))\n\t\tthis.#authorities = new Map(Object.entries(options.authorities ?? {}))\n\t\tthis.#schedulers = new Map(Object.entries(options.schedulers ?? {}))\n\t\tthis.#store = options.store\n\t}\n\n\tprovider(name: string): ProviderInterface {\n\t\treturn requireEntry(this.#providers, 'provider', name)\n\t}\n\n\ttool(name: string): ToolInterface {\n\t\treturn requireEntry(this.#tools, 'tool', name)\n\t}\n\n\tauthority(name: string): AuthorityInterface {\n\t\treturn requireEntry(this.#authorities, 'authority', name)\n\t}\n\n\tscheduler(name: string): SchedulerInterface {\n\t\treturn requireEntry(this.#schedulers, 'scheduler', name)\n\t}\n\n\tbuild(input: AgentJobInput, signal?: AbortSignal): AgentInterface {\n\t\tconst provider = this.provider(input.provider)\n\t\tconst agent = new Agent(provider, this.#buildOptions(input, signal))\n\t\t// Seed the conversation onto the rehydrated agent's context — the serializable\n\t\t// MessageInputs become stored messages (each id minted by the manager).\n\t\tfor (const message of input.messages) agent.context.messages.add(message)\n\t\treturn agent\n\t}\n\n\t// Assemble the AgentOptions for one job: a fresh ToolManager loaded from the named\n\t// tools, the rebuilt token budget, the resolved authority / scheduler, plus the data\n\t// fields and the threaded cancel. Optional fields are omitted (not set to `undefined`)\n\t// so the Agent's `?? default` fallbacks behave exactly as for a hand-built agent. When\n\t// the registry carries a conversation store, thread a fresh store-backed\n\t// ConversationManager for this build (a fresh conversation id per build ⇒ no\n\t// collisions in the shared store) — omitted when no store is set, so the shape matches a\n\t// registry with no `store`.\n\t#buildOptions(input: AgentJobInput, signal: AbortSignal | undefined): AgentOptions {\n\t\tconst budget = input.budget === undefined ? undefined : createTokenBudget({ max: input.budget })\n\t\treturn {\n\t\t\ttools: this.#buildToolManager(input.tools),\n\t\t\t...(input.system === undefined ? {} : { system: input.system }),\n\t\t\t...(input.limit === undefined ? {} : { limit: input.limit }),\n\t\t\t...(input.timeout === undefined ? {} : { timeout: input.timeout }),\n\t\t\t...(budget === undefined ? {} : { budget }),\n\t\t\t...(input.authority === undefined ? {} : { authority: this.authority(input.authority) }),\n\t\t\t...(input.scheduler === undefined ? {} : { scheduler: this.scheduler(input.scheduler) }),\n\t\t\t...(this.#store === undefined\n\t\t\t\t? {}\n\t\t\t\t: { conversations: new ConversationManager({ store: this.#store }) }),\n\t\t\t...(signal === undefined ? {} : { signal }),\n\t\t}\n\t}\n\n\t// A fresh tool registry loaded with the named tools (each resolved — an unknown name\n\t// throws). Always a new manager per build, so concurrent jobs never share one.\n\t#buildToolManager(names: readonly string[] | undefined): ToolManager {\n\t\tconst manager = new ToolManager()\n\t\tif (names !== undefined) for (const name of names) manager.add(this.tool(name))\n\t\treturn manager\n\t}\n}\n","import type { ProviderInterface } from '../providers/index.js'\nimport type {\n\tAgentInterface,\n\tAgentJobInput,\n\tAgentOptions,\n\tAgentQueueOptions,\n\tAgentRegistryInterface,\n\tAgentRegistryOptions,\n\tAgentResult,\n\tAgentRunnerOptions,\n\tAuthorityInterface,\n\tAuthorityOptions,\n\tChannelInterface,\n} from './types.js'\nimport type { QueueInterface } from '@orkestrel/queue'\nimport type { RunnerInterface } from '@orkestrel/workflow'\nimport { createQueue } from '@orkestrel/queue'\nimport { createRunner } from '@orkestrel/workflow'\nimport { Agent } from './Agent.js'\nimport { AgentFanout } from './AgentFanout.js'\nimport { Channel } from './Channel.js'\nimport { Authority } from './Authority.js'\nimport { AgentRegistry } from './AgentRegistry.js'\nimport { extractQueueOptions, handleAgentQueueJob } from './helpers.js'\n\n/**\n * Creates an agent loop — an {@link AgentInterface} composing a\n * {@link ProviderInterface}, its {@link AgentContextInterface}, and a tool registry\n * into a bounded context → provider → tools → repeat turn, exposed as a one-shot\n * `generate` and a live `stream`.\n *\n * @remarks\n * One private loop drives the turn; `generate` awaits the settled result of the same run\n * `stream` exposes and leaves its live chunks undrained, so they can never diverge. Each turn is bounded by one cancel folded from\n * `signal` + `timeout` + `budget` + `allowance` (through `AbortSignal.any`) — any trip (or `abort()`)\n * commits a partial result (the stream's `result` resolves on a cancel, rejects only\n * on a genuine provider / tool error). The `scheduler` paces between turns; tool\n * iteration is capped at `limit`. Default: `DEFAULT_AGENT_LIMIT`. Tools are advertised\n * structurally through `context.tools.definitions()`. Two observation surfaces: the\n * {@link AgentChunk} stream (pull — per-token content) and a typed `emitter` (push —\n * lifecycle + `usage` / `tool` / `deny` for fire-and-forget observers).\n *\n * @param provider - The {@link ProviderInterface} the loop drives each turn\n * @param options - Optional `system` / `tools` / `limit` / `timeout` / `budget` /\n * `scheduler` / `signal` (see {@link AgentOptions})\n * @returns A working {@link AgentInterface}\n *\n * @example\n * ```ts\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { createAgent } from '@orkestrel/agent'\n * import { createTokenBudget } from '@orkestrel/budget'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * const agent = createAgent(provider, {\n * \tsystem: 'You are concise.',\n * \tbudget: createTokenBudget({ max: 50_000, scope: 'total' }),\n * })\n * agent.context.messages.add({ role: 'user', content: 'Say hi.' })\n *\n * const stream = agent.stream()\n * for await (const chunk of stream.events) {\n * \tif (chunk.category === 'token') process.stdout.write(chunk.content)\n * }\n * const result = await stream.result // { content, usage?, partial }\n * ```\n */\nexport function createAgent(provider: ProviderInterface, options?: AgentOptions): AgentInterface {\n\treturn new Agent(provider, options)\n}\n\n/**\n * Creates an empty unbounded async channel — a {@link ChannelInterface} a producer writes\n * values into (`push`) and ends (`close` / `fail`) regardless of consumption, while a\n * consumer reads them back live through `drain`.\n *\n * @remarks\n * Write and read are decoupled, so the producer never waits for a consumer: an agent's eager\n * pump writes each chunk into one, which is why a run's `result` settles whether or not the\n * live events are drained. A value pushed at an already-parked consumer is delivered, buffered\n * values are yielded before the end is reported, and the first failure wins.\n *\n * @typeParam T - The value type the channel carries\n * @returns A fresh, empty {@link ChannelInterface}\n *\n * @example\n * ```ts\n * import { createChannel } from '@orkestrel/agent'\n *\n * const channel = createChannel<number>()\n * channel.push(1)\n * channel.close()\n * for await (const value of channel.drain()) {\n * \tvalue // 1\n * }\n * ```\n */\nexport function createChannel<T>(): ChannelInterface<T> {\n\treturn new Channel<T>()\n}\n\n/**\n * Creates a policy gate — an {@link AuthorityInterface} the agent loop consults before\n * each tool call runs, evaluating the ordered rules first-match-wins and falling back\n * to the configured default when none match.\n *\n * @remarks\n * `rules` are evaluated in order — the first whose `match` is true decides (a matched\n * rule allows unless its `allowed` is explicitly `false`). When no rule matches, the\n * `fallback` decides. Default: `{ zone: DEFAULT_AUTHORITY_ZONE, allowed: true }`\n * (allow-unmatched — a rules list of denials acts as a denylist). Pass an\n * `allowed: false` `fallback` to flip the gate to deny-by-default (an allowlist). Wire\n * the result into `createAgent` through `AgentOptions.authority`: a denied call is fed back\n * to the model as a denial `ToolResult` (not executed), so the model\n * can react. Synchronous — `evaluate` returns the verdict directly.\n *\n * @param options - Optional `rules` (ordered) and `fallback` (see {@link AuthorityOptions})\n * @returns A working {@link AuthorityInterface}\n *\n * @example\n * ```ts\n * import { createAgent, createAuthority } from '@orkestrel/agent'\n *\n * // Deny the `delete` tool, allow everything else.\n * const authority = createAuthority({\n * \trules: [{ match: (c) => c.call.name === 'delete', zone: 'restricted', allowed: false }],\n * })\n * const agent = createAgent(provider, { tools, authority })\n * ```\n */\nexport function createAuthority(options?: AuthorityOptions): AuthorityInterface {\n\treturn new Authority(options)\n}\n\n/**\n * Creates a registry of live providers, tools, authorities, and schedulers whose `build` method returns a seeded, signal-wired {@link AgentInterface} from a serializable job.\n *\n * @remarks\n * `providers` is required; `tools` / `authorities` / `schedulers` are optional pools.\n * The accessors (`provider` / `tool` / `authority` / `scheduler`) throw an\n * {@link import('./errors.js').AgentError} carrying `code: 'REGISTRY'` and the message\n * `unknown <category>: <name>` on an unregistered name — a misconfigured or crash-restored\n * job fails loudly rather than running with a missing dependency. `build(input, signal)`\n * resolves the names, rebuilds the token budget from its ceiling, seeds the agent's\n * context with the job's messages, and threads `signal` so a queue / runner abort\n * propagates. This is the bridge that makes durable, serializable agent jobs runnable.\n *\n * @param options - The named pools (see {@link AgentRegistryOptions})\n * @returns A working {@link AgentRegistryInterface}\n *\n * @example\n * ```ts\n * import { createAgentRegistry } from '@orkestrel/agent'\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { createTool } from '@orkestrel/tool'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * const registry = createAgentRegistry({\n * \tproviders: { main: provider },\n * \ttools: { add: createTool({ name: 'add', execute: (a) => Number(a.x) + Number(a.y) }) },\n * })\n * const agent = registry.build({ provider: 'main', messages: [{ role: 'user', content: 'Hi.' }] })\n * ```\n */\nexport function createAgentRegistry(options: AgentRegistryOptions): AgentRegistryInterface {\n\treturn new AgentRegistry(options)\n}\n\n/**\n * Creates a durable, bounded-concurrency agent-job queue — a {@link QueueInterface} over\n * serializable values of {@link AgentJobInput} that composes `createQueue`: each job is rehydrated\n * through the `registry` into a live {@link AgentInterface}, run to its {@link AgentResult},\n * and subjected to the partial-as-configurable-failure policy.\n *\n * @remarks\n * - **Composes the substrate (no new engine).** The handler is the only new logic;\n * bounded `concurrency`, `retries`, the per-attempt `timeout`, and durable persistence\n * through `store` (+ `restore()` after a crash) are all the backing Queue's. `enqueue`\n * returns a per-job promise.\n * - **Durable + serializable.** Because `AgentJobInput` is JSON-serializable, a `store`\n * persists outstanding jobs; `restore()` re-enqueues them and the `registry` rehydrates the\n * live pieces from the names. A job survives a crash only through a store whose rows outlive\n * the process (for example `createDatabaseQueueStore`); a `createMemoryQueueStore` row is\n * gone when the process exits.\n * - **Partial policy.** A partial result throws an\n * {@link import('./errors.js').AgentJobError} by default, so a job cancelled by its\n * attempt deadline / a queue abort retries while attempts remain; `partial: true`\n * resolves the partial as success instead.\n * - **Cancellation threads through.** The handler passes `context.signal` into\n * `registry.build`, so a queue `abort()` or a per-attempt timeout cancels the in-flight\n * agent (which commits a partial → throws → retries / fails per policy).\n *\n * @param options - The `registry`, the `partial` policy, and the substrate knobs\n * (`concurrency` / `retries` / `timeout` / `store`) (see {@link AgentQueueOptions})\n * @returns A {@link QueueInterface} of {@link AgentJobInput} → {@link AgentResult}\n *\n * @example\n * ```ts\n * import type { AgentJobInput, ProviderInterface } from '@orkestrel/agent'\n * import type { QueueStoreInterface } from '@orkestrel/queue'\n * import { createAgentQueue, createAgentRegistry } from '@orkestrel/agent'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * declare const store: QueueStoreInterface<AgentJobInput> // a durable store the host supplies\n * const registry = createAgentRegistry({ providers: { main: provider } })\n * const queue = createAgentQueue({ registry, concurrency: 2, retries: 1, store })\n * const result = await queue.enqueue({ provider: 'main', messages: [{ role: 'user', content: 'ok?' }] })\n * ```\n */\nexport function createAgentQueue(\n\toptions: AgentQueueOptions,\n): QueueInterface<AgentJobInput, AgentResult> {\n\tconst { registry, partial = false, store } = options\n\treturn createQueue<AgentJobInput, AgentResult>({\n\t\t...extractQueueOptions(options),\n\t\t...(store === undefined ? {} : { store }),\n\t\thandler: handleAgentQueueJob.bind(undefined, registry, partial),\n\t})\n}\n\n/**\n * Creates an agent-job runner — a {@link RunnerInterface} over serializable\n * values of {@link AgentJobInput} that composes `createRunner` (one-shot, ordered, fail-fast), each unit\n * rehydrated through the `registry` and subjected to the partial policy. The runner also carries\n * sub-agent fan-out: a parent job's handler can call `controller.spawn` with a child job.\n *\n * @remarks\n * - **Composes the substrate (no new engine).** Bounded `concurrency`, `retries`, the\n * per-attempt `timeout`, ordered results, and fail-fast are all the backing Runner's;\n * the handler adds only rehydration + the partial policy.\n * - **Sub-agent fan-out.** Each unit's handler receives a `ControllerInterface` whose\n * `spawn(childJob)` launches a child agent job through the same bounded queue (the\n * child's result joins the run after the declared units, in spawn order). A unit spawns its\n * declared `children` on its first attempt only, so a retried parent never runs a child\n * twice. On a bounded\n * runner, fan out and return — do not await a spawn inline from within the handler (a\n * slot-holding handler awaiting its own spawn can deadlock; see `ControllerInterface`).\n * - **Partial policy + cancellation.** Same as `createAgentQueue`: a partial result\n * throws by default (the run's fail-fast engages), `partial: true` resolves it; the\n * handler threads `controller.signal` into `registry.build`, so a runner abort / a\n * per-attempt timeout cancels the agent.\n *\n * @param options - The `registry`, the `partial` policy, and the substrate knobs\n * (`concurrency` / `retries` / `timeout`) (see {@link AgentRunnerOptions})\n * @returns A {@link RunnerInterface} of {@link AgentJobInput} → {@link AgentResult}\n *\n * @example\n * ```ts\n * import { createAgentRunner, createAgentRegistry } from '@orkestrel/agent'\n *\n * const registry = createAgentRegistry({ providers: { main: provider } })\n * const runner = createAgentRunner({ registry, concurrency: 2 })\n * // Run one job that fans out a child; results hold the parent, then the spawn.\n * const child = { provider: 'main', messages: [{ role: 'user', content: 'child' }] }\n * const parent = { provider: 'main', messages: [{ role: 'user', content: 'parent' }], children: [child] }\n * const results = await runner.execute([parent]) // declared first, then any spawns\n * ```\n */\nexport function createAgentRunner(\n\toptions: AgentRunnerOptions,\n): RunnerInterface<AgentJobInput, AgentResult> {\n\tconst { registry, partial = false } = options\n\tconst fanout = new AgentFanout(registry, partial)\n\treturn createRunner<AgentJobInput, AgentResult>({\n\t\t...extractQueueOptions(options),\n\t\thandler: fanout.execute.bind(fanout),\n\t})\n}\n","import type { LedgerCategory, LedgerNote, LedgerQuestion, LedgerShare } from './types.js'\n\n/**\n * Lists the categories the ledger files a message under, in the order the category question\n * names them — the one list the {@link LedgerCategory} union derives from.\n */\nexport const LEDGER_CATEGORIES = Object.freeze([\n\t'fact',\n\t'rule',\n\t'correction',\n\t'request',\n\t'opinion',\n\t'chatter',\n\t'distractor',\n] as const)\n\n/** Lists the categories whose messages the projection leaves out as quiet. */\nexport const QUIET_CATEGORIES: readonly LedgerCategory[] = Object.freeze(['chatter', 'distractor'])\n\n/** Lists the categories whose messages state what the desk acts on, which the briefing renders. */\nexport const DECISIVE_CATEGORIES: readonly LedgerCategory[] = Object.freeze([\n\t'fact',\n\t'rule',\n\t'correction',\n])\n\n/** Lists the categories that place a message no owner claims on the rules record. */\nexport const PLACED_CATEGORIES: readonly LedgerCategory[] = Object.freeze(['rule', 'correction'])\n\n/** Names the key of the record that holds the rules no owner claims. */\nexport const LEDGER_RULES_KEY = 'rules'\n\n/** Prefixes the key of an owner's record, which the owner's id follows. */\nexport const LEDGER_OWNER_PREFIX = 'owner:'\n\n/**\n * Supplies the wording of every question the ledger asks its judge.\n *\n * @remarks\n * The wording names a support desk. Fit the cutoffs for the wording and judge you use.\n */\nexport const LEDGER_QUESTIONS: LedgerQuestion = Object.freeze({\n\tcategory: Object.freeze({\n\t\tform: 'choice',\n\t\tinstructions: 'Which category best describes what this support-desk message states?',\n\t\tcriteria: Object.freeze({\n\t\t\tfact: 'States a fact about a customer, an order, an account, the desk, or the day',\n\t\t\trule: 'States a standing rule, policy, or instruction the desk must follow',\n\t\t\tcorrection: 'Corrects, replaces, or withdraws a value or rule stated earlier',\n\t\t\trequest: 'Asks the assistant to do a task or to answer a question',\n\t\t\topinion: 'States a personal view or judgment rather than a fact',\n\t\t\tchatter: 'Talk with the agent that states nothing the desk acts on',\n\t\t\tdistractor: \"A statement about something outside the desk's work\",\n\t\t}),\n\t}),\n\ttopic: 'Does this support-desk message concern the named desk topic?',\n\tamends: Object.freeze({\n\t\tform: 'noul',\n\t\tinstructions:\n\t\t\t'Does the later message replace or withdraw any value or rule the earlier message states?',\n\t\tcriteria: Object.freeze({\n\t\t\ttrue: 'The later message replaces or withdraws at least one value or rule the earlier message states',\n\t\t\tfalse:\n\t\t\t\t'Every value and rule the earlier message states stays in force after the later message',\n\t\t}),\n\t}),\n\tsupersedes: Object.freeze({\n\t\tform: 'noul',\n\t\tinstructions:\n\t\t\t'Does the later message replace or withdraw everything the earlier message states?',\n\t\tcriteria: Object.freeze({\n\t\t\ttrue: 'The later message replaces or withdraws everything the earlier message states',\n\t\t\tfalse: 'Some value or rule the earlier message states stays in force after the later message',\n\t\t}),\n\t}),\n})\n\n/**\n * Supplies the text of each ledger note, worded for a model that answers in its final\n * message.\n */\nexport const LEDGER_NOTES: LedgerNote = Object.freeze({\n\tcue: '[Desk] Give your complete answer now as your final message, from what you already have.',\n\tresults: '[Desk] What your lookups and recalls returned in this request:',\n\trepeat:\n\t\t'You already have this result earlier in this request; give your complete answer now as your final message.',\n\tclosure:\n\t\t'recall is closed for the rest of this request; give your final answer from what you have',\n})\n\n/**\n * Supplies the default prompt and tail shares.\n */\nexport const DEFAULT_LEDGER_SHARE: LedgerShare = Object.freeze({\n\tprompt: 0.7,\n\ttail: 0.35,\n})\n\n/**\n * Caps the tool-iteration turns of a ledger's agent at 8 turns.\n */\nexport const DEFAULT_LEDGER_LIMIT = 8\n\n/**\n * Caps the `recall` calls of one request at 2 calls.\n */\nexport const DEFAULT_RECALL_LIMIT = 2\n\n/**\n * Holds back the share of the prompt budget the scale can rise by between calibration and a\n * request's first call.\n *\n * @remarks\n * Across the `ledger-deny` and `ledger-admit` series of 2026-10-08, a\n * request's first-call tokens per estimate unit rose at most from 1.150 at the seed to 1.212, 5.4\n * percent; the ledger divides its prompt budget by 1.06.\n */\nexport const LEDGER_SCALE_DRIFT = 0.06\n\n/** Matches the logprob decoding failure `invalid or duplicate top logprob token`, which the ledger holds for the ledger's life. */\nexport const DETERMINISTIC_JUDGE_ERROR = /invalid or duplicate top logprob token/\n","import type { LedgerErrorCode } from './types.js'\nimport { isInstance } from '@orkestrel/contract'\n\n/**\n * Reports an invalid ledger configuration, failed calibration, or unowned request selection,\n * carrying the machine-readable `code`.\n *\n * @remarks\n * A threshold, share, capacity, limit, topic, lookup, or gauge outside its bounds is a programmer\n * error and throws this with the matching {@link LedgerErrorCode}. A calibration call that reports\n * no prompt usage throws this with `'GAUGE'`. Narrow a caught value with {@link isLedgerError} and\n * branch on `error.code`. A selection without an active `respond` call, or for a request other than\n * that call's request or a ledger note, reports `'REQUEST'` through the selection's fault.\n */\nexport class LedgerError extends Error {\n\t/** Names the machine-readable condition; the {@link LedgerErrorCode} union describes each code. */\n\treadonly code: LedgerErrorCode\n\n\t/**\n\t * Records the failure condition and its description.\n\t *\n\t * @param code - The machine-readable condition, exposed as `error.code`\n\t * @param message - The human-readable description of the failure\n\t */\n\tconstructor(code: LedgerErrorCode, message: string) {\n\t\tsuper(message)\n\t\tthis.name = 'LedgerError'\n\t\tthis.code = code\n\t}\n}\n\n/**\n * Narrows an unknown caught value to a {@link LedgerError} through `instanceof`, so a `catch` can\n * branch on its `code`.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns True if `value` is a {@link LedgerError}; false otherwise\n *\n * @example\n * ```ts\n * isLedgerError(new LedgerError('GAUGE', 'calibration reported no prompt usage')) // true\n * ```\n */\nexport function isLedgerError(value: unknown): value is LedgerError {\n\treturn isInstance(value, LedgerError)\n}\n","import type { Message } from '../types.js'\nimport type {\n\tGaugeCall,\n\tLedgerAmendment,\n\tLedgerCategory,\n\tLedgerLine,\n\tLedgerLookupReading,\n\tLedgerLookupState,\n\tLedgerPlanningGroup,\n\tLedgerProjection,\n\tLedgerProjectionInput,\n\tLedgerProjectionRequest,\n\tLedgerRecord,\n\tLedgerRegistry,\n\tLedgerRenderContext,\n\tLedgerTokenSet,\n\tLedgerTopic,\n\tLedgerWordSet,\n} from './types.js'\nimport type { ToolCall } from '@orkestrel/tool'\nimport { canonicalStringify, isError, isFiniteNumber, isString } from '@orkestrel/contract'\nimport { estimateMessages } from '../agents/helpers.js'\nimport { renderJSON } from '../helpers.js'\nimport { isNonNegativeSafeInteger } from '../validators.js'\nimport { LEDGER_OWNER_PREFIX, LEDGER_RULES_KEY, PLACED_CATEGORIES } from './constants.js'\nimport { LedgerError } from './errors.js'\n\n/**\n * Collects the live message ids placed in records or left without a record.\n * @param projection - The projected records and unplaced ids\n * @returns The distinct live message ids\n * @example\n * ```ts\n * collectProjectionIds({ records: [], amendments: [], orphans: ['message-1'] }) // Set { 'message-1' }\n * ```\n */\nexport function collectProjectionIds(projection: LedgerProjection): ReadonlySet<string> {\n\treturn new Set([...projection.orphans, ...projection.records.flatMap((record) => record.members)])\n}\n\n/**\n * Scans admitted amendments in breadth-first order without revisiting a message.\n * @param amendments - The later messages attached to each earlier message\n * @param start - The first message to visit\n * @param admit - The predicate that admits a message and its descendants\n * @returns The admitted message ids in visit order\n * @example\n * ```ts\n * scanAmendments(new Map([['first', ['second']]]), 'first', () => true) // ['first', 'second']\n * ```\n */\nexport function scanAmendments(\n\tamendments: ReadonlyMap<string, readonly string[]>,\n\tstart: string,\n\tadmit: (id: string) => boolean,\n): readonly string[] {\n\tconst queue = [start]\n\tconst seen = new Set<string>()\n\tconst admitted: string[] = []\n\tfor (const id of queue) {\n\t\tif (seen.has(id)) continue\n\t\tseen.add(id)\n\t\tif (!admit(id)) continue\n\t\tadmitted.push(id)\n\t\tfor (const later of amendments.get(id) ?? []) queue.push(later)\n\t}\n\treturn admitted\n}\n\n/**\n * Builds the placeholder assistant recall call used to price recall framing.\n * @param topic - The recall topic to price\n * @returns The assistant message carrying the recall call\n * @example\n * ```ts\n * buildRecallMessage('refunds').calls?.[0]?.arguments // { topic: 'refunds' }\n * ```\n */\nexport function buildRecallMessage(topic: string): Message {\n\treturn {\n\t\tid: 'call',\n\t\trole: 'assistant',\n\t\tcontent: '',\n\t\tcalls: [{ id: 'call_00000000', name: 'recall', arguments: { topic } }],\n\t}\n}\n\n/**\n * Renders topic names as a comma-separated list in their supplied order.\n * @param topics - The configured desk topics\n * @returns The topic names joined by a comma and a space\n * @example\n * ```ts\n * renderTopicNames([{ name: 'refunds', criterion: 'Refund amounts' }]) // 'refunds'\n * ```\n */\nexport function renderTopicNames(topics: readonly LedgerTopic[]): string {\n\treturn topics.map((topic) => topic.name).join(', ')\n}\n\n/**\n * Renders an error and its causes, stopping after 4 entries.\n * @param error - The thrown value to describe\n * @returns The names and messages joined by a cause separator\n * @example\n * ```ts\n * renderCauseChain(new Error('refused', { cause: 'offline' })) // 'Error: refused <- offline'\n * ```\n */\nexport function renderCauseChain(error: unknown): string {\n\t// The error, then at most three causes: each step extends the chain by the last entry's cause.\n\treturn Array.from({ length: 3 })\n\t\t.reduce<readonly unknown[]>(\n\t\t\t(chain) => {\n\t\t\t\tconst last = chain.at(-1)\n\t\t\t\tconst cause = isError(last) ? last.cause : undefined\n\t\t\t\treturn cause === undefined ? chain : [...chain, cause]\n\t\t\t},\n\t\t\terror === undefined ? [] : [error],\n\t\t)\n\t\t.map((one) => (isError(one) ? `${one.name}: ${one.message}` : String(one)))\n\t\t.join(' <- ')\n}\n\n/**\n * Extracts lowercase words and capitalized names that do not open a sentence.\n * @param message - The message whose text supplies the words\n * @returns The distinct words and non-opening names\n * @example\n * ```ts\n * extractWords({ id: 'note', role: 'user', content: 'Ask Odile.' }).names // Set { 'odile' }\n * ```\n */\nexport function extractWords(message: Message): LedgerWordSet {\n\treturn {\n\t\twords: new Set(message.content.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? []),\n\t\tnames: new Set(\n\t\t\t[...message.content.matchAll(/(?<![\\p{L}\\p{N}'-])\\p{Lu}\\p{Ll}+(?![\\p{L}\\p{N}-])/gu)]\n\t\t\t\t.filter((match) => {\n\t\t\t\t\tconst before = message.content.slice(0, match.index).trimEnd()\n\t\t\t\t\treturn before !== '' && !/[.!?:;]$/.test(before)\n\t\t\t\t})\n\t\t\t\t.map((match) => match[0].toLowerCase()),\n\t\t),\n\t}\n}\n\n/**\n * Splits a topic part into lowercase words with surrounding punctuation removed.\n * @param part - The topic part to split\n * @returns The nonempty normalized words\n * @example\n * ```ts\n * splitWords('Refunds, BW-5512!') // ['refunds', 'bw-5512']\n * ```\n */\nexport function splitWords(part: string): readonly string[] {\n\treturn part\n\t\t.split(/\\s+/)\n\t\t.map((word) => word.replace(/^[\\p{P}\\p{S}]+|[\\p{P}\\p{S}]+$/gu, '').toLowerCase())\n\t\t.filter((word) => word !== '')\n}\n\n/**\n * Finds the call that owns a tool message within a collected tool group.\n * @param group - The assistant leader followed by its tool results\n * @param message - The tool result to pair; distinct leader ids pair by result id when any result has one\n * @returns The call matching the result's call id, or its position when the leader repeats an id or every result lacks an id; undefined when unpaired\n * @example\n * ```ts\n * findLedgerCall(group, result)?.arguments\n * ```\n */\nexport function findLedgerCall(group: readonly Message[], message: Message): ToolCall | undefined {\n\tconst [leader, ...results] = group\n\tconst at = results.findIndex((result) => result.id === message.id)\n\tif (message.role !== 'tool' || at < 0) return undefined\n\tconst calls = leader?.calls ?? []\n\tconst duplicate = new Set(calls.map((call) => call.id)).size !== calls.length\n\treturn !duplicate && results.some((result) => result.call !== undefined)\n\t\t? calls.find((call) => call.id === message.call)\n\t\t: calls[at]\n}\n\n/**\n * Ranks a briefing source for removal before the next prompt.\n *\n * @param group - The planning group: 1 for a topic match, 2 for an off-topic rule or correction, or 3 for a name match\n * @param unsettled - If `true`, the source is a user message without a decisive category; if `false`, it is another source\n * @param category - The source's recorded category, or undefined when undecided\n * @returns The ascending removal rank: name matches, unsettled sources, off-topic corrections, off-topic rules, then topic matches\n * @remarks\n * The planner removes lower ranks first. Equal ranks 0, 1, and 4 remove lower scores first;\n * every equal rank then removes later conversation positions first.\n * @example\n * ```ts\n * rankLedgerCut(2, false, 'rule') // 3\n * ```\n */\nexport function rankLedgerCut(\n\tgroup: LedgerPlanningGroup,\n\tunsettled: boolean,\n\tcategory: LedgerCategory | undefined,\n): number {\n\treturn group === 3 ? 0 : unsettled ? 1 : group === 2 ? (category === 'rule' ? 3 : 2) : 4\n}\n\n/**\n * Resolves the generation cap and checks it against the context capacity.\n *\n * @param predict - The optional generation cap in tokens; see {@link LedgerOptions}\n * @param capacity - The context capacity in tokens\n * @returns The validated cap\n * @throws {LedgerError} Thrown when the cap is not a nonnegative safe integer less than capacity (code `'CAPACITY'`)\n * @example\n * ```ts\n * resolvePredict(1024, 4096) // 1024\n * ```\n */\nexport function resolvePredict(predict: number | undefined, capacity: number): number {\n\tconst resolved = predict ?? 0\n\tif (!isNonNegativeSafeInteger(resolved) || resolved >= capacity)\n\t\tthrow new LedgerError(\n\t\t\t'CAPACITY',\n\t\t\t'predict must be a nonnegative safe integer less than capacity',\n\t\t)\n\treturn resolved\n}\n\n/**\n * Computes the completion tokens attributable to a message's thinking.\n *\n * @remarks\n * Weights the completion by thinking characters divided by the combined characters of thinking,\n * content, and JSON-serialized calls. Rounds to the nearest integer and caps at the completion.\n * An empty generation yields 0. The completion must be a finite nonnegative integer token count.\n * Calls that cannot be JSON-serialized contribute 0 characters.\n *\n * @param message - The generated thinking, content, and optional calls\n * @param completion - The tokens reported for the completion\n * @returns The thinking share in tokens, or 0 when no thinking characters exist\n *\n * @example\n * ```ts\n * computeThinking({ thinking: 'plan', content: 'ok' }, 10) // 7\n * ```\n */\nexport function computeThinking(\n\tmessage: Pick<Message, 'thinking' | 'content' | 'calls'>,\n\tcompletion: number,\n): number {\n\tconst thinking = message.thinking?.length ?? 0\n\tif (thinking === 0) return 0\n\tconst calls = message.calls === undefined ? 0 : (renderJSON(message.calls)?.length ?? 0)\n\tconst generated = thinking + message.content.length + calls\n\treturn Math.min(completion, Math.round(completion * (thinking / generated)))\n}\n\n/**\n * Splits a message into its sentences.\n *\n * @remarks\n * A sentence ends at a period, question mark, or exclamation mark followed by a space and a capital\n * letter, a digit, or a quote, so a decimal point, an id, or an amount never splits one.\n *\n * @param text - The message text\n * @returns The trimmed, non-empty sentences in order\n *\n * @example\n * ```ts\n * splitSentences('Refunds over $200 need a manager. Ask Odile.')\n * // ['Refunds over $200 need a manager.', 'Ask Odile.']\n * ```\n */\nexport function splitSentences(text: string): readonly string[] {\n\treturn text\n\t\t.split(/(?<=[.!?])\\s+(?=[\\p{Lu}\\d\"'“])/u)\n\t\t.map((sentence) => sentence.trim())\n\t\t.filter((sentence) => sentence !== '')\n}\n\n/**\n * Reads the id-shaped tokens and the numbers of a text.\n *\n * @param text - The text to read\n * @returns The uppercased hyphenated ids that hold a digit, and the numbers outside those ids with grouping commas removed\n *\n * @example\n * ```ts\n * const tokens = extractTokens('Order bw-5512 totals 1,200.50')\n * // tokens.ids is Set { 'BW-5512' }, tokens.numbers is Set { 1200.5 }\n * ```\n */\nexport function extractTokens(text: string): LedgerTokenSet {\n\tconst idShape = /\\b[A-Za-z0-9]+(?:-[A-Za-z0-9]+)+\\b/g\n\tconst ids = new Set(\n\t\t[...text.matchAll(idShape)].flatMap(([token]) =>\n\t\t\t/\\d/.test(token) ? [token.toUpperCase()] : [],\n\t\t),\n\t)\n\tconst rest = text.replace(idShape, (token) => (/\\d/.test(token) ? ' ' : token))\n\tconst numbers = new Set(\n\t\t[...rest.matchAll(/(?<![\\w.])\\d[\\d,]*(?:\\.\\d+)?/g)].flatMap(([token]) => {\n\t\t\tconst value = Number(token.replace(/,/g, ''))\n\t\t\treturn Number.isFinite(value) ? [value] : []\n\t\t}),\n\t)\n\treturn { ids, numbers }\n}\n\n/**\n * Collects the capitalized name runs of a text, leaving out the run that opens each sentence.\n *\n * @remarks\n * A sentence opens with a capital whatever its first word is, so its opening run proves nothing.\n * This is the reading the person prefix of {@link buildRecords} rests on.\n *\n * @param text - The text to read\n * @returns The capitalized runs in order, repeats included\n *\n * @example\n * ```ts\n * collectNames('Odile phoned. We asked about Odile Marlow.') // ['Odile Marlow']\n * ```\n */\nexport function collectNames(text: string): readonly string[] {\n\treturn splitSentences(text).flatMap((sentence) =>\n\t\t[...sentence.matchAll(/(?<![\\p{L}\\p{N}'-])\\p{Lu}\\p{Ll}+(?: \\p{Lu}\\p{Ll}+)*(?![\\p{L}\\p{N}-])/gu)]\n\t\t\t.filter((match) => (match.index ?? 0) > 0)\n\t\t\t.map((match) => match[0]),\n\t)\n}\n\n/**\n * Normalizes a lookup argument string to the spelling that lookup identity and owner linking compare.\n *\n * @remarks\n * {@link identifyLookup} and {@link linkOwners} read an argument through this one form, so a reading\n * a later lookup replaces and the owner link of its argument agree on the spelling.\n *\n * @param value - The string argument a lookup call carried\n * @returns The argument trimmed and uppercased\n *\n * @example\n * ```ts\n * normalizeArgument(' bw-5512 ') // 'BW-5512'\n * ```\n */\nexport function normalizeArgument(value: string): string {\n\treturn value.trim().toUpperCase()\n}\n\n/**\n * Splits a tool result into its lines at each line feed, with or without a carriage return before it.\n *\n * @remarks\n * The recall listing keys each recalled line by its first line, and the answer note reads a result\n * line by line, so both read lines through this one split.\n *\n * @param text - The tool result text\n * @returns The lines in order, an empty line included; one empty line for an empty text\n *\n * @example\n * ```ts\n * splitResultLines('Account BW-20931.\\r\\nRefund is $148.50.') // ['Account BW-20931.', 'Refund is $148.50.']\n * ```\n */\nexport function splitResultLines(text: string): readonly string[] {\n\treturn text.split(/\\r\\n|\\n/)\n}\n\n/**\n * Renders a lookup call as its tool name and its JSON arguments.\n *\n * @remarks\n * The arguments keep the text `JSON.stringify` writes, key order included. Arguments JSON cannot\n * carry, such as a `BigInt` or a cycle, render the bare tool name instead of throwing.\n *\n * @param name - The lookup tool name\n * @param args - The arguments the call carried\n * @returns The tool name, a space, and the JSON arguments; the bare tool name when JSON cannot carry them\n *\n * @example\n * ```ts\n * renderLookupCall('lookup_order', { id: 'BW-5512' }) // 'lookup_order {\"id\":\"BW-5512\"}'\n * renderLookupCall('lookup_order', { count: 1n }) // 'lookup_order'\n * ```\n */\nexport function renderLookupCall(name: string, args: Readonly<Record<string, unknown>>): string {\n\tconst rendered = renderJSON(args)\n\treturn rendered === undefined ? name : `${name} ${rendered}`\n}\n\n/**\n * Identifies a lookup reading for projection by its tool name and normalized arguments.\n *\n * @remarks\n * Two calls share an identity whatever the key order of their arguments at any depth. A top-level\n * string argument passes through {@link normalizeArgument} first, so `\"lh-1 \"` and `\"LH-1\"` name one call.\n * The ledger's repeat stop instead compares the tool name and canonical arguments without this\n * string normalization, so those argument spellings remain distinct within a request.\n * An uncanonicalizable call has no identity and neither replaces nor is replaced by another reading.\n *\n * @param name - The tool name\n * @param args - The arguments the call carried\n * @returns The name, a space, and the canonical arguments, or `undefined` when uncanonicalizable\n *\n * @example\n * ```ts\n * identifyLookup('lookup_order', { id: 'bw-5512', opts: { tier: 2, region: 'north' } }) ===\n * \tidentifyLookup('lookup_order', { opts: { region: 'north', tier: 2 }, id: ' BW-5512' }) // true\n * ```\n */\nexport function identifyLookup(\n\tname: string,\n\targs: Readonly<Record<string, unknown>>,\n): string | undefined {\n\tconst normalized = Object.fromEntries(\n\t\tObject.entries(args).map(([key, value]) => [\n\t\t\tkey,\n\t\t\tisString(value) ? normalizeArgument(value) : value,\n\t\t]),\n\t)\n\tconst canonical = canonicalStringify(normalized)\n\treturn canonical === undefined ? undefined : `${name} ${canonical}`\n}\n\n/**\n * Links each id-shaped lookup argument to its owner.\n *\n * @remarks\n * An owner argument links to itself. Any other id-shaped argument links to the single owner id its\n * reading's text names. An empty reading links nothing, and a later reading overwrites an earlier\n * link of the same argument.\n *\n * @param readings - The lookup readings in conversation order\n * @param owners - The owners keyed by id\n * @returns The owner id of each linked argument id; an argument whose text names no owner or several is absent\n *\n * @example\n * ```ts\n * linkOwners(\n * \t[{ id: 'tool-1', name: 'lookup_order', arguments: { id: 'BW-5512' }, text: 'Order BW-5512 for account BW-20931.', result: { ids: [], owners: [] } }],\n * \tnew Map([['BW-20931', ['Brightwater Studio']]]),\n * ) // Map { 'BW-5512' => 'BW-20931' }\n * ```\n */\nexport function linkOwners(\n\treadings: readonly LedgerLookupReading[],\n\towners: ReadonlyMap<string, readonly string[]>,\n): ReadonlyMap<string, string> {\n\t// A later pair of the same argument overwrites an earlier one, as the `Map` constructor does. The\n\t// spread visits a hole in `readings` as an undefined reading, as iteration does; `flatMap` skips it.\n\treturn new Map(\n\t\t[...readings].flatMap((reading) => {\n\t\t\tif (reading.result === undefined) return []\n\t\t\tconst named = [...extractTokens(reading.text).ids].filter((id) => owners.has(id))\n\t\t\tconst [only] = named\n\t\t\treturn Object.values(reading.arguments)\n\t\t\t\t.filter(isString)\n\t\t\t\t.map((value) => normalizeArgument(value))\n\t\t\t\t.filter((subject) => extractTokens(subject).ids.has(subject))\n\t\t\t\t.flatMap((subject) => {\n\t\t\t\t\tif (owners.has(subject)) return [[subject, subject] as const]\n\t\t\t\t\treturn named.length === 1 && only !== undefined ? [[subject, only] as const] : []\n\t\t\t\t})\n\t\t}),\n\t)\n}\n\n/**\n * Collects the ids and the owner names the lookup readings named.\n *\n * @remarks\n * Every reading counts, a replaced one included, because an id a lookup named stays registered.\n * An empty reading names nothing. An owner name is trimmed, and a name without a letter is dropped.\n *\n * @param readings - The lookup readings in conversation order\n * @returns The registry: every id named, and each owner's names in the order read\n *\n * @example\n * ```ts\n * const registry = collectRegistry([\n * \t{ id: 'tool-1', name: 'lookup_customer', arguments: { account: 'BW-20931' }, text: 'Account BW-20931: Brightwater Studio', result: { ids: ['BW-20931'], owners: [{ id: 'BW-20931', names: ['Brightwater Studio'] }] } },\n * ])\n * // registry.owners is Map { 'BW-20931' => ['Brightwater Studio'] }\n * ```\n */\nexport function collectRegistry(readings: readonly LedgerLookupReading[]): LedgerRegistry {\n\t// The spread and `Array.from` visit a hole in `readings` or in an owner list as an undefined\n\t// entry, as iteration does; `flatMap` and `map` skip it.\n\tconst results = [...readings].flatMap((reading) =>\n\t\treading.result === undefined ? [] : [reading.result],\n\t)\n\treturn {\n\t\tids: new Set(\n\t\t\tresults.flatMap((result) => [\n\t\t\t\t...result.ids,\n\t\t\t\t...Array.from(result.owners, (owner) => owner.id),\n\t\t\t]),\n\t\t),\n\t\towners: new Map(\n\t\t\t[\n\t\t\t\t...Map.groupBy(\n\t\t\t\t\tresults.flatMap((result) => Array.from(result.owners)),\n\t\t\t\t\t(owner) => owner.id,\n\t\t\t\t),\n\t\t\t].map(([id, listed]) => [\n\t\t\t\tid,\n\t\t\t\t[\n\t\t\t\t\t...new Set(\n\t\t\t\t\t\tlisted.flatMap((owner) =>\n\t\t\t\t\t\t\towner.names.map((name) => name.trim()).filter((name) => /\\p{L}/u.test(name)),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t]),\n\t\t),\n\t}\n}\n\n/**\n * Matches the registry ids and owners a text names.\n *\n * @remarks\n * An id counts when the text holds it as an id token. An owner counts when the text holds one of\n * its names whole. With `partial`, a capitalized name word that only one name carries also names\n * that name's owners, matched case-sensitively so a common word that spells a first name does not.\n *\n * @param registry - The registry to match against\n * @param text - The text to read\n * @param partial - If `true`, a name word only one name carries also names its owners; if `false`, only a whole name does\n * @returns The registry ids and owner ids the text names\n *\n * @example\n * ```ts\n * const registry = { ids: new Set(['BW-20931']), owners: new Map([['BW-20931', ['Brightwater Studio']]]) }\n * matchEntities(registry, 'Ask Brightwater about it', true) // Set { 'BW-20931' }\n * matchEntities(registry, 'Ask Brightwater about it', false) // Set {}\n * ```\n */\nexport function matchEntities(\n\tregistry: LedgerRegistry,\n\ttext: string,\n\tpartial: boolean,\n): ReadonlySet<string> {\n\tconst tokens = extractTokens(text).ids\n\t// `Array.from` visits a hole in an owner's names as an undefined name, as iteration does; `map` skips it.\n\tconst aliases = Map.groupBy(\n\t\t[...registry.owners].flatMap(([id, names]) => Array.from(names, (name) => ({ name, id }))),\n\t\t(entry) => entry.name,\n\t)\n\t// A word's carriers are the distinct names it appears in.\n\tconst carriers = Map.groupBy(\n\t\t[...aliases.keys()].flatMap((name) => [...new Set(name.split(/\\s+/))]),\n\t\t(word) => word,\n\t)\n\treturn new Set([\n\t\t...[...registry.ids].filter((id) => tokens.has(id)),\n\t\t...[...aliases].flatMap(([name, entries]) => {\n\t\t\tconst words = partial\n\t\t\t\t? name\n\t\t\t\t\t\t.split(/\\s+/)\n\t\t\t\t\t\t.filter((word) => /^\\p{Lu}\\p{L}+$/u.test(word) && carriers.get(word)?.length === 1)\n\t\t\t\t: []\n\t\t\tconst needles = [\n\t\t\t\t{ needle: name, flags: 'iu' },\n\t\t\t\t...words.map((word) => ({ needle: word, flags: 'u' })),\n\t\t\t]\n\t\t\tconst named = needles.some(({ needle, flags }) => {\n\t\t\t\tconst escaped = needle.replace(/[.*+?^$()|{}[\\]\\\\]/g, '\\\\$&')\n\t\t\t\treturn new RegExp(`(?<![\\\\p{L}\\\\p{N}])${escaped}(?![\\\\p{L}\\\\p{N}])`, flags).test(text)\n\t\t\t})\n\t\t\treturn named ? entries.map((entry) => entry.id) : []\n\t\t}),\n\t])\n}\n\n/**\n * Projects the owner records and the rules record from a conversation's messages.\n *\n * @remarks\n * Each line is a sentence of a live message, verbatim except that a sentence that opens with a pronoun opens with its party and a colon. A message is live when it is a user message,\n * or a tool message whose reading is the last reading of its call, and the input neither excludes it nor\n * files it quiet or replaced. A reading with an undefined `result` still replaces the earlier\n * reading of the same call, so the earlier result leaves every record.\n *\n * A live message joins the owner records its entities name, directly or through a linked lookup\n * argument. A message that names no owner joins where its earlier side of an amendment pair joins,\n * or on the rules record when it is filed as a rule or a correction, and is an orphan otherwise.\n *\n * Every live sentence is retained. Accepted direct edges are listed in `amendments`. An amending message\n * that is itself superseded retains its accepted edge without restoring its text.\n *\n * A sentence that opens with a pronoun takes the party named in the sentence before it. The reading\n * trusts capitals, so a capitalized word that is no person, such as a carrier named mid-sentence,\n * is read as the party. This is a documented limit: the prefix carries\n * the follow-up facts the records exist for.\n *\n * @param input - The messages, readings, entities, and classification to project\n * @returns The records with owner records ordered by their first member and the rules record last, the accepted amendments, and the live message ids no record placed\n *\n * @example\n * ```ts\n * const projection = buildRecords({\n * \tsystem: 'You staff the desk.',\n * \texclusions: [],\n * \towners: new Map([['BW-20931', ['Brightwater Studio']]]),\n * \tmessages: [{ id: 'user-1', role: 'user', content: 'Brightwater Studio asked for a refund.' }],\n * \treadings: [],\n * \tentities: new Map([['user-1', ['BW-20931']]]),\n * \tclassification: { quiet: new Set(), categories: new Map(), topics: new Map(), amendments: new Map(), supersessions: new Map() },\n * })\n * // projection.records[0].title === 'Brightwater Studio (account BW-20931)'\n * ```\n */\nexport function buildRecords(input: LedgerProjectionInput): LedgerProjection {\n\tconst position = new Map(input.messages.map((message, at) => [message.id, at]))\n\tconst byId = new Map(input.messages.map((message) => [message.id, message]))\n\tconst live = collectLive(input)\n\tconst links = linkOwners(input.readings, input.owners)\n\tconst amending = new Map(\n\t\t[\n\t\t\t...Map.groupBy(\n\t\t\t\t[...input.classification.amendments].flatMap(([earlier, laters]) =>\n\t\t\t\t\tlaters.map((later) => ({ earlier, later })),\n\t\t\t\t),\n\t\t\t\t(pair) => pair.later,\n\t\t\t),\n\t\t].map(([later, pairs]) => [later, pairs.map((pair) => pair.earlier)]),\n\t)\n\tconst amendments = collectAmendments(input, byId, live)\n\tconst holders = [...input.owners.values()].flat()\n\tconst system = collectNames(input.system)\n\t// The memo belongs to this projection alone: `placeMember` inserts each placement once.\n\tconst settled = new Map<string, ReadonlySet<string>>()\n\tconst placements = live.map((id) => ({\n\t\tid,\n\t\tkeys: placeMember(input, links, amending, id, new Set(), settled),\n\t}))\n\tconst orphans = placements.filter((placement) => placement.keys.size === 0).map(({ id }) => id)\n\tconst members = Map.groupBy(\n\t\tplacements.flatMap(({ id, keys }) => [...keys].map((key) => ({ key, id }))),\n\t\t(entry) => entry.key,\n\t)\n\tconst records = [...members]\n\t\t.map(([key, entries]) => {\n\t\t\tconst ids = entries.map((entry) => entry.id)\n\t\t\tconst lines = ids.flatMap((id) => buildLines(input, byId, id, holders, system))\n\t\t\tconst owner = key.slice(LEDGER_OWNER_PREFIX.length)\n\t\t\tconst holder = input.owners.get(owner)?.[0]\n\t\t\tconst title =\n\t\t\t\tkey === LEDGER_RULES_KEY\n\t\t\t\t\t? 'Rules'\n\t\t\t\t\t: holder === undefined\n\t\t\t\t\t\t? `account ${owner}`\n\t\t\t\t\t\t: `${holder} (account ${owner})`\n\t\t\tconst first = position.get(ids[0] ?? '') ?? 0\n\t\t\treturn {\n\t\t\t\tfirst,\n\t\t\t\trecord: {\n\t\t\t\t\tkey,\n\t\t\t\t\ttitle,\n\t\t\t\t\tmembers: ids,\n\t\t\t\t\tlines,\n\t\t\t\t} satisfies LedgerRecord,\n\t\t\t}\n\t\t})\n\t\t.sort(\n\t\t\t(left, right) =>\n\t\t\t\tNumber(left.record.key === LEDGER_RULES_KEY) -\n\t\t\t\t\tNumber(right.record.key === LEDGER_RULES_KEY) ||\n\t\t\t\tleft.first - right.first ||\n\t\t\t\t(left.record.key < right.record.key ? -1 : left.record.key > right.record.key ? 1 : 0),\n\t\t)\n\t\t.map(({ record }) => record)\n\treturn { records, amendments, orphans }\n}\n\n/**\n * Selects a request's records, collapsing owners with equal ordered member ids under titles joined with `; `.\n *\n * @remarks\n * The view holds the owner records the request names in the order it names them, then the rules\n * record with the lines whose topics meet the request's first, each group in position order. The\n * returned records and lines are copies. Owner records with the same member ids in the same order\n * collapse into the first requested record, keeping its key, members, and lines and joining their\n * titles with `; ` before trimming.\n *\n * @param projection - The output of {@link buildRecords}\n * @param request - The owners and the desk topics the request names\n * @returns The selected records; an owner with no record yields none\n *\n * @example\n * ```ts\n * selectRecords(projection, { owners: ['BW-20931'], topics: ['refunds'] }).map((record) => record.key)\n * // ['owner:BW-20931', 'rules']\n * ```\n */\nexport function selectRecords(\n\tprojection: LedgerProjection,\n\trequest: LedgerProjectionRequest,\n): readonly LedgerRecord[] {\n\tconst topics = new Set(request.topics)\n\tconst rules = projection.records.find((one) => one.key === LEDGER_RULES_KEY)\n\t// Lines that meet a request topic lead; each side keeps its position order. `groupBy` visits a\n\t// hole in `lines` as an undefined line, as iteration does; `filter` skips it.\n\tconst sides = Map.groupBy(\n\t\t(rules?.lines ?? []).filter(() => true),\n\t\t(line) => line.topics.some((topic) => topics.has(topic)),\n\t)\n\tconst owners = [...new Set(request.owners)].flatMap((owner) => {\n\t\tconst record = projection.records.find((one) => one.key === `${LEDGER_OWNER_PREFIX}${owner}`)\n\t\treturn record === undefined ? [] : [record]\n\t})\n\tconst groups = Map.groupBy(owners, (record) => JSON.stringify(record.members))\n\treturn [\n\t\t...[...groups.values()].flatMap(([record, ...rest]) =>\n\t\t\trecord === undefined\n\t\t\t\t? []\n\t\t\t\t: [\n\t\t\t\t\t\tstructuredClone({\n\t\t\t\t\t\t\t...record,\n\t\t\t\t\t\t\ttitle: [record.title, ...rest.map((one) => one.title)].join('; '),\n\t\t\t\t\t\t}),\n\t\t\t\t\t],\n\t\t),\n\t\t...(rules === undefined\n\t\t\t? []\n\t\t\t: [\n\t\t\t\t\tstructuredClone({\n\t\t\t\t\t\t...rules,\n\t\t\t\t\t\tlines: [...(sides.get(true) ?? []), ...(sides.get(false) ?? [])],\n\t\t\t\t\t}),\n\t\t\t\t]),\n\t]\n}\n\n/**\n * Renders one record as a heading and one list item per line.\n *\n * @remarks\n * The briefing joins rendered records with one blank line.\n *\n * @param record - A record or view with a `title` and `lines`\n * @param context - Rendering facts for optional accepted amendment annotations\n * @returns `## TITLE` followed by `- LINE` for each line\n *\n * @example\n * ```ts\n * renderLedgerRecord({ title: 'Rules', lines: [{ text: 'Refunds need a manager.', source: 'user-1', sentence: 0, topics: [], role: 'user' }] })\n * // '## Rules\\n- Refunds need a manager.'\n * ```\n */\nexport function renderLedgerRecord(\n\trecord: Pick<LedgerRecord, 'title' | 'lines'>,\n\tcontext?: LedgerRenderContext,\n): string {\n\treturn [\n\t\t`## ${record.title}`,\n\t\t...record.lines.flatMap((line) =>\n\t\t\t[context === undefined ? '' : renderLedgerAnnotation(line, context), `- ${line.text}`].filter(\n\t\t\t\t(text) => text !== '',\n\t\t\t),\n\t\t),\n\t].join('\\n')\n}\n\n/**\n * Renders one owner record under a `###` heading, which the briefing nests under its one `## Pinned` heading.\n *\n * @param record - An owner record or view with a `title` and `lines`\n * @param context - Rendering facts for optional accepted amendment annotations\n * @returns `### TITLE` followed by `- LINE` for each line\n *\n * @example\n * ```ts\n * renderLedgerPinned({ title: 'Odile Marlow (account OM-30418)', lines: [] }) // '### Odile Marlow (account OM-30418)'\n * ```\n */\nexport function renderLedgerPinned(\n\trecord: Pick<LedgerRecord, 'title' | 'lines'>,\n\tcontext?: LedgerRenderContext,\n): string {\n\treturn `#${renderLedgerRecord(record, context)}`\n}\n\n/**\n * Derives complete source identities, first occurrences, and local references from the actual briefing lines.\n * @param messages - Original messages whose indexed sentences establish completeness\n * @param lines - Retained lines in rendering order after deduplication and trimming\n * @param amendments - Accepted direct message amendment edges\n * @returns Immutable rendering facts for this retained population\n *\n * @example\n * ```ts\n * buildLedgerRenderContext([], [], []).complete.size // 0\n * ```\n */\nexport function buildLedgerRenderContext(\n\tmessages: readonly Message[],\n\tlines: readonly LedgerLine[],\n\tamendments: readonly LedgerAmendment[],\n): LedgerRenderContext {\n\tconst identities = new Set(lines.map((line) => `${line.source} ${line.sentence}`))\n\treturn {\n\t\tamendments,\n\t\tcomplete: new Set(\n\t\t\tmessages\n\t\t\t\t.filter((message) => {\n\t\t\t\t\tconst sentences = splitSentences(message.content)\n\t\t\t\t\treturn (\n\t\t\t\t\t\tsentences.length > 0 &&\n\t\t\t\t\t\tsentences.every((_, index) => identities.has(`${message.id} ${index}`))\n\t\t\t\t\t)\n\t\t\t\t})\n\t\t\t\t.map((message) => message.id),\n\t\t),\n\t\tfirst: new Map(lines.toReversed().map((line) => [line.source, line])),\n\t\treferences: new Map(\n\t\t\t[...new Set(lines.map((line) => line.source))].map((source, index) => [\n\t\t\t\tsource,\n\t\t\t\tString(index + 1),\n\t\t\t]),\n\t\t),\n\t}\n}\n\n/**\n * Renders source framing and unresolved amendment scope at a source's first retained line.\n * @param line - The retained occurrence to annotate\n * @param context - Actual complete sources, first occurrences, local references, and accepted amendment edges\n * @returns Source framing and truthful inclusion notes, or empty text for an unrelated or repeated occurrence\n * @throws {LedgerError} Thrown when the context holds no reference for the annotated source or a fully included amender (code `'REQUEST'`)\n *\n * @example\n * ```ts\n * renderLedgerAnnotation({ text: 'Unchanged.', source: 'user-1', sentence: 0, topics: [], role: 'user' }, buildLedgerRenderContext([], [], [])) // ''\n * ```\n */\nexport function renderLedgerAnnotation(line: LedgerLine, context: LedgerRenderContext): string {\n\tif (context.first.get(line.source) !== line) return ''\n\tconst amendments = context.amendments.filter((pair) => pair.earlier === line.source)\n\tconst endpoint =\n\t\tcontext.complete.has(line.source) &&\n\t\tcontext.amendments.some((pair) => pair.later === line.source && context.first.has(pair.earlier))\n\tif (amendments.length === 0 && !endpoint) return ''\n\tconst included = amendments.filter((pair) => context.complete.has(pair.later))\n\tif (\n\t\tcontext.references.get(line.source) === undefined ||\n\t\tincluded.some((pair) => context.references.get(pair.later) === undefined)\n\t)\n\t\tthrow new LedgerError('REFERENCE', 'Ledger rendering requires retained source references')\n\treturn [\n\t\t`[Ledger source ${context.references.get(line.source)}]`,\n\t\t...included.map(\n\t\t\t(pair) =>\n\t\t\t\t`Accepted later amendment [Ledger source ${context.references.get(pair.later)}] is fully included in this briefing. Sentence scope is unresolved.`,\n\t\t),\n\t\t...(amendments.some((pair) => !context.complete.has(pair.later))\n\t\t\t? [\n\t\t\t\t\t'Accepted later amendment text is not fully included in this briefing. Sentence scope is unresolved.',\n\t\t\t\t]\n\t\t\t: []),\n\t].join('\\n')\n}\n\n/**\n * Splits a recall topic at its joints.\n *\n * @remarks\n * The joints are a comma, a semicolon, a slash, and the word `and`. A topic with no joint is\n * returned whole, so a model that joins a name and an id recalls each part alone.\n *\n * @param topic - The topic the model asked for\n * @returns The trimmed, non-empty parts when there are at least 2; otherwise the topic itself\n *\n * @example\n * ```ts\n * splitTopic('BW-5512, Odile Marlow and refunds') // ['BW-5512', 'Odile Marlow', 'refunds']\n * ```\n */\nexport function splitTopic(topic: string): readonly string[] {\n\tconst parts = topic\n\t\t.split(/\\s*[,;/]\\s*|\\s+and\\s+/i)\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part !== '')\n\treturn parts.length > 1 ? parts : [topic]\n}\n\n/**\n * Cuts entries to a room and names how many it left out.\n *\n * @remarks\n * The cut keeps at least one entry. When it leaves entries out, its last line reads\n * `N older items not shown; name a narrower topic to narrow the recall`, which\n * {@link matchesCutLine} recognizes.\n *\n * @param entries - The entries in the order they are kept\n * @param room - The estimate units the joined entries can take\n * @returns The kept entries followed by the cut line when any were left out, joined by newlines\n *\n * @example\n * ```ts\n * cutListing(['first entry', 'second entry'], 1) // 'first entry\\n1 older item not shown; name a narrower topic to narrow the recall'\n * ```\n */\nexport function cutListing(entries: readonly string[], room: number): string {\n\t// The cut keeps at least one entry, and stops at the first entry whose addition passes the room.\n\tconst stop = [...entries.keys()].findIndex(\n\t\t(at) =>\n\t\t\tat > 0 &&\n\t\t\testimateMessages([\n\t\t\t\t{\n\t\t\t\t\tid: 'recall',\n\t\t\t\t\trole: 'tool',\n\t\t\t\t\tcontent: entries.slice(0, at + 1).join('\\n'),\n\t\t\t\t},\n\t\t\t]) > room,\n\t)\n\tconst kept = entries.slice(0, stop === -1 ? undefined : stop)\n\tconst left = entries.length - kept.length\n\treturn [\n\t\t...kept,\n\t\t...(left > 0\n\t\t\t? [\n\t\t\t\t\t`${left} older item${left === 1 ? '' : 's'} not shown; name a narrower topic to narrow the recall`,\n\t\t\t\t]\n\t\t\t: []),\n\t].join('\\n')\n}\n\n/**\n * Checks whether a line is the cut line {@link cutListing} writes.\n *\n * @param line - The line to check\n * @returns True if the line is a cut line; false otherwise\n *\n * @example\n * ```ts\n * matchesCutLine('2 older items not shown; name a narrower topic to narrow the recall') // true\n * ```\n */\nexport function matchesCutLine(line: string): boolean {\n\treturn /^\\d+ older items? not shown; /.test(line)\n}\n\n/**\n * Renders the tail stub of a lookup result from an earlier request.\n *\n * @param name - The lookup tool name\n * @param args - The arguments the call carried; arguments JSON cannot carry leave the call as its bare tool name, per {@link renderLookupCall}\n * @param state - What became of the result: `failed`, `empty`, `shown` in the briefing, or `hidden` from it\n * @returns The stub text, which carries the call and its state\n *\n * @example\n * ```ts\n * renderStub('lookup_order', { id: 'BW-5512' }, 'hidden')\n * // 'lookup_order {\"id\":\"BW-5512\"}: result not shown; call recall with BW-5512'\n * ```\n */\nexport function renderStub(\n\tname: string,\n\targs: Readonly<Record<string, unknown>>,\n\tstate: LedgerLookupState,\n): string {\n\tconst head = renderLookupCall(name, args)\n\tif (state === 'failed') return `${head}: failed`\n\tif (state === 'empty') return `${head}: no record`\n\tif (state === 'shown') return `${head}: result shown under Pinned in the system message`\n\tconst id = Object.values(args).find(isString)\n\treturn `${head}: result not shown; call recall with ${(id ?? '').trim() || 'its id'}`\n}\n\n/**\n * Fits the marginal tokens one estimate unit adds within a request.\n *\n * @remarks\n * The fit is the least-squares slope of prompt tokens over estimate, taken within each set of calls\n * that advertised the same number of tools and pooled over every group. The estimate counts no tool\n * schema, so a pooled fit across tool counts would read the dropped schemas as a falling rate.\n *\n * @param groups - The calls of each request\n * @returns The slope, or undefined when no set holds 2 calls with a prompt count and an estimate that differ\n *\n * @example\n * ```ts\n * fitSlope([[{ estimate: 100, prompt: 130, tools: 2 }, { estimate: 200, prompt: 260, tools: 2 }]]) // 1.3\n * ```\n */\nexport function fitSlope(groups: ReadonlyArray<readonly GaugeCall[]>): number | undefined {\n\t// The spread visits a hole in `groups` as an undefined group, as iteration does; `flatMap` skips it.\n\tconst terms = [...groups].flatMap((group) =>\n\t\t[...Map.groupBy(group, (call) => call.tools).values()].flatMap((set) => {\n\t\t\tconst points = set.flatMap((call) =>\n\t\t\t\tisFiniteNumber(call.prompt) && call.estimate > 0\n\t\t\t\t\t? [{ estimate: call.estimate, prompt: call.prompt }]\n\t\t\t\t\t: [],\n\t\t\t)\n\t\t\tif (points.length < 2) return []\n\t\t\tconst meanX = points.reduce((sum, point) => sum + point.estimate, 0) / points.length\n\t\t\tconst meanY = points.reduce((sum, point) => sum + point.prompt, 0) / points.length\n\t\t\treturn points.map((point) => ({\n\t\t\t\tspread: (point.estimate - meanX) ** 2,\n\t\t\t\tproduct: (point.estimate - meanX) * (point.prompt - meanY),\n\t\t\t}))\n\t\t}),\n\t)\n\tconst spread = terms.reduce((sum, term) => sum + term.spread, 0)\n\tconst product = terms.reduce((sum, term) => sum + term.product, 0)\n\treturn spread > 0 ? product / spread : undefined\n}\n\n/**\n * Collects the ids of the live messages in conversation order.\n *\n * @remarks\n * A message is live when it is a user message, or a tool message whose reading is the last reading of its\n * call, and the input neither excludes it nor files it quiet or replaced. A reading replaces any\n * earlier reading of the same call, an empty one included, so an empty lookup leaves the earlier\n * result out of every record. A reading with no canonical identity stays live as its own source\n * and participates in no replacement.\n *\n * @param input - The messages, readings, and classification to read\n * @returns The live message ids\n *\n * @example\n * ```ts\n * collectLive(input) // ['user-1', 'tool-2']\n * ```\n */\nexport function collectLive(input: LedgerProjectionInput): readonly string[] {\n\tconst { classification } = input\n\tconst excluded = new Set(input.exclusions)\n\tconst position = new Map(input.messages.map((message, at) => [message.id, at]))\n\tconst readings = input.readings.filter((reading) => position.has(reading.id))\n\tconst identities = new Map(\n\t\treadings.map((reading) => [reading.id, identifyLookup(reading.name, reading.arguments)]),\n\t)\n\tconst current = new Set(\n\t\treadings\n\t\t\t.filter(\n\t\t\t\t(reading) =>\n\t\t\t\t\treading.result !== undefined &&\n\t\t\t\t\t!readings.some(\n\t\t\t\t\t\t(later) =>\n\t\t\t\t\t\t\tidentities.get(reading.id) !== undefined &&\n\t\t\t\t\t\t\t(position.get(later.id) ?? -1) > (position.get(reading.id) ?? -1) &&\n\t\t\t\t\t\t\tidentities.get(later.id) === identities.get(reading.id),\n\t\t\t\t\t),\n\t\t\t)\n\t\t\t.map((reading) => reading.id),\n\t)\n\treturn [...new Map(input.messages.map((message) => [message.id, message])).values()]\n\t\t.filter(\n\t\t\t(message) => message.role === 'user' || (message.role === 'tool' && current.has(message.id)),\n\t\t)\n\t\t.map((message) => message.id)\n\t\t.filter(\n\t\t\t(id) =>\n\t\t\t\t!excluded.has(id) &&\n\t\t\t\t!classification.quiet.has(id) &&\n\t\t\t\t(classification.supersessions.get(id) ?? []).length === 0,\n\t\t)\n}\n\n/**\n * Places a message on the record keys it joins.\n *\n * @remarks\n * A message joins the owner records its entities name, directly or through a linked lookup argument.\n * A message that names no owner joins where the earlier side of its amendment pair joins, and a\n * message with no earlier side joins the rules record when it is filed as a rule or a correction.\n * A message that is not live still places, because a correction joins where its earlier side would\n * join.\n *\n * With `settled`, the walk returns a placement the map holds without walking again, and records each\n * placement whose walk, its nested walks included, excluded no earlier side through `seen`. Such a\n * walk reaches no cycle. While every `seen` holds only the path that reached the message, as\n * {@link buildRecords} passes it, that path never holds a message the recorded walk reached, so a\n * fresh walk returns the same keys in the same order. A placement a cycle cut stays unrecorded,\n * because its keys depend on the path that reached it. Sharing one map across the members of one\n * input bounds a dense amendment graph to one walk per message.\n *\n * @param input - The owners, entities, and classification to read\n * @param links - The owner of each linked lookup argument, from {@link linkOwners}\n * @param amending - The earlier sides of each message's amendment pairs\n * @param id - The message id\n * @param seen - The ids already visited, which stops a cycle of amendment pairs\n * @param settled - The placements already walked for the same `input`, `links`, and `amending`; the walk adds to it. Default: no map, so every call walks\n * @returns The record keys, empty when the message is an orphan\n *\n * @example\n * ```ts\n * placeMember(input, new Map(), new Map(), 'user-1', new Set()) // Set { 'owner:BW-20931' }\n * ```\n */\nexport function placeMember(\n\tinput: LedgerProjectionInput,\n\tlinks: ReadonlyMap<string, string>,\n\tamending: ReadonlyMap<string, readonly string[]>,\n\tid: string,\n\tseen: ReadonlySet<string>,\n\tsettled?: Map<string, ReadonlySet<string>>,\n): ReadonlySet<string> {\n\tconst known = settled?.get(id)\n\tif (known !== undefined) return known\n\tconst owners = (input.entities.get(id) ?? []).flatMap((entity) => {\n\t\tconst owner = input.owners.has(entity) ? entity : links.get(entity)\n\t\treturn owner === undefined ? [] : [`${LEDGER_OWNER_PREFIX}${owner}`]\n\t})\n\tconst owned = owners.length > 0\n\tconst sides = owned ? [] : (amending.get(id) ?? []).filter((side) => side !== id)\n\tconst earlier = sides.filter((side) => !seen.has(side))\n\tconst category = input.classification.categories.get(id)\n\tconst ruled =\n\t\t!owned && earlier.length === 0 && category !== undefined && PLACED_CATEGORIES.includes(category)\n\tconst keys = new Set([\n\t\t...owners,\n\t\t...earlier.flatMap((side) => [\n\t\t\t...placeMember(input, links, amending, side, new Set([...seen, id]), settled),\n\t\t]),\n\t\t...(ruled ? [LEDGER_RULES_KEY] : []),\n\t])\n\tif (\n\t\tsettled !== undefined &&\n\t\tearlier.length === sides.length &&\n\t\tearlier.every((side) => settled.has(side))\n\t)\n\t\tsettled.set(id, keys)\n\treturn keys\n}\n\n/**\n * Collects accepted direct amendments of live messages.\n *\n * @remarks\n * An accepted edge relates an earlier live message to an amender without claiming which sentences\n * changed. An amender takes effect while live and retains its edge after another message supersedes\n * it, without restoring the superseded text. An excluded or quiet user or tool message has no effect.\n *\n * @param input - The exclusions and classification to read\n * @param byId - The messages by id\n * @param live - The live message ids from {@link collectLive}\n * @returns The distinct accepted direct edges in conversation order\n *\n * @example\n * ```ts\n * collectAmendments(input, byId, ['user-1', 'user-3']) // [{ earlier: 'user-1', later: 'user-3' }]\n * ```\n */\nexport function collectAmendments(\n\tinput: LedgerProjectionInput,\n\tbyId: ReadonlyMap<string, Message>,\n\tlive: readonly string[],\n): readonly LedgerAmendment[] {\n\tconst { classification } = input\n\tconst excluded = new Set(input.exclusions)\n\tconst living = new Set(live)\n\tconst ordered = [...new Set(input.messages.map((message) => message.id))]\n\tconst positions = new Map(ordered.map((id, index) => [id, index]))\n\tconst effective = new Set([\n\t\t...live,\n\t\t...[...byId.values()]\n\t\t\t.filter(\n\t\t\t\t(message) =>\n\t\t\t\t\tmessage.role !== 'assistant' &&\n\t\t\t\t\t!excluded.has(message.id) &&\n\t\t\t\t\t!classification.quiet.has(message.id) &&\n\t\t\t\t\t(classification.supersessions.get(message.id) ?? []).length > 0,\n\t\t\t)\n\t\t\t.map((message) => message.id),\n\t])\n\treturn ordered\n\t\t.filter((id) => living.has(id))\n\t\t.flatMap((earlier) =>\n\t\t\t[...new Set(classification.amendments.get(earlier) ?? [])]\n\t\t\t\t.filter((later) => effective.has(later) && positions.has(later))\n\t\t\t\t.sort((a, b) => (positions.get(a) ?? 0) - (positions.get(b) ?? 0))\n\t\t\t\t.map((later) => ({ earlier, later })),\n\t\t)\n}\n\n/**\n * Builds the record lines of one message.\n *\n * @remarks\n * Each original indexed sentence becomes a line. A sentence that opens with a pronoun and follows\n * another sentence takes the last name of the sentence before it that is neither an owner name nor\n * a system name, and its line text opens with that party and a colon.\n *\n * @param input - The classification whose topics the lines carry\n * @param byId - The messages by id\n * @param id - The message id\n * @param holders - The owner names, which never serve as a party\n * @param system - The system text's names, which never serve as a party\n * @returns The lines in sentence order; empty when the message is absent\n *\n * @example\n * ```ts\n * buildLines(input, byId, 'user-1', [], []).map((line) => line.text)\n * // ['Odile Marlow phoned about BW-5512.', 'Odile Marlow: She wants a refund.']\n * ```\n */\nexport function buildLines(\n\tinput: LedgerProjectionInput,\n\tbyId: ReadonlyMap<string, Message>,\n\tid: string,\n\tholders: readonly string[],\n\tsystem: readonly string[],\n): readonly LedgerLine[] {\n\tconst message = byId.get(id)\n\tif (message === undefined) return []\n\tconst sentences = splitSentences(message.content)\n\tconst topics = input.classification.topics.get(id) ?? []\n\treturn sentences.flatMap((sentence, at) => {\n\t\tconst party =\n\t\t\t/^(?:He|She|They|His|Her|Their)(?![\\p{L}\\p{N}])/u.test(sentence) && at > 0\n\t\t\t\t? collectNames(sentences[at - 1] ?? '')\n\t\t\t\t\t\t.filter((name) => !holders.includes(name) && !system.includes(name))\n\t\t\t\t\t\t.at(-1)\n\t\t\t\t: undefined\n\t\tconst line = {\n\t\t\ttext: party === undefined ? sentence : `${party}: ${sentence}`,\n\t\t\tsource: id,\n\t\t\tsentence: at,\n\t\t\ttopics: [...topics],\n\t\t\trole: message.role,\n\t\t}\n\t\treturn [party === undefined ? line : { ...line, party }]\n\t})\n}\n","import type { ChoiceAnswer, Judgment, JudgmentInput, Message } from '../types.js'\nimport type {\n\tClassifierInterface,\n\tClassifierOptions,\n\tClassifierPhase,\n\tClassifierReading,\n\tClassifierResult,\n\tLedgerCategory,\n\tLedgerClassification,\n\tLedgerTopic,\n} from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport { isArray, isError, isString, parseJSONAs } from '@orkestrel/contract'\nimport { errorToMessage } from '@orkestrel/workflow'\nimport { isJudgeAbortError } from '../errors.js'\nimport { matchesJudgment, renderJSON, sumUsage } from '../helpers.js'\nimport { isJudgeError } from '../providers/errors.js'\nimport {\n\tDECISIVE_CATEGORIES,\n\tDETERMINISTIC_JUDGE_ERROR,\n\tLEDGER_CATEGORIES,\n\tQUIET_CATEGORIES,\n} from './constants.js'\nimport { extractTokens, renderCauseChain } from './helpers.js'\n\n/**\n * Files messages through the conversation's judgment manager and reads their categories and corrections.\n *\n * @example\n * ```ts\n * const classifier = new Classifier(options)\n * await classifier.classify(new Set(), signal)\n * const filing = classifier.classification()\n * ```\n */\nexport class Classifier implements ClassifierInterface {\n\treadonly #options: ClassifierOptions\n\treadonly #failed = new Set<string>()\n\n\t/**\n\t * Creates the filing engine with the ledger's handlers and calibrated questions.\n\t * @param options - The conversation, judge, questions, cutoffs, and handlers\n\t */\n\tconstructor(options: ClassifierOptions) {\n\t\tthis.#options = options\n\t}\n\n\t/**\n\t * Asks the judge every question the filing still lacks, in the measured order.\n\t * @param requests - The request ids, which skip category questions and receive only enabled request-topic questions\n\t * @param signal - The caller's signal; an abort returns a fault with completed judgments and usage\n\t * @returns The judgment keys, summed usage, and one reading per logical question attempt, in asking order; a throw from the assign or entities handler, or a caller abort, returns the partial result with `fault`; a judge rejection under a live signal leaves that question undecided and sets no `fault`\n\t */\n\tasync classify(requests: ReadonlySet<string>, signal: AbortSignal): Promise<ClassifierResult> {\n\t\tconst results: ClassifierResult[] = []\n\t\tconst fault = await this.#gather(requests, signal, results).then(\n\t\t\t(): Error | undefined => undefined,\n\t\t\t(error: unknown) => (isError(error) ? error : new Error(errorToMessage(error))),\n\t\t)\n\t\tconst usage = results.reduce<TokenUsage | undefined>(\n\t\t\t(total, result) => (result.usage === undefined ? total : sumUsage(total, result.usage)),\n\t\t\tundefined,\n\t\t)\n\t\treturn {\n\t\t\tjudgments: results.flatMap((result) => result.judgments),\n\t\t\treadings: results.flatMap((result) => result.readings),\n\t\t\t...(fault === undefined ? {} : { fault }),\n\t\t\t...(usage === undefined ? {} : { usage }),\n\t\t}\n\t}\n\n\t/**\n\t * Reads the category a message is filed under.\n\t * @param id - The message id\n\t * @returns The assigned category, the recorded category at the cutoff, or `undefined`\n\t */\n\tcategory(id: string): LedgerCategory | undefined {\n\t\tconst message = this.#options.conversation.message(id)\n\t\tif (message === undefined) return undefined\n\t\tconst assigned = this.#options.assign(message)\n\t\tif (assigned !== undefined) return assigned\n\t\tconst answer = this.#readCategories(id)\n\t\tconst cutoff = this.#options.thresholds.category\n\t\tconst candidates = Object.entries(answer?.probabilities ?? {}).flatMap(\n\t\t\t([option, probability]) => {\n\t\t\t\tconst category = LEDGER_CATEGORIES.find((candidate) => candidate === option)\n\t\t\t\treturn category !== undefined && probability >= cutoff ? [{ category, probability }] : []\n\t\t\t},\n\t\t)\n\t\t// The first category with the highest probability wins a tie.\n\t\treturn candidates.reduce<{ category: LedgerCategory; probability: number } | undefined>(\n\t\t\t(best, candidate) =>\n\t\t\t\tbest === undefined || candidate.probability > best.probability ? candidate : best,\n\t\t\tundefined,\n\t\t)?.category\n\t}\n\n\t/**\n\t * Reports whether a message files under a quiet category.\n\t * @param id - The message id\n\t * @returns True if the assigned or recorded category is quiet; false otherwise.\n\t */\n\tquiet(id: string): boolean {\n\t\tconst message = this.#options.conversation.message(id)\n\t\tif (message === undefined) return false\n\t\tconst assigned = this.#options.assign(message)\n\t\tif (assigned !== undefined) return QUIET_CATEGORIES.includes(assigned)\n\t\treturn this.#weigh(id, QUIET_CATEGORIES) >= this.#options.thresholds.category\n\t}\n\n\t/**\n\t * Reports whether a message files under a decisive category.\n\t * @param id - The message id\n\t * @returns True if the recorded decisive weight reaches the category cutoff; false otherwise.\n\t */\n\tdecisive(id: string): boolean {\n\t\treturn this.#weigh(id, DECISIVE_CATEGORIES) >= this.#options.thresholds.category\n\t}\n\n\t/**\n\t * Reads the topics a message concerns.\n\t * @param id - The message id\n\t * @returns The names of the topics whose recorded weight reaches the topic cutoff\n\t */\n\ttopics(id: string): ReadonlySet<string> {\n\t\tconst message = this.#options.conversation.message(id)\n\t\t// The spread visits a hole in the topic list as an undefined topic, as iteration does; `filter` skips it.\n\t\treturn new Set(\n\t\t\tmessage === undefined\n\t\t\t\t? []\n\t\t\t\t: [...this.#options.topics]\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(topic) =>\n\t\t\t\t\t\t\t\t(this.#readNoul(this.#buildTopic(id, topic)) ?? 0) >=\n\t\t\t\t\t\t\t\tthis.#options.thresholds.topic,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.map((topic) => topic.name),\n\t\t)\n\t}\n\n\t/**\n\t * Reads the whole filing from the recorded judgments.\n\t * @returns The quiet ids, categories, topics, and the amendment and supersession marks\n\t */\n\tclassification(): LedgerClassification {\n\t\tconst messages = this.#options.conversation.messages()\n\t\tconst positions = new Map(messages.map((message, at) => [message.id, at]))\n\t\t// Each message files in HEAD's call order: quiet, then category, then topics.\n\t\tconst filed = messages.map((message) => ({\n\t\t\tid: message.id,\n\t\t\tquiet: this.quiet(message.id),\n\t\t\tcategory: this.category(message.id),\n\t\t\ttopics: [...this.topics(message.id)],\n\t\t}))\n\t\tconst pairs = this.#options.conversation.judgments.judgments().flatMap((judgment) => {\n\t\t\tconst key = parseJSONAs(judgment.id, isArray)\n\t\t\tif (key === undefined) return []\n\t\t\tconst [head, earlier, later] = key\n\t\t\tif ((head !== 'amends' && head !== 'supersedes') || !isString(earlier) || !isString(later))\n\t\t\t\treturn []\n\t\t\tconst before = this.#options.conversation.message(earlier)\n\t\t\tconst after = this.#options.conversation.message(later)\n\t\t\tif (\n\t\t\t\tbefore === undefined ||\n\t\t\t\tafter === undefined ||\n\t\t\t\t(this.#readNoul(this.#buildPair(head, earlier, later)) ?? 0) <\n\t\t\t\t\tthis.#options.thresholds[head]\n\t\t\t)\n\t\t\t\treturn []\n\t\t\tconst own = extractTokens(before.content)\n\t\t\tconst other = extractTokens(after.content)\n\t\t\treturn head === 'amends' &&\n\t\t\t\t![...own.ids].some((id) => other.ids.has(id)) &&\n\t\t\t\t![...own.numbers].some((number) => other.numbers.has(number))\n\t\t\t\t? []\n\t\t\t\t: [{ head, earlier, later }]\n\t\t})\n\t\treturn {\n\t\t\tquiet: new Set(filed.filter((one) => one.quiet).map((one) => one.id)),\n\t\t\tcategories: new Map(\n\t\t\t\tfiled.flatMap((one) =>\n\t\t\t\t\tone.category === undefined ? [] : [[one.id, one.category] as const],\n\t\t\t\t),\n\t\t\t),\n\t\t\ttopics: new Map(filed.map((one) => [one.id, one.topics])),\n\t\t\tamendments: this.#sortLaters(pairs, positions),\n\t\t\tsupersessions: this.#sortLaters(\n\t\t\t\tpairs.filter((pair) => pair.head === 'supersedes'),\n\t\t\t\tpositions,\n\t\t\t),\n\t\t}\n\t}\n\n\t// Groups the later ids under each earlier id in first-seen order, each without repeats and in\n\t// conversation order; a stable sort keeps the first-seen order of ids at one position.\n\t#sortLaters(\n\t\tpairs: ReadonlyArray<{ readonly earlier: string; readonly later: string }>,\n\t\tpositions: ReadonlyMap<string, number>,\n\t): ReadonlyMap<string, readonly string[]> {\n\t\treturn new Map(\n\t\t\t[...Map.groupBy(pairs, (pair) => pair.earlier)].map(([earlier, grouped]) => [\n\t\t\t\tearlier,\n\t\t\t\t[...new Set(grouped.map((pair) => pair.later))].sort(\n\t\t\t\t\t(left, right) => (positions.get(left) ?? 0) - (positions.get(right) ?? 0),\n\t\t\t\t),\n\t\t\t]),\n\t\t)\n\t}\n\n\t// Asks every question in order, appending each answer to `results` so a throw still leaves the\n\t// answers completed before it.\n\tasync #gather(\n\t\trequests: ReadonlySet<string>,\n\t\tsignal: AbortSignal,\n\t\tresults: ClassifierResult[],\n\t): Promise<void> {\n\t\tconst messages = this.#options.conversation.messages()\n\t\tconst asked = messages.filter((message) => this.#options.assign(message) === undefined)\n\t\tfor (const message of asked) {\n\t\t\tif (!requests.has(message.id))\n\t\t\t\tresults.push(await this.#ask(this.#buildCategory(message.id), 'category', signal, results))\n\t\t}\n\t\tfor (const message of asked) {\n\t\t\tif (!requests.has(message.id) && this.quiet(message.id)) continue\n\t\t\tfor (const topic of this.#options.topics) {\n\t\t\t\tif (requests.has(message.id) && topic.requested === false) continue\n\t\t\t\tresults.push(await this.#ask(this.#buildTopic(message.id, topic), 'topic', signal, results))\n\t\t\t}\n\t\t}\n\t\tfor (const later of asked) {\n\t\t\tif (\n\t\t\t\tlater.role !== 'user' ||\n\t\t\t\t(this.#readCategories(later.id)?.probabilities.correction ?? 0) <\n\t\t\t\t\tthis.#options.thresholds.correction\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tconst near = this.#collectNear(later)\n\t\t\tif (near.size === 0) continue\n\t\t\tfor (const earlier of messages) {\n\t\t\t\tif (earlier.id === later.id) break\n\t\t\t\tif (\n\t\t\t\t\tthis.quiet(earlier.id) ||\n\t\t\t\t\t![...this.#collectNear(earlier)].some((topic) => near.has(topic))\n\t\t\t\t)\n\t\t\t\t\tcontinue\n\t\t\t\tconst spec = this.#buildPair('amends', earlier.id, later.id)\n\t\t\t\tresults.push(await this.#ask(spec, 'amends', signal, results))\n\t\t\t\tif ((this.#readNoul(spec) ?? 0) >= this.#options.thresholds.amends)\n\t\t\t\t\tresults.push(\n\t\t\t\t\t\tawait this.#ask(\n\t\t\t\t\t\t\tthis.#buildPair('supersedes', earlier.id, later.id),\n\t\t\t\t\t\t\t'supersedes',\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\tresults,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\t#renderState(id: string): string {\n\t\tconst message = this.#options.conversation.message(id)\n\t\treturn `${message?.role ?? 'unknown'}: ${message?.content ?? ''}`\n\t}\n\n\t#buildCategory(id: string): JudgmentInput {\n\t\treturn {\n\t\t\tid: JSON.stringify(['category', id]),\n\t\t\tquestion: {\n\t\t\t\tform: 'choice',\n\t\t\t\t...(this.#options.questions.category.instructions === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { instructions: this.#options.questions.category.instructions }),\n\t\t\t\tcriteria: Object.fromEntries(\n\t\t\t\t\tLEDGER_CATEGORIES.map((category) => [\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\tthis.#options.questions.category.criteria[category],\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t},\n\t\t\tsources: [id],\n\t\t\tstate: this.#renderState(id),\n\t\t\tmodel: this.#options.judge.model,\n\t\t}\n\t}\n\n\t#buildTopic(id: string, topic: LedgerTopic): JudgmentInput {\n\t\treturn {\n\t\t\tid: JSON.stringify(['topic', id, topic.name]),\n\t\t\tquestion: {\n\t\t\t\tform: 'noul',\n\t\t\t\tinstructions: this.#options.questions.topic,\n\t\t\t\tcriteria: {\n\t\t\t\t\ttrue: `The message concerns ${topic.name}: ${topic.criterion}`,\n\t\t\t\t\tfalse: `The message does not concern ${topic.name}`,\n\t\t\t\t},\n\t\t\t},\n\t\t\tsources: [id],\n\t\t\tstate: this.#renderState(id),\n\t\t\tmodel: this.#options.judge.model,\n\t\t}\n\t}\n\n\t#buildPair(head: 'amends' | 'supersedes', earlier: string, later: string): JudgmentInput {\n\t\treturn {\n\t\t\tid: JSON.stringify([head, earlier, later]),\n\t\t\tquestion: this.#options.questions[head],\n\t\t\tsources: [earlier, later],\n\t\t\tstate: `Earlier message: ${this.#renderState(earlier)}\\nLater message: ${this.#renderState(later)}`,\n\t\t\tmodel: this.#options.judge.model,\n\t\t}\n\t}\n\n\t#read(spec: JudgmentInput): Judgment | undefined {\n\t\tconst recorded = this.#options.conversation.judgments.judgment(spec.id)\n\t\treturn recorded !== undefined &&\n\t\t\tmatchesJudgment(recorded, spec.question, spec.sources, spec.state, this.#options.judge.model)\n\t\t\t? recorded\n\t\t\t: undefined\n\t}\n\n\t#readNoul(spec: JudgmentInput): number | undefined {\n\t\tconst answer = this.#read(spec)?.answer\n\t\treturn answer?.form === 'noul' ? answer.noul : undefined\n\t}\n\n\t#readCategories(id: string): ChoiceAnswer | undefined {\n\t\tconst answer = this.#read(this.#buildCategory(id))?.answer\n\t\treturn answer?.form === 'choice' ? answer : undefined\n\t}\n\n\t#weigh(id: string, categories: readonly LedgerCategory[]): number {\n\t\tconst answer = this.#readCategories(id)\n\t\treturn categories.reduce((sum, category) => sum + (answer?.probabilities[category] ?? 0), 0)\n\t}\n\n\t#collectNear(message: Message): ReadonlySet<string> {\n\t\tconst argumentsText =\n\t\t\tmessage.calls === undefined\n\t\t\t\t? undefined\n\t\t\t\t: renderJSON(message.calls.map((call) => call.arguments))\n\t\tconst text =\n\t\t\targumentsText === undefined ? message.content : `${message.content} ${argumentsText}`\n\t\treturn new Set([\n\t\t\t...this.#options.entities(text, false),\n\t\t\t...(this.#options.assign(message) === undefined ? this.topics(message.id) : []),\n\t\t])\n\t}\n\n\tasync #ask(\n\t\tspec: JudgmentInput,\n\t\tphase: ClassifierPhase,\n\t\tsignal: AbortSignal,\n\t\tresults: ClassifierResult[],\n\t): Promise<ClassifierResult> {\n\t\tif (this.#read(spec) !== undefined)\n\t\t\treturn { judgments: [spec.id], readings: [{ key: spec.id, phase, outcome: 'cached' }] }\n\t\tconst fingerprint = JSON.stringify(spec)\n\t\tif (this.#failed.has(fingerprint))\n\t\t\treturn { judgments: [], readings: [{ key: spec.id, phase, outcome: 'skipped' }] }\n\t\tsignal.throwIfAborted()\n\t\tconst started = performance.now()\n\t\ttry {\n\t\t\tconst [judgment] = await this.#options.conversation.judgments.resolve(\n\t\t\t\tthis.#options.judge,\n\t\t\t\t{ state: spec.state, questions: { [spec.id]: spec.question } },\n\t\t\t\tspec.sources,\n\t\t\t\tsignal,\n\t\t\t)\n\t\t\tconst readings: readonly ClassifierReading[] = [\n\t\t\t\t{ key: spec.id, phase, outcome: 'resolved', duration: performance.now() - started },\n\t\t\t]\n\t\t\treturn judgment === undefined\n\t\t\t\t? { judgments: [], readings }\n\t\t\t\t: {\n\t\t\t\t\t\tjudgments: [spec.id],\n\t\t\t\t\t\t...(judgment.usage === undefined ? {} : { usage: judgment.usage }),\n\t\t\t\t\t\treadings,\n\t\t\t\t\t}\n\t\t} catch (error) {\n\t\t\t// A rejection records its reading in the pushed result alone, so the empty result returned under a live signal repeats none.\n\t\t\tconst readings: readonly ClassifierReading[] = [\n\t\t\t\t{\n\t\t\t\t\tkey: spec.id,\n\t\t\t\t\tphase,\n\t\t\t\t\toutcome: isJudgeAbortError(error) || signal.aborted ? 'aborted' : 'failed',\n\t\t\t\t\tduration: performance.now() - started,\n\t\t\t\t},\n\t\t\t]\n\t\t\tif (isJudgeAbortError(error))\n\t\t\t\tresults.push({\n\t\t\t\t\tjudgments:\n\t\t\t\t\t\tObject.hasOwn(error.partial.answers, spec.id) ||\n\t\t\t\t\t\t(error.partial.refusals !== undefined && Object.hasOwn(error.partial.refusals, spec.id))\n\t\t\t\t\t\t\t? [spec.id]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\t...(error.partial.usage === undefined ? {} : { usage: error.partial.usage }),\n\t\t\t\t\treadings,\n\t\t\t\t})\n\t\t\telse results.push({ judgments: [], readings })\n\t\t\tif (\n\t\t\t\t(isJudgeError(error) && error.code === 'QUESTION') ||\n\t\t\t\tDETERMINISTIC_JUDGE_ERROR.test(renderCauseChain(error))\n\t\t\t)\n\t\t\t\tthis.#failed.add(fingerprint)\n\t\t\tif (signal.aborted) throw error\n\t\t\treturn { judgments: [], readings: [] }\n\t\t}\n\t}\n}\n","import { isFiniteNumber } from '@orkestrel/contract'\n\n/**\n * Checks whether a value is finite and lies in the interval (0, 1].\n * @param value - The value to inspect\n * @returns True if the value is a valid ledger fraction; false otherwise\n * @example\n * ```ts\n * isFraction(0.8) // true\n * ```\n */\nexport function isFraction(value: unknown): value is number {\n\treturn isFiniteNumber(value) && value > 0 && value <= 1\n}\n\n/**\n * Checks whether a value is a positive safe integer.\n * @param value - The value to inspect\n * @returns True if the value is a positive safe integer; false otherwise\n * @example\n * ```ts\n * isPositiveSafeInteger(4096) // true\n * ```\n */\nexport function isPositiveSafeInteger(value: unknown): value is number {\n\treturn isFiniteNumber(value) && Number.isSafeInteger(value) && value > 0\n}\n","import type { ThinkingReplay } from '../types.js'\nimport type { GaugeCall, GaugeInterface, GaugeOptions } from './types.js'\nimport { isFiniteNumber } from '@orkestrel/contract'\nimport { estimateMessages } from '../agents/helpers.js'\nimport { LedgerError } from './errors.js'\nimport { isPositiveSafeInteger } from './validators.js'\nimport { buildRecallMessage, fitSlope, resolvePredict } from './helpers.js'\n\n/**\n * Prices prompts in tokens from a measured scale and overhead cost, and measures the room a request\n * has left.\n *\n * @remarks\n * `observe` rescales from the first call of each finished request with the overhead cost taken out,\n * and keeps that request's calls for the marginal rate and the longest final completion for the reply\n * reserve after subtracting its thinking. `overhead` never changes after construction.\n * {@link GaugeOptions} defines the measured use, reply reserve, and recall-room formulas.\n * {@link LedgerOptions} defines the ledger's plan budget and recall close rule.\n *\n * @example\n * ```ts\n * const gauge = new Gauge({ scale: 1.16, overhead: 498, capacity: 32768 })\n * gauge.room([{ estimate: 1719, prompt: 2498, tools: 3 }], '') // estimate units a recall result can take\n * ```\n */\nexport class Gauge implements GaugeInterface {\n\treadonly #capacity: number\n\treadonly #predict: number\n\treadonly #replay: ThinkingReplay\n\t#history: ReadonlyArray<readonly GaugeCall[]> = []\n\t#scale: number\n\t#overhead: number\n\t#reply = 0\n\n\t/**\n\t * Holds the starting price and the capacity.\n\t *\n\t * @param options - The starting `scale` and `overhead` price and the context `capacity`\n\t * @throws {LedgerError} Thrown when `scale` is not finite and above 0, or `overhead` is not finite and at least 0 (code `'GAUGE'`)\n\t * @throws {LedgerError} Thrown when `capacity` is not a positive safe integer (code `'CAPACITY'`)\n\t * @throws {LedgerError} Thrown when `predict` is not a nonnegative safe integer less than `capacity` (code `'CAPACITY'`)\n\t */\n\tconstructor(options: GaugeOptions) {\n\t\tif (!isFiniteNumber(options.scale) || options.scale <= 0) {\n\t\t\tthrow new LedgerError('GAUGE', 'gauge scale must be finite and greater than 0')\n\t\t}\n\t\tif (!isFiniteNumber(options.overhead) || options.overhead < 0) {\n\t\t\tthrow new LedgerError('GAUGE', 'gauge overhead must be finite and at least 0')\n\t\t}\n\t\tif (!isPositiveSafeInteger(options.capacity)) {\n\t\t\tthrow new LedgerError('CAPACITY', 'gauge capacity must be a positive safe integer')\n\t\t}\n\t\tthis.#scale = options.scale\n\t\tthis.#overhead = options.overhead\n\t\tthis.#capacity = options.capacity\n\t\tthis.#predict = resolvePredict(options.predict, options.capacity)\n\t\tthis.#replay = options.replay ?? 'none'\n\t}\n\n\tget scale(): number {\n\t\treturn this.#scale\n\t}\n\n\tget overhead(): number {\n\t\treturn this.#overhead\n\t}\n\n\t/**\n\t * Reads the marginal rate of prompt tokens per estimate unit.\n\t *\n\t * @remarks\n\t * Returns the scale when the fit is undefined, nonfinite, or not above 0, so a degenerate fit never prices recall room.\n\t *\n\t * @param calls - The calls of the request in progress\n\t * @returns The fitted slope, or the scale when the slope is unusable\n\t */\n\trate(calls: readonly GaugeCall[]): number {\n\t\tconst slope = fitSlope([...this.#history, calls])\n\t\treturn slope !== undefined && isFiniteNumber(slope) && slope > 0 ? slope : this.#scale\n\t}\n\n\tremainder(calls: readonly GaugeCall[]): number {\n\t\tconst call = calls.at(-1)\n\t\tconst used = isFiniteNumber(call?.prompt)\n\t\t\t? call.prompt + (call.completion ?? 0) - (this.#replay === 'none' ? (call.thinking ?? 0) : 0)\n\t\t\t: this.#overhead + this.#scale * (call?.estimate ?? 0)\n\t\treturn Math.max(0, this.#capacity - used)\n\t}\n\n\treserve(calls: readonly GaugeCall[], longest: string): number {\n\t\tconst rate = this.rate(calls)\n\t\t// Before any reply is observed, the longest assistant text stands in for the reply.\n\t\tconst reply =\n\t\t\tthis.#reply > 0\n\t\t\t\t? this.#reply\n\t\t\t\t: rate * estimateMessages([{ id: 'reply', role: 'assistant', content: longest }])\n\t\tconst recall =\n\t\t\trate * estimateMessages([buildRecallMessage(''), { id: 'result', role: 'tool', content: '' }])\n\t\treturn reply + recall\n\t}\n\n\troom(calls: readonly GaugeCall[], longest: string): number {\n\t\treturn Math.max(\n\t\t\t0,\n\t\t\t(this.remainder(calls) - this.#predict - this.reserve(calls, longest)) / 2 / this.rate(calls),\n\t\t)\n\t}\n\n\tobserve(calls: readonly GaugeCall[], reply?: GaugeCall): void {\n\t\tconst first = calls[0]\n\t\tif (first !== undefined && isFiniteNumber(first.prompt) && first.estimate > 0) {\n\t\t\tconst priced = first.prompt - this.#overhead\n\t\t\tif (priced > 0) this.#scale = priced / first.estimate\n\t\t}\n\t\tthis.#history = [...this.#history, [...calls]]\n\t\tif (isFiniteNumber(reply?.completion))\n\t\t\tthis.#reply = Math.max(this.#reply, reply.completion - (reply.thinking ?? 0))\n\t}\n}\n","import type { Selection } from '../contexts/types.js'\nimport type { GaugeCall } from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport { sumUsage } from '../helpers.js'\n\n/**\n * Holds what one pass of a ledger request keeps: the selection its run adopted last, the\n * conversation boundary its calls count additions from, its summed usage, and its gauge calls.\n *\n * @remarks\n * A `LedgerRequest` opens one pass per agent run and exposes only projections of it, so no public\n * signature names this class. The pass appends one final record to its log for each call observed,\n * each usage reported, and each thinking share, in emission order, and derives `calls`, `call`, and\n * `position` from it: a usage or thinking record joins the last call observed before it, and one\n * recorded before the first call joins none.\n */\nexport class LedgerPass {\n\t#log: ReadonlyArray<\n\t\t| { readonly call: GaugeCall; readonly position: number }\n\t\t| { readonly usage: { readonly prompt: number; readonly completion: number } }\n\t\t| { readonly thinking: number }\n\t> = []\n\t#selection: Selection | undefined\n\t#boundary: number\n\t#usage: TokenUsage | undefined\n\n\t/**\n\t * Opens the pass at a conversation boundary.\n\t *\n\t * @param boundary - The conversation length when the pass's run starts\n\t */\n\tconstructor(boundary: number) {\n\t\tthis.#boundary = boundary\n\t}\n\n\t/**\n\t * Returns the selection the pass's run adopted last.\n\t *\n\t * @returns The selection, or undefined before one\n\t */\n\tget selection(): Selection | undefined {\n\t\treturn this.#selection\n\t}\n\n\t/**\n\t * Returns the conversation length the pass's calls count additions from.\n\t *\n\t * @returns The length at the pass's start or at its last adopted selection\n\t */\n\tget boundary(): number {\n\t\treturn this.#boundary\n\t}\n\n\t/**\n\t * Returns the summed usage of the pass's selections and calls.\n\t *\n\t * @returns The summed usage, or undefined while none reported usage\n\t */\n\tget usage(): TokenUsage | undefined {\n\t\treturn this.#usage\n\t}\n\n\t/**\n\t * Returns the call in flight.\n\t *\n\t * @returns The latest call the pass observed, or undefined before one\n\t */\n\tget call(): GaugeCall | undefined {\n\t\treturn this.calls.at(-1)\n\t}\n\n\t/**\n\t * Returns the conversation length when the call in flight started.\n\t *\n\t * @returns The position, or undefined before a call\n\t */\n\tget position(): number | undefined {\n\t\treturn this.#log.flatMap((entry) => ('position' in entry ? [entry.position] : [])).at(-1)\n\t}\n\n\t/**\n\t * Returns the pass's gauge calls in order.\n\t *\n\t * @returns Each observed call with the last usage and thinking recorded after it, before the next call\n\t */\n\tget calls(): readonly GaugeCall[] {\n\t\treturn this.#log.flatMap((entry, index) => {\n\t\t\tif (!('call' in entry)) return []\n\t\t\tconst after = this.#log.slice(index + 1)\n\t\t\tconst next = after.findIndex((one) => 'call' in one)\n\t\t\tconst joined = next === -1 ? after : after.slice(0, next)\n\t\t\tconst usage = joined.flatMap((one) => ('usage' in one ? [one.usage] : [])).at(-1)\n\t\t\tconst thinking = joined.flatMap((one) => ('thinking' in one ? [one.thinking] : [])).at(-1)\n\t\t\tconst billed =\n\t\t\t\tusage === undefined\n\t\t\t\t\t? entry.call\n\t\t\t\t\t: { ...entry.call, prompt: usage.prompt, completion: usage.completion }\n\t\t\treturn [thinking === undefined ? billed : { ...billed, thinking }]\n\t\t})\n\t}\n\n\t/**\n\t * Records the selection the pass's run adopted and adds the usage it spent.\n\t *\n\t * @param selection - The selection the run built its prompt from\n\t * @param boundary - The conversation length when the run adopted it\n\t */\n\tadopt(selection: Selection, boundary: number): void {\n\t\tthis.#selection = selection\n\t\tthis.#boundary = boundary\n\t\tif (selection.usage !== undefined) this.#usage = sumUsage(this.#usage, selection.usage)\n\t}\n\n\t/**\n\t * Starts a call, appending its record to the log.\n\t *\n\t * @param call - The call's estimate and advertised tool count\n\t * @param position - The conversation length when the call starts\n\t */\n\tobserve(call: GaugeCall, position: number): void {\n\t\tthis.#log = [...this.#log, { call, position }]\n\t}\n\n\t/**\n\t * Adds one call's reported usage to the pass's summed usage.\n\t *\n\t * @param usage - The usage the provider reported\n\t */\n\tspend(usage: TokenUsage): void {\n\t\tthis.#usage = sumUsage(this.#usage, usage)\n\t}\n\n\t/**\n\t * Appends a reported usage to the log, which joins the call observed last as its prompt and completion.\n\t *\n\t * @remarks\n\t * The record keeps the prompt and completion values the usage held at this call, so a later change\n\t * to the caller's object never reaches a reading.\n\t *\n\t * @param usage - The usage the provider reported for the call\n\t */\n\tbill(usage: TokenUsage): void {\n\t\tthis.#log = [...this.#log, { usage: { prompt: usage.prompt, completion: usage.completion } }]\n\t}\n\n\t/**\n\t * Appends the thinking share to the log, which joins the call observed last.\n\t *\n\t * @param thinking - The completion tokens attributed to the call's thinking\n\t */\n\tthink(thinking: number): void {\n\t\tthis.#log = [...this.#log, { thinking }]\n\t}\n}\n","import type { Selection } from '../contexts/types.js'\nimport type { ConversationInterface } from '../conversations/types.js'\nimport type { Message } from '../types.js'\nimport type { ClassifierReading, GaugeCall, LedgerRequestInterface } from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport { canonicalStringify } from '@orkestrel/contract'\nimport { isNonNegativeSafeInteger } from '../validators.js'\nimport { DEFAULT_RECALL_LIMIT, LEDGER_NOTES } from './constants.js'\nimport { LedgerError } from './errors.js'\nimport { computeThinking } from './helpers.js'\nimport { LedgerPass } from './LedgerPass.js'\n\n/**\n * Holds what one ledger request keeps while it is served: its message, its filing readings and\n * plan, the gauge calls of its passes, and its repeat and recall stops.\n *\n * @remarks\n * A ledger creates one request per `respond` call and drops it when the call settles. Each pass the\n * request opens holds its own selection, boundary, usage, and calls; the request reads the current\n * pass, the last one opened. {@link LedgerRequestInterface} describes each member.\n *\n * @example\n * ```ts\n * const request = new LedgerRequest('What approval is needed?', 1)\n * request.enter(conversation) // the appended user message\n * request.admit('lookup', { id: 'BW-20931' })\n * request.admit('lookup', { id: 'BW-20931' }) // throws Error(LEDGER_NOTES.repeat)\n * request.recall()\n * request.recall() // throws Error(LEDGER_NOTES.closure): the limit of 1 is spent\n * ```\n */\nexport class LedgerRequest implements LedgerRequestInterface {\n\treadonly #content: string\n\treadonly #limit: number\n\t#message: Message | undefined\n\t#plan: Selection | undefined\n\t#passes: readonly LedgerPass[] = []\n\t#readings: readonly ClassifierReading[] = []\n\t#admitted: ReadonlySet<string> = new Set()\n\t#listings: ReadonlyMap<string, ReadonlyMap<string, string>> = new Map()\n\t#recalls = 0\n\t#closed = false\n\n\t/**\n\t * Holds the request's content and its recall limit.\n\t *\n\t * @param content - The request text `enter` appends\n\t * @param limit - The `recall` calls the request can make. Default: the `DEFAULT_RECALL_LIMIT` constant\n\t * @throws {LedgerError} Thrown when `limit` is not a nonnegative safe integer (code `'LIMIT'`)\n\t */\n\tconstructor(content: string, limit: number = DEFAULT_RECALL_LIMIT) {\n\t\tif (!isNonNegativeSafeInteger(limit))\n\t\t\tthrow new LedgerError('LIMIT', 'limits must be nonnegative safe integers')\n\t\tthis.#content = content\n\t\tthis.#limit = limit\n\t}\n\n\t/**\n\t * Returns the request message.\n\t *\n\t * @returns The message `enter` appended, or undefined before it\n\t */\n\tget message(): Message | undefined {\n\t\treturn this.#message\n\t}\n\n\t/**\n\t * Returns the selection the request's last successful plan produced.\n\t *\n\t * @returns The planned selection, or undefined before one\n\t */\n\tget plan(): Selection | undefined {\n\t\treturn this.#plan\n\t}\n\n\t/**\n\t * Returns the selection the current pass's run adopted last.\n\t *\n\t * @returns The selection, or undefined before one\n\t */\n\tget selection(): Selection | undefined {\n\t\treturn this.#passes.at(-1)?.selection\n\t}\n\n\t/**\n\t * Returns the conversation length the current pass's calls count additions from.\n\t *\n\t * @returns The length, or undefined before a pass\n\t */\n\tget boundary(): number | undefined {\n\t\treturn this.#passes.at(-1)?.boundary\n\t}\n\n\t/**\n\t * Returns the summed usage of the current pass.\n\t *\n\t * @returns The summed usage, or undefined while none reported usage\n\t */\n\tget usage(): TokenUsage | undefined {\n\t\treturn this.#passes.at(-1)?.usage\n\t}\n\n\t/**\n\t * Returns the gauge calls of every pass.\n\t *\n\t * @returns The calls in order, the call in flight last\n\t */\n\tget calls(): readonly GaugeCall[] {\n\t\treturn this.#passes.flatMap((pass) => pass.calls)\n\t}\n\n\t/**\n\t * Returns the filing readings of the request's planning selections.\n\t *\n\t * @returns The readings in asking order\n\t */\n\tget readings(): readonly ClassifierReading[] {\n\t\treturn this.#readings\n\t}\n\n\tenter(conversation: ConversationInterface): Message {\n\t\tif (this.#message !== undefined) return this.#message\n\t\tthis.#message = conversation.add({ role: 'user', content: this.#content })\n\t\treturn this.#message\n\t}\n\n\topen(boundary: number): void {\n\t\tthis.#passes = [...this.#passes, new LedgerPass(boundary)]\n\t}\n\n\tadopt(selection: Selection, boundary: number): void {\n\t\tthis.#passes.at(-1)?.adopt(selection, boundary)\n\t}\n\n\tobserve(call: GaugeCall, position: number): void {\n\t\tthis.#passes.at(-1)?.observe(call, position)\n\t}\n\n\tspend(usage: TokenUsage): void {\n\t\tthis.#passes.at(-1)?.spend(usage)\n\t\t// The call in flight can belong to an earlier pass until the current pass observes its first call.\n\t\tthis.#passes.findLast((pass) => pass.call !== undefined)?.bill(usage)\n\t}\n\n\tthink(messages: readonly Message[]): void {\n\t\tconst pass = this.#passes.findLast((one) => one.call !== undefined)\n\t\tconst completion = pass?.call?.completion\n\t\tif (pass?.position === undefined || completion === undefined) return\n\t\tconst message = messages.slice(pass.position).find((entry) => entry.role === 'assistant')\n\t\tif (message?.thinking === undefined) return\n\t\tpass.think(computeThinking(message, completion))\n\t}\n\n\tfile(readings: readonly ClassifierReading[], plan?: Selection): void {\n\t\tthis.#readings = [...this.#readings, ...readings]\n\t\tif (plan !== undefined) this.#plan = plan\n\t}\n\n\tadmit(name: string, args: Readonly<Record<string, unknown>>): void {\n\t\tconst key = canonicalStringify([name, args])\n\t\tif (key === undefined) throw new Error('tool arguments have no canonical identity')\n\t\tif (this.#admitted.has(key)) throw new Error(LEDGER_NOTES.repeat)\n\t\tthis.#admitted = new Set([...this.#admitted, key])\n\t}\n\n\trecall(): void {\n\t\tif (this.#recalls >= this.#limit) this.#closed = true\n\t\tif (this.#closed) throw new Error(LEDGER_NOTES.closure)\n\t\tthis.#recalls += 1\n\t}\n\n\tclose(): void {\n\t\tthis.#closed = true\n\t}\n\n\tlist(result: string, lines: ReadonlyMap<string, string>): void {\n\t\tthis.#listings = new Map([...this.#listings, [result, lines]])\n\t}\n\n\tlisting(result: string): ReadonlyMap<string, string> | undefined {\n\t\treturn this.#listings.get(result)\n\t}\n}\n","import type { AgentInterface, AgentResult } from '../agents/types.js'\nimport type { Selection } from '../contexts/types.js'\nimport type { ConversationInterface } from '../conversations/types.js'\nimport type { ProviderInterface } from '../providers/types.js'\nimport type { Message, ThinkingReplay } from '../types.js'\nimport type {\n\tClassifierResult,\n\tLedgerAmendment,\n\tLedgerCategory,\n\tLedgerGauge,\n\tLedgerInterface,\n\tLedgerLine,\n\tLedgerLookupReading,\n\tLedgerOptions,\n\tLedgerProjection,\n\tLedgerProjectionInput,\n\tLedgerRecord,\n\tLedgerRenderContext,\n\tLedgerResult,\n\tLedgerShare,\n} from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport type { ToolCall, ToolContext, ToolResult } from '@orkestrel/tool'\nimport { createAbort } from '@orkestrel/abort'\nimport { attempt, isError, isFiniteNumber, isString } from '@orkestrel/contract'\nimport { createTool, createToolManager } from '@orkestrel/tool'\nimport { createAgent } from '../agents/factories.js'\nimport { AgentError } from '../agents/errors.js'\nimport { estimateMessages } from '../agents/helpers.js'\nimport { createScope } from '../contexts/factories.js'\nimport { createConversationManager } from '../conversations/factories.js'\nimport {\n\tcollectExchanges,\n\tcollectToolGroups,\n\thasCalls,\n\tstripThinking,\n\tsumUsage,\n} from '../helpers.js'\nimport { isNonNegativeSafeInteger } from '../validators.js'\nimport { Classifier } from './Classifier.js'\nimport { Gauge } from './Gauge.js'\nimport { LedgerRequest } from './LedgerRequest.js'\nimport {\n\tDEFAULT_LEDGER_LIMIT,\n\tDEFAULT_LEDGER_SHARE,\n\tLEDGER_NOTES,\n\tLEDGER_OWNER_PREFIX,\n\tLEDGER_RULES_KEY,\n\tLEDGER_SCALE_DRIFT,\n} from './constants.js'\nimport { isLedgerError, LedgerError } from './errors.js'\nimport {\n\tbuildLines,\n\tbuildLedgerRenderContext,\n\tbuildRecallMessage,\n\tcollectProjectionIds,\n\textractWords,\n\trenderTopicNames,\n\tscanAmendments,\n\tsplitWords,\n\tbuildRecords,\n\tcollectNames,\n\tcollectRegistry,\n\tcutListing,\n\textractTokens,\n\tlinkOwners,\n\tmatchEntities,\n\trankLedgerCut,\n\tresolvePredict,\n\tfindLedgerCall,\n\tmatchesCutLine,\n\trenderLedgerAnnotation,\n\trenderLedgerPinned,\n\trenderLedgerRecord,\n\trenderLookupCall,\n\trenderStub,\n\tselectRecords,\n\tsplitResultLines,\n\tsplitTopic,\n\tsplitSentences,\n} from './helpers.js'\nimport { isFraction, isPositiveSafeInteger } from './validators.js'\n\n/**\n * Serves one conversation through classified records, a bounded briefing, and a final answer pass.\n * @example\n * ```ts\n * const ledger = new Ledger(provider, options)\n * ledger.conversation.add({ role: 'user', content: 'The refund needs approval.' })\n * const reply = await ledger.respond('What approval is needed?')\n * ```\n */\nexport class Ledger implements LedgerInterface {\n\treadonly #provider: ProviderInterface\n\treadonly #options: LedgerOptions\n\treadonly #replay: ThinkingReplay\n\treadonly #predict: number\n\treadonly #share: LedgerShare\n\treadonly #conversation: ConversationInterface\n\treadonly #agent: AgentInterface\n\treadonly #classifier: Classifier\n\treadonly #requests = new Set<string>()\n\treadonly #annotations = new Set<string>()\n\treadonly #results = new Map<string, ToolResult>()\n\treadonly #pending = new Map<number, ToolResult>()\n\treadonly #live = new Set<LedgerRequest>()\n\treadonly #calibrations = new Set<AbortSignal>()\n\t#gauge: Gauge | undefined\n\n\t/**\n\t * Composes the conversation, classifier, tools, and agent.\n\t * @param provider - The provider that serves the conversation\n\t * @param options - The filing policy, capacity, and request bounds\n\t * @throws {LedgerError} Thrown when a threshold, share, capacity, limit, topic, lookup, or gauge is invalid\n\t * @throws {LedgerError} Thrown when `predict` is not a nonnegative safe integer less than `capacity` (code `'CAPACITY'`)\n\t */\n\tconstructor(provider: ProviderInterface, options: LedgerOptions) {\n\t\tfor (const key of ['category', 'topic', 'correction', 'amends', 'supersedes'] as const) {\n\t\t\tconst value = options.thresholds[key]\n\t\t\tif (!isFraction(value))\n\t\t\t\tthrow new LedgerError('THRESHOLD', 'thresholds must be finite and in (0, 1]')\n\t\t}\n\t\tfor (const value of Object.values(options.share ?? {})) {\n\t\t\tif (!isFraction(value)) throw new LedgerError('SHARE', 'shares must be finite and in (0, 1]')\n\t\t}\n\t\tif (!isPositiveSafeInteger(options.capacity))\n\t\t\tthrow new LedgerError('CAPACITY', 'capacity must be a positive safe integer')\n\t\tthis.#predict = resolvePredict(options.predict, options.capacity)\n\t\tfor (const value of [options.recall?.limit, options.agent?.limit]) {\n\t\t\tif (value !== undefined && !isNonNegativeSafeInteger(value))\n\t\t\t\tthrow new LedgerError('LIMIT', 'limits must be nonnegative safe integers')\n\t\t}\n\t\t// `Array.from` visits a hole in either list as an undefined entry, as iteration does, so the\n\t\t// read of its `name` refuses it; `map` skips it.\n\t\tconst topics = Array.from(options.topics, (topic) => topic.name)\n\t\tif (topics.some((name) => name.trim() === '') || new Set(topics).size !== topics.length)\n\t\t\tthrow new LedgerError('TOPIC', 'topic names must be nonempty and unique')\n\t\tconst lookups = ['recall', ...Array.from(options.lookups ?? [], (lookup) => lookup.tool.name)]\n\t\tif (new Set(lookups).size !== lookups.length)\n\t\t\tthrow new LedgerError('LOOKUP', 'lookup names must be unique and cannot be recall')\n\t\tthis.#provider = provider\n\t\tthis.#replay = provider.replay ?? 'none'\n\t\tthis.#options = options\n\t\tthis.#share = { ...DEFAULT_LEDGER_SHARE, ...options.share }\n\t\tif (options.gauge !== undefined)\n\t\t\tthis.#gauge = new Gauge({\n\t\t\t\t...options.gauge,\n\t\t\t\tcapacity: options.capacity,\n\t\t\t\tpredict: this.#predict,\n\t\t\t\treplay: this.#replay,\n\t\t\t})\n\t\tconst conversations = createConversationManager()\n\t\tthis.#conversation = conversations.add()\n\t\tconversations.switch(this.#conversation.id)\n\t\tthis.#classifier = new Classifier({\n\t\t\tconversation: this.#conversation,\n\t\t\tjudge: options.judge,\n\t\t\tquestions: options.questions,\n\t\t\tthresholds: options.thresholds,\n\t\t\ttopics: options.topics,\n\t\t\tassign: this.#assign.bind(this),\n\t\t\tentities: (text, partial) =>\n\t\t\t\tmatchEntities(collectRegistry(this.#readLookups()), text, partial),\n\t\t})\n\t\tconst tools = createToolManager()\n\t\tfor (const lookup of options.lookups ?? []) {\n\t\t\ttools.add(\n\t\t\t\tcreateTool({\n\t\t\t\t\tname: lookup.tool.name,\n\t\t\t\t\t...(lookup.tool.parameters === undefined ? {} : { parameters: lookup.tool.parameters }),\n\t\t\t\t\t...(lookup.tool.description === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { description: lookup.tool.description }),\n\t\t\t\t\t...(lookup.tool.summary === undefined ? {} : { summary: lookup.tool.summary }),\n\t\t\t\t\t...(lookup.tool.title === undefined ? {} : { title: lookup.tool.title }),\n\t\t\t\t\t...(lookup.tool.annotations === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { annotations: lookup.tool.annotations }),\n\t\t\t\t\texecute: (args, context) => this.#lookup(lookup.tool.name, args, context),\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\ttools.add(\n\t\t\tcreateTool({\n\t\t\t\tname: 'recall',\n\t\t\t\tdescription: `Recall what the full conversation record holds on a topic: an owner name, an id, or one of the desk topics ${renderTopicNames(options.topics)}. Returns source lines, newest first.`,\n\t\t\t\tparameters: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\ttopic: { type: 'string', description: 'An owner name, an id, or a desk topic' },\n\t\t\t\t\t},\n\t\t\t\t\trequired: ['topic'],\n\t\t\t\t},\n\t\t\t\texecute: (args) => this.#recall(args),\n\t\t\t}),\n\t\t)\n\t\tthis.#agent = createAgent(provider, {\n\t\t\t...options.agent,\n\t\t\tconversations,\n\t\t\tsystem: options.system,\n\t\t\ttools,\n\t\t\tlimit: options.agent?.limit ?? DEFAULT_LEDGER_LIMIT,\n\t\t\tstrict: false,\n\t\t\tselect: (_conversation, request, signal) => this.#select(request, signal),\n\t\t})\n\t\tthis.#agent.emitter.on('tool', (_call, result) => {\n\t\t\tthis.#flush()\n\t\t\tthis.#pending.set(this.#conversation.messages().length, result)\n\t\t\tif (!result.success && result.error === LEDGER_NOTES.repeat) {\n\t\t\t\tthis.#current()?.close()\n\t\t\t\tthis.#agent.abort('repeat')\n\t\t\t}\n\t\t})\n\t\tthis.#agent.emitter.on('select', (selection) => {\n\t\t\tif (isLedgerError(selection.fault) && selection.fault.code === 'REQUEST') return\n\t\t\tthis.#current()?.adopt(selection, this.#conversation.messages().length)\n\t\t})\n\t\tthis.#agent.emitter.on('turn', () => this.#observeTurn())\n\t\tthis.#agent.emitter.on('usage', (usage) => this.#current()?.spend(usage))\n\t}\n\n\t/**\n\t * Returns the owned request engine.\n\t * @returns The engine serving this conversation\n\t */\n\tget agent(): AgentInterface {\n\t\treturn this.#agent\n\t}\n\t/**\n\t * Returns the owned message history.\n\t * @returns The history filed and served by this ledger\n\t */\n\tget conversation(): ConversationInterface {\n\t\treturn this.#conversation\n\t}\n\t/**\n\t * Returns the stored prompt price.\n\t * @returns The scale and overhead cost, or undefined before calibration\n\t */\n\tget gauge(): LedgerGauge | undefined {\n\t\treturn this.#gauge === undefined\n\t\t\t? undefined\n\t\t\t: { scale: this.#gauge.scale, overhead: this.#gauge.overhead }\n\t}\n\n\t/**\n\t * Measures message scale and tool overhead from provider prompt usage.\n\t * @param signal - The signal bounding both calibration calls; an abort rejects with its reason\n\t * @returns The stored scale and overhead cost\n\t * @throws {LedgerError} Thrown when either call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)\n\t * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)\n\t */\n\tasync calibrate(signal: AbortSignal): Promise<LedgerGauge> {\n\t\tif (this.#busy()) throw new AgentError('CONCURRENCY', 'a ledger request is already active')\n\t\tthis.#calibrations.add(signal)\n\t\ttry {\n\t\t\treturn await this.#measureGauge(signal)\n\t\t} finally {\n\t\t\tthis.#calibrations.delete(signal)\n\t\t}\n\t}\n\n\t/**\n\t * Appends a request and serves it, recovering an unfinished or rejected first pass with one answer pass.\n\t * A calibration call that reports no prompt usage, or a prompt usage of 0 or less, rejects with `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error.\n\t * When the answer pass rejects, `respond` rejects with that error. Every rejection leaves the ledger free for a later call.\n\t * @param content - The request text\n\t * @param signal - The caller's cancellation signal; an abort during calibration rejects with its reason\n\t * @returns The final pass, the usage of every pass, and the filing readings of this request alone\n\t * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)\n\t * @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)\n\t * @throws {ContractError} Thrown when `signal` is defined and is not a native `AbortSignal`\n\t */\n\tasync respond(content: string, signal?: AbortSignal): Promise<LedgerResult> {\n\t\tif (this.#busy()) throw new AgentError('CONCURRENCY', 'a ledger request is already active')\n\t\tconst abort = createAbort({ ...(signal === undefined ? {} : { signal }) })\n\t\tconst caller = abort.signal\n\t\tconst request = new LedgerRequest(content, this.#options.recall?.limit)\n\t\tthis.#live.add(request)\n\t\ttry {\n\t\t\tif (this.#gauge === undefined) await this.#measureGauge(caller)\n\t\t\tconst entered = request.enter(this.#conversation)\n\t\t\tthis.#requests.add(entered.id)\n\t\t\t// The answer pass recovers a rejected first pass; the agent's error event carries its cause.\n\t\t\tconst first = await this.#generatePass(request, caller, this.#options.think).catch(\n\t\t\t\t(): AgentResult => ({\n\t\t\t\t\tcontent: '',\n\t\t\t\t\tpartial: true,\n\t\t\t\t\t...(request.usage === undefined ? {} : { usage: request.usage }),\n\t\t\t\t}),\n\t\t\t)\n\t\t\tconst passes = [first]\n\t\t\tif (!caller.aborted && (first.partial || first.content.trim() === '')) {\n\t\t\t\tconst digest = this.#buildDigest(request, entered)\n\t\t\t\tif (digest !== undefined)\n\t\t\t\t\tthis.#annotations.add(this.#conversation.add({ role: 'user', content: digest }).id)\n\t\t\t\tthis.#annotations.add(\n\t\t\t\t\tthis.#conversation.add({ role: 'user', content: LEDGER_NOTES.cue }).id,\n\t\t\t\t)\n\t\t\t\tconst previous = this.#agent.context.scope\n\t\t\t\tthis.#agent.context.apply(\n\t\t\t\t\tcreateScope({\n\t\t\t\t\t\tname: 'answer',\n\t\t\t\t\t\ttools: [],\n\t\t\t\t\t\tselect: async (_conversation, message, selecting) => {\n\t\t\t\t\t\t\tconst selection = await this.#select(message, selecting)\n\t\t\t\t\t\t\tif (selection.fault !== undefined) return selection\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...selection,\n\t\t\t\t\t\t\t\tmessages: selection.messages.filter((one) => one.role !== 'tool' && !hasCalls(one)),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\ttry {\n\t\t\t\t\tpasses.push(await this.#generatePass(request, caller, false))\n\t\t\t\t} finally {\n\t\t\t\t\tthis.#agent.context.apply(previous)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst last = passes.at(-1) ?? first\n\t\t\trequest.think(this.#conversation.messages())\n\t\t\tconst calls = request.calls\n\t\t\tthis.#gauge?.observe(\n\t\t\t\tcalls,\n\t\t\t\t!last.partial && last.content.trim() !== '' ? calls.at(-1) : undefined,\n\t\t\t)\n\t\t\tconst usage = passes.reduce<TokenUsage | undefined>(\n\t\t\t\t(total, pass) => (pass.usage === undefined ? total : sumUsage(total, pass.usage)),\n\t\t\t\tundefined,\n\t\t\t)\n\t\t\t// Joined as a `joinThinking` fold would join them: an empty part adds no separator.\n\t\t\tconst parts = passes.flatMap((pass) => (pass.thinking === undefined ? [] : [pass.thinking]))\n\t\t\treturn {\n\t\t\t\tcontent: last.content,\n\t\t\t\tpartial: last.partial,\n\t\t\t\tpasses,\n\t\t\t\treadings: request.readings,\n\t\t\t\t...(usage === undefined ? {} : { usage }),\n\t\t\t\t...(parts.length === 0\n\t\t\t\t\t? {}\n\t\t\t\t\t: { thinking: parts.filter((part) => part.length > 0).join('\\n\\n') }),\n\t\t\t\t...(last.stop === undefined ? {} : { stop: last.stop }),\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#flush()\n\t\t\tthis.#live.delete(request)\n\t\t}\n\t}\n\n\tasync #measureGauge(signal: AbortSignal): Promise<LedgerGauge> {\n\t\ttry {\n\t\t\tconst messages = stripThinking(\n\t\t\t\t[\n\t\t\t\t\t{ id: 'system', role: 'system', content: this.#options.system },\n\t\t\t\t\t...this.#conversation.view(),\n\t\t\t\t\t{ id: 'calibration', role: 'user', content: '' },\n\t\t\t\t],\n\t\t\t\tthis.#replay,\n\t\t\t).slice(0, -1)\n\t\t\tconst priced = await this.#provider.generate(\n\t\t\t\tmessages,\n\t\t\t\tsignal,\n\t\t\t\tthis.#agent.context.tools.definitions(),\n\t\t\t\t{ think: false },\n\t\t\t)\n\t\t\tconst bare = await this.#provider.generate(messages, signal, undefined, { think: false })\n\t\t\tif (\n\t\t\t\t!isFiniteNumber(priced.usage?.prompt) ||\n\t\t\t\tpriced.usage.prompt <= 0 ||\n\t\t\t\t!isFiniteNumber(bare.usage?.prompt) ||\n\t\t\t\tbare.usage.prompt <= 0\n\t\t\t)\n\t\t\t\tthrow new LedgerError('GAUGE', 'calibration requires prompt usage from both calls')\n\t\t\tthis.#gauge = new Gauge({\n\t\t\t\tcapacity: this.#options.capacity,\n\t\t\t\tpredict: this.#predict,\n\t\t\t\treplay: this.#replay,\n\t\t\t\tscale: bare.usage.prompt / estimateMessages(messages),\n\t\t\t\toverhead: Math.max(0, priced.usage.prompt - bare.usage.prompt),\n\t\t\t})\n\t\t\treturn { scale: this.#gauge.scale, overhead: this.#gauge.overhead }\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted()\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync #generatePass(\n\t\trequest: LedgerRequest,\n\t\tsignal: AbortSignal,\n\t\tthink?: boolean,\n\t): Promise<AgentResult> {\n\t\trequest.open(this.#conversation.messages().length)\n\t\treturn await this.#agent.generate({ signal, ...(think === undefined ? {} : { think }) })\n\t}\n\n\t// The live `respond` call's request once it has entered its message; a run during the call's\n\t// calibration reaches none. A refusal on every add caps the registry at one request.\n\t#current(): LedgerRequest | undefined {\n\t\tconst [request] = this.#live\n\t\treturn request?.message === undefined ? undefined : request\n\t}\n\n\t#busy(): boolean {\n\t\treturn this.#live.size > 0 || this.#calibrations.size > 0\n\t}\n\n\t#flush(): void {\n\t\t// Filing calls this once per message, and reading the messages copies them all.\n\t\tif (this.#pending.size === 0) return\n\t\tconst messages = this.#conversation.messages()\n\t\tfor (const [at, result] of this.#pending) {\n\t\t\tconst message = messages[at]\n\t\t\tif (message?.role === 'tool') {\n\t\t\t\tthis.#results.set(message.id, result)\n\t\t\t\tthis.#pending.delete(at)\n\t\t\t}\n\t\t}\n\t}\n\n\t#assign(message: Message): LedgerCategory | undefined {\n\t\tthis.#flush()\n\t\tif (this.#annotations.has(message.id)) return 'chatter'\n\t\tif (message.role === 'tool') {\n\t\t\tthis.#readLookups()\n\t\t\treturn this.#results.get(message.id)?.success === false ? 'chatter' : 'fact'\n\t\t}\n\t\tif (message.role !== 'assistant') return undefined\n\t\tif (hasCalls(message)) return 'chatter'\n\t\tconst messages = this.#conversation.messages()\n\t\tconst first = messages.findIndex((one) => this.#requests.has(one.id))\n\t\treturn first >= 0 && messages.findIndex((one) => one.id === message.id) > first\n\t\t\t? 'chatter'\n\t\t\t: undefined\n\t}\n\n\t#readLookups(): readonly LedgerLookupReading[] {\n\t\tthis.#flush()\n\t\treturn collectToolGroups(this.#conversation.messages()).flatMap((group) =>\n\t\t\tgroup.slice(1).flatMap((message): LedgerLookupReading[] => {\n\t\t\t\tconst call = findLedgerCall(group, message)\n\t\t\t\tconst lookup = this.#options.lookups?.find((one) => one.tool.name === call?.name)\n\t\t\t\tif (\n\t\t\t\t\tcall === undefined ||\n\t\t\t\t\tlookup === undefined ||\n\t\t\t\t\tthis.#results.get(message.id)?.success === false\n\t\t\t\t)\n\t\t\t\t\treturn []\n\t\t\t\tconst reading = attempt(() => lookup.read(call.arguments, message.content))\n\t\t\t\tif (!reading.success) {\n\t\t\t\t\t// Caches the failed read, so no later reading calls its handler again.\n\t\t\t\t\tthis.#results.set(message.id, {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tid: call.id,\n\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\terror: isError(reading.error) ? reading.error.message : String(reading.error),\n\t\t\t\t\t})\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tconst result = reading.value\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: message.id,\n\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\targuments: call.arguments,\n\t\t\t\t\t\ttext: message.content,\n\t\t\t\t\t\tresult:\n\t\t\t\t\t\t\tresult === undefined\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t...result,\n\t\t\t\t\t\t\t\t\t\tids: [\n\t\t\t\t\t\t\t\t\t\t\t...new Set([\n\t\t\t\t\t\t\t\t\t\t\t\t...result.ids,\n\t\t\t\t\t\t\t\t\t\t\t\t...Object.values(call.arguments)\n\t\t\t\t\t\t\t\t\t\t\t\t\t.filter(isString)\n\t\t\t\t\t\t\t\t\t\t\t\t\t.flatMap((value) => [...extractTokens(value).ids]),\n\t\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t}),\n\t\t)\n\t}\n\n\t#project(): { readonly input: LedgerProjectionInput; readonly projection: LedgerProjection } {\n\t\tconst readings = this.#readLookups()\n\t\tconst registry = collectRegistry(readings)\n\t\tconst messages = this.#conversation.messages()\n\t\tconst input: LedgerProjectionInput = {\n\t\t\tsystem: this.#options.system,\n\t\t\texclusions: [...this.#requests, ...this.#annotations],\n\t\t\towners: registry.owners,\n\t\t\tmessages,\n\t\t\treadings,\n\t\t\tentities: new Map(\n\t\t\t\tmessages.map((message) => [\n\t\t\t\t\tmessage.id,\n\t\t\t\t\t[...matchEntities(registry, message.content, true)],\n\t\t\t\t]),\n\t\t\t),\n\t\t\tclassification: this.#classifier.classification(),\n\t\t}\n\t\treturn { input, projection: buildRecords(input) }\n\t}\n\n\t#projectLines(input: LedgerProjectionInput, id: string) {\n\t\treturn buildLines(\n\t\t\tinput,\n\t\t\tnew Map(input.messages.map((message) => [message.id, message])),\n\t\t\tid,\n\t\t\t[...input.owners.values()].flat(),\n\t\t\tcollectNames(this.#options.system),\n\t\t)\n\t}\n\n\t#renderSource(id: string, lines: readonly LedgerLine[], context: LedgerRenderContext): string {\n\t\tconst message = this.#conversation.message(id)\n\t\tif (message === undefined) return ''\n\t\tconst sentences = splitSentences(message.content)\n\t\tconst text = sentences.every((_, index) => lines.some((line) => line.sentence === index))\n\t\t\t? message.content\n\t\t\t: lines.map((line) => sentences[line.sentence] ?? '').join(' ')\n\t\tif (text === '') return ''\n\t\tconst reading = this.#readLookups().find((one) => one.id === id)\n\t\treturn [\n\t\t\t...lines.map((line) => renderLedgerAnnotation(line, context)),\n\t\t\tmessage.role !== 'tool' || reading === undefined\n\t\t\t\t? text\n\t\t\t\t: `${renderLookupCall(reading.name, reading.arguments)}: ${text}`,\n\t\t]\n\t\t\t.filter((part) => part !== '')\n\t\t\t.join('\\n')\n\t}\n\n\t#collectAfter(request: Message): readonly Message[] {\n\t\tconst messages = this.#conversation.messages()\n\t\tconst start = messages.findIndex((message) => message.id === request.id)\n\t\treturn messages\n\t\t\t.slice(start + 1)\n\t\t\t.filter(\n\t\t\t\t(message) =>\n\t\t\t\t\tmessage.role !== 'assistant' || hasCalls(message) || message.content.trim() !== '',\n\t\t\t)\n\t}\n\n\tasync #select(message: Message, signal: AbortSignal): Promise<Selection> {\n\t\tconst request = this.#current()\n\t\tconst selected = request?.message\n\t\tif (\n\t\t\trequest === undefined ||\n\t\t\tselected === undefined ||\n\t\t\t(message.id !== selected.id && !this.#annotations.has(message.id))\n\t\t)\n\t\t\treturn this.#refuse(\n\t\t\t\tnew LedgerError(\n\t\t\t\t\t'REQUEST',\n\t\t\t\t\t'ledger selection requires a request owned by an active respond call',\n\t\t\t\t),\n\t\t\t\t{ judgments: [] },\n\t\t\t)\n\t\tconst plan = request.plan\n\t\tif (this.#annotations.has(message.id) && plan !== undefined)\n\t\t\treturn {\n\t\t\t\tmessages: [...plan.messages, ...this.#collectAfter(selected)],\n\t\t\t\tjudgments: [],\n\t\t\t\t...(plan.briefing === undefined ? {} : { briefing: plan.briefing }),\n\t\t\t}\n\t\treturn await this.#classifier.classify(this.#requests, signal).then(\n\t\t\t(classified) => this.#file(classified, request, selected, message),\n\t\t\t(error: unknown) => this.#refuse(error, { judgments: [] }),\n\t\t)\n\t}\n\n\t// Files a classification's readings into the request and plans the selection, falling back to\n\t// the conversation view when the filing faulted or planning threw.\n\t#file(\n\t\tclassified: ClassifierResult,\n\t\trequest: LedgerRequest,\n\t\tselected: Message,\n\t\tmessage: Message,\n\t): Selection {\n\t\tconst { readings, ...filed } = classified\n\t\tconst planned = attempt(() => {\n\t\t\tif (filed.fault !== undefined) throw filed.fault\n\t\t\treturn { ...this.#plan(selected), ...filed }\n\t\t})\n\t\trequest.file(readings, planned.success ? planned.value : undefined)\n\t\tif (!planned.success) return this.#refuse(planned.error, filed)\n\t\treturn this.#annotations.has(message.id)\n\t\t\t? {\n\t\t\t\t\t...planned.value,\n\t\t\t\t\tmessages: [...planned.value.messages, ...this.#collectAfter(selected)],\n\t\t\t\t}\n\t\t\t: planned.value\n\t}\n\n\t// Falls back to the conversation view with the failure as the selection's fault, keeping the\n\t// filing completed before it.\n\t#refuse(error: unknown, filing: Omit<ClassifierResult, 'readings'>): Selection {\n\t\treturn {\n\t\t\t...filing,\n\t\t\tmessages: this.#conversation.view(),\n\t\t\tfault: isError(error) ? error : new Error(String(error)),\n\t\t}\n\t}\n\n\t#price(messages: readonly Message[]): number {\n\t\treturn (this.#gauge?.scale ?? 1) * estimateMessages(messages)\n\t}\n\n\t#plan(request: Message): Pick<Selection, 'messages' | 'briefing'> {\n\t\tconst { input, projection } = this.#project()\n\t\tconst registry = collectRegistry(input.readings)\n\t\tconst links = linkOwners(input.readings, registry.owners)\n\t\tconst near = new Set([\n\t\t\t...matchEntities(registry, request.content, true),\n\t\t\t...this.#classifier.topics(request.id),\n\t\t])\n\t\tconst owners = [...near].flatMap((id) => {\n\t\t\tconst owner = registry.owners.has(id) ? id : links.get(id)\n\t\t\treturn owner === undefined ? [] : [owner]\n\t\t})\n\t\tconst records = selectRecords(projection, { owners, topics: [...near] })\n\t\tconst total =\n\t\t\tMath.max(\n\t\t\t\t0,\n\t\t\t\t(this.#options.capacity - this.#predict) * this.#share.prompt -\n\t\t\t\t\t(this.#gauge?.overhead ?? 0),\n\t\t\t) /\n\t\t\t(1 + LEDGER_SCALE_DRIFT)\n\t\tconst tail = this.#selectTail(request, total * this.#share.tail, input)\n\t\tconst cap = total - this.#price(stripThinking(tail, this.#replay))\n\t\tconst tailIds = new Set(tail.map((message) => message.id))\n\t\tconst scoped = records.some((record) => record.key !== LEDGER_RULES_KEY)\n\t\tconst held = new Set([\n\t\t\t...projection.records\n\t\t\t\t.filter((record) => scoped || record.key === LEDGER_RULES_KEY)\n\t\t\t\t.flatMap((record) => record.members),\n\t\t\t...(records.length > 0\n\t\t\t\t? projection.records.flatMap((record) =>\n\t\t\t\t\t\trecord.members.filter(\n\t\t\t\t\t\t\t(id) =>\n\t\t\t\t\t\t\t\tthis.#conversation.message(id)?.role === 'user' &&\n\t\t\t\t\t\t\t\tthis.#classifier.category(id) === 'rule' &&\n\t\t\t\t\t\t\t\tthis.#classifier.decisive(id),\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t: []),\n\t\t])\n\t\tconst texts = input.messages\n\t\t\t.filter((message) => !hasCalls(message))\n\t\t\t.map((message) => ({\n\t\t\t\tmessage,\n\t\t\t\t...extractWords(message),\n\t\t\t}))\n\t\tconst asked = texts.find(({ message }) => message.id === request.id)\n\t\tconst counts = new Map(\n\t\t\t[\n\t\t\t\t...Map.groupBy(\n\t\t\t\t\ttexts.flatMap((text) => [...text.words]),\n\t\t\t\t\t(word) => word,\n\t\t\t\t),\n\t\t\t].map(([word, occurrences]) => [word, occurrences.length]),\n\t\t)\n\t\tconst live = collectProjectionIds(projection)\n\t\tconst units = texts.flatMap(({ message, words, names }, position) => {\n\t\t\tif (\n\t\t\t\t!live.has(message.id) ||\n\t\t\t\theld.has(message.id) ||\n\t\t\t\t(message.role !== 'tool' && tailIds.has(message.id))\n\t\t\t)\n\t\t\t\treturn []\n\t\t\tconst tokens = extractTokens(message.content)\n\t\t\tif (message.role === 'user' && tokens.ids.size + tokens.numbers.size + names.size === 0)\n\t\t\t\treturn []\n\t\t\tconst category = this.#classifier.category(message.id)\n\t\t\tconst unsettled = message.role === 'user' && !this.#classifier.decisive(message.id)\n\t\t\tconst topics = new Set([\n\t\t\t\t...(input.entities.get(message.id) ?? []),\n\t\t\t\t...this.#classifier.topics(message.id),\n\t\t\t])\n\t\t\tconst ruled = !unsettled && (category === 'rule' || category === 'correction')\n\t\t\tconst group = [...topics].some((topic) => near.has(topic))\n\t\t\t\t? 1\n\t\t\t\t: ruled\n\t\t\t\t\t? 2\n\t\t\t\t\t: [...names].some((name) => asked?.names.has(name))\n\t\t\t\t\t\t? 3\n\t\t\t\t\t\t: 4\n\t\t\tif (group === 4) return []\n\t\t\tconst score = [...words]\n\t\t\t\t.filter((word) => asked?.words.has(word))\n\t\t\t\t.reduce((sum, word) => sum + Math.log(texts.length / (counts.get(word) ?? 1)), 0)\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: message.id,\n\t\t\t\t\tlines: this.#projectLines(input, message.id),\n\t\t\t\t\tposition,\n\t\t\t\t\tgroup,\n\t\t\t\t\truled,\n\t\t\t\t\tunsettled: unsettled,\n\t\t\t\t\tscore,\n\t\t\t\t\tcategory,\n\t\t\t\t\tcut: rankLedgerCut(group, unsettled, category),\n\t\t\t\t},\n\t\t\t]\n\t\t})\n\t\tconst ordered = [...units].sort(\n\t\t\t(left, right) =>\n\t\t\t\tleft.group - right.group ||\n\t\t\t\t(left.group === 1 ? Number(left.unsettled) - Number(right.unsettled) : 0) ||\n\t\t\t\t((left.group === 1 && left.unsettled) || left.group === 3 ? right.score - left.score : 0) ||\n\t\t\t\tleft.position - right.position,\n\t\t)\n\t\tconst cuts = [...ordered].sort(\n\t\t\t(left, right) =>\n\t\t\t\tleft.cut - right.cut ||\n\t\t\t\t(left.cut === 0 || left.cut === 1 || left.cut === 4 ? left.score - right.score : 0) ||\n\t\t\t\tright.position - left.position,\n\t\t)\n\t\tconst rules = records.find((record) => record.key === LEDGER_RULES_KEY)\n\t\tconst steps = [\n\t\t\t...(rules?.lines\n\t\t\t\t.filter((line) => !line.topics.some((topic) => near.has(topic)))\n\t\t\t\t.map(() => ({ key: rules.key, source: undefined })) ?? []),\n\t\t\t...cuts.map((unit) => ({ key: undefined, source: unit.source })),\n\t\t\t...(rules?.lines\n\t\t\t\t.filter((line) => line.topics.some((topic) => near.has(topic)))\n\t\t\t\t.map(() => ({ key: rules.key, source: undefined })) ?? []),\n\t\t\t...records\n\t\t\t\t.filter((record) => record.key !== LEDGER_RULES_KEY)\n\t\t\t\t.flatMap((record) => record.lines.map(() => ({ key: record.key, source: undefined })))\n\t\t\t\t.reverse(),\n\t\t]\n\t\tconst mapped = ordered.map((unit) => ({\n\t\t\tsource: unit.source,\n\t\t\trecord: this.#buildUnitRecord(unit.source, unit.category, input, projection, held),\n\t\t}))\n\t\tconst trimmed = this.#trim(\n\t\t\tsteps,\n\t\t\trecords,\n\t\t\tmapped,\n\t\t\tnew Set(ordered.map((unit) => unit.source)),\n\t\t\tcap,\n\t\t\tprojection.amendments,\n\t\t)\n\t\tconst briefing = trimmed.briefing\n\t\tconst shown = new Set([\n\t\t\t...trimmed.included,\n\t\t\t...records.flatMap((record) =>\n\t\t\t\trecord.members.filter((source) => {\n\t\t\t\t\tconst full = record.lines.filter((line) => line.source === source)\n\t\t\t\t\tconst visible =\n\t\t\t\t\t\ttrimmed.records\n\t\t\t\t\t\t\t.find((one) => one.key === record.key)\n\t\t\t\t\t\t\t?.lines.filter((line) => line.source === source) ?? []\n\t\t\t\t\treturn full.length > 0 && full.length === visible.length\n\t\t\t\t}),\n\t\t\t),\n\t\t])\n\t\treturn {\n\t\t\tmessages: tail.map((message) =>\n\t\t\t\tmessage.role === 'tool' ? this.#renderTailStub(message, shown) : message,\n\t\t\t),\n\t\t\t...(briefing === '' ? {} : { briefing }),\n\t\t}\n\t}\n\n\t// Renders the briefing for each cut in step order (each step drops the last line of the record\n\t// it keys or the source it names) and returns the first cut whose system message fits `cap`; the\n\t// cut after every step is returned unchecked. No cut renders after the one returned.\n\t#trim(\n\t\tsteps: ReadonlyArray<{ readonly key: string | undefined; readonly source: string | undefined }>,\n\t\trecords: readonly LedgerRecord[],\n\t\tmapped: ReadonlyArray<{ readonly source: string; readonly record: LedgerRecord }>,\n\t\tincluded: ReadonlySet<string>,\n\t\tcap: number,\n\t\tamendments: readonly LedgerAmendment[],\n\t): {\n\t\treadonly briefing: string\n\t\treadonly records: readonly LedgerRecord[]\n\t\treadonly included: ReadonlySet<string>\n\t} {\n\t\tconst trimmed = steps.reduce<{\n\t\t\treadonly briefing: string | undefined\n\t\t\treadonly records: readonly LedgerRecord[]\n\t\t\treadonly included: ReadonlySet<string>\n\t\t}>(\n\t\t\t(cut, step) => {\n\t\t\t\tif (cut.briefing !== undefined) return cut\n\t\t\t\tconst briefing = this.#render(cut.records, mapped, cut.included, amendments)\n\t\t\t\tconst content = [this.#options.system, briefing].filter((part) => part !== '').join('\\n\\n')\n\t\t\t\tif (this.#price([{ id: 'system', role: 'system', content }]) <= cap)\n\t\t\t\t\treturn { ...cut, briefing }\n\t\t\t\treturn {\n\t\t\t\t\tbriefing: undefined,\n\t\t\t\t\trecords: cut.records.map((record) =>\n\t\t\t\t\t\trecord.key === step.key ? { ...record, lines: record.lines.slice(0, -1) } : record,\n\t\t\t\t\t),\n\t\t\t\t\tincluded: new Set([...cut.included].filter((source) => source !== step.source)),\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ briefing: undefined, records, included },\n\t\t)\n\t\treturn {\n\t\t\trecords: trimmed.records,\n\t\t\tincluded: trimmed.included,\n\t\t\tbriefing:\n\t\t\t\ttrimmed.briefing ?? this.#render(trimmed.records, mapped, trimmed.included, amendments),\n\t\t}\n\t}\n\n\t#buildUnitRecord(\n\t\tsource: string,\n\t\tcategory: LedgerCategory | undefined,\n\t\tinput: LedgerProjectionInput,\n\t\tprojection: LedgerProjection,\n\t\theld: ReadonlySet<string>,\n\t): LedgerRecord {\n\t\treturn {\n\t\t\tkey: category === 'rule' ? LEDGER_RULES_KEY : source,\n\t\t\ttitle: '',\n\t\t\tmembers: [source],\n\t\t\tlines: this.#collectAmended(\n\t\t\t\tinput,\n\t\t\t\tprojection,\n\t\t\t\tsource,\n\t\t\t\tcategory === 'rule'\n\t\t\t\t\t? new Set(projection.records.flatMap((record) => record.members))\n\t\t\t\t\t: held,\n\t\t\t),\n\t\t}\n\t}\n\n\t#collectAmended(\n\t\tinput: LedgerProjectionInput,\n\t\tprojection: LedgerProjection,\n\t\tsource: string,\n\t\theld: ReadonlySet<string>,\n\t): readonly LedgerLine[] {\n\t\tconst live = collectProjectionIds(projection)\n\t\treturn scanAmendments(\n\t\t\tinput.classification.amendments,\n\t\t\tsource,\n\t\t\t(id) => id === source || (!held.has(id) && live.has(id)),\n\t\t).flatMap((id) => this.#projectLines(input, id))\n\t}\n\n\t#render(\n\t\trecords: readonly LedgerRecord[],\n\t\tmapped: ReadonlyArray<{ readonly source: string; readonly record: LedgerRecord }>,\n\t\tincluded: ReadonlySet<string>,\n\t\tamendments: readonly LedgerAmendment[],\n\t): string {\n\t\tconst entries = mapped\n\t\t\t.filter((unit) => included.has(unit.source))\n\t\t\t.flatMap(({ record: unit }) =>\n\t\t\t\t[...Map.groupBy(unit.lines, (line) => line.source)].map(([source, lines]) => ({\n\t\t\t\t\tunit,\n\t\t\t\t\tsource,\n\t\t\t\t\tlines,\n\t\t\t\t})),\n\t\t\t)\n\t\t// A source renders once, under the first unit that carries it.\n\t\tconst first = new Map(entries.toReversed().map((entry) => [entry.source, entry]))\n\t\tconst unique = entries.filter((entry) => first.get(entry.source) === entry)\n\t\tconst record = records.find(\n\t\t\t(candidate) => candidate.key === LEDGER_RULES_KEY && candidate.lines.length > 0,\n\t\t)\n\t\tconst ownerRecords = records.filter(\n\t\t\t(candidate) => candidate.key !== LEDGER_RULES_KEY && candidate.lines.length > 0,\n\t\t)\n\t\t// The context reads the lines in the order the briefing emits them, so each source's first\n\t\t// retained line carries its annotation and its reference.\n\t\tconst context = buildLedgerRenderContext(\n\t\t\tthis.#conversation.messages(),\n\t\t\t[\n\t\t\t\t...ownerRecords.flatMap((candidate) => candidate.lines),\n\t\t\t\t...unique\n\t\t\t\t\t.filter((entry) => entry.unit.key !== LEDGER_RULES_KEY)\n\t\t\t\t\t.flatMap((entry) => entry.lines),\n\t\t\t\t...(record?.lines ?? []),\n\t\t\t\t...unique\n\t\t\t\t\t.filter((entry) => entry.unit.key === LEDGER_RULES_KEY)\n\t\t\t\t\t.flatMap((entry) => entry.lines),\n\t\t\t],\n\t\t\tamendments,\n\t\t)\n\t\tconst owners = ownerRecords.map((owner) => renderLedgerPinned(owner, context)).join('\\n\\n')\n\t\tconst rendered = unique.map(({ unit, source, lines }) => ({\n\t\t\trules: unit.key === LEDGER_RULES_KEY,\n\t\t\ttexts:\n\t\t\t\tunit.key === LEDGER_RULES_KEY && source === unit.members[0]\n\t\t\t\t\t? lines.map((line) => this.#renderSource(source, [line], context))\n\t\t\t\t\t: [this.#renderSource(source, lines, context)],\n\t\t}))\n\t\tconst pinned = rendered.filter((one) => !one.rules).flatMap((one) => one.texts)\n\t\tconst rules = rendered.filter((one) => one.rules).flatMap((one) => one.texts)\n\t\tconst body = [owners, pinned.join('\\n')].filter((text) => text !== '').join('\\n\\n')\n\t\treturn [\n\t\t\tbody === '' ? '' : `## Pinned\\n${body}`,\n\t\t\trecord === undefined\n\t\t\t\t? rules.length === 0\n\t\t\t\t\t? ''\n\t\t\t\t\t: ['## Rules', ...rules].join('\\n')\n\t\t\t\t: [renderLedgerRecord(record, context), ...rules].join('\\n'),\n\t\t]\n\t\t\t.filter((text) => text !== '')\n\t\t\t.join('\\n\\n')\n\t}\n\n\t#selectTail(request: Message, cap: number, input: LedgerProjectionInput): readonly Message[] {\n\t\tconst first = input.messages.findIndex((message) => this.#requests.has(message.id))\n\t\tconst seed = input.messages.slice(\n\t\t\t0,\n\t\t\tfirst < 0 ? input.messages.findIndex((message) => message.id === request.id) : first,\n\t\t)\n\t\tconst groups = collectToolGroups(seed).flatMap((group) => {\n\t\t\tconst leader = group[0]\n\t\t\tif (leader === undefined) return []\n\t\t\tconst kept = (leader.calls ?? []).flatMap((call) => {\n\t\t\t\tconst message = group.slice(1).find((result) => findLedgerCall(group, result) === call)\n\t\t\t\tconst result = message === undefined ? undefined : this.#results.get(message.id)\n\t\t\t\treturn message === undefined ||\n\t\t\t\t\t!this.#options.lookups?.some((lookup) => lookup.tool.name === call.name) ||\n\t\t\t\t\t(result?.success === false && result.error === LEDGER_NOTES.repeat)\n\t\t\t\t\t? []\n\t\t\t\t\t: [{ call, message }]\n\t\t\t})\n\t\t\treturn [{ leader, kept }]\n\t\t})\n\t\tconst calls = new Map<string, readonly ToolCall[]>(\n\t\t\tgroups.map(({ leader, kept }) => [leader.id, kept.map(({ call }) => call)]),\n\t\t)\n\t\tconst results = new Set(groups.flatMap(({ kept }) => kept.map(({ message }) => message.id)))\n\t\tconst history = seed\n\t\t\t.filter(\n\t\t\t\t(message) =>\n\t\t\t\t\t!this.#annotations.has(message.id) &&\n\t\t\t\t\t(message.role !== 'tool' || results.has(message.id)) &&\n\t\t\t\t\t!(\n\t\t\t\t\t\tmessage.role === 'assistant' &&\n\t\t\t\t\t\thasCalls(message) &&\n\t\t\t\t\t\t(calls.get(message.id)?.length ?? 0) === 0 &&\n\t\t\t\t\t\tmessage.content === ''\n\t\t\t\t\t),\n\t\t\t)\n\t\t\t.map((message) =>\n\t\t\t\tmessage.role === 'tool'\n\t\t\t\t\t? this.#renderTailStub(message)\n\t\t\t\t\t: calls.has(message.id)\n\t\t\t\t\t\t? (calls.get(message.id)?.length ?? 0) > 0\n\t\t\t\t\t\t\t? { ...message, calls: calls.get(message.id) ?? [] }\n\t\t\t\t\t\t\t: { id: message.id, role: message.role, content: message.content }\n\t\t\t\t\t\t: message,\n\t\t\t)\n\t\t// Newest exchange first: the tail keeps every exchange before the first whose addition passes\n\t\t// `cap`, and each candidate is the kept exchanges in conversation order, then the request.\n\t\tconst exchanges = collectExchanges(history).toReversed()\n\t\tconst stop = exchanges.findIndex(\n\t\t\t(_exchange, index) =>\n\t\t\t\tthis.#price(\n\t\t\t\t\tstripThinking(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t...exchanges\n\t\t\t\t\t\t\t\t.slice(0, index + 1)\n\t\t\t\t\t\t\t\t.toReversed()\n\t\t\t\t\t\t\t\t.flat(),\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t],\n\t\t\t\t\t\tthis.#replay,\n\t\t\t\t\t),\n\t\t\t\t) > cap,\n\t\t)\n\t\treturn [\n\t\t\t...exchanges\n\t\t\t\t.slice(0, stop === -1 ? exchanges.length : stop)\n\t\t\t\t.toReversed()\n\t\t\t\t.flat(),\n\t\t\trequest,\n\t\t]\n\t}\n\n\t#renderTailStub(message: Message, shown?: ReadonlySet<string>): Message {\n\t\tconst group = collectToolGroups(this.#conversation.messages()).find((entries) =>\n\t\t\tentries.some((one) => one.id === message.id),\n\t\t)\n\t\tconst call = group === undefined ? undefined : findLedgerCall(group, message)\n\t\tconst reading = this.#readLookups().find((one) => one.id === message.id)\n\t\tconst hidden = renderStub(call?.name ?? 'tool', call?.arguments ?? {}, 'hidden')\n\t\tconst visible = renderStub(call?.name ?? 'tool', call?.arguments ?? {}, 'shown')\n\t\treturn {\n\t\t\t...message,\n\t\t\tcontent: renderStub(\n\t\t\t\tcall?.name ?? 'tool',\n\t\t\t\tcall?.arguments ?? {},\n\t\t\t\tthis.#results.get(message.id)?.success === false\n\t\t\t\t\t? 'failed'\n\t\t\t\t\t: reading?.result === undefined\n\t\t\t\t\t\t? 'empty'\n\t\t\t\t\t\t: shown === undefined\n\t\t\t\t\t\t\t? hidden.length > visible.length\n\t\t\t\t\t\t\t\t? 'hidden'\n\t\t\t\t\t\t\t\t: 'shown'\n\t\t\t\t\t\t\t: shown.has(message.id)\n\t\t\t\t\t\t\t\t? 'shown'\n\t\t\t\t\t\t\t\t: 'hidden',\n\t\t\t),\n\t\t}\n\t}\n\n\t#observeTurn(): void {\n\t\tthis.#flush()\n\t\tconst request = this.#current()\n\t\tconst boundary = request?.boundary\n\t\tif (request === undefined || boundary === undefined) return\n\t\tconst additions = this.#conversation.messages().slice(boundary)\n\t\tconst messages = this.#agent.context.build(request.selection)\n\t\tconst names = this.#agent.context.scope?.tools\n\t\trequest.observe(\n\t\t\t{\n\t\t\t\testimate: estimateMessages(stripThinking([...messages, ...additions], this.#replay)),\n\t\t\t\ttools: this.#agent.context.tools\n\t\t\t\t\t.definitions()\n\t\t\t\t\t.filter((tool) => names === undefined || names.includes(tool.name)).length,\n\t\t\t},\n\t\t\tthis.#conversation.messages().length,\n\t\t)\n\t}\n\n\t#findLongest(): string {\n\t\treturn this.#conversation\n\t\t\t.messages()\n\t\t\t.filter((message) => message.role === 'assistant')\n\t\t\t.reduce(\n\t\t\t\t(longest, message) => (message.content.length > longest.length ? message.content : longest),\n\t\t\t\t'',\n\t\t\t)\n\t}\n\n\t#lookup(name: string, args: Readonly<Record<string, unknown>>, context: ToolContext): unknown {\n\t\tthis.#current()?.admit(name, args)\n\t\tconst lookup = this.#options.lookups?.find((one) => one.tool.name === name)\n\t\tif (lookup === undefined) throw new Error(`unknown lookup ${name}`)\n\t\treturn lookup.tool.execute(args, context)\n\t}\n\n\t#recall(args: Readonly<Record<string, unknown>>): string {\n\t\tconst request = this.#current()\n\t\trequest?.think(this.#conversation.messages())\n\t\tconst topic = isString(args.topic) ? args.topic.trim() : ''\n\t\trequest?.admit('recall', { topic })\n\t\tconst gauge = this.#gauge\n\t\tconst calls = request?.calls ?? []\n\t\tif (\n\t\t\tgauge !== undefined &&\n\t\t\tcalls.length > 0 &&\n\t\t\tgauge.remainder(calls) - this.#predict < 2 * gauge.reserve(calls, this.#findLongest())\n\t\t)\n\t\t\trequest?.close()\n\t\trequest?.recall()\n\t\tconst guidance = `an owner name, an id, or one of ${renderTopicNames(this.#options.topics)}`\n\t\tif (topic === '') throw new Error(`recall needs a topic: ${guidance}`)\n\t\tconst room =\n\t\t\t(gauge?.room(calls, this.#findLongest()) ?? 0) - estimateMessages([buildRecallMessage(topic)])\n\t\tconst { input, projection } = this.#project()\n\t\tconst registry = collectRegistry(input.readings)\n\t\tconst searches = splitTopic(topic).map((part) => {\n\t\t\tconst words = splitWords(part)\n\t\t\tconst matched = new Set([\n\t\t\t\t...[...registry.ids].filter(\n\t\t\t\t\t(id) =>\n\t\t\t\t\t\textractTokens(part).ids.has(id) ||\n\t\t\t\t\t\twords.every((word) =>\n\t\t\t\t\t\t\t`${id} ${(registry.owners.get(id) ?? []).join(' ')}`.toLowerCase().includes(word),\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t...this.#options.topics\n\t\t\t\t\t.filter((one) => words.every((word) => one.name.toLowerCase().includes(word)))\n\t\t\t\t\t.map((one) => one.name),\n\t\t\t])\n\t\t\treturn { words, matched }\n\t\t})\n\t\tconst start = input.messages.findIndex((message) => message.id === request?.message?.id)\n\t\tconst listable = new Map(\n\t\t\tinput.messages\n\t\t\t\t.filter(\n\t\t\t\t\t(message, at) =>\n\t\t\t\t\t\t!this.#requests.has(message.id) && (at < start || message.role === 'tool'),\n\t\t\t\t)\n\t\t\t\t.map((message) => [message.id, message]),\n\t\t)\n\t\tconst readings = new Map(input.readings.map((reading) => [reading.id, reading]))\n\t\tconst matched = new Set(searches.flatMap((search) => [...search.matched]))\n\t\tconst wordings = searches.filter(\n\t\t\t(search) => search.matched.size === 0 && search.words.length > 0,\n\t\t)\n\t\t// Newest first; each item's amenders are claimed by it, so an older item never lists them again.\n\t\tconst listing = [...listable.values()].reverse().reduce<{\n\t\t\treadonly done: ReadonlySet<string>\n\t\t\treadonly listed: readonly string[]\n\t\t\treadonly recalled: ReadonlyMap<string, string>\n\t\t}>(\n\t\t\t(state, message) => {\n\t\t\t\tconst reading = readings.get(message.id)\n\t\t\t\tconst topics = new Set([\n\t\t\t\t\t...(input.entities.get(message.id) ?? []),\n\t\t\t\t\t...this.#classifier.topics(message.id),\n\t\t\t\t\t...projection.records\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(record) =>\n\t\t\t\t\t\t\t\trecord.key.startsWith(LEDGER_OWNER_PREFIX) && record.members.includes(message.id),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.map((record) => record.key.slice(LEDGER_OWNER_PREFIX.length)),\n\t\t\t\t])\n\t\t\t\tconst onTopic =\n\t\t\t\t\t(message.role === 'tool'\n\t\t\t\t\t\t? reading?.result !== undefined\n\t\t\t\t\t\t: !hasCalls(message) && !this.#classifier.quiet(message.id)) &&\n\t\t\t\t\t[...matched].some((match) => topics.has(match))\n\t\t\t\tconst worded =\n\t\t\t\t\t(message.role === 'tool' ? reading !== undefined : message.role === 'user') &&\n\t\t\t\t\twordings.some((search) =>\n\t\t\t\t\t\tsearch.words.every((word) => message.content.toLowerCase().includes(word)),\n\t\t\t\t\t)\n\t\t\t\tif (!onTopic && !worded) return state\n\t\t\t\tconst items = scanAmendments(\n\t\t\t\t\tinput.classification.amendments,\n\t\t\t\t\tmessage.id,\n\t\t\t\t\t(candidate) => listable.has(candidate) && !state.done.has(candidate),\n\t\t\t\t).flatMap((id) => {\n\t\t\t\t\tconst source = listable.get(id)\n\t\t\t\t\tif (source === undefined) return []\n\t\t\t\t\tconst lookup = readings.get(id)\n\t\t\t\t\tconst text =\n\t\t\t\t\t\tlookup === undefined\n\t\t\t\t\t\t\t? source.content\n\t\t\t\t\t\t\t: `${renderLookupCall(lookup.name, lookup.arguments)}: ${source.content}`\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\tstored:\n\t\t\t\t\t\t\t\tlookup === undefined\n\t\t\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\tsplitResultLines(text)[0] ?? '',\n\t\t\t\t\t\t\t\t\t\t\t\tsplitResultLines(source.content)[0] ?? '',\n\t\t\t\t\t\t\t\t\t\t\t] as const,\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t\treturn {\n\t\t\t\t\tdone: new Set([...state.done, ...items.map((item) => item.id)]),\n\t\t\t\t\tlisted:\n\t\t\t\t\t\titems.length === 0\n\t\t\t\t\t\t\t? state.listed\n\t\t\t\t\t\t\t: [...state.listed, items.map((item) => item.text).join('\\n')],\n\t\t\t\t\trecalled: new Map([...state.recalled, ...items.flatMap((item) => item.stored)]),\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ done: new Set(), listed: [], recalled: new Map() },\n\t\t)\n\t\tconst result =\n\t\t\tlisting.listed.length === 0\n\t\t\t\t? `nothing on \"${topic}\"; recall ${guidance}`\n\t\t\t\t: cutListing(listing.listed, room)\n\t\trequest?.list(result, listing.recalled)\n\t\treturn result\n\t}\n\n\t#buildDigest(request: LedgerRequest, entered: Message): string | undefined {\n\t\tthis.#flush()\n\t\t// Each line once, at its first occurrence.\n\t\tconst lines = [\n\t\t\t...new Set(\n\t\t\t\tthis.#collectAfter(entered).flatMap((message) => {\n\t\t\t\t\tconst result = this.#results.get(message.id)\n\t\t\t\t\tif (message.role !== 'tool' || result?.success !== true) return []\n\t\t\t\t\tconst listing = result.name === 'recall'\n\t\t\t\t\tif (listing && /^nothing on /.test(message.content)) return []\n\t\t\t\t\tconst recalled = listing ? request.listing(message.content) : undefined\n\t\t\t\t\treturn splitResultLines(message.content)\n\t\t\t\t\t\t.filter((line) => !listing || !matchesCutLine(line))\n\t\t\t\t\t\t.map((line) => recalled?.get(line) ?? line)\n\t\t\t\t}),\n\t\t\t),\n\t\t]\n\t\treturn lines.length === 0 ? undefined : `${LEDGER_NOTES.results}\\n${lines.join('\\n')}`\n\t}\n}\n","import type { ProviderInterface } from '../providers/types.js'\nimport type { LedgerInterface, LedgerOptions } from './types.js'\nimport { Ledger } from './Ledger.js'\n\n/**\n * Creates a conversation ledger after checking its thresholds, allocation, and tool names.\n * @param provider - The provider that answers requests\n * @param options - The judge, projection policy, capacity, and agent bounds\n * @returns The ledger and its owned conversation and agent\n * @throws {LedgerError} Thrown when an option lies outside its documented bounds\n * @example\n * ```ts\n * const ledger = createLedger(provider, options)\n * const reply = await ledger.respond('Check the order.')\n * ```\n */\nexport function createLedger(provider: ProviderInterface, options: LedgerOptions): LedgerInterface {\n\treturn new Ledger(provider, options)\n}\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"index.js","names":[],"sources":["../../../src/core/constants.ts","../../../src/core/errors.ts","../../../src/core/shapers.ts","../../../src/core/contracts.ts","../../../src/core/cloners.ts","../../../src/core/helpers.ts","../../../src/core/validators.ts","../../../src/core/providers/constants.ts","../../../src/core/providers/errors.ts","../../../src/core/providers/shapers.ts","../../../src/core/providers/contracts.ts","../../../src/core/providers/helpers.ts","../../../src/core/providers/RelayStream.ts","../../../src/core/providers/ThinkSplitter.ts","../../../src/core/providers/AgentProvider.ts","../../../src/core/providers/RelayProvider.ts","../../../src/core/providers/AgentJudge.ts","../../../src/core/providers/validators.ts","../../../src/core/providers/SystemOneJudge.ts","../../../src/core/providers/factories.ts","../../../src/core/conversations/constants.ts","../../../src/core/conversations/errors.ts","../../../src/core/conversations/validators.ts","../../../src/core/conversations/helpers.ts","../../../src/core/conversations/JudgmentManager.ts","../../../src/core/conversations/Conversation.ts","../../../src/core/conversations/ConversationManager.ts","../../../src/core/conversations/stores/MemoryConversationStore.ts","../../../src/core/conversations/stores/DatabaseConversationStore.ts","../../../src/core/conversations/factories.ts","../../../src/core/contexts/constants.ts","../../../src/core/contexts/instructions/Instruction.ts","../../../src/core/contexts/instructions/InstructionManager.ts","../../../src/core/contexts/helpers.ts","../../../src/core/contexts/scopes/Scope.ts","../../../src/core/contexts/scopes/ScopeManager.ts","../../../src/core/contexts/AgentContext.ts","../../../src/core/contexts/factories.ts","../../../src/core/agents/constants.ts","../../../src/core/agents/errors.ts","../../../src/core/agents/Channel.ts","../../../src/core/agents/helpers.ts","../../../src/core/agents/Agent.ts","../../../src/core/agents/AgentFanout.ts","../../../src/core/agents/Authority.ts","../../../src/core/agents/AgentRegistry.ts","../../../src/core/agents/factories.ts","../../../src/core/ledgers/constants.ts","../../../src/core/ledgers/errors.ts","../../../src/core/ledgers/helpers.ts","../../../src/core/ledgers/Classifier.ts","../../../src/core/ledgers/validators.ts","../../../src/core/ledgers/Gauge.ts","../../../src/core/ledgers/LedgerPass.ts","../../../src/core/ledgers/LedgerRequest.ts","../../../src/core/ledgers/Ledger.ts","../../../src/core/ledgers/factories.ts"],"sourcesContent":["/**\n * Lists the roles a conversation message can play, in the order the wire contract names them —\n * the one list the {@link import('./types.js').MessageRole} union derives from, the message\n * guard tests membership against, and the message shape passes to its literal contract.\n */\nexport const MESSAGE_ROLES = Object.freeze(['system', 'user', 'assistant', 'tool'] as const)\n","import type { JudgeResult } from './types.js'\nimport {\n\tINTRINSICS,\n\tholds,\n\tisObject,\n\tisFunction,\n\tisNumber,\n\tisString,\n\tarrayOf,\n} from '@orkestrel/contract'\n\n/**\n * Reports a judge call cancelled by the caller's signal or its deadline, carrying the\n * {@link JudgeResult} merged from the calls that completed before the cancel and the\n * machine-readable `code` `'ABORT'`.\n *\n * @remarks\n * `partial` keeps the answers and the usage of every completed call, so usage reported by\n * completed calls is retained; a cancel before the first call carries an empty partial. `cause` holds the failure the\n * cancel superseded when a throw raced the abort, and is undefined when the cancel was the only\n * failure.\n */\nexport class JudgeAbortError extends Error {\n\t/** Names the machine-readable condition — `'ABORT'`: a judge call cancelled mid-flight. */\n\treadonly code = 'ABORT' as const\n\treadonly partial: JudgeResult\n\n\tconstructor(partial: JudgeResult, options?: ErrorOptions) {\n\t\tsuper('judge call aborted', options)\n\t\tthis.name = 'JudgeAbortError'\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/agent.JudgeAbortError'), { value: this })\n\t\tthis.partial = partial\n\t}\n}\n\n/**\n * Narrows a caught value to a {@link JudgeAbortError} through its identity brand and declared members, so a `catch` can\n * recover its `partial` result.\n *\n * @param value - The caught value\n * @returns True if the value is a {@link JudgeAbortError}; false otherwise\n * @example\n * ```ts\n * isJudgeAbortError(new JudgeAbortError({ model: 'tev1:0.8b', answers: {} })) // true\n * ```\n */\nexport function isJudgeAbortError(value: unknown): value is JudgeAbortError {\n\treturn holds(() => {\n\t\tif (\n\t\t\t!(\n\t\t\t\tvalue instanceof Error &&\n\t\t\t\tINTRINSICS.prototype(value) !== Error.prototype &&\n\t\t\t\tINTRINSICS.describe(value, Symbol.for('@orkestrel/agent.JudgeAbortError'))?.value === value\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\tconst code = INTRINSICS.reflect.read(value, 'code')\n\t\tif (!(code === 'ABORT')) return false\n\t\tconst partial = INTRINSICS.reflect.read(value, 'partial')\n\t\tif (!(isObject(partial) || isFunction(partial))) return false\n\t\tconst answers = INTRINSICS.reflect.read(partial, 'answers')\n\t\tconst refusals = INTRINSICS.reflect.read(partial, 'refusals')\n\t\tconst usage = INTRINSICS.reflect.read(partial, 'usage')\n\t\treturn (\n\t\t\tisString(INTRINSICS.reflect.read(partial, 'model')) &&\n\t\t\t(usage === undefined ||\n\t\t\t\t((isObject(usage) || isFunction(usage)) &&\n\t\t\t\t\t['prompt', 'completion', 'total'].every((key) =>\n\t\t\t\t\t\tisNumber(INTRINSICS.reflect.read(usage, key)),\n\t\t\t\t\t))) &&\n\t\t\t(isObject(answers) || isFunction(answers)) &&\n\t\t\tINTRINSICS.values(answers).every((answer: unknown) => {\n\t\t\t\tif (!(isObject(answer) || isFunction(answer))) return false\n\t\t\t\tconst form = INTRINSICS.reflect.read(answer, 'form')\n\t\t\t\tif (form === 'noul') return isNumber(INTRINSICS.reflect.read(answer, 'noul'))\n\t\t\t\tconst probabilities = INTRINSICS.reflect.read(answer, 'probabilities')\n\t\t\t\tif (form === 'score') return arrayOf(isNumber)(probabilities)\n\t\t\t\treturn (\n\t\t\t\t\tform === 'choice' &&\n\t\t\t\t\t(isObject(probabilities) || isFunction(probabilities)) &&\n\t\t\t\t\tINTRINSICS.values(probabilities).every(isNumber)\n\t\t\t\t)\n\t\t\t}) &&\n\t\t\t(refusals === undefined ||\n\t\t\t\t((isObject(refusals) || isFunction(refusals)) &&\n\t\t\t\t\tINTRINSICS.values(refusals).every(\n\t\t\t\t\t\t(refusal: unknown) =>\n\t\t\t\t\t\t\t(isObject(refusal) || isFunction(refusal)) &&\n\t\t\t\t\t\t\tarrayOf(isString)(INTRINSICS.reflect.read(refusal, 'missing')),\n\t\t\t\t\t)))\n\t\t)\n\t})\n}\n","import type { ContractShape } from '@orkestrel/contract'\nimport { MESSAGE_ROLES } from './constants.js'\nimport {\n\tarrayShape,\n\tjsonShape,\n\tliteralShape,\n\tobjectShape,\n\toptionalShape,\n\trecordShape,\n\tstringShape,\n} from '@orkestrel/contract'\n\n/**\n * Describes a tool call's JSON wire projection.\n *\n * @remarks\n * The wire is strictly narrower than the domain: non-JSON arguments are refused.\n * Calls carry only id, name, and arguments; execution context stays local.\n * The guard refuses every extra member; the contract parser drops extra members.\n */\nexport const toolCallShape = objectShape({\n\tid: stringShape(),\n\tname: stringShape(),\n\targuments: recordShape(jsonShape()),\n}) satisfies ContractShape\n\n/**\n * Describes a conversation message's JSON wire projection.\n *\n * @remarks\n * The wire is strictly narrower than Message: non-JSON call arguments are refused,\n * and execution context stays local. The guard refuses extra members; the parser drops them.\n */\nexport const messageShape = objectShape({\n\tid: stringShape(),\n\trole: literalShape(MESSAGE_ROLES),\n\tcontent: stringShape(),\n\tcalls: optionalShape(arrayShape(toolCallShape)),\n\tcall: optionalShape(stringShape()),\n\timages: optionalShape(arrayShape(stringShape())),\n\tthinking: optionalShape(stringShape()),\n}) satisfies ContractShape\n","import { createContract } from '@orkestrel/contract'\nimport { messageShape } from './shapers.js'\n\n/** Validates and projects conversation messages at a JSON wire boundary. */\nexport const messageContract = createContract(messageShape)\n","import { attempt, parseJSON } from '@orkestrel/contract'\n\n/**\n * Owns a value by serializing it to JSON and parsing the text, so the copy shares nothing with its source.\n *\n * @remarks\n * A value that JSON cannot carry, such as a cycle or a bigint, and a value that serializes to\n * nothing, such as a function, both return undefined, so a guard over the result refuses them.\n * A proxied value serializes through its traps, where a structured clone refuses it.\n *\n * @param value - The value to own\n * @returns The owned JSON copy, or undefined when the value is not JSON\n * @example\n * ```ts\n * copyJSON({ state: 'A ticket.' }) // { state: 'A ticket.' }\n * copyJSON(() => 1) // undefined\n * ```\n */\nexport function copyJSON(value: unknown): unknown {\n\tconst text = attempt(() => JSON.stringify(value))\n\tif (!text.success || typeof text.value !== 'string') return undefined\n\treturn parseJSON(text.value)\n}\n","import type { JudgeQuestion, Judgment, Message, ThinkingReplay } from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport { attempt, isFiniteNumber } from '@orkestrel/contract'\n\n/**\n * Filters a list of members by a {@link import('./contexts/index.js').ScopeInterface} allow-list of keys —\n * `undefined` passes everything, `[]` passes nothing, and a non-empty list passes the listed keys\n * alone, order preserved. The pure, total set-membership primitive the context's build step and\n * the agent loop's tool-advertise step apply a scope through.\n *\n * @remarks\n * Varies by the allow-list's shape, so a `Scope` category expresses \"all /\n * none / only these\":\n * - `undefined` ⇒ no constraint — every member passes (returned unchanged).\n * - `[]` (empty) ⇒ none pass (no key is in an empty set).\n * - a non-empty list ⇒ only members whose `key(member)` is in the list pass.\n *\n * Preserves the members' order. Keys are matched by a `Set` for membership.\n *\n * @typeParam T - The member type being filtered\n * @param allow - The allow-list of keys (`undefined` ⇒ all, `[]` ⇒ none, else only-listed)\n * @param members - The members to filter (returned unchanged when `allow` is `undefined`)\n * @param key - Extracts the key a member is matched on (for example an instruction's `name`)\n * @returns The members that pass the allow-list, in their original order\n *\n * @example\n * ```ts\n * const members = [{ name: 'refunds' }, { name: 'billing' }]\n * filterAllowList(undefined, members, (member) => member.name) // [{ name: 'refunds' }, { name: 'billing' }]\n * filterAllowList([], members, (member) => member.name) // []\n * filterAllowList(['billing'], members, (member) => member.name) // [{ name: 'billing' }]\n * ```\n */\nexport function filterAllowList<T>(\n\tallow: readonly string[] | undefined,\n\tmembers: readonly T[],\n\tkey: (member: T) => string,\n): readonly T[] {\n\tif (allow === undefined) return members\n\tif (allow.length === 0) return []\n\tconst set = new Set(allow)\n\treturn members.filter((member) => set.has(key(member)))\n}\n\n/**\n * Joins the reasoning a run's provider calls separated from the answer — the first call\n * seeds the accumulation, a later call appends blank-line separated so each turn's reasoning\n * stays readable.\n *\n * @remarks\n * Pure and total. `running` is `undefined` until a call surfaces reasoning, so the first join\n * returns `next` verbatim. Each call's non-empty thinking is recorded on the assistant message\n * that call appends. The joined result also includes thinking from calls that appended no\n * message, such as an aborted call. Only recorded thinking can return to a provider,\n * as its `replay` policy allows. Thinking stays out of `content`.\n *\n * @param running - The reasoning accumulated so far (`undefined` before the first)\n * @param next - This call's separated reasoning\n * @returns The joined reasoning\n *\n * @example\n * ```ts\n * joinThinking(undefined, 'first') // 'first'\n * joinThinking('', 'x') // 'x'\n * joinThinking('first', 'second') // 'first\\n\\nsecond'\n * ```\n */\nexport function joinThinking(running: string | undefined, next: string): string {\n\tif (running === undefined || running.length === 0) return next\n\treturn next.length === 0 ? running : `${running}\\n\\n${next}`\n}\n\n/**\n * Applies a {@link ThinkingReplay} policy to a conversation, returning the messages a provider\n * sends with only the assistant thinking the policy allows.\n *\n * @remarks\n * Pure and total. `'all'` returns the input array itself. `'none'` drops `thinking` from every\n * message that carries it. `'turn'` drops it from every message at or before the last `user`\n * message and keeps it after, the turn in progress; with no `user` message every message counts\n * as inside the turn. A message without `thinking`, or one that keeps it, is the same object;\n * a message that loses it is a copy without that member, so no `undefined` member is written.\n *\n * @param messages - The conversation to project (left unchanged)\n * @param replay - The policy naming which thinking stays\n * @returns The messages with the policy applied\n *\n * @example\n * ```ts\n * const messages = [\n * \t{ id: '1', role: 'user', content: 'Plan the trip' },\n * \t{ id: '2', role: 'assistant', content: 'Booked', thinking: 'Compare fares first' },\n * ]\n * stripThinking(messages, 'none') // [{ id: '1', ... }, { id: '2', role: 'assistant', content: 'Booked' }]\n * stripThinking(messages, 'turn') // the thinking on '2' stays: it follows the last user message\n * ```\n */\nexport function stripThinking(\n\tmessages: readonly Message[],\n\treplay: ThinkingReplay,\n): readonly Message[] {\n\tif (replay === 'all') return messages\n\tconst last =\n\t\treplay === 'none' ? messages.length - 1 : messages.findLastIndex((one) => one.role === 'user')\n\treturn messages.map((message, index) => {\n\t\tif (message.thinking === undefined || index > last) return message\n\t\tconst { thinking: _thinking, ...rest } = message\n\t\treturn rest\n\t})\n}\n\n/**\n * Sanitizes one reported token count into a non-negative integer — a non-finite or\n * non-positive value becomes `0`, and a positive fractional value floors down.\n *\n * @param value - The token count to sanitize\n * @returns The floored count, or `0` when the value is non-finite or non-positive\n * @example\n * ```ts\n * sanitizeToken(12.7) // 12\n * sanitizeToken(-1) // 0\n * sanitizeToken(Number.NaN) // 0\n * ```\n */\nexport function sanitizeToken(value: number): number {\n\treturn isFiniteNumber(value) && value > 0 ? Math.floor(value) : 0\n}\n\n/**\n * Sanitizes a {@link TokenUsage} into non-negative integers — the guard an agent's\n * abort-usage path applies to a provider's partial usage before it is charged against a\n * budget or folded into the run total.\n *\n * @remarks\n * Per field (`prompt` / `completion` / `total`): a non-finite value (`NaN`, `+Infinity`,\n * `-Infinity`) or a negative value floors to `0`; a fractional value floors to its\n * non-negative integer part. No upper cap is applied. Total — never throws.\n *\n * @param usage - The token usage to sanitize (for example a provider's abort-partial usage)\n * @returns A new {@link TokenUsage} with every field a non-negative integer\n *\n * @example\n * ```ts\n * sanitizeUsage({ prompt: -5, completion: NaN, total: 12.7 }) // { prompt: 0, completion: 0, total: 12 }\n * ```\n */\nexport function sanitizeUsage(usage: TokenUsage): TokenUsage {\n\treturn {\n\t\tprompt: sanitizeToken(usage.prompt),\n\t\tcompletion: sanitizeToken(usage.completion),\n\t\ttotal: sanitizeToken(usage.total),\n\t}\n}\n\n/**\n * Adds two {@link TokenUsage} values field by field — the running total an agent run keeps\n * across its provider calls.\n *\n * @remarks\n * Pure and total: the first call seeds the total (`running` `undefined` returns `next`\n * unchanged), later calls accumulate. No sanitization happens here — charge a provider's\n * reported usage through {@link sanitizeUsage} first.\n *\n * @param running - The total so far (`undefined` before the first usage-bearing call)\n * @param next - This call's reported usage\n * @returns The summed usage\n *\n * @example\n * ```ts\n * sumUsage(undefined, { prompt: 2, completion: 1, total: 3 }) // { prompt: 2, completion: 1, total: 3 }\n * sumUsage({ prompt: 2, completion: 1, total: 3 }, { prompt: 1, completion: 1, total: 2 })\n * // { prompt: 3, completion: 2, total: 5 }\n * ```\n */\nexport function sumUsage(running: TokenUsage | undefined, next: TokenUsage): TokenUsage {\n\tif (running === undefined) return next\n\treturn {\n\t\tprompt: running.prompt + next.prompt,\n\t\tcompletion: running.completion + next.completion,\n\t\ttotal: running.total + next.total,\n\t}\n}\n\n/**\n * Removes each key through a single-key remover and folds the outcomes, so a batch `remove`\n * reports whether the whole batch applied.\n *\n * @remarks\n * Every key is passed to `remove` even after one is missing, so a present key still takes\n * effect (and emits) when an earlier key was absent.\n *\n * @typeParam K - The key type the remover accepts\n * @param keys - The keys to remove, in order\n * @param remove - Removes one key and returns whether it was present\n * @returns True if every key was present and removed; false otherwise (an empty list returns true)\n *\n * @example\n * ```ts\n * const stored = new Set(['refunds', 'billing'])\n * removeEntries(['refunds', 'escalations'], (key) => stored.delete(key)) // false\n * removeEntries(['billing'], (key) => stored.delete(key)) // true\n * ```\n */\nexport function removeEntries<K>(keys: readonly K[], remove: (key: K) => boolean): boolean {\n\t// `Array.from` passes a hole in `keys` to `remove` as `undefined`, as iteration does; `map` skips it.\n\treturn Array.from(keys, (key) => remove(key)).every((removed) => removed)\n}\n\n/**\n * Collects whole exchanges, joining every exchange spanned by a tool group.\n *\n * @remarks\n * A user message opens an exchange that ends before the next user message. Leading messages\n * form their own exchange. A tool group joins every exchange between its first and last member.\n *\n * @param messages - The messages in prompt order\n * @returns The exchanges in prompt order, with each message retained unchanged\n * @example\n * ```ts\n * collectExchanges([\n * \t{ id: 'greeting', role: 'assistant', content: 'Welcome.' },\n * \t{ id: 'request', role: 'user', content: 'Read the order.' },\n * ]) // a leading exchange and a request exchange\n * ```\n */\nexport function collectExchanges(messages: readonly Message[]): ReadonlyArray<readonly Message[]> {\n\tif (messages.length === 0) return []\n\tconst positions = new Map(messages.map((message, index) => [message, index]))\n\tconst spans = collectToolGroups(messages).map((group) => {\n\t\tconst spanned = group.flatMap((message) => {\n\t\t\tconst position = positions.get(message)\n\t\t\treturn position === undefined ? [] : [position]\n\t\t})\n\t\treturn {\n\t\t\tstart: spanned.reduce((least, position) => Math.min(least, position), messages.length),\n\t\t\tend: spanned.reduce((most, position) => Math.max(most, position), 0),\n\t\t}\n\t})\n\tconst starts = [\n\t\t...new Set([\n\t\t\t0,\n\t\t\t...[...messages.entries()].flatMap(([index, message]) =>\n\t\t\t\tmessage.role === 'user' ? [index] : [],\n\t\t\t),\n\t\t]),\n\t].filter((boundary) => !spans.some((span) => span.start < boundary && boundary <= span.end))\n\treturn starts.map((start, position) =>\n\t\tmessages.slice(start, starts[position + 1] ?? messages.length),\n\t)\n}\n\n/**\n * Checks whether a message carries at least one tool call.\n *\n * @remarks\n * Pure and total. An absent `calls` member and an empty list both return false, so a tool-free\n * assistant turn and a turn whose provider reported an empty call list read alike.\n *\n * @param message - The message to inspect; only its `calls` member is read\n * @returns True if `calls` holds at least one call; false otherwise\n * @example\n * ```ts\n * hasCalls({ calls: [{ id: 'order', name: 'lookup', arguments: {} }] }) // true\n * hasCalls({ calls: [] }) // false\n * hasCalls({}) // false\n * ```\n */\nexport function hasCalls(message: Pick<Message, 'calls'>): boolean {\n\treturn (message.calls?.length ?? 0) > 0\n}\n\n/**\n * Collects each assistant message that carries calls together with the tool messages that answer\n * it, then each run of tool messages that no assistant message owns.\n *\n * @remarks\n * A tool message belongs to the one assistant message whose calls hold its `call` id. Without that\n * unique owner, it belongs to the assistant message that leads its run of tool messages when that\n * leader holds the id, repeats a call id, or the tool message has no `call`. Any other tool message\n * joins the orphan run it sits in. Compaction and the stock selection each keep a group on one side\n * of their cut.\n *\n * @param messages - The messages in prompt order\n * @returns The owned groups in owner order, then the orphan runs, each in prompt order\n * @example\n * ```ts\n * collectToolGroups([\n * \t{ id: 'lookup', role: 'assistant', content: '', calls: [{ id: 'order', name: 'lookup', arguments: {} }] },\n * \t{ id: 'result', role: 'tool', content: 'LH-81660 is late', call: 'order' },\n * ]) // one group holding the lookup call and its result\n * ```\n */\nexport function collectToolGroups(messages: readonly Message[]): ReadonlyArray<readonly Message[]> {\n\tconst leaders = messages.filter((message) => message.role === 'assistant' && hasCalls(message))\n\tconst leading = new Set(leaders)\n\t// `Array.from` passes a hole in `calls` to the mapper as `undefined`, as iteration does; `map` skips it.\n\tconst owners = Map.groupBy(\n\t\tleaders.flatMap((leader) =>\n\t\t\tArray.from(leader.calls ?? [], (call) => ({ id: call.id, leader })),\n\t\t),\n\t\t(entry) => entry.id,\n\t)\n\tconst starts = [...messages.entries()].flatMap(([index, message]) =>\n\t\tmessage.role === 'tool' ? [] : [index],\n\t)\n\t// A run is one non-tool message, which leads it when it owns calls, and the tool messages after it.\n\tconst runs = [\n\t\t{ leader: undefined, tools: messages.slice(0, starts[0] ?? messages.length) },\n\t\t...starts.map((start, position) => {\n\t\t\tconst message = messages[start]\n\t\t\treturn {\n\t\t\t\tleader: message !== undefined && leading.has(message) ? message : undefined,\n\t\t\t\ttools: messages.slice(start + 1, starts[position + 1] ?? messages.length),\n\t\t\t}\n\t\t}),\n\t]\n\tconst placed = runs.map(({ leader, tools }) => {\n\t\tconst local = leader?.calls ?? []\n\t\tconst duplicate = new Set(local.map((call) => call.id)).size !== local.length\n\t\treturn tools.map((message) => {\n\t\t\tconst paired =\n\t\t\t\tleader !== undefined &&\n\t\t\t\t(duplicate || message.call === undefined || local.some((call) => call.id === message.call))\n\t\t\tconst sharing = message.call === undefined ? undefined : owners.get(message.call)\n\t\t\tconst owner = sharing?.length === 1 ? sharing[0]?.leader : paired ? leader : undefined\n\t\t\treturn { message, owner }\n\t\t})\n\t})\n\tconst owned = Map.groupBy(\n\t\tplaced.flat().filter((entry) => entry.owner !== undefined),\n\t\t(entry) => entry.owner,\n\t)\n\tconst groups = [...leading].map((leader) => [\n\t\tleader,\n\t\t...(owned.get(leader) ?? []).map((entry) => entry.message),\n\t])\n\tconst orphans = placed.flatMap((run) => {\n\t\tconst orphan = run.filter((entry) => entry.owner === undefined).map((entry) => entry.message)\n\t\treturn orphan.length > 0 ? [orphan] : []\n\t})\n\treturn [...groups, ...orphans]\n}\n\n/**\n * Renders a value as the JSON text `JSON.stringify` produces, or `undefined` when JSON cannot\n * carry the value.\n *\n * @remarks\n * Pure and total. Where `JSON.stringify` returns text, the result is the same text, property order\n * included; `canonicalStringify` from `@orkestrel/contract` sorts keys instead. A value\n * `JSON.stringify` throws on, such as a `BigInt` or a cycle, and a value it renders as nothing,\n * such as `undefined`, a function, or a symbol, return `undefined`.\n *\n * @param value - The value to render\n * @returns The JSON text, or `undefined` when the value has no JSON text\n * @example\n * ```ts\n * renderJSON({ order: 'LH-81660', late: true }) // '{\"order\":\"LH-81660\",\"late\":true}'\n * renderJSON(10n) // undefined\n * renderJSON(undefined) // undefined\n * ```\n */\nexport function renderJSON(value: unknown): string | undefined {\n\tconst outcome = attempt((): string | undefined => JSON.stringify(value))\n\treturn outcome.success ? outcome.value : undefined\n}\n\n/**\n * Matches a recorded question, ordered sources, rendered state, and judge identity by JSON text, so key order counts.\n *\n * @param judgment - The recorded judgment to compare\n * @param question - The question to ask\n * @param sources - The ordered source message ids\n * @param state - The rendered state to compare\n * @param model - The configured judge identity\n * @returns True if every identity component matches; false otherwise\n * @example\n * ```ts\n * matchesJudgment(judgment, question, ['message-a'], 'Charged twice', judge.model)\n * ```\n */\nexport function matchesJudgment(\n\tjudgment: Judgment,\n\tquestion: JudgeQuestion,\n\tsources: readonly string[],\n\tstate: string,\n\tmodel: string,\n): boolean {\n\treturn (\n\t\tjudgment.model === model &&\n\t\tjudgment.state === state &&\n\t\tjudgment.sources.length === sources.length &&\n\t\tjudgment.sources.every((id, index) => id === sources[index]) &&\n\t\tJSON.stringify(judgment.question) === JSON.stringify(question)\n\t)\n}\n","import type { JudgeEntry, JudgeQuestion } from './types.js'\nimport {\n\tarrayOf,\n\tattempt,\n\tisArray,\n\tisFiniteNumber,\n\tisJSONValue,\n\tisRecord,\n\tisString,\n\tnullableOf,\n\toptionalOf,\n} from '@orkestrel/contract'\n\n/**\n * Checks whether a value is a judge entry: a string, a JSON record, or a JSON array.\n *\n * @remarks\n * Total: a cycle, a non-JSON member, a class instance, and a hostile input return false. `null`\n * is not an entry; a criteria guard admits it where the protocol keeps it.\n *\n * @param value - The unknown entry candidate\n * @returns True if the value is a string or JSON structure the model can read; false otherwise\n * @example\n * ```ts\n * isJudgeEntry('Customer asks for a refund') // true\n * isJudgeEntry({ ticket: 4182, tags: ['billing'] }) // true\n * isJudgeEntry(null) // false\n * isJudgeEntry({ opened: new Date() }) // false\n * ```\n */\nexport function isJudgeEntry(value: unknown): value is JudgeEntry {\n\tif (isString(value)) return true\n\treturn (isRecord(value) || isArray(value)) && isJSONValue(value)\n}\n\n/**\n * Checks whether a value is a well-formed judge question of the choice, score, or noul form.\n *\n * @remarks\n * Total: a hostile input returns false. A choice needs at least 2 options and a score at least 2\n * levels, because the confidence formula divides by the candidate count; a description or a level\n * can be `null`. `instructions` and noul `criteria` are omitted when absent and never `null`.\n * Server limits on option, level, and question counts are left to the server.\n *\n * @param value - The unknown question candidate\n * @returns True if the value is a question the judge engine can send; false otherwise\n * @example\n * ```ts\n * isJudgeQuestion({ form: 'choice', criteria: { billing: null, bug: 'Software defect' } }) // true\n * isJudgeQuestion({ form: 'score', criteria: ['Cosmetic', null, 'Blocking'] }) // true\n * isJudgeQuestion({ form: 'noul', instructions: 'Is a refund owed?' }) // true\n * isJudgeQuestion({ form: 'choice', criteria: { billing: null } }) // false\n * ```\n */\nexport function isJudgeQuestion(value: unknown): value is JudgeQuestion {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { form, instructions, criteria } = value\n\t\tif (instructions !== undefined && !isJudgeEntry(instructions)) return false\n\t\tif (form === 'choice') {\n\t\t\treturn (\n\t\t\t\tisRecord(criteria) &&\n\t\t\t\tObject.keys(criteria).length >= 2 &&\n\t\t\t\tObject.values(criteria).every(nullableOf(isJudgeEntry))\n\t\t\t)\n\t\t}\n\t\tif (form === 'score') {\n\t\t\treturn arrayOf(nullableOf(isJudgeEntry))(criteria) && criteria.length >= 2\n\t\t}\n\t\tif (form !== 'noul') return false\n\t\tif (criteria === undefined) return true\n\t\tif (!isRecord(criteria)) return false\n\t\treturn optionalOf(isJudgeEntry)(criteria.true) && optionalOf(isJudgeEntry)(criteria.false)\n\t})\n\treturn checked.success && checked.value\n}\n\n/**\n * Checks whether a value is a non-negative safe integer, `-0` included.\n *\n * @remarks\n * Total: a non-number, `NaN`, an infinity, a fraction, a negative number, and an integer past\n * `Number.MAX_SAFE_INTEGER` return false. It differs from `isNonNegativeInteger` in\n * `@orkestrel/contract` at two values: that guard rejects `-0` and admits an unsafe integer such\n * as `2 ** 53`, while this guard admits `-0` and rejects `2 ** 53`.\n *\n * @param value - The unknown count or limit candidate\n * @returns True if the value is a safe integer at or above zero; false otherwise\n * @example\n * ```ts\n * isNonNegativeSafeInteger(0) // true\n * isNonNegativeSafeInteger(-0) // true\n * isNonNegativeSafeInteger(2 ** 53) // false\n * isNonNegativeSafeInteger(1.5) // false\n * ```\n */\nexport function isNonNegativeSafeInteger(value: unknown): value is number {\n\treturn isFiniteNumber(value) && Number.isSafeInteger(value) && value >= 0\n}\n","/**\n * Names the opening tag a {@link import('./ThinkSplitter.js').ThinkSplitter} recognizes as the start of\n * an in-content reasoning span — `'<think>'`, the de-facto wire convention thinking models\n * (qwen3, DeepSeek-R1 family) emit their chain-of-thought under when a daemon renders it inline\n * instead of on a separate wire field. Paired with {@link THINK_CLOSE}.\n */\nexport const THINK_OPEN = '<think>'\n\n/**\n * Names the closing tag that ends a {@link THINK_OPEN} reasoning span — `'</think>'`. A span the\n * stream never closes (the model was cut off mid-reasoning) is treated as thinking to its end,\n * and {@link import('./types.js').ThinkSplitterInterface.flush} settles it.\n */\nexport const THINK_CLOSE = '</think>'\n\n/**\n * Holds the default provider deadline in milliseconds — `120_000`, the wall-clock bound a call\n * runs under when `AgentProviderInput.timeout` is omitted, folded with the caller's signal so\n * whichever trips first cancels the call.\n */\nexport const DEFAULT_PROVIDER_TIMEOUT = 120_000\n\n/**\n * Bounds the decoded error excerpt's input in bytes — `2048`, the leading bytes of a non-OK\n * response body handed to the decoder before the read cancels the remainder, so a `ProviderError`\n * message never carries a longer excerpt.\n */\nexport const MAX_ERROR_BODY_LENGTH = 2048\n\n/**\n * Holds the default relay request limit in bytes — `1_048_576`, the byte budget a relay applies\n * to an inbound body when `RelayOptions.limit` is omitted, refusing a body that reaches it.\n */\nexport const DEFAULT_RELAY_LIMIT = 1_048_576\n\n/**\n * Names the relay's newline-delimited JSON content type — `'application/x-ndjson; charset=utf-8'`,\n * the header a relay response carries beside `cache-control: no-store`.\n */\nexport const RELAY_CONTENT_TYPE = 'application/x-ndjson; charset=utf-8'\n\n/**\n * Names the public message for an unexpected upstream relay failure — `'relay provider failed'`,\n * the fixed text every `error` frame carries, so an upstream failure's own message never reaches\n * the browser.\n */\nexport const RELAY_PROVIDER_MESSAGE = 'relay provider failed'\n\n/**\n * Names the status a relay answers when the `authorize` callback returns anything but `true` or throws —\n * `401`, carried with no body and reaching the browser as a `ProviderError` with the `HTTP` code.\n */\nexport const UNAUTHORIZED_RELAY_STATUS = 401\n\n/**\n * Names the status a relay answers when the upstream provider call cannot be constructed — `502`,\n * carried with no body after `provider.stream` was entered and threw before returning its\n * iterator.\n */\nexport const UPSTREAM_RELAY_STATUS = 502\n\n/**\n * Names the status a relay answers for a body that is missing, unreadable, or rejected by\n * `providerRequestContract` — `400`, carried with no body and reaching the browser as a\n * `ProviderError` with the `HTTP` code.\n */\nexport const INVALID_RELAY_STATUS = 400\n\n/**\n * Names the status a relay answers for a request body at or above its byte budget — `413`,\n * carried with no body and answered for an aborted inbound read as well.\n */\nexport const OVERSIZED_RELAY_STATUS = 413\n\n/** Names the System One decision endpoint shared by compatible servers. */\nexport const SYSTEM_ONE_PATH = '/v1/systemone'\n","import type {\n\tJudgeErrorCode,\n\tProviderErrorCode,\n\tProviderErrorOptions,\n\tProviderResult,\n} from './types.js'\nimport {\n\tINTRINSICS,\n\tholds,\n\tisObject,\n\tisFunction,\n\tisNumber,\n\tisString,\n\tisBoolean,\n\tarrayOf,\n} from '@orkestrel/contract'\n\n/**\n * Reports a provider stream cancelled mid-flight by its bound signal — thrown by the\n * `stream` method of a {@link ProviderInterface}, carrying the {@link ProviderResult} assembled from\n * whatever streamed before the cancel and the machine-readable `code` `'ABORT'`.\n *\n * @remarks\n * Lets a caller recover the partial content (and any tool calls / usage seen so far)\n * on cancellation: `catch` the throw, narrow with {@link isProviderAbortError}, and\n * read `partial`. `code` is the machine-readable condition (`'ABORT'` — the only one this\n * error reports), so a `catch` branches on it rather than on the message string. `cause`\n * holds the failure the cancel superseded when a throw raced the abort — the wire decoder's\n * {@link ProviderError}, say — and is undefined when the cancel was the only failure.\n */\nexport class ProviderAbortError extends Error {\n\t/** Names the machine-readable condition — `'ABORT'`: a stream cancelled mid-flight. */\n\treadonly code = 'ABORT' as const\n\treadonly partial: ProviderResult\n\n\tconstructor(partial: ProviderResult, options?: ErrorOptions) {\n\t\tsuper('provider stream aborted', options)\n\t\tthis.name = 'ProviderAbortError'\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/agent.ProviderAbortError'), { value: this })\n\t\tthis.partial = partial\n\t}\n}\n\n/**\n * Narrows an unknown caught value to a {@link ProviderAbortError} through its identity brand and declared members, so a\n * `catch` can recover its `partial` result.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns True if `value` is a {@link ProviderAbortError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tfor await (const delta of provider.stream(messages, signal)) render(delta)\n * } catch (error) {\n * \tif (isProviderAbortError(error)) keep(error.partial.content) // recover partial\n * }\n * ```\n */\nexport function isProviderAbortError(value: unknown): value is ProviderAbortError {\n\treturn holds(() => {\n\t\tif (\n\t\t\t!(\n\t\t\t\tvalue instanceof Error &&\n\t\t\t\tINTRINSICS.prototype(value) !== Error.prototype &&\n\t\t\t\tINTRINSICS.describe(value, Symbol.for('@orkestrel/agent.ProviderAbortError'))?.value ===\n\t\t\t\t\tvalue\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\tconst code = INTRINSICS.reflect.read(value, 'code')\n\t\tif (!(code === 'ABORT')) return false\n\t\tconst partial = INTRINSICS.reflect.read(value, 'partial')\n\t\tif (!(isObject(partial) || isFunction(partial))) return false\n\t\tconst usage = INTRINSICS.reflect.read(partial, 'usage')\n\t\tconst tools = INTRINSICS.reflect.read(partial, 'tools')\n\t\treturn (\n\t\t\tisString(INTRINSICS.reflect.read(partial, 'content')) &&\n\t\t\t(INTRINSICS.reflect.read(partial, 'thinking') === undefined ||\n\t\t\t\tisString(INTRINSICS.reflect.read(partial, 'thinking'))) &&\n\t\t\t(INTRINSICS.reflect.read(partial, 'truncated') === undefined ||\n\t\t\t\tisBoolean(INTRINSICS.reflect.read(partial, 'truncated'))) &&\n\t\t\t(usage === undefined ||\n\t\t\t\t((isObject(usage) || isFunction(usage)) &&\n\t\t\t\t\t['prompt', 'completion', 'total'].every((key) =>\n\t\t\t\t\t\tisNumber(INTRINSICS.reflect.read(usage, key)),\n\t\t\t\t\t))) &&\n\t\t\t(tools === undefined ||\n\t\t\t\tarrayOf(\n\t\t\t\t\t(tool: unknown) =>\n\t\t\t\t\t\t(isObject(tool) || isFunction(tool)) &&\n\t\t\t\t\t\tisString(INTRINSICS.reflect.read(tool, 'id')) &&\n\t\t\t\t\t\tisString(INTRINSICS.reflect.read(tool, 'name')) &&\n\t\t\t\t\t\t(isObject(INTRINSICS.reflect.read(tool, 'arguments')) ||\n\t\t\t\t\t\t\tisFunction(INTRINSICS.reflect.read(tool, 'arguments'))),\n\t\t\t\t)(tools))\n\t\t)\n\t})\n}\n\n/**\n * Reports a coded provider failure with its HTTP status and underlying cause when available.\n *\n * @remarks\n * The provider base throws this error for a non-OK HTTP response, a missing response\n * body, or a missing settled result when strict assembly is enabled. Concrete wire\n * decoders also use it for malformed records and relayed provider failures.\n * `status` is present only for an `HTTP` failure; other codes leave it undefined.\n */\nexport class ProviderError extends Error {\n\t/** Names the machine-readable condition — `'HTTP'`: a non-OK response, including a relay refusing an oversized request with 413; `'PROTOCOL'`: a missing response body, a malformed wire record, or a strict stream with no settled result; `'PROVIDER'`: an upstream failure carried by a relay error record. */\n\treadonly code: ProviderErrorCode\n\t/** Holds the response status for an HTTP failure, or undefined for other codes. */\n\treadonly status: number | undefined\n\n\tconstructor(code: ProviderErrorCode, message: string, options?: ProviderErrorOptions) {\n\t\tsuper(message, options)\n\t\tthis.name = 'ProviderError'\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/agent.ProviderError'), { value: this })\n\t\tthis.code = code\n\t\tthis.status = options?.status\n\t}\n}\n\n/**\n * Narrows a caught value to the provider failure class through its identity brand and declared members.\n *\n * @param value - The caught value\n * @returns True if the value is a provider failure; false otherwise\n * @example\n * ```ts\n * isProviderError(new ProviderError('HTTP', 'unavailable', { status: 503 })) // true\n * ```\n */\nexport function isProviderError(value: unknown): value is ProviderError {\n\treturn holds(() => {\n\t\tif (\n\t\t\t!(\n\t\t\t\tvalue instanceof Error &&\n\t\t\t\tINTRINSICS.prototype(value) !== Error.prototype &&\n\t\t\t\tINTRINSICS.describe(value, Symbol.for('@orkestrel/agent.ProviderError'))?.value === value\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\tconst code = INTRINSICS.reflect.read(value, 'code')\n\t\tif (!(code === 'HTTP' || code === 'PROTOCOL' || code === 'PROVIDER')) return false\n\t\tconst status = INTRINSICS.reflect.read(value, 'status')\n\t\treturn status === undefined || isNumber(status)\n\t})\n}\n\n/**\n * Reports a coded judge failure with its HTTP status and underlying cause when available.\n *\n * @remarks\n * The judge engine throws this error for a non-OK HTTP response, a missing or unparsable\n * response body, and a request refused before inference. Concrete wire decoders also use it for\n * a response they cannot read and for a wire limit. `status` is present only for an `HTTP`\n * failure; other codes leave it undefined.\n */\nexport class JudgeError extends Error {\n\t/** Names the machine-readable condition — `'HTTP'`: a non-OK response; `'PROTOCOL'`: a missing, unparsable, or unreadable response body; `'QUESTION'`: a request refused before inference. */\n\treadonly code: JudgeErrorCode\n\t/** Holds the response status for an HTTP failure, or undefined for other codes. */\n\treadonly status: number | undefined\n\n\tconstructor(code: JudgeErrorCode, message: string, options?: ProviderErrorOptions) {\n\t\tsuper(message, options)\n\t\tthis.name = 'JudgeError'\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/agent.JudgeError'), { value: this })\n\t\tthis.code = code\n\t\tthis.status = options?.status\n\t}\n}\n\n/**\n * Narrows a caught value to the judge failure class through its identity brand and declared members.\n *\n * @param value - The caught value\n * @returns True if the value is a {@link JudgeError}; false otherwise\n * @example\n * ```ts\n * isJudgeError(new JudgeError('HTTP', 'judge error: 429', { status: 429 })) // true\n * ```\n */\nexport function isJudgeError(value: unknown): value is JudgeError {\n\treturn holds(() => {\n\t\tif (\n\t\t\t!(\n\t\t\t\tvalue instanceof Error &&\n\t\t\t\tINTRINSICS.prototype(value) !== Error.prototype &&\n\t\t\t\tINTRINSICS.describe(value, Symbol.for('@orkestrel/agent.JudgeError'))?.value === value\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\tconst code = INTRINSICS.reflect.read(value, 'code')\n\t\tif (!(code === 'HTTP' || code === 'PROTOCOL' || code === 'QUESTION')) return false\n\t\tconst status = INTRINSICS.reflect.read(value, 'status')\n\t\treturn status === undefined || isNumber(status)\n\t})\n}\n","import type { ContractShape } from '@orkestrel/contract'\nimport {\n\tarrayShape,\n\tbooleanShape,\n\tjsonShape,\n\tliteralShape,\n\tnumberShape,\n\tobjectShape,\n\toptionalShape,\n\trecordShape,\n\tstringShape,\n\tunionShape,\n} from '@orkestrel/contract'\nimport { messageShape, toolCallShape } from '../shapers.js'\n\n/**\n * Describes a provider request's JSON wire projection.\n *\n * @remarks\n * The wire is strictly narrower than `ProviderRequest`: non-JSON arguments, parameters,\n * or schema members are refused. Execution context stays local; the guard refuses\n * extra members, and the parser drops them.\n */\nexport const providerRequestShape = objectShape({\n\tmessages: arrayShape(messageShape),\n\ttools: optionalShape(\n\t\tarrayShape(\n\t\t\tobjectShape({\n\t\t\t\tname: stringShape(),\n\t\t\t\tdescription: optionalShape(stringShape()),\n\t\t\t\tparameters: optionalShape(recordShape(jsonShape())),\n\t\t\t}),\n\t\t),\n\t),\n\toptions: optionalShape(\n\t\tobjectShape({\n\t\t\tthink: optionalShape(booleanShape()),\n\t\t\tschema: optionalShape(recordShape(jsonShape())),\n\t\t}),\n\t),\n}) satisfies ContractShape\n\n/**\n * Describes a provider result's JSON wire projection.\n *\n * @remarks\n * The wire is strictly narrower than `ProviderResult`: non-JSON call arguments are\n * refused. Execution context stays local; the guard refuses extra members, and the parser drops them.\n */\nexport const providerResultShape = objectShape({\n\tcontent: stringShape(),\n\tthinking: optionalShape(stringShape()),\n\ttools: optionalShape(arrayShape(toolCallShape)),\n\tusage: optionalShape(\n\t\tobjectShape({\n\t\t\tprompt: numberShape(),\n\t\t\tcompletion: numberShape(),\n\t\t\ttotal: numberShape(),\n\t\t}),\n\t),\n\ttruncated: optionalShape(booleanShape()),\n}) satisfies ContractShape\n\n/**\n * Describes the channel-discriminated JSON relay wire projection.\n *\n * @remarks\n * The wire is strictly narrower than `RelayFrame` through its `result` and `partial`\n * fields: non-JSON arguments are refused. Execution context stays local; the guard\n * refuses extra members, and the parser drops them.\n */\nexport const relayFrameShape = unionShape(\n\tobjectShape({ channel: literalShape(['content', 'thinking']), text: stringShape() }),\n\tobjectShape({ channel: literalShape(['result']), result: providerResultShape }),\n\tobjectShape({ channel: literalShape(['abort']), partial: providerResultShape }),\n\tobjectShape({ channel: literalShape(['error']), message: stringShape() }),\n) satisfies ContractShape\n","import { createContract } from '@orkestrel/contract'\nimport { providerRequestShape, providerResultShape, relayFrameShape } from './shapers.js'\n\n/** Validates and projects provider requests at a JSON wire boundary. */\nexport const providerRequestContract = createContract(providerRequestShape)\n\n/** Validates and projects provider results at a JSON wire boundary. */\nexport const providerResultContract = createContract(providerResultShape)\n\n/** Validates and projects channel-discriminated relay frames at a JSON wire boundary. */\nexport const relayFrameContract = createContract(relayFrameShape)\n","import type {\n\tFailureRead,\n\tProviderOptions,\n\tProviderRequest,\n\tProviderResult,\n\tReading,\n\tSystemOneAnswer,\n\tSystemOneQuestion,\n\tSystemOneUsage,\n\tTextRead,\n} from './types.js'\nimport type { JudgeAnswer, JudgeQuestion, JudgeResult, Refusal } from '../types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport type { ToolCall } from '@orkestrel/tool'\nimport { isTokenUsage } from '@orkestrel/budget'\nimport { attempt, boundsOf, isArray, isNumber } from '@orkestrel/contract'\nimport { JudgeError } from './errors.js'\nimport { MAX_ERROR_BODY_LENGTH } from './constants.js'\nimport { sanitizeUsage, sumUsage } from '../helpers.js'\n\n/**\n * Assembles a provider result with only populated optional fields.\n *\n * @param content - The authoritative answer\n * @param thinking - The joined reasoning\n * @param tools - The accumulated calls\n * @param usage - The reported token usage\n * @param truncated - Whether the model stopped at its own limit, or undefined when the wire did not report it\n * @returns The assembled result\n * @example\n * ```ts\n * buildProviderResult('ok', '', [], undefined, undefined) // { content: 'ok' }\n * ```\n */\nexport function buildProviderResult(\n\tcontent: string,\n\tthinking: string,\n\ttools: readonly ToolCall[],\n\tusage: TokenUsage | undefined,\n\ttruncated: boolean | undefined,\n): ProviderResult {\n\treturn {\n\t\tcontent,\n\t\t...(thinking.length === 0 ? {} : { thinking }),\n\t\t...(tools.length === 0 ? {} : { tools }),\n\t\t...(usage === undefined ? {} : { usage }),\n\t\t...(truncated === undefined ? {} : { truncated }),\n\t}\n}\n\n/**\n * Cancels a stream reader and releases its lock, swallowing a cancellation failure so the\n * caller's own outcome stands.\n *\n * @param reader - The reader to cancel and release\n * @returns A promise that settles after the lock is released\n *\n * @example\n * ```ts\n * const body = new Response('answer').body\n * if (body !== null) await releaseReader(body.getReader())\n * ```\n */\nexport async function releaseReader(\n\treader: ReadableStreamDefaultReader<Uint8Array>,\n): Promise<void> {\n\ttry {\n\t\tawait reader.cancel()\n\t} catch {\n\t\t// Preserve the caller's outcome when the source refuses cancellation.\n\t} finally {\n\t\treader.releaseLock()\n\t}\n}\n\n/**\n * Arms signal propagation to a byte reader and returns the controller that removes the listener.\n *\n * @param reader - The reader whose pending read an abort releases\n * @param signal - The optional caller signal\n * @returns The listener cleanup controller after any already-aborted cancellation settles\n * @example\n * ```ts\n * const reader = new ReadableStream<Uint8Array>().getReader()\n * const cleanup = await armReaderAbort(reader, new AbortController().signal)\n * cleanup.abort()\n * await releaseReader(reader)\n * ```\n */\nexport async function armReaderAbort(\n\treader: ReadableStreamDefaultReader<Uint8Array>,\n\tsignal: AbortSignal | undefined,\n): Promise<AbortController> {\n\tconst cleanup = new AbortController()\n\tsignal?.addEventListener(\n\t\t'abort',\n\t\t() => {\n\t\t\tvoid reader.cancel(signal.reason).catch(() => {\n\t\t\t\t// Preserve the caller's outcome when source cancellation rejects.\n\t\t\t})\n\t\t},\n\t\t{ once: true, signal: cleanup.signal },\n\t)\n\tif (signal?.aborted) {\n\t\tawait reader.cancel(signal.reason).catch(() => {\n\t\t\t// An already-aborted read retains the same cancellation contract.\n\t\t})\n\t\tcleanup.abort()\n\t}\n\treturn cleanup\n}\n\n/**\n * Reads a bounded HTTP failure excerpt and preserves an unreadable body's cause.\n *\n * @remarks\n * Both HTTP engines, the provider and the judge, translate a non-OK response here and throw\n * their own coded error from the result. When the excerpt is read and `signal` has aborted, the\n * abort is the call's outcome, so the signal's reason is thrown. When the body read fails, the\n * failure is returned as `cause` whether or not `signal` has aborted, so a read that raced the\n * abort stays recorded on the error the caller throws.\n *\n * @param response - The failed HTTP response\n * @param prefix - The error taxonomy prefix, including its trailing colon\n * @param signal - The call's combined caller and deadline signal\n * @returns The status message with any excerpt, the response status, and any body-read failure\n * @throws Thrown when the excerpt is read after `signal` aborts, with the signal's reason\n * @example\n * ```ts\n * await readFailure(new Response('unavailable', { status: 503 }), 'provider error:', new AbortController().signal)\n * // { message: 'provider error: 503 - unavailable', status: 503 }\n * ```\n */\nexport async function readFailure(\n\tresponse: Response,\n\tprefix: string,\n\tsignal: AbortSignal,\n): Promise<FailureRead> {\n\tconst status = response.status\n\tconst body = response.body\n\tif (body === null) {\n\t\tsignal.throwIfAborted()\n\t\treturn { message: `${prefix} ${status}`, status }\n\t}\n\treturn readText(body, MAX_ERROR_BODY_LENGTH, signal).then(\n\t\t(read) => {\n\t\t\tsignal.throwIfAborted()\n\t\t\treturn { message: `${prefix} ${status}${read.text === '' ? '' : ` - ${read.text}`}`, status }\n\t\t},\n\t\t(cause: unknown) => ({\n\t\t\tmessage: `${prefix} ${status} - (error body unavailable)`,\n\t\t\tstatus,\n\t\t\t...(cause === undefined ? {} : { cause }),\n\t\t}),\n\t)\n}\n\n/**\n * Reads a UTF-8 prefix of a byte stream and cancels its remainder.\n *\n * @remarks\n * The `limit` parameter bounds bytes passed to the decoder, including a partial final\n * character. An omitted limit reads to completion. A source may deliver a chunk larger\n * than the remaining limit; its unused bytes are discarded without decoding.\n * The read can overshoot by one source chunk. An abort leaves completion false.\n *\n * @param body - The readable byte stream\n * @param limit - The maximum byte prefix, or undefined for the complete stream\n * @param signal - The optional cancellation bound; abort returns the decoded prefix\n * @returns The decoded prefix and whether EOF occurred within the byte budget\n * @example\n * ```ts\n * import { readText } from '@orkestrel/agent'\n *\n * const body = new Response('answer').body\n * if (body !== null) await readText(body, 3) // { text: 'ans', complete: false }\n * ```\n */\nexport async function readText(\n\tbody: ReadableStream<Uint8Array>,\n\tlimit?: number,\n\tsignal?: AbortSignal,\n): Promise<TextRead> {\n\tconst reader = body.getReader()\n\tconst decoder = new TextDecoder()\n\ttry {\n\t\tconst cleanup = await armReaderAbort(reader, signal)\n\t\ttry {\n\t\t\t// Each step's decoded text and the byte budget left after it: the next read's budget is the\n\t\t\t// latest step's, and the text joins every step.\n\t\t\tconst steps: Array<{ readonly text: string; readonly remaining: number }> = []\n\t\t\tfor (;;) {\n\t\t\t\tconst remaining = steps.at(-1)?.remaining ?? limit ?? Infinity\n\t\t\t\tconst step = remaining > 0 && signal?.aborted !== true ? await reader.read() : undefined\n\t\t\t\tif (step === undefined || signal?.aborted === true || step.done) {\n\t\t\t\t\treturn {\n\t\t\t\t\t\ttext: steps.map((one) => one.text).join('') + decoder.decode(),\n\t\t\t\t\t\tcomplete: step?.done === true && signal?.aborted !== true,\n\t\t\t\t\t}\n\t\t\t\t}\n\t\t\t\tconst bytes = step.value.subarray(0, remaining)\n\t\t\t\tsteps.push({\n\t\t\t\t\ttext: decoder.decode(bytes, { stream: true }),\n\t\t\t\t\tremaining: remaining - bytes.byteLength,\n\t\t\t\t})\n\t\t\t}\n\t\t} finally {\n\t\t\tcleanup.abort()\n\t\t}\n\t} finally {\n\t\tawait releaseReader(reader)\n\t}\n}\n\n/**\n * Decodes UTF-8 chunks with a final flush and releases the stream on every exit.\n *\n * @param body - The readable byte stream\n * @param signal - The optional cancellation bound; abort ends iteration without further chunks\n * @returns Decoded text chunks, including a held decoder tail\n * @example\n * ```ts\n * const body = new Response('answer').body\n * if (body !== null) for await (const chunk of readChunks(body)) render(chunk)\n * ```\n */\nexport async function* readChunks(\n\tbody: ReadableStream<Uint8Array>,\n\tsignal?: AbortSignal,\n): AsyncGenerator<string> {\n\tconst reader = body.getReader()\n\tconst decoder = new TextDecoder()\n\ttry {\n\t\tconst cleanup = await armReaderAbort(reader, signal)\n\t\ttry {\n\t\t\tif (signal?.aborted) return\n\t\t\tfor (;;) {\n\t\t\t\tconst step = await reader.read()\n\t\t\t\tif (signal?.aborted) return\n\t\t\t\tif (step.done) break\n\t\t\t\tconst chunk = decoder.decode(step.value, { stream: true })\n\t\t\t\tif (chunk.length > 0) yield chunk\n\t\t\t}\n\t\t\tconst tail = decoder.decode()\n\t\t\tif (tail.length > 0) yield tail\n\t\t} finally {\n\t\t\tcleanup.abort()\n\t\t}\n\t} finally {\n\t\tawait releaseReader(reader)\n\t}\n}\n\n/**\n * Derives the winner, its probability, the published confidence, and a score answer's expected\n * level from a judge answer's distribution.\n *\n * @remarks\n * The winner is the first strictly greatest candidate in enumeration order: an option name in\n * criteria order, a level index, or `'false'` then `'true'` for a noul, so a noul of exactly 0.5\n * names `'false'`. Confidence follows the TypeSafe formulas, whatever confidence a server sent: a\n * choice reads `(max(p) - 1/n) / (1 - 1/n)`, a noul reads `|2p - 1|` (the choice formula at\n * n = 2), and a score reads `max(0, 1 - spread / even_spread)`, where `spread` sums each level's\n * probability times its distance from the winning level and `even_spread` is the mean distance\n * from the middle level. `score` is the expected level `sum(i * p_i)` and is set only for a score\n * answer.\n *\n * @param answer - The answer whose distribution is read\n * @returns The derived measures\n * @throws JudgeError Thrown when a choice or score answer has fewer than 2 candidates\n * (code `PROTOCOL`), because the confidence formulas divide by the candidate count\n * @example\n * ```ts\n * computeReading({ form: 'choice', probabilities: { billing: 0.88, technical: 0.12, sales: 0 } })\n * // { winner: 'billing', probability: 0.88, confidence: 0.82 } to 2 decimals\n * computeReading({ form: 'score', probabilities: [0, 0.57, 0.43] })\n * // { winner: '1', probability: 0.57, confidence: 0.355, score: 1.43 } to 3 decimals\n * computeReading({ form: 'noul', noul: 0.5 }) // { winner: 'false', probability: 0.5, confidence: 0 }\n * ```\n */\nexport function computeReading(answer: JudgeAnswer): Reading {\n\tif (answer.form === 'noul') {\n\t\tconst yes = answer.noul > 0.5\n\t\treturn {\n\t\t\twinner: yes ? 'true' : 'false',\n\t\t\tprobability: yes ? answer.noul : 1 - answer.noul,\n\t\t\tconfidence: Math.abs(2 * answer.noul - 1),\n\t\t}\n\t}\n\tconst candidates: ReadonlyArray<readonly [string, number]> =\n\t\tanswer.form === 'choice'\n\t\t\t? Object.entries(answer.probabilities)\n\t\t\t: answer.probabilities.map((probability, level) => [String(level), probability])\n\tconst count = candidates.length\n\tif (count < 2) {\n\t\tthrow new JudgeError('PROTOCOL', 'judge error: an answer needs at least 2 candidates')\n\t}\n\t// The first strictly greatest candidate wins a tie. The spread visits a hole in a score\n\t// distribution as an undefined candidate, which the destructuring refuses; `reduce` skips it.\n\tconst { winner, index, probability } = [...candidates].reduce(\n\t\t(top, [name, candidate], position) =>\n\t\t\tcandidate > top.probability ? { winner: name, index: position, probability: candidate } : top,\n\t\t{ winner: '', index: 0, probability: -Infinity },\n\t)\n\tif (answer.form === 'choice') {\n\t\treturn { winner, probability, confidence: (probability - 1 / count) / (1 - 1 / count) }\n\t}\n\tconst spread = answer.probabilities.reduce(\n\t\t(sum, candidate, level) => sum + candidate * Math.abs(level - index),\n\t\t0,\n\t)\n\tconst even = answer.probabilities.reduce(\n\t\t(sum, _candidate, level) => sum + Math.abs(level - (count - 1) / 2),\n\t\t0,\n\t)\n\tconst score = answer.probabilities.reduce((sum, candidate, level) => sum + level * candidate, 0)\n\treturn { winner, probability, confidence: Math.max(0, 1 - spread / (even / count)), score }\n}\n\n/**\n * Merges the results of a judge request's calls into one result.\n *\n * @remarks\n * Pure and total. Answers and refusals are joined by question id; `refusals` is omitted when no\n * call refused a question. Each call's usage passes through {@link sanitizeUsage} and the totals\n * add through {@link sumUsage}; `usage` is omitted when no call reported one. The model is the\n * first call's, or the given model when the list is empty, as the empty partial of a cancel\n * before the first call requires.\n *\n * @param model - The judge's configured model, reported when no call completed\n * @param results - The completed calls' results in call order\n * @returns The merged result\n * @example\n * ```ts\n * buildJudgeResult('tev1:0.8b', []) // { model: 'tev1:0.8b', answers: {} }\n * buildJudgeResult('jev-latest', [\n * \t{ model: 'jev-1.13.0', answers: { urgent: { form: 'noul', noul: 0.95 } } },\n * \t{ model: 'jev-1.13.0', answers: {}, refusals: { team: { missing: ['sales'] } } },\n * ])\n * // { model: 'jev-1.13.0', answers: { urgent: ... }, refusals: { team: { missing: ['sales'] } } }\n * ```\n */\nexport function buildJudgeResult(model: string, results: readonly JudgeResult[]): JudgeResult {\n\t// The spread visits a hole in `results` as an undefined result, as iteration does; `reduce` skips it.\n\tconst calls = [...results]\n\tconst answers = calls.reduce<Readonly<Record<string, JudgeAnswer>>>(\n\t\t(merged, result) => ({ ...merged, ...result.answers }),\n\t\t{},\n\t)\n\tconst refusals = calls.reduce<Readonly<Record<string, Refusal>>>(\n\t\t(merged, result) => ({ ...merged, ...result.refusals }),\n\t\t{},\n\t)\n\tconst usage = calls.reduce<TokenUsage | undefined>(\n\t\t(total, result) =>\n\t\t\tresult.usage === undefined ? total : sumUsage(total, sanitizeUsage(result.usage)),\n\t\tundefined,\n\t)\n\treturn {\n\t\tmodel: results[0]?.model ?? model,\n\t\tanswers,\n\t\t...(Object.keys(refusals).length === 0 ? {} : { refusals }),\n\t\t...(usage === undefined ? {} : { usage }),\n\t}\n}\n\n/**\n * Builds a request's JSON headers, awaiting the caller's header hook inside the call's\n * cancellation bound.\n *\n * @remarks\n * The headers start with `Content-Type: application/json`; each entry the hook returns is set\n * over them, so the hook overrides the content type only when it returns that header. The hook\n * receives `signal` and races its abort, and the abort listener is removed on every exit. Both\n * HTTP engines, the provider and the judge, read their headers here.\n *\n * @param hook - The caller's header hook, or undefined for the JSON content type alone\n * @param signal - The call's combined caller and deadline signal\n * @returns The request headers\n * @throws Thrown when the signal aborts before the hook settles, with the signal's reason, and\n * when the hook throws or rejects, with the hook's own failure\n * @example\n * ```ts\n * const signal = new AbortController().signal\n * // API_KEY stands for the server's bearer key.\n * const headers = await buildProviderHeaders(() => ({ authorization: 'Bearer API_KEY' }), signal)\n * headers.get('authorization') // 'Bearer API_KEY'\n * headers.get('content-type') // 'application/json'\n * ```\n */\nexport async function buildProviderHeaders(\n\thook: ProviderOptions['headers'],\n\tsignal: AbortSignal,\n): Promise<Headers> {\n\tconst headers = new Headers({ 'Content-Type': 'application/json' })\n\tif (hook === undefined) return headers\n\tconst cleanup = new AbortController()\n\tconst aborted = Promise.withResolvers<never>()\n\tsignal.addEventListener('abort', () => aborted.reject(signal.reason), {\n\t\tonce: true,\n\t\tsignal: cleanup.signal,\n\t})\n\ttry {\n\t\tsignal.throwIfAborted()\n\t\tconst entries = await Promise.race([\n\t\t\tPromise.resolve().then(() => hook(signal)),\n\t\t\taborted.promise,\n\t\t])\n\t\tfor (const [key, value] of Object.entries(entries)) headers.set(key, value)\n\t\treturn headers\n\t} finally {\n\t\tcleanup.abort()\n\t}\n}\n\n/**\n * Projects a provider request onto the declared members the relay wire carries.\n *\n * @remarks\n * Each message keeps `id`, `role`, `content`, and any `calls`, `call`, `images`, and `thinking`;\n * each call keeps only `id`, `name`, and `arguments`, so a local execution context never reaches\n * the wire. Each tool keeps `name` and any `description` and `parameters`, and the options keep\n * any `think` and `schema`. An absent member stays absent. The projection shares every nested\n * value with the input rather than copying it, so the caller snapshots and validates the result;\n * a throwing getter propagates its failure.\n *\n * @param request - The domain conversation and call configuration\n * @returns The request with only the members the relay wire declares\n * @example\n * ```ts\n * requestToRelay({\n * \tmessages: [{ id: 'turn-1', role: 'user', content: 'Track BW-5512' }],\n * \toptions: { think: false },\n * })\n * // { messages: [{ id: 'turn-1', role: 'user', content: 'Track BW-5512' }], options: { think: false } }\n * ```\n */\nexport function requestToRelay(request: ProviderRequest): ProviderRequest {\n\treturn {\n\t\tmessages: request.messages.map((message) => ({\n\t\t\tid: message.id,\n\t\t\trole: message.role,\n\t\t\tcontent: message.content,\n\t\t\t...(message.calls === undefined\n\t\t\t\t? {}\n\t\t\t\t: {\n\t\t\t\t\t\tcalls: message.calls.map((call) => ({\n\t\t\t\t\t\t\tid: call.id,\n\t\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\t\targuments: call.arguments,\n\t\t\t\t\t\t})),\n\t\t\t\t\t}),\n\t\t\t...(message.call === undefined ? {} : { call: message.call }),\n\t\t\t...(message.images === undefined ? {} : { images: message.images }),\n\t\t\t...(message.thinking === undefined ? {} : { thinking: message.thinking }),\n\t\t})),\n\t\t...(request.tools === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\ttools: request.tools.map((tool) => ({\n\t\t\t\t\t\tname: tool.name,\n\t\t\t\t\t\t...(tool.description === undefined ? {} : { description: tool.description }),\n\t\t\t\t\t\t...(tool.parameters === undefined ? {} : { parameters: tool.parameters }),\n\t\t\t\t\t})),\n\t\t\t\t}),\n\t\t...(request.options === undefined\n\t\t\t? {}\n\t\t\t: {\n\t\t\t\t\toptions: {\n\t\t\t\t\t\t...(request.options.think === undefined ? {} : { think: request.options.think }),\n\t\t\t\t\t\t...(request.options.schema === undefined ? {} : { schema: request.options.schema }),\n\t\t\t\t\t},\n\t\t\t\t}),\n\t}\n}\n\n/**\n * Projects a judge question onto the System One wire while preserving omitted members.\n *\n * @param question - The domain question to send\n * @returns The wire question with `type` replacing `form`\n * @example\n * ```ts\n * questionToSystemOne({ form: 'noul' }) // { type: 'noul' }\n * ```\n */\nexport function questionToSystemOne(question: JudgeQuestion): SystemOneQuestion {\n\treturn {\n\t\ttype: question.form,\n\t\t...(question.instructions === undefined ? {} : { instructions: question.instructions }),\n\t\t...(question.criteria === undefined ? {} : { criteria: question.criteria }),\n\t}\n}\n\n/**\n * Extracts a System One distribution in question criteria order and drops server measures.\n *\n * @remarks\n * Every requested candidate must have a finite probability in [0, 1]; the helper checks each\n * requested candidate itself and reads no other member. Score maps and arrays project onto the\n * requested levels. Additional candidates are ignored, sums are unconstrained, and probabilities\n * are preserved without normalization.\n *\n * @param answer - The wire answer to decode\n * @param question - The question defining the form and candidate order\n * @returns The domain answer, or undefined for a mismatched form or a requested candidate whose\n * probability is missing, not finite, or outside [0, 1]\n * @example\n * ```ts\n * extractSystemOneAnswer({ type: 'noul', noul: 0.9 }, { form: 'noul' })\n * // { form: 'noul', noul: 0.9 }\n * ```\n */\nexport function extractSystemOneAnswer(\n\tanswer: SystemOneAnswer,\n\tquestion: JudgeQuestion,\n): JudgeAnswer | undefined {\n\tconst bounded = boundsOf(0, 1)\n\tif (answer.type === 'noul' && question.form === 'noul') {\n\t\treturn bounded(answer.noul) ? { form: 'noul', noul: answer.noul } : undefined\n\t}\n\tif (answer.type === 'choice' && question.form === 'choice') {\n\t\tconst labels = Object.keys(question.criteria)\n\t\tconst entries = labels.flatMap((label) => {\n\t\t\tconst probability = Object.hasOwn(answer.probabilities, label)\n\t\t\t\t? answer.probabilities[label]\n\t\t\t\t: undefined\n\t\t\treturn bounded(probability) ? [[label, probability] as const] : []\n\t\t})\n\t\treturn entries.length === labels.length\n\t\t\t? { form: 'choice', probabilities: Object.fromEntries(entries) }\n\t\t\t: undefined\n\t}\n\tif (answer.type !== 'score' || question.form !== 'score') return undefined\n\t// `keys()` visits a hole in the criteria list too, so a hole is a requested level.\n\tconst levels = [...question.criteria.keys()]\n\tconst probabilities = levels.flatMap((level) => {\n\t\tconst probability = Object.hasOwn(answer.probabilities, level)\n\t\t\t? isArray(answer.probabilities)\n\t\t\t\t? answer.probabilities[level]\n\t\t\t\t: answer.probabilities[String(level)]\n\t\t\t: undefined\n\t\treturn bounded(probability) ? [probability] : []\n\t})\n\treturn probabilities.length === levels.length ? { form: 'score', probabilities } : undefined\n}\n\n/**\n * Maps complete System One token counts onto validated token usage.\n *\n * @param usage - The optional wire token counts\n * @returns Token usage, or undefined for missing, null, negative, or non-finite counts\n * @example\n * ```ts\n * extractSystemOneUsage({ input_tokens: 975, output_tokens: 4 })\n * // { prompt: 975, completion: 4, total: 979 }\n * ```\n */\nexport function extractSystemOneUsage(usage: SystemOneUsage | undefined): TokenUsage | undefined {\n\tconst extracted = attempt(() => {\n\t\tif (usage === undefined) return undefined\n\t\tconst { input_tokens: prompt, output_tokens: completion } = usage\n\t\tif (!isNumber(prompt) || !isNumber(completion)) return undefined\n\t\tconst result = { prompt, completion, total: prompt + completion }\n\t\treturn isTokenUsage(result) ? result : undefined\n\t})\n\treturn extracted.success ? extracted.value : undefined\n}\n","import type { ProviderDelta, ProviderResult, RelayFrame, RelayStreamOptions } from './types.js'\nimport type { ThinkingReplay } from '../types.js'\nimport { RELAY_CONTENT_TYPE, RELAY_PROVIDER_MESSAGE } from './constants.js'\nimport { ProviderError, isProviderAbortError } from './errors.js'\nimport { relayFrameContract } from './contracts.js'\nimport { stripThinking } from '../helpers.js'\n\n/**\n * Streams a provider call as validated NDJSON frames under response backpressure.\n *\n * @remarks\n * Cancellation aborts upstream before returning its iterator. Request listeners are\n * released on settlement. Unexpected provider failures carry a fixed public message.\n * An inbound abort leaves the response body neither closed nor errored — a server runtime\n * cancels that body when the client disconnects — so a consumer that aborts the inbound\n * signal itself must cancel the body rather than keep reading it.\n *\n * @example\n * ```ts\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { RelayStream } from '@orkestrel/agent'\n *\n * export function respond(provider: ProviderInterface, signal: AbortSignal): Response {\n * \treturn new RelayStream({ provider, request: { messages: [] }, signal }).response\n * }\n * ```\n */\nexport class RelayStream {\n\treadonly #replay: ThinkingReplay\n\treadonly #upstream = new AbortController()\n\treadonly #encoder = new TextEncoder()\n\treadonly #iterator: AsyncGenerator<ProviderDelta, ProviderResult>\n\treadonly #signal: AbortSignal\n\treadonly #listener: () => void\n\treadonly #response: Response\n\t#settled = false\n\n\tconstructor(options: RelayStreamOptions) {\n\t\tthis.#replay = options.provider.replay ?? 'none'\n\t\tthis.#signal = options.signal\n\t\tthis.#listener = this.#abort.bind(this)\n\t\tif (this.#signal.aborted) this.#abortProvider()\n\t\tthis.#iterator = options.provider.stream(\n\t\t\tstripThinking(options.request.messages, this.#replay),\n\t\t\tthis.#upstream.signal,\n\t\t\toptions.request.tools,\n\t\t\toptions.request.options,\n\t\t)\n\t\tthis.#signal.addEventListener('abort', this.#listener, { once: true })\n\t\tthis.#response = new Response(\n\t\t\tnew ReadableStream<Uint8Array>({\n\t\t\t\tpull: this.#pull.bind(this),\n\t\t\t\tcancel: this.#abort.bind(this),\n\t\t\t}),\n\t\t\t{ headers: { 'content-type': RELAY_CONTENT_TYPE, 'cache-control': 'no-store' } },\n\t\t)\n\t}\n\n\t/** Exposes the pull-driven response for the provider call. */\n\tget response(): Response {\n\t\treturn this.#response\n\t}\n\n\tasync #pull(controller: ReadableStreamDefaultController<Uint8Array>): Promise<void> {\n\t\tif (this.#settled) return\n\t\ttry {\n\t\t\tconst step = await this.#iterator.next()\n\t\t\tif (this.#settled) return\n\t\t\tthis.#write(controller, step.done ? { channel: 'result', result: step.value } : step.value)\n\t\t\tif (step.done) this.#finish(controller)\n\t\t} catch (error) {\n\t\t\tif (this.#settled) return\n\t\t\tconst frame: RelayFrame = isProviderAbortError(error)\n\t\t\t\t? { channel: 'abort', partial: error.partial }\n\t\t\t\t: { channel: 'error', message: RELAY_PROVIDER_MESSAGE }\n\t\t\tthis.#write(\n\t\t\t\tcontroller,\n\t\t\t\trelayFrameContract.is(frame)\n\t\t\t\t\t? frame\n\t\t\t\t\t: { channel: 'error', message: RELAY_PROVIDER_MESSAGE },\n\t\t\t)\n\t\t\tthis.#finish(controller)\n\t\t\tthis.#abortProvider()\n\t\t\tawait this.#return()\n\t\t}\n\t}\n\n\tasync #abort(): Promise<void> {\n\t\tif (this.#settled) return\n\t\tthis.#settled = true\n\t\tthis.#abortProvider()\n\t\ttry {\n\t\t\tawait this.#return()\n\t\t} finally {\n\t\t\tthis.#release()\n\t\t}\n\t}\n\n\tasync #return(): Promise<void> {\n\t\ttry {\n\t\t\tawait this.#iterator.return({ content: '' })\n\t\t} catch {\n\t\t\t// A settled response has no error channel for upstream cleanup failures.\n\t\t}\n\t}\n\n\t#write(controller: ReadableStreamDefaultController<Uint8Array>, frame: RelayFrame): void {\n\t\tif (!relayFrameContract.is(frame)) throw new ProviderError('PROTOCOL', 'invalid relay frame')\n\t\tcontroller.enqueue(this.#encoder.encode(`${JSON.stringify(frame)}\\n`))\n\t}\n\n\t#finish(controller: ReadableStreamDefaultController<Uint8Array>): void {\n\t\tthis.#settled = true\n\t\tthis.#release()\n\t\tcontroller.close()\n\t}\n\n\t#abortProvider(): void {\n\t\tthis.#upstream.abort(this.#signal.reason)\n\t}\n\n\t#release(): void {\n\t\tthis.#signal.removeEventListener('abort', this.#listener)\n\t}\n}\n","import type { ThinkSplitterInterface } from './types.js'\nimport { THINK_CLOSE, THINK_OPEN } from './constants.js'\n\n/**\n * Separates `<think>…</think>` spans from raw content deltas with per-stream state: text inside a\n * span accumulates on `thinking`, and text outside it returns as clean content, so a provider\n * yields the answer alone and surfaces the reasoning as\n * {@link import('./types.js').ProviderResult.thinking}. A tag split across deltas is held until\n * disambiguated, `flush()` settles the stream end, and one splitter serves one stream.\n *\n * @remarks\n * - **Cross-chunk tags.** A tag may arrive split across wire deltas (`'<thi'` then\n * `'nk>'`): any suffix of the pending text that is a strict prefix of a tag being\n * scanned for is held back (neither surfaced nor routed) until the next delta — or\n * `flush()` — disambiguates it. A held tag prefix that never completes is real\n * content; a held close-tag prefix inside a span is thinking.\n * - **The implicit leading open (the qwen3-template shape).** Some chat templates\n * pre-seed `<think>` into the prompt scaffold, so the wire stream begins\n * mid-reasoning and only a bare `</think>` appears. Before any tag event, a bare\n * close therefore reclassifies everything surfaced so far (plus the pre-close\n * pending) as thinking — `content` is corrected retroactively (the already-returned\n * prefix cannot be recalled, so `content` is the authoritative accumulation). The\n * rule is one-shot: after any tag event a bare `</think>` is plain text.\n * - **Multiple spans** accumulate onto `thinking` in stream order. A nested-looking\n * `<think>` inside an open span is thinking text (no nesting is tracked — the\n * first `</think>` closes the span), matching how the models emit it.\n * - **Unclosed span at stream end.** `flush()` routes the open span's tail (including\n * any held partial close tag) to `thinking` — a cut-off model was still reasoning.\n * - **One splitter, one stream.** State is per-stream; create a fresh instance per\n * provider call ({@link import('./factories.js').createThinkSplitter}).\n *\n * @example\n * ```ts\n * const splitter = new ThinkSplitter()\n * splitter.split('<thi') // '' (held — ambiguous)\n * splitter.split('nk>plan</think>ok') // 'ok'\n * splitter.thinking // 'plan'\n * splitter.content // 'ok'\n * splitter.flush() // '' (nothing held)\n * ```\n */\nexport class ThinkSplitter implements ThinkSplitterInterface {\n\t// The undecided tail of the stream — text not yet routed to content or thinking\n\t// (at most one partial tag's worth between calls; transiently the whole delta).\n\t#pending = ''\n\t// Whether the scanner is inside an open `<think>` span.\n\t#inside = false\n\t// Whether a tag event has occurred (an explicit open, or the one-shot implicit-open\n\t// close) — before it, a bare `</think>` closes the implicit span a chat template\n\t// pre-seeded; after it, a bare close is plain text.\n\t#opened = false\n\t#content = ''\n\t#thinking = ''\n\n\tget content(): string {\n\t\treturn this.#content\n\t}\n\n\tget thinking(): string {\n\t\treturn this.#thinking\n\t}\n\n\tsplit(delta: string): string {\n\t\tconst out = this.#scan(delta)\n\t\tthis.#content += out\n\t\treturn out\n\t}\n\n\tflush(): string {\n\t\tconst pending = this.#pending\n\t\tthis.#pending = ''\n\t\tif (this.#inside) {\n\t\t\t// An unclosed span at stream end — the tail (held partial close tag included)\n\t\t\t// is thinking: the model was cut off mid-reasoning, never mid-answer.\n\t\t\tthis.#thinking += pending\n\t\t\tthis.#inside = false\n\t\t\treturn ''\n\t\t}\n\t\t// A held partial tag that never completed was real content after all.\n\t\tthis.#content += pending\n\t\treturn pending\n\t}\n\n\t// Drive the state machine over one delta, returning the clean content it surfaces —\n\t// the wrapper folds the return into `#content`, which the implicit-open branch may\n\t// have reset a moment earlier (the reclassification).\n\t#scan(delta: string): string {\n\t\tthis.#pending += delta\n\t\treturn [...this.#surface()].join('')\n\t}\n\n\t// Walk the pending text, yielding each clean content piece in order and routing reasoning to\n\t// `#thinking`; return once the remainder is undecided and held for the next delta. A piece is\n\t// yielded only after `#opened` is set, so the reclassification below never meets one.\n\t*#surface(): Generator<string, void> {\n\t\tfor (;;) {\n\t\t\tif (this.#inside) {\n\t\t\t\tconst close = this.#pending.indexOf(THINK_CLOSE)\n\t\t\t\tif (close === -1) {\n\t\t\t\t\t// No close yet — route all but a possible partial close-tag suffix to\n\t\t\t\t\t// thinking, holding that suffix for the next delta to disambiguate.\n\t\t\t\t\tthis.#thinking += this.#hold([THINK_CLOSE])\n\t\t\t\t\treturn\n\t\t\t\t}\n\t\t\t\tthis.#thinking += this.#pending.slice(0, close)\n\t\t\t\tthis.#pending = this.#pending.slice(close + THINK_CLOSE.length)\n\t\t\t\tthis.#inside = false\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst open = this.#pending.indexOf(THINK_OPEN)\n\t\t\tif (!this.#opened) {\n\t\t\t\t// The implicit leading open: before any tag event, a bare close (arriving\n\t\t\t\t// ahead of any explicit open) means the stream began inside a pre-seeded\n\t\t\t\t// span — everything surfaced so far was reasoning. Reclassify it.\n\t\t\t\tconst close = this.#pending.indexOf(THINK_CLOSE)\n\t\t\t\tif (close !== -1 && (open === -1 || close < open)) {\n\t\t\t\t\tthis.#thinking += this.#content + this.#pending.slice(0, close)\n\t\t\t\t\tthis.#content = ''\n\t\t\t\t\tthis.#pending = this.#pending.slice(close + THINK_CLOSE.length)\n\t\t\t\t\tthis.#opened = true\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (open === -1) {\n\t\t\t\t// No open tag — surface all but a possible partial tag suffix as content\n\t\t\t\t// (before any tag event a split leading close must not leak either, so the\n\t\t\t\t// close tag's prefixes are held back too).\n\t\t\t\tconst tags = this.#opened ? [THINK_OPEN] : [THINK_OPEN, THINK_CLOSE]\n\t\t\t\tyield this.#hold(tags)\n\t\t\t\treturn\n\t\t\t}\n\t\t\tthis.#opened = true\n\t\t\tyield this.#pending.slice(0, open)\n\t\t\tthis.#pending = this.#pending.slice(open + THINK_OPEN.length)\n\t\t\tthis.#inside = true\n\t\t}\n\t}\n\n\t// Settle the pending text against the given tags' possible partial suffixes: the\n\t// longest ambiguous suffix stays pending for the next delta; everything before it\n\t// is returned for routing.\n\t#hold(tags: readonly string[]): string {\n\t\tconst keep = Math.max(...tags.map((tag) => this.#overlap(tag)))\n\t\tconst cut = this.#pending.length - keep\n\t\tconst settled = this.#pending.slice(0, cut)\n\t\tthis.#pending = this.#pending.slice(cut)\n\t\treturn settled\n\t}\n\n\t// The length of the longest strict prefix of `tag` that suffixes the pending text —\n\t// how many trailing characters are an ambiguous partial tag and must be held back.\n\t#overlap(tag: string): number {\n\t\tconst max = Math.min(this.#pending.length, tag.length - 1)\n\t\treturn (\n\t\t\tArray.from({ length: max }, (_, index) => max - index).find((length) =>\n\t\t\t\tthis.#pending.endsWith(tag.slice(0, length)),\n\t\t\t) ?? 0\n\t\t)\n\t}\n}\n","import type {\n\tAgentProviderInput,\n\tAgentProviderInterface,\n\tProviderDelta,\n\tProviderIncrement,\n\tProviderOptions,\n\tProviderParserInterface,\n\tProviderRequest,\n\tProviderResult,\n\tProviderStreamOptions,\n\tThinkSplitterInterface,\n} from './types.js'\nimport type { Message, ThinkingReplay } from '../types.js'\nimport type { ToolDefinition } from '@orkestrel/tool'\nimport { Timeout } from '@orkestrel/timeout'\nimport { DEFAULT_PROVIDER_TIMEOUT } from './constants.js'\nimport { ProviderAbortError, ProviderError } from './errors.js'\nimport { ThinkSplitter } from './ThinkSplitter.js'\nimport { buildProviderResult, readChunks, buildProviderHeaders, readFailure } from './helpers.js'\nimport { joinThinking } from '../helpers.js'\n\n/**\n * Implements bounded HTTP streaming and result assembly behind concrete wire seams.\n *\n * @remarks\n * Every call owns its parser, splitter, deadline, and accumulation. Success bodies\n * have no size limit. A qwen3 implicit-open reclassification corrects the final\n * content while content deltas already yielded cannot be recalled. A subclass fills\n * `name`, `frame`, `encode`, `read`, and `finish`; the constructor takes the `split`\n * and `strict` switches to control reasoning separation and settled-result requirements.\n * The `replay` input names which stored thinking the agent and relay send back. Default: `'none'`.\n *\n * @example Writing a provider for a new wire\n * ```ts\n * import type {\n * \tProviderIncrement,\n * \tProviderOptions,\n * \tProviderParserInterface,\n * \tProviderRequest,\n * } from '@orkestrel/agent'\n * import { AgentProvider } from '@orkestrel/agent'\n *\n * class TextFrame implements ProviderParserInterface<string> {\n * \tparse(chunk: string): readonly string[] {\n * \t\treturn [chunk]\n * \t}\n * \tclear(): void {} // Raw text retains no framing state.\n * }\n *\n * interface TextOptions extends ProviderOptions {\n * \treadonly url: string\n * }\n *\n * class TextProvider extends AgentProvider<string> {\n * \treadonly name = 'text'\n * \tconstructor(options: TextOptions) {\n * \t\tsuper({ ...options, path: '/generate' })\n * \t}\n * \tframe(): ProviderParserInterface<string> {\n * \t\treturn new TextFrame()\n * \t}\n * \tencode(request: ProviderRequest): object {\n * \t\treturn { messages: request.messages }\n * \t}\n * \tread(record: string): ProviderIncrement {\n * \t\treturn { content: record, thinking: '', tools: [] }\n * \t}\n * \tfinish(_parser: ProviderParserInterface<string>): readonly string[] {\n * \t\treturn [] // Raw text retains no records at end of input.\n * \t}\n * }\n * ```\n */\nexport abstract class AgentProvider<\n\tTRecord = Readonly<Record<string, unknown>>,\n> implements AgentProviderInterface<TRecord> {\n\treadonly #id: string\n\treadonly #replay: ThinkingReplay\n\treadonly #url: string\n\treadonly #path: string\n\treadonly #timeout: number\n\treadonly #transport: typeof globalThis.fetch\n\treadonly #headers: ProviderOptions['headers']\n\treadonly #split: boolean\n\treadonly #strict: boolean\n\n\tconstructor(input: AgentProviderInput) {\n\t\tthis.#id = crypto.randomUUID()\n\t\tthis.#replay = input.replay ?? 'none'\n\t\tthis.#url = input.url\n\t\tthis.#path = input.path ?? ''\n\t\tthis.#timeout = input.timeout ?? DEFAULT_PROVIDER_TIMEOUT\n\t\tthis.#transport = input.fetch ?? globalThis.fetch.bind(globalThis)\n\t\tthis.#headers = input.headers\n\t\tthis.#split = input.split ?? true\n\t\tthis.#strict = input.strict ?? false\n\t}\n\n\t/** Identifies the concrete backend. */\n\tabstract readonly name: string\n\n\t/** Exposes the instance's minted UUID. */\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\t/** Names which stored assistant thinking the agent and relay send back. */\n\tget replay(): ThinkingReplay {\n\t\treturn this.#replay\n\t}\n\n\t/** Creates fresh framing state for the call. */\n\tabstract frame(): ProviderParserInterface<TRecord>\n\t/** Projects a domain request onto the concrete protocol's wire body. */\n\tabstract encode(request: ProviderRequest): object\n\t/** Decodes a framed record into a turn increment. */\n\tabstract read(record: TRecord): ProviderIncrement\n\t/** Returns any records retained at end of input. */\n\tabstract finish(parser: ProviderParserInterface<TRecord>): readonly TRecord[]\n\n\t/**\n\t * Generates a complete turn by draining the shared stream engine.\n\t *\n\t * @param messages - The conversation turns\n\t * @param signal - The caller's cancellation bound\n\t * @param tools - The advertised tool definitions\n\t * @param options - The per-call generation configuration\n\t * @returns The terminal stream result\n\t */\n\tasync generate(\n\t\tmessages: readonly Message[],\n\t\tsignal: AbortSignal,\n\t\ttools?: readonly ToolDefinition[],\n\t\toptions?: ProviderStreamOptions,\n\t): Promise<ProviderResult> {\n\t\tconst stream = this.stream(messages, signal, tools, options)\n\t\tfor (;;) {\n\t\t\tconst step = await stream.next()\n\t\t\tif (step.done) return step.value\n\t\t}\n\t}\n\n\t/**\n\t * Streams decoded deltas and returns the authoritative or assembled turn result.\n\t *\n\t * @param messages - The conversation turns\n\t * @param signal - The caller's cancellation bound\n\t * @param tools - The advertised tool definitions\n\t * @param options - The per-call generation configuration\n\t * @returns Content and native thinking deltas followed by the settled result\n\t * @throws ProviderAbortError Thrown when the combined cancellation bound fires\n\t * @throws ProviderError Thrown when the response is non-OK, the response has no body, a wire record\n\t * is malformed or carries an upstream failure, or a strict stream ends without a settled result\n\t */\n\tasync *stream(\n\t\tmessages: readonly Message[],\n\t\tsignal: AbortSignal,\n\t\ttools?: readonly ToolDefinition[],\n\t\toptions?: ProviderStreamOptions,\n\t): AsyncGenerator<ProviderDelta, ProviderResult> {\n\t\tif (signal.aborted) throw new ProviderAbortError({ content: '' })\n\t\tconst timeout = new Timeout({ ms: this.#timeout })\n\t\ttimeout.start()\n\t\tconst combined = AbortSignal.any([timeout.signal, signal])\n\t\ttry {\n\t\t\tconst parser = this.#frame(combined)\n\t\t\ttry {\n\t\t\t\treturn yield* this.#read(parser, messages, tools, options, combined)\n\t\t\t} finally {\n\t\t\t\tparser.clear()\n\t\t\t}\n\t\t} finally {\n\t\t\ttimeout.clear()\n\t\t}\n\t}\n\n\t// Creates the call's framing state; a failure that raced the cancel becomes the empty partial.\n\t#frame(combined: AbortSignal): ProviderParserInterface<TRecord> {\n\t\ttry {\n\t\t\treturn this.frame()\n\t\t} catch (error) {\n\t\t\tthrow this.#translate(error, combined, undefined, [])\n\t\t}\n\t}\n\n\t// Requests, frames, folds, and settles one call. Each decoded increment joins a local list\n\t// before its deltas are exposed, so a cancel during a yield assembles from what the body produced.\n\tasync *#read(\n\t\tparser: ProviderParserInterface<TRecord>,\n\t\tmessages: readonly Message[],\n\t\ttools: readonly ToolDefinition[] | undefined,\n\t\toptions: ProviderStreamOptions | undefined,\n\t\tcombined: AbortSignal,\n\t): AsyncGenerator<ProviderDelta, ProviderResult> {\n\t\tconst splitter = this.#split ? new ThinkSplitter() : undefined\n\t\tconst increments: ProviderIncrement[] = []\n\t\ttry {\n\t\t\tconst response = await this.#request(\n\t\t\t\t{\n\t\t\t\t\tmessages,\n\t\t\t\t\t...(tools === undefined ? {} : { tools }),\n\t\t\t\t\t...(options === undefined ? {} : { options }),\n\t\t\t\t},\n\t\t\t\tcombined,\n\t\t\t)\n\t\t\tif (response.body === null) {\n\t\t\t\tthrow new ProviderError('PROTOCOL', 'provider error: no response body')\n\t\t\t}\n\t\t\tfor await (const chunk of readChunks(response.body, combined)) {\n\t\t\t\tcombined.throwIfAborted()\n\t\t\t\tfor (const record of parser.parse(chunk)) {\n\t\t\t\t\tconst increment = this.read(record)\n\t\t\t\t\tincrements.push(increment)\n\t\t\t\t\tif (increment.result === undefined) yield* this.#emit(increment, splitter, combined)\n\t\t\t\t\tcombined.throwIfAborted()\n\t\t\t\t\tif (increment.result !== undefined) return increment.result\n\t\t\t\t}\n\t\t\t}\n\t\t\tcombined.throwIfAborted()\n\t\t\tfor (const record of this.finish(parser)) {\n\t\t\t\tconst increment = this.read(record)\n\t\t\t\tincrements.push(increment)\n\t\t\t\tif (increment.result === undefined) yield* this.#emit(increment, splitter, combined)\n\t\t\t\tcombined.throwIfAborted()\n\t\t\t\tif (increment.result !== undefined) return increment.result\n\t\t\t}\n\t\t\tconst tail = splitter?.flush() ?? ''\n\t\t\tif (tail.length > 0) yield { channel: 'content', text: tail }\n\t\t\tcombined.throwIfAborted()\n\t\t\tif (this.#strict) {\n\t\t\t\tthrow new ProviderError('PROTOCOL', 'provider error: missing settled result')\n\t\t\t}\n\t\t\treturn this.#assemble(splitter, increments)\n\t\t} catch (error) {\n\t\t\tthrow this.#translate(error, combined, splitter, increments)\n\t\t}\n\t}\n\n\t// Surfaces one increment's deltas: the split content, then — unless the call was cancelled in\n\t// between — its native thinking.\n\t*#emit(\n\t\tincrement: ProviderIncrement,\n\t\tsplitter: ThinkSplitterInterface | undefined,\n\t\tsignal: AbortSignal,\n\t): Generator<ProviderDelta> {\n\t\tconst content = splitter?.split(increment.content) ?? increment.content\n\t\tif (content.length > 0) yield { channel: 'content', text: content }\n\t\tsignal.throwIfAborted()\n\t\tif (increment.thinking.length > 0) yield { channel: 'thinking', text: increment.thinking }\n\t}\n\n\t// The error a failed call throws: a cancel becomes a ProviderAbortError carrying the partial\n\t// assembled so far (a throw that raced the cancel is its cause); any other failure is itself.\n\t#translate(\n\t\terror: unknown,\n\t\tcombined: AbortSignal,\n\t\tsplitter: ThinkSplitterInterface | undefined,\n\t\tincrements: readonly ProviderIncrement[],\n\t): unknown {\n\t\tif (!combined.aborted) return error\n\t\tsplitter?.flush()\n\t\treturn new ProviderAbortError(\n\t\t\tthis.#assemble(splitter, increments),\n\t\t\terror === combined.reason ? undefined : { cause: error },\n\t\t)\n\t}\n\n\t// Both exits assemble alike, so an aborted call's partial carries what a settled call would. A\n\t// settled-result increment replaces the fold.\n\t#assemble(\n\t\tsplitter: ThinkSplitterInterface | undefined,\n\t\tincrements: readonly ProviderIncrement[],\n\t): ProviderResult {\n\t\tconst last = increments.at(-1)\n\t\tconst folded = last?.result === undefined ? increments : [last]\n\t\treturn buildProviderResult(\n\t\t\tsplitter?.content ?? folded.map((one) => one.content).join(''),\n\t\t\tjoinThinking(splitter?.thinking, folded.map((one) => one.thinking).join('')),\n\t\t\tfolded.flatMap((one) => [...one.tools]),\n\t\t\tfolded.findLast((one) => one.usage !== undefined)?.usage,\n\t\t\tfolded.findLast((one) => one.truncated !== undefined)?.truncated,\n\t\t)\n\t}\n\n\t// Send one request and translate its HTTP failure into the shared provider taxonomy.\n\tasync #request(request: ProviderRequest, signal: AbortSignal): Promise<Response> {\n\t\tconst headers = await buildProviderHeaders(this.#headers, signal)\n\t\tsignal.throwIfAborted()\n\t\tconst response = await this.#transport(this.#url + this.#path, {\n\t\t\tmethod: 'POST',\n\t\t\theaders,\n\t\t\tbody: JSON.stringify(this.encode(request)),\n\t\t\tsignal,\n\t\t})\n\t\tif (!response.ok) {\n\t\t\tconst { message, ...options } = await readFailure(response, 'provider error:', signal)\n\t\t\tthrow new ProviderError('HTTP', message, options)\n\t\t}\n\t\treturn response\n\t}\n}\n","import type {\n\tProviderIncrement,\n\tProviderParserInterface,\n\tProviderRequest,\n\tRelayProviderOptions,\n} from './types.js'\nimport { attempt, cloneJSONValue } from '@orkestrel/contract'\nimport { AgentProvider } from './AgentProvider.js'\nimport { ProviderAbortError, ProviderError } from './errors.js'\nimport { requestToRelay } from './helpers.js'\nimport { providerRequestContract, relayFrameContract } from './contracts.js'\n\n/**\n * Carries provider calls over an authenticated NDJSON relay endpoint.\n *\n * @remarks\n * Tool execution context stays local; calls carry only `id`, `name`, and `arguments`.\n * The wire body is an owned snapshot of\n * the projection read through property descriptors, so a serializer reachable only through a\n * `get` trap or a prototype is never consulted; an own function-valued property such as a\n * `toJSON` method is a value outside JSON and is refused before fetching, with the clone's\n * failure as the refusal's `cause`. A remote abort reconstructs a `ProviderAbortError` instance\n * without aborting the\n * local signal; the `Agent` runtime treats that instance as an error unless its own bound\n * signal is aborted.\n * Content is preserved verbatim, including literal thinking tags.\n * A refusal reaches the browser as a `ProviderError` instance with the `HTTP` code and status.\n * This is the browser end alone; {@link createRelay} mounts the server end.\n * The example of {@link createRelayProvider} is the browser half of that pair.\n *\n * @example\n * ```ts\n * import type { ProviderResult } from '@orkestrel/agent'\n * import { RelayProvider } from '@orkestrel/agent'\n * // The browser application supplies this parser dependency.\n * import { createNDJSONParser } from '@orkestrel/ndjson'\n *\n * export function ask(bearer: string, signal: AbortSignal): Promise<ProviderResult> {\n * \tconst browser = new RelayProvider({\n * \t\turl: 'https://relay.example/relay',\n * \t\tparser: createNDJSONParser,\n * \t\theaders: () => ({ authorization: `Bearer ${bearer}` }),\n * \t})\n * \treturn browser.generate([{ id: 'ask', role: 'user', content: 'ping' }], signal)\n * }\n * ```\n */\nexport class RelayProvider extends AgentProvider {\n\treadonly #parser: () => ProviderParserInterface\n\n\tconstructor(options: RelayProviderOptions) {\n\t\tconst { url, timeout, fetch, headers, replay } = options\n\t\tsuper({\n\t\t\turl,\n\t\t\tsplit: false,\n\t\t\tstrict: true,\n\t\t\t...(timeout === undefined ? {} : { timeout }),\n\t\t\t...(fetch === undefined ? {} : { fetch }),\n\t\t\t...(headers === undefined ? {} : { headers }),\n\t\t\t...(replay === undefined ? {} : { replay }),\n\t\t})\n\t\tthis.#parser = options.parser\n\t}\n\n\t/** Identifies the relay backend. */\n\treadonly name = 'relay'\n\n\t/** Creates fresh framing state for each response. */\n\tframe(): ProviderParserInterface {\n\t\treturn this.#parser()\n\t}\n\n\t/**\n\t * Projects declared request fields and refuses values the JSON wire cannot carry.\n\t *\n\t * @remarks\n\t * The snapshot is taken from property descriptors, so a custom serializer a projected\n\t * value carries is ignored rather than consulted and cannot reach the wire.\n\t *\n\t * @param request - The domain conversation and call configuration\n\t * @returns The validated wire request\n\t * @throws {ProviderError} Thrown when the snapshot cannot be taken — a hostile read or a\n\t * value outside JSON — carrying that failure as its `cause`, and when the snapshot the\n\t * projection produced is not a valid wire request\n\t */\n\tencode(request: ProviderRequest): object {\n\t\tconst snapshot = attempt(() => cloneJSONValue(requestToRelay(request)))\n\t\tif (!snapshot.success) {\n\t\t\tthrow new ProviderError('PROTOCOL', 'relay request is not JSON', { cause: snapshot.error })\n\t\t}\n\t\tif (!providerRequestContract.is(snapshot.value)) {\n\t\t\tthrow new ProviderError('PROTOCOL', 'relay request is not JSON')\n\t\t}\n\t\treturn snapshot.value\n\t}\n\n\t/**\n\t * Validates a relay frame and translates its channel into the shared stream engine.\n\t *\n\t * @param record - The framed wire record\n\t * @returns A delta contribution or authoritative result\n\t * @throws {ProviderAbortError} Thrown when the frame's channel is `abort`, carrying its partial result\n\t * @throws {ProviderError} Thrown when the frame fails validation or its channel is `error`\n\t */\n\tread(record: Readonly<Record<string, unknown>>): ProviderIncrement {\n\t\tif (!relayFrameContract.is(record)) {\n\t\t\tthrow new ProviderError('PROTOCOL', 'invalid relay frame')\n\t\t}\n\t\tswitch (record.channel) {\n\t\t\tcase 'content':\n\t\t\t\treturn { content: record.text, thinking: '', tools: [] }\n\t\t\tcase 'thinking':\n\t\t\t\treturn { content: '', thinking: record.text, tools: [] }\n\t\t\tcase 'result':\n\t\t\t\treturn { content: '', thinking: '', tools: [], result: record.result }\n\t\t\tcase 'abort':\n\t\t\t\tthrow new ProviderAbortError(record.partial)\n\t\t\tcase 'error':\n\t\t\t\tthrow new ProviderError('PROVIDER', record.message)\n\t\t}\n\t}\n\n\t/**\n\t * Recovers an unterminated final frame by completing its NDJSON line.\n\t *\n\t * @param parser - The call's retained framing state\n\t * @returns Records completed by the final newline\n\t */\n\tfinish(parser: ProviderParserInterface): ReadonlyArray<Readonly<Record<string, unknown>>> {\n\t\treturn parser.parse('\\n')\n\t}\n}\n","import type { AgentJudgeInput, AgentJudgeInterface, ProviderOptions } from './types.js'\nimport type { JudgeRequest, JudgeResult } from '../types.js'\nimport { isRecord, parseJSON } from '@orkestrel/contract'\nimport { Timeout } from '@orkestrel/timeout'\nimport { DEFAULT_PROVIDER_TIMEOUT } from './constants.js'\nimport { JudgeError } from './errors.js'\nimport { copyJSON } from '../cloners.js'\nimport { JudgeAbortError } from '../errors.js'\nimport { buildJudgeResult, buildProviderHeaders, readFailure, readText } from './helpers.js'\nimport { isJudgeEntry, isJudgeQuestion } from '../validators.js'\n\n/**\n * Implements the bounded HTTP calls, validation, and result merging of a judge behind concrete\n * wire seams.\n *\n * @remarks\n * A subclass fills `name`, `encode`, and `read`; the constructor takes the `batch` switch that\n * decides whether one call carries every question or each question gets its own call in key\n * order. `ask` validates the request before any call, builds every body before the first call so\n * a wire limit refuses the request before inference, and runs the calls one after another, each\n * under its own deadline folded with the caller's signal. A cancel throws a `JudgeAbortError`\n * whose `partial` merges the calls that completed. A transport error reaches the caller unchanged.\n *\n * @example Writing a judge wire\n * ```ts\n * import type { JudgeRequest, JudgeResult } from '@orkestrel/agent'\n * import { AgentJudge, JudgeError } from '@orkestrel/agent'\n * import { isFiniteNumber, isRecord } from '@orkestrel/contract'\n *\n * // A wire whose server answers one yes/no question per call as { \"yes\": 0.93 }.\n * class YesJudge extends AgentJudge {\n * \treadonly name = 'yes'\n * \tencode(request: JudgeRequest): object {\n * \t\treturn { model: this.model, state: request.state, questions: request.questions }\n * \t}\n * \tread(value: unknown, request: JudgeRequest): JudgeResult {\n * \t\tconst [id] = Object.keys(request.questions)\n * \t\tif (id === undefined || !isRecord(value) || !isFiniteNumber(value.yes)) {\n * \t\t\tthrow new JudgeError('PROTOCOL', 'judge error: unreadable answer')\n * \t\t}\n * \t\treturn { model: this.model, answers: { [id]: { form: 'noul', noul: value.yes } } }\n * \t}\n * }\n *\n * const judge = new YesJudge({\n * \turl: 'http://localhost:8010',\n * \tpath: '/v1/yes',\n * \tmodel: 'yes-1',\n * \tbatch: false,\n * })\n * ```\n */\nexport abstract class AgentJudge implements AgentJudgeInterface {\n\treadonly #id: string\n\treadonly #url: string\n\treadonly #path: string\n\treadonly #model: string\n\treadonly #timeout: number\n\treadonly #transport: typeof globalThis.fetch\n\treadonly #headers: ProviderOptions['headers']\n\treadonly #batch: boolean\n\n\tconstructor(input: AgentJudgeInput) {\n\t\tthis.#id = crypto.randomUUID()\n\t\tthis.#url = input.url\n\t\tthis.#path = input.path ?? ''\n\t\tthis.#model = input.model\n\t\tthis.#timeout = input.timeout ?? DEFAULT_PROVIDER_TIMEOUT\n\t\tthis.#transport = input.fetch ?? globalThis.fetch.bind(globalThis)\n\t\tthis.#headers = input.headers\n\t\tthis.#batch = input.batch ?? true\n\t}\n\n\t/** Identifies the concrete wire. */\n\tabstract readonly name: string\n\n\t/** Exposes the instance's minted UUID. */\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\t/** Exposes the configured model identity. */\n\tget model(): string {\n\t\treturn this.#model\n\t}\n\n\t/** Projects one call's request onto the concrete protocol's wire body. */\n\tabstract encode(request: JudgeRequest): object\n\t/** Decodes one call's parsed response body into the answers for that call's questions. */\n\tabstract read(value: unknown, request: JudgeRequest): JudgeResult\n\n\t/**\n\t * Asks every question of the request about its state and merges the answers of every call.\n\t *\n\t * @param request - The state and the questions keyed by caller id\n\t * @param signal - The caller's cancellation bound\n\t * @returns The merged answers, refusals, and usage of every call\n\t * @throws JudgeAbortError Thrown when the caller's signal or a call's deadline fires, carrying\n\t * the merged result of the completed calls\n\t * @throws JudgeError Thrown when the question map is empty, a question or the state is malformed,\n\t * or the wire refuses the request before any call (code `QUESTION`); when a response is non-OK\n\t * (code `HTTP`); and when a response body is missing or unparsable (code `PROTOCOL`)\n\t */\n\tasync ask(request: JudgeRequest, signal: AbortSignal): Promise<JudgeResult> {\n\t\tif (signal.aborted) throw new JudgeAbortError(buildJudgeResult(this.#model, []))\n\t\t// The request is owned through JSON before validation, so a caller mutating it while a call\n\t\t// is pending cannot make `read` decode against criteria that were never sent, and a proxied\n\t\t// request (a reactive view) is owned where a structured clone would refuse it.\n\t\tconst state = copyJSON(request.state)\n\t\tif (!isJudgeEntry(state)) {\n\t\t\tthrow new JudgeError('QUESTION', 'judge error: state is not a judge entry')\n\t\t}\n\t\tconst questions = isRecord(request.questions) ? Object.entries(request.questions) : []\n\t\tif (questions.length === 0) throw new JudgeError('QUESTION', 'judge error: no questions')\n\t\tconst entries = questions.map(([id, question]) => {\n\t\t\tconst copy = copyJSON(question)\n\t\t\tif (!isJudgeQuestion(copy)) {\n\t\t\t\tthrow new JudgeError('QUESTION', `judge error: question ${id} is malformed`)\n\t\t\t}\n\t\t\treturn [id, copy] as const\n\t\t})\n\t\tconst owned: JudgeRequest = { state, questions: Object.fromEntries(entries) }\n\t\tconst parts: readonly JudgeRequest[] = this.#batch\n\t\t\t? [owned]\n\t\t\t: entries.map(([id, question]) => ({ state, questions: { [id]: question } }))\n\t\tconst calls = parts.map((part) => ({ request: part, body: JSON.stringify(this.encode(part)) }))\n\t\tconst results: JudgeResult[] = []\n\t\tfor (const call of calls) {\n\t\t\tresults.push(await this.#call(call.request, call.body, signal, results))\n\t\t}\n\t\treturn buildJudgeResult(this.#model, results)\n\t}\n\n\tasync #call(\n\t\trequest: JudgeRequest,\n\t\tbody: string,\n\t\tsignal: AbortSignal,\n\t\tcompleted: readonly JudgeResult[],\n\t): Promise<JudgeResult> {\n\t\tconst timeout = new Timeout({ ms: this.#timeout })\n\t\ttimeout.start()\n\t\tconst combined = AbortSignal.any([timeout.signal, signal])\n\t\ttry {\n\t\t\tconst headers = await buildProviderHeaders(this.#headers, combined)\n\t\t\tcombined.throwIfAborted()\n\t\t\tconst response = await this.#transport(this.#url + this.#path, {\n\t\t\t\tmethod: 'POST',\n\t\t\t\theaders,\n\t\t\t\tbody,\n\t\t\t\tsignal: combined,\n\t\t\t})\n\t\t\tif (!response.ok) {\n\t\t\t\tconst { message, ...options } = await readFailure(response, 'judge error:', combined)\n\t\t\t\tthrow new JudgeError('HTTP', message, options)\n\t\t\t}\n\t\t\tif (response.body === null) {\n\t\t\t\tthrow new JudgeError('PROTOCOL', 'judge error: no response body')\n\t\t\t}\n\t\t\tconst text = await readText(response.body, undefined, combined)\n\t\t\tcombined.throwIfAborted()\n\t\t\tconst value = parseJSON(text.text)\n\t\t\tif (value === undefined) throw new JudgeError('PROTOCOL', 'judge error: invalid JSON body')\n\t\t\tconst result = this.read(value, request)\n\t\t\tcombined.throwIfAborted()\n\t\t\treturn result\n\t\t} catch (error) {\n\t\t\tif (combined.aborted) {\n\t\t\t\t// A throw that raced the cancel is the call's real failure, so it is recorded as the cause.\n\t\t\t\tthrow new JudgeAbortError(\n\t\t\t\t\tbuildJudgeResult(this.#model, completed),\n\t\t\t\t\terror === combined.reason ? undefined : { cause: error },\n\t\t\t\t)\n\t\t\t}\n\t\t\tthrow error\n\t\t} finally {\n\t\t\ttimeout.clear()\n\t\t}\n\t}\n}\n","import type { SystemOneAnswer, SystemOneResponse } from './types.js'\nimport {\n\tarrayOf,\n\tattempt,\n\tboundsOf,\n\tisArray,\n\tisNumber,\n\tisRecord,\n\tisString,\n\tnullableOf,\n\toptionalOf,\n} from '@orkestrel/contract'\n\n/**\n * Checks whether a value is a System One response envelope with optional model and usage.\n *\n * @remarks\n * Answers remain unknown until checked against their questions. Missing and null usage counts\n * are accepted. Extra members are ignored, and unreadable fields return false.\n *\n * @param value - The unknown response candidate\n * @returns True if the envelope fields have their wire types; false otherwise\n * @example\n * ```ts\n * isSystemOneResponse({ answers: {}, usage: { input_tokens: null } }) // true\n * ```\n */\nexport function isSystemOneResponse(value: unknown): value is SystemOneResponse {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { model, answers, usage } = value\n\t\tif (!optionalOf(isString)(model) || !isRecord(answers)) return false\n\t\tif (usage === undefined) return true\n\t\tif (!isRecord(usage)) return false\n\t\treturn (\n\t\t\toptionalOf(nullableOf(isNumber))(usage.input_tokens) &&\n\t\t\toptionalOf(nullableOf(isNumber))(usage.output_tokens)\n\t\t)\n\t})\n\treturn checked.success && checked.value\n}\n\n/**\n * Checks whether a value is a System One answer whose type and distribution the wire can read.\n *\n * @remarks\n * The guard checks `type` and the distribution the wire dereferences: the `noul` number for a\n * noul, the `probabilities` map for a choice, and the `probabilities` map or dense array for a\n * score, each probability a finite number in [0, 1]. The `choice`, `score`, `confidence`, and\n * `legend` members are carried unchecked, because the wire never reads them, so a value this\n * guard accepts can hold any value in those members. Distribution sums are not constrained;\n * values are never normalized. Hostile reads return false.\n *\n * @param value - The unknown answer candidate\n * @returns True if the type and the distribution satisfy the wire contract; false otherwise\n * @example\n * ```ts\n * isSystemOneAnswer({ type: 'noul', noul: 0.9 }) // true\n * isSystemOneAnswer({ type: 'score', probabilities: [0.2, 0.8] }) // true\n * isSystemOneAnswer({ type: 'noul', noul: 1.1 }) // false\n * ```\n */\nexport function isSystemOneAnswer(value: unknown): value is SystemOneAnswer {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { type } = value\n\t\tif (type === 'noul') return boundsOf(0, 1)(value.noul)\n\t\tif (type !== 'choice' && type !== 'score') return false\n\t\tconst { probabilities } = value\n\t\tif (type === 'score' && isArray(probabilities)) {\n\t\t\treturn arrayOf(boundsOf(0, 1))(probabilities)\n\t\t}\n\t\treturn isRecord(probabilities) && Object.values(probabilities).every(boundsOf(0, 1))\n\t})\n\treturn checked.success && checked.value\n}\n","import type { SystemOneJudgeOptions, SystemOneRequest } from './types.js'\nimport type { JudgeRequest, JudgeResult } from '../types.js'\nimport { AgentJudge } from './AgentJudge.js'\nimport { SYSTEM_ONE_PATH } from './constants.js'\nimport { extractSystemOneAnswer, extractSystemOneUsage, questionToSystemOne } from './helpers.js'\nimport { isSystemOneAnswer, isSystemOneResponse } from './validators.js'\nimport { JudgeError } from './errors.js'\n\n/**\n * Carries judge questions over the System One protocol and derives answers from server distributions.\n *\n * @remarks\n * The caller supplies the server origin and model. Every question travels in one request.\n * Server measures are ignored; the response model is preserved.\n * `headers` supplies authentication through the shared judge engine.\n * The example readings are those of the response Ollama 0.40.0 returned for that request on 2026-10-07.\n *\n * @example Asking a System One server a choice, a noul, and a score\n * ```ts\n * import { computeReading, createSystemOneJudge } from '@orkestrel/agent'\n *\n * const judge = createSystemOneJudge({ url: 'http://localhost:11434', model: 'tev1:0.8b' })\n * const result = await judge.ask(\n * \t{\n * \t\tstate: 'Our checkout has returned 500 errors since 9am. I want a refund for today.',\n * \t\tquestions: {\n * \t\t\tlabel: {\n * \t\t\t\tform: 'choice',\n * \t\t\t\tinstructions: 'Which label fits this ticket?',\n * \t\t\t\tcriteria: { billing: 'Payments and refunds', bug: 'Software errors', account: null },\n * \t\t\t},\n * \t\t\trefund: {\n * \t\t\t\tform: 'noul',\n * \t\t\t\tinstructions: 'Does the customer ask for money back?',\n * \t\t\t\tcriteria: {\n * \t\t\t\t\ttrue: 'The customer asks for a refund or for money back.',\n * \t\t\t\t\tfalse: 'The customer does not ask for money back.',\n * \t\t\t\t},\n * \t\t\t},\n * \t\t\tseverity: {\n * \t\t\t\tform: 'score',\n * \t\t\t\tinstructions: 'How severe is the reported issue?',\n * \t\t\t\tcriteria: ['Cosmetic; no impact', 'Degraded, workaround exists', 'Blocking; no workaround'],\n * \t\t\t},\n * \t\t},\n * \t},\n * \tAbortSignal.timeout(30_000),\n * )\n * const readings = Object.fromEntries(\n * \tObject.entries(result.answers).map(([id, answer]) => [id, computeReading(answer)]),\n * )\n * result.model // 'tev1:0.8b' — the model the server named\n * result.usage // { prompt: 975, completion: 4, total: 979 }\n * readings.label // { winner: 'bug', probability: 0.9691, confidence: 0.9536 } to 4 decimals\n * readings.refund // { winner: 'true', probability: 0.9979, confidence: 0.9958 } to 4 decimals\n * readings.severity // { winner: '1', probability: 0.9494, confidence: 0.9241, score: 0.9919 } to 4 decimals\n * ```\n */\nexport class SystemOneJudge extends AgentJudge {\n\tconstructor(options: SystemOneJudgeOptions) {\n\t\tsuper({ ...options, path: SYSTEM_ONE_PATH, batch: true })\n\t}\n\n\t/** Identifies the System One protocol. */\n\treadonly name = 'systemone'\n\n\t/**\n\t * Projects the state and questions onto the System One request with the configured model.\n\t *\n\t * @param request - The state and questions keyed by caller id\n\t * @returns The System One request body\n\t */\n\tencode(request: JudgeRequest): SystemOneRequest {\n\t\treturn {\n\t\t\tstate: request.state,\n\t\t\tmodel: this.model,\n\t\t\tquestions: Object.fromEntries(\n\t\t\t\tObject.entries(request.questions).map(([id, question]) => [\n\t\t\t\t\tid,\n\t\t\t\t\tquestionToSystemOne(question),\n\t\t\t\t]),\n\t\t\t),\n\t\t}\n\t}\n\n\t/**\n\t * Decodes requested System One answers and reports the server model and available usage.\n\t *\n\t * @param value - The parsed response body\n\t * @param request - The questions defining the expected answers\n\t * @returns The decoded distributions, model, and available usage\n\t * @throws JudgeError Thrown when the envelope is malformed or an answer is invalid (code `PROTOCOL`);\n\t * the message names the question id of an invalid answer\n\t */\n\tread(value: unknown, request: JudgeRequest): JudgeResult {\n\t\tif (!isSystemOneResponse(value)) {\n\t\t\tthrow new JudgeError('PROTOCOL', 'judge error: invalid System One response envelope')\n\t\t}\n\t\tconst entries = Object.entries(request.questions).map(([id, question]) => {\n\t\t\tif (!Object.hasOwn(value.answers, id)) {\n\t\t\t\tthrow new JudgeError('PROTOCOL', `judge error: question ${id} has no System One answer`)\n\t\t\t}\n\t\t\tconst wire = value.answers[id]\n\t\t\tif (!isSystemOneAnswer(wire)) {\n\t\t\t\tthrow new JudgeError(\n\t\t\t\t\t'PROTOCOL',\n\t\t\t\t\t`judge error: question ${id} has an invalid System One answer`,\n\t\t\t\t)\n\t\t\t}\n\t\t\tconst answer = extractSystemOneAnswer(wire, question)\n\t\t\tif (answer === undefined) {\n\t\t\t\tthrow new JudgeError(\n\t\t\t\t\t'PROTOCOL',\n\t\t\t\t\t`judge error: question ${id} has a mismatched or incomplete System One answer`,\n\t\t\t\t)\n\t\t\t}\n\t\t\treturn [id, answer] as const\n\t\t})\n\t\tconst usage = extractSystemOneUsage(value.usage)\n\t\treturn {\n\t\t\tmodel: value.model ?? this.model,\n\t\t\tanswers: Object.fromEntries(entries),\n\t\t\t...(usage === undefined ? {} : { usage }),\n\t\t}\n\t}\n}\n","import type {\n\tProviderInterface,\n\tRelayHandler,\n\tRelayOptions,\n\tRelayProviderOptions,\n\tSystemOneJudgeOptions,\n\tThinkSplitterInterface,\n} from './types.js'\nimport type { JudgeInterface } from '../types.js'\nimport { parseJSONAs } from '@orkestrel/contract'\nimport {\n\tDEFAULT_RELAY_LIMIT,\n\tINVALID_RELAY_STATUS,\n\tOVERSIZED_RELAY_STATUS,\n\tUNAUTHORIZED_RELAY_STATUS,\n\tUPSTREAM_RELAY_STATUS,\n} from './constants.js'\nimport { readText } from './helpers.js'\nimport { providerRequestContract } from './contracts.js'\nimport { RelayStream } from './RelayStream.js'\nimport { RelayProvider } from './RelayProvider.js'\nimport { ThinkSplitter } from './ThinkSplitter.js'\nimport { SystemOneJudge } from './SystemOneJudge.js'\n\n/**\n * Creates an authorized relay handler that validates a bounded JSON request before streaming.\n *\n * @remarks\n * Answers with the `401` status when authorization refuses or throws, the `400`\n * status when the body is missing, unreadable, or invalid, the `413` status when\n * the body fills its byte budget or the inbound read is aborted, and the `502`\n * status when the upstream provider call cannot be constructed. Refusals carry no body.\n *\n * @param options - The upstream provider, authorization decision, and optional byte budget\n * @returns A fetch-standard handler suitable for a router\n * @example Mounting the relay on your server\n * ```ts\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { createRelay } from '@orkestrel/agent'\n * import { createDispatcher } from '@orkestrel/router'\n * import { createServer } from '@orkestrel/server'\n *\n * declare const upstream: ProviderInterface // the server-side provider holding the credential\n * declare const bearer: string\n *\n * const handler = createRelay({\n * \tprovider: upstream,\n * \tauthorize: (request) => request.headers.get('authorization') === `Bearer ${bearer}`,\n * })\n * const dispatcher = createDispatcher({\n * \troutes: [{ method: 'POST', path: '/relay', handler }],\n * })\n *\n * export function serve(request: Request): Promise<Response> {\n * \treturn dispatcher.handle(request, undefined)\n * }\n *\n * const server = createServer({ dispatcher, state: () => undefined })\n * await server.start()\n * process.on('SIGTERM', () => server.stop()) // signal cancellation, drain, then close the listener\n * ```\n */\nexport function createRelay(options: RelayOptions): RelayHandler {\n\tconst { provider, authorize, limit } = options\n\treturn async (request) => {\n\t\ttry {\n\t\t\tif ((await authorize(request)) !== true) {\n\t\t\t\treturn new Response(undefined, { status: UNAUTHORIZED_RELAY_STATUS })\n\t\t\t}\n\t\t} catch {\n\t\t\treturn new Response(undefined, { status: UNAUTHORIZED_RELAY_STATUS })\n\t\t}\n\t\tif (request.body === null) return new Response(undefined, { status: INVALID_RELAY_STATUS })\n\t\tconst read = await readText(request.body, limit ?? DEFAULT_RELAY_LIMIT, request.signal).catch(\n\t\t\t() => undefined,\n\t\t)\n\t\tif (read === undefined) {\n\t\t\treturn new Response(undefined, {\n\t\t\t\tstatus: request.signal.aborted ? OVERSIZED_RELAY_STATUS : INVALID_RELAY_STATUS,\n\t\t\t})\n\t\t}\n\t\tif (!read.complete) return new Response(undefined, { status: OVERSIZED_RELAY_STATUS })\n\t\tconst parsed = parseJSONAs(read.text, providerRequestContract.is)\n\t\tif (parsed === undefined) return new Response(undefined, { status: INVALID_RELAY_STATUS })\n\t\ttry {\n\t\t\treturn new RelayStream({ provider, request: parsed, signal: request.signal }).response\n\t\t} catch {\n\t\t\treturn new Response(undefined, { status: UPSTREAM_RELAY_STATUS })\n\t\t}\n\t}\n}\n\n/**\n * Creates a provider that carries calls through a relay endpoint.\n *\n * @remarks\n * This is the browser end alone. {@link createRelay} mounts the server end, and its example\n * is the server half this one pairs with.\n *\n * @param options - The endpoint, parser factory, and HTTP call configuration\n * @returns The relay provider behind the shared provider interface; construct\n * {@link RelayProvider} directly to reach its wire seams\n * @example Reaching the relay from the browser\n * ```ts\n * import type { ProviderInterface, ProviderParserInterface } from '@orkestrel/agent'\n * import { createRelayProvider, ProviderError } from '@orkestrel/agent'\n * import { createAbort } from '@orkestrel/abort'\n * import { isRecord, parseJSONAs } from '@orkestrel/contract'\n *\n * class RelayFrameParser implements ProviderParserInterface {\n * \t#pending = ''\n * \tparse(chunk: string): ReadonlyArray<Readonly<Record<string, unknown>>> {\n * \t\tthis.#pending += chunk\n * \t\tconst lines = this.#pending.split(/\\r\\n|\\n/)\n * \t\tthis.#pending = lines.pop() ?? ''\n * \t\treturn lines\n * \t\t\t.filter((line) => line.trim().length > 0)\n * \t\t\t.map((line) => {\n * \t\t\t\tconst record = parseJSONAs(line, isRecord)\n * \t\t\t\tif (record === undefined) throw new ProviderError('PROTOCOL', 'invalid JSON record')\n * \t\t\t\treturn record\n * \t\t\t})\n * \t}\n * \tclear(): void {\n * \t\tthis.#pending = ''\n * \t}\n * }\n *\n * declare const bearer: string\n * const abort = createAbort()\n * const messages = [{ id: '1', role: 'user', content: 'Say hello.' }] as const\n *\n * const browser: ProviderInterface = createRelayProvider({\n * \turl: 'https://app.example/relay',\n * \tparser: () => new RelayFrameParser(),\n * \theaders: () => ({ authorization: `Bearer ${bearer}` }),\n * })\n * const result = await browser.generate(messages, abort.signal) // a ProviderResult like a local provider's\n * ```\n */\nexport function createRelayProvider(options: RelayProviderOptions): ProviderInterface {\n\treturn new RelayProvider(options)\n}\n\n/**\n * Creates a fresh stream-stateful `<think>` separator — a {@link ThinkSplitterInterface} that\n * splits a thinking model's in-content `<think>…</think>` reasoning spans away from the answer,\n * delta by delta, so a provider yields clean content alone and surfaces the accumulated\n * reasoning as {@link import('./types.js').ProviderResult.thinking}. One splitter serves one\n * stream.\n *\n * @remarks\n * Feed each raw wire delta through `split(delta)` (it returns the clean content to\n * surface — possibly `''` mid-think) and settle the stream end with `flush()` (a held\n * partial open tag that never completed returns as final content; an unclosed think\n * span lands on `thinking`). Tags split across deltas are held back until\n * disambiguated, multiple spans accumulate in order, and a nested-looking `<think>`\n * inside an open span is thinking text. One splitter serves one stream — create\n * a fresh one per provider call.\n *\n * @returns A fresh {@link ThinkSplitterInterface} (state empty, outside any span)\n *\n * @example\n * ```ts\n * import { createThinkSplitter } from '@orkestrel/agent'\n *\n * const splitter = createThinkSplitter()\n * const clean = splitter.split('<think>plan the answer</think>Here it is.')\n * clean // 'Here it is.'\n * splitter.thinking // 'plan the answer'\n * ```\n */\nexport function createThinkSplitter(): ThinkSplitterInterface {\n\treturn new ThinkSplitter()\n}\n\n/**\n * Creates a judge that sends every question through the configured System One server.\n *\n * @param options - The server origin, model, and optional transport, headers, and timeout\n * @returns The configured judge behind its shared interface\n * @example\n * ```ts\n * const judge = createSystemOneJudge({ url: 'http://localhost:11434', model: 'tev1:0.8b' })\n * ```\n */\nexport function createSystemOneJudge(options: SystemOneJudgeOptions): JudgeInterface {\n\treturn new SystemOneJudge(options)\n}\n","/**\n * Sets the default number of recent live messages the `compact()` method of a\n * {@link ConversationInterface} retains verbatim — `0`, so a manual `compact()` keeps no recent tail and folds every\n * exchange before the newest user message into one summarized section. A caller retains a recent\n * tail by passing `keep` (on\n * {@link ConversationOptions}, {@link ConversationManagerOptions}, or per-fold through\n * {@link CompactOptions}), folding at most the older `count - keep` messages, cut back to whole\n * exchanges, and leaving at least the most recent `keep` live for the next turn. Overridable everywhere `keep` is accepted.\n */\nexport const DEFAULT_CONVERSATION_KEEP = 0\n\n/**\n * Names the framing label the `view()` method of a {@link ConversationInterface} prefixes onto the\n * summary of each compacted section so a small model reads it as a condensed recap of earlier turns — the lean\n * `'[Summary of earlier messages] '` marker, never a literal assistant turn to echo or treat as\n * the live answer.\n *\n * @remarks\n * Deliberately a fixed, lean handful of tokens (a short bracketed marker) so the framing adds a\n * bounded `prefix × sections` overhead and never an open-ended blow-up — the\n * {@link ConversationInterface} no-bloat test guard pins exactly that. Kept here (beside\n * {@link DEFAULT_CONVERSATION_KEEP}) as the one tunable framing constant of the conversation\n * layer, so the wording has a single source of truth (the `view()` recap framing is distinct\n * from the cross-conversation provenance marker of `reference()`, which is rendered inline\n * because it interpolates the per-call provenance `label`).\n */\nexport const CONVERSATION_RECAP_PREFIX = '[Summary of earlier messages] '\n","import type { ConversationErrorCode } from './types.js'\nimport type { CodedErrorOptions } from '../types.js'\nimport { INTRINSICS, holds, isObject, isFunction } from '@orkestrel/contract'\n\n/**\n * Reports a conversation with no {@link ConversationSummaryHandler} to fold its messages with, a\n * `sections` cap below `1`, a `keep` that is not a nonnegative safe integer, or a judgment or\n * judge request that JSON cannot carry — thrown by the `compact()` method of a\n * {@link ConversationInterface}, its construction, or its judgment store, carrying the\n * machine-readable `code` `'SUMMARIZER' | 'SECTIONS' | 'JUDGMENT' | 'KEEP'`.\n *\n * @remarks\n * Compaction requires a summarizer (it digests the folded slice into a section summary); a\n * conversation created without one can still store + `view()` its live tail, but a `compact()`\n * is a programmer error and throws this with `'SUMMARIZER'`.\n * A `sections` cap (on {@link import('./types.js').ConversationOptions} /\n * {@link import('./types.js').ConversationManagerOptions} /\n * {@link import('./types.js').CompactOptions}) must be `>= 1`, and cannot combine with\n * `rolling` — either is a programmer error and throws this with `'SECTIONS'`. A `keep` on the same options must be a nonnegative\n * safe integer — any other value is a programmer error and throws this with `'KEEP'`. A judgment\n * record or a judge request that JSON cannot carry, or whose copy fails its guard, is a\n * programmer error and throws this with `'JUDGMENT'`, its `context` naming the `question` id\n * where one exists. Narrow a caught value with {@link isConversationError} and branch on\n * `error.code`.\n */\nexport class ConversationError extends Error {\n\t/** Names the machine-readable condition — `'SUMMARIZER'`: a `compact()` with no summarizer; `'SECTIONS'`: a sub-1 `sections` cap, or a cap combined with `rolling`; `'JUDGMENT'`: a judgment or judge request that is not JSON; `'KEEP'`: a `keep` that is not a nonnegative safe integer. */\n\treadonly code: ConversationErrorCode\n\t/** Holds the values that locate the failure, such as the `question` id of a malformed question, or `undefined` when none were supplied. */\n\treadonly context: Readonly<Record<string, unknown>> | undefined\n\n\t/**\n\t * Creates the error with its code, message, and optional cause and context.\n\t *\n\t * @param code - The machine-readable {@link ConversationErrorCode}\n\t * @param message - The human-readable description\n\t * @param options - The optional {@link CodedErrorOptions}; `cause` reaches `Error.cause` only when present\n\t */\n\tconstructor(code: ConversationErrorCode, message: string, options?: CodedErrorOptions) {\n\t\tsuper(message, options?.cause === undefined ? undefined : { cause: options.cause })\n\t\tthis.name = 'ConversationError'\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/agent.ConversationError'), { value: this })\n\t\tthis.code = code\n\t\tthis.context = options?.context\n\t}\n}\n\n/**\n * Narrows an unknown caught value to a {@link ConversationError} through its identity brand and declared members, so a\n * `catch` can branch on its `code`.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns True if `value` is a {@link ConversationError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tawait conversation.compact()\n * } catch (error) {\n * \tif (isConversationError(error) && error.code === 'SUMMARIZER') addSummarizer()\n * }\n * ```\n */\nexport function isConversationError(value: unknown): value is ConversationError {\n\treturn holds(() => {\n\t\tif (\n\t\t\t!(\n\t\t\t\tvalue instanceof Error &&\n\t\t\t\tINTRINSICS.prototype(value) !== Error.prototype &&\n\t\t\t\tINTRINSICS.describe(value, Symbol.for('@orkestrel/agent.ConversationError'))?.value ===\n\t\t\t\t\tvalue\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\tconst code = INTRINSICS.reflect.read(value, 'code')\n\t\tif (!(code === 'SUMMARIZER' || code === 'SECTIONS' || code === 'JUDGMENT' || code === 'KEEP'))\n\t\t\treturn false\n\t\tconst context = INTRINSICS.reflect.read(value, 'context')\n\t\treturn context === undefined || isObject(context) || isFunction(context)\n\t})\n}\n","import type { ConversationSnapshot, Section } from './types.js'\nimport type { Judgment, Message } from '../types.js'\nimport { isTokenUsage } from '@orkestrel/budget'\nimport {\n\tarrayOf,\n\tattempt,\n\tisFiniteNumber,\n\tisRecord,\n\tisString,\n\toptionalOf,\n\tobjectOf,\n\trecordOf,\n} from '@orkestrel/contract'\nimport { isToolCall } from '@orkestrel/tool'\nimport { MESSAGE_ROLES } from '../constants.js'\nimport { isJudgeQuestion } from '../validators.js'\n\n/**\n * Checks whether a value satisfies the domain conversation-message contract.\n *\n * @remarks\n * Roles belong to MessageRole, image elements are strings, `thinking` is a string, and `call` is a string on any\n * role, as the flat Message type admits. Tool arguments may carry non-JSON values, as the\n * domain type permits; the message wire contract is narrower. Unreadable fields and hostile\n * inputs return false.\n *\n * @param value - The unknown message candidate\n * @returns True if the domain message fields are valid; false otherwise\n * @example\n * ```ts\n * isMessage({ id: '1', role: 'user', content: 'hi' }) // true\n * isMessage({ id: '1', role: 'other', content: '' }) // false\n * isMessage({ id: '1', role: 'user', content: '', images: [1] }) // false\n * isMessage({ id: '1', role: 'assistant', content: '', thinking: 1 }) // false\n * ```\n */\nexport function isMessage(value: unknown): value is Message {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { id, role, content, calls, call, images, thinking } = value\n\t\tif (!isString(id) || !isString(content)) return false\n\t\tif (!MESSAGE_ROLES.some((one) => one === role)) return false\n\t\tif (calls !== undefined && !arrayOf(isToolCall)(calls)) return false\n\t\tif (call !== undefined && !isString(call)) return false\n\t\tif (images !== undefined && !arrayOf(isString)(images)) return false\n\t\treturn thinking === undefined || isString(thinking)\n\t})\n\treturn checked.success && checked.value\n}\n\n/**\n * Checks whether a stored judgment carries a valid question and exactly one answer or refusal.\n *\n * @remarks\n * Unknown members, malformed members, and unreadable inputs return false. Answer fields follow\n * the root judge value types; this storage guard does not impose a wire's probability or\n * candidate limits. The `time`, `noul`, and probability numbers must be finite, because a stored\n * record is owned through JSON, which turns `NaN` and the infinities into `null`; so every record\n * this guard accepts hydrates through a `JudgmentManager`.\n *\n * @param value - The unknown stored record\n * @returns True if the record satisfies the judgment contract; false otherwise\n * @example\n * ```ts\n * isJudgment({ id: 'q', question: { form: 'noul' }, answer: { form: 'noul', noul: 0.9 }, model: 'judge', sources: [], state: 'text', time: 0 }) // true\n * isJudgment({ id: 'q' }) // false\n * ```\n */\nexport function isJudgment(value: unknown): value is Judgment {\n\tconst checked = attempt(() => {\n\t\tif (!isRecord(value)) return false\n\t\tconst { answer, refusal } = value\n\t\tif (\n\t\t\t!recordOf(\n\t\t\t\t{\n\t\t\t\t\tid: isString,\n\t\t\t\t\tquestion: isJudgeQuestion,\n\t\t\t\t\tmodel: isString,\n\t\t\t\t\tsources: arrayOf(isString),\n\t\t\t\t\tstate: isString,\n\t\t\t\t\ttime: isFiniteNumber,\n\t\t\t\t\tusage: optionalOf(isTokenUsage),\n\t\t\t\t\t...(answer === undefined ? { refusal: isRecord } : { answer: isRecord }),\n\t\t\t\t},\n\t\t\t\t['usage'],\n\t\t\t)(value)\n\t\t)\n\t\t\treturn false\n\t\tif (answer === undefined) return objectOf({ missing: arrayOf(isString) })(refusal)\n\t\tif (refusal !== undefined || !isRecord(answer)) return false\n\t\tif (answer.form === 'noul') return isFiniteNumber(answer.noul)\n\t\tif (answer.form === 'score') return arrayOf(isFiniteNumber)(answer.probabilities)\n\t\treturn (\n\t\t\tanswer.form === 'choice' &&\n\t\t\tisRecord(answer.probabilities) &&\n\t\t\tObject.values(answer.probabilities).every(isFiniteNumber)\n\t\t)\n\t})\n\treturn checked.success && checked.value\n}\n\n/**\n * Checks whether an `unknown` is structurally a {@link Section} record — a `string` `id` and\n * `summary` beside a `messages` array of valid {@link Message} records, the per-section step of\n * the {@link isConversationSnapshot} read-boundary narrow. Total, never throwing, and never an\n * assertion.\n *\n * @remarks\n * A total guard (it never throws — adversarial input, a throwing getter included, returns\n * `false`). It checks the shape of the section: a record with a `string` `id`, a `string`\n * `summary`, and a dense `messages` array every element of which is a valid {@link Message}\n * record ({@link isMessage}); a sparse `messages` array is refused. Enough to safely impose\n * the {@link Section} type at a storage boundary without a cast.\n *\n * @param value - The value to test (one element of a snapshot's `sections` array)\n * @returns True if `value` has the structural shape of a {@link Section}; false otherwise\n *\n * @example\n * ```ts\n * isSection({ id: 's', summary: 'recap', messages: [{ id: '1', role: 'user', content: 'hi' }] }) // true\n * isSection({ id: 's', summary: 'recap', messages: 'nope' }) // false\n * isSection({ id: 's', messages: [] }) // false (missing summary)\n * ```\n */\nexport function isSection(value: unknown): value is Section {\n\treturn (\n\t\tisRecord(value) &&\n\t\tobjectOf({ id: isString, summary: isString, messages: arrayOf(isMessage) })(value)\n\t)\n}\n\n/**\n * Narrows an `unknown` to a {@link ConversationSnapshot} — a `string` `id` and valid\n * `sections` and `messages` arrays; the total boundary guard for an untrusted snapshot read (a storage row a\n * {@link import('./stores/DatabaseConversationStore.js').DatabaseConversationStore}\n * reads back from its opaque JSON column, a snapshot loaded from disk), never throwing. The exact\n * analogue of {@link import('@orkestrel/workspace').isWorkspaceSnapshot}.\n *\n * @remarks\n * A total guard (it never throws — adversarial input returns `false`). It checks the shape of the\n * snapshot: a `string` `id`, a `sections` array every element of which is a valid\n * {@link Section} ({@link isSection}), a `messages` array every element of which is a\n * valid {@link Message} ({@link isMessage}), and optional valid `judgments` — enough to safely\n * impose the\n * {@link ConversationSnapshot} type at a storage boundary without a cast. The structural twin of\n * {@link import('@orkestrel/workspace').isWorkspaceSnapshot}. Unknown members are admitted, so a\n * 0.0.29 snapshot that carries a conversation `summary` passes. A malformed blob (a non-record,\n * a missing / non-string `id`, a non-array `sections` / `messages`, or any malformed\n * element) resolves `false`, so a\n * {@link import('./stores/DatabaseConversationStore.js').DatabaseConversationStore}\n * read yields `undefined` rather than a broken conversation.\n *\n * @param value - The value to test (an opaque storage read)\n * @returns True if `value` has the structural shape of a {@link ConversationSnapshot}; false otherwise\n *\n * @example\n * ```ts\n * isConversationSnapshot({ id: 'c1', sections: [], messages: [] }) // true\n * isConversationSnapshot({ id: 'c1', sections: 'nope', messages: [] }) // false\n * isConversationSnapshot({ sections: [], messages: [] }) // false (missing id)\n * ```\n */\nexport function isConversationSnapshot(value: unknown): value is ConversationSnapshot {\n\treturn (\n\t\tisRecord(value) &&\n\t\tobjectOf(\n\t\t\t{\n\t\t\t\tid: isString,\n\t\t\t\tsections: arrayOf(isSection),\n\t\t\t\tmessages: arrayOf(isMessage),\n\t\t\t\tjudgments: optionalOf(arrayOf(isJudgment)),\n\t\t\t},\n\t\t\t['judgments'],\n\t\t)(value)\n\t)\n}\n","import type { Section } from './types.js'\nimport type { JudgeRequest, JudgeResult, Judgment, JudgmentInput, Message } from '../types.js'\nimport { CONVERSATION_RECAP_PREFIX } from './constants.js'\nimport { ConversationError } from './errors.js'\nimport { isJudgment } from './validators.js'\nimport { isNonNegativeSafeInteger } from '../validators.js'\n\n/**\n * Builds records for answered or refused request keys, attaching usage only for a single question.\n *\n * @param request - The request whose question keys define record order\n * @param result - The reported answers, refusals, model, and usage\n * @param sources - The ordered source message ids\n * @param state - The rendered state read by the judge\n * @param model - The configured judge identity the records carry\n * @returns Inputs for completed question keys in request order\n * @example\n * ```ts\n * buildJudgments(request, result, ['message-a'], 'Charged twice', judge.model)\n * ```\n */\nexport function buildJudgments(\n\trequest: JudgeRequest,\n\tresult: JudgeResult,\n\tsources: readonly string[],\n\tstate: string,\n\tmodel: string,\n): readonly JudgmentInput[] {\n\tconst single = Object.keys(request.questions).length === 1\n\treturn Object.entries(request.questions).flatMap(([id, question]): readonly JudgmentInput[] => {\n\t\tconst answer = Object.hasOwn(result.answers, id) ? result.answers[id] : undefined\n\t\tconst refusal =\n\t\t\tresult.refusals !== undefined && Object.hasOwn(result.refusals, id)\n\t\t\t\t? result.refusals[id]\n\t\t\t\t: undefined\n\t\tif (answer === undefined && refusal === undefined) return []\n\t\treturn [\n\t\t\t{\n\t\t\t\tid,\n\t\t\t\tquestion,\n\t\t\t\tmodel,\n\t\t\t\tsources,\n\t\t\t\tstate,\n\t\t\t\t...(answer !== undefined ? { answer } : refusal !== undefined ? { refusal } : {}),\n\t\t\t\t...(single && result.usage !== undefined ? { usage: result.usage } : {}),\n\t\t\t},\n\t\t]\n\t})\n}\n\n/**\n * Builds the raw synthetic summary message for one compacted section — role `'assistant'`, the\n * section's stable `id`, and its `summary` verbatim as content.\n *\n * @remarks\n * Pure and total. This is the unframed form a `sections` cap merge digests when it folds the\n * oldest sections into one (a summary over their section summaries); the recap label is absent\n * from that merge input. A rolling fold instead re-reads the framed recap — see\n * {@link buildRecapMessage}.\n *\n * @param section - The compacted section to render\n * @returns The synthetic summary message\n *\n * @example\n * ```ts\n * buildSummaryMessage({ id: 's1', summary: 'recap', messages: [] })\n * // { id: 's1', role: 'assistant', content: 'recap' }\n * ```\n */\nexport function buildSummaryMessage(section: Section): Message {\n\treturn { id: section.id, role: 'assistant', content: section.summary }\n}\n\n/**\n * Builds the framed recap message for one compacted section — the same role and stable `id` as\n * {@link buildSummaryMessage}, with the content prefixed by {@link\n * import('./constants.js').CONVERSATION_RECAP_PREFIX}.\n *\n * @remarks\n * Pure and total. The prefix is what makes a small model read the message as a condensed\n * recap of earlier turns rather than a literal assistant turn to echo or answer from. It is a\n * fixed handful of tokens, so a conversation's `view()` stays lean however many sections it\n * carries.\n *\n * @param section - The compacted section to render\n * @returns The framed recap message\n *\n * @example\n * ```ts\n * buildRecapMessage({ id: 's1', summary: 'recap', messages: [] })\n * // { id: 's1', role: 'assistant', content: `${CONVERSATION_RECAP_PREFIX}recap` }\n * ```\n */\nexport function buildRecapMessage(section: Section): Message {\n\treturn {\n\t\tid: section.id,\n\t\trole: 'assistant',\n\t\tcontent: `${CONVERSATION_RECAP_PREFIX}${section.summary}`,\n\t}\n}\n\n/**\n * Returns a stored judgment record after checking it, or throws a coded error.\n *\n * @remarks\n * A stored record is the JSON copy of its input, so a proxied record is accepted and the stored\n * value is exactly what a snapshot can carry. The check is {@link isJudgment}.\n *\n * @param value - The JSON copy of a judgment record or input\n * @returns The value, narrowed to a {@link Judgment}\n * @throws ConversationError Thrown when the value is not a valid judgment record (code `'JUDGMENT'`)\n *\n * @example\n * ```ts\n * requireJudgment(copyJSON(record)) // the record, narrowed\n * requireJudgment({ id: 'refund' }) // throws ConversationError ('JUDGMENT')\n * ```\n */\nexport function requireJudgment(value: unknown): Judgment {\n\tif (!isJudgment(value)) {\n\t\tthrow new ConversationError('JUDGMENT', 'conversation error: a judgment must be a JSON record')\n\t}\n\treturn value\n}\n\n/**\n * Returns a `sections` cap after checking its lower bound, or throws a coded error.\n *\n * @remarks\n * A supplied cap must satisfy `>= 1`; fractional caps and positive infinity pass, and `NaN`\n * is refused. An absent cap leaves the sections list unbounded.\n *\n * @param cap - The cap to check, or `undefined` for no cap\n * @returns The cap unchanged, or `undefined` when none was supplied\n * @throws ConversationError Thrown when the cap does not satisfy `>= 1` (code `'SECTIONS'`, including `NaN`)\n *\n * @example\n * ```ts\n * requireSectionsCap(2) // 2\n * requireSectionsCap(undefined) // undefined\n * requireSectionsCap(0) // throws ConversationError ('SECTIONS')\n * ```\n */\nexport function requireSectionsCap(cap: number | undefined): number | undefined {\n\tif (cap !== undefined && !(cap >= 1)) {\n\t\tthrow new ConversationError('SECTIONS', 'a sections cap must be >= 1')\n\t}\n\treturn cap\n}\n\n/**\n * Returns the rolling switch after checking it does not combine with a `sections` cap, or throws a\n * coded error.\n *\n * @remarks\n * A rolling conversation keeps one section, so a cap has nothing to bound. The cap checked is the\n * effective one: inherited from a manager, configured on the conversation, or supplied to one\n * `compact()` call.\n *\n * @param rolling - Whether folds roll every prior section into one\n * @param cap - The effective `sections` cap, or `undefined` for none\n * @returns The rolling switch unchanged\n * @throws ConversationError Thrown when `rolling` is true and a cap is present (code `'SECTIONS'`)\n *\n * @example\n * ```ts\n * requireRolling(true, undefined) // true\n * requireRolling(false, 2) // false\n * requireRolling(true, 2) // throws ConversationError ('SECTIONS')\n * ```\n */\nexport function requireRolling(rolling: boolean, cap: number | undefined): boolean {\n\tif (rolling && cap !== undefined) {\n\t\tthrow new ConversationError('SECTIONS', 'rolling cannot combine with a sections cap', {\n\t\t\tcontext: { sections: cap },\n\t\t})\n\t}\n\treturn rolling\n}\n\n/**\n * Returns a retained-tail size after checking it is a nonnegative safe integer, or throws a coded\n * error.\n *\n * @remarks\n * The check is {@link import('../validators.js').isNonNegativeSafeInteger}, so `0` and `-0`\n * pass while `NaN`, a fraction, a negative, and either infinity are refused. The error's `context`\n * carries the refused value as `keep`.\n *\n * @param keep - The retained-tail size to check\n * @returns The size unchanged\n * @throws ConversationError Thrown when `keep` is not a nonnegative safe integer (code `'KEEP'`)\n *\n * @example\n * ```ts\n * requireKeep(2) // 2\n * requireKeep(1.5) // throws ConversationError ('KEEP')\n * ```\n */\nexport function requireKeep(keep: number): number {\n\tif (!isNonNegativeSafeInteger(keep)) {\n\t\tthrow new ConversationError('KEEP', 'a keep must be a nonnegative safe integer', {\n\t\t\tcontext: { keep },\n\t\t})\n\t}\n\treturn keep\n}\n\n/**\n * Settles with a promise, or rejects with the reason of a signal that aborts first, so a caller\n * is released at once even when the work behind the promise ignores the signal.\n *\n * @remarks\n * An absent signal returns `promise` itself. An already-aborted signal rejects with its reason\n * without waiting. The abort listener is removed as soon as `promise` settles. A rejection of\n * `promise` after the abort is handled here and never surfaces as unhandled.\n *\n * @param promise - The work to wait for\n * @param signal - The cancellation signal, or `undefined` for none\n * @returns A promise that settles as `promise` does, or rejects with `signal.reason` on abort\n *\n * @example\n * ```ts\n * const controller = new AbortController()\n * const raced = raceSignal(new Promise<string>(() => {}), controller.signal)\n * controller.abort(new Error('stop'))\n * await raced // rejects with the Error 'stop'\n * ```\n */\nexport function raceSignal<T>(promise: Promise<T>, signal: AbortSignal | undefined): Promise<T> {\n\tif (signal === undefined) return promise\n\treturn new Promise<T>((resolve, reject) => {\n\t\t// Aborting `settled` removes the abort listener once the promise settles.\n\t\tconst settled = new AbortController()\n\t\tif (signal.aborted) reject(signal.reason)\n\t\telse {\n\t\t\tsignal.addEventListener('abort', () => reject(signal.reason), {\n\t\t\t\tonce: true,\n\t\t\t\tsignal: settled.signal,\n\t\t\t})\n\t\t}\n\t\t// Settling an already-rejected race is a no-op, and this handler is what keeps a late\n\t\t// rejection of `promise` from surfacing as unhandled.\n\t\tvoid promise.then(resolve, reject).finally(() => settled.abort())\n\t})\n}\n","import type { JudgmentManagerInterface } from './types.js'\nimport type { JudgeInterface, JudgeRequest, Judgment, JudgmentInput } from '../types.js'\nimport { isArray, isRecord } from '@orkestrel/contract'\nimport { ConversationError } from './errors.js'\nimport { buildJudgments, requireJudgment } from './helpers.js'\nimport { copyJSON } from '../cloners.js'\nimport { JudgeAbortError, isJudgeAbortError } from '../errors.js'\nimport { matchesJudgment, removeEntries } from '../helpers.js'\nimport { isJudgeEntry, isJudgeQuestion } from '../validators.js'\n\n/**\n * Stores judgments in insertion order and asks a judge only for unmatched question identities.\n *\n * @remarks\n * Adding an existing key replaces it without changing its insertion position. Construction\n * restores recorded times; adding stamps the current epoch milliseconds. Caller input is owned\n * through JSON on arrival, so a proxied record or request is accepted where a structured clone\n * refuses it, and records are copied on reads, so callers cannot change the stored identity\n * through nested values.\n *\n * @example\n * ```ts\n * const judgments = new JudgmentManager()\n * const records = await judgments.resolve(judge, request, ['message-a'], signal)\n * ```\n */\nexport class JudgmentManager implements JudgmentManagerInterface {\n\treadonly #judgments: Map<string, Judgment>\n\n\t/**\n\t * Restores records without replacing their storage times.\n\t * @param judgments - The previously stored judgments to restore. Default: an empty list\n\t */\n\tconstructor(judgments: readonly Judgment[] = []) {\n\t\t// `Array.from` visits a hole in `judgments` as an undefined record, which `requireJudgment` refuses; `map` skips it.\n\t\tthis.#judgments = new Map(\n\t\t\tArray.from(judgments, (judgment) => requireJudgment(copyJSON(judgment))).map((owned) => [\n\t\t\t\towned.id,\n\t\t\t\towned,\n\t\t\t]),\n\t\t)\n\t}\n\n\tget count(): number {\n\t\treturn this.#judgments.size\n\t}\n\n\tadd(input: JudgmentInput): Judgment\n\tadd(inputs: readonly JudgmentInput[]): readonly Judgment[]\n\tadd(input: JudgmentInput | readonly JudgmentInput[]): Judgment | readonly Judgment[] {\n\t\tif (isArray(input)) return input.map((one) => this.#store(one))\n\t\treturn this.#store(input)\n\t}\n\n\tjudgment(id: string): Judgment | undefined {\n\t\tconst judgment = this.#judgments.get(id)\n\t\treturn judgment === undefined ? undefined : structuredClone(judgment)\n\t}\n\n\tjudgments(): readonly Judgment[] {\n\t\treturn structuredClone([...this.#judgments.values()])\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) return removeEntries(ids, (id) => this.#judgments.delete(id))\n\t\treturn this.#judgments.delete(ids)\n\t}\n\n\tclear(): void {\n\t\tthis.#judgments.clear()\n\t}\n\n\tasync resolve(\n\t\tjudge: JudgeInterface,\n\t\trequest: JudgeRequest,\n\t\tsources: readonly string[],\n\t\tsignal: AbortSignal,\n\t): Promise<readonly Judgment[]> {\n\t\t// The request is owned through JSON before it is compared or sent, as the judge engine owns\n\t\t// it, so a proxied request is accepted and a caller mutating it mid-flight changes nothing.\n\t\tconst state = copyJSON(request.state)\n\t\tif (!isJudgeEntry(state)) {\n\t\t\tthrow new ConversationError(\n\t\t\t\t'JUDGMENT',\n\t\t\t\t'conversation error: the judge state is not a judge entry',\n\t\t\t)\n\t\t}\n\t\tconst rendered = typeof state === 'string' ? state : JSON.stringify(state)\n\t\tconst origins = [...sources]\n\t\tconst entries = isRecord(request.questions) ? Object.entries(request.questions) : []\n\t\tconst checked = entries.map(([id, raw]) => {\n\t\t\tconst question = copyJSON(raw)\n\t\t\tif (!isJudgeQuestion(question)) {\n\t\t\t\tthrow new ConversationError('JUDGMENT', `conversation error: question ${id} is malformed`, {\n\t\t\t\t\tcontext: { question: id },\n\t\t\t\t})\n\t\t\t}\n\t\t\treturn [id, question] as const\n\t\t})\n\t\tconst matched = new Map(\n\t\t\tchecked.flatMap(([id, question]) => {\n\t\t\t\tconst judgment = this.#judgments.get(id)\n\t\t\t\treturn judgment !== undefined &&\n\t\t\t\t\tmatchesJudgment(judgment, question, origins, rendered, judge.model)\n\t\t\t\t\t? [[id, judgment] as const]\n\t\t\t\t\t: []\n\t\t\t}),\n\t\t)\n\t\tconst pending = checked.filter(([id]) => !matched.has(id))\n\t\tconst added =\n\t\t\tpending.length === 0\n\t\t\t\t? []\n\t\t\t\t: await this.#ask(\n\t\t\t\t\t\tjudge,\n\t\t\t\t\t\t{ state, questions: Object.fromEntries(pending) },\n\t\t\t\t\t\torigins,\n\t\t\t\t\t\trendered,\n\t\t\t\t\t\tsignal,\n\t\t\t\t\t)\n\t\tconst resolved = new Map([\n\t\t\t...matched,\n\t\t\t...added.map((judgment) => [judgment.id, judgment] as const),\n\t\t])\n\t\treturn entries.flatMap(([id]) => {\n\t\t\tconst judgment = resolved.get(id)\n\t\t\treturn judgment === undefined ? [] : [structuredClone(judgment)]\n\t\t})\n\t}\n\n\t// Asks the judge for the unmatched questions and stores what it answered. An aborted ask stores\n\t// its partial answers before it rethrows, so finished work survives the cancellation.\n\tasync #ask(\n\t\tjudge: JudgeInterface,\n\t\tunmatched: JudgeRequest,\n\t\torigins: readonly string[],\n\t\trendered: string,\n\t\tsignal: AbortSignal,\n\t): Promise<readonly Judgment[]> {\n\t\tif (signal.aborted) throw new JudgeAbortError({ model: judge.model, answers: {} })\n\t\ttry {\n\t\t\tconst result = await judge.ask(unmatched, signal)\n\t\t\treturn this.add(buildJudgments(unmatched, result, origins, rendered, judge.model))\n\t\t} catch (error) {\n\t\t\tif (isJudgeAbortError(error))\n\t\t\t\tthis.add(buildJudgments(unmatched, error.partial, origins, rendered, judge.model))\n\t\t\tthrow error\n\t\t}\n\t}\n\n\t#store(input: JudgmentInput): Judgment {\n\t\tconst copy = copyJSON(input)\n\t\tconst judgment = requireJudgment(isRecord(copy) ? { ...copy, time: Date.now() } : copy)\n\t\tthis.#judgments.set(judgment.id, judgment)\n\t\treturn structuredClone(judgment)\n\t}\n}\n","import type {\n\tCompactOptions,\n\tConversationEventMap,\n\tConversationInterface,\n\tConversationOptions,\n\tConversationReferenceOptions,\n\tConversationSnapshot,\n\tConversationSummaryHandler,\n\tJudgmentManagerInterface,\n\tSection,\n} from './types.js'\nimport type { Message, MessageInput } from '../types.js'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { collectExchanges, removeEntries, stripThinking } from '../helpers.js'\nimport { DEFAULT_CONVERSATION_KEEP } from './constants.js'\nimport { ConversationError } from './errors.js'\nimport {\n\tbuildRecapMessage,\n\tbuildSummaryMessage,\n\traceSignal,\n\trequireKeep,\n\trequireRolling,\n\trequireSectionsCap,\n} from './helpers.js'\nimport { JudgmentManager } from './JudgmentManager.js'\n\n/**\n * Represents a conversation — a live uncompacted tail of messages it owns directly above a flat\n * message store, plus compacted, summarized {@link Section} records and a `summarizable` flag,\n * with on-demand `rehydrate` and substring `search`, driven by a provider-agnostic\n * {@link ConversationSummaryHandler} seam so `core` never imports a provider. Observable through\n * its own `emitter`.\n *\n * @remarks\n * - **Live tail + sections.** The conversation owns its live tail directly — `#messages` is an\n * insertion-ordered `Map` of immutable {@link Message} records keyed by their minted id\n * (`add` / `message` / `messages` / `remove` / `clear` / `count`), exactly as a `Workspace`\n * owns its files (no separate per-value manager). `#sections` are the compacted history\n * (oldest → newest), each a summarized slice that retains its originals.\n * - **`view()`.** Each section folds to one synthetic summary message (role `'assistant'` — a\n * prior-context recap — keyed by the stable `id` of the section), then the live messages\n * verbatim. The per-section summaries are the compaction benefit.\n * - **`compact()`.** Folds the oldest `count - keep` live messages into a section (its\n * `summary` from `#summarize`), removes them from the live tail by id, and emits `compact`.\n * The fold stops before the newest user message, so the request a run serves and its turns\n * stay live. An exchange is a user message and every message after it up to the next user\n * message. Leading messages form a separate exchange, retained until the first user exchange\n * can also fold. A cut inside an exchange moves back to its start, so a fold removes whole\n * exchanges. A cut inside an assistant call group, which only a group spanning two exchanges\n * allows, moves before the group, so a tool result never stays live without its call. Returns\n * the section, or `undefined` when nothing folds. A {@link ConversationError} is thrown when no\n * `#summarize` was supplied. Calls run one at a time, a fold commits only when its messages are\n * still the live entries after the summarizer settles, and `options.signal` rejects the call\n * with its reason at once and commits nothing after the abort.\n * - **Rolling.** With `rolling`, a fold makes one summarizer call over the framed recaps of all\n * prior sections then the slice, and replaces those sections with one that retains their\n * originals then the slice. It emits `compact` once and never `collapse`, commits nothing when\n * the call throws, aborts, or the slice or prior sections changed, and cannot combine with a\n * `sections` cap (`'SECTIONS'`).\n * - **`rehydrate(id)` / `search(query)`.** `rehydrate` returns the full original messages of a\n * known section and emits its `id` through `rehydrate`, even when the list is empty. An unknown\n * id returns `undefined` without an event. The read never reinserts messages. `search` is a case-insensitive\n * substring scan of `content` across all messages (the originals of every section + the live\n * tail).\n * - **Observable.** The owned {@link emitter} ({@link ConversationEventMap}) carries\n * `compact` / `collapse` / `rehydrate`, emitted directly, strictly after the state change;\n * the emitter isolates a listener throw and routes it to its `error` handler (the `error`\n * option), so a buggy observer can never corrupt a compaction.\n *\n * @example\n * ```ts\n * const conversation = new Conversation({ summarize: async (m) => `recap of ${m.length}` })\n * conversation.add([\n * \t{ role: 'user', content: 'Hello' },\n * \t{ role: 'assistant', content: 'Hi there' },\n * \t{ role: 'user', content: 'What did I say?' },\n * ])\n * const section = await conversation.compact() // folds the first two into one summarized section\n * conversation.view() // [<recap of 2>, { role: 'user', content: 'What did I say?' }]\n * ```\n */\nexport class Conversation implements ConversationInterface {\n\treadonly #id: string\n\t// The push observation surface — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into a compaction.\n\treadonly #emitter: Emitter<ConversationEventMap>\n\t// The provider-agnostic summarizer seam — `undefined` ⇒ `compact()` throws (a conversation\n\t// can still store + view a live tail; it cannot fold).\n\treadonly #summarize: ConversationSummaryHandler | undefined\n\t// How many recent live messages a `compact()` retains verbatim (older ones fold).\n\treadonly #keep: number\n\t// The optional cap on the compacted sections list — `undefined` ⇒ unlimited. Enforced\n\t// after appending a fresh `compact()` fold: an overflow folds the oldest sections into one.\n\treadonly #cap: number | undefined\n\t// Whether a fold replaces every prior section with one that digests their recaps and the slice.\n\t// Never combined with a cap.\n\treadonly #rolling: boolean\n\t// The compacted history, oldest → newest — each summarized slice retains its originals.\n\t// Replaced on every change rather than mutated in place.\n\t#sections: readonly Section[]\n\t// The live uncompacted tail the conversation owns directly — an insertion-ordered Map of\n\t// immutable messages keyed by their minted id.\n\treadonly #messages: Map<string, Message>\n\treadonly #judgments: JudgmentManager\n\t// The folds in flight, one per `compact()` call from its start until it settles. A later call\n\t// waits on every member it finds, so an aborted waiter never releases it ahead of a fold still\n\t// running.\n\treadonly #pending = new Set<Promise<Section | undefined>>()\n\n\tconstructor(options?: ConversationOptions) {\n\t\t// A summarizer is a function and is never serialized, so it comes from options beside the\n\t\t// snapshot. Restoring is silent: nothing was edited, so no event fires.\n\t\tconst snapshot = options?.snapshot\n\t\tthis.#judgments = new JudgmentManager(snapshot?.judgments)\n\t\tthis.#id = snapshot?.id ?? options?.id ?? crypto.randomUUID()\n\t\tthis.#emitter = new Emitter<ConversationEventMap>(options)\n\t\tthis.#summarize = options?.summarize\n\t\tthis.#keep = requireKeep(options?.keep ?? DEFAULT_CONVERSATION_KEEP)\n\t\tthis.#cap = requireSectionsCap(options?.sections)\n\t\tthis.#rolling = options?.rolling ?? false\n\t\trequireRolling(this.#rolling, this.#cap)\n\t\tthis.#sections = snapshot === undefined ? [] : [...snapshot.sections]\n\t\tthis.#messages = new Map(snapshot?.messages.map((message) => [message.id, message]))\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget judgments(): JudgmentManagerInterface {\n\t\treturn this.#judgments\n\t}\n\n\tget emitter(): EmitterInterface<ConversationEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget sections(): readonly Section[] {\n\t\treturn [...this.#sections]\n\t}\n\n\tget summarizable(): boolean {\n\t\t// True exactly when a summarizer was supplied — the clean signal the automatic compaction of\n\t\t// the agent loop gates on (a non-summarizable conversation is never auto-compacted, so the\n\t\t// auto path never throws the `SUMMARIZER` ConversationError). A manual `compact()` still throws.\n\t\treturn this.#summarize !== undefined\n\t}\n\n\tget count(): number {\n\t\treturn this.#messages.size\n\t}\n\n\tadd(input: MessageInput): Message\n\tadd(inputs: readonly MessageInput[]): readonly Message[]\n\tadd(input: MessageInput | readonly MessageInput[]): Message | readonly Message[] {\n\t\tif (isArray(input)) return input.map((one) => this.#create(one))\n\t\treturn this.#create(input)\n\t}\n\n\tmessage(id: string): Message | undefined {\n\t\treturn this.#messages.get(id)\n\t}\n\n\tmessages(): readonly Message[] {\n\t\treturn [...this.#messages.values()]\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\treturn removeEntries(ids, (id) => this.#messages.delete(id))\n\t\t}\n\t\treturn this.#messages.delete(ids)\n\t}\n\n\tclear(): void {\n\t\tthis.#messages.clear()\n\t}\n\n\tview(): readonly Message[] {\n\t\t// The recap is framed (a `[Summary of earlier messages]` label prefix) so a small model reads\n\t\t// it as a condensed recap of prior turns, not as a literal assistant turn it must echo / treat\n\t\t// as the latest answer — a lean label (a handful of tokens), proven no-bloat by a test guard.\n\t\treturn [\n\t\t\t...this.#sections.map((section) => buildRecapMessage(section)),\n\t\t\t...this.#messages.values(),\n\t\t]\n\t}\n\n\tasync compact(options?: CompactOptions): Promise<Section | undefined> {\n\t\tconst summarize = this.#summarize\n\t\tif (summarize === undefined) {\n\t\t\tthrow new ConversationError(\n\t\t\t\t'SUMMARIZER',\n\t\t\t\t'cannot compact a conversation without a summarizer',\n\t\t\t)\n\t\t}\n\t\tconst cap = requireSectionsCap(options?.sections ?? this.#cap)\n\t\trequireRolling(this.#rolling, cap)\n\t\tconst keep = requireKeep(options?.keep ?? this.#keep)\n\t\tconst signal = options?.signal\n\t\tsignal?.throwIfAborted()\n\t\t// Queue behind every earlier fold, captured before this call adds its own. An earlier waiter\n\t\t// that aborts leaves the folds it waited on in the set, so a later call still waits for them.\n\t\tconst previous = this.#pending.size === 0 ? undefined : Promise.allSettled([...this.#pending])\n\t\tconst fold = this.#fold(previous, summarize, cap, keep, signal)\n\t\tthis.#pending.add(fold)\n\t\tvoid fold.then(\n\t\t\t() => this.#pending.delete(fold),\n\t\t\t() => this.#pending.delete(fold),\n\t\t)\n\t\treturn fold\n\t}\n\n\trehydrate(id: string): readonly Message[] | undefined {\n\t\tconst section = this.#sections.find((one) => one.id === id)\n\t\tif (section === undefined) return undefined\n\t\t// Emitted after resolving, because a read has no mutation for a listener to perturb.\n\t\tthis.#emitter.emit('rehydrate', id)\n\t\treturn section.messages\n\t}\n\n\tsearch(query: string): readonly Message[] {\n\t\t// Section originals (oldest → newest) come before the live tail.\n\t\tconst needle = query.toLowerCase()\n\t\tconst all = [\n\t\t\t...this.#sections.flatMap((section) => section.messages),\n\t\t\t...this.#messages.values(),\n\t\t]\n\t\treturn all.filter((message) => message.content.toLowerCase().includes(needle))\n\t}\n\n\treference(options?: ConversationReferenceOptions): string {\n\t\t// The leading marker states the block is not part of the live conversation, so a small\n\t\t// model reads the cherry-picked excerpts as foreign material it attributes to that source,\n\t\t// never as its own latest turns.\n\t\tconst label = options?.label ?? this.#id\n\t\tconst messages = options?.messages ?? []\n\t\t// `Array.from` visits a hole in `messages` as an undefined message, as iteration does; `map` skips it.\n\t\treturn [\n\t\t\t`[Reference — conversation \"${label}\" — NOT part of this conversation]`,\n\t\t\t...(messages.length > 0\n\t\t\t\t? [\n\t\t\t\t\t\t'Relevant messages:',\n\t\t\t\t\t\t...Array.from(messages, (message) => `- ${message.role}: ${message.content}`),\n\t\t\t\t\t]\n\t\t\t\t: []),\n\t\t].join('\\n')\n\t}\n\n\tsnapshot(): ConversationSnapshot {\n\t\t// The summarizer / keep are not serialized — they are live config re-supplied on hydrate\n\t\t// (a ConversationSummaryHandler is a function, not data).\n\t\treturn {\n\t\t\tid: this.#id,\n\t\t\tsections: this.sections,\n\t\t\tmessages: this.messages(),\n\t\t\t...(this.#judgments.count === 0 ? {} : { judgments: this.#judgments.judgments() }),\n\t\t}\n\t}\n\n\t// One serialized fold: wait for the earlier call, read the live tail, summarize, then commit\n\t// only what is unchanged. Every await is raced against the signal and followed by a check, so\n\t// an abort commits nothing after it.\n\tasync #fold(\n\t\tprevious: Promise<unknown> | undefined,\n\t\tsummarize: ConversationSummaryHandler,\n\t\tcap: number | undefined,\n\t\tkeep: number,\n\t\tsignal: AbortSignal | undefined,\n\t): Promise<Section | undefined> {\n\t\tif (previous !== undefined) await raceSignal(previous, signal)\n\t\tsignal?.throwIfAborted()\n\t\tconst live = [...this.#messages.values()]\n\t\t// The newest user message is the request a run serves, so it and its turns stay live.\n\t\tconst newest = live.findLastIndex((message) => message.role === 'user')\n\t\tconst first = live.findIndex((message) => message.role === 'user')\n\t\tconst wanted = Math.min(\n\t\t\tkeep <= 0 ? live.length : live.length - keep,\n\t\t\tnewest === -1 ? live.length : newest,\n\t\t)\n\t\t// A cut inside an exchange moves back to that exchange's start so a whole exchange folds or\n\t\t// stays. At most one exchange strictly contains the cut.\n\t\tconst { aligned } = collectExchanges(live).reduce(\n\t\t\t(cut, exchange) => {\n\t\t\t\tconst end = cut.start + exchange.length\n\t\t\t\treturn { start: end, aligned: cut.start < wanted && wanted < end ? cut.start : cut.aligned }\n\t\t\t},\n\t\t\t{ start: 0, aligned: wanted },\n\t\t)\n\t\t// Retain the leading context until the first user exchange can fold with it.\n\t\tconst fold = first >= 0 && aligned <= first ? 0 : aligned\n\t\tif (fold <= 0) return undefined\n\t\tconst slice = live.slice(0, fold)\n\t\t// A rolling fold digests every prior recap (framed, oldest first) ahead of the slice in one\n\t\t// call; the originals behind those recaps are never sent.\n\t\tconst prior = this.#rolling ? this.#sections : []\n\t\tconst request = [...prior.map((one) => buildRecapMessage(one)), ...stripThinking(slice, 'none')]\n\t\tconst summary = await raceSignal(summarize(request, signal), signal)\n\t\tsignal?.throwIfAborted()\n\t\t// A `remove` or `clear` while the summarizer ran changed what this fold covers, so commit\n\t\t// nothing rather than fold messages the caller dropped back into a section.\n\t\tif (!slice.every((message) => this.#messages.get(message.id) === message)) return undefined\n\t\t// The recaps the digest covers must still be the sections held, or the replacement would drop\n\t\t// a section it never summarized.\n\t\tif (\n\t\t\tthis.#rolling &&\n\t\t\t(this.#sections.length !== prior.length ||\n\t\t\t\t!prior.every((one, index) => this.#sections[index] === one))\n\t\t) {\n\t\t\treturn undefined\n\t\t}\n\t\tconst section: Section = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\tsummary,\n\t\t\tmessages: this.#rolling ? [...prior.flatMap((one) => one.messages), ...slice] : slice,\n\t\t}\n\t\tfor (const message of slice) this.#messages.delete(message.id)\n\t\tthis.#sections = this.#rolling ? [section] : [...this.#sections, section]\n\t\t// Preserve the original sections if the merge fails by replacing them only after summarizing.\n\t\tif (cap !== undefined && this.#sections.length > cap) {\n\t\t\tconst overflow = this.#sections.length - cap + 1\n\t\t\tconst folded = this.#sections.slice(0, overflow)\n\t\t\tconst digest = await raceSignal(\n\t\t\t\tsummarize(\n\t\t\t\t\tfolded.map((one) => buildSummaryMessage(one)),\n\t\t\t\t\tsignal,\n\t\t\t\t),\n\t\t\t\tsignal,\n\t\t\t)\n\t\t\tsignal?.throwIfAborted()\n\t\t\t// Only a fold changes `#sections`, and folds run one at a time, so the head holds here;\n\t\t\t// the check keeps a merge from ever replacing sections it did not summarize.\n\t\t\tif (!folded.every((one, index) => this.#sections[index] === one)) return undefined\n\t\t\tconst merged: Section = {\n\t\t\t\tid: crypto.randomUUID(),\n\t\t\t\tsummary: digest,\n\t\t\t\tmessages: folded.flatMap((one) => one.messages),\n\t\t\t}\n\t\t\tthis.#sections = [merged, ...this.#sections.slice(overflow)]\n\t\t\tthis.#emitter.emit('collapse', merged)\n\t\t}\n\t\t// Observe the section last, so a swallowed listener throw can't perturb the fold.\n\t\tthis.#emitter.emit('compact', section)\n\t\treturn section\n\t}\n\n\t// Spread each optional only when present, so an absent optional is never stored as `undefined`.\n\t#create(input: MessageInput): Message {\n\t\tconst message: Message = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\trole: input.role,\n\t\t\tcontent: input.content,\n\t\t\t...(input.calls === undefined ? {} : { calls: input.calls }),\n\t\t\t...(input.call === undefined ? {} : { call: input.call }),\n\t\t\t...(input.images === undefined ? {} : { images: input.images }),\n\t\t\t...(input.thinking === undefined ? {} : { thinking: input.thinking }),\n\t\t}\n\t\tthis.#messages.set(message.id, message)\n\t\treturn message\n\t}\n}\n","import type {\n\tConversationInput,\n\tConversationInterface,\n\tConversationManagerInterface,\n\tConversationManagerOptions,\n\tConversationStoreInterface,\n\tConversationSummaryHandler,\n} from './types.js'\nimport { isArray } from '@orkestrel/contract'\nimport { DEFAULT_CONVERSATION_KEEP } from './constants.js'\nimport { Conversation } from './Conversation.js'\nimport { requireKeep } from './helpers.js'\nimport { removeEntries } from '../helpers.js'\n\n/**\n * Registers {@link Conversation} instances keyed by `id`, in insertion order, with an active pointer —\n * the id-keyed store over the conversation layer, the `active` / `switch` seam the\n * {@link import('../contexts/index.js').AgentContext} renders, and the durable `open` / `save`\n * store seam. Event-free (a registry, like\n * {@link import('@orkestrel/workspace').WorkspaceManager}); the observability lives on each\n * {@link Conversation}.\n *\n * @remarks\n * - **Registry.** Conversations live in an insertion-ordered `Map` keyed by `id`. `add(input?)`\n * mints a {@link Conversation} (its `id` from `input` or `crypto.randomUUID()`), flowing the\n * default `#summarize` / `#keep` of the manager in unless the `input` overrides them, and stores\n * it (an already-present `id` overwrites — last write wins). `count` is the map size,\n * `conversation(id)` looks one up, `conversations()` lists them in insertion order.\n * - **Active pointer.** `active` is the active conversation (the agent's message source the\n * context renders), `undefined` until the first `add` (which auto-activates it — a registry\n * with conversations always has one active). A subsequent `add` leaves `active` unchanged.\n * `switch(id)` re-points `active` to the conversation with `id` and returns it; an unknown `id`\n * returns `undefined` and leaves `active` unchanged (the lenient lookup style — never throws,\n * no added error code).\n * - **Removal.** `remove` drops one by id, or a batch — `true` only when every supplied id was\n * removed; removing the active conversation sets `active` to `undefined`. `clear` empties the registry\n * and sets `active` to `undefined`.\n * - **Event-free.** A purely registry store — no Emitter, no events (each conversation owns\n * its own observable `emitter`).\n *\n * @example\n * ```ts\n * const manager = new ConversationManager({ summarize: async (m) => `recap of ${m.length}` })\n * const conversation = manager.add() // auto-activates — active === conversation\n * manager.add({ id: 'scratch' }) // leaves active unchanged\n * manager.switch('scratch') // re-points active to the 'scratch' conversation\n * manager.count // 2\n * ```\n */\nexport class ConversationManager implements ConversationManagerInterface {\n\treadonly #conversations = new Map<string, ConversationInterface>()\n\t// The active conversation's id — the message source the context renders; `undefined` until the\n\t// first `add` auto-activates one (kept as an id, never a stale reference, so a re-add / removal\n\t// of that id is reflected through the live map lookup in `active`).\n\t#active: string | undefined\n\t// The default summarizer flowed into every conversation `add` creates (a per-`add` override\n\t// wins); a conversation created with neither cannot `compact` (it throws a ConversationError).\n\treadonly #summarize: ConversationSummaryHandler | undefined\n\t// The default retained-tail size flowed into every conversation `add` creates (overridable).\n\treadonly #keep: number\n\t// The default `sections` cap flowed into every conversation `add` creates (overridable); `undefined` ⇒ unlimited.\n\treadonly #sections: number | undefined\n\t// The optional durable store backing `open` / `save`; `undefined` ⇒ registry-only (both lenient).\n\treadonly #store: ConversationStoreInterface | undefined\n\n\tconstructor(options?: ConversationManagerOptions) {\n\t\tthis.#summarize = options?.summarize\n\t\tthis.#keep = requireKeep(options?.keep ?? DEFAULT_CONVERSATION_KEEP)\n\t\tthis.#sections = options?.sections\n\t\tthis.#store = options?.store\n\t}\n\n\tget count(): number {\n\t\treturn this.#conversations.size\n\t}\n\n\tget active(): ConversationInterface | undefined {\n\t\treturn this.#active === undefined ? undefined : this.#conversations.get(this.#active)\n\t}\n\n\tconversation(id: string): ConversationInterface | undefined {\n\t\treturn this.#conversations.get(id)\n\t}\n\n\tconversations(): readonly ConversationInterface[] {\n\t\treturn [...this.#conversations.values()]\n\t}\n\n\tadd(input?: ConversationInput): ConversationInterface {\n\t\t// An optional `snapshot` hydrates through the declared `ConversationOptions.snapshot` seam,\n\t\t// so the live summarize / keep ride beside it in the same options object.\n\t\tconst sections = input?.sections ?? this.#sections\n\t\tconst summarize = input?.summarize ?? this.#summarize\n\t\tconst conversation = new Conversation({\n\t\t\t...(input?.id === undefined ? {} : { id: input.id }),\n\t\t\t...(input?.on === undefined ? {} : { on: input.on }),\n\t\t\t...(input?.error === undefined ? {} : { error: input.error }),\n\t\t\t...(summarize === undefined ? {} : { summarize }),\n\t\t\tkeep: input?.keep ?? this.#keep,\n\t\t\t...(sections === undefined ? {} : { sections }),\n\t\t\t...(input?.rolling === undefined ? {} : { rolling: input.rolling }),\n\t\t\t...(input?.snapshot === undefined ? {} : { snapshot: input.snapshot }),\n\t\t})\n\t\tthis.#conversations.set(conversation.id, conversation)\n\t\t// First conversation auto-activates: a registry that holds conversations always has one active.\n\t\tif (this.#active === undefined) this.#active = conversation.id\n\t\treturn conversation\n\t}\n\n\tswitch(id: string): ConversationInterface | undefined {\n\t\t// Lenient (mirrors `conversation(id)`): an unknown id re-points nothing and returns undefined.\n\t\tconst conversation = this.#conversations.get(id)\n\t\tif (conversation === undefined) return undefined\n\t\tthis.#active = id\n\t\treturn conversation\n\t}\n\n\tasync open(id: string): Promise<ConversationInterface | undefined> {\n\t\tconst existing = this.#conversations.get(id)\n\t\tif (existing !== undefined) {\n\t\t\tthis.#active = id\n\t\t\treturn existing\n\t\t}\n\t\tif (this.#store === undefined) return undefined\n\t\tconst snapshot = await this.#store.get(id)\n\t\t// A conversation registered while the read was pending is live state; the stored snapshot\n\t\t// is older, so it must not overwrite it.\n\t\tconst registered = this.#conversations.get(id)\n\t\tif (registered !== undefined) {\n\t\t\tthis.#active = id\n\t\t\treturn registered\n\t\t}\n\t\t// A store answering with another conversation's snapshot would register and activate the\n\t\t// wrong id, so only a snapshot of `id` hydrates.\n\t\tif (snapshot === undefined || snapshot.id !== id) return undefined\n\t\t// Reuse `add` so the default summarize / keep of the manager flow into the rehydrated conversation.\n\t\tconst conversation = this.add({ snapshot })\n\t\t// Re-point `active` explicitly: `add` only auto-activates the first conversation, so an open\n\t\t// into a non-empty registry must still make the rehydrated one active.\n\t\tthis.#active = conversation.id\n\t\treturn conversation\n\t}\n\n\tasync save(id: string): Promise<boolean> {\n\t\tconst conversation = this.#conversations.get(id)\n\t\tif (this.#store === undefined || conversation === undefined) return false\n\t\tawait this.#store.set(conversation.snapshot())\n\t\treturn true\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\t// Each present id still clears `active` when it was the active conversation.\n\t\t\treturn removeEntries(ids, (id) => this.#drop(id))\n\t\t}\n\t\treturn this.#drop(ids)\n\t}\n\n\tclear(): void {\n\t\tthis.#conversations.clear()\n\t\t// An emptied registry has no active conversation.\n\t\tthis.#active = undefined\n\t}\n\n\t// Delete one conversation by id; when it was the active one, clear the active pointer (a removed\n\t// conversation can never stay active).\n\t#drop(id: string): boolean {\n\t\tconst removed = this.#conversations.delete(id)\n\t\tif (removed && this.#active === id) this.#active = undefined\n\t\treturn removed\n\t}\n}\n","import type { ConversationSnapshot, ConversationStoreInterface } from '../types.js'\n\n/**\n * Implements the {@link ConversationStoreInterface} in memory — a process-lifetime `Map` of\n * {@link ConversationSnapshot} records keyed by conversation id, the default store\n * {@link import('../factories.js').createMemoryConversationStore} builds and the default\n * backing for `open` / `save`. The exact twin of\n * {@link import('@orkestrel/workspace').MemoryWorkspaceStore}.\n *\n * @remarks\n * A plain `Map<string, ConversationSnapshot>` — the snapshot is already pure,\n * self-contained JSON, so no encoding is needed for the memory tier. Like the\n * {@link import('@orkestrel/workspace').MemoryWorkspaceStore} it twins,\n * there is no idle-TTL and no eviction: a persisted conversation lives until an explicit `delete`. A\n * durable backend (JSON / SQLite / IndexedDB) swaps in through the same interface without touching\n * the {@link import('../ConversationManager.js').ConversationManager} or the\n * {@link import('../Conversation.js').Conversation} — its driver-pluggable twin is\n * {@link import('./DatabaseConversationStore.js').DatabaseConversationStore} (the snapshot as one\n * opaque JSON column).\n *\n * - **`get` resolves the persisted snapshot for an id**, or `undefined` if none is stored.\n * - **`set` inserts / replaces under the snapshot's own `id`** (no separate id param).\n * - **`delete` drops a snapshot by id**; an absent id is a no-op (no throw).\n *\n * The public surface is exactly `get` / `set` / `delete` — no extra members (the method\n * bijection with {@link ConversationStoreInterface}). Hydration is a caller concern: a\n * {@link import('../ConversationManager.js').ConversationManager} reads a snapshot back and rebuilds\n * the live conversation through the `snapshot` option (its `open` / `save`).\n *\n * @example\n * ```ts\n * import { createConversation, createMemoryConversationStore } from '@orkestrel/agent'\n *\n * const store = createMemoryConversationStore()\n * const conversation = createConversation()\n * conversation.add({ role: 'user', content: 'hello' })\n * await store.set(conversation.snapshot()) // persist the conversation\n * const snapshot = await store.get(conversation.id)\n * await store.delete(conversation.id) // drop it\n * ```\n */\nexport class MemoryConversationStore implements ConversationStoreInterface {\n\treadonly #snapshots = new Map<string, ConversationSnapshot>()\n\n\t/**\n\t * Resolves the persisted snapshot for `id`, or `undefined` if none is stored.\n\t *\n\t * @param id - The conversation id to resolve (a {@link ConversationSnapshot.id})\n\t * @returns The persisted snapshot, or `undefined` if absent\n\t */\n\tget(id: string): Promise<ConversationSnapshot | undefined> {\n\t\treturn Promise.resolve(this.#snapshots.get(id))\n\t}\n\n\t/**\n\t * Inserts or replaces a snapshot under its own `snapshot.id` (no separate id param —\n\t * mirroring the `set` method of {@link import('@orkestrel/workspace').WorkspaceStoreInterface}).\n\t *\n\t * @param snapshot - The snapshot to store (keyed by its `id`)\n\t * @returns A promise that resolves after the snapshot is stored\n\t */\n\tset(snapshot: ConversationSnapshot): Promise<void> {\n\t\tthis.#snapshots.set(snapshot.id, snapshot)\n\t\treturn Promise.resolve()\n\t}\n\n\t/**\n\t * Drops a snapshot by id; an absent id is a no-op (no throw).\n\t *\n\t * @param id - The conversation id to drop\n\t * @returns A promise that resolves after the snapshot is dropped\n\t */\n\tdelete(id: string): Promise<void> {\n\t\t// `Map.delete` of an absent id is a no-op, so no presence check is needed.\n\t\tthis.#snapshots.delete(id)\n\t\treturn Promise.resolve()\n\t}\n}\n","import type {\n\tConversationSnapshot,\n\tConversationSnapshotRow,\n\tConversationStoreInterface,\n} from '../types.js'\nimport type { TableInterface } from '@orkestrel/database'\nimport { isConversationSnapshot } from '../validators.js'\n\n/**\n * Backs a {@link ConversationStoreInterface} with one table of the `databases` layer — a\n * conversation's durable state is a row holding the snapshot as one opaque JSON column, narrowed\n * back on `get` by {@link import('../validators.js').isConversationSnapshot}, so persistence\n * reduces to keyed point-access (`get` / `set` / `delete`) over a {@link TableInterface}. The\n * driver-pluggable twin of the plain-`Map`\n * {@link import('./MemoryConversationStore.js').MemoryConversationStore}, and the exact twin of\n * {@link import('@orkestrel/workspace').DatabaseWorkspaceStore}.\n *\n * @remarks\n * The store is driver-agnostic: it holds a single {@link TableInterface} whose backend (memory,\n * JSON, SQLite, IndexedDB) is chosen by whoever builds it (the factories), so a JSON / SQLite /\n * IndexedDB backend swaps in without touching the\n * {@link import('../ConversationManager.js').ConversationManager} or the\n * {@link import('../Conversation.js').Conversation} — the same seam as\n * {@link import('@orkestrel/workspace').DatabaseWorkspaceStore}. Default driver: memory\n * ({@link import('../factories.js').createDatabaseConversationStore} passes\n * `createMemoryDriver()`), so it also works in memory out of the box; you opt into the\n * durable plumbing by passing a JSON / SQLite / IndexedDB driver.\n *\n * The {@link ConversationSnapshot} is stored as one opaque JSON column — the table is a row of\n * `{ id; snapshot }` ({@link ConversationSnapshotRow}), the snapshot the whole JSON blob (a\n * `rawShape` column the factory builds) — exactly as `DatabaseWorkspaceStore` stores its snapshot.\n * The snapshot is already a complete, self-contained, pure-JSON payload, so storing it whole is\n * lossless and keeps the row type flat (`snapshot` reads back as `unknown`).\n *\n * - **`set(snapshot)` upserts under the snapshot's own `id`** (no separate id param) — it writes\n * the row `{ id: snapshot.id, snapshot }`.\n * - **`get(id)` resolves the stored snapshot for an id**, narrowing the opaque JSON column back to\n * a {@link ConversationSnapshot} ({@link import('../validators.js').isConversationSnapshot} — the\n * total guard for an untrusted storage read), or `undefined` if none is stored, the blob is\n * malformed, or the blob's own `id` is not the requested one.\n * - **`delete(id)` drops a snapshot by id**; an absent id is a no-op (no throw).\n *\n * Unlike a session store there is no idle-TTL / eviction — a persisted conversation lives until an\n * explicit `delete`. The public surface is exactly `get` / `set` / `delete` — no extra members (the\n * method bijection with {@link ConversationStoreInterface}). Hydration stays a caller concern: a\n * {@link import('../ConversationManager.js').ConversationManager} reads a snapshot back and rebuilds\n * the live conversation through the `snapshot` option (its `open` / `save`).\n *\n * @example\n * ```ts\n * import { createConversation, createDatabaseConversationStore } from '@orkestrel/agent'\n * import { createMemoryDriver } from '@orkestrel/database'\n *\n * const store = createDatabaseConversationStore(createMemoryDriver()) // a durable driver swaps in here\n * const conversation = createConversation()\n * conversation.add({ role: 'user', content: 'hello' })\n * await store.set(conversation.snapshot()) // persist the conversation (one JSON column)\n * const snapshot = await store.get(conversation.id)\n * await store.delete(conversation.id) // drop it\n * ```\n */\nexport class DatabaseConversationStore implements ConversationStoreInterface {\n\treadonly #table: TableInterface<ConversationSnapshotRow>\n\n\t/**\n\t * Wraps a table as a conversation store.\n\t *\n\t * @param table - The {@link TableInterface} holding the snapshots — its row is the\n\t * {@link ConversationSnapshotRow} `{ id; snapshot }` shape (the snapshot one opaque JSON column)\n\t */\n\tconstructor(table: TableInterface<ConversationSnapshotRow>) {\n\t\tthis.#table = table\n\t}\n\n\t/**\n\t * Resolves the persisted snapshot for `id`, narrowing the opaque JSON column back to a\n\t * `ConversationSnapshot`.\n\t *\n\t * @remarks\n\t * The column is an untrusted storage read, so a blob that fails\n\t * {@link import('../validators.js').isConversationSnapshot}, or whose own `id` is not `id`,\n\t * resolves `undefined` rather than a conversation under the wrong key.\n\t *\n\t * @param id - The conversation id to resolve (the row key)\n\t * @returns The persisted snapshot, or `undefined` when no row is stored, the blob is malformed,\n\t * or the blob names another id\n\t */\n\tasync get(id: string): Promise<ConversationSnapshot | undefined> {\n\t\tconst row = await this.#table.get(id)\n\t\tif (row === undefined) return undefined\n\t\t// The snapshot crosses back as an untrusted storage read (a structured clone / a JSON row),\n\t\t// so narrow the opaque JSON column with the total boundary guard rather than a cast;\n\t\t// a malformed blob resolves `undefined`, never a broken conversation.\n\t\tconst snapshot = row.snapshot\n\t\treturn isConversationSnapshot(snapshot) && snapshot.id === id ? snapshot : undefined\n\t}\n\n\t/**\n\t * Inserts or replaces under the snapshot's own `id` (no separate id param) — the row is\n\t * `{ id, snapshot }`.\n\t *\n\t * @param snapshot - The snapshot to store, keyed by its `id`\n\t * @returns A promise that resolves once the row is written\n\t */\n\tasync set(snapshot: ConversationSnapshot): Promise<void> {\n\t\tawait this.#table.set({ id: snapshot.id, snapshot })\n\t}\n\n\t/**\n\t * Drops a snapshot by id; an absent id is a no-op (no throw).\n\t *\n\t * @param id - The conversation id to drop\n\t * @returns A promise that resolves once the row is gone\n\t */\n\tasync delete(id: string): Promise<void> {\n\t\tawait this.#table.remove(id)\n\t}\n}\n","import type {\n\tConversationInterface,\n\tConversationManagerInterface,\n\tConversationManagerOptions,\n\tConversationOptions,\n\tConversationSnapshotRow,\n\tConversationStoreInterface,\n} from './types.js'\nimport type { DriverInterface, TableInterface } from '@orkestrel/database'\nimport { rawShape, stringShape } from '@orkestrel/contract'\nimport { createDatabase, createMemoryDriver } from '@orkestrel/database'\nimport { Conversation } from './Conversation.js'\nimport { ConversationManager } from './ConversationManager.js'\nimport { MemoryConversationStore } from './stores/MemoryConversationStore.js'\nimport { DatabaseConversationStore } from './stores/DatabaseConversationStore.js'\n\n/**\n * Creates a conversation — a {@link ConversationInterface} grouping messages above a flat\n * message store it owns directly, with compaction into summarized sections, on-demand\n * `rehydrate`, and substring `search`, driven by a provider-agnostic\n * {@link ConversationSummaryHandler} seam.\n *\n * @remarks\n * Append turns through the conversation's own `add` (the live tail it owns); `view()` is the model input\n * (each section as a summary message, then the live tail). `compact()` folds the older live\n * messages into a summarized {@link Section}, whole exchanges at a time — it requires a\n * `summarize` (without one `compact()` throws a `ConversationError`); `keep` retains a recent\n * tail (Default: `DEFAULT_CONVERSATION_KEEP`, which folds up to the newest user message).\n * `rehydrate(id)` / `search(query)` read the retained originals. Observable (`emitter` —\n * `compact` / `collapse` / `rehydrate`), wired\n * through the reserved `on` option; the emitter isolates a listener throw and routes it to\n * its `error` handler (the `error` option), so it can never corrupt a compaction.\n *\n * @param options - Optional `id` / `on` hooks + the `summarize` seam + `keep` + `sections` (see {@link ConversationOptions})\n * @returns A working {@link ConversationInterface}\n *\n * @example Conversations & compaction\n * ```ts\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { createConversation } from '@orkestrel/agent'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * // The summarizer seam — built from the provider by the runtime; core stays provider-agnostic.\n * // Append the instruction as the FINAL user turn: a chat model emits nothing when the prompt\n * // ends on an assistant turn, so a leading-system instruction is unreliable.\n * const conversation = createConversation({\n * \tsummarize: async (messages, signal) =>\n * \t\t(\n * \t\t\tawait provider.generate(\n * \t\t\t\t[\n * \t\t\t\t\t...messages,\n * \t\t\t\t\t{ id: 's', role: 'user', content: 'Summarize the conversation so far concisely.' },\n * \t\t\t\t],\n * \t\t\t\tsignal ?? AbortSignal.timeout(30_000), // the compact() call's signal, when it passed one\n * \t\t\t)\n * \t\t).content,\n * \tkeep: 2, // retain at least the 2 most recent messages verbatim on each compaction\n * })\n * conversation.add([\n * \t{ role: 'user', content: 'My name is Ada.' },\n * \t{ role: 'assistant', content: 'Nice to meet you, Ada.' },\n * \t{ role: 'user', content: 'Book a table for two at 19:00.' },\n * \t{ role: 'assistant', content: 'Booked for two at 19:00.' },\n * \t{ role: 'user', content: 'What did I say my name was?' },\n * ])\n *\n * const section = await conversation.compact() // folds the first exchange → a summarized section\n * conversation.view() // [<section summary message>, ...the retained recent exchanges] — the model input\n * conversation.search('ada') // case-insensitive across sections' originals + the live tail\n * section && conversation.rehydrate(section.id) // the section's full original messages (a pure read)\n * ```\n */\nexport function createConversation(options?: ConversationOptions): ConversationInterface {\n\treturn new Conversation(options)\n}\n\n/**\n * Creates a conversation registry — a {@link ConversationManagerInterface} holding\n * {@link ConversationInterface} instances keyed by their `id`, in insertion order, with an active pointer:\n * the id-keyed store over the conversation layer plus the `active` / `switch` seam the context\n * renders. `add` auto-activates the first conversation and flows the registry's default\n * `summarize` / `keep` into every conversation it creates.\n *\n * @remarks\n * Starts empty; `add(input?)` mints a {@link ConversationInterface} (its `id` from the input\n * or a random UUID), flowing the manager's default `summarize` / `keep` in unless the input\n * overrides them, and stores it (an already-present `id` overwrites — last write wins) — and\n * auto-activates the first one (a registry with conversations always has one `active`); a later\n * `add` leaves `active` unchanged. `switch(id)` re-points `active` (an unknown `id` returns\n * `undefined`, leaving `active` unchanged — lenient, never throws); `conversation(id)` /\n * `conversations()` look up; `remove` (one or a batch) reports `true` only when every supplied id\n * was removed and clears `active` if it was a removed one; `clear` empties it and clears `active`.\n * Event-free\n * (each conversation owns its own observable `emitter`). A conversation created with neither a\n * manager default nor a per-`add` `summarize` cannot `compact` (it throws a `ConversationError`).\n *\n * @param options - Optional default `summarize` / `keep` (see {@link ConversationManagerOptions})\n * @returns An empty {@link ConversationManagerInterface}\n *\n * @example\n * ```ts\n * import { createConversationManager } from '@orkestrel/agent'\n *\n * const conversations = createConversationManager({ summarize: async (m) => `recap of ${m.length}` })\n * const chat = conversations.add() // auto-activates — conversations.active === chat\n * chat.add({ role: 'user', content: 'Hello' })\n * ```\n */\nexport function createConversationManager(\n\toptions?: ConversationManagerOptions,\n): ConversationManagerInterface {\n\treturn new ConversationManager(options)\n}\n\n/**\n * Creates the in-memory conversation store — a {@link ConversationStoreInterface} backed by a\n * process-lifetime `Map` of {@link import('./types.js').ConversationSnapshot} records keyed by conversation\n * id, the default backing for the durable {@link ConversationManagerInterface.open} /\n * {@link ConversationManagerInterface.save} seam. The exact twin of\n * {@link import('@orkestrel/workspace').createMemoryWorkspaceStore}.\n *\n * @remarks\n * A plain `Map` (the snapshot is already pure JSON, so no encoding is needed for the memory tier),\n * the structural twin of {@link import('@orkestrel/workspace').createMemoryWorkspaceStore}.\n * `get` / `set` / `delete` are async (the\n * same shape a durable backend fits); unlike a session store there is no idle-TTL / eviction — a\n * persisted conversation lives until an explicit `delete`. Its driver-pluggable twin is\n * {@link createDatabaseConversationStore} (the snapshot as one opaque JSON column over a `databases`\n * table) — for a durable store pass it a JSON / SQLite / IndexedDB driver, and it swaps in without\n * touching the manager or the conversation. Hydration stays a manager concern: read a snapshot back\n * and rebuild the live conversation through the `snapshot` option (re-supplying the live\n * `summarize` / `keep`).\n *\n * @returns A memory-backed {@link ConversationStoreInterface}\n *\n * @example\n * ```ts\n * import { createConversationManager, createMemoryConversationStore } from '@orkestrel/agent'\n *\n * const store = createMemoryConversationStore()\n * const manager = createConversationManager({ store })\n * const conversation = manager.add()\n * conversation.add({ role: 'user', content: 'hello' })\n * await manager.save(conversation.id) // persist the conversation\n * ```\n */\nexport function createMemoryConversationStore(): ConversationStoreInterface {\n\treturn new MemoryConversationStore()\n}\n\n/**\n * Creates a {@link DatabaseConversationStore} over any {@link DriverInterface} — the durable,\n * driver-pluggable backing for the conversation persistence\n * seam, holding each snapshot as one opaque JSON column and standing as the opt-in twin of\n * {@link createMemoryConversationStore}. The exact twin of\n * {@link import('@orkestrel/workspace').createDatabaseWorkspaceStore}.\n *\n * @remarks\n * Builds a one-table database (`conversations`, keyed by `id`) over the supplied driver, the snapshot\n * held as one opaque JSON column — the column map is `{ id; snapshot }` where `snapshot` is a\n * `rawShape` (a JSON blob), exactly as\n * {@link import('@orkestrel/workspace').createDatabaseWorkspaceStore} stores its snapshot. The\n * snapshot is already a complete, self-contained, pure-JSON payload, so storing it whole is lossless\n * and keeps the row type flat (the column reads back as `unknown`, narrowed on `get` by\n * {@link import('./validators.js').isConversationSnapshot}). Default driver:\n * {@link createMemoryDriver}, so the store also works in memory out of the box; pass a server\n * `createJSONDriver` / `createSQLiteDriver` (or a browser IndexedDB driver) for a persistent one —\n * the durability is the driver's job, the store engine is shared. It swaps in behind\n * {@link ConversationStoreInterface} without touching the manager or the conversation.\n *\n * @param driver - The storage backend the snapshots persist to. Default: {@link createMemoryDriver}\n * @returns A {@link ConversationStoreInterface} over the driver\n *\n * @example\n * ```ts\n * import { createConversationManager, createDatabaseConversationStore } from '@orkestrel/agent'\n * import { createMemoryDriver } from '@orkestrel/database'\n *\n * const store = createDatabaseConversationStore(createMemoryDriver()) // a durable driver swaps in here\n * const manager = createConversationManager({ store })\n * const conversation = manager.add()\n * conversation.add({ role: 'user', content: 'hello' })\n * await manager.save(conversation.id) // persist the conversation (one JSON column)\n * ```\n */\nexport function createDatabaseConversationStore(\n\tdriver: DriverInterface = createMemoryDriver(),\n): ConversationStoreInterface {\n\t// The snapshot is stored as one opaque JSON column (`rawShape`), so the row infers flat —\n\t// `{ id: string; snapshot: unknown }` = `ConversationSnapshotRow` — and the sections/messages\n\t// snapshot shape never forces a contract `Infer`.\n\tconst columns = { id: stringShape(), snapshot: rawShape({}) }\n\tconst database = createDatabase({ driver, tables: { conversations: columns } })\n\tconst table: TableInterface<ConversationSnapshotRow> = database.table('conversations')\n\treturn new DatabaseConversationStore(table)\n}\n","/**\n * Names the section header the `build()` method of {@link import('./AgentContext.js').AgentContext}\n * renders the active workspace's text files under — `'## Workspace'`, the leading line of the dedicated\n * workspace block in the system message.\n *\n * @remarks\n * `build()` owns the workspace render (a `Workspace` / `WorkspaceManager` stays file-focused — no\n * `open` / `format` getters), so this header lives here as the contexts module's one\n * workspace-section framing constant rather than on a manager. Each workspace text file renders\n * beneath it as a fenced `` File: <path>\\n```<language>\\n<text>\\n``` `` block through\n * {@link import('./helpers.js').renderFencedFile}, and the block is placed immediately after the\n * instructions section in the system block. The workspace's image files render no section: their\n * `base64` payload attaches to the last user message.\n */\nexport const WORKSPACE_SECTION_HEADER = '## Workspace'\n","import type { InstructionInput, InstructionInterface } from '../types.js'\n\n/**\n * Represents an immutable named directive — an {@link InstructionInterface} assembled once from\n * its input (`name` / `content` and an optional `priority`), the `id` minted at\n * construction. Default: `0` for `priority`.\n *\n * @remarks\n * A thin immutable value object (mirroring {@link import('@orkestrel/tool').Tool}): the\n * constructor mints a fresh `id` (`crypto.randomUUID()`), copies the input's `name` /\n * `content`, resolves `priority` to the input's value or `0`, and carries the input's\n * per-item `override` value when supplied; otherwise that property is `undefined`.\n * Never mutated after construction. An\n * {@link import('./InstructionManager.js').InstructionManager} keys it by `name` and\n * renders it (highest `priority` first) under its section header.\n *\n * @example\n * ```ts\n * const instruction = new Instruction({ name: 'tone', content: 'Be concise.', priority: 5 })\n * instruction.priority // 5\n * ```\n */\nexport class Instruction implements InstructionInterface {\n\treadonly id: string\n\treadonly name: string\n\treadonly content: string\n\treadonly priority: number\n\treadonly override?: string\n\n\tconstructor(input: InstructionInput) {\n\t\tthis.id = crypto.randomUUID()\n\t\tthis.name = input.name\n\t\tthis.content = input.content\n\t\tthis.priority = input.priority ?? 0\n\t\tif (input.override !== undefined) this.override = input.override\n\t}\n}\n","import type {\n\tContextSectionFormat,\n\tInstructionInput,\n\tInstructionInterface,\n\tInstructionManagerEventMap,\n\tInstructionManagerInterface,\n\tInstructionManagerOptions,\n} from '../types.js'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { removeEntries } from '../../helpers.js'\nimport { Instruction } from './Instruction.js'\n\n/**\n * Registers the immutable {@link Instruction} instances a richer context assembles a directives block\n * from — keyed by `name` so adding an instruction whose name is already stored overwrites it,\n * last write wins, and listed by descending `priority`, carrying the `open` / `render` / `close` build contract and an observable `emitter`.\n *\n * @remarks\n * - **Registry.** Instructions live in an insertion-ordered `Map` keyed by `name`;\n * `add` takes one {@link InstructionInput} or a batch, mints each instruction's\n * `id`, and adding an instruction whose name is already stored overwrites it (last write wins).\n * `count` is the map size, `instruction(name)` looks one up, and `instructions()` lists them sorted by\n * descending `priority` (a stable sort, so equal priorities keep insertion order).\n * - **Build contract (the whole format cascade).** `open` is the section header a context\n * renders the instructions under, `render(instruction)` renders one instruction, and\n * `close` is the line after them. Each resolves the cascade most-specific-first: `render`\n * returns the instruction's {@link InstructionInput.override}, else the\n * `InstructionManagerOptions.format` `render`, else its `content`; `open` returns the\n * options `open`, else the built-in header; `close` returns the options `close`, else\n * `undefined`. A context reads the three and frames the section from them (see\n * {@link import('../AgentContext.js').AgentContext}).\n * - **Removal.** `remove` drops one by name, or a batch — `true` only when every supplied\n * name was removed; `clear` empties the registry.\n * - **Observable.** The owned {@link emitter} ({@link InstructionManagerEventMap})\n * carries `add` (the created instruction) / `remove` (the name) / `clear` for\n * fire-and-forget observers. Every event is emitted directly, strictly after the map\n * mutation completes; the emitter isolates a listener throw and routes it to its `error`\n * handler (the `error` option), so a buggy observer can never corrupt a mutation.\n *\n * @example\n * ```ts\n * const manager = new InstructionManager()\n * manager.add([\n * \t{ name: 'tone', content: 'Be concise.', priority: 1 },\n * \t{ name: 'safety', content: 'Refuse unsafe requests.', priority: 10 },\n * ])\n * manager.instructions().map((one) => one.name) // ['safety', 'tone'] — highest priority first\n * ```\n */\nexport class InstructionManager implements InstructionManagerInterface {\n\treadonly #instructions = new Map<string, InstructionInterface>()\n\t// The push observation surface — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into a mutation.\n\treadonly #emitter: Emitter<InstructionManagerEventMap>\n\treadonly #format: ContextSectionFormat<InstructionInterface> | undefined\n\n\tconstructor(options?: InstructionManagerOptions) {\n\t\tthis.#emitter = new Emitter<InstructionManagerEventMap>(options)\n\t\tthis.#format = options?.format\n\t}\n\n\tget emitter(): EmitterInterface<InstructionManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#instructions.size\n\t}\n\n\tget open(): string {\n\t\treturn this.#format?.open ?? '## Instructions'\n\t}\n\n\tget close(): string | undefined {\n\t\treturn this.#format?.close\n\t}\n\n\tadd(input: InstructionInput): InstructionInterface\n\tadd(inputs: readonly InstructionInput[]): readonly InstructionInterface[]\n\tadd(\n\t\tinput: InstructionInput | readonly InstructionInput[],\n\t): InstructionInterface | readonly InstructionInterface[] {\n\t\tif (isArray(input)) return input.map((one) => this.#create(one))\n\t\treturn this.#create(input)\n\t}\n\n\tinstruction(name: string): InstructionInterface | undefined {\n\t\treturn this.#instructions.get(name)\n\t}\n\n\tinstructions(): readonly InstructionInterface[] {\n\t\t// A stable descending-priority sort — Array.prototype.sort is stable, so equal\n\t\t// priorities keep their insertion order (the map's iteration order).\n\t\treturn [...this.#instructions.values()].sort((a, b) => b.priority - a.priority)\n\t}\n\n\trender(instruction: InstructionInterface): string {\n\t\treturn instruction.override ?? this.#format?.render?.(instruction) ?? instruction.content\n\t}\n\n\tremove(name: string): boolean\n\tremove(names: readonly string[]): boolean\n\tremove(names: string | readonly string[]): boolean {\n\t\tif (isArray(names)) {\n\t\t\t// Each present name still emits.\n\t\t\treturn removeEntries(names, (name) => this.#delete(name))\n\t\t}\n\t\treturn this.#delete(names)\n\t}\n\n\tclear(): void {\n\t\tthis.#instructions.clear()\n\t\t// Observe the cleared registry — after the map emptied, so a swallowed listener\n\t\t// throw can never alter the clear (no payload — `clear` is a pure signal).\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\t// Mint an immutable instruction, store it by name (overwriting a same-name one), and\n\t// emit `add` after the map mutation — so a swallowed listener throw can't perturb it.\n\t#create(input: InstructionInput): InstructionInterface {\n\t\tconst instruction = new Instruction(input)\n\t\tthis.#instructions.set(instruction.name, instruction)\n\t\tthis.#emitter.emit('add', instruction)\n\t\treturn instruction\n\t}\n\n\t// Delete one instruction, emitting `remove` only when one was actually removed (a\n\t// delete of an absent name returns `false` and emits nothing) — after the deletion.\n\t#delete(name: string): boolean {\n\t\tconst removed = this.#instructions.delete(name)\n\t\tif (removed) this.#emitter.emit('remove', name)\n\t\treturn removed\n\t}\n}\n","import type { Message } from '../types.js'\nimport type { FileInterface } from '@orkestrel/workspace'\nimport { isBinary } from '@orkestrel/workspace'\n\n/**\n * Renders a path-addressed text body as a fenced reference block — a `File: <path>` label line\n * over a language-tagged fence, the framing the\n * active-workspace text-file render of {@link import('./AgentContext.js').AgentContext} emits.\n *\n * @remarks\n * Produces `` File: <path>\\n```<language>\\n<content>\\n``` `` — the `File:` label line, then a\n * fenced code block tagged with `language`, the `content` verbatim inside. The fence is one\n * backtick longer than the longest backtick run in `content`, and never shorter than three (the\n * CommonMark rule), so file text holding a triple backtick cannot close the block early and\n * land outside it; content with no run of three or more keeps the three-backtick fence. Pure\n * string assembly, total — never throws. The one fenced-file format string for the whole\n * module — `AgentContext.build()` frames an active workspace's text files with it (each carries\n * its own `language` on its {@link import('@orkestrel/workspace').FileContent} text arm).\n *\n * @param path - The file path shown on the `File:` label line\n * @param language - The fenced-code language tag (for example `'typescript'`)\n * @param content - The file body rendered verbatim inside the fence\n * @returns The fenced reference block\n *\n * @example\n * ```ts\n * import { renderFencedFile } from '@orkestrel/agent'\n *\n * renderFencedFile('src/main.ts', 'typescript', 'const x = 1')\n * // 'File: src/main.ts\\n```typescript\\nconst x = 1\\n```'\n * ```\n */\nexport function renderFencedFile(path: string, language: string, content: string): string {\n\tconst runs = content.match(/`+/g) ?? []\n\tconst longest = runs.reduce((most, run) => Math.max(most, run.length), 0)\n\tconst fence = '`'.repeat(Math.max(3, longest + 1))\n\treturn `File: ${path}\\n${fence}${language}\\n${content}\\n${fence}`\n}\n\n/**\n * Renders one context section — the resolved `open`, each item's rendering, and the resolved\n * `close` when one exists, blank-line joined; `undefined` when the section has no items.\n *\n * @remarks\n * Pure and total. A section with no items renders nothing (`undefined`), so an empty or fully\n * scoped-out manager stays silent — its `open` / `close` appear only when the section has items.\n * An empty or absent slot is dropped before the join, so an `open: ''`, a `close: ''`, an unset\n * `close` (there is no built-in close), and an item rendered to `''` each add no blank line; a\n * section whose every slot is empty renders nothing (`undefined`).\n *\n * @typeParam T - The section item being rendered\n * @param open - The section's resolved leading text\n * @param members - The already scope-filtered items\n * @param render - Renders one item to its prompt text\n * @param close - The section's resolved trailing text, or `undefined` for none\n * @returns The rendered section, or `undefined` when there are no items or every slot is empty\n *\n * @example\n * ```ts\n * renderSection('## Instructions', [{ content: 'Be terse.' }], (one) => one.content, undefined)\n * // '## Instructions\\n\\nBe terse.'\n * renderSection('<rules>', [], (one) => one.content, '</rules>') // undefined (no items)\n * ```\n */\nexport function renderSection<T>(\n\topen: string,\n\tmembers: readonly T[],\n\trender: (member: T) => string,\n\tclose: string | undefined,\n): string | undefined {\n\tif (members.length === 0) return undefined\n\tconst lines = [open, ...members.map(render), close].flatMap((line) =>\n\t\tline === undefined || line === '' ? [] : [line],\n\t)\n\treturn lines.length === 0 ? undefined : lines.join('\\n\\n')\n}\n\n/**\n * Copies a message with image data merged onto its `images` — the message's own images first,\n * then the attached data, keeping every other field and never mutating the original.\n *\n * @remarks\n * Pure and total: the original message is never mutated. Every other field the source message\n * carries (`calls`, `call`, `thinking`) is kept as given, and an absent one stays absent,\n * mirroring the store's present-when-given convention.\n *\n * @param message - The message to copy (left unchanged)\n * @param payloads - The base64 image data to attach\n * @returns A new message carrying the merged `images`\n *\n * @example\n * ```ts\n * // IMAGE_BASE64 stands for the base64 text of one image.\n * attachImages({ id: '1', role: 'user', content: 'Describe' }, ['IMAGE_BASE64'])\n * // { id: '1', role: 'user', content: 'Describe', images: ['IMAGE_BASE64'] }\n * ```\n */\nexport function attachImages(message: Message, payloads: readonly string[]): Message {\n\treturn { ...message, images: [...(message.images ?? []), ...payloads] }\n}\n\n/**\n * Attaches image data to a conversation's last user message — the turn a vision provider reads\n * images off — as a new array with that one message replaced by its carrying copy, and unchanged\n * when there is no data or no user turn.\n *\n * @remarks\n * Pure and total: the conversation and its messages are never mutated, and the returned array\n * replaces exactly the one target message with the copy {@link attachImages} builds. Empty\n * data returns the conversation unchanged; a conversation with no user message returns it\n * unchanged too (there is nowhere to attach, and the images already rode the system block). A hole\n * in a sparse conversation is not a user message.\n *\n * @param conversation - The messages to attach into (left unchanged)\n * @param payloads - The base64 image data to attach\n * @returns The conversation with its last user message replaced by the carrying copy\n *\n * @example\n * ```ts\n * attachUserImages([{ id: '1', role: 'user', content: 'Describe' }], ['IMAGE_BASE64'])\n * // [{ id: '1', role: 'user', content: 'Describe', images: ['IMAGE_BASE64'] }]\n * ```\n */\nexport function attachUserImages(\n\tconversation: readonly Message[],\n\tpayloads: readonly string[],\n): readonly Message[] {\n\tif (payloads.length === 0) return conversation\n\tconst target = conversation.findLastIndex(\n\t\t(message: Message | undefined) => message?.role === 'user',\n\t)\n\tif (target === -1) return conversation\n\treturn conversation.map((message, index) =>\n\t\tindex === target ? attachImages(message, payloads) : message,\n\t)\n}\n\n/**\n * Collects the `base64` payload of the image files in a workspace file list — the data an agent\n * context attaches to the last user message.\n *\n * @remarks\n * Pure and total. `isBinary` narrows the tagless content to its binary arm (a total guard,\n * never an assertion), then the MIME prefix gates it to an image, so a text file and a non-image\n * binary (a PDF) are both skipped. Order follows the file list.\n *\n * @param files - The (already scope-filtered) workspace files\n * @returns The `base64` payload of each image file, in file order\n *\n * @example\n * ```ts\n * collectImageData([createFile({ path: 'a.png', content: { base64: 'IMAGE_BASE64', mime: 'image/png' } })])\n * // ['IMAGE_BASE64']\n * ```\n */\nexport function collectImageData(files: readonly FileInterface[]): readonly string[] {\n\t// The spread visits a hole in `files` as an undefined file, as iteration does; `flatMap` skips it.\n\treturn [...files].flatMap((file) =>\n\t\tisBinary(file.content) && file.content.mime.startsWith('image/') ? [file.content.base64] : [],\n\t)\n}\n\n/**\n * Intersects two scope category lists under the \"`undefined` is the universal set\" rule — a\n * fresh copy that can only tighten, and the primitive a scope narrows through.\n *\n * @remarks\n * Pure and total, and it can only tighten: `undefined` ∩ `undefined` is `undefined` (still no\n * constraint); `undefined` ∩ a list is a copy of that list (the `undefined` side imposes\n * nothing); a list ∩ a list keeps the child keys the parent also allows, so a parent-excluded\n * key can never be re-admitted. Every returned list is a fresh copy, so a later mutation of\n * either input cannot leak into the result.\n *\n * @param parent - The parent's allow-list (`undefined` ⇒ no constraint)\n * @param child - The narrowing allow-list (`undefined` ⇒ no constraint)\n * @returns The intersected allow-list, or `undefined` when neither side constrains\n *\n * @example\n * ```ts\n * intersectKeys(['read', 'write'], ['write', 'admin']) // ['write']\n * intersectKeys(undefined, ['read']) // ['read']\n * intersectKeys(undefined, undefined) // undefined\n * ```\n */\nexport function intersectKeys(\n\tparent: readonly string[] | undefined,\n\tchild: readonly string[] | undefined,\n): readonly string[] | undefined {\n\tif (parent === undefined) return child === undefined ? undefined : [...child]\n\tif (child === undefined) return [...parent]\n\tconst allowed = new Set(parent)\n\treturn child.filter((key) => allowed.has(key))\n}\n","import type { ScopeFilter, ScopeInput, ScopeInterface, SelectionHandler } from '../types.js'\nimport { intersectKeys } from '../helpers.js'\n\n/**\n * Represents a named, immutable filter over a richer context's items — an optional allow-list per\n * category (`instructions` / `tools` / `files`), each keyed by that category's identity (an\n * instruction's `name`, a tool's `name`, a workspace file's `path`) and read as an allow-list:\n * `undefined` lets everything pass, `[]` lets nothing pass, and a non-empty list passes the listed\n * keys alone. `narrow` composes a tighter child by set intersection.\n *\n * @remarks\n * - **A category list is three-way.** `undefined` ⇒ no constraint on that category (all\n * pass); `[]` ⇒ none pass; a non-empty list ⇒ only the listed keys pass. The build\n * step / loop apply this through `filterAllowList`.\n * - **Immutable.** The `id` is minted at construction; every supplied list is copied in\n * (so a later mutation of the caller's array can't leak in), and the lists are\n * `readonly`. A `Scope` is never mutated after construction — `narrow` returns a new\n * one rather than altering this one.\n * - **`narrow` is set-intersection (immutable composition).** A child scope's visible set\n * per category is the intersection of this scope's list and the config's list — but\n * `undefined` means \"no constraint\", so it acts as the universal set: intersecting\n * `undefined` with a list yields the list, and `undefined` with `undefined` stays\n * `undefined`. Narrowing can only tighten, never widen — a key excluded by a parent\n * can never be re-admitted by a child. The child keeps this scope's `name` and `select` handler.\n *\n * @example\n * ```ts\n * const scope = new Scope({ name: 'reader', tools: ['search', 'read'] })\n * // narrow intersects: tools ∩ ['read', 'write'] = ['read'] (write was never in the parent).\n * const tighter = scope.narrow({ tools: ['read', 'write'] })\n * tighter.tools // ['read']\n * // instructions had no parent constraint (undefined) → the child's list passes through.\n * tighter.narrow({ instructions: ['safety'] }).instructions // ['safety']\n * ```\n */\nexport class Scope implements ScopeInterface {\n\treadonly id: string = crypto.randomUUID()\n\treadonly name: string\n\treadonly instructions?: readonly string[]\n\treadonly tools?: readonly string[]\n\treadonly files?: readonly string[]\n\treadonly select?: SelectionHandler\n\n\tconstructor(input: ScopeInput) {\n\t\tthis.name = input.name\n\t\tif (input.select !== undefined) this.select = input.select\n\t\t// Copy each supplied list in (a later mutation of the caller's array can't leak in);\n\t\t// an omitted list stays `undefined` — the absence of a constraint.\n\t\tif (input.instructions !== undefined) this.instructions = [...input.instructions]\n\t\tif (input.tools !== undefined) this.tools = [...input.tools]\n\t\tif (input.files !== undefined) this.files = [...input.files]\n\t}\n\n\tnarrow(config: ScopeFilter): ScopeInterface {\n\t\tconst instructions = intersectKeys(this.instructions, config.instructions)\n\t\tconst tools = intersectKeys(this.tools, config.tools)\n\t\tconst files = intersectKeys(this.files, config.files)\n\t\treturn new Scope({\n\t\t\tname: this.name,\n\t\t\t...(this.select === undefined ? {} : { select: this.select }),\n\t\t\t...(instructions === undefined ? {} : { instructions }),\n\t\t\t...(tools === undefined ? {} : { tools }),\n\t\t\t...(files === undefined ? {} : { files }),\n\t\t})\n\t}\n}\n","import type {\n\tScopeInput,\n\tScopeInterface,\n\tScopeManagerEventMap,\n\tScopeManagerInterface,\n\tScopeManagerOptions,\n} from '../types.js'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport { isArray } from '@orkestrel/contract'\nimport { Emitter } from '@orkestrel/emitter'\nimport { removeEntries } from '../../helpers.js'\nimport { Scope } from './Scope.js'\n\n/**\n * Registers the named filters a richer context reuses — immutable {@link Scope} instances keyed by their\n * minted `id`, in insertion order, where `add` always mints and stores rather than overwriting,\n * and an observable `emitter` reports each change.\n *\n * @remarks\n * - **Registry.** Scopes live in an insertion-ordered `Map` keyed by their minted `id`;\n * `add` mints a {@link Scope} from a {@link ScopeInput} (an `id` plus the three\n * allow-lists), stores it, and returns it. `count` is the map size, `scope(id)` looks\n * one up, and `scopes()` lists them in insertion order. (Unlike the name-keyed\n * instruction registry, a scope's key is its minted `id`, so two scopes may share a\n * `name`; `add` therefore never overwrites.)\n * - **Removal.** `remove` drops one by id, or a batch — `true` only when every supplied id\n * was removed; `clear` empties the registry.\n * - **Observable.** The owned {@link emitter} ({@link ScopeManagerEventMap}) carries\n * `add` (the added scope) / `remove` (the id) / `clear`. Every event is emitted\n * directly, strictly after the map mutation completes; the emitter isolates a listener\n * throw and routes it to its `error` handler (the `error` option), so a buggy observer can\n * never corrupt a mutation.\n *\n * @example\n * ```ts\n * const manager = new ScopeManager()\n * const reader = manager.add({ name: 'reader', tools: ['search', 'read'] })\n * manager.scope(reader.id) // the same scope\n * manager.count // 1\n * ```\n */\nexport class ScopeManager implements ScopeManagerInterface {\n\treadonly #scopes = new Map<string, ScopeInterface>()\n\t// The push observation surface — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into a mutation.\n\treadonly #emitter: Emitter<ScopeManagerEventMap>\n\n\tconstructor(options?: ScopeManagerOptions) {\n\t\tthis.#emitter = new Emitter<ScopeManagerEventMap>(options)\n\t}\n\n\tget emitter(): EmitterInterface<ScopeManagerEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget count(): number {\n\t\treturn this.#scopes.size\n\t}\n\n\tadd(input: ScopeInput): ScopeInterface {\n\t\tconst scope = new Scope(input)\n\t\tthis.#scopes.set(scope.id, scope)\n\t\t// Observe the added scope — after the map set, so a swallowed listener throw can't\n\t\t// perturb the store the caller is about to use.\n\t\tthis.#emitter.emit('add', scope)\n\t\treturn scope\n\t}\n\n\tscope(id: string): ScopeInterface | undefined {\n\t\treturn this.#scopes.get(id)\n\t}\n\n\tscopes(): readonly ScopeInterface[] {\n\t\treturn [...this.#scopes.values()]\n\t}\n\n\tremove(id: string): boolean\n\tremove(ids: readonly string[]): boolean\n\tremove(ids: string | readonly string[]): boolean {\n\t\tif (isArray(ids)) {\n\t\t\t// Each present id still emits.\n\t\t\treturn removeEntries(ids, (id) => this.#delete(id))\n\t\t}\n\t\treturn this.#delete(ids)\n\t}\n\n\tclear(): void {\n\t\tthis.#scopes.clear()\n\t\t// Observe the cleared registry — after the map emptied, so a swallowed listener\n\t\t// throw can never alter the clear (no payload — `clear` is a pure signal).\n\t\tthis.#emitter.emit('clear')\n\t}\n\n\t// Delete one scope, emitting `remove` only when one was actually removed (a delete of\n\t// an absent id returns `false` and emits nothing) — after the deletion.\n\t#delete(id: string): boolean {\n\t\tconst removed = this.#scopes.delete(id)\n\t\tif (removed) this.#emitter.emit('remove', id)\n\t\treturn removed\n\t}\n}\n","import type {\n\tAgentContextInterface,\n\tAgentContextOptions,\n\tInstructionManagerInterface,\n\tScopeInterface,\n\tSelection,\n\tSelectionHandler,\n} from './types.js'\nimport type {\n\tConversationInterface,\n\tConversationManagerInterface,\n\tMessageManagerInterface,\n} from '../conversations/index.js'\nimport type { Message } from '../types.js'\nimport type { ToolManagerInterface } from '@orkestrel/tool'\nimport type { WorkspaceManagerInterface } from '@orkestrel/workspace'\nimport { ToolManager } from '@orkestrel/tool'\nimport { isText, WorkspaceManager } from '@orkestrel/workspace'\nimport { InstructionManager } from './instructions/InstructionManager.js'\nimport { ConversationManager } from '../conversations/index.js'\nimport { filterAllowList } from '../helpers.js'\nimport { attachUserImages, collectImageData, renderFencedFile, renderSection } from './helpers.js'\nimport { WORKSPACE_SECTION_HEADER } from './constants.js'\n\n/**\n * Assembles a provider request from the richer turn context — the optional system prompt, the\n * observable context managers (instructions / workspaces), the\n * {@link ConversationManagerInterface} message source whose active conversation is `messages`, the\n * {@link ToolManagerInterface} registry, and an active {@link ScopeInterface} changed through\n * {@link AgentContextInterface.apply}. `build()` folds the scoped managers and the active\n * workspace into one system block, then the conversation, and never reads `tools`.\n *\n * @remarks\n * - **Composition.** `system` is the optional system prompt; `instructions` / `tools` /\n * `workspaces` / `conversations` are the registries passed in `options` (bring your own), or\n * fresh empty ones when omitted (so `workspaces` is always present); `messages` is the active\n * conversation's live tail (always defined — see the following item). `scope` is the active filter —\n * `undefined` (the default) ⇒ no filtering; change it through `apply(scope)`. The structural\n * `workspaces` / `conversations` registries are fixed at construction; switch their active\n * members through their own `switch(id)` methods.\n * - **The message source — the conversation registry's active conversation.** `conversations` is a\n * {@link ConversationManagerInterface}. The constructor adds a default conversation when the\n * manager has no active one, so the dynamic `messages` getter — `this.#conversations.active` — is\n * always defined. `messages` returns the active conversation itself (it owns the live tail + the\n * message verbs directly, satisfying {@link MessageManagerInterface} structurally — the same\n * reference, no duplication), and `build()` folds that conversation's `view()` (its per-section\n * summaries + live tail) as the authoritative message inclusion — the scope does not filter the\n * conversation (it owns inclusion through compaction; scope filters only instructions / tools /\n * workspace files). Because `messages` is read dynamically, an agent switches the active\n * conversation between runs (`conversations.switch(id)`) to serve many threads (the real\n * multi-conversation pattern); switch between runs, not during a run, and use separate agents for\n * concurrent threads.\n * - **`build()` — the scoped assembly + the format cascade.** It folds, in order,\n * the system prompt then the scope-filtered instructions → the active workspace's text files\n * (each as a block: the section's `open` text, each item's rendering, then any `close` text)\n * into one leading `system` message (prepended only when at least one part exists), then\n * appends the active conversation's `view()` (the conversation owns message inclusion through\n * compaction — the scope does not filter the conversation). The instruction manager resolves\n * each `open` / item / `close` most-specific-first: `open` = manager-options-override >\n * built-in; per item = item-override > manager-options-override > built-in; `close` =\n * manager-options-override (no built-in ⇒ no closing line when unset) (see\n * {@link AgentContextInterface.build}). With no override set, each section is its built-in\n * header + items, no closing line. The active workspace's scoped-in image files' `base64` payload is attached to\n * the last user message (a vision provider reads images off a user turn); when no user message\n * exists the attachment is skipped. Built fresh each call (recomputed, never cached), so it\n * always reflects the current managers / messages / scope / active workspace; it never mutates a\n * manager or the stored messages.\n * - **The active workspace, rendered by carrier — the sole document/image context.**\n * `workspaces.active` (when set) has its {@link import('@orkestrel/workspace').FileInterface} values scope-filtered by `scope.files`,\n * then split: text files fold into a dedicated `## Workspace` system section (fenced reference\n * blocks — placed right after the instructions section), and image files' `base64` payload attaches\n * to the last user message. Active-only — never the other registered workspaces; with no active\n * workspace nothing renders for workspaces. `build()` owns this render (a `Workspace` /\n * `WorkspaceManager` stays file-focused).\n * - **Tools are structural, not in the prompt.** The registry is advertised to the provider\n * through `tools.definitions()` (scope-filtered by the loop), never serialized into the\n * message array — so the output of the `build()` method carries no tool content, scoped or not.\n * - **Event-free context; observable managers.** The context itself owns no Emitter; the\n * context managers each carry their own (the push observation surface).\n *\n * @example\n * ```ts\n * const context = new AgentContext({ system: 'You are concise.' })\n * context.instructions.add({ name: 'tone', content: 'Be terse.' })\n * context.messages.add({ role: 'user', content: 'Hi' })\n * context.build() // [{ role: 'system', content: 'You are concise.\\n\\n## Instructions\\n\\nBe terse.' }, { role: 'user', content: 'Hi' }]\n * ```\n */\nexport class AgentContext implements AgentContextInterface {\n\treadonly #system: string | undefined\n\treadonly #instructions: InstructionManagerInterface\n\t// The workspace registry whose active workspace `build()` renders by carrier (text files →\n\t// the system block, image files → the last user message). Always present (a fresh empty\n\t// manager when none was supplied). The registry is structural; switch its active workspace\n\t// through `workspaces.switch(id)`. `build()` reads `active` / its `files()` fresh each call.\n\treadonly #workspaces: WorkspaceManagerInterface\n\t// The conversation registry whose active conversation is the message source: the dynamic\n\t// `messages` getter returns `#conversations.active`, which the constructor seeds when absent, and\n\t// `build()` folds that conversation's `view()`. The registry is structural; switch its active\n\t// conversation through `conversations.switch(id)`.\n\treadonly #conversations: ConversationManagerInterface\n\treadonly #tools: ToolManagerInterface\n\t// The agent default; the active scope's `select` overrides it at each `select` call.\n\treadonly #select: SelectionHandler | undefined\n\t#scope: ScopeInterface | undefined\n\n\tconstructor(options?: AgentContextOptions) {\n\t\tthis.#system = options?.system\n\t\tthis.#instructions = options?.instructions ?? new InstructionManager()\n\t\t// Default to a fresh empty registry so `context.workspaces` is always present (mirroring\n\t\t// the always-present instruction manager); a supplied one is reused. The active workspace\n\t\t// is the sole document/image context.\n\t\tthis.#workspaces = options?.workspaces ?? new WorkspaceManager()\n\t\t// The conversation registry the message source flows from — a supplied one is reused, else a\n\t\t// fresh empty one. Seed an active conversation so `context.messages` (the active conversation's\n\t\t// live tail) is always defined: when the manager has none active, call `add()` for a default\n\t\t// (which auto-activates it). NB: `messages` is not captured here — it is computed dynamically\n\t\t// (the getter reads `#conversations.active`), so it always tracks the current active\n\t\t// conversation's live tail, no duplication.\n\t\tthis.#conversations = options?.conversations ?? new ConversationManager()\n\t\tif (this.#conversations.active === undefined) this.#conversations.add()\n\t\tthis.#tools = options?.tools ?? new ToolManager()\n\t\tthis.#select = options?.select\n\t\tthis.#scope = options?.scope\n\t}\n\n\tget system(): string | undefined {\n\t\treturn this.#system\n\t}\n\n\tget instructions(): InstructionManagerInterface {\n\t\treturn this.#instructions\n\t}\n\n\tget workspaces(): WorkspaceManagerInterface {\n\t\treturn this.#workspaces\n\t}\n\n\t// Dynamic — the active conversation itself (it owns its live tail + the message verbs directly,\n\t// like a `Workspace` owns its files), always defined: the constructor adds a default when the\n\t// registry has no active conversation. Computed on every read (never captured), so\n\t// `context.messages` always points at the current active conversation (the same reference — no\n\t// duplication) and follows a `conversations.switch(id)`. The active `Conversation` satisfies the\n\t// message-verb contract directly, so this stays a `MessageManagerInterface`. The\n\t// `#ensureConversation()` method re-seats a default if a caller's supplied manager was emptied (for\n\t// example `clear()`), so the getter is total — never undefined.\n\tget messages(): MessageManagerInterface {\n\t\treturn this.#ensureConversation()\n\t}\n\n\tget conversations(): ConversationManagerInterface {\n\t\treturn this.#conversations\n\t}\n\n\tget tools(): ToolManagerInterface {\n\t\treturn this.#tools\n\t}\n\n\tget scope(): ScopeInterface | undefined {\n\t\treturn this.#scope\n\t}\n\n\tapply(scope: ScopeInterface | undefined): void {\n\t\tthis.#scope = scope\n\t}\n\n\tselect(request: Message, signal: AbortSignal): Promise<Selection> | undefined {\n\t\t// Returning `undefined` synchronously keeps the loop's default path free of an `await`.\n\t\tconst handler = this.#scope?.select ?? this.#select\n\t\tif (handler === undefined) return undefined\n\t\treturn this.#check(handler, this.#ensureConversation(), request, signal)\n\t}\n\n\tbuild(selection?: Selection): readonly Message[] {\n\t\tconst scope = this.#scope\n\t\t// Tools reach the provider structurally. Each manager resolves its format cascade.\n\t\tconst parts: string[] = []\n\t\t// Configured by `=== undefined`, not falsiness — an explicitly supplied '' (or a\n\t\t// whitespace-only) system is opted in and prepended verbatim; a truthiness check would drop it.\n\t\tif (this.#system !== undefined) parts.push(this.#system)\n\t\tconst instructions = filterAllowList(\n\t\t\tscope?.instructions,\n\t\t\tthis.#instructions.instructions(),\n\t\t\t(one) => one.name,\n\t\t)\n\t\tconst instructed = renderSection(\n\t\t\tthis.#instructions.open,\n\t\t\tinstructions,\n\t\t\t(one) => this.#instructions.render(one),\n\t\t\tthis.#instructions.close,\n\t\t)\n\t\tif (instructed !== undefined) parts.push(instructed)\n\t\t// The active workspace is the sole document/image context. `build()` owns this render\n\t\t// because a `Workspace` / `WorkspaceManager` stays file-focused.\n\t\tconst files = filterAllowList(\n\t\t\tscope?.files,\n\t\t\tthis.#workspaces.active?.files() ?? [],\n\t\t\t(one) => one.path,\n\t\t)\n\t\tconst workspaceTexts = files.flatMap((file) =>\n\t\t\tisText(file.content)\n\t\t\t\t? [{ path: file.path, language: file.content.language, text: file.content.text }]\n\t\t\t\t: [],\n\t\t)\n\t\tconst documented = renderSection(\n\t\t\tWORKSPACE_SECTION_HEADER,\n\t\t\tworkspaceTexts,\n\t\t\t(file) => renderFencedFile(file.path, file.language, file.text),\n\t\t\tundefined,\n\t\t)\n\t\tif (documented !== undefined) parts.push(documented)\n\n\t\t// The active conversation's `view()` is authoritative (the per-section\n\t\t// summaries + the live tail) — the conversation owns message inclusion through compaction, so the\n\t\t// scope does not filter the conversation here (scope filters only the preceding instructions /\n\t\t// tools / workspace files). The active conversation is always present (the constructor adds\n\t\t// one), with `#ensureConversation()` as a total fallback if a caller emptied its supplied registry.\n\t\tconst conversation = selection?.messages ?? this.#ensureConversation().view()\n\t\t// A vision provider reads image payloads from a user turn.\n\t\tconst tail = attachUserImages(conversation, collectImageData(files))\n\n\t\t// A faulted selection's messages are `view()`, so the plan its briefing rested on is void.\n\t\tif (\n\t\t\tselection !== undefined &&\n\t\t\tselection.fault === undefined &&\n\t\t\tselection.briefing !== undefined &&\n\t\t\tselection.briefing !== ''\n\t\t) {\n\t\t\tparts.push(selection.briefing)\n\t\t}\n\n\t\tif (parts.length === 0) return tail\n\t\tconst system: Message = {\n\t\t\tid: crypto.randomUUID(),\n\t\t\trole: 'system',\n\t\t\tcontent: parts.join('\\n\\n'),\n\t\t}\n\t\treturn [system, ...tail]\n\t}\n\n\t// Another run can append to the conversation while the handler awaits, so the view's ids are\n\t// recorded before the call (an async body runs synchronously up to its first `await`) and\n\t// compared after it; a changed view turns the handler's selection into a fault over `view()`.\n\tasync #check(\n\t\thandler: SelectionHandler,\n\t\tconversation: ConversationInterface,\n\t\trequest: Message,\n\t\tsignal: AbortSignal,\n\t): Promise<Selection> {\n\t\tconst before = conversation.view().map((message) => message.id)\n\t\tconst selection = await handler(conversation, request, signal)\n\t\tconst after = conversation.view()\n\t\tif (\n\t\t\tafter.length === before.length &&\n\t\t\tafter.every((message, index) => message.id === before[index])\n\t\t) {\n\t\t\treturn selection\n\t\t}\n\t\tconst text = `conversation ${conversation.id} changed during selection: ${before.length} messages before, ${after.length} after`\n\t\treturn {\n\t\t\tmessages: after,\n\t\t\tjudgments: selection.judgments,\n\t\t\t...(selection.usage === undefined ? {} : { usage: selection.usage }),\n\t\t\tfault:\n\t\t\t\tselection.fault === undefined\n\t\t\t\t\t? new Error(text)\n\t\t\t\t\t: new Error(text, { cause: selection.fault }),\n\t\t}\n\t}\n\n\t// A supplied registry can be emptied after construction. Re-seat a default so the message\n\t// source stays defined, preferring the active conversation an add observer may have selected.\n\t#ensureConversation(): ConversationInterface {\n\t\tif (this.#conversations.active !== undefined) return this.#conversations.active\n\t\tconst conversation = this.#conversations.add()\n\t\treturn this.#conversations.active ?? conversation\n\t}\n}\n","import type {\n\tAgentContextInterface,\n\tAgentContextOptions,\n\tInstructionInput,\n\tInstructionInterface,\n\tInstructionManagerInterface,\n\tInstructionManagerOptions,\n\tScopeInput,\n\tScopeInterface,\n\tScopeManagerInterface,\n\tScopeManagerOptions,\n} from './types.js'\nimport { Instruction } from './instructions/Instruction.js'\nimport { InstructionManager } from './instructions/InstructionManager.js'\nimport { Scope } from './scopes/Scope.js'\nimport { ScopeManager } from './scopes/ScopeManager.js'\nimport { AgentContext } from './AgentContext.js'\n\n/**\n * Creates an instruction — an immutable {@link InstructionInterface} (a named directive)\n * from its `name` / `content` and optional `priority`, the `id` minted at construction.\n *\n * @remarks\n * Only `name` / `content` are required; `priority` orders the instruction in the\n * rendered list of an {@link InstructionManagerInterface} (higher first). Default: `0`.\n * Stored immutable — never mutated after creation.\n *\n * @param input - `name` / `content` (required) and an optional `priority` (see\n * {@link InstructionInput})\n * @returns A working {@link InstructionInterface}\n *\n * @example\n * ```ts\n * import { createInstruction } from '@orkestrel/agent'\n *\n * const instruction = createInstruction({ name: 'tone', content: 'Be concise.', priority: 5 })\n * ```\n */\nexport function createInstruction(input: InstructionInput): InstructionInterface {\n\treturn new Instruction(input)\n}\n\n/**\n * Creates an instruction registry — an {@link InstructionManagerInterface} holding\n * immutable instructions keyed by `name`, listed by descending `priority`.\n *\n * @remarks\n * Starts empty; `add` (one or a batch) mints each `id` and overwrites a same-name\n * instruction (last write wins); `instructions()` lists them sorted by descending\n * `priority` (stable for ties); `open` / `render` / `close` are the build contract a richer\n * context renders an instructions block with; `remove` (one or a batch) reports `true` only\n * when every supplied name was removed; `clear` empties it. Carries an observable `emitter`\n * ({@link import('./types.js').InstructionManagerEventMap}) wired through the reserved `on`\n * option; the emitter isolates a listener throw and routes it to its `error` handler\n * (the `error` option), so it can never corrupt a mutation. An optional `format`\n * override is the manager-options level of the `AgentContext` build cascade (consulted by\n * `open` / `render` / `close`, beating the built-in; a per-item\n * `InstructionInput.override` still beats it).\n *\n * @param options - Optional `on` hooks + a `format` override (see {@link InstructionManagerOptions})\n * @returns An empty {@link InstructionManagerInterface}\n *\n * @example\n * ```ts\n * import { createInstructionManager } from '@orkestrel/agent'\n *\n * const instructions = createInstructionManager()\n * instructions.add({ name: 'tone', content: 'Be concise.', priority: 5 })\n * ```\n */\nexport function createInstructionManager(\n\toptions?: InstructionManagerOptions,\n): InstructionManagerInterface {\n\treturn new InstructionManager(options)\n}\n\n/**\n * Creates a named scope — an immutable {@link ScopeInterface} from its `name` and its\n * per-category allow-lists, the `id` minted at construction.\n *\n * @remarks\n * Each list is three-way: `undefined` ⇒ no constraint on that category (all pass), `[]` ⇒\n * none pass, a non-empty list ⇒ only the listed keys pass. `narrow(config)` composes a\n * tighter child by set-intersection (an `undefined` side imposing no constraint). Stored\n * immutable — never mutated after creation (`narrow` returns a new scope).\n *\n * @param input - `name` (required) and the optional `instructions` / `tools` / `files`\n * allow-lists (see {@link ScopeInput})\n * @returns A working {@link ScopeInterface}\n *\n * @example\n * ```ts\n * import { createScope } from '@orkestrel/agent'\n *\n * const reader = createScope({ name: 'reader', tools: ['search', 'read'] })\n * reader.narrow({ tools: ['read', 'write'] }).tools // ['read'] — intersection tightens\n * ```\n */\nexport function createScope(input: ScopeInput): ScopeInterface {\n\treturn new Scope(input)\n}\n\n/**\n * Creates a scope registry — a {@link ScopeManagerInterface} holding immutable scopes keyed\n * by their minted `id`, in insertion order.\n *\n * @remarks\n * Starts empty; `add` mints each scope's `id` and stores it (keyed by `id`, so it\n * never overwrites — two scopes may share a `name`); `scopes()` lists them in insertion order;\n * `remove` (one or a batch) reports `true` only when every supplied id was removed; `clear`\n * empties it. Carries an observable `emitter`\n * ({@link import('./types.js').ScopeManagerEventMap}) wired through the reserved `on`\n * option; the emitter isolates a listener throw and routes it to its `error` handler\n * (the `error` option), so it can never corrupt a mutation.\n *\n * @param options - Optional `on` hooks (see {@link ScopeManagerOptions})\n * @returns An empty {@link ScopeManagerInterface}\n *\n * @example\n * ```ts\n * import { createScopeManager } from '@orkestrel/agent'\n *\n * const scopes = createScopeManager()\n * const reader = scopes.add({ name: 'reader', tools: ['search'] })\n * ```\n */\nexport function createScopeManager(options?: ScopeManagerOptions): ScopeManagerInterface {\n\treturn new ScopeManager(options)\n}\n\n/**\n * Creates a richer turn context — an {@link AgentContextInterface} assembling a provider request\n * from the optional system prompt, the instruction registry, the workspace registry (the only\n * document channel), the conversation registry that is its `messages` source, the tool registry,\n * and the active scope, which `build()` folds into the next turn's input.\n *\n * @remarks\n * `system` is the optional system prompt; `tools` / `instructions` / `workspaces` are pre-built\n * managers to reuse (empty ones are created when omitted, so `context.workspaces` is always\n * present); `scope` is the initial active filter (`undefined` ⇒ no filtering, changeable afterwards\n * through `context.apply(...)`). `conversations` is the message source: a supplied manager's\n * active conversation is reused as `messages`, and a default conversation is added only when it\n * has none (a fresh registry with one default conversation is created when omitted). `build()`\n * folds the scoped instructions — plus the active workspace's scope-filtered text files (fenced) —\n * into one leading `system` message and appends the active conversation's `view()` (attaching the\n * active workspace's scope-filtered image files' `base64` payload to the last user message), built\n * fresh each call; the scope never filters the conversation. The active workspace is the sole\n * document/image context. Tools are advertised structurally (through\n * `tools.definitions()`, scope-filtered by the loop), never serialized into the prompt.\n *\n * @param options - Optional `system` / `tools` / `instructions` / `workspaces` /\n * `conversations` / `scope` / `select` (see {@link AgentContextOptions})\n * @returns A working {@link AgentContextInterface}\n *\n * @example\n * ```ts\n * import { createAgentContext } from '@orkestrel/agent'\n *\n * const context = createAgentContext({ system: 'You are concise.' })\n * context.instructions.add({ name: 'tone', content: 'Be terse.' })\n * context.messages.add({ role: 'user', content: 'Hi' })\n * context.build() // [{ role: 'system', content: 'You are concise.\\n\\n## Instructions\\n\\nBe terse.' }, { role: 'user', content: 'Hi' }]\n * ```\n */\nexport function createAgentContext(options?: AgentContextOptions): AgentContextInterface {\n\treturn new AgentContext(options)\n}\n","/**\n * Caps an {@link AgentInterface} turn's tool iterations by default — `10` context → provider →\n * tools cycles before the loop stops, so a model that keeps requesting tools can never loop\n * forever. Overridable per agent through `AgentOptions.limit`.\n */\nexport const DEFAULT_AGENT_LIMIT = 10\n\n/**\n * Names the default zone for an unmatched tool call allowed by an authority.\n */\nexport const DEFAULT_AUTHORITY_ZONE = 'default'\n\n/**\n * Estimates the role and framing overhead added to each message by {@link estimateMessages}.\n */\nexport const MESSAGE_TOKEN_OVERHEAD = 4\n\n/**\n * Names the coarse, deliberately approximate per-image token cost\n * {@link import('./helpers.js').estimateMessages} charges for each attached image — `512`, because\n * a base64 payload's length is no reliable token proxy.\n *\n * @remarks\n * A base64 image payload's length is not a reliable token proxy (a vision model's actual image\n * token cost depends on resolution / tiling, not byte size), so this is a fixed, coarse\n * per-image estimate rather than a derivation from `image.length` — a planning heuristic, not an\n * exact count.\n */\nexport const IMAGE_TOKEN_ESTIMATE = 512\n","import type { AgentErrorCode, AgentResult } from './types.js'\nimport type { CodedErrorOptions } from '../types.js'\nimport {\n\tINTRINSICS,\n\tholds,\n\tisObject,\n\tisFunction,\n\tisNumber,\n\tisString,\n\tisBoolean,\n} from '@orkestrel/contract'\n\n// A real error type, not a sentinel. An agent job treats a partial result\n// (a job committed early from an abort / budget / timeout) as a failure by default — the\n// queue / runner handler throws this so the Queue's retries + a Runner's fail-fast\n// engage. It carries the partial AgentResult so a caller (or a `retries: 0` enqueue that\n// rejects with it) can still inspect what accumulated.\n\n/**\n * Reports an {@link AgentInterface} run that ended {@link AgentResult.partial} under a\n * `partial` policy of `false` (the default) — thrown by an agent-job handler (a\n * `createAgentQueue` / `createAgentRunner` job), carrying the partial {@link AgentResult} so\n * the failure stays inspectable, and the machine-readable `code` `'PARTIAL'`.\n *\n * @remarks\n * A partial result means the agent was cancelled (an external `signal` abort, a queue /\n * runner abort threaded in, a `timeout` deadline, or an exhausted token `budget`) rather\n * than finishing naturally. For a durable job that is a failure by default: throwing this\n * lets the Queue's retries re-run the job and a Runner's fail-fast abort its siblings.\n * Set `partial: true` (see `AgentQueueOptions` / `AgentRunnerOptions`) to treat a\n * partial as success instead, in which case this is never thrown. Narrow a caught value\n * with {@link isAgentJobError} to read `partial`. `code` is the machine-readable condition\n * (`'PARTIAL'` — the only one this error reports), so a `catch` branches on it rather than on\n * the message string.\n */\nexport class AgentJobError extends Error {\n\t/** Names the machine-readable condition — `'PARTIAL'`: a job that ended partial under a disallowing policy. */\n\treadonly code = 'PARTIAL' as const\n\t/** Holds the partial {@link AgentResult} the cancelled job produced. */\n\treadonly partial: AgentResult\n\n\tconstructor(message: string, partial: AgentResult) {\n\t\tsuper(message)\n\t\tthis.name = 'AgentJobError'\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/agent.AgentJobError'), { value: this })\n\t\tthis.partial = partial\n\t}\n}\n\n/**\n * Narrows an unknown caught value to an {@link AgentJobError} through its identity brand and declared members, so a\n * `catch` can recover its `partial` result.\n *\n * @param value - The value to test (typically a `catch` binding or a rejected enqueue)\n * @returns True if `value` is an {@link AgentJobError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tawait queue.enqueue(job) // retries: 0 → a partial rejects with the error\n * } catch (error) {\n * \tif (isAgentJobError(error)) keep(error.partial.content) // recover the partial content\n * }\n * ```\n */\nexport function isAgentJobError(value: unknown): value is AgentJobError {\n\treturn holds(() => {\n\t\tif (\n\t\t\t!(\n\t\t\t\tvalue instanceof Error &&\n\t\t\t\tINTRINSICS.prototype(value) !== Error.prototype &&\n\t\t\t\tINTRINSICS.describe(value, Symbol.for('@orkestrel/agent.AgentJobError'))?.value === value\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\tconst code = INTRINSICS.reflect.read(value, 'code')\n\t\tif (!(code === 'PARTIAL')) return false\n\t\tconst partial = INTRINSICS.reflect.read(value, 'partial')\n\t\tif (!(isObject(partial) || isFunction(partial))) return false\n\t\tconst usage = INTRINSICS.reflect.read(partial, 'usage')\n\t\tconst stop = INTRINSICS.reflect.read(partial, 'stop')\n\t\tif (stop !== undefined) {\n\t\t\tif (!(isObject(stop) || isFunction(stop))) return false\n\t\t\tconst layer = INTRINSICS.reflect.read(stop, 'layer')\n\t\t\tconst spent = INTRINSICS.reflect.read(stop, 'usage')\n\t\t\tif (\n\t\t\t\t!isString(INTRINSICS.reflect.read(stop, 'id')) ||\n\t\t\t\t!(\n\t\t\t\t\tINTRINSICS.reflect.read(stop, 'estimate') === undefined ||\n\t\t\t\t\tisNumber(INTRINSICS.reflect.read(stop, 'estimate'))\n\t\t\t\t) ||\n\t\t\t\t!(\n\t\t\t\t\tspent === undefined ||\n\t\t\t\t\t((isObject(spent) || isFunction(spent)) &&\n\t\t\t\t\t\t['prompt', 'completion', 'total'].every((key) =>\n\t\t\t\t\t\t\tisNumber(INTRINSICS.reflect.read(spent, key)),\n\t\t\t\t\t\t))\n\t\t\t\t)\n\t\t\t)\n\t\t\t\treturn false\n\t\t\tif (\n\t\t\t\tlayer !== 'model' &&\n\t\t\t\t!(\n\t\t\t\t\t(layer === 'meter' || layer === 'budget') &&\n\t\t\t\t\tisNumber(INTRINSICS.reflect.read(stop, 'max')) &&\n\t\t\t\t\tisNumber(INTRINSICS.reflect.read(stop, 'consumed'))\n\t\t\t\t)\n\t\t\t)\n\t\t\t\treturn false\n\t\t}\n\t\treturn (\n\t\t\tisString(INTRINSICS.reflect.read(partial, 'content')) &&\n\t\t\t(INTRINSICS.reflect.read(partial, 'thinking') === undefined ||\n\t\t\t\tisString(INTRINSICS.reflect.read(partial, 'thinking'))) &&\n\t\t\tisBoolean(INTRINSICS.reflect.read(partial, 'partial')) &&\n\t\t\t(usage === undefined ||\n\t\t\t\t((isObject(usage) || isFunction(usage)) &&\n\t\t\t\t\t['prompt', 'completion', 'total'].every((key) =>\n\t\t\t\t\t\tisNumber(INTRINSICS.reflect.read(usage, key)),\n\t\t\t\t\t)))\n\t\t)\n\t})\n}\n\n// A real error type, not a sentinel. A run that would share an accounting instance with a live\n// run would corrupt that accounting, so `stream()` throws this synchronously, before any state\n// mutation or emit, rather than letting the runs race. Carries a machine-readable `code` so a\n// `catch` branches on `error.code`, mirroring `ConversationError` in `conversations/errors.ts`.\n\n/**\n * Reports a run sharing accounting with a live run, a `limit` that is not a nonnegative safe integer, a name absent from a registry pool, or a strict run whose request exceeds its window. Agent construction, the `stream` and `generate` methods, and registry accessors throw synchronously, before returning a handle or promise; a `'WINDOW'` refusal rejects the run's `result` instead. Await the call inside `try`/`catch` to catch it.\n *\n * @remarks\n * `'CONCURRENCY'` reports a run started while another run on the same agent is live, when the\n * agent carries a `window` (a shared context budget) or when the run's effective `budget` or\n * `allowance` is an instance a live run holds — the second run's `start()` would replace that\n * instance's signal and race its charges against the first run's. Use separate agents, or\n * distinct budget and allowance instances per run with no `window`, for concurrent runs. Its\n * `context` names the `agent` id.\n * `'LIMIT'` reports a construction or per-run `limit` that is not a nonnegative safe integer,\n * including one a rehydrated job carries into `build`. `'REGISTRY'` reports a rehydration name\n * absent from its registry pool, on `provider` / `tool` / `authority` / `scheduler` / `build`;\n * its `context` names the `category` and the `name`. `'WINDOW'` reports a `strict` run whose\n * complete provider request is still over the `window` budget, equal to its `max` included, after\n * the one permitted fold or with no fold possible; it settles the run `error` before the provider\n * is called, and its `context` holds the `agent` id, the measured `consumed`, and the window `max`.\n * Narrow a caught value with {@link isAgentError} and branch on `error.code`.\n */\nexport class AgentError extends Error {\n\t/** Names the machine-readable condition — `'CONCURRENCY'`: a run sharing accounting with a live run; `'LIMIT'`: a `limit` that is not a nonnegative safe integer; `'REGISTRY'`: a rehydration name absent from its registry pool; `'WINDOW'`: a strict run whose complete request is still over its window budget. */\n\treadonly code: AgentErrorCode\n\t/** Holds the values that locate the failure, such as the `agent` id of a refused run, or `undefined` when none were supplied. */\n\treadonly context: Readonly<Record<string, unknown>> | undefined\n\n\t/**\n\t * Creates the error with its code, message, and optional cause and context.\n\t *\n\t * @param code - The machine-readable {@link AgentErrorCode}\n\t * @param message - The human-readable description\n\t * @param options - The optional {@link CodedErrorOptions}; `cause` reaches `Error.cause` only when present\n\t */\n\tconstructor(code: AgentErrorCode, message: string, options?: CodedErrorOptions) {\n\t\tsuper(message, options?.cause === undefined ? undefined : { cause: options.cause })\n\t\tthis.name = 'AgentError'\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/agent.AgentError'), { value: this })\n\t\tthis.code = code\n\t\tthis.context = options?.context\n\t}\n}\n\n/**\n * Narrows an unknown caught value to an {@link AgentError} through its identity brand and declared members, so a `catch`\n * can branch on its `code`.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns True if `value` is an {@link AgentError}; false otherwise\n *\n * @example\n * ```ts\n * try {\n * \tagent.stream()\n * } catch (error) {\n * \tif (isAgentError(error) && error.code === 'CONCURRENCY') useSeparateAgents()\n * }\n * ```\n */\nexport function isAgentError(value: unknown): value is AgentError {\n\treturn holds(() => {\n\t\tif (\n\t\t\t!(\n\t\t\t\tvalue instanceof Error &&\n\t\t\t\tINTRINSICS.prototype(value) !== Error.prototype &&\n\t\t\t\tINTRINSICS.describe(value, Symbol.for('@orkestrel/agent.AgentError'))?.value === value\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\tconst code = INTRINSICS.reflect.read(value, 'code')\n\t\tif (!(code === 'CONCURRENCY' || code === 'LIMIT' || code === 'REGISTRY' || code === 'WINDOW'))\n\t\t\treturn false\n\t\tconst context = INTRINSICS.reflect.read(value, 'context')\n\t\treturn context === undefined || isObject(context) || isFunction(context)\n\t})\n}\n","import type { ChannelInterface } from './types.js'\n\n/**\n * Buffers chunks in a minimal unbounded async channel — the eager pump writes them in (`push`)\n * and ends it (`close` / `fail`) regardless of consumption, while a consumer reads them back live\n * through the `drain` async-iterator. Decoupling write from read is what lets a producer make\n * progress without a consumer pulling, and it is why an agent's `result` settles whether or not\n * its `events` are drained.\n *\n * @remarks\n * A waiting `drain` parks its void resolver in `#waiting`; `push` / `close` / `fail`\n * enqueue/flag, then fire and clear every parked resolver, so each parked reader wakes,\n * re-reads the shared buffer, and either takes the next chunk, returns (on `close`), throws\n * (on `fail`), or parks again when another reader took the chunk first. Taking a chunk is\n * synchronous, so each value reaches exactly one reader.\n * A `return()` issued while a read is parked waits for the next `push`, `close`, or `fail`.\n * The parked read takes a pushed value before that `return()` settles.\n *\n * @example\n * ```ts\n * import { Channel } from '@orkestrel/agent'\n *\n * const channel = new Channel<number>()\n * channel.push(1)\n * channel.close()\n * for await (const value of channel.drain()) {\n * \tvalue // 1\n * }\n * ```\n */\nexport class Channel<T> implements ChannelInterface<T> {\n\t#buffer: ReadonlyArray<{ readonly value: T }> = []\n\t#waiting: ReadonlyArray<() => void> = []\n\t#closed = false\n\t#failure: { error: unknown } | undefined\n\n\tpush(value: T): void {\n\t\tthis.#buffer = [...this.#buffer, { value }]\n\t\tthis.#signal()\n\t}\n\n\tclose(): void {\n\t\tthis.#closed = true\n\t\tthis.#signal()\n\t}\n\n\tfail(error: unknown): void {\n\t\t// First failure wins; a later close / fail can't override a recorded error.\n\t\tif (this.#failure === undefined) this.#failure = { error }\n\t\tthis.#closed = true\n\t\tthis.#signal()\n\t}\n\n\tasync *drain(): AsyncGenerator<T, void> {\n\t\tfor (;;) {\n\t\t\t// Yield everything buffered before checking for end, so a close / fail that\n\t\t\t// arrives alongside the last chunks still delivers those chunks first.\n\t\t\twhile (this.#buffer.length > 0) {\n\t\t\t\tconst [cell, ...remaining] = this.#buffer\n\t\t\t\tthis.#buffer = remaining\n\t\t\t\tif (cell !== undefined) yield cell.value\n\t\t\t}\n\t\t\tif (this.#failure !== undefined) throw this.#failure.error\n\t\t\tif (this.#closed) return\n\t\t\tawait this.#park()\n\t\t}\n\t}\n\n\t// Wake every parked reader, not one: with concurrent readers, a single woken reader would\n\t// leave the rest parked past a `close` / `fail`. The list is cleared before firing, so a\n\t// reader that re-parks arms the next wait. A `signal` with no parked reader is a no-op (the\n\t// buffer / flags are already set, so the next `drain` pass reads them without parking).\n\t#signal(): void {\n\t\tconst waiting = this.#waiting\n\t\tthis.#waiting = []\n\t\tfor (const wake of waiting) wake()\n\t}\n\n\t#park(): Promise<void> {\n\t\treturn new Promise<void>((resolve) => {\n\t\t\tthis.#waiting = [...this.#waiting, resolve]\n\t\t})\n\t}\n}\n","import type { Message } from '../types.js'\nimport type { ProviderRequest } from '../providers/index.js'\nimport type {\n\tAgentInterface,\n\tAgentJobInput,\n\tAgentRegistryInterface,\n\tAgentResult,\n\tAgentRunResult,\n\tAgentStop,\n\tAgentTurn,\n\tMessageMeasure,\n\tRequestMeasure,\n} from './types.js'\nimport type { BudgetInterface, TokenUsage } from '@orkestrel/budget'\nimport type { JSONValue } from '@orkestrel/contract'\nimport type { QueueContext, QueueOptions } from '@orkestrel/queue'\nimport type { ToolCall, ToolResult } from '@orkestrel/tool'\nimport { isBudget, isBudgetError } from '@orkestrel/budget'\nimport {\n\tattempt,\n\tContractError,\n\tisBoolean,\n\tisFiniteNumber,\n\tisObject,\n\tisString,\n\tparseJSONValue,\n\tpreview,\n} from '@orkestrel/contract'\nimport { IMAGE_TOKEN_ESTIMATE, MESSAGE_TOKEN_OVERHEAD } from './constants.js'\nimport { AgentError, AgentJobError } from './errors.js'\nimport { hasCalls, renderJSON } from '../helpers.js'\nimport { isNonNegativeSafeInteger } from '../validators.js'\n\n/**\n * Projects an unknown value onto a fresh, exact `JSONValue` representation of an\n * {@link AgentResult} — capturing each structural field once through a total boundary,\n * accepting conforming accessors and inherited properties, preserving finite negative and\n * fractional usage counts, dropping extras, and resolving `undefined` for a malformed field, a\n * non-finite usage number, a throwing getter, or a hostile or revoked proxy.\n *\n * @remarks\n * This is a total hostile-boundary projection. Each structural field is captured once\n * through Contract's sanctioned exception boundary, so conforming accessors and inherited\n * properties are supported while a throwing getter or revoked proxy returns `undefined`.\n * Present usage counts must be finite numbers; negative and fractional values are preserved,\n * not normalized. The result is exact `{ content, thinking?, usage?, partial, stop? }`. A present\n * `stop` is read once, then its `layer`, `id`, `max`, `consumed`, `estimate`, and `usage` once each\n * in that order, `max` and `consumed` only on a `meter` or `budget` arm; the arm is rebuilt\n * exactly, omitting absent readings, and a malformed `stop` refuses the whole value. Extra input\n * properties are dropped while a fresh exact plain object is rebuilt and deep-gated through\n * {@link import('@orkestrel/contract').parseJSONValue}.\n *\n * @param value - The unknown value to project\n * @returns A fresh JSON value containing only AgentResult fields, or `undefined` when invalid\n *\n * @example\n * ```ts\n * import { agentResultToJSON } from '@orkestrel/agent'\n *\n * agentResultToJSON({ content: 'done', usage: { prompt: 2, completion: 1, total: 3 }, partial: false })\n * // { content: 'done', usage: { prompt: 2, completion: 1, total: 3 }, partial: false }\n * ```\n */\nexport function agentResultToJSON(value: unknown): JSONValue | undefined {\n\tconst captured = attempt(() => {\n\t\tif (!isObject(value)) return undefined\n\n\t\tconst content = Reflect.get(value, 'content')\n\t\tconst thinking = Reflect.get(value, 'thinking')\n\t\tconst usage = Reflect.get(value, 'usage')\n\t\tconst partial = Reflect.get(value, 'partial')\n\t\tconst stop = Reflect.get(value, 'stop')\n\t\tif (!isString(content) || !isBoolean(partial)) return undefined\n\t\tif (thinking !== undefined && !isString(thinking)) return undefined\n\t\tconst projectedUsage = usage === undefined ? undefined : tokenUsageToJSON(usage)\n\t\tif (usage !== undefined && projectedUsage === undefined) return undefined\n\t\tif (stop !== undefined && !isObject(stop)) return undefined\n\n\t\tconst layer = isObject(stop) ? Reflect.get(stop, 'layer') : undefined\n\t\tconst id = isObject(stop) ? Reflect.get(stop, 'id') : undefined\n\t\tconst ranked = layer === 'meter' || layer === 'budget'\n\t\tconst max = isObject(stop) && ranked ? Reflect.get(stop, 'max') : undefined\n\t\tconst consumed = isObject(stop) && ranked ? Reflect.get(stop, 'consumed') : undefined\n\t\tconst estimate = isObject(stop) ? Reflect.get(stop, 'estimate') : undefined\n\t\tconst spent = isObject(stop) ? Reflect.get(stop, 'usage') : undefined\n\t\tconst projectedSpent = spent === undefined ? undefined : tokenUsageToJSON(spent)\n\t\tconst readings = {\n\t\t\t...(isFiniteNumber(estimate) ? { estimate } : {}),\n\t\t\t...(projectedSpent === undefined ? {} : { usage: projectedSpent }),\n\t\t}\n\t\tconst projectedStop =\n\t\t\t!isString(id) ||\n\t\t\t(estimate !== undefined && !isFiniteNumber(estimate)) ||\n\t\t\t(spent !== undefined && projectedSpent === undefined)\n\t\t\t\t? undefined\n\t\t\t\t: ranked && isFiniteNumber(max) && isFiniteNumber(consumed)\n\t\t\t\t\t? { layer, id, max, consumed, ...readings }\n\t\t\t\t\t: layer === 'model'\n\t\t\t\t\t\t? { layer, id, ...readings }\n\t\t\t\t\t\t: undefined\n\t\tif (stop !== undefined && projectedStop === undefined) return undefined\n\n\t\treturn {\n\t\t\tcontent,\n\t\t\t...(thinking === undefined ? {} : { thinking }),\n\t\t\t...(projectedUsage === undefined ? {} : { usage: projectedUsage }),\n\t\t\tpartial,\n\t\t\t...(projectedStop === undefined ? {} : { stop: projectedStop }),\n\t\t}\n\t})\n\n\treturn captured.success ? parseJSONValue(captured.value) : undefined\n}\n\n/**\n * Projects an unknown value onto a fresh, exact `TokenUsage` — capturing `prompt`, `completion`, and\n * `total` once each through a total boundary, preserving finite negative and fractional counts,\n * dropping extras, and resolving `undefined` for a non-object, a missing or non-finite count, a\n * throwing getter, or a hostile or revoked proxy.\n *\n * @remarks\n * The capture runs inside Contract's sanctioned exception boundary, so conforming accessors and\n * inherited properties are read while a throwing getter or a revoked proxy returns `undefined`.\n * Counts are not normalized. A caller that treats an absent usage as valid checks for `undefined`\n * before it projects, because this function refuses `undefined` like any other non-object.\n *\n * @param value - The unknown value to project\n * @returns A fresh `{ prompt, completion, total }`, or `undefined` when the value is not a finite usage triple\n *\n * @example\n * ```ts\n * import { tokenUsageToJSON } from '@orkestrel/agent'\n *\n * tokenUsageToJSON({ prompt: 2, completion: -1, total: 1.5, cached: 4 }) // { prompt: 2, completion: -1, total: 1.5 }\n * tokenUsageToJSON({ prompt: 2, completion: Infinity, total: 3 }) // undefined\n * ```\n */\nexport function tokenUsageToJSON(value: unknown): TokenUsage | undefined {\n\tconst captured = attempt(() => {\n\t\tif (!isObject(value)) return undefined\n\t\tconst prompt = Reflect.get(value, 'prompt')\n\t\tconst completion = Reflect.get(value, 'completion')\n\t\tconst total = Reflect.get(value, 'total')\n\t\treturn isFiniteNumber(prompt) && isFiniteNumber(completion) && isFiniteNumber(total)\n\t\t\t? { prompt, completion, total }\n\t\t\t: undefined\n\t})\n\treturn captured.success ? captured.value : undefined\n}\n\n/**\n * Infers which of a run's three failure layers stopped it — the meter allowance, a cost budget, or\n * the model's own token limit — and returns the stop record with the final call's readings, or\n * `undefined` when no layer stopped the run.\n *\n * @remarks\n * The layer that stopped the final provider call first wins. A model-truncated final answer whose\n * call returned unaborted is a `model` stop, even when that call's reconciled usage then exhausted a\n * budget or a cancel then landed before the run settled. Otherwise a `BudgetError` reason is a\n * `meter` stop when the allowance is exhausted, the reason is the allowance signal's own reason, its\n * context carries the allowance's `id` and `max`, and either the allowance is a separate instance or\n * the run had aborted when the call returned; any other `BudgetError` is a `budget` stop. The\n * identity test tells an allowance and a budget that share an `id` apart, and the readings test\n * tells a parent budget linked through the allowance's `signal` option apart from the allowance. An\n * external cancel, a deadline, or an `abort()` reason yields `undefined`. Two inputs still read as\n * the meter's: a charge a caller makes to the run's shared allowance from its own code while a call\n * streams, and a parent with the allowance's own `id` and `max` that aborted before `start()` when\n * the allowance then exhausts.\n *\n * @param reason - The run signal's abort reason (`undefined` while it is unaborted)\n * @param allowance - The run's meter allowance, or `undefined` for a run with no meter layer\n * @param budget - The run's cost budget, or `undefined` for an unbudgeted run\n * @param provider - The provider's trace `id`, named by a `model` stop\n * @param turn - The run's final turn record, or `undefined` when the run took no turn\n * @returns The stop record, or `undefined` when no layer stopped the run\n *\n * @example\n * ```ts\n * const allowance = createTokenBudget({ id: 'meter', max: 2 })\n * allowance.start()\n * allowance.consume({ prompt: 0, completion: 3, total: 3 })\n * inferStop(allowance.signal.reason, allowance, undefined, 'ollama', undefined)\n * // { layer: 'meter', id: 'meter', max: 2, consumed: 3 }\n * ```\n */\nexport function inferStop(\n\treason: unknown,\n\tallowance: BudgetInterface<TokenUsage> | undefined,\n\tbudget: BudgetInterface<TokenUsage> | undefined,\n\tprovider: string,\n\tturn: AgentTurn | undefined,\n): AgentStop | undefined {\n\tconst readings = {\n\t\t...(turn?.estimate === undefined ? {} : { estimate: turn.estimate }),\n\t\t...(turn?.usage === undefined ? {} : { usage: turn.usage }),\n\t}\n\tconst interrupted = turn?.interrupted === true\n\tif (!interrupted && turn?.truncated === true) return { layer: 'model', id: provider, ...readings }\n\tif (!isBudgetError(reason)) return undefined\n\tconst metered =\n\t\tallowance !== undefined &&\n\t\tallowance.exhausted &&\n\t\treason === allowance.signal.reason &&\n\t\treason.context.id === allowance.id &&\n\t\treason.context.max === allowance.max &&\n\t\t(allowance !== budget || interrupted)\n\treturn {\n\t\tlayer: metered ? 'meter' : 'budget',\n\t\tid: reason.context.id,\n\t\tmax: reason.context.max,\n\t\tconsumed: reason.context.consumed,\n\t\t...readings,\n\t}\n}\n\n/**\n * Estimates the context-token footprint of a string — the deterministic `ceil(length / 4)`\n * character heuristic {@link estimateMessages} sums over a conversation's messages (the default\n * context-budget estimator).\n *\n * @remarks\n * Approximates `ceil(length / 4)` (4 characters per token), so the same input always yields the same estimate (no model round-trip).\n * Empty text is `0`. This is a planning heuristic for reasoning about how much a turn's\n * messages cost the next request, not an exact tokenizer count — it never calls a provider,\n * so the agent layer stays provider-agnostic and synchronous where it can be.\n *\n * @param text - The text to estimate (a section summary, a message's content)\n * @returns The estimated token count (`ceil(text.length / 4)`; `0` for empty text)\n *\n * @example\n * ```ts\n * estimateTokens('') // 0\n * estimateTokens('hello') // 2 (ceil(5 / 4))\n * estimateTokens('a'.repeat(40)) // 10\n * ```\n */\nexport function estimateTokens(text: string): number {\n\treturn Math.ceil(text.length / 4)\n}\n\n/**\n * Estimates the context-token footprint of a batch of messages — each message's content plus\n * {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}, a tool-call JSON estimate, a thinking estimate, and\n * {@link import('./constants.js').IMAGE_TOKEN_ESTIMATE} for each attached image. The {@link estimateRequest} message term\n * for an agent's context budget (the\n * {@link import('./types.js').AgentOptions} `window`), a provider-independent approximation for conforming messages rather than an exact tokenizer count.\n *\n * @remarks\n * Sums, per message, {@link estimateTokens} over its `content` (the `ceil(length / 4)` character\n * heuristic) plus {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} (a fixed per-message\n * role/framing overhead) plus, when present, {@link estimateTokens} over its JSON-stringified\n * `calls` plus, when present, {@link estimateTokens} over its `thinking` plus `images.length * `{@link import('./constants.js').IMAGE_TOKEN_ESTIMATE} (a coarse,\n * deliberately-approximate per-image cost — a base64 length is not a token proxy). Deterministic\n * and provider-free — the same messages always yield the same estimate, with an empty batch `0`.\n * It is the message term of the request estimate an agent's auto-compaction context budget\n * measures; a caller wanting a sharper count supplies its own `consumer` to `createBudget`\n * instead. A `calls` list JSON cannot carry (a circular or `BigInt`\n * `ToolCall.arguments`) contributes a fixed\n * {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} (the same per-message overhead scale)\n * instead of an estimate of the (unreachable) serialized length.\n *\n * @param messages - The messages to estimate (a turn's appended assistant + tool messages)\n * @returns The summed estimated token count (`0` when empty)\n *\n * @example\n * ```ts\n * estimateMessages([]) // 0\n * estimateMessages([{ id: '1', role: 'user', content: 'hello' }]) // 6 (2 content + 4 overhead)\n * ```\n */\nexport function estimateMessages(messages: readonly Message[]): number {\n\treturn messages.reduce((sum, message) => {\n\t\tconst measure = measureMessage(message)\n\t\treturn (\n\t\t\tsum + measure.content + measure.uniform + measure.calls + measure.thinking + measure.images\n\t\t)\n\t}, 0)\n}\n\n/**\n * Measures the disjoint estimate components of one message — its content, framing, rendered calls,\n * thinking, and attached images — as the same heuristic units {@link estimateMessages} sums.\n *\n * @remarks\n * The result is a structural estimate, not a tokenizer allocation. `id` and `role` are joins back to\n * the message, not token components, and a provider's template effects and the estimation error are\n * not individually attributed. `content` is `ceil(length / 4)`, `uniform` is\n * {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}, `calls` is the estimate of the JSON-rendered\n * calls (`0` when the message carries none, the framing overhead when they cannot be rendered),\n * `thinking` is the estimate of the thinking (`0` when absent), and `images` is the attached image\n * count times {@link import('./constants.js').IMAGE_TOKEN_ESTIMATE}. The message is not mutated.\n *\n * @param message - The message to measure\n * @returns The message's identity and its estimate components\n *\n * @example\n * ```ts\n * measureMessage({ id: '1', role: 'user', content: 'hello' })\n * // { id: '1', role: 'user', content: 2, uniform: 4, calls: 0, thinking: 0, images: 0 }\n * ```\n */\nexport function measureMessage(message: Message): MessageMeasure {\n\tconst rendered = hasCalls(message) ? renderJSON(message.calls) : ''\n\tconst calls = rendered === undefined ? MESSAGE_TOKEN_OVERHEAD : estimateTokens(rendered)\n\treturn {\n\t\tid: message.id,\n\t\trole: message.role,\n\t\tcontent: estimateTokens(message.content),\n\t\tuniform: MESSAGE_TOKEN_OVERHEAD,\n\t\tcalls,\n\t\tthinking: message.thinking === undefined ? 0 : estimateTokens(message.thinking),\n\t\timages: (message.images?.length ?? 0) * IMAGE_TOKEN_ESTIMATE,\n\t}\n}\n\n/**\n * Estimates the context-token footprint of a complete provider request — its messages through\n * {@link estimateMessages}, plus the rendered advertised `tools`, plus the rendered\n * `options.schema`. The `consumer` estimator an agent's `window` budget measures every request\n * through, a provider-independent heuristic rather than an exact tokenizer count.\n *\n * @remarks\n * Adds {@link estimateTokens} over the JSON rendering of `tools` and of `options.schema` to the\n * message estimate. An absent or empty `tools` list and an absent or empty `schema` add `0`, so a\n * request that advertises neither equals {@link estimateMessages} of its messages. A value JSON\n * cannot carry contributes a fixed {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD}. The\n * estimate counts JSON characters, not a provider's template: the chat template's own tokens, how\n * a provider encodes tool definitions, and the `think` flag are not counted, and no tokenizer\n * runs. A model's real prompt count can exceed it, so choose the window `max` with headroom\n * measured against the provider.\n *\n * @param request - The {@link ProviderRequest} to estimate: messages, advertised tools, call options\n * @returns The estimated token count (`0` for an empty request)\n *\n * @example\n * ```ts\n * estimateRequest({ messages: [{ id: '1', role: 'user', content: 'hello' }] }) // 6, equal to estimateMessages\n * ```\n */\nexport function estimateRequest(request: ProviderRequest): number {\n\tconst measure = measureRequest(request)\n\treturn measure.messages.reduce(\n\t\t(sum, message) =>\n\t\t\tsum + message.content + message.uniform + message.calls + message.thinking + message.images,\n\t\tmeasure.tools + measure.schema,\n\t)\n}\n\n/**\n * Measures the disjoint estimate components of a complete provider request — each message through\n * {@link measureMessage}, plus the rendered advertised `tools` and `options.schema` — as the same\n * heuristic units {@link estimateRequest} sums.\n *\n * @remarks\n * The result is a structural estimate, not a tokenizer allocation; a provider's template effects, how\n * it encodes tool definitions, the `think` flag, and the estimation error are not individually\n * attributed. `messages` keeps the request's message order, duplicate ids included. `tools` and\n * `schema` are each `0` when absent or empty and the estimate of their JSON rendering otherwise, or\n * the {@link import('./constants.js').MESSAGE_TOKEN_OVERHEAD} when JSON cannot carry them. The request\n * is not mutated.\n *\n * @param request - The {@link ProviderRequest} to measure: messages, advertised tools, call options\n * @returns The per-message components and the tools and schema estimates\n *\n * @example\n * ```ts\n * measureRequest({ messages: [{ id: '1', role: 'user', content: 'hello' }] })\n * // { messages: [{ id: '1', role: 'user', content: 2, uniform: 4, calls: 0, thinking: 0, images: 0 }], tools: 0, schema: 0 }\n * ```\n */\nexport function measureRequest(request: ProviderRequest): RequestMeasure {\n\tconst tools = request.tools !== undefined && request.tools.length > 0 ? request.tools : undefined\n\tconst schema = request.options?.schema\n\tconst [toolsEstimate = 0, schemaEstimate = 0] = [\n\t\ttools,\n\t\tschema !== undefined && Object.keys(schema).length > 0 ? schema : undefined,\n\t].map((part) => {\n\t\tif (part === undefined) return 0\n\t\tconst rendered = renderJSON(part)\n\t\treturn rendered === undefined ? MESSAGE_TOKEN_OVERHEAD : estimateTokens(rendered)\n\t})\n\treturn {\n\t\tmessages: request.messages.map((message) => measureMessage(message)),\n\t\ttools: toolsEstimate,\n\t\tschema: schemaEstimate,\n\t}\n}\n\n/**\n * Runs one rehydrated agent and applies the partial-as-configurable-failure policy — a partial\n * run throws an {@link import('./errors.js').AgentJobError} unless the `partial` policy allows\n * it, and a natural finish resolves. The shared job-handler step `createAgentQueue` and\n * `createAgentRunner` both settle each job through, so the policy can never diverge between\n * them.\n *\n * @remarks\n * A turn that committed partial (a cancel — abort / budget / timeout) is by default a\n * failure, so it throws an {@link import('./errors.js').AgentJobError} carrying the partial\n * (the Queue's retries + a Runner's fail-fast then engage); the `partial` policy resolves\n * it as success instead. A natural finish always resolves with its result.\n *\n * @param agent - The rehydrated {@link AgentInterface} to run to its {@link AgentResult}\n * @param partial - The partial policy. If `true`, a partial result resolves as success; if\n * `false` (the default policy), a partial result throws an {@link AgentJobError}\n * @returns The agent's {@link AgentResult} (a natural finish, or a partial one under the\n * `partial` policy)\n * @throws {AgentJobError} Thrown when the run ended partial and the `partial` policy is `false`\n *\n * @example\n * ```ts\n * const result = await settleAgentJob(registry.build(input, signal), false)\n * ```\n */\nexport async function settleAgentJob(\n\tagent: AgentInterface,\n\tpartial: boolean,\n): Promise<AgentResult> {\n\tconst result = await agent.generate()\n\tif (result.partial && !partial) throw new AgentJobError('agent job ended partial', result)\n\treturn result\n}\n\n/**\n * Handles one queued agent job by rehydrating it through a registry with the queue\n * attempt's signal, then applying the shared partial-result policy.\n *\n * @param registry - The registry that rehydrates the serializable job\n * @param partial - The partial policy. If `true`, a partial result resolves; if `false`, it throws\n * @param input - The serializable agent job\n * @param context - The queue attempt whose signal bounds the agent\n * @returns The settled agent result\n *\n * @example\n * ```ts\n * const result = await handleAgentQueueJob(registry, false, input, context)\n * ```\n */\nexport function handleAgentQueueJob(\n\tregistry: AgentRegistryInterface,\n\tpartial: boolean,\n\tinput: AgentJobInput,\n\tcontext: QueueContext,\n): Promise<AgentResult> {\n\treturn settleAgentJob(registry.build(input, context.signal), partial)\n}\n\n/**\n * Assembles the settled {@link AgentResult} from a run's {@link AgentRunResult} — `thinking`,\n * `usage`, and `stop` are carried only when the run surfaced them, and the loop-internal\n * `exhausted` flag is left out.\n *\n * @remarks\n * Pure and total. An absent optional is omitted rather than stored as `undefined` (the\n * present-when-given convention the message store follows), so a settled result JSON\n * round-trips without an explicit `undefined` field. The keys follow `content`, `partial`,\n * `thinking`, `usage`, then `stop`. `exhausted` is loop bookkeeping and does not reach the public\n * result — the `exhaust` event carries it instead.\n *\n * @param outcome - The run's settled outcome\n * @returns The public {@link AgentResult}\n *\n * @example\n * ```ts\n * assembleResult({ content: 'hi', thinking: undefined, usage: undefined, partial: false, exhausted: false, stop: undefined })\n * // { content: 'hi', partial: false }\n * ```\n */\nexport function assembleResult(outcome: AgentRunResult): AgentResult {\n\treturn {\n\t\tcontent: outcome.content,\n\t\tpartial: outcome.partial,\n\t\t...(outcome.thinking === undefined ? {} : { thinking: outcome.thinking }),\n\t\t...(outcome.usage === undefined ? {} : { usage: outcome.usage }),\n\t\t...(outcome.stop === undefined ? {} : { stop: outcome.stop }),\n\t}\n}\n\n/**\n * Synthesizes the denial {@link ToolResult} an authority-blocked call is fed back with — the\n * call's `id` / `name` keyed back, carrying a denial `error` instead of a value.\n *\n * @remarks\n * Pure and total. The rule's `reason` is rendered as `denied: <reason>` when one was given,\n * else the generic `denied by authority`. There is no `value`, so the agent loop feeds it back\n * exactly like a tool error and the model can react to it.\n *\n * @param call - The denied {@link ToolCall}\n * @param reason - The rule's explanation, or `undefined` for the generic denial\n * @returns The failure-arm {@link ToolResult}\n *\n * @example\n * ```ts\n * denyCall({ id: '1', name: 'drop', arguments: {} }, 'read-only mode')\n * // { success: false, id: '1', name: 'drop', error: 'denied: read-only mode' }\n * ```\n */\nexport function denyCall(call: ToolCall, reason: string | undefined): ToolResult {\n\treturn {\n\t\tsuccess: false,\n\t\tid: call.id,\n\t\tname: call.name,\n\t\terror: reason !== undefined ? `denied: ${reason}` : 'denied by authority',\n\t}\n}\n\n/**\n * Consumes a reported usage against a budget over what was already charged, so a turn's total\n * draw is never less than the report and nothing is charged twice.\n *\n * @remarks\n * The full `prompt` count is consumed because no earlier charge covers it. Each of `completion`\n * and `total` is consumed less `charged`, floored at 0. An estimate above the report is not\n * refunded. The usage must already be sanitized: a\n * non-finite field yields a non-finite charge, which the installed `Budget` refuses by throwing\n * a `range` `ContractError`. Without a budget the call consumes nothing.\n *\n * @param budget - The budget to consume against, or `undefined` for an unmetered run\n * @param usage - The sanitized usage the provider reported\n * @param charged - The completion tokens already consumed this turn\n *\n * @example\n * ```ts\n * const budget = createBudget<TokenUsage>({ max: 1000, consumer: (usage) => usage.total })\n * chargeUsage(budget, { prompt: 20, completion: 30, total: 50 }, 10)\n * budget.consumed // 40\n * ```\n */\nexport function chargeUsage(\n\tbudget: BudgetInterface<TokenUsage> | undefined,\n\tusage: TokenUsage,\n\tcharged: number,\n): void {\n\tbudget?.consume({\n\t\tprompt: usage.prompt,\n\t\tcompletion: Math.max(0, usage.completion - charged),\n\t\ttotal: Math.max(0, usage.total - charged),\n\t})\n}\n\n/**\n * Returns a tool-iteration cap after checking it is a nonnegative safe integer, or throws a coded\n * error.\n *\n * @remarks\n * The check is {@link import('../validators.js').isNonNegativeSafeInteger}, so `0` and `-0`\n * pass while `NaN`, a fraction, a negative, and either infinity are refused. The error's `context`\n * carries the refused value as `limit`.\n *\n * @param limit - The tool-iteration cap to check\n * @returns The cap unchanged\n * @throws {AgentError} Thrown when `limit` is not a nonnegative safe integer (code `'LIMIT'`)\n *\n * @example\n * ```ts\n * requireLimit(3) // 3\n * requireLimit(1.5) // throws AgentError ('LIMIT')\n * ```\n */\nexport function requireLimit(limit: number): number {\n\tif (!isNonNegativeSafeInteger(limit)) {\n\t\tthrow new AgentError('LIMIT', 'a limit must be a nonnegative safe integer', {\n\t\t\tcontext: { limit },\n\t\t})\n\t}\n\treturn limit\n}\n\n/**\n * Returns a run's budget or allowance after checking it implements `BudgetInterface`, or throws a\n * coded error before the run starts it.\n *\n * @remarks\n * The check is `isBudget` from `@orkestrel/budget`, a total guard. `undefined` passes, because an\n * absent bound is no bound. The error's `context` carries the option path, the limit\n * `'BudgetInterface'`, and a preview of the refused value.\n *\n * @param value - The effective `budget` or `allowance`, or `undefined`\n * @param key - The option the value came from, named in the error's path\n * @returns The value unchanged\n * @throws {ContractError} Thrown when `value` is defined and does not implement `BudgetInterface` (code `'placement'`)\n *\n * @example\n * ```ts\n * requireBudget(createTokenBudget({ max: 10 }), 'budget') // the budget\n * requireBudget({ consume() {} }, 'allowance') // throws ContractError ('placement')\n * ```\n */\nexport function requireBudget(\n\tvalue: BudgetInterface<TokenUsage> | undefined,\n\tkey: 'budget' | 'allowance',\n): BudgetInterface<TokenUsage> | undefined {\n\tif (value === undefined || isBudget(value)) return value\n\tthrow new ContractError(`Agent: ${key} must implement BudgetInterface`, {\n\t\tcode: 'placement',\n\t\tcontext: { path: ['options', key], limit: 'BudgetInterface', received: preview(value) },\n\t})\n}\n\n/**\n * Renders a tool's output as the string content of its tool message.\n *\n * @remarks\n * A string passes through unchanged and `undefined` renders as `''`. Any other value renders as\n * its `JSON.stringify` text, byte for byte, when JSON can carry it. A value JSON cannot carry (a\n * `BigInt`, a cycle, a symbol, a throwing `toJSON`) renders as `String(value)`, and as `''` when\n * that conversion throws too, so a tool's output never rejects the run that dispatched it.\n *\n * @param value - The tool's output (`ToolSuccess.value`, which may be `undefined`)\n * @returns The message content\n *\n * @example\n * ```ts\n * renderToolValue('sunny') // 'sunny'\n * renderToolValue({ count: 2 }) // '{\"count\":2}'\n * renderToolValue(undefined) // ''\n * renderToolValue(10n) // '10'\n * ```\n */\nexport function renderToolValue(value: unknown): string {\n\tif (typeof value === 'string') return value\n\tif (value === undefined) return ''\n\tconst rendered = renderJSON(value)\n\tif (rendered !== undefined) return rendered\n\tconst fallback = attempt(() => String(value))\n\treturn fallback.success ? fallback.value : ''\n}\n\n/**\n * Returns a registered value or throws when its name is absent.\n * @param pool - The named values\n * @param category - The registry category named in an error\n * @param name - The requested key\n * @returns The registered value\n * @throws {AgentError} Thrown when the name is absent, with code REGISTRY and a `context` naming the `category` and the `name`.\n * @example\n * ```ts\n * requireEntry(new Map([['main', provider]]), 'provider', 'main') // provider\n * ```\n */\nexport function requireEntry<T>(pool: ReadonlyMap<string, T>, category: string, name: string): T {\n\tconst value = pool.get(name)\n\tif (value === undefined) {\n\t\tthrow new AgentError('REGISTRY', `unknown ${category}: ${name}`, {\n\t\t\tcontext: { category, name },\n\t\t})\n\t}\n\treturn value\n}\n\n/**\n * Extracts the present concurrency, retry, and deadline options for an agent job queue.\n * @param options - The queue options to project\n * @returns The present queue options, omitting absent keys\n * @example\n * ```ts\n * extractQueueOptions({ concurrency: 2 }) // { concurrency: 2 }\n * ```\n */\nexport function extractQueueOptions(\n\toptions: Pick<QueueOptions<AgentJobInput, AgentResult>, 'concurrency' | 'retries' | 'timeout'>,\n): Pick<QueueOptions<AgentJobInput, AgentResult>, 'concurrency' | 'retries' | 'timeout'> {\n\tconst { concurrency, retries, timeout } = options\n\treturn {\n\t\t...(concurrency === undefined ? {} : { concurrency }),\n\t\t...(retries === undefined ? {} : { retries }),\n\t\t...(timeout === undefined ? {} : { timeout }),\n\t}\n}\n","import type {\n\tAgentChunk,\n\tAgentEventMap,\n\tAgentInterface,\n\tAgentOptions,\n\tAgentResult,\n\tAgentRunOptions,\n\tAgentStatus,\n\tAgentStreamInterface,\n\tAgentTurn,\n\tAuthorityInterface,\n\tAgentRunResult,\n} from './types.js'\nimport type { ProviderInterface, ProviderRequest, ProviderResult } from '../providers/index.js'\nimport type { AgentContextInterface, Selection } from '../contexts/index.js'\nimport type { Section } from '../conversations/index.js'\nimport type { Message, ThinkingReplay } from '../types.js'\nimport type { AbortInterface } from '@orkestrel/abort'\nimport type { BudgetInterface, MeterInterface, TokenUsage } from '@orkestrel/budget'\nimport type { Result } from '@orkestrel/contract'\nimport type { EmitterInterface } from '@orkestrel/emitter'\nimport type { ToolCall, ToolManagerInterface, ToolResult } from '@orkestrel/tool'\nimport type { SchedulerInterface } from '@orkestrel/workflow'\nimport type { TimeoutInterface } from '@orkestrel/timeout'\nimport { createAbort } from '@orkestrel/abort'\nimport { createTokenMeter } from '@orkestrel/budget'\nimport { attempt } from '@orkestrel/contract'\nimport { createTimeout } from '@orkestrel/timeout'\nimport { Emitter } from '@orkestrel/emitter'\nimport { errorToMessage } from '@orkestrel/workflow'\nimport { AgentContext } from '../contexts/index.js'\nimport { DEFAULT_AGENT_LIMIT } from './constants.js'\nimport { AgentError } from './errors.js'\nimport { Channel } from './Channel.js'\nimport {\n\tassembleResult,\n\tchargeUsage,\n\tdenyCall,\n\testimateTokens,\n\tinferStop,\n\trenderToolValue,\n\trequireBudget,\n\trequireLimit,\n} from './helpers.js'\nimport { filterAllowList, sanitizeUsage, stripThinking, sumUsage } from '../helpers.js'\nimport { isProviderAbortError } from '../providers/index.js'\n\n/**\n * Composes a {@link ProviderInterface}, an {@link AgentContext}, and a\n * {@link ToolManagerInterface} into a bounded context → provider → tools → repeat turn, exposed\n * as both a one-shot `generate` and a live `stream` that share one private run — bounded by the\n * run `signal`, the `timeout`, and the `budget` folded through `AbortSignal.any`, paced by\n * `scheduler`, with tool iteration capped at `limit`.\n *\n * @remarks\n * - **One loop, two faces.** A single private async generator (`#execute`) drives the\n * whole run. `stream` drives it eagerly into a private {@link Channel} and settles `result`\n * from the outcome the generator returns, through one `.then` — so `result` settles\n * whether or not the live `events` are drained; `generate` awaits that same\n * settled `result` — so the two can never diverge.\n * - **The turn.** `#execute` builds the provider input once, then runs up to `limit` turns,\n * each appending one readonly {@link AgentTurn} record: drive `provider.stream(...)`,\n * yielding each content delta as a `token` chunk and charging its estimate to the\n * `allowance` when one is set; reconcile the turn's usage against the `budget`, before a\n * genuine provider error rejects the run too, and yield a `usage` chunk; if the model\n * requested tools, append the assistant turn, pass them to the tool manager's `execute`\n * method, yield a `tool` chunk per call, append each tool result message, and continue;\n * otherwise append the final assistant message and stop. The run's content,\n * thinking, usage, and stop derive from the turn records. Each assistant message stores its\n * call's non-empty thinking.\n * Provider calls and prompt estimates apply the provider's `replay` policy to the working\n * array; an absent policy means `'none'`.\n * - **Bounded.** Each run arms one cancel through `createAbort({ signal: AbortSignal.any([\n * …]) })` folding the external `signal`, the `timeout` deadline, and the `budget` and\n * `allowance` signals; `abort()` fires it. Any trip stops the loop and commits a partial result\n * (the `result` promise resolves, never rejects, on a cancel) — only a genuine\n * provider / tool error rejects.\n * - **Paced + capped.** The loop calls the `scheduler` object's `yield` method between turns when given; tool\n * iteration is capped at `limit`.\n * - **Two observation surfaces.** The pull {@link AgentChunk} stream carries per-token\n * deltas (+ usage/tool chunks); the push {@link emitter} ({@link AgentEventMap}) carries\n * lifecycle + usage/tool/deny moments for fire-and-forget observers. Every event is\n * emitted directly, after the relevant state transition / settle; the emitter isolates a\n * listener throw and routes it to its `error` handler (the `error` option), so a buggy\n * observer can never escape into / reorder / corrupt the settle-once loop — observation is\n * purely a side-channel.\n *\n * @example\n * ```ts\n * const agent = new Agent(provider, { system: 'You are concise.' })\n * agent.context.messages.add({ role: 'user', content: 'Say hi.' })\n * const result = await agent.generate()\n * ```\n */\nexport class Agent implements AgentInterface {\n\treadonly #id: string\n\treadonly #provider: ProviderInterface\n\treadonly #replay: ThinkingReplay\n\treadonly #context: AgentContextInterface\n\treadonly #limit: number\n\treadonly #timeoutMs: number | undefined\n\treadonly #budget: BudgetInterface<TokenUsage> | undefined\n\t// The meter layer's allowance: the budget each content delta's estimate is charged against while\n\t// a call streams. `undefined` ⇒ no meter layer; the estimate is still measured for `usage`.\n\treadonly #allowance: BudgetInterface<TokenUsage> | undefined\n\treadonly #scheduler: SchedulerInterface | undefined\n\treadonly #signal: AbortSignal | undefined\n\treadonly #authority: AuthorityInterface | undefined\n\t// The context budget that admits each provider request — its `consumer` is a token estimator\n\t// over the complete `ProviderRequest`, its `max` the context window. `#admit` re-measures the\n\t// exact request (replay-filtered messages, advertised tools, per-call options) against it before\n\t// every dispatch; `undefined` ⇒ disabled, and the loop never calls `#admit`. Reset (`clear()`)\n\t// at run entry so no stale `consumed` carries across runs / a conversation switch. Not the hard\n\t// cost `budget` ceiling — when the request reaches its `max` this compacts + continues\n\t// (non-fatal on a summarizer throw, futile-guarded) and never aborts; only `strict` refuses.\n\treadonly #window: BudgetInterface<ProviderRequest> | undefined\n\t// When true, a summarizer failure during automatic compaction rethrows (after the `fault`\n\t// event) instead of skipping compaction and continuing over-window, and a request still over\n\t// the window after the permitted fold is refused with a WINDOW error before dispatch.\n\treadonly #strict: boolean\n\t// The push observation surface — owned, never inherited. The emitter isolates a\n\t// listener throw (routing it to the `error` handler), so it can never escape into the loop. No\n\t// `destroy()`: the Agent holds no other teardownable resources, and an `Emitter` owns\n\t// only listener sets (no timers / handles), so it is reclaimed with the agent — there\n\t// is no leak to clear, and adding lifecycle the entity does not otherwise need is avoided.\n\treadonly #emitter: Emitter<AgentEventMap>\n\t// The label the last run settled on. `status` derives the live answer from `#runs`, so an\n\t// overlapping run can never report `done` while another is still in flight.\n\t#settled: AgentStatus = 'idle'\n\t// Every in-flight run's abort handle, mapped to the distinct budget and allowance instances that\n\t// run holds — a run adds its entry on `stream()` and its settle removes it, so `abort()` fires\n\t// every live run, not only the most recent, and the concurrency guard reads which instances are\n\t// held. Per-run, never a single shared slot a later `stream()` could clobber: `generate`/`stream`\n\t// are reusable and may overlap, and each run must cancel independently (its own `stream.abort()`\n\t// fires its own handle; `agent.abort()` fires them all).\n\treadonly #runs = new Map<AbortInterface, ReadonlyArray<BudgetInterface<TokenUsage>>>()\n\n\tconstructor(provider: ProviderInterface, options?: AgentOptions) {\n\t\tthis.#limit = requireLimit(options?.limit ?? DEFAULT_AGENT_LIMIT)\n\t\tthis.#id = crypto.randomUUID()\n\t\tthis.#provider = provider\n\t\tthis.#replay = provider.replay ?? 'none'\n\t\tthis.#context = new AgentContext({\n\t\t\t...(options?.system === undefined ? {} : { system: options.system }),\n\t\t\t...(options?.tools === undefined ? {} : { tools: options.tools }),\n\t\t\t...(options?.instructions === undefined ? {} : { instructions: options.instructions }),\n\t\t\t...(options?.workspaces === undefined ? {} : { workspaces: options.workspaces }),\n\t\t\t...(options?.scope === undefined ? {} : { scope: options.scope }),\n\t\t\t...(options?.conversations === undefined ? {} : { conversations: options.conversations }),\n\t\t\t...(options?.select === undefined ? {} : { select: options.select }),\n\t\t})\n\t\tthis.#timeoutMs = options?.timeout\n\t\tthis.#budget = options?.budget\n\t\tthis.#allowance = options?.allowance\n\t\tthis.#scheduler = options?.scheduler\n\t\tthis.#signal = options?.signal\n\t\tthis.#authority = options?.authority\n\t\tthis.#window = options?.window\n\t\tthis.#strict = options?.strict ?? false\n\t\tthis.#emitter = new Emitter<AgentEventMap>(options)\n\t}\n\n\tget id(): string {\n\t\treturn this.#id\n\t}\n\n\tget emitter(): EmitterInterface<AgentEventMap> {\n\t\treturn this.#emitter\n\t}\n\n\tget status(): AgentStatus {\n\t\t// Derived, never stored: a live run outranks any settled label, so overlapping runs can\n\t\t// never report `done` while one is still in flight, and a settled `error` is not erased\n\t\t// by a later run's `done` until that later run itself settles.\n\t\treturn this.#runs.size > 0 ? 'running' : this.#settled\n\t}\n\n\tget context(): AgentContextInterface {\n\t\treturn this.#context\n\t}\n\n\tgenerate(options?: AgentRunOptions): Promise<AgentResult> {\n\t\t// Zero loop logic of its own — start the stream (whose eager drive settles `result`\n\t\t// independently of any consumer) and await that same settled result, so `generate`\n\t\t// and `stream` can never diverge. No manual drain needed: the drive runs regardless.\n\t\treturn this.stream(options).result\n\t}\n\n\tstream(options?: AgentRunOptions): AgentStreamInterface {\n\t\t// Resolve effective per-run bounds — a per-run override wins, else the construction\n\t\t// default. `limit`, `budget`, and `allowance` also thread into `#execute` (the loop bound,\n\t\t// the reconcile, and the mid-stream meter); each budget is the same instance folded into\n\t\t// `#combineSignals`, so its trip both aborts the run and is the budget the run charges.\n\t\tconst limit = options?.limit === undefined ? this.#limit : requireLimit(options.limit)\n\t\t// Both bounds are checked before the concurrency guard and before either `start()`, so a\n\t\t// refused bound leaves the other untouched and nothing emitted.\n\t\tconst budget = requireBudget(options?.budget ?? this.#budget, 'budget')\n\t\tconst allowance = requireBudget(options?.allowance ?? this.#allowance, 'allowance')\n\t\t// The distinct accounting instances this run holds, cost budget first: an allowance that is\n\t\t// the budget itself is held, started, and folded once.\n\t\tconst held = [budget, allowance].filter(\n\t\t\t(one, index, all): one is BudgetInterface<TokenUsage> =>\n\t\t\t\tone !== undefined && all.indexOf(one) === index,\n\t\t)\n\t\t// Concurrency guard: a `window` is one context budget every run clears and measures, and a\n\t\t// budget instance carries one signal that `start()` replaces — a second live run on either\n\t\t// would race the first run's accounting or orphan its bound. Thrown synchronously, before\n\t\t// any state mutation or emit, so a sequential/awaited caller is never affected and runs\n\t\t// holding distinct budget instances with no `window` still overlap.\n\t\tif (\n\t\t\tthis.#runs.size > 0 &&\n\t\t\t(this.#window !== undefined ||\n\t\t\t\t[...this.#runs.values()].some((live) => live.some((one) => held.includes(one))))\n\t\t) {\n\t\t\tthrow new AgentError(\n\t\t\t\t'CONCURRENCY',\n\t\t\t\t'a live run on this agent holds the window or this budget or allowance instance; use separate agents or distinct instances per run',\n\t\t\t\t{ context: { agent: this.#id } },\n\t\t\t)\n\t\t}\n\t\t// The deadline is created unarmed: its signal keeps its identity when `start()` arms it, so\n\t\t// it can be composed first and armed only after nothing left can throw.\n\t\tconst timeoutMs = options?.timeout ?? this.#timeoutMs\n\t\tconst timeout = timeoutMs === undefined ? undefined : createTimeout({ ms: timeoutMs })\n\t\t// `start()` replaces each held budget's signal, so it precedes the composition that reads it.\n\t\tfor (const one of held) one.start()\n\t\t// Fold every present bound (external signal + a per-run signal + deadline + budget +\n\t\t// allowance) into one cancel the run races against; this run's own `abort()` fires this handle.\n\t\tconst signal = this.#combineSignals(timeout, budget, allowance, options?.signal)\n\t\tconst abort = createAbort(signal === undefined ? {} : { signal })\n\t\ttimeout?.start()\n\t\tthis.#runs.set(abort, held)\n\t\t// Observe the run begin — after the run joins `#runs` (which is what `status` derives\n\t\t// `running` from), so a swallowed listener throw can't perturb the state the drive is\n\t\t// about to change.\n\t\tthis.#emitter.emit('start', this.id)\n\t\tconst channel = new Channel<AgentChunk>()\n\t\tconst settled = Promise.withResolvers<AgentResult>()\n\t\t// Kick off the eager drive synchronously (not lazily on first `events` pull): it drives\n\t\t// `#execute` into the channel, and the run settles from its outcome regardless of whether\n\t\t// anyone drains `events`. The per-run `think` / `schema` preferences ride through to\n\t\t// `provider.stream`; `limit` / `budget` / `allowance` ride through as the effective run bounds.\n\t\tvoid this.#drive(\n\t\t\tabort,\n\t\t\tchannel,\n\t\t\toptions?.think,\n\t\t\toptions?.schema,\n\t\t\tlimit,\n\t\t\tbudget,\n\t\t\tallowance,\n\t\t).then(\n\t\t\t(outcome) => this.#finish(abort, timeout, channel, settled, limit, outcome),\n\t\t\t(error: unknown) => this.#fail(abort, timeout, channel, settled, error),\n\t\t)\n\t\t// An abandoned handle (neither `events` drained nor `result` awaited) must not surface an\n\t\t// unhandledRejection on a genuine error — guard the public result, where the rejection lives\n\t\t// (`#fail` rejects `settled` without re-throwing, so the drive's settle itself resolves).\n\t\t// A caller who awaits `result` still gets the rejection: `.catch` returns a derived promise, it\n\t\t// does not consume the original's rejection.\n\t\tsettled.promise.catch(() => {})\n\t\treturn {\n\t\t\tevents: this.#drainEvents(channel, abort),\n\t\t\tresult: settled.promise,\n\t\t\t// Fire this run's own handle (the closed-over `abort`), never a shared field a\n\t\t\t// later `stream()` could have replaced — so a handle's `abort()` always cancels\n\t\t\t// the run it belongs to, even when runs overlap.\n\t\t\tabort: abort.abort.bind(abort),\n\t\t}\n\t}\n\n\tabort(reason?: unknown): void {\n\t\t// Cancel every in-flight run — iterate a snapshot so a settle-driven `#runs.delete`\n\t\t// (a cancelled run unwinding) can't disturb the walk. Aborting is idempotent, so an\n\t\t// already-finished or already-cancelled handle is a harmless no-op.\n\t\tfor (const abort of [...this.#runs.keys()]) abort.abort(reason)\n\t}\n\n\t// Settles a finished or cancelled run: the deadline clears, the run leaves `#runs` (releasing its\n\t// budget instances), the channel closes, and the assembled result resolves before it is observed.\n\t// A cancel still resolves a partial, so a cancelled run emits `abort` (the cancel reason) then\n\t// `finish`; limit exhaustion is not a cancel and emits `exhaust` (the turn count) instead. Every\n\t// emit follows the resolve, so an isolated listener throw can't reorder the settle.\n\t#finish(\n\t\tabort: AbortInterface,\n\t\ttimeout: TimeoutInterface | undefined,\n\t\tchannel: Channel<AgentChunk>,\n\t\tsettled: PromiseWithResolvers<AgentResult>,\n\t\tlimit: number,\n\t\toutcome: AgentRunResult,\n\t): void {\n\t\ttimeout?.clear()\n\t\tthis.#runs.delete(abort)\n\t\tthis.#settled = 'done'\n\t\tchannel.close()\n\t\tconst result = assembleResult(outcome)\n\t\tsettled.resolve(result)\n\t\tif (outcome.exhausted) this.#emitter.emit('exhaust', limit)\n\t\telse if (outcome.partial) this.#emitter.emit('abort', abort.signal.reason)\n\t\tthis.#emitter.emit('finish', result)\n\t}\n\n\t// Settles a run a genuine (non-cancel) provider / tool error stopped: the channel fails, the\n\t// result rejects, and the failure is observed after the reject.\n\t#fail(\n\t\tabort: AbortInterface,\n\t\ttimeout: TimeoutInterface | undefined,\n\t\tchannel: Channel<AgentChunk>,\n\t\tsettled: PromiseWithResolvers<AgentResult>,\n\t\terror: unknown,\n\t): void {\n\t\ttimeout?.clear()\n\t\tthis.#runs.delete(abort)\n\t\tthis.#settled = 'error'\n\t\tchannel.fail(error)\n\t\tsettled.reject(error)\n\t\tthis.#emitter.emit('error', error)\n\t}\n\n\t// Drives `#execute` by hand, pushing each chunk into the channel, and returns the generator's\n\t// return value; a genuine provider / tool error rejects. `for await` would discard the return.\n\tasync #drive(\n\t\tabort: AbortInterface,\n\t\tchannel: Channel<AgentChunk>,\n\t\tthink: boolean | undefined,\n\t\tschema: Readonly<Record<string, unknown>> | undefined,\n\t\tlimit: number,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t\tallowance: BudgetInterface<TokenUsage> | undefined,\n\t): Promise<AgentRunResult> {\n\t\tconst run = this.#execute(abort, think, schema, limit, budget, allowance)\n\t\tfor (;;) {\n\t\t\tconst next = await run.next()\n\t\t\tif (next.done === true) return next.value\n\t\t\tchannel.push(next.value)\n\t\t}\n\t}\n\n\t// The live event stream: drain the channel the drive writes into, yielding each `AgentChunk` as it\n\t// is pushed (and throwing if the drive called `fail` on the channel). Its `return()` — fired when\n\t// a consumer exits with `break` early — fires the turn abort, so the run stops promptly: the drive\n\t// then completes the loop with `partial: true`, calls `clear` on the deadline, and settles\n\t// `result` to a non-misleading `{ partial: true }`, leaving `status` no longer `running`.\n\tasync *#drainEvents(\n\t\tchannel: Channel<AgentChunk>,\n\t\tabort: AbortInterface,\n\t): AsyncGenerator<AgentChunk, void> {\n\t\ttry {\n\t\t\tyield* channel.drain()\n\t\t} finally {\n\t\t\t// Early break (consumer stopped pulling): cancel the run so the drive unwinds and\n\t\t\t// settles partial. A natural end reaches here too with the signal already done, so\n\t\t\t// this abort is a harmless no-op then.\n\t\t\tabort.abort()\n\t\t}\n\t}\n\n\t// The core loop, shared by generate + stream. Builds the provider input once, then runs turns up\n\t// to `limit`, appending each turn's readonly record, and continues only while the latest turn\n\t// requested tools. A cancel (the bound abort) ends a turn with a `cancel` record — it never\n\t// throws; only a genuine provider / tool error propagates. Every record is local to one call, so\n\t// concurrent runs share nothing, and the settled `AgentRunResult` derives from the records.\n\t// Each turn runs in this generator, which delegates only the provider stream to `#provide`: a\n\t// delta crosses these two layers before `#drive` pushes it, and no per-turn generator settles\n\t// between a turn's chunks. Every further layer would let a consumer's early `return()` cancel the\n\t// provider a step sooner.\n\tasync *#execute(\n\t\tabort: AbortInterface,\n\t\tthink: boolean | undefined,\n\t\tschema: Readonly<Record<string, unknown>> | undefined,\n\t\tlimit: number,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t\tallowance: BudgetInterface<TokenUsage> | undefined,\n\t): AsyncGenerator<AgentChunk, AgentRunResult> {\n\t\t// Compaction can fold the request into a section, so every select site receives the object\n\t\t// captured at run entry.\n\t\tconst last = this.#context.conversations.active?.view().at(-1)\n\t\tconst request = last?.role === 'user' ? last : undefined\n\t\t// `#select` returns `undefined` when no handler is set, so the default path awaits nothing\n\t\t// before the first provider request.\n\t\tconst selecting = this.#select(request, abort, budget)\n\t\tconst entry =\n\t\t\tselecting === undefined\n\t\t\t\t? { messages: this.#context.build(), usage: undefined }\n\t\t\t\t: await selecting\n\t\tconst tools = this.#context.tools\n\t\t// The per-call options are fixed for the run, so every request carries this one snapshot;\n\t\t// absent when neither preference is set.\n\t\tconst options: ProviderRequest['options'] =\n\t\t\tthink === undefined && schema === undefined\n\t\t\t\t? undefined\n\t\t\t\t: {\n\t\t\t\t\t\t...(think === undefined ? {} : { think }),\n\t\t\t\t\t\t...(schema === undefined ? {} : { schema }),\n\t\t\t\t\t}\n\t\t// Reset `#window` at run entry so no stale `consumed` carries across runs / a conversation\n\t\t// switch. A `limit: 0` run never measures or folds, and adds no `await` when `window` is unset.\n\t\tthis.#window?.clear()\n\t\t// A cancel at the entry select site of a `limit: 0` run never reaches a turn's abort checks.\n\t\tconst cancelled = abort.signal.aborted\n\t\t// One readonly record per turn; the turn index is the list length.\n\t\tconst turns: AgentTurn[] = []\n\t\t// One turn per step: observe it, pace the boundary, admit the request, stream the provider,\n\t\t// reconcile the usage, then dispatch the requested tools or record the final answer. A cancel\n\t\t// appends a `cancel` record, which ends the loop; a genuine error throws. The section before\n\t\t// the provider call adds no `await` on the default path, so the provider's `stream()` is\n\t\t// entered in `agent.stream()`'s own call.\n\t\twhile (turns.length < limit && (turns.at(-1)?.outcome ?? 'tools') === 'tools') {\n\t\t\tconst index = turns.length\n\t\t\tconst base = turns.at(-1)?.messages ?? entry.messages\n\t\t\tconst futile = turns.at(-1)?.futile ?? false\n\t\t\t// The record of a turn a cancel stopped before its provider call.\n\t\t\tconst stopped: AgentTurn = {\n\t\t\t\tcontent: '',\n\t\t\t\tthinking: undefined,\n\t\t\t\tusage: undefined,\n\t\t\t\tspent: undefined,\n\t\t\t\tmessages: base,\n\t\t\t\toutcome: 'cancel',\n\t\t\t\tpartial: true,\n\t\t\t\tfutile,\n\t\t\t\testimate: undefined,\n\t\t\t\tinterrupted: false,\n\t\t\t\ttruncated: false,\n\t\t\t}\n\t\t\t// Observe each turn begin (the turn index). The emitter isolates a listener throw, so it\n\t\t\t// can't perturb the turn that immediately follows.\n\t\t\tthis.#emitter.emit('turn', index)\n\t\t\t// Pace between expensive turns — never before the first. A scheduler honours the signal by\n\t\t\t// rejecting a pending yield on abort, so a cancel landing at the turn boundary surfaces here\n\t\t\t// as a throw; it stops the turn like any cancel, while a genuine scheduler fault propagates.\n\t\t\tif (index > 0) {\n\t\t\t\ttry {\n\t\t\t\t\tawait this.#scheduler?.yield({ signal: abort.signal })\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (!abort.signal.aborted) throw error\n\t\t\t\t}\n\t\t\t}\n\t\t\tif (abort.signal.aborted) {\n\t\t\t\tturns.push(stopped)\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// Snapshot the allow-list before listeners can change the active scope this turn.\n\t\t\tconst names = this.#context.scope?.tools?.slice()\n\t\t\tconst advertised = filterAllowList(\n\t\t\t\tnames,\n\t\t\t\ttools.definitions(),\n\t\t\t\t(definition) => definition.name,\n\t\t\t)\n\t\t\tconst definitions = advertised.length > 0 ? advertised : undefined\n\t\t\t// Admit the request: compose it once from the replay-filtered messages and this turn's tool\n\t\t\t// and option snapshot, measure it against `#window`, and dispatch exactly the request the\n\t\t\t// window last measured (the rebuilt one after a fold). With no `window` it is composed and\n\t\t\t// dispatched with no extra `await`.\n\t\t\tconst composed = this.#compose(base, definitions, options)\n\t\t\tconst admitted =\n\t\t\t\tthis.#window === undefined\n\t\t\t\t\t? { dispatch: composed, messages: base, spent: undefined, futile }\n\t\t\t\t\t: await this.#admit(\n\t\t\t\t\t\t\tthis.#window,\n\t\t\t\t\t\t\tcomposed,\n\t\t\t\t\t\t\tbase,\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t\tindex > 0,\n\t\t\t\t\t\t\tfutile,\n\t\t\t\t\t\t\tabort,\n\t\t\t\t\t\t\tbudget,\n\t\t\t\t\t\t)\n\t\t\tif (admitted.dispatch === undefined) {\n\t\t\t\tturns.push({\n\t\t\t\t\t...stopped,\n\t\t\t\t\tmessages: admitted.messages,\n\t\t\t\t\tspent: admitted.spent,\n\t\t\t\t\tfutile: admitted.futile,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// The turn's streamed content, one entry per content delta; the meter charges only when an\n\t\t\t// allowance exists.\n\t\t\tconst streamed: string[] = []\n\t\t\tconst meter =\n\t\t\t\tallowance === undefined\n\t\t\t\t\t? undefined\n\t\t\t\t\t: createTokenMeter({ budget: allowance, estimator: estimateTokens })\n\t\t\tconst provided = yield* this.#provide(admitted.dispatch, abort.signal, streamed, meter)\n\t\t\tconst settled = this.#reconcile(provided, abort, streamed, admitted, meter, budget, allowance)\n\t\t\tif (!provided.success) {\n\t\t\t\tturns.push({ ...settled, outcome: 'cancel', partial: true })\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\tconst result = provided.value\n\t\t\tconst recorded = settled.thinking === undefined ? {} : { thinking: settled.thinking }\n\t\t\tif (settled.usage !== undefined) {\n\t\t\t\t// Observe this turn's usage — the result already exists; emit beside the yield.\n\t\t\t\tthis.#emitter.emit('usage', settled.usage, settled.estimate)\n\t\t\t\tyield { category: 'usage', usage: settled.usage, estimate: settled.estimate }\n\t\t\t}\n\t\t\tif (definitions === undefined) {\n\t\t\t\tfor (const call of result.tools ?? []) {\n\t\t\t\t\tthis.#emitter.emit('deny', call, 'no tool is advertised in the active scope')\n\t\t\t\t}\n\t\t\t} else if (result.tools !== undefined && result.tools.length > 0) {\n\t\t\t\tconst admittedCalls = filterAllowList(names, result.tools, (call) => call.name)\n\t\t\t\tconst authorization = this.#authorize(result.tools, admittedCalls)\n\t\t\t\tif (abort.signal.aborted) {\n\t\t\t\t\tturns.push({ ...settled, outcome: 'cancel', partial: true })\n\t\t\t\t\tcontinue\n\t\t\t\t}\n\t\t\t\tconst assistant = this.#context.messages.add({\n\t\t\t\t\trole: 'assistant',\n\t\t\t\t\tcontent: result.content,\n\t\t\t\t\tcalls: result.tools,\n\t\t\t\t\t...recorded,\n\t\t\t\t})\n\t\t\t\tconst results = await this.#dispatch(tools, result.tools, abort.signal, authorization)\n\t\t\t\t// Each dispatched call's tool message, appended per step of a loop that yields.\n\t\t\t\tconst replies: Message[] = []\n\t\t\t\tfor (const [position, call] of result.tools.entries()) {\n\t\t\t\t\tconst outcome = results[position]\n\t\t\t\t\tif (outcome === undefined) continue\n\t\t\t\t\t// Observe the dispatched tool + its result — beside the `tool` yield (the result\n\t\t\t\t\t// already exists). Carries the same pair the chunk carries.\n\t\t\t\t\tthis.#emitter.emit('tool', call, outcome)\n\t\t\t\t\tyield { category: 'tool', call, result: outcome }\n\t\t\t\t\t// `call` comes from the paired call rather than the result's `id`, so tool message\n\t\t\t\t\t// `position` names `calls[position]` even when a supplied tool manager returns another id.\n\t\t\t\t\treplies.push(\n\t\t\t\t\t\tthis.#context.messages.add({\n\t\t\t\t\t\t\trole: 'tool',\n\t\t\t\t\t\t\tcontent: outcome.success ? renderToolValue(outcome.value) : outcome.error,\n\t\t\t\t\t\t\tcall: call.id,\n\t\t\t\t\t\t}),\n\t\t\t\t\t)\n\t\t\t\t}\n\t\t\t\t// The next turn's admission measures and folds the grown prompt, so a final answer never\n\t\t\t\t// pays for a fold. A tools turn's truncation does not end the run, so it is not recorded.\n\t\t\t\tturns.push({\n\t\t\t\t\t...settled,\n\t\t\t\t\tmessages: [...admitted.messages, assistant, ...replies],\n\t\t\t\t\toutcome: 'tools',\n\t\t\t\t\tpartial: true,\n\t\t\t\t})\n\t\t\t\tcontinue\n\t\t\t}\n\t\t\t// No tools: this turn's content is the final answer — record it and finish.\n\t\t\tthis.#context.messages.add({ role: 'assistant', content: result.content, ...recorded })\n\t\t\tturns.push({\n\t\t\t\t...settled,\n\t\t\t\tcontent: result.content,\n\t\t\t\toutcome: 'answer',\n\t\t\t\tpartial: abort.signal.aborted,\n\t\t\t\ttruncated: result.truncated === true,\n\t\t\t})\n\t\t}\n\t\tconst final = turns.at(-1)\n\t\tconst thinkings = turns.flatMap((turn) => (turn.thinking === undefined ? [] : [turn.thinking]))\n\t\treturn {\n\t\t\tcontent:\n\t\t\t\tfinal?.outcome === 'answer' ? final.content : turns.map((turn) => turn.content).join(''),\n\t\t\tthinking: thinkings.length === 0 ? undefined : thinkings.join('\\n\\n'),\n\t\t\t// Every turn's usage, then the entry selection's, then each rebuild's, in turn order.\n\t\t\tusage: [\n\t\t\t\t...turns.map((turn) => turn.usage),\n\t\t\t\tentry.usage,\n\t\t\t\t...turns.map((turn) => turn.spent),\n\t\t\t].reduce<TokenUsage | undefined>(\n\t\t\t\t(total, one) => (one === undefined ? total : sumUsage(total, one)),\n\t\t\t\tundefined,\n\t\t\t),\n\t\t\tpartial: final?.partial ?? cancelled,\n\t\t\t// Every allowed turn requested tools; a cancel during the last one is an `abort`, never an\n\t\t\t// `exhaust`, so the signal is read here.\n\t\t\texhausted: final?.outcome === 'tools' && !abort.signal.aborted,\n\t\t\tstop: inferStop(abort.signal.reason, allowance, budget, this.#provider.id, final),\n\t\t}\n\t}\n\n\t// Settles one provider call into its turn's record fields, charges the cost budget at the one\n\t// charge site, then rethrows a genuine failure. A cancelled call's fields still describe what it\n\t// streamed; the caller adds the ending.\n\t#reconcile(\n\t\tprovided: Result<ProviderResult>,\n\t\tabort: AbortInterface,\n\t\tstreamed: readonly string[],\n\t\tadmitted: Pick<AgentTurn, 'messages' | 'spent' | 'futile'>,\n\t\tmeter: MeterInterface | undefined,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t\tallowance: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\t// Read before any reconcile: an abort seen here landed while the call ran, and a charge that\n\t\t// trips a bound below cannot turn a genuine failure into a partial.\n\t\tconst interrupted = abort.signal.aborted\n\t\t// The abort partial of an interrupted call is the only carrier of its reasoning and usage; the\n\t\t// streamed deltas already hold its content. A genuine failure contributes no usage.\n\t\tconst partial =\n\t\t\t!provided.success && interrupted && isProviderAbortError(provided.error)\n\t\t\t\t? provided.error.partial\n\t\t\t\t: undefined\n\t\tconst reasoning = provided.success ? provided.value.thinking : partial?.thinking\n\t\tconst thinking = reasoning !== undefined && reasoning.length > 0 ? reasoning : undefined\n\t\tconst content = streamed.join('')\n\t\tconst estimate = estimateTokens(content)\n\t\tconst reported = provided.success ? provided.value.usage : partial?.usage\n\t\tconst usage = reported === undefined ? undefined : sanitizeUsage(reported)\n\t\t// The one charge site for every path, a genuine failure included. The estimate is already on\n\t\t// the cost budget only when the meter charged that same instance; a call that reported no usage\n\t\t// keeps its estimate on the cost budget, unless the meter put it there.\n\t\tconst charged = allowance === budget ? (meter?.charged ?? 0) : 0\n\t\tconst billed =\n\t\t\tusage ??\n\t\t\t(allowance === budget ? undefined : { prompt: 0, completion: estimate, total: estimate })\n\t\tif (billed !== undefined) chargeUsage(budget, billed, charged)\n\t\tif (!provided.success && !interrupted) throw provided.error\n\t\treturn {\n\t\t\tcontent,\n\t\t\tthinking,\n\t\t\tusage,\n\t\t\tspent: admitted.spent,\n\t\t\tmessages: admitted.messages,\n\t\t\tfutile: admitted.futile,\n\t\t\testimate,\n\t\t\tinterrupted,\n\t\t\ttruncated: false,\n\t\t}\n\t}\n\n\t// Composes the exact request one provider dispatch sends: the working messages after the\n\t// provider's replay policy, the advertised tool definitions, and the per-call `think` / `schema`\n\t// options. Keys are omitted when undefined, so the provider receives no tools and no options\n\t// object when there are none. The request owns its messages array, a shallow copy after the\n\t// replay filter, because that filter returns the working array itself for a policy that keeps\n\t// every message. The admission step measures this object and `#provide` sends it, so the\n\t// measured and the dispatched request can never diverge.\n\t#compose(\n\t\tmessages: readonly Message[],\n\t\ttools: ProviderRequest['tools'],\n\t\toptions: ProviderRequest['options'],\n\t): ProviderRequest {\n\t\treturn {\n\t\t\tmessages: [...stripThinking(messages, this.#replay)],\n\t\t\t...(tools === undefined ? {} : { tools }),\n\t\t\t...(options === undefined ? {} : { options }),\n\t\t}\n\t}\n\n\t// Admits one request against the context `window` budget immediately before its provider\n\t// dispatch, so only called when a window is set. `clear()` then consuming the request makes\n\t// `window.consumed` its estimated footprint, and `exhausted` means it has reached `max`. A\n\t// request over the window folds the active conversation once when it is summarizable and not\n\t// latched futile, then rebuilds through selection, recomposes with the same tool and option\n\t// snapshot, and measures again; the request that measures last is the one dispatched. A\n\t// non-summarizable conversation is measured but never folded, so the auto path never throws the\n\t// `compact()` SUMMARIZER error. A cancel anywhere returns no dispatch so the run settles partial,\n\t// and wins over `strict`; otherwise `strict` refuses a request still over the window with a\n\t// WINDOW error before any dispatch, while the lenient default sends it.\n\tasync #admit(\n\t\twindow: BudgetInterface<ProviderRequest>,\n\t\tcomposed: ProviderRequest,\n\t\tmessages: readonly Message[],\n\t\trequest: Message | undefined,\n\t\tlatch: boolean,\n\t\tfutile: boolean,\n\t\tabort: AbortInterface,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\twindow.clear()\n\t\twindow.consume(composed)\n\t\tif (!window.exhausted) return { dispatch: composed, messages, spent: undefined, futile }\n\t\t// A cancelled run is about to settle, so a fold would spend summarizer time on a request no\n\t\t// provider reads; the next run's first admission folds instead.\n\t\tif (abort.signal.aborted) return { dispatch: undefined, messages, spent: undefined, futile }\n\t\tconst conversation = this.#context.conversations.active\n\t\tif (conversation?.summarizable !== true || futile) {\n\t\t\treturn { dispatch: this.#enforce(window, composed), messages, spent: undefined, futile }\n\t\t}\n\t\t// The run signal bounds the fold: `compact()` rejects with its reason on a cancel and\n\t\t// commits nothing, even when the summarizer ignores the signal.\n\t\treturn conversation.compact({ signal: abort.signal }).then(\n\t\t\t(section) => this.#refold(section, window, composed, messages, request, latch, abort, budget),\n\t\t\t(error: unknown) => this.#unfold(error, composed, messages, abort),\n\t\t)\n\t}\n\n\t// A fold that settled: a cancel wins; nothing folded latches on a later turn, where the tail had\n\t// its chance to grow, but not on the first; otherwise rebuild through selection (compaction\n\t// changed the view the handler evaluates) and measure the rebuilt request.\n\tasync #refold(\n\t\tsection: Section | undefined,\n\t\twindow: BudgetInterface<ProviderRequest>,\n\t\tcomposed: ProviderRequest,\n\t\tmessages: readonly Message[],\n\t\trequest: Message | undefined,\n\t\tlatch: boolean,\n\t\tabort: AbortInterface,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\tif (abort.signal.aborted)\n\t\t\treturn { dispatch: undefined, messages, spent: undefined, futile: false }\n\t\tif (section === undefined) {\n\t\t\treturn {\n\t\t\t\tdispatch: this.#enforce(window, composed),\n\t\t\t\tmessages,\n\t\t\t\tspent: undefined,\n\t\t\t\tfutile: latch,\n\t\t\t}\n\t\t}\n\t\tconst selecting = this.#select(request, abort, budget)\n\t\tconst rebuilt =\n\t\t\tselecting === undefined\n\t\t\t\t? { messages: this.#context.build(), usage: undefined }\n\t\t\t\t: await selecting\n\t\tif (abort.signal.aborted) {\n\t\t\treturn {\n\t\t\t\tdispatch: undefined,\n\t\t\t\tmessages: rebuilt.messages,\n\t\t\t\tspent: rebuilt.usage,\n\t\t\t\tfutile: false,\n\t\t\t}\n\t\t}\n\t\tconst dispatch = this.#compose(rebuilt.messages, composed.tools, composed.options)\n\t\twindow.clear()\n\t\twindow.consume(dispatch)\n\t\treturn {\n\t\t\tdispatch: this.#enforce(window, dispatch),\n\t\t\tmessages: rebuilt.messages,\n\t\t\tspent: rebuilt.usage,\n\t\t\tfutile: false,\n\t\t}\n\t}\n\n\t// A fold that rejected: a cancel wins over the failure it caused, as on the select path;\n\t// otherwise surface the summarizer failure observably, rethrow under `strict`, and send the\n\t// over-window request leniently.\n\t#unfold(\n\t\terror: unknown,\n\t\tcomposed: ProviderRequest,\n\t\tmessages: readonly Message[],\n\t\tabort: AbortInterface,\n\t) {\n\t\tif (abort.signal.aborted)\n\t\t\treturn { dispatch: undefined, messages, spent: undefined, futile: false }\n\t\tthis.#emitter.emit('fault', error)\n\t\tif (this.#strict) throw error\n\t\treturn { dispatch: composed, messages, spent: undefined, futile: false }\n\t}\n\n\t// Refuses, under `strict`, a request the window still measures over its max; returns it otherwise.\n\t#enforce(window: BudgetInterface<ProviderRequest>, request: ProviderRequest): ProviderRequest {\n\t\tif (this.#strict && window.exhausted) {\n\t\t\tthrow new AgentError(\n\t\t\t\t'WINDOW',\n\t\t\t\t`the request measures ${window.consumed} against a window of ${window.max} and cannot shrink`,\n\t\t\t\t{ context: { agent: this.#id, consumed: window.consumed, max: window.max } },\n\t\t\t)\n\t\t}\n\t\treturn request\n\t}\n\n\t// One select site: the handler's pending selection settled into the working messages and the\n\t// usage it spent, or `undefined` when there is no request or no handler, so the caller builds from\n\t// `view()` without an await.\n\t#select(\n\t\trequest: Message | undefined,\n\t\tabort: AbortInterface,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\tconst pending = request === undefined ? undefined : this.#context.select(request, abort.signal)\n\t\treturn pending === undefined\n\t\t\t? undefined\n\t\t\t: pending.then(\n\t\t\t\t\t(selection) => this.#adopt(selection, abort, budget),\n\t\t\t\t\t(error: unknown) => this.#reject(error, abort),\n\t\t\t\t)\n\t}\n\n\t// A resolved selection: charge its usage before the abort check, because judge calls were spent\n\t// either way and the charge can itself trip the run's bound; then build from it unless a cancel or\n\t// a strict fault intervenes. A cancelled site builds from `view()` and emits no `select`.\n\t#adopt(\n\t\tselection: Selection,\n\t\tabort: AbortInterface,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t) {\n\t\tconst usage = selection.usage === undefined ? undefined : sanitizeUsage(selection.usage)\n\t\tif (usage !== undefined) chargeUsage(budget, usage, 0)\n\t\tif (abort.signal.aborted) return { messages: this.#context.build(), usage }\n\t\tif (selection.fault !== undefined) {\n\t\t\tthis.#emitter.emit('fault', selection.fault)\n\t\t\tif (abort.signal.aborted) return { messages: this.#context.build(), usage }\n\t\t\tif (this.#strict) throw selection.fault\n\t\t}\n\t\tconst messages = this.#context.build(selection)\n\t\tthis.#emitter.emit('select', selection)\n\t\treturn { messages, usage }\n\t}\n\n\t// A rejected selection: a fault unless cancelled, rethrown under `strict`, then the default build.\n\t#reject(error: unknown, abort: AbortInterface) {\n\t\tif (!abort.signal.aborted) {\n\t\t\tthis.#emitter.emit('fault', error)\n\t\t\t// A `fault` listener can cancel the run synchronously; the cancel then wins over `strict`.\n\t\t\tif (this.#strict && !abort.signal.aborted) throw error\n\t\t}\n\t\treturn { messages: this.#context.build(), usage: undefined }\n\t}\n\n\t// Evaluate policy and emit denials before the run's final pre-dispatch abort guard:\n\t// policy callbacks and denial listeners can cancel the run synchronously.\n\t#authorize(calls: readonly ToolCall[], admitted: readonly ToolCall[]) {\n\t\t// `entries()` visits a hole as `undefined`, as a `for…of` over the calls does.\n\t\tconst decisions = [...calls.entries()].map(([index, call]) => ({\n\t\t\tindex,\n\t\t\tcall,\n\t\t\tdenial: this.#decide(call, admitted),\n\t\t}))\n\t\treturn {\n\t\t\tallowed: new Map(\n\t\t\t\tdecisions.flatMap((one) =>\n\t\t\t\t\tone.denial === undefined ? [[one.index, one.call] as const] : [],\n\t\t\t\t),\n\t\t\t),\n\t\t\tdenials: new Map(\n\t\t\t\tdecisions.flatMap((one) =>\n\t\t\t\t\tone.denial === undefined ? [] : [[one.index, one.denial] as const],\n\t\t\t\t),\n\t\t\t),\n\t\t}\n\t}\n\n\t// Decides one call — scope, then authority — and emits `deny` with the reason of a denial.\n\t#decide(call: ToolCall, admitted: readonly ToolCall[]): ToolResult | undefined {\n\t\tif (!admitted.includes(call)) {\n\t\t\tconst reason = `${call.name} is not in the active scope`\n\t\t\tconst denial = denyCall(call, reason)\n\t\t\tthis.#emitter.emit('deny', call, reason)\n\t\t\treturn denial\n\t\t}\n\t\tconst authority = this.#authority\n\t\tif (authority === undefined) return undefined\n\t\t// A security gate must fail closed: if a policy `evaluate` throws, the call is not\n\t\t// cleared, so it must not run. Synthesize a denial (carrying the error's message)\n\t\t// instead of letting the throw reject the whole run — the tool stays unexecuted and\n\t\t// the model still receives a denial it can react to, exactly like an explicit `deny`.\n\t\tconst evaluated = attempt(() => authority.evaluate({ call }))\n\t\tif (!evaluated.success) {\n\t\t\t// The declared `@orkestrel/workflow` normalizer, so a fail-closed denial carries a\n\t\t\t// non-empty explanation the model can read: an `Error` with an empty `message`\n\t\t\t// normalizes to real text, and a throw whose stringification itself fails is caught\n\t\t\t// rather than escaping the gate and rejecting the run.\n\t\t\tconst reason = errorToMessage(evaluated.error)\n\t\t\tconst denial = denyCall(call, reason)\n\t\t\tthis.#emitter.emit('deny', call, reason)\n\t\t\treturn denial\n\t\t}\n\t\tif (evaluated.value.allowed) return undefined\n\t\tconst denial = denyCall(call, evaluated.value.reason)\n\t\tthis.#emitter.emit('deny', call, evaluated.value.reason)\n\t\treturn denial\n\t}\n\n\t// Carry cancellation into entered handlers, then merge executed results and denials\n\t// in call order. An all-denied turn costs no tool run.\n\tasync #dispatch(\n\t\ttools: ToolManagerInterface,\n\t\tcalls: readonly ToolCall[],\n\t\tsignal: AbortSignal,\n\t\tauthorization: {\n\t\t\treadonly allowed: ReadonlyMap<number, ToolCall>\n\t\t\treadonly denials: ReadonlyMap<number, ToolResult>\n\t\t},\n\t): Promise<readonly ToolResult[]> {\n\t\tconst { allowed, denials } = authorization\n\t\tconst executed = allowed.size > 0 ? await tools.execute([...allowed.values()], { signal }) : []\n\t\t// Denials and executed results never share an index.\n\t\tconst results = new Map<number, ToolResult>([\n\t\t\t...denials,\n\t\t\t...[...allowed.keys()].flatMap((index, offset) => {\n\t\t\t\tconst result = executed[offset]\n\t\t\t\treturn result === undefined ? [] : [[index, result] as const]\n\t\t\t}),\n\t\t])\n\t\treturn calls.map((call, index) => results.get(index) ?? denyCall(call, undefined))\n\t}\n\n\t// Drive one provider stream turn: read the `channel` of each {@link ProviderDelta} — a `'content'`\n\t// delta is the answer (appended to the turn's `streamed` log, charged through the meter, surfaced\n\t// as a `token` chunk, in that order); a `'thinking'` delta is live reasoning (surfaced as a `think`\n\t// chunk, never metered — reasoning is not answer content) — returning the provider's assembled\n\t// result or its failure as a Result built through the installed `attempt`, so the turn reads a\n\t// provider or meter failure from a value. It sends the composed {@link ProviderRequest}\n\t// unchanged — the messages already carry only the thinking the provider's replay policy permits\n\t// (default `'none'`), and the tools and options are the turn's snapshot, absent when there are\n\t// none. It pulls the provider itself, so no generator layer sits between a delta and the turn.\n\tasync *#provide(\n\t\trequest: ProviderRequest,\n\t\tsignal: AbortSignal,\n\t\tstreamed: string[],\n\t\tmeter: MeterInterface | undefined,\n\t): AsyncGenerator<AgentChunk, Result<ProviderResult>> {\n\t\ttry {\n\t\t\tconst generator = this.#provider.stream(\n\t\t\t\trequest.messages,\n\t\t\t\tsignal,\n\t\t\t\trequest.tools,\n\t\t\t\trequest.options,\n\t\t\t)\n\t\t\tfor (;;) {\n\t\t\t\tconst next = await generator.next()\n\t\t\t\tif (next.done === true) {\n\t\t\t\t\tconst result = next.value\n\t\t\t\t\treturn attempt(() => result)\n\t\t\t\t}\n\t\t\t\tconst delta = next.value\n\t\t\t\tif (delta.channel === 'content') {\n\t\t\t\t\tstreamed.push(delta.text)\n\t\t\t\t\tmeter?.charge(delta.text)\n\t\t\t\t\tyield { category: 'token', content: delta.text }\n\t\t\t\t} else {\n\t\t\t\t\tyield { category: 'think', content: delta.text }\n\t\t\t\t}\n\t\t\t}\n\t\t} catch (error) {\n\t\t\treturn attempt((): ProviderResult => {\n\t\t\t\tthrow error\n\t\t\t})\n\t\t}\n\t}\n\n\t// The parent signal for a run's abort: the external signal, an optional per-run signal\n\t// (composed with, never replacing, the construction `signal`), the deadline, the effective\n\t// budget, and an allowance that is not the budget itself, folded through `AbortSignal.any` —\n\t// or a lone present one, or `undefined` when none. The budget precedes the allowance, so when\n\t// both are exhausted before the run the budget's reason is the run's.\n\t#combineSignals(\n\t\ttimeout: TimeoutInterface | undefined,\n\t\tbudget: BudgetInterface<TokenUsage> | undefined,\n\t\tallowance: BudgetInterface<TokenUsage> | undefined,\n\t\tsignal: AbortSignal | undefined,\n\t): AbortSignal | undefined {\n\t\tconst signals = [\n\t\t\tthis.#signal,\n\t\t\tsignal,\n\t\t\ttimeout?.signal,\n\t\t\tbudget?.signal,\n\t\t\tallowance === budget ? undefined : allowance?.signal,\n\t\t].filter((one): one is AbortSignal => one !== undefined)\n\t\tif (signals.length === 0) return undefined\n\t\tif (signals.length === 1) return signals[0]\n\t\treturn AbortSignal.any(signals)\n\t}\n}\n","import type { AgentJobInput, AgentRegistryInterface, AgentResult } from './types.js'\nimport type { ControllerInterface } from '@orkestrel/workflow'\nimport { settleAgentJob } from './helpers.js'\n\n/**\n * Executes one runner's agent jobs — spawning each unit's declared children on its first attempt\n * only, then rehydrating the unit through a registry with the controller signal and settling it\n * under the shared partial-result policy.\n *\n * @remarks\n * One instance serves one runner, because it records every unit it has fanned out. The runner\n * calls its handler once per attempt with the same unit id, so a retried attempt finds its unit\n * recorded and spawns no child again. Children are fired through the controller without being\n * awaited inline, so a bounded runner frees the parent's slot for them. `createAgentRunner`\n * creates one instance per runner and binds its `execute` method as the runner's handler.\n *\n * @example\n * ```ts\n * import type { AgentJobInput, ProviderInterface } from '@orkestrel/agent'\n * import { AgentFanout, createAgentRegistry } from '@orkestrel/agent'\n * import { createRunner } from '@orkestrel/workflow'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * const fanout = new AgentFanout(createAgentRegistry({ providers: { main: provider } }), false)\n * const runner = createRunner({ handler: fanout.execute.bind(fanout), retries: 1 })\n * const child: AgentJobInput = { provider: 'main', messages: [{ role: 'user', content: 'child' }] }\n * const parent: AgentJobInput = { ...child, messages: [{ role: 'user', content: 'parent' }], children: [child] }\n * const results = await runner.execute([parent]) // the parent's result, then the child's\n * ```\n */\nexport class AgentFanout {\n\treadonly #registry: AgentRegistryInterface\n\treadonly #partial: boolean\n\t// The ids of the units whose children this runner already spawned. Copy-on-write, and never\n\t// shrunk: a unit id stays recorded so every later attempt of that unit skips the fan-out.\n\t#spawned: ReadonlySet<string> = new Set<string>()\n\n\t/**\n\t * Creates the fan-out for one runner over a registry and a partial policy.\n\t *\n\t * @param registry - The registry that rehydrates each serializable job\n\t * @param partial - The partial policy. If `true`, a partial result resolves; if `false`, it throws an `AgentJobError`\n\t */\n\tconstructor(registry: AgentRegistryInterface, partial: boolean) {\n\t\tthis.#registry = registry\n\t\tthis.#partial = partial\n\t}\n\n\t/**\n\t * Executes one unit: spawns its declared children unless an earlier attempt of the unit already\n\t * did, then runs the rehydrated agent and settles it under the partial policy.\n\t *\n\t * @param controller - The runner controller for this unit's attempt\n\t * @returns The settled agent result of the unit\n\t * @throws {AgentJobError} Thrown when the run ended partial and the partial policy is `false`\n\t */\n\texecute(controller: ControllerInterface<AgentJobInput, AgentResult>): Promise<AgentResult> {\n\t\tconst children = controller.input.children\n\t\tif (children !== undefined && !this.#spawned.has(controller.id)) {\n\t\t\tthis.#spawned = new Set([...this.#spawned, controller.id])\n\t\t\tfor (const child of children) void controller.spawn(child)\n\t\t}\n\t\treturn settleAgentJob(this.#registry.build(controller.input, controller.signal), this.#partial)\n\t}\n}\n","import type {\n\tAuthorityContext,\n\tAuthorityDecision,\n\tAuthorityInterface,\n\tAuthorityOptions,\n\tAuthorityRule,\n} from './types.js'\nimport { DEFAULT_AUTHORITY_ZONE } from './constants.js'\n\n/**\n * Gates the agent loop's tool calls — the synchronous policy consulted before each call runs,\n * turning one {@link AuthorityContext} into an {@link AuthorityDecision} by walking the ordered\n * rules first-match-wins and falling back to a configurable default, which allows an unmatched\n * call unless its `fallback` denies.\n *\n * @remarks\n * - **Ordered, first-match-wins.** `evaluate` walks the configured rules in order and\n * returns the first whose `match(context)` is true as\n * `{ zone, allowed: rule.allowed ?? true, reason }` — a matched rule allows by\n * default and denies only when its `allowed` is explicitly `false`.\n * - **Fallback.** When no rule matches, `evaluate` returns the configured `fallback`.\n * Default: `{ zone: DEFAULT_AUTHORITY_ZONE, allowed: true }` (allow-unmatched),\n * so a rules list of denials behaves as a denylist. To make the gate deny-by-default\n * (an allowlist — only matched rules that allow get through), pass an `allowed: false`\n * `fallback`.\n * - **Consulted before each tool call.** The agent loop calls `evaluate({ call })` for\n * every {@link import('@orkestrel/tool').ToolCall} the model emits; a denied call is fed\n * back to the model as a denial {@link import('@orkestrel/tool').ToolResult} (a `tool`\n * chunk + a tool message) instead of being executed — no tool execution —\n * so the model receives the denial and can react.\n * - **Synchronous.** `evaluate` returns the verdict directly.\n * - **Event-free.** A purely functional gate — no Emitter, no events.\n *\n * @example\n * ```ts\n * // A denylist: deny the `delete` tool, allow everything else (default fallback).\n * const authority = new Authority({\n * \trules: [{ match: (c) => c.call.name === 'delete', zone: 'restricted', allowed: false }],\n * })\n * authority.evaluate({ call: { id: '1', name: 'delete', arguments: {} } }) // { zone: 'restricted', allowed: false }\n * authority.evaluate({ call: { id: '2', name: 'add', arguments: {} } }) // { zone: 'default', allowed: true }\n * ```\n */\nexport class Authority implements AuthorityInterface {\n\treadonly #rules: readonly AuthorityRule[]\n\treadonly #fallback: AuthorityDecision\n\n\tconstructor(options?: AuthorityOptions) {\n\t\tthis.#rules = options?.rules ?? []\n\t\tthis.#fallback = options?.fallback ?? { zone: DEFAULT_AUTHORITY_ZONE, allowed: true }\n\t}\n\n\tevaluate(context: AuthorityContext): AuthorityDecision {\n\t\tfor (const rule of this.#rules) {\n\t\t\tif (rule.match(context))\n\t\t\t\treturn {\n\t\t\t\t\tzone: rule.zone,\n\t\t\t\t\tallowed: rule.allowed ?? true,\n\t\t\t\t\t...(rule.reason === undefined ? {} : { reason: rule.reason }),\n\t\t\t\t}\n\t\t}\n\t\treturn this.#fallback\n\t}\n}\n","import type {\n\tAgentInterface,\n\tAgentJobInput,\n\tAgentOptions,\n\tAgentRegistryInterface,\n\tAgentRegistryOptions,\n\tAuthorityInterface,\n} from './types.js'\nimport type { ProviderInterface } from '../providers/index.js'\nimport type { ConversationStoreInterface } from '../conversations/index.js'\nimport type { ToolInterface } from '@orkestrel/tool'\nimport type { SchedulerInterface } from '@orkestrel/workflow'\nimport { createTokenBudget } from '@orkestrel/budget'\nimport { ToolManager } from '@orkestrel/tool'\nimport { Agent } from './Agent.js'\nimport { ConversationManager } from '../conversations/index.js'\nimport { requireEntry } from './helpers.js'\n\n/**\n * Makes a durable, JSON-serializable {@link AgentJobInput} runnable — holds the named pools of\n * live, non-serializable pieces (providers, tools, authorities, schedulers), throws on a name\n * absent from its pool, and its `build` method returns a seeded, signal-wired {@link Agent} from a job's names and\n * data.\n *\n * @remarks\n * - **Why it exists.** An `AgentJobInput` is serializable so it can survive a crash in a\n * Queue's store; the live objects it needs (a provider with sockets, tools / rules /\n * schedulers carrying functions) cannot serialize. The registry closes that gap:\n * construct it once with the live pools, then a queue / runner handler calls `build`\n * on each (possibly restored) job to get a ready agent.\n * - **Accessors throw on a miss.** `provider` / `tool` / `authority` / `scheduler` resolve a\n * name against their pool and throw an {@link AgentError} carrying `code: 'REGISTRY'` and\n * the message `unknown <category>: <name>` when it is absent — an unknown name in a\n * rehydrated job is a programmer / config error that must fail loudly at build time, never\n * silently resolve to `undefined` and run an agent missing a dependency.\n * - **`build` rehydrates.** Resolve the job's `provider`; assemble a fresh\n * {@link ToolManager} from the `tools` names; rebuild the token `budget` from its\n * ceiling (`createTokenBudget({ max })`); resolve the optional `authority` /\n * `scheduler` names; construct the {@link Agent} with `system` / `limit` / `timeout` /\n * the threaded `signal`; seed its context with the job's `messages`; return it. The\n * `signal` is the queue attempt's / runner unit's cancel, so a bounded abort propagates\n * into the agent (which commits a partial — the job's `partial` policy then\n * decides success vs. retry). A job `limit` that is not a nonnegative safe integer throws an\n * {@link AgentError} carrying `code: 'LIMIT'` from the agent's construction.\n * - **Event-free.** A pure resolver — no Emitter, no events.\n *\n * @example\n * ```ts\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * const registry = new AgentRegistry({ providers: { main: provider } })\n * const agent = registry.build({ provider: 'main', messages: [{ role: 'user', content: 'Say ok.' }] })\n * const result = await agent.generate()\n * ```\n */\nexport class AgentRegistry implements AgentRegistryInterface {\n\treadonly #providers: ReadonlyMap<string, ProviderInterface>\n\treadonly #tools: ReadonlyMap<string, ToolInterface>\n\treadonly #authorities: ReadonlyMap<string, AuthorityInterface>\n\treadonly #schedulers: ReadonlyMap<string, SchedulerInterface>\n\treadonly #store: ConversationStoreInterface | undefined\n\n\tconstructor(options: AgentRegistryOptions) {\n\t\tthis.#providers = new Map(Object.entries(options.providers))\n\t\tthis.#tools = new Map(Object.entries(options.tools ?? {}))\n\t\tthis.#authorities = new Map(Object.entries(options.authorities ?? {}))\n\t\tthis.#schedulers = new Map(Object.entries(options.schedulers ?? {}))\n\t\tthis.#store = options.store\n\t}\n\n\tprovider(name: string): ProviderInterface {\n\t\treturn requireEntry(this.#providers, 'provider', name)\n\t}\n\n\ttool(name: string): ToolInterface {\n\t\treturn requireEntry(this.#tools, 'tool', name)\n\t}\n\n\tauthority(name: string): AuthorityInterface {\n\t\treturn requireEntry(this.#authorities, 'authority', name)\n\t}\n\n\tscheduler(name: string): SchedulerInterface {\n\t\treturn requireEntry(this.#schedulers, 'scheduler', name)\n\t}\n\n\tbuild(input: AgentJobInput, signal?: AbortSignal): AgentInterface {\n\t\tconst provider = this.provider(input.provider)\n\t\tconst agent = new Agent(provider, this.#buildOptions(input, signal))\n\t\t// Seed the conversation onto the rehydrated agent's context — the serializable\n\t\t// MessageInputs become stored messages (each id minted by the manager).\n\t\tfor (const message of input.messages) agent.context.messages.add(message)\n\t\treturn agent\n\t}\n\n\t// Assemble the AgentOptions for one job: a fresh ToolManager loaded from the named\n\t// tools, the rebuilt token budget, the resolved authority / scheduler, plus the data\n\t// fields and the threaded cancel. Optional fields are omitted (not set to `undefined`)\n\t// so the Agent's `?? default` fallbacks behave exactly as for a hand-built agent. When\n\t// the registry carries a conversation store, thread a fresh store-backed\n\t// ConversationManager for this build (a fresh conversation id per build ⇒ no\n\t// collisions in the shared store) — omitted when no store is set, so the shape matches a\n\t// registry with no `store`.\n\t#buildOptions(input: AgentJobInput, signal: AbortSignal | undefined): AgentOptions {\n\t\tconst budget = input.budget === undefined ? undefined : createTokenBudget({ max: input.budget })\n\t\treturn {\n\t\t\ttools: this.#buildToolManager(input.tools),\n\t\t\t...(input.system === undefined ? {} : { system: input.system }),\n\t\t\t...(input.limit === undefined ? {} : { limit: input.limit }),\n\t\t\t...(input.timeout === undefined ? {} : { timeout: input.timeout }),\n\t\t\t...(budget === undefined ? {} : { budget }),\n\t\t\t...(input.authority === undefined ? {} : { authority: this.authority(input.authority) }),\n\t\t\t...(input.scheduler === undefined ? {} : { scheduler: this.scheduler(input.scheduler) }),\n\t\t\t...(this.#store === undefined\n\t\t\t\t? {}\n\t\t\t\t: { conversations: new ConversationManager({ store: this.#store }) }),\n\t\t\t...(signal === undefined ? {} : { signal }),\n\t\t}\n\t}\n\n\t// A fresh tool registry loaded with the named tools (each resolved — an unknown name\n\t// throws). Always a new manager per build, so concurrent jobs never share one.\n\t#buildToolManager(names: readonly string[] | undefined): ToolManager {\n\t\tconst manager = new ToolManager()\n\t\tif (names !== undefined) for (const name of names) manager.add(this.tool(name))\n\t\treturn manager\n\t}\n}\n","import type { ProviderInterface } from '../providers/index.js'\nimport type {\n\tAgentInterface,\n\tAgentJobInput,\n\tAgentOptions,\n\tAgentQueueOptions,\n\tAgentRegistryInterface,\n\tAgentRegistryOptions,\n\tAgentResult,\n\tAgentRunnerOptions,\n\tAuthorityInterface,\n\tAuthorityOptions,\n\tChannelInterface,\n} from './types.js'\nimport type { QueueInterface } from '@orkestrel/queue'\nimport type { RunnerInterface } from '@orkestrel/workflow'\nimport { createQueue } from '@orkestrel/queue'\nimport { createRunner } from '@orkestrel/workflow'\nimport { Agent } from './Agent.js'\nimport { AgentFanout } from './AgentFanout.js'\nimport { Channel } from './Channel.js'\nimport { Authority } from './Authority.js'\nimport { AgentRegistry } from './AgentRegistry.js'\nimport { extractQueueOptions, handleAgentQueueJob } from './helpers.js'\n\n/**\n * Creates an agent loop — an {@link AgentInterface} composing a\n * {@link ProviderInterface}, its {@link AgentContextInterface}, and a tool registry\n * into a bounded context → provider → tools → repeat turn, exposed as a one-shot\n * `generate` and a live `stream`.\n *\n * @remarks\n * One private loop drives the turn; `generate` awaits the settled result of the same run\n * `stream` exposes and leaves its live chunks undrained, so they can never diverge. Each turn is bounded by one cancel folded from\n * `signal` + `timeout` + `budget` + `allowance` (through `AbortSignal.any`) — any trip (or `abort()`)\n * commits a partial result (the stream's `result` resolves on a cancel, rejects only\n * on a genuine provider / tool error). The `scheduler` paces between turns; tool\n * iteration is capped at `limit`. Default: `DEFAULT_AGENT_LIMIT`. Tools are advertised\n * structurally through `context.tools.definitions()`. Two observation surfaces: the\n * {@link AgentChunk} stream (pull — per-token content) and a typed `emitter` (push —\n * lifecycle + `usage` / `tool` / `deny` for fire-and-forget observers).\n *\n * @param provider - The {@link ProviderInterface} the loop drives each turn\n * @param options - Optional `system` / `tools` / `limit` / `timeout` / `budget` /\n * `scheduler` / `signal` (see {@link AgentOptions})\n * @returns A working {@link AgentInterface}\n *\n * @example\n * ```ts\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { createAgent } from '@orkestrel/agent'\n * import { createTokenBudget } from '@orkestrel/budget'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * const agent = createAgent(provider, {\n * \tsystem: 'You are concise.',\n * \tbudget: createTokenBudget({ max: 50_000, scope: 'total' }),\n * })\n * agent.context.messages.add({ role: 'user', content: 'Say hi.' })\n *\n * const stream = agent.stream()\n * for await (const chunk of stream.events) {\n * \tif (chunk.category === 'token') process.stdout.write(chunk.content)\n * }\n * const result = await stream.result // { content, usage?, partial }\n * ```\n */\nexport function createAgent(provider: ProviderInterface, options?: AgentOptions): AgentInterface {\n\treturn new Agent(provider, options)\n}\n\n/**\n * Creates an empty unbounded async channel — a {@link ChannelInterface} a producer writes\n * values into (`push`) and ends (`close` / `fail`) regardless of consumption, while a\n * consumer reads them back live through `drain`.\n *\n * @remarks\n * Write and read are decoupled, so the producer never waits for a consumer: an agent's eager\n * pump writes each chunk into one, which is why a run's `result` settles whether or not the\n * live events are drained. A value pushed at an already-parked consumer is delivered, buffered\n * values are yielded before the end is reported, and the first failure wins.\n *\n * @typeParam T - The value type the channel carries\n * @returns A fresh, empty {@link ChannelInterface}\n *\n * @example\n * ```ts\n * import { createChannel } from '@orkestrel/agent'\n *\n * const channel = createChannel<number>()\n * channel.push(1)\n * channel.close()\n * for await (const value of channel.drain()) {\n * \tvalue // 1\n * }\n * ```\n */\nexport function createChannel<T>(): ChannelInterface<T> {\n\treturn new Channel<T>()\n}\n\n/**\n * Creates a policy gate — an {@link AuthorityInterface} the agent loop consults before\n * each tool call runs, evaluating the ordered rules first-match-wins and falling back\n * to the configured default when none match.\n *\n * @remarks\n * `rules` are evaluated in order — the first whose `match` is true decides (a matched\n * rule allows unless its `allowed` is explicitly `false`). When no rule matches, the\n * `fallback` decides. Default: `{ zone: DEFAULT_AUTHORITY_ZONE, allowed: true }`\n * (allow-unmatched — a rules list of denials acts as a denylist). Pass an\n * `allowed: false` `fallback` to flip the gate to deny-by-default (an allowlist). Wire\n * the result into `createAgent` through `AgentOptions.authority`: a denied call is fed back\n * to the model as a denial `ToolResult` (not executed), so the model\n * can react. Synchronous — `evaluate` returns the verdict directly.\n *\n * @param options - Optional `rules` (ordered) and `fallback` (see {@link AuthorityOptions})\n * @returns A working {@link AuthorityInterface}\n *\n * @example\n * ```ts\n * import { createAgent, createAuthority } from '@orkestrel/agent'\n *\n * // Deny the `delete` tool, allow everything else.\n * const authority = createAuthority({\n * \trules: [{ match: (c) => c.call.name === 'delete', zone: 'restricted', allowed: false }],\n * })\n * const agent = createAgent(provider, { tools, authority })\n * ```\n */\nexport function createAuthority(options?: AuthorityOptions): AuthorityInterface {\n\treturn new Authority(options)\n}\n\n/**\n * Creates a registry of live providers, tools, authorities, and schedulers whose `build` method returns a seeded, signal-wired {@link AgentInterface} from a serializable job.\n *\n * @remarks\n * `providers` is required; `tools` / `authorities` / `schedulers` are optional pools.\n * The accessors (`provider` / `tool` / `authority` / `scheduler`) throw an\n * {@link import('./errors.js').AgentError} carrying `code: 'REGISTRY'` and the message\n * `unknown <category>: <name>` on an unregistered name — a misconfigured or crash-restored\n * job fails loudly rather than running with a missing dependency. `build(input, signal)`\n * resolves the names, rebuilds the token budget from its ceiling, seeds the agent's\n * context with the job's messages, and threads `signal` so a queue / runner abort\n * propagates. This is the bridge that makes durable, serializable agent jobs runnable.\n *\n * @param options - The named pools (see {@link AgentRegistryOptions})\n * @returns A working {@link AgentRegistryInterface}\n *\n * @example\n * ```ts\n * import { createAgentRegistry } from '@orkestrel/agent'\n * import type { ProviderInterface } from '@orkestrel/agent'\n * import { createTool } from '@orkestrel/tool'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * const registry = createAgentRegistry({\n * \tproviders: { main: provider },\n * \ttools: { add: createTool({ name: 'add', execute: (a) => Number(a.x) + Number(a.y) }) },\n * })\n * const agent = registry.build({ provider: 'main', messages: [{ role: 'user', content: 'Hi.' }] })\n * ```\n */\nexport function createAgentRegistry(options: AgentRegistryOptions): AgentRegistryInterface {\n\treturn new AgentRegistry(options)\n}\n\n/**\n * Creates a durable, bounded-concurrency agent-job queue — a {@link QueueInterface} over\n * serializable values of {@link AgentJobInput} that composes `createQueue`: each job is rehydrated\n * through the `registry` into a live {@link AgentInterface}, run to its {@link AgentResult},\n * and subjected to the partial-as-configurable-failure policy.\n *\n * @remarks\n * - **Composes the substrate (no new engine).** The handler is the only new logic;\n * bounded `concurrency`, `retries`, the per-attempt `timeout`, and durable persistence\n * through `store` (+ `restore()` after a crash) are all the backing Queue's. `enqueue`\n * returns a per-job promise.\n * - **Durable + serializable.** Because `AgentJobInput` is JSON-serializable, a `store`\n * persists outstanding jobs; `restore()` re-enqueues them and the `registry` rehydrates the\n * live pieces from the names. A job survives a crash only through a store whose rows outlive\n * the process (for example `createDatabaseQueueStore`); a `createMemoryQueueStore` row is\n * gone when the process exits.\n * - **Partial policy.** A partial result throws an\n * {@link import('./errors.js').AgentJobError} by default, so a job cancelled by its\n * attempt deadline / a queue abort retries while attempts remain; `partial: true`\n * resolves the partial as success instead.\n * - **Cancellation threads through.** The handler passes `context.signal` into\n * `registry.build`, so a queue `abort()` or a per-attempt timeout cancels the in-flight\n * agent (which commits a partial → throws → retries / fails per policy).\n *\n * @param options - The `registry`, the `partial` policy, and the substrate knobs\n * (`concurrency` / `retries` / `timeout` / `store`) (see {@link AgentQueueOptions})\n * @returns A {@link QueueInterface} of {@link AgentJobInput} → {@link AgentResult}\n *\n * @example\n * ```ts\n * import type { AgentJobInput, ProviderInterface } from '@orkestrel/agent'\n * import type { QueueStoreInterface } from '@orkestrel/queue'\n * import { createAgentQueue, createAgentRegistry } from '@orkestrel/agent'\n *\n * declare const provider: ProviderInterface // any concrete implementation supplied by the host app\n * declare const store: QueueStoreInterface<AgentJobInput> // a durable store the host supplies\n * const registry = createAgentRegistry({ providers: { main: provider } })\n * const queue = createAgentQueue({ registry, concurrency: 2, retries: 1, store })\n * const result = await queue.enqueue({ provider: 'main', messages: [{ role: 'user', content: 'ok?' }] })\n * ```\n */\nexport function createAgentQueue(\n\toptions: AgentQueueOptions,\n): QueueInterface<AgentJobInput, AgentResult> {\n\tconst { registry, partial = false, store } = options\n\treturn createQueue<AgentJobInput, AgentResult>({\n\t\t...extractQueueOptions(options),\n\t\t...(store === undefined ? {} : { store }),\n\t\thandler: handleAgentQueueJob.bind(undefined, registry, partial),\n\t})\n}\n\n/**\n * Creates an agent-job runner — a {@link RunnerInterface} over serializable\n * values of {@link AgentJobInput} that composes `createRunner` (one-shot, ordered, fail-fast), each unit\n * rehydrated through the `registry` and subjected to the partial policy. The runner also carries\n * sub-agent fan-out: a parent job's handler can call `controller.spawn` with a child job.\n *\n * @remarks\n * - **Composes the substrate (no new engine).** Bounded `concurrency`, `retries`, the\n * per-attempt `timeout`, ordered results, and fail-fast are all the backing Runner's;\n * the handler adds only rehydration + the partial policy.\n * - **Sub-agent fan-out.** Each unit's handler receives a `ControllerInterface` whose\n * `spawn(childJob)` launches a child agent job through the same bounded queue (the\n * child's result joins the run after the declared units, in spawn order). A unit spawns its\n * declared `children` on its first attempt only, so a retried parent never runs a child\n * twice. On a bounded\n * runner, fan out and return — do not await a spawn inline from within the handler (a\n * slot-holding handler awaiting its own spawn can deadlock; see `ControllerInterface`).\n * - **Partial policy + cancellation.** Same as `createAgentQueue`: a partial result\n * throws by default (the run's fail-fast engages), `partial: true` resolves it; the\n * handler threads `controller.signal` into `registry.build`, so a runner abort / a\n * per-attempt timeout cancels the agent.\n *\n * @param options - The `registry`, the `partial` policy, and the substrate knobs\n * (`concurrency` / `retries` / `timeout`) (see {@link AgentRunnerOptions})\n * @returns A {@link RunnerInterface} of {@link AgentJobInput} → {@link AgentResult}\n *\n * @example\n * ```ts\n * import { createAgentRunner, createAgentRegistry } from '@orkestrel/agent'\n *\n * const registry = createAgentRegistry({ providers: { main: provider } })\n * const runner = createAgentRunner({ registry, concurrency: 2 })\n * // Run one job that fans out a child; results hold the parent, then the spawn.\n * const child = { provider: 'main', messages: [{ role: 'user', content: 'child' }] }\n * const parent = { provider: 'main', messages: [{ role: 'user', content: 'parent' }], children: [child] }\n * const results = await runner.execute([parent]) // declared first, then any spawns\n * ```\n */\nexport function createAgentRunner(\n\toptions: AgentRunnerOptions,\n): RunnerInterface<AgentJobInput, AgentResult> {\n\tconst { registry, partial = false } = options\n\tconst fanout = new AgentFanout(registry, partial)\n\treturn createRunner<AgentJobInput, AgentResult>({\n\t\t...extractQueueOptions(options),\n\t\thandler: fanout.execute.bind(fanout),\n\t})\n}\n","import type { LedgerCategory, LedgerNote, LedgerQuestion, LedgerShare } from './types.js'\n\n/**\n * Lists the categories the ledger files a message under, in the order the category question\n * names them — the one list the {@link LedgerCategory} union derives from.\n */\nexport const LEDGER_CATEGORIES = Object.freeze([\n\t'fact',\n\t'rule',\n\t'correction',\n\t'request',\n\t'opinion',\n\t'chatter',\n\t'distractor',\n] as const)\n\n/** Lists the categories whose messages the projection leaves out as quiet. */\nexport const QUIET_CATEGORIES: readonly LedgerCategory[] = Object.freeze(['chatter', 'distractor'])\n\n/** Lists the categories whose messages state what the desk acts on, which the briefing renders. */\nexport const DECISIVE_CATEGORIES: readonly LedgerCategory[] = Object.freeze([\n\t'fact',\n\t'rule',\n\t'correction',\n])\n\n/** Lists the categories that place a message no owner claims on the rules record. */\nexport const PLACED_CATEGORIES: readonly LedgerCategory[] = Object.freeze(['rule', 'correction'])\n\n/** Names the key of the record that holds the rules no owner claims. */\nexport const LEDGER_RULES_KEY = 'rules'\n\n/** Prefixes the key of an owner's record, which the owner's id follows. */\nexport const LEDGER_OWNER_PREFIX = 'owner:'\n\n/**\n * Supplies the wording of every question the ledger asks its judge.\n *\n * @remarks\n * The wording names a support desk. Fit the cutoffs for the wording and judge you use.\n */\nexport const LEDGER_QUESTIONS: LedgerQuestion = Object.freeze({\n\tcategory: Object.freeze({\n\t\tform: 'choice',\n\t\tinstructions: 'Which category best describes what this support-desk message states?',\n\t\tcriteria: Object.freeze({\n\t\t\tfact: 'States a fact about a customer, an order, an account, the desk, or the day',\n\t\t\trule: 'States a standing rule, policy, or instruction the desk must follow',\n\t\t\tcorrection: 'Corrects, replaces, or withdraws a value or rule stated earlier',\n\t\t\trequest: 'Asks the assistant to do a task or to answer a question',\n\t\t\topinion: 'States a personal view or judgment rather than a fact',\n\t\t\tchatter: 'Talk with the agent that states nothing the desk acts on',\n\t\t\tdistractor: \"A statement about something outside the desk's work\",\n\t\t}),\n\t}),\n\ttopic: 'Does this support-desk message concern the named desk topic?',\n\tamends: Object.freeze({\n\t\tform: 'noul',\n\t\tinstructions:\n\t\t\t'Does the later message replace or withdraw any value or rule the earlier message states?',\n\t\tcriteria: Object.freeze({\n\t\t\ttrue: 'The later message replaces or withdraws at least one value or rule the earlier message states',\n\t\t\tfalse:\n\t\t\t\t'Every value and rule the earlier message states stays in force after the later message',\n\t\t}),\n\t}),\n\tsupersedes: Object.freeze({\n\t\tform: 'noul',\n\t\tinstructions:\n\t\t\t'Does the later message replace or withdraw everything the earlier message states?',\n\t\tcriteria: Object.freeze({\n\t\t\ttrue: 'The later message replaces or withdraws everything the earlier message states',\n\t\t\tfalse: 'Some value or rule the earlier message states stays in force after the later message',\n\t\t}),\n\t}),\n})\n\n/**\n * Supplies the text of each ledger note, worded for a model that answers in its final\n * message.\n */\nexport const LEDGER_NOTES: LedgerNote = Object.freeze({\n\tcue: '[Desk] Give your complete answer now as your final message, from what you already have.',\n\tresults: '[Desk] What your lookups and recalls returned in this request:',\n\trepeat:\n\t\t'You already have this result earlier in this request; give your complete answer now as your final message.',\n\tclosure:\n\t\t'recall is closed for the rest of this request; give your final answer from what you have',\n})\n\n/**\n * Supplies the default prompt and tail shares.\n */\nexport const DEFAULT_LEDGER_SHARE: LedgerShare = Object.freeze({\n\tprompt: 0.7,\n\ttail: 0.35,\n})\n\n/**\n * Caps the tool-iteration turns of a ledger's agent at 8 turns.\n */\nexport const DEFAULT_LEDGER_LIMIT = 8\n\n/**\n * Caps the `recall` calls of one request at 2 calls.\n */\nexport const DEFAULT_RECALL_LIMIT = 2\n\n/**\n * Holds back the share of the prompt budget the scale can rise by between calibration and a\n * request's first call.\n *\n * @remarks\n * Across the `ledger-deny` and `ledger-admit` series of 2026-10-08, a\n * request's first-call tokens per estimate unit rose at most from 1.150 at the seed to 1.212, 5.4\n * percent; the ledger divides its prompt budget by 1.06.\n */\nexport const LEDGER_SCALE_DRIFT = 0.06\n\n/** Matches the logprob decoding failure `invalid or duplicate top logprob token`, which the ledger holds for the ledger's life. */\nexport const DETERMINISTIC_JUDGE_ERROR = /invalid or duplicate top logprob token/\n","import type { LedgerErrorCode } from './types.js'\nimport { INTRINSICS, holds } from '@orkestrel/contract'\n\n/**\n * Reports an invalid ledger configuration, failed calibration, or unowned request selection,\n * carrying the machine-readable `code`.\n *\n * @remarks\n * A threshold, share, capacity, limit, topic, lookup, or gauge outside its bounds is a programmer\n * error and throws this with the matching {@link LedgerErrorCode}. A calibration call that reports\n * no prompt usage throws this with `'GAUGE'`. Narrow a caught value with {@link isLedgerError} and\n * branch on `error.code`. A selection without an active `respond` call, or for a request other than\n * that call's request or a ledger note, reports `'REQUEST'` through the selection's fault.\n */\nexport class LedgerError extends Error {\n\t/** Names the machine-readable condition; the {@link LedgerErrorCode} union describes each code. */\n\treadonly code: LedgerErrorCode\n\n\t/**\n\t * Records the failure condition and its description.\n\t *\n\t * @param code - The machine-readable condition, exposed as `error.code`\n\t * @param message - The human-readable description of the failure\n\t */\n\tconstructor(code: LedgerErrorCode, message: string) {\n\t\tsuper(message)\n\t\tthis.name = 'LedgerError'\n\t\tINTRINSICS.define(this, Symbol.for('@orkestrel/agent.LedgerError'), { value: this })\n\t\tthis.code = code\n\t}\n}\n\n/**\n * Narrows an unknown caught value to a {@link LedgerError} through its identity brand and declared members, so a `catch` can\n * branch on its `code`.\n *\n * @param value - The value to test (typically a `catch` binding)\n * @returns True if `value` is a {@link LedgerError}; false otherwise\n *\n * @example\n * ```ts\n * isLedgerError(new LedgerError('GAUGE', 'calibration reported no prompt usage')) // true\n * ```\n */\nexport function isLedgerError(value: unknown): value is LedgerError {\n\treturn holds(() => {\n\t\tif (\n\t\t\t!(\n\t\t\t\tvalue instanceof Error &&\n\t\t\t\tINTRINSICS.prototype(value) !== Error.prototype &&\n\t\t\t\tINTRINSICS.describe(value, Symbol.for('@orkestrel/agent.LedgerError'))?.value === value\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\tconst code = INTRINSICS.reflect.read(value, 'code')\n\t\tif (\n\t\t\t!(\n\t\t\t\tcode === 'REQUEST' ||\n\t\t\t\tcode === 'THRESHOLD' ||\n\t\t\t\tcode === 'SHARE' ||\n\t\t\t\tcode === 'CAPACITY' ||\n\t\t\t\tcode === 'LIMIT' ||\n\t\t\t\tcode === 'TOPIC' ||\n\t\t\t\tcode === 'LOOKUP' ||\n\t\t\t\tcode === 'GAUGE' ||\n\t\t\t\tcode === 'REFERENCE'\n\t\t\t)\n\t\t)\n\t\t\treturn false\n\t\treturn true\n\t})\n}\n","import type { Message } from '../types.js'\nimport type {\n\tGaugeCall,\n\tLedgerAmendment,\n\tLedgerCategory,\n\tLedgerLine,\n\tLedgerLookupReading,\n\tLedgerLookupState,\n\tLedgerPlanGroup,\n\tLedgerProjection,\n\tLedgerProjectionInput,\n\tLedgerProjectionRequest,\n\tLedgerRecord,\n\tLedgerRegistry,\n\tLedgerRenderContext,\n\tLedgerTokenSet,\n\tLedgerTopic,\n\tLedgerWordSet,\n} from './types.js'\nimport type { ToolCall } from '@orkestrel/tool'\nimport { canonicalStringify, isError, isFiniteNumber, isString } from '@orkestrel/contract'\nimport { estimateMessages } from '../agents/helpers.js'\nimport { renderJSON } from '../helpers.js'\nimport { isNonNegativeSafeInteger } from '../validators.js'\nimport { LEDGER_OWNER_PREFIX, LEDGER_RULES_KEY, PLACED_CATEGORIES } from './constants.js'\nimport { LedgerError } from './errors.js'\n\n/**\n * Collects the live message ids placed in records or left without a record.\n * @param projection - The projected records and unplaced ids\n * @returns The distinct live message ids\n * @example\n * ```ts\n * collectProjectionIds({ records: [], amendments: [], orphans: ['message-1'] }) // Set { 'message-1' }\n * ```\n */\nexport function collectProjectionIds(projection: LedgerProjection): ReadonlySet<string> {\n\treturn new Set([...projection.orphans, ...projection.records.flatMap((record) => record.members)])\n}\n\n/**\n * Scans admitted amendments in breadth-first order without revisiting a message.\n * @param amendments - The later messages attached to each earlier message\n * @param start - The first message to visit\n * @param admit - The predicate that admits a message and its descendants\n * @returns The admitted message ids in visit order\n * @example\n * ```ts\n * scanAmendments(new Map([['first', ['second']]]), 'first', () => true) // ['first', 'second']\n * ```\n */\nexport function scanAmendments(\n\tamendments: ReadonlyMap<string, readonly string[]>,\n\tstart: string,\n\tadmit: (id: string) => boolean,\n): readonly string[] {\n\tconst queue = [start]\n\tconst seen = new Set<string>()\n\tconst admitted: string[] = []\n\tfor (const id of queue) {\n\t\tif (seen.has(id)) continue\n\t\tseen.add(id)\n\t\tif (!admit(id)) continue\n\t\tadmitted.push(id)\n\t\tfor (const later of amendments.get(id) ?? []) queue.push(later)\n\t}\n\treturn admitted\n}\n\n/**\n * Builds the placeholder assistant recall call used to price recall framing.\n * @param topic - The recall topic to price\n * @returns The assistant message carrying the recall call\n * @example\n * ```ts\n * buildRecallMessage('refunds').calls?.[0]?.arguments // { topic: 'refunds' }\n * ```\n */\nexport function buildRecallMessage(topic: string): Message {\n\treturn {\n\t\tid: 'call',\n\t\trole: 'assistant',\n\t\tcontent: '',\n\t\tcalls: [{ id: 'call_00000000', name: 'recall', arguments: { topic } }],\n\t}\n}\n\n/**\n * Renders topic names as a comma-separated list in their supplied order.\n * @param topics - The configured desk topics\n * @returns The topic names joined by a comma and a space\n * @example\n * ```ts\n * renderTopicNames([{ name: 'refunds', criterion: 'Refund amounts' }]) // 'refunds'\n * ```\n */\nexport function renderTopicNames(topics: readonly LedgerTopic[]): string {\n\treturn topics.map((topic) => topic.name).join(', ')\n}\n\n/**\n * Renders an error and its causes, stopping after 4 entries.\n * @param error - The thrown value to describe\n * @returns The names and messages joined by a cause separator\n * @example\n * ```ts\n * renderCauseChain(new Error('refused', { cause: 'offline' })) // 'Error: refused <- offline'\n * ```\n */\nexport function renderCauseChain(error: unknown): string {\n\t// The error, then at most three causes: each step extends the chain by the last entry's cause.\n\treturn Array.from({ length: 3 })\n\t\t.reduce<readonly unknown[]>(\n\t\t\t(chain) => {\n\t\t\t\tconst last = chain.at(-1)\n\t\t\t\tconst cause = isError(last) ? last.cause : undefined\n\t\t\t\treturn cause === undefined ? chain : [...chain, cause]\n\t\t\t},\n\t\t\terror === undefined ? [] : [error],\n\t\t)\n\t\t.map((one) => (isError(one) ? `${one.name}: ${one.message}` : String(one)))\n\t\t.join(' <- ')\n}\n\n/**\n * Extracts lowercase words and capitalized names that do not open a sentence.\n * @param message - The message whose text supplies the words\n * @returns The distinct words and non-opening names\n * @example\n * ```ts\n * extractWords({ id: 'note', role: 'user', content: 'Ask Odile.' }).names // Set { 'odile' }\n * ```\n */\nexport function extractWords(message: Message): LedgerWordSet {\n\treturn {\n\t\twords: new Set(message.content.toLowerCase().match(/[\\p{L}\\p{N}]+/gu) ?? []),\n\t\tnames: new Set(\n\t\t\t[...message.content.matchAll(/(?<![\\p{L}\\p{N}'-])\\p{Lu}\\p{Ll}+(?![\\p{L}\\p{N}-])/gu)]\n\t\t\t\t.filter((match) => {\n\t\t\t\t\tconst before = message.content.slice(0, match.index).trimEnd()\n\t\t\t\t\treturn before !== '' && !/[.!?:;]$/.test(before)\n\t\t\t\t})\n\t\t\t\t.map((match) => match[0].toLowerCase()),\n\t\t),\n\t}\n}\n\n/**\n * Splits a topic part into lowercase words with surrounding punctuation removed.\n * @param part - The topic part to split\n * @returns The nonempty normalized words\n * @example\n * ```ts\n * splitWords('Refunds, BW-5512!') // ['refunds', 'bw-5512']\n * ```\n */\nexport function splitWords(part: string): readonly string[] {\n\treturn part\n\t\t.split(/\\s+/)\n\t\t.map((word) => word.replace(/^[\\p{P}\\p{S}]+|[\\p{P}\\p{S}]+$/gu, '').toLowerCase())\n\t\t.filter((word) => word !== '')\n}\n\n/**\n * Finds the call that owns a tool message within a collected tool group.\n * @param group - The assistant leader followed by its tool results\n * @param message - The tool result to pair; distinct leader ids pair by result id when any result has one\n * @returns The call matching the result's call id, or its position when the leader repeats an id or every result lacks an id; undefined when unpaired\n * @example\n * ```ts\n * findLedgerCall(group, result)?.arguments\n * ```\n */\nexport function findLedgerCall(group: readonly Message[], message: Message): ToolCall | undefined {\n\tconst [leader, ...results] = group\n\tconst at = results.findIndex((result) => result.id === message.id)\n\tif (message.role !== 'tool' || at < 0) return undefined\n\tconst calls = leader?.calls ?? []\n\tconst duplicate = new Set(calls.map((call) => call.id)).size !== calls.length\n\treturn !duplicate && results.some((result) => result.call !== undefined)\n\t\t? calls.find((call) => call.id === message.call)\n\t\t: calls[at]\n}\n\n/**\n * Ranks a briefing source for removal before the next prompt.\n *\n * @param group - The planning group: 1 for a topic match, 2 for an off-topic rule or correction, or 3 for a name match\n * @param unsettled - If `true`, the source is a user message without a decisive category; if `false`, it is another source\n * @param category - The source's recorded category, or undefined when undecided\n * @returns The ascending removal rank: name matches, unsettled sources, off-topic corrections, off-topic rules, then topic matches\n * @remarks\n * The planner removes lower ranks first. Equal ranks 0, 1, and 4 remove lower scores first;\n * every equal rank then removes later conversation positions first.\n * @example\n * ```ts\n * rankLedgerCut(2, false, 'rule') // 3\n * ```\n */\nexport function rankLedgerCut(\n\tgroup: LedgerPlanGroup,\n\tunsettled: boolean,\n\tcategory: LedgerCategory | undefined,\n): number {\n\treturn group === 3 ? 0 : unsettled ? 1 : group === 2 ? (category === 'rule' ? 3 : 2) : 4\n}\n\n/**\n * Resolves the generation cap and checks it against the context capacity.\n *\n * @param predict - The optional generation cap in tokens; see {@link LedgerOptions}\n * @param capacity - The context capacity in tokens\n * @returns The validated cap\n * @throws {LedgerError} Thrown when the cap is not a nonnegative safe integer less than capacity (code `'CAPACITY'`)\n * @example\n * ```ts\n * resolvePredict(1024, 4096) // 1024\n * ```\n */\nexport function resolvePredict(predict: number | undefined, capacity: number): number {\n\tconst resolved = predict ?? 0\n\tif (!isNonNegativeSafeInteger(resolved) || resolved >= capacity)\n\t\tthrow new LedgerError(\n\t\t\t'CAPACITY',\n\t\t\t'predict must be a nonnegative safe integer less than capacity',\n\t\t)\n\treturn resolved\n}\n\n/**\n * Computes the completion tokens attributable to a message's thinking.\n *\n * @remarks\n * Weights the completion by thinking characters divided by the combined characters of thinking,\n * content, and JSON-serialized calls. Rounds to the nearest integer and caps at the completion.\n * An empty generation yields 0. The completion must be a finite nonnegative integer token count.\n * Calls that cannot be JSON-serialized contribute 0 characters.\n *\n * @param message - The generated thinking, content, and optional calls\n * @param completion - The tokens reported for the completion\n * @returns The thinking share in tokens, or 0 when no thinking characters exist\n *\n * @example\n * ```ts\n * computeThinking({ thinking: 'plan', content: 'ok' }, 10) // 7\n * ```\n */\nexport function computeThinking(\n\tmessage: Pick<Message, 'thinking' | 'content' | 'calls'>,\n\tcompletion: number,\n): number {\n\tconst thinking = message.thinking?.length ?? 0\n\tif (thinking === 0) return 0\n\tconst calls = message.calls === undefined ? 0 : (renderJSON(message.calls)?.length ?? 0)\n\tconst generated = thinking + message.content.length + calls\n\treturn Math.min(completion, Math.round(completion * (thinking / generated)))\n}\n\n/**\n * Splits a message into its sentences.\n *\n * @remarks\n * A sentence ends at a period, question mark, or exclamation mark followed by a space and a capital\n * letter, a digit, or a quote, so a decimal point, an id, or an amount never splits one.\n *\n * @param text - The message text\n * @returns The trimmed, non-empty sentences in order\n *\n * @example\n * ```ts\n * splitSentences('Refunds over $200 need a manager. Ask Odile.')\n * // ['Refunds over $200 need a manager.', 'Ask Odile.']\n * ```\n */\nexport function splitSentences(text: string): readonly string[] {\n\treturn text\n\t\t.split(/(?<=[.!?])\\s+(?=[\\p{Lu}\\d\"'“])/u)\n\t\t.map((sentence) => sentence.trim())\n\t\t.filter((sentence) => sentence !== '')\n}\n\n/**\n * Reads the id-shaped tokens and the numbers of a text.\n *\n * @param text - The text to read\n * @returns The uppercased hyphenated ids that hold a digit, and the numbers outside those ids with grouping commas removed\n *\n * @example\n * ```ts\n * const tokens = extractTokens('Order bw-5512 totals 1,200.50')\n * // tokens.ids is Set { 'BW-5512' }, tokens.numbers is Set { 1200.5 }\n * ```\n */\nexport function extractTokens(text: string): LedgerTokenSet {\n\tconst idShape = /\\b[A-Za-z0-9]+(?:-[A-Za-z0-9]+)+\\b/g\n\tconst ids = new Set(\n\t\t[...text.matchAll(idShape)].flatMap(([token]) =>\n\t\t\t/\\d/.test(token) ? [token.toUpperCase()] : [],\n\t\t),\n\t)\n\tconst rest = text.replace(idShape, (token) => (/\\d/.test(token) ? ' ' : token))\n\tconst numbers = new Set(\n\t\t[...rest.matchAll(/(?<![\\w.])\\d[\\d,]*(?:\\.\\d+)?/g)].flatMap(([token]) => {\n\t\t\tconst value = Number(token.replace(/,/g, ''))\n\t\t\treturn Number.isFinite(value) ? [value] : []\n\t\t}),\n\t)\n\treturn { ids, numbers }\n}\n\n/**\n * Collects the capitalized name runs of a text, leaving out the run that opens each sentence.\n *\n * @remarks\n * A sentence opens with a capital whatever its first word is, so its opening run proves nothing.\n * This is the reading the person prefix of {@link buildRecords} rests on.\n *\n * @param text - The text to read\n * @returns The capitalized runs in order, repeats included\n *\n * @example\n * ```ts\n * collectNames('Odile phoned. We asked about Odile Marlow.') // ['Odile Marlow']\n * ```\n */\nexport function collectNames(text: string): readonly string[] {\n\treturn splitSentences(text).flatMap((sentence) =>\n\t\t[...sentence.matchAll(/(?<![\\p{L}\\p{N}'-])\\p{Lu}\\p{Ll}+(?: \\p{Lu}\\p{Ll}+)*(?![\\p{L}\\p{N}-])/gu)]\n\t\t\t.filter((match) => (match.index ?? 0) > 0)\n\t\t\t.map((match) => match[0]),\n\t)\n}\n\n/**\n * Normalizes a lookup argument string to the spelling that lookup identity and owner linking compare.\n *\n * @remarks\n * {@link identifyLookup} and {@link linkOwners} read an argument through this one form, so a reading\n * a later lookup replaces and the owner link of its argument agree on the spelling.\n *\n * @param value - The string argument a lookup call carried\n * @returns The argument trimmed and uppercased\n *\n * @example\n * ```ts\n * normalizeArgument(' bw-5512 ') // 'BW-5512'\n * ```\n */\nexport function normalizeArgument(value: string): string {\n\treturn value.trim().toUpperCase()\n}\n\n/**\n * Splits a tool result into its lines at each line feed, with or without a carriage return before it.\n *\n * @remarks\n * The recall listing keys each recalled line by its first line, and the answer note reads a result\n * line by line, so both read lines through this one split.\n *\n * @param text - The tool result text\n * @returns The lines in order, an empty line included; one empty line for an empty text\n *\n * @example\n * ```ts\n * splitResultLines('Account BW-20931.\\r\\nRefund is $148.50.') // ['Account BW-20931.', 'Refund is $148.50.']\n * ```\n */\nexport function splitResultLines(text: string): readonly string[] {\n\treturn text.split(/\\r\\n|\\n/)\n}\n\n/**\n * Renders a lookup call as its tool name and its JSON arguments.\n *\n * @remarks\n * The arguments keep the text `JSON.stringify` writes, key order included. Arguments JSON cannot\n * carry, such as a `BigInt` or a cycle, render the bare tool name instead of throwing.\n *\n * @param name - The lookup tool name\n * @param args - The arguments the call carried\n * @returns The tool name, a space, and the JSON arguments; the bare tool name when JSON cannot carry them\n *\n * @example\n * ```ts\n * renderLookupCall('lookup_order', { id: 'BW-5512' }) // 'lookup_order {\"id\":\"BW-5512\"}'\n * renderLookupCall('lookup_order', { count: 1n }) // 'lookup_order'\n * ```\n */\nexport function renderLookupCall(name: string, args: Readonly<Record<string, unknown>>): string {\n\tconst rendered = renderJSON(args)\n\treturn rendered === undefined ? name : `${name} ${rendered}`\n}\n\n/**\n * Identifies a lookup reading for projection by its tool name and normalized arguments.\n *\n * @remarks\n * Two calls share an identity whatever the key order of their arguments at any depth. A top-level\n * string argument passes through {@link normalizeArgument} first, so `\"lh-1 \"` and `\"LH-1\"` name one call.\n * The ledger's repeat stop instead compares the tool name and canonical arguments without this\n * string normalization, so those argument spellings remain distinct within a request.\n * An uncanonicalizable call has no identity and neither replaces nor is replaced by another reading.\n *\n * @param name - The tool name\n * @param args - The arguments the call carried\n * @returns The name, a space, and the canonical arguments, or `undefined` when uncanonicalizable\n *\n * @example\n * ```ts\n * identifyLookup('lookup_order', { id: 'bw-5512', opts: { tier: 2, region: 'north' } }) ===\n * \tidentifyLookup('lookup_order', { opts: { region: 'north', tier: 2 }, id: ' BW-5512' }) // true\n * ```\n */\nexport function identifyLookup(\n\tname: string,\n\targs: Readonly<Record<string, unknown>>,\n): string | undefined {\n\tconst normalized = Object.fromEntries(\n\t\tObject.entries(args).map(([key, value]) => [\n\t\t\tkey,\n\t\t\tisString(value) ? normalizeArgument(value) : value,\n\t\t]),\n\t)\n\tconst canonical = canonicalStringify(normalized)\n\treturn canonical === undefined ? undefined : `${name} ${canonical}`\n}\n\n/**\n * Links each id-shaped lookup argument to its owner.\n *\n * @remarks\n * An owner argument links to itself. Any other id-shaped argument links to the single owner id its\n * reading's text names. An empty reading links nothing, and a later reading overwrites an earlier\n * link of the same argument.\n *\n * @param readings - The lookup readings in conversation order\n * @param owners - The owners keyed by id\n * @returns The owner id of each linked argument id; an argument whose text names no owner or several is absent\n *\n * @example\n * ```ts\n * linkOwners(\n * \t[{ id: 'tool-1', name: 'lookup_order', arguments: { id: 'BW-5512' }, text: 'Order BW-5512 for account BW-20931.', result: { ids: [], owners: [] } }],\n * \tnew Map([['BW-20931', ['Brightwater Studio']]]),\n * ) // Map { 'BW-5512' => 'BW-20931' }\n * ```\n */\nexport function linkOwners(\n\treadings: readonly LedgerLookupReading[],\n\towners: ReadonlyMap<string, readonly string[]>,\n): ReadonlyMap<string, string> {\n\t// A later pair of the same argument overwrites an earlier one, as the `Map` constructor does. The\n\t// spread visits a hole in `readings` as an undefined reading, as iteration does; `flatMap` skips it.\n\treturn new Map(\n\t\t[...readings].flatMap((reading) => {\n\t\t\tif (reading.result === undefined) return []\n\t\t\tconst named = [...extractTokens(reading.text).ids].filter((id) => owners.has(id))\n\t\t\tconst [only] = named\n\t\t\treturn Object.values(reading.arguments)\n\t\t\t\t.filter(isString)\n\t\t\t\t.map((value) => normalizeArgument(value))\n\t\t\t\t.filter((subject) => extractTokens(subject).ids.has(subject))\n\t\t\t\t.flatMap((subject) => {\n\t\t\t\t\tif (owners.has(subject)) return [[subject, subject] as const]\n\t\t\t\t\treturn named.length === 1 && only !== undefined ? [[subject, only] as const] : []\n\t\t\t\t})\n\t\t}),\n\t)\n}\n\n/**\n * Collects the ids and the owner names the lookup readings named.\n *\n * @remarks\n * Every reading counts, a replaced one included, because an id a lookup named stays registered.\n * An empty reading names nothing. An owner name is trimmed, and a name without a letter is dropped.\n *\n * @param readings - The lookup readings in conversation order\n * @returns The registry: every id named, and each owner's names in the order read\n *\n * @example\n * ```ts\n * const registry = collectRegistry([\n * \t{ id: 'tool-1', name: 'lookup_customer', arguments: { account: 'BW-20931' }, text: 'Account BW-20931: Brightwater Studio', result: { ids: ['BW-20931'], owners: [{ id: 'BW-20931', names: ['Brightwater Studio'] }] } },\n * ])\n * // registry.owners is Map { 'BW-20931' => ['Brightwater Studio'] }\n * ```\n */\nexport function collectRegistry(readings: readonly LedgerLookupReading[]): LedgerRegistry {\n\t// The spread and `Array.from` visit a hole in `readings` or in an owner list as an undefined\n\t// entry, as iteration does; `flatMap` and `map` skip it.\n\tconst results = [...readings].flatMap((reading) =>\n\t\treading.result === undefined ? [] : [reading.result],\n\t)\n\treturn {\n\t\tids: new Set(\n\t\t\tresults.flatMap((result) => [\n\t\t\t\t...result.ids,\n\t\t\t\t...Array.from(result.owners, (owner) => owner.id),\n\t\t\t]),\n\t\t),\n\t\towners: new Map(\n\t\t\t[\n\t\t\t\t...Map.groupBy(\n\t\t\t\t\tresults.flatMap((result) => Array.from(result.owners)),\n\t\t\t\t\t(owner) => owner.id,\n\t\t\t\t),\n\t\t\t].map(([id, listed]) => [\n\t\t\t\tid,\n\t\t\t\t[\n\t\t\t\t\t...new Set(\n\t\t\t\t\t\tlisted.flatMap((owner) =>\n\t\t\t\t\t\t\towner.names.map((name) => name.trim()).filter((name) => /\\p{L}/u.test(name)),\n\t\t\t\t\t\t),\n\t\t\t\t\t),\n\t\t\t\t],\n\t\t\t]),\n\t\t),\n\t}\n}\n\n/**\n * Matches the registry ids and owners a text names.\n *\n * @remarks\n * An id counts when the text holds it as an id token. An owner counts when the text holds one of\n * its names whole. With `partial`, a capitalized name word that only one name carries also names\n * that name's owners, matched case-sensitively so a common word that spells a first name does not.\n *\n * @param registry - The registry to match against\n * @param text - The text to read\n * @param partial - If `true`, a name word only one name carries also names its owners; if `false`, only a whole name does\n * @returns The registry ids and owner ids the text names\n *\n * @example\n * ```ts\n * const registry = { ids: new Set(['BW-20931']), owners: new Map([['BW-20931', ['Brightwater Studio']]]) }\n * matchEntities(registry, 'Ask Brightwater about it', true) // Set { 'BW-20931' }\n * matchEntities(registry, 'Ask Brightwater about it', false) // Set {}\n * ```\n */\nexport function matchEntities(\n\tregistry: LedgerRegistry,\n\ttext: string,\n\tpartial: boolean,\n): ReadonlySet<string> {\n\tconst tokens = extractTokens(text).ids\n\t// `Array.from` visits a hole in an owner's names as an undefined name, as iteration does; `map` skips it.\n\tconst aliases = Map.groupBy(\n\t\t[...registry.owners].flatMap(([id, names]) => Array.from(names, (name) => ({ name, id }))),\n\t\t(entry) => entry.name,\n\t)\n\t// A word's carriers are the distinct names it appears in.\n\tconst carriers = Map.groupBy(\n\t\t[...aliases.keys()].flatMap((name) => [...new Set(name.split(/\\s+/))]),\n\t\t(word) => word,\n\t)\n\treturn new Set([\n\t\t...[...registry.ids].filter((id) => tokens.has(id)),\n\t\t...[...aliases].flatMap(([name, entries]) => {\n\t\t\tconst words = partial\n\t\t\t\t? name\n\t\t\t\t\t\t.split(/\\s+/)\n\t\t\t\t\t\t.filter((word) => /^\\p{Lu}\\p{L}+$/u.test(word) && carriers.get(word)?.length === 1)\n\t\t\t\t: []\n\t\t\tconst needles = [\n\t\t\t\t{ needle: name, flags: 'iu' },\n\t\t\t\t...words.map((word) => ({ needle: word, flags: 'u' })),\n\t\t\t]\n\t\t\tconst named = needles.some(({ needle, flags }) => {\n\t\t\t\tconst escaped = needle.replace(/[.*+?^$()|{}[\\]\\\\]/g, '\\\\$&')\n\t\t\t\treturn new RegExp(`(?<![\\\\p{L}\\\\p{N}])${escaped}(?![\\\\p{L}\\\\p{N}])`, flags).test(text)\n\t\t\t})\n\t\t\treturn named ? entries.map((entry) => entry.id) : []\n\t\t}),\n\t])\n}\n\n/**\n * Projects the owner records and the rules record from a conversation's messages.\n *\n * @remarks\n * Each line is a sentence of a live message, verbatim except that a sentence that opens with a pronoun opens with its party and a colon. A message is live when it is a user message,\n * or a tool message whose reading is the last reading of its call, and the input neither excludes it nor\n * files it quiet or replaced. A reading with an undefined `result` still replaces the earlier\n * reading of the same call, so the earlier result leaves every record.\n *\n * A live message joins the owner records its entities name, directly or through a linked lookup\n * argument. A message that names no owner joins where its earlier side of an amendment pair joins,\n * or on the rules record when it is filed as a rule or a correction, and is an orphan otherwise.\n *\n * Every live sentence is retained. Accepted direct edges are listed in `amendments`. An amending message\n * that is itself superseded retains its accepted edge without restoring its text.\n *\n * A sentence that opens with a pronoun takes the party named in the sentence before it. The reading\n * trusts capitals, so a capitalized word that is no person, such as a carrier named mid-sentence,\n * is read as the party. This is a documented limit: the prefix carries\n * the follow-up facts the records exist for.\n *\n * @param input - The messages, readings, entities, and classification to project\n * @returns The records with owner records ordered by their first member and the rules record last, the accepted amendments, and the live message ids no record placed\n *\n * @example\n * ```ts\n * const projection = buildRecords({\n * \tsystem: 'You staff the desk.',\n * \texclusions: [],\n * \towners: new Map([['BW-20931', ['Brightwater Studio']]]),\n * \tmessages: [{ id: 'user-1', role: 'user', content: 'Brightwater Studio asked for a refund.' }],\n * \treadings: [],\n * \tentities: new Map([['user-1', ['BW-20931']]]),\n * \tclassification: { quiet: new Set(), categories: new Map(), topics: new Map(), amendments: new Map(), supersessions: new Map() },\n * })\n * // projection.records[0].title === 'Brightwater Studio (account BW-20931)'\n * ```\n */\nexport function buildRecords(input: LedgerProjectionInput): LedgerProjection {\n\tconst position = new Map(input.messages.map((message, at) => [message.id, at]))\n\tconst byId = new Map(input.messages.map((message) => [message.id, message]))\n\tconst live = collectLive(input)\n\tconst links = linkOwners(input.readings, input.owners)\n\tconst amending = new Map(\n\t\t[\n\t\t\t...Map.groupBy(\n\t\t\t\t[...input.classification.amendments].flatMap(([earlier, laters]) =>\n\t\t\t\t\tlaters.map((later) => ({ earlier, later })),\n\t\t\t\t),\n\t\t\t\t(pair) => pair.later,\n\t\t\t),\n\t\t].map(([later, pairs]) => [later, pairs.map((pair) => pair.earlier)]),\n\t)\n\tconst amendments = collectAmendments(input, byId, live)\n\tconst holders = [...input.owners.values()].flat()\n\tconst system = collectNames(input.system)\n\t// The memo belongs to this projection alone: `placeMember` inserts each placement once.\n\tconst settled = new Map<string, ReadonlySet<string>>()\n\tconst placements = live.map((id) => ({\n\t\tid,\n\t\tkeys: placeMember(input, links, amending, id, new Set(), settled),\n\t}))\n\tconst orphans = placements.filter((placement) => placement.keys.size === 0).map(({ id }) => id)\n\tconst members = Map.groupBy(\n\t\tplacements.flatMap(({ id, keys }) => [...keys].map((key) => ({ key, id }))),\n\t\t(entry) => entry.key,\n\t)\n\tconst records = [...members]\n\t\t.map(([key, entries]) => {\n\t\t\tconst ids = entries.map((entry) => entry.id)\n\t\t\tconst lines = ids.flatMap((id) => buildLines(input, byId, id, holders, system))\n\t\t\tconst owner = key.slice(LEDGER_OWNER_PREFIX.length)\n\t\t\tconst holder = input.owners.get(owner)?.[0]\n\t\t\tconst title =\n\t\t\t\tkey === LEDGER_RULES_KEY\n\t\t\t\t\t? 'Rules'\n\t\t\t\t\t: holder === undefined\n\t\t\t\t\t\t? `account ${owner}`\n\t\t\t\t\t\t: `${holder} (account ${owner})`\n\t\t\tconst first = position.get(ids[0] ?? '') ?? 0\n\t\t\treturn {\n\t\t\t\tfirst,\n\t\t\t\trecord: {\n\t\t\t\t\tkey,\n\t\t\t\t\ttitle,\n\t\t\t\t\tmembers: ids,\n\t\t\t\t\tlines,\n\t\t\t\t} satisfies LedgerRecord,\n\t\t\t}\n\t\t})\n\t\t.sort(\n\t\t\t(left, right) =>\n\t\t\t\tNumber(left.record.key === LEDGER_RULES_KEY) -\n\t\t\t\t\tNumber(right.record.key === LEDGER_RULES_KEY) ||\n\t\t\t\tleft.first - right.first ||\n\t\t\t\t(left.record.key < right.record.key ? -1 : left.record.key > right.record.key ? 1 : 0),\n\t\t)\n\t\t.map(({ record }) => record)\n\treturn { records, amendments, orphans }\n}\n\n/**\n * Selects a request's records, collapsing owners with equal ordered member ids under titles joined with `; `.\n *\n * @remarks\n * The view holds the owner records the request names in the order it names them, then the rules\n * record with the lines whose topics meet the request's first, each group in position order. The\n * returned records and lines are copies. Owner records with the same member ids in the same order\n * collapse into the first requested record, keeping its key, members, and lines and joining their\n * titles with `; ` before trimming.\n *\n * @param projection - The output of {@link buildRecords}\n * @param request - The owners and the desk topics the request names\n * @returns The selected records; an owner with no record yields none\n *\n * @example\n * ```ts\n * selectRecords(projection, { owners: ['BW-20931'], topics: ['refunds'] }).map((record) => record.key)\n * // ['owner:BW-20931', 'rules']\n * ```\n */\nexport function selectRecords(\n\tprojection: LedgerProjection,\n\trequest: LedgerProjectionRequest,\n): readonly LedgerRecord[] {\n\tconst topics = new Set(request.topics)\n\tconst rules = projection.records.find((one) => one.key === LEDGER_RULES_KEY)\n\t// Lines that meet a request topic lead; each side keeps its position order. `groupBy` visits a\n\t// hole in `lines` as an undefined line, as iteration does; `filter` skips it.\n\tconst sides = Map.groupBy(\n\t\t(rules?.lines ?? []).filter(() => true),\n\t\t(line) => line.topics.some((topic) => topics.has(topic)),\n\t)\n\tconst owners = [...new Set(request.owners)].flatMap((owner) => {\n\t\tconst record = projection.records.find((one) => one.key === `${LEDGER_OWNER_PREFIX}${owner}`)\n\t\treturn record === undefined ? [] : [record]\n\t})\n\tconst groups = Map.groupBy(owners, (record) => JSON.stringify(record.members))\n\treturn [\n\t\t...[...groups.values()].flatMap(([record, ...rest]) =>\n\t\t\trecord === undefined\n\t\t\t\t? []\n\t\t\t\t: [\n\t\t\t\t\t\tstructuredClone({\n\t\t\t\t\t\t\t...record,\n\t\t\t\t\t\t\ttitle: [record.title, ...rest.map((one) => one.title)].join('; '),\n\t\t\t\t\t\t}),\n\t\t\t\t\t],\n\t\t),\n\t\t...(rules === undefined\n\t\t\t? []\n\t\t\t: [\n\t\t\t\t\tstructuredClone({\n\t\t\t\t\t\t...rules,\n\t\t\t\t\t\tlines: [...(sides.get(true) ?? []), ...(sides.get(false) ?? [])],\n\t\t\t\t\t}),\n\t\t\t\t]),\n\t]\n}\n\n/**\n * Renders one record as a heading and one list item per line.\n *\n * @remarks\n * The briefing joins rendered records with one blank line.\n *\n * @param record - A record or view with a `title` and `lines`\n * @param context - Rendering facts for optional accepted amendment annotations\n * @returns `## TITLE` followed by `- LINE` for each line\n *\n * @example\n * ```ts\n * renderLedgerRecord({ title: 'Rules', lines: [{ text: 'Refunds need a manager.', source: 'user-1', sentence: 0, topics: [], role: 'user' }] })\n * // '## Rules\\n- Refunds need a manager.'\n * ```\n */\nexport function renderLedgerRecord(\n\trecord: Pick<LedgerRecord, 'title' | 'lines'>,\n\tcontext?: LedgerRenderContext,\n): string {\n\treturn [\n\t\t`## ${record.title}`,\n\t\t...record.lines.flatMap((line) =>\n\t\t\t[context === undefined ? '' : renderLedgerAnnotation(line, context), `- ${line.text}`].filter(\n\t\t\t\t(text) => text !== '',\n\t\t\t),\n\t\t),\n\t].join('\\n')\n}\n\n/**\n * Renders one owner record under a `###` heading, which the briefing nests under its one `## Pinned` heading.\n *\n * @param record - An owner record or view with a `title` and `lines`\n * @param context - Rendering facts for optional accepted amendment annotations\n * @returns `### TITLE` followed by `- LINE` for each line\n *\n * @example\n * ```ts\n * renderLedgerPinned({ title: 'Odile Marlow (account OM-30418)', lines: [] }) // '### Odile Marlow (account OM-30418)'\n * ```\n */\nexport function renderLedgerPinned(\n\trecord: Pick<LedgerRecord, 'title' | 'lines'>,\n\tcontext?: LedgerRenderContext,\n): string {\n\treturn `#${renderLedgerRecord(record, context)}`\n}\n\n/**\n * Derives complete source identities, first occurrences, and local references from the actual briefing lines.\n * @param messages - Original messages whose indexed sentences establish completeness\n * @param lines - Retained lines in rendering order after deduplication and trimming\n * @param amendments - Accepted direct message amendment edges\n * @returns Immutable rendering facts for this retained population\n *\n * @example\n * ```ts\n * buildLedgerRenderContext([], [], []).complete.size // 0\n * ```\n */\nexport function buildLedgerRenderContext(\n\tmessages: readonly Message[],\n\tlines: readonly LedgerLine[],\n\tamendments: readonly LedgerAmendment[],\n): LedgerRenderContext {\n\tconst identities = new Set(lines.map((line) => `${line.source} ${line.sentence}`))\n\treturn {\n\t\tamendments,\n\t\tcomplete: new Set(\n\t\t\tmessages\n\t\t\t\t.filter((message) => {\n\t\t\t\t\tconst sentences = splitSentences(message.content)\n\t\t\t\t\treturn (\n\t\t\t\t\t\tsentences.length > 0 &&\n\t\t\t\t\t\tsentences.every((_, index) => identities.has(`${message.id} ${index}`))\n\t\t\t\t\t)\n\t\t\t\t})\n\t\t\t\t.map((message) => message.id),\n\t\t),\n\t\tfirst: new Map(lines.toReversed().map((line) => [line.source, line])),\n\t\treferences: new Map(\n\t\t\t[...new Set(lines.map((line) => line.source))].map((source, index) => [\n\t\t\t\tsource,\n\t\t\t\tString(index + 1),\n\t\t\t]),\n\t\t),\n\t}\n}\n\n/**\n * Renders source framing and unresolved amendment scope at a source's first retained line.\n * @param line - The retained occurrence to annotate\n * @param context - Actual complete sources, first occurrences, local references, and accepted amendment edges\n * @returns Source framing and truthful inclusion notes, or empty text for an unrelated or repeated occurrence\n * @throws {LedgerError} Thrown when the context holds no reference for the annotated source or a fully included amender (code `'REQUEST'`)\n *\n * @example\n * ```ts\n * renderLedgerAnnotation({ text: 'Unchanged.', source: 'user-1', sentence: 0, topics: [], role: 'user' }, buildLedgerRenderContext([], [], [])) // ''\n * ```\n */\nexport function renderLedgerAnnotation(line: LedgerLine, context: LedgerRenderContext): string {\n\tif (context.first.get(line.source) !== line) return ''\n\tconst amendments = context.amendments.filter((pair) => pair.earlier === line.source)\n\tconst endpoint =\n\t\tcontext.complete.has(line.source) &&\n\t\tcontext.amendments.some((pair) => pair.later === line.source && context.first.has(pair.earlier))\n\tif (amendments.length === 0 && !endpoint) return ''\n\tconst included = amendments.filter((pair) => context.complete.has(pair.later))\n\tif (\n\t\tcontext.references.get(line.source) === undefined ||\n\t\tincluded.some((pair) => context.references.get(pair.later) === undefined)\n\t)\n\t\tthrow new LedgerError('REFERENCE', 'Ledger rendering requires retained source references')\n\treturn [\n\t\t`[Ledger source ${context.references.get(line.source)}]`,\n\t\t...included.map(\n\t\t\t(pair) =>\n\t\t\t\t`Accepted later amendment [Ledger source ${context.references.get(pair.later)}] is fully included in this briefing. Sentence scope is unresolved.`,\n\t\t),\n\t\t...(amendments.some((pair) => !context.complete.has(pair.later))\n\t\t\t? [\n\t\t\t\t\t'Accepted later amendment text is not fully included in this briefing. Sentence scope is unresolved.',\n\t\t\t\t]\n\t\t\t: []),\n\t].join('\\n')\n}\n\n/**\n * Splits a recall topic at its joints.\n *\n * @remarks\n * The joints are a comma, a semicolon, a slash, and the word `and`. A topic with no joint is\n * returned whole, so a model that joins a name and an id recalls each part alone.\n *\n * @param topic - The topic the model asked for\n * @returns The trimmed, non-empty parts when there are at least 2; otherwise the topic itself\n *\n * @example\n * ```ts\n * splitTopic('BW-5512, Odile Marlow and refunds') // ['BW-5512', 'Odile Marlow', 'refunds']\n * ```\n */\nexport function splitTopic(topic: string): readonly string[] {\n\tconst parts = topic\n\t\t.split(/\\s*[,;/]\\s*|\\s+and\\s+/i)\n\t\t.map((part) => part.trim())\n\t\t.filter((part) => part !== '')\n\treturn parts.length > 1 ? parts : [topic]\n}\n\n/**\n * Cuts entries to a room and names how many it left out.\n *\n * @remarks\n * The cut keeps at least one entry. When it leaves entries out, its last line reads\n * `N older items not shown; name a narrower topic to narrow the recall`, which\n * {@link matchesCutLine} recognizes.\n *\n * @param entries - The entries in the order they are kept\n * @param room - The estimate units the joined entries can take\n * @returns The kept entries followed by the cut line when any were left out, joined by newlines\n *\n * @example\n * ```ts\n * cutListing(['first entry', 'second entry'], 1) // 'first entry\\n1 older item not shown; name a narrower topic to narrow the recall'\n * ```\n */\nexport function cutListing(entries: readonly string[], room: number): string {\n\t// The cut keeps at least one entry, and stops at the first entry whose addition passes the room.\n\tconst stop = [...entries.keys()].findIndex(\n\t\t(at) =>\n\t\t\tat > 0 &&\n\t\t\testimateMessages([\n\t\t\t\t{\n\t\t\t\t\tid: 'recall',\n\t\t\t\t\trole: 'tool',\n\t\t\t\t\tcontent: entries.slice(0, at + 1).join('\\n'),\n\t\t\t\t},\n\t\t\t]) > room,\n\t)\n\tconst kept = entries.slice(0, stop === -1 ? undefined : stop)\n\tconst left = entries.length - kept.length\n\treturn [\n\t\t...kept,\n\t\t...(left > 0\n\t\t\t? [\n\t\t\t\t\t`${left} older item${left === 1 ? '' : 's'} not shown; name a narrower topic to narrow the recall`,\n\t\t\t\t]\n\t\t\t: []),\n\t].join('\\n')\n}\n\n/**\n * Checks whether a line is the cut line {@link cutListing} writes.\n *\n * @param line - The line to check\n * @returns True if the line is a cut line; false otherwise\n *\n * @example\n * ```ts\n * matchesCutLine('2 older items not shown; name a narrower topic to narrow the recall') // true\n * ```\n */\nexport function matchesCutLine(line: string): boolean {\n\treturn /^\\d+ older items? not shown; /.test(line)\n}\n\n/**\n * Renders the tail stub of a lookup result from an earlier request.\n *\n * @param name - The lookup tool name\n * @param args - The arguments the call carried; arguments JSON cannot carry leave the call as its bare tool name, per {@link renderLookupCall}\n * @param state - What became of the result: `failed`, `empty`, `shown` in the briefing, or `hidden` from it\n * @returns The stub text, which carries the call and its state\n *\n * @example\n * ```ts\n * renderStub('lookup_order', { id: 'BW-5512' }, 'hidden')\n * // 'lookup_order {\"id\":\"BW-5512\"}: result not shown; call recall with BW-5512'\n * ```\n */\nexport function renderStub(\n\tname: string,\n\targs: Readonly<Record<string, unknown>>,\n\tstate: LedgerLookupState,\n): string {\n\tconst head = renderLookupCall(name, args)\n\tif (state === 'failed') return `${head}: failed`\n\tif (state === 'empty') return `${head}: no record`\n\tif (state === 'shown') return `${head}: result shown under Pinned in the system message`\n\tconst id = Object.values(args).find(isString)\n\treturn `${head}: result not shown; call recall with ${(id ?? '').trim() || 'its id'}`\n}\n\n/**\n * Fits the marginal tokens one estimate unit adds within a request.\n *\n * @remarks\n * The fit is the least-squares slope of prompt tokens over estimate, taken within each set of calls\n * that advertised the same number of tools and pooled over every group. The estimate counts no tool\n * schema, so a pooled fit across tool counts would read the dropped schemas as a falling rate.\n *\n * @param groups - The calls of each request\n * @returns The slope, or undefined when no set holds 2 calls with a prompt count and an estimate that differ\n *\n * @example\n * ```ts\n * fitSlope([[{ estimate: 100, prompt: 130, tools: 2 }, { estimate: 200, prompt: 260, tools: 2 }]]) // 1.3\n * ```\n */\nexport function fitSlope(groups: ReadonlyArray<readonly GaugeCall[]>): number | undefined {\n\t// The spread visits a hole in `groups` as an undefined group, as iteration does; `flatMap` skips it.\n\tconst terms = [...groups].flatMap((group) =>\n\t\t[...Map.groupBy(group, (call) => call.tools).values()].flatMap((set) => {\n\t\t\tconst points = set.flatMap((call) =>\n\t\t\t\tisFiniteNumber(call.prompt) && call.estimate > 0\n\t\t\t\t\t? [{ estimate: call.estimate, prompt: call.prompt }]\n\t\t\t\t\t: [],\n\t\t\t)\n\t\t\tif (points.length < 2) return []\n\t\t\tconst meanX = points.reduce((sum, point) => sum + point.estimate, 0) / points.length\n\t\t\tconst meanY = points.reduce((sum, point) => sum + point.prompt, 0) / points.length\n\t\t\treturn points.map((point) => ({\n\t\t\t\tspread: (point.estimate - meanX) ** 2,\n\t\t\t\tproduct: (point.estimate - meanX) * (point.prompt - meanY),\n\t\t\t}))\n\t\t}),\n\t)\n\tconst spread = terms.reduce((sum, term) => sum + term.spread, 0)\n\tconst product = terms.reduce((sum, term) => sum + term.product, 0)\n\treturn spread > 0 ? product / spread : undefined\n}\n\n/**\n * Collects the ids of the live messages in conversation order.\n *\n * @remarks\n * A message is live when it is a user message, or a tool message whose reading is the last reading of its\n * call, and the input neither excludes it nor files it quiet or replaced. A reading replaces any\n * earlier reading of the same call, an empty one included, so an empty lookup leaves the earlier\n * result out of every record. A reading with no canonical identity stays live as its own source\n * and participates in no replacement.\n *\n * @param input - The messages, readings, and classification to read\n * @returns The live message ids\n *\n * @example\n * ```ts\n * collectLive(input) // ['user-1', 'tool-2']\n * ```\n */\nexport function collectLive(input: LedgerProjectionInput): readonly string[] {\n\tconst { classification } = input\n\tconst excluded = new Set(input.exclusions)\n\tconst position = new Map(input.messages.map((message, at) => [message.id, at]))\n\tconst readings = input.readings.filter((reading) => position.has(reading.id))\n\tconst identities = new Map(\n\t\treadings.map((reading) => [reading.id, identifyLookup(reading.name, reading.arguments)]),\n\t)\n\tconst current = new Set(\n\t\treadings\n\t\t\t.filter(\n\t\t\t\t(reading) =>\n\t\t\t\t\treading.result !== undefined &&\n\t\t\t\t\t!readings.some(\n\t\t\t\t\t\t(later) =>\n\t\t\t\t\t\t\tidentities.get(reading.id) !== undefined &&\n\t\t\t\t\t\t\t(position.get(later.id) ?? -1) > (position.get(reading.id) ?? -1) &&\n\t\t\t\t\t\t\tidentities.get(later.id) === identities.get(reading.id),\n\t\t\t\t\t),\n\t\t\t)\n\t\t\t.map((reading) => reading.id),\n\t)\n\treturn [...new Map(input.messages.map((message) => [message.id, message])).values()]\n\t\t.filter(\n\t\t\t(message) => message.role === 'user' || (message.role === 'tool' && current.has(message.id)),\n\t\t)\n\t\t.map((message) => message.id)\n\t\t.filter(\n\t\t\t(id) =>\n\t\t\t\t!excluded.has(id) &&\n\t\t\t\t!classification.quiet.has(id) &&\n\t\t\t\t(classification.supersessions.get(id) ?? []).length === 0,\n\t\t)\n}\n\n/**\n * Places a message on the record keys it joins.\n *\n * @remarks\n * A message joins the owner records its entities name, directly or through a linked lookup argument.\n * A message that names no owner joins where the earlier side of its amendment pair joins, and a\n * message with no earlier side joins the rules record when it is filed as a rule or a correction.\n * A message that is not live still places, because a correction joins where its earlier side would\n * join.\n *\n * With `settled`, the walk returns a placement the map holds without walking again, and records each\n * placement whose walk, its nested walks included, excluded no earlier side through `seen`. Such a\n * walk reaches no cycle. While every `seen` holds only the path that reached the message, as\n * {@link buildRecords} passes it, that path never holds a message the recorded walk reached, so a\n * fresh walk returns the same keys in the same order. A placement a cycle cut stays unrecorded,\n * because its keys depend on the path that reached it. Sharing one map across the members of one\n * input bounds a dense amendment graph to one walk per message.\n *\n * @param input - The owners, entities, and classification to read\n * @param links - The owner of each linked lookup argument, from {@link linkOwners}\n * @param amending - The earlier sides of each message's amendment pairs\n * @param id - The message id\n * @param seen - The ids already visited, which stops a cycle of amendment pairs\n * @param settled - The placements already walked for the same `input`, `links`, and `amending`; the walk adds to it. Default: no map, so every call walks\n * @returns The record keys, empty when the message is an orphan\n *\n * @example\n * ```ts\n * placeMember(input, new Map(), new Map(), 'user-1', new Set()) // Set { 'owner:BW-20931' }\n * ```\n */\nexport function placeMember(\n\tinput: LedgerProjectionInput,\n\tlinks: ReadonlyMap<string, string>,\n\tamending: ReadonlyMap<string, readonly string[]>,\n\tid: string,\n\tseen: ReadonlySet<string>,\n\tsettled?: Map<string, ReadonlySet<string>>,\n): ReadonlySet<string> {\n\tconst known = settled?.get(id)\n\tif (known !== undefined) return known\n\tconst owners = (input.entities.get(id) ?? []).flatMap((entity) => {\n\t\tconst owner = input.owners.has(entity) ? entity : links.get(entity)\n\t\treturn owner === undefined ? [] : [`${LEDGER_OWNER_PREFIX}${owner}`]\n\t})\n\tconst owned = owners.length > 0\n\tconst sides = owned ? [] : (amending.get(id) ?? []).filter((side) => side !== id)\n\tconst earlier = sides.filter((side) => !seen.has(side))\n\tconst category = input.classification.categories.get(id)\n\tconst ruled =\n\t\t!owned && earlier.length === 0 && category !== undefined && PLACED_CATEGORIES.includes(category)\n\tconst keys = new Set([\n\t\t...owners,\n\t\t...earlier.flatMap((side) => [\n\t\t\t...placeMember(input, links, amending, side, new Set([...seen, id]), settled),\n\t\t]),\n\t\t...(ruled ? [LEDGER_RULES_KEY] : []),\n\t])\n\tif (\n\t\tsettled !== undefined &&\n\t\tearlier.length === sides.length &&\n\t\tearlier.every((side) => settled.has(side))\n\t)\n\t\tsettled.set(id, keys)\n\treturn keys\n}\n\n/**\n * Collects accepted direct amendments of live messages.\n *\n * @remarks\n * An accepted edge relates an earlier live message to an amender without claiming which sentences\n * changed. An amender takes effect while live and retains its edge after another message supersedes\n * it, without restoring the superseded text. An excluded or quiet user or tool message has no effect.\n *\n * @param input - The exclusions and classification to read\n * @param byId - The messages by id\n * @param live - The live message ids from {@link collectLive}\n * @returns The distinct accepted direct edges in conversation order\n *\n * @example\n * ```ts\n * collectAmendments(input, byId, ['user-1', 'user-3']) // [{ earlier: 'user-1', later: 'user-3' }]\n * ```\n */\nexport function collectAmendments(\n\tinput: LedgerProjectionInput,\n\tbyId: ReadonlyMap<string, Message>,\n\tlive: readonly string[],\n): readonly LedgerAmendment[] {\n\tconst { classification } = input\n\tconst excluded = new Set(input.exclusions)\n\tconst living = new Set(live)\n\tconst ordered = [...new Set(input.messages.map((message) => message.id))]\n\tconst positions = new Map(ordered.map((id, index) => [id, index]))\n\tconst effective = new Set([\n\t\t...live,\n\t\t...[...byId.values()]\n\t\t\t.filter(\n\t\t\t\t(message) =>\n\t\t\t\t\tmessage.role !== 'assistant' &&\n\t\t\t\t\t!excluded.has(message.id) &&\n\t\t\t\t\t!classification.quiet.has(message.id) &&\n\t\t\t\t\t(classification.supersessions.get(message.id) ?? []).length > 0,\n\t\t\t)\n\t\t\t.map((message) => message.id),\n\t])\n\treturn ordered\n\t\t.filter((id) => living.has(id))\n\t\t.flatMap((earlier) =>\n\t\t\t[...new Set(classification.amendments.get(earlier) ?? [])]\n\t\t\t\t.filter((later) => effective.has(later) && positions.has(later))\n\t\t\t\t.sort((a, b) => (positions.get(a) ?? 0) - (positions.get(b) ?? 0))\n\t\t\t\t.map((later) => ({ earlier, later })),\n\t\t)\n}\n\n/**\n * Builds the record lines of one message.\n *\n * @remarks\n * Each original indexed sentence becomes a line. A sentence that opens with a pronoun and follows\n * another sentence takes the last name of the sentence before it that is neither an owner name nor\n * a system name, and its line text opens with that party and a colon.\n *\n * @param input - The classification whose topics the lines carry\n * @param byId - The messages by id\n * @param id - The message id\n * @param holders - The owner names, which never serve as a party\n * @param system - The system text's names, which never serve as a party\n * @returns The lines in sentence order; empty when the message is absent\n *\n * @example\n * ```ts\n * buildLines(input, byId, 'user-1', [], []).map((line) => line.text)\n * // ['Odile Marlow phoned about BW-5512.', 'Odile Marlow: She wants a refund.']\n * ```\n */\nexport function buildLines(\n\tinput: LedgerProjectionInput,\n\tbyId: ReadonlyMap<string, Message>,\n\tid: string,\n\tholders: readonly string[],\n\tsystem: readonly string[],\n): readonly LedgerLine[] {\n\tconst message = byId.get(id)\n\tif (message === undefined) return []\n\tconst sentences = splitSentences(message.content)\n\tconst topics = input.classification.topics.get(id) ?? []\n\treturn sentences.flatMap((sentence, at) => {\n\t\tconst party =\n\t\t\t/^(?:He|She|They|His|Her|Their)(?![\\p{L}\\p{N}])/u.test(sentence) && at > 0\n\t\t\t\t? collectNames(sentences[at - 1] ?? '')\n\t\t\t\t\t\t.filter((name) => !holders.includes(name) && !system.includes(name))\n\t\t\t\t\t\t.at(-1)\n\t\t\t\t: undefined\n\t\tconst line = {\n\t\t\ttext: party === undefined ? sentence : `${party}: ${sentence}`,\n\t\t\tsource: id,\n\t\t\tsentence: at,\n\t\t\ttopics: [...topics],\n\t\t\trole: message.role,\n\t\t}\n\t\treturn [party === undefined ? line : { ...line, party }]\n\t})\n}\n","import type { ChoiceAnswer, Judgment, JudgmentInput, Message } from '../types.js'\nimport type {\n\tClassifierInterface,\n\tClassifierOptions,\n\tClassifierPhase,\n\tClassifierReading,\n\tClassifierResult,\n\tLedgerCategory,\n\tLedgerClassification,\n\tLedgerTopic,\n} from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport { isArray, isError, isString, parseJSONAs } from '@orkestrel/contract'\nimport { errorToMessage } from '@orkestrel/workflow'\nimport { isJudgeAbortError } from '../errors.js'\nimport { matchesJudgment, renderJSON, sumUsage } from '../helpers.js'\nimport { isJudgeError } from '../providers/errors.js'\nimport {\n\tDECISIVE_CATEGORIES,\n\tDETERMINISTIC_JUDGE_ERROR,\n\tLEDGER_CATEGORIES,\n\tQUIET_CATEGORIES,\n} from './constants.js'\nimport { extractTokens, renderCauseChain } from './helpers.js'\n\n/**\n * Files messages through the conversation's judgment manager and reads their categories and corrections.\n *\n * @example\n * ```ts\n * const classifier = new Classifier(options)\n * await classifier.classify(new Set(), signal)\n * const filing = classifier.classification()\n * ```\n */\nexport class Classifier implements ClassifierInterface {\n\treadonly #options: ClassifierOptions\n\treadonly #failed = new Set<string>()\n\n\t/**\n\t * Creates the filing engine with the ledger's handlers and calibrated questions.\n\t * @param options - The conversation, judge, questions, cutoffs, and handlers\n\t */\n\tconstructor(options: ClassifierOptions) {\n\t\tthis.#options = options\n\t}\n\n\t/**\n\t * Asks the judge every question the filing still lacks, in the measured order.\n\t * @param requests - The request ids, which skip category questions and receive only enabled request-topic questions\n\t * @param signal - The caller's signal; an abort returns a fault with completed judgments and usage\n\t * @returns The judgment keys, summed usage, and one reading per logical question attempt, in asking order; a throw from the assign or entities handler, or a caller abort, returns the partial result with `fault`; a judge rejection under a live signal leaves that question undecided and sets no `fault`\n\t */\n\tasync classify(requests: ReadonlySet<string>, signal: AbortSignal): Promise<ClassifierResult> {\n\t\tconst results: ClassifierResult[] = []\n\t\tconst fault = await this.#gather(requests, signal, results).then(\n\t\t\t(): Error | undefined => undefined,\n\t\t\t(error: unknown) => (isError(error) ? error : new Error(errorToMessage(error))),\n\t\t)\n\t\tconst usage = results.reduce<TokenUsage | undefined>(\n\t\t\t(total, result) => (result.usage === undefined ? total : sumUsage(total, result.usage)),\n\t\t\tundefined,\n\t\t)\n\t\treturn {\n\t\t\tjudgments: results.flatMap((result) => result.judgments),\n\t\t\treadings: results.flatMap((result) => result.readings),\n\t\t\t...(fault === undefined ? {} : { fault }),\n\t\t\t...(usage === undefined ? {} : { usage }),\n\t\t}\n\t}\n\n\t/**\n\t * Reads the category a message is filed under.\n\t * @param id - The message id\n\t * @returns The assigned category, the recorded category at the cutoff, or `undefined`\n\t */\n\tcategory(id: string): LedgerCategory | undefined {\n\t\tconst message = this.#options.conversation.message(id)\n\t\tif (message === undefined) return undefined\n\t\tconst assigned = this.#options.assign(message)\n\t\tif (assigned !== undefined) return assigned\n\t\tconst answer = this.#readCategories(id)\n\t\tconst cutoff = this.#options.thresholds.category\n\t\tconst candidates = Object.entries(answer?.probabilities ?? {}).flatMap(\n\t\t\t([option, probability]) => {\n\t\t\t\tconst category = LEDGER_CATEGORIES.find((candidate) => candidate === option)\n\t\t\t\treturn category !== undefined && probability >= cutoff ? [{ category, probability }] : []\n\t\t\t},\n\t\t)\n\t\t// The first category with the highest probability wins a tie.\n\t\treturn candidates.reduce<{ category: LedgerCategory; probability: number } | undefined>(\n\t\t\t(best, candidate) =>\n\t\t\t\tbest === undefined || candidate.probability > best.probability ? candidate : best,\n\t\t\tundefined,\n\t\t)?.category\n\t}\n\n\t/**\n\t * Reports whether a message files under a quiet category.\n\t * @param id - The message id\n\t * @returns True if the assigned or recorded category is quiet; false otherwise.\n\t */\n\tquiet(id: string): boolean {\n\t\tconst message = this.#options.conversation.message(id)\n\t\tif (message === undefined) return false\n\t\tconst assigned = this.#options.assign(message)\n\t\tif (assigned !== undefined) return QUIET_CATEGORIES.includes(assigned)\n\t\treturn this.#weigh(id, QUIET_CATEGORIES) >= this.#options.thresholds.category\n\t}\n\n\t/**\n\t * Reports whether a message files under a decisive category.\n\t * @param id - The message id\n\t * @returns True if the recorded decisive weight reaches the category cutoff; false otherwise.\n\t */\n\tdecisive(id: string): boolean {\n\t\treturn this.#weigh(id, DECISIVE_CATEGORIES) >= this.#options.thresholds.category\n\t}\n\n\t/**\n\t * Reads the topics a message concerns.\n\t * @param id - The message id\n\t * @returns The names of the topics whose recorded weight reaches the topic cutoff\n\t */\n\ttopics(id: string): ReadonlySet<string> {\n\t\tconst message = this.#options.conversation.message(id)\n\t\t// The spread visits a hole in the topic list as an undefined topic, as iteration does; `filter` skips it.\n\t\treturn new Set(\n\t\t\tmessage === undefined\n\t\t\t\t? []\n\t\t\t\t: [...this.#options.topics]\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(topic) =>\n\t\t\t\t\t\t\t\t(this.#readNoul(this.#buildTopic(id, topic)) ?? 0) >=\n\t\t\t\t\t\t\t\tthis.#options.thresholds.topic,\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.map((topic) => topic.name),\n\t\t)\n\t}\n\n\t/**\n\t * Reads the whole filing from the recorded judgments.\n\t * @returns The quiet ids, categories, topics, and the amendment and supersession marks\n\t */\n\tclassification(): LedgerClassification {\n\t\tconst messages = this.#options.conversation.messages()\n\t\tconst positions = new Map(messages.map((message, at) => [message.id, at]))\n\t\t// Each message files in HEAD's call order: quiet, then category, then topics.\n\t\tconst filed = messages.map((message) => ({\n\t\t\tid: message.id,\n\t\t\tquiet: this.quiet(message.id),\n\t\t\tcategory: this.category(message.id),\n\t\t\ttopics: [...this.topics(message.id)],\n\t\t}))\n\t\tconst pairs = this.#options.conversation.judgments.judgments().flatMap((judgment) => {\n\t\t\tconst key = parseJSONAs(judgment.id, isArray)\n\t\t\tif (key === undefined) return []\n\t\t\tconst [head, earlier, later] = key\n\t\t\tif ((head !== 'amends' && head !== 'supersedes') || !isString(earlier) || !isString(later))\n\t\t\t\treturn []\n\t\t\tconst before = this.#options.conversation.message(earlier)\n\t\t\tconst after = this.#options.conversation.message(later)\n\t\t\tif (\n\t\t\t\tbefore === undefined ||\n\t\t\t\tafter === undefined ||\n\t\t\t\t(this.#readNoul(this.#buildPair(head, earlier, later)) ?? 0) <\n\t\t\t\t\tthis.#options.thresholds[head]\n\t\t\t)\n\t\t\t\treturn []\n\t\t\tconst own = extractTokens(before.content)\n\t\t\tconst other = extractTokens(after.content)\n\t\t\treturn head === 'amends' &&\n\t\t\t\t![...own.ids].some((id) => other.ids.has(id)) &&\n\t\t\t\t![...own.numbers].some((number) => other.numbers.has(number))\n\t\t\t\t? []\n\t\t\t\t: [{ head, earlier, later }]\n\t\t})\n\t\treturn {\n\t\t\tquiet: new Set(filed.filter((one) => one.quiet).map((one) => one.id)),\n\t\t\tcategories: new Map(\n\t\t\t\tfiled.flatMap((one) =>\n\t\t\t\t\tone.category === undefined ? [] : [[one.id, one.category] as const],\n\t\t\t\t),\n\t\t\t),\n\t\t\ttopics: new Map(filed.map((one) => [one.id, one.topics])),\n\t\t\tamendments: this.#sortLaters(pairs, positions),\n\t\t\tsupersessions: this.#sortLaters(\n\t\t\t\tpairs.filter((pair) => pair.head === 'supersedes'),\n\t\t\t\tpositions,\n\t\t\t),\n\t\t}\n\t}\n\n\t// Groups the later ids under each earlier id in first-seen order, each without repeats and in\n\t// conversation order; a stable sort keeps the first-seen order of ids at one position.\n\t#sortLaters(\n\t\tpairs: ReadonlyArray<{ readonly earlier: string; readonly later: string }>,\n\t\tpositions: ReadonlyMap<string, number>,\n\t): ReadonlyMap<string, readonly string[]> {\n\t\treturn new Map(\n\t\t\t[...Map.groupBy(pairs, (pair) => pair.earlier)].map(([earlier, grouped]) => [\n\t\t\t\tearlier,\n\t\t\t\t[...new Set(grouped.map((pair) => pair.later))].sort(\n\t\t\t\t\t(left, right) => (positions.get(left) ?? 0) - (positions.get(right) ?? 0),\n\t\t\t\t),\n\t\t\t]),\n\t\t)\n\t}\n\n\t// Asks every question in order, appending each answer to `results` so a throw still leaves the\n\t// answers completed before it.\n\tasync #gather(\n\t\trequests: ReadonlySet<string>,\n\t\tsignal: AbortSignal,\n\t\tresults: ClassifierResult[],\n\t): Promise<void> {\n\t\tconst messages = this.#options.conversation.messages()\n\t\tconst asked = messages.filter((message) => this.#options.assign(message) === undefined)\n\t\tfor (const message of asked) {\n\t\t\tif (!requests.has(message.id))\n\t\t\t\tresults.push(await this.#ask(this.#buildCategory(message.id), 'category', signal, results))\n\t\t}\n\t\tfor (const message of asked) {\n\t\t\tif (!requests.has(message.id) && this.quiet(message.id)) continue\n\t\t\tfor (const topic of this.#options.topics) {\n\t\t\t\tif (requests.has(message.id) && topic.requested === false) continue\n\t\t\t\tresults.push(await this.#ask(this.#buildTopic(message.id, topic), 'topic', signal, results))\n\t\t\t}\n\t\t}\n\t\tfor (const later of asked) {\n\t\t\tif (\n\t\t\t\tlater.role !== 'user' ||\n\t\t\t\t(this.#readCategories(later.id)?.probabilities.correction ?? 0) <\n\t\t\t\t\tthis.#options.thresholds.correction\n\t\t\t)\n\t\t\t\tcontinue\n\t\t\tconst near = this.#collectNear(later)\n\t\t\tif (near.size === 0) continue\n\t\t\tfor (const earlier of messages) {\n\t\t\t\tif (earlier.id === later.id) break\n\t\t\t\tif (\n\t\t\t\t\tthis.quiet(earlier.id) ||\n\t\t\t\t\t![...this.#collectNear(earlier)].some((topic) => near.has(topic))\n\t\t\t\t)\n\t\t\t\t\tcontinue\n\t\t\t\tconst spec = this.#buildPair('amends', earlier.id, later.id)\n\t\t\t\tresults.push(await this.#ask(spec, 'amends', signal, results))\n\t\t\t\tif ((this.#readNoul(spec) ?? 0) >= this.#options.thresholds.amends)\n\t\t\t\t\tresults.push(\n\t\t\t\t\t\tawait this.#ask(\n\t\t\t\t\t\t\tthis.#buildPair('supersedes', earlier.id, later.id),\n\t\t\t\t\t\t\t'supersedes',\n\t\t\t\t\t\t\tsignal,\n\t\t\t\t\t\t\tresults,\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t}\n\t\t}\n\t}\n\n\t#renderState(id: string): string {\n\t\tconst message = this.#options.conversation.message(id)\n\t\treturn `${message?.role ?? 'unknown'}: ${message?.content ?? ''}`\n\t}\n\n\t#buildCategory(id: string): JudgmentInput {\n\t\treturn {\n\t\t\tid: JSON.stringify(['category', id]),\n\t\t\tquestion: {\n\t\t\t\tform: 'choice',\n\t\t\t\t...(this.#options.questions.category.instructions === undefined\n\t\t\t\t\t? {}\n\t\t\t\t\t: { instructions: this.#options.questions.category.instructions }),\n\t\t\t\tcriteria: Object.fromEntries(\n\t\t\t\t\tLEDGER_CATEGORIES.map((category) => [\n\t\t\t\t\t\tcategory,\n\t\t\t\t\t\tthis.#options.questions.category.criteria[category],\n\t\t\t\t\t]),\n\t\t\t\t),\n\t\t\t},\n\t\t\tsources: [id],\n\t\t\tstate: this.#renderState(id),\n\t\t\tmodel: this.#options.judge.model,\n\t\t}\n\t}\n\n\t#buildTopic(id: string, topic: LedgerTopic): JudgmentInput {\n\t\treturn {\n\t\t\tid: JSON.stringify(['topic', id, topic.name]),\n\t\t\tquestion: {\n\t\t\t\tform: 'noul',\n\t\t\t\tinstructions: this.#options.questions.topic,\n\t\t\t\tcriteria: {\n\t\t\t\t\ttrue: `The message concerns ${topic.name}: ${topic.criterion}`,\n\t\t\t\t\tfalse: `The message does not concern ${topic.name}`,\n\t\t\t\t},\n\t\t\t},\n\t\t\tsources: [id],\n\t\t\tstate: this.#renderState(id),\n\t\t\tmodel: this.#options.judge.model,\n\t\t}\n\t}\n\n\t#buildPair(head: 'amends' | 'supersedes', earlier: string, later: string): JudgmentInput {\n\t\treturn {\n\t\t\tid: JSON.stringify([head, earlier, later]),\n\t\t\tquestion: this.#options.questions[head],\n\t\t\tsources: [earlier, later],\n\t\t\tstate: `Earlier message: ${this.#renderState(earlier)}\\nLater message: ${this.#renderState(later)}`,\n\t\t\tmodel: this.#options.judge.model,\n\t\t}\n\t}\n\n\t#read(spec: JudgmentInput): Judgment | undefined {\n\t\tconst recorded = this.#options.conversation.judgments.judgment(spec.id)\n\t\treturn recorded !== undefined &&\n\t\t\tmatchesJudgment(recorded, spec.question, spec.sources, spec.state, this.#options.judge.model)\n\t\t\t? recorded\n\t\t\t: undefined\n\t}\n\n\t#readNoul(spec: JudgmentInput): number | undefined {\n\t\tconst answer = this.#read(spec)?.answer\n\t\treturn answer?.form === 'noul' ? answer.noul : undefined\n\t}\n\n\t#readCategories(id: string): ChoiceAnswer | undefined {\n\t\tconst answer = this.#read(this.#buildCategory(id))?.answer\n\t\treturn answer?.form === 'choice' ? answer : undefined\n\t}\n\n\t#weigh(id: string, categories: readonly LedgerCategory[]): number {\n\t\tconst answer = this.#readCategories(id)\n\t\treturn categories.reduce((sum, category) => sum + (answer?.probabilities[category] ?? 0), 0)\n\t}\n\n\t#collectNear(message: Message): ReadonlySet<string> {\n\t\tconst argumentsText =\n\t\t\tmessage.calls === undefined\n\t\t\t\t? undefined\n\t\t\t\t: renderJSON(message.calls.map((call) => call.arguments))\n\t\tconst text =\n\t\t\targumentsText === undefined ? message.content : `${message.content} ${argumentsText}`\n\t\treturn new Set([\n\t\t\t...this.#options.entities(text, false),\n\t\t\t...(this.#options.assign(message) === undefined ? this.topics(message.id) : []),\n\t\t])\n\t}\n\n\tasync #ask(\n\t\tspec: JudgmentInput,\n\t\tphase: ClassifierPhase,\n\t\tsignal: AbortSignal,\n\t\tresults: ClassifierResult[],\n\t): Promise<ClassifierResult> {\n\t\tif (this.#read(spec) !== undefined)\n\t\t\treturn { judgments: [spec.id], readings: [{ key: spec.id, phase, outcome: 'cached' }] }\n\t\tconst fingerprint = JSON.stringify(spec)\n\t\tif (this.#failed.has(fingerprint))\n\t\t\treturn { judgments: [], readings: [{ key: spec.id, phase, outcome: 'skipped' }] }\n\t\tsignal.throwIfAborted()\n\t\tconst started = performance.now()\n\t\ttry {\n\t\t\tconst [judgment] = await this.#options.conversation.judgments.resolve(\n\t\t\t\tthis.#options.judge,\n\t\t\t\t{ state: spec.state, questions: { [spec.id]: spec.question } },\n\t\t\t\tspec.sources,\n\t\t\t\tsignal,\n\t\t\t)\n\t\t\tconst readings: readonly ClassifierReading[] = [\n\t\t\t\t{ key: spec.id, phase, outcome: 'resolved', duration: performance.now() - started },\n\t\t\t]\n\t\t\treturn judgment === undefined\n\t\t\t\t? { judgments: [], readings }\n\t\t\t\t: {\n\t\t\t\t\t\tjudgments: [spec.id],\n\t\t\t\t\t\t...(judgment.usage === undefined ? {} : { usage: judgment.usage }),\n\t\t\t\t\t\treadings,\n\t\t\t\t\t}\n\t\t} catch (error) {\n\t\t\t// A rejection records its reading in the pushed result alone, so the empty result returned under a live signal repeats none.\n\t\t\tconst readings: readonly ClassifierReading[] = [\n\t\t\t\t{\n\t\t\t\t\tkey: spec.id,\n\t\t\t\t\tphase,\n\t\t\t\t\toutcome: isJudgeAbortError(error) || signal.aborted ? 'aborted' : 'failed',\n\t\t\t\t\tduration: performance.now() - started,\n\t\t\t\t},\n\t\t\t]\n\t\t\tif (isJudgeAbortError(error))\n\t\t\t\tresults.push({\n\t\t\t\t\tjudgments:\n\t\t\t\t\t\tObject.hasOwn(error.partial.answers, spec.id) ||\n\t\t\t\t\t\t(error.partial.refusals !== undefined && Object.hasOwn(error.partial.refusals, spec.id))\n\t\t\t\t\t\t\t? [spec.id]\n\t\t\t\t\t\t\t: [],\n\t\t\t\t\t...(error.partial.usage === undefined ? {} : { usage: error.partial.usage }),\n\t\t\t\t\treadings,\n\t\t\t\t})\n\t\t\telse results.push({ judgments: [], readings })\n\t\t\tif (\n\t\t\t\t(isJudgeError(error) && error.code === 'QUESTION') ||\n\t\t\t\tDETERMINISTIC_JUDGE_ERROR.test(renderCauseChain(error))\n\t\t\t)\n\t\t\t\tthis.#failed.add(fingerprint)\n\t\t\tif (signal.aborted) throw error\n\t\t\treturn { judgments: [], readings: [] }\n\t\t}\n\t}\n}\n","import { isFiniteNumber } from '@orkestrel/contract'\n\n/**\n * Checks whether a value is finite and lies in the interval (0, 1].\n * @param value - The value to inspect\n * @returns True if the value is a valid ledger fraction; false otherwise\n * @example\n * ```ts\n * isFraction(0.8) // true\n * ```\n */\nexport function isFraction(value: unknown): value is number {\n\treturn isFiniteNumber(value) && value > 0 && value <= 1\n}\n\n/**\n * Checks whether a value is a positive safe integer.\n * @param value - The value to inspect\n * @returns True if the value is a positive safe integer; false otherwise\n * @example\n * ```ts\n * isPositiveSafeInteger(4096) // true\n * ```\n */\nexport function isPositiveSafeInteger(value: unknown): value is number {\n\treturn isFiniteNumber(value) && Number.isSafeInteger(value) && value > 0\n}\n","import type { ThinkingReplay } from '../types.js'\nimport type { GaugeCall, GaugeInterface, GaugeOptions } from './types.js'\nimport { isFiniteNumber } from '@orkestrel/contract'\nimport { estimateMessages } from '../agents/helpers.js'\nimport { LedgerError } from './errors.js'\nimport { isPositiveSafeInteger } from './validators.js'\nimport { buildRecallMessage, fitSlope, resolvePredict } from './helpers.js'\n\n/**\n * Prices prompts in tokens from a measured scale and overhead cost, and measures the room a request\n * has left.\n *\n * @remarks\n * `observe` rescales from the first call of each finished request with the overhead cost taken out,\n * and keeps that request's calls for the marginal rate and the longest final completion for the reply\n * reserve after subtracting its thinking. `overhead` never changes after construction.\n * {@link GaugeOptions} defines the measured use, reply reserve, and recall-room formulas.\n * {@link LedgerOptions} defines the ledger's plan budget and recall close rule.\n *\n * @example\n * ```ts\n * const gauge = new Gauge({ scale: 1.16, overhead: 498, capacity: 32768 })\n * gauge.room([{ estimate: 1719, prompt: 2498, tools: 3 }], '') // estimate units a recall result can take\n * ```\n */\nexport class Gauge implements GaugeInterface {\n\treadonly #capacity: number\n\treadonly #predict: number\n\treadonly #replay: ThinkingReplay\n\t#history: ReadonlyArray<readonly GaugeCall[]> = []\n\t#scale: number\n\t#overhead: number\n\t#reply = 0\n\n\t/**\n\t * Holds the starting price and the capacity.\n\t *\n\t * @param options - The starting `scale` and `overhead` price and the context `capacity`\n\t * @throws {LedgerError} Thrown when `scale` is not finite and above 0, or `overhead` is not finite and at least 0 (code `'GAUGE'`)\n\t * @throws {LedgerError} Thrown when `capacity` is not a positive safe integer (code `'CAPACITY'`)\n\t * @throws {LedgerError} Thrown when `predict` is not a nonnegative safe integer less than `capacity` (code `'CAPACITY'`)\n\t */\n\tconstructor(options: GaugeOptions) {\n\t\tif (!isFiniteNumber(options.scale) || options.scale <= 0) {\n\t\t\tthrow new LedgerError('GAUGE', 'gauge scale must be finite and greater than 0')\n\t\t}\n\t\tif (!isFiniteNumber(options.overhead) || options.overhead < 0) {\n\t\t\tthrow new LedgerError('GAUGE', 'gauge overhead must be finite and at least 0')\n\t\t}\n\t\tif (!isPositiveSafeInteger(options.capacity)) {\n\t\t\tthrow new LedgerError('CAPACITY', 'gauge capacity must be a positive safe integer')\n\t\t}\n\t\tthis.#scale = options.scale\n\t\tthis.#overhead = options.overhead\n\t\tthis.#capacity = options.capacity\n\t\tthis.#predict = resolvePredict(options.predict, options.capacity)\n\t\tthis.#replay = options.replay ?? 'none'\n\t}\n\n\tget scale(): number {\n\t\treturn this.#scale\n\t}\n\n\tget overhead(): number {\n\t\treturn this.#overhead\n\t}\n\n\t/**\n\t * Reads the marginal rate of prompt tokens per estimate unit.\n\t *\n\t * @remarks\n\t * Returns the scale when the fit is undefined, nonfinite, or not above 0, so a degenerate fit never prices recall room.\n\t *\n\t * @param calls - The calls of the request in progress\n\t * @returns The fitted slope, or the scale when the slope is unusable\n\t */\n\trate(calls: readonly GaugeCall[]): number {\n\t\tconst slope = fitSlope([...this.#history, calls])\n\t\treturn slope !== undefined && isFiniteNumber(slope) && slope > 0 ? slope : this.#scale\n\t}\n\n\tremainder(calls: readonly GaugeCall[]): number {\n\t\tconst call = calls.at(-1)\n\t\tconst used = isFiniteNumber(call?.prompt)\n\t\t\t? call.prompt + (call.completion ?? 0) - (this.#replay === 'none' ? (call.thinking ?? 0) : 0)\n\t\t\t: this.#overhead + this.#scale * (call?.estimate ?? 0)\n\t\treturn Math.max(0, this.#capacity - used)\n\t}\n\n\treserve(calls: readonly GaugeCall[], longest: string): number {\n\t\tconst rate = this.rate(calls)\n\t\t// Before any reply is observed, the longest assistant text stands in for the reply.\n\t\tconst reply =\n\t\t\tthis.#reply > 0\n\t\t\t\t? this.#reply\n\t\t\t\t: rate * estimateMessages([{ id: 'reply', role: 'assistant', content: longest }])\n\t\tconst recall =\n\t\t\trate * estimateMessages([buildRecallMessage(''), { id: 'result', role: 'tool', content: '' }])\n\t\treturn reply + recall\n\t}\n\n\troom(calls: readonly GaugeCall[], longest: string): number {\n\t\treturn Math.max(\n\t\t\t0,\n\t\t\t(this.remainder(calls) - this.#predict - this.reserve(calls, longest)) / 2 / this.rate(calls),\n\t\t)\n\t}\n\n\tobserve(calls: readonly GaugeCall[], reply?: GaugeCall): void {\n\t\tconst first = calls[0]\n\t\tif (first !== undefined && isFiniteNumber(first.prompt) && first.estimate > 0) {\n\t\t\tconst priced = first.prompt - this.#overhead\n\t\t\tif (priced > 0) this.#scale = priced / first.estimate\n\t\t}\n\t\tthis.#history = [...this.#history, [...calls]]\n\t\tif (isFiniteNumber(reply?.completion))\n\t\t\tthis.#reply = Math.max(this.#reply, reply.completion - (reply.thinking ?? 0))\n\t}\n}\n","import type { Selection } from '../contexts/types.js'\nimport type { GaugeCall } from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport { sumUsage } from '../helpers.js'\n\n/**\n * Holds what one pass of a ledger request keeps: the selection its run adopted last, the\n * conversation boundary its calls count additions from, its summed usage, and its gauge calls.\n *\n * @remarks\n * A `LedgerRequest` opens one pass per agent run and exposes only projections of it, so no public\n * signature names this class. The pass appends one final record to its log for each call observed,\n * each usage reported, and each thinking share, in emission order, and derives `calls`, `call`, and\n * `position` from it: a usage or thinking record joins the last call observed before it, and one\n * recorded before the first call joins none.\n */\nexport class LedgerPass {\n\t#log: ReadonlyArray<\n\t\t| { readonly call: GaugeCall; readonly position: number }\n\t\t| { readonly usage: { readonly prompt: number; readonly completion: number } }\n\t\t| { readonly thinking: number }\n\t> = []\n\t#selection: Selection | undefined\n\t#boundary: number\n\t#usage: TokenUsage | undefined\n\n\t/**\n\t * Opens the pass at a conversation boundary.\n\t *\n\t * @param boundary - The conversation length when the pass's run starts\n\t */\n\tconstructor(boundary: number) {\n\t\tthis.#boundary = boundary\n\t}\n\n\t/**\n\t * Returns the selection the pass's run adopted last.\n\t *\n\t * @returns The selection, or undefined before one\n\t */\n\tget selection(): Selection | undefined {\n\t\treturn this.#selection\n\t}\n\n\t/**\n\t * Returns the conversation length the pass's calls count additions from.\n\t *\n\t * @returns The length at the pass's start or at its last adopted selection\n\t */\n\tget boundary(): number {\n\t\treturn this.#boundary\n\t}\n\n\t/**\n\t * Returns the summed usage of the pass's selections and calls.\n\t *\n\t * @returns The summed usage, or undefined while none reported usage\n\t */\n\tget usage(): TokenUsage | undefined {\n\t\treturn this.#usage\n\t}\n\n\t/**\n\t * Returns the call in flight.\n\t *\n\t * @returns The latest call the pass observed, or undefined before one\n\t */\n\tget call(): GaugeCall | undefined {\n\t\treturn this.calls.at(-1)\n\t}\n\n\t/**\n\t * Returns the conversation length when the call in flight started.\n\t *\n\t * @returns The position, or undefined before a call\n\t */\n\tget position(): number | undefined {\n\t\treturn this.#log.flatMap((entry) => ('position' in entry ? [entry.position] : [])).at(-1)\n\t}\n\n\t/**\n\t * Returns the pass's gauge calls in order.\n\t *\n\t * @returns Each observed call with the last usage and thinking recorded after it, before the next call\n\t */\n\tget calls(): readonly GaugeCall[] {\n\t\treturn this.#log.flatMap((entry, index) => {\n\t\t\tif (!('call' in entry)) return []\n\t\t\tconst after = this.#log.slice(index + 1)\n\t\t\tconst next = after.findIndex((one) => 'call' in one)\n\t\t\tconst joined = next === -1 ? after : after.slice(0, next)\n\t\t\tconst usage = joined.flatMap((one) => ('usage' in one ? [one.usage] : [])).at(-1)\n\t\t\tconst thinking = joined.flatMap((one) => ('thinking' in one ? [one.thinking] : [])).at(-1)\n\t\t\tconst billed =\n\t\t\t\tusage === undefined\n\t\t\t\t\t? entry.call\n\t\t\t\t\t: { ...entry.call, prompt: usage.prompt, completion: usage.completion }\n\t\t\treturn [thinking === undefined ? billed : { ...billed, thinking }]\n\t\t})\n\t}\n\n\t/**\n\t * Records the selection the pass's run adopted and adds the usage it spent.\n\t *\n\t * @param selection - The selection the run built its prompt from\n\t * @param boundary - The conversation length when the run adopted it\n\t */\n\tadopt(selection: Selection, boundary: number): void {\n\t\tthis.#selection = selection\n\t\tthis.#boundary = boundary\n\t\tif (selection.usage !== undefined) this.#usage = sumUsage(this.#usage, selection.usage)\n\t}\n\n\t/**\n\t * Starts a call, appending its record to the log.\n\t *\n\t * @param call - The call's estimate and advertised tool count\n\t * @param position - The conversation length when the call starts\n\t */\n\tobserve(call: GaugeCall, position: number): void {\n\t\tthis.#log = [...this.#log, { call, position }]\n\t}\n\n\t/**\n\t * Adds one call's reported usage to the pass's summed usage.\n\t *\n\t * @param usage - The usage the provider reported\n\t */\n\tspend(usage: TokenUsage): void {\n\t\tthis.#usage = sumUsage(this.#usage, usage)\n\t}\n\n\t/**\n\t * Appends a reported usage to the log, which joins the call observed last as its prompt and completion.\n\t *\n\t * @remarks\n\t * The record keeps the prompt and completion values the usage held at this call, so a later change\n\t * to the caller's object never reaches a reading.\n\t *\n\t * @param usage - The usage the provider reported for the call\n\t */\n\tbill(usage: TokenUsage): void {\n\t\tthis.#log = [...this.#log, { usage: { prompt: usage.prompt, completion: usage.completion } }]\n\t}\n\n\t/**\n\t * Appends the thinking share to the log, which joins the call observed last.\n\t *\n\t * @param thinking - The completion tokens attributed to the call's thinking\n\t */\n\tthink(thinking: number): void {\n\t\tthis.#log = [...this.#log, { thinking }]\n\t}\n}\n","import type { Selection } from '../contexts/types.js'\nimport type { ConversationInterface } from '../conversations/types.js'\nimport type { Message } from '../types.js'\nimport type { ClassifierReading, GaugeCall, LedgerRequestInterface } from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport { canonicalStringify } from '@orkestrel/contract'\nimport { isNonNegativeSafeInteger } from '../validators.js'\nimport { DEFAULT_RECALL_LIMIT, LEDGER_NOTES } from './constants.js'\nimport { LedgerError } from './errors.js'\nimport { computeThinking } from './helpers.js'\nimport { LedgerPass } from './LedgerPass.js'\n\n/**\n * Holds what one ledger request keeps while it is served: its message, its filing readings and\n * plan, the gauge calls of its passes, and its repeat and recall stops.\n *\n * @remarks\n * A ledger creates one request per `respond` call and drops it when the call settles. Each pass the\n * request opens holds its own selection, boundary, usage, and calls; the request reads the current\n * pass, the last one opened. {@link LedgerRequestInterface} describes each member.\n *\n * @example\n * ```ts\n * const request = new LedgerRequest('What approval is needed?', 1)\n * request.enter(conversation) // the appended user message\n * request.admit('lookup', { id: 'BW-20931' })\n * request.admit('lookup', { id: 'BW-20931' }) // throws Error(LEDGER_NOTES.repeat)\n * request.recall()\n * request.recall() // throws Error(LEDGER_NOTES.closure): the limit of 1 is spent\n * ```\n */\nexport class LedgerRequest implements LedgerRequestInterface {\n\treadonly #content: string\n\treadonly #limit: number\n\t#message: Message | undefined\n\t#plan: Selection | undefined\n\t#passes: readonly LedgerPass[] = []\n\t#readings: readonly ClassifierReading[] = []\n\t#admitted: ReadonlySet<string> = new Set()\n\t#listings: ReadonlyMap<string, ReadonlyMap<string, string>> = new Map()\n\t#recalls = 0\n\t#closed = false\n\n\t/**\n\t * Holds the request's content and its recall limit.\n\t *\n\t * @param content - The request text `enter` appends\n\t * @param limit - The `recall` calls the request can make. Default: the `DEFAULT_RECALL_LIMIT` constant\n\t * @throws {LedgerError} Thrown when `limit` is not a nonnegative safe integer (code `'LIMIT'`)\n\t */\n\tconstructor(content: string, limit: number = DEFAULT_RECALL_LIMIT) {\n\t\tif (!isNonNegativeSafeInteger(limit))\n\t\t\tthrow new LedgerError('LIMIT', 'limits must be nonnegative safe integers')\n\t\tthis.#content = content\n\t\tthis.#limit = limit\n\t}\n\n\t/**\n\t * Returns the request message.\n\t *\n\t * @returns The message `enter` appended, or undefined before it\n\t */\n\tget message(): Message | undefined {\n\t\treturn this.#message\n\t}\n\n\t/**\n\t * Returns the selection the request's last successful plan produced.\n\t *\n\t * @returns The planned selection, or undefined before one\n\t */\n\tget plan(): Selection | undefined {\n\t\treturn this.#plan\n\t}\n\n\t/**\n\t * Returns the selection the current pass's run adopted last.\n\t *\n\t * @returns The selection, or undefined before one\n\t */\n\tget selection(): Selection | undefined {\n\t\treturn this.#passes.at(-1)?.selection\n\t}\n\n\t/**\n\t * Returns the conversation length the current pass's calls count additions from.\n\t *\n\t * @returns The length, or undefined before a pass\n\t */\n\tget boundary(): number | undefined {\n\t\treturn this.#passes.at(-1)?.boundary\n\t}\n\n\t/**\n\t * Returns the summed usage of the current pass.\n\t *\n\t * @returns The summed usage, or undefined while none reported usage\n\t */\n\tget usage(): TokenUsage | undefined {\n\t\treturn this.#passes.at(-1)?.usage\n\t}\n\n\t/**\n\t * Returns the gauge calls of every pass.\n\t *\n\t * @returns The calls in order, the call in flight last\n\t */\n\tget calls(): readonly GaugeCall[] {\n\t\treturn this.#passes.flatMap((pass) => pass.calls)\n\t}\n\n\t/**\n\t * Returns the filing readings of the request's planning selections.\n\t *\n\t * @returns The readings in asking order\n\t */\n\tget readings(): readonly ClassifierReading[] {\n\t\treturn this.#readings\n\t}\n\n\tenter(conversation: ConversationInterface): Message {\n\t\tif (this.#message !== undefined) return this.#message\n\t\tthis.#message = conversation.add({ role: 'user', content: this.#content })\n\t\treturn this.#message\n\t}\n\n\topen(boundary: number): void {\n\t\tthis.#passes = [...this.#passes, new LedgerPass(boundary)]\n\t}\n\n\tadopt(selection: Selection, boundary: number): void {\n\t\tthis.#passes.at(-1)?.adopt(selection, boundary)\n\t}\n\n\tobserve(call: GaugeCall, position: number): void {\n\t\tthis.#passes.at(-1)?.observe(call, position)\n\t}\n\n\tspend(usage: TokenUsage): void {\n\t\tthis.#passes.at(-1)?.spend(usage)\n\t\t// The call in flight can belong to an earlier pass until the current pass observes its first call.\n\t\tthis.#passes.findLast((pass) => pass.call !== undefined)?.bill(usage)\n\t}\n\n\tthink(messages: readonly Message[]): void {\n\t\tconst pass = this.#passes.findLast((one) => one.call !== undefined)\n\t\tconst completion = pass?.call?.completion\n\t\tif (pass?.position === undefined || completion === undefined) return\n\t\tconst message = messages.slice(pass.position).find((entry) => entry.role === 'assistant')\n\t\tif (message?.thinking === undefined) return\n\t\tpass.think(computeThinking(message, completion))\n\t}\n\n\tfile(readings: readonly ClassifierReading[], plan?: Selection): void {\n\t\tthis.#readings = [...this.#readings, ...readings]\n\t\tif (plan !== undefined) this.#plan = plan\n\t}\n\n\tadmit(name: string, args: Readonly<Record<string, unknown>>): void {\n\t\tconst key = canonicalStringify([name, args])\n\t\tif (key === undefined) throw new Error('tool arguments have no canonical identity')\n\t\tif (this.#admitted.has(key)) throw new Error(LEDGER_NOTES.repeat)\n\t\tthis.#admitted = new Set([...this.#admitted, key])\n\t}\n\n\trecall(): void {\n\t\tif (this.#recalls >= this.#limit) this.#closed = true\n\t\tif (this.#closed) throw new Error(LEDGER_NOTES.closure)\n\t\tthis.#recalls += 1\n\t}\n\n\tclose(): void {\n\t\tthis.#closed = true\n\t}\n\n\tlist(result: string, lines: ReadonlyMap<string, string>): void {\n\t\tthis.#listings = new Map([...this.#listings, [result, lines]])\n\t}\n\n\tlisting(result: string): ReadonlyMap<string, string> | undefined {\n\t\treturn this.#listings.get(result)\n\t}\n}\n","import type { AgentInterface, AgentResult } from '../agents/types.js'\nimport type { Selection } from '../contexts/types.js'\nimport type { ConversationInterface } from '../conversations/types.js'\nimport type { ProviderInterface } from '../providers/types.js'\nimport type { Message, ThinkingReplay } from '../types.js'\nimport type {\n\tClassifierResult,\n\tLedgerAmendment,\n\tLedgerCategory,\n\tLedgerGauge,\n\tLedgerInterface,\n\tLedgerLine,\n\tLedgerLookupReading,\n\tLedgerOptions,\n\tLedgerProjection,\n\tLedgerProjectionInput,\n\tLedgerRecord,\n\tLedgerRenderContext,\n\tLedgerResult,\n\tLedgerShare,\n} from './types.js'\nimport type { TokenUsage } from '@orkestrel/budget'\nimport type { ToolCall, ToolContext, ToolResult } from '@orkestrel/tool'\nimport { createAbort } from '@orkestrel/abort'\nimport { attempt, isError, isFiniteNumber, isString } from '@orkestrel/contract'\nimport { createTool, createToolManager } from '@orkestrel/tool'\nimport { createAgent } from '../agents/factories.js'\nimport { AgentError } from '../agents/errors.js'\nimport { estimateMessages } from '../agents/helpers.js'\nimport { createScope } from '../contexts/factories.js'\nimport { createConversationManager } from '../conversations/factories.js'\nimport {\n\tcollectExchanges,\n\tcollectToolGroups,\n\thasCalls,\n\tstripThinking,\n\tsumUsage,\n} from '../helpers.js'\nimport { isNonNegativeSafeInteger } from '../validators.js'\nimport { Classifier } from './Classifier.js'\nimport { Gauge } from './Gauge.js'\nimport { LedgerRequest } from './LedgerRequest.js'\nimport {\n\tDEFAULT_LEDGER_LIMIT,\n\tDEFAULT_LEDGER_SHARE,\n\tLEDGER_NOTES,\n\tLEDGER_OWNER_PREFIX,\n\tLEDGER_RULES_KEY,\n\tLEDGER_SCALE_DRIFT,\n} from './constants.js'\nimport { isLedgerError, LedgerError } from './errors.js'\nimport {\n\tbuildLines,\n\tbuildLedgerRenderContext,\n\tbuildRecallMessage,\n\tcollectProjectionIds,\n\textractWords,\n\trenderTopicNames,\n\tscanAmendments,\n\tsplitWords,\n\tbuildRecords,\n\tcollectNames,\n\tcollectRegistry,\n\tcutListing,\n\textractTokens,\n\tlinkOwners,\n\tmatchEntities,\n\trankLedgerCut,\n\tresolvePredict,\n\tfindLedgerCall,\n\tmatchesCutLine,\n\trenderLedgerAnnotation,\n\trenderLedgerPinned,\n\trenderLedgerRecord,\n\trenderLookupCall,\n\trenderStub,\n\tselectRecords,\n\tsplitResultLines,\n\tsplitTopic,\n\tsplitSentences,\n} from './helpers.js'\nimport { isFraction, isPositiveSafeInteger } from './validators.js'\n\n/**\n * Serves one conversation through classified records, a bounded briefing, and a final answer pass.\n * @example\n * ```ts\n * const ledger = new Ledger(provider, options)\n * ledger.conversation.add({ role: 'user', content: 'The refund needs approval.' })\n * const reply = await ledger.respond('What approval is needed?')\n * ```\n */\nexport class Ledger implements LedgerInterface {\n\treadonly #provider: ProviderInterface\n\treadonly #options: LedgerOptions\n\treadonly #replay: ThinkingReplay\n\treadonly #predict: number\n\treadonly #share: LedgerShare\n\treadonly #conversation: ConversationInterface\n\treadonly #agent: AgentInterface\n\treadonly #classifier: Classifier\n\treadonly #requests = new Set<string>()\n\treadonly #annotations = new Set<string>()\n\treadonly #results = new Map<string, ToolResult>()\n\treadonly #pending = new Map<number, ToolResult>()\n\treadonly #live = new Set<LedgerRequest>()\n\treadonly #calibrations = new Set<AbortSignal>()\n\t#gauge: Gauge | undefined\n\n\t/**\n\t * Composes the conversation, classifier, tools, and agent.\n\t * @param provider - The provider that serves the conversation\n\t * @param options - The filing policy, capacity, and request bounds\n\t * @throws {LedgerError} Thrown when a threshold, share, capacity, limit, topic, lookup, or gauge is invalid\n\t * @throws {LedgerError} Thrown when `predict` is not a nonnegative safe integer less than `capacity` (code `'CAPACITY'`)\n\t */\n\tconstructor(provider: ProviderInterface, options: LedgerOptions) {\n\t\tfor (const key of ['category', 'topic', 'correction', 'amends', 'supersedes'] as const) {\n\t\t\tconst value = options.thresholds[key]\n\t\t\tif (!isFraction(value))\n\t\t\t\tthrow new LedgerError('THRESHOLD', 'thresholds must be finite and in (0, 1]')\n\t\t}\n\t\tfor (const value of Object.values(options.share ?? {})) {\n\t\t\tif (!isFraction(value)) throw new LedgerError('SHARE', 'shares must be finite and in (0, 1]')\n\t\t}\n\t\tif (!isPositiveSafeInteger(options.capacity))\n\t\t\tthrow new LedgerError('CAPACITY', 'capacity must be a positive safe integer')\n\t\tthis.#predict = resolvePredict(options.predict, options.capacity)\n\t\tfor (const value of [options.recall?.limit, options.agent?.limit]) {\n\t\t\tif (value !== undefined && !isNonNegativeSafeInteger(value))\n\t\t\t\tthrow new LedgerError('LIMIT', 'limits must be nonnegative safe integers')\n\t\t}\n\t\t// `Array.from` visits a hole in either list as an undefined entry, as iteration does, so the\n\t\t// read of its `name` refuses it; `map` skips it.\n\t\tconst topics = Array.from(options.topics, (topic) => topic.name)\n\t\tif (topics.some((name) => name.trim() === '') || new Set(topics).size !== topics.length)\n\t\t\tthrow new LedgerError('TOPIC', 'topic names must be nonempty and unique')\n\t\tconst lookups = ['recall', ...Array.from(options.lookups ?? [], (lookup) => lookup.tool.name)]\n\t\tif (new Set(lookups).size !== lookups.length)\n\t\t\tthrow new LedgerError('LOOKUP', 'lookup names must be unique and cannot be recall')\n\t\tthis.#provider = provider\n\t\tthis.#replay = provider.replay ?? 'none'\n\t\tthis.#options = options\n\t\tthis.#share = { ...DEFAULT_LEDGER_SHARE, ...options.share }\n\t\tif (options.gauge !== undefined)\n\t\t\tthis.#gauge = new Gauge({\n\t\t\t\t...options.gauge,\n\t\t\t\tcapacity: options.capacity,\n\t\t\t\tpredict: this.#predict,\n\t\t\t\treplay: this.#replay,\n\t\t\t})\n\t\tconst conversations = createConversationManager()\n\t\tthis.#conversation = conversations.add()\n\t\tconversations.switch(this.#conversation.id)\n\t\tthis.#classifier = new Classifier({\n\t\t\tconversation: this.#conversation,\n\t\t\tjudge: options.judge,\n\t\t\tquestions: options.questions,\n\t\t\tthresholds: options.thresholds,\n\t\t\ttopics: options.topics,\n\t\t\tassign: this.#assign.bind(this),\n\t\t\tentities: (text, partial) =>\n\t\t\t\tmatchEntities(collectRegistry(this.#readLookups()), text, partial),\n\t\t})\n\t\tconst tools = createToolManager()\n\t\tfor (const lookup of options.lookups ?? []) {\n\t\t\ttools.add(\n\t\t\t\tcreateTool({\n\t\t\t\t\tname: lookup.tool.name,\n\t\t\t\t\t...(lookup.tool.parameters === undefined ? {} : { parameters: lookup.tool.parameters }),\n\t\t\t\t\t...(lookup.tool.description === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { description: lookup.tool.description }),\n\t\t\t\t\t...(lookup.tool.summary === undefined ? {} : { summary: lookup.tool.summary }),\n\t\t\t\t\t...(lookup.tool.title === undefined ? {} : { title: lookup.tool.title }),\n\t\t\t\t\t...(lookup.tool.annotations === undefined\n\t\t\t\t\t\t? {}\n\t\t\t\t\t\t: { annotations: lookup.tool.annotations }),\n\t\t\t\t\texecute: (args, context) => this.#lookup(lookup.tool.name, args, context),\n\t\t\t\t}),\n\t\t\t)\n\t\t}\n\t\ttools.add(\n\t\t\tcreateTool({\n\t\t\t\tname: 'recall',\n\t\t\t\tdescription: `Recall what the full conversation record holds on a topic: an owner name, an id, or one of the desk topics ${renderTopicNames(options.topics)}. Returns source lines, newest first.`,\n\t\t\t\tparameters: {\n\t\t\t\t\ttype: 'object',\n\t\t\t\t\tproperties: {\n\t\t\t\t\t\ttopic: { type: 'string', description: 'An owner name, an id, or a desk topic' },\n\t\t\t\t\t},\n\t\t\t\t\trequired: ['topic'],\n\t\t\t\t},\n\t\t\t\texecute: (args) => this.#recall(args),\n\t\t\t}),\n\t\t)\n\t\tthis.#agent = createAgent(provider, {\n\t\t\t...options.agent,\n\t\t\tconversations,\n\t\t\tsystem: options.system,\n\t\t\ttools,\n\t\t\tlimit: options.agent?.limit ?? DEFAULT_LEDGER_LIMIT,\n\t\t\tstrict: false,\n\t\t\tselect: (_conversation, request, signal) => this.#select(request, signal),\n\t\t})\n\t\tthis.#agent.emitter.on('tool', (_call, result) => {\n\t\t\tthis.#flush()\n\t\t\tthis.#pending.set(this.#conversation.messages().length, result)\n\t\t\tif (!result.success && result.error === LEDGER_NOTES.repeat) {\n\t\t\t\tthis.#current()?.close()\n\t\t\t\tthis.#agent.abort('repeat')\n\t\t\t}\n\t\t})\n\t\tthis.#agent.emitter.on('select', (selection) => {\n\t\t\tif (isLedgerError(selection.fault) && selection.fault.code === 'REQUEST') return\n\t\t\tthis.#current()?.adopt(selection, this.#conversation.messages().length)\n\t\t})\n\t\tthis.#agent.emitter.on('turn', () => this.#observeTurn())\n\t\tthis.#agent.emitter.on('usage', (usage) => this.#current()?.spend(usage))\n\t}\n\n\t/**\n\t * Returns the owned request engine.\n\t * @returns The engine serving this conversation\n\t */\n\tget agent(): AgentInterface {\n\t\treturn this.#agent\n\t}\n\t/**\n\t * Returns the owned message history.\n\t * @returns The history filed and served by this ledger\n\t */\n\tget conversation(): ConversationInterface {\n\t\treturn this.#conversation\n\t}\n\t/**\n\t * Returns the stored prompt price.\n\t * @returns The scale and overhead cost, or undefined before calibration\n\t */\n\tget gauge(): LedgerGauge | undefined {\n\t\treturn this.#gauge === undefined\n\t\t\t? undefined\n\t\t\t: { scale: this.#gauge.scale, overhead: this.#gauge.overhead }\n\t}\n\n\t/**\n\t * Measures message scale and tool overhead from provider prompt usage.\n\t * @param signal - The signal bounding both calibration calls; an abort rejects with its reason\n\t * @returns The stored scale and overhead cost\n\t * @throws {LedgerError} Thrown when either call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)\n\t * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)\n\t */\n\tasync calibrate(signal: AbortSignal): Promise<LedgerGauge> {\n\t\tif (this.#busy()) throw new AgentError('CONCURRENCY', 'a ledger request is already active')\n\t\tthis.#calibrations.add(signal)\n\t\ttry {\n\t\t\treturn await this.#measureGauge(signal)\n\t\t} finally {\n\t\t\tthis.#calibrations.delete(signal)\n\t\t}\n\t}\n\n\t/**\n\t * Appends a request and serves it, recovering an unfinished or rejected first pass with one answer pass.\n\t * A calibration call that reports no prompt usage, or a prompt usage of 0 or less, rejects with `LedgerError` code `'GAUGE'`; a provider error during calibration rejects with that error.\n\t * When the answer pass rejects, `respond` rejects with that error. Every rejection leaves the ledger free for a later call.\n\t * @param content - The request text\n\t * @param signal - The caller's cancellation signal; an abort during calibration rejects with its reason\n\t * @returns The final pass, the usage of every pass, and the filing readings of this request alone\n\t * @throws {AgentError} Thrown when a request or calibration is active (code `'CONCURRENCY'`)\n\t * @throws {LedgerError} Thrown when a calibration call reports no prompt usage, or a prompt usage of 0 or less (code `'GAUGE'`)\n\t * @throws {ContractError} Thrown when `signal` is defined and is not a native `AbortSignal`\n\t */\n\tasync respond(content: string, signal?: AbortSignal): Promise<LedgerResult> {\n\t\tif (this.#busy()) throw new AgentError('CONCURRENCY', 'a ledger request is already active')\n\t\tconst abort = createAbort({ ...(signal === undefined ? {} : { signal }) })\n\t\tconst caller = abort.signal\n\t\tconst request = new LedgerRequest(content, this.#options.recall?.limit)\n\t\tthis.#live.add(request)\n\t\ttry {\n\t\t\tif (this.#gauge === undefined) await this.#measureGauge(caller)\n\t\t\tconst entered = request.enter(this.#conversation)\n\t\t\tthis.#requests.add(entered.id)\n\t\t\t// The answer pass recovers a rejected first pass; the agent's error event carries its cause.\n\t\t\tconst first = await this.#generatePass(request, caller, this.#options.think).catch(\n\t\t\t\t(): AgentResult => ({\n\t\t\t\t\tcontent: '',\n\t\t\t\t\tpartial: true,\n\t\t\t\t\t...(request.usage === undefined ? {} : { usage: request.usage }),\n\t\t\t\t}),\n\t\t\t)\n\t\t\tconst passes = [first]\n\t\t\tif (!caller.aborted && (first.partial || first.content.trim() === '')) {\n\t\t\t\tconst digest = this.#buildDigest(request, entered)\n\t\t\t\tif (digest !== undefined)\n\t\t\t\t\tthis.#annotations.add(this.#conversation.add({ role: 'user', content: digest }).id)\n\t\t\t\tthis.#annotations.add(\n\t\t\t\t\tthis.#conversation.add({ role: 'user', content: LEDGER_NOTES.cue }).id,\n\t\t\t\t)\n\t\t\t\tconst previous = this.#agent.context.scope\n\t\t\t\tthis.#agent.context.apply(\n\t\t\t\t\tcreateScope({\n\t\t\t\t\t\tname: 'answer',\n\t\t\t\t\t\ttools: [],\n\t\t\t\t\t\tselect: async (_conversation, message, selecting) => {\n\t\t\t\t\t\t\tconst selection = await this.#select(message, selecting)\n\t\t\t\t\t\t\tif (selection.fault !== undefined) return selection\n\t\t\t\t\t\t\treturn {\n\t\t\t\t\t\t\t\t...selection,\n\t\t\t\t\t\t\t\tmessages: selection.messages.filter((one) => one.role !== 'tool' && !hasCalls(one)),\n\t\t\t\t\t\t\t}\n\t\t\t\t\t\t},\n\t\t\t\t\t}),\n\t\t\t\t)\n\t\t\t\ttry {\n\t\t\t\t\tpasses.push(await this.#generatePass(request, caller, false))\n\t\t\t\t} finally {\n\t\t\t\t\tthis.#agent.context.apply(previous)\n\t\t\t\t}\n\t\t\t}\n\t\t\tconst last = passes.at(-1) ?? first\n\t\t\trequest.think(this.#conversation.messages())\n\t\t\tconst calls = request.calls\n\t\t\tthis.#gauge?.observe(\n\t\t\t\tcalls,\n\t\t\t\t!last.partial && last.content.trim() !== '' ? calls.at(-1) : undefined,\n\t\t\t)\n\t\t\tconst usage = passes.reduce<TokenUsage | undefined>(\n\t\t\t\t(total, pass) => (pass.usage === undefined ? total : sumUsage(total, pass.usage)),\n\t\t\t\tundefined,\n\t\t\t)\n\t\t\t// Joined as a `joinThinking` fold would join them: an empty part adds no separator.\n\t\t\tconst parts = passes.flatMap((pass) => (pass.thinking === undefined ? [] : [pass.thinking]))\n\t\t\treturn {\n\t\t\t\tcontent: last.content,\n\t\t\t\tpartial: last.partial,\n\t\t\t\tpasses,\n\t\t\t\treadings: request.readings,\n\t\t\t\t...(usage === undefined ? {} : { usage }),\n\t\t\t\t...(parts.length === 0\n\t\t\t\t\t? {}\n\t\t\t\t\t: { thinking: parts.filter((part) => part.length > 0).join('\\n\\n') }),\n\t\t\t\t...(last.stop === undefined ? {} : { stop: last.stop }),\n\t\t\t}\n\t\t} finally {\n\t\t\tthis.#flush()\n\t\t\tthis.#live.delete(request)\n\t\t}\n\t}\n\n\tasync #measureGauge(signal: AbortSignal): Promise<LedgerGauge> {\n\t\ttry {\n\t\t\tconst messages = stripThinking(\n\t\t\t\t[\n\t\t\t\t\t{ id: 'system', role: 'system', content: this.#options.system },\n\t\t\t\t\t...this.#conversation.view(),\n\t\t\t\t\t{ id: 'calibration', role: 'user', content: '' },\n\t\t\t\t],\n\t\t\t\tthis.#replay,\n\t\t\t).slice(0, -1)\n\t\t\tconst priced = await this.#provider.generate(\n\t\t\t\tmessages,\n\t\t\t\tsignal,\n\t\t\t\tthis.#agent.context.tools.definitions(),\n\t\t\t\t{ think: false },\n\t\t\t)\n\t\t\tconst bare = await this.#provider.generate(messages, signal, undefined, { think: false })\n\t\t\tif (\n\t\t\t\t!isFiniteNumber(priced.usage?.prompt) ||\n\t\t\t\tpriced.usage.prompt <= 0 ||\n\t\t\t\t!isFiniteNumber(bare.usage?.prompt) ||\n\t\t\t\tbare.usage.prompt <= 0\n\t\t\t)\n\t\t\t\tthrow new LedgerError('GAUGE', 'calibration requires prompt usage from both calls')\n\t\t\tthis.#gauge = new Gauge({\n\t\t\t\tcapacity: this.#options.capacity,\n\t\t\t\tpredict: this.#predict,\n\t\t\t\treplay: this.#replay,\n\t\t\t\tscale: bare.usage.prompt / estimateMessages(messages),\n\t\t\t\toverhead: Math.max(0, priced.usage.prompt - bare.usage.prompt),\n\t\t\t})\n\t\t\treturn { scale: this.#gauge.scale, overhead: this.#gauge.overhead }\n\t\t} catch (error) {\n\t\t\tsignal.throwIfAborted()\n\t\t\tthrow error\n\t\t}\n\t}\n\n\tasync #generatePass(\n\t\trequest: LedgerRequest,\n\t\tsignal: AbortSignal,\n\t\tthink?: boolean,\n\t): Promise<AgentResult> {\n\t\trequest.open(this.#conversation.messages().length)\n\t\treturn await this.#agent.generate({ signal, ...(think === undefined ? {} : { think }) })\n\t}\n\n\t// The live `respond` call's request once it has entered its message; a run during the call's\n\t// calibration reaches none. A refusal on every add caps the registry at one request.\n\t#current(): LedgerRequest | undefined {\n\t\tconst [request] = this.#live\n\t\treturn request?.message === undefined ? undefined : request\n\t}\n\n\t#busy(): boolean {\n\t\treturn this.#live.size > 0 || this.#calibrations.size > 0\n\t}\n\n\t#flush(): void {\n\t\t// Filing calls this once per message, and reading the messages copies them all.\n\t\tif (this.#pending.size === 0) return\n\t\tconst messages = this.#conversation.messages()\n\t\tfor (const [at, result] of this.#pending) {\n\t\t\tconst message = messages[at]\n\t\t\tif (message?.role === 'tool') {\n\t\t\t\tthis.#results.set(message.id, result)\n\t\t\t\tthis.#pending.delete(at)\n\t\t\t}\n\t\t}\n\t}\n\n\t#assign(message: Message): LedgerCategory | undefined {\n\t\tthis.#flush()\n\t\tif (this.#annotations.has(message.id)) return 'chatter'\n\t\tif (message.role === 'tool') {\n\t\t\tthis.#readLookups()\n\t\t\treturn this.#results.get(message.id)?.success === false ? 'chatter' : 'fact'\n\t\t}\n\t\tif (message.role !== 'assistant') return undefined\n\t\tif (hasCalls(message)) return 'chatter'\n\t\tconst messages = this.#conversation.messages()\n\t\tconst first = messages.findIndex((one) => this.#requests.has(one.id))\n\t\treturn first >= 0 && messages.findIndex((one) => one.id === message.id) > first\n\t\t\t? 'chatter'\n\t\t\t: undefined\n\t}\n\n\t#readLookups(): readonly LedgerLookupReading[] {\n\t\tthis.#flush()\n\t\treturn collectToolGroups(this.#conversation.messages()).flatMap((group) =>\n\t\t\tgroup.slice(1).flatMap((message): LedgerLookupReading[] => {\n\t\t\t\tconst call = findLedgerCall(group, message)\n\t\t\t\tconst lookup = this.#options.lookups?.find((one) => one.tool.name === call?.name)\n\t\t\t\tif (\n\t\t\t\t\tcall === undefined ||\n\t\t\t\t\tlookup === undefined ||\n\t\t\t\t\tthis.#results.get(message.id)?.success === false\n\t\t\t\t)\n\t\t\t\t\treturn []\n\t\t\t\tconst reading = attempt(() => lookup.read(call.arguments, message.content))\n\t\t\t\tif (!reading.success) {\n\t\t\t\t\t// Caches the failed read, so no later reading calls its handler again.\n\t\t\t\t\tthis.#results.set(message.id, {\n\t\t\t\t\t\tsuccess: false,\n\t\t\t\t\t\tid: call.id,\n\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\terror: isError(reading.error) ? reading.error.message : String(reading.error),\n\t\t\t\t\t})\n\t\t\t\t\treturn []\n\t\t\t\t}\n\t\t\t\tconst result = reading.value\n\t\t\t\treturn [\n\t\t\t\t\t{\n\t\t\t\t\t\tid: message.id,\n\t\t\t\t\t\tname: call.name,\n\t\t\t\t\t\targuments: call.arguments,\n\t\t\t\t\t\ttext: message.content,\n\t\t\t\t\t\tresult:\n\t\t\t\t\t\t\tresult === undefined\n\t\t\t\t\t\t\t\t? undefined\n\t\t\t\t\t\t\t\t: {\n\t\t\t\t\t\t\t\t\t\t...result,\n\t\t\t\t\t\t\t\t\t\tids: [\n\t\t\t\t\t\t\t\t\t\t\t...new Set([\n\t\t\t\t\t\t\t\t\t\t\t\t...result.ids,\n\t\t\t\t\t\t\t\t\t\t\t\t...Object.values(call.arguments)\n\t\t\t\t\t\t\t\t\t\t\t\t\t.filter(isString)\n\t\t\t\t\t\t\t\t\t\t\t\t\t.flatMap((value) => [...extractTokens(value).ids]),\n\t\t\t\t\t\t\t\t\t\t\t]),\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t\t\t\t},\n\t\t\t\t\t},\n\t\t\t\t]\n\t\t\t}),\n\t\t)\n\t}\n\n\t#project(): { readonly input: LedgerProjectionInput; readonly projection: LedgerProjection } {\n\t\tconst readings = this.#readLookups()\n\t\tconst registry = collectRegistry(readings)\n\t\tconst messages = this.#conversation.messages()\n\t\tconst input: LedgerProjectionInput = {\n\t\t\tsystem: this.#options.system,\n\t\t\texclusions: [...this.#requests, ...this.#annotations],\n\t\t\towners: registry.owners,\n\t\t\tmessages,\n\t\t\treadings,\n\t\t\tentities: new Map(\n\t\t\t\tmessages.map((message) => [\n\t\t\t\t\tmessage.id,\n\t\t\t\t\t[...matchEntities(registry, message.content, true)],\n\t\t\t\t]),\n\t\t\t),\n\t\t\tclassification: this.#classifier.classification(),\n\t\t}\n\t\treturn { input, projection: buildRecords(input) }\n\t}\n\n\t#projectLines(input: LedgerProjectionInput, id: string) {\n\t\treturn buildLines(\n\t\t\tinput,\n\t\t\tnew Map(input.messages.map((message) => [message.id, message])),\n\t\t\tid,\n\t\t\t[...input.owners.values()].flat(),\n\t\t\tcollectNames(this.#options.system),\n\t\t)\n\t}\n\n\t#renderSource(id: string, lines: readonly LedgerLine[], context: LedgerRenderContext): string {\n\t\tconst message = this.#conversation.message(id)\n\t\tif (message === undefined) return ''\n\t\tconst sentences = splitSentences(message.content)\n\t\tconst text = sentences.every((_, index) => lines.some((line) => line.sentence === index))\n\t\t\t? message.content\n\t\t\t: lines.map((line) => sentences[line.sentence] ?? '').join(' ')\n\t\tif (text === '') return ''\n\t\tconst reading = this.#readLookups().find((one) => one.id === id)\n\t\treturn [\n\t\t\t...lines.map((line) => renderLedgerAnnotation(line, context)),\n\t\t\tmessage.role !== 'tool' || reading === undefined\n\t\t\t\t? text\n\t\t\t\t: `${renderLookupCall(reading.name, reading.arguments)}: ${text}`,\n\t\t]\n\t\t\t.filter((part) => part !== '')\n\t\t\t.join('\\n')\n\t}\n\n\t#collectAfter(request: Message): readonly Message[] {\n\t\tconst messages = this.#conversation.messages()\n\t\tconst start = messages.findIndex((message) => message.id === request.id)\n\t\treturn messages\n\t\t\t.slice(start + 1)\n\t\t\t.filter(\n\t\t\t\t(message) =>\n\t\t\t\t\tmessage.role !== 'assistant' || hasCalls(message) || message.content.trim() !== '',\n\t\t\t)\n\t}\n\n\tasync #select(message: Message, signal: AbortSignal): Promise<Selection> {\n\t\tconst request = this.#current()\n\t\tconst selected = request?.message\n\t\tif (\n\t\t\trequest === undefined ||\n\t\t\tselected === undefined ||\n\t\t\t(message.id !== selected.id && !this.#annotations.has(message.id))\n\t\t)\n\t\t\treturn this.#refuse(\n\t\t\t\tnew LedgerError(\n\t\t\t\t\t'REQUEST',\n\t\t\t\t\t'ledger selection requires a request owned by an active respond call',\n\t\t\t\t),\n\t\t\t\t{ judgments: [] },\n\t\t\t)\n\t\tconst plan = request.plan\n\t\tif (this.#annotations.has(message.id) && plan !== undefined)\n\t\t\treturn {\n\t\t\t\tmessages: [...plan.messages, ...this.#collectAfter(selected)],\n\t\t\t\tjudgments: [],\n\t\t\t\t...(plan.briefing === undefined ? {} : { briefing: plan.briefing }),\n\t\t\t}\n\t\treturn await this.#classifier.classify(this.#requests, signal).then(\n\t\t\t(classified) => this.#file(classified, request, selected, message),\n\t\t\t(error: unknown) => this.#refuse(error, { judgments: [] }),\n\t\t)\n\t}\n\n\t// Files a classification's readings into the request and plans the selection, falling back to\n\t// the conversation view when the filing faulted or planning threw.\n\t#file(\n\t\tclassified: ClassifierResult,\n\t\trequest: LedgerRequest,\n\t\tselected: Message,\n\t\tmessage: Message,\n\t): Selection {\n\t\tconst { readings, ...filed } = classified\n\t\tconst planned = attempt(() => {\n\t\t\tif (filed.fault !== undefined) throw filed.fault\n\t\t\treturn { ...this.#plan(selected), ...filed }\n\t\t})\n\t\trequest.file(readings, planned.success ? planned.value : undefined)\n\t\tif (!planned.success) return this.#refuse(planned.error, filed)\n\t\treturn this.#annotations.has(message.id)\n\t\t\t? {\n\t\t\t\t\t...planned.value,\n\t\t\t\t\tmessages: [...planned.value.messages, ...this.#collectAfter(selected)],\n\t\t\t\t}\n\t\t\t: planned.value\n\t}\n\n\t// Falls back to the conversation view with the failure as the selection's fault, keeping the\n\t// filing completed before it.\n\t#refuse(error: unknown, filing: Omit<ClassifierResult, 'readings'>): Selection {\n\t\treturn {\n\t\t\t...filing,\n\t\t\tmessages: this.#conversation.view(),\n\t\t\tfault: isError(error) ? error : new Error(String(error)),\n\t\t}\n\t}\n\n\t#price(messages: readonly Message[]): number {\n\t\treturn (this.#gauge?.scale ?? 1) * estimateMessages(messages)\n\t}\n\n\t#plan(request: Message): Pick<Selection, 'messages' | 'briefing'> {\n\t\tconst { input, projection } = this.#project()\n\t\tconst registry = collectRegistry(input.readings)\n\t\tconst links = linkOwners(input.readings, registry.owners)\n\t\tconst near = new Set([\n\t\t\t...matchEntities(registry, request.content, true),\n\t\t\t...this.#classifier.topics(request.id),\n\t\t])\n\t\tconst owners = [...near].flatMap((id) => {\n\t\t\tconst owner = registry.owners.has(id) ? id : links.get(id)\n\t\t\treturn owner === undefined ? [] : [owner]\n\t\t})\n\t\tconst records = selectRecords(projection, { owners, topics: [...near] })\n\t\tconst total =\n\t\t\tMath.max(\n\t\t\t\t0,\n\t\t\t\t(this.#options.capacity - this.#predict) * this.#share.prompt -\n\t\t\t\t\t(this.#gauge?.overhead ?? 0),\n\t\t\t) /\n\t\t\t(1 + LEDGER_SCALE_DRIFT)\n\t\tconst tail = this.#selectTail(request, total * this.#share.tail, input)\n\t\tconst cap = total - this.#price(stripThinking(tail, this.#replay))\n\t\tconst tailIds = new Set(tail.map((message) => message.id))\n\t\tconst scoped = records.some((record) => record.key !== LEDGER_RULES_KEY)\n\t\tconst held = new Set([\n\t\t\t...projection.records\n\t\t\t\t.filter((record) => scoped || record.key === LEDGER_RULES_KEY)\n\t\t\t\t.flatMap((record) => record.members),\n\t\t\t...(records.length > 0\n\t\t\t\t? projection.records.flatMap((record) =>\n\t\t\t\t\t\trecord.members.filter(\n\t\t\t\t\t\t\t(id) =>\n\t\t\t\t\t\t\t\tthis.#conversation.message(id)?.role === 'user' &&\n\t\t\t\t\t\t\t\tthis.#classifier.category(id) === 'rule' &&\n\t\t\t\t\t\t\t\tthis.#classifier.decisive(id),\n\t\t\t\t\t\t),\n\t\t\t\t\t)\n\t\t\t\t: []),\n\t\t])\n\t\tconst texts = input.messages\n\t\t\t.filter((message) => !hasCalls(message))\n\t\t\t.map((message) => ({\n\t\t\t\tmessage,\n\t\t\t\t...extractWords(message),\n\t\t\t}))\n\t\tconst asked = texts.find(({ message }) => message.id === request.id)\n\t\tconst counts = new Map(\n\t\t\t[\n\t\t\t\t...Map.groupBy(\n\t\t\t\t\ttexts.flatMap((text) => [...text.words]),\n\t\t\t\t\t(word) => word,\n\t\t\t\t),\n\t\t\t].map(([word, occurrences]) => [word, occurrences.length]),\n\t\t)\n\t\tconst live = collectProjectionIds(projection)\n\t\tconst units = texts.flatMap(({ message, words, names }, position) => {\n\t\t\tif (\n\t\t\t\t!live.has(message.id) ||\n\t\t\t\theld.has(message.id) ||\n\t\t\t\t(message.role !== 'tool' && tailIds.has(message.id))\n\t\t\t)\n\t\t\t\treturn []\n\t\t\tconst tokens = extractTokens(message.content)\n\t\t\tif (message.role === 'user' && tokens.ids.size + tokens.numbers.size + names.size === 0)\n\t\t\t\treturn []\n\t\t\tconst category = this.#classifier.category(message.id)\n\t\t\tconst unsettled = message.role === 'user' && !this.#classifier.decisive(message.id)\n\t\t\tconst topics = new Set([\n\t\t\t\t...(input.entities.get(message.id) ?? []),\n\t\t\t\t...this.#classifier.topics(message.id),\n\t\t\t])\n\t\t\tconst ruled = !unsettled && (category === 'rule' || category === 'correction')\n\t\t\tconst group = [...topics].some((topic) => near.has(topic))\n\t\t\t\t? 1\n\t\t\t\t: ruled\n\t\t\t\t\t? 2\n\t\t\t\t\t: [...names].some((name) => asked?.names.has(name))\n\t\t\t\t\t\t? 3\n\t\t\t\t\t\t: 4\n\t\t\tif (group === 4) return []\n\t\t\tconst score = [...words]\n\t\t\t\t.filter((word) => asked?.words.has(word))\n\t\t\t\t.reduce((sum, word) => sum + Math.log(texts.length / (counts.get(word) ?? 1)), 0)\n\t\t\treturn [\n\t\t\t\t{\n\t\t\t\t\tsource: message.id,\n\t\t\t\t\tlines: this.#projectLines(input, message.id),\n\t\t\t\t\tposition,\n\t\t\t\t\tgroup,\n\t\t\t\t\truled,\n\t\t\t\t\tunsettled: unsettled,\n\t\t\t\t\tscore,\n\t\t\t\t\tcategory,\n\t\t\t\t\tcut: rankLedgerCut(group, unsettled, category),\n\t\t\t\t},\n\t\t\t]\n\t\t})\n\t\tconst ordered = [...units].sort(\n\t\t\t(left, right) =>\n\t\t\t\tleft.group - right.group ||\n\t\t\t\t(left.group === 1 ? Number(left.unsettled) - Number(right.unsettled) : 0) ||\n\t\t\t\t((left.group === 1 && left.unsettled) || left.group === 3 ? right.score - left.score : 0) ||\n\t\t\t\tleft.position - right.position,\n\t\t)\n\t\tconst cuts = [...ordered].sort(\n\t\t\t(left, right) =>\n\t\t\t\tleft.cut - right.cut ||\n\t\t\t\t(left.cut === 0 || left.cut === 1 || left.cut === 4 ? left.score - right.score : 0) ||\n\t\t\t\tright.position - left.position,\n\t\t)\n\t\tconst rules = records.find((record) => record.key === LEDGER_RULES_KEY)\n\t\tconst steps = [\n\t\t\t...(rules?.lines\n\t\t\t\t.filter((line) => !line.topics.some((topic) => near.has(topic)))\n\t\t\t\t.map(() => ({ key: rules.key, source: undefined })) ?? []),\n\t\t\t...cuts.map((unit) => ({ key: undefined, source: unit.source })),\n\t\t\t...(rules?.lines\n\t\t\t\t.filter((line) => line.topics.some((topic) => near.has(topic)))\n\t\t\t\t.map(() => ({ key: rules.key, source: undefined })) ?? []),\n\t\t\t...records\n\t\t\t\t.filter((record) => record.key !== LEDGER_RULES_KEY)\n\t\t\t\t.flatMap((record) => record.lines.map(() => ({ key: record.key, source: undefined })))\n\t\t\t\t.reverse(),\n\t\t]\n\t\tconst mapped = ordered.map((unit) => ({\n\t\t\tsource: unit.source,\n\t\t\trecord: this.#buildUnitRecord(unit.source, unit.category, input, projection, held),\n\t\t}))\n\t\tconst trimmed = this.#trim(\n\t\t\tsteps,\n\t\t\trecords,\n\t\t\tmapped,\n\t\t\tnew Set(ordered.map((unit) => unit.source)),\n\t\t\tcap,\n\t\t\tprojection.amendments,\n\t\t)\n\t\tconst briefing = trimmed.briefing\n\t\tconst shown = new Set([\n\t\t\t...trimmed.included,\n\t\t\t...records.flatMap((record) =>\n\t\t\t\trecord.members.filter((source) => {\n\t\t\t\t\tconst full = record.lines.filter((line) => line.source === source)\n\t\t\t\t\tconst visible =\n\t\t\t\t\t\ttrimmed.records\n\t\t\t\t\t\t\t.find((one) => one.key === record.key)\n\t\t\t\t\t\t\t?.lines.filter((line) => line.source === source) ?? []\n\t\t\t\t\treturn full.length > 0 && full.length === visible.length\n\t\t\t\t}),\n\t\t\t),\n\t\t])\n\t\treturn {\n\t\t\tmessages: tail.map((message) =>\n\t\t\t\tmessage.role === 'tool' ? this.#renderTailStub(message, shown) : message,\n\t\t\t),\n\t\t\t...(briefing === '' ? {} : { briefing }),\n\t\t}\n\t}\n\n\t// Renders the briefing for each cut in step order (each step drops the last line of the record\n\t// it keys or the source it names) and returns the first cut whose system message fits `cap`; the\n\t// cut after every step is returned unchecked. No cut renders after the one returned.\n\t#trim(\n\t\tsteps: ReadonlyArray<{ readonly key: string | undefined; readonly source: string | undefined }>,\n\t\trecords: readonly LedgerRecord[],\n\t\tmapped: ReadonlyArray<{ readonly source: string; readonly record: LedgerRecord }>,\n\t\tincluded: ReadonlySet<string>,\n\t\tcap: number,\n\t\tamendments: readonly LedgerAmendment[],\n\t): {\n\t\treadonly briefing: string\n\t\treadonly records: readonly LedgerRecord[]\n\t\treadonly included: ReadonlySet<string>\n\t} {\n\t\tconst trimmed = steps.reduce<{\n\t\t\treadonly briefing: string | undefined\n\t\t\treadonly records: readonly LedgerRecord[]\n\t\t\treadonly included: ReadonlySet<string>\n\t\t}>(\n\t\t\t(cut, step) => {\n\t\t\t\tif (cut.briefing !== undefined) return cut\n\t\t\t\tconst briefing = this.#render(cut.records, mapped, cut.included, amendments)\n\t\t\t\tconst content = [this.#options.system, briefing].filter((part) => part !== '').join('\\n\\n')\n\t\t\t\tif (this.#price([{ id: 'system', role: 'system', content }]) <= cap)\n\t\t\t\t\treturn { ...cut, briefing }\n\t\t\t\treturn {\n\t\t\t\t\tbriefing: undefined,\n\t\t\t\t\trecords: cut.records.map((record) =>\n\t\t\t\t\t\trecord.key === step.key ? { ...record, lines: record.lines.slice(0, -1) } : record,\n\t\t\t\t\t),\n\t\t\t\t\tincluded: new Set([...cut.included].filter((source) => source !== step.source)),\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ briefing: undefined, records, included },\n\t\t)\n\t\treturn {\n\t\t\trecords: trimmed.records,\n\t\t\tincluded: trimmed.included,\n\t\t\tbriefing:\n\t\t\t\ttrimmed.briefing ?? this.#render(trimmed.records, mapped, trimmed.included, amendments),\n\t\t}\n\t}\n\n\t#buildUnitRecord(\n\t\tsource: string,\n\t\tcategory: LedgerCategory | undefined,\n\t\tinput: LedgerProjectionInput,\n\t\tprojection: LedgerProjection,\n\t\theld: ReadonlySet<string>,\n\t): LedgerRecord {\n\t\treturn {\n\t\t\tkey: category === 'rule' ? LEDGER_RULES_KEY : source,\n\t\t\ttitle: '',\n\t\t\tmembers: [source],\n\t\t\tlines: this.#collectAmended(\n\t\t\t\tinput,\n\t\t\t\tprojection,\n\t\t\t\tsource,\n\t\t\t\tcategory === 'rule'\n\t\t\t\t\t? new Set(projection.records.flatMap((record) => record.members))\n\t\t\t\t\t: held,\n\t\t\t),\n\t\t}\n\t}\n\n\t#collectAmended(\n\t\tinput: LedgerProjectionInput,\n\t\tprojection: LedgerProjection,\n\t\tsource: string,\n\t\theld: ReadonlySet<string>,\n\t): readonly LedgerLine[] {\n\t\tconst live = collectProjectionIds(projection)\n\t\treturn scanAmendments(\n\t\t\tinput.classification.amendments,\n\t\t\tsource,\n\t\t\t(id) => id === source || (!held.has(id) && live.has(id)),\n\t\t).flatMap((id) => this.#projectLines(input, id))\n\t}\n\n\t#render(\n\t\trecords: readonly LedgerRecord[],\n\t\tmapped: ReadonlyArray<{ readonly source: string; readonly record: LedgerRecord }>,\n\t\tincluded: ReadonlySet<string>,\n\t\tamendments: readonly LedgerAmendment[],\n\t): string {\n\t\tconst entries = mapped\n\t\t\t.filter((unit) => included.has(unit.source))\n\t\t\t.flatMap(({ record: unit }) =>\n\t\t\t\t[...Map.groupBy(unit.lines, (line) => line.source)].map(([source, lines]) => ({\n\t\t\t\t\tunit,\n\t\t\t\t\tsource,\n\t\t\t\t\tlines,\n\t\t\t\t})),\n\t\t\t)\n\t\t// A source renders once, under the first unit that carries it.\n\t\tconst first = new Map(entries.toReversed().map((entry) => [entry.source, entry]))\n\t\tconst unique = entries.filter((entry) => first.get(entry.source) === entry)\n\t\tconst record = records.find(\n\t\t\t(candidate) => candidate.key === LEDGER_RULES_KEY && candidate.lines.length > 0,\n\t\t)\n\t\tconst ownerRecords = records.filter(\n\t\t\t(candidate) => candidate.key !== LEDGER_RULES_KEY && candidate.lines.length > 0,\n\t\t)\n\t\t// The context reads the lines in the order the briefing emits them, so each source's first\n\t\t// retained line carries its annotation and its reference.\n\t\tconst context = buildLedgerRenderContext(\n\t\t\tthis.#conversation.messages(),\n\t\t\t[\n\t\t\t\t...ownerRecords.flatMap((candidate) => candidate.lines),\n\t\t\t\t...unique\n\t\t\t\t\t.filter((entry) => entry.unit.key !== LEDGER_RULES_KEY)\n\t\t\t\t\t.flatMap((entry) => entry.lines),\n\t\t\t\t...(record?.lines ?? []),\n\t\t\t\t...unique\n\t\t\t\t\t.filter((entry) => entry.unit.key === LEDGER_RULES_KEY)\n\t\t\t\t\t.flatMap((entry) => entry.lines),\n\t\t\t],\n\t\t\tamendments,\n\t\t)\n\t\tconst owners = ownerRecords.map((owner) => renderLedgerPinned(owner, context)).join('\\n\\n')\n\t\tconst rendered = unique.map(({ unit, source, lines }) => ({\n\t\t\trules: unit.key === LEDGER_RULES_KEY,\n\t\t\ttexts:\n\t\t\t\tunit.key === LEDGER_RULES_KEY && source === unit.members[0]\n\t\t\t\t\t? lines.map((line) => this.#renderSource(source, [line], context))\n\t\t\t\t\t: [this.#renderSource(source, lines, context)],\n\t\t}))\n\t\tconst pinned = rendered.filter((one) => !one.rules).flatMap((one) => one.texts)\n\t\tconst rules = rendered.filter((one) => one.rules).flatMap((one) => one.texts)\n\t\tconst body = [owners, pinned.join('\\n')].filter((text) => text !== '').join('\\n\\n')\n\t\treturn [\n\t\t\tbody === '' ? '' : `## Pinned\\n${body}`,\n\t\t\trecord === undefined\n\t\t\t\t? rules.length === 0\n\t\t\t\t\t? ''\n\t\t\t\t\t: ['## Rules', ...rules].join('\\n')\n\t\t\t\t: [renderLedgerRecord(record, context), ...rules].join('\\n'),\n\t\t]\n\t\t\t.filter((text) => text !== '')\n\t\t\t.join('\\n\\n')\n\t}\n\n\t#selectTail(request: Message, cap: number, input: LedgerProjectionInput): readonly Message[] {\n\t\tconst first = input.messages.findIndex((message) => this.#requests.has(message.id))\n\t\tconst seed = input.messages.slice(\n\t\t\t0,\n\t\t\tfirst < 0 ? input.messages.findIndex((message) => message.id === request.id) : first,\n\t\t)\n\t\tconst groups = collectToolGroups(seed).flatMap((group) => {\n\t\t\tconst leader = group[0]\n\t\t\tif (leader === undefined) return []\n\t\t\tconst kept = (leader.calls ?? []).flatMap((call) => {\n\t\t\t\tconst message = group.slice(1).find((result) => findLedgerCall(group, result) === call)\n\t\t\t\tconst result = message === undefined ? undefined : this.#results.get(message.id)\n\t\t\t\treturn message === undefined ||\n\t\t\t\t\t!this.#options.lookups?.some((lookup) => lookup.tool.name === call.name) ||\n\t\t\t\t\t(result?.success === false && result.error === LEDGER_NOTES.repeat)\n\t\t\t\t\t? []\n\t\t\t\t\t: [{ call, message }]\n\t\t\t})\n\t\t\treturn [{ leader, kept }]\n\t\t})\n\t\tconst calls = new Map<string, readonly ToolCall[]>(\n\t\t\tgroups.map(({ leader, kept }) => [leader.id, kept.map(({ call }) => call)]),\n\t\t)\n\t\tconst results = new Set(groups.flatMap(({ kept }) => kept.map(({ message }) => message.id)))\n\t\tconst history = seed\n\t\t\t.filter(\n\t\t\t\t(message) =>\n\t\t\t\t\t!this.#annotations.has(message.id) &&\n\t\t\t\t\t(message.role !== 'tool' || results.has(message.id)) &&\n\t\t\t\t\t!(\n\t\t\t\t\t\tmessage.role === 'assistant' &&\n\t\t\t\t\t\thasCalls(message) &&\n\t\t\t\t\t\t(calls.get(message.id)?.length ?? 0) === 0 &&\n\t\t\t\t\t\tmessage.content === ''\n\t\t\t\t\t),\n\t\t\t)\n\t\t\t.map((message) =>\n\t\t\t\tmessage.role === 'tool'\n\t\t\t\t\t? this.#renderTailStub(message)\n\t\t\t\t\t: calls.has(message.id)\n\t\t\t\t\t\t? (calls.get(message.id)?.length ?? 0) > 0\n\t\t\t\t\t\t\t? { ...message, calls: calls.get(message.id) ?? [] }\n\t\t\t\t\t\t\t: { id: message.id, role: message.role, content: message.content }\n\t\t\t\t\t\t: message,\n\t\t\t)\n\t\t// Newest exchange first: the tail keeps every exchange before the first whose addition passes\n\t\t// `cap`, and each candidate is the kept exchanges in conversation order, then the request.\n\t\tconst exchanges = collectExchanges(history).toReversed()\n\t\tconst stop = exchanges.findIndex(\n\t\t\t(_exchange, index) =>\n\t\t\t\tthis.#price(\n\t\t\t\t\tstripThinking(\n\t\t\t\t\t\t[\n\t\t\t\t\t\t\t...exchanges\n\t\t\t\t\t\t\t\t.slice(0, index + 1)\n\t\t\t\t\t\t\t\t.toReversed()\n\t\t\t\t\t\t\t\t.flat(),\n\t\t\t\t\t\t\trequest,\n\t\t\t\t\t\t],\n\t\t\t\t\t\tthis.#replay,\n\t\t\t\t\t),\n\t\t\t\t) > cap,\n\t\t)\n\t\treturn [\n\t\t\t...exchanges\n\t\t\t\t.slice(0, stop === -1 ? exchanges.length : stop)\n\t\t\t\t.toReversed()\n\t\t\t\t.flat(),\n\t\t\trequest,\n\t\t]\n\t}\n\n\t#renderTailStub(message: Message, shown?: ReadonlySet<string>): Message {\n\t\tconst group = collectToolGroups(this.#conversation.messages()).find((entries) =>\n\t\t\tentries.some((one) => one.id === message.id),\n\t\t)\n\t\tconst call = group === undefined ? undefined : findLedgerCall(group, message)\n\t\tconst reading = this.#readLookups().find((one) => one.id === message.id)\n\t\tconst hidden = renderStub(call?.name ?? 'tool', call?.arguments ?? {}, 'hidden')\n\t\tconst visible = renderStub(call?.name ?? 'tool', call?.arguments ?? {}, 'shown')\n\t\treturn {\n\t\t\t...message,\n\t\t\tcontent: renderStub(\n\t\t\t\tcall?.name ?? 'tool',\n\t\t\t\tcall?.arguments ?? {},\n\t\t\t\tthis.#results.get(message.id)?.success === false\n\t\t\t\t\t? 'failed'\n\t\t\t\t\t: reading?.result === undefined\n\t\t\t\t\t\t? 'empty'\n\t\t\t\t\t\t: shown === undefined\n\t\t\t\t\t\t\t? hidden.length > visible.length\n\t\t\t\t\t\t\t\t? 'hidden'\n\t\t\t\t\t\t\t\t: 'shown'\n\t\t\t\t\t\t\t: shown.has(message.id)\n\t\t\t\t\t\t\t\t? 'shown'\n\t\t\t\t\t\t\t\t: 'hidden',\n\t\t\t),\n\t\t}\n\t}\n\n\t#observeTurn(): void {\n\t\tthis.#flush()\n\t\tconst request = this.#current()\n\t\tconst boundary = request?.boundary\n\t\tif (request === undefined || boundary === undefined) return\n\t\tconst additions = this.#conversation.messages().slice(boundary)\n\t\tconst messages = this.#agent.context.build(request.selection)\n\t\tconst names = this.#agent.context.scope?.tools\n\t\trequest.observe(\n\t\t\t{\n\t\t\t\testimate: estimateMessages(stripThinking([...messages, ...additions], this.#replay)),\n\t\t\t\ttools: this.#agent.context.tools\n\t\t\t\t\t.definitions()\n\t\t\t\t\t.filter((tool) => names === undefined || names.includes(tool.name)).length,\n\t\t\t},\n\t\t\tthis.#conversation.messages().length,\n\t\t)\n\t}\n\n\t#findLongest(): string {\n\t\treturn this.#conversation\n\t\t\t.messages()\n\t\t\t.filter((message) => message.role === 'assistant')\n\t\t\t.reduce(\n\t\t\t\t(longest, message) => (message.content.length > longest.length ? message.content : longest),\n\t\t\t\t'',\n\t\t\t)\n\t}\n\n\t#lookup(name: string, args: Readonly<Record<string, unknown>>, context: ToolContext): unknown {\n\t\tthis.#current()?.admit(name, args)\n\t\tconst lookup = this.#options.lookups?.find((one) => one.tool.name === name)\n\t\tif (lookup === undefined) throw new Error(`unknown lookup ${name}`)\n\t\treturn lookup.tool.execute(args, context)\n\t}\n\n\t#recall(args: Readonly<Record<string, unknown>>): string {\n\t\tconst request = this.#current()\n\t\trequest?.think(this.#conversation.messages())\n\t\tconst topic = isString(args.topic) ? args.topic.trim() : ''\n\t\trequest?.admit('recall', { topic })\n\t\tconst gauge = this.#gauge\n\t\tconst calls = request?.calls ?? []\n\t\tif (\n\t\t\tgauge !== undefined &&\n\t\t\tcalls.length > 0 &&\n\t\t\tgauge.remainder(calls) - this.#predict < 2 * gauge.reserve(calls, this.#findLongest())\n\t\t)\n\t\t\trequest?.close()\n\t\trequest?.recall()\n\t\tconst guidance = `an owner name, an id, or one of ${renderTopicNames(this.#options.topics)}`\n\t\tif (topic === '') throw new Error(`recall needs a topic: ${guidance}`)\n\t\tconst room =\n\t\t\t(gauge?.room(calls, this.#findLongest()) ?? 0) - estimateMessages([buildRecallMessage(topic)])\n\t\tconst { input, projection } = this.#project()\n\t\tconst registry = collectRegistry(input.readings)\n\t\tconst searches = splitTopic(topic).map((part) => {\n\t\t\tconst words = splitWords(part)\n\t\t\tconst matched = new Set([\n\t\t\t\t...[...registry.ids].filter(\n\t\t\t\t\t(id) =>\n\t\t\t\t\t\textractTokens(part).ids.has(id) ||\n\t\t\t\t\t\twords.every((word) =>\n\t\t\t\t\t\t\t`${id} ${(registry.owners.get(id) ?? []).join(' ')}`.toLowerCase().includes(word),\n\t\t\t\t\t\t),\n\t\t\t\t),\n\t\t\t\t...this.#options.topics\n\t\t\t\t\t.filter((one) => words.every((word) => one.name.toLowerCase().includes(word)))\n\t\t\t\t\t.map((one) => one.name),\n\t\t\t])\n\t\t\treturn { words, matched }\n\t\t})\n\t\tconst start = input.messages.findIndex((message) => message.id === request?.message?.id)\n\t\tconst listable = new Map(\n\t\t\tinput.messages\n\t\t\t\t.filter(\n\t\t\t\t\t(message, at) =>\n\t\t\t\t\t\t!this.#requests.has(message.id) && (at < start || message.role === 'tool'),\n\t\t\t\t)\n\t\t\t\t.map((message) => [message.id, message]),\n\t\t)\n\t\tconst readings = new Map(input.readings.map((reading) => [reading.id, reading]))\n\t\tconst matched = new Set(searches.flatMap((search) => [...search.matched]))\n\t\tconst wordings = searches.filter(\n\t\t\t(search) => search.matched.size === 0 && search.words.length > 0,\n\t\t)\n\t\t// Newest first; each item's amenders are claimed by it, so an older item never lists them again.\n\t\tconst listing = [...listable.values()].reverse().reduce<{\n\t\t\treadonly done: ReadonlySet<string>\n\t\t\treadonly listed: readonly string[]\n\t\t\treadonly recalled: ReadonlyMap<string, string>\n\t\t}>(\n\t\t\t(state, message) => {\n\t\t\t\tconst reading = readings.get(message.id)\n\t\t\t\tconst topics = new Set([\n\t\t\t\t\t...(input.entities.get(message.id) ?? []),\n\t\t\t\t\t...this.#classifier.topics(message.id),\n\t\t\t\t\t...projection.records\n\t\t\t\t\t\t.filter(\n\t\t\t\t\t\t\t(record) =>\n\t\t\t\t\t\t\t\trecord.key.startsWith(LEDGER_OWNER_PREFIX) && record.members.includes(message.id),\n\t\t\t\t\t\t)\n\t\t\t\t\t\t.map((record) => record.key.slice(LEDGER_OWNER_PREFIX.length)),\n\t\t\t\t])\n\t\t\t\tconst onTopic =\n\t\t\t\t\t(message.role === 'tool'\n\t\t\t\t\t\t? reading?.result !== undefined\n\t\t\t\t\t\t: !hasCalls(message) && !this.#classifier.quiet(message.id)) &&\n\t\t\t\t\t[...matched].some((match) => topics.has(match))\n\t\t\t\tconst worded =\n\t\t\t\t\t(message.role === 'tool' ? reading !== undefined : message.role === 'user') &&\n\t\t\t\t\twordings.some((search) =>\n\t\t\t\t\t\tsearch.words.every((word) => message.content.toLowerCase().includes(word)),\n\t\t\t\t\t)\n\t\t\t\tif (!onTopic && !worded) return state\n\t\t\t\tconst items = scanAmendments(\n\t\t\t\t\tinput.classification.amendments,\n\t\t\t\t\tmessage.id,\n\t\t\t\t\t(candidate) => listable.has(candidate) && !state.done.has(candidate),\n\t\t\t\t).flatMap((id) => {\n\t\t\t\t\tconst source = listable.get(id)\n\t\t\t\t\tif (source === undefined) return []\n\t\t\t\t\tconst lookup = readings.get(id)\n\t\t\t\t\tconst text =\n\t\t\t\t\t\tlookup === undefined\n\t\t\t\t\t\t\t? source.content\n\t\t\t\t\t\t\t: `${renderLookupCall(lookup.name, lookup.arguments)}: ${source.content}`\n\t\t\t\t\treturn [\n\t\t\t\t\t\t{\n\t\t\t\t\t\t\tid,\n\t\t\t\t\t\t\ttext,\n\t\t\t\t\t\t\tstored:\n\t\t\t\t\t\t\t\tlookup === undefined\n\t\t\t\t\t\t\t\t\t? []\n\t\t\t\t\t\t\t\t\t: [\n\t\t\t\t\t\t\t\t\t\t\t[\n\t\t\t\t\t\t\t\t\t\t\t\tsplitResultLines(text)[0] ?? '',\n\t\t\t\t\t\t\t\t\t\t\t\tsplitResultLines(source.content)[0] ?? '',\n\t\t\t\t\t\t\t\t\t\t\t] as const,\n\t\t\t\t\t\t\t\t\t\t],\n\t\t\t\t\t\t},\n\t\t\t\t\t]\n\t\t\t\t})\n\t\t\t\treturn {\n\t\t\t\t\tdone: new Set([...state.done, ...items.map((item) => item.id)]),\n\t\t\t\t\tlisted:\n\t\t\t\t\t\titems.length === 0\n\t\t\t\t\t\t\t? state.listed\n\t\t\t\t\t\t\t: [...state.listed, items.map((item) => item.text).join('\\n')],\n\t\t\t\t\trecalled: new Map([...state.recalled, ...items.flatMap((item) => item.stored)]),\n\t\t\t\t}\n\t\t\t},\n\t\t\t{ done: new Set(), listed: [], recalled: new Map() },\n\t\t)\n\t\tconst result =\n\t\t\tlisting.listed.length === 0\n\t\t\t\t? `nothing on \"${topic}\"; recall ${guidance}`\n\t\t\t\t: cutListing(listing.listed, room)\n\t\trequest?.list(result, listing.recalled)\n\t\treturn result\n\t}\n\n\t#buildDigest(request: LedgerRequest, entered: Message): string | undefined {\n\t\tthis.#flush()\n\t\t// Each line once, at its first occurrence.\n\t\tconst lines = [\n\t\t\t...new Set(\n\t\t\t\tthis.#collectAfter(entered).flatMap((message) => {\n\t\t\t\t\tconst result = this.#results.get(message.id)\n\t\t\t\t\tif (message.role !== 'tool' || result?.success !== true) return []\n\t\t\t\t\tconst listing = result.name === 'recall'\n\t\t\t\t\tif (listing && /^nothing on /.test(message.content)) return []\n\t\t\t\t\tconst recalled = listing ? request.listing(message.content) : undefined\n\t\t\t\t\treturn splitResultLines(message.content)\n\t\t\t\t\t\t.filter((line) => !listing || !matchesCutLine(line))\n\t\t\t\t\t\t.map((line) => recalled?.get(line) ?? line)\n\t\t\t\t}),\n\t\t\t),\n\t\t]\n\t\treturn lines.length === 0 ? undefined : `${LEDGER_NOTES.results}\\n${lines.join('\\n')}`\n\t}\n}\n","import type { ProviderInterface } from '../providers/types.js'\nimport type { LedgerInterface, LedgerOptions } from './types.js'\nimport { Ledger } from './Ledger.js'\n\n/**\n * Creates a conversation ledger after checking its thresholds, allocation, and tool names.\n * @param provider - The provider that answers requests\n * @param options - The judge, projection policy, capacity, and agent bounds\n * @returns The ledger and its owned conversation and agent\n * @throws {LedgerError} Thrown when an option lies outside its documented bounds\n * @example\n * ```ts\n * const ledger = createLedger(provider, options)\n * const reply = await ledger.respond('Check the order.')\n * ```\n */\nexport function createLedger(provider: ProviderInterface, options: LedgerOptions): LedgerInterface {\n\treturn new Ledger(provider, options)\n}\n"],"mappings":";;;;;;;;;;;;;;;;AAKA,IAAa,gBAAgB,OAAO,OAAO;CAAC;CAAU;CAAQ;CAAa;AAAM,CAAU;;;;;;;;;;;;;ACiB3F,IAAa,kBAAb,cAAqC,MAAM;;CAE1C,OAAgB;CAChB;CAEA,YAAY,SAAsB,SAAwB;EACzD,MAAM,sBAAsB,OAAO;EACnC,KAAK,OAAO;EACZ,WAAW,OAAO,MAAM,OAAO,IAAI,kCAAkC,GAAG,EAAE,OAAO,KAAK,CAAC;EACvF,KAAK,UAAU;CAChB;AACD;;;;;;;;;;;;AAaA,SAAgB,kBAAkB,OAA0C;CAC3E,OAAO,YAAY;EAClB,IACC,EACC,iBAAiB,SACjB,WAAW,UAAU,KAAK,MAAM,MAAM,aACtC,WAAW,SAAS,OAAO,OAAO,IAAI,kCAAkC,CAAC,CAAC,EAAE,UAAU,QAGvF,OAAO;EAER,IAAI,EADS,WAAW,QAAQ,KAAK,OAAO,MACtC,MAAS,UAAU,OAAO;EAChC,MAAM,UAAU,WAAW,QAAQ,KAAK,OAAO,SAAS;EACxD,IAAI,EAAE,SAAS,OAAO,KAAK,WAAW,OAAO,IAAI,OAAO;EACxD,MAAM,UAAU,WAAW,QAAQ,KAAK,SAAS,SAAS;EAC1D,MAAM,WAAW,WAAW,QAAQ,KAAK,SAAS,UAAU;EAC5D,MAAM,QAAQ,WAAW,QAAQ,KAAK,SAAS,OAAO;EACtD,OACC,SAAS,WAAW,QAAQ,KAAK,SAAS,OAAO,CAAC,MACjD,UAAU,KAAA,MACR,SAAS,KAAK,KAAK,WAAW,KAAK,MACpC;GAAC;GAAU;GAAc;EAAO,CAAC,CAAC,OAAO,QACxC,SAAS,WAAW,QAAQ,KAAK,OAAO,GAAG,CAAC,CAC7C,OACD,SAAS,OAAO,KAAK,WAAW,OAAO,MACxC,WAAW,OAAO,OAAO,CAAC,CAAC,OAAO,WAAoB;GACrD,IAAI,EAAE,SAAS,MAAM,KAAK,WAAW,MAAM,IAAI,OAAO;GACtD,MAAM,OAAO,WAAW,QAAQ,KAAK,QAAQ,MAAM;GACnD,IAAI,SAAS,QAAQ,OAAO,SAAS,WAAW,QAAQ,KAAK,QAAQ,MAAM,CAAC;GAC5E,MAAM,gBAAgB,WAAW,QAAQ,KAAK,QAAQ,eAAe;GACrE,IAAI,SAAS,SAAS,OAAO,QAAQ,QAAQ,CAAC,CAAC,aAAa;GAC5D,OACC,SAAS,aACR,SAAS,aAAa,KAAK,WAAW,aAAa,MACpD,WAAW,OAAO,aAAa,CAAC,CAAC,MAAM,QAAQ;EAEjD,CAAC,MACA,aAAa,KAAA,MACX,SAAS,QAAQ,KAAK,WAAW,QAAQ,MAC1C,WAAW,OAAO,QAAQ,CAAC,CAAC,OAC1B,aACC,SAAS,OAAO,KAAK,WAAW,OAAO,MACxC,QAAQ,QAAQ,CAAC,CAAC,WAAW,QAAQ,KAAK,SAAS,SAAS,CAAC,CAC/D;CAEJ,CAAC;AACF;;;;;;;;;;ACxEA,IAAa,gBAAgB,YAAY;CACxC,IAAI,YAAY;CAChB,MAAM,YAAY;CAClB,WAAW,YAAY,UAAU,CAAC;AACnC,CAAC;;;;;;;;AASD,IAAa,eAAe,YAAY;CACvC,IAAI,YAAY;CAChB,MAAM,aAAa,aAAa;CAChC,SAAS,YAAY;CACrB,OAAO,cAAc,WAAW,aAAa,CAAC;CAC9C,MAAM,cAAc,YAAY,CAAC;CACjC,QAAQ,cAAc,WAAW,YAAY,CAAC,CAAC;CAC/C,UAAU,cAAc,YAAY,CAAC;AACtC,CAAC;;;ACrCD,IAAa,kBAAkB,eAAe,YAAY;;;;;;;;;;;;;;;;;;ACc1D,SAAgB,SAAS,OAAyB;CACjD,MAAM,OAAO,cAAc,KAAK,UAAU,KAAK,CAAC;CAChD,IAAI,CAAC,KAAK,WAAW,OAAO,KAAK,UAAU,UAAU,OAAO,KAAA;CAC5D,OAAO,UAAU,KAAK,KAAK;AAC5B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACWA,SAAgB,gBACf,OACA,SACA,KACe;CACf,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,IAAI,MAAM,WAAW,GAAG,OAAO,CAAC;CAChC,MAAM,MAAM,IAAI,IAAI,KAAK;CACzB,OAAO,QAAQ,QAAQ,WAAW,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC;AACvD;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,aAAa,SAA6B,MAAsB;CAC/E,IAAI,YAAY,KAAA,KAAa,QAAQ,WAAW,GAAG,OAAO;CAC1D,OAAO,KAAK,WAAW,IAAI,UAAU,GAAG,QAAQ,MAAM;AACvD;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,cACf,UACA,QACqB;CACrB,IAAI,WAAW,OAAO,OAAO;CAC7B,MAAM,OACL,WAAW,SAAS,SAAS,SAAS,IAAI,SAAS,eAAe,QAAQ,IAAI,SAAS,MAAM;CAC9F,OAAO,SAAS,KAAK,SAAS,UAAU;EACvC,IAAI,QAAQ,aAAa,KAAA,KAAa,QAAQ,MAAM,OAAO;EAC3D,MAAM,EAAE,UAAU,WAAW,GAAG,SAAS;EACzC,OAAO;CACR,CAAC;AACF;;;;;;;;;;;;;;AAeA,SAAgB,cAAc,OAAuB;CACpD,OAAO,eAAe,KAAK,KAAK,QAAQ,IAAI,KAAK,MAAM,KAAK,IAAI;AACjE;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,cAAc,OAA+B;CAC5D,OAAO;EACN,QAAQ,cAAc,MAAM,MAAM;EAClC,YAAY,cAAc,MAAM,UAAU;EAC1C,OAAO,cAAc,MAAM,KAAK;CACjC;AACD;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,SAAS,SAAiC,MAA8B;CACvF,IAAI,YAAY,KAAA,GAAW,OAAO;CAClC,OAAO;EACN,QAAQ,QAAQ,SAAS,KAAK;EAC9B,YAAY,QAAQ,aAAa,KAAK;EACtC,OAAO,QAAQ,QAAQ,KAAK;CAC7B;AACD;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,cAAiB,MAAoB,QAAsC;CAE1F,OAAO,MAAM,KAAK,OAAO,QAAQ,OAAO,GAAG,CAAC,CAAC,CAAC,OAAO,YAAY,OAAO;AACzE;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,iBAAiB,UAAiE;CACjG,IAAI,SAAS,WAAW,GAAG,OAAO,CAAC;CACnC,MAAM,YAAY,IAAI,IAAI,SAAS,KAAK,SAAS,UAAU,CAAC,SAAS,KAAK,CAAC,CAAC;CAC5E,MAAM,QAAQ,kBAAkB,QAAQ,CAAC,CAAC,KAAK,UAAU;EACxD,MAAM,UAAU,MAAM,SAAS,YAAY;GAC1C,MAAM,WAAW,UAAU,IAAI,OAAO;GACtC,OAAO,aAAa,KAAA,IAAY,CAAC,IAAI,CAAC,QAAQ;EAC/C,CAAC;EACD,OAAO;GACN,OAAO,QAAQ,QAAQ,OAAO,aAAa,KAAK,IAAI,OAAO,QAAQ,GAAG,SAAS,MAAM;GACrF,KAAK,QAAQ,QAAQ,MAAM,aAAa,KAAK,IAAI,MAAM,QAAQ,GAAG,CAAC;EACpE;CACD,CAAC;CACD,MAAM,SAAS,CACd,mBAAG,IAAI,IAAI,CACV,GACA,GAAG,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,aAC3C,QAAQ,SAAS,SAAS,CAAC,KAAK,IAAI,CAAC,CACtC,CACD,CAAC,CACF,CAAC,CAAC,QAAQ,aAAa,CAAC,MAAM,MAAM,SAAS,KAAK,QAAQ,YAAY,YAAY,KAAK,GAAG,CAAC;CAC3F,OAAO,OAAO,KAAK,OAAO,aACzB,SAAS,MAAM,OAAO,OAAO,WAAW,MAAM,SAAS,MAAM,CAC9D;AACD;;;;;;;;;;;;;;;;;AAkBA,SAAgB,SAAS,SAA0C;CAClE,QAAQ,QAAQ,OAAO,UAAU,KAAK;AACvC;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,kBAAkB,UAAiE;CAClG,MAAM,UAAU,SAAS,QAAQ,YAAY,QAAQ,SAAS,eAAe,SAAS,OAAO,CAAC;CAC9F,MAAM,UAAU,IAAI,IAAI,OAAO;CAE/B,MAAM,SAAS,IAAI,QAClB,QAAQ,SAAS,WAChB,MAAM,KAAK,OAAO,SAAS,CAAC,IAAI,UAAU;EAAE,IAAI,KAAK;EAAI;CAAO,EAAE,CACnE,IACC,UAAU,MAAM,EAClB;CACA,MAAM,SAAS,CAAC,GAAG,SAAS,QAAQ,CAAC,CAAC,CAAC,SAAS,CAAC,OAAO,aACvD,QAAQ,SAAS,SAAS,CAAC,IAAI,CAAC,KAAK,CACtC;CAYA,MAAM,SAAS,CATd;EAAE,QAAQ,KAAA;EAAW,OAAO,SAAS,MAAM,GAAG,OAAO,MAAM,SAAS,MAAM;CAAE,GAC5E,GAAG,OAAO,KAAK,OAAO,aAAa;EAClC,MAAM,UAAU,SAAS;EACzB,OAAO;GACN,QAAQ,YAAY,KAAA,KAAa,QAAQ,IAAI,OAAO,IAAI,UAAU,KAAA;GAClE,OAAO,SAAS,MAAM,QAAQ,GAAG,OAAO,WAAW,MAAM,SAAS,MAAM;EACzE;CACD,CAAC,CAEa,CAAA,CAAK,KAAK,EAAE,QAAQ,YAAY;EAC9C,MAAM,QAAQ,QAAQ,SAAS,CAAC;EAChC,MAAM,YAAY,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,MAAM;EACvE,OAAO,MAAM,KAAK,YAAY;GAC7B,MAAM,SACL,WAAW,KAAA,MACV,aAAa,QAAQ,SAAS,KAAA,KAAa,MAAM,MAAM,SAAS,KAAK,OAAO,QAAQ,IAAI;GAC1F,MAAM,UAAU,QAAQ,SAAS,KAAA,IAAY,KAAA,IAAY,OAAO,IAAI,QAAQ,IAAI;GAEhF,OAAO;IAAE;IAAS,OADJ,SAAS,WAAW,IAAI,QAAQ,EAAE,EAAE,SAAS,SAAS,SAAS,KAAA;GACrD;EACzB,CAAC;CACF,CAAC;CACD,MAAM,QAAQ,IAAI,QACjB,OAAO,KAAK,CAAC,CAAC,QAAQ,UAAU,MAAM,UAAU,KAAA,CAAS,IACxD,UAAU,MAAM,KAClB;CACA,MAAM,SAAS,CAAC,GAAG,OAAO,CAAC,CAAC,KAAK,WAAW,CAC3C,QACA,IAAI,MAAM,IAAI,MAAM,KAAK,CAAC,EAAA,CAAG,KAAK,UAAU,MAAM,OAAO,CAC1D,CAAC;CACD,MAAM,UAAU,OAAO,SAAS,QAAQ;EACvC,MAAM,SAAS,IAAI,QAAQ,UAAU,MAAM,UAAU,KAAA,CAAS,CAAC,CAAC,KAAK,UAAU,MAAM,OAAO;EAC5F,OAAO,OAAO,SAAS,IAAI,CAAC,MAAM,IAAI,CAAC;CACxC,CAAC;CACD,OAAO,CAAC,GAAG,QAAQ,GAAG,OAAO;AAC9B;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,WAAW,OAAoC;CAC9D,MAAM,UAAU,cAAkC,KAAK,UAAU,KAAK,CAAC;CACvE,OAAO,QAAQ,UAAU,QAAQ,QAAQ,KAAA;AAC1C;;;;;;;;;;;;;;;AAgBA,SAAgB,gBACf,UACA,UACA,SACA,OACA,OACU;CACV,OACC,SAAS,UAAU,SACnB,SAAS,UAAU,SACnB,SAAS,QAAQ,WAAW,QAAQ,UACpC,SAAS,QAAQ,OAAO,IAAI,UAAU,OAAO,QAAQ,MAAM,KAC3D,KAAK,UAAU,SAAS,QAAQ,MAAM,KAAK,UAAU,QAAQ;AAE/D;;;;;;;;;;;;;;;;;;;AC7WA,SAAgB,aAAa,OAAqC;CACjE,IAAI,SAAS,KAAK,GAAG,OAAO;CAC5B,QAAQ,SAAS,KAAK,KAAK,QAAQ,KAAK,MAAM,YAAY,KAAK;AAChE;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,gBAAgB,OAAwC;CACvE,MAAM,UAAU,cAAc;EAC7B,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;EAC7B,MAAM,EAAE,MAAM,cAAc,aAAa;EACzC,IAAI,iBAAiB,KAAA,KAAa,CAAC,aAAa,YAAY,GAAG,OAAO;EACtE,IAAI,SAAS,UACZ,OACC,SAAS,QAAQ,KACjB,OAAO,KAAK,QAAQ,CAAC,CAAC,UAAU,KAChC,OAAO,OAAO,QAAQ,CAAC,CAAC,MAAM,WAAW,YAAY,CAAC;EAGxD,IAAI,SAAS,SACZ,OAAO,QAAQ,WAAW,YAAY,CAAC,CAAC,CAAC,QAAQ,KAAK,SAAS,UAAU;EAE1E,IAAI,SAAS,QAAQ,OAAO;EAC5B,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,IAAI,CAAC,SAAS,QAAQ,GAAG,OAAO;EAChC,OAAO,WAAW,YAAY,CAAC,CAAC,SAAS,IAAI,KAAK,WAAW,YAAY,CAAC,CAAC,SAAS,KAAK;CAC1F,CAAC;CACD,OAAO,QAAQ,WAAW,QAAQ;AACnC;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,yBAAyB,OAAiC;CACzE,OAAO,eAAe,KAAK,KAAK,OAAO,cAAc,KAAK,KAAK,SAAS;AACzE;;;;;;;;AC5FA,IAAa,aAAa;;;;;;AAO1B,IAAa,cAAc;;;;;;AAO3B,IAAa,2BAA2B;;;;;;AAOxC,IAAa,wBAAwB;;;;;AAMrC,IAAa,sBAAsB;;;;;AAMnC,IAAa,qBAAqB;;;;;;AAOlC,IAAa,yBAAyB;;;;;AAMtC,IAAa,4BAA4B;;;;;;AAOzC,IAAa,wBAAwB;;;;;;AAOrC,IAAa,uBAAuB;;;;;AAMpC,IAAa,yBAAyB;;AAGtC,IAAa,kBAAkB;;;;;;;;;;;;;;;AC7C/B,IAAa,qBAAb,cAAwC,MAAM;;CAE7C,OAAgB;CAChB;CAEA,YAAY,SAAyB,SAAwB;EAC5D,MAAM,2BAA2B,OAAO;EACxC,KAAK,OAAO;EACZ,WAAW,OAAO,MAAM,OAAO,IAAI,qCAAqC,GAAG,EAAE,OAAO,KAAK,CAAC;EAC1F,KAAK,UAAU;CAChB;AACD;;;;;;;;;;;;;;;;;AAkBA,SAAgB,qBAAqB,OAA6C;CACjF,OAAO,YAAY;EAClB,IACC,EACC,iBAAiB,SACjB,WAAW,UAAU,KAAK,MAAM,MAAM,aACtC,WAAW,SAAS,OAAO,OAAO,IAAI,qCAAqC,CAAC,CAAC,EAAE,UAC9E,QAGF,OAAO;EAER,IAAI,EADS,WAAW,QAAQ,KAAK,OAAO,MACtC,MAAS,UAAU,OAAO;EAChC,MAAM,UAAU,WAAW,QAAQ,KAAK,OAAO,SAAS;EACxD,IAAI,EAAE,SAAS,OAAO,KAAK,WAAW,OAAO,IAAI,OAAO;EACxD,MAAM,QAAQ,WAAW,QAAQ,KAAK,SAAS,OAAO;EACtD,MAAM,QAAQ,WAAW,QAAQ,KAAK,SAAS,OAAO;EACtD,OACC,SAAS,WAAW,QAAQ,KAAK,SAAS,SAAS,CAAC,MACnD,WAAW,QAAQ,KAAK,SAAS,UAAU,MAAM,KAAA,KACjD,SAAS,WAAW,QAAQ,KAAK,SAAS,UAAU,CAAC,OACrD,WAAW,QAAQ,KAAK,SAAS,WAAW,MAAM,KAAA,KAClD,UAAU,WAAW,QAAQ,KAAK,SAAS,WAAW,CAAC,OACvD,UAAU,KAAA,MACR,SAAS,KAAK,KAAK,WAAW,KAAK,MACpC;GAAC;GAAU;GAAc;EAAO,CAAC,CAAC,OAAO,QACxC,SAAS,WAAW,QAAQ,KAAK,OAAO,GAAG,CAAC,CAC7C,OACD,UAAU,KAAA,KACV,SACE,UACC,SAAS,IAAI,KAAK,WAAW,IAAI,MAClC,SAAS,WAAW,QAAQ,KAAK,MAAM,IAAI,CAAC,KAC5C,SAAS,WAAW,QAAQ,KAAK,MAAM,MAAM,CAAC,MAC7C,SAAS,WAAW,QAAQ,KAAK,MAAM,WAAW,CAAC,KACnD,WAAW,WAAW,QAAQ,KAAK,MAAM,WAAW,CAAC,EACxD,CAAC,CAAC,KAAK;CAEV,CAAC;AACF;;;;;;;;;;AAWA,IAAa,gBAAb,cAAmC,MAAM;;CAExC;;CAEA;CAEA,YAAY,MAAyB,SAAiB,SAAgC;EACrF,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO;EACZ,WAAW,OAAO,MAAM,OAAO,IAAI,gCAAgC,GAAG,EAAE,OAAO,KAAK,CAAC;EACrF,KAAK,OAAO;EACZ,KAAK,SAAS,SAAS;CACxB;AACD;;;;;;;;;;;AAYA,SAAgB,gBAAgB,OAAwC;CACvE,OAAO,YAAY;EAClB,IACC,EACC,iBAAiB,SACjB,WAAW,UAAU,KAAK,MAAM,MAAM,aACtC,WAAW,SAAS,OAAO,OAAO,IAAI,gCAAgC,CAAC,CAAC,EAAE,UAAU,QAGrF,OAAO;EACR,MAAM,OAAO,WAAW,QAAQ,KAAK,OAAO,MAAM;EAClD,IAAI,EAAE,SAAS,UAAU,SAAS,cAAc,SAAS,aAAa,OAAO;EAC7E,MAAM,SAAS,WAAW,QAAQ,KAAK,OAAO,QAAQ;EACtD,OAAO,WAAW,KAAA,KAAa,SAAS,MAAM;CAC/C,CAAC;AACF;;;;;;;;;;AAWA,IAAa,aAAb,cAAgC,MAAM;;CAErC;;CAEA;CAEA,YAAY,MAAsB,SAAiB,SAAgC;EAClF,MAAM,SAAS,OAAO;EACtB,KAAK,OAAO;EACZ,WAAW,OAAO,MAAM,OAAO,IAAI,6BAA6B,GAAG,EAAE,OAAO,KAAK,CAAC;EAClF,KAAK,OAAO;EACZ,KAAK,SAAS,SAAS;CACxB;AACD;;;;;;;;;;;AAYA,SAAgB,aAAa,OAAqC;CACjE,OAAO,YAAY;EAClB,IACC,EACC,iBAAiB,SACjB,WAAW,UAAU,KAAK,MAAM,MAAM,aACtC,WAAW,SAAS,OAAO,OAAO,IAAI,6BAA6B,CAAC,CAAC,EAAE,UAAU,QAGlF,OAAO;EACR,MAAM,OAAO,WAAW,QAAQ,KAAK,OAAO,MAAM;EAClD,IAAI,EAAE,SAAS,UAAU,SAAS,cAAc,SAAS,aAAa,OAAO;EAC7E,MAAM,SAAS,WAAW,QAAQ,KAAK,OAAO,QAAQ;EACtD,OAAO,WAAW,KAAA,KAAa,SAAS,MAAM;CAC/C,CAAC;AACF;;;;;;;;;;ACjLA,IAAa,uBAAuB,YAAY;CAC/C,UAAU,WAAW,YAAY;CACjC,OAAO,cACN,WACC,YAAY;EACX,MAAM,YAAY;EAClB,aAAa,cAAc,YAAY,CAAC;EACxC,YAAY,cAAc,YAAY,UAAU,CAAC,CAAC;CACnD,CAAC,CACF,CACD;CACA,SAAS,cACR,YAAY;EACX,OAAO,cAAc,aAAa,CAAC;EACnC,QAAQ,cAAc,YAAY,UAAU,CAAC,CAAC;CAC/C,CAAC,CACF;AACD,CAAC;;;;;;;;AASD,IAAa,sBAAsB,YAAY;CAC9C,SAAS,YAAY;CACrB,UAAU,cAAc,YAAY,CAAC;CACrC,OAAO,cAAc,WAAW,aAAa,CAAC;CAC9C,OAAO,cACN,YAAY;EACX,QAAQ,YAAY;EACpB,YAAY,YAAY;EACxB,OAAO,YAAY;CACpB,CAAC,CACF;CACA,WAAW,cAAc,aAAa,CAAC;AACxC,CAAC;;;;;;;;;AAUD,IAAa,kBAAkB,WAC9B,YAAY;CAAE,SAAS,aAAa,CAAC,WAAW,UAAU,CAAC;CAAG,MAAM,YAAY;AAAE,CAAC,GACnF,YAAY;CAAE,SAAS,aAAa,CAAC,QAAQ,CAAC;CAAG,QAAQ;AAAoB,CAAC,GAC9E,YAAY;CAAE,SAAS,aAAa,CAAC,OAAO,CAAC;CAAG,SAAS;AAAoB,CAAC,GAC9E,YAAY;CAAE,SAAS,aAAa,CAAC,OAAO,CAAC;CAAG,SAAS,YAAY;AAAE,CAAC,CACzE;;;ACxEA,IAAa,0BAA0B,eAAe,oBAAoB;;AAG1E,IAAa,yBAAyB,eAAe,mBAAmB;;AAGxE,IAAa,qBAAqB,eAAe,eAAe;;;;;;;;;;;;;;;;ACwBhE,SAAgB,oBACf,SACA,UACA,OACA,OACA,WACiB;CACjB,OAAO;EACN;EACA,GAAI,SAAS,WAAW,IAAI,CAAC,IAAI,EAAE,SAAS;EAC5C,GAAI,MAAM,WAAW,IAAI,CAAC,IAAI,EAAE,MAAM;EACtC,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EACvC,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU;CAChD;AACD;;;;;;;;;;;;;;AAeA,eAAsB,cACrB,QACgB;CAChB,IAAI;EACH,MAAM,OAAO,OAAO;CACrB,QAAQ,CAER,UAAU;EACT,OAAO,YAAY;CACpB;AACD;;;;;;;;;;;;;;;AAgBA,eAAsB,eACrB,QACA,QAC2B;CAC3B,MAAM,UAAU,IAAI,gBAAgB;CACpC,QAAQ,iBACP,eACM;EACL,OAAY,OAAO,OAAO,MAAM,CAAC,CAAC,YAAY,CAE9C,CAAC;CACF,GACA;EAAE,MAAM;EAAM,QAAQ,QAAQ;CAAO,CACtC;CACA,IAAI,QAAQ,SAAS;EACpB,MAAM,OAAO,OAAO,OAAO,MAAM,CAAC,CAAC,YAAY,CAE/C,CAAC;EACD,QAAQ,MAAM;CACf;CACA,OAAO;AACR;;;;;;;;;;;;;;;;;;;;;;AAuBA,eAAsB,YACrB,UACA,QACA,QACuB;CACvB,MAAM,SAAS,SAAS;CACxB,MAAM,OAAO,SAAS;CACtB,IAAI,SAAS,MAAM;EAClB,OAAO,eAAe;EACtB,OAAO;GAAE,SAAS,GAAG,OAAO,GAAG;GAAU;EAAO;CACjD;CACA,OAAO,SAAS,MAAM,uBAAuB,MAAM,CAAC,CAAC,MACnD,SAAS;EACT,OAAO,eAAe;EACtB,OAAO;GAAE,SAAS,GAAG,OAAO,GAAG,SAAS,KAAK,SAAS,KAAK,KAAK,MAAM,KAAK;GAAU;EAAO;CAC7F,IACC,WAAoB;EACpB,SAAS,GAAG,OAAO,GAAG,OAAO;EAC7B;EACA,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;CACxC,EACD;AACD;;;;;;;;;;;;;;;;;;;;;;AAuBA,eAAsB,SACrB,MACA,OACA,QACoB;CACpB,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,UAAU,IAAI,YAAY;CAChC,IAAI;EACH,MAAM,UAAU,MAAM,eAAe,QAAQ,MAAM;EACnD,IAAI;GAGH,MAAM,QAAsE,CAAC;GAC7E,SAAS;IACR,MAAM,YAAY,MAAM,GAAG,EAAE,CAAC,EAAE,aAAa,SAAS;IACtD,MAAM,OAAO,YAAY,KAAK,QAAQ,YAAY,OAAO,MAAM,OAAO,KAAK,IAAI,KAAA;IAC/E,IAAI,SAAS,KAAA,KAAa,QAAQ,YAAY,QAAQ,KAAK,MAC1D,OAAO;KACN,MAAM,MAAM,KAAK,QAAQ,IAAI,IAAI,CAAC,CAAC,KAAK,EAAE,IAAI,QAAQ,OAAO;KAC7D,UAAU,MAAM,SAAS,QAAQ,QAAQ,YAAY;IACtD;IAED,MAAM,QAAQ,KAAK,MAAM,SAAS,GAAG,SAAS;IAC9C,MAAM,KAAK;KACV,MAAM,QAAQ,OAAO,OAAO,EAAE,QAAQ,KAAK,CAAC;KAC5C,WAAW,YAAY,MAAM;IAC9B,CAAC;GACF;EACD,UAAU;GACT,QAAQ,MAAM;EACf;CACD,UAAU;EACT,MAAM,cAAc,MAAM;CAC3B;AACD;;;;;;;;;;;;;AAcA,gBAAuB,WACtB,MACA,QACyB;CACzB,MAAM,SAAS,KAAK,UAAU;CAC9B,MAAM,UAAU,IAAI,YAAY;CAChC,IAAI;EACH,MAAM,UAAU,MAAM,eAAe,QAAQ,MAAM;EACnD,IAAI;GACH,IAAI,QAAQ,SAAS;GACrB,SAAS;IACR,MAAM,OAAO,MAAM,OAAO,KAAK;IAC/B,IAAI,QAAQ,SAAS;IACrB,IAAI,KAAK,MAAM;IACf,MAAM,QAAQ,QAAQ,OAAO,KAAK,OAAO,EAAE,QAAQ,KAAK,CAAC;IACzD,IAAI,MAAM,SAAS,GAAG,MAAM;GAC7B;GACA,MAAM,OAAO,QAAQ,OAAO;GAC5B,IAAI,KAAK,SAAS,GAAG,MAAM;EAC5B,UAAU;GACT,QAAQ,MAAM;EACf;CACD,UAAU;EACT,MAAM,cAAc,MAAM;CAC3B;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA6BA,SAAgB,eAAe,QAA8B;CAC5D,IAAI,OAAO,SAAS,QAAQ;EAC3B,MAAM,MAAM,OAAO,OAAO;EAC1B,OAAO;GACN,QAAQ,MAAM,SAAS;GACvB,aAAa,MAAM,OAAO,OAAO,IAAI,OAAO;GAC5C,YAAY,KAAK,IAAI,IAAI,OAAO,OAAO,CAAC;EACzC;CACD;CACA,MAAM,aACL,OAAO,SAAS,WACb,OAAO,QAAQ,OAAO,aAAa,IACnC,OAAO,cAAc,KAAK,aAAa,UAAU,CAAC,OAAO,KAAK,GAAG,WAAW,CAAC;CACjF,MAAM,QAAQ,WAAW;CACzB,IAAI,QAAQ,GACX,MAAM,IAAI,WAAW,YAAY,oDAAoD;CAItF,MAAM,EAAE,QAAQ,OAAO,gBAAgB,CAAC,GAAG,UAAU,CAAC,CAAC,QACrD,KAAK,CAAC,MAAM,YAAY,aACxB,YAAY,IAAI,cAAc;EAAE,QAAQ;EAAM,OAAO;EAAU,aAAa;CAAU,IAAI,KAC3F;EAAE,QAAQ;EAAI,OAAO;EAAG,aAAa;CAAU,CAChD;CACA,IAAI,OAAO,SAAS,UACnB,OAAO;EAAE;EAAQ;EAAa,aAAa,cAAc,IAAI,UAAU,IAAI,IAAI;CAAO;CAEvF,MAAM,SAAS,OAAO,cAAc,QAClC,KAAK,WAAW,UAAU,MAAM,YAAY,KAAK,IAAI,QAAQ,KAAK,GACnE,CACD;CACA,MAAM,OAAO,OAAO,cAAc,QAChC,KAAK,YAAY,UAAU,MAAM,KAAK,IAAI,SAAS,QAAQ,KAAK,CAAC,GAClE,CACD;CACA,MAAM,QAAQ,OAAO,cAAc,QAAQ,KAAK,WAAW,UAAU,MAAM,QAAQ,WAAW,CAAC;CAC/F,OAAO;EAAE;EAAQ;EAAa,YAAY,KAAK,IAAI,GAAG,IAAI,UAAU,OAAO,MAAM;EAAG;CAAM;AAC3F;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,iBAAiB,OAAe,SAA8C;CAE7F,MAAM,QAAQ,CAAC,GAAG,OAAO;CACzB,MAAM,UAAU,MAAM,QACpB,QAAQ,YAAY;EAAE,GAAG;EAAQ,GAAG,OAAO;CAAQ,IACpD,CAAC,CACF;CACA,MAAM,WAAW,MAAM,QACrB,QAAQ,YAAY;EAAE,GAAG;EAAQ,GAAG,OAAO;CAAS,IACrD,CAAC,CACF;CACA,MAAM,QAAQ,MAAM,QAClB,OAAO,WACP,OAAO,UAAU,KAAA,IAAY,QAAQ,SAAS,OAAO,cAAc,OAAO,KAAK,CAAC,GACjF,KAAA,CACD;CACA,OAAO;EACN,OAAO,QAAQ,EAAE,EAAE,SAAS;EAC5B;EACA,GAAI,OAAO,KAAK,QAAQ,CAAC,CAAC,WAAW,IAAI,CAAC,IAAI,EAAE,SAAS;EACzD,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;CACxC;AACD;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,eAAsB,qBACrB,MACA,QACmB;CACnB,MAAM,UAAU,IAAI,QAAQ,EAAE,gBAAgB,mBAAmB,CAAC;CAClE,IAAI,SAAS,KAAA,GAAW,OAAO;CAC/B,MAAM,UAAU,IAAI,gBAAgB;CACpC,MAAM,UAAU,QAAQ,cAAqB;CAC7C,OAAO,iBAAiB,eAAe,QAAQ,OAAO,OAAO,MAAM,GAAG;EACrE,MAAM;EACN,QAAQ,QAAQ;CACjB,CAAC;CACD,IAAI;EACH,OAAO,eAAe;EACtB,MAAM,UAAU,MAAM,QAAQ,KAAK,CAClC,QAAQ,QAAQ,CAAC,CAAC,WAAW,KAAK,MAAM,CAAC,GACzC,QAAQ,OACT,CAAC;EACD,KAAK,MAAM,CAAC,KAAK,UAAU,OAAO,QAAQ,OAAO,GAAG,QAAQ,IAAI,KAAK,KAAK;EAC1E,OAAO;CACR,UAAU;EACT,QAAQ,MAAM;CACf;AACD;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,eAAe,SAA2C;CACzE,OAAO;EACN,UAAU,QAAQ,SAAS,KAAK,aAAa;GAC5C,IAAI,QAAQ;GACZ,MAAM,QAAQ;GACd,SAAS,QAAQ;GACjB,GAAI,QAAQ,UAAU,KAAA,IACnB,CAAC,IACD,EACA,OAAO,QAAQ,MAAM,KAAK,UAAU;IACnC,IAAI,KAAK;IACT,MAAM,KAAK;IACX,WAAW,KAAK;GACjB,EAAE,EACH;GACF,GAAI,QAAQ,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,QAAQ,KAAK;GAC3D,GAAI,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;GACjE,GAAI,QAAQ,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,QAAQ,SAAS;EACxE,EAAE;EACF,GAAI,QAAQ,UAAU,KAAA,IACnB,CAAC,IACD,EACA,OAAO,QAAQ,MAAM,KAAK,UAAU;GACnC,MAAM,KAAK;GACX,GAAI,KAAK,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa,KAAK,YAAY;GAC1E,GAAI,KAAK,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,KAAK,WAAW;EACxE,EAAE,EACH;EACF,GAAI,QAAQ,YAAY,KAAA,IACrB,CAAC,IACD,EACA,SAAS;GACR,GAAI,QAAQ,QAAQ,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,QAAQ,MAAM;GAC9E,GAAI,QAAQ,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,QAAQ,OAAO;EAClF,EACD;CACH;AACD;;;;;;;;;;;AAYA,SAAgB,oBAAoB,UAA4C;CAC/E,OAAO;EACN,MAAM,SAAS;EACf,GAAI,SAAS,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,SAAS,aAAa;EACrF,GAAI,SAAS,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,SAAS,SAAS;CAC1E;AACD;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,uBACf,QACA,UAC0B;CAC1B,MAAM,UAAU,SAAS,GAAG,CAAC;CAC7B,IAAI,OAAO,SAAS,UAAU,SAAS,SAAS,QAC/C,OAAO,QAAQ,OAAO,IAAI,IAAI;EAAE,MAAM;EAAQ,MAAM,OAAO;CAAK,IAAI,KAAA;CAErE,IAAI,OAAO,SAAS,YAAY,SAAS,SAAS,UAAU;EAC3D,MAAM,SAAS,OAAO,KAAK,SAAS,QAAQ;EAC5C,MAAM,UAAU,OAAO,SAAS,UAAU;GACzC,MAAM,cAAc,OAAO,OAAO,OAAO,eAAe,KAAK,IAC1D,OAAO,cAAc,SACrB,KAAA;GACH,OAAO,QAAQ,WAAW,IAAI,CAAC,CAAC,OAAO,WAAW,CAAU,IAAI,CAAC;EAClE,CAAC;EACD,OAAO,QAAQ,WAAW,OAAO,SAC9B;GAAE,MAAM;GAAU,eAAe,OAAO,YAAY,OAAO;EAAE,IAC7D,KAAA;CACJ;CACA,IAAI,OAAO,SAAS,WAAW,SAAS,SAAS,SAAS,OAAO,KAAA;CAEjE,MAAM,SAAS,CAAC,GAAG,SAAS,SAAS,KAAK,CAAC;CAC3C,MAAM,gBAAgB,OAAO,SAAS,UAAU;EAC/C,MAAM,cAAc,OAAO,OAAO,OAAO,eAAe,KAAK,IAC1D,QAAQ,OAAO,aAAa,IAC3B,OAAO,cAAc,SACrB,OAAO,cAAc,OAAO,KAAK,KAClC,KAAA;EACH,OAAO,QAAQ,WAAW,IAAI,CAAC,WAAW,IAAI,CAAC;CAChD,CAAC;CACD,OAAO,cAAc,WAAW,OAAO,SAAS;EAAE,MAAM;EAAS;CAAc,IAAI,KAAA;AACpF;;;;;;;;;;;;AAaA,SAAgB,sBAAsB,OAA2D;CAChG,MAAM,YAAY,cAAc;EAC/B,IAAI,UAAU,KAAA,GAAW,OAAO,KAAA;EAChC,MAAM,EAAE,cAAc,QAAQ,eAAe,eAAe;EAC5D,IAAI,CAAC,SAAS,MAAM,KAAK,CAAC,SAAS,UAAU,GAAG,OAAO,KAAA;EACvD,MAAM,SAAS;GAAE;GAAQ;GAAY,OAAO,SAAS;EAAW;EAChE,OAAO,aAAa,MAAM,IAAI,SAAS,KAAA;CACxC,CAAC;CACD,OAAO,UAAU,UAAU,UAAU,QAAQ,KAAA;AAC9C;;;;;;;;;;;;;;;;;;;;;;AC5hBA,IAAa,cAAb,MAAyB;CACxB;CACA,YAAqB,IAAI,gBAAgB;CACzC,WAAoB,IAAI,YAAY;CACpC;CACA;CACA;CACA;CACA,WAAW;CAEX,YAAY,SAA6B;EACxC,KAAK,UAAU,QAAQ,SAAS,UAAU;EAC1C,KAAK,UAAU,QAAQ;EACvB,KAAK,YAAY,KAAK,OAAO,KAAK,IAAI;EACtC,IAAI,KAAK,QAAQ,SAAS,KAAK,eAAe;EAC9C,KAAK,YAAY,QAAQ,SAAS,OACjC,cAAc,QAAQ,QAAQ,UAAU,KAAK,OAAO,GACpD,KAAK,UAAU,QACf,QAAQ,QAAQ,OAChB,QAAQ,QAAQ,OACjB;EACA,KAAK,QAAQ,iBAAiB,SAAS,KAAK,WAAW,EAAE,MAAM,KAAK,CAAC;EACrE,KAAK,YAAY,IAAI,SACpB,IAAI,eAA2B;GAC9B,MAAM,KAAK,MAAM,KAAK,IAAI;GAC1B,QAAQ,KAAK,OAAO,KAAK,IAAI;EAC9B,CAAC,GACD,EAAE,SAAS;GAAE,gBAAgB;GAAoB,iBAAiB;EAAW,EAAE,CAChF;CACD;;CAGA,IAAI,WAAqB;EACxB,OAAO,KAAK;CACb;CAEA,MAAM,MAAM,YAAwE;EACnF,IAAI,KAAK,UAAU;EACnB,IAAI;GACH,MAAM,OAAO,MAAM,KAAK,UAAU,KAAK;GACvC,IAAI,KAAK,UAAU;GACnB,KAAK,OAAO,YAAY,KAAK,OAAO;IAAE,SAAS;IAAU,QAAQ,KAAK;GAAM,IAAI,KAAK,KAAK;GAC1F,IAAI,KAAK,MAAM,KAAK,QAAQ,UAAU;EACvC,SAAS,OAAO;GACf,IAAI,KAAK,UAAU;GACnB,MAAM,QAAoB,qBAAqB,KAAK,IACjD;IAAE,SAAS;IAAS,SAAS,MAAM;GAAQ,IAC3C;IAAE,SAAS;IAAS,SAAS;GAAuB;GACvD,KAAK,OACJ,YACA,mBAAmB,GAAG,KAAK,IACxB,QACA;IAAE,SAAS;IAAS,SAAS;GAAuB,CACxD;GACA,KAAK,QAAQ,UAAU;GACvB,KAAK,eAAe;GACpB,MAAM,KAAK,QAAQ;EACpB;CACD;CAEA,MAAM,SAAwB;EAC7B,IAAI,KAAK,UAAU;EACnB,KAAK,WAAW;EAChB,KAAK,eAAe;EACpB,IAAI;GACH,MAAM,KAAK,QAAQ;EACpB,UAAU;GACT,KAAK,SAAS;EACf;CACD;CAEA,MAAM,UAAyB;EAC9B,IAAI;GACH,MAAM,KAAK,UAAU,OAAO,EAAE,SAAS,GAAG,CAAC;EAC5C,QAAQ,CAER;CACD;CAEA,OAAO,YAAyD,OAAyB;EACxF,IAAI,CAAC,mBAAmB,GAAG,KAAK,GAAG,MAAM,IAAI,cAAc,YAAY,qBAAqB;EAC5F,WAAW,QAAQ,KAAK,SAAS,OAAO,GAAG,KAAK,UAAU,KAAK,EAAE,GAAG,CAAC;CACtE;CAEA,QAAQ,YAA+D;EACtE,KAAK,WAAW;EAChB,KAAK,SAAS;EACd,WAAW,MAAM;CAClB;CAEA,iBAAuB;EACtB,KAAK,UAAU,MAAM,KAAK,QAAQ,MAAM;CACzC;CAEA,WAAiB;EAChB,KAAK,QAAQ,oBAAoB,SAAS,KAAK,SAAS;CACzD;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACnFA,IAAa,gBAAb,MAA6D;CAG5D,WAAW;CAEX,UAAU;CAIV,UAAU;CACV,WAAW;CACX,YAAY;CAEZ,IAAI,UAAkB;EACrB,OAAO,KAAK;CACb;CAEA,IAAI,WAAmB;EACtB,OAAO,KAAK;CACb;CAEA,MAAM,OAAuB;EAC5B,MAAM,MAAM,KAAK,MAAM,KAAK;EAC5B,KAAK,YAAY;EACjB,OAAO;CACR;CAEA,QAAgB;EACf,MAAM,UAAU,KAAK;EACrB,KAAK,WAAW;EAChB,IAAI,KAAK,SAAS;GAGjB,KAAK,aAAa;GAClB,KAAK,UAAU;GACf,OAAO;EACR;EAEA,KAAK,YAAY;EACjB,OAAO;CACR;CAKA,MAAM,OAAuB;EAC5B,KAAK,YAAY;EACjB,OAAO,CAAC,GAAG,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE;CACpC;CAKA,CAAC,WAAoC;EACpC,SAAS;GACR,IAAI,KAAK,SAAS;IACjB,MAAM,QAAQ,KAAK,SAAS,QAAQ,WAAW;IAC/C,IAAI,UAAU,IAAI;KAGjB,KAAK,aAAa,KAAK,MAAM,CAAC,WAAW,CAAC;KAC1C;IACD;IACA,KAAK,aAAa,KAAK,SAAS,MAAM,GAAG,KAAK;IAC9C,KAAK,WAAW,KAAK,SAAS,MAAM,QAAQ,YAAY,MAAM;IAC9D,KAAK,UAAU;IACf;GACD;GACA,MAAM,OAAO,KAAK,SAAS,QAAQ,UAAU;GAC7C,IAAI,CAAC,KAAK,SAAS;IAIlB,MAAM,QAAQ,KAAK,SAAS,QAAQ,WAAW;IAC/C,IAAI,UAAU,OAAO,SAAS,MAAM,QAAQ,OAAO;KAClD,KAAK,aAAa,KAAK,WAAW,KAAK,SAAS,MAAM,GAAG,KAAK;KAC9D,KAAK,WAAW;KAChB,KAAK,WAAW,KAAK,SAAS,MAAM,QAAQ,YAAY,MAAM;KAC9D,KAAK,UAAU;KACf;IACD;GACD;GACA,IAAI,SAAS,IAAI;IAIhB,MAAM,OAAO,KAAK,UAAU,CAAC,UAAU,IAAI,CAAC,YAAY,WAAW;IACnE,MAAM,KAAK,MAAM,IAAI;IACrB;GACD;GACA,KAAK,UAAU;GACf,MAAM,KAAK,SAAS,MAAM,GAAG,IAAI;GACjC,KAAK,WAAW,KAAK,SAAS,MAAM,OAAO,WAAW,MAAM;GAC5D,KAAK,UAAU;EAChB;CACD;CAKA,MAAM,MAAiC;EACtC,MAAM,OAAO,KAAK,IAAI,GAAG,KAAK,KAAK,QAAQ,KAAK,SAAS,GAAG,CAAC,CAAC;EAC9D,MAAM,MAAM,KAAK,SAAS,SAAS;EACnC,MAAM,UAAU,KAAK,SAAS,MAAM,GAAG,GAAG;EAC1C,KAAK,WAAW,KAAK,SAAS,MAAM,GAAG;EACvC,OAAO;CACR;CAIA,SAAS,KAAqB;EAC7B,MAAM,MAAM,KAAK,IAAI,KAAK,SAAS,QAAQ,IAAI,SAAS,CAAC;EACzD,OACC,MAAM,KAAK,EAAE,QAAQ,IAAI,IAAI,GAAG,UAAU,MAAM,KAAK,CAAC,CAAC,MAAM,WAC5D,KAAK,SAAS,SAAS,IAAI,MAAM,GAAG,MAAM,CAAC,CAC5C,KAAK;CAEP;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACtFA,IAAsB,gBAAtB,MAE6C;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,OAA2B;EACtC,KAAK,MAAM,OAAO,WAAW;EAC7B,KAAK,UAAU,MAAM,UAAU;EAC/B,KAAK,OAAO,MAAM;EAClB,KAAK,QAAQ,MAAM,QAAQ;EAC3B,KAAK,WAAW,MAAM,WAAA;EACtB,KAAK,aAAa,MAAM,SAAS,WAAW,MAAM,KAAK,UAAU;EACjE,KAAK,WAAW,MAAM;EACtB,KAAK,SAAS,MAAM,SAAS;EAC7B,KAAK,UAAU,MAAM,UAAU;CAChC;;CAMA,IAAI,KAAa;EAChB,OAAO,KAAK;CACb;;CAGA,IAAI,SAAyB;EAC5B,OAAO,KAAK;CACb;;;;;;;;;;CAoBA,MAAM,SACL,UACA,QACA,OACA,SAC0B;EAC1B,MAAM,SAAS,KAAK,OAAO,UAAU,QAAQ,OAAO,OAAO;EAC3D,SAAS;GACR,MAAM,OAAO,MAAM,OAAO,KAAK;GAC/B,IAAI,KAAK,MAAM,OAAO,KAAK;EAC5B;CACD;;;;;;;;;;;;;CAcA,OAAO,OACN,UACA,QACA,OACA,SACgD;EAChD,IAAI,OAAO,SAAS,MAAM,IAAI,mBAAmB,EAAE,SAAS,GAAG,CAAC;EAChE,MAAM,UAAU,IAAI,QAAQ,EAAE,IAAI,KAAK,SAAS,CAAC;EACjD,QAAQ,MAAM;EACd,MAAM,WAAW,YAAY,IAAI,CAAC,QAAQ,QAAQ,MAAM,CAAC;EACzD,IAAI;GACH,MAAM,SAAS,KAAK,OAAO,QAAQ;GACnC,IAAI;IACH,OAAO,OAAO,KAAK,MAAM,QAAQ,UAAU,OAAO,SAAS,QAAQ;GACpE,UAAU;IACT,OAAO,MAAM;GACd;EACD,UAAU;GACT,QAAQ,MAAM;EACf;CACD;CAGA,OAAO,UAAyD;EAC/D,IAAI;GACH,OAAO,KAAK,MAAM;EACnB,SAAS,OAAO;GACf,MAAM,KAAK,WAAW,OAAO,UAAU,KAAA,GAAW,CAAC,CAAC;EACrD;CACD;CAIA,OAAO,MACN,QACA,UACA,OACA,SACA,UACgD;EAChD,MAAM,WAAW,KAAK,SAAS,IAAI,cAAc,IAAI,KAAA;EACrD,MAAM,aAAkC,CAAC;EACzC,IAAI;GACH,MAAM,WAAW,MAAM,KAAK,SAC3B;IACC;IACA,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;IACvC,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;GAC5C,GACA,QACD;GACA,IAAI,SAAS,SAAS,MACrB,MAAM,IAAI,cAAc,YAAY,kCAAkC;GAEvE,WAAW,MAAM,SAAS,WAAW,SAAS,MAAM,QAAQ,GAAG;IAC9D,SAAS,eAAe;IACxB,KAAK,MAAM,UAAU,OAAO,MAAM,KAAK,GAAG;KACzC,MAAM,YAAY,KAAK,KAAK,MAAM;KAClC,WAAW,KAAK,SAAS;KACzB,IAAI,UAAU,WAAW,KAAA,GAAW,OAAO,KAAK,MAAM,WAAW,UAAU,QAAQ;KACnF,SAAS,eAAe;KACxB,IAAI,UAAU,WAAW,KAAA,GAAW,OAAO,UAAU;IACtD;GACD;GACA,SAAS,eAAe;GACxB,KAAK,MAAM,UAAU,KAAK,OAAO,MAAM,GAAG;IACzC,MAAM,YAAY,KAAK,KAAK,MAAM;IAClC,WAAW,KAAK,SAAS;IACzB,IAAI,UAAU,WAAW,KAAA,GAAW,OAAO,KAAK,MAAM,WAAW,UAAU,QAAQ;IACnF,SAAS,eAAe;IACxB,IAAI,UAAU,WAAW,KAAA,GAAW,OAAO,UAAU;GACtD;GACA,MAAM,OAAO,UAAU,MAAM,KAAK;GAClC,IAAI,KAAK,SAAS,GAAG,MAAM;IAAE,SAAS;IAAW,MAAM;GAAK;GAC5D,SAAS,eAAe;GACxB,IAAI,KAAK,SACR,MAAM,IAAI,cAAc,YAAY,wCAAwC;GAE7E,OAAO,KAAK,UAAU,UAAU,UAAU;EAC3C,SAAS,OAAO;GACf,MAAM,KAAK,WAAW,OAAO,UAAU,UAAU,UAAU;EAC5D;CACD;CAIA,CAAC,MACA,WACA,UACA,QAC2B;EAC3B,MAAM,UAAU,UAAU,MAAM,UAAU,OAAO,KAAK,UAAU;EAChE,IAAI,QAAQ,SAAS,GAAG,MAAM;GAAE,SAAS;GAAW,MAAM;EAAQ;EAClE,OAAO,eAAe;EACtB,IAAI,UAAU,SAAS,SAAS,GAAG,MAAM;GAAE,SAAS;GAAY,MAAM,UAAU;EAAS;CAC1F;CAIA,WACC,OACA,UACA,UACA,YACU;EACV,IAAI,CAAC,SAAS,SAAS,OAAO;EAC9B,UAAU,MAAM;EAChB,OAAO,IAAI,mBACV,KAAK,UAAU,UAAU,UAAU,GACnC,UAAU,SAAS,SAAS,KAAA,IAAY,EAAE,OAAO,MAAM,CACxD;CACD;CAIA,UACC,UACA,YACiB;EACjB,MAAM,OAAO,WAAW,GAAG,EAAE;EAC7B,MAAM,SAAS,MAAM,WAAW,KAAA,IAAY,aAAa,CAAC,IAAI;EAC9D,OAAO,oBACN,UAAU,WAAW,OAAO,KAAK,QAAQ,IAAI,OAAO,CAAC,CAAC,KAAK,EAAE,GAC7D,aAAa,UAAU,UAAU,OAAO,KAAK,QAAQ,IAAI,QAAQ,CAAC,CAAC,KAAK,EAAE,CAAC,GAC3E,OAAO,SAAS,QAAQ,CAAC,GAAG,IAAI,KAAK,CAAC,GACtC,OAAO,UAAU,QAAQ,IAAI,UAAU,KAAA,CAAS,CAAC,EAAE,OACnD,OAAO,UAAU,QAAQ,IAAI,cAAc,KAAA,CAAS,CAAC,EAAE,SACxD;CACD;CAGA,MAAM,SAAS,SAA0B,QAAwC;EAChF,MAAM,UAAU,MAAM,qBAAqB,KAAK,UAAU,MAAM;EAChE,OAAO,eAAe;EACtB,MAAM,WAAW,MAAM,KAAK,WAAW,KAAK,OAAO,KAAK,OAAO;GAC9D,QAAQ;GACR;GACA,MAAM,KAAK,UAAU,KAAK,OAAO,OAAO,CAAC;GACzC;EACD,CAAC;EACD,IAAI,CAAC,SAAS,IAAI;GACjB,MAAM,EAAE,SAAS,GAAG,YAAY,MAAM,YAAY,UAAU,mBAAmB,MAAM;GACrF,MAAM,IAAI,cAAc,QAAQ,SAAS,OAAO;EACjD;EACA,OAAO;CACR;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7PA,IAAa,gBAAb,cAAmC,cAAc;CAChD;CAEA,YAAY,SAA+B;EAC1C,MAAM,EAAE,KAAK,SAAS,OAAO,SAAS,WAAW;EACjD,MAAM;GACL;GACA,OAAO;GACP,QAAQ;GACR,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;GAC3C,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;GACvC,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;GAC3C,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EAC1C,CAAC;EACD,KAAK,UAAU,QAAQ;CACxB;;CAGA,OAAgB;;CAGhB,QAAiC;EAChC,OAAO,KAAK,QAAQ;CACrB;;;;;;;;;;;;;;CAeA,OAAO,SAAkC;EACxC,MAAM,WAAW,cAAc,eAAe,eAAe,OAAO,CAAC,CAAC;EACtE,IAAI,CAAC,SAAS,SACb,MAAM,IAAI,cAAc,YAAY,6BAA6B,EAAE,OAAO,SAAS,MAAM,CAAC;EAE3F,IAAI,CAAC,wBAAwB,GAAG,SAAS,KAAK,GAC7C,MAAM,IAAI,cAAc,YAAY,2BAA2B;EAEhE,OAAO,SAAS;CACjB;;;;;;;;;CAUA,KAAK,QAA8D;EAClE,IAAI,CAAC,mBAAmB,GAAG,MAAM,GAChC,MAAM,IAAI,cAAc,YAAY,qBAAqB;EAE1D,QAAQ,OAAO,SAAf;GACC,KAAK,WACJ,OAAO;IAAE,SAAS,OAAO;IAAM,UAAU;IAAI,OAAO,CAAC;GAAE;GACxD,KAAK,YACJ,OAAO;IAAE,SAAS;IAAI,UAAU,OAAO;IAAM,OAAO,CAAC;GAAE;GACxD,KAAK,UACJ,OAAO;IAAE,SAAS;IAAI,UAAU;IAAI,OAAO,CAAC;IAAG,QAAQ,OAAO;GAAO;GACtE,KAAK,SACJ,MAAM,IAAI,mBAAmB,OAAO,OAAO;GAC5C,KAAK,SACJ,MAAM,IAAI,cAAc,YAAY,OAAO,OAAO;EACpD;CACD;;;;;;;CAQA,OAAO,QAAmF;EACzF,OAAO,OAAO,MAAM,IAAI;CACzB;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/EA,IAAsB,aAAtB,MAAgE;CAC/D;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CAEA,YAAY,OAAwB;EACnC,KAAK,MAAM,OAAO,WAAW;EAC7B,KAAK,OAAO,MAAM;EAClB,KAAK,QAAQ,MAAM,QAAQ;EAC3B,KAAK,SAAS,MAAM;EACpB,KAAK,WAAW,MAAM,WAAA;EACtB,KAAK,aAAa,MAAM,SAAS,WAAW,MAAM,KAAK,UAAU;EACjE,KAAK,WAAW,MAAM;EACtB,KAAK,SAAS,MAAM,SAAS;CAC9B;;CAMA,IAAI,KAAa;EAChB,OAAO,KAAK;CACb;;CAGA,IAAI,QAAgB;EACnB,OAAO,KAAK;CACb;;;;;;;;;;;;;CAmBA,MAAM,IAAI,SAAuB,QAA2C;EAC3E,IAAI,OAAO,SAAS,MAAM,IAAI,gBAAgB,iBAAiB,KAAK,QAAQ,CAAC,CAAC,CAAC;EAI/E,MAAM,QAAQ,SAAS,QAAQ,KAAK;EACpC,IAAI,CAAC,aAAa,KAAK,GACtB,MAAM,IAAI,WAAW,YAAY,yCAAyC;EAE3E,MAAM,YAAY,SAAS,QAAQ,SAAS,IAAI,OAAO,QAAQ,QAAQ,SAAS,IAAI,CAAC;EACrF,IAAI,UAAU,WAAW,GAAG,MAAM,IAAI,WAAW,YAAY,2BAA2B;EACxF,MAAM,UAAU,UAAU,KAAK,CAAC,IAAI,cAAc;GACjD,MAAM,OAAO,SAAS,QAAQ;GAC9B,IAAI,CAAC,gBAAgB,IAAI,GACxB,MAAM,IAAI,WAAW,YAAY,yBAAyB,GAAG,cAAc;GAE5E,OAAO,CAAC,IAAI,IAAI;EACjB,CAAC;EACD,MAAM,QAAsB;GAAE;GAAO,WAAW,OAAO,YAAY,OAAO;EAAE;EAI5E,MAAM,SAHiC,KAAK,SACzC,CAAC,KAAK,IACN,QAAQ,KAAK,CAAC,IAAI,eAAe;GAAE;GAAO,WAAW,GAAG,KAAK,SAAS;EAAE,EAAE,EAAA,CACzD,KAAK,UAAU;GAAE,SAAS;GAAM,MAAM,KAAK,UAAU,KAAK,OAAO,IAAI,CAAC;EAAE,EAAE;EAC9F,MAAM,UAAyB,CAAC;EAChC,KAAK,MAAM,QAAQ,OAClB,QAAQ,KAAK,MAAM,KAAK,MAAM,KAAK,SAAS,KAAK,MAAM,QAAQ,OAAO,CAAC;EAExE,OAAO,iBAAiB,KAAK,QAAQ,OAAO;CAC7C;CAEA,MAAM,MACL,SACA,MACA,QACA,WACuB;EACvB,MAAM,UAAU,IAAI,QAAQ,EAAE,IAAI,KAAK,SAAS,CAAC;EACjD,QAAQ,MAAM;EACd,MAAM,WAAW,YAAY,IAAI,CAAC,QAAQ,QAAQ,MAAM,CAAC;EACzD,IAAI;GACH,MAAM,UAAU,MAAM,qBAAqB,KAAK,UAAU,QAAQ;GAClE,SAAS,eAAe;GACxB,MAAM,WAAW,MAAM,KAAK,WAAW,KAAK,OAAO,KAAK,OAAO;IAC9D,QAAQ;IACR;IACA;IACA,QAAQ;GACT,CAAC;GACD,IAAI,CAAC,SAAS,IAAI;IACjB,MAAM,EAAE,SAAS,GAAG,YAAY,MAAM,YAAY,UAAU,gBAAgB,QAAQ;IACpF,MAAM,IAAI,WAAW,QAAQ,SAAS,OAAO;GAC9C;GACA,IAAI,SAAS,SAAS,MACrB,MAAM,IAAI,WAAW,YAAY,+BAA+B;GAEjE,MAAM,OAAO,MAAM,SAAS,SAAS,MAAM,KAAA,GAAW,QAAQ;GAC9D,SAAS,eAAe;GACxB,MAAM,QAAQ,UAAU,KAAK,IAAI;GACjC,IAAI,UAAU,KAAA,GAAW,MAAM,IAAI,WAAW,YAAY,gCAAgC;GAC1F,MAAM,SAAS,KAAK,KAAK,OAAO,OAAO;GACvC,SAAS,eAAe;GACxB,OAAO;EACR,SAAS,OAAO;GACf,IAAI,SAAS,SAEZ,MAAM,IAAI,gBACT,iBAAiB,KAAK,QAAQ,SAAS,GACvC,UAAU,SAAS,SAAS,KAAA,IAAY,EAAE,OAAO,MAAM,CACxD;GAED,MAAM;EACP,UAAU;GACT,QAAQ,MAAM;EACf;CACD;AACD;;;;;;;;;;;;;;;;ACvJA,SAAgB,oBAAoB,OAA4C;CAC/E,MAAM,UAAU,cAAc;EAC7B,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;EAC7B,MAAM,EAAE,OAAO,SAAS,UAAU;EAClC,IAAI,CAAC,WAAW,QAAQ,CAAC,CAAC,KAAK,KAAK,CAAC,SAAS,OAAO,GAAG,OAAO;EAC/D,IAAI,UAAU,KAAA,GAAW,OAAO;EAChC,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;EAC7B,OACC,WAAW,WAAW,QAAQ,CAAC,CAAC,CAAC,MAAM,YAAY,KACnD,WAAW,WAAW,QAAQ,CAAC,CAAC,CAAC,MAAM,aAAa;CAEtD,CAAC;CACD,OAAO,QAAQ,WAAW,QAAQ;AACnC;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,kBAAkB,OAA0C;CAC3E,MAAM,UAAU,cAAc;EAC7B,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;EAC7B,MAAM,EAAE,SAAS;EACjB,IAAI,SAAS,QAAQ,OAAO,SAAS,GAAG,CAAC,CAAC,CAAC,MAAM,IAAI;EACrD,IAAI,SAAS,YAAY,SAAS,SAAS,OAAO;EAClD,MAAM,EAAE,kBAAkB;EAC1B,IAAI,SAAS,WAAW,QAAQ,aAAa,GAC5C,OAAO,QAAQ,SAAS,GAAG,CAAC,CAAC,CAAC,CAAC,aAAa;EAE7C,OAAO,SAAS,aAAa,KAAK,OAAO,OAAO,aAAa,CAAC,CAAC,MAAM,SAAS,GAAG,CAAC,CAAC;CACpF,CAAC;CACD,OAAO,QAAQ,WAAW,QAAQ;AACnC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACjBA,IAAa,iBAAb,cAAoC,WAAW;CAC9C,YAAY,SAAgC;EAC3C,MAAM;GAAE,GAAG;GAAS,MAAM;GAAiB,OAAO;EAAK,CAAC;CACzD;;CAGA,OAAgB;;;;;;;CAQhB,OAAO,SAAyC;EAC/C,OAAO;GACN,OAAO,QAAQ;GACf,OAAO,KAAK;GACZ,WAAW,OAAO,YACjB,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,cAAc,CACzD,IACA,oBAAoB,QAAQ,CAC7B,CAAC,CACF;EACD;CACD;;;;;;;;;;CAWA,KAAK,OAAgB,SAAoC;EACxD,IAAI,CAAC,oBAAoB,KAAK,GAC7B,MAAM,IAAI,WAAW,YAAY,mDAAmD;EAErF,MAAM,UAAU,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,KAAK,CAAC,IAAI,cAAc;GACzE,IAAI,CAAC,OAAO,OAAO,MAAM,SAAS,EAAE,GACnC,MAAM,IAAI,WAAW,YAAY,yBAAyB,GAAG,0BAA0B;GAExF,MAAM,OAAO,MAAM,QAAQ;GAC3B,IAAI,CAAC,kBAAkB,IAAI,GAC1B,MAAM,IAAI,WACT,YACA,yBAAyB,GAAG,kCAC7B;GAED,MAAM,SAAS,uBAAuB,MAAM,QAAQ;GACpD,IAAI,WAAW,KAAA,GACd,MAAM,IAAI,WACT,YACA,yBAAyB,GAAG,kDAC7B;GAED,OAAO,CAAC,IAAI,MAAM;EACnB,CAAC;EACD,MAAM,QAAQ,sBAAsB,MAAM,KAAK;EAC/C,OAAO;GACN,OAAO,MAAM,SAAS,KAAK;GAC3B,SAAS,OAAO,YAAY,OAAO;GACnC,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EACxC;CACD;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC/DA,SAAgB,YAAY,SAAqC;CAChE,MAAM,EAAE,UAAU,WAAW,UAAU;CACvC,OAAO,OAAO,YAAY;EACzB,IAAI;GACH,IAAK,MAAM,UAAU,OAAO,MAAO,MAClC,OAAO,IAAI,SAAS,KAAA,GAAW,EAAE,QAAA,IAAkC,CAAC;EAEtE,QAAQ;GACP,OAAO,IAAI,SAAS,KAAA,GAAW,EAAE,QAAA,IAAkC,CAAC;EACrE;EACA,IAAI,QAAQ,SAAS,MAAM,OAAO,IAAI,SAAS,KAAA,GAAW,EAAE,QAAA,IAA6B,CAAC;EAC1F,MAAM,OAAO,MAAM,SAAS,QAAQ,MAAM,SAAA,SAA8B,QAAQ,MAAM,CAAC,CAAC,YACjF,KAAA,CACP;EACA,IAAI,SAAS,KAAA,GACZ,OAAO,IAAI,SAAS,KAAA,GAAW,EAC9B,QAAQ,QAAQ,OAAO,UAAA,MAAA,IACxB,CAAC;EAEF,IAAI,CAAC,KAAK,UAAU,OAAO,IAAI,SAAS,KAAA,GAAW,EAAE,QAAA,IAA+B,CAAC;EACrF,MAAM,SAAS,YAAY,KAAK,MAAM,wBAAwB,EAAE;EAChE,IAAI,WAAW,KAAA,GAAW,OAAO,IAAI,SAAS,KAAA,GAAW,EAAE,QAAA,IAA6B,CAAC;EACzF,IAAI;GACH,OAAO,IAAI,YAAY;IAAE;IAAU,SAAS;IAAQ,QAAQ,QAAQ;GAAO,CAAC,CAAC,CAAC;EAC/E,QAAQ;GACP,OAAO,IAAI,SAAS,KAAA,GAAW,EAAE,QAAA,IAA8B,CAAC;EACjE;CACD;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkDA,SAAgB,oBAAoB,SAAkD;CACrF,OAAO,IAAI,cAAc,OAAO;AACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,sBAA8C;CAC7D,OAAO,IAAI,cAAc;AAC1B;;;;;;;;;;;AAYA,SAAgB,qBAAqB,SAAgD;CACpF,OAAO,IAAI,eAAe,OAAO;AAClC;;;;;;;;;;;ACnLA,IAAa,4BAA4B;;;;;;;;;;;;;;;;AAiBzC,IAAa,4BAA4B;;;;;;;;;;;;;;;;;;;;;;;ACDzC,IAAa,oBAAb,cAAuC,MAAM;;CAE5C;;CAEA;;;;;;;;CASA,YAAY,MAA6B,SAAiB,SAA6B;EACtF,MAAM,SAAS,SAAS,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,CAAC;EAClF,KAAK,OAAO;EACZ,WAAW,OAAO,MAAM,OAAO,IAAI,oCAAoC,GAAG,EAAE,OAAO,KAAK,CAAC;EACzF,KAAK,OAAO;EACZ,KAAK,UAAU,SAAS;CACzB;AACD;;;;;;;;;;;;;;;;;AAkBA,SAAgB,oBAAoB,OAA4C;CAC/E,OAAO,YAAY;EAClB,IACC,EACC,iBAAiB,SACjB,WAAW,UAAU,KAAK,MAAM,MAAM,aACtC,WAAW,SAAS,OAAO,OAAO,IAAI,oCAAoC,CAAC,CAAC,EAAE,UAC7E,QAGF,OAAO;EACR,MAAM,OAAO,WAAW,QAAQ,KAAK,OAAO,MAAM;EAClD,IAAI,EAAE,SAAS,gBAAgB,SAAS,cAAc,SAAS,cAAc,SAAS,SACrF,OAAO;EACR,MAAM,UAAU,WAAW,QAAQ,KAAK,OAAO,SAAS;EACxD,OAAO,YAAY,KAAA,KAAa,SAAS,OAAO,KAAK,WAAW,OAAO;CACxE,CAAC;AACF;;;;;;;;;;;;;;;;;;;;;AC5CA,SAAgB,UAAU,OAAkC;CAC3D,MAAM,UAAU,cAAc;EAC7B,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;EAC7B,MAAM,EAAE,IAAI,MAAM,SAAS,OAAO,MAAM,QAAQ,aAAa;EAC7D,IAAI,CAAC,SAAS,EAAE,KAAK,CAAC,SAAS,OAAO,GAAG,OAAO;EAChD,IAAI,CAAC,cAAc,MAAM,QAAQ,QAAQ,IAAI,GAAG,OAAO;EACvD,IAAI,UAAU,KAAA,KAAa,CAAC,QAAQ,UAAU,CAAC,CAAC,KAAK,GAAG,OAAO;EAC/D,IAAI,SAAS,KAAA,KAAa,CAAC,SAAS,IAAI,GAAG,OAAO;EAClD,IAAI,WAAW,KAAA,KAAa,CAAC,QAAQ,QAAQ,CAAC,CAAC,MAAM,GAAG,OAAO;EAC/D,OAAO,aAAa,KAAA,KAAa,SAAS,QAAQ;CACnD,CAAC;CACD,OAAO,QAAQ,WAAW,QAAQ;AACnC;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,WAAW,OAAmC;CAC7D,MAAM,UAAU,cAAc;EAC7B,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO;EAC7B,MAAM,EAAE,QAAQ,YAAY;EAC5B,IACC,CAAC,SACA;GACC,IAAI;GACJ,UAAU;GACV,OAAO;GACP,SAAS,QAAQ,QAAQ;GACzB,OAAO;GACP,MAAM;GACN,OAAO,WAAW,YAAY;GAC9B,GAAI,WAAW,KAAA,IAAY,EAAE,SAAS,SAAS,IAAI,EAAE,QAAQ,SAAS;EACvE,GACA,CAAC,OAAO,CACT,CAAC,CAAC,KAAK,GAEP,OAAO;EACR,IAAI,WAAW,KAAA,GAAW,OAAO,SAAS,EAAE,SAAS,QAAQ,QAAQ,EAAE,CAAC,CAAC,CAAC,OAAO;EACjF,IAAI,YAAY,KAAA,KAAa,CAAC,SAAS,MAAM,GAAG,OAAO;EACvD,IAAI,OAAO,SAAS,QAAQ,OAAO,eAAe,OAAO,IAAI;EAC7D,IAAI,OAAO,SAAS,SAAS,OAAO,QAAQ,cAAc,CAAC,CAAC,OAAO,aAAa;EAChF,OACC,OAAO,SAAS,YAChB,SAAS,OAAO,aAAa,KAC7B,OAAO,OAAO,OAAO,aAAa,CAAC,CAAC,MAAM,cAAc;CAE1D,CAAC;CACD,OAAO,QAAQ,WAAW,QAAQ;AACnC;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,UAAU,OAAkC;CAC3D,OACC,SAAS,KAAK,KACd,SAAS;EAAE,IAAI;EAAU,SAAS;EAAU,UAAU,QAAQ,SAAS;CAAE,CAAC,CAAC,CAAC,KAAK;AAEnF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,uBAAuB,OAA+C;CACrF,OACC,SAAS,KAAK,KACd,SACC;EACC,IAAI;EACJ,UAAU,QAAQ,SAAS;EAC3B,UAAU,QAAQ,SAAS;EAC3B,WAAW,WAAW,QAAQ,UAAU,CAAC;CAC1C,GACA,CAAC,WAAW,CACb,CAAC,CAAC,KAAK;AAET;;;;;;;;;;;;;;;;AC1JA,SAAgB,eACf,SACA,QACA,SACA,OACA,OAC2B;CAC3B,MAAM,SAAS,OAAO,KAAK,QAAQ,SAAS,CAAC,CAAC,WAAW;CACzD,OAAO,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,SAAS,CAAC,IAAI,cAAwC;EAC9F,MAAM,SAAS,OAAO,OAAO,OAAO,SAAS,EAAE,IAAI,OAAO,QAAQ,MAAM,KAAA;EACxE,MAAM,UACL,OAAO,aAAa,KAAA,KAAa,OAAO,OAAO,OAAO,UAAU,EAAE,IAC/D,OAAO,SAAS,MAChB,KAAA;EACJ,IAAI,WAAW,KAAA,KAAa,YAAY,KAAA,GAAW,OAAO,CAAC;EAC3D,OAAO,CACN;GACC;GACA;GACA;GACA;GACA;GACA,GAAI,WAAW,KAAA,IAAY,EAAE,OAAO,IAAI,YAAY,KAAA,IAAY,EAAE,QAAQ,IAAI,CAAC;GAC/E,GAAI,UAAU,OAAO,UAAU,KAAA,IAAY,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC;EACvE,CACD;CACD,CAAC;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,oBAAoB,SAA2B;CAC9D,OAAO;EAAE,IAAI,QAAQ;EAAI,MAAM;EAAa,SAAS,QAAQ;CAAQ;AACtE;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,kBAAkB,SAA2B;CAC5D,OAAO;EACN,IAAI,QAAQ;EACZ,MAAM;EACN,SAAS,GAAG,4BAA4B,QAAQ;CACjD;AACD;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,gBAAgB,OAA0B;CACzD,IAAI,CAAC,WAAW,KAAK,GACpB,MAAM,IAAI,kBAAkB,YAAY,sDAAsD;CAE/F,OAAO;AACR;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,mBAAmB,KAA6C;CAC/E,IAAI,QAAQ,KAAA,KAAa,EAAE,OAAO,IACjC,MAAM,IAAI,kBAAkB,YAAY,6BAA6B;CAEtE,OAAO;AACR;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,eAAe,SAAkB,KAAkC;CAClF,IAAI,WAAW,QAAQ,KAAA,GACtB,MAAM,IAAI,kBAAkB,YAAY,8CAA8C,EACrF,SAAS,EAAE,UAAU,IAAI,EAC1B,CAAC;CAEF,OAAO;AACR;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,YAAY,MAAsB;CACjD,IAAI,CAAC,yBAAyB,IAAI,GACjC,MAAM,IAAI,kBAAkB,QAAQ,6CAA6C,EAChF,SAAS,EAAE,KAAK,EACjB,CAAC;CAEF,OAAO;AACR;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,WAAc,SAAqB,QAA6C;CAC/F,IAAI,WAAW,KAAA,GAAW,OAAO;CACjC,OAAO,IAAI,SAAY,SAAS,WAAW;EAE1C,MAAM,UAAU,IAAI,gBAAgB;EACpC,IAAI,OAAO,SAAS,OAAO,OAAO,MAAM;OAEvC,OAAO,iBAAiB,eAAe,OAAO,OAAO,MAAM,GAAG;GAC7D,MAAM;GACN,QAAQ,QAAQ;EACjB,CAAC;EAIF,QAAa,KAAK,SAAS,MAAM,CAAC,CAAC,cAAc,QAAQ,MAAM,CAAC;CACjE,CAAC;AACF;;;;;;;;;;;;;;;;;;AC3NA,IAAa,kBAAb,MAAiE;CAChE;;;;;CAMA,YAAY,YAAiC,CAAC,GAAG;EAEhD,KAAK,aAAa,IAAI,IACrB,MAAM,KAAK,YAAY,aAAa,gBAAgB,SAAS,QAAQ,CAAC,CAAC,CAAC,CAAC,KAAK,UAAU,CACvF,MAAM,IACN,KACD,CAAC,CACF;CACD;CAEA,IAAI,QAAgB;EACnB,OAAO,KAAK,WAAW;CACxB;CAIA,IAAI,OAAiF;EACpF,IAAI,QAAQ,KAAK,GAAG,OAAO,MAAM,KAAK,QAAQ,KAAK,OAAO,GAAG,CAAC;EAC9D,OAAO,KAAK,OAAO,KAAK;CACzB;CAEA,SAAS,IAAkC;EAC1C,MAAM,WAAW,KAAK,WAAW,IAAI,EAAE;EACvC,OAAO,aAAa,KAAA,IAAY,KAAA,IAAY,gBAAgB,QAAQ;CACrE;CAEA,YAAiC;EAChC,OAAO,gBAAgB,CAAC,GAAG,KAAK,WAAW,OAAO,CAAC,CAAC;CACrD;CAIA,OAAO,KAA0C;EAChD,IAAI,QAAQ,GAAG,GAAG,OAAO,cAAc,MAAM,OAAO,KAAK,WAAW,OAAO,EAAE,CAAC;EAC9E,OAAO,KAAK,WAAW,OAAO,GAAG;CAClC;CAEA,QAAc;EACb,KAAK,WAAW,MAAM;CACvB;CAEA,MAAM,QACL,OACA,SACA,SACA,QAC+B;EAG/B,MAAM,QAAQ,SAAS,QAAQ,KAAK;EACpC,IAAI,CAAC,aAAa,KAAK,GACtB,MAAM,IAAI,kBACT,YACA,0DACD;EAED,MAAM,WAAW,OAAO,UAAU,WAAW,QAAQ,KAAK,UAAU,KAAK;EACzE,MAAM,UAAU,CAAC,GAAG,OAAO;EAC3B,MAAM,UAAU,SAAS,QAAQ,SAAS,IAAI,OAAO,QAAQ,QAAQ,SAAS,IAAI,CAAC;EACnF,MAAM,UAAU,QAAQ,KAAK,CAAC,IAAI,SAAS;GAC1C,MAAM,WAAW,SAAS,GAAG;GAC7B,IAAI,CAAC,gBAAgB,QAAQ,GAC5B,MAAM,IAAI,kBAAkB,YAAY,gCAAgC,GAAG,gBAAgB,EAC1F,SAAS,EAAE,UAAU,GAAG,EACzB,CAAC;GAEF,OAAO,CAAC,IAAI,QAAQ;EACrB,CAAC;EACD,MAAM,UAAU,IAAI,IACnB,QAAQ,SAAS,CAAC,IAAI,cAAc;GACnC,MAAM,WAAW,KAAK,WAAW,IAAI,EAAE;GACvC,OAAO,aAAa,KAAA,KACnB,gBAAgB,UAAU,UAAU,SAAS,UAAU,MAAM,KAAK,IAChE,CAAC,CAAC,IAAI,QAAQ,CAAU,IACxB,CAAC;EACL,CAAC,CACF;EACA,MAAM,UAAU,QAAQ,QAAQ,CAAC,QAAQ,CAAC,QAAQ,IAAI,EAAE,CAAC;EACzD,MAAM,QACL,QAAQ,WAAW,IAChB,CAAC,IACD,MAAM,KAAK,KACX,OACA;GAAE;GAAO,WAAW,OAAO,YAAY,OAAO;EAAE,GAChD,SACA,UACA,MACD;EACH,MAAM,WAAW,IAAI,IAAI,CACxB,GAAG,SACH,GAAG,MAAM,KAAK,aAAa,CAAC,SAAS,IAAI,QAAQ,CAAU,CAC5D,CAAC;EACD,OAAO,QAAQ,SAAS,CAAC,QAAQ;GAChC,MAAM,WAAW,SAAS,IAAI,EAAE;GAChC,OAAO,aAAa,KAAA,IAAY,CAAC,IAAI,CAAC,gBAAgB,QAAQ,CAAC;EAChE,CAAC;CACF;CAIA,MAAM,KACL,OACA,WACA,SACA,UACA,QAC+B;EAC/B,IAAI,OAAO,SAAS,MAAM,IAAI,gBAAgB;GAAE,OAAO,MAAM;GAAO,SAAS,CAAC;EAAE,CAAC;EACjF,IAAI;GACH,MAAM,SAAS,MAAM,MAAM,IAAI,WAAW,MAAM;GAChD,OAAO,KAAK,IAAI,eAAe,WAAW,QAAQ,SAAS,UAAU,MAAM,KAAK,CAAC;EAClF,SAAS,OAAO;GACf,IAAI,kBAAkB,KAAK,GAC1B,KAAK,IAAI,eAAe,WAAW,MAAM,SAAS,SAAS,UAAU,MAAM,KAAK,CAAC;GAClF,MAAM;EACP;CACD;CAEA,OAAO,OAAgC;EACtC,MAAM,OAAO,SAAS,KAAK;EAC3B,MAAM,WAAW,gBAAgB,SAAS,IAAI,IAAI;GAAE,GAAG;GAAM,MAAM,KAAK,IAAI;EAAE,IAAI,IAAI;EACtF,KAAK,WAAW,IAAI,SAAS,IAAI,QAAQ;EACzC,OAAO,gBAAgB,QAAQ;CAChC;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC1EA,IAAa,eAAb,MAA2D;CAC1D;CAGA;CAGA;CAEA;CAGA;CAGA;CAGA;CAGA;CACA;CAIA,2BAAoB,IAAI,IAAkC;CAE1D,YAAY,SAA+B;EAG1C,MAAM,WAAW,SAAS;EAC1B,KAAK,aAAa,IAAI,gBAAgB,UAAU,SAAS;EACzD,KAAK,MAAM,UAAU,MAAM,SAAS,MAAM,OAAO,WAAW;EAC5D,KAAK,WAAW,IAAI,QAA8B,OAAO;EACzD,KAAK,aAAa,SAAS;EAC3B,KAAK,QAAQ,YAAY,SAAS,QAAA,CAAiC;EACnE,KAAK,OAAO,mBAAmB,SAAS,QAAQ;EAChD,KAAK,WAAW,SAAS,WAAW;EACpC,eAAe,KAAK,UAAU,KAAK,IAAI;EACvC,KAAK,YAAY,aAAa,KAAA,IAAY,CAAC,IAAI,CAAC,GAAG,SAAS,QAAQ;EACpE,KAAK,YAAY,IAAI,IAAI,UAAU,SAAS,KAAK,YAAY,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC;CACpF;CAEA,IAAI,KAAa;EAChB,OAAO,KAAK;CACb;CAEA,IAAI,YAAsC;EACzC,OAAO,KAAK;CACb;CAEA,IAAI,UAAkD;EACrD,OAAO,KAAK;CACb;CAEA,IAAI,WAA+B;EAClC,OAAO,CAAC,GAAG,KAAK,SAAS;CAC1B;CAEA,IAAI,eAAwB;EAI3B,OAAO,KAAK,eAAe,KAAA;CAC5B;CAEA,IAAI,QAAgB;EACnB,OAAO,KAAK,UAAU;CACvB;CAIA,IAAI,OAA6E;EAChF,IAAI,QAAQ,KAAK,GAAG,OAAO,MAAM,KAAK,QAAQ,KAAK,QAAQ,GAAG,CAAC;EAC/D,OAAO,KAAK,QAAQ,KAAK;CAC1B;CAEA,QAAQ,IAAiC;EACxC,OAAO,KAAK,UAAU,IAAI,EAAE;CAC7B;CAEA,WAA+B;EAC9B,OAAO,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC;CACnC;CAIA,OAAO,KAA0C;EAChD,IAAI,QAAQ,GAAG,GACd,OAAO,cAAc,MAAM,OAAO,KAAK,UAAU,OAAO,EAAE,CAAC;EAE5D,OAAO,KAAK,UAAU,OAAO,GAAG;CACjC;CAEA,QAAc;EACb,KAAK,UAAU,MAAM;CACtB;CAEA,OAA2B;EAI1B,OAAO,CACN,GAAG,KAAK,UAAU,KAAK,YAAY,kBAAkB,OAAO,CAAC,GAC7D,GAAG,KAAK,UAAU,OAAO,CAC1B;CACD;CAEA,MAAM,QAAQ,SAAwD;EACrE,MAAM,YAAY,KAAK;EACvB,IAAI,cAAc,KAAA,GACjB,MAAM,IAAI,kBACT,cACA,oDACD;EAED,MAAM,MAAM,mBAAmB,SAAS,YAAY,KAAK,IAAI;EAC7D,eAAe,KAAK,UAAU,GAAG;EACjC,MAAM,OAAO,YAAY,SAAS,QAAQ,KAAK,KAAK;EACpD,MAAM,SAAS,SAAS;EACxB,QAAQ,eAAe;EAGvB,MAAM,WAAW,KAAK,SAAS,SAAS,IAAI,KAAA,IAAY,QAAQ,WAAW,CAAC,GAAG,KAAK,QAAQ,CAAC;EAC7F,MAAM,OAAO,KAAK,MAAM,UAAU,WAAW,KAAK,MAAM,MAAM;EAC9D,KAAK,SAAS,IAAI,IAAI;EACtB,KAAU,WACH,KAAK,SAAS,OAAO,IAAI,SACzB,KAAK,SAAS,OAAO,IAAI,CAChC;EACA,OAAO;CACR;CAEA,UAAU,IAA4C;EACrD,MAAM,UAAU,KAAK,UAAU,MAAM,QAAQ,IAAI,OAAO,EAAE;EAC1D,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;EAElC,KAAK,SAAS,KAAK,aAAa,EAAE;EAClC,OAAO,QAAQ;CAChB;CAEA,OAAO,OAAmC;EAEzC,MAAM,SAAS,MAAM,YAAY;EAKjC,OAAO,CAHN,GAAG,KAAK,UAAU,SAAS,YAAY,QAAQ,QAAQ,GACvD,GAAG,KAAK,UAAU,OAAO,CAEnB,CAAA,CAAI,QAAQ,YAAY,QAAQ,QAAQ,YAAY,CAAC,CAAC,SAAS,MAAM,CAAC;CAC9E;CAEA,UAAU,SAAgD;EAIzD,MAAM,QAAQ,SAAS,SAAS,KAAK;EACrC,MAAM,WAAW,SAAS,YAAY,CAAC;EAEvC,OAAO,CACN,8BAA8B,MAAM,qCACpC,GAAI,SAAS,SAAS,IACnB,CACA,sBACA,GAAG,MAAM,KAAK,WAAW,YAAY,KAAK,QAAQ,KAAK,IAAI,QAAQ,SAAS,CAC7E,IACC,CAAC,CACL,CAAC,CAAC,KAAK,IAAI;CACZ;CAEA,WAAiC;EAGhC,OAAO;GACN,IAAI,KAAK;GACT,UAAU,KAAK;GACf,UAAU,KAAK,SAAS;GACxB,GAAI,KAAK,WAAW,UAAU,IAAI,CAAC,IAAI,EAAE,WAAW,KAAK,WAAW,UAAU,EAAE;EACjF;CACD;CAKA,MAAM,MACL,UACA,WACA,KACA,MACA,QAC+B;EAC/B,IAAI,aAAa,KAAA,GAAW,MAAM,WAAW,UAAU,MAAM;EAC7D,QAAQ,eAAe;EACvB,MAAM,OAAO,CAAC,GAAG,KAAK,UAAU,OAAO,CAAC;EAExC,MAAM,SAAS,KAAK,eAAe,YAAY,QAAQ,SAAS,MAAM;EACtE,MAAM,QAAQ,KAAK,WAAW,YAAY,QAAQ,SAAS,MAAM;EACjE,MAAM,SAAS,KAAK,IACnB,QAAQ,IAAI,KAAK,SAAS,KAAK,SAAS,MACxC,WAAW,KAAK,KAAK,SAAS,MAC/B;EAGA,MAAM,EAAE,YAAY,iBAAiB,IAAI,CAAC,CAAC,QACzC,KAAK,aAAa;GAClB,MAAM,MAAM,IAAI,QAAQ,SAAS;GACjC,OAAO;IAAE,OAAO;IAAK,SAAS,IAAI,QAAQ,UAAU,SAAS,MAAM,IAAI,QAAQ,IAAI;GAAQ;EAC5F,GACA;GAAE,OAAO;GAAG,SAAS;EAAO,CAC7B;EAEA,MAAM,OAAO,SAAS,KAAK,WAAW,QAAQ,IAAI;EAClD,IAAI,QAAQ,GAAG,OAAO,KAAA;EACtB,MAAM,QAAQ,KAAK,MAAM,GAAG,IAAI;EAGhC,MAAM,QAAQ,KAAK,WAAW,KAAK,YAAY,CAAC;EAEhD,MAAM,UAAU,MAAM,WAAW,UAAU,CAD1B,GAAG,MAAM,KAAK,QAAQ,kBAAkB,GAAG,CAAC,GAAG,GAAG,cAAc,OAAO,MAAM,CACnD,GAAS,MAAM,GAAG,MAAM;EACnE,QAAQ,eAAe;EAGvB,IAAI,CAAC,MAAM,OAAO,YAAY,KAAK,UAAU,IAAI,QAAQ,EAAE,MAAM,OAAO,GAAG,OAAO,KAAA;EAGlF,IACC,KAAK,aACJ,KAAK,UAAU,WAAW,MAAM,UAChC,CAAC,MAAM,OAAO,KAAK,UAAU,KAAK,UAAU,WAAW,GAAG,IAE3D;EAED,MAAM,UAAmB;GACxB,IAAI,OAAO,WAAW;GACtB;GACA,UAAU,KAAK,WAAW,CAAC,GAAG,MAAM,SAAS,QAAQ,IAAI,QAAQ,GAAG,GAAG,KAAK,IAAI;EACjF;EACA,KAAK,MAAM,WAAW,OAAO,KAAK,UAAU,OAAO,QAAQ,EAAE;EAC7D,KAAK,YAAY,KAAK,WAAW,CAAC,OAAO,IAAI,CAAC,GAAG,KAAK,WAAW,OAAO;EAExE,IAAI,QAAQ,KAAA,KAAa,KAAK,UAAU,SAAS,KAAK;GACrD,MAAM,WAAW,KAAK,UAAU,SAAS,MAAM;GAC/C,MAAM,SAAS,KAAK,UAAU,MAAM,GAAG,QAAQ;GAC/C,MAAM,SAAS,MAAM,WACpB,UACC,OAAO,KAAK,QAAQ,oBAAoB,GAAG,CAAC,GAC5C,MACD,GACA,MACD;GACA,QAAQ,eAAe;GAGvB,IAAI,CAAC,OAAO,OAAO,KAAK,UAAU,KAAK,UAAU,WAAW,GAAG,GAAG,OAAO,KAAA;GACzE,MAAM,SAAkB;IACvB,IAAI,OAAO,WAAW;IACtB,SAAS;IACT,UAAU,OAAO,SAAS,QAAQ,IAAI,QAAQ;GAC/C;GACA,KAAK,YAAY,CAAC,QAAQ,GAAG,KAAK,UAAU,MAAM,QAAQ,CAAC;GAC3D,KAAK,SAAS,KAAK,YAAY,MAAM;EACtC;EAEA,KAAK,SAAS,KAAK,WAAW,OAAO;EACrC,OAAO;CACR;CAGA,QAAQ,OAA8B;EACrC,MAAM,UAAmB;GACxB,IAAI,OAAO,WAAW;GACtB,MAAM,MAAM;GACZ,SAAS,MAAM;GACf,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;GAC1D,GAAI,MAAM,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,MAAM,KAAK;GACvD,GAAI,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;GAC7D,GAAI,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;EACpE;EACA,KAAK,UAAU,IAAI,QAAQ,IAAI,OAAO;EACtC,OAAO;CACR;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3TA,IAAa,sBAAb,MAAyE;CACxE,iCAA0B,IAAI,IAAmC;CAIjE;CAGA;CAEA;CAEA;CAEA;CAEA,YAAY,SAAsC;EACjD,KAAK,aAAa,SAAS;EAC3B,KAAK,QAAQ,YAAY,SAAS,QAAA,CAAiC;EACnE,KAAK,YAAY,SAAS;EAC1B,KAAK,SAAS,SAAS;CACxB;CAEA,IAAI,QAAgB;EACnB,OAAO,KAAK,eAAe;CAC5B;CAEA,IAAI,SAA4C;EAC/C,OAAO,KAAK,YAAY,KAAA,IAAY,KAAA,IAAY,KAAK,eAAe,IAAI,KAAK,OAAO;CACrF;CAEA,aAAa,IAA+C;EAC3D,OAAO,KAAK,eAAe,IAAI,EAAE;CAClC;CAEA,gBAAkD;EACjD,OAAO,CAAC,GAAG,KAAK,eAAe,OAAO,CAAC;CACxC;CAEA,IAAI,OAAkD;EAGrD,MAAM,WAAW,OAAO,YAAY,KAAK;EACzC,MAAM,YAAY,OAAO,aAAa,KAAK;EAC3C,MAAM,eAAe,IAAI,aAAa;GACrC,GAAI,OAAO,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,MAAM,GAAG;GAClD,GAAI,OAAO,OAAO,KAAA,IAAY,CAAC,IAAI,EAAE,IAAI,MAAM,GAAG;GAClD,GAAI,OAAO,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;GAC3D,GAAI,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU;GAC/C,MAAM,OAAO,QAAQ,KAAK;GAC1B,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS;GAC7C,GAAI,OAAO,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;GACjE,GAAI,OAAO,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,MAAM,SAAS;EACrE,CAAC;EACD,KAAK,eAAe,IAAI,aAAa,IAAI,YAAY;EAErD,IAAI,KAAK,YAAY,KAAA,GAAW,KAAK,UAAU,aAAa;EAC5D,OAAO;CACR;CAEA,OAAO,IAA+C;EAErD,MAAM,eAAe,KAAK,eAAe,IAAI,EAAE;EAC/C,IAAI,iBAAiB,KAAA,GAAW,OAAO,KAAA;EACvC,KAAK,UAAU;EACf,OAAO;CACR;CAEA,MAAM,KAAK,IAAwD;EAClE,MAAM,WAAW,KAAK,eAAe,IAAI,EAAE;EAC3C,IAAI,aAAa,KAAA,GAAW;GAC3B,KAAK,UAAU;GACf,OAAO;EACR;EACA,IAAI,KAAK,WAAW,KAAA,GAAW,OAAO,KAAA;EACtC,MAAM,WAAW,MAAM,KAAK,OAAO,IAAI,EAAE;EAGzC,MAAM,aAAa,KAAK,eAAe,IAAI,EAAE;EAC7C,IAAI,eAAe,KAAA,GAAW;GAC7B,KAAK,UAAU;GACf,OAAO;EACR;EAGA,IAAI,aAAa,KAAA,KAAa,SAAS,OAAO,IAAI,OAAO,KAAA;EAEzD,MAAM,eAAe,KAAK,IAAI,EAAE,SAAS,CAAC;EAG1C,KAAK,UAAU,aAAa;EAC5B,OAAO;CACR;CAEA,MAAM,KAAK,IAA8B;EACxC,MAAM,eAAe,KAAK,eAAe,IAAI,EAAE;EAC/C,IAAI,KAAK,WAAW,KAAA,KAAa,iBAAiB,KAAA,GAAW,OAAO;EACpE,MAAM,KAAK,OAAO,IAAI,aAAa,SAAS,CAAC;EAC7C,OAAO;CACR;CAIA,OAAO,KAA0C;EAChD,IAAI,QAAQ,GAAG,GAEd,OAAO,cAAc,MAAM,OAAO,KAAK,MAAM,EAAE,CAAC;EAEjD,OAAO,KAAK,MAAM,GAAG;CACtB;CAEA,QAAc;EACb,KAAK,eAAe,MAAM;EAE1B,KAAK,UAAU,KAAA;CAChB;CAIA,MAAM,IAAqB;EAC1B,MAAM,UAAU,KAAK,eAAe,OAAO,EAAE;EAC7C,IAAI,WAAW,KAAK,YAAY,IAAI,KAAK,UAAU,KAAA;EACnD,OAAO;CACR;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpIA,IAAa,0BAAb,MAA2E;CAC1E,6BAAsB,IAAI,IAAkC;;;;;;;CAQ5D,IAAI,IAAuD;EAC1D,OAAO,QAAQ,QAAQ,KAAK,WAAW,IAAI,EAAE,CAAC;CAC/C;;;;;;;;CASA,IAAI,UAA+C;EAClD,KAAK,WAAW,IAAI,SAAS,IAAI,QAAQ;EACzC,OAAO,QAAQ,QAAQ;CACxB;;;;;;;CAQA,OAAO,IAA2B;EAEjC,KAAK,WAAW,OAAO,EAAE;EACzB,OAAO,QAAQ,QAAQ;CACxB;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AChBA,IAAa,4BAAb,MAA6E;CAC5E;;;;;;;CAQA,YAAY,OAAgD;EAC3D,KAAK,SAAS;CACf;;;;;;;;;;;;;;CAeA,MAAM,IAAI,IAAuD;EAChE,MAAM,MAAM,MAAM,KAAK,OAAO,IAAI,EAAE;EACpC,IAAI,QAAQ,KAAA,GAAW,OAAO,KAAA;EAI9B,MAAM,WAAW,IAAI;EACrB,OAAO,uBAAuB,QAAQ,KAAK,SAAS,OAAO,KAAK,WAAW,KAAA;CAC5E;;;;;;;;CASA,MAAM,IAAI,UAA+C;EACxD,MAAM,KAAK,OAAO,IAAI;GAAE,IAAI,SAAS;GAAI;EAAS,CAAC;CACpD;;;;;;;CAQA,MAAM,OAAO,IAA2B;EACvC,MAAM,KAAK,OAAO,OAAO,EAAE;CAC5B;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7CA,SAAgB,mBAAmB,SAAsD;CACxF,OAAO,IAAI,aAAa,OAAO;AAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,0BACf,SAC+B;CAC/B,OAAO,IAAI,oBAAoB,OAAO;AACvC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAkCA,SAAgB,gCAA4D;CAC3E,OAAO,IAAI,wBAAwB;AACpC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,SAAgB,gCACf,SAA0B,mBAAmB,GAChB;CAI7B,MAAM,UAAU;EAAE,IAAI,YAAY;EAAG,UAAU,SAAS,CAAC,CAAC;CAAE;CAG5D,OAAO,IAAI,0BAFM,eAAe;EAAE;EAAQ,QAAQ,EAAE,eAAe,QAAQ;CAAE,CACtB,CAAA,CAAS,MAAM,eACjC,CAAK;AAC3C;;;;;;;;;;;;;;;;ACrLA,IAAa,2BAA2B;;;;;;;;;;;;;;;;;;;;;;ACQxC,IAAa,cAAb,MAAyD;CACxD;CACA;CACA;CACA;CACA;CAEA,YAAY,OAAyB;EACpC,KAAK,KAAK,OAAO,WAAW;EAC5B,KAAK,OAAO,MAAM;EAClB,KAAK,UAAU,MAAM;EACrB,KAAK,WAAW,MAAM,YAAY;EAClC,IAAI,MAAM,aAAa,KAAA,GAAW,KAAK,WAAW,MAAM;CACzD;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACeA,IAAa,qBAAb,MAAuE;CACtE,gCAAyB,IAAI,IAAkC;CAG/D;CACA;CAEA,YAAY,SAAqC;EAChD,KAAK,WAAW,IAAI,QAAoC,OAAO;EAC/D,KAAK,UAAU,SAAS;CACzB;CAEA,IAAI,UAAwD;EAC3D,OAAO,KAAK;CACb;CAEA,IAAI,QAAgB;EACnB,OAAO,KAAK,cAAc;CAC3B;CAEA,IAAI,OAAe;EAClB,OAAO,KAAK,SAAS,QAAQ;CAC9B;CAEA,IAAI,QAA4B;EAC/B,OAAO,KAAK,SAAS;CACtB;CAIA,IACC,OACyD;EACzD,IAAI,QAAQ,KAAK,GAAG,OAAO,MAAM,KAAK,QAAQ,KAAK,QAAQ,GAAG,CAAC;EAC/D,OAAO,KAAK,QAAQ,KAAK;CAC1B;CAEA,YAAY,MAAgD;EAC3D,OAAO,KAAK,cAAc,IAAI,IAAI;CACnC;CAEA,eAAgD;EAG/C,OAAO,CAAC,GAAG,KAAK,cAAc,OAAO,CAAC,CAAC,CAAC,MAAM,GAAG,MAAM,EAAE,WAAW,EAAE,QAAQ;CAC/E;CAEA,OAAO,aAA2C;EACjD,OAAO,YAAY,YAAY,KAAK,SAAS,SAAS,WAAW,KAAK,YAAY;CACnF;CAIA,OAAO,OAA4C;EAClD,IAAI,QAAQ,KAAK,GAEhB,OAAO,cAAc,QAAQ,SAAS,KAAK,QAAQ,IAAI,CAAC;EAEzD,OAAO,KAAK,QAAQ,KAAK;CAC1B;CAEA,QAAc;EACb,KAAK,cAAc,MAAM;EAGzB,KAAK,SAAS,KAAK,OAAO;CAC3B;CAIA,QAAQ,OAA+C;EACtD,MAAM,cAAc,IAAI,YAAY,KAAK;EACzC,KAAK,cAAc,IAAI,YAAY,MAAM,WAAW;EACpD,KAAK,SAAS,KAAK,OAAO,WAAW;EACrC,OAAO;CACR;CAIA,QAAQ,MAAuB;EAC9B,MAAM,UAAU,KAAK,cAAc,OAAO,IAAI;EAC9C,IAAI,SAAS,KAAK,SAAS,KAAK,UAAU,IAAI;EAC9C,OAAO;CACR;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACvGA,SAAgB,iBAAiB,MAAc,UAAkB,SAAyB;CAEzF,MAAM,WADO,QAAQ,MAAM,KAAK,KAAK,CAAC,EAAA,CACjB,QAAQ,MAAM,QAAQ,KAAK,IAAI,MAAM,IAAI,MAAM,GAAG,CAAC;CACxE,MAAM,QAAQ,IAAI,OAAO,KAAK,IAAI,GAAG,UAAU,CAAC,CAAC;CACjD,OAAO,SAAS,KAAK,IAAI,QAAQ,SAAS,IAAI,QAAQ,IAAI;AAC3D;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,SAAgB,cACf,MACA,SACA,QACA,OACqB;CACrB,IAAI,QAAQ,WAAW,GAAG,OAAO,KAAA;CACjC,MAAM,QAAQ;EAAC;EAAM,GAAG,QAAQ,IAAI,MAAM;EAAG;CAAK,CAAC,CAAC,SAAS,SAC5D,SAAS,KAAA,KAAa,SAAS,KAAK,CAAC,IAAI,CAAC,IAAI,CAC/C;CACA,OAAO,MAAM,WAAW,IAAI,KAAA,IAAY,MAAM,KAAK,MAAM;AAC1D;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,aAAa,SAAkB,UAAsC;CACpF,OAAO;EAAE,GAAG;EAAS,QAAQ,CAAC,GAAI,QAAQ,UAAU,CAAC,GAAI,GAAG,QAAQ;CAAE;AACvE;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,iBACf,cACA,UACqB;CACrB,IAAI,SAAS,WAAW,GAAG,OAAO;CAClC,MAAM,SAAS,aAAa,eAC1B,YAAiC,SAAS,SAAS,MACrD;CACA,IAAI,WAAW,IAAI,OAAO;CAC1B,OAAO,aAAa,KAAK,SAAS,UACjC,UAAU,SAAS,aAAa,SAAS,QAAQ,IAAI,OACtD;AACD;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,iBAAiB,OAAoD;CAEpF,OAAO,CAAC,GAAG,KAAK,CAAC,CAAC,SAAS,SAC1B,SAAS,KAAK,OAAO,KAAK,KAAK,QAAQ,KAAK,WAAW,QAAQ,IAAI,CAAC,KAAK,QAAQ,MAAM,IAAI,CAAC,CAC7F;AACD;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,cACf,QACA,OACgC;CAChC,IAAI,WAAW,KAAA,GAAW,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,CAAC,GAAG,KAAK;CAC5E,IAAI,UAAU,KAAA,GAAW,OAAO,CAAC,GAAG,MAAM;CAC1C,MAAM,UAAU,IAAI,IAAI,MAAM;CAC9B,OAAO,MAAM,QAAQ,QAAQ,QAAQ,IAAI,GAAG,CAAC;AAC9C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7JA,IAAa,QAAb,MAAa,MAAgC;CAC5C,KAAsB,OAAO,WAAW;CACxC;CACA;CACA;CACA;CACA;CAEA,YAAY,OAAmB;EAC9B,KAAK,OAAO,MAAM;EAClB,IAAI,MAAM,WAAW,KAAA,GAAW,KAAK,SAAS,MAAM;EAGpD,IAAI,MAAM,iBAAiB,KAAA,GAAW,KAAK,eAAe,CAAC,GAAG,MAAM,YAAY;EAChF,IAAI,MAAM,UAAU,KAAA,GAAW,KAAK,QAAQ,CAAC,GAAG,MAAM,KAAK;EAC3D,IAAI,MAAM,UAAU,KAAA,GAAW,KAAK,QAAQ,CAAC,GAAG,MAAM,KAAK;CAC5D;CAEA,OAAO,QAAqC;EAC3C,MAAM,eAAe,cAAc,KAAK,cAAc,OAAO,YAAY;EACzE,MAAM,QAAQ,cAAc,KAAK,OAAO,OAAO,KAAK;EACpD,MAAM,QAAQ,cAAc,KAAK,OAAO,OAAO,KAAK;EACpD,OAAO,IAAI,MAAM;GAChB,MAAM,KAAK;GACX,GAAI,KAAK,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO;GAC3D,GAAI,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,aAAa;GACrD,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;GACvC,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EACxC,CAAC;CACF;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACxBA,IAAa,eAAb,MAA2D;CAC1D,0BAAmB,IAAI,IAA4B;CAGnD;CAEA,YAAY,SAA+B;EAC1C,KAAK,WAAW,IAAI,QAA8B,OAAO;CAC1D;CAEA,IAAI,UAAkD;EACrD,OAAO,KAAK;CACb;CAEA,IAAI,QAAgB;EACnB,OAAO,KAAK,QAAQ;CACrB;CAEA,IAAI,OAAmC;EACtC,MAAM,QAAQ,IAAI,MAAM,KAAK;EAC7B,KAAK,QAAQ,IAAI,MAAM,IAAI,KAAK;EAGhC,KAAK,SAAS,KAAK,OAAO,KAAK;EAC/B,OAAO;CACR;CAEA,MAAM,IAAwC;EAC7C,OAAO,KAAK,QAAQ,IAAI,EAAE;CAC3B;CAEA,SAAoC;EACnC,OAAO,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC;CACjC;CAIA,OAAO,KAA0C;EAChD,IAAI,QAAQ,GAAG,GAEd,OAAO,cAAc,MAAM,OAAO,KAAK,QAAQ,EAAE,CAAC;EAEnD,OAAO,KAAK,QAAQ,GAAG;CACxB;CAEA,QAAc;EACb,KAAK,QAAQ,MAAM;EAGnB,KAAK,SAAS,KAAK,OAAO;CAC3B;CAIA,QAAQ,IAAqB;EAC5B,MAAM,UAAU,KAAK,QAAQ,OAAO,EAAE;EACtC,IAAI,SAAS,KAAK,SAAS,KAAK,UAAU,EAAE;EAC5C,OAAO;CACR;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACZA,IAAa,eAAb,MAA2D;CAC1D;CACA;CAKA;CAKA;CACA;CAEA;CACA;CAEA,YAAY,SAA+B;EAC1C,KAAK,UAAU,SAAS;EACxB,KAAK,gBAAgB,SAAS,gBAAgB,IAAI,mBAAmB;EAIrE,KAAK,cAAc,SAAS,cAAc,IAAI,iBAAiB;EAO/D,KAAK,iBAAiB,SAAS,iBAAiB,IAAI,oBAAoB;EACxE,IAAI,KAAK,eAAe,WAAW,KAAA,GAAW,KAAK,eAAe,IAAI;EACtE,KAAK,SAAS,SAAS,SAAS,IAAI,YAAY;EAChD,KAAK,UAAU,SAAS;EACxB,KAAK,SAAS,SAAS;CACxB;CAEA,IAAI,SAA6B;EAChC,OAAO,KAAK;CACb;CAEA,IAAI,eAA4C;EAC/C,OAAO,KAAK;CACb;CAEA,IAAI,aAAwC;EAC3C,OAAO,KAAK;CACb;CAUA,IAAI,WAAoC;EACvC,OAAO,KAAK,oBAAoB;CACjC;CAEA,IAAI,gBAA8C;EACjD,OAAO,KAAK;CACb;CAEA,IAAI,QAA8B;EACjC,OAAO,KAAK;CACb;CAEA,IAAI,QAAoC;EACvC,OAAO,KAAK;CACb;CAEA,MAAM,OAAyC;EAC9C,KAAK,SAAS;CACf;CAEA,OAAO,SAAkB,QAAqD;EAE7E,MAAM,UAAU,KAAK,QAAQ,UAAU,KAAK;EAC5C,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;EAClC,OAAO,KAAK,OAAO,SAAS,KAAK,oBAAoB,GAAG,SAAS,MAAM;CACxE;CAEA,MAAM,WAA2C;EAChD,MAAM,QAAQ,KAAK;EAEnB,MAAM,QAAkB,CAAC;EAGzB,IAAI,KAAK,YAAY,KAAA,GAAW,MAAM,KAAK,KAAK,OAAO;EACvD,MAAM,eAAe,gBACpB,OAAO,cACP,KAAK,cAAc,aAAa,IAC/B,QAAQ,IAAI,IACd;EACA,MAAM,aAAa,cAClB,KAAK,cAAc,MACnB,eACC,QAAQ,KAAK,cAAc,OAAO,GAAG,GACtC,KAAK,cAAc,KACpB;EACA,IAAI,eAAe,KAAA,GAAW,MAAM,KAAK,UAAU;EAGnD,MAAM,QAAQ,gBACb,OAAO,OACP,KAAK,YAAY,QAAQ,MAAM,KAAK,CAAC,IACpC,QAAQ,IAAI,IACd;EAMA,MAAM,aAAa,cAClB,0BANsB,MAAM,SAAS,SACrC,OAAO,KAAK,OAAO,IAChB,CAAC;GAAE,MAAM,KAAK;GAAM,UAAU,KAAK,QAAQ;GAAU,MAAM,KAAK,QAAQ;EAAK,CAAC,IAC9E,CAAC,CAIJ,IACC,SAAS,iBAAiB,KAAK,MAAM,KAAK,UAAU,KAAK,IAAI,GAC9D,KAAA,CACD;EACA,IAAI,eAAe,KAAA,GAAW,MAAM,KAAK,UAAU;EASnD,MAAM,OAAO,iBAFQ,WAAW,YAAY,KAAK,oBAAoB,CAAC,CAAC,KAAK,GAEhC,iBAAiB,KAAK,CAAC;EAGnE,IACC,cAAc,KAAA,KACd,UAAU,UAAU,KAAA,KACpB,UAAU,aAAa,KAAA,KACvB,UAAU,aAAa,IAEvB,MAAM,KAAK,UAAU,QAAQ;EAG9B,IAAI,MAAM,WAAW,GAAG,OAAO;EAM/B,OAAO,CAAC;GAJP,IAAI,OAAO,WAAW;GACtB,MAAM;GACN,SAAS,MAAM,KAAK,MAAM;EAEnB,GAAQ,GAAG,IAAI;CACxB;CAKA,MAAM,OACL,SACA,cACA,SACA,QACqB;EACrB,MAAM,SAAS,aAAa,KAAK,CAAC,CAAC,KAAK,YAAY,QAAQ,EAAE;EAC9D,MAAM,YAAY,MAAM,QAAQ,cAAc,SAAS,MAAM;EAC7D,MAAM,QAAQ,aAAa,KAAK;EAChC,IACC,MAAM,WAAW,OAAO,UACxB,MAAM,OAAO,SAAS,UAAU,QAAQ,OAAO,OAAO,MAAM,GAE5D,OAAO;EAER,MAAM,OAAO,gBAAgB,aAAa,GAAG,6BAA6B,OAAO,OAAO,oBAAoB,MAAM,OAAO;EACzH,OAAO;GACN,UAAU;GACV,WAAW,UAAU;GACrB,GAAI,UAAU,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,UAAU,MAAM;GAClE,OACC,UAAU,UAAU,KAAA,IACjB,IAAI,MAAM,IAAI,IACd,IAAI,MAAM,MAAM,EAAE,OAAO,UAAU,MAAM,CAAC;EAC/C;CACD;CAIA,sBAA6C;EAC5C,IAAI,KAAK,eAAe,WAAW,KAAA,GAAW,OAAO,KAAK,eAAe;EACzE,MAAM,eAAe,KAAK,eAAe,IAAI;EAC7C,OAAO,KAAK,eAAe,UAAU;CACtC;AACD;;;;;;;;;;;;;;;;;;;;;;AC/OA,SAAgB,kBAAkB,OAA+C;CAChF,OAAO,IAAI,YAAY,KAAK;AAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA8BA,SAAgB,yBACf,SAC8B;CAC9B,OAAO,IAAI,mBAAmB,OAAO;AACtC;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,YAAY,OAAmC;CAC9D,OAAO,IAAI,MAAM,KAAK;AACvB;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,mBAAmB,SAAsD;CACxF,OAAO,IAAI,aAAa,OAAO;AAChC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAoCA,SAAgB,mBAAmB,SAAsD;CACxF,OAAO,IAAI,aAAa,OAAO;AAChC;;;;;;;ACjKA,IAAa,sBAAsB;;;;AAKnC,IAAa,yBAAyB;;;;AAKtC,IAAa,yBAAyB;;;;;;;;;;;;AAatC,IAAa,uBAAuB;;;;;;;;;;;;;;;;;;;ACOpC,IAAa,gBAAb,cAAmC,MAAM;;CAExC,OAAgB;;CAEhB;CAEA,YAAY,SAAiB,SAAsB;EAClD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,WAAW,OAAO,MAAM,OAAO,IAAI,gCAAgC,GAAG,EAAE,OAAO,KAAK,CAAC;EACrF,KAAK,UAAU;CAChB;AACD;;;;;;;;;;;;;;;;;AAkBA,SAAgB,gBAAgB,OAAwC;CACvE,OAAO,YAAY;EAClB,IACC,EACC,iBAAiB,SACjB,WAAW,UAAU,KAAK,MAAM,MAAM,aACtC,WAAW,SAAS,OAAO,OAAO,IAAI,gCAAgC,CAAC,CAAC,EAAE,UAAU,QAGrF,OAAO;EAER,IAAI,EADS,WAAW,QAAQ,KAAK,OAAO,MACtC,MAAS,YAAY,OAAO;EAClC,MAAM,UAAU,WAAW,QAAQ,KAAK,OAAO,SAAS;EACxD,IAAI,EAAE,SAAS,OAAO,KAAK,WAAW,OAAO,IAAI,OAAO;EACxD,MAAM,QAAQ,WAAW,QAAQ,KAAK,SAAS,OAAO;EACtD,MAAM,OAAO,WAAW,QAAQ,KAAK,SAAS,MAAM;EACpD,IAAI,SAAS,KAAA,GAAW;GACvB,IAAI,EAAE,SAAS,IAAI,KAAK,WAAW,IAAI,IAAI,OAAO;GAClD,MAAM,QAAQ,WAAW,QAAQ,KAAK,MAAM,OAAO;GACnD,MAAM,QAAQ,WAAW,QAAQ,KAAK,MAAM,OAAO;GACnD,IACC,CAAC,SAAS,WAAW,QAAQ,KAAK,MAAM,IAAI,CAAC,KAC7C,EACC,WAAW,QAAQ,KAAK,MAAM,UAAU,MAAM,KAAA,KAC9C,SAAS,WAAW,QAAQ,KAAK,MAAM,UAAU,CAAC,MAEnD,EACC,UAAU,KAAA,MACR,SAAS,KAAK,KAAK,WAAW,KAAK,MACpC;IAAC;IAAU;IAAc;GAAO,CAAC,CAAC,OAAO,QACxC,SAAS,WAAW,QAAQ,KAAK,OAAO,GAAG,CAAC,CAC7C,IAGF,OAAO;GACR,IACC,UAAU,WACV,GACE,UAAU,WAAW,UAAU,aAChC,SAAS,WAAW,QAAQ,KAAK,MAAM,KAAK,CAAC,KAC7C,SAAS,WAAW,QAAQ,KAAK,MAAM,UAAU,CAAC,IAGnD,OAAO;EACT;EACA,OACC,SAAS,WAAW,QAAQ,KAAK,SAAS,SAAS,CAAC,MACnD,WAAW,QAAQ,KAAK,SAAS,UAAU,MAAM,KAAA,KACjD,SAAS,WAAW,QAAQ,KAAK,SAAS,UAAU,CAAC,MACtD,UAAU,WAAW,QAAQ,KAAK,SAAS,SAAS,CAAC,MACpD,UAAU,KAAA,MACR,SAAS,KAAK,KAAK,WAAW,KAAK,MACpC;GAAC;GAAU;GAAc;EAAO,CAAC,CAAC,OAAO,QACxC,SAAS,WAAW,QAAQ,KAAK,OAAO,GAAG,CAAC,CAC7C;CAEJ,CAAC;AACF;;;;;;;;;;;;;;;;;;;;AA0BA,IAAa,aAAb,cAAgC,MAAM;;CAErC;;CAEA;;;;;;;;CASA,YAAY,MAAsB,SAAiB,SAA6B;EAC/E,MAAM,SAAS,SAAS,UAAU,KAAA,IAAY,KAAA,IAAY,EAAE,OAAO,QAAQ,MAAM,CAAC;EAClF,KAAK,OAAO;EACZ,WAAW,OAAO,MAAM,OAAO,IAAI,6BAA6B,GAAG,EAAE,OAAO,KAAK,CAAC;EAClF,KAAK,OAAO;EACZ,KAAK,UAAU,SAAS;CACzB;AACD;;;;;;;;;;;;;;;;;AAkBA,SAAgB,aAAa,OAAqC;CACjE,OAAO,YAAY;EAClB,IACC,EACC,iBAAiB,SACjB,WAAW,UAAU,KAAK,MAAM,MAAM,aACtC,WAAW,SAAS,OAAO,OAAO,IAAI,6BAA6B,CAAC,CAAC,EAAE,UAAU,QAGlF,OAAO;EACR,MAAM,OAAO,WAAW,QAAQ,KAAK,OAAO,MAAM;EAClD,IAAI,EAAE,SAAS,iBAAiB,SAAS,WAAW,SAAS,cAAc,SAAS,WACnF,OAAO;EACR,MAAM,UAAU,WAAW,QAAQ,KAAK,OAAO,SAAS;EACxD,OAAO,YAAY,KAAA,KAAa,SAAS,OAAO,KAAK,WAAW,OAAO;CACxE,CAAC;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC5KA,IAAa,UAAb,MAAuD;CACtD,UAAgD,CAAC;CACjD,WAAsC,CAAC;CACvC,UAAU;CACV;CAEA,KAAK,OAAgB;EACpB,KAAK,UAAU,CAAC,GAAG,KAAK,SAAS,EAAE,MAAM,CAAC;EAC1C,KAAK,QAAQ;CACd;CAEA,QAAc;EACb,KAAK,UAAU;EACf,KAAK,QAAQ;CACd;CAEA,KAAK,OAAsB;EAE1B,IAAI,KAAK,aAAa,KAAA,GAAW,KAAK,WAAW,EAAE,MAAM;EACzD,KAAK,UAAU;EACf,KAAK,QAAQ;CACd;CAEA,OAAO,QAAiC;EACvC,SAAS;GAGR,OAAO,KAAK,QAAQ,SAAS,GAAG;IAC/B,MAAM,CAAC,MAAM,GAAG,aAAa,KAAK;IAClC,KAAK,UAAU;IACf,IAAI,SAAS,KAAA,GAAW,MAAM,KAAK;GACpC;GACA,IAAI,KAAK,aAAa,KAAA,GAAW,MAAM,KAAK,SAAS;GACrD,IAAI,KAAK,SAAS;GAClB,MAAM,KAAK,MAAM;EAClB;CACD;CAMA,UAAgB;EACf,MAAM,UAAU,KAAK;EACrB,KAAK,WAAW,CAAC;EACjB,KAAK,MAAM,QAAQ,SAAS,KAAK;CAClC;CAEA,QAAuB;EACtB,OAAO,IAAI,SAAe,YAAY;GACrC,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,OAAO;EAC3C,CAAC;CACF;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACpBA,SAAgB,kBAAkB,OAAuC;CACxE,MAAM,WAAW,cAAc;EAC9B,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO,KAAA;EAE7B,MAAM,UAAU,QAAQ,IAAI,OAAO,SAAS;EAC5C,MAAM,WAAW,QAAQ,IAAI,OAAO,UAAU;EAC9C,MAAM,QAAQ,QAAQ,IAAI,OAAO,OAAO;EACxC,MAAM,UAAU,QAAQ,IAAI,OAAO,SAAS;EAC5C,MAAM,OAAO,QAAQ,IAAI,OAAO,MAAM;EACtC,IAAI,CAAC,SAAS,OAAO,KAAK,CAAC,UAAU,OAAO,GAAG,OAAO,KAAA;EACtD,IAAI,aAAa,KAAA,KAAa,CAAC,SAAS,QAAQ,GAAG,OAAO,KAAA;EAC1D,MAAM,iBAAiB,UAAU,KAAA,IAAY,KAAA,IAAY,iBAAiB,KAAK;EAC/E,IAAI,UAAU,KAAA,KAAa,mBAAmB,KAAA,GAAW,OAAO,KAAA;EAChE,IAAI,SAAS,KAAA,KAAa,CAAC,SAAS,IAAI,GAAG,OAAO,KAAA;EAElD,MAAM,QAAQ,SAAS,IAAI,IAAI,QAAQ,IAAI,MAAM,OAAO,IAAI,KAAA;EAC5D,MAAM,KAAK,SAAS,IAAI,IAAI,QAAQ,IAAI,MAAM,IAAI,IAAI,KAAA;EACtD,MAAM,SAAS,UAAU,WAAW,UAAU;EAC9C,MAAM,MAAM,SAAS,IAAI,KAAK,SAAS,QAAQ,IAAI,MAAM,KAAK,IAAI,KAAA;EAClE,MAAM,WAAW,SAAS,IAAI,KAAK,SAAS,QAAQ,IAAI,MAAM,UAAU,IAAI,KAAA;EAC5E,MAAM,WAAW,SAAS,IAAI,IAAI,QAAQ,IAAI,MAAM,UAAU,IAAI,KAAA;EAClE,MAAM,QAAQ,SAAS,IAAI,IAAI,QAAQ,IAAI,MAAM,OAAO,IAAI,KAAA;EAC5D,MAAM,iBAAiB,UAAU,KAAA,IAAY,KAAA,IAAY,iBAAiB,KAAK;EAC/E,MAAM,WAAW;GAChB,GAAI,eAAe,QAAQ,IAAI,EAAE,SAAS,IAAI,CAAC;GAC/C,GAAI,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,eAAe;EACjE;EACA,MAAM,gBACL,CAAC,SAAS,EAAE,KACX,aAAa,KAAA,KAAa,CAAC,eAAe,QAAQ,KAClD,UAAU,KAAA,KAAa,mBAAmB,KAAA,IACxC,KAAA,IACA,UAAU,eAAe,GAAG,KAAK,eAAe,QAAQ,IACvD;GAAE;GAAO;GAAI;GAAK;GAAU,GAAG;EAAS,IACxC,UAAU,UACT;GAAE;GAAO;GAAI,GAAG;EAAS,IACzB,KAAA;EACN,IAAI,SAAS,KAAA,KAAa,kBAAkB,KAAA,GAAW,OAAO,KAAA;EAE9D,OAAO;GACN;GACA,GAAI,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS;GAC7C,GAAI,mBAAmB,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,eAAe;GAChE;GACA,GAAI,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,cAAc;EAC9D;CACD,CAAC;CAED,OAAO,SAAS,UAAU,eAAe,SAAS,KAAK,IAAI,KAAA;AAC5D;;;;;;;;;;;;;;;;;;;;;;;;AAyBA,SAAgB,iBAAiB,OAAwC;CACxE,MAAM,WAAW,cAAc;EAC9B,IAAI,CAAC,SAAS,KAAK,GAAG,OAAO,KAAA;EAC7B,MAAM,SAAS,QAAQ,IAAI,OAAO,QAAQ;EAC1C,MAAM,aAAa,QAAQ,IAAI,OAAO,YAAY;EAClD,MAAM,QAAQ,QAAQ,IAAI,OAAO,OAAO;EACxC,OAAO,eAAe,MAAM,KAAK,eAAe,UAAU,KAAK,eAAe,KAAK,IAChF;GAAE;GAAQ;GAAY;EAAM,IAC5B,KAAA;CACJ,CAAC;CACD,OAAO,SAAS,UAAU,SAAS,QAAQ,KAAA;AAC5C;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAqCA,SAAgB,UACf,QACA,WACA,QACA,UACA,MACwB;CACxB,MAAM,WAAW;EAChB,GAAI,MAAM,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS;EAClE,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,KAAK,MAAM;CAC1D;CACA,MAAM,cAAc,MAAM,gBAAgB;CAC1C,IAAI,CAAC,eAAe,MAAM,cAAc,MAAM,OAAO;EAAE,OAAO;EAAS,IAAI;EAAU,GAAG;CAAS;CACjG,IAAI,CAAC,cAAc,MAAM,GAAG,OAAO,KAAA;CAQnC,OAAO;EACN,OAPA,cAAc,KAAA,KACd,UAAU,aACV,WAAW,UAAU,OAAO,UAC5B,OAAO,QAAQ,OAAO,UAAU,MAChC,OAAO,QAAQ,QAAQ,UAAU,QAChC,cAAc,UAAU,eAER,UAAU;EAC3B,IAAI,OAAO,QAAQ;EACnB,KAAK,OAAO,QAAQ;EACpB,UAAU,OAAO,QAAQ;EACzB,GAAG;CACJ;AACD;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,eAAe,MAAsB;CACpD,OAAO,KAAK,KAAK,KAAK,SAAS,CAAC;AACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,iBAAiB,UAAsC;CACtE,OAAO,SAAS,QAAQ,KAAK,YAAY;EACxC,MAAM,UAAU,eAAe,OAAO;EACtC,OACC,MAAM,QAAQ,UAAU,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,WAAW,QAAQ;CAEvF,GAAG,CAAC;AACL;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,eAAe,SAAkC;CAChE,MAAM,WAAW,SAAS,OAAO,IAAI,WAAW,QAAQ,KAAK,IAAI;CACjE,MAAM,QAAQ,aAAa,KAAA,IAAA,IAAqC,eAAe,QAAQ;CACvF,OAAO;EACN,IAAI,QAAQ;EACZ,MAAM,QAAQ;EACd,SAAS,eAAe,QAAQ,OAAO;EACvC,SAAA;EACA;EACA,UAAU,QAAQ,aAAa,KAAA,IAAY,IAAI,eAAe,QAAQ,QAAQ;EAC9E,SAAS,QAAQ,QAAQ,UAAU,KAAA;CACpC;AACD;;;;;;;;;;;;;;;;;;;;;;;;;AA0BA,SAAgB,gBAAgB,SAAkC;CACjE,MAAM,UAAU,eAAe,OAAO;CACtC,OAAO,QAAQ,SAAS,QACtB,KAAK,YACL,MAAM,QAAQ,UAAU,QAAQ,UAAU,QAAQ,QAAQ,QAAQ,WAAW,QAAQ,QACtF,QAAQ,QAAQ,QAAQ,MACzB;AACD;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,eAAe,SAA0C;CACxE,MAAM,QAAQ,QAAQ,UAAU,KAAA,KAAa,QAAQ,MAAM,SAAS,IAAI,QAAQ,QAAQ,KAAA;CACxF,MAAM,SAAS,QAAQ,SAAS;CAChC,MAAM,CAAC,gBAAgB,GAAG,iBAAiB,KAAK,CAC/C,OACA,WAAW,KAAA,KAAa,OAAO,KAAK,MAAM,CAAC,CAAC,SAAS,IAAI,SAAS,KAAA,CACnE,CAAC,CAAC,KAAK,SAAS;EACf,IAAI,SAAS,KAAA,GAAW,OAAO;EAC/B,MAAM,WAAW,WAAW,IAAI;EAChC,OAAO,aAAa,KAAA,IAAA,IAAqC,eAAe,QAAQ;CACjF,CAAC;CACD,OAAO;EACN,UAAU,QAAQ,SAAS,KAAK,YAAY,eAAe,OAAO,CAAC;EACnE,OAAO;EACP,QAAQ;CACT;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;AA2BA,eAAsB,eACrB,OACA,SACuB;CACvB,MAAM,SAAS,MAAM,MAAM,SAAS;CACpC,IAAI,OAAO,WAAW,CAAC,SAAS,MAAM,IAAI,cAAc,2BAA2B,MAAM;CACzF,OAAO;AACR;;;;;;;;;;;;;;;;AAiBA,SAAgB,oBACf,UACA,SACA,OACA,SACuB;CACvB,OAAO,eAAe,SAAS,MAAM,OAAO,QAAQ,MAAM,GAAG,OAAO;AACrE;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,eAAe,SAAsC;CACpE,OAAO;EACN,SAAS,QAAQ;EACjB,SAAS,QAAQ;EACjB,GAAI,QAAQ,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,QAAQ,SAAS;EACvE,GAAI,QAAQ,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;EAC9D,GAAI,QAAQ,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,QAAQ,KAAK;CAC5D;AACD;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,SAAS,MAAgB,QAAwC;CAChF,OAAO;EACN,SAAS;EACT,IAAI,KAAK;EACT,MAAM,KAAK;EACX,OAAO,WAAW,KAAA,IAAY,WAAW,WAAW;CACrD;AACD;;;;;;;;;;;;;;;;;;;;;;;AAwBA,SAAgB,YACf,QACA,OACA,SACO;CACP,QAAQ,QAAQ;EACf,QAAQ,MAAM;EACd,YAAY,KAAK,IAAI,GAAG,MAAM,aAAa,OAAO;EAClD,OAAO,KAAK,IAAI,GAAG,MAAM,QAAQ,OAAO;CACzC,CAAC;AACF;;;;;;;;;;;;;;;;;;;;AAqBA,SAAgB,aAAa,OAAuB;CACnD,IAAI,CAAC,yBAAyB,KAAK,GAClC,MAAM,IAAI,WAAW,SAAS,8CAA8C,EAC3E,SAAS,EAAE,MAAM,EAClB,CAAC;CAEF,OAAO;AACR;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,cACf,OACA,KAC0C;CAC1C,IAAI,UAAU,KAAA,KAAa,SAAS,KAAK,GAAG,OAAO;CACnD,MAAM,IAAI,cAAc,UAAU,IAAI,kCAAkC;EACvE,MAAM;EACN,SAAS;GAAE,MAAM,CAAC,WAAW,GAAG;GAAG,OAAO;GAAmB,UAAU,QAAQ,KAAK;EAAE;CACvF,CAAC;AACF;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,gBAAgB,OAAwB;CACvD,IAAI,OAAO,UAAU,UAAU,OAAO;CACtC,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,MAAM,WAAW,WAAW,KAAK;CACjC,IAAI,aAAa,KAAA,GAAW,OAAO;CACnC,MAAM,WAAW,cAAc,OAAO,KAAK,CAAC;CAC5C,OAAO,SAAS,UAAU,SAAS,QAAQ;AAC5C;;;;;;;;;;;;;AAcA,SAAgB,aAAgB,MAA8B,UAAkB,MAAiB;CAChG,MAAM,QAAQ,KAAK,IAAI,IAAI;CAC3B,IAAI,UAAU,KAAA,GACb,MAAM,IAAI,WAAW,YAAY,WAAW,SAAS,IAAI,QAAQ,EAChE,SAAS;EAAE;EAAU;CAAK,EAC3B,CAAC;CAEF,OAAO;AACR;;;;;;;;;;AAWA,SAAgB,oBACf,SACwF;CACxF,MAAM,EAAE,aAAa,SAAS,YAAY;CAC1C,OAAO;EACN,GAAI,gBAAgB,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY;EACnD,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;EAC3C,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;CAC5C;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC7jBA,IAAa,QAAb,MAA6C;CAC5C;CACA;CACA;CACA;CACA;CACA;CACA;CAGA;CACA;CACA;CACA;CAQA;CAIA;CAMA;CAGA,WAAwB;CAOxB,wBAAiB,IAAI,IAAgE;CAErF,YAAY,UAA6B,SAAwB;EAChE,KAAK,SAAS,aAAa,SAAS,SAAA,EAA4B;EAChE,KAAK,MAAM,OAAO,WAAW;EAC7B,KAAK,YAAY;EACjB,KAAK,UAAU,SAAS,UAAU;EAClC,KAAK,WAAW,IAAI,aAAa;GAChC,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;GAClE,GAAI,SAAS,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;GAC/D,GAAI,SAAS,iBAAiB,KAAA,IAAY,CAAC,IAAI,EAAE,cAAc,QAAQ,aAAa;GACpF,GAAI,SAAS,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,QAAQ,WAAW;GAC9E,GAAI,SAAS,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;GAC/D,GAAI,SAAS,kBAAkB,KAAA,IAAY,CAAC,IAAI,EAAE,eAAe,QAAQ,cAAc;GACvF,GAAI,SAAS,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,QAAQ,OAAO;EACnE,CAAC;EACD,KAAK,aAAa,SAAS;EAC3B,KAAK,UAAU,SAAS;EACxB,KAAK,aAAa,SAAS;EAC3B,KAAK,aAAa,SAAS;EAC3B,KAAK,UAAU,SAAS;EACxB,KAAK,aAAa,SAAS;EAC3B,KAAK,UAAU,SAAS;EACxB,KAAK,UAAU,SAAS,UAAU;EAClC,KAAK,WAAW,IAAI,QAAuB,OAAO;CACnD;CAEA,IAAI,KAAa;EAChB,OAAO,KAAK;CACb;CAEA,IAAI,UAA2C;EAC9C,OAAO,KAAK;CACb;CAEA,IAAI,SAAsB;EAIzB,OAAO,KAAK,MAAM,OAAO,IAAI,YAAY,KAAK;CAC/C;CAEA,IAAI,UAAiC;EACpC,OAAO,KAAK;CACb;CAEA,SAAS,SAAiD;EAIzD,OAAO,KAAK,OAAO,OAAO,CAAC,CAAC;CAC7B;CAEA,OAAO,SAAiD;EAKvD,MAAM,QAAQ,SAAS,UAAU,KAAA,IAAY,KAAK,SAAS,aAAa,QAAQ,KAAK;EAGrF,MAAM,SAAS,cAAc,SAAS,UAAU,KAAK,SAAS,QAAQ;EACtE,MAAM,YAAY,cAAc,SAAS,aAAa,KAAK,YAAY,WAAW;EAGlF,MAAM,OAAO,CAAC,QAAQ,SAAS,CAAC,CAAC,QAC/B,KAAK,OAAO,QACZ,QAAQ,KAAA,KAAa,IAAI,QAAQ,GAAG,MAAM,KAC5C;EAMA,IACC,KAAK,MAAM,OAAO,MACjB,KAAK,YAAY,KAAA,KACjB,CAAC,GAAG,KAAK,MAAM,OAAO,CAAC,CAAC,CAAC,MAAM,SAAS,KAAK,MAAM,QAAQ,KAAK,SAAS,GAAG,CAAC,CAAC,IAE/E,MAAM,IAAI,WACT,eACA,qIACA,EAAE,SAAS,EAAE,OAAO,KAAK,IAAI,EAAE,CAChC;EAID,MAAM,YAAY,SAAS,WAAW,KAAK;EAC3C,MAAM,UAAU,cAAc,KAAA,IAAY,KAAA,IAAY,cAAc,EAAE,IAAI,UAAU,CAAC;EAErF,KAAK,MAAM,OAAO,MAAM,IAAI,MAAM;EAGlC,MAAM,SAAS,KAAK,gBAAgB,SAAS,QAAQ,WAAW,SAAS,MAAM;EAC/E,MAAM,QAAQ,YAAY,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,CAAC;EAChE,SAAS,MAAM;EACf,KAAK,MAAM,IAAI,OAAO,IAAI;EAI1B,KAAK,SAAS,KAAK,SAAS,KAAK,EAAE;EACnC,MAAM,UAAU,IAAI,QAAoB;EACxC,MAAM,UAAU,QAAQ,cAA2B;EAKnD,KAAU,OACT,OACA,SACA,SAAS,OACT,SAAS,QACT,OACA,QACA,SACD,CAAC,CAAC,MACA,YAAY,KAAK,QAAQ,OAAO,SAAS,SAAS,SAAS,OAAO,OAAO,IACzE,UAAmB,KAAK,MAAM,OAAO,SAAS,SAAS,SAAS,KAAK,CACvE;EAMA,QAAQ,QAAQ,YAAY,CAAC,CAAC;EAC9B,OAAO;GACN,QAAQ,KAAK,aAAa,SAAS,KAAK;GACxC,QAAQ,QAAQ;GAIhB,OAAO,MAAM,MAAM,KAAK,KAAK;EAC9B;CACD;CAEA,MAAM,QAAwB;EAI7B,KAAK,MAAM,SAAS,CAAC,GAAG,KAAK,MAAM,KAAK,CAAC,GAAG,MAAM,MAAM,MAAM;CAC/D;CAOA,QACC,OACA,SACA,SACA,SACA,OACA,SACO;EACP,SAAS,MAAM;EACf,KAAK,MAAM,OAAO,KAAK;EACvB,KAAK,WAAW;EAChB,QAAQ,MAAM;EACd,MAAM,SAAS,eAAe,OAAO;EACrC,QAAQ,QAAQ,MAAM;EACtB,IAAI,QAAQ,WAAW,KAAK,SAAS,KAAK,WAAW,KAAK;OACrD,IAAI,QAAQ,SAAS,KAAK,SAAS,KAAK,SAAS,MAAM,OAAO,MAAM;EACzE,KAAK,SAAS,KAAK,UAAU,MAAM;CACpC;CAIA,MACC,OACA,SACA,SACA,SACA,OACO;EACP,SAAS,MAAM;EACf,KAAK,MAAM,OAAO,KAAK;EACvB,KAAK,WAAW;EAChB,QAAQ,KAAK,KAAK;EAClB,QAAQ,OAAO,KAAK;EACpB,KAAK,SAAS,KAAK,SAAS,KAAK;CAClC;CAIA,MAAM,OACL,OACA,SACA,OACA,QACA,OACA,QACA,WAC0B;EAC1B,MAAM,MAAM,KAAK,SAAS,OAAO,OAAO,QAAQ,OAAO,QAAQ,SAAS;EACxE,SAAS;GACR,MAAM,OAAO,MAAM,IAAI,KAAK;GAC5B,IAAI,KAAK,SAAS,MAAM,OAAO,KAAK;GACpC,QAAQ,KAAK,KAAK,KAAK;EACxB;CACD;CAOA,OAAO,aACN,SACA,OACmC;EACnC,IAAI;GACH,OAAO,QAAQ,MAAM;EACtB,UAAU;GAIT,MAAM,MAAM;EACb;CACD;CAWA,OAAO,SACN,OACA,OACA,QACA,OACA,QACA,WAC6C;EAG7C,MAAM,OAAO,KAAK,SAAS,cAAc,QAAQ,KAAK,CAAC,CAAC,GAAG,EAAE;EAC7D,MAAM,UAAU,MAAM,SAAS,SAAS,OAAO,KAAA;EAG/C,MAAM,YAAY,KAAK,QAAQ,SAAS,OAAO,MAAM;EACrD,MAAM,QACL,cAAc,KAAA,IACX;GAAE,UAAU,KAAK,SAAS,MAAM;GAAG,OAAO,KAAA;EAAU,IACpD,MAAM;EACV,MAAM,QAAQ,KAAK,SAAS;EAG5B,MAAM,UACL,UAAU,KAAA,KAAa,WAAW,KAAA,IAC/B,KAAA,IACA;GACA,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;GACvC,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EAC1C;EAGH,KAAK,SAAS,MAAM;EAEpB,MAAM,YAAY,MAAM,OAAO;EAE/B,MAAM,QAAqB,CAAC;EAM5B,OAAO,MAAM,SAAS,UAAU,MAAM,GAAG,EAAE,CAAC,EAAE,WAAW,aAAa,SAAS;GAC9E,MAAM,QAAQ,MAAM;GACpB,MAAM,OAAO,MAAM,GAAG,EAAE,CAAC,EAAE,YAAY,MAAM;GAC7C,MAAM,SAAS,MAAM,GAAG,EAAE,CAAC,EAAE,UAAU;GAEvC,MAAM,UAAqB;IAC1B,SAAS;IACT,UAAU,KAAA;IACV,OAAO,KAAA;IACP,OAAO,KAAA;IACP,UAAU;IACV,SAAS;IACT,SAAS;IACT;IACA,UAAU,KAAA;IACV,aAAa;IACb,WAAW;GACZ;GAGA,KAAK,SAAS,KAAK,QAAQ,KAAK;GAIhC,IAAI,QAAQ,GACX,IAAI;IACH,MAAM,KAAK,YAAY,MAAM,EAAE,QAAQ,MAAM,OAAO,CAAC;GACtD,SAAS,OAAO;IACf,IAAI,CAAC,MAAM,OAAO,SAAS,MAAM;GAClC;GAED,IAAI,MAAM,OAAO,SAAS;IACzB,MAAM,KAAK,OAAO;IAClB;GACD;GAEA,MAAM,QAAQ,KAAK,SAAS,OAAO,OAAO,MAAM;GAChD,MAAM,aAAa,gBAClB,OACA,MAAM,YAAY,IACjB,eAAe,WAAW,IAC5B;GACA,MAAM,cAAc,WAAW,SAAS,IAAI,aAAa,KAAA;GAKzD,MAAM,WAAW,KAAK,SAAS,MAAM,aAAa,OAAO;GACzD,MAAM,WACL,KAAK,YAAY,KAAA,IACd;IAAE,UAAU;IAAU,UAAU;IAAM,OAAO,KAAA;IAAW;GAAO,IAC/D,MAAM,KAAK,OACX,KAAK,SACL,UACA,MACA,SACA,QAAQ,GACR,QACA,OACA,MACD;GACH,IAAI,SAAS,aAAa,KAAA,GAAW;IACpC,MAAM,KAAK;KACV,GAAG;KACH,UAAU,SAAS;KACnB,OAAO,SAAS;KAChB,QAAQ,SAAS;IAClB,CAAC;IACD;GACD;GAGA,MAAM,WAAqB,CAAC;GAC5B,MAAM,QACL,cAAc,KAAA,IACX,KAAA,IACA,iBAAiB;IAAE,QAAQ;IAAW,WAAW;GAAe,CAAC;GACrE,MAAM,WAAW,OAAO,KAAK,SAAS,SAAS,UAAU,MAAM,QAAQ,UAAU,KAAK;GACtF,MAAM,UAAU,KAAK,WAAW,UAAU,OAAO,UAAU,UAAU,OAAO,QAAQ,SAAS;GAC7F,IAAI,CAAC,SAAS,SAAS;IACtB,MAAM,KAAK;KAAE,GAAG;KAAS,SAAS;KAAU,SAAS;IAAK,CAAC;IAC3D;GACD;GACA,MAAM,SAAS,SAAS;GACxB,MAAM,WAAW,QAAQ,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,QAAQ,SAAS;GACpF,IAAI,QAAQ,UAAU,KAAA,GAAW;IAEhC,KAAK,SAAS,KAAK,SAAS,QAAQ,OAAO,QAAQ,QAAQ;IAC3D,MAAM;KAAE,UAAU;KAAS,OAAO,QAAQ;KAAO,UAAU,QAAQ;IAAS;GAC7E;GACA,IAAI,gBAAgB,KAAA,GACnB,KAAK,MAAM,QAAQ,OAAO,SAAS,CAAC,GACnC,KAAK,SAAS,KAAK,QAAQ,MAAM,2CAA2C;QAEvE,IAAI,OAAO,UAAU,KAAA,KAAa,OAAO,MAAM,SAAS,GAAG;IACjE,MAAM,gBAAgB,gBAAgB,OAAO,OAAO,QAAQ,SAAS,KAAK,IAAI;IAC9E,MAAM,gBAAgB,KAAK,WAAW,OAAO,OAAO,aAAa;IACjE,IAAI,MAAM,OAAO,SAAS;KACzB,MAAM,KAAK;MAAE,GAAG;MAAS,SAAS;MAAU,SAAS;KAAK,CAAC;KAC3D;IACD;IACA,MAAM,YAAY,KAAK,SAAS,SAAS,IAAI;KAC5C,MAAM;KACN,SAAS,OAAO;KAChB,OAAO,OAAO;KACd,GAAG;IACJ,CAAC;IACD,MAAM,UAAU,MAAM,KAAK,UAAU,OAAO,OAAO,OAAO,MAAM,QAAQ,aAAa;IAErF,MAAM,UAAqB,CAAC;IAC5B,KAAK,MAAM,CAAC,UAAU,SAAS,OAAO,MAAM,QAAQ,GAAG;KACtD,MAAM,UAAU,QAAQ;KACxB,IAAI,YAAY,KAAA,GAAW;KAG3B,KAAK,SAAS,KAAK,QAAQ,MAAM,OAAO;KACxC,MAAM;MAAE,UAAU;MAAQ;MAAM,QAAQ;KAAQ;KAGhD,QAAQ,KACP,KAAK,SAAS,SAAS,IAAI;MAC1B,MAAM;MACN,SAAS,QAAQ,UAAU,gBAAgB,QAAQ,KAAK,IAAI,QAAQ;MACpE,MAAM,KAAK;KACZ,CAAC,CACF;IACD;IAGA,MAAM,KAAK;KACV,GAAG;KACH,UAAU;MAAC,GAAG,SAAS;MAAU;MAAW,GAAG;KAAO;KACtD,SAAS;KACT,SAAS;IACV,CAAC;IACD;GACD;GAEA,KAAK,SAAS,SAAS,IAAI;IAAE,MAAM;IAAa,SAAS,OAAO;IAAS,GAAG;GAAS,CAAC;GACtF,MAAM,KAAK;IACV,GAAG;IACH,SAAS,OAAO;IAChB,SAAS;IACT,SAAS,MAAM,OAAO;IACtB,WAAW,OAAO,cAAc;GACjC,CAAC;EACF;EACA,MAAM,QAAQ,MAAM,GAAG,EAAE;EACzB,MAAM,YAAY,MAAM,SAAS,SAAU,KAAK,aAAa,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAE;EAC9F,OAAO;GACN,SACC,OAAO,YAAY,WAAW,MAAM,UAAU,MAAM,KAAK,SAAS,KAAK,OAAO,CAAC,CAAC,KAAK,EAAE;GACxF,UAAU,UAAU,WAAW,IAAI,KAAA,IAAY,UAAU,KAAK,MAAM;GAEpE,OAAO;IACN,GAAG,MAAM,KAAK,SAAS,KAAK,KAAK;IACjC,MAAM;IACN,GAAG,MAAM,KAAK,SAAS,KAAK,KAAK;GAClC,CAAC,CAAC,QACA,OAAO,QAAS,QAAQ,KAAA,IAAY,QAAQ,SAAS,OAAO,GAAG,GAChE,KAAA,CACD;GACA,SAAS,OAAO,WAAW;GAG3B,WAAW,OAAO,YAAY,WAAW,CAAC,MAAM,OAAO;GACvD,MAAM,UAAU,MAAM,OAAO,QAAQ,WAAW,QAAQ,KAAK,UAAU,IAAI,KAAK;EACjF;CACD;CAKA,WACC,UACA,OACA,UACA,UACA,OACA,QACA,WACC;EAGD,MAAM,cAAc,MAAM,OAAO;EAGjC,MAAM,UACL,CAAC,SAAS,WAAW,eAAe,qBAAqB,SAAS,KAAK,IACpE,SAAS,MAAM,UACf,KAAA;EACJ,MAAM,YAAY,SAAS,UAAU,SAAS,MAAM,WAAW,SAAS;EACxE,MAAM,WAAW,cAAc,KAAA,KAAa,UAAU,SAAS,IAAI,YAAY,KAAA;EAC/E,MAAM,UAAU,SAAS,KAAK,EAAE;EAChC,MAAM,WAAW,eAAe,OAAO;EACvC,MAAM,WAAW,SAAS,UAAU,SAAS,MAAM,QAAQ,SAAS;EACpE,MAAM,QAAQ,aAAa,KAAA,IAAY,KAAA,IAAY,cAAc,QAAQ;EAIzE,MAAM,UAAU,cAAc,SAAU,OAAO,WAAW,IAAK;EAC/D,MAAM,SACL,UACC,cAAc,SAAS,KAAA,IAAY;GAAE,QAAQ;GAAG,YAAY;GAAU,OAAO;EAAS;EACxF,IAAI,WAAW,KAAA,GAAW,YAAY,QAAQ,QAAQ,OAAO;EAC7D,IAAI,CAAC,SAAS,WAAW,CAAC,aAAa,MAAM,SAAS;EACtD,OAAO;GACN;GACA;GACA;GACA,OAAO,SAAS;GAChB,UAAU,SAAS;GACnB,QAAQ,SAAS;GACjB;GACA;GACA,WAAW;EACZ;CACD;CASA,SACC,UACA,OACA,SACkB;EAClB,OAAO;GACN,UAAU,CAAC,GAAG,cAAc,UAAU,KAAK,OAAO,CAAC;GACnD,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;GACvC,GAAI,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ;EAC5C;CACD;CAYA,MAAM,OACL,QACA,UACA,UACA,SACA,OACA,QACA,OACA,QACC;EACD,OAAO,MAAM;EACb,OAAO,QAAQ,QAAQ;EACvB,IAAI,CAAC,OAAO,WAAW,OAAO;GAAE,UAAU;GAAU;GAAU,OAAO,KAAA;GAAW;EAAO;EAGvF,IAAI,MAAM,OAAO,SAAS,OAAO;GAAE,UAAU,KAAA;GAAW;GAAU,OAAO,KAAA;GAAW;EAAO;EAC3F,MAAM,eAAe,KAAK,SAAS,cAAc;EACjD,IAAI,cAAc,iBAAiB,QAAQ,QAC1C,OAAO;GAAE,UAAU,KAAK,SAAS,QAAQ,QAAQ;GAAG;GAAU,OAAO,KAAA;GAAW;EAAO;EAIxF,OAAO,aAAa,QAAQ,EAAE,QAAQ,MAAM,OAAO,CAAC,CAAC,CAAC,MACpD,YAAY,KAAK,QAAQ,SAAS,QAAQ,UAAU,UAAU,SAAS,OAAO,OAAO,MAAM,IAC3F,UAAmB,KAAK,QAAQ,OAAO,UAAU,UAAU,KAAK,CAClE;CACD;CAKA,MAAM,QACL,SACA,QACA,UACA,UACA,SACA,OACA,OACA,QACC;EACD,IAAI,MAAM,OAAO,SAChB,OAAO;GAAE,UAAU,KAAA;GAAW;GAAU,OAAO,KAAA;GAAW,QAAQ;EAAM;EACzE,IAAI,YAAY,KAAA,GACf,OAAO;GACN,UAAU,KAAK,SAAS,QAAQ,QAAQ;GACxC;GACA,OAAO,KAAA;GACP,QAAQ;EACT;EAED,MAAM,YAAY,KAAK,QAAQ,SAAS,OAAO,MAAM;EACrD,MAAM,UACL,cAAc,KAAA,IACX;GAAE,UAAU,KAAK,SAAS,MAAM;GAAG,OAAO,KAAA;EAAU,IACpD,MAAM;EACV,IAAI,MAAM,OAAO,SAChB,OAAO;GACN,UAAU,KAAA;GACV,UAAU,QAAQ;GAClB,OAAO,QAAQ;GACf,QAAQ;EACT;EAED,MAAM,WAAW,KAAK,SAAS,QAAQ,UAAU,SAAS,OAAO,SAAS,OAAO;EACjF,OAAO,MAAM;EACb,OAAO,QAAQ,QAAQ;EACvB,OAAO;GACN,UAAU,KAAK,SAAS,QAAQ,QAAQ;GACxC,UAAU,QAAQ;GAClB,OAAO,QAAQ;GACf,QAAQ;EACT;CACD;CAKA,QACC,OACA,UACA,UACA,OACC;EACD,IAAI,MAAM,OAAO,SAChB,OAAO;GAAE,UAAU,KAAA;GAAW;GAAU,OAAO,KAAA;GAAW,QAAQ;EAAM;EACzE,KAAK,SAAS,KAAK,SAAS,KAAK;EACjC,IAAI,KAAK,SAAS,MAAM;EACxB,OAAO;GAAE,UAAU;GAAU;GAAU,OAAO,KAAA;GAAW,QAAQ;EAAM;CACxE;CAGA,SAAS,QAA0C,SAA2C;EAC7F,IAAI,KAAK,WAAW,OAAO,WAC1B,MAAM,IAAI,WACT,UACA,wBAAwB,OAAO,SAAS,uBAAuB,OAAO,IAAI,qBAC1E,EAAE,SAAS;GAAE,OAAO,KAAK;GAAK,UAAU,OAAO;GAAU,KAAK,OAAO;EAAI,EAAE,CAC5E;EAED,OAAO;CACR;CAKA,QACC,SACA,OACA,QACC;EACD,MAAM,UAAU,YAAY,KAAA,IAAY,KAAA,IAAY,KAAK,SAAS,OAAO,SAAS,MAAM,MAAM;EAC9F,OAAO,YAAY,KAAA,IAChB,KAAA,IACA,QAAQ,MACP,cAAc,KAAK,OAAO,WAAW,OAAO,MAAM,IAClD,UAAmB,KAAK,QAAQ,OAAO,KAAK,CAC9C;CACH;CAKA,OACC,WACA,OACA,QACC;EACD,MAAM,QAAQ,UAAU,UAAU,KAAA,IAAY,KAAA,IAAY,cAAc,UAAU,KAAK;EACvF,IAAI,UAAU,KAAA,GAAW,YAAY,QAAQ,OAAO,CAAC;EACrD,IAAI,MAAM,OAAO,SAAS,OAAO;GAAE,UAAU,KAAK,SAAS,MAAM;GAAG;EAAM;EAC1E,IAAI,UAAU,UAAU,KAAA,GAAW;GAClC,KAAK,SAAS,KAAK,SAAS,UAAU,KAAK;GAC3C,IAAI,MAAM,OAAO,SAAS,OAAO;IAAE,UAAU,KAAK,SAAS,MAAM;IAAG;GAAM;GAC1E,IAAI,KAAK,SAAS,MAAM,UAAU;EACnC;EACA,MAAM,WAAW,KAAK,SAAS,MAAM,SAAS;EAC9C,KAAK,SAAS,KAAK,UAAU,SAAS;EACtC,OAAO;GAAE;GAAU;EAAM;CAC1B;CAGA,QAAQ,OAAgB,OAAuB;EAC9C,IAAI,CAAC,MAAM,OAAO,SAAS;GAC1B,KAAK,SAAS,KAAK,SAAS,KAAK;GAEjC,IAAI,KAAK,WAAW,CAAC,MAAM,OAAO,SAAS,MAAM;EAClD;EACA,OAAO;GAAE,UAAU,KAAK,SAAS,MAAM;GAAG,OAAO,KAAA;EAAU;CAC5D;CAIA,WAAW,OAA4B,UAA+B;EAErE,MAAM,YAAY,CAAC,GAAG,MAAM,QAAQ,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW;GAC9D;GACA;GACA,QAAQ,KAAK,QAAQ,MAAM,QAAQ;EACpC,EAAE;EACF,OAAO;GACN,SAAS,IAAI,IACZ,UAAU,SAAS,QAClB,IAAI,WAAW,KAAA,IAAY,CAAC,CAAC,IAAI,OAAO,IAAI,IAAI,CAAU,IAAI,CAAC,CAChE,CACD;GACA,SAAS,IAAI,IACZ,UAAU,SAAS,QAClB,IAAI,WAAW,KAAA,IAAY,CAAC,IAAI,CAAC,CAAC,IAAI,OAAO,IAAI,MAAM,CAAU,CAClE,CACD;EACD;CACD;CAGA,QAAQ,MAAgB,UAAuD;EAC9E,IAAI,CAAC,SAAS,SAAS,IAAI,GAAG;GAC7B,MAAM,SAAS,GAAG,KAAK,KAAK;GAC5B,MAAM,SAAS,SAAS,MAAM,MAAM;GACpC,KAAK,SAAS,KAAK,QAAQ,MAAM,MAAM;GACvC,OAAO;EACR;EACA,MAAM,YAAY,KAAK;EACvB,IAAI,cAAc,KAAA,GAAW,OAAO,KAAA;EAKpC,MAAM,YAAY,cAAc,UAAU,SAAS,EAAE,KAAK,CAAC,CAAC;EAC5D,IAAI,CAAC,UAAU,SAAS;GAKvB,MAAM,SAAS,eAAe,UAAU,KAAK;GAC7C,MAAM,SAAS,SAAS,MAAM,MAAM;GACpC,KAAK,SAAS,KAAK,QAAQ,MAAM,MAAM;GACvC,OAAO;EACR;EACA,IAAI,UAAU,MAAM,SAAS,OAAO,KAAA;EACpC,MAAM,SAAS,SAAS,MAAM,UAAU,MAAM,MAAM;EACpD,KAAK,SAAS,KAAK,QAAQ,MAAM,UAAU,MAAM,MAAM;EACvD,OAAO;CACR;CAIA,MAAM,UACL,OACA,OACA,QACA,eAIiC;EACjC,MAAM,EAAE,SAAS,YAAY;EAC7B,MAAM,WAAW,QAAQ,OAAO,IAAI,MAAM,MAAM,QAAQ,CAAC,GAAG,QAAQ,OAAO,CAAC,GAAG,EAAE,OAAO,CAAC,IAAI,CAAC;EAE9F,MAAM,UAAU,IAAI,IAAwB,CAC3C,GAAG,SACH,GAAG,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,SAAS,OAAO,WAAW;GACjD,MAAM,SAAS,SAAS;GACxB,OAAO,WAAW,KAAA,IAAY,CAAC,IAAI,CAAC,CAAC,OAAO,MAAM,CAAU;EAC7D,CAAC,CACF,CAAC;EACD,OAAO,MAAM,KAAK,MAAM,UAAU,QAAQ,IAAI,KAAK,KAAK,SAAS,MAAM,KAAA,CAAS,CAAC;CAClF;CAWA,OAAO,SACN,SACA,QACA,UACA,OACqD;EACrD,IAAI;GACH,MAAM,YAAY,KAAK,UAAU,OAChC,QAAQ,UACR,QACA,QAAQ,OACR,QAAQ,OACT;GACA,SAAS;IACR,MAAM,OAAO,MAAM,UAAU,KAAK;IAClC,IAAI,KAAK,SAAS,MAAM;KACvB,MAAM,SAAS,KAAK;KACpB,OAAO,cAAc,MAAM;IAC5B;IACA,MAAM,QAAQ,KAAK;IACnB,IAAI,MAAM,YAAY,WAAW;KAChC,SAAS,KAAK,MAAM,IAAI;KACxB,OAAO,OAAO,MAAM,IAAI;KACxB,MAAM;MAAE,UAAU;MAAS,SAAS,MAAM;KAAK;IAChD,OACC,MAAM;KAAE,UAAU;KAAS,SAAS,MAAM;IAAK;GAEjD;EACD,SAAS,OAAO;GACf,OAAO,cAA8B;IACpC,MAAM;GACP,CAAC;EACF;CACD;CAOA,gBACC,SACA,QACA,WACA,QAC0B;EAC1B,MAAM,UAAU;GACf,KAAK;GACL;GACA,SAAS;GACT,QAAQ;GACR,cAAc,SAAS,KAAA,IAAY,WAAW;EAC/C,CAAC,CAAC,QAAQ,QAA4B,QAAQ,KAAA,CAAS;EACvD,IAAI,QAAQ,WAAW,GAAG,OAAO,KAAA;EACjC,IAAI,QAAQ,WAAW,GAAG,OAAO,QAAQ;EACzC,OAAO,YAAY,IAAI,OAAO;CAC/B;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACv5BA,IAAa,cAAb,MAAyB;CACxB;CACA;CAGA,2BAAgC,IAAI,IAAY;;;;;;;CAQhD,YAAY,UAAkC,SAAkB;EAC/D,KAAK,YAAY;EACjB,KAAK,WAAW;CACjB;;;;;;;;;CAUA,QAAQ,YAAmF;EAC1F,MAAM,WAAW,WAAW,MAAM;EAClC,IAAI,aAAa,KAAA,KAAa,CAAC,KAAK,SAAS,IAAI,WAAW,EAAE,GAAG;GAChE,KAAK,2BAAW,IAAI,IAAI,CAAC,GAAG,KAAK,UAAU,WAAW,EAAE,CAAC;GACzD,KAAK,MAAM,SAAS,UAAU,WAAgB,MAAM,KAAK;EAC1D;EACA,OAAO,eAAe,KAAK,UAAU,MAAM,WAAW,OAAO,WAAW,MAAM,GAAG,KAAK,QAAQ;CAC/F;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACrBA,IAAa,YAAb,MAAqD;CACpD;CACA;CAEA,YAAY,SAA4B;EACvC,KAAK,SAAS,SAAS,SAAS,CAAC;EACjC,KAAK,YAAY,SAAS,YAAY;GAAE,MAAA;GAA8B,SAAS;EAAK;CACrF;CAEA,SAAS,SAA8C;EACtD,KAAK,MAAM,QAAQ,KAAK,QACvB,IAAI,KAAK,MAAM,OAAO,GACrB,OAAO;GACN,MAAM,KAAK;GACX,SAAS,KAAK,WAAW;GACzB,GAAI,KAAK,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,KAAK,OAAO;EAC5D;EAEF,OAAO,KAAK;CACb;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;ACTA,IAAa,gBAAb,MAA6D;CAC5D;CACA;CACA;CACA;CACA;CAEA,YAAY,SAA+B;EAC1C,KAAK,aAAa,IAAI,IAAI,OAAO,QAAQ,QAAQ,SAAS,CAAC;EAC3D,KAAK,SAAS,IAAI,IAAI,OAAO,QAAQ,QAAQ,SAAS,CAAC,CAAC,CAAC;EACzD,KAAK,eAAe,IAAI,IAAI,OAAO,QAAQ,QAAQ,eAAe,CAAC,CAAC,CAAC;EACrE,KAAK,cAAc,IAAI,IAAI,OAAO,QAAQ,QAAQ,cAAc,CAAC,CAAC,CAAC;EACnE,KAAK,SAAS,QAAQ;CACvB;CAEA,SAAS,MAAiC;EACzC,OAAO,aAAa,KAAK,YAAY,YAAY,IAAI;CACtD;CAEA,KAAK,MAA6B;EACjC,OAAO,aAAa,KAAK,QAAQ,QAAQ,IAAI;CAC9C;CAEA,UAAU,MAAkC;EAC3C,OAAO,aAAa,KAAK,cAAc,aAAa,IAAI;CACzD;CAEA,UAAU,MAAkC;EAC3C,OAAO,aAAa,KAAK,aAAa,aAAa,IAAI;CACxD;CAEA,MAAM,OAAsB,QAAsC;EAEjE,MAAM,QAAQ,IAAI,MADD,KAAK,SAAS,MAAM,QACb,GAAU,KAAK,cAAc,OAAO,MAAM,CAAC;EAGnE,KAAK,MAAM,WAAW,MAAM,UAAU,MAAM,QAAQ,SAAS,IAAI,OAAO;EACxE,OAAO;CACR;CAUA,cAAc,OAAsB,QAA+C;EAClF,MAAM,SAAS,MAAM,WAAW,KAAA,IAAY,KAAA,IAAY,kBAAkB,EAAE,KAAK,MAAM,OAAO,CAAC;EAC/F,OAAO;GACN,OAAO,KAAK,kBAAkB,MAAM,KAAK;GACzC,GAAI,MAAM,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,QAAQ,MAAM,OAAO;GAC7D,GAAI,MAAM,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,MAAM;GAC1D,GAAI,MAAM,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,MAAM,QAAQ;GAChE,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;GACzC,GAAI,MAAM,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,KAAK,UAAU,MAAM,SAAS,EAAE;GACtF,GAAI,MAAM,cAAc,KAAA,IAAY,CAAC,IAAI,EAAE,WAAW,KAAK,UAAU,MAAM,SAAS,EAAE;GACtF,GAAI,KAAK,WAAW,KAAA,IACjB,CAAC,IACD,EAAE,eAAe,IAAI,oBAAoB,EAAE,OAAO,KAAK,OAAO,CAAC,EAAE;GACpE,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO;EAC1C;CACD;CAIA,kBAAkB,OAAmD;EACpE,MAAM,UAAU,IAAI,YAAY;EAChC,IAAI,UAAU,KAAA,GAAW,KAAK,MAAM,QAAQ,OAAO,QAAQ,IAAI,KAAK,KAAK,IAAI,CAAC;EAC9E,OAAO;CACR;AACD;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AC3DA,SAAgB,YAAY,UAA6B,SAAwC;CAChG,OAAO,IAAI,MAAM,UAAU,OAAO;AACnC;;;;;;;;;;;;;;;;;;;;;;;;;;;AA4BA,SAAgB,gBAAwC;CACvD,OAAO,IAAI,QAAW;AACvB;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA+BA,SAAgB,gBAAgB,SAAgD;CAC/E,OAAO,IAAI,UAAU,OAAO;AAC7B;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAgCA,SAAgB,oBAAoB,SAAuD;CAC1F,OAAO,IAAI,cAAc,OAAO;AACjC;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AA2CA,SAAgB,iBACf,SAC6C;CAC7C,MAAM,EAAE,UAAU,UAAU,OAAO,UAAU;CAC7C,OAAO,YAAwC;EAC9C,GAAG,oBAAoB,OAAO;EAC9B,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EACvC,SAAS,oBAAoB,KAAK,KAAA,GAAW,UAAU,OAAO;CAC/D,CAAC;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,SAAgB,kBACf,SAC8C;CAC9C,MAAM,EAAE,UAAU,UAAU,UAAU;CACtC,MAAM,SAAS,IAAI,YAAY,UAAU,OAAO;CAChD,OAAO,aAAyC;EAC/C,GAAG,oBAAoB,OAAO;EAC9B,SAAS,OAAO,QAAQ,KAAK,MAAM;CACpC,CAAC;AACF;;;;;;ACrQA,IAAa,oBAAoB,OAAO,OAAO;CAC9C;CACA;CACA;CACA;CACA;CACA;CACA;AACD,CAAU;;AAGV,IAAa,mBAA8C,OAAO,OAAO,CAAC,WAAW,YAAY,CAAC;;AAGlG,IAAa,sBAAiD,OAAO,OAAO;CAC3E;CACA;CACA;AACD,CAAC;;AAGD,IAAa,oBAA+C,OAAO,OAAO,CAAC,QAAQ,YAAY,CAAC;;AAGhG,IAAa,mBAAmB;;AAGhC,IAAa,sBAAsB;;;;;;;AAQnC,IAAa,mBAAmC,OAAO,OAAO;CAC7D,UAAU,OAAO,OAAO;EACvB,MAAM;EACN,cAAc;EACd,UAAU,OAAO,OAAO;GACvB,MAAM;GACN,MAAM;GACN,YAAY;GACZ,SAAS;GACT,SAAS;GACT,SAAS;GACT,YAAY;EACb,CAAC;CACF,CAAC;CACD,OAAO;CACP,QAAQ,OAAO,OAAO;EACrB,MAAM;EACN,cACC;EACD,UAAU,OAAO,OAAO;GACvB,MAAM;GACN,OACC;EACF,CAAC;CACF,CAAC;CACD,YAAY,OAAO,OAAO;EACzB,MAAM;EACN,cACC;EACD,UAAU,OAAO,OAAO;GACvB,MAAM;GACN,OAAO;EACR,CAAC;CACF,CAAC;AACF,CAAC;;;;;AAMD,IAAa,eAA2B,OAAO,OAAO;CACrD,KAAK;CACL,SAAS;CACT,QACC;CACD,SACC;AACF,CAAC;;;;AAKD,IAAa,uBAAoC,OAAO,OAAO;CAC9D,QAAQ;CACR,MAAM;AACP,CAAC;;;;AAKD,IAAa,uBAAuB;;;;AAKpC,IAAa,uBAAuB;;;;;;;;;;AAWpC,IAAa,qBAAqB;;AAGlC,IAAa,4BAA4B;;;;;;;;;;;;;AC1GzC,IAAa,cAAb,cAAiC,MAAM;;CAEtC;;;;;;;CAQA,YAAY,MAAuB,SAAiB;EACnD,MAAM,OAAO;EACb,KAAK,OAAO;EACZ,WAAW,OAAO,MAAM,OAAO,IAAI,8BAA8B,GAAG,EAAE,OAAO,KAAK,CAAC;EACnF,KAAK,OAAO;CACb;AACD;;;;;;;;;;;;;AAcA,SAAgB,cAAc,OAAsC;CACnE,OAAO,YAAY;EAClB,IACC,EACC,iBAAiB,SACjB,WAAW,UAAU,KAAK,MAAM,MAAM,aACtC,WAAW,SAAS,OAAO,OAAO,IAAI,8BAA8B,CAAC,CAAC,EAAE,UAAU,QAGnF,OAAO;EACR,MAAM,OAAO,WAAW,QAAQ,KAAK,OAAO,MAAM;EAClD,IACC,EACC,SAAS,aACT,SAAS,eACT,SAAS,WACT,SAAS,cACT,SAAS,WACT,SAAS,WACT,SAAS,YACT,SAAS,WACT,SAAS,cAGV,OAAO;EACR,OAAO;CACR,CAAC;AACF;;;;;;;;;;;ACnCA,SAAgB,qBAAqB,YAAmD;CACvF,uBAAO,IAAI,IAAI,CAAC,GAAG,WAAW,SAAS,GAAG,WAAW,QAAQ,SAAS,WAAW,OAAO,OAAO,CAAC,CAAC;AAClG;;;;;;;;;;;;AAaA,SAAgB,eACf,YACA,OACA,OACoB;CACpB,MAAM,QAAQ,CAAC,KAAK;CACpB,MAAM,uBAAO,IAAI,IAAY;CAC7B,MAAM,WAAqB,CAAC;CAC5B,KAAK,MAAM,MAAM,OAAO;EACvB,IAAI,KAAK,IAAI,EAAE,GAAG;EAClB,KAAK,IAAI,EAAE;EACX,IAAI,CAAC,MAAM,EAAE,GAAG;EAChB,SAAS,KAAK,EAAE;EAChB,KAAK,MAAM,SAAS,WAAW,IAAI,EAAE,KAAK,CAAC,GAAG,MAAM,KAAK,KAAK;CAC/D;CACA,OAAO;AACR;;;;;;;;;;AAWA,SAAgB,mBAAmB,OAAwB;CAC1D,OAAO;EACN,IAAI;EACJ,MAAM;EACN,SAAS;EACT,OAAO,CAAC;GAAE,IAAI;GAAiB,MAAM;GAAU,WAAW,EAAE,MAAM;EAAE,CAAC;CACtE;AACD;;;;;;;;;;AAWA,SAAgB,iBAAiB,QAAwC;CACxE,OAAO,OAAO,KAAK,UAAU,MAAM,IAAI,CAAC,CAAC,KAAK,IAAI;AACnD;;;;;;;;;;AAWA,SAAgB,iBAAiB,OAAwB;CAExD,OAAO,MAAM,KAAK,EAAE,QAAQ,EAAE,CAAC,CAAC,CAC9B,QACC,UAAU;EACV,MAAM,OAAO,MAAM,GAAG,EAAE;EACxB,MAAM,QAAQ,QAAQ,IAAI,IAAI,KAAK,QAAQ,KAAA;EAC3C,OAAO,UAAU,KAAA,IAAY,QAAQ,CAAC,GAAG,OAAO,KAAK;CACtD,GACA,UAAU,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK,CAClC,CAAC,CACA,KAAK,QAAS,QAAQ,GAAG,IAAI,GAAG,IAAI,KAAK,IAAI,IAAI,YAAY,OAAO,GAAG,CAAE,CAAC,CAC1E,KAAK,MAAM;AACd;;;;;;;;;;AAWA,SAAgB,aAAa,SAAiC;CAC7D,OAAO;EACN,OAAO,IAAI,IAAI,QAAQ,QAAQ,YAAY,CAAC,CAAC,MAAM,iBAAiB,KAAK,CAAC,CAAC;EAC3E,OAAO,IAAI,IACV,CAAC,GAAG,QAAQ,QAAQ,SAAS,qDAAqD,CAAC,CAAC,CAClF,QAAQ,UAAU;GAClB,MAAM,SAAS,QAAQ,QAAQ,MAAM,GAAG,MAAM,KAAK,CAAC,CAAC,QAAQ;GAC7D,OAAO,WAAW,MAAM,CAAC,WAAW,KAAK,MAAM;EAChD,CAAC,CAAC,CACD,KAAK,UAAU,MAAM,EAAE,CAAC,YAAY,CAAC,CACxC;CACD;AACD;;;;;;;;;;AAWA,SAAgB,WAAW,MAAiC;CAC3D,OAAO,KACL,MAAM,KAAK,CAAC,CACZ,KAAK,SAAS,KAAK,QAAQ,mCAAmC,EAAE,CAAC,CAAC,YAAY,CAAC,CAAC,CAChF,QAAQ,SAAS,SAAS,EAAE;AAC/B;;;;;;;;;;;AAYA,SAAgB,eAAe,OAA2B,SAAwC;CACjG,MAAM,CAAC,QAAQ,GAAG,WAAW;CAC7B,MAAM,KAAK,QAAQ,WAAW,WAAW,OAAO,OAAO,QAAQ,EAAE;CACjE,IAAI,QAAQ,SAAS,UAAU,KAAK,GAAG,OAAO,KAAA;CAC9C,MAAM,QAAQ,QAAQ,SAAS,CAAC;CAEhC,OAAO,EADW,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,EAAE,CAAC,CAAC,CAAC,SAAS,MAAM,WAClD,QAAQ,MAAM,WAAW,OAAO,SAAS,KAAA,CAAS,IACpE,MAAM,MAAM,SAAS,KAAK,OAAO,QAAQ,IAAI,IAC7C,MAAM;AACV;;;;;;;;;;;;;;;;AAiBA,SAAgB,cACf,OACA,WACA,UACS;CACT,OAAO,UAAU,IAAI,IAAI,YAAY,IAAI,UAAU,IAAK,aAAa,SAAS,IAAI,IAAK;AACxF;;;;;;;;;;;;;AAcA,SAAgB,eAAe,SAA6B,UAA0B;CACrF,MAAM,WAAW,WAAW;CAC5B,IAAI,CAAC,yBAAyB,QAAQ,KAAK,YAAY,UACtD,MAAM,IAAI,YACT,YACA,+DACD;CACD,OAAO;AACR;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,gBACf,SACA,YACS;CACT,MAAM,WAAW,QAAQ,UAAU,UAAU;CAC7C,IAAI,aAAa,GAAG,OAAO;CAC3B,MAAM,QAAQ,QAAQ,UAAU,KAAA,IAAY,IAAK,WAAW,QAAQ,KAAK,CAAC,EAAE,UAAU;CACtF,MAAM,YAAY,WAAW,QAAQ,QAAQ,SAAS;CACtD,OAAO,KAAK,IAAI,YAAY,KAAK,MAAM,cAAc,WAAW,UAAU,CAAC;AAC5E;;;;;;;;;;;;;;;;;AAkBA,SAAgB,eAAe,MAAiC;CAC/D,OAAO,KACL,MAAM,iCAAiC,CAAC,CACxC,KAAK,aAAa,SAAS,KAAK,CAAC,CAAC,CAClC,QAAQ,aAAa,aAAa,EAAE;AACvC;;;;;;;;;;;;;AAcA,SAAgB,cAAc,MAA8B;CAC3D,MAAM,UAAU;CAChB,MAAM,MAAM,IAAI,IACf,CAAC,GAAG,KAAK,SAAS,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,WACrC,KAAK,KAAK,KAAK,IAAI,CAAC,MAAM,YAAY,CAAC,IAAI,CAAC,CAC7C,CACD;CACA,MAAM,OAAO,KAAK,QAAQ,UAAU,UAAW,KAAK,KAAK,KAAK,IAAI,MAAM,KAAM;CAO9E,OAAO;EAAE;EAAK,SAAA,IANM,IACnB,CAAC,GAAG,KAAK,SAAS,+BAA+B,CAAC,CAAC,CAAC,SAAS,CAAC,WAAW;GACxE,MAAM,QAAQ,OAAO,MAAM,QAAQ,MAAM,EAAE,CAAC;GAC5C,OAAO,OAAO,SAAS,KAAK,IAAI,CAAC,KAAK,IAAI,CAAC;EAC5C,CAAC,CAEY;CAAQ;AACvB;;;;;;;;;;;;;;;;AAiBA,SAAgB,aAAa,MAAiC;CAC7D,OAAO,eAAe,IAAI,CAAC,CAAC,SAAS,aACpC,CAAC,GAAG,SAAS,SAAS,wEAAwE,CAAC,CAAC,CAC9F,QAAQ,WAAW,MAAM,SAAS,KAAK,CAAC,CAAC,CACzC,KAAK,UAAU,MAAM,EAAE,CAC1B;AACD;;;;;;;;;;;;;;;;AAiBA,SAAgB,kBAAkB,OAAuB;CACxD,OAAO,MAAM,KAAK,CAAC,CAAC,YAAY;AACjC;;;;;;;;;;;;;;;;AAiBA,SAAgB,iBAAiB,MAAiC;CACjE,OAAO,KAAK,MAAM,SAAS;AAC5B;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,iBAAiB,MAAc,MAAiD;CAC/F,MAAM,WAAW,WAAW,IAAI;CAChC,OAAO,aAAa,KAAA,IAAY,OAAO,GAAG,KAAK,GAAG;AACnD;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,eACf,MACA,MACqB;CACrB,MAAM,aAAa,OAAO,YACzB,OAAO,QAAQ,IAAI,CAAC,CAAC,KAAK,CAAC,KAAK,WAAW,CAC1C,KACA,SAAS,KAAK,IAAI,kBAAkB,KAAK,IAAI,KAC9C,CAAC,CACF;CACA,MAAM,YAAY,mBAAmB,UAAU;CAC/C,OAAO,cAAc,KAAA,IAAY,KAAA,IAAY,GAAG,KAAK,GAAG;AACzD;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,WACf,UACA,QAC8B;CAG9B,OAAO,IAAI,IACV,CAAC,GAAG,QAAQ,CAAC,CAAC,SAAS,YAAY;EAClC,IAAI,QAAQ,WAAW,KAAA,GAAW,OAAO,CAAC;EAC1C,MAAM,QAAQ,CAAC,GAAG,cAAc,QAAQ,IAAI,CAAC,CAAC,GAAG,CAAC,CAAC,QAAQ,OAAO,OAAO,IAAI,EAAE,CAAC;EAChF,MAAM,CAAC,QAAQ;EACf,OAAO,OAAO,OAAO,QAAQ,SAAS,CAAC,CACrC,OAAO,QAAQ,CAAC,CAChB,KAAK,UAAU,kBAAkB,KAAK,CAAC,CAAC,CACxC,QAAQ,YAAY,cAAc,OAAO,CAAC,CAAC,IAAI,IAAI,OAAO,CAAC,CAAC,CAC5D,SAAS,YAAY;GACrB,IAAI,OAAO,IAAI,OAAO,GAAG,OAAO,CAAC,CAAC,SAAS,OAAO,CAAU;GAC5D,OAAO,MAAM,WAAW,KAAK,SAAS,KAAA,IAAY,CAAC,CAAC,SAAS,IAAI,CAAU,IAAI,CAAC;EACjF,CAAC;CACH,CAAC,CACF;AACD;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,gBAAgB,UAA0D;CAGzF,MAAM,UAAU,CAAC,GAAG,QAAQ,CAAC,CAAC,SAAS,YACtC,QAAQ,WAAW,KAAA,IAAY,CAAC,IAAI,CAAC,QAAQ,MAAM,CACpD;CACA,OAAO;EACN,KAAK,IAAI,IACR,QAAQ,SAAS,WAAW,CAC3B,GAAG,OAAO,KACV,GAAG,MAAM,KAAK,OAAO,SAAS,UAAU,MAAM,EAAE,CACjD,CAAC,CACF;EACA,QAAQ,IAAI,IACX,CACC,GAAG,IAAI,QACN,QAAQ,SAAS,WAAW,MAAM,KAAK,OAAO,MAAM,CAAC,IACpD,UAAU,MAAM,EAClB,CACD,CAAC,CAAC,KAAK,CAAC,IAAI,YAAY,CACvB,IACA,CACC,GAAG,IAAI,IACN,OAAO,SAAS,UACf,MAAM,MAAM,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,QAAQ,SAAS,SAAS,KAAK,IAAI,CAAC,CAC5E,CACD,CACD,CACD,CAAC,CACF;CACD;AACD;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,cACf,UACA,MACA,SACsB;CACtB,MAAM,SAAS,cAAc,IAAI,CAAC,CAAC;CAEnC,MAAM,UAAU,IAAI,QACnB,CAAC,GAAG,SAAS,MAAM,CAAC,CAAC,SAAS,CAAC,IAAI,WAAW,MAAM,KAAK,QAAQ,UAAU;EAAE;EAAM;CAAG,EAAE,CAAC,IACxF,UAAU,MAAM,IAClB;CAEA,MAAM,WAAW,IAAI,QACpB,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,SAAS,SAAS,CAAC,GAAG,IAAI,IAAI,KAAK,MAAM,KAAK,CAAC,CAAC,CAAC,IACpE,SAAS,IACX;CACA,uBAAO,IAAI,IAAI,CACd,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,QAAQ,OAAO,OAAO,IAAI,EAAE,CAAC,GAClD,GAAG,CAAC,GAAG,OAAO,CAAC,CAAC,SAAS,CAAC,MAAM,aAAa;EAC5C,MAAM,QAAQ,UACX,KACC,MAAM,KAAK,CAAC,CACZ,QAAQ,SAAS,kBAAkB,KAAK,IAAI,KAAK,SAAS,IAAI,IAAI,CAAC,EAAE,WAAW,CAAC,IAClF,CAAC;EASJ,OAJc,CAHb;GAAE,QAAQ;GAAM,OAAO;EAAK,GAC5B,GAAG,MAAM,KAAK,UAAU;GAAE,QAAQ;GAAM,OAAO;EAAI,EAAE,CAExC,CAAA,CAAQ,MAAM,EAAE,QAAQ,YAAY;GACjD,MAAM,UAAU,OAAO,QAAQ,uBAAuB,MAAM;GAC5D,OAAO,IAAI,OAAO,sBAAsB,QAAQ,qBAAqB,KAAK,CAAC,CAAC,KAAK,IAAI;EACtF,CACO,IAAQ,QAAQ,KAAK,UAAU,MAAM,EAAE,IAAI,CAAC;CACpD,CAAC,CACF,CAAC;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAwCA,SAAgB,aAAa,OAAgD;CAC5E,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,KAAK,SAAS,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;CAC9E,MAAM,OAAO,IAAI,IAAI,MAAM,SAAS,KAAK,YAAY,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC;CAC3E,MAAM,OAAO,YAAY,KAAK;CAC9B,MAAM,QAAQ,WAAW,MAAM,UAAU,MAAM,MAAM;CACrD,MAAM,WAAW,IAAI,IACpB,CACC,GAAG,IAAI,QACN,CAAC,GAAG,MAAM,eAAe,UAAU,CAAC,CAAC,SAAS,CAAC,SAAS,YACvD,OAAO,KAAK,WAAW;EAAE;EAAS;CAAM,EAAE,CAC3C,IACC,SAAS,KAAK,KAChB,CACD,CAAC,CAAC,KAAK,CAAC,OAAO,WAAW,CAAC,OAAO,MAAM,KAAK,SAAS,KAAK,OAAO,CAAC,CAAC,CACrE;CACA,MAAM,aAAa,kBAAkB,OAAO,MAAM,IAAI;CACtD,MAAM,UAAU,CAAC,GAAG,MAAM,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK;CAChD,MAAM,SAAS,aAAa,MAAM,MAAM;CAExC,MAAM,0BAAU,IAAI,IAAiC;CACrD,MAAM,aAAa,KAAK,KAAK,QAAQ;EACpC;EACA,MAAM,YAAY,OAAO,OAAO,UAAU,oBAAI,IAAI,IAAI,GAAG,OAAO;CACjE,EAAE;CACF,MAAM,UAAU,WAAW,QAAQ,cAAc,UAAU,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,EAAE,SAAS,EAAE;CAoC9F,OAAO;EAAE,SA/BO,CAAC,GAJD,IAAI,QACnB,WAAW,SAAS,EAAE,IAAI,WAAW,CAAC,GAAG,IAAI,CAAC,CAAC,KAAK,SAAS;GAAE;GAAK;EAAG,EAAE,CAAC,IACzE,UAAU,MAAM,GAEE,CAAO,CAAC,CAC1B,KAAK,CAAC,KAAK,aAAa;GACxB,MAAM,MAAM,QAAQ,KAAK,UAAU,MAAM,EAAE;GAC3C,MAAM,QAAQ,IAAI,SAAS,OAAO,WAAW,OAAO,MAAM,IAAI,SAAS,MAAM,CAAC;GAC9E,MAAM,QAAQ,IAAI,MAAM,oBAAoB,MAAM;GAClD,MAAM,SAAS,MAAM,OAAO,IAAI,KAAK,CAAC,GAAG;GACzC,MAAM,QACL,QAAA,UACG,UACA,WAAW,KAAA,IACV,WAAW,UACX,GAAG,OAAO,YAAY,MAAM;GAEjC,OAAO;IACN,OAFa,SAAS,IAAI,IAAI,MAAM,EAAE,KAAK;IAG3C,QAAQ;KACP;KACA;KACA,SAAS;KACT;IACD;GACD;EACD,CAAC,CAAC,CACD,MACC,MAAM,UACN,OAAO,KAAK,OAAO,QAAA,OAAwB,IAC1C,OAAO,MAAM,OAAO,QAAA,OAAwB,KAC7C,KAAK,QAAQ,MAAM,UAClB,KAAK,OAAO,MAAM,MAAM,OAAO,MAAM,KAAK,KAAK,OAAO,MAAM,MAAM,OAAO,MAAM,IAAI,EACtF,CAAC,CACA,KAAK,EAAE,aAAa,MACb;EAAS;EAAY;CAAQ;AACvC;;;;;;;;;;;;;;;;;;;;;AAsBA,SAAgB,cACf,YACA,SAC0B;CAC1B,MAAM,SAAS,IAAI,IAAI,QAAQ,MAAM;CACrC,MAAM,QAAQ,WAAW,QAAQ,MAAM,QAAQ,IAAI,QAAQ,gBAAgB;CAG3E,MAAM,QAAQ,IAAI,SAChB,OAAO,SAAS,CAAC,EAAA,CAAG,aAAa,IAAI,IACrC,SAAS,KAAK,OAAO,MAAM,UAAU,OAAO,IAAI,KAAK,CAAC,CACxD;CACA,MAAM,SAAS,CAAC,GAAG,IAAI,IAAI,QAAQ,MAAM,CAAC,CAAC,CAAC,SAAS,UAAU;EAC9D,MAAM,SAAS,WAAW,QAAQ,MAAM,QAAQ,IAAI,QAAQ,GAAG,sBAAsB,OAAO;EAC5F,OAAO,WAAW,KAAA,IAAY,CAAC,IAAI,CAAC,MAAM;CAC3C,CAAC;CAED,OAAO,CACN,GAAG,CAAC,GAFU,IAAI,QAAQ,SAAS,WAAW,KAAK,UAAU,OAAO,OAAO,CAEpE,CAAA,CAAO,OAAO,CAAC,CAAC,CAAC,SAAS,CAAC,QAAQ,GAAG,UAC5C,WAAW,KAAA,IACR,CAAC,IACD,CACA,gBAAgB;EACf,GAAG;EACH,OAAO,CAAC,OAAO,OAAO,GAAG,KAAK,KAAK,QAAQ,IAAI,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;CACjE,CAAC,CACF,CACH,GACA,GAAI,UAAU,KAAA,IACX,CAAC,IACD,CACA,gBAAgB;EACf,GAAG;EACH,OAAO,CAAC,GAAI,MAAM,IAAI,IAAI,KAAK,CAAC,GAAI,GAAI,MAAM,IAAI,KAAK,KAAK,CAAC,CAAE;CAChE,CAAC,CACF,CACH;AACD;;;;;;;;;;;;;;;;;AAkBA,SAAgB,mBACf,QACA,SACS;CACT,OAAO,CACN,MAAM,OAAO,SACb,GAAG,OAAO,MAAM,SAAS,SACxB,CAAC,YAAY,KAAA,IAAY,KAAK,uBAAuB,MAAM,OAAO,GAAG,KAAK,KAAK,MAAM,CAAC,CAAC,QACrF,SAAS,SAAS,EACpB,CACD,CACD,CAAC,CAAC,KAAK,IAAI;AACZ;;;;;;;;;;;;;AAcA,SAAgB,mBACf,QACA,SACS;CACT,OAAO,IAAI,mBAAmB,QAAQ,OAAO;AAC9C;;;;;;;;;;;;;AAcA,SAAgB,yBACf,UACA,OACA,YACsB;CACtB,MAAM,aAAa,IAAI,IAAI,MAAM,KAAK,SAAS,GAAG,KAAK,OAAO,GAAG,KAAK,UAAU,CAAC;CACjF,OAAO;EACN;EACA,UAAU,IAAI,IACb,SACE,QAAQ,YAAY;GACpB,MAAM,YAAY,eAAe,QAAQ,OAAO;GAChD,OACC,UAAU,SAAS,KACnB,UAAU,OAAO,GAAG,UAAU,WAAW,IAAI,GAAG,QAAQ,GAAG,GAAG,OAAO,CAAC;EAExE,CAAC,CAAC,CACD,KAAK,YAAY,QAAQ,EAAE,CAC9B;EACA,OAAO,IAAI,IAAI,MAAM,WAAW,CAAC,CAAC,KAAK,SAAS,CAAC,KAAK,QAAQ,IAAI,CAAC,CAAC;EACpE,YAAY,IAAI,IACf,CAAC,GAAG,IAAI,IAAI,MAAM,KAAK,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,CAAC,KAAK,QAAQ,UAAU,CACrE,QACA,OAAO,QAAQ,CAAC,CACjB,CAAC,CACF;CACD;AACD;;;;;;;;;;;;;AAcA,SAAgB,uBAAuB,MAAkB,SAAsC;CAC9F,IAAI,QAAQ,MAAM,IAAI,KAAK,MAAM,MAAM,MAAM,OAAO;CACpD,MAAM,aAAa,QAAQ,WAAW,QAAQ,SAAS,KAAK,YAAY,KAAK,MAAM;CACnF,MAAM,WACL,QAAQ,SAAS,IAAI,KAAK,MAAM,KAChC,QAAQ,WAAW,MAAM,SAAS,KAAK,UAAU,KAAK,UAAU,QAAQ,MAAM,IAAI,KAAK,OAAO,CAAC;CAChG,IAAI,WAAW,WAAW,KAAK,CAAC,UAAU,OAAO;CACjD,MAAM,WAAW,WAAW,QAAQ,SAAS,QAAQ,SAAS,IAAI,KAAK,KAAK,CAAC;CAC7E,IACC,QAAQ,WAAW,IAAI,KAAK,MAAM,MAAM,KAAA,KACxC,SAAS,MAAM,SAAS,QAAQ,WAAW,IAAI,KAAK,KAAK,MAAM,KAAA,CAAS,GAExE,MAAM,IAAI,YAAY,aAAa,sDAAsD;CAC1F,OAAO;EACN,kBAAkB,QAAQ,WAAW,IAAI,KAAK,MAAM,EAAE;EACtD,GAAG,SAAS,KACV,SACA,2CAA2C,QAAQ,WAAW,IAAI,KAAK,KAAK,EAAE,oEAChF;EACA,GAAI,WAAW,MAAM,SAAS,CAAC,QAAQ,SAAS,IAAI,KAAK,KAAK,CAAC,IAC5D,CACA,qGACD,IACC,CAAC;CACL,CAAC,CAAC,KAAK,IAAI;AACZ;;;;;;;;;;;;;;;;AAiBA,SAAgB,WAAW,OAAkC;CAC5D,MAAM,QAAQ,MACZ,MAAM,wBAAwB,CAAC,CAC/B,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAC1B,QAAQ,SAAS,SAAS,EAAE;CAC9B,OAAO,MAAM,SAAS,IAAI,QAAQ,CAAC,KAAK;AACzC;;;;;;;;;;;;;;;;;;AAmBA,SAAgB,WAAW,SAA4B,MAAsB;CAE5E,MAAM,OAAO,CAAC,GAAG,QAAQ,KAAK,CAAC,CAAC,CAAC,WAC/B,OACA,KAAK,KACL,iBAAiB,CAChB;EACC,IAAI;EACJ,MAAM;EACN,SAAS,QAAQ,MAAM,GAAG,KAAK,CAAC,CAAC,CAAC,KAAK,IAAI;CAC5C,CACD,CAAC,IAAI,IACP;CACA,MAAM,OAAO,QAAQ,MAAM,GAAG,SAAS,KAAK,KAAA,IAAY,IAAI;CAC5D,MAAM,OAAO,QAAQ,SAAS,KAAK;CACnC,OAAO,CACN,GAAG,MACH,GAAI,OAAO,IACR,CACA,GAAG,KAAK,aAAa,SAAS,IAAI,KAAK,IAAI,uDAC5C,IACC,CAAC,CACL,CAAC,CAAC,KAAK,IAAI;AACZ;;;;;;;;;;;;AAaA,SAAgB,eAAe,MAAuB;CACrD,OAAO,gCAAgC,KAAK,IAAI;AACjD;;;;;;;;;;;;;;;AAgBA,SAAgB,WACf,MACA,MACA,OACS;CACT,MAAM,OAAO,iBAAiB,MAAM,IAAI;CACxC,IAAI,UAAU,UAAU,OAAO,GAAG,KAAK;CACvC,IAAI,UAAU,SAAS,OAAO,GAAG,KAAK;CACtC,IAAI,UAAU,SAAS,OAAO,GAAG,KAAK;CAEtC,OAAO,GAAG,KAAK,wCADJ,OAAO,OAAO,IAAI,CAAC,CAAC,KAAK,QACmB,KAAM,GAAA,CAAI,KAAK,KAAK;AAC5E;;;;;;;;;;;;;;;;;AAkBA,SAAgB,SAAS,QAAiE;CAEzF,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC,SAAS,UAClC,CAAC,GAAG,IAAI,QAAQ,QAAQ,SAAS,KAAK,KAAK,CAAC,CAAC,OAAO,CAAC,CAAC,CAAC,SAAS,QAAQ;EACvE,MAAM,SAAS,IAAI,SAAS,SAC3B,eAAe,KAAK,MAAM,KAAK,KAAK,WAAW,IAC5C,CAAC;GAAE,UAAU,KAAK;GAAU,QAAQ,KAAK;EAAO,CAAC,IACjD,CAAC,CACL;EACA,IAAI,OAAO,SAAS,GAAG,OAAO,CAAC;EAC/B,MAAM,QAAQ,OAAO,QAAQ,KAAK,UAAU,MAAM,MAAM,UAAU,CAAC,IAAI,OAAO;EAC9E,MAAM,QAAQ,OAAO,QAAQ,KAAK,UAAU,MAAM,MAAM,QAAQ,CAAC,IAAI,OAAO;EAC5E,OAAO,OAAO,KAAK,WAAW;GAC7B,SAAS,MAAM,WAAW,UAAU;GACpC,UAAU,MAAM,WAAW,UAAU,MAAM,SAAS;EACrD,EAAE;CACH,CAAC,CACF;CACA,MAAM,SAAS,MAAM,QAAQ,KAAK,SAAS,MAAM,KAAK,QAAQ,CAAC;CAC/D,MAAM,UAAU,MAAM,QAAQ,KAAK,SAAS,MAAM,KAAK,SAAS,CAAC;CACjE,OAAO,SAAS,IAAI,UAAU,SAAS,KAAA;AACxC;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,YAAY,OAAiD;CAC5E,MAAM,EAAE,mBAAmB;CAC3B,MAAM,WAAW,IAAI,IAAI,MAAM,UAAU;CACzC,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,KAAK,SAAS,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;CAC9E,MAAM,WAAW,MAAM,SAAS,QAAQ,YAAY,SAAS,IAAI,QAAQ,EAAE,CAAC;CAC5E,MAAM,aAAa,IAAI,IACtB,SAAS,KAAK,YAAY,CAAC,QAAQ,IAAI,eAAe,QAAQ,MAAM,QAAQ,SAAS,CAAC,CAAC,CACxF;CACA,MAAM,UAAU,IAAI,IACnB,SACE,QACC,YACA,QAAQ,WAAW,KAAA,KACnB,CAAC,SAAS,MACR,UACA,WAAW,IAAI,QAAQ,EAAE,MAAM,KAAA,MAC9B,SAAS,IAAI,MAAM,EAAE,KAAK,OAAO,SAAS,IAAI,QAAQ,EAAE,KAAK,OAC9D,WAAW,IAAI,MAAM,EAAE,MAAM,WAAW,IAAI,QAAQ,EAAE,CACxD,CACF,CAAC,CACA,KAAK,YAAY,QAAQ,EAAE,CAC9B;CACA,OAAO,CAAC,GAAG,IAAI,IAAI,MAAM,SAAS,KAAK,YAAY,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,CAAC,CAAC,OAAO,CAAC,CAAC,CAClF,QACC,YAAY,QAAQ,SAAS,UAAW,QAAQ,SAAS,UAAU,QAAQ,IAAI,QAAQ,EAAE,CAC3F,CAAC,CACA,KAAK,YAAY,QAAQ,EAAE,CAAC,CAC5B,QACC,OACA,CAAC,SAAS,IAAI,EAAE,KAChB,CAAC,eAAe,MAAM,IAAI,EAAE,MAC3B,eAAe,cAAc,IAAI,EAAE,KAAK,CAAC,EAAA,CAAG,WAAW,CAC1D;AACF;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;;AAiCA,SAAgB,YACf,OACA,OACA,UACA,IACA,MACA,SACsB;CACtB,MAAM,QAAQ,SAAS,IAAI,EAAE;CAC7B,IAAI,UAAU,KAAA,GAAW,OAAO;CAChC,MAAM,UAAU,MAAM,SAAS,IAAI,EAAE,KAAK,CAAC,EAAA,CAAG,SAAS,WAAW;EACjE,MAAM,QAAQ,MAAM,OAAO,IAAI,MAAM,IAAI,SAAS,MAAM,IAAI,MAAM;EAClE,OAAO,UAAU,KAAA,IAAY,CAAC,IAAI,CAAC,GAAG,sBAAsB,OAAO;CACpE,CAAC;CACD,MAAM,QAAQ,OAAO,SAAS;CAC9B,MAAM,QAAQ,QAAQ,CAAC,KAAK,SAAS,IAAI,EAAE,KAAK,CAAC,EAAA,CAAG,QAAQ,SAAS,SAAS,EAAE;CAChF,MAAM,UAAU,MAAM,QAAQ,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC;CACtD,MAAM,WAAW,MAAM,eAAe,WAAW,IAAI,EAAE;CACvD,MAAM,QACL,CAAC,SAAS,QAAQ,WAAW,KAAK,aAAa,KAAA,KAAa,kBAAkB,SAAS,QAAQ;CAChG,MAAM,uBAAO,IAAI,IAAI;EACpB,GAAG;EACH,GAAG,QAAQ,SAAS,SAAS,CAC5B,GAAG,YAAY,OAAO,OAAO,UAAU,sBAAM,IAAI,IAAI,CAAC,GAAG,MAAM,EAAE,CAAC,GAAG,OAAO,CAC7E,CAAC;EACD,GAAI,QAAQ,CAAC,gBAAgB,IAAI,CAAC;CACnC,CAAC;CACD,IACC,YAAY,KAAA,KACZ,QAAQ,WAAW,MAAM,UACzB,QAAQ,OAAO,SAAS,QAAQ,IAAI,IAAI,CAAC,GAEzC,QAAQ,IAAI,IAAI,IAAI;CACrB,OAAO;AACR;;;;;;;;;;;;;;;;;;;AAoBA,SAAgB,kBACf,OACA,MACA,MAC6B;CAC7B,MAAM,EAAE,mBAAmB;CAC3B,MAAM,WAAW,IAAI,IAAI,MAAM,UAAU;CACzC,MAAM,SAAS,IAAI,IAAI,IAAI;CAC3B,MAAM,UAAU,CAAC,GAAG,IAAI,IAAI,MAAM,SAAS,KAAK,YAAY,QAAQ,EAAE,CAAC,CAAC;CACxE,MAAM,YAAY,IAAI,IAAI,QAAQ,KAAK,IAAI,UAAU,CAAC,IAAI,KAAK,CAAC,CAAC;CACjE,MAAM,4BAAY,IAAI,IAAI,CACzB,GAAG,MACH,GAAG,CAAC,GAAG,KAAK,OAAO,CAAC,CAAC,CACnB,QACC,YACA,QAAQ,SAAS,eACjB,CAAC,SAAS,IAAI,QAAQ,EAAE,KACxB,CAAC,eAAe,MAAM,IAAI,QAAQ,EAAE,MACnC,eAAe,cAAc,IAAI,QAAQ,EAAE,KAAK,CAAC,EAAA,CAAG,SAAS,CAChE,CAAC,CACA,KAAK,YAAY,QAAQ,EAAE,CAC9B,CAAC;CACD,OAAO,QACL,QAAQ,OAAO,OAAO,IAAI,EAAE,CAAC,CAAC,CAC9B,SAAS,YACT,CAAC,GAAG,IAAI,IAAI,eAAe,WAAW,IAAI,OAAO,KAAK,CAAC,CAAC,CAAC,CAAC,CACxD,QAAQ,UAAU,UAAU,IAAI,KAAK,KAAK,UAAU,IAAI,KAAK,CAAC,CAAC,CAC/D,MAAM,GAAG,OAAO,UAAU,IAAI,CAAC,KAAK,MAAM,UAAU,IAAI,CAAC,KAAK,EAAE,CAAC,CACjE,KAAK,WAAW;EAAE;EAAS;CAAM,EAAE,CACtC;AACF;;;;;;;;;;;;;;;;;;;;;;AAuBA,SAAgB,WACf,OACA,MACA,IACA,SACA,QACwB;CACxB,MAAM,UAAU,KAAK,IAAI,EAAE;CAC3B,IAAI,YAAY,KAAA,GAAW,OAAO,CAAC;CACnC,MAAM,YAAY,eAAe,QAAQ,OAAO;CAChD,MAAM,SAAS,MAAM,eAAe,OAAO,IAAI,EAAE,KAAK,CAAC;CACvD,OAAO,UAAU,SAAS,UAAU,OAAO;EAC1C,MAAM,QACL,kDAAkD,KAAK,QAAQ,KAAK,KAAK,IACtE,aAAa,UAAU,KAAK,MAAM,EAAE,CAAC,CACpC,QAAQ,SAAS,CAAC,QAAQ,SAAS,IAAI,KAAK,CAAC,OAAO,SAAS,IAAI,CAAC,CAAC,CACnE,GAAG,EAAE,IACN,KAAA;EACJ,MAAM,OAAO;GACZ,MAAM,UAAU,KAAA,IAAY,WAAW,GAAG,MAAM,IAAI;GACpD,QAAQ;GACR,UAAU;GACV,QAAQ,CAAC,GAAG,MAAM;GAClB,MAAM,QAAQ;EACf;EACA,OAAO,CAAC,UAAU,KAAA,IAAY,OAAO;GAAE,GAAG;GAAM;EAAM,CAAC;CACxD,CAAC;AACF;;;;;;;;;;;;AC5qCA,IAAa,aAAb,MAAuD;CACtD;CACA,0BAAmB,IAAI,IAAY;;;;;CAMnC,YAAY,SAA4B;EACvC,KAAK,WAAW;CACjB;;;;;;;CAQA,MAAM,SAAS,UAA+B,QAAgD;EAC7F,MAAM,UAA8B,CAAC;EACrC,MAAM,QAAQ,MAAM,KAAK,QAAQ,UAAU,QAAQ,OAAO,CAAC,CAAC,WAClC,KAAA,IACxB,UAAoB,QAAQ,KAAK,IAAI,QAAQ,IAAI,MAAM,eAAe,KAAK,CAAC,CAC9E;EACA,MAAM,QAAQ,QAAQ,QACpB,OAAO,WAAY,OAAO,UAAU,KAAA,IAAY,QAAQ,SAAS,OAAO,OAAO,KAAK,GACrF,KAAA,CACD;EACA,OAAO;GACN,WAAW,QAAQ,SAAS,WAAW,OAAO,SAAS;GACvD,UAAU,QAAQ,SAAS,WAAW,OAAO,QAAQ;GACrD,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;GACvC,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EACxC;CACD;;;;;;CAOA,SAAS,IAAwC;EAChD,MAAM,UAAU,KAAK,SAAS,aAAa,QAAQ,EAAE;EACrD,IAAI,YAAY,KAAA,GAAW,OAAO,KAAA;EAClC,MAAM,WAAW,KAAK,SAAS,OAAO,OAAO;EAC7C,IAAI,aAAa,KAAA,GAAW,OAAO;EACnC,MAAM,SAAS,KAAK,gBAAgB,EAAE;EACtC,MAAM,SAAS,KAAK,SAAS,WAAW;EAQxC,OAPmB,OAAO,QAAQ,QAAQ,iBAAiB,CAAC,CAAC,CAAC,CAAC,SAC7D,CAAC,QAAQ,iBAAiB;GAC1B,MAAM,WAAW,kBAAkB,MAAM,cAAc,cAAc,MAAM;GAC3E,OAAO,aAAa,KAAA,KAAa,eAAe,SAAS,CAAC;IAAE;IAAU;GAAY,CAAC,IAAI,CAAC;EACzF,CAGM,CAAA,CAAW,QAChB,MAAM,cACN,SAAS,KAAA,KAAa,UAAU,cAAc,KAAK,cAAc,YAAY,MAC9E,KAAA,CACD,CAAC,EAAE;CACJ;;;;;;CAOA,MAAM,IAAqB;EAC1B,MAAM,UAAU,KAAK,SAAS,aAAa,QAAQ,EAAE;EACrD,IAAI,YAAY,KAAA,GAAW,OAAO;EAClC,MAAM,WAAW,KAAK,SAAS,OAAO,OAAO;EAC7C,IAAI,aAAa,KAAA,GAAW,OAAO,iBAAiB,SAAS,QAAQ;EACrE,OAAO,KAAK,OAAO,IAAI,gBAAgB,KAAK,KAAK,SAAS,WAAW;CACtE;;;;;;CAOA,SAAS,IAAqB;EAC7B,OAAO,KAAK,OAAO,IAAI,mBAAmB,KAAK,KAAK,SAAS,WAAW;CACzE;;;;;;CAOA,OAAO,IAAiC;EACvC,MAAM,UAAU,KAAK,SAAS,aAAa,QAAQ,EAAE;EAErD,OAAO,IAAI,IACV,YAAY,KAAA,IACT,CAAC,IACD,CAAC,GAAG,KAAK,SAAS,MAAM,CAAC,CACxB,QACC,WACC,KAAK,UAAU,KAAK,YAAY,IAAI,KAAK,CAAC,KAAK,MAChD,KAAK,SAAS,WAAW,KAC3B,CAAC,CACA,KAAK,UAAU,MAAM,IAAI,CAC9B;CACD;;;;;CAMA,iBAAuC;EACtC,MAAM,WAAW,KAAK,SAAS,aAAa,SAAS;EACrD,MAAM,YAAY,IAAI,IAAI,SAAS,KAAK,SAAS,OAAO,CAAC,QAAQ,IAAI,EAAE,CAAC,CAAC;EAEzE,MAAM,QAAQ,SAAS,KAAK,aAAa;GACxC,IAAI,QAAQ;GACZ,OAAO,KAAK,MAAM,QAAQ,EAAE;GAC5B,UAAU,KAAK,SAAS,QAAQ,EAAE;GAClC,QAAQ,CAAC,GAAG,KAAK,OAAO,QAAQ,EAAE,CAAC;EACpC,EAAE;EACF,MAAM,QAAQ,KAAK,SAAS,aAAa,UAAU,UAAU,CAAC,CAAC,SAAS,aAAa;GACpF,MAAM,MAAM,YAAY,SAAS,IAAI,OAAO;GAC5C,IAAI,QAAQ,KAAA,GAAW,OAAO,CAAC;GAC/B,MAAM,CAAC,MAAM,SAAS,SAAS;GAC/B,IAAK,SAAS,YAAY,SAAS,gBAAiB,CAAC,SAAS,OAAO,KAAK,CAAC,SAAS,KAAK,GACxF,OAAO,CAAC;GACT,MAAM,SAAS,KAAK,SAAS,aAAa,QAAQ,OAAO;GACzD,MAAM,QAAQ,KAAK,SAAS,aAAa,QAAQ,KAAK;GACtD,IACC,WAAW,KAAA,KACX,UAAU,KAAA,MACT,KAAK,UAAU,KAAK,WAAW,MAAM,SAAS,KAAK,CAAC,KAAK,KACzD,KAAK,SAAS,WAAW,OAE1B,OAAO,CAAC;GACT,MAAM,MAAM,cAAc,OAAO,OAAO;GACxC,MAAM,QAAQ,cAAc,MAAM,OAAO;GACzC,OAAO,SAAS,YACf,CAAC,CAAC,GAAG,IAAI,GAAG,CAAC,CAAC,MAAM,OAAO,MAAM,IAAI,IAAI,EAAE,CAAC,KAC5C,CAAC,CAAC,GAAG,IAAI,OAAO,CAAC,CAAC,MAAM,WAAW,MAAM,QAAQ,IAAI,MAAM,CAAC,IAC1D,CAAC,IACD,CAAC;IAAE;IAAM;IAAS;GAAM,CAAC;EAC7B,CAAC;EACD,OAAO;GACN,OAAO,IAAI,IAAI,MAAM,QAAQ,QAAQ,IAAI,KAAK,CAAC,CAAC,KAAK,QAAQ,IAAI,EAAE,CAAC;GACpE,YAAY,IAAI,IACf,MAAM,SAAS,QACd,IAAI,aAAa,KAAA,IAAY,CAAC,IAAI,CAAC,CAAC,IAAI,IAAI,IAAI,QAAQ,CAAU,CACnE,CACD;GACA,QAAQ,IAAI,IAAI,MAAM,KAAK,QAAQ,CAAC,IAAI,IAAI,IAAI,MAAM,CAAC,CAAC;GACxD,YAAY,KAAK,YAAY,OAAO,SAAS;GAC7C,eAAe,KAAK,YACnB,MAAM,QAAQ,SAAS,KAAK,SAAS,YAAY,GACjD,SACD;EACD;CACD;CAIA,YACC,OACA,WACyC;EACzC,OAAO,IAAI,IACV,CAAC,GAAG,IAAI,QAAQ,QAAQ,SAAS,KAAK,OAAO,CAAC,CAAC,CAAC,KAAK,CAAC,SAAS,aAAa,CAC3E,SACA,CAAC,GAAG,IAAI,IAAI,QAAQ,KAAK,SAAS,KAAK,KAAK,CAAC,CAAC,CAAC,CAAC,MAC9C,MAAM,WAAW,UAAU,IAAI,IAAI,KAAK,MAAM,UAAU,IAAI,KAAK,KAAK,EACxE,CACD,CAAC,CACF;CACD;CAIA,MAAM,QACL,UACA,QACA,SACgB;EAChB,MAAM,WAAW,KAAK,SAAS,aAAa,SAAS;EACrD,MAAM,QAAQ,SAAS,QAAQ,YAAY,KAAK,SAAS,OAAO,OAAO,MAAM,KAAA,CAAS;EACtF,KAAK,MAAM,WAAW,OACrB,IAAI,CAAC,SAAS,IAAI,QAAQ,EAAE,GAC3B,QAAQ,KAAK,MAAM,KAAK,KAAK,KAAK,eAAe,QAAQ,EAAE,GAAG,YAAY,QAAQ,OAAO,CAAC;EAE5F,KAAK,MAAM,WAAW,OAAO;GAC5B,IAAI,CAAC,SAAS,IAAI,QAAQ,EAAE,KAAK,KAAK,MAAM,QAAQ,EAAE,GAAG;GACzD,KAAK,MAAM,SAAS,KAAK,SAAS,QAAQ;IACzC,IAAI,SAAS,IAAI,QAAQ,EAAE,KAAK,MAAM,cAAc,OAAO;IAC3D,QAAQ,KAAK,MAAM,KAAK,KAAK,KAAK,YAAY,QAAQ,IAAI,KAAK,GAAG,SAAS,QAAQ,OAAO,CAAC;GAC5F;EACD;EACA,KAAK,MAAM,SAAS,OAAO;GAC1B,IACC,MAAM,SAAS,WACd,KAAK,gBAAgB,MAAM,EAAE,CAAC,EAAE,cAAc,cAAc,KAC5D,KAAK,SAAS,WAAW,YAE1B;GACD,MAAM,OAAO,KAAK,aAAa,KAAK;GACpC,IAAI,KAAK,SAAS,GAAG;GACrB,KAAK,MAAM,WAAW,UAAU;IAC/B,IAAI,QAAQ,OAAO,MAAM,IAAI;IAC7B,IACC,KAAK,MAAM,QAAQ,EAAE,KACrB,CAAC,CAAC,GAAG,KAAK,aAAa,OAAO,CAAC,CAAC,CAAC,MAAM,UAAU,KAAK,IAAI,KAAK,CAAC,GAEhE;IACD,MAAM,OAAO,KAAK,WAAW,UAAU,QAAQ,IAAI,MAAM,EAAE;IAC3D,QAAQ,KAAK,MAAM,KAAK,KAAK,MAAM,UAAU,QAAQ,OAAO,CAAC;IAC7D,KAAK,KAAK,UAAU,IAAI,KAAK,MAAM,KAAK,SAAS,WAAW,QAC3D,QAAQ,KACP,MAAM,KAAK,KACV,KAAK,WAAW,cAAc,QAAQ,IAAI,MAAM,EAAE,GAClD,cACA,QACA,OACD,CACD;GACF;EACD;CACD;CAEA,aAAa,IAAoB;EAChC,MAAM,UAAU,KAAK,SAAS,aAAa,QAAQ,EAAE;EACrD,OAAO,GAAG,SAAS,QAAQ,UAAU,IAAI,SAAS,WAAW;CAC9D;CAEA,eAAe,IAA2B;EACzC,OAAO;GACN,IAAI,KAAK,UAAU,CAAC,YAAY,EAAE,CAAC;GACnC,UAAU;IACT,MAAM;IACN,GAAI,KAAK,SAAS,UAAU,SAAS,iBAAiB,KAAA,IACnD,CAAC,IACD,EAAE,cAAc,KAAK,SAAS,UAAU,SAAS,aAAa;IACjE,UAAU,OAAO,YAChB,kBAAkB,KAAK,aAAa,CACnC,UACA,KAAK,SAAS,UAAU,SAAS,SAAS,SAC3C,CAAC,CACF;GACD;GACA,SAAS,CAAC,EAAE;GACZ,OAAO,KAAK,aAAa,EAAE;GAC3B,OAAO,KAAK,SAAS,MAAM;EAC5B;CACD;CAEA,YAAY,IAAY,OAAmC;EAC1D,OAAO;GACN,IAAI,KAAK,UAAU;IAAC;IAAS;IAAI,MAAM;GAAI,CAAC;GAC5C,UAAU;IACT,MAAM;IACN,cAAc,KAAK,SAAS,UAAU;IACtC,UAAU;KACT,MAAM,wBAAwB,MAAM,KAAK,IAAI,MAAM;KACnD,OAAO,gCAAgC,MAAM;IAC9C;GACD;GACA,SAAS,CAAC,EAAE;GACZ,OAAO,KAAK,aAAa,EAAE;GAC3B,OAAO,KAAK,SAAS,MAAM;EAC5B;CACD;CAEA,WAAW,MAA+B,SAAiB,OAA8B;EACxF,OAAO;GACN,IAAI,KAAK,UAAU;IAAC;IAAM;IAAS;GAAK,CAAC;GACzC,UAAU,KAAK,SAAS,UAAU;GAClC,SAAS,CAAC,SAAS,KAAK;GACxB,OAAO,oBAAoB,KAAK,aAAa,OAAO,EAAE,mBAAmB,KAAK,aAAa,KAAK;GAChG,OAAO,KAAK,SAAS,MAAM;EAC5B;CACD;CAEA,MAAM,MAA2C;EAChD,MAAM,WAAW,KAAK,SAAS,aAAa,UAAU,SAAS,KAAK,EAAE;EACtE,OAAO,aAAa,KAAA,KACnB,gBAAgB,UAAU,KAAK,UAAU,KAAK,SAAS,KAAK,OAAO,KAAK,SAAS,MAAM,KAAK,IAC1F,WACA,KAAA;CACJ;CAEA,UAAU,MAAyC;EAClD,MAAM,SAAS,KAAK,MAAM,IAAI,CAAC,EAAE;EACjC,OAAO,QAAQ,SAAS,SAAS,OAAO,OAAO,KAAA;CAChD;CAEA,gBAAgB,IAAsC;EACrD,MAAM,SAAS,KAAK,MAAM,KAAK,eAAe,EAAE,CAAC,CAAC,EAAE;EACpD,OAAO,QAAQ,SAAS,WAAW,SAAS,KAAA;CAC7C;CAEA,OAAO,IAAY,YAA+C;EACjE,MAAM,SAAS,KAAK,gBAAgB,EAAE;EACtC,OAAO,WAAW,QAAQ,KAAK,aAAa,OAAO,QAAQ,cAAc,aAAa,IAAI,CAAC;CAC5F;CAEA,aAAa,SAAuC;EACnD,MAAM,gBACL,QAAQ,UAAU,KAAA,IACf,KAAA,IACA,WAAW,QAAQ,MAAM,KAAK,SAAS,KAAK,SAAS,CAAC;EAC1D,MAAM,OACL,kBAAkB,KAAA,IAAY,QAAQ,UAAU,GAAG,QAAQ,QAAQ,GAAG;EACvE,uBAAO,IAAI,IAAI,CACd,GAAG,KAAK,SAAS,SAAS,MAAM,KAAK,GACrC,GAAI,KAAK,SAAS,OAAO,OAAO,MAAM,KAAA,IAAY,KAAK,OAAO,QAAQ,EAAE,IAAI,CAAC,CAC9E,CAAC;CACF;CAEA,MAAM,KACL,MACA,OACA,QACA,SAC4B;EAC5B,IAAI,KAAK,MAAM,IAAI,MAAM,KAAA,GACxB,OAAO;GAAE,WAAW,CAAC,KAAK,EAAE;GAAG,UAAU,CAAC;IAAE,KAAK,KAAK;IAAI;IAAO,SAAS;GAAS,CAAC;EAAE;EACvF,MAAM,cAAc,KAAK,UAAU,IAAI;EACvC,IAAI,KAAK,QAAQ,IAAI,WAAW,GAC/B,OAAO;GAAE,WAAW,CAAC;GAAG,UAAU,CAAC;IAAE,KAAK,KAAK;IAAI;IAAO,SAAS;GAAU,CAAC;EAAE;EACjF,OAAO,eAAe;EACtB,MAAM,UAAU,YAAY,IAAI;EAChC,IAAI;GACH,MAAM,CAAC,YAAY,MAAM,KAAK,SAAS,aAAa,UAAU,QAC7D,KAAK,SAAS,OACd;IAAE,OAAO,KAAK;IAAO,WAAW,GAAG,KAAK,KAAK,KAAK,SAAS;GAAE,GAC7D,KAAK,SACL,MACD;GACA,MAAM,WAAyC,CAC9C;IAAE,KAAK,KAAK;IAAI;IAAO,SAAS;IAAY,UAAU,YAAY,IAAI,IAAI;GAAQ,CACnF;GACA,OAAO,aAAa,KAAA,IACjB;IAAE,WAAW,CAAC;IAAG;GAAS,IAC1B;IACA,WAAW,CAAC,KAAK,EAAE;IACnB,GAAI,SAAS,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,SAAS,MAAM;IAChE;GACD;EACH,SAAS,OAAO;GAEf,MAAM,WAAyC,CAC9C;IACC,KAAK,KAAK;IACV;IACA,SAAS,kBAAkB,KAAK,KAAK,OAAO,UAAU,YAAY;IAClE,UAAU,YAAY,IAAI,IAAI;GAC/B,CACD;GACA,IAAI,kBAAkB,KAAK,GAC1B,QAAQ,KAAK;IACZ,WACC,OAAO,OAAO,MAAM,QAAQ,SAAS,KAAK,EAAE,KAC3C,MAAM,QAAQ,aAAa,KAAA,KAAa,OAAO,OAAO,MAAM,QAAQ,UAAU,KAAK,EAAE,IACnF,CAAC,KAAK,EAAE,IACR,CAAC;IACL,GAAI,MAAM,QAAQ,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,MAAM,QAAQ,MAAM;IAC1E;GACD,CAAC;QACG,QAAQ,KAAK;IAAE,WAAW,CAAC;IAAG;GAAS,CAAC;GAC7C,IACE,aAAa,KAAK,KAAK,MAAM,SAAS,cACvC,0BAA0B,KAAK,iBAAiB,KAAK,CAAC,GAEtD,KAAK,QAAQ,IAAI,WAAW;GAC7B,IAAI,OAAO,SAAS,MAAM;GAC1B,OAAO;IAAE,WAAW,CAAC;IAAG,UAAU,CAAC;GAAE;EACtC;CACD;AACD;;;;;;;;;;;AC9YA,SAAgB,WAAW,OAAiC;CAC3D,OAAO,eAAe,KAAK,KAAK,QAAQ,KAAK,SAAS;AACvD;;;;;;;;;;AAWA,SAAgB,sBAAsB,OAAiC;CACtE,OAAO,eAAe,KAAK,KAAK,OAAO,cAAc,KAAK,KAAK,QAAQ;AACxE;;;;;;;;;;;;;;;;;;;ACDA,IAAa,QAAb,MAA6C;CAC5C;CACA;CACA;CACA,WAAgD,CAAC;CACjD;CACA;CACA,SAAS;;;;;;;;;CAUT,YAAY,SAAuB;EAClC,IAAI,CAAC,eAAe,QAAQ,KAAK,KAAK,QAAQ,SAAS,GACtD,MAAM,IAAI,YAAY,SAAS,+CAA+C;EAE/E,IAAI,CAAC,eAAe,QAAQ,QAAQ,KAAK,QAAQ,WAAW,GAC3D,MAAM,IAAI,YAAY,SAAS,8CAA8C;EAE9E,IAAI,CAAC,sBAAsB,QAAQ,QAAQ,GAC1C,MAAM,IAAI,YAAY,YAAY,gDAAgD;EAEnF,KAAK,SAAS,QAAQ;EACtB,KAAK,YAAY,QAAQ;EACzB,KAAK,YAAY,QAAQ;EACzB,KAAK,WAAW,eAAe,QAAQ,SAAS,QAAQ,QAAQ;EAChE,KAAK,UAAU,QAAQ,UAAU;CAClC;CAEA,IAAI,QAAgB;EACnB,OAAO,KAAK;CACb;CAEA,IAAI,WAAmB;EACtB,OAAO,KAAK;CACb;;;;;;;;;;CAWA,KAAK,OAAqC;EACzC,MAAM,QAAQ,SAAS,CAAC,GAAG,KAAK,UAAU,KAAK,CAAC;EAChD,OAAO,UAAU,KAAA,KAAa,eAAe,KAAK,KAAK,QAAQ,IAAI,QAAQ,KAAK;CACjF;CAEA,UAAU,OAAqC;EAC9C,MAAM,OAAO,MAAM,GAAG,EAAE;EACxB,MAAM,OAAO,eAAe,MAAM,MAAM,IACrC,KAAK,UAAU,KAAK,cAAc,MAAM,KAAK,YAAY,SAAU,KAAK,YAAY,IAAK,KACzF,KAAK,YAAY,KAAK,UAAU,MAAM,YAAY;EACrD,OAAO,KAAK,IAAI,GAAG,KAAK,YAAY,IAAI;CACzC;CAEA,QAAQ,OAA6B,SAAyB;EAC7D,MAAM,OAAO,KAAK,KAAK,KAAK;EAQ5B,QALC,KAAK,SAAS,IACX,KAAK,SACL,OAAO,iBAAiB,CAAC;GAAE,IAAI;GAAS,MAAM;GAAa,SAAS;EAAQ,CAAC,CAAC,KAEjF,OAAO,iBAAiB,CAAC,mBAAmB,EAAE,GAAG;GAAE,IAAI;GAAU,MAAM;GAAQ,SAAS;EAAG,CAAC,CAAC;CAE/F;CAEA,KAAK,OAA6B,SAAyB;EAC1D,OAAO,KAAK,IACX,IACC,KAAK,UAAU,KAAK,IAAI,KAAK,WAAW,KAAK,QAAQ,OAAO,OAAO,KAAK,IAAI,KAAK,KAAK,KAAK,CAC7F;CACD;CAEA,QAAQ,OAA6B,OAAyB;EAC7D,MAAM,QAAQ,MAAM;EACpB,IAAI,UAAU,KAAA,KAAa,eAAe,MAAM,MAAM,KAAK,MAAM,WAAW,GAAG;GAC9E,MAAM,SAAS,MAAM,SAAS,KAAK;GACnC,IAAI,SAAS,GAAG,KAAK,SAAS,SAAS,MAAM;EAC9C;EACA,KAAK,WAAW,CAAC,GAAG,KAAK,UAAU,CAAC,GAAG,KAAK,CAAC;EAC7C,IAAI,eAAe,OAAO,UAAU,GACnC,KAAK,SAAS,KAAK,IAAI,KAAK,QAAQ,MAAM,cAAc,MAAM,YAAY,EAAE;CAC9E;AACD;;;;;;;;;;;;;ACtGA,IAAa,aAAb,MAAwB;CACvB,OAII,CAAC;CACL;CACA;CACA;;;;;;CAOA,YAAY,UAAkB;EAC7B,KAAK,YAAY;CAClB;;;;;;CAOA,IAAI,YAAmC;EACtC,OAAO,KAAK;CACb;;;;;;CAOA,IAAI,WAAmB;EACtB,OAAO,KAAK;CACb;;;;;;CAOA,IAAI,QAAgC;EACnC,OAAO,KAAK;CACb;;;;;;CAOA,IAAI,OAA8B;EACjC,OAAO,KAAK,MAAM,GAAG,EAAE;CACxB;;;;;;CAOA,IAAI,WAA+B;EAClC,OAAO,KAAK,KAAK,SAAS,UAAW,cAAc,QAAQ,CAAC,MAAM,QAAQ,IAAI,CAAC,CAAE,CAAC,CAAC,GAAG,EAAE;CACzF;;;;;;CAOA,IAAI,QAA8B;EACjC,OAAO,KAAK,KAAK,SAAS,OAAO,UAAU;GAC1C,IAAI,EAAE,UAAU,QAAQ,OAAO,CAAC;GAChC,MAAM,QAAQ,KAAK,KAAK,MAAM,QAAQ,CAAC;GACvC,MAAM,OAAO,MAAM,WAAW,QAAQ,UAAU,GAAG;GACnD,MAAM,SAAS,SAAS,KAAK,QAAQ,MAAM,MAAM,GAAG,IAAI;GACxD,MAAM,QAAQ,OAAO,SAAS,QAAS,WAAW,MAAM,CAAC,IAAI,KAAK,IAAI,CAAC,CAAE,CAAC,CAAC,GAAG,EAAE;GAChF,MAAM,WAAW,OAAO,SAAS,QAAS,cAAc,MAAM,CAAC,IAAI,QAAQ,IAAI,CAAC,CAAE,CAAC,CAAC,GAAG,EAAE;GACzF,MAAM,SACL,UAAU,KAAA,IACP,MAAM,OACN;IAAE,GAAG,MAAM;IAAM,QAAQ,MAAM;IAAQ,YAAY,MAAM;GAAW;GACxE,OAAO,CAAC,aAAa,KAAA,IAAY,SAAS;IAAE,GAAG;IAAQ;GAAS,CAAC;EAClE,CAAC;CACF;;;;;;;CAQA,MAAM,WAAsB,UAAwB;EACnD,KAAK,aAAa;EAClB,KAAK,YAAY;EACjB,IAAI,UAAU,UAAU,KAAA,GAAW,KAAK,SAAS,SAAS,KAAK,QAAQ,UAAU,KAAK;CACvF;;;;;;;CAQA,QAAQ,MAAiB,UAAwB;EAChD,KAAK,OAAO,CAAC,GAAG,KAAK,MAAM;GAAE;GAAM;EAAS,CAAC;CAC9C;;;;;;CAOA,MAAM,OAAyB;EAC9B,KAAK,SAAS,SAAS,KAAK,QAAQ,KAAK;CAC1C;;;;;;;;;;CAWA,KAAK,OAAyB;EAC7B,KAAK,OAAO,CAAC,GAAG,KAAK,MAAM,EAAE,OAAO;GAAE,QAAQ,MAAM;GAAQ,YAAY,MAAM;EAAW,EAAE,CAAC;CAC7F;;;;;;CAOA,MAAM,UAAwB;EAC7B,KAAK,OAAO,CAAC,GAAG,KAAK,MAAM,EAAE,SAAS,CAAC;CACxC;AACD;;;;;;;;;;;;;;;;;;;;;AC1HA,IAAa,gBAAb,MAA6D;CAC5D;CACA;CACA;CACA;CACA,UAAiC,CAAC;CAClC,YAA0C,CAAC;CAC3C,4BAAiC,IAAI,IAAI;CACzC,4BAA8D,IAAI,IAAI;CACtE,WAAW;CACX,UAAU;;;;;;;;CASV,YAAY,SAAiB,QAAA,GAAsC;EAClE,IAAI,CAAC,yBAAyB,KAAK,GAClC,MAAM,IAAI,YAAY,SAAS,0CAA0C;EAC1E,KAAK,WAAW;EAChB,KAAK,SAAS;CACf;;;;;;CAOA,IAAI,UAA+B;EAClC,OAAO,KAAK;CACb;;;;;;CAOA,IAAI,OAA8B;EACjC,OAAO,KAAK;CACb;;;;;;CAOA,IAAI,YAAmC;EACtC,OAAO,KAAK,QAAQ,GAAG,EAAE,CAAC,EAAE;CAC7B;;;;;;CAOA,IAAI,WAA+B;EAClC,OAAO,KAAK,QAAQ,GAAG,EAAE,CAAC,EAAE;CAC7B;;;;;;CAOA,IAAI,QAAgC;EACnC,OAAO,KAAK,QAAQ,GAAG,EAAE,CAAC,EAAE;CAC7B;;;;;;CAOA,IAAI,QAA8B;EACjC,OAAO,KAAK,QAAQ,SAAS,SAAS,KAAK,KAAK;CACjD;;;;;;CAOA,IAAI,WAAyC;EAC5C,OAAO,KAAK;CACb;CAEA,MAAM,cAA8C;EACnD,IAAI,KAAK,aAAa,KAAA,GAAW,OAAO,KAAK;EAC7C,KAAK,WAAW,aAAa,IAAI;GAAE,MAAM;GAAQ,SAAS,KAAK;EAAS,CAAC;EACzE,OAAO,KAAK;CACb;CAEA,KAAK,UAAwB;EAC5B,KAAK,UAAU,CAAC,GAAG,KAAK,SAAS,IAAI,WAAW,QAAQ,CAAC;CAC1D;CAEA,MAAM,WAAsB,UAAwB;EACnD,KAAK,QAAQ,GAAG,EAAE,CAAC,EAAE,MAAM,WAAW,QAAQ;CAC/C;CAEA,QAAQ,MAAiB,UAAwB;EAChD,KAAK,QAAQ,GAAG,EAAE,CAAC,EAAE,QAAQ,MAAM,QAAQ;CAC5C;CAEA,MAAM,OAAyB;EAC9B,KAAK,QAAQ,GAAG,EAAE,CAAC,EAAE,MAAM,KAAK;EAEhC,KAAK,QAAQ,UAAU,SAAS,KAAK,SAAS,KAAA,CAAS,CAAC,EAAE,KAAK,KAAK;CACrE;CAEA,MAAM,UAAoC;EACzC,MAAM,OAAO,KAAK,QAAQ,UAAU,QAAQ,IAAI,SAAS,KAAA,CAAS;EAClE,MAAM,aAAa,MAAM,MAAM;EAC/B,IAAI,MAAM,aAAa,KAAA,KAAa,eAAe,KAAA,GAAW;EAC9D,MAAM,UAAU,SAAS,MAAM,KAAK,QAAQ,CAAC,CAAC,MAAM,UAAU,MAAM,SAAS,WAAW;EACxF,IAAI,SAAS,aAAa,KAAA,GAAW;EACrC,KAAK,MAAM,gBAAgB,SAAS,UAAU,CAAC;CAChD;CAEA,KAAK,UAAwC,MAAwB;EACpE,KAAK,YAAY,CAAC,GAAG,KAAK,WAAW,GAAG,QAAQ;EAChD,IAAI,SAAS,KAAA,GAAW,KAAK,QAAQ;CACtC;CAEA,MAAM,MAAc,MAA+C;EAClE,MAAM,MAAM,mBAAmB,CAAC,MAAM,IAAI,CAAC;EAC3C,IAAI,QAAQ,KAAA,GAAW,MAAM,IAAI,MAAM,2CAA2C;EAClF,IAAI,KAAK,UAAU,IAAI,GAAG,GAAG,MAAM,IAAI,MAAM,aAAa,MAAM;EAChE,KAAK,4BAAY,IAAI,IAAI,CAAC,GAAG,KAAK,WAAW,GAAG,CAAC;CAClD;CAEA,SAAe;EACd,IAAI,KAAK,YAAY,KAAK,QAAQ,KAAK,UAAU;EACjD,IAAI,KAAK,SAAS,MAAM,IAAI,MAAM,aAAa,OAAO;EACtD,KAAK,YAAY;CAClB;CAEA,QAAc;EACb,KAAK,UAAU;CAChB;CAEA,KAAK,QAAgB,OAA0C;EAC9D,KAAK,YAAY,IAAI,IAAI,CAAC,GAAG,KAAK,WAAW,CAAC,QAAQ,KAAK,CAAC,CAAC;CAC9D;CAEA,QAAQ,QAAyD;EAChE,OAAO,KAAK,UAAU,IAAI,MAAM;CACjC;AACD;;;;;;;;;;;AC1FA,IAAa,SAAb,MAA+C;CAC9C;CACA;CACA;CACA;CACA;CACA;CACA;CACA;CACA,4BAAqB,IAAI,IAAY;CACrC,+BAAwB,IAAI,IAAY;CACxC,2BAAoB,IAAI,IAAwB;CAChD,2BAAoB,IAAI,IAAwB;CAChD,wBAAiB,IAAI,IAAmB;CACxC,gCAAyB,IAAI,IAAiB;CAC9C;;;;;;;;CASA,YAAY,UAA6B,SAAwB;EAChE,KAAK,MAAM,OAAO;GAAC;GAAY;GAAS;GAAc;GAAU;EAAY,GAAY;GACvF,MAAM,QAAQ,QAAQ,WAAW;GACjC,IAAI,CAAC,WAAW,KAAK,GACpB,MAAM,IAAI,YAAY,aAAa,yCAAyC;EAC9E;EACA,KAAK,MAAM,SAAS,OAAO,OAAO,QAAQ,SAAS,CAAC,CAAC,GACpD,IAAI,CAAC,WAAW,KAAK,GAAG,MAAM,IAAI,YAAY,SAAS,qCAAqC;EAE7F,IAAI,CAAC,sBAAsB,QAAQ,QAAQ,GAC1C,MAAM,IAAI,YAAY,YAAY,0CAA0C;EAC7E,KAAK,WAAW,eAAe,QAAQ,SAAS,QAAQ,QAAQ;EAChE,KAAK,MAAM,SAAS,CAAC,QAAQ,QAAQ,OAAO,QAAQ,OAAO,KAAK,GAC/D,IAAI,UAAU,KAAA,KAAa,CAAC,yBAAyB,KAAK,GACzD,MAAM,IAAI,YAAY,SAAS,0CAA0C;EAI3E,MAAM,SAAS,MAAM,KAAK,QAAQ,SAAS,UAAU,MAAM,IAAI;EAC/D,IAAI,OAAO,MAAM,SAAS,KAAK,KAAK,MAAM,EAAE,KAAK,IAAI,IAAI,MAAM,CAAC,CAAC,SAAS,OAAO,QAChF,MAAM,IAAI,YAAY,SAAS,yCAAyC;EACzE,MAAM,UAAU,CAAC,UAAU,GAAG,MAAM,KAAK,QAAQ,WAAW,CAAC,IAAI,WAAW,OAAO,KAAK,IAAI,CAAC;EAC7F,IAAI,IAAI,IAAI,OAAO,CAAC,CAAC,SAAS,QAAQ,QACrC,MAAM,IAAI,YAAY,UAAU,kDAAkD;EACnF,KAAK,YAAY;EACjB,KAAK,UAAU,SAAS,UAAU;EAClC,KAAK,WAAW;EAChB,KAAK,SAAS;GAAE,GAAG;GAAsB,GAAG,QAAQ;EAAM;EAC1D,IAAI,QAAQ,UAAU,KAAA,GACrB,KAAK,SAAS,IAAI,MAAM;GACvB,GAAG,QAAQ;GACX,UAAU,QAAQ;GAClB,SAAS,KAAK;GACd,QAAQ,KAAK;EACd,CAAC;EACF,MAAM,gBAAgB,0BAA0B;EAChD,KAAK,gBAAgB,cAAc,IAAI;EACvC,cAAc,OAAO,KAAK,cAAc,EAAE;EAC1C,KAAK,cAAc,IAAI,WAAW;GACjC,cAAc,KAAK;GACnB,OAAO,QAAQ;GACf,WAAW,QAAQ;GACnB,YAAY,QAAQ;GACpB,QAAQ,QAAQ;GAChB,QAAQ,KAAK,QAAQ,KAAK,IAAI;GAC9B,WAAW,MAAM,YAChB,cAAc,gBAAgB,KAAK,aAAa,CAAC,GAAG,MAAM,OAAO;EACnE,CAAC;EACD,MAAM,QAAQ,kBAAkB;EAChC,KAAK,MAAM,UAAU,QAAQ,WAAW,CAAC,GACxC,MAAM,IACL,WAAW;GACV,MAAM,OAAO,KAAK;GAClB,GAAI,OAAO,KAAK,eAAe,KAAA,IAAY,CAAC,IAAI,EAAE,YAAY,OAAO,KAAK,WAAW;GACrF,GAAI,OAAO,KAAK,gBAAgB,KAAA,IAC7B,CAAC,IACD,EAAE,aAAa,OAAO,KAAK,YAAY;GAC1C,GAAI,OAAO,KAAK,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,OAAO,KAAK,QAAQ;GAC5E,GAAI,OAAO,KAAK,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,OAAO,KAAK,MAAM;GACtE,GAAI,OAAO,KAAK,gBAAgB,KAAA,IAC7B,CAAC,IACD,EAAE,aAAa,OAAO,KAAK,YAAY;GAC1C,UAAU,MAAM,YAAY,KAAK,QAAQ,OAAO,KAAK,MAAM,MAAM,OAAO;EACzE,CAAC,CACF;EAED,MAAM,IACL,WAAW;GACV,MAAM;GACN,aAAa,8GAA8G,iBAAiB,QAAQ,MAAM,EAAE;GAC5J,YAAY;IACX,MAAM;IACN,YAAY,EACX,OAAO;KAAE,MAAM;KAAU,aAAa;IAAwC,EAC/E;IACA,UAAU,CAAC,OAAO;GACnB;GACA,UAAU,SAAS,KAAK,QAAQ,IAAI;EACrC,CAAC,CACF;EACA,KAAK,SAAS,YAAY,UAAU;GACnC,GAAG,QAAQ;GACX;GACA,QAAQ,QAAQ;GAChB;GACA,OAAO,QAAQ,OAAO,SAAA;GACtB,QAAQ;GACR,SAAS,eAAe,SAAS,WAAW,KAAK,QAAQ,SAAS,MAAM;EACzE,CAAC;EACD,KAAK,OAAO,QAAQ,GAAG,SAAS,OAAO,WAAW;GACjD,KAAK,OAAO;GACZ,KAAK,SAAS,IAAI,KAAK,cAAc,SAAS,CAAC,CAAC,QAAQ,MAAM;GAC9D,IAAI,CAAC,OAAO,WAAW,OAAO,UAAU,aAAa,QAAQ;IAC5D,KAAK,SAAS,CAAC,EAAE,MAAM;IACvB,KAAK,OAAO,MAAM,QAAQ;GAC3B;EACD,CAAC;EACD,KAAK,OAAO,QAAQ,GAAG,WAAW,cAAc;GAC/C,IAAI,cAAc,UAAU,KAAK,KAAK,UAAU,MAAM,SAAS,WAAW;GAC1E,KAAK,SAAS,CAAC,EAAE,MAAM,WAAW,KAAK,cAAc,SAAS,CAAC,CAAC,MAAM;EACvE,CAAC;EACD,KAAK,OAAO,QAAQ,GAAG,cAAc,KAAK,aAAa,CAAC;EACxD,KAAK,OAAO,QAAQ,GAAG,UAAU,UAAU,KAAK,SAAS,CAAC,EAAE,MAAM,KAAK,CAAC;CACzE;;;;;CAMA,IAAI,QAAwB;EAC3B,OAAO,KAAK;CACb;;;;;CAKA,IAAI,eAAsC;EACzC,OAAO,KAAK;CACb;;;;;CAKA,IAAI,QAAiC;EACpC,OAAO,KAAK,WAAW,KAAA,IACpB,KAAA,IACA;GAAE,OAAO,KAAK,OAAO;GAAO,UAAU,KAAK,OAAO;EAAS;CAC/D;;;;;;;;CASA,MAAM,UAAU,QAA2C;EAC1D,IAAI,KAAK,MAAM,GAAG,MAAM,IAAI,WAAW,eAAe,oCAAoC;EAC1F,KAAK,cAAc,IAAI,MAAM;EAC7B,IAAI;GACH,OAAO,MAAM,KAAK,cAAc,MAAM;EACvC,UAAU;GACT,KAAK,cAAc,OAAO,MAAM;EACjC;CACD;;;;;;;;;;;;CAaA,MAAM,QAAQ,SAAiB,QAA6C;EAC3E,IAAI,KAAK,MAAM,GAAG,MAAM,IAAI,WAAW,eAAe,oCAAoC;EAE1F,MAAM,SADQ,YAAY,EAAE,GAAI,WAAW,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,EAAG,CACzD,CAAA,CAAM;EACrB,MAAM,UAAU,IAAI,cAAc,SAAS,KAAK,SAAS,QAAQ,KAAK;EACtE,KAAK,MAAM,IAAI,OAAO;EACtB,IAAI;GACH,IAAI,KAAK,WAAW,KAAA,GAAW,MAAM,KAAK,cAAc,MAAM;GAC9D,MAAM,UAAU,QAAQ,MAAM,KAAK,aAAa;GAChD,KAAK,UAAU,IAAI,QAAQ,EAAE;GAE7B,MAAM,QAAQ,MAAM,KAAK,cAAc,SAAS,QAAQ,KAAK,SAAS,KAAK,CAAC,CAAC,aACxD;IACnB,SAAS;IACT,SAAS;IACT,GAAI,QAAQ,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,OAAO,QAAQ,MAAM;GAC/D,EACD;GACA,MAAM,SAAS,CAAC,KAAK;GACrB,IAAI,CAAC,OAAO,YAAY,MAAM,WAAW,MAAM,QAAQ,KAAK,MAAM,KAAK;IACtE,MAAM,SAAS,KAAK,aAAa,SAAS,OAAO;IACjD,IAAI,WAAW,KAAA,GACd,KAAK,aAAa,IAAI,KAAK,cAAc,IAAI;KAAE,MAAM;KAAQ,SAAS;IAAO,CAAC,CAAC,CAAC,EAAE;IACnF,KAAK,aAAa,IACjB,KAAK,cAAc,IAAI;KAAE,MAAM;KAAQ,SAAS,aAAa;IAAI,CAAC,CAAC,CAAC,EACrE;IACA,MAAM,WAAW,KAAK,OAAO,QAAQ;IACrC,KAAK,OAAO,QAAQ,MACnB,YAAY;KACX,MAAM;KACN,OAAO,CAAC;KACR,QAAQ,OAAO,eAAe,SAAS,cAAc;MACpD,MAAM,YAAY,MAAM,KAAK,QAAQ,SAAS,SAAS;MACvD,IAAI,UAAU,UAAU,KAAA,GAAW,OAAO;MAC1C,OAAO;OACN,GAAG;OACH,UAAU,UAAU,SAAS,QAAQ,QAAQ,IAAI,SAAS,UAAU,CAAC,SAAS,GAAG,CAAC;MACnF;KACD;IACD,CAAC,CACF;IACA,IAAI;KACH,OAAO,KAAK,MAAM,KAAK,cAAc,SAAS,QAAQ,KAAK,CAAC;IAC7D,UAAU;KACT,KAAK,OAAO,QAAQ,MAAM,QAAQ;IACnC;GACD;GACA,MAAM,OAAO,OAAO,GAAG,EAAE,KAAK;GAC9B,QAAQ,MAAM,KAAK,cAAc,SAAS,CAAC;GAC3C,MAAM,QAAQ,QAAQ;GACtB,KAAK,QAAQ,QACZ,OACA,CAAC,KAAK,WAAW,KAAK,QAAQ,KAAK,MAAM,KAAK,MAAM,GAAG,EAAE,IAAI,KAAA,CAC9D;GACA,MAAM,QAAQ,OAAO,QACnB,OAAO,SAAU,KAAK,UAAU,KAAA,IAAY,QAAQ,SAAS,OAAO,KAAK,KAAK,GAC/E,KAAA,CACD;GAEA,MAAM,QAAQ,OAAO,SAAS,SAAU,KAAK,aAAa,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK,QAAQ,CAAE;GAC3F,OAAO;IACN,SAAS,KAAK;IACd,SAAS,KAAK;IACd;IACA,UAAU,QAAQ;IAClB,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;IACvC,GAAI,MAAM,WAAW,IAClB,CAAC,IACD,EAAE,UAAU,MAAM,QAAQ,SAAS,KAAK,SAAS,CAAC,CAAC,CAAC,KAAK,MAAM,EAAE;IACpE,GAAI,KAAK,SAAS,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM,KAAK,KAAK;GACtD;EACD,UAAU;GACT,KAAK,OAAO;GACZ,KAAK,MAAM,OAAO,OAAO;EAC1B;CACD;CAEA,MAAM,cAAc,QAA2C;EAC9D,IAAI;GACH,MAAM,WAAW,cAChB;IACC;KAAE,IAAI;KAAU,MAAM;KAAU,SAAS,KAAK,SAAS;IAAO;IAC9D,GAAG,KAAK,cAAc,KAAK;IAC3B;KAAE,IAAI;KAAe,MAAM;KAAQ,SAAS;IAAG;GAChD,GACA,KAAK,OACN,CAAC,CAAC,MAAM,GAAG,EAAE;GACb,MAAM,SAAS,MAAM,KAAK,UAAU,SACnC,UACA,QACA,KAAK,OAAO,QAAQ,MAAM,YAAY,GACtC,EAAE,OAAO,MAAM,CAChB;GACA,MAAM,OAAO,MAAM,KAAK,UAAU,SAAS,UAAU,QAAQ,KAAA,GAAW,EAAE,OAAO,MAAM,CAAC;GACxF,IACC,CAAC,eAAe,OAAO,OAAO,MAAM,KACpC,OAAO,MAAM,UAAU,KACvB,CAAC,eAAe,KAAK,OAAO,MAAM,KAClC,KAAK,MAAM,UAAU,GAErB,MAAM,IAAI,YAAY,SAAS,mDAAmD;GACnF,KAAK,SAAS,IAAI,MAAM;IACvB,UAAU,KAAK,SAAS;IACxB,SAAS,KAAK;IACd,QAAQ,KAAK;IACb,OAAO,KAAK,MAAM,SAAS,iBAAiB,QAAQ;IACpD,UAAU,KAAK,IAAI,GAAG,OAAO,MAAM,SAAS,KAAK,MAAM,MAAM;GAC9D,CAAC;GACD,OAAO;IAAE,OAAO,KAAK,OAAO;IAAO,UAAU,KAAK,OAAO;GAAS;EACnE,SAAS,OAAO;GACf,OAAO,eAAe;GACtB,MAAM;EACP;CACD;CAEA,MAAM,cACL,SACA,QACA,OACuB;EACvB,QAAQ,KAAK,KAAK,cAAc,SAAS,CAAC,CAAC,MAAM;EACjD,OAAO,MAAM,KAAK,OAAO,SAAS;GAAE;GAAQ,GAAI,UAAU,KAAA,IAAY,CAAC,IAAI,EAAE,MAAM;EAAG,CAAC;CACxF;CAIA,WAAsC;EACrC,MAAM,CAAC,WAAW,KAAK;EACvB,OAAO,SAAS,YAAY,KAAA,IAAY,KAAA,IAAY;CACrD;CAEA,QAAiB;EAChB,OAAO,KAAK,MAAM,OAAO,KAAK,KAAK,cAAc,OAAO;CACzD;CAEA,SAAe;EAEd,IAAI,KAAK,SAAS,SAAS,GAAG;EAC9B,MAAM,WAAW,KAAK,cAAc,SAAS;EAC7C,KAAK,MAAM,CAAC,IAAI,WAAW,KAAK,UAAU;GACzC,MAAM,UAAU,SAAS;GACzB,IAAI,SAAS,SAAS,QAAQ;IAC7B,KAAK,SAAS,IAAI,QAAQ,IAAI,MAAM;IACpC,KAAK,SAAS,OAAO,EAAE;GACxB;EACD;CACD;CAEA,QAAQ,SAA8C;EACrD,KAAK,OAAO;EACZ,IAAI,KAAK,aAAa,IAAI,QAAQ,EAAE,GAAG,OAAO;EAC9C,IAAI,QAAQ,SAAS,QAAQ;GAC5B,KAAK,aAAa;GAClB,OAAO,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,YAAY,QAAQ,YAAY;EACvE;EACA,IAAI,QAAQ,SAAS,aAAa,OAAO,KAAA;EACzC,IAAI,SAAS,OAAO,GAAG,OAAO;EAC9B,MAAM,WAAW,KAAK,cAAc,SAAS;EAC7C,MAAM,QAAQ,SAAS,WAAW,QAAQ,KAAK,UAAU,IAAI,IAAI,EAAE,CAAC;EACpE,OAAO,SAAS,KAAK,SAAS,WAAW,QAAQ,IAAI,OAAO,QAAQ,EAAE,IAAI,QACvE,YACA,KAAA;CACJ;CAEA,eAA+C;EAC9C,KAAK,OAAO;EACZ,OAAO,kBAAkB,KAAK,cAAc,SAAS,CAAC,CAAC,CAAC,SAAS,UAChE,MAAM,MAAM,CAAC,CAAC,CAAC,SAAS,YAAmC;GAC1D,MAAM,OAAO,eAAe,OAAO,OAAO;GAC1C,MAAM,SAAS,KAAK,SAAS,SAAS,MAAM,QAAQ,IAAI,KAAK,SAAS,MAAM,IAAI;GAChF,IACC,SAAS,KAAA,KACT,WAAW,KAAA,KACX,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,YAAY,OAE3C,OAAO,CAAC;GACT,MAAM,UAAU,cAAc,OAAO,KAAK,KAAK,WAAW,QAAQ,OAAO,CAAC;GAC1E,IAAI,CAAC,QAAQ,SAAS;IAErB,KAAK,SAAS,IAAI,QAAQ,IAAI;KAC7B,SAAS;KACT,IAAI,KAAK;KACT,MAAM,KAAK;KACX,OAAO,QAAQ,QAAQ,KAAK,IAAI,QAAQ,MAAM,UAAU,OAAO,QAAQ,KAAK;IAC7E,CAAC;IACD,OAAO,CAAC;GACT;GACA,MAAM,SAAS,QAAQ;GACvB,OAAO,CACN;IACC,IAAI,QAAQ;IACZ,MAAM,KAAK;IACX,WAAW,KAAK;IAChB,MAAM,QAAQ;IACd,QACC,WAAW,KAAA,IACR,KAAA,IACA;KACA,GAAG;KACH,KAAK,CACJ,mBAAG,IAAI,IAAI,CACV,GAAG,OAAO,KACV,GAAG,OAAO,OAAO,KAAK,SAAS,CAAC,CAC9B,OAAO,QAAQ,CAAC,CAChB,SAAS,UAAU,CAAC,GAAG,cAAc,KAAK,CAAC,CAAC,GAAG,CAAC,CACnD,CAAC,CACF;IACD;GACJ,CACD;EACD,CAAC,CACF;CACD;CAEA,WAA6F;EAC5F,MAAM,WAAW,KAAK,aAAa;EACnC,MAAM,WAAW,gBAAgB,QAAQ;EACzC,MAAM,WAAW,KAAK,cAAc,SAAS;EAC7C,MAAM,QAA+B;GACpC,QAAQ,KAAK,SAAS;GACtB,YAAY,CAAC,GAAG,KAAK,WAAW,GAAG,KAAK,YAAY;GACpD,QAAQ,SAAS;GACjB;GACA;GACA,UAAU,IAAI,IACb,SAAS,KAAK,YAAY,CACzB,QAAQ,IACR,CAAC,GAAG,cAAc,UAAU,QAAQ,SAAS,IAAI,CAAC,CACnD,CAAC,CACF;GACA,gBAAgB,KAAK,YAAY,eAAe;EACjD;EACA,OAAO;GAAE;GAAO,YAAY,aAAa,KAAK;EAAE;CACjD;CAEA,cAAc,OAA8B,IAAY;EACvD,OAAO,WACN,OACA,IAAI,IAAI,MAAM,SAAS,KAAK,YAAY,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC,GAC9D,IACA,CAAC,GAAG,MAAM,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,GAChC,aAAa,KAAK,SAAS,MAAM,CAClC;CACD;CAEA,cAAc,IAAY,OAA8B,SAAsC;EAC7F,MAAM,UAAU,KAAK,cAAc,QAAQ,EAAE;EAC7C,IAAI,YAAY,KAAA,GAAW,OAAO;EAClC,MAAM,YAAY,eAAe,QAAQ,OAAO;EAChD,MAAM,OAAO,UAAU,OAAO,GAAG,UAAU,MAAM,MAAM,SAAS,KAAK,aAAa,KAAK,CAAC,IACrF,QAAQ,UACR,MAAM,KAAK,SAAS,UAAU,KAAK,aAAa,EAAE,CAAC,CAAC,KAAK,GAAG;EAC/D,IAAI,SAAS,IAAI,OAAO;EACxB,MAAM,UAAU,KAAK,aAAa,CAAC,CAAC,MAAM,QAAQ,IAAI,OAAO,EAAE;EAC/D,OAAO,CACN,GAAG,MAAM,KAAK,SAAS,uBAAuB,MAAM,OAAO,CAAC,GAC5D,QAAQ,SAAS,UAAU,YAAY,KAAA,IACpC,OACA,GAAG,iBAAiB,QAAQ,MAAM,QAAQ,SAAS,EAAE,IAAI,MAC7D,CAAC,CACC,QAAQ,SAAS,SAAS,EAAE,CAAC,CAC7B,KAAK,IAAI;CACZ;CAEA,cAAc,SAAsC;EACnD,MAAM,WAAW,KAAK,cAAc,SAAS;EAC7C,MAAM,QAAQ,SAAS,WAAW,YAAY,QAAQ,OAAO,QAAQ,EAAE;EACvE,OAAO,SACL,MAAM,QAAQ,CAAC,CAAC,CAChB,QACC,YACA,QAAQ,SAAS,eAAe,SAAS,OAAO,KAAK,QAAQ,QAAQ,KAAK,MAAM,EAClF;CACF;CAEA,MAAM,QAAQ,SAAkB,QAAyC;EACxE,MAAM,UAAU,KAAK,SAAS;EAC9B,MAAM,WAAW,SAAS;EAC1B,IACC,YAAY,KAAA,KACZ,aAAa,KAAA,KACZ,QAAQ,OAAO,SAAS,MAAM,CAAC,KAAK,aAAa,IAAI,QAAQ,EAAE,GAEhE,OAAO,KAAK,QACX,IAAI,YACH,WACA,qEACD,GACA,EAAE,WAAW,CAAC,EAAE,CACjB;EACD,MAAM,OAAO,QAAQ;EACrB,IAAI,KAAK,aAAa,IAAI,QAAQ,EAAE,KAAK,SAAS,KAAA,GACjD,OAAO;GACN,UAAU,CAAC,GAAG,KAAK,UAAU,GAAG,KAAK,cAAc,QAAQ,CAAC;GAC5D,WAAW,CAAC;GACZ,GAAI,KAAK,aAAa,KAAA,IAAY,CAAC,IAAI,EAAE,UAAU,KAAK,SAAS;EAClE;EACD,OAAO,MAAM,KAAK,YAAY,SAAS,KAAK,WAAW,MAAM,CAAC,CAAC,MAC7D,eAAe,KAAK,MAAM,YAAY,SAAS,UAAU,OAAO,IAChE,UAAmB,KAAK,QAAQ,OAAO,EAAE,WAAW,CAAC,EAAE,CAAC,CAC1D;CACD;CAIA,MACC,YACA,SACA,UACA,SACY;EACZ,MAAM,EAAE,UAAU,GAAG,UAAU;EAC/B,MAAM,UAAU,cAAc;GAC7B,IAAI,MAAM,UAAU,KAAA,GAAW,MAAM,MAAM;GAC3C,OAAO;IAAE,GAAG,KAAK,MAAM,QAAQ;IAAG,GAAG;GAAM;EAC5C,CAAC;EACD,QAAQ,KAAK,UAAU,QAAQ,UAAU,QAAQ,QAAQ,KAAA,CAAS;EAClE,IAAI,CAAC,QAAQ,SAAS,OAAO,KAAK,QAAQ,QAAQ,OAAO,KAAK;EAC9D,OAAO,KAAK,aAAa,IAAI,QAAQ,EAAE,IACpC;GACA,GAAG,QAAQ;GACX,UAAU,CAAC,GAAG,QAAQ,MAAM,UAAU,GAAG,KAAK,cAAc,QAAQ,CAAC;EACtE,IACC,QAAQ;CACZ;CAIA,QAAQ,OAAgB,QAAuD;EAC9E,OAAO;GACN,GAAG;GACH,UAAU,KAAK,cAAc,KAAK;GAClC,OAAO,QAAQ,KAAK,IAAI,QAAQ,IAAI,MAAM,OAAO,KAAK,CAAC;EACxD;CACD;CAEA,OAAO,UAAsC;EAC5C,QAAQ,KAAK,QAAQ,SAAS,KAAK,iBAAiB,QAAQ;CAC7D;CAEA,MAAM,SAA4D;EACjE,MAAM,EAAE,OAAO,eAAe,KAAK,SAAS;EAC5C,MAAM,WAAW,gBAAgB,MAAM,QAAQ;EAC/C,MAAM,QAAQ,WAAW,MAAM,UAAU,SAAS,MAAM;EACxD,MAAM,uBAAO,IAAI,IAAI,CACpB,GAAG,cAAc,UAAU,QAAQ,SAAS,IAAI,GAChD,GAAG,KAAK,YAAY,OAAO,QAAQ,EAAE,CACtC,CAAC;EAKD,MAAM,UAAU,cAAc,YAAY;GAAE,QAJ7B,CAAC,GAAG,IAAI,CAAC,CAAC,SAAS,OAAO;IACxC,MAAM,QAAQ,SAAS,OAAO,IAAI,EAAE,IAAI,KAAK,MAAM,IAAI,EAAE;IACzD,OAAO,UAAU,KAAA,IAAY,CAAC,IAAI,CAAC,KAAK;GACzC,CAC4C;GAAQ,QAAQ,CAAC,GAAG,IAAI;EAAE,CAAC;EACvE,MAAM,QACL,KAAK,IACJ,IACC,KAAK,SAAS,WAAW,KAAK,YAAY,KAAK,OAAO,UACrD,KAAK,QAAQ,YAAY,EAC5B,KACC,IAAI;EACN,MAAM,OAAO,KAAK,YAAY,SAAS,QAAQ,KAAK,OAAO,MAAM,KAAK;EACtE,MAAM,MAAM,QAAQ,KAAK,OAAO,cAAc,MAAM,KAAK,OAAO,CAAC;EACjE,MAAM,UAAU,IAAI,IAAI,KAAK,KAAK,YAAY,QAAQ,EAAE,CAAC;EACzD,MAAM,SAAS,QAAQ,MAAM,WAAW,OAAO,QAAQ,gBAAgB;EACvE,MAAM,uBAAO,IAAI,IAAI,CACpB,GAAG,WAAW,QACZ,QAAQ,WAAW,UAAU,OAAO,QAAA,OAAwB,CAAC,CAC7D,SAAS,WAAW,OAAO,OAAO,GACpC,GAAI,QAAQ,SAAS,IAClB,WAAW,QAAQ,SAAS,WAC5B,OAAO,QAAQ,QACb,OACA,KAAK,cAAc,QAAQ,EAAE,CAAC,EAAE,SAAS,UACzC,KAAK,YAAY,SAAS,EAAE,MAAM,UAClC,KAAK,YAAY,SAAS,EAAE,CAC9B,CACD,IACC,CAAC,CACL,CAAC;EACD,MAAM,QAAQ,MAAM,SAClB,QAAQ,YAAY,CAAC,SAAS,OAAO,CAAC,CAAC,CACvC,KAAK,aAAa;GAClB;GACA,GAAG,aAAa,OAAO;EACxB,EAAE;EACH,MAAM,QAAQ,MAAM,MAAM,EAAE,cAAc,QAAQ,OAAO,QAAQ,EAAE;EACnE,MAAM,SAAS,IAAI,IAClB,CACC,GAAG,IAAI,QACN,MAAM,SAAS,SAAS,CAAC,GAAG,KAAK,KAAK,CAAC,IACtC,SAAS,IACX,CACD,CAAC,CAAC,KAAK,CAAC,MAAM,iBAAiB,CAAC,MAAM,YAAY,MAAM,CAAC,CAC1D;EACA,MAAM,OAAO,qBAAqB,UAAU;EA2C5C,MAAM,UAAU,CAAC,GA1CH,MAAM,SAAS,EAAE,SAAS,OAAO,SAAS,aAAa;GACpE,IACC,CAAC,KAAK,IAAI,QAAQ,EAAE,KACpB,KAAK,IAAI,QAAQ,EAAE,KAClB,QAAQ,SAAS,UAAU,QAAQ,IAAI,QAAQ,EAAE,GAElD,OAAO,CAAC;GACT,MAAM,SAAS,cAAc,QAAQ,OAAO;GAC5C,IAAI,QAAQ,SAAS,UAAU,OAAO,IAAI,OAAO,OAAO,QAAQ,OAAO,MAAM,SAAS,GACrF,OAAO,CAAC;GACT,MAAM,WAAW,KAAK,YAAY,SAAS,QAAQ,EAAE;GACrD,MAAM,YAAY,QAAQ,SAAS,UAAU,CAAC,KAAK,YAAY,SAAS,QAAQ,EAAE;GAClF,MAAM,yBAAS,IAAI,IAAI,CACtB,GAAI,MAAM,SAAS,IAAI,QAAQ,EAAE,KAAK,CAAC,GACvC,GAAG,KAAK,YAAY,OAAO,QAAQ,EAAE,CACtC,CAAC;GACD,MAAM,QAAQ,CAAC,cAAc,aAAa,UAAU,aAAa;GACjE,MAAM,QAAQ,CAAC,GAAG,MAAM,CAAC,CAAC,MAAM,UAAU,KAAK,IAAI,KAAK,CAAC,IACtD,IACA,QACC,IACA,CAAC,GAAG,KAAK,CAAC,CAAC,MAAM,SAAS,OAAO,MAAM,IAAI,IAAI,CAAC,IAC/C,IACA;GACL,IAAI,UAAU,GAAG,OAAO,CAAC;GACzB,MAAM,QAAQ,CAAC,GAAG,KAAK,CAAC,CACtB,QAAQ,SAAS,OAAO,MAAM,IAAI,IAAI,CAAC,CAAC,CACxC,QAAQ,KAAK,SAAS,MAAM,KAAK,IAAI,MAAM,UAAU,OAAO,IAAI,IAAI,KAAK,EAAE,GAAG,CAAC;GACjF,OAAO,CACN;IACC,QAAQ,QAAQ;IAChB,OAAO,KAAK,cAAc,OAAO,QAAQ,EAAE;IAC3C;IACA;IACA;IACW;IACX;IACA;IACA,KAAK,cAAc,OAAO,WAAW,QAAQ;GAC9C,CACD;EACD,CACoB,CAAK,CAAC,CAAC,MACzB,MAAM,UACN,KAAK,QAAQ,MAAM,UAClB,KAAK,UAAU,IAAI,OAAO,KAAK,SAAS,IAAI,OAAO,MAAM,SAAS,IAAI,OACrE,KAAK,UAAU,KAAK,KAAK,aAAc,KAAK,UAAU,IAAI,MAAM,QAAQ,KAAK,QAAQ,MACvF,KAAK,WAAW,MAAM,QACxB;EACA,MAAM,OAAO,CAAC,GAAG,OAAO,CAAC,CAAC,MACxB,MAAM,UACN,KAAK,MAAM,MAAM,QAChB,KAAK,QAAQ,KAAK,KAAK,QAAQ,KAAK,KAAK,QAAQ,IAAI,KAAK,QAAQ,MAAM,QAAQ,MACjF,MAAM,WAAW,KAAK,QACxB;EACA,MAAM,QAAQ,QAAQ,MAAM,WAAW,OAAO,QAAQ,gBAAgB;EACtE,MAAM,QAAQ;GACb,GAAI,OAAO,MACT,QAAQ,SAAS,CAAC,KAAK,OAAO,MAAM,UAAU,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAC/D,WAAW;IAAE,KAAK,MAAM;IAAK,QAAQ,KAAA;GAAU,EAAE,KAAK,CAAC;GACzD,GAAG,KAAK,KAAK,UAAU;IAAE,KAAK,KAAA;IAAW,QAAQ,KAAK;GAAO,EAAE;GAC/D,GAAI,OAAO,MACT,QAAQ,SAAS,KAAK,OAAO,MAAM,UAAU,KAAK,IAAI,KAAK,CAAC,CAAC,CAAC,CAC9D,WAAW;IAAE,KAAK,MAAM;IAAK,QAAQ,KAAA;GAAU,EAAE,KAAK,CAAC;GACzD,GAAG,QACD,QAAQ,WAAW,OAAO,QAAQ,gBAAgB,CAAC,CACnD,SAAS,WAAW,OAAO,MAAM,WAAW;IAAE,KAAK,OAAO;IAAK,QAAQ,KAAA;GAAU,EAAE,CAAC,CAAC,CACrF,QAAQ;EACX;EACA,MAAM,SAAS,QAAQ,KAAK,UAAU;GACrC,QAAQ,KAAK;GACb,QAAQ,KAAK,iBAAiB,KAAK,QAAQ,KAAK,UAAU,OAAO,YAAY,IAAI;EAClF,EAAE;EACF,MAAM,UAAU,KAAK,MACpB,OACA,SACA,QACA,IAAI,IAAI,QAAQ,KAAK,SAAS,KAAK,MAAM,CAAC,GAC1C,KACA,WAAW,UACZ;EACA,MAAM,WAAW,QAAQ;EACzB,MAAM,wBAAQ,IAAI,IAAI,CACrB,GAAG,QAAQ,UACX,GAAG,QAAQ,SAAS,WACnB,OAAO,QAAQ,QAAQ,WAAW;GACjC,MAAM,OAAO,OAAO,MAAM,QAAQ,SAAS,KAAK,WAAW,MAAM;GACjE,MAAM,UACL,QAAQ,QACN,MAAM,QAAQ,IAAI,QAAQ,OAAO,GAAG,CAAC,EACpC,MAAM,QAAQ,SAAS,KAAK,WAAW,MAAM,KAAK,CAAC;GACvD,OAAO,KAAK,SAAS,KAAK,KAAK,WAAW,QAAQ;EACnD,CAAC,CACF,CACD,CAAC;EACD,OAAO;GACN,UAAU,KAAK,KAAK,YACnB,QAAQ,SAAS,SAAS,KAAK,gBAAgB,SAAS,KAAK,IAAI,OAClE;GACA,GAAI,aAAa,KAAK,CAAC,IAAI,EAAE,SAAS;EACvC;CACD;CAKA,MACC,OACA,SACA,QACA,UACA,KACA,YAKC;EACD,MAAM,UAAU,MAAM,QAKpB,KAAK,SAAS;GACd,IAAI,IAAI,aAAa,KAAA,GAAW,OAAO;GACvC,MAAM,WAAW,KAAK,QAAQ,IAAI,SAAS,QAAQ,IAAI,UAAU,UAAU;GAC3E,MAAM,UAAU,CAAC,KAAK,SAAS,QAAQ,QAAQ,CAAC,CAAC,QAAQ,SAAS,SAAS,EAAE,CAAC,CAAC,KAAK,MAAM;GAC1F,IAAI,KAAK,OAAO,CAAC;IAAE,IAAI;IAAU,MAAM;IAAU;GAAQ,CAAC,CAAC,KAAK,KAC/D,OAAO;IAAE,GAAG;IAAK;GAAS;GAC3B,OAAO;IACN,UAAU,KAAA;IACV,SAAS,IAAI,QAAQ,KAAK,WACzB,OAAO,QAAQ,KAAK,MAAM;KAAE,GAAG;KAAQ,OAAO,OAAO,MAAM,MAAM,GAAG,EAAE;IAAE,IAAI,MAC7E;IACA,UAAU,IAAI,IAAI,CAAC,GAAG,IAAI,QAAQ,CAAC,CAAC,QAAQ,WAAW,WAAW,KAAK,MAAM,CAAC;GAC/E;EACD,GACA;GAAE,UAAU,KAAA;GAAW;GAAS;EAAS,CAC1C;EACA,OAAO;GACN,SAAS,QAAQ;GACjB,UAAU,QAAQ;GAClB,UACC,QAAQ,YAAY,KAAK,QAAQ,QAAQ,SAAS,QAAQ,QAAQ,UAAU,UAAU;EACxF;CACD;CAEA,iBACC,QACA,UACA,OACA,YACA,MACe;EACf,OAAO;GACN,KAAK,aAAa,SAAS,mBAAmB;GAC9C,OAAO;GACP,SAAS,CAAC,MAAM;GAChB,OAAO,KAAK,gBACX,OACA,YACA,QACA,aAAa,SACV,IAAI,IAAI,WAAW,QAAQ,SAAS,WAAW,OAAO,OAAO,CAAC,IAC9D,IACJ;EACD;CACD;CAEA,gBACC,OACA,YACA,QACA,MACwB;EACxB,MAAM,OAAO,qBAAqB,UAAU;EAC5C,OAAO,eACN,MAAM,eAAe,YACrB,SACC,OAAO,OAAO,UAAW,CAAC,KAAK,IAAI,EAAE,KAAK,KAAK,IAAI,EAAE,CACvD,CAAC,CAAC,SAAS,OAAO,KAAK,cAAc,OAAO,EAAE,CAAC;CAChD;CAEA,QACC,SACA,QACA,UACA,YACS;EACT,MAAM,UAAU,OACd,QAAQ,SAAS,SAAS,IAAI,KAAK,MAAM,CAAC,CAAC,CAC3C,SAAS,EAAE,QAAQ,WACnB,CAAC,GAAG,IAAI,QAAQ,KAAK,QAAQ,SAAS,KAAK,MAAM,CAAC,CAAC,CAAC,KAAK,CAAC,QAAQ,YAAY;GAC7E;GACA;GACA;EACD,EAAE,CACH;EAED,MAAM,QAAQ,IAAI,IAAI,QAAQ,WAAW,CAAC,CAAC,KAAK,UAAU,CAAC,MAAM,QAAQ,KAAK,CAAC,CAAC;EAChF,MAAM,SAAS,QAAQ,QAAQ,UAAU,MAAM,IAAI,MAAM,MAAM,MAAM,KAAK;EAC1E,MAAM,SAAS,QAAQ,MACrB,cAAc,UAAU,QAAA,WAA4B,UAAU,MAAM,SAAS,CAC/E;EACA,MAAM,eAAe,QAAQ,QAC3B,cAAc,UAAU,QAAA,WAA4B,UAAU,MAAM,SAAS,CAC/E;EAGA,MAAM,UAAU,yBACf,KAAK,cAAc,SAAS,GAC5B;GACC,GAAG,aAAa,SAAS,cAAc,UAAU,KAAK;GACtD,GAAG,OACD,QAAQ,UAAU,MAAM,KAAK,QAAQ,gBAAgB,CAAC,CACtD,SAAS,UAAU,MAAM,KAAK;GAChC,GAAI,QAAQ,SAAS,CAAC;GACtB,GAAG,OACD,QAAQ,UAAU,MAAM,KAAK,QAAQ,gBAAgB,CAAC,CACtD,SAAS,UAAU,MAAM,KAAK;EACjC,GACA,UACD;EACA,MAAM,SAAS,aAAa,KAAK,UAAU,mBAAmB,OAAO,OAAO,CAAC,CAAC,CAAC,KAAK,MAAM;EAC1F,MAAM,WAAW,OAAO,KAAK,EAAE,MAAM,QAAQ,aAAa;GACzD,OAAO,KAAK,QAAQ;GACpB,OACC,KAAK,QAAA,WAA4B,WAAW,KAAK,QAAQ,KACtD,MAAM,KAAK,SAAS,KAAK,cAAc,QAAQ,CAAC,IAAI,GAAG,OAAO,CAAC,IAC/D,CAAC,KAAK,cAAc,QAAQ,OAAO,OAAO,CAAC;EAChD,EAAE;EACF,MAAM,SAAS,SAAS,QAAQ,QAAQ,CAAC,IAAI,KAAK,CAAC,CAAC,SAAS,QAAQ,IAAI,KAAK;EAC9E,MAAM,QAAQ,SAAS,QAAQ,QAAQ,IAAI,KAAK,CAAC,CAAC,SAAS,QAAQ,IAAI,KAAK;EAC5E,MAAM,OAAO,CAAC,QAAQ,OAAO,KAAK,IAAI,CAAC,CAAC,CAAC,QAAQ,SAAS,SAAS,EAAE,CAAC,CAAC,KAAK,MAAM;EAClF,OAAO,CACN,SAAS,KAAK,KAAK,cAAc,QACjC,WAAW,KAAA,IACR,MAAM,WAAW,IAChB,KACA,CAAC,YAAY,GAAG,KAAK,CAAC,CAAC,KAAK,IAAI,IACjC,CAAC,mBAAmB,QAAQ,OAAO,GAAG,GAAG,KAAK,CAAC,CAAC,KAAK,IAAI,CAC7D,CAAC,CACC,QAAQ,SAAS,SAAS,EAAE,CAAC,CAC7B,KAAK,MAAM;CACd;CAEA,YAAY,SAAkB,KAAa,OAAkD;EAC5F,MAAM,QAAQ,MAAM,SAAS,WAAW,YAAY,KAAK,UAAU,IAAI,QAAQ,EAAE,CAAC;EAClF,MAAM,OAAO,MAAM,SAAS,MAC3B,GACA,QAAQ,IAAI,MAAM,SAAS,WAAW,YAAY,QAAQ,OAAO,QAAQ,EAAE,IAAI,KAChF;EACA,MAAM,SAAS,kBAAkB,IAAI,CAAC,CAAC,SAAS,UAAU;GACzD,MAAM,SAAS,MAAM;GACrB,IAAI,WAAW,KAAA,GAAW,OAAO,CAAC;GAUlC,OAAO,CAAC;IAAE;IAAQ,OATJ,OAAO,SAAS,CAAC,EAAA,CAAG,SAAS,SAAS;KACnD,MAAM,UAAU,MAAM,MAAM,CAAC,CAAC,CAAC,MAAM,WAAW,eAAe,OAAO,MAAM,MAAM,IAAI;KACtF,MAAM,SAAS,YAAY,KAAA,IAAY,KAAA,IAAY,KAAK,SAAS,IAAI,QAAQ,EAAE;KAC/E,OAAO,YAAY,KAAA,KAClB,CAAC,KAAK,SAAS,SAAS,MAAM,WAAW,OAAO,KAAK,SAAS,KAAK,IAAI,KACtE,QAAQ,YAAY,SAAS,OAAO,UAAU,aAAa,SAC1D,CAAC,IACD,CAAC;MAAE;MAAM;KAAQ,CAAC;IACtB,CACkB;GAAK,CAAC;EACzB,CAAC;EACD,MAAM,QAAQ,IAAI,IACjB,OAAO,KAAK,EAAE,QAAQ,WAAW,CAAC,OAAO,IAAI,KAAK,KAAK,EAAE,WAAW,IAAI,CAAC,CAAC,CAC3E;EACA,MAAM,UAAU,IAAI,IAAI,OAAO,SAAS,EAAE,WAAW,KAAK,KAAK,EAAE,cAAc,QAAQ,EAAE,CAAC,CAAC;EAwB3F,MAAM,YAAY,iBAvBF,KACd,QACC,YACA,CAAC,KAAK,aAAa,IAAI,QAAQ,EAAE,MAChC,QAAQ,SAAS,UAAU,QAAQ,IAAI,QAAQ,EAAE,MAClD,EACC,QAAQ,SAAS,eACjB,SAAS,OAAO,MACf,MAAM,IAAI,QAAQ,EAAE,CAAC,EAAE,UAAU,OAAO,KACzC,QAAQ,YAAY,GAEvB,CAAC,CACA,KAAK,YACL,QAAQ,SAAS,SACd,KAAK,gBAAgB,OAAO,IAC5B,MAAM,IAAI,QAAQ,EAAE,KAClB,MAAM,IAAI,QAAQ,EAAE,CAAC,EAAE,UAAU,KAAK,IACtC;GAAE,GAAG;GAAS,OAAO,MAAM,IAAI,QAAQ,EAAE,KAAK,CAAC;EAAE,IACjD;GAAE,IAAI,QAAQ;GAAI,MAAM,QAAQ;GAAM,SAAS,QAAQ;EAAQ,IAChE,OAI6B,CAAO,CAAC,CAAC,WAAW;EACvD,MAAM,OAAO,UAAU,WACrB,WAAW,UACX,KAAK,OACJ,cACC,CACC,GAAG,UACD,MAAM,GAAG,QAAQ,CAAC,CAAC,CACnB,WAAW,CAAC,CACZ,KAAK,GACP,OACD,GACA,KAAK,OACN,CACD,IAAI,GACN;EACA,OAAO,CACN,GAAG,UACD,MAAM,GAAG,SAAS,KAAK,UAAU,SAAS,IAAI,CAAC,CAC/C,WAAW,CAAC,CACZ,KAAK,GACP,OACD;CACD;CAEA,gBAAgB,SAAkB,OAAsC;EACvE,MAAM,QAAQ,kBAAkB,KAAK,cAAc,SAAS,CAAC,CAAC,CAAC,MAAM,YACpE,QAAQ,MAAM,QAAQ,IAAI,OAAO,QAAQ,EAAE,CAC5C;EACA,MAAM,OAAO,UAAU,KAAA,IAAY,KAAA,IAAY,eAAe,OAAO,OAAO;EAC5E,MAAM,UAAU,KAAK,aAAa,CAAC,CAAC,MAAM,QAAQ,IAAI,OAAO,QAAQ,EAAE;EACvE,MAAM,SAAS,WAAW,MAAM,QAAQ,QAAQ,MAAM,aAAa,CAAC,GAAG,QAAQ;EAC/E,MAAM,UAAU,WAAW,MAAM,QAAQ,QAAQ,MAAM,aAAa,CAAC,GAAG,OAAO;EAC/E,OAAO;GACN,GAAG;GACH,SAAS,WACR,MAAM,QAAQ,QACd,MAAM,aAAa,CAAC,GACpB,KAAK,SAAS,IAAI,QAAQ,EAAE,CAAC,EAAE,YAAY,QACxC,WACA,SAAS,WAAW,KAAA,IACnB,UACA,UAAU,KAAA,IACT,OAAO,SAAS,QAAQ,SACvB,WACA,UACD,MAAM,IAAI,QAAQ,EAAE,IACnB,UACA,QACP;EACD;CACD;CAEA,eAAqB;EACpB,KAAK,OAAO;EACZ,MAAM,UAAU,KAAK,SAAS;EAC9B,MAAM,WAAW,SAAS;EAC1B,IAAI,YAAY,KAAA,KAAa,aAAa,KAAA,GAAW;EACrD,MAAM,YAAY,KAAK,cAAc,SAAS,CAAC,CAAC,MAAM,QAAQ;EAC9D,MAAM,WAAW,KAAK,OAAO,QAAQ,MAAM,QAAQ,SAAS;EAC5D,MAAM,QAAQ,KAAK,OAAO,QAAQ,OAAO;EACzC,QAAQ,QACP;GACC,UAAU,iBAAiB,cAAc,CAAC,GAAG,UAAU,GAAG,SAAS,GAAG,KAAK,OAAO,CAAC;GACnF,OAAO,KAAK,OAAO,QAAQ,MACzB,YAAY,CAAC,CACb,QAAQ,SAAS,UAAU,KAAA,KAAa,MAAM,SAAS,KAAK,IAAI,CAAC,CAAC,CAAC;EACtE,GACA,KAAK,cAAc,SAAS,CAAC,CAAC,MAC/B;CACD;CAEA,eAAuB;EACtB,OAAO,KAAK,cACV,SAAS,CAAC,CACV,QAAQ,YAAY,QAAQ,SAAS,WAAW,CAAC,CACjD,QACC,SAAS,YAAa,QAAQ,QAAQ,SAAS,QAAQ,SAAS,QAAQ,UAAU,SACnF,EACD;CACF;CAEA,QAAQ,MAAc,MAAyC,SAA+B;EAC7F,KAAK,SAAS,CAAC,EAAE,MAAM,MAAM,IAAI;EACjC,MAAM,SAAS,KAAK,SAAS,SAAS,MAAM,QAAQ,IAAI,KAAK,SAAS,IAAI;EAC1E,IAAI,WAAW,KAAA,GAAW,MAAM,IAAI,MAAM,kBAAkB,MAAM;EAClE,OAAO,OAAO,KAAK,QAAQ,MAAM,OAAO;CACzC;CAEA,QAAQ,MAAiD;EACxD,MAAM,UAAU,KAAK,SAAS;EAC9B,SAAS,MAAM,KAAK,cAAc,SAAS,CAAC;EAC5C,MAAM,QAAQ,SAAS,KAAK,KAAK,IAAI,KAAK,MAAM,KAAK,IAAI;EACzD,SAAS,MAAM,UAAU,EAAE,MAAM,CAAC;EAClC,MAAM,QAAQ,KAAK;EACnB,MAAM,QAAQ,SAAS,SAAS,CAAC;EACjC,IACC,UAAU,KAAA,KACV,MAAM,SAAS,KACf,MAAM,UAAU,KAAK,IAAI,KAAK,WAAW,IAAI,MAAM,QAAQ,OAAO,KAAK,aAAa,CAAC,GAErF,SAAS,MAAM;EAChB,SAAS,OAAO;EAChB,MAAM,WAAW,mCAAmC,iBAAiB,KAAK,SAAS,MAAM;EACzF,IAAI,UAAU,IAAI,MAAM,IAAI,MAAM,yBAAyB,UAAU;EACrE,MAAM,QACJ,OAAO,KAAK,OAAO,KAAK,aAAa,CAAC,KAAK,KAAK,iBAAiB,CAAC,mBAAmB,KAAK,CAAC,CAAC;EAC9F,MAAM,EAAE,OAAO,eAAe,KAAK,SAAS;EAC5C,MAAM,WAAW,gBAAgB,MAAM,QAAQ;EAC/C,MAAM,WAAW,WAAW,KAAK,CAAC,CAAC,KAAK,SAAS;GAChD,MAAM,QAAQ,WAAW,IAAI;GAa7B,OAAO;IAAE;IAAO,yBAAA,IAZI,IAAI,CACvB,GAAG,CAAC,GAAG,SAAS,GAAG,CAAC,CAAC,QACnB,OACA,cAAc,IAAI,CAAC,CAAC,IAAI,IAAI,EAAE,KAC9B,MAAM,OAAO,SACZ,GAAG,GAAG,IAAI,SAAS,OAAO,IAAI,EAAE,KAAK,CAAC,EAAA,CAAG,KAAK,GAAG,IAAI,YAAY,CAAC,CAAC,SAAS,IAAI,CACjF,CACF,GACA,GAAG,KAAK,SAAS,OACf,QAAQ,QAAQ,MAAM,OAAO,SAAS,IAAI,KAAK,YAAY,CAAC,CAAC,SAAS,IAAI,CAAC,CAAC,CAAC,CAC7E,KAAK,QAAQ,IAAI,IAAI,CACxB,CACgB;GAAQ;EACzB,CAAC;EACD,MAAM,QAAQ,MAAM,SAAS,WAAW,YAAY,QAAQ,OAAO,SAAS,SAAS,EAAE;EACvF,MAAM,WAAW,IAAI,IACpB,MAAM,SACJ,QACC,SAAS,OACT,CAAC,KAAK,UAAU,IAAI,QAAQ,EAAE,MAAM,KAAK,SAAS,QAAQ,SAAS,OACrE,CAAC,CACA,KAAK,YAAY,CAAC,QAAQ,IAAI,OAAO,CAAC,CACzC;EACA,MAAM,WAAW,IAAI,IAAI,MAAM,SAAS,KAAK,YAAY,CAAC,QAAQ,IAAI,OAAO,CAAC,CAAC;EAC/E,MAAM,UAAU,IAAI,IAAI,SAAS,SAAS,WAAW,CAAC,GAAG,OAAO,OAAO,CAAC,CAAC;EACzE,MAAM,WAAW,SAAS,QACxB,WAAW,OAAO,QAAQ,SAAS,KAAK,OAAO,MAAM,SAAS,CAChE;EAEA,MAAM,UAAU,CAAC,GAAG,SAAS,OAAO,CAAC,CAAC,CAAC,QAAQ,CAAC,CAAC,QAK/C,OAAO,YAAY;GACnB,MAAM,UAAU,SAAS,IAAI,QAAQ,EAAE;GACvC,MAAM,yBAAS,IAAI,IAAI;IACtB,GAAI,MAAM,SAAS,IAAI,QAAQ,EAAE,KAAK,CAAC;IACvC,GAAG,KAAK,YAAY,OAAO,QAAQ,EAAE;IACrC,GAAG,WAAW,QACZ,QACC,WACA,OAAO,IAAI,WAAA,QAA8B,KAAK,OAAO,QAAQ,SAAS,QAAQ,EAAE,CAClF,CAAC,CACA,KAAK,WAAW,OAAO,IAAI,MAAM,oBAAoB,MAAM,CAAC;GAC/D,CAAC;GACD,MAAM,WACJ,QAAQ,SAAS,SACf,SAAS,WAAW,KAAA,IACpB,CAAC,SAAS,OAAO,KAAK,CAAC,KAAK,YAAY,MAAM,QAAQ,EAAE,MAC3D,CAAC,GAAG,OAAO,CAAC,CAAC,MAAM,UAAU,OAAO,IAAI,KAAK,CAAC;GAC/C,MAAM,UACJ,QAAQ,SAAS,SAAS,YAAY,KAAA,IAAY,QAAQ,SAAS,WACpE,SAAS,MAAM,WACd,OAAO,MAAM,OAAO,SAAS,QAAQ,QAAQ,YAAY,CAAC,CAAC,SAAS,IAAI,CAAC,CAC1E;GACD,IAAI,CAAC,WAAW,CAAC,QAAQ,OAAO;GAChC,MAAM,QAAQ,eACb,MAAM,eAAe,YACrB,QAAQ,KACP,cAAc,SAAS,IAAI,SAAS,KAAK,CAAC,MAAM,KAAK,IAAI,SAAS,CACpE,CAAC,CAAC,SAAS,OAAO;IACjB,MAAM,SAAS,SAAS,IAAI,EAAE;IAC9B,IAAI,WAAW,KAAA,GAAW,OAAO,CAAC;IAClC,MAAM,SAAS,SAAS,IAAI,EAAE;IAC9B,MAAM,OACL,WAAW,KAAA,IACR,OAAO,UACP,GAAG,iBAAiB,OAAO,MAAM,OAAO,SAAS,EAAE,IAAI,OAAO;IAClE,OAAO,CACN;KACC;KACA;KACA,QACC,WAAW,KAAA,IACR,CAAC,IACD,CACA,CACC,iBAAiB,IAAI,CAAC,CAAC,MAAM,IAC7B,iBAAiB,OAAO,OAAO,CAAC,CAAC,MAAM,EACxC,CACD;IACJ,CACD;GACD,CAAC;GACD,OAAO;IACN,sBAAM,IAAI,IAAI,CAAC,GAAG,MAAM,MAAM,GAAG,MAAM,KAAK,SAAS,KAAK,EAAE,CAAC,CAAC;IAC9D,QACC,MAAM,WAAW,IACd,MAAM,SACN,CAAC,GAAG,MAAM,QAAQ,MAAM,KAAK,SAAS,KAAK,IAAI,CAAC,CAAC,KAAK,IAAI,CAAC;IAC/D,UAAU,IAAI,IAAI,CAAC,GAAG,MAAM,UAAU,GAAG,MAAM,SAAS,SAAS,KAAK,MAAM,CAAC,CAAC;GAC/E;EACD,GACA;GAAE,sBAAM,IAAI,IAAI;GAAG,QAAQ,CAAC;GAAG,0BAAU,IAAI,IAAI;EAAE,CACpD;EACA,MAAM,SACL,QAAQ,OAAO,WAAW,IACvB,eAAe,MAAM,YAAY,aACjC,WAAW,QAAQ,QAAQ,IAAI;EACnC,SAAS,KAAK,QAAQ,QAAQ,QAAQ;EACtC,OAAO;CACR;CAEA,aAAa,SAAwB,SAAsC;EAC1E,KAAK,OAAO;EAEZ,MAAM,QAAQ,CACb,GAAG,IAAI,IACN,KAAK,cAAc,OAAO,CAAC,CAAC,SAAS,YAAY;GAChD,MAAM,SAAS,KAAK,SAAS,IAAI,QAAQ,EAAE;GAC3C,IAAI,QAAQ,SAAS,UAAU,QAAQ,YAAY,MAAM,OAAO,CAAC;GACjE,MAAM,UAAU,OAAO,SAAS;GAChC,IAAI,WAAW,eAAe,KAAK,QAAQ,OAAO,GAAG,OAAO,CAAC;GAC7D,MAAM,WAAW,UAAU,QAAQ,QAAQ,QAAQ,OAAO,IAAI,KAAA;GAC9D,OAAO,iBAAiB,QAAQ,OAAO,CAAC,CACtC,QAAQ,SAAS,CAAC,WAAW,CAAC,eAAe,IAAI,CAAC,CAAC,CACnD,KAAK,SAAS,UAAU,IAAI,IAAI,KAAK,IAAI;EAC5C,CAAC,CACF,CACD;EACA,OAAO,MAAM,WAAW,IAAI,KAAA,IAAY,GAAG,aAAa,QAAQ,IAAI,MAAM,KAAK,IAAI;CACpF;AACD;;;;;;;;;;;;;;AC3pCA,SAAgB,aAAa,UAA6B,SAAyC;CAClG,OAAO,IAAI,OAAO,UAAU,OAAO;AACpC"}
|