@mirasoth/soothe-client 0.2.1 → 0.4.1

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/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/verbosity.ts","../src/events.ts","../src/helpers.ts","../src/session.ts","../src/appkit/broadcaster.ts","../src/appkit/thinking_step.ts","../src/appkit/classifier.ts","../src/appkit/query_gate.ts","../src/appkit/client.ts","../src/appkit/pool.ts","../src/appkit/turn_runner.ts"],"sourcesContent":["/**\n * Verbosity levels and tiers for event filtering.\n */\n\n/** User-configurable verbosity setting. */\nexport type VerbosityLevel = \"quiet\" | \"normal\" | \"debug\";\n\n/** Minimum verbosity level at which content is visible. */\nexport enum VerbosityTier {\n /** Always visible (errors, assistant text, final reports) */\n Quiet = 0,\n /** Standard progress (plan updates, milestones, agentic loop) */\n Normal = 1,\n /** Detailed internals (protocol events, tool calls, subagent activity) */\n Detailed = 2,\n /** Everything including internals (thinking, heartbeats) */\n Debug = 3,\n /** Never shown at any level (implementation details) */\n Internal = 99,\n}\n\nconst verbosityLevelValues: Record<VerbosityLevel, number> = {\n quiet: 0,\n normal: 1,\n debug: 3,\n};\n\n/** Returns true if content at the given tier is visible at the given verbosity. */\nexport function shouldShow(tier: VerbosityTier, verbosity: VerbosityLevel): boolean {\n if (tier === VerbosityTier.Internal) {\n return false;\n }\n const level = verbosityLevelValues[verbosity] ?? 1; // default to normal\n return tier <= level;\n}\n\n/** Checks whether a string is a valid verbosity level. */\nexport function isValidVerbosityLevel(s: string): s is VerbosityLevel {\n return s in verbosityLevelValues;\n}\n","/**\n * Client-facing event namespace constants for the Soothe daemon wire protocol.\n *\n * Internal catalog types (`soothe.internal.*`) are server-only and are never\n * broadcast to WebSocket clients. Do not add them here.\n *\n * Format: soothe.<domain>.<component>.<action>\n */\n\nimport { VerbosityTier } from \"./verbosity.js\";\n\n// Plan events (client UX)\nexport const EventPlanCreated = \"soothe.cognition.plan.created\";\n\n// Explore subagent events (built-in wire, IG-339)\nexport const EventExploreStarted = \"soothe.subagent.explore.started\";\nexport const EventExploreMilestone = \"soothe.subagent.explore.milestone\";\nexport const EventExploreStepCompleted = \"soothe.subagent.explore.step.completed\";\nexport const EventExploreCompleted = \"soothe.subagent.explore.completed\";\n\n// Tacitus subagent events (built-in wire, IG-339)\nexport const EventTacitusStarted = \"soothe.subagent.tacitus.started\";\nexport const EventTacitusGatherSummary = \"soothe.subagent.tacitus.gather.summary\";\nexport const EventTacitusCompleted = \"soothe.subagent.tacitus.completed\";\n\n// Control-plane wire envelopes (not soothe.* catalog events)\nexport const EventReplayComplete = \"replay_complete\";\nexport const EventLoopReattachedWire = \"loop_reattached\";\n\n// Card ledger replay frames (RFC-413, card_binder design)\nexport const EventCardReplayBegin = \"card.replay_begin\";\nexport const EventCardCreated = \"card.created\";\nexport const EventCardReplayEnd = \"card.replay_end\";\n\n// Tool events\nexport const EventToolStarted = \"soothe.tool.execution.started\";\nexport const EventToolCompleted = \"soothe.tool.execution.completed\";\nexport const EventToolError = \"soothe.tool.execution.error\";\n\n// Stream tool call events (RFC-450, IG-416)\nexport const EventStreamToolCallUpdate = \"soothe.stream.tool_call.update\";\nexport const EventToolCallUpdatesBatch = \"tool_call_updates_batch\";\n\n// StrangeLoop events (cognition domain)\nexport const EventStrangeLoopStarted = \"soothe.cognition.strange_loop.started\";\nexport const EventStrangeLoopCompleted = \"soothe.cognition.strange_loop.completed\";\nexport const EventStrangeLoopPlanDecision = \"soothe.cognition.strange_loop.plan.decision\";\nexport const EventStrangeLoopReasoned = \"soothe.cognition.strange_loop.reasoned\";\nexport const EventStrangeLoopStepStarted = \"soothe.cognition.strange_loop.step.started\";\nexport const EventStrangeLoopStepQueued = \"soothe.cognition.strange_loop.step.queued\";\nexport const EventStrangeLoopStepCompleted = \"soothe.cognition.strange_loop.step.completed\";\nexport const EventStrangeLoopContextCompacted = \"soothe.cognition.strange_loop.context.compacted\";\n\n// Message protocol events (client stream metadata)\nexport const EventMessageReceived = \"soothe.protocol.message.received\";\nexport const EventMessageSent = \"soothe.protocol.message.sent\";\n\n// Output events\nexport const EventFinalReport = \"soothe.output.autonomous.final_report.reported\";\n\n// Autopilot events (RFC-228)\nexport const EventAutopilotGoalStatus = \"soothe.autopilot.goal.status\";\nexport const EventAutopilotGoalProgress = \"soothe.autopilot.goal.progress\";\nexport const EventAutopilotGoalCreated = \"soothe.autopilot.goal.created\";\nexport const EventAutopilotGoalCompleted = \"soothe.autopilot.goal.completed\";\nexport const EventAutopilotWorkerAssigned = \"soothe.autopilot.worker.assigned\";\nexport const EventAutopilotWorkerUnassigned = \"soothe.autopilot.worker.unassigned\";\n\n// Error events\nexport const EventGeneralFailed = \"soothe.error.general.failed\";\n\n// ---------------------------------------------------------------------------\n// Namespace parsing\n// ---------------------------------------------------------------------------\n\n/** Splits a 4-segment event namespace into domain, component, and action. */\nexport function parseNamespace(\n ns: string,\n): { domain: string; component: string; action: string } | null {\n const parts = splitNamespace(ns);\n if (parts.length < 4 || parts[0] !== \"soothe\") {\n return null;\n }\n if (parts[1] === \"internal\") {\n return null;\n }\n return { domain: parts[1], component: parts[2], action: parts[3] };\n}\n\nfunction splitNamespace(ns: string): string[] {\n const parts: string[] = [];\n let start = 0;\n for (let i = 0; i < ns.length; i++) {\n if (ns[i] === \".\") {\n parts.push(ns.slice(start, i));\n start = i + 1;\n }\n }\n parts.push(ns.slice(start));\n return parts;\n}\n\n// ---------------------------------------------------------------------------\n// Classification\n// ---------------------------------------------------------------------------\n\n/** Returns the VerbosityTier for a given event type string. */\nexport function classifyEventVerbosity(eventTypeOrNamespace: string): VerbosityTier {\n const parsed = parseNamespace(eventTypeOrNamespace);\n if (!parsed) {\n return classifyByEventTypeString(eventTypeOrNamespace);\n }\n return classifyByDomainAndComponent(parsed.domain, parsed.component, eventTypeOrNamespace);\n}\n\nfunction classifyByDomainAndComponent(\n domain: string,\n _component: string,\n full: string,\n): VerbosityTier {\n switch (domain) {\n case \"cognition\":\n return VerbosityTier.Normal;\n case \"protocol\":\n return VerbosityTier.Detailed;\n case \"tool\":\n return VerbosityTier.Internal;\n case \"subagent\":\n return classifySubagentEvent(full);\n case \"autopilot\":\n return VerbosityTier.Normal;\n case \"output\":\n case \"error\":\n return VerbosityTier.Quiet;\n default:\n return VerbosityTier.Normal;\n }\n}\n\nfunction classifySubagentEvent(full: string): VerbosityTier {\n const parsed = parseNamespace(full);\n if (!parsed) return VerbosityTier.Normal;\n switch (parsed.action) {\n case \"started\":\n case \"completed\":\n return VerbosityTier.Normal;\n default:\n return VerbosityTier.Detailed;\n }\n}\n\nfunction classifyByEventTypeString(eventType: string): VerbosityTier {\n if (eventType === EventFinalReport || eventType === EventGeneralFailed) {\n return VerbosityTier.Quiet;\n }\n if (eventType === EventToolStarted) {\n return VerbosityTier.Internal;\n }\n return VerbosityTier.Normal;\n}\n\n// ---------------------------------------------------------------------------\n// Event classification helpers\n// ---------------------------------------------------------------------------\n\n/** Event types that represent completion milestones. */\nexport function isCompletionEvent(eventType: string): boolean {\n return (\n eventType.endsWith(\".completed\") ||\n eventType.endsWith(\".failed\") ||\n eventType === EventGeneralFailed\n );\n}\n\n/** Lifecycle subagent events (started/completed) for progress UI. */\nexport function isSubagentProgressEvent(eventType: string): boolean {\n const parsed = parseNamespace(eventType);\n if (!parsed || parsed.domain !== \"subagent\") {\n return false;\n }\n return parsed.action === \"started\" || parsed.action === \"completed\";\n}\n","/**\n * Convenience RPC helper functions for the Soothe client (RFC-450 protocol-1).\n */\n\nimport type { Client } from \"./client.js\";\nimport { defaultConfig } from \"./config.js\";\n\n/** Checks daemon status via RPC. */\nexport async function checkDaemonStatus(\n client: Client,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\"daemon_status\", {}, \"daemon_status\", timeout ?? 5_000);\n}\n\n/** Performs a composite health check: connect + handshake + status RPC. */\nexport async function isDaemonLive(wsURL: string, timeout?: number): Promise<boolean> {\n const { Client } = await import(\"./client.js\");\n const t = timeout ?? 5_000;\n const client = new Client(wsURL, defaultConfig());\n\n try {\n await client.connect();\n } catch {\n return false;\n }\n\n try {\n await checkDaemonStatus(client, t);\n return true;\n } catch {\n return false;\n } finally {\n client.close();\n }\n}\n\n/** Requests daemon shutdown via RPC. */\nexport async function requestDaemonShutdown(client: Client, timeout?: number): Promise<void> {\n const resp = await client.requestResponse(\n \"daemon_shutdown\",\n {},\n \"daemon_shutdown\",\n timeout ?? 10_000,\n );\n if (resp.status !== \"acknowledged\") {\n throw new Error(`shutdown not acknowledged: ${JSON.stringify(resp)}`);\n }\n}\n\n/** Fetches the skills catalog via RPC. */\nexport async function fetchSkillsCatalog(\n client: Client,\n timeout?: number,\n): Promise<Record<string, unknown>[]> {\n const resp = await client.requestResponse(\"skills_list\", {}, \"skills_list\", timeout ?? 15_000);\n const skillsRaw = resp.skills;\n if (!skillsRaw || !Array.isArray(skillsRaw)) return [];\n return skillsRaw.filter((s): s is Record<string, unknown> => typeof s === \"object\" && s !== null);\n}\n\n/** Fetches a daemon config section via RPC. */\nexport async function fetchConfigSection(\n client: Client,\n section: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n const resp = await client.requestResponse(\n \"config_get\",\n { section },\n \"config_get\",\n timeout ?? 5_000,\n );\n const sec = resp[section];\n if (sec && typeof sec === \"object\") {\n return sec as Record<string, unknown>;\n }\n return resp;\n}\n\n/** Requests daemon config reload via RPC. */\nexport async function requestDaemonConfigReload(\n client: Client,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\"config_reload\", {}, \"config_reload\", timeout ?? 15_000);\n}\n\n/** Requests loop history (RFC-631) and waits for the response. */\nexport async function fetchLoopHistory(\n client: Client,\n loopID: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\n \"loop_history_fetch\",\n { loop_id: loopID },\n \"loop_history_fetch\",\n timeout ?? 15_000,\n );\n}\n\n/** Submits credentials for daemon-side authentication and waits for the response. */\nexport async function authenticate(\n client: Client,\n accessKey: string,\n secretKey: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\n \"auth\",\n { access_key: accessKey, secret_key: secretKey },\n \"auth\",\n timeout ?? 15_000,\n );\n}\n\n/** Refreshes the daemon-side auth token and waits for the response. */\nexport async function refreshAuthToken(\n client: Client,\n refreshToken: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\n \"auth_refresh\",\n { refresh_token: refreshToken },\n \"auth_refresh\",\n timeout ?? 15_000,\n );\n}\n","/**\n * Session bootstrap flows, wait helpers, and connect-with-retries.\n *\n * Under protocol-1 (RFC-450) the connection handshake (connection_init /\n * connection_ack) is performed by `client.connect()`. Bootstrap therefore\n * jumps straight to loop_new + subscribe(loop_events).\n */\n\nimport type { Client } from \"./client.js\";\nimport type { Config } from \"./config.js\";\nimport { defaultConfig } from \"./config.js\";\nimport { newLoopNewMessage } from \"./protocol.js\";\nimport { DaemonError } from \"./errors.js\";\n\n// ---------------------------------------------------------------------------\n// Bootstrap flows (loop-first, RFC-503)\n// ---------------------------------------------------------------------------\n\n/**\n * loop_new (or reuse id) → subscribe(loop_events); returns the loop id.\n * The protocol-1 handshake is assumed to have completed in `client.connect()`.\n */\nexport async function bootstrapLoopSession(\n client: Client,\n resumeLoopId: string | null | undefined,\n config?: Config,\n loopNew?: import(\"./protocol.js\").LoopNewOptions,\n): Promise<string> {\n const cfg = config ?? defaultConfig();\n\n let loopId = (resumeLoopId ?? \"\").trim();\n if (!loopId) {\n const env = newLoopNewMessage(loopNew);\n const newResp = await client.requestResponse(\n env.method,\n env.params ?? {},\n \"loop_new\",\n cfg.loopStatusTimeout,\n );\n loopId = String(newResp.loop_id ?? \"\").trim();\n if (!loopId) {\n throw new Error(\"loop_new response missing loop_id\");\n }\n }\n\n // Subscribe to the loop event stream. Confirmation arrives as a `next`\n // frame; client.subscribe() handles the initial ack/error window.\n await client.subscribe(\n \"loop_events\",\n { loop_id: loopId, verbosity: cfg.verbosityLevel },\n cfg.subscriptionTimeout,\n );\n\n return loopId;\n}\n\n// ---------------------------------------------------------------------------\n// Wait helpers (use client's readEventWithTimeout internally)\n// ---------------------------------------------------------------------------\n\n/**\n * Blocks until connection_ack reports readiness \"ready\". Resolves immediately\n * if the handshake already completed during connect().\n */\nexport async function waitDaemonReady(client: Client, timeout: number): Promise<void> {\n if (client.isConnected()) return;\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n const ev = (await client.readEventWithTimeout(remaining)) as Record<string, unknown> | null;\n if (ev === null) break;\n if (ev.type === \"connection_ack\") {\n const result = (ev.result as Record<string, unknown> | undefined) ?? {};\n const state = result.readiness_state as string | undefined;\n if (state === \"ready\") return;\n throw new Error(`daemon not ready: state=${JSON.stringify(state ?? \"unknown\")}`);\n }\n }\n throw new Error(`timeout after ${timeout}ms waiting for connection_ack (ready)`);\n}\n\n/** Waits for a status message with a non-empty loop_id. */\nexport async function waitLoopStatusWithID(\n client: Client,\n timeout: number,\n): Promise<Record<string, unknown>> {\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n const ev = (await client.readEventWithTimeout(remaining)) as Record<string, unknown> | null;\n if (ev === null) break;\n\n if (ev.type === \"error\") {\n const errObj = (ev.error as { code?: number; message?: string }) ?? {};\n throw new DaemonError(errObj.code ?? -32603, errObj.message ?? \"daemon error\");\n }\n\n if (ev.type === \"status\") {\n const lid = ev.loop_id as string | undefined;\n if (lid && lid !== \"\") {\n return ev;\n }\n }\n }\n throw new Error(`timeout after ${timeout}ms waiting for status with loop_id`);\n}\n\n/** Waits for a subscription confirmation `next` matching loop id. */\nexport async function waitSubscriptionConfirmed(\n client: Client,\n wantLoopID: string,\n _wantVerbosity: string,\n timeout: number,\n): Promise<void> {\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n const ev = (await client.readEventWithTimeout(remaining)) as Record<string, unknown> | null;\n if (ev === null) break;\n if (ev.type === \"next\") {\n const payload = (ev.payload as Record<string, unknown> | undefined) ?? {};\n const lid = String(payload.loop_id ?? \"\");\n if (lid === wantLoopID && payload.success === true) return;\n continue;\n }\n if (ev.type === \"error\") {\n const errObj = (ev.error as { message?: string }) ?? {};\n throw new Error(`daemon error: ${errObj.message ?? \"subscription failed\"}`);\n }\n }\n throw new Error(`timeout after ${timeout}ms waiting for subscription confirmation`);\n}\n\n// ---------------------------------------------------------------------------\n// Connect with retries\n// ---------------------------------------------------------------------------\n\n/** Attempts to connect to the Soothe daemon with bounded retries. */\nexport async function connectWithRetries(\n client: Client,\n maxRetries?: number,\n retryDelay?: number,\n): Promise<void> {\n const retries = maxRetries && maxRetries > 0 ? maxRetries : 40;\n const delay = retryDelay && retryDelay > 0 ? retryDelay : 250;\n\n let lastErr: Error | null = null;\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n await client.connect();\n return;\n } catch (err) {\n lastErr = err as Error;\n }\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n throw new Error(\n `failed to connect after ${retries} attempts: ${lastErr?.message ?? \"unknown error\"}`,\n );\n}\n","/**\n * SSE-style pub/sub fan-out for appkit (RFC-629 Layer 1).\n *\n * Generic, string-keyed pub/sub for SSE-style event delivery. The\n * application-agnostic successor to a domain-keyed broadcaster: applications\n * convert from their domain key type to `string` at their own boundary.\n *\n * Slow consumers do not stall the broadcaster: each subscriber has a bounded\n * queue and overflowing events are dropped (drop-on-full).\n */\n\n/** One Server-Sent Event payload. The Type vocabulary is app-defined. */\nexport interface SSEEvent {\n type: string;\n data: unknown;\n}\n\n/** Per-subscriber bounded queue. Events past the cap are dropped. */\nconst SUBSCRIBER_QUEUE_CAP = 100;\n\ninterface Subscriber {\n queue: SSEEvent[];\n /** Resolvers waiting for the next event. */\n waiters: Array<(ev: SSEEvent | null) => void>;\n closed: boolean;\n}\n\n/**\n * SSEBroadcaster fans events out to all subscribers for a session id.\n * Non-blocking: a full subscriber queue drops the event so one slow consumer\n * cannot block the others.\n */\nexport class SSEBroadcaster {\n private subscribers = new Map<string, Map<string, Subscriber>>();\n private nextSubID = 0;\n\n /** Creates an empty broadcaster. */\n constructor() {}\n\n /**\n * Registers a new subscriber channel for a session id. Returns an async\n * iterable the subscriber reads events from. Unsubscribe via\n * `unsubscribe()` or `close()`.\n */\n subscribe(sessionID: string): { iterable: AsyncIterable<SSEEvent>; id: string } {\n const subID = String(this.nextSubID++);\n const sub: Subscriber = { queue: [], waiters: [], closed: false };\n let subs = this.subscribers.get(sessionID);\n if (!subs) {\n subs = new Map();\n this.subscribers.set(sessionID, subs);\n }\n subs.set(subID, sub);\n\n const iterable: AsyncIterable<SSEEvent> = {\n [Symbol.asyncIterator]() {\n return {\n next(): Promise<IteratorResult<SSEEvent>> {\n if (sub.queue.length > 0) {\n return Promise.resolve({ value: sub.queue.shift()!, done: false });\n }\n if (sub.closed) {\n return Promise.resolve({ value: undefined as unknown as SSEEvent, done: true });\n }\n return new Promise<IteratorResult<SSEEvent>>(resolve => {\n sub.waiters.push(ev => {\n if (ev === null) {\n resolve({ value: undefined as unknown as SSEEvent, done: true });\n } else {\n resolve({ value: ev, done: false });\n }\n });\n });\n },\n };\n },\n };\n return { iterable, id: subID };\n }\n\n /** Removes a subscriber by id and closes its iterable. Safe if unknown. */\n unsubscribe(sessionID: string, subID: string): void {\n const subs = this.subscribers.get(sessionID);\n if (!subs) return;\n const sub = subs.get(subID);\n if (!sub) return;\n sub.closed = true;\n for (const w of sub.waiters) w(null);\n sub.waiters = [];\n subs.delete(subID);\n if (subs.size === 0) this.subscribers.delete(sessionID);\n }\n\n /**\n * Sends an event to all subscribers for a session id. Non-blocking: a full\n * subscriber queue is skipped (drop-on-full) so one slow consumer cannot\n * block the others.\n */\n broadcast(sessionID: string, event: SSEEvent): void {\n const subs = this.subscribers.get(sessionID);\n if (!subs) return;\n for (const sub of subs.values()) {\n if (sub.closed) continue;\n if (sub.waiters.length > 0) {\n const w = sub.waiters.shift()!;\n w(event);\n } else if (sub.queue.length < SUBSCRIBER_QUEUE_CAP) {\n sub.queue.push(event);\n }\n // else: drop-on-full.\n }\n }\n\n /** Closes all subscribers for a session id and removes the entry. */\n close(sessionID: string): void {\n const subs = this.subscribers.get(sessionID);\n if (!subs) return;\n for (const sub of subs.values()) {\n sub.closed = true;\n for (const w of sub.waiters) w(null);\n sub.waiters = [];\n }\n this.subscribers.delete(sessionID);\n }\n\n /** Closes every subscriber channel across all sessions. */\n closeAll(): void {\n for (const [sessionID, subs] of this.subscribers) {\n for (const sub of subs.values()) {\n sub.closed = true;\n for (const w of sub.waiters) w(null);\n sub.waiters = [];\n }\n this.subscribers.delete(sessionID);\n }\n }\n}\n","/**\n * Thinking-step extraction for appkit (RFC-629 Layer 1).\n *\n * Maps an allowlisted progress event to one structured UI line. Free-form\n * streams (tokens, reports, reasoning) are excluded. Ported from the Go\n * appkit's thinking_step with the allowlist made configurable.\n */\n\nconst MAX_THINKING_STEP_RUNES = 280;\n\n/** Default thinking-step event allowlist (triarch's set). */\nexport const DEFAULT_THINKING_STEP_EVENTS: ReadonlySet<string> = new Set([\n \"soothe.cognition.plan.step.started\",\n \"soothe.cognition.plan.step.completed\",\n \"soothe.cognition.plan.step.failed\",\n \"soothe.lifecycle.iteration.started\",\n \"soothe.agent.loop.step.started\",\n \"soothe.agent.loop.started\",\n \"soothe.cognition.plan.batch.started\",\n \"soothe.cognition.plan.created\",\n \"soothe.cognition.goal.created\",\n \"soothe.tool.execution.started\",\n]);\n\n/**\n * Maps an allowlisted progress event to one structured UI line. Returns\n * [line, true] for a recognized event; [\"\", false] otherwise. `allow` may be\n * omitted to use the default allowlist.\n */\nexport function extractThinkingStep(\n eventType: string,\n data: Record<string, unknown> | null,\n allow?: ReadonlySet<string>,\n): [string, boolean] {\n if (!eventType || !data) return [\"\", false];\n const et = eventType.trim();\n if (!et) return [\"\", false];\n\n const allowlist = allow ?? DEFAULT_THINKING_STEP_EVENTS;\n if (!allowlist.has(et)) return [\"\", false];\n\n let line = \"\";\n switch (et) {\n case \"soothe.cognition.plan.step.started\":\n line = formatPlanStepLine(data, \"\");\n break;\n case \"soothe.cognition.plan.step.completed\":\n line = formatPlanStepLine(data, \"done\");\n break;\n case \"soothe.cognition.plan.step.failed\": {\n const stepID = strField(data, \"step_id\");\n const errMsg = strField(data, \"error\");\n if (stepID && errMsg) line = `Step ${stepID} failed: ${errMsg}`;\n else if (stepID) line = `Step ${stepID} failed`;\n else if (errMsg) line = `Step failed: ${errMsg}`;\n break;\n }\n case \"soothe.agent.loop.step.started\":\n line = formatAgentStepLine(data, \"\");\n break;\n case \"soothe.cognition.plan.batch.started\": {\n const n = data[\"parallel_count\"];\n if (typeof n === \"number\" && n > 0) line = `Running ${Math.floor(n)} steps in parallel`;\n break;\n }\n case \"soothe.cognition.plan.created\":\n case \"soothe.agent.loop.started\": {\n const g = strField(data, \"goal\");\n if (g) line = \"Goal: \" + g;\n break;\n }\n case \"soothe.cognition.goal.created\": {\n const g = strField(data, \"friendly_message\", \"description\");\n if (g) line = \"Goal: \" + g;\n break;\n }\n case \"soothe.lifecycle.iteration.started\": {\n const g = strField(data, \"goal_description\");\n if (g) line = \"Iteration: \" + g;\n break;\n }\n case \"soothe.tool.execution.started\": {\n const name = strField(data, \"tool_name\", \"name\");\n if (name) line = \"Tool: \" + name;\n break;\n }\n default:\n return [\"\", false];\n }\n\n line = line.trim();\n if (!line) return [\"\", false];\n const runes = [...line];\n if (runes.length > MAX_THINKING_STEP_RUNES) {\n line = runes.slice(0, MAX_THINKING_STEP_RUNES).join(\"\") + \"…\";\n }\n return [line, true];\n}\n\nfunction formatPlanStepLine(data: Record<string, unknown>, suffix: string): string {\n const stepID = strField(data, \"step_id\");\n const desc = strField(data, \"description\");\n if (stepID && suffix) return `Step ${stepID}: ${suffix}`;\n if (stepID && desc) return `Step ${stepID}: ${desc}`;\n if (stepID) return `Step ${stepID}`;\n if (desc && suffix) return `Step: ${suffix}`;\n if (desc) return `Step: ${desc}`;\n if (suffix) return \"Step: \" + suffix;\n return \"\";\n}\n\nfunction formatAgentStepLine(data: Record<string, unknown>, suffix: string): string {\n const stepID = strField(data, \"step_id\");\n const desc = strField(data, \"description\");\n if (stepID && desc) return `Step ${stepID}: ${desc}`;\n if (desc) return suffix ? `Step: ${suffix}` : `Step: ${desc}`;\n if (stepID) return `Step ${stepID}`;\n return \"\";\n}\n\n/** Returns the first non-empty trimmed string field among `keys`. */\nfunction strField(data: Record<string, unknown>, ...keys: string[]): string {\n for (const key of keys) {\n const v = data[key];\n if (typeof v === \"string\") {\n const s = v.trim();\n if (s) return s;\n }\n }\n return \"\";\n}\n","/**\n * Event classifier for appkit (RFC-629 Layer 1).\n *\n * Maps a stream of decoded daemon events into deliverable/streaming/terminal\n * outcomes, keyed on (namespace, mode, phase) per RFC-614/RFC-403\n * (RFC-629 constraint #4). The app-agnostic successor to triarch's\n * ProcessChatEvent, with the deliverable phase set promoted from hardcoded\n * constants to configuration.\n *\n * Event shape: a protocol-1 `next` envelope carries\n * `{type:\"next\", payload:{namespace, mode, data, loop_id}}`. The daemon\n * wraps legacy free-form frames as `{payload:{namespace, mode:<orig type>,\n * data:<orig frame>}}` (RFC-450 §9.3). The classifier inspects the payload's\n * `mode`/`data`/`namespace` and the inner message's `phase`/`type`/`content`.\n */\n\nimport { DaemonError } from \"../errors.js\";\nimport { EventFinalReport } from \"../events.js\";\nimport { DEFAULT_THINKING_STEP_EVENTS, extractThinkingStep } from \"./thinking_step.js\";\n\n/** How a processed event should end the query loop. */\nexport enum ChatEventTerminal {\n /** Accumulate content; the query is still running. */\n Continue = 0,\n /** A user-visible final reply; persist it. */\n DeliverableComplete = 1,\n /** The query failed; persist an error. */\n FailedComplete = 2,\n}\n\n/** The structured outcome of classifying one daemon event. */\nexport interface ChatEventResult {\n content?: string;\n /** User-visible progress line (not a final reply). */\n thinkingStep?: string;\n terminal: ChatEventTerminal;\n /** soothe wire event type when terminal === DeliverableComplete. */\n completionEvent?: string;\n err?: Error;\n}\n\n/**\n * Product-specific decisions an EventClassifier needs. The DeliverablePhases\n * set is the key product knob: which message `phase` values count as\n * user-facing deliverables (triarch uses quiz, goal_completion, direct_model, and\n * direct intent_hint phases text_completion, image_to_text, ocr, embed;\n * other apps pass their own).\n */\nexport interface ClassifierConfig {\n /** Recognizes loop-tagged message phases that may end a query with\n * user-facing text. Required. */\n deliverablePhases: ReadonlySet<string>;\n /** Minimum trimmed rune count for a reply to be persisted as final\n * (avoids finishing on stub ACKs like \"...\"). Defaults to 8. */\n minDeliverableRunes?: number;\n /** Optional app override of the default thinking-step event allowlist. */\n thinkingStepEvents?: ReadonlySet<string>;\n}\n\n/** Event type of the daemon's replay completion signal (internal). */\nconst EVENT_LOOP_HISTORY_REPLAYED = \"soothe.lifecycle.loop.history.replayed\";\n\n/** Maps a stream of decoded daemon events into deliverable/streaming/terminal outcomes. */\nexport class EventClassifier {\n private deliverablePhases: ReadonlySet<string>;\n private minDeliverableRunes: number;\n private thinkingStepEvents?: ReadonlySet<string>;\n\n constructor(cfg: ClassifierConfig) {\n if (!cfg.deliverablePhases) {\n throw new Error(\"appkit: ClassifierConfig.deliverablePhases must not be nil\");\n }\n this.deliverablePhases = cfg.deliverablePhases;\n this.minDeliverableRunes =\n cfg.minDeliverableRunes && cfg.minDeliverableRunes > 0 ? cfg.minDeliverableRunes : 8;\n this.thinkingStepEvents = cfg.thinkingStepEvents;\n }\n\n /**\n * Inspects one decoded event and returns its outcome. `accumulated` is the\n * running assistant text so far, used to pick the final reply when a\n * deliverable event arrives.\n */\n classify(msg: unknown, accumulated: string): ChatEventResult {\n return this.processChatEvent(msg, accumulated);\n }\n\n /**\n * Reports whether a persisted completion_event is user-facing. Uses the\n * configured deliverable phase set; recognizes the protocol output namespace\n * and final_report component as deliverable.\n */\n isDeliverableCompletionEvent(eventType: string): boolean {\n if (!eventType) return false;\n if (eventType === EventFinalReport) return true;\n if (eventType.startsWith(\"soothe.protocol.message.\")) {\n const phase = eventType.slice(\"soothe.protocol.message.\".length);\n return this.isDeliverableLoopPhase(phase);\n }\n return eventType.includes(\"soothe.output\") && eventType.includes(\"responded\");\n }\n\n isDeliverableLoopPhase(phase: string): boolean {\n return this.deliverablePhases.has(phase);\n }\n\n private deliverableResult(content: string, completionEvent: string): ChatEventResult {\n return { content, terminal: ChatEventTerminal.DeliverableComplete, completionEvent };\n }\n\n private continueResult(content: string): ChatEventResult {\n return { content, terminal: ChatEventTerminal.Continue };\n }\n\n private failedResult(err: Error): ChatEventResult {\n return { terminal: ChatEventTerminal.FailedComplete, err };\n }\n\n /** Reports whether trimmed assistant text is long enough to persist as final. */\n isSubstantiveAssistantReply(content: string): boolean {\n return [...content.trim()].length >= this.minDeliverableRunes;\n }\n\n /**\n * Picks the user-visible reply for a completed query. Only a deliverable\n * terminal result with a recognized completion event yields a final reply.\n */\n resolveDeliverableFinalContent(\n eventResult: ChatEventResult,\n _accumulated: string,\n ): [string, boolean] {\n if (eventResult.terminal !== ChatEventTerminal.DeliverableComplete) return [\"\", false];\n if (!this.isDeliverableCompletionEvent(eventResult.completionEvent ?? \"\")) return [\"\", false];\n const final = (eventResult.content ?? \"\").trim();\n if (final) return [final, true];\n return [\"\", false];\n }\n\n /** The event→outcome mapper, ported from triarch's ProcessChatEvent. */\n private processChatEvent(msg: unknown, _accumulated: string): ChatEventResult {\n if (!msg || typeof msg !== \"object\") {\n return { terminal: ChatEventTerminal.Continue };\n }\n const m = msg as Record<string, unknown>;\n const typ = m.type as string | undefined;\n\n // Protocol-1 `next` envelope: the daemon wraps legacy frames in payload.\n if (typ === \"next\") {\n return this.classifyNextEnvelope(m);\n }\n\n // Protocol-1 RPC responses / subscription confirmations arrive as\n // response/next/complete envelopes. An `error` envelope is a daemon\n // failure; everything else is a protocol-level ack (not a deliverable).\n if (\n typ === \"response\" ||\n typ === \"complete\" ||\n typ === \"receipt_response\" ||\n typ === \"connection_ack\" ||\n typ === \"status\"\n ) {\n return { terminal: ChatEventTerminal.Continue };\n }\n if (typ === \"error\") {\n const errObj = (m.error as { code?: number; message?: string; data?: unknown }) ?? {};\n const code = typeof errObj.code === \"number\" ? errObj.code : -32603;\n return this.failedResult(\n new DaemonError(code, errObj.message ?? \"daemon error\", errObj.data),\n );\n }\n\n // Legacy flat-form `event` frame (mode/data at top level).\n if (typ === \"event\") {\n return this.classifyEventPayload(\n (m.namespace as unknown) ?? null,\n (m.mode as string) ?? \"\",\n m.data,\n );\n }\n\n return { terminal: ChatEventTerminal.Continue };\n }\n\n /** Classifies a `next` envelope by projecting its payload. */\n private classifyNextEnvelope(env: Record<string, unknown>): ChatEventResult {\n const payload = (env.payload as Record<string, unknown> | undefined) ?? {};\n // The inner event frame lives in payload.data, with its own mode/data.\n const innerData = payload.data as Record<string, unknown> | undefined;\n if (innerData && typeof innerData === \"object\") {\n const innerMode = (innerData.mode as string) ?? \"\";\n if (innerMode) {\n return this.classifyEventPayload(\n (innerData.namespace as unknown) ?? payload.namespace ?? null,\n innerMode,\n innerData.data,\n );\n }\n }\n // Fallback: payload itself carries mode/data directly.\n const mode = (payload.mode as string) ?? \"\";\n if (mode) {\n return this.classifyEventPayload((payload.namespace as unknown) ?? null, mode, payload.data);\n }\n return { terminal: ChatEventTerminal.Continue };\n }\n\n /**\n * Classifies an event payload by (namespace, mode, phase). `data` may be a\n * map or an array of messages (mode=\"messages\").\n */\n private classifyEventPayload(namespace: unknown, mode: string, data: unknown): ChatEventResult {\n // Normalize namespace to a string for matching.\n const ns = namespaceToString(namespace);\n\n // Normalize data to a map for thinking-step / output extraction.\n const dataMap = normalizeEventData(data);\n\n if (dataMap) {\n let dataType = ns;\n const dt = dataMap[\"type\"];\n if (typeof dt === \"string\" && dt) dataType = dt;\n if (dataType === EVENT_LOOP_HISTORY_REPLAYED) {\n return { terminal: ChatEventTerminal.Continue };\n }\n const [step, ok] = extractThinkingStep(dataType, dataMap, this.thinkingStepEvents);\n if (ok) {\n return { thinkingStep: step, terminal: ChatEventTerminal.Continue };\n }\n }\n\n // mode=\"messages\": assistant content (streaming chunks or deliverable).\n if (mode === \"messages\") {\n const result = this.classifyMessagesMode(data, ns);\n if (result) return result;\n }\n\n if (!dataMap) {\n return { terminal: ChatEventTerminal.Continue };\n }\n\n let dataType = ns;\n const dt = dataMap[\"type\"];\n if (typeof dt === \"string\" && dt) dataType = dt;\n let completionEvent = dataType;\n if (!completionEvent) completionEvent = ns;\n\n // soothe.output / responded namespaces.\n if (\n isNamespaceMatch(ns, dataType, \"soothe.output\") ||\n isNamespaceMatch(ns, dataType, \"responded\")\n ) {\n const [content, ok] = extractContentFromData(dataMap);\n if (ok) {\n if (this.isFinalOutputEvent(dataType, ns)) {\n return this.deliverableResult(content, completionEvent);\n }\n return this.continueResult(content);\n }\n }\n\n if (\n isNamespaceMatch(ns, dataType, \"agent_loop.completed\") ||\n isNamespaceMatch(ns, dataType, \"agent_loop.reasoned\") ||\n isNamespaceMatch(ns, dataType, \"loop.completed\")\n ) {\n const [content, ok] = extractContentFromData(dataMap);\n if (ok) return this.continueResult(content);\n }\n\n if (isNamespaceMatch(ns, dataType, \"final_report\")) {\n const [content, ok] = extractContentFromData(dataMap);\n if (ok) return this.deliverableResult(content, completionEvent);\n }\n\n if (dataType.includes(\"soothe.error.\") || ns.includes(\"soothe.error.\")) {\n const errType = dataType || ns;\n const msg = dataMap[\"message\"];\n if (typeof msg === \"string\" && msg) {\n return this.failedResult(new Error(`${errType}: ${msg}`));\n }\n const [content, ok] = extractContentFromData(dataMap);\n if (ok) return this.failedResult(new Error(`${errType}: ${content}`));\n return this.failedResult(new Error(errType));\n }\n\n if (\n isNamespaceMatch(ns, dataType, \"stream\") ||\n isNamespaceMatch(ns, dataType, \"progress\") ||\n isNamespaceMatch(ns, dataType, \"tool_call_updates_batch\") ||\n isNamespaceMatch(ns, dataType, \"soothe.stream.tool_call.update\")\n ) {\n const delta = dataMap[\"delta\"];\n if (typeof delta === \"string\") return this.continueResult(delta);\n }\n\n if (\n isNamespaceMatch(ns, dataType, \"heartbeat\") ||\n isNamespaceMatch(ns, dataType, \"system.daemon\") ||\n isNamespaceMatch(ns, dataType, \"agent_loop.started\") ||\n isNamespaceMatch(ns, dataType, \"intent.classified\")\n ) {\n return { terminal: ChatEventTerminal.Continue };\n }\n\n return { terminal: ChatEventTerminal.Continue };\n }\n\n /** Classifies a mode=\"messages\" payload (array of message objects). */\n private classifyMessagesMode(data: unknown, _ns: string): ChatEventResult | null {\n const items = Array.isArray(data) ? data : null;\n if (!items || items.length === 0) return null;\n const first = items[0];\n if (!first || typeof first !== \"object\") return null;\n\n const [msgType, rawContent, phase, hasPayload] = firstMessagePayload(data);\n if (hasPayload && rawContent && isStreamingMessageType(msgType)) {\n return this.continueResult(rawContent);\n }\n\n // Loop-tagged assistant message.\n const loopMsg = loopAIMessage(data);\n if (loopMsg) {\n const content = loopMsg.content;\n if (content) {\n if (isStreamingMessageType(loopMsg.type)) {\n return this.continueResult(content);\n }\n if (\n this.isDeliverableLoopPhase(loopMsg.phase) &&\n this.isSubstantiveAssistantReply(content)\n ) {\n return this.deliverableResult(content, \"soothe.protocol.message.\" + loopMsg.phase);\n }\n return this.continueResult(content);\n }\n }\n\n // Direct-LLM assistant content (mode=messages, terminal AIMessage, no phase).\n const [directContent, directOk] = this.messagesModeAssistantContent(data);\n if (directOk && this.isSubstantiveAssistantReply(directContent)) {\n return this.deliverableResult(directContent, \"soothe.protocol.message.direct_model\");\n }\n\n if (hasPayload && rawContent) {\n if (isTerminalMessageType(msgType) || msgType === \"\") {\n if (this.isDeliverableLoopPhase(phase) && this.isSubstantiveAssistantReply(rawContent)) {\n return this.deliverableResult(rawContent, \"soothe.protocol.message.\" + phase);\n }\n return this.continueResult(rawContent);\n }\n return this.continueResult(rawContent);\n }\n return null;\n }\n\n /**\n * Extracts plain assistant text from mode=\"messages\" events that carry a\n * terminal AIMessage without loop-tagged phase metadata (legacy direct_llm turns\n * before phase tagging; prefer deliverablePhases including text_completion).\n */\n private messagesModeAssistantContent(data: unknown): [string, boolean] {\n if (!Array.isArray(data) || data.length === 0) return [\"\", false];\n const msgMap = data[0] as Record<string, unknown>;\n if (!msgMap || typeof msgMap !== \"object\") return [\"\", false];\n const phase = typeof msgMap.phase === \"string\" ? msgMap.phase.trim() : \"\";\n if (phase) return [\"\", false];\n const msgType = typeof msgMap.type === \"string\" ? msgMap.type : \"\";\n if (msgType && !isTerminalMessageType(msgType)) return [\"\", false];\n const content = extractContentFromMessage(msgMap).trim();\n if (!content) return [\"\", false];\n return [content, true];\n }\n\n /** soothe output/responded events that carry user-facing final text. */\n private isFinalOutputEvent(dataType: string, ns: string): boolean {\n const combined = dataType + \" \" + ns;\n if (combined.includes(\"final_report\")) return true;\n for (const phase of this.deliverablePhases) {\n if (combined.includes(phase)) return true;\n }\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers (module-private)\n// ---------------------------------------------------------------------------\n\nfunction isStreamingMessageType(msgType: string): boolean {\n return msgType === \"AIMessageChunk\" || msgType === \"ai_chunk\" || msgType === \"message_chunk\";\n}\n\nfunction isTerminalMessageType(msgType: string): boolean {\n return msgType === \"AIMessage\" || msgType === \"ai\" || msgType === \"assistant\";\n}\n\n/** Extracts the first message's (type, content, phase, hasPayload). */\nfunction firstMessagePayload(data: unknown): [string, string, string, boolean] {\n if (!Array.isArray(data) || data.length === 0) return [\"\", \"\", \"\", false];\n const msgMap = data[0] as Record<string, unknown>;\n if (!msgMap || typeof msgMap !== \"object\") return [\"\", \"\", \"\", false];\n const msgType = typeof msgMap.type === \"string\" ? msgMap.type : \"\";\n const phase = typeof msgMap.phase === \"string\" ? msgMap.phase : \"\";\n const content = extractContentFromMessage(msgMap);\n return [msgType, content, phase, true];\n}\n\n/** Extracts a loop-tagged assistant message (type, content, phase). */\nfunction loopAIMessage(data: unknown): { type: string; content: string; phase: string } | null {\n if (!Array.isArray(data) || data.length === 0) return null;\n const msgMap = data[0] as Record<string, unknown>;\n if (!msgMap || typeof msgMap !== \"object\") return null;\n const phase = typeof msgMap.phase === \"string\" ? msgMap.phase.trim() : \"\";\n if (!phase) return null;\n const type = typeof msgMap.type === \"string\" ? msgMap.type : \"\";\n const content = extractContentFromMessage(msgMap);\n return { type, content, phase };\n}\n\nfunction extractContentFromMessage(msgMap: Record<string, unknown>): string {\n const c = msgMap.content;\n if (typeof c === \"string\" && c) return c;\n if (Array.isArray(c) && c.length > 0) {\n let b = \"\";\n for (const item of c) {\n if (typeof item === \"string\") {\n b += item;\n continue;\n }\n if (item && typeof item === \"object\") {\n const blk = item as Record<string, unknown>;\n const t = blk.text;\n if (typeof t === \"string\") b += t;\n }\n }\n return b;\n }\n const blocks = msgMap.content_blocks;\n if (Array.isArray(blocks) && blocks.length > 0) {\n let b = \"\";\n for (const blk of blocks) {\n if (blk && typeof blk === \"object\") {\n const m = blk as Record<string, unknown>;\n const t = m.text;\n if (typeof t === \"string\") b += t;\n }\n }\n return b;\n }\n return \"\";\n}\n\nfunction extractContentFromData(data: Record<string, unknown>): [string, boolean] {\n for (const key of [\n \"final_stdout_message\",\n \"completion_summary\",\n \"content\",\n \"text\",\n \"response\",\n \"output\",\n \"message\",\n \"report\",\n ]) {\n const val = data[key];\n if (typeof val === \"string\" && val) return [val, true];\n }\n const nested = data.data;\n if (nested && typeof nested === \"object\") {\n const nm = nested as Record<string, unknown>;\n for (const key of [\n \"final_stdout_message\",\n \"completion_summary\",\n \"content\",\n \"text\",\n \"response\",\n \"output\",\n \"message\",\n \"report\",\n ]) {\n const val = nm[key];\n if (typeof val === \"string\" && val) return [val, true];\n }\n }\n return [\"\", false];\n}\n\nfunction isNamespaceMatch(ns: string, dataType: string, pattern: string): boolean {\n return dataType.includes(pattern) || ns.includes(pattern);\n}\n\n/** Normalizes a namespace value (string or string[]) to a dotted string. */\nfunction namespaceToString(namespace: unknown): string {\n if (typeof namespace === \"string\") return namespace;\n if (Array.isArray(namespace)) return namespace.filter(s => typeof s === \"string\").join(\".\");\n return \"\";\n}\n\n/** Normalizes event data to a map. Strings are parsed as JSON. */\nfunction normalizeEventData(data: unknown): Record<string, unknown> | null {\n if (data == null) return null;\n if (typeof data === \"object\" && !Array.isArray(data)) {\n return data as Record<string, unknown>;\n }\n if (typeof data === \"string\") {\n try {\n const m = JSON.parse(data);\n if (m && typeof m === \"object\" && !Array.isArray(m)) return m;\n } catch {\n return null;\n }\n }\n return null;\n}\n\n// Re-export for callers that want the default allowlist.\nexport { DEFAULT_THINKING_STEP_EVENTS };\n","/**\n * Single-flight query gate for appkit (RFC-629 Layer 1).\n *\n * Enforces single-flight query execution per session id and the\n * cancel-before-context ordering: when a query is cancelled, the daemon is\n * told to stop (command_request{command:\"cancel\"}) BEFORE the local abort\n * signal is cancelled, on a detached timeout so the caller's cancellation\n * cannot block the wire send.\n *\n * The app-agnostic successor to triarch's AcquireQuery/CancelQuery/\n * sendLoopCancelCommand.\n */\n\n/** Returned when a session already has an in-flight query. */\nexport class ErrQueryBusy extends Error {\n constructor() {\n super(\"appkit: query already in progress for session\");\n this.name = \"ErrQueryBusy\";\n }\n}\n\ninterface QueryState {\n /** Local abort for the query's timeout context. */\n abort: AbortController;\n /** Daemon-cancel sender (sends command_request{cancel} for the loop). */\n sendCancel: ((signal: AbortSignal) => Promise<void>) | null;\n}\n\n/**\n * QueryGate enforces single-flight query execution per session id.\n */\nexport class QueryGate {\n private active = new Map<string, QueryState>();\n\n /** Constructs an empty gate. */\n constructor() {}\n\n /**\n * Reserves sessionID for one agent turn. Returns ErrQueryBusy if a query is\n * already in flight. `abort` is the AbortController for the query's timeout\n * context. `sendCancel` is the daemon-cancel sender; it is invoked from\n * `cancel()` on a detached 10s timeout.\n */\n acquire(\n sessionID: string,\n abort: AbortController,\n sendCancel: ((signal: AbortSignal) => Promise<void>) | null,\n ): void {\n if (this.active.has(sessionID)) {\n throw new ErrQueryBusy();\n }\n this.active.set(sessionID, { abort, sendCancel });\n }\n\n /**\n * Cooperatively stops a running query for sessionID. Sends the daemon cancel\n * (on a detached 10s-timeout abort so caller cancellation cannot block the\n * wire send) BEFORE aborting the local context. Returns silently if no query\n * is in flight (intent already satisfied).\n */\n async cancel(sessionID: string): Promise<void> {\n const state = this.active.get(sessionID);\n if (!state) return;\n this.active.delete(sessionID);\n\n if (state.sendCancel) {\n const detached = new AbortController();\n const timer = setTimeout(() => detached.abort(), 10_000);\n try {\n await state.sendCancel(detached.signal);\n } catch {\n // Log but proceed to local cancel; the query is still stopping locally.\n } finally {\n clearTimeout(timer);\n }\n }\n state.abort.abort();\n }\n\n /**\n * Clears the gate for sessionID without sending a daemon cancel. Call when a\n * query completes normally (success or local failure) so the next turn can\n * acquire.\n */\n release(sessionID: string): void {\n this.active.delete(sessionID);\n }\n\n /** Reports whether a query is in flight for sessionID. */\n isActive(sessionID: string): boolean {\n return this.active.has(sessionID);\n }\n}\n","/**\n * ManagedClient — the subset of the core Client that appkit's ConnectionPool\n * and TurnRunner depend on (RFC-629 Layer 1).\n *\n * The concrete `Client` satisfies it; tests supply a fake. Defining it as an\n * interface lets appkit be unit-tested without a live WebSocket daemon.\n */\n\nimport type { Client, InputOptions } from \"../client.js\";\nimport type { Config } from \"../config.js\";\nimport type { DecodedMessage } from \"../protocol.js\";\nimport type { DisconnectCause } from \"../errors.js\";\n\n/**\n * ManagedClient is the subset of the core Client that appkit depends on.\n * Methods are async (TS) rather than channel-based (Go).\n */\nexport interface ManagedClient {\n /** Dials and handshakes. */\n connect(): Promise<void>;\n /** Re-dials after a drop. */\n reconnect(): Promise<void>;\n /** Resumes a loop by id and probes liveness. */\n reattachAndProbe(loopID: string): Promise<void>;\n /** Sends a fire-and-forget notification (e.g. loop_input). */\n sendMessage(msg: unknown): Promise<void>;\n /** Sends user input to the daemon (loop_input notification). */\n sendInput(text: string, options?: InputOptions): Promise<void>;\n /** Starts the read loop, returning the event stream. */\n receiveMessages(signal?: AbortSignal): AsyncGenerator<DecodedMessage>;\n /** Returns whether the connection has dropped. */\n isDisconnected(): boolean;\n /** Returns the drop cause, or null if not dropped. */\n disconnectCause(): DisconnectCause | null;\n /** Reports connection liveness. */\n isConnected(): boolean;\n /** Tears down the connection. */\n close(): void;\n}\n\n/**\n * Builds a fresh ManagedClient for a daemon URL and config. ConnectionPool\n * calls it per pooled connection. Applications may supply a custom factory\n * (e.g. wrapping Client with logging/metrics).\n */\nexport type ClientFactory = (url: string, config?: Config) => ManagedClient;\n\nimport { defaultConfig } from \"../config.js\";\nimport { Client as CoreClient } from \"../client.js\";\n\n/** Returns a ClientFactory that builds a core Client. */\nexport function defaultClientFactory(): ClientFactory {\n return (url: string, config?: Config) => {\n return new CoreClient(url, config ?? defaultConfig()) as unknown as ManagedClient;\n };\n}\n\n/**\n * Creates a new loop (loop_new + subscribe) on a connected client and returns\n * the new loop id. The default implementation calls bootstrapLoopSession;\n * apps may override it.\n */\nexport type BootstrapFunc = (\n client: ManagedClient,\n workspaceID: string,\n userID: string,\n config?: Config,\n) => Promise<string>;\n\nimport { bootstrapLoopSession } from \"../session.js\";\nimport type { LoopNewOptions } from \"../protocol.js\";\n\n/** Default bootstrap: loop_new + subscribe(loop_events). */\nexport function defaultBootstrapFunc(): BootstrapFunc {\n return async (client: ManagedClient, workspaceID: string, userID: string, config?: Config) => {\n // bootstrapLoopSession expects a Client; cast through unknown.\n const c = client as unknown as Client;\n const opts: LoopNewOptions = {\n client_workspace: workspaceID,\n user_id: userID,\n client_workspace_id: workspaceID,\n };\n return bootstrapLoopSession(c, \"\", config, opts);\n };\n}\n","/**\n * Per-session connection pool for appkit (RFC-629 Layer 1).\n *\n * Manages a pool of daemon connections, one active per session. Reuses an\n * active connection when still live, otherwise bootstraps a fresh loop\n * (loop_new + subscribe) or reattaches an existing one (loop_reattach +\n * subscribe + reattachAndProbe). Persistence of session↔loop mappings is\n * abstracted behind SessionStore.\n *\n * The app-agnostic successor to triarch's SoothePoolManager connection\n * mechanics.\n */\n\nimport { StaleLoopError } from \"../errors.js\";\nimport type { Config } from \"../config.js\";\nimport { defaultConfig } from \"../config.js\";\nimport type { DecodedMessage } from \"../protocol.js\";\nimport type { SessionStore } from \"./session_store.js\";\nimport {\n type BootstrapFunc,\n type ClientFactory,\n type ManagedClient,\n defaultBootstrapFunc,\n defaultClientFactory,\n} from \"./client.js\";\n\n/** Returned when no free connection slot is available. */\nexport class ErrPoolExhausted extends Error {\n constructor() {\n super(\"appkit: connection pool exhausted\");\n this.name = \"ErrPoolExhausted\";\n }\n}\n\n/** Configures a ConnectionPool. Zero values use defaults. */\nexport interface PoolConfig {\n poolSize: number;\n queryTimeout: number; // ms\n connectionTimeout: number; // ms\n maxIdleTime: number; // ms\n healthCheckInterval: number; // ms\n}\n\n/** Returns env-overridable defaults (mirrors triarch). */\nexport function defaultPoolConfig(): PoolConfig {\n return {\n poolSize: 1000,\n queryTimeout: 30 * 60 * 1000,\n connectionTimeout: 30_000,\n maxIdleTime: 10 * 60 * 1000,\n healthCheckInterval: 30_000,\n };\n}\n\n/** One connection slot in the pool. */\nexport class PooledConn {\n slotID: number;\n client: ManagedClient;\n eventStream: AsyncGenerator<DecodedMessage> | null = null;\n streamController: AbortController | null = null;\n sessionID = \"\";\n loopID = \"\";\n workspaceID = \"\";\n lastUsed = 0;\n\n constructor(slotID: number, client: ManagedClient) {\n this.slotID = slotID;\n this.client = client;\n }\n\n /** Reports whether the underlying client signalled a drop. */\n isDisconnected(): boolean {\n return this.client.isDisconnected();\n }\n\n isConnected(): boolean {\n return this.client.isConnected() && !this.isDisconnected();\n }\n\n getLoopID(): string {\n return this.loopID;\n }\n}\n\n/**\n * ConnectionPool manages a pool of daemon connections, one active per session.\n */\nexport class ConnectionPool {\n private cfg: PoolConfig;\n private scfg: Config;\n private factory: ClientFactory;\n private bootstrap: BootstrapFunc;\n private store: SessionStore;\n private pool: PooledConn[] = [];\n private activeSlots = new Map<string, PooledConn>();\n private nextSlotID = 1;\n private url: string;\n\n /**\n * Constructs a pool. `url` is the daemon WebSocket URL. If cfg is null,\n * defaultPoolConfig is used; if scfg is null, defaultConfig is used; nil\n * factory/bootstrap fall back to the defaults.\n */\n constructor(\n url: string,\n store: SessionStore,\n cfg?: PoolConfig | null,\n scfg?: Config | null,\n factory?: ClientFactory | null,\n ) {\n this.cfg = cfg ?? defaultPoolConfig();\n this.scfg = scfg ?? defaultConfig();\n this.factory = factory ?? defaultClientFactory();\n this.bootstrap = defaultBootstrapFunc();\n this.store = store;\n this.url = url;\n // Pre-seed the pool with up to poolSize slots.\n for (let i = 0; i < this.cfg.poolSize; i++) {\n this.pool.push(new PooledConn(this.nextSlotID++, this.factory(url, this.scfg)));\n }\n }\n\n /** Overrides the loop bootstrap function (useful for test fakes). */\n withBootstrap(f: BootstrapFunc): ConnectionPool {\n if (f) this.bootstrap = f;\n return this;\n }\n\n /**\n * Returns a live connection for sessionID, reusing an active slot or\n * bootstrapping/reattaching as needed. The caller must call `release()`\n * when done with the connection (a turn completes or the session is reset).\n */\n async acquire(\n sessionID: string,\n workspaceID: string,\n userID: string,\n _signal?: AbortSignal,\n ): Promise<PooledConn> {\n // 1. Reuse active connection when still live.\n const existing = this.activeSlots.get(sessionID);\n if (existing) {\n if (existing.isDisconnected() || !existing.isConnected()) {\n await this.release(sessionID);\n } else {\n existing.lastUsed = Date.now();\n await this.store.updateLastUsed(sessionID).catch(() => {});\n return existing;\n }\n }\n\n // 2. Pull a slot from the pool.\n const conn = this.pool.pop();\n if (!conn) throw new ErrPoolExhausted();\n this.activeSlots.set(sessionID, conn);\n\n const { loopID, ok } = await this.store\n .getLoopIDForSession(sessionID)\n .catch(() => ({ loopID: \"\", ok: false }));\n let finalLoopID = \"\";\n try {\n if (!ok || !loopID) {\n // Fresh bootstrap.\n await conn.client.connect();\n finalLoopID = await this.bootstrapNew(conn, workspaceID, userID);\n await this.store.createSession(workspaceID, sessionID, finalLoopID, \"\").catch(() => {});\n } else {\n // Reattach.\n try {\n await this.resumeAndReattach(conn, loopID);\n finalLoopID = loopID;\n } catch {\n // Reattach failed (incl. StaleLoopError) → fresh bootstrap.\n await conn.client.connect();\n finalLoopID = await this.bootstrapNew(conn, workspaceID, userID);\n await this.store.createSession(workspaceID, sessionID, finalLoopID, \"\").catch(() => {});\n }\n }\n } catch (err) {\n await this.release(sessionID);\n throw err;\n }\n\n conn.sessionID = sessionID;\n conn.loopID = finalLoopID;\n conn.workspaceID = workspaceID;\n conn.lastUsed = Date.now();\n await this.store.updateLastUsed(sessionID).catch(() => {});\n return conn;\n }\n\n /** Tears down the connection for sessionID and returns the slot. */\n async release(sessionID: string): Promise<void> {\n const conn = this.activeSlots.get(sessionID);\n if (!conn) return;\n this.activeSlots.delete(sessionID);\n if (conn.streamController) {\n conn.streamController.abort();\n conn.streamController = null;\n }\n try {\n conn.client.close();\n } catch {\n // ignore\n }\n conn.sessionID = \"\";\n conn.loopID = \"\";\n conn.eventStream = null;\n // Return a fresh slot to the pool (the closed client is spent).\n this.pool.push(new PooledConn(this.nextSlotID++, this.factory(this.url, this.scfg)));\n }\n\n /**\n * Tears down the connection for sessionID so the next acquire bootstraps\n * fresh. The store should archive the loop id so getLoopIDForSession returns\n * false next time.\n */\n async resetSession(sessionID: string): Promise<void> {\n await this.release(sessionID);\n }\n\n /** Gracefully shuts down all active connections. */\n stop(): void {\n for (const [sid, conn] of this.activeSlots) {\n if (conn.streamController) conn.streamController.abort();\n try {\n conn.client.close();\n } catch {\n // ignore\n }\n this.activeSlots.delete(sid);\n }\n }\n\n /** Stats snapshot for observability. */\n stats(): { active: number; idle: number } {\n return { active: this.activeSlots.size, idle: this.pool.length };\n }\n\n /** Bootstrap a fresh loop and start the reader. */\n private async bootstrapNew(\n conn: PooledConn,\n workspaceID: string,\n userID: string,\n ): Promise<string> {\n const loopID = await this.bootstrap(conn.client, workspaceID, userID, this.scfg);\n this.startReader(conn);\n return loopID;\n }\n\n /** Reconnect + reattach an existing loop, then start the reader. */\n private async resumeAndReattach(conn: PooledConn, loopID: string): Promise<void> {\n await conn.client.connect();\n try {\n await conn.client.reattachAndProbe(loopID);\n } catch (err) {\n if (err instanceof StaleLoopError) throw err;\n throw err;\n }\n this.startReader(conn);\n }\n\n /** Starts a receiveMessages generator and stores the stream + controller. */\n private startReader(conn: PooledConn): void {\n const controller = new AbortController();\n conn.streamController = controller;\n conn.eventStream = conn.client.receiveMessages(controller.signal);\n }\n}\n","/**\n * Turn runner for appkit (RFC-629 Layer 1).\n *\n * Executes one query turn end-to-end: acquire a pooled connection, enforce\n * single-flight, send loop_input, consume the event stream, classify events,\n * resolve the deliverable, persist the reply, and broadcast completion.\n *\n * The app-agnostic successor to triarch's ExecuteQuery.\n */\n\nimport type { PooledConn } from \"./pool.js\";\nimport { type ConnectionPool } from \"./pool.js\";\nimport { type EventClassifier, ChatEventTerminal } from \"./classifier.js\";\nimport { type QueryGate } from \"./query_gate.js\";\nimport { type SSEBroadcaster, SSEEvent } from \"./broadcaster.js\";\nimport type { SessionStore, SessionMessage } from \"./session_store.js\";\nimport type { LoopInputIntentHint } from \"../intent_hints.js\";\nimport { validateLoopInputIntentHint } from \"../intent_hints.js\";\nimport type { DecodedMessage } from \"../protocol.js\";\n\n/** Returned when a turn exceeds the configured timeout. */\nexport class ErrQueryTimeout extends Error {\n constructor() {\n super(\"appkit: query timeout\");\n this.name = \"ErrQueryTimeout\";\n }\n}\n\n/** Configures a TurnRunner. */\nexport interface TurnConfig {\n /** Per-turn deadline in ms. Defaults to 30m. */\n queryTimeout: number;\n}\n\n/** Carries optional daemon hints on a loop_input payload. */\nexport interface InputOpts {\n intentHint?: LoopInputIntentHint;\n preferredSubagent?: string;\n responseSchema?: Record<string, unknown>;\n responseSchemaName?: string;\n responseSchemaStrict?: boolean;\n}\n\n/** Optional attachment shape (IG-327: {mime_type, data(base64)}). */\nexport type Attachment = Record<string, unknown>;\n\n/**\n * Builds a loop_input payload with optional attachments. Apps build this from\n * their product modes (e.g. triarch's ask/agent/deep-research).\n */\nexport function inputMessageForLoop(\n text: string,\n loopID: string,\n attachments?: Attachment[],\n opts?: InputOpts,\n): Record<string, unknown> {\n const msg: Record<string, unknown> = { type: \"loop_input\", content: text };\n if (loopID) msg.loop_id = loopID;\n if (attachments && attachments.length > 0) msg.attachments = attachments;\n if (opts) {\n if (opts.intentHint?.trim()) {\n const hintError = validateLoopInputIntentHint(opts.intentHint);\n if (hintError) {\n throw new Error(hintError);\n }\n msg.intent_hint = opts.intentHint.trim();\n }\n if (opts.preferredSubagent?.trim()) msg.preferred_subagent = opts.preferredSubagent.trim();\n if (opts.responseSchema && Object.keys(opts.responseSchema).length > 0) {\n msg.response_schema = opts.responseSchema;\n }\n if (opts.responseSchemaName?.trim()) msg.response_schema_name = opts.responseSchemaName.trim();\n if (opts.responseSchemaStrict !== undefined)\n msg.response_schema_strict = opts.responseSchemaStrict;\n }\n return msg;\n}\n\n/** Completion hook signature. */\nexport type OnComplete = (\n sessionID: string,\n loopID: string,\n content: string,\n completionEvent: string,\n elapsedMs: number,\n) => void;\n/** Error hook signature. */\nexport type OnError = (sessionID: string, loopID: string, err: Error) => void;\n\n/**\n * TurnRunner executes one query turn end-to-end.\n */\nexport class TurnRunner {\n private pool: ConnectionPool;\n private gate: QueryGate;\n private classifier: EventClassifier;\n private store: SessionStore;\n private broadcaster: SSEBroadcaster | null;\n private cfg: TurnConfig;\n private buildInput: typeof inputMessageForLoop = inputMessageForLoop;\n private onComplete: OnComplete | null = null;\n private onError: OnError | null = null;\n\n /**\n * Constructs a TurnRunner. pool, gate, classifier, and store are required;\n * broadcaster may be null.\n */\n constructor(\n pool: ConnectionPool,\n gate: QueryGate,\n classifier: EventClassifier,\n store: SessionStore,\n broadcaster: SSEBroadcaster | null,\n cfg: TurnConfig,\n ) {\n this.pool = pool;\n this.gate = gate;\n this.classifier = classifier;\n this.store = store;\n this.broadcaster = broadcaster;\n this.cfg = { queryTimeout: cfg.queryTimeout > 0 ? cfg.queryTimeout : 30 * 60 * 1000 };\n }\n\n /** Overrides the loop_input payload builder. */\n withInputBuilder(f: typeof inputMessageForLoop): TurnRunner {\n if (f) this.buildInput = f;\n return this;\n }\n\n /** Sets a completion hook (runs inline on success). */\n withOnComplete(f: OnComplete): TurnRunner {\n this.onComplete = f;\n return this;\n }\n\n /** Sets an error hook (runs inline on failure). */\n withOnError(f: OnError): TurnRunner {\n this.onError = f;\n return this;\n }\n\n /**\n * Runs one query turn. The response is broadcast via the SSE broadcaster and\n * persisted via the SessionStore; it is not returned to the caller (SSE\n * subscribers receive it). Resolves on success; rejects on failure\n * (ErrQueryTimeout, AbortError, or a daemon/processing error).\n */\n async execute(\n sessionID: string,\n message: string,\n userID: string,\n workspaceID: string,\n attachments: Attachment[] | null,\n opts: InputOpts | null,\n signal?: AbortSignal,\n ): Promise<void> {\n let conn: PooledConn;\n try {\n conn = await this.pool.acquire(sessionID, workspaceID, userID, signal);\n } catch (err) {\n await this.persistFailed(sessionID, \"\", err as Error);\n this.broadcastError(sessionID, err as Error);\n this.onError?.(sessionID, \"\", err as Error);\n throw err;\n }\n const loopID = conn.getLoopID();\n\n const timeoutController = new AbortController();\n const timeoutMs = this.cfg.queryTimeout;\n const timer = setTimeout(() => timeoutController.abort(), timeoutMs);\n\n // Build the daemon-cancel sender for this loop; register with the gate.\n const sendCancel = async (detachedSignal: AbortSignal) => {\n await this.sendLoopCancel(detachedSignal, conn, loopID);\n };\n try {\n this.gate.acquire(sessionID, timeoutController, sendCancel);\n } catch (err) {\n clearTimeout(timer);\n await this.pool.release(sessionID);\n await this.persistFailed(sessionID, loopID, err as Error);\n this.broadcastError(sessionID, err as Error);\n this.onError?.(sessionID, loopID, err as Error);\n throw err;\n }\n\n try {\n // Send loop_input.\n const inputMsg = this.buildInput(\n message,\n loopID,\n attachments ?? undefined,\n opts ?? undefined,\n );\n try {\n await conn.client.sendMessage(inputMsg);\n } catch (err) {\n await this.persistFailed(sessionID, loopID, err as Error);\n this.broadcastError(sessionID, err as Error);\n this.onError?.(sessionID, loopID, err as Error);\n throw err;\n }\n\n const eventStream = conn.eventStream;\n if (!eventStream) {\n const err = new Error(`missing event stream for session ${sessionID} (loop ${loopID})`);\n await this.persistFailed(sessionID, loopID, err);\n this.broadcastError(sessionID, err);\n this.onError?.(sessionID, loopID, err);\n throw err;\n }\n\n let assistantContent = \"\";\n const startedAt = Date.now();\n\n // A promise that resolves when the per-turn timeout OR the caller's\n // abort signal fires, so the stream-wait loop can race against it\n // instead of blocking forever on a stalled stream.\n const abortRace = new Promise<\"timeout\" | \"caller\">(resolve => {\n const onTimeout = () => resolve(\"timeout\");\n timeoutController.signal.addEventListener(\"abort\", onTimeout, { once: true });\n if (signal) {\n const onCaller = () => resolve(\"caller\");\n signal.addEventListener(\"abort\", onCaller, { once: true });\n }\n });\n\n const iterator = eventStream[Symbol.asyncIterator]();\n\n while (true) {\n const next = iterator.next();\n const raced = await Promise.race([\n next.then(res => ({ tag: \"msg\" as const, res })),\n abortRace.then(tag => ({ tag })),\n ]);\n\n if (\"tag\" in raced && raced.tag !== \"msg\") {\n if (raced.tag === \"caller\" || signal?.aborted) {\n const err = new Error(\"aborted\");\n await this.persistFailed(sessionID, loopID, err);\n this.broadcastError(sessionID, err);\n this.onError?.(sessionID, loopID, err);\n throw err;\n }\n // Timeout: tell the daemon to stop, then persist/broadcast.\n await this.sendLoopCancel(new AbortController().signal, conn, loopID).catch(() => {});\n await this.persistFailed(sessionID, loopID, new ErrQueryTimeout());\n this.broadcastError(sessionID, new ErrQueryTimeout());\n this.onError?.(sessionID, loopID, new ErrQueryTimeout());\n throw new ErrQueryTimeout();\n }\n\n const res = (raced as { tag: \"msg\"; res: IteratorResult<DecodedMessage> }).res;\n if (res.done) {\n // Stream ended without a deliverable — treat as failure.\n const err = new Error(\"event stream closed\");\n await this.persistFailed(sessionID, loopID, err);\n this.broadcastError(sessionID, err);\n this.onError?.(sessionID, loopID, err);\n throw err;\n }\n const msg = res.value;\n\n const eventResult = this.classifier.classify(msg, assistantContent);\n if (eventResult.err && eventResult.terminal === ChatEventTerminal.FailedComplete) {\n await this.persistFailed(sessionID, loopID, eventResult.err);\n this.broadcastError(sessionID, eventResult.err);\n this.onError?.(sessionID, loopID, eventResult.err);\n throw eventResult.err;\n }\n\n const step = (eventResult.thinkingStep ?? \"\").trim();\n if (step) this.broadcastThinkingStep(sessionID, step);\n\n if (eventResult.content) {\n if (eventResult.content.startsWith(assistantContent)) {\n assistantContent = eventResult.content;\n } else {\n assistantContent += eventResult.content;\n }\n }\n\n const [final, deliverable] = this.classifier.resolveDeliverableFinalContent(\n eventResult,\n assistantContent,\n );\n if (deliverable) {\n const elapsedMs = Date.now() - startedAt;\n await this.persistResponse(\n sessionID,\n loopID,\n final,\n startedAt,\n eventResult.completionEvent ?? \"\",\n );\n this.broadcastComplete(sessionID, final);\n this.onComplete?.(sessionID, loopID, final, eventResult.completionEvent ?? \"\", elapsedMs);\n return;\n }\n }\n } finally {\n clearTimeout(timer);\n this.gate.release(sessionID);\n }\n }\n\n /** Asks the daemon to cooperatively stop the loop runner on a detached signal. */\n private async sendLoopCancel(\n _signal: AbortSignal,\n conn: PooledConn,\n loopID: string,\n ): Promise<void> {\n const lid = (loopID ?? \"\").trim();\n if (!conn || !lid) return;\n const cancelMsg = { type: \"command_request\", command: \"cancel\", loop_id: lid };\n await conn.client.sendMessage(cancelMsg);\n }\n\n private async persistResponse(\n sessionID: string,\n loopID: string,\n content: string,\n startedAt: number,\n completionEvent: string,\n ): Promise<void> {\n const msg: SessionMessage = {\n role: \"assistant\",\n content,\n metadata: {\n started_at: startedAt,\n completed_at: Date.now(),\n duration_ms: Date.now() - startedAt,\n status: \"completed\",\n completion_event: completionEvent,\n deliverable: true,\n },\n };\n await this.store.appendMessage(sessionID, msg).catch(() => {});\n }\n\n private async persistFailed(sessionID: string, _loopID: string, err: Error): Promise<void> {\n const msg: SessionMessage = {\n role: \"error\",\n content: err.message,\n metadata: { status: \"failed\", error_message: err.message },\n };\n await this.store.appendMessage(sessionID, msg).catch(() => {});\n }\n\n private broadcastThinkingStep(sessionID: string, step: string): void {\n if (!this.broadcaster) return;\n this.broadcaster.broadcast(sessionID, { type: \"delta\", data: step + \"\\n\" } as SSEEvent);\n }\n\n private broadcastComplete(sessionID: string, content: string): void {\n this.broadcaster?.broadcast(sessionID, { type: \"complete\", data: content } as SSEEvent);\n }\n\n private broadcastError(sessionID: string, err: Error): void {\n this.broadcaster?.broadcast(sessionID, { type: \"query_error\", data: err.message } as SSEEvent);\n }\n}\n"],"mappings":"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","names":["VerbosityTier","Client","ChatEventTerminal","dataType","dt","res"]}
1
+ {"version":3,"sources":["../src/session.ts","../src/command_client.ts","../src/helpers.ts","../src/appkit/broadcaster.ts","../src/appkit/thinking_step.ts","../src/appkit/classifier.ts","../src/appkit/query_gate.ts","../src/appkit/client.ts","../src/appkit/pool.ts","../src/appkit/attachments.ts","../src/appkit/turn_runner.ts","../src/appkit/chunk_filter.ts","../src/appkit/events.ts","../src/appkit/observability.ts","../src/appkit/daemon_session.ts"],"sourcesContent":["/**\n * Session bootstrap flows, wait helpers, and connect-with-retries.\n *\n * Under protocol-1 the connection handshake (connection_init /\n * connection_ack) is performed by `client.connect()`. Bootstrap therefore\n * jumps straight to loop_new + subscribe(loop_events).\n */\n\nimport type { Client } from \"./client.js\";\nimport type { Config } from \"./config.js\";\nimport { defaultConfig } from \"./config.js\";\nimport { newLoopNewMessage } from \"./protocol.js\";\nimport { DaemonError } from \"./errors.js\";\n\n// ---------------------------------------------------------------------------\n// Bootstrap flows\n// ---------------------------------------------------------------------------\n\n/**\n * loop_new (or reuse id) → subscribe(loop_events); returns the loop id.\n * The protocol-1 handshake is assumed to have completed in `client.connect()`.\n */\nexport async function bootstrapLoopSession(\n client: Client,\n resumeLoopId: string | null | undefined,\n config?: Config,\n loopNew?: import(\"./protocol.js\").LoopNewOptions,\n): Promise<string> {\n const cfg = config ?? defaultConfig();\n\n let loopId = (resumeLoopId ?? \"\").trim();\n if (!loopId) {\n const env = newLoopNewMessage(loopNew);\n const newResp = await client.requestResponse(\n env.method,\n env.params ?? {},\n \"loop_new\",\n cfg.loopStatusTimeout,\n );\n loopId = String(newResp.loop_id ?? \"\").trim();\n if (!loopId) {\n throw new Error(\"loop_new response missing loop_id\");\n }\n }\n\n // Subscribe to the loop event stream. Confirmation arrives as a `next`\n // frame; client.subscribe() handles the initial ack/error window.\n await client.subscribe(\n \"loop_events\",\n { loop_id: loopId, verbosity: cfg.verbosityLevel },\n cfg.subscriptionTimeout,\n );\n\n return loopId;\n}\n\n// ---------------------------------------------------------------------------\n// Wait helpers (use client's readEventWithTimeout internally)\n// ---------------------------------------------------------------------------\n\n/**\n * Blocks until connection_ack reports readiness \"ready\". Resolves immediately\n * if the handshake already completed during connect().\n */\nexport async function waitDaemonReady(client: Client, timeout: number): Promise<void> {\n if (client.isConnected()) return;\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n const ev = (await client.readEventWithTimeout(remaining)) as Record<string, unknown> | null;\n if (ev === null) break;\n if (ev.type === \"connection_ack\") {\n const result = (ev.result as Record<string, unknown> | undefined) ?? {};\n const state = result.readiness_state as string | undefined;\n if (state === \"ready\") return;\n throw new Error(`daemon not ready: state=${JSON.stringify(state ?? \"unknown\")}`);\n }\n }\n throw new Error(`timeout after ${timeout}ms waiting for connection_ack (ready)`);\n}\n\n/** Waits for a status message with a non-empty loop_id. */\nexport async function waitLoopStatusWithID(\n client: Client,\n timeout: number,\n): Promise<Record<string, unknown>> {\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n const ev = (await client.readEventWithTimeout(remaining)) as Record<string, unknown> | null;\n if (ev === null) break;\n\n if (ev.type === \"error\") {\n const errObj = (ev.error as { code?: number; message?: string }) ?? {};\n throw new DaemonError(errObj.code ?? -32603, errObj.message ?? \"daemon error\");\n }\n\n if (ev.type === \"status\") {\n const lid = ev.loop_id as string | undefined;\n if (lid && lid !== \"\") {\n return ev;\n }\n }\n }\n throw new Error(`timeout after ${timeout}ms waiting for status with loop_id`);\n}\n\n/** Waits for a subscription confirmation `next` matching loop id. */\nexport async function waitSubscriptionConfirmed(\n client: Client,\n wantLoopID: string,\n _wantVerbosity: string,\n timeout: number,\n): Promise<void> {\n const deadline = Date.now() + timeout;\n while (Date.now() < deadline) {\n const remaining = deadline - Date.now();\n if (remaining <= 0) break;\n const ev = (await client.readEventWithTimeout(remaining)) as Record<string, unknown> | null;\n if (ev === null) break;\n if (ev.type === \"next\") {\n const payload = (ev.payload as Record<string, unknown> | undefined) ?? {};\n const lid = String(payload.loop_id ?? \"\");\n if (lid === wantLoopID && payload.success === true) return;\n continue;\n }\n if (ev.type === \"error\") {\n const errObj = (ev.error as { message?: string }) ?? {};\n throw new Error(`daemon error: ${errObj.message ?? \"subscription failed\"}`);\n }\n }\n throw new Error(`timeout after ${timeout}ms waiting for subscription confirmation`);\n}\n\n// ---------------------------------------------------------------------------\n// Connect with retries\n// ---------------------------------------------------------------------------\n\n/** Attempts to connect to the Soothe daemon with bounded retries. */\nexport async function connectWithRetries(\n client: Client,\n maxRetries?: number,\n retryDelay?: number,\n): Promise<void> {\n const retries = maxRetries && maxRetries > 0 ? maxRetries : 40;\n const delay = retryDelay && retryDelay > 0 ? retryDelay : 250;\n\n let lastErr: Error | null = null;\n for (let attempt = 0; attempt < retries; attempt++) {\n try {\n await client.connect();\n return;\n } catch (err) {\n lastErr = err as Error;\n }\n await new Promise(resolve => setTimeout(resolve, delay));\n }\n throw new Error(\n `failed to connect after ${retries} attempts: ${lastErr?.message ?? \"unknown error\"}`,\n );\n}\n","/**\n * Ephemeral one-shot RPC client for jobs / cron / autopilot.\n * Mirrors Python AsyncCommandClient / CommandClient.\n */\n\nimport { Client } from \"./client.js\";\nimport { defaultConfig, type Config } from \"./config.js\";\nimport type { MethodName } from \"./protocol.js\";\nimport { connectWithRetries } from \"./session.js\";\n\nexport class CommandClient {\n readonly url: string;\n readonly timeoutMs: number;\n private readonly config: Config;\n\n constructor(url: string, opts?: { timeoutMs?: number; config?: Config }) {\n this.url = url;\n this.timeoutMs = opts?.timeoutMs && opts.timeoutMs > 0 ? opts.timeoutMs : 30_000;\n this.config = opts?.config ?? defaultConfig();\n }\n\n private async withClient<T>(fn: (client: Client) => Promise<T>): Promise<T> {\n const client = new Client(this.url, this.config);\n try {\n await connectWithRetries(client, 5, 250);\n return await fn(client);\n } finally {\n client.close();\n }\n }\n\n /** Generic one-shot RPC. */\n async request(\n method: MethodName,\n params: Record<string, unknown> = {},\n ): Promise<Record<string, unknown>> {\n return this.withClient(client =>\n client.requestResponse(method, params, undefined, this.timeoutMs),\n );\n }\n\n async jobCreate(goal: string, workspace = \"\"): Promise<Record<string, unknown>> {\n const params: Record<string, unknown> = { goal };\n if (workspace) params.workspace = workspace;\n return this.request(\"job_create\", params);\n }\n\n async jobStatus(jobId: string): Promise<Record<string, unknown>> {\n return this.request(\"job_status\", { job_id: jobId });\n }\n\n async jobCancel(jobId: string): Promise<Record<string, unknown>> {\n return this.request(\"job_cancel\", { job_id: jobId });\n }\n\n /** Return autopilot scheduler status (running / dreaming / pool). */\n async autopilotStatus(): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_status\");\n }\n\n /** Submit a new autopilot goal (returns goal_id). */\n async autopilotSubmit(\n description: string,\n opts?: { priority?: number; workspace?: string },\n ): Promise<Record<string, unknown>> {\n const params: Record<string, unknown> = {\n description,\n priority: opts?.priority ?? 50,\n };\n if (opts?.workspace) params.workspace = opts.workspace;\n return this.request(\"autopilot_submit\", params);\n }\n\n /** List all goals (including non-root children). */\n async autopilotListGoals(): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_list_goals\");\n }\n\n /** Fetch one goal by id. */\n async autopilotGetGoal(goalId: string): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_get_goal\", { goal_id: goalId });\n }\n\n /** Cancel a goal and its non-terminal descendants. */\n async autopilotCancelGoal(goalId: string): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_cancel_goal\", { goal_id: goalId });\n }\n\n /** Cancel every open (non-terminal) goal. */\n async autopilotCancelAll(): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_cancel_all\");\n }\n\n /** Exit dreaming mode and resume scheduling. */\n async autopilotWake(): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_wake\");\n }\n\n /** Force dreaming mode. */\n async autopilotDream(): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_dream\");\n }\n\n /** Resume a suspended or blocked goal. */\n async autopilotResume(goalId: string): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_resume\", { goal_id: goalId });\n }\n\n /** List root goals only (jobs). Prefer job* for job control. */\n async autopilotListJobs(): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_list_jobs\");\n }\n\n /** Get a root job with DAG snapshot. Prefer jobStatus / getJobDag. */\n async autopilotGetJob(jobId: string): Promise<Record<string, unknown>> {\n return this.request(\"autopilot_get_job\", { job_id: jobId });\n }\n\n async cronAdd(text: string, priority = 0): Promise<Record<string, unknown>> {\n const params: Record<string, unknown> = { text };\n if (priority > 0) params.priority = priority;\n return this.request(\"cron_add\", params);\n }\n\n async cronList(status = \"\"): Promise<Record<string, unknown>> {\n const params: Record<string, unknown> = {};\n if (status) params.status = status;\n return this.request(\"cron_list\", params);\n }\n}\n","/**\n * Convenience RPC helper functions for the Soothe client.\n */\n\nimport type { Client } from \"./client.js\";\nimport { defaultConfig } from \"./config.js\";\n\n/** Checks daemon status via RPC. */\nexport async function checkDaemonStatus(\n client: Client,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\"daemon_status\", {}, \"daemon_status\", timeout ?? 5_000);\n}\n\n/** Performs a composite health check: connect + handshake + status RPC. */\nexport async function isDaemonLive(wsURL: string, timeout?: number): Promise<boolean> {\n const { Client } = await import(\"./client.js\");\n const t = timeout ?? 5_000;\n const client = new Client(wsURL, defaultConfig());\n\n try {\n await client.connect();\n } catch {\n return false;\n }\n\n try {\n await checkDaemonStatus(client, t);\n return true;\n } catch {\n return false;\n } finally {\n client.close();\n }\n}\n\n/** Requests daemon shutdown via RPC. */\nexport async function requestDaemonShutdown(client: Client, timeout?: number): Promise<void> {\n const resp = await client.requestResponse(\n \"daemon_shutdown\",\n {},\n \"daemon_shutdown\",\n timeout ?? 10_000,\n );\n if (resp.status !== \"acknowledged\") {\n throw new Error(`shutdown not acknowledged: ${JSON.stringify(resp)}`);\n }\n}\n\n/** Fetches the skills catalog via RPC. */\nexport async function fetchSkillsCatalog(\n client: Client,\n timeout?: number,\n): Promise<Record<string, unknown>[]> {\n const resp = await client.requestResponse(\"skills_list\", {}, \"skills_list\", timeout ?? 15_000);\n const skillsRaw = resp.skills;\n if (!skillsRaw || !Array.isArray(skillsRaw)) return [];\n return skillsRaw.filter((s): s is Record<string, unknown> => typeof s === \"object\" && s !== null);\n}\n\n/** Fetches a daemon config section via RPC. */\nexport async function fetchConfigSection(\n client: Client,\n section: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n const resp = await client.requestResponse(\n \"config_get\",\n { section },\n \"config_get\",\n timeout ?? 5_000,\n );\n const sec = resp[section];\n if (sec && typeof sec === \"object\") {\n return sec as Record<string, unknown>;\n }\n return resp;\n}\n\n/** Requests daemon config reload via RPC. */\nexport async function requestDaemonConfigReload(\n client: Client,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\"config_reload\", {}, \"config_reload\", timeout ?? 15_000);\n}\n\n/** Requests loop history and waits for the response. */\nexport async function fetchLoopHistory(\n client: Client,\n loopID: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\n \"loop_history_fetch\",\n { loop_id: loopID },\n \"loop_history_fetch\",\n timeout ?? 15_000,\n );\n}\n\n/** Submits credentials for daemon-side authentication and waits for the response. */\nexport async function authenticate(\n client: Client,\n accessKey: string,\n secretKey: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\n \"auth\",\n { access_key: accessKey, secret_key: secretKey },\n \"auth\",\n timeout ?? 15_000,\n );\n}\n\n/** Refreshes the daemon-side auth token and waits for the response. */\nexport async function refreshAuthToken(\n client: Client,\n refreshToken: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.requestResponse(\n \"auth_refresh\",\n { refresh_token: refreshToken },\n \"auth_refresh\",\n timeout ?? 15_000,\n );\n}\n\n/** Fetch bound display-card snapshot for a loop. */\nexport async function fetchLoopCards(\n client: Client,\n loopID: string,\n timeout?: number,\n): Promise<Record<string, unknown>> {\n return client.fetchLoopCards(loopID, timeout);\n}\n\n/** Fetch persisted conversation/activity rows for a loop. */\nexport async function fetchLoopMessages(\n client: Client,\n loopID: string,\n opts?: { limit?: number; offset?: number; includeEvents?: boolean; timeout?: number },\n): Promise<Record<string, unknown>> {\n return client.getLoopMessages(\n loopID,\n opts?.limit,\n opts?.offset,\n opts?.includeEvents,\n opts?.timeout,\n );\n}\n\n/**\n * Connect, handshake, and yield a ready Client. Always closes in finally.\n */\nexport async function connectedWebsocket<T>(\n wsUrl: string,\n fn: (client: Client) => Promise<T>,\n timeoutMs = 30_000,\n): Promise<T> {\n const { Client } = await import(\"./client.js\");\n const client = new Client(wsUrl, defaultConfig());\n const deadline = Date.now() + timeoutMs;\n try {\n await client.connect();\n while (!client.isConnected() && Date.now() < deadline) {\n await new Promise(r => setTimeout(r, 25));\n }\n if (!client.isConnected()) {\n throw new Error(\"Timed out waiting for daemon handshake\");\n }\n return await fn(client);\n } finally {\n client.close();\n }\n}\n\n/**\n * One-shot protocol-1 RPC / notify / subscribe with dict-style error contract.\n * Callers check `if (\"error\" in response)`.\n */\nexport async function protocol1Rpc(\n wsUrl: string,\n method: string,\n params: Record<string, unknown> | null = null,\n opts: { mode?: \"request\" | \"notify\" | \"subscribe\"; timeoutMs?: number } = {},\n): Promise<Record<string, unknown>> {\n const mode = opts.mode ?? \"request\";\n const timeoutMs = opts.timeoutMs ?? 30_000;\n try {\n return await connectedWebsocket(\n wsUrl,\n async client => {\n if (mode === \"notify\") {\n await client.notify(method as import(\"./protocol.js\").MethodName, params ?? {});\n return {};\n }\n if (mode === \"subscribe\") {\n const subId = await client.subscribe(\n method as \"loop_events\" | \"autopilot_events\",\n params ?? {},\n timeoutMs,\n );\n return { subscription_id: subId };\n }\n const result = await client.requestResponse(\n method as import(\"./protocol.js\").MethodName,\n params ?? {},\n method,\n timeoutMs,\n );\n return result && typeof result === \"object\" ? result : { result };\n },\n timeoutMs,\n );\n } catch (exc) {\n const msg = exc instanceof Error ? exc.message : String(exc);\n if (msg.toLowerCase().includes(\"timed out\") || msg.toLowerCase().includes(\"timeout\")) {\n return { error: \"Timed out waiting for daemon response\" };\n }\n if (msg.toLowerCase().includes(\"connect\") || msg.toLowerCase().includes(\"dial\")) {\n return { error: `Connection error: ${msg}` };\n }\n return { error: msg };\n }\n}\n","/**\n * SSE-style pub/sub fan-out for appkit.\n *\n * Generic, string-keyed pub/sub for SSE-style event delivery. The\n * application-agnostic successor to a domain-keyed broadcaster: applications\n * convert from their domain key type to `string` at their own boundary.\n *\n * Slow consumers do not stall the broadcaster: each subscriber has a bounded\n * queue and overflowing events are dropped (drop-on-full).\n */\n\n/** One Server-Sent Event payload. The Type vocabulary is app-defined. */\nexport interface SSEEvent {\n type: string;\n data: unknown;\n}\n\n/** Per-subscriber bounded queue. Events past the cap are dropped. */\nconst SUBSCRIBER_QUEUE_CAP = 100;\n\ninterface Subscriber {\n queue: SSEEvent[];\n /** Resolvers waiting for the next event. */\n waiters: Array<(ev: SSEEvent | null) => void>;\n closed: boolean;\n}\n\n/**\n * SSEBroadcaster fans events out to all subscribers for a session id.\n * Non-blocking: a full subscriber queue drops the event so one slow consumer\n * cannot block the others.\n */\nexport class SSEBroadcaster {\n private subscribers = new Map<string, Map<string, Subscriber>>();\n private nextSubID = 0;\n\n /** Creates an empty broadcaster. */\n constructor() {}\n\n /**\n * Registers a new subscriber channel for a session id. Returns an async\n * iterable the subscriber reads events from. Unsubscribe via\n * `unsubscribe()` or `close()`.\n */\n subscribe(sessionID: string): { iterable: AsyncIterable<SSEEvent>; id: string } {\n const subID = String(this.nextSubID++);\n const sub: Subscriber = { queue: [], waiters: [], closed: false };\n let subs = this.subscribers.get(sessionID);\n if (!subs) {\n subs = new Map();\n this.subscribers.set(sessionID, subs);\n }\n subs.set(subID, sub);\n\n const iterable: AsyncIterable<SSEEvent> = {\n [Symbol.asyncIterator]() {\n return {\n next(): Promise<IteratorResult<SSEEvent>> {\n if (sub.queue.length > 0) {\n return Promise.resolve({ value: sub.queue.shift()!, done: false });\n }\n if (sub.closed) {\n return Promise.resolve({ value: undefined as unknown as SSEEvent, done: true });\n }\n return new Promise<IteratorResult<SSEEvent>>(resolve => {\n sub.waiters.push(ev => {\n if (ev === null) {\n resolve({ value: undefined as unknown as SSEEvent, done: true });\n } else {\n resolve({ value: ev, done: false });\n }\n });\n });\n },\n };\n },\n };\n return { iterable, id: subID };\n }\n\n /** Removes a subscriber by id and closes its iterable. Safe if unknown. */\n unsubscribe(sessionID: string, subID: string): void {\n const subs = this.subscribers.get(sessionID);\n if (!subs) return;\n const sub = subs.get(subID);\n if (!sub) return;\n sub.closed = true;\n for (const w of sub.waiters) w(null);\n sub.waiters = [];\n subs.delete(subID);\n if (subs.size === 0) this.subscribers.delete(sessionID);\n }\n\n /**\n * Sends an event to all subscribers for a session id. Non-blocking: a full\n * subscriber queue is skipped (drop-on-full) so one slow consumer cannot\n * block the others.\n */\n broadcast(sessionID: string, event: SSEEvent): void {\n const subs = this.subscribers.get(sessionID);\n if (!subs) return;\n for (const sub of subs.values()) {\n if (sub.closed) continue;\n if (sub.waiters.length > 0) {\n const w = sub.waiters.shift()!;\n w(event);\n } else if (sub.queue.length < SUBSCRIBER_QUEUE_CAP) {\n sub.queue.push(event);\n }\n // else: drop-on-full.\n }\n }\n\n /** Closes all subscribers for a session id and removes the entry. */\n close(sessionID: string): void {\n const subs = this.subscribers.get(sessionID);\n if (!subs) return;\n for (const sub of subs.values()) {\n sub.closed = true;\n for (const w of sub.waiters) w(null);\n sub.waiters = [];\n }\n this.subscribers.delete(sessionID);\n }\n\n /** Closes every subscriber channel across all sessions. */\n closeAll(): void {\n for (const [sessionID, subs] of this.subscribers) {\n for (const sub of subs.values()) {\n sub.closed = true;\n for (const w of sub.waiters) w(null);\n sub.waiters = [];\n }\n this.subscribers.delete(sessionID);\n }\n }\n}\n","/**\n * Thinking-step extraction for appkit.\n *\n * Maps an allowlisted progress event to one structured UI line. Free-form\n * streams (tokens, reports, reasoning) are excluded. Ported from the Go\n * appkit's thinking_step with the allowlist made configurable.\n */\n\nconst MAX_THINKING_STEP_RUNES = 280;\n\n/** Default thinking-step event allowlist (triarch's set). */\nexport const DEFAULT_THINKING_STEP_EVENTS: ReadonlySet<string> = new Set([\n \"soothe.cognition.plan.step.started\",\n \"soothe.cognition.plan.step.completed\",\n \"soothe.cognition.plan.step.failed\",\n \"soothe.lifecycle.iteration.started\",\n \"soothe.agent.loop.step.started\",\n \"soothe.agent.loop.started\",\n \"soothe.cognition.plan.batch.started\",\n \"soothe.cognition.plan.created\",\n \"soothe.cognition.goal.created\",\n \"soothe.tool.execution.started\",\n]);\n\n/**\n * Maps an allowlisted progress event to one structured UI line. Returns\n * [line, true] for a recognized event; [\"\", false] otherwise. `allow` may be\n * omitted to use the default allowlist.\n */\nexport function extractThinkingStep(\n eventType: string,\n data: Record<string, unknown> | null,\n allow?: ReadonlySet<string>,\n): [string, boolean] {\n if (!eventType || !data) return [\"\", false];\n const et = eventType.trim();\n if (!et) return [\"\", false];\n\n const allowlist = allow ?? DEFAULT_THINKING_STEP_EVENTS;\n if (!allowlist.has(et)) return [\"\", false];\n\n let line = \"\";\n switch (et) {\n case \"soothe.cognition.plan.step.started\":\n line = formatPlanStepLine(data, \"\");\n break;\n case \"soothe.cognition.plan.step.completed\":\n line = formatPlanStepLine(data, \"done\");\n break;\n case \"soothe.cognition.plan.step.failed\": {\n const stepID = strField(data, \"step_id\");\n const errMsg = strField(data, \"error\");\n if (stepID && errMsg) line = `Step ${stepID} failed: ${errMsg}`;\n else if (stepID) line = `Step ${stepID} failed`;\n else if (errMsg) line = `Step failed: ${errMsg}`;\n break;\n }\n case \"soothe.agent.loop.step.started\":\n line = formatAgentStepLine(data, \"\");\n break;\n case \"soothe.cognition.plan.batch.started\": {\n const n = data[\"parallel_count\"];\n if (typeof n === \"number\" && n > 0) line = `Running ${Math.floor(n)} steps in parallel`;\n break;\n }\n case \"soothe.cognition.plan.created\":\n case \"soothe.agent.loop.started\": {\n const g = strField(data, \"goal\");\n if (g) line = \"Goal: \" + g;\n break;\n }\n case \"soothe.cognition.goal.created\": {\n const g = strField(data, \"friendly_message\", \"description\");\n if (g) line = \"Goal: \" + g;\n break;\n }\n case \"soothe.lifecycle.iteration.started\": {\n const g = strField(data, \"goal_description\");\n if (g) line = \"Iteration: \" + g;\n break;\n }\n case \"soothe.tool.execution.started\": {\n const name = strField(data, \"tool_name\", \"name\");\n if (name) line = \"Tool: \" + name;\n break;\n }\n default:\n return [\"\", false];\n }\n\n line = line.trim();\n if (!line) return [\"\", false];\n const runes = [...line];\n if (runes.length > MAX_THINKING_STEP_RUNES) {\n line = runes.slice(0, MAX_THINKING_STEP_RUNES).join(\"\") + \"…\";\n }\n return [line, true];\n}\n\nfunction formatPlanStepLine(data: Record<string, unknown>, suffix: string): string {\n const stepID = strField(data, \"step_id\");\n const desc = strField(data, \"description\");\n if (stepID && suffix) return `Step ${stepID}: ${suffix}`;\n if (stepID && desc) return `Step ${stepID}: ${desc}`;\n if (stepID) return `Step ${stepID}`;\n if (desc && suffix) return `Step: ${suffix}`;\n if (desc) return `Step: ${desc}`;\n if (suffix) return \"Step: \" + suffix;\n return \"\";\n}\n\nfunction formatAgentStepLine(data: Record<string, unknown>, suffix: string): string {\n const stepID = strField(data, \"step_id\");\n const desc = strField(data, \"description\");\n if (stepID && desc) return `Step ${stepID}: ${desc}`;\n if (desc) return suffix ? `Step: ${suffix}` : `Step: ${desc}`;\n if (stepID) return `Step ${stepID}`;\n return \"\";\n}\n\n/** Returns the first non-empty trimmed string field among `keys`. */\nfunction strField(data: Record<string, unknown>, ...keys: string[]): string {\n for (const key of keys) {\n const v = data[key];\n if (typeof v === \"string\") {\n const s = v.trim();\n if (s) return s;\n }\n }\n return \"\";\n}\n","/**\n * Event classifier for appkit.\n *\n * Maps a stream of decoded daemon events into deliverable/streaming/terminal\n * outcomes, keyed on (namespace, mode, phase). The app-agnostic successor to\n * product-specific ProcessChatEvent helpers, with the deliverable phase set\n * promoted from hardcoded constants to configuration.\n *\n * Event shape: a protocol-1 `next` envelope carries\n * `{type:\"next\", payload:{namespace, mode, data, loop_id}}`. The daemon\n * wraps legacy free-form frames as `{payload:{namespace, mode:<orig type>,\n * data:<orig frame>}}`. The classifier inspects the payload's\n * `mode`/`data`/`namespace` and the inner message's `phase`/`type`/`content`.\n */\n\nimport { DaemonError } from \"../errors.js\";\nimport { EventFinalReport } from \"../events.js\";\nimport { DEFAULT_THINKING_STEP_EVENTS, extractThinkingStep } from \"./thinking_step.js\";\n\n/** How a processed event should end the query loop. */\nexport enum ChatEventTerminal {\n /** Accumulate content; the query is still running. */\n Continue = 0,\n /** A user-visible final reply; persist it. */\n DeliverableComplete = 1,\n /** The query failed; persist an error. */\n FailedComplete = 2,\n}\n\n/** The structured outcome of classifying one daemon event. */\nexport interface ChatEventResult {\n content?: string;\n /** User-visible progress line (not a final reply). */\n thinkingStep?: string;\n terminal: ChatEventTerminal;\n /** soothe wire event type when terminal === DeliverableComplete. */\n completionEvent?: string;\n err?: Error;\n}\n\n/**\n * Product-specific decisions an EventClassifier needs. The DeliverablePhases\n * set is the key product knob: which message `phase` values count as\n * user-facing deliverables (triarch uses quiz, goal_completion, direct_model, and\n * direct intent_hint phases text_completion, image_to_text, ocr, embed;\n * other apps pass their own).\n */\nexport interface ClassifierConfig {\n /** Recognizes loop-tagged message phases that may end a query with\n * user-facing text. Required. */\n deliverablePhases: ReadonlySet<string>;\n /** Minimum trimmed rune count for a reply to be persisted as final\n * (avoids finishing on stub ACKs like \"...\"). Defaults to 8. */\n minDeliverableRunes?: number;\n /** Optional app override of the default thinking-step event allowlist. */\n thinkingStepEvents?: ReadonlySet<string>;\n /**\n * When true, a status frame with state=idle and non-empty accumulated\n * assistant text is DeliverableComplete (typical for direct-model turns).\n * Default false keeps Continue-on-status behaviour.\n */\n treatStatusIdleAsComplete?: boolean;\n}\n\n/** Event type of the daemon's replay completion signal (internal). */\nconst EVENT_LOOP_HISTORY_REPLAYED = \"soothe.lifecycle.loop.history.replayed\";\n\n/** Maps a stream of decoded daemon events into deliverable/streaming/terminal outcomes. */\nexport class EventClassifier {\n private deliverablePhases: ReadonlySet<string>;\n private minDeliverableRunes: number;\n private thinkingStepEvents?: ReadonlySet<string>;\n private treatStatusIdleAsComplete: boolean;\n\n constructor(cfg: ClassifierConfig) {\n if (!cfg.deliverablePhases) {\n throw new Error(\"appkit: ClassifierConfig.deliverablePhases must not be nil\");\n }\n this.deliverablePhases = cfg.deliverablePhases;\n this.minDeliverableRunes =\n cfg.minDeliverableRunes && cfg.minDeliverableRunes > 0 ? cfg.minDeliverableRunes : 8;\n this.thinkingStepEvents = cfg.thinkingStepEvents;\n this.treatStatusIdleAsComplete = Boolean(cfg.treatStatusIdleAsComplete);\n }\n\n /**\n * Inspects one decoded event and returns its outcome. `accumulated` is the\n * running assistant text so far, used to pick the final reply when a\n * deliverable event arrives.\n */\n classify(msg: unknown, accumulated: string): ChatEventResult {\n return this.processChatEvent(msg, accumulated);\n }\n\n /**\n * Reports whether a persisted completion_event is user-facing. Uses the\n * configured deliverable phase set; recognizes the protocol output namespace\n * and final_report component as deliverable.\n */\n isDeliverableCompletionEvent(eventType: string): boolean {\n if (!eventType) return false;\n switch (eventType) {\n case \"status.idle\":\n case \"idle_timeout\":\n case \"query_timeout\":\n case \"stream_closed\":\n return true;\n }\n if (eventType === EventFinalReport) return true;\n if (eventType.startsWith(\"soothe.protocol.message.\")) {\n const phase = eventType.slice(\"soothe.protocol.message.\".length);\n return this.isDeliverableLoopPhase(phase);\n }\n return eventType.includes(\"soothe.output\") && eventType.includes(\"responded\");\n }\n\n isDeliverableLoopPhase(phase: string): boolean {\n return this.deliverablePhases.has(phase);\n }\n\n private deliverableResult(content: string, completionEvent: string): ChatEventResult {\n return { content, terminal: ChatEventTerminal.DeliverableComplete, completionEvent };\n }\n\n private continueResult(content: string): ChatEventResult {\n return { content, terminal: ChatEventTerminal.Continue };\n }\n\n private failedResult(err: Error): ChatEventResult {\n return { terminal: ChatEventTerminal.FailedComplete, err };\n }\n\n /** Reports whether trimmed assistant text is long enough to persist as final. */\n isSubstantiveAssistantReply(content: string): boolean {\n return [...content.trim()].length >= this.minDeliverableRunes;\n }\n\n /**\n * Picks the user-visible reply for a completed query. Only a deliverable\n * terminal result with a recognized completion event yields a final reply.\n */\n resolveDeliverableFinalContent(\n eventResult: ChatEventResult,\n _accumulated: string,\n ): [string, boolean] {\n if (eventResult.terminal !== ChatEventTerminal.DeliverableComplete) return [\"\", false];\n if (!this.isDeliverableCompletionEvent(eventResult.completionEvent ?? \"\")) return [\"\", false];\n const final = (eventResult.content ?? \"\").trim();\n if (final) return [final, true];\n return [\"\", false];\n }\n\n /** The event→outcome mapper, ported from triarch's ProcessChatEvent. */\n private processChatEvent(msg: unknown, accumulated: string): ChatEventResult {\n if (!msg || typeof msg !== \"object\") {\n return { terminal: ChatEventTerminal.Continue };\n }\n const m = msg as Record<string, unknown>;\n const typ = m.type as string | undefined;\n\n // Protocol-1 `next` envelope: the daemon wraps legacy frames in payload.\n if (typ === \"next\") {\n return this.classifyNextEnvelope(m, accumulated);\n }\n\n // Protocol-1 RPC responses / subscription confirmations arrive as\n // response/next/complete envelopes. An `error` envelope is a daemon\n // failure; everything else is a protocol-level ack (not a deliverable).\n if (\n typ === \"response\" ||\n typ === \"complete\" ||\n typ === \"receipt_response\" ||\n typ === \"connection_ack\"\n ) {\n return { terminal: ChatEventTerminal.Continue };\n }\n if (typ === \"status\") {\n if (\n this.treatStatusIdleAsComplete &&\n String(m.state ?? \"\")\n .trim()\n .toLowerCase() === \"idle\" &&\n this.isSubstantiveAssistantReply(accumulated)\n ) {\n return this.deliverableResult(accumulated.trim(), \"status.idle\");\n }\n return { terminal: ChatEventTerminal.Continue };\n }\n if (typ === \"error\") {\n const errObj = (m.error as { code?: number; message?: string; data?: unknown }) ?? {};\n const code = typeof errObj.code === \"number\" ? errObj.code : -32603;\n return this.failedResult(\n new DaemonError(code, errObj.message ?? \"daemon error\", errObj.data),\n );\n }\n\n // Legacy flat-form `event` frame (mode/data at top level).\n if (typ === \"event\") {\n return this.classifyEventPayload(\n (m.namespace as unknown) ?? null,\n (m.mode as string) ?? \"\",\n m.data,\n );\n }\n\n return { terminal: ChatEventTerminal.Continue };\n }\n\n /** Classifies a `next` envelope by projecting its payload. */\n private classifyNextEnvelope(env: Record<string, unknown>, accumulated: string): ChatEventResult {\n const payload = (env.payload as Record<string, unknown> | undefined) ?? {};\n // The inner event frame lives in payload.data, with its own mode/data.\n const innerData = payload.data as Record<string, unknown> | undefined;\n if (innerData && typeof innerData === \"object\") {\n const innerType = (innerData.type as string) ?? \"\";\n if (innerType === \"status\") {\n return this.processChatEvent(innerData, accumulated);\n }\n const innerMode = (innerData.mode as string) ?? \"\";\n if (innerMode) {\n return this.classifyEventPayload(\n (innerData.namespace as unknown) ?? payload.namespace ?? null,\n innerMode,\n innerData.data,\n );\n }\n }\n // Fallback: payload itself carries mode/data directly.\n const mode = (payload.mode as string) ?? \"\";\n if (mode === \"status\" || mode === \"\") {\n if (typeof payload.state === \"string\" || (innerData && \"state\" in (innerData ?? {}))) {\n return this.processChatEvent({ type: \"status\", ...(innerData ?? payload) }, accumulated);\n }\n }\n if (mode) {\n return this.classifyEventPayload((payload.namespace as unknown) ?? null, mode, payload.data);\n }\n return { terminal: ChatEventTerminal.Continue };\n }\n\n /**\n * Classifies an event payload by (namespace, mode, phase). `data` may be a\n * map or an array of messages (mode=\"messages\").\n */\n private classifyEventPayload(namespace: unknown, mode: string, data: unknown): ChatEventResult {\n // Normalize namespace to a string for matching.\n const ns = namespaceToString(namespace);\n\n // Normalize data to a map for thinking-step / output extraction.\n const dataMap = normalizeEventData(data);\n\n if (dataMap) {\n let dataType = ns;\n const dt = dataMap[\"type\"];\n if (typeof dt === \"string\" && dt) dataType = dt;\n if (dataType === EVENT_LOOP_HISTORY_REPLAYED) {\n return { terminal: ChatEventTerminal.Continue };\n }\n const [step, ok] = extractThinkingStep(dataType, dataMap, this.thinkingStepEvents);\n if (ok) {\n return { thinkingStep: step, terminal: ChatEventTerminal.Continue };\n }\n }\n\n // mode=\"messages\": assistant content (streaming chunks or deliverable).\n if (mode === \"messages\") {\n const result = this.classifyMessagesMode(data, ns);\n if (result) return result;\n }\n\n if (!dataMap) {\n return { terminal: ChatEventTerminal.Continue };\n }\n\n let dataType = ns;\n const dt = dataMap[\"type\"];\n if (typeof dt === \"string\" && dt) dataType = dt;\n let completionEvent = dataType;\n if (!completionEvent) completionEvent = ns;\n\n // soothe.output / responded namespaces.\n if (\n isNamespaceMatch(ns, dataType, \"soothe.output\") ||\n isNamespaceMatch(ns, dataType, \"responded\")\n ) {\n const [content, ok] = extractContentFromData(dataMap);\n if (ok) {\n if (this.isFinalOutputEvent(dataType, ns)) {\n return this.deliverableResult(content, completionEvent);\n }\n return this.continueResult(content);\n }\n }\n\n if (\n isNamespaceMatch(ns, dataType, \"agent_loop.completed\") ||\n isNamespaceMatch(ns, dataType, \"agent_loop.reasoned\") ||\n isNamespaceMatch(ns, dataType, \"loop.completed\")\n ) {\n const [content, ok] = extractContentFromData(dataMap);\n if (ok) return this.continueResult(content);\n }\n\n if (isNamespaceMatch(ns, dataType, \"final_report\")) {\n const [content, ok] = extractContentFromData(dataMap);\n if (ok) return this.deliverableResult(content, completionEvent);\n }\n\n if (dataType.includes(\"soothe.error.\") || ns.includes(\"soothe.error.\")) {\n const errType = dataType || ns;\n const msg = dataMap[\"message\"];\n if (typeof msg === \"string\" && msg) {\n return this.failedResult(new Error(`${errType}: ${msg}`));\n }\n const [content, ok] = extractContentFromData(dataMap);\n if (ok) return this.failedResult(new Error(`${errType}: ${content}`));\n return this.failedResult(new Error(errType));\n }\n\n if (\n isNamespaceMatch(ns, dataType, \"stream\") ||\n isNamespaceMatch(ns, dataType, \"progress\") ||\n isNamespaceMatch(ns, dataType, \"tool_call_updates_batch\") ||\n isNamespaceMatch(ns, dataType, \"soothe.stream.tool_call.update\")\n ) {\n const delta = dataMap[\"delta\"];\n if (typeof delta === \"string\") return this.continueResult(delta);\n }\n\n if (\n isNamespaceMatch(ns, dataType, \"heartbeat\") ||\n isNamespaceMatch(ns, dataType, \"system.daemon\") ||\n isNamespaceMatch(ns, dataType, \"agent_loop.started\") ||\n isNamespaceMatch(ns, dataType, \"intent.classified\")\n ) {\n return { terminal: ChatEventTerminal.Continue };\n }\n\n return { terminal: ChatEventTerminal.Continue };\n }\n\n /** Classifies a mode=\"messages\" payload (array of message objects). */\n private classifyMessagesMode(data: unknown, _ns: string): ChatEventResult | null {\n const items = Array.isArray(data) ? data : null;\n if (!items || items.length === 0) return null;\n const first = items[0];\n if (!first || typeof first !== \"object\") return null;\n\n const [msgType, rawContent, phase, hasPayload] = firstMessagePayload(data);\n if (hasPayload && rawContent && isStreamingMessageType(msgType)) {\n return this.continueResult(rawContent);\n }\n\n // Loop-tagged assistant message.\n const loopMsg = loopAIMessage(data);\n if (loopMsg) {\n const content = loopMsg.content;\n if (content) {\n if (isStreamingMessageType(loopMsg.type)) {\n return this.continueResult(content);\n }\n if (\n this.isDeliverableLoopPhase(loopMsg.phase) &&\n this.isSubstantiveAssistantReply(content)\n ) {\n return this.deliverableResult(content, \"soothe.protocol.message.\" + loopMsg.phase);\n }\n return this.continueResult(content);\n }\n }\n\n // Direct-LLM assistant content (mode=messages, terminal AIMessage, no phase).\n const [directContent, directOk] = this.messagesModeAssistantContent(data);\n if (directOk && this.isSubstantiveAssistantReply(directContent)) {\n return this.deliverableResult(directContent, \"soothe.protocol.message.direct_model\");\n }\n\n if (hasPayload && rawContent) {\n if (isTerminalMessageType(msgType) || msgType === \"\") {\n if (this.isDeliverableLoopPhase(phase) && this.isSubstantiveAssistantReply(rawContent)) {\n return this.deliverableResult(rawContent, \"soothe.protocol.message.\" + phase);\n }\n return this.continueResult(rawContent);\n }\n return this.continueResult(rawContent);\n }\n return null;\n }\n\n /**\n * Extracts plain assistant text from mode=\"messages\" events that carry a\n * terminal AIMessage without loop-tagged phase metadata (legacy direct_llm turns\n * before phase tagging; prefer deliverablePhases including text_completion).\n */\n private messagesModeAssistantContent(data: unknown): [string, boolean] {\n if (!Array.isArray(data) || data.length === 0) return [\"\", false];\n const msgMap = data[0] as Record<string, unknown>;\n if (!msgMap || typeof msgMap !== \"object\") return [\"\", false];\n const phase = typeof msgMap.phase === \"string\" ? msgMap.phase.trim() : \"\";\n if (phase) return [\"\", false];\n const msgType = typeof msgMap.type === \"string\" ? msgMap.type : \"\";\n if (msgType && !isTerminalMessageType(msgType)) return [\"\", false];\n const content = extractContentFromMessage(msgMap).trim();\n if (!content) return [\"\", false];\n return [content, true];\n }\n\n /** soothe output/responded events that carry user-facing final text. */\n private isFinalOutputEvent(dataType: string, ns: string): boolean {\n const combined = dataType + \" \" + ns;\n if (combined.includes(\"final_report\")) return true;\n for (const phase of this.deliverablePhases) {\n if (combined.includes(phase)) return true;\n }\n return false;\n }\n}\n\n// ---------------------------------------------------------------------------\n// Helpers (module-private)\n// ---------------------------------------------------------------------------\n\nfunction isStreamingMessageType(msgType: string): boolean {\n return msgType === \"AIMessageChunk\" || msgType === \"ai_chunk\" || msgType === \"message_chunk\";\n}\n\nfunction isTerminalMessageType(msgType: string): boolean {\n return msgType === \"AIMessage\" || msgType === \"ai\" || msgType === \"assistant\";\n}\n\n/** Extracts the first message's (type, content, phase, hasPayload). */\nfunction firstMessagePayload(data: unknown): [string, string, string, boolean] {\n if (!Array.isArray(data) || data.length === 0) return [\"\", \"\", \"\", false];\n const msgMap = data[0] as Record<string, unknown>;\n if (!msgMap || typeof msgMap !== \"object\") return [\"\", \"\", \"\", false];\n const msgType = typeof msgMap.type === \"string\" ? msgMap.type : \"\";\n const phase = typeof msgMap.phase === \"string\" ? msgMap.phase : \"\";\n const content = extractContentFromMessage(msgMap);\n return [msgType, content, phase, true];\n}\n\n/** Extracts a loop-tagged assistant message (type, content, phase). */\nfunction loopAIMessage(data: unknown): { type: string; content: string; phase: string } | null {\n if (!Array.isArray(data) || data.length === 0) return null;\n const msgMap = data[0] as Record<string, unknown>;\n if (!msgMap || typeof msgMap !== \"object\") return null;\n const phase = typeof msgMap.phase === \"string\" ? msgMap.phase.trim() : \"\";\n if (!phase) return null;\n const type = typeof msgMap.type === \"string\" ? msgMap.type : \"\";\n const content = extractContentFromMessage(msgMap);\n return { type, content, phase };\n}\n\nfunction extractContentFromMessage(msgMap: Record<string, unknown>): string {\n const c = msgMap.content;\n if (typeof c === \"string\" && c) return c;\n if (Array.isArray(c) && c.length > 0) {\n let b = \"\";\n for (const item of c) {\n if (typeof item === \"string\") {\n b += item;\n continue;\n }\n if (item && typeof item === \"object\") {\n const blk = item as Record<string, unknown>;\n const t = blk.text;\n if (typeof t === \"string\") b += t;\n }\n }\n return b;\n }\n const blocks = msgMap.content_blocks;\n if (Array.isArray(blocks) && blocks.length > 0) {\n let b = \"\";\n for (const blk of blocks) {\n if (blk && typeof blk === \"object\") {\n const m = blk as Record<string, unknown>;\n const t = m.text;\n if (typeof t === \"string\") b += t;\n }\n }\n return b;\n }\n return \"\";\n}\n\nfunction extractContentFromData(data: Record<string, unknown>): [string, boolean] {\n for (const key of [\n \"final_stdout_message\",\n \"completion_summary\",\n \"content\",\n \"text\",\n \"response\",\n \"output\",\n \"message\",\n \"report\",\n ]) {\n const val = data[key];\n if (typeof val === \"string\" && val) return [val, true];\n }\n const nested = data.data;\n if (nested && typeof nested === \"object\") {\n const nm = nested as Record<string, unknown>;\n for (const key of [\n \"final_stdout_message\",\n \"completion_summary\",\n \"content\",\n \"text\",\n \"response\",\n \"output\",\n \"message\",\n \"report\",\n ]) {\n const val = nm[key];\n if (typeof val === \"string\" && val) return [val, true];\n }\n }\n return [\"\", false];\n}\n\nfunction isNamespaceMatch(ns: string, dataType: string, pattern: string): boolean {\n return dataType.includes(pattern) || ns.includes(pattern);\n}\n\n/** Normalizes a namespace value (string or string[]) to a dotted string. */\nfunction namespaceToString(namespace: unknown): string {\n if (typeof namespace === \"string\") return namespace;\n if (Array.isArray(namespace)) return namespace.filter(s => typeof s === \"string\").join(\".\");\n return \"\";\n}\n\n/** Normalizes event data to a map. Strings are parsed as JSON. */\nfunction normalizeEventData(data: unknown): Record<string, unknown> | null {\n if (data == null) return null;\n if (typeof data === \"object\" && !Array.isArray(data)) {\n return data as Record<string, unknown>;\n }\n if (typeof data === \"string\") {\n try {\n const m = JSON.parse(data);\n if (m && typeof m === \"object\" && !Array.isArray(m)) return m;\n } catch {\n return null;\n }\n }\n return null;\n}\n\n// Re-export for callers that want the default allowlist.\nexport { DEFAULT_THINKING_STEP_EVENTS };\n","/**\n * Single-flight query gate for appkit.\n *\n * Enforces single-flight query execution per session id and the\n * cancel-before-context ordering: when a query is cancelled, the daemon is\n * told to stop (command_request{command:\"cancel\"}) BEFORE the local abort\n * signal is cancelled, on a detached timeout so the caller's cancellation\n * cannot block the wire send.\n *\n * The app-agnostic successor to triarch's AcquireQuery/CancelQuery/\n * sendLoopCancelCommand.\n */\n\n/** Returned when a session already has an in-flight query. */\nexport class ErrQueryBusy extends Error {\n constructor() {\n super(\"appkit: query already in progress for session\");\n this.name = \"ErrQueryBusy\";\n }\n}\n\ninterface QueryState {\n /** Local abort for the query's timeout context. */\n abort: AbortController;\n /** Daemon-cancel sender (sends command_request{cancel} for the loop). */\n sendCancel: ((signal: AbortSignal) => Promise<void>) | null;\n}\n\n/**\n * QueryGate enforces single-flight query execution per session id.\n */\nexport class QueryGate {\n private active = new Map<string, QueryState>();\n\n /** Constructs an empty gate. */\n constructor() {}\n\n /**\n * Reserves sessionID for one agent turn. Returns ErrQueryBusy if a query is\n * already in flight. `abort` is the AbortController for the query's timeout\n * context. `sendCancel` is the daemon-cancel sender; it is invoked from\n * `cancel()` on a detached 10s timeout.\n */\n acquire(\n sessionID: string,\n abort: AbortController,\n sendCancel: ((signal: AbortSignal) => Promise<void>) | null,\n ): void {\n if (this.active.has(sessionID)) {\n throw new ErrQueryBusy();\n }\n this.active.set(sessionID, { abort, sendCancel });\n }\n\n /**\n * Cooperatively stops a running query for sessionID. Sends the daemon cancel\n * (on a detached 10s-timeout abort so caller cancellation cannot block the\n * wire send) BEFORE aborting the local context. Returns silently if no query\n * is in flight (intent already satisfied).\n */\n async cancel(sessionID: string): Promise<void> {\n const state = this.active.get(sessionID);\n if (!state) return;\n this.active.delete(sessionID);\n\n if (state.sendCancel) {\n const detached = new AbortController();\n const timer = setTimeout(() => detached.abort(), 10_000);\n try {\n await state.sendCancel(detached.signal);\n } catch {\n // Log but proceed to local cancel; the query is still stopping locally.\n } finally {\n clearTimeout(timer);\n }\n }\n state.abort.abort();\n }\n\n /**\n * Clears the gate for sessionID without sending a daemon cancel. Call when a\n * query completes normally (success or local failure) so the next turn can\n * acquire.\n */\n release(sessionID: string): void {\n this.active.delete(sessionID);\n }\n\n /** Reports whether a query is in flight for sessionID. */\n isActive(sessionID: string): boolean {\n return this.active.has(sessionID);\n }\n}\n","/**\n * ManagedClient — the subset of the core Client that appkit's ConnectionPool\n * and TurnRunner depend on.\n *\n * The concrete `Client` satisfies it; tests supply a fake. Defining it as an\n * interface lets appkit be unit-tested without a live WebSocket daemon.\n */\n\nimport type { Client, InputOptions } from \"../client.js\";\nimport type { Config } from \"../config.js\";\nimport type { DecodedMessage } from \"../protocol.js\";\nimport type { DisconnectCause } from \"../errors.js\";\n\n/**\n * ManagedClient is the subset of the core Client that appkit depends on.\n * Methods are async (TS) rather than channel-based (Go).\n */\nexport interface ManagedClient {\n /** Dials and handshakes. */\n connect(): Promise<void>;\n /** Re-dials after a drop. */\n reconnect(): Promise<void>;\n /** Resumes a loop by id and probes liveness. */\n reattachAndProbe(loopID: string): Promise<void>;\n /** Sends a fire-and-forget notification (e.g. loop_input). */\n sendMessage(msg: unknown): Promise<void>;\n /** Sends user input to the daemon (loop_input notification). */\n sendInput(text: string, options?: InputOptions): Promise<void>;\n /** Starts the read loop, returning the event stream. */\n receiveMessages(signal?: AbortSignal): AsyncGenerator<DecodedMessage>;\n /** Returns whether the connection has dropped. */\n isDisconnected(): boolean;\n /** Returns the drop cause, or null if not dropped. */\n disconnectCause(): DisconnectCause | null;\n /** Reports connection liveness. */\n isConnected(): boolean;\n /** Tears down the connection. */\n close(): void;\n}\n\n/**\n * Builds a fresh ManagedClient for a daemon URL and config. ConnectionPool\n * calls it per pooled connection. Applications may supply a custom factory\n * (e.g. wrapping Client with logging/metrics).\n */\nexport type ClientFactory = (url: string, config?: Config) => ManagedClient;\n\nimport { defaultConfig } from \"../config.js\";\nimport { Client as CoreClient } from \"../client.js\";\n\n/** Returns a ClientFactory that builds a core Client. */\nexport function defaultClientFactory(): ClientFactory {\n return (url: string, config?: Config) => {\n return new CoreClient(url, config ?? defaultConfig()) as unknown as ManagedClient;\n };\n}\n\n/**\n * Creates a new loop (loop_new + subscribe) on a connected client and returns\n * the new loop id. The default implementation calls bootstrapLoopSession;\n * apps may override it.\n */\nexport type BootstrapFunc = (\n client: ManagedClient,\n workspaceID: string,\n userID: string,\n config?: Config,\n) => Promise<string>;\n\nimport { bootstrapLoopSession } from \"../session.js\";\nimport type { LoopNewOptions } from \"../protocol.js\";\n\n/** Default bootstrap: loop_new + subscribe(loop_events). */\nexport function defaultBootstrapFunc(): BootstrapFunc {\n return async (client: ManagedClient, workspaceID: string, userID: string, config?: Config) => {\n // bootstrapLoopSession expects a Client; cast through unknown.\n const c = client as unknown as Client;\n const opts: LoopNewOptions = {\n client_workspace: workspaceID,\n user_id: userID,\n client_workspace_id: workspaceID,\n };\n return bootstrapLoopSession(c, \"\", config, opts);\n };\n}\n","/**\n * Per-session connection pool for appkit.\n *\n * Manages a pool of daemon connections, one active per session. Reuses an\n * active connection when still live, otherwise bootstraps a fresh loop\n * (loop_new + subscribe) or reattaches an existing one (loop_reattach +\n * subscribe + reattachAndProbe). Persistence of session↔loop mappings is\n * abstracted behind SessionStore.\n *\n * The app-agnostic successor to triarch's SoothePoolManager connection\n * mechanics.\n */\n\nimport { StaleLoopError } from \"../errors.js\";\nimport type { Config } from \"../config.js\";\nimport { defaultConfig } from \"../config.js\";\nimport type { DecodedMessage } from \"../protocol.js\";\nimport type { SessionStore } from \"./session_store.js\";\nimport {\n type BootstrapFunc,\n type ClientFactory,\n type ManagedClient,\n defaultBootstrapFunc,\n defaultClientFactory,\n} from \"./client.js\";\n\n/** Returned when no free connection slot is available. */\nexport class ErrPoolExhausted extends Error {\n constructor() {\n super(\"appkit: connection pool exhausted\");\n this.name = \"ErrPoolExhausted\";\n }\n}\n\n/** Configures a ConnectionPool. Zero values use defaults. */\nexport interface PoolConfig {\n poolSize: number;\n queryTimeout: number; // ms\n connectionTimeout: number; // ms\n maxIdleTime: number; // ms\n healthCheckInterval: number; // ms\n}\n\n/** Returns env-overridable defaults (mirrors triarch).\n * `maxIdleTime` is enforced on acquire; `healthCheckInterval` is reserved. */\nexport function defaultPoolConfig(): PoolConfig {\n return {\n poolSize: 1000,\n queryTimeout: 30 * 60 * 1000,\n connectionTimeout: 30_000,\n maxIdleTime: 10 * 60 * 1000,\n healthCheckInterval: 30_000,\n };\n}\n\n/** One connection slot in the pool. */\nexport class PooledConn {\n slotID: number;\n client: ManagedClient;\n eventStream: AsyncGenerator<DecodedMessage> | null = null;\n streamController: AbortController | null = null;\n sessionID = \"\";\n loopID = \"\";\n workspaceID = \"\";\n lastUsed = 0;\n\n constructor(slotID: number, client: ManagedClient) {\n this.slotID = slotID;\n this.client = client;\n }\n\n /** Reports whether the underlying client signalled a drop. */\n isDisconnected(): boolean {\n return this.client.isDisconnected();\n }\n\n isConnected(): boolean {\n return this.client.isConnected() && !this.isDisconnected();\n }\n\n getLoopID(): string {\n return this.loopID;\n }\n}\n\n/**\n * ConnectionPool manages a pool of daemon connections, one active per session.\n */\nexport class ConnectionPool {\n private cfg: PoolConfig;\n private scfg: Config;\n private factory: ClientFactory;\n private bootstrap: BootstrapFunc;\n private store: SessionStore;\n private pool: PooledConn[] = [];\n private activeSlots = new Map<string, PooledConn>();\n private nextSlotID = 1;\n private url: string;\n\n /**\n * Constructs a pool. `url` is the daemon WebSocket URL. If cfg is null,\n * defaultPoolConfig is used; if scfg is null, defaultConfig is used; nil\n * factory/bootstrap fall back to the defaults.\n */\n constructor(\n url: string,\n store: SessionStore,\n cfg?: PoolConfig | null,\n scfg?: Config | null,\n factory?: ClientFactory | null,\n ) {\n this.cfg = cfg ?? defaultPoolConfig();\n this.scfg = scfg ?? defaultConfig();\n this.factory = factory ?? defaultClientFactory();\n this.bootstrap = defaultBootstrapFunc();\n this.store = store;\n this.url = url;\n // Pre-seed the pool with up to poolSize slots.\n for (let i = 0; i < this.cfg.poolSize; i++) {\n this.pool.push(new PooledConn(this.nextSlotID++, this.factory(url, this.scfg)));\n }\n }\n\n /** Overrides the loop bootstrap function (useful for test fakes). */\n withBootstrap(f: BootstrapFunc): ConnectionPool {\n if (f) this.bootstrap = f;\n return this;\n }\n\n /**\n * Returns a live connection for sessionID, reusing an active slot or\n * bootstrapping/reattaching as needed. The caller must call `release()`\n * when done with the connection (a turn completes or the session is reset).\n */\n async acquire(\n sessionID: string,\n workspaceID: string,\n userID: string,\n _signal?: AbortSignal,\n ): Promise<PooledConn> {\n // 1. Reuse active connection when still live.\n const existing = this.activeSlots.get(sessionID);\n if (existing) {\n if (existing.isDisconnected() || !existing.isConnected()) {\n await this.release(sessionID);\n } else {\n const idleTooLong =\n this.cfg.maxIdleTime > 0 &&\n existing.lastUsed > 0 &&\n Date.now() - existing.lastUsed > this.cfg.maxIdleTime;\n if (idleTooLong) {\n await this.release(sessionID);\n } else {\n existing.lastUsed = Date.now();\n await this.store.updateLastUsed(sessionID).catch(() => {});\n return existing;\n }\n }\n }\n\n // 2. Pull a slot from the pool.\n const conn = this.pool.pop();\n if (!conn) throw new ErrPoolExhausted();\n this.activeSlots.set(sessionID, conn);\n\n const { loopID, ok } = await this.store\n .getLoopIDForSession(sessionID)\n .catch(() => ({ loopID: \"\", ok: false }));\n let finalLoopID = \"\";\n try {\n if (!ok || !loopID) {\n // Fresh bootstrap.\n await conn.client.connect();\n finalLoopID = await this.bootstrapNew(conn, workspaceID, userID);\n await this.store.createSession(workspaceID, sessionID, finalLoopID, \"\").catch(() => {});\n } else {\n // Reattach.\n try {\n await this.resumeAndReattach(conn, loopID);\n finalLoopID = loopID;\n } catch {\n // Reattach failed (incl. StaleLoopError) → fresh bootstrap.\n await conn.client.connect();\n finalLoopID = await this.bootstrapNew(conn, workspaceID, userID);\n await this.store.createSession(workspaceID, sessionID, finalLoopID, \"\").catch(() => {});\n }\n }\n } catch (err) {\n await this.release(sessionID);\n throw err;\n }\n\n conn.sessionID = sessionID;\n conn.loopID = finalLoopID;\n conn.workspaceID = workspaceID;\n conn.lastUsed = Date.now();\n await this.store.updateLastUsed(sessionID).catch(() => {});\n return conn;\n }\n\n /** Tears down the connection for sessionID and returns the slot. */\n async release(sessionID: string): Promise<void> {\n const conn = this.activeSlots.get(sessionID);\n if (!conn) return;\n this.activeSlots.delete(sessionID);\n if (conn.streamController) {\n conn.streamController.abort();\n conn.streamController = null;\n }\n try {\n conn.client.close();\n } catch {\n // ignore\n }\n conn.sessionID = \"\";\n conn.loopID = \"\";\n conn.eventStream = null;\n // Return a fresh slot to the pool (the closed client is spent).\n this.pool.push(new PooledConn(this.nextSlotID++, this.factory(this.url, this.scfg)));\n }\n\n /**\n * Tears down the connection for sessionID so the next acquire bootstraps\n * fresh. The store should archive the loop id so getLoopIDForSession returns\n * false next time.\n */\n async resetSession(sessionID: string): Promise<void> {\n await this.release(sessionID);\n }\n\n /** Gracefully shuts down all active connections. */\n stop(): void {\n for (const [sid, conn] of this.activeSlots) {\n if (conn.streamController) conn.streamController.abort();\n try {\n conn.client.close();\n } catch {\n // ignore\n }\n this.activeSlots.delete(sid);\n }\n }\n\n /** Stats snapshot for observability. */\n stats(): { active: number; idle: number } {\n return { active: this.activeSlots.size, idle: this.pool.length };\n }\n\n /** Bootstrap a fresh loop and start the reader. */\n private async bootstrapNew(\n conn: PooledConn,\n workspaceID: string,\n userID: string,\n ): Promise<string> {\n const loopID = await this.bootstrap(conn.client, workspaceID, userID, this.scfg);\n this.startReader(conn);\n return loopID;\n }\n\n /** Reconnect + reattach an existing loop, then start the reader. */\n private async resumeAndReattach(conn: PooledConn, loopID: string): Promise<void> {\n await conn.client.connect();\n try {\n await conn.client.reattachAndProbe(loopID);\n } catch (err) {\n if (err instanceof StaleLoopError) throw err;\n throw err;\n }\n this.startReader(conn);\n }\n\n /** Starts a receiveMessages generator and stores the stream + controller. */\n private startReader(conn: PooledConn): void {\n const controller = new AbortController();\n conn.streamController = controller;\n conn.eventStream = conn.client.receiveMessages(controller.signal);\n }\n}\n","/**\n * Attachment image compaction for appkit.\n *\n * When `sharp` is installed (optionalDependency), oversized image/* payloads\n * are downscaled. Without sharp, attachments pass through unchanged.\n */\n\nexport interface CompactImageOptions {\n /** Max width or height in pixels. Default 768. */\n maxDim?: number;\n /** JPEG encode quality 1–100. Default 85. */\n jpegQuality?: number;\n}\n\nfunction compactDefaults(opts?: CompactImageOptions | null): { maxDim: number; quality: number } {\n return {\n maxDim: opts?.maxDim && opts.maxDim > 0 ? opts.maxDim : 768,\n quality: opts?.jpegQuality && opts.jpegQuality > 0 ? opts.jpegQuality : 85,\n };\n}\n\ntype SharpModule = {\n default: (\n input: Buffer,\n options?: { failOn?: string },\n ) => {\n metadata: () => Promise<{ width?: number; height?: number }>;\n resize: (\n w: number,\n h: number,\n opts?: { fit?: string },\n ) => {\n png: () => { toBuffer: () => Promise<Buffer> };\n jpeg: (opts?: { quality?: number }) => { toBuffer: () => Promise<Buffer> };\n };\n };\n};\n\nlet sharpLoader: Promise<SharpModule | null> | null = null;\n\nasync function loadSharp(): Promise<SharpModule | null> {\n if (!sharpLoader) {\n sharpLoader = (async () => {\n try {\n const m = await (Function('return import(\"sharp\")')() as Promise<{ default: unknown }>);\n return m as unknown as SharpModule;\n } catch {\n return null;\n }\n })();\n }\n return sharpLoader;\n}\n\n/**\n * Downscales image/* payloads when either dimension exceeds MaxDim.\n * Non-images and decode failures pass through unchanged.\n * PNG stays PNG; other image types re-encode as JPEG when sharp is available.\n */\nexport async function compactImageAttachment(\n mimeType: string,\n dataB64: string,\n opts?: CompactImageOptions | null,\n): Promise<[string, string]> {\n if (!dataB64 || !mimeType.startsWith(\"image/\")) {\n return [mimeType, dataB64];\n }\n let raw: Buffer;\n try {\n raw = Buffer.from(dataB64, \"base64\");\n } catch {\n return [mimeType, dataB64];\n }\n if (raw.length === 0) return [mimeType, dataB64];\n\n const sharpMod = await loadSharp();\n if (!sharpMod) return [mimeType, dataB64];\n\n const { maxDim, quality } = compactDefaults(opts);\n try {\n const img = sharpMod.default(raw, { failOn: \"none\" });\n const meta = await img.metadata();\n const w = meta.width ?? 0;\n const h = meta.height ?? 0;\n if (w <= 0 || h <= 0 || (w <= maxDim && h <= maxDim)) {\n return [mimeType, dataB64];\n }\n let nw = w;\n let nh = h;\n if (w >= h) {\n if (w > maxDim) {\n nw = maxDim;\n nh = Math.max(1, Math.round((h * maxDim) / w));\n }\n } else if (h > maxDim) {\n nh = maxDim;\n nw = Math.max(1, Math.round((w * maxDim) / h));\n }\n const resized = img.resize(nw, nh, { fit: \"fill\" });\n if (mimeType === \"image/png\") {\n const buf = await resized.png().toBuffer();\n return [mimeType, buf.toString(\"base64\")];\n }\n const buf = await resized.jpeg({ quality }).toBuffer();\n return [\"image/jpeg\", buf.toString(\"base64\")];\n } catch {\n return [mimeType, dataB64];\n }\n}\n\n/**\n * Applies compactImageAttachment to each attachment map with mime_type + data.\n */\nexport async function compactAttachments(\n atts: Record<string, unknown>[],\n opts?: CompactImageOptions | null,\n): Promise<Record<string, unknown>[]> {\n if (!atts.length) return atts;\n const out: Record<string, unknown>[] = [];\n for (const att of atts) {\n const cp: Record<string, unknown> = { ...att };\n const mime = typeof cp.mime_type === \"string\" ? cp.mime_type : \"\";\n const data = typeof cp.data === \"string\" ? cp.data : \"\";\n if (mime && data) {\n const [outMime, outData] = await compactImageAttachment(mime, data, opts);\n cp.mime_type = outMime;\n cp.data = outData;\n }\n out.push(cp);\n }\n return out;\n}\n","/**\n * Turn runner for appkit.\n *\n * Executes one query turn end-to-end: acquire a pooled connection, enforce\n * single-flight, send loop_input, consume the event stream, classify events,\n * resolve the deliverable, persist the reply, and broadcast completion.\n *\n * Supports lifecycle knobs: idle timeout, soft-complete\n * policies, attachment compaction, and stream-close soft-complete.\n */\n\nimport type { PooledConn } from \"./pool.js\";\nimport { type ConnectionPool } from \"./pool.js\";\nimport { type EventClassifier, ChatEventTerminal } from \"./classifier.js\";\nimport { type QueryGate } from \"./query_gate.js\";\nimport { type SSEBroadcaster, SSEEvent } from \"./broadcaster.js\";\nimport type { SessionStore, SessionMessage } from \"./session_store.js\";\nimport type { LoopInputIntentHint } from \"../intent_hints.js\";\nimport { validateLoopInputIntentHint } from \"../intent_hints.js\";\nimport type { DecodedMessage } from \"../protocol.js\";\nimport { compactAttachments, type CompactImageOptions } from \"./attachments.js\";\n\n/** Returned when a turn exceeds the configured timeout and policy is Fail. */\nexport class ErrQueryTimeout extends Error {\n constructor() {\n super(\"appkit: query timeout\");\n this.name = \"ErrQueryTimeout\";\n }\n}\n\n/** Returned when no events arrive within IdleTimeout and policy is Fail. */\nexport class ErrIdleTimeout extends Error {\n constructor() {\n super(\"appkit: idle timeout\");\n this.name = \"ErrIdleTimeout\";\n }\n}\n\n/** Selects fail vs soft-complete behaviour for idle, query, and stream-close. */\nexport enum TimeoutPolicy {\n Fail = 0,\n SoftComplete = 1,\n}\n\nexport type StreamClosePolicy = TimeoutPolicy;\nexport const StreamCloseFail = TimeoutPolicy.Fail;\nexport const StreamCloseSoftComplete = TimeoutPolicy.SoftComplete;\n\n/** Configures a TurnRunner. */\nexport interface TurnConfig {\n /** Per-turn deadline in ms. Defaults to 30m. */\n queryTimeout: number;\n /** Max silence between classified events in ms. Zero disables (default). */\n idleTimeout?: number;\n /**\n * When > 0, raises idleTimeout for turns with attachments if idleTimeout\n * is positive but below this floor.\n */\n minIdleTimeoutWithAttachments?: number;\n /** Fail vs soft-complete when the idle watchdog fires. Default Fail. */\n onIdleTimeout?: TimeoutPolicy;\n /** Fail vs soft-complete when queryTimeout fires. Default Fail. */\n onQueryTimeout?: TimeoutPolicy;\n /** Fail vs soft-complete when the event stream closes. Default Fail. */\n onStreamClose?: StreamClosePolicy;\n /** Run compactAttachments before buildInput. Default false. */\n compactAttachmentsBeforeSend?: boolean;\n /** Overrides for compactAttachmentsBeforeSend. */\n compactImageOpts?: CompactImageOptions | null;\n}\n\n/** Carries optional daemon hints on a loop_input payload. */\nexport interface InputOpts {\n intentHint?: LoopInputIntentHint;\n preferredSubagent?: string;\n responseSchema?: Record<string, unknown>;\n responseSchemaName?: string;\n responseSchemaStrict?: boolean;\n}\n\n/** Optional attachment shape ({mime_type, data(base64)}). */\nexport type Attachment = Record<string, unknown>;\n\n/**\n * Builds a loop_input payload with optional attachments. Apps build this from\n * their product modes (e.g. triarch's ask/agent/deep-research).\n */\nexport function inputMessageForLoop(\n text: string,\n loopID: string,\n attachments?: Attachment[],\n opts?: InputOpts,\n): Record<string, unknown> {\n const msg: Record<string, unknown> = { type: \"loop_input\", content: text };\n if (loopID) msg.loop_id = loopID;\n if (attachments && attachments.length > 0) msg.attachments = attachments;\n if (opts) {\n if (opts.intentHint?.trim()) {\n const hintError = validateLoopInputIntentHint(opts.intentHint);\n if (hintError) {\n throw new Error(hintError);\n }\n msg.intent_hint = opts.intentHint.trim();\n }\n if (opts.preferredSubagent?.trim()) msg.preferred_subagent = opts.preferredSubagent.trim();\n if (opts.responseSchema && Object.keys(opts.responseSchema).length > 0) {\n msg.response_schema = opts.responseSchema;\n }\n if (opts.responseSchemaName?.trim()) msg.response_schema_name = opts.responseSchemaName.trim();\n if (opts.responseSchemaStrict !== undefined)\n msg.response_schema_strict = opts.responseSchemaStrict;\n }\n return msg;\n}\n\n/** Effective idle timeout for a turn (attachment floor applied). */\nexport function idleTimeoutForTurn(cfg: TurnConfig, hasAttachments: boolean): number {\n const idle = cfg.idleTimeout ?? 0;\n if (idle <= 0) return 0;\n const floor = cfg.minIdleTimeoutWithAttachments ?? 0;\n if (hasAttachments && floor > 0 && idle < floor) return floor;\n return idle;\n}\n\n/** Completion hook signature. */\nexport type OnComplete = (\n sessionID: string,\n loopID: string,\n content: string,\n completionEvent: string,\n elapsedMs: number,\n) => void;\n/** Error hook signature. */\nexport type OnError = (sessionID: string, loopID: string, err: Error) => void;\n\n/**\n * TurnRunner executes one query turn end-to-end.\n */\nexport class TurnRunner {\n private pool: ConnectionPool;\n private gate: QueryGate;\n private classifier: EventClassifier;\n private store: SessionStore;\n private broadcaster: SSEBroadcaster | null;\n private cfg: TurnConfig;\n private buildInput: typeof inputMessageForLoop = inputMessageForLoop;\n private onComplete: OnComplete | null = null;\n private onError: OnError | null = null;\n\n constructor(\n pool: ConnectionPool,\n gate: QueryGate,\n classifier: EventClassifier,\n store: SessionStore,\n broadcaster: SSEBroadcaster | null,\n cfg: TurnConfig,\n ) {\n this.pool = pool;\n this.gate = gate;\n this.classifier = classifier;\n this.store = store;\n this.broadcaster = broadcaster;\n this.cfg = {\n ...cfg,\n queryTimeout: cfg.queryTimeout > 0 ? cfg.queryTimeout : 30 * 60 * 1000,\n };\n }\n\n withInputBuilder(f: typeof inputMessageForLoop): TurnRunner {\n if (f) this.buildInput = f;\n return this;\n }\n\n withOnComplete(f: OnComplete): TurnRunner {\n this.onComplete = f;\n return this;\n }\n\n withOnError(f: OnError): TurnRunner {\n this.onError = f;\n return this;\n }\n\n async execute(\n sessionID: string,\n message: string,\n userID: string,\n workspaceID: string,\n attachments: Attachment[] | null,\n opts: InputOpts | null,\n signal?: AbortSignal,\n ): Promise<void> {\n let conn: PooledConn;\n try {\n conn = await this.pool.acquire(sessionID, workspaceID, userID, signal);\n } catch (err) {\n await this.persistFailed(sessionID, \"\", err as Error);\n this.broadcastError(sessionID, err as Error);\n this.onError?.(sessionID, \"\", err as Error);\n throw err;\n }\n const loopID = conn.getLoopID();\n\n const timeoutController = new AbortController();\n const timeoutMs = this.cfg.queryTimeout;\n const timer = setTimeout(() => timeoutController.abort(), timeoutMs);\n\n const sendCancel = async (detachedSignal: AbortSignal) => {\n await this.sendLoopCancel(detachedSignal, conn, loopID);\n };\n try {\n this.gate.acquire(sessionID, timeoutController, sendCancel);\n } catch (err) {\n clearTimeout(timer);\n await this.pool.release(sessionID);\n await this.persistFailed(sessionID, loopID, err as Error);\n this.broadcastError(sessionID, err as Error);\n this.onError?.(sessionID, loopID, err as Error);\n throw err;\n }\n\n let idleTimer: ReturnType<typeof setTimeout> | null = null;\n const clearIdle = () => {\n if (idleTimer) {\n clearTimeout(idleTimer);\n idleTimer = null;\n }\n };\n\n try {\n let atts = attachments ?? undefined;\n if (this.cfg.compactAttachmentsBeforeSend && atts && atts.length > 0) {\n atts = await compactAttachments(atts, this.cfg.compactImageOpts);\n }\n\n const inputMsg = this.buildInput(message, loopID, atts, opts ?? undefined);\n try {\n await conn.client.sendMessage(inputMsg);\n } catch (err) {\n await this.persistFailed(sessionID, loopID, err as Error);\n this.broadcastError(sessionID, err as Error);\n this.onError?.(sessionID, loopID, err as Error);\n throw err;\n }\n\n const eventStream = conn.eventStream;\n if (!eventStream) {\n const err = new Error(`missing event stream for session ${sessionID} (loop ${loopID})`);\n await this.persistFailed(sessionID, loopID, err);\n this.broadcastError(sessionID, err);\n this.onError?.(sessionID, loopID, err);\n throw err;\n }\n\n let assistantContent = \"\";\n const startedAt = Date.now();\n const idleForTurn = idleTimeoutForTurn(this.cfg, (attachments?.length ?? 0) > 0);\n\n type RaceTag = \"timeout\" | \"caller\" | \"idle\";\n let idleReject: (() => void) | null = null;\n\n const armIdle = (): Promise<\"idle\"> => {\n clearIdle();\n idleReject = null;\n if (idleForTurn <= 0) {\n return new Promise<\"idle\">(() => {});\n }\n return new Promise<\"idle\">(resolve => {\n idleReject = () => resolve(\"idle\");\n idleTimer = setTimeout(() => {\n idleReject?.();\n }, idleForTurn);\n });\n };\n\n let idleRace = armIdle();\n\n const abortRace = new Promise<RaceTag>(resolve => {\n const onTimeout = () => resolve(\"timeout\");\n timeoutController.signal.addEventListener(\"abort\", onTimeout, { once: true });\n if (signal) {\n const onCaller = () => resolve(\"caller\");\n signal.addEventListener(\"abort\", onCaller, { once: true });\n }\n });\n\n const iterator = eventStream[Symbol.asyncIterator]();\n\n while (true) {\n const next = iterator.next();\n const raced = await Promise.race([\n next.then(res => ({ tag: \"msg\" as const, res })),\n abortRace.then(tag => ({ tag })),\n idleRace.then(tag => ({ tag })),\n ]);\n\n if (\"tag\" in raced && raced.tag !== \"msg\") {\n if (raced.tag === \"caller\" || signal?.aborted) {\n clearIdle();\n const err = new Error(\"aborted\");\n await this.persistFailed(sessionID, loopID, err);\n this.broadcastError(sessionID, err);\n this.onError?.(sessionID, loopID, err);\n throw err;\n }\n if (raced.tag === \"idle\") {\n clearIdle();\n await this.sendLoopCancel(new AbortController().signal, conn, loopID).catch(() => {});\n await this.finishTimeout(\n sessionID,\n loopID,\n assistantContent,\n startedAt,\n new ErrIdleTimeout(),\n \"idle_timeout\",\n this.cfg.onIdleTimeout ?? TimeoutPolicy.Fail,\n );\n return;\n }\n clearIdle();\n await this.sendLoopCancel(new AbortController().signal, conn, loopID).catch(() => {});\n await this.finishTimeout(\n sessionID,\n loopID,\n assistantContent,\n startedAt,\n new ErrQueryTimeout(),\n \"query_timeout\",\n this.cfg.onQueryTimeout ?? TimeoutPolicy.Fail,\n );\n return;\n }\n\n const res = (raced as { tag: \"msg\"; res: IteratorResult<DecodedMessage> }).res;\n if (res.done) {\n clearIdle();\n if (\n (this.cfg.onStreamClose ?? TimeoutPolicy.Fail) === TimeoutPolicy.SoftComplete &&\n assistantContent.trim() !== \"\"\n ) {\n await this.completeTurn(\n sessionID,\n loopID,\n assistantContent,\n startedAt,\n \"stream_closed\",\n );\n return;\n }\n const err = new Error(\"event stream closed\");\n await this.persistFailed(sessionID, loopID, err);\n this.broadcastError(sessionID, err);\n this.onError?.(sessionID, loopID, err);\n throw err;\n }\n\n idleRace = armIdle();\n const msg = res.value;\n\n const eventResult = this.classifier.classify(msg, assistantContent);\n if (eventResult.err && eventResult.terminal === ChatEventTerminal.FailedComplete) {\n clearIdle();\n await this.persistFailed(sessionID, loopID, eventResult.err);\n this.broadcastError(sessionID, eventResult.err);\n this.onError?.(sessionID, loopID, eventResult.err);\n throw eventResult.err;\n }\n\n const step = (eventResult.thinkingStep ?? \"\").trim();\n if (step) this.broadcastThinkingStep(sessionID, step);\n\n if (eventResult.content) {\n if (eventResult.content.startsWith(assistantContent)) {\n assistantContent = eventResult.content;\n } else {\n assistantContent += eventResult.content;\n }\n }\n\n const [final, deliverable] = this.classifier.resolveDeliverableFinalContent(\n eventResult,\n assistantContent,\n );\n if (deliverable) {\n clearIdle();\n await this.completeTurn(\n sessionID,\n loopID,\n final,\n startedAt,\n eventResult.completionEvent ?? \"\",\n );\n return;\n }\n }\n } finally {\n clearIdle();\n clearTimeout(timer);\n this.gate.release(sessionID);\n }\n }\n\n private async finishTimeout(\n sessionID: string,\n loopID: string,\n content: string,\n startedAt: number,\n failErr: Error,\n completionEvent: string,\n policy: TimeoutPolicy,\n ): Promise<void> {\n if (policy === TimeoutPolicy.SoftComplete && content.trim() !== \"\") {\n await this.completeTurn(sessionID, loopID, content, startedAt, completionEvent);\n return;\n }\n await this.persistFailed(sessionID, loopID, failErr);\n this.broadcastError(sessionID, failErr);\n this.onError?.(sessionID, loopID, failErr);\n throw failErr;\n }\n\n private async completeTurn(\n sessionID: string,\n loopID: string,\n final: string,\n startedAt: number,\n completionEvent: string,\n ): Promise<void> {\n const elapsedMs = Date.now() - startedAt;\n await this.persistResponse(sessionID, loopID, final, startedAt, completionEvent);\n this.broadcastComplete(sessionID, final);\n this.onComplete?.(sessionID, loopID, final, completionEvent, elapsedMs);\n }\n\n private async sendLoopCancel(\n _signal: AbortSignal,\n conn: PooledConn,\n loopID: string,\n ): Promise<void> {\n const lid = (loopID ?? \"\").trim();\n if (!conn || !lid) return;\n const cancelMsg = { type: \"command_request\", command: \"cancel\", loop_id: lid };\n await conn.client.sendMessage(cancelMsg);\n }\n\n private async persistResponse(\n sessionID: string,\n loopID: string,\n content: string,\n startedAt: number,\n completionEvent: string,\n ): Promise<void> {\n const msg: SessionMessage = {\n role: \"assistant\",\n content,\n metadata: {\n started_at: startedAt,\n completed_at: Date.now(),\n duration_ms: Date.now() - startedAt,\n status: \"completed\",\n completion_event: completionEvent,\n deliverable: true,\n },\n };\n await this.store.appendMessage(sessionID, msg).catch(() => {});\n }\n\n private async persistFailed(sessionID: string, _loopID: string, err: Error): Promise<void> {\n const msg: SessionMessage = {\n role: \"error\",\n content: err.message,\n metadata: { status: \"failed\", error_message: err.message },\n };\n await this.store.appendMessage(sessionID, msg).catch(() => {});\n }\n\n private broadcastThinkingStep(sessionID: string, step: string): void {\n if (!this.broadcaster) return;\n this.broadcaster.broadcast(sessionID, { type: \"delta\", data: step + \"\\n\" } as SSEEvent);\n }\n\n private broadcastComplete(sessionID: string, content: string): void {\n this.broadcaster?.broadcast(sessionID, { type: \"complete\", data: content } as SSEEvent);\n }\n\n private broadcastError(sessionID: string, err: Error): void {\n this.broadcaster?.broadcast(sessionID, { type: \"query_error\", data: err.message } as SSEEvent);\n }\n}\n","/**\n * Early filters for daemon stream chunks (wire / dict-shaped payloads).\n */\n\nconst MSG_PAIR_LEN = 2;\n\n/** True when an updates chunk carries no LangGraph interrupt. */\nexport function updatesChunkIsNoop(data: unknown): boolean {\n if (!data || typeof data !== \"object\") return true;\n return !(\"__interrupt__\" in (data as Record<string, unknown>));\n}\n\nfunction wireBody(msg: Record<string, unknown>): Record<string, unknown> {\n for (const key of [\"kwargs\", \"data\"] as const) {\n const nested = msg[key];\n if (nested && typeof nested === \"object\") return nested as Record<string, unknown>;\n }\n return msg;\n}\n\nfunction dictHasToolInvocation(msg: Record<string, unknown>): boolean {\n const body = wireBody(msg);\n if (body.tool_calls || body.tool_call_chunks) return true;\n for (const key of [\"content\", \"content_blocks\"] as const) {\n const raw = body[key];\n if (Array.isArray(raw)) {\n for (const item of raw) {\n if (\n item &&\n typeof item === \"object\" &&\n [\"tool_call\", \"tool_call_chunk\", \"tool_use\"].includes(\n String((item as Record<string, unknown>).type ?? \"\"),\n )\n ) {\n return true;\n }\n }\n }\n }\n return false;\n}\n\nfunction plainText(msg: Record<string, unknown>): string {\n const body = wireBody(msg);\n const content = body.content ?? msg.content;\n if (typeof content === \"string\") return content;\n if (Array.isArray(content)) {\n const parts: string[] = [];\n for (const block of content) {\n if (typeof block === \"string\") parts.push(block);\n else if (block && typeof block === \"object\") {\n const text = (block as Record<string, unknown>).text;\n if (typeof text === \"string\") parts.push(text);\n }\n }\n return parts.join(\"\");\n }\n return \"\";\n}\n\n/** True when a wire messages pair has no tool, text, or loop phase payload. */\nexport function messageChunkIsNonActionable(data: unknown): boolean {\n if (!Array.isArray(data) || data.length !== MSG_PAIR_LEN) return false;\n const msg = data[0];\n if (msg === null || msg === undefined) return true;\n if (!msg || typeof msg !== \"object\") return false;\n const m = msg as Record<string, unknown>;\n const body = wireBody(m);\n const raw = String(body.type ?? m.type ?? \"\");\n if (raw === \"tool\" || raw === \"ToolMessage\" || raw.endsWith(\"ToolMessage\")) return false;\n if (dictHasToolInvocation(m)) return false;\n if (body.phase || m.phase) return false;\n return !plainText(m).trim();\n}\n\n/** Return true when the chunk can be skipped before the turn pipeline. */\nexport function shouldDropStreamChunkEarly(\n _namespace: unknown[],\n mode: string,\n data: unknown,\n): boolean {\n if (mode === \"updates\") return updatesChunkIsNoop(data);\n if (mode === \"messages\") return messageChunkIsNonActionable(data);\n return false;\n}\n","/**\n * Protocol-1 streaming frame helpers for application loops.\n */\n\n/** Unwrap a protocol-1 next envelope to its inner streaming frame. */\nexport function unwrapNext(\n event: Record<string, unknown> | null | undefined,\n): Record<string, unknown> | null | undefined {\n if (!event || typeof event !== \"object\") return event;\n if (event.type !== \"next\") return event;\n const payload = event.payload;\n if (!payload || typeof payload !== \"object\") return event;\n const data = (payload as Record<string, unknown>).data;\n return data && typeof data === \"object\" ? (data as Record<string, unknown>) : event;\n}\n\n/**\n * Return whether a daemon frame belongs to the active StrangeLoop session.\n */\nexport function isLoopScopedEvent(event: Record<string, unknown>, activeLoopId: string): boolean {\n let eventType = String(event.type ?? \"\");\n let frame = event;\n if (eventType === \"next\") {\n const inner = unwrapNext(event);\n if (inner && typeof inner === \"object\") {\n frame = inner;\n eventType = String(inner.type ?? \"\");\n return eventType !== \"status\" && eventType !== \"event\"\n ? true\n : String(inner.loop_id ?? \"\") === activeLoopId;\n }\n }\n if (eventType !== \"status\" && eventType !== \"event\") return true;\n return String(frame.loop_id ?? \"\") === activeLoopId;\n}\n","/**\n * Per-turn observability counters for daemon stream consumption.\n */\n\nexport class TurnEventStats {\n total = 0;\n messages = 0;\n updates = 0;\n custom = 0;\n skipped = 0;\n filteredEarly = 0;\n toolCalls = 0;\n toolResults = 0;\n textChunks = 0;\n heartbeatsDropped = 0;\n postIdleDrained = 0;\n inboundDropped = 0;\n}\n","/**\n * Dual-socket daemon loop session with turn streaming (Python DaemonSession parity).\n *\n * Owns a subscribed stream WebSocket plus an RPC sidecar so metadata calls do not\n * starve loop events. `iterTurnChunks` handles idle timeout, post-idle drain,\n * loop scoping, and connection-loss detection.\n */\n\nimport { Client } from \"../client.js\";\nimport { defaultConfig, type Config } from \"../config.js\";\nimport { StaleLoopError } from \"../errors.js\";\nimport { bootstrapLoopSession, connectWithRetries } from \"../session.js\";\nimport { STREAM_END, isTurnEndCustomData, isTurnProgressChunk } from \"../stream_terminal.js\";\nimport { shouldDropStreamChunkEarly } from \"./chunk_filter.js\";\nimport { unwrapNext } from \"./events.js\";\nimport { TurnEventStats } from \"./observability.js\";\n\nexport const DEFAULT_POST_IDLE_DRAIN_MS = 500;\n\nexport type EarlyDropFn = (namespace: unknown[], mode: string, data: unknown) => boolean;\nexport type StatsFactory = () => TurnEventStats;\nexport type StreamDeliveryResolver = () => string;\n\nexport interface DaemonSessionOptions {\n workspace?: string | null;\n streamDelivery?: string | StreamDeliveryResolver;\n postIdleDrainDeadlineMs?: number;\n earlyDropFn?: EarlyDropFn | null;\n statsFactory?: StatsFactory | null;\n config?: Config;\n}\n\nexport type TurnChunk = [namespace: unknown[], mode: string, data: unknown];\n\n/** Daemon-backed loop session with stream + RPC sockets. */\nexport class DaemonSession {\n private wsUrl: string;\n private workspace: string | null | undefined;\n private streamDelivery: string | StreamDeliveryResolver;\n private client: Client;\n private rpcClient: Client;\n private loopId: string | null = null;\n private readBusy = false;\n private rpcBusy = false;\n private rpcConnected = false;\n private streaming = false;\n private postIdleDrainDeadlineMs: number;\n private closed = false;\n private earlyDropFn: EarlyDropFn;\n private statsFactory: StatsFactory;\n private config: Config;\n\n turnEventStats: TurnEventStats;\n lastTurnEndState: string | null = null;\n lastTurnCancellationSeen = false;\n lastTurnErrorMessage: string | null = null;\n\n constructor(wsUrl: string, opts: DaemonSessionOptions = {}) {\n this.wsUrl = wsUrl;\n this.workspace = opts.workspace;\n this.streamDelivery = opts.streamDelivery ?? \"adaptive\";\n this.config = opts.config ?? defaultConfig();\n this.client = new Client(wsUrl, this.config);\n this.rpcClient = new Client(wsUrl, this.config);\n this.postIdleDrainDeadlineMs =\n opts.postIdleDrainDeadlineMs && opts.postIdleDrainDeadlineMs > 0\n ? opts.postIdleDrainDeadlineMs\n : DEFAULT_POST_IDLE_DRAIN_MS;\n this.earlyDropFn = opts.earlyDropFn ?? shouldDropStreamChunkEarly;\n this.statsFactory = opts.statsFactory ?? (() => new TurnEventStats());\n this.turnEventStats = this.statsFactory();\n }\n\n get streamClient(): Client {\n return this.client;\n }\n\n get rpcSideClient(): Client {\n return this.rpcClient;\n }\n\n get activeLoopId(): string | null {\n return this.loopId;\n }\n\n private resolveStreamDeliveryMode(): string {\n const delivery = this.streamDelivery;\n if (typeof delivery === \"function\") return String(delivery() || \"adaptive\");\n return String(delivery || \"adaptive\");\n }\n\n get streamDeliveryMode(): string {\n return this.resolveStreamDeliveryMode();\n }\n\n private shouldDrop(namespace: unknown[], mode: string, data: unknown): boolean {\n return Boolean(this.earlyDropFn(namespace, mode, data));\n }\n\n async connect(resumeLoopId?: string | null): Promise<Record<string, unknown>> {\n await connectWithRetries(this.client);\n return this.bootstrapLoop(resumeLoopId ?? null);\n }\n\n private async bootstrapLoop(resumeLoopId: string | null): Promise<Record<string, unknown>> {\n const loopNew = this.workspace\n ? { client_workspace: this.workspace, workspace: this.workspace }\n : undefined;\n const loopId = await bootstrapLoopSession(this.client, resumeLoopId, this.config, loopNew);\n this.loopId = loopId;\n return { type: \"status\", loop_id: loopId, state: \"ready\" };\n }\n\n async newLoop(): Promise<Record<string, unknown>> {\n return this.bootstrapLoop(null);\n }\n\n async switchLoop(loopId: string): Promise<Record<string, unknown>> {\n return this.bootstrapLoop(loopId);\n }\n\n async ensureConnected(): Promise<void> {\n if (this.client.isConnected() && !this.client.isDisconnected()) return;\n\n let resumeLoopId = this.loopId;\n if (this.rpcConnected) {\n this.rpcClient.close();\n this.rpcConnected = false;\n }\n\n try {\n await this.client.reconnect();\n } catch {\n this.client.close();\n await connectWithRetries(this.client);\n }\n\n if (resumeLoopId) {\n try {\n await this.client.reattachAndProbe(resumeLoopId);\n this.loopId = resumeLoopId;\n return;\n } catch (err) {\n if (!(err instanceof StaleLoopError)) throw err;\n resumeLoopId = null;\n }\n }\n\n await this.bootstrapLoop(resumeLoopId);\n }\n\n async close(): Promise<void> {\n if (this.closed) return;\n this.closed = true;\n this.client.close();\n this.rpcClient.close();\n this.rpcConnected = false;\n }\n\n async detach(): Promise<void> {\n if (!this.client.isConnected()) return;\n try {\n await this.client.notify(\"disconnect\", {});\n } catch {\n // ignore\n }\n }\n\n async sendTurn(\n text: string,\n options?: {\n autonomous?: boolean;\n maxIterations?: number;\n preferredSubagent?: string;\n model?: string;\n modelParams?: Record<string, unknown>;\n attachments?: Array<{ mime_type: string; data: string }>;\n clarificationMode?: string;\n clarificationAnswer?: boolean;\n intentHint?: string;\n },\n ): Promise<void> {\n if (!this.loopId) throw new Error(\"No active loop session\");\n await this.client.sendInput(text, {\n loopID: this.loopId,\n autonomous: options?.autonomous,\n maxIterations: options?.maxIterations,\n subagent: options?.preferredSubagent,\n model: options?.model,\n modelParams: options?.modelParams,\n attachments: options?.attachments,\n clarificationMode: options?.clarificationMode,\n clarificationAnswer: options?.clarificationAnswer,\n intentHint: options?.intentHint as\n import(\"../intent_hints.js\").LoopInputIntentHint | undefined,\n });\n }\n\n async cancelActiveTurn(): Promise<void> {\n await this.client.notify(\"slash_command\", { cmd: \"/cancel\" });\n }\n\n private async *drainStreamEventsAfterIdle(\n expectedLoopId: string | null,\n ): AsyncGenerator<TurnChunk> {\n const deadline = Date.now() + this.postIdleDrainDeadlineMs;\n let exp = expectedLoopId;\n while (Date.now() < deadline) {\n const event = await this.client.readEventWithTimeout(250);\n if (!event) break;\n let frame = event;\n let eventType = String(frame.type ?? \"\");\n if (eventType === \"next\") {\n frame = unwrapNext(frame) ?? frame;\n eventType = String(frame.type ?? \"\");\n }\n const eventLoopId = frame.loop_id;\n if (exp && typeof eventLoopId === \"string\" && eventLoopId && eventLoopId !== exp) {\n continue;\n }\n if (eventType === \"error\") {\n const errObj = (frame.error as { message?: string }) ?? {};\n throw new Error(String(errObj.message || frame.message || \"daemon error\"));\n }\n if (eventType === \"status\") {\n const loopEv = frame.loop_id;\n if (typeof loopEv === \"string\" && loopEv) {\n this.loopId = loopEv;\n exp = loopEv;\n }\n continue;\n }\n if (eventType !== \"event\") continue;\n const data = frame.data;\n const namespace = Array.isArray(frame.namespace) ? (frame.namespace as unknown[]) : [];\n const mode = String(frame.mode ?? \"\");\n if (this.shouldDrop(namespace, mode, data)) {\n this.turnEventStats.filteredEarly += 1;\n continue;\n }\n this.turnEventStats.postIdleDrained += 1;\n yield [namespace, mode, data];\n }\n }\n\n private async withRpcLock<T>(fn: () => Promise<T>): Promise<T> {\n while (this.rpcBusy) {\n await new Promise(r => setTimeout(r, 5));\n }\n this.rpcBusy = true;\n try {\n return await fn();\n } finally {\n this.rpcBusy = false;\n }\n }\n\n private async ensureRpcConnected(): Promise<void> {\n if (this.rpcConnected && this.rpcClient.isConnected()) return;\n await connectWithRetries(this.rpcClient);\n this.rpcConnected = true;\n }\n\n async listLoops(_limit = 20): Promise<Record<string, unknown>> {\n return this.withRpcLock(async () => {\n await this.ensureRpcConnected();\n return this.rpcClient.listLoops(15_000);\n });\n }\n\n async fetchLoopCards(loopId: string): Promise<{\n cards: unknown[];\n seq: number;\n contextTokens: number;\n success: boolean;\n }> {\n const lid = String(loopId || \"\").trim();\n if (!lid) return { cards: [], seq: 0, contextTokens: 0, success: false };\n return this.withRpcLock(async () => {\n await this.ensureRpcConnected();\n try {\n const resp = await this.rpcClient.fetchLoopCards(lid, 30_000);\n const rawCards = resp.cards;\n return {\n cards: Array.isArray(rawCards) ? rawCards : [],\n seq: Number(resp.seq ?? 0),\n contextTokens:\n typeof resp.context_tokens === \"number\" && resp.context_tokens >= 0\n ? resp.context_tokens\n : 0,\n success: true,\n };\n } catch {\n return { cards: [], seq: 0, contextTokens: 0, success: false };\n }\n });\n }\n\n async fetchLoopHistory(loopId: string): Promise<{\n goals: unknown[];\n liveCards: unknown[];\n liveGoalIndex: number | null;\n contextTokens: number;\n success: boolean;\n }> {\n const lid = String(loopId || \"\").trim();\n if (!lid) {\n return { goals: [], liveCards: [], liveGoalIndex: null, contextTokens: 0, success: false };\n }\n return this.withRpcLock(async () => {\n await this.ensureRpcConnected();\n try {\n const resp = await this.rpcClient.fetchLoopHistory(lid, 30_000);\n const liveGoalIndex = resp.live_goal_index;\n return {\n goals: Array.isArray(resp.goals) ? resp.goals : [],\n liveCards: Array.isArray(resp.live_cards) ? resp.live_cards : [],\n liveGoalIndex: typeof liveGoalIndex === \"number\" ? liveGoalIndex : null,\n contextTokens:\n typeof resp.context_tokens === \"number\" && resp.context_tokens >= 0\n ? resp.context_tokens\n : 0,\n success: Boolean(resp.success ?? true),\n };\n } catch {\n return {\n goals: [],\n liveCards: [],\n liveGoalIndex: null,\n contextTokens: 0,\n success: false,\n };\n }\n });\n }\n\n async fetchConversationLog(\n loopId: string,\n opts: { limit?: number; offset?: number; includeEvents?: boolean } = {},\n ): Promise<Record<string, unknown>[]> {\n const lid = String(loopId || \"\").trim();\n if (!lid) return [];\n return this.withRpcLock(async () => {\n await this.ensureRpcConnected();\n const resp = await this.rpcClient.getLoopMessages(\n lid,\n opts.limit ?? 100,\n opts.offset ?? 0,\n opts.includeEvents ?? false,\n );\n const raw = resp.messages;\n if (!Array.isArray(raw)) return [];\n return raw.filter((m): m is Record<string, unknown> => !!m && typeof m === \"object\");\n });\n }\n\n async *iterTurnChunks(opts: { maxWaitMs?: number } = {}): AsyncGenerator<TurnChunk> {\n this.turnEventStats = this.statsFactory();\n this.lastTurnEndState = null;\n this.lastTurnCancellationSeen = false;\n this.lastTurnErrorMessage = null;\n\n let queryStarted = false;\n let expectedLoopId = this.loopId;\n let streamPayloadSeen = false;\n let turnProgressSeen = false;\n this.streaming = true;\n const absoluteDeadline =\n opts.maxWaitMs !== undefined && opts.maxWaitMs > 0 ? Date.now() + opts.maxWaitMs : null;\n\n this.client.peelStalePendingControlEvents();\n\n while (this.readBusy) {\n await new Promise(r => setTimeout(r, 5));\n }\n this.readBusy = true;\n try {\n while (true) {\n if (absoluteDeadline !== null && Date.now() >= absoluteDeadline) {\n throw new Error(\n `Turn timed out after ${opts.maxWaitMs}ms (loop=${expectedLoopId ?? \"?\"})`,\n );\n }\n const event = await this.client.readEvent();\n if (!event) {\n if (queryStarted && !this.client.isConnectionAlive()) {\n this.lastTurnEndState = \"connection_lost\";\n throw new Error(\"Daemon connection lost\");\n }\n break;\n }\n\n let frame: Record<string, unknown> = event;\n let eventType = String(frame.type ?? \"\");\n if (eventType === \"next\") {\n frame = unwrapNext(frame) ?? frame;\n eventType = String(frame.type ?? \"\");\n }\n\n const eventLoopId = frame.loop_id;\n if (\n expectedLoopId &&\n typeof eventLoopId === \"string\" &&\n eventLoopId &&\n eventLoopId !== expectedLoopId\n ) {\n continue;\n }\n\n if (eventType === \"error\") {\n const errObj = (frame.error as { message?: string }) ?? {};\n throw new Error(String(errObj.message || frame.message || \"daemon error\"));\n }\n\n if (eventType === \"status\") {\n const loopEv = frame.loop_id;\n if (typeof loopEv === \"string\" && loopEv) {\n this.loopId = loopEv;\n expectedLoopId = loopEv;\n }\n const state = String(frame.state ?? \"\");\n if (state === \"running\") {\n queryStarted = true;\n } else if (queryStarted && state === \"stopped\") {\n this.lastTurnEndState = state;\n yield* this.drainStreamEventsAfterIdle(expectedLoopId);\n break;\n } else if (queryStarted && state === \"idle\") {\n if (!streamPayloadSeen && !this.lastTurnCancellationSeen) continue;\n this.lastTurnEndState = state;\n yield* this.drainStreamEventsAfterIdle(expectedLoopId);\n break;\n }\n continue;\n }\n\n if (eventType === \"command_response\") {\n const content = String(frame.content ?? \"\");\n if (content.includes(\"Cancellation requested\")) {\n this.lastTurnCancellationSeen = true;\n }\n continue;\n }\n\n if (eventType !== \"event\") continue;\n\n const data = frame.data;\n const namespace = Array.isArray(frame.namespace) ? (frame.namespace as unknown[]) : [];\n const mode = String(frame.mode ?? \"\");\n if (this.shouldDrop(namespace, mode, data)) {\n this.turnEventStats.filteredEarly += 1;\n continue;\n }\n\n if (mode === \"custom\" && isTurnEndCustomData(data)) {\n if (!queryStarted || !turnProgressSeen) continue;\n }\n\n streamPayloadSeen = true;\n if (isTurnProgressChunk(mode, data)) turnProgressSeen = true;\n yield [namespace, mode, data];\n\n if (mode === \"custom\" && isTurnEndCustomData(data)) {\n const customType = String((data as Record<string, unknown>).type ?? \"\").trim();\n this.lastTurnEndState = customType === STREAM_END ? \"stream_end\" : \"completed\";\n yield* this.drainStreamEventsAfterIdle(expectedLoopId);\n break;\n }\n }\n } catch (exc) {\n this.lastTurnErrorMessage = String(exc);\n throw exc;\n } finally {\n this.streaming = false;\n this.readBusy = false;\n }\n }\n}\n"],"mappings":"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","names":["Client","ChatEventTerminal","dataType","dt","buf","TimeoutPolicy","res"]}