@genesislcap/ai-assistant 15.86.1 → 15.87.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/ai-assistant.api.json +5026 -645
- package/dist/ai-assistant.d.ts +802 -0
- package/dist/chat-driver.cjs +1487 -132
- package/dist/chat-driver.cjs.map +4 -4
- package/dist/chat-driver.mjs +1480 -132
- package/dist/chat-driver.mjs.map +4 -4
- package/dist/custom-elements.json +2779 -657
- package/dist/dts/autopilot/autopilot-session.d.ts +25 -0
- package/dist/dts/autopilot/autopilot-session.d.ts.map +1 -1
- package/dist/dts/chat-driver-node.d.ts +2 -0
- package/dist/dts/chat-driver-node.d.ts.map +1 -1
- package/dist/dts/components/ai-driver/ai-driver.d.ts +15 -0
- package/dist/dts/components/ai-driver/ai-driver.d.ts.map +1 -1
- package/dist/dts/components/ai-driver/base-driver-decorator.d.ts +6 -0
- package/dist/dts/components/ai-driver/base-driver-decorator.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/chat-driver.d.ts +7 -0
- package/dist/dts/components/chat-driver/chat-driver.d.ts.map +1 -1
- package/dist/dts/components/chat-driver/interaction-controller.d.ts +12 -0
- package/dist/dts/components/chat-driver/interaction-controller.d.ts.map +1 -1
- package/dist/dts/headless/describe-interaction.d.ts +17 -0
- package/dist/dts/headless/describe-interaction.d.ts.map +1 -0
- package/dist/dts/headless/headless-debug.d.ts +28 -0
- package/dist/dts/headless/headless-debug.d.ts.map +1 -0
- package/dist/dts/headless/headless-persistence.d.ts +35 -0
- package/dist/dts/headless/headless-persistence.d.ts.map +1 -0
- package/dist/dts/headless/headless-session.d.ts +180 -0
- package/dist/dts/headless/headless-session.d.ts.map +1 -0
- package/dist/dts/headless/headless.types.d.ts +435 -0
- package/dist/dts/headless/headless.types.d.ts.map +1 -0
- package/dist/dts/headless/index.d.ts +5 -0
- package/dist/dts/headless/index.d.ts.map +1 -0
- package/dist/dts/headless-server/compact.d.ts +52 -0
- package/dist/dts/headless-server/compact.d.ts.map +1 -0
- package/dist/dts/headless-server/index.d.ts +23 -0
- package/dist/dts/headless-server/index.d.ts.map +1 -0
- package/dist/dts/headless-server/server.d.ts +13 -0
- package/dist/dts/headless-server/server.d.ts.map +1 -0
- package/dist/dts/headless-server/types.d.ts +210 -0
- package/dist/dts/headless-server/types.d.ts.map +1 -0
- package/dist/dts/index.d.ts +2 -0
- package/dist/dts/index.d.ts.map +1 -1
- package/dist/dts/main/main.d.ts.map +1 -1
- package/dist/dts/state/debug-event-log.d.ts +1 -1
- package/dist/dts/state/debug-event-log.d.ts.map +1 -1
- package/dist/dts/state/decision-surface.d.ts +5 -4
- package/dist/dts/state/decision-surface.d.ts.map +1 -1
- package/dist/dts/state/persistence/debug-log-assembly.d.ts +49 -0
- package/dist/dts/state/persistence/debug-log-assembly.d.ts.map +1 -0
- package/dist/dts/state/persistence/index.d.ts +1 -0
- package/dist/dts/state/persistence/index.d.ts.map +1 -1
- package/dist/dts/state/persistence/session-persister.d.ts +7 -0
- package/dist/dts/state/persistence/session-persister.d.ts.map +1 -1
- package/dist/dts/types/interaction-surface.d.ts +30 -0
- package/dist/dts/types/interaction-surface.d.ts.map +1 -1
- package/dist/esm/autopilot/autopilot-session.js +31 -16
- package/dist/esm/chat-driver-node.js +8 -0
- package/dist/esm/components/ai-driver/base-driver-decorator.js +12 -0
- package/dist/esm/components/chat-driver/chat-driver.js +8 -0
- package/dist/esm/components/chat-driver/interaction-controller.js +66 -0
- package/dist/esm/headless/describe-interaction.js +55 -0
- package/dist/esm/headless/headless-debug.js +62 -0
- package/dist/esm/headless/headless-persistence.js +192 -0
- package/dist/esm/headless/headless-session.js +808 -0
- package/dist/esm/headless/headless.types.js +1 -0
- package/dist/esm/headless/index.js +3 -0
- package/dist/esm/headless-server/compact.js +160 -0
- package/dist/esm/headless-server/index.js +21 -0
- package/dist/esm/headless-server/server.js +746 -0
- package/dist/esm/headless-server/types.js +3 -0
- package/dist/esm/index.js +3 -0
- package/dist/esm/main/main.js +18 -37
- package/dist/esm/state/debug-event-log.js +6 -1
- package/dist/esm/state/decision-surface.js +75 -48
- package/dist/esm/state/persistence/debug-log-assembly.js +69 -0
- package/dist/esm/state/persistence/index.js +1 -0
- package/dist/esm/state/persistence/session-persister.js +16 -0
- package/dist/headless-server.cjs +853 -0
- package/dist/headless-server.cjs.map +7 -0
- package/dist/headless-server.mjs +819 -0
- package/dist/headless-server.mjs.map +7 -0
- package/package.json +28 -18
- package/scripts/build-headless-server-node.mjs +42 -0
- package/scripts/smoke-chat-driver-node.mjs +3 -0
- package/scripts/smoke-headless-server-node.mjs +112 -0
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../src/headless-server/index.ts", "../src/headless-server/compact.ts", "../src/headless-server/server.ts", "../src/headless-server/types.ts"],
|
|
4
|
+
"sourcesContent": ["/**\n * Node-only entry point for the headless assistant protocol server\n * (`@genesislcap/ai-assistant/headless-server`).\n *\n * The server speaks a small HTTP/JSON protocol over a {@link HeadlessSession}: one JSON command in,\n * one compact JSON reply out. A coding agent or a script can drive an assistant journey with no\n * browser. It uses `node:http` and `node:fs`, so it has an entry of its own, built for Node\n * (`dist/headless-server.{mjs,cjs}`), and is never reachable from the package root\n * (`src/index.ts`): a browser bundle must not see a `node:` import.\n *\n * It knows only a session and Node built-ins. Its imports of `../headless` are type-only, so the\n * bundle carries no second copy of `HeadlessSession`: the session it is given comes from\n * `@genesislcap/ai-assistant` (or `/chat-driver`), whichever the host built it with.\n * `headless-server-entry.test.ts` holds all of this.\n *\n * @packageDocumentation\n * @beta\n */\nexport {\n capOutput,\n compactDecision,\n compactEvent,\n firstLines,\n leanDecisionText,\n shortDecision,\n} from './compact';\nexport { createHeadlessServer } from './server';\nexport { DECISION_TEXTS, DEFAULT_DECISION_TEXT } from './types';\nexport type {\n Command,\n CompactAction,\n CompactDecision,\n CompactEvent,\n Composer,\n DecisionText,\n ExtraOp,\n ExtraOpResult,\n HeadlessServer,\n HeadlessServerHandle,\n Reply,\n ServerOptions,\n Status,\n WorkingInfo,\n} from './types';\n", "import type { HeadlessEvent, InteractionDescription } from '../headless';\nimport type { CompactAction, CompactDecision, CompactEvent, DecisionText } from './types';\n\n/** How much of an assistant message a reply carries: its first lines, and how long it was. */\nconst MESSAGE_LINES = 3;\nconst MESSAGE_CHARS = 300;\n/** A turn's final text is what a written question looks like, so it gets more room. */\nconst TURN_TEXT_CHARS = 1500;\n\n/** The first `lines` lines of `text`, at most `chars` characters, and its full length when it was cut. */\nexport function firstLines(\n text: string,\n lines: number,\n chars: number,\n): { text: string; chars?: number } {\n const kept = text.split('\\n').slice(0, lines).join('\\n');\n const cut = kept.length > chars ? `${kept.slice(0, chars)}\u2026` : kept;\n return cut === text ? { text } : { text: cut, chars: text.length };\n}\n\n/** The keys of `source` that are set, as a new object: a field with nothing to say is dropped. */\nexport function present<T extends Record<string, unknown>>(source: T): Partial<T> {\n const out: Record<string, unknown> = {};\n for (const [key, value] of Object.entries(source)) {\n if (value === undefined || value === null || value === '' || value === false) continue;\n if (Array.isArray(value) && value.length === 0) continue;\n out[key] = value;\n }\n return out as Partial<T>;\n}\n\nexport interface CompactOptions {\n probeEvent?: { name: string; keys: readonly string[] };\n}\n\n/**\n * One session event, compact. `decision` and `working` are not reported as events: what the person is asked\n * is the reply's `decision`, and what is working is its `working`. A message carries its first lines and\n * its length; a probe event is the host's view of it (see `ServerOptions.probeEvent`).\n */\nexport function compactEvent(\n event: HeadlessEvent,\n options: CompactOptions = {},\n): CompactEvent | undefined {\n switch (event.type) {\n case 'decision':\n case 'working':\n return undefined;\n case 'settled':\n return {\n event: 'settled',\n component: event.component,\n ...present({\n answeredBy: event.answeredBy,\n auto: event.auto,\n raw: event.raw,\n resolvedItself: event.resolvedItself,\n }),\n };\n case 'message': {\n const { text, chars } = firstLines(event.text, MESSAGE_LINES, MESSAGE_CHARS);\n return { event: 'message', text, ...present({ chars: chars ?? event.chars }) };\n }\n case 'turn': {\n const out: CompactEvent = {\n event: 'turn',\n reason: event.reason,\n ...present({ failureReason: event.failureReason }),\n };\n if (event.text) {\n const { text, chars } = firstLines(event.text, Number.MAX_SAFE_INTEGER, TURN_TEXT_CHARS);\n out.text = text;\n if (chars ?? event.chars) out.chars = chars ?? event.chars;\n }\n return out;\n }\n case 'autopilot':\n // An autopilot that is not available says nothing the reader can use.\n if (event.mode === 'unavailable' && !event.needsUser) return undefined;\n return {\n event: 'autopilot',\n mode: event.mode,\n status: event.status,\n ...present({ needsUser: event.needsUser, working: event.working, reason: event.reason }),\n };\n case 'error':\n return { event: 'error', where: event.where, message: event.message };\n case 'probe': {\n const view = options.probeEvent;\n if (!view) {\n const changed = Object.fromEntries(event.changed.map((key) => [key, event.probe[key]]));\n return { event: 'probe', ...changed };\n }\n if (!event.changed.some((key) => view.keys.includes(key))) return undefined;\n return {\n event: view.name,\n ...Object.fromEntries(view.keys.map((key) => [key, event.probe[key] ?? null])),\n };\n }\n default:\n return undefined;\n }\n}\n\n/** How the platform's Views list marks the preview view (`renderViews`), at the end of its line. */\nconst PREVIEW_MARK = ' (shown below as Now)';\n/** The line that carries the preview view as JSON (`renderDecision`). */\nconst NOW_PREFIX = 'Now: ';\n/** What `capRead` appends, on a line of its own, to a read it cut. It belongs to the `Now:` line. */\nconst CUT_PREFIX = '[Cut at ';\n\n/**\n * A decision's text without its `Now: <the preview view as JSON>` line, and nothing else (`decisionText:\n * \"lean\"`). `renderDecision` writes the preview as `Now: ${capRead(JSON.stringify(view))}`: `JSON.stringify`\n * with no indent never breaks a line, so the JSON is the one line, and `capRead` adds a second, `[Cut at \u2026]`,\n * only when it cut it. Both go; in their place is a pointer to `read`. The line is found by position, not\n * by prefix alone: it follows the Views list, whose entry for the preview ends `(shown below as Now)`, so a\n * card that itself has a line starting `Now: ` is not mistaken for it.\n *\n * The text comes back as it was when there is no preview to find (a card with no preview view, or a short-form\n * decision, which shows no `Now:`), or when `views` does not name the one the Views list marks.\n */\nexport function leanDecisionText(text: string, views?: Readonly<Record<string, string>>): string {\n const names = Object.keys(views ?? {});\n if (!names.length) return text;\n const lines = text.split('\\n');\n const marked = lines.findIndex((line) => line.endsWith(PREVIEW_MARK));\n if (marked < 0) return text;\n // The entry starts at or before the marked line (a description may run to several lines).\n const startsEntry = (line: string, name: string): boolean =>\n line === ` ${name}${PREVIEW_MARK}` || line.startsWith(` ${name} \u2014 `);\n let entry = marked;\n while (entry >= 0 && !names.some((n) => startsEntry(lines[entry], n))) entry -= 1;\n const view = entry < 0 ? undefined : names.find((n) => startsEntry(lines[entry], n));\n if (view === undefined) return text;\n const now = lines.findIndex((line, i) => i > marked && line.startsWith(NOW_PREFIX));\n if (now < 0) return text;\n const end = lines[now + 1]?.startsWith(CUT_PREFIX) ? now + 2 : now + 1;\n lines.splice(\n now,\n end - now,\n `(The \"${view}\" view is not repeated here: read it with read ${view}.)`,\n );\n return lines.join('\\n');\n}\n\n/**\n * A decision as the reply carries it: what to read and what to choose from, and nothing empty. With\n * `decisionText: \"lean\"` its `text` leaves out the preview view's JSON ({@link leanDecisionText}); nothing\n * else about it changes.\n */\nexport function compactDecision(\n description: InteractionDescription,\n decisionText: DecisionText = 'full',\n): CompactDecision {\n const actions: CompactAction[] = description.actions.map((a) => ({\n ...(a.n !== undefined ? { n: a.n } : {}),\n name: a.name,\n ...present({ label: a.label !== a.name ? a.label : undefined }),\n enabled: a.enabled,\n ...present({\n unavailable: a.unavailable,\n args: a.args,\n argsSchema: a.args === 'fields' ? (a.argsSchema as Record<string, unknown>) : undefined,\n }),\n }));\n return {\n interactionId: description.interactionId,\n component: description.component,\n text:\n decisionText === 'lean'\n ? leanDecisionText(description.text, description.views)\n : description.text,\n actions,\n ...(description.views && Object.keys(description.views).length\n ? { views: { ...description.views } }\n : {}),\n ...(description.controller ? {} : { controller: false as const }),\n };\n}\n\n/**\n * A decision cut to what a caller who has already read the card needs: which interaction, and the actions as\n * `n`, `name`, `enabled`. For the reply to an edit, and to a refused action, where the card has not changed\n * enough to be worth sending again.\n */\nexport function shortDecision(\n interactionId: string,\n component: string,\n actions: ReadonlyArray<{ n?: number; name: string; enabled: boolean }>,\n): CompactDecision {\n return {\n interactionId,\n component,\n actions: actions.map((a) => ({\n ...(a.n !== undefined ? { n: a.n } : {}),\n name: a.name,\n enabled: a.enabled,\n })),\n };\n}\n\n/** The most an action's `output` may take in a reply, as JSON. */\nconst OUTPUT_CHARS = 4000;\n\n/** What an editing action returned, as the reply carries it: whole when small, else its first characters. */\nexport function capOutput(output: unknown): unknown {\n let json: string | undefined;\n try {\n json = JSON.stringify(output);\n } catch {\n return String(output);\n }\n if (json === undefined || json.length <= OUTPUT_CHARS) return output;\n return { truncated: `${json.slice(0, OUTPUT_CHARS)}\u2026`, chars: json.length };\n}\n", "import { createWriteStream, mkdirSync, type WriteStream } from 'node:fs';\nimport { writeFile } from 'node:fs/promises';\nimport { createServer, type IncomingMessage, type Server, type ServerResponse } from 'node:http';\nimport type { AddressInfo } from 'node:net';\nimport { join, resolve } from 'node:path';\nimport type { ChatAttachment } from '@genesislcap/foundation-ai';\nimport type {\n HeadlessEvent,\n HeadlessActResult,\n HeadlessEventType,\n HeadlessSession,\n HeadlessState,\n PendingSummary,\n} from '../headless';\nimport { capOutput, compactDecision, compactEvent, present, shortDecision } from './compact';\nimport {\n DECISION_TEXTS,\n DEFAULT_DECISION_TEXT,\n type Command,\n type CompactEvent,\n type Composer,\n type DecisionText,\n type ExtraOpResult,\n type HeadlessServer,\n type Reply,\n type ServerOptions,\n type Status,\n type WorkingInfo,\n} from './types';\n\nconst DEFAULT_MAX_WAIT_MS = 100_000;\n/** The longest a command may ask to wait (an hour), ms. A larger `maxWaitMs` is cut to it. */\nconst MAX_WAIT_CAP_MS = 3_600_000;\n/** The ops the server answers itself: a host's `extraOps` cannot take their names. */\nconst BUILTIN_OPS: readonly string[] = [\n 'send',\n 'act',\n 'resolve',\n 'autopilot',\n 'wait',\n 'state',\n 'read',\n 'debugLog',\n 'stop',\n];\nconst BYTES_PER_KB = 1024;\nconst MAX_BODY_MB = 16;\nconst MAX_BODY_BYTES = MAX_BODY_MB * BYTES_PER_KB * BYTES_PER_KB;\n/** HTTP statuses the server answers with. */\nconst HTTP_OK = 200;\nconst HTTP_BAD_REQUEST = 400;\nconst HTTP_FORBIDDEN = 403;\nconst HTTP_NOT_FOUND = 404;\nconst HTTP_UNSUPPORTED_MEDIA_TYPE = 415;\n/** The addresses that mean this machine: a bound `host` that is none of them is the host's own choice. */\nconst LOOPBACK_HOSTS = ['127.0.0.1', 'localhost', '[::1]', '::1'];\nconst HTTP_SERVER_ERROR = 500;\n/** How long `shutdown` lets a reply on its way finish before it drops every connection, ms. */\nconst CLOSE_GRACE_MS = 500;\n/** Cost is reported to four decimal places. */\nconst MONEY_SCALE = 10_000;\n/** How long the log watcher sleeps between looks when nothing happens. */\nconst WATCH_MS = 2000;\nconst ALL_EVENT_TYPES: readonly HeadlessEventType[] = [\n 'decision',\n 'working',\n 'settled',\n 'message',\n 'turn',\n 'autopilot',\n 'probe',\n 'error',\n];\n\n/** `until` as the caller wrote it: one name or several. `idle` is the server's own, not an event type. */\nfunction untilOf(value: unknown): { types: HeadlessEventType[]; idle: boolean } | undefined {\n if (value === undefined) return undefined;\n const names = (Array.isArray(value) ? value : [value]).map(String);\n return {\n types: names.filter((n): n is HeadlessEventType =>\n (ALL_EVENT_TYPES as readonly string[]).includes(n),\n ),\n idle: names.includes('idle'),\n };\n}\n\n/** `maxWaitMs` as the caller wrote it: a finite number cut to `0..MAX_WAIT_CAP_MS`, else the default. */\nfunction waitMsOf(value: unknown, fallback: number): number {\n const n = Number(value ?? fallback);\n return Number.isFinite(n) ? Math.min(Math.max(0, n), MAX_WAIT_CAP_MS) : fallback;\n}\n\nconst hasOwn = (target: object | undefined, key: string): boolean =>\n !!target && Object.prototype.hasOwnProperty.call(target, key);\n\nconst money = (usd: number): number => Math.round(usd * MONEY_SCALE) / MONEY_SCALE;\n\n/**\n * The headless server (PLAN \u00A75, D7): `node:http` on 127.0.0.1, `GET /health` and `POST /cmd`.\n *\n * Every command is APPLIED and then LONG-POLLS (\u00A75.5): the reply comes when the journey next needs the\n * person (an interaction is held by them and ready), a turn ends, the run ends, or something fails, or at\n * `maxWaitMs` with `status: \"working\"`. Nothing is lost on a client timeout: the command was applied before\n * the wait, events carry `seq`, and `{op: \"wait\", since}` returns everything after it.\n *\n * The session is the only thing it drives; what the host owns is reached through {@link ServerOptions}.\n */\n// oxlint-disable-next-line max-lines-per-function -- one closure over the session, the log and the HTTP server, as it was in Create\nexport function createHeadlessServer(options: ServerOptions): HeadlessServer {\n const runDir = resolve(options.runDir);\n mkdirSync(runDir, { recursive: true });\n const defaultMaxWaitMs = waitMsOf(options.defaultMaxWaitMs, DEFAULT_MAX_WAIT_MS);\n let decisionText: DecisionText = options.decisionText ?? DEFAULT_DECISION_TEXT;\n const announce = options.announce ?? ((line: string) => console.log(line));\n const events: WriteStream = createWriteStream(join(runDir, 'events.jsonl'), { flags: 'a' });\n const startedAt = Date.now();\n\n let session: HeadlessSession | undefined;\n let http: Server | undefined;\n let closing = false;\n let loggedSeq = 0;\n /** Serialises the APPLY phase of commands that change things; a long wait never holds it. */\n let applying: Promise<unknown> = Promise.resolve();\n /** The save chain: every flush runs after the one before it, so the last one sees the latest state. */\n let flushing: Promise<void> = Promise.resolve();\n\n let resolveClosed!: () => void;\n const closed = new Promise<void>((r) => {\n resolveClosed = r;\n });\n\n const appendLog = (line: Record<string, unknown>): void => {\n if (!events.writableEnded) events.write(`${JSON.stringify(line)}\\n`);\n };\n\n /** Write every event the log has not yet written. */\n function drainLog(): void {\n if (!session) return;\n for (const event of session.eventsSince(loggedSeq)) {\n appendLog({ kind: 'event', ...event });\n loggedSeq = event.seq;\n }\n }\n\n /** Save what the host and the session hold, after any save already running. Never rejects. */\n function flushAll(): Promise<void> {\n flushing = flushing.then(async () => {\n try {\n await options.flush?.();\n await session?.flush();\n } catch (e) {\n appendLog({\n kind: 'error',\n where: 'flush',\n message: e instanceof Error ? e.message : String(e),\n });\n }\n });\n return flushing;\n }\n\n /** Follow the log in the background: write it down, and save at every turn end, whoever's turn. */\n async function watch(s: HeadlessSession): Promise<void> {\n let cursor = s.state().lastSeq;\n // Everything before the attach goes in the log too.\n drainLog();\n const watching = (): boolean => !closing && session === s;\n while (watching()) {\n try {\n // oxlint-disable-next-line no-await-in-loop -- a sequential watcher and poll: each step needs the last\n const woken = await s.wait({ since: cursor, until: ALL_EVENT_TYPES, maxWaitMs: WATCH_MS });\n cursor = woken.nextSeq;\n drainLog();\n // oxlint-disable-next-line no-await-in-loop -- a sequential watcher and poll: each step needs the last\n if (woken.events.some((e) => e.type === 'turn')) await flushAll();\n if (woken.status === 'closed') break;\n } catch (e) {\n appendLog({\n kind: 'error',\n where: 'watch',\n message: e instanceof Error ? e.message : String(e),\n });\n break;\n }\n }\n }\n\n const handle: HeadlessServer = {\n get session() {\n return session;\n },\n runDir,\n get decisionText() {\n return decisionText;\n },\n setDecisionText(mode) {\n decisionText = mode;\n },\n attach(next) {\n if (session === next) return;\n session = next;\n // A new session numbers its events from 1: the old one's last `seq` would hide its first ones.\n loggedSeq = 0;\n void watch(next);\n },\n listen,\n handle: runCommand,\n shutdown,\n closed,\n };\n if (options.session) handle.attach(options.session);\n\n // ---------------------------------------------------------------------------------------- replies\n\n const composerOf = (state: HeadlessState | undefined): Composer => {\n if (!state) return 'blocked:not-started';\n const blocked = options.composerBlockedReason?.();\n if (blocked) return `blocked:${blocked}`;\n return state.busy ? 'busy' : 'open';\n };\n\n /** The status a reply with no waiting reports: what the session is doing now. */\n function statusNow(state: HeadlessState | undefined): Status {\n if (!state) return 'idle';\n if (state.pending) return 'decision';\n if (options.isEnded?.()) return 'ended';\n if (state.autopilot?.needsUser) return 'needs-user';\n return state.busy ? 'working' : 'idle';\n }\n\n const probeView = (state: HeadlessState): Record<string, unknown> | undefined => {\n const view = options.probeEvent;\n if (!view) return undefined;\n return Object.fromEntries(view.keys.map((key) => [key, state.probe[key] ?? null]));\n };\n\n /** What is going on, in words: the host's account of the open widget, or whose turn it is with none open. */\n function stageOf(state: HeadlessState, other: PendingSummary | undefined): string | undefined {\n if (other) {\n let stage: string | undefined;\n try {\n stage = options.describeWorking?.(other.interactionId, other.component);\n } catch {\n /* a stage is a nicety: a host that cannot say is the same as one that has nothing to say */\n }\n if (stage) return stage;\n // A paused autopilot answers nothing, whatever its `working` flag says.\n const idle = other.heldBy === 'autopilot' && state.autopilot?.mode !== 'running';\n return other.heldBy !== 'user' && !idle ? `${other.heldBy} is answering it` : undefined;\n }\n // The flag can stay true while the mode is `paused`: only a running autopilot is doing anything.\n if (state.autopilot?.working && state.autopilot.mode === 'running') {\n return 'autopilot is working';\n }\n return state.busy ? 'assistant is thinking (no widget open)' : undefined;\n }\n\n function workingInfo(state: HeadlessState, startedMs: number): WorkingInfo {\n const other = state.others.find((o) => !o.ready || o.heldBy !== 'user') ?? state.others[0];\n return {\n ...(other ? { component: other.component, heldBy: other.heldBy } : {}),\n elapsedMs: Date.now() - startedMs,\n ...present({ probe: probeView(state), stage: stageOf(state, other) }),\n };\n }\n\n /** A command's own `decisionText` when it names a valid one, else the server's. */\n const decisionTextFor = (command: Command | undefined): DecisionText =>\n DECISION_TEXTS.includes(command?.decisionText as DecisionText)\n ? (command!.decisionText as DecisionText)\n : decisionText;\n\n function reply(\n command: Command | undefined,\n status: Status,\n since: readonly HeadlessEvent[],\n extra: Partial<Reply> & { ok?: boolean } = {},\n startedMs = Date.now(),\n ): Reply {\n const state = session?.state();\n const compact: CompactEvent[] = since\n .map((e) => compactEvent(e, { probeEvent: options.probeEvent }))\n .filter((e): e is CompactEvent => !!e);\n return {\n ok: extra.ok ?? true,\n ...(command?.id !== undefined ? { id: command.id } : {}),\n status,\n ...(compact.length ? { since: compact } : {}),\n ...(state?.pending\n ? { decision: compactDecision(state.pending, decisionTextFor(command)) }\n : {}),\n ...(status === 'working' && state ? { working: workingInfo(state, startedMs) } : {}),\n composer: composerOf(state),\n cost: { usd: money(state?.cost.costUsd ?? 0) },\n nextSeq: state?.lastSeq ?? 0,\n ...extra,\n } as Reply;\n }\n\n /** A refusal: the reason, and where things stand (including the decision, if one is waiting). */\n function refuse(\n command: Command,\n error: string,\n reason?: string,\n since: number | undefined = undefined,\n /** The interaction an `act` was refused on: when it is the pending one, its card is not sent again. */\n shortFor?: string,\n ): Reply {\n const state = session?.state();\n const missed = session && since !== undefined ? session.eventsSince(since) : [];\n const pending = state?.pending;\n return reply(command, statusNow(state), missed, {\n ok: false,\n error,\n ...(reason ? { reason } : {}),\n ...(pending && shortFor !== undefined && pending.interactionId === shortFor\n ? { decision: shortDecision(pending.interactionId, pending.component, pending.actions) }\n : {}),\n });\n }\n\n /**\n * The reply to an action that ran and did not settle the interaction (a form field set): at once, with what\n * it returned and the actions as they now stand, and not the card, which the caller has read.\n */\n function edited(\n command: Command,\n interactionId: string,\n result: Extract<HeadlessActResult, { ok: true }>,\n cursor: number,\n ): Reply {\n const s = session!;\n const state = s.state();\n const open = state.pending?.interactionId === interactionId ? state.pending : undefined;\n const actions = result.description?.actions ?? open?.actions ?? result.actions;\n const component =\n result.description?.component ??\n open?.component ??\n state.others.find((o) => o.interactionId === interactionId)?.component ??\n '';\n return reply(command, 'edited', s.eventsSince(cursor), {\n decision: shortDecision(interactionId, component, actions),\n ...(result.output !== undefined ? { output: capOutput(result.output) } : {}),\n });\n }\n\n // ------------------------------------------------------------------------------------ the long poll\n\n /**\n * Wait for the journey to need the caller, then reply with everything since `cursor`. A `signal` that\n * aborts (the connection closed) ends the wait with a `working` reply that no one will read. The terminal\n * conditions are read from the session's live state, not from the events alone, so an event that has\n * since been overtaken (a decision the autopilot took back) does not end the wait.\n */\n async function poll(\n command: Command,\n cursor: number,\n startedMs: number,\n signal?: AbortSignal,\n ): Promise<Reply> {\n const s = session;\n if (!s) return reply(command, 'idle', [], {}, startedMs);\n const maxWaitMs = waitMsOf(command.maxWaitMs, defaultMaxWaitMs);\n const deadline = startedMs + maxWaitMs;\n const until = untilOf(command.until);\n let waitFrom = cursor;\n for (;;) {\n const since = s.eventsSince(cursor);\n const state = s.state();\n const verdict = terminal(since, state, until);\n if (verdict) {\n // oxlint-disable-next-line no-await-in-loop -- a sequential watcher and poll: each step needs the last\n if (since.some((e) => e.type === 'turn') || verdict === 'ended') await flushAll();\n drainLog();\n return reply(command, verdict, s.eventsSince(cursor), {}, startedMs);\n }\n const remaining = deadline - Date.now();\n // A caller that hung up has no one to wait for: stop looking, and let the waiter go.\n if (remaining <= 0 || signal?.aborted) {\n drainLog();\n return reply(command, 'working', since, {}, startedMs);\n }\n\n // oxlint-disable-next-line no-await-in-loop -- a sequential watcher and poll: each step needs the last\n const woken = await s.wait({\n since: waitFrom,\n ...(until ? { until: until.types } : {}),\n maxWaitMs: remaining,\n ...(signal ? { signal } : {}),\n });\n waitFrom = woken.nextSeq;\n if (woken.status === 'closed') {\n drainLog();\n return reply(command, 'ended', s.eventsSince(cursor), {}, startedMs);\n }\n }\n }\n\n /** The status this state and these events call for, or `undefined` to keep waiting. */\n function terminal(\n since: readonly HeadlessEvent[],\n state: HeadlessState,\n until: { types: HeadlessEventType[]; idle: boolean } | undefined,\n ): Status | undefined {\n const turnEnded = since.some((e) => e.type === 'turn');\n const failed = since.some((e) => e.type === 'error' || (e.type === 'turn' && e.failureReason));\n if (options.isEnded?.() && !state.pending && (turnEnded || !state.busy)) return 'ended';\n if (until) {\n if (state.pending && until.types.includes('decision')) return 'decision';\n if (since.some((e) => until.types.includes(e.type))) {\n return since.some((e) => e.type === 'error')\n ? 'error'\n : turnEnded\n ? 'turn'\n : statusNow(state);\n }\n if (until.idle && !state.busy && !state.pending) return 'idle';\n return undefined;\n }\n if (state.pending) return 'decision';\n if (failed) return 'error';\n if (turnEnded) return 'turn';\n if (state.autopilot?.needsUser) return 'needs-user';\n return undefined;\n }\n\n // ----------------------------------------------------------------------------------------- the ops\n\n const isOpen = (state: HeadlessState, interactionId: string): boolean =>\n state.pending?.interactionId === interactionId ||\n state.others.some((o) => o.interactionId === interactionId);\n\n /** The standard refusal for a command on an interaction that is no longer (or never was) pending. */\n const gone = (command: Command, interactionId: string, since: number): Reply =>\n refuse(\n command,\n `interaction ${interactionId} is not pending: it has settled, or never existed`,\n 'ended',\n since,\n );\n\n const notStarted = (command: Command): Reply =>\n refuse(\n command,\n options.extraOps?.start\n ? 'not started: send {\"op\":\"start\", \u2026} first'\n : 'no session is attached',\n 'not-started',\n );\n\n const str = (value: unknown): string | undefined =>\n typeof value === 'string' ? value : undefined;\n\n /** `act`'s action: a digit string is the option's number. */\n const actionOf = (value: unknown): string | number =>\n typeof value === 'string' && /^\\d+$/.test(value) ? Number(value) : (value as string | number);\n\n async function applyOp(\n command: Command,\n s: HeadlessSession,\n cursor: number,\n ): Promise<Reply | 'poll'> {\n const state = s.state();\n switch (command.op) {\n case 'send': {\n const text = str(command.text);\n if (text === undefined) return refuse(command, '`send` needs `text`', 'invalid-command');\n const paths = Array.isArray(command.files) ? command.files.map(String) : [];\n let attachments: ChatAttachment[] | undefined;\n if (paths.length) {\n if (!options.readAttachment) {\n return refuse(command, 'this server cannot read files', 'invalid-command');\n }\n try {\n attachments = await Promise.all(paths.map((p) => options.readAttachment!(p)));\n } catch (e) {\n return refuse(\n command,\n `could not read a file: ${e instanceof Error ? e.message : String(e)}`,\n 'invalid-command',\n );\n }\n }\n const sent = s.send(text, {\n ...(attachments ? { attachments } : {}),\n ...(str(command.agent) ? { agent: str(command.agent) } : {}),\n });\n return sent.ok ? 'poll' : refuse(command, sent.error, 'refused', cursor);\n }\n case 'act': {\n const interactionId = str(command.interactionId);\n if (!interactionId || command.action === undefined) {\n return refuse(command, '`act` needs `interactionId` and `action`', 'invalid-command');\n }\n if (!isOpen(state, interactionId)) return gone(command, interactionId, cursor);\n const result = await s.act(interactionId, actionOf(command.action), {\n ...(str(command.text) !== undefined ? { text: str(command.text) } : {}),\n ...(Array.isArray(command.options) ? { options: command.options.map(String) } : {}),\n ...(command.fields !== undefined ? { fields: command.fields } : {}),\n });\n if (!result.ok) return refuse(command, result.message, result.error, cursor, interactionId);\n // An edit (not a finishing action) settles nothing, so there is nothing to wait for.\n if (result.finished === false) return edited(command, interactionId, result, cursor);\n return 'poll';\n }\n case 'resolve': {\n const interactionId = str(command.interactionId);\n if (!interactionId)\n return refuse(command, '`resolve` needs `interactionId` and `result`', 'invalid-command');\n if (!isOpen(state, interactionId)) return gone(command, interactionId, cursor);\n const resolved = s.resolve(interactionId, command.result);\n return resolved.ok ? 'poll' : refuse(command, resolved.error, 'refused', cursor);\n }\n case 'autopilot': {\n const mode = {\n pause: 'pause',\n paused: 'pause',\n resume: 'resume',\n running: 'resume',\n stop: 'stop',\n }[String(command.mode)] as 'pause' | 'resume' | 'stop' | undefined;\n if (!mode)\n return refuse(\n command,\n '`autopilot` needs `mode`: running, paused or stop',\n 'invalid-command',\n );\n const done = s.autopilot(mode);\n return done.ok ? 'poll' : refuse(command, done.error, 'refused', cursor);\n }\n case 'wait':\n return 'poll';\n default:\n return refuse(command, `unknown op \"${command.op}\"`, 'unknown-op');\n }\n }\n\n /** Ops that report and do not wait. */\n async function readOp(command: Command, s: HeadlessSession): Promise<Reply | undefined> {\n switch (command.op) {\n case 'state': {\n const state = s.state();\n return reply(command, statusNow(state), [], {\n ...(state.others.length ? { others: state.others } : {}),\n ...(state.autopilot ? { autopilot: state.autopilot } : {}),\n ...(Object.keys(state.probe).length ? { probe: state.probe } : {}),\n busy: state.busy,\n });\n }\n case 'read': {\n const interactionId = str(command.interactionId);\n if (!interactionId)\n return refuse(command, '`read` needs `interactionId`', 'invalid-command');\n const read = await s.read(interactionId, {\n ...(str(command.view) ? { view: str(command.view) } : {}),\n ...(str(command.tool) ? { tool: str(command.tool) } : {}),\n ...(command.args && typeof command.args === 'object'\n ? { args: command.args as Record<string, unknown> }\n : {}),\n });\n return read.ok\n ? ({\n ok: true,\n ...(command.id !== undefined ? { id: command.id } : {}),\n content: read.content,\n } as unknown as Reply)\n : ({\n ok: false,\n ...(command.id !== undefined ? { id: command.id } : {}),\n error: read.error,\n } as unknown as Reply);\n }\n case 'debugLog': {\n await flushAll();\n const log = await s.debugLog();\n const path = join(runDir, 'debug-log.json');\n await writeFile(path, JSON.stringify(log));\n const byKind: Record<string, number> = {};\n for (const entry of log.timeline) {\n const kind = String((entry as { kind?: unknown }).kind ?? 'unknown');\n byKind[kind] = (byKind[kind] ?? 0) + 1;\n }\n const usd = log.sessionUsage?.costUsd ?? s.state().cost.costUsd;\n return reply(command, statusNow(s.state()), [], {\n path,\n entries: { total: log.timeline.length, byKind },\n cost: { usd: money(usd) },\n });\n }\n default:\n return undefined;\n }\n }\n\n /** Run one command to its reply. Never throws: a failure is a reply. */\n async function runCommand(raw: unknown, signal?: AbortSignal): Promise<Reply> {\n const startedMs = Date.now();\n const command = raw as Command;\n if (!command || typeof command !== 'object' || typeof command.op !== 'string') {\n return reply(undefined, statusNow(session?.state()), [], {\n ok: false,\n error: 'a command is a JSON object with a string `op`',\n reason: 'invalid-command',\n });\n }\n appendLog({ kind: 'command', at: new Date().toISOString(), command });\n if (command.decisionText !== undefined && !DECISION_TEXTS.includes(command.decisionText)) {\n return refuse(\n command,\n `\\`decisionText\\` must be one of ${DECISION_TEXTS.join(', ')} (got ${JSON.stringify(command.decisionText)})`,\n 'invalid-command',\n );\n }\n try {\n const out = await dispatch(command, startedMs, signal);\n drainLog();\n return out;\n } catch (e) {\n drainLog();\n appendLog({\n kind: 'error',\n where: `op:${command.op}`,\n message: e instanceof Error ? e.message : String(e),\n });\n return reply(command, statusNow(session?.state()), [], {\n ok: false,\n status: 'error',\n error: e instanceof Error ? e.message : String(e),\n reason: 'threw',\n });\n }\n }\n\n async function dispatch(\n command: Command,\n startedMs: number,\n signal?: AbortSignal,\n ): Promise<Reply> {\n if (command.op === 'stop') {\n session?.stop();\n const out = reply(command, 'ended', [], { stopped: true });\n // After the reply is on its way: the process may exit when the shutdown finishes.\n setTimeout(() => void shutdown(), 0);\n return out;\n }\n // A built-in wins over a host op of the same name, and an op is an OWN property of `extraOps`:\n // `toString` and `constructor` are not ops.\n const isBuiltin = BUILTIN_OPS.includes(command.op);\n const extra =\n !isBuiltin && hasOwn(options.extraOps, command.op)\n ? options.extraOps![command.op]\n : undefined;\n if (!extra && !isBuiltin) {\n return refuse(command, `unknown op \"${command.op}\"`, 'unknown-op');\n }\n\n if (command.op === 'state' || command.op === 'read' || command.op === 'debugLog') {\n if (!session) return notStarted(command);\n return (await readOp(command, session)) as Reply;\n }\n\n // The cursor: where the log stood before the command, unless the caller names one.\n const cursor =\n typeof command.since === 'number' ? command.since : (session?.state().lastSeq ?? 0);\n\n if (command.op === 'wait') {\n if (!session) return notStarted(command);\n return poll(command, cursor, startedMs, signal);\n }\n\n // The apply phase is serial; the wait that follows is not.\n const previous = applying;\n let release!: () => void;\n applying = new Promise<void>((r) => {\n release = r;\n });\n let applied: Reply | 'poll' | ExtraOpResult;\n try {\n await previous;\n if (extra) {\n applied = await extra(command, handle);\n } else {\n if (!session) return notStarted(command);\n applied = await applyOp(command, session, cursor);\n }\n } finally {\n release();\n }\n\n if (applied === 'poll') return poll(command, cursor, startedMs, signal);\n if ('status' in applied) return applied;\n // An extra op's result.\n if (!applied.ok)\n return refuse(\n command,\n applied.error ?? 'refused',\n 'refused',\n typeof command.since === 'number' ? cursor : undefined,\n );\n const wait = applied.poll ?? !!session;\n if (!wait || !session) {\n const pending = session?.state().pending;\n return reply(\n command,\n statusNow(session?.state()),\n [],\n {\n ...applied.fields,\n ...(applied.shortDecision && pending\n ? { decision: shortDecision(pending.interactionId, pending.component, pending.actions) }\n : {}),\n },\n startedMs,\n );\n }\n const polled = await poll(command, cursor, startedMs, signal);\n return { ...polled, ...applied.fields };\n }\n\n // ------------------------------------------------------------------------------------------- HTTP\n\n function readBody(req: IncomingMessage): Promise<string> {\n return new Promise((resolveBody, reject) => {\n const chunks: Buffer[] = [];\n let size = 0;\n req.on('data', (chunk: Buffer) => {\n size += chunk.length;\n if (size > MAX_BODY_BYTES) {\n reject(new Error('the command is too large'));\n req.destroy();\n return;\n }\n chunks.push(chunk);\n });\n req.on('end', () => resolveBody(Buffer.concat(chunks).toString('utf8')));\n req.on('error', reject);\n });\n }\n\n function send(res: ServerResponse, status: number, body: unknown): void {\n const json = JSON.stringify(body);\n res.writeHead(status, {\n 'content-type': 'application/json; charset=utf-8',\n 'content-length': Buffer.byteLength(json),\n });\n res.end(json);\n }\n\n /**\n * Whether a request may be answered. The socket is on this machine, but a web page open in the\n * developer's browser can reach it: so a request that carries an `Origin` (a browser sent it) is\n * refused, and the `Host` must be this server's own address (a rebound name is not), and a command is\n * `application/json`, which a page cannot send without a preflight this server never answers.\n */\n function refusal(\n req: IncomingMessage,\n port: number,\n ): { status: number; error: string } | undefined {\n if (req.headers.origin !== undefined) {\n return { status: HTTP_FORBIDDEN, error: 'a request from a web page is refused' };\n }\n const bound = options.host ?? '127.0.0.1';\n // Only a loopback bind has a `Host` to hold to; a host that binds wider has chosen who reaches it.\n if (LOOPBACK_HOSTS.includes(bound)) {\n const host = (req.headers.host ?? '').toLowerCase();\n if (!LOOPBACK_HOSTS.some((name) => host === `${name}:${port}`)) {\n return {\n status: HTTP_FORBIDDEN,\n error: `the Host must be 127.0.0.1:${port} or localhost:${port}`,\n };\n }\n }\n if (req.method === 'POST') {\n const type = (req.headers['content-type'] ?? '').split(';')[0].trim().toLowerCase();\n if (type !== 'application/json') {\n return {\n status: HTTP_UNSUPPORTED_MEDIA_TYPE,\n error: 'POST /cmd takes content-type: application/json',\n };\n }\n }\n return undefined;\n }\n\n async function onRequest(req: IncomingMessage, res: ServerResponse): Promise<void> {\n const refused = refusal(req, (http!.address() as AddressInfo).port);\n if (refused) {\n send(res, refused.status, { ok: false, status: 'error', error: refused.error });\n return;\n }\n const url = (req.url ?? '/').split('?')[0];\n if (req.method === 'GET' && url === '/health') {\n const state = session?.state();\n send(res, HTTP_OK, {\n ok: true,\n started: !!session,\n runDir,\n pid: process.pid,\n uptimeMs: Date.now() - startedAt,\n ...(state ? { status: statusNow(state), nextSeq: state.lastSeq } : {}),\n });\n return;\n }\n if (req.method === 'POST' && url === '/cmd') {\n let command: unknown;\n try {\n command = JSON.parse(await readBody(req));\n } catch (e) {\n send(res, HTTP_BAD_REQUEST, {\n ok: false,\n status: 'error',\n error: `bad command: ${e instanceof Error ? e.message : String(e)}`,\n });\n return;\n }\n // A client that hangs up ends the wait it started; the command it sent was applied all the same.\n const gone = new AbortController();\n res.on('close', () => {\n if (!res.writableEnded) gone.abort();\n });\n const out = await runCommand(command, gone.signal);\n if (!gone.signal.aborted) send(res, HTTP_OK, out);\n return;\n }\n send(res, HTTP_NOT_FOUND, {\n ok: false,\n error: 'GET /health, or POST /cmd with one JSON command',\n });\n }\n\n function listen(): Promise<{ port: number; runDir: string }> {\n return new Promise((resolveListen, reject) => {\n http = createServer((req, res) => {\n onRequest(req, res).catch((e) => {\n if (!res.headersSent)\n send(res, HTTP_SERVER_ERROR, { ok: false, status: 'error', error: String(e) });\n else res.end();\n });\n });\n http.once('error', reject);\n http.listen(options.port ?? 0, options.host ?? '127.0.0.1', () => {\n const { port } = http!.address() as AddressInfo;\n announce(`HEADLESS_READY port=${port} runDir=${runDir}`);\n resolveListen({ port, runDir });\n });\n });\n }\n\n async function shutdown(): Promise<void> {\n if (closing) return closed;\n closing = true;\n try {\n session?.stop();\n } catch {\n /* stopping is best effort */\n }\n await flushAll();\n drainLog();\n await new Promise<void>((r) => {\n if (!http) {\n r();\n return;\n }\n http.close(() => r());\n http.closeIdleConnections?.();\n // A reply on its way (`stop`'s) gets a moment; a long poll in flight must not hold the process open.\n setTimeout(() => http?.closeAllConnections?.(), CLOSE_GRACE_MS).unref();\n });\n await new Promise<void>((r) => {\n events.end(r);\n });\n await options.onClosed?.();\n resolveClosed();\n return closed;\n }\n\n return handle;\n}\n", "import type { ChatAttachment } from '@genesislcap/foundation-ai';\nimport type { HeadlessSession, HeadlessState, InteractionDescription } from '../headless';\n\n/**\n * The wire protocol of the headless server (GENC-0 PLAN \u00A75): one JSON command in, one compact JSON reply out.\n *\n * This directory knows only `HeadlessSession` and Node built-ins. It is written so that it moves to the\n * platform as a file move (PLAN P7b): nothing in it may import the Create host or `client/src`, and\n * `headless-server-entry.test.ts` fails if anything does.\n */\n\n/** One command. `op` names it; the rest are its arguments. */\nexport interface Command {\n op: string;\n /** Echoed in the reply, so a caller can match them up. */\n id?: string | number;\n /** The cursor: events after this `seq` are reported. Default: where the log stood when the command arrived. */\n since?: number;\n /** The longest the reply waits for the journey to need the person, ms. Default 100000. */\n maxWaitMs?: number;\n /** For this command's reply only: `\"full\"` or `\"lean\"`, over the server's setting ({@link DecisionText}). */\n decisionText?: DecisionText;\n [argument: string]: unknown;\n}\n\n/**\n * Why a reply came back when it did.\n * - `decision`: an interaction is waiting for the person, and `decision` describes it.\n * - `turn`: a turn ended with nothing pending; the final text is in `since`.\n * - `error`: something failed (a turn that ended in a typed failure, an `error` event): see `since`.\n * - `needs-user`: the autopilot has stopped for the person with no interaction to show.\n * - `ended`: the run is over (the host says so, or the session was closed).\n * - `working`: `maxWaitMs` passed and the journey is still going: send `wait` with the `nextSeq`.\n * - `idle`: nothing is running or pending (a `state` reply, or a refusal while nothing is open).\n * - `edited`: an `act` ran an action that did not settle the interaction (a form field set, say). The reply is\n * at once and short: `decision` carries the actions but not the card's text, and `output` is what the action\n * returned, if anything. The card in full is `state`'s `decision.text`.\n */\nexport type Status =\n | 'decision'\n | 'turn'\n | 'error'\n | 'needs-user'\n | 'ended'\n | 'working'\n | 'idle'\n | 'edited';\n\n/**\n * How much of a decision's `text` a reply carries.\n * - `full`: all of what the platform's `renderDecision` writes, which is what the autopilot reads. For a widget\n * whose surface has a preview view that includes a `Now: <the preview view as JSON>` line.\n * - `lean`: the same, without that one line: a pointer to `read <view>` stands in its place. The card's own\n * text, its Views, Facts, Guidance and Actions are as they were, and `read` returns the full view either way.\n */\nexport type DecisionText = 'full' | 'lean';\n\nexport const DECISION_TEXTS: readonly DecisionText[] = ['full', 'lean'];\n\n/** What the server uses when neither it nor the command says. Its readers are models that can `read` a view. */\nexport const DEFAULT_DECISION_TEXT: DecisionText = 'lean';\n\n/** One event, shortened for a reader that pays for every token. `event` is its kind. */\nexport interface CompactEvent {\n event: string;\n [field: string]: unknown;\n}\n\n/** What the person is asked: a {@link InteractionDescription} cut to what a reader chooses by. */\nexport interface CompactDecision {\n interactionId: string;\n component: string;\n /**\n * The widget as the autopilot reads it: the question, its views and facts, the numbered actions. Absent from\n * a short decision (an `edited` reply, a refused `act`): the caller has the card already.\n */\n text?: string;\n actions: CompactAction[];\n /** The views `read` takes, each with what it holds. */\n views?: Record<string, string>;\n /** Present, and `false`, when the widget has no controller: only `resolve` can settle it. */\n controller?: false;\n}\n\nexport interface CompactAction {\n n?: number;\n name: string;\n label?: string;\n enabled: boolean;\n unavailable?: string;\n args?: 'options' | 'text' | 'fields';\n argsSchema?: Record<string, unknown>;\n}\n\n/** What is going on while the reply says `working`. */\nexport interface WorkingInfo {\n /** The widget someone else holds or that is not ready, when there is one. */\n component?: string;\n heldBy?: string;\n /** How long this command has waited. */\n elapsedMs: number;\n /** The host's probe, cut to the keys it shows (see {@link ServerOptions.probeEvent}). */\n probe?: Record<string, unknown>;\n /**\n * What it is doing, in words: the host's account of the widget ({@link ServerOptions.describeWorking}), or,\n * with no widget open, that the turn is the assistant's own (`assistant is thinking`) or the autopilot's.\n */\n stage?: string;\n}\n\nexport type Composer = 'open' | 'busy' | `blocked:${string}`;\n\n/** A reply. Fields with nothing to say are absent. */\nexport interface Reply {\n ok: boolean;\n id?: string | number;\n status: Status;\n /** Events after the cursor, compact. */\n since?: CompactEvent[];\n decision?: CompactDecision;\n working?: WorkingInfo;\n composer: Composer;\n cost: { usd: number };\n /** The cursor for the next call: pass it as `since`. */\n nextSeq: number;\n error?: string;\n /** A short code for a refusal, e.g. the driver's `disabled`, `invalid-args`, `not-held`. */\n reason?: string;\n [field: string]: unknown;\n}\n\n/** What an op the host registers returns. */\nexport interface ExtraOpResult {\n ok: boolean;\n error?: string;\n /** Merged into the reply as it is. */\n fields?: Record<string, unknown>;\n /** Wait for the journey after applying, as the built-in ops do. Default `true` when `ok` and a session is attached. */\n poll?: boolean;\n /**\n * Reply with the pending decision cut to its actions (no card text), as an `edited` reply does. For an op that\n * reports and does not wait, so a small answer is not followed by the whole card. Default: the full decision.\n */\n shortDecision?: boolean;\n}\n\n/** An op the host adds, such as `start`. */\nexport type ExtraOp = (command: Command, server: HeadlessServerHandle) => Promise<ExtraOpResult>;\n\n/** What an extra op may do with the server. */\nexport interface HeadlessServerHandle {\n /** Hand the server the session once it exists. Starts the event log and the turn-end flushes. */\n attach(session: HeadlessSession): void;\n readonly session: HeadlessSession | undefined;\n readonly runDir: string;\n /** The server's `decisionText` now. */\n readonly decisionText: DecisionText;\n /** Change the server's `decisionText`, for the replies that follow (a command's own still wins). */\n setDecisionText(mode: DecisionText): void;\n}\n\nexport interface ServerOptions {\n /** Where `events.jsonl` (and `debug-log.json`) go. Created if missing. */\n runDir: string;\n /** The session, when the host has one at the start. Otherwise a host op calls `attach`. */\n session?: HeadlessSession;\n /** The port to listen on. Default `0`: the OS picks one, and the ready line reports it. */\n port?: number;\n /**\n * The address to bind. Default `127.0.0.1`: no other machine reaches it. A web page open on this one\n * can still send to it, so the server refuses a request that carries an `Origin`, whose `Host` is not its\n * own address (DNS rebinding), or whose body is not `application/json`. Binding wider than loopback turns\n * the `Host` check off, and nothing then limits who may send commands.\n */\n host?: string;\n /** Ops the host adds, by name. A built-in of the same name wins, and only the names it lists are ops. */\n extraOps?: Readonly<Record<string, ExtraOp>>;\n /** Turn a `send`'s file path into an attachment. Without it `send` refuses files. */\n readAttachment?: (path: string) => Promise<ChatAttachment>;\n /**\n * Save what the host owns outside the session (its project, say). Called at every turn end, before\n * `debugLog` reports and on stop. The session's own `flush()` is called as well, after it.\n */\n flush?: () => Promise<void>;\n /** Whether the run is over, for the `ended` status. */\n isEnded?: () => boolean;\n /** Why the composer is blocked (a budget wall), when it is. */\n composerBlockedReason?: () => string | undefined;\n /**\n * How a change in the host's probe shows in `since`: an event named `name`, carrying the current value of\n * `keys`, emitted when one of them changed. Without it a `probe` event reports whichever keys changed.\n * The same keys are the probe's part of a `working` reply.\n */\n probeEvent?: { name: string; keys: readonly string[] };\n /**\n * What a widget that is working is doing, in a few words (its stage, its status line), for `working.stage`.\n * Called with the interaction's id and widget type, when a `working` reply has a widget to describe; return\n * `undefined` for one it knows nothing about. A throw is the same as `undefined`.\n */\n describeWorking?: (interactionId: string, component: string) => string | undefined;\n /** How much of a decision's text a reply carries, unless a command says. Default {@link DEFAULT_DECISION_TEXT}. */\n decisionText?: DecisionText;\n /** The default for `maxWaitMs`. Default 100000. A command's own is cut to one hour. */\n defaultMaxWaitMs?: number;\n /** Where the one ready line goes. Default `console.log`. */\n announce?: (line: string) => void;\n /** Called once the server has shut down. */\n onClosed?: () => void | Promise<void>;\n}\n\n/** The server, as `createHeadlessServer` returns it. */\nexport interface HeadlessServer extends HeadlessServerHandle {\n /** Start listening, announce `HEADLESS_READY port=<n> runDir=<path>`, and say where. */\n listen(): Promise<{ port: number; runDir: string }>;\n /**\n * Run one command, as a `POST /cmd` does. For tests, and for hosts that drive it without HTTP. Its wait\n * ends early when `signal` aborts (the caller went away); the command itself is applied either way.\n */\n handle(command: unknown, signal?: AbortSignal): Promise<Reply>;\n /** Stop: the running turn, the saves, the event log, the HTTP server. Idempotent. */\n shutdown(): Promise<void>;\n /** Resolves when {@link shutdown} has finished. */\n readonly closed: Promise<void>;\n}\n\n/** The state a reply is built from. */\nexport type SessionState = HeadlessState;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
|
+
"names": ["gone"]
|
|
7
|
+
}
|