@agimon-ai/doompi-core 0.0.1-alpha.108 → 0.0.1-alpha.109
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/dist/src/pi/piSessionRuntime.cjs +1 -4
- package/dist/src/pi/piSessionRuntime.cjs.map +1 -1
- package/dist/src/pi/piSessionRuntime.d.mts.map +1 -1
- package/dist/src/pi/piSessionRuntime.mjs +1 -4
- package/dist/src/pi/piSessionRuntime.mjs.map +1 -1
- package/dist/src/schemas/headless.cjs.map +1 -1
- package/dist/src/schemas/headless.d.mts +6 -7
- package/dist/src/schemas/headless.d.mts.map +1 -1
- package/dist/src/schemas/headless.mjs.map +1 -1
- package/dist/src/server/directHarnessRuntime.cjs +195 -58
- package/dist/src/server/directHarnessRuntime.cjs.map +1 -1
- package/dist/src/server/directHarnessRuntime.mjs +195 -58
- package/dist/src/server/directHarnessRuntime.mjs.map +1 -1
- package/dist/src/services/piExtensionHost/index.cjs +20 -13
- package/dist/src/services/piExtensionHost/index.cjs.map +1 -1
- package/dist/src/services/piExtensionHost/index.mjs +20 -13
- package/dist/src/services/piExtensionHost/index.mjs.map +1 -1
- package/dist/src/services/piSessionEntries/index.cjs +14 -5
- package/dist/src/services/piSessionEntries/index.cjs.map +1 -1
- package/dist/src/services/piSessionEntries/index.mjs +14 -5
- package/dist/src/services/piSessionEntries/index.mjs.map +1 -1
- package/dist/src/systems/child/adapters/headlessChildSessionService.cjs +6 -2
- package/dist/src/systems/child/adapters/headlessChildSessionService.cjs.map +1 -1
- package/dist/src/systems/child/adapters/headlessChildSessionService.d.mts.map +1 -1
- package/dist/src/systems/child/adapters/headlessChildSessionService.mjs +6 -2
- package/dist/src/systems/child/adapters/headlessChildSessionService.mjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.cjs +7 -5
- package/dist/src/systems/main/adapters/headlessSessionHost.cjs.map +1 -1
- package/dist/src/systems/main/adapters/headlessSessionHost.mjs +7 -5
- package/dist/src/systems/main/adapters/headlessSessionHost.mjs.map +1 -1
- package/dist/src/types/server/directHarnessRuntime.d.mts +9 -1
- package/dist/src/types/server/directHarnessRuntime.d.mts.map +1 -1
- package/dist/terminalPiChildSessionService.cjs +6 -2
- package/dist/terminalPiChildSessionService.cjs.map +1 -1
- package/dist/terminalPiChildSessionService.d.mts.map +1 -1
- package/dist/terminalPiChildSessionService.mjs +6 -2
- package/dist/terminalPiChildSessionService.mjs.map +1 -1
- package/package.json +4 -4
|
@@ -409,10 +409,7 @@ function createAgentSessionRuntime(options) {
|
|
|
409
409
|
async steer(text) {
|
|
410
410
|
requireLive();
|
|
411
411
|
const args = messageArgs(text);
|
|
412
|
-
|
|
413
|
-
type: "error",
|
|
414
|
-
error: String(error)
|
|
415
|
-
}));
|
|
412
|
+
await options.runtime.steer(args.message, args.images);
|
|
416
413
|
},
|
|
417
414
|
async abort() {
|
|
418
415
|
requireLive();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"piSessionRuntime.cjs","names":["createRpcTranscript","createSessionPresentation","createAcpSessionUpdateProjection","replicatedState","BACKGROUND_CONTEXT","transcriptCursor","readTranscriptPage","RemoteServiceProvider","DoomSessionManagementService","createRemoteServiceEndpoint","SessionNotFoundError","DoomSessionService"],"sources":["../../../src/pi/piSessionRuntime.ts"],"sourcesContent":["import {\n createRemoteServiceEndpoint,\n RemoteServiceProvider,\n replicatedState,\n type Context,\n type MutableReplicatedState,\n type RemoteServiceEndpoint,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { RoutedServerServiceHost, RoutedSessionHandle, ServerHost } from '@earendil-works/pi-server';\nimport { SessionNotFoundError } from '@earendil-works/pi-server';\n\nimport {\n DoomSessionManagementService,\n DoomSessionService,\n type SessionService,\n type SessionMessageArgs,\n type PromptArgs,\n type SessionServiceState,\n type SessionSnapshot,\n type SessionLifecycle,\n type TranscriptItem,\n type TranscriptPage,\n type TranscriptPageRequest,\n type RewindResult,\n type SessionStateInfo,\n type SessionStats,\n type SessionCommand,\n type ModelRef,\n type ThinkingLevel,\n} from '../exports/sessionProtocol';\nimport { createAcpSessionUpdateProjection } from '../services/acpSessionUpdates';\nimport { createRpcTranscript, type RpcTranscript } from '../services/rpcTranscript';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { createSessionPresentation } from '../services/sessionPresentation';\nimport { readTranscriptPage, transcriptCursor } from '../services/transcriptPages';\nimport type { DirectHarnessRuntime, DirectHarnessFrame } from '../types/server/directHarnessRuntime';\n\nconst SETTLED = 'agent_settled';\nconst PROMPT_LATENCY_EVENT = 'doompi_server.prompt_latency';\nconst SELECTION_COMMANDS = new Set(['mode', 'domains', 'profile', 'minor']);\n\nfunction isSelectionCommand(text: string): boolean {\n const match = /^\\/(\\S+)/.exec(text);\n return match !== null && SELECTION_COMMANDS.has(match[1]!);\n}\n\ntype PromptLatency = {\n readonly startedAt: number;\n lastStageAt: number;\n readonly reported: Set<string>;\n};\n\nasync function sessionStats(runtime: DirectHarnessRuntime, sessionId: string): Promise<SessionStats> {\n const stored = await runtime.getSessionStats();\n const { contextUsage, sessionFile } = stored;\n return {\n sessionId,\n ...(sessionFile === undefined ? {} : { sessionFile }),\n totalMessages: stored.messageCount,\n tokens: {\n input: stored.usage.input,\n output: stored.usage.output,\n cacheRead: stored.usage.cacheRead,\n cacheWrite: stored.usage.cacheWrite,\n total: stored.usage.totalTokens,\n },\n cost: stored.usage.cost.total,\n ...(contextUsage === undefined ? {} : { contextUsage }),\n };\n}\n\nexport interface AgentSessionRuntimeOptions {\n runtime: DirectHarnessRuntime;\n sessionId: string;\n sessionName: string;\n cwd: string;\n telemetry?: ServerTelemetry;\n /** Subscribes to the combined harness and headless presentation projection. */\n onPresentationFrame?: (listener: (frame: DirectHarnessFrame) => void) => () => void;\n /** Delivers one answered extension UI request to the session-scoped headless host. */\n respondToExtensionUi?: (frame: DirectHarnessFrame) => boolean;\n /** Test seam for the projection. */\n transcript?: RpcTranscript;\n readThreadTranscript?: (\n threadId: string,\n request: TranscriptPageRequest,\n context: Context,\n ) => Promise<TranscriptPage>;\n}\n\nexport interface AgentSessionRuntime extends SessionService {\n readonly state: MutableReplicatedState<SessionServiceState>;\n initialize(): Promise<void>;\n dispose(): Promise<void>;\n}\n\n/** Projects one in-process harness runtime as a Chord session service. */\nexport function createAgentSessionRuntime(options: AgentSessionRuntimeOptions): AgentSessionRuntime {\n const transcript =\n options.transcript ??\n createRpcTranscript({\n id: options.sessionId,\n cwd: options.cwd,\n name: options.sessionName,\n now: Date.now,\n retainEntries: 0,\n });\n const presentation = createSessionPresentation();\n const acpUpdates = createAcpSessionUpdateProjection();\n let updateSequence = 0;\n const inFlight = new Map<string, TranscriptItem>();\n let historyGeneration = 0;\n const summary = (snapshot: SessionSnapshot): Omit<SessionSnapshot, 'transcript'> => {\n const { transcript: _history, ...value } = snapshot;\n return value;\n };\n const state = replicatedState<SessionServiceState>({\n snapshot: { ...summary(transcript.snapshot()), fastMode: false },\n progress: null,\n updates: [],\n presentation: { revision: 0, dropped: 0, events: [], projections: [] },\n });\n void options.runtime\n .readState()\n .then((runtimeState) => {\n if (!disposed)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.snapshot.fastMode = runtimeState.fastMode === true;\n });\n })\n .catch((error) => {\n if (!disposed) present({ type: 'error', error: String(error) });\n });\n const present = (frame: Record<string, unknown>): boolean => {\n if (frame.type === 'fast_mode_changed' && typeof frame.enabled === 'boolean')\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.snapshot.fastMode = frame.enabled as boolean;\n });\n const entry = frame.entry as { seq?: number } | undefined;\n if (frame.type === 'entry_appended' && typeof entry?.seq === 'number')\n frame = {\n ...frame,\n transcriptCursor: transcriptCursor(options.sessionId, options.runtime.laneName, historyGeneration, entry.seq),\n };\n const next = presentation.record(frame);\n if (next)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.presentation = next;\n });\n return next !== undefined;\n };\n const settlers = new Set<{ resolve(): void; reject(error: Error): void }>();\n const promptFailures = new Set<(error: Error) => void>();\n let promptLatency: PromptLatency | undefined;\n let lastToolResultAt: number | undefined;\n let assistantMessageStartedAt: number | undefined;\n let disposed = false;\n const reportPromptLatency = (phase: string): void => {\n const active = promptLatency;\n if (active === undefined || active.reported.has(phase) || options.telemetry === undefined) return;\n const now = Date.now();\n active.reported.add(phase);\n observe(\n options.telemetry.recordEvent(PROMPT_LATENCY_EVENT, {\n session_id: options.sessionId,\n phase,\n duration_ms: now - active.startedAt,\n stage_duration_ms: now - active.lastStageAt,\n }),\n );\n active.lastStageAt = now;\n };\n const rejectSettlers = (error: Error): void => {\n for (const waiter of settlers) waiter.reject(error);\n settlers.clear();\n };\n\n const subscribePresentation =\n options.onPresentationFrame ??\n ((listener: (frame: DirectHarnessFrame) => void) => options.runtime.onPresentationFrame(listener));\n const unsubscribePresentation = subscribePresentation((frame) => {\n if (disposed) return;\n const message =\n typeof frame.message === 'object' && frame.message !== null ? (frame.message as { role?: unknown }) : undefined;\n if (frame.type === 'message_end' && message?.role === 'toolResult') lastToolResultAt = Date.now();\n if (frame.type === 'message_start' && message?.role === 'assistant') {\n const now = Date.now();\n assistantMessageStartedAt = now;\n if (lastToolResultAt !== undefined && options.telemetry) {\n observe(\n options.telemetry.recordEvent('doompi_server.tool_result_to_response', {\n session_id: options.sessionId,\n duration_ms: now - lastToolResultAt,\n }),\n );\n }\n lastToolResultAt = undefined;\n }\n if (frame.type === 'message_end' && message?.role === 'assistant') {\n if (assistantMessageStartedAt !== undefined && options.telemetry)\n observe(\n options.telemetry.recordEvent('doompi_server.assistant_message', {\n session_id: options.sessionId,\n duration_ms: Date.now() - assistantMessageStartedAt,\n }),\n );\n assistantMessageStartedAt = undefined;\n }\n if (frame.type === 'agent_start') reportPromptLatency('agent_started');\n else if (frame.type === 'message_start' && message?.role === 'assistant') reportPromptLatency('response_started');\n else if (frame.type === 'message_update' && message?.role === 'assistant') reportPromptLatency('first_response');\n else if (frame.type === 'message_end' && message?.role === 'assistant') reportPromptLatency('response_completed');\n const reductionStartedAt = performance.now();\n const reduction = transcript.apply(frame);\n if (frame.type === 'lifecycle_update' && frame.lifecycle !== undefined)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n const lifecycle = frame.lifecycle as SessionLifecycle;\n if ((draft.snapshot.lifecycle?.revision ?? -1) <= lifecycle.revision) draft.snapshot.lifecycle = lifecycle;\n });\n const updates = acpUpdates.apply(frame, reduction);\n const reductionDurationMs = performance.now() - reductionStartedAt;\n if (reduction.aggregate && options.telemetry) {\n observe(\n options.telemetry.recordEvent('doompi_server.transcript.aggregate', {\n session_id: options.sessionId,\n ...reduction.aggregate,\n }),\n );\n }\n if (reduction.snapshot || updates.length > 0) {\n state.change(BACKGROUND_CONTEXT, (draft) => {\n if (reduction.snapshot)\n draft.snapshot = {\n ...summary(reduction.snapshot),\n fastMode: draft.snapshot.fastMode ?? false,\n ...(draft.snapshot.lifecycle === undefined ? {} : { lifecycle: draft.snapshot.lifecycle }),\n };\n if (updates.length > 0) {\n const events = draft.updates ?? [];\n for (const update of updates) events.push({ sequence: ++updateSequence, update });\n if (events.length > 128) events.splice(0, events.length - 128);\n draft.updates = events;\n }\n });\n }\n if (reduction.progress) {\n const progress = reduction.progress;\n if (progress.type === 'item_finished') inFlight.delete(progress.item.id);\n else inFlight.set(progress.item.id, progress.item);\n }\n if (state.value.snapshot.phase === 'idle') inFlight.clear();\n if (frame.type === 'navigation_end') historyGeneration += 1;\n const changed = present(frame);\n const publishStartedAt = performance.now();\n void (reduction.snapshot || reduction.progress || updates.length > 0 || changed);\n const publishDurationMs = performance.now() - publishStartedAt;\n if (options.telemetry && (reductionDurationMs >= 50 || publishDurationMs >= 50 || frame.type === SETTLED))\n observe(\n options.telemetry.recordEvent('doompi_server.presentation_frame', {\n session_id: options.sessionId,\n 'frame.type': frame.type,\n phase: 'reduce_and_publish',\n duration_ms: reductionDurationMs + publishDurationMs,\n }),\n );\n if (frame.type === SETTLED) {\n lastToolResultAt = undefined;\n assistantMessageStartedAt = undefined;\n reportPromptLatency('settled');\n promptLatency = undefined;\n const waiting = [...settlers];\n settlers.clear();\n for (const settle of waiting) settle.resolve();\n }\n });\n\n const terminate = (error: Error): void => {\n if (disposed) return;\n disposed = true;\n for (const fail of promptFailures) fail(error);\n promptFailures.clear();\n rejectSettlers(error);\n unsubscribePresentation();\n };\n observe(\n options.runtime.exited.then(\n () => terminate(new Error('The session runtime exited')),\n (error: unknown) => terminate(error instanceof Error ? error : new Error(String(error))),\n ),\n );\n const requireLive = (): void => {\n if (disposed) throw new Error('The session runtime is disposed');\n };\n const guardContext = (context: Context): void => {\n requireLive();\n context.abortSignal?.throwIfAborted();\n };\n const awaitSettled = (): { promise: Promise<void>; resolve(): void; reject(error: Error): void } => {\n let fail!: (error: Error) => void;\n let finish!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const waiter = {\n resolve: () => {\n settlers.delete(waiter);\n resolve();\n },\n reject: (error: Error) => {\n settlers.delete(waiter);\n reject(error);\n },\n };\n fail = waiter.reject;\n finish = waiter.resolve;\n settlers.add(waiter);\n });\n observe(promise);\n return { promise, resolve: finish, reject: fail };\n };\n const messageArgs = (\n input: string | SessionMessageArgs,\n ): { message: string; images?: SessionMessageArgs['images'] } => {\n const args = typeof input === 'string' ? { text: input } : input;\n if (!args || typeof args.text !== 'string') throw new Error('Prompt message must be a string');\n if (\n args.images !== undefined &&\n (!Array.isArray(args.images) ||\n !args.images.every(\n (image) => image?.type === 'image' && typeof image.data === 'string' && typeof image.mimeType === 'string',\n ))\n )\n throw new Error('Invalid message images');\n return { message: args.text, ...(args.images === undefined ? {} : { images: args.images }) };\n };\n const hydrate = async (): Promise<void> => {\n const lifecycle = await options.runtime.readLifecycle();\n if (disposed) return;\n state.change(BACKGROUND_CONTEXT, (draft) => {\n if ((draft.snapshot.lifecycle?.revision ?? -1) <= lifecycle.revision) draft.snapshot.lifecycle = lifecycle;\n draft.presentation = presentation.resetCustomEntries();\n });\n };\n let initializing: Promise<void> | undefined;\n\n return {\n state,\n async readTranscriptPage(args, context) {\n guardContext(context);\n if (args.threadId !== undefined) {\n if (!options.readThreadTranscript) throw new Error('Child transcript reader is unavailable');\n return options.readThreadTranscript(args.threadId, args, context);\n }\n const generation = historyGeneration;\n const revision = state.value.presentation?.revision ?? 0;\n const drafts = [...inFlight.values()];\n const started = performance.now();\n let snapshot: ReturnType<DirectHarnessRuntime['readEntries']> | undefined;\n const readEntries = () => (snapshot ??= options.runtime.readEntries());\n const page = await readTranscriptPage(\n {\n sessionId: options.runtime.sessionId,\n laneName: options.runtime.laneName,\n lane: {\n getTipId: async () => (await readEntries()).leafId,\n findEntries: async (query) => {\n let entries = (await readEntries()).entries;\n if (query.type) entries = entries.filter((e) => e.type === query.type);\n if (query.customType)\n entries = entries.filter((e) => e.type === 'custom' && e.customType === query.customType);\n if (query.cursor)\n entries = entries.filter((e) =>\n query.order === 'oldestFirst' ? e.seq > query.cursor!.seq : e.seq < query.cursor!.seq,\n );\n if (query.order === 'newestFirst') entries = entries.toReversed();\n return query.limit === undefined ? entries : entries.slice(0, query.limit);\n },\n },\n },\n args,\n generation,\n context,\n );\n if (options.telemetry)\n observe(\n options.telemetry.recordEvent('doompi_server.transcript_page', {\n session_id: options.sessionId,\n phase: args.direction ?? 'latest',\n duration_ms: performance.now() - started,\n count: page.entries.length,\n }),\n );\n if (generation !== historyGeneration) throw new Error('STALE_TRANSCRIPT_CURSOR');\n return { ...page, revision, drafts };\n },\n initialize() {\n initializing ??= hydrate().catch((error: unknown) => {\n initializing = undefined;\n throw error;\n });\n return initializing;\n },\n async prompt(text: string | PromptArgs, context) {\n guardContext(context);\n const args = messageArgs(text);\n const waitFor = typeof text === 'string' ? 'settled' : (text.waitFor ?? 'settled');\n if (waitFor !== 'accepted' && waitFor !== 'settled') throw new Error('Invalid prompt acknowledgement mode');\n let projection: ReturnType<typeof awaitSettled> | undefined;\n let latency: PromptLatency | undefined;\n let submitted = false;\n let failed: Error | undefined;\n let rejectFailure!: (error: Error) => void;\n const failure = new Promise<void>((_resolve, reject) => {\n rejectFailure = reject;\n });\n const fail = (error: Error): void => {\n if (failed !== undefined) return;\n failed = error;\n projection?.reject(error);\n rejectFailure(error);\n if (latency !== undefined && promptLatency === latency) {\n reportPromptLatency('failed');\n promptLatency = undefined;\n }\n };\n const cancel = (): void => {\n if (failed !== undefined) return;\n fail(new Error('The session prompt was cancelled', { cause: context.abortSignal?.reason }));\n if (submitted && waitFor === 'settled') void options.runtime.abort().catch(() => undefined);\n };\n const guardPrompt = (): void => {\n if (failed !== undefined) throw failed;\n guardContext(context);\n };\n const submit = async () => {\n guardPrompt();\n submitted = true;\n const submission = await options.runtime.submitPrompt(args.message, args.images);\n observe(submission.settled);\n guardPrompt();\n return submission;\n };\n const span = <T>(name: string, callback: () => Promise<T>): Promise<T> => {\n const operation = options.telemetry\n ? options.telemetry.runInSpan(name, { session_id: options.sessionId }, callback)\n : callback();\n observe(operation);\n return operation;\n };\n const run = async (): Promise<void> => {\n guardPrompt();\n const lifecycle = await options.runtime.readLifecycle();\n guardPrompt();\n if (lifecycle.operation !== null || settlers.size > 0) {\n if (isSelectionCommand(args.message)) {\n const handled = await options.runtime.dispatchCommand(args.message);\n guardPrompt();\n if (handled) return;\n }\n throw new Error('A turn is already running');\n }\n if (waitFor === 'accepted' && !options.telemetry) {\n await submit();\n return;\n }\n const startedAt = Date.now();\n latency = promptLatency = { startedAt, lastStageAt: startedAt, reported: new Set() };\n const settled = (projection = awaitSettled());\n let resolveAdmission: (() => void) | undefined;\n const admitted =\n waitFor === 'accepted'\n ? new Promise<void>((resolve) => {\n resolveAdmission = resolve;\n })\n : undefined;\n const completion = span('doompi_server.prompt_to_settled', async () => {\n const submission = await span('doompi_server.prompt_admission', submit);\n guardPrompt();\n if (submission.handledCommand) settled.resolve();\n reportPromptLatency('accepted');\n resolveAdmission?.();\n await Promise.all([\n span('doompi_server.prompt_engine_settlement', () => submission.settled),\n span('doompi_server.prompt_projection_settlement', () => settled.promise),\n ]);\n }).catch((error: unknown) => {\n const cause = error instanceof Error ? error : new Error(String(error));\n fail(cause);\n throw cause;\n });\n if (admitted) await Promise.race([admitted, completion]);\n else await completion;\n };\n promptFailures.add(fail);\n context.abortSignal?.addEventListener('abort', cancel, { once: true });\n try {\n await Promise.race([run(), failure]);\n } catch (error) {\n const cause = error instanceof Error ? error : new Error(String(error));\n fail(cause);\n throw cause;\n } finally {\n promptFailures.delete(fail);\n context.abortSignal?.removeEventListener('abort', cancel);\n }\n },\n async steer(text: string | SessionMessageArgs) {\n requireLive();\n const args = messageArgs(text);\n const submission = await options.runtime.submitUserPrompt(args.message, args.images);\n void submission.settled.catch((error: unknown) => present({ type: 'error', error: String(error) }));\n },\n async abort() {\n requireLive();\n await options.runtime.abort((await options.runtime.readLifecycle()).operation?.id);\n },\n async abortOperation(args) {\n requireLive();\n if (!args || typeof args.operationId !== 'string' || !args.operationId)\n throw new Error('Invalid operation identity');\n await options.runtime.abort(args.operationId);\n },\n async setModel(model, context) {\n guardContext(context);\n if (!model || typeof model.provider !== 'string' || typeof model.id !== 'string')\n throw new Error('Invalid model');\n await options.runtime.setModel(model);\n },\n async setFastMode(enabled, context) {\n guardContext(context);\n if (typeof enabled !== 'boolean') throw new Error('Invalid fast mode');\n await options.runtime.setFastMode(enabled);\n state.change(context, (draft) => {\n draft.snapshot.fastMode = enabled;\n });\n },\n async setThinking(thinkingLevel, context) {\n guardContext(context);\n if (!['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'].includes(thinkingLevel))\n throw new Error('Invalid thinking level');\n await options.runtime.setThinkingLevel(thinkingLevel);\n },\n async followUp(args, context) {\n guardContext(context);\n const message = messageArgs(args);\n await options.runtime.followUp(message.message, message.images);\n },\n async enqueueAutomatic(args, context) {\n guardContext(context);\n const message = messageArgs(args);\n return options.runtime.enqueueAutomatic(message.message, message.images);\n },\n async removeQueued(args, context) {\n guardContext(context);\n if (!args || typeof args.id !== 'string' || !args.id) throw new Error('Invalid queue identity');\n return options.runtime.removeQueued(args.id);\n },\n async promoteQueued(args, context) {\n guardContext(context);\n if (\n !args ||\n typeof args.id !== 'string' ||\n !args.id ||\n (args.operationId !== undefined && (typeof args.operationId !== 'string' || !args.operationId))\n )\n throw new Error('Invalid queue promotion');\n return options.runtime.promoteQueued(args.id, args.operationId);\n },\n async resumeQueue(context) {\n guardContext(context);\n await options.runtime.resumeQueue();\n },\n async clearQueue(context) {\n guardContext(context);\n return options.runtime.clearQueue();\n },\n async rewind(args, context) {\n guardContext(context);\n if (!args || typeof args.itemId !== 'string' || !args.itemId) throw new Error('Invalid rewind identity');\n const { entries } = await options.runtime.readEntries();\n const entry = entries.toReversed().find((candidate) => {\n if (candidate.type !== 'message' || typeof candidate.id !== 'string') return false;\n const message = candidate.message;\n if (!message || typeof message !== 'object' || Array.isArray(message)) return false;\n const record = message as unknown as Record<string, unknown>;\n return (\n candidate.id === args.itemId ||\n record.id === args.itemId ||\n (record.role === 'user' && typeof record.timestamp === 'number' && args.itemId === `user-${record.timestamp}`)\n );\n });\n if (!entry) throw new Error('The selected message is not in the active session tree.');\n const result = await options.runtime.navigateTree(entry.id, {\n ...(args.summarize === undefined ? {} : { summarize: args.summarize }),\n ...(args.customInstructions === undefined ? {} : { customInstructions: args.customInstructions }),\n ...(args.replaceInstructions === undefined ? {} : { replaceInstructions: args.replaceInstructions }),\n ...(args.label === undefined ? {} : { label: args.label }),\n });\n if (!result.cancelled) await hydrate();\n return result as RewindResult;\n },\n async extensionUiResponse(response, context) {\n guardContext(context);\n if (\n !response ||\n typeof response.id !== 'string' ||\n !response.id ||\n !(\n ('value' in response && typeof response.value === 'string') ||\n ('confirmed' in response && typeof response.confirmed === 'boolean') ||\n ('cancelled' in response && response.cancelled === true)\n )\n )\n throw new Error('Invalid extension UI response');\n if (!options.respondToExtensionUi?.({ ...response, type: 'extension_ui_response' }))\n throw new Error(`No pending extension UI request: ${response.id}`);\n present({ type: 'extension_ui_answered', id: response.id });\n state.change(context, () => undefined);\n },\n async getState(context) {\n guardContext(context);\n const runtimeState = await options.runtime.readState();\n return { ...runtimeState, fastMode: runtimeState.fastMode === true } as unknown as SessionStateInfo;\n },\n async getSessionStats(context) {\n guardContext(context);\n return sessionStats(options.runtime, options.sessionId);\n },\n async getCommands(context) {\n guardContext(context);\n return options.runtime.listCommands() as SessionCommand[];\n },\n async getAvailableModels(context) {\n guardContext(context);\n return (await options.runtime.availableModels()).map((model) => ({\n provider: model.provider,\n id: model.id,\n })) as ModelRef[];\n },\n async getAvailableThinkingLevels(context) {\n guardContext(context);\n return (await options.runtime.availableThinkingLevels()) as ThinkingLevel[];\n },\n async compact(args, context) {\n guardContext(context);\n await options.runtime.compact(args.customInstructions);\n return null;\n },\n async setName(name, context) {\n guardContext(context);\n if (typeof name !== 'string' || name.length > 256) throw new Error('Invalid session name');\n await options.runtime.setName(name);\n },\n async dispose() {\n terminate(new Error('The session runtime is disposed'));\n },\n };\n}\n\nexport interface AgentServerServiceOptions extends AgentSessionRuntimeOptions {\n createdAt: number;\n}\n\nexport interface DoomSessionMetadata {\n id: string;\n createdAt: number;\n storageVersion: number;\n cwd: string;\n sessionName: string;\n}\n\nfunction endpointAttachment(endpoint: RemoteServiceEndpoint): {\n invokeService: RemoteServiceEndpoint['invoke'];\n release(): void;\n} {\n return {\n invokeService: (call, publish, context) => endpoint.invoke(call, publish, context),\n release: () => endpoint.dispose(),\n };\n}\n\nfunction managementHost(): RoutedServerServiceHost {\n return {\n attachClient(presentation) {\n const provider = new RemoteServiceProvider([{ service: DoomSessionManagementService, mode: 'singleton' }]);\n provider.provide(DoomSessionManagementService, {\n attach: (sessionId, context) => presentation.attachSession(sessionId, context),\n detach: (context) => presentation.detachSession(context),\n });\n return endpointAttachment(createRemoteServiceEndpoint(provider));\n },\n };\n}\n\n/** Creates the 0.85 routed host for one supervised DoomPi session. */\nexport function createAgentServerService(options: AgentServerServiceOptions): ServerHost<DoomSessionMetadata> {\n const metadata: DoomSessionMetadata = {\n id: options.sessionId,\n createdAt: options.createdAt,\n storageVersion: 1,\n cwd: options.cwd,\n sessionName: options.sessionName,\n };\n const runtime = createAgentSessionRuntime(options);\n let closed = false;\n\n return {\n serverServices: managementHost(),\n async resolveSession(sessionId) {\n if (sessionId !== metadata.id) throw new SessionNotFoundError(`No session ${sessionId}`);\n return metadata;\n },\n async openSession() {\n if (closed) throw new SessionNotFoundError('The session service is closed');\n await runtime.initialize();\n const provider = new RemoteServiceProvider([{ service: DoomSessionService, mode: 'singleton' }]);\n provider.provide(DoomSessionService, runtime);\n const handle: RoutedSessionHandle = {\n attachClient: () => endpointAttachment(createRemoteServiceEndpoint(provider)),\n async close() {\n if (closed) return;\n closed = true;\n provider.dispose();\n await runtime.dispose();\n },\n };\n return handle;\n },\n };\n}\n\nexport type { SessionSnapshot };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"piSessionRuntime.cjs","names":["createRpcTranscript","createSessionPresentation","createAcpSessionUpdateProjection","replicatedState","BACKGROUND_CONTEXT","transcriptCursor","readTranscriptPage","RemoteServiceProvider","DoomSessionManagementService","createRemoteServiceEndpoint","SessionNotFoundError","DoomSessionService"],"sources":["../../../src/pi/piSessionRuntime.ts"],"sourcesContent":["import {\n createRemoteServiceEndpoint,\n RemoteServiceProvider,\n replicatedState,\n type Context,\n type MutableReplicatedState,\n type RemoteServiceEndpoint,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { RoutedServerServiceHost, RoutedSessionHandle, ServerHost } from '@earendil-works/pi-server';\nimport { SessionNotFoundError } from '@earendil-works/pi-server';\n\nimport {\n DoomSessionManagementService,\n DoomSessionService,\n type SessionService,\n type SessionMessageArgs,\n type PromptArgs,\n type SessionServiceState,\n type SessionSnapshot,\n type SessionLifecycle,\n type TranscriptItem,\n type TranscriptPage,\n type TranscriptPageRequest,\n type RewindResult,\n type SessionStateInfo,\n type SessionStats,\n type SessionCommand,\n type ModelRef,\n type ThinkingLevel,\n} from '../exports/sessionProtocol';\nimport { createAcpSessionUpdateProjection } from '../services/acpSessionUpdates';\nimport { createRpcTranscript, type RpcTranscript } from '../services/rpcTranscript';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { createSessionPresentation } from '../services/sessionPresentation';\nimport { readTranscriptPage, transcriptCursor } from '../services/transcriptPages';\nimport type { DirectHarnessRuntime, DirectHarnessFrame } from '../types/server/directHarnessRuntime';\n\nconst SETTLED = 'agent_settled';\nconst PROMPT_LATENCY_EVENT = 'doompi_server.prompt_latency';\nconst SELECTION_COMMANDS = new Set(['mode', 'domains', 'profile', 'minor']);\n\nfunction isSelectionCommand(text: string): boolean {\n const match = /^\\/(\\S+)/.exec(text);\n return match !== null && SELECTION_COMMANDS.has(match[1]!);\n}\n\ntype PromptLatency = {\n readonly startedAt: number;\n lastStageAt: number;\n readonly reported: Set<string>;\n};\n\nasync function sessionStats(runtime: DirectHarnessRuntime, sessionId: string): Promise<SessionStats> {\n const stored = await runtime.getSessionStats();\n const { contextUsage, sessionFile } = stored;\n return {\n sessionId,\n ...(sessionFile === undefined ? {} : { sessionFile }),\n totalMessages: stored.messageCount,\n tokens: {\n input: stored.usage.input,\n output: stored.usage.output,\n cacheRead: stored.usage.cacheRead,\n cacheWrite: stored.usage.cacheWrite,\n total: stored.usage.totalTokens,\n },\n cost: stored.usage.cost.total,\n ...(contextUsage === undefined ? {} : { contextUsage }),\n };\n}\n\nexport interface AgentSessionRuntimeOptions {\n runtime: DirectHarnessRuntime;\n sessionId: string;\n sessionName: string;\n cwd: string;\n telemetry?: ServerTelemetry;\n /** Subscribes to the combined harness and headless presentation projection. */\n onPresentationFrame?: (listener: (frame: DirectHarnessFrame) => void) => () => void;\n /** Delivers one answered extension UI request to the session-scoped headless host. */\n respondToExtensionUi?: (frame: DirectHarnessFrame) => boolean;\n /** Test seam for the projection. */\n transcript?: RpcTranscript;\n readThreadTranscript?: (\n threadId: string,\n request: TranscriptPageRequest,\n context: Context,\n ) => Promise<TranscriptPage>;\n}\n\nexport interface AgentSessionRuntime extends SessionService {\n readonly state: MutableReplicatedState<SessionServiceState>;\n initialize(): Promise<void>;\n dispose(): Promise<void>;\n}\n\n/** Projects one in-process harness runtime as a Chord session service. */\nexport function createAgentSessionRuntime(options: AgentSessionRuntimeOptions): AgentSessionRuntime {\n const transcript =\n options.transcript ??\n createRpcTranscript({\n id: options.sessionId,\n cwd: options.cwd,\n name: options.sessionName,\n now: Date.now,\n retainEntries: 0,\n });\n const presentation = createSessionPresentation();\n const acpUpdates = createAcpSessionUpdateProjection();\n let updateSequence = 0;\n const inFlight = new Map<string, TranscriptItem>();\n let historyGeneration = 0;\n const summary = (snapshot: SessionSnapshot): Omit<SessionSnapshot, 'transcript'> => {\n const { transcript: _history, ...value } = snapshot;\n return value;\n };\n const state = replicatedState<SessionServiceState>({\n snapshot: { ...summary(transcript.snapshot()), fastMode: false },\n progress: null,\n updates: [],\n presentation: { revision: 0, dropped: 0, events: [], projections: [] },\n });\n void options.runtime\n .readState()\n .then((runtimeState) => {\n if (!disposed)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.snapshot.fastMode = runtimeState.fastMode === true;\n });\n })\n .catch((error) => {\n if (!disposed) present({ type: 'error', error: String(error) });\n });\n const present = (frame: Record<string, unknown>): boolean => {\n if (frame.type === 'fast_mode_changed' && typeof frame.enabled === 'boolean')\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.snapshot.fastMode = frame.enabled as boolean;\n });\n const entry = frame.entry as { seq?: number } | undefined;\n if (frame.type === 'entry_appended' && typeof entry?.seq === 'number')\n frame = {\n ...frame,\n transcriptCursor: transcriptCursor(options.sessionId, options.runtime.laneName, historyGeneration, entry.seq),\n };\n const next = presentation.record(frame);\n if (next)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.presentation = next;\n });\n return next !== undefined;\n };\n const settlers = new Set<{ resolve(): void; reject(error: Error): void }>();\n const promptFailures = new Set<(error: Error) => void>();\n let promptLatency: PromptLatency | undefined;\n let lastToolResultAt: number | undefined;\n let assistantMessageStartedAt: number | undefined;\n let disposed = false;\n const reportPromptLatency = (phase: string): void => {\n const active = promptLatency;\n if (active === undefined || active.reported.has(phase) || options.telemetry === undefined) return;\n const now = Date.now();\n active.reported.add(phase);\n observe(\n options.telemetry.recordEvent(PROMPT_LATENCY_EVENT, {\n session_id: options.sessionId,\n phase,\n duration_ms: now - active.startedAt,\n stage_duration_ms: now - active.lastStageAt,\n }),\n );\n active.lastStageAt = now;\n };\n const rejectSettlers = (error: Error): void => {\n for (const waiter of settlers) waiter.reject(error);\n settlers.clear();\n };\n\n const subscribePresentation =\n options.onPresentationFrame ??\n ((listener: (frame: DirectHarnessFrame) => void) => options.runtime.onPresentationFrame(listener));\n const unsubscribePresentation = subscribePresentation((frame) => {\n if (disposed) return;\n const message =\n typeof frame.message === 'object' && frame.message !== null ? (frame.message as { role?: unknown }) : undefined;\n if (frame.type === 'message_end' && message?.role === 'toolResult') lastToolResultAt = Date.now();\n if (frame.type === 'message_start' && message?.role === 'assistant') {\n const now = Date.now();\n assistantMessageStartedAt = now;\n if (lastToolResultAt !== undefined && options.telemetry) {\n observe(\n options.telemetry.recordEvent('doompi_server.tool_result_to_response', {\n session_id: options.sessionId,\n duration_ms: now - lastToolResultAt,\n }),\n );\n }\n lastToolResultAt = undefined;\n }\n if (frame.type === 'message_end' && message?.role === 'assistant') {\n if (assistantMessageStartedAt !== undefined && options.telemetry)\n observe(\n options.telemetry.recordEvent('doompi_server.assistant_message', {\n session_id: options.sessionId,\n duration_ms: Date.now() - assistantMessageStartedAt,\n }),\n );\n assistantMessageStartedAt = undefined;\n }\n if (frame.type === 'agent_start') reportPromptLatency('agent_started');\n else if (frame.type === 'message_start' && message?.role === 'assistant') reportPromptLatency('response_started');\n else if (frame.type === 'message_update' && message?.role === 'assistant') reportPromptLatency('first_response');\n else if (frame.type === 'message_end' && message?.role === 'assistant') reportPromptLatency('response_completed');\n const reductionStartedAt = performance.now();\n const reduction = transcript.apply(frame);\n if (frame.type === 'lifecycle_update' && frame.lifecycle !== undefined)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n const lifecycle = frame.lifecycle as SessionLifecycle;\n if ((draft.snapshot.lifecycle?.revision ?? -1) <= lifecycle.revision) draft.snapshot.lifecycle = lifecycle;\n });\n const updates = acpUpdates.apply(frame, reduction);\n const reductionDurationMs = performance.now() - reductionStartedAt;\n if (reduction.aggregate && options.telemetry) {\n observe(\n options.telemetry.recordEvent('doompi_server.transcript.aggregate', {\n session_id: options.sessionId,\n ...reduction.aggregate,\n }),\n );\n }\n if (reduction.snapshot || updates.length > 0) {\n state.change(BACKGROUND_CONTEXT, (draft) => {\n if (reduction.snapshot)\n draft.snapshot = {\n ...summary(reduction.snapshot),\n fastMode: draft.snapshot.fastMode ?? false,\n ...(draft.snapshot.lifecycle === undefined ? {} : { lifecycle: draft.snapshot.lifecycle }),\n };\n if (updates.length > 0) {\n const events = draft.updates ?? [];\n for (const update of updates) events.push({ sequence: ++updateSequence, update });\n if (events.length > 128) events.splice(0, events.length - 128);\n draft.updates = events;\n }\n });\n }\n if (reduction.progress) {\n const progress = reduction.progress;\n if (progress.type === 'item_finished') inFlight.delete(progress.item.id);\n else inFlight.set(progress.item.id, progress.item);\n }\n if (state.value.snapshot.phase === 'idle') inFlight.clear();\n if (frame.type === 'navigation_end') historyGeneration += 1;\n const changed = present(frame);\n const publishStartedAt = performance.now();\n void (reduction.snapshot || reduction.progress || updates.length > 0 || changed);\n const publishDurationMs = performance.now() - publishStartedAt;\n if (options.telemetry && (reductionDurationMs >= 50 || publishDurationMs >= 50 || frame.type === SETTLED))\n observe(\n options.telemetry.recordEvent('doompi_server.presentation_frame', {\n session_id: options.sessionId,\n 'frame.type': frame.type,\n phase: 'reduce_and_publish',\n duration_ms: reductionDurationMs + publishDurationMs,\n }),\n );\n if (frame.type === SETTLED) {\n lastToolResultAt = undefined;\n assistantMessageStartedAt = undefined;\n reportPromptLatency('settled');\n promptLatency = undefined;\n const waiting = [...settlers];\n settlers.clear();\n for (const settle of waiting) settle.resolve();\n }\n });\n\n const terminate = (error: Error): void => {\n if (disposed) return;\n disposed = true;\n for (const fail of promptFailures) fail(error);\n promptFailures.clear();\n rejectSettlers(error);\n unsubscribePresentation();\n };\n observe(\n options.runtime.exited.then(\n () => terminate(new Error('The session runtime exited')),\n (error: unknown) => terminate(error instanceof Error ? error : new Error(String(error))),\n ),\n );\n const requireLive = (): void => {\n if (disposed) throw new Error('The session runtime is disposed');\n };\n const guardContext = (context: Context): void => {\n requireLive();\n context.abortSignal?.throwIfAborted();\n };\n const awaitSettled = (): { promise: Promise<void>; resolve(): void; reject(error: Error): void } => {\n let fail!: (error: Error) => void;\n let finish!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const waiter = {\n resolve: () => {\n settlers.delete(waiter);\n resolve();\n },\n reject: (error: Error) => {\n settlers.delete(waiter);\n reject(error);\n },\n };\n fail = waiter.reject;\n finish = waiter.resolve;\n settlers.add(waiter);\n });\n observe(promise);\n return { promise, resolve: finish, reject: fail };\n };\n const messageArgs = (\n input: string | SessionMessageArgs,\n ): { message: string; images?: SessionMessageArgs['images'] } => {\n const args = typeof input === 'string' ? { text: input } : input;\n if (!args || typeof args.text !== 'string') throw new Error('Prompt message must be a string');\n if (\n args.images !== undefined &&\n (!Array.isArray(args.images) ||\n !args.images.every(\n (image) => image?.type === 'image' && typeof image.data === 'string' && typeof image.mimeType === 'string',\n ))\n )\n throw new Error('Invalid message images');\n return { message: args.text, ...(args.images === undefined ? {} : { images: args.images }) };\n };\n const hydrate = async (): Promise<void> => {\n const lifecycle = await options.runtime.readLifecycle();\n if (disposed) return;\n state.change(BACKGROUND_CONTEXT, (draft) => {\n if ((draft.snapshot.lifecycle?.revision ?? -1) <= lifecycle.revision) draft.snapshot.lifecycle = lifecycle;\n draft.presentation = presentation.resetCustomEntries();\n });\n };\n let initializing: Promise<void> | undefined;\n\n return {\n state,\n async readTranscriptPage(args, context) {\n guardContext(context);\n if (args.threadId !== undefined) {\n if (!options.readThreadTranscript) throw new Error('Child transcript reader is unavailable');\n return options.readThreadTranscript(args.threadId, args, context);\n }\n const generation = historyGeneration;\n const revision = state.value.presentation?.revision ?? 0;\n const drafts = [...inFlight.values()];\n const started = performance.now();\n let snapshot: ReturnType<DirectHarnessRuntime['readEntries']> | undefined;\n const readEntries = () => (snapshot ??= options.runtime.readEntries());\n const page = await readTranscriptPage(\n {\n sessionId: options.runtime.sessionId,\n laneName: options.runtime.laneName,\n lane: {\n getTipId: async () => (await readEntries()).leafId,\n findEntries: async (query) => {\n let entries = (await readEntries()).entries;\n if (query.type) entries = entries.filter((e) => e.type === query.type);\n if (query.customType)\n entries = entries.filter((e) => e.type === 'custom' && e.customType === query.customType);\n if (query.cursor)\n entries = entries.filter((e) =>\n query.order === 'oldestFirst' ? e.seq > query.cursor!.seq : e.seq < query.cursor!.seq,\n );\n if (query.order === 'newestFirst') entries = entries.toReversed();\n return query.limit === undefined ? entries : entries.slice(0, query.limit);\n },\n },\n },\n args,\n generation,\n context,\n );\n if (options.telemetry)\n observe(\n options.telemetry.recordEvent('doompi_server.transcript_page', {\n session_id: options.sessionId,\n phase: args.direction ?? 'latest',\n duration_ms: performance.now() - started,\n count: page.entries.length,\n }),\n );\n if (generation !== historyGeneration) throw new Error('STALE_TRANSCRIPT_CURSOR');\n return { ...page, revision, drafts };\n },\n initialize() {\n initializing ??= hydrate().catch((error: unknown) => {\n initializing = undefined;\n throw error;\n });\n return initializing;\n },\n async prompt(text: string | PromptArgs, context) {\n guardContext(context);\n const args = messageArgs(text);\n const waitFor = typeof text === 'string' ? 'settled' : (text.waitFor ?? 'settled');\n if (waitFor !== 'accepted' && waitFor !== 'settled') throw new Error('Invalid prompt acknowledgement mode');\n let projection: ReturnType<typeof awaitSettled> | undefined;\n let latency: PromptLatency | undefined;\n let submitted = false;\n let failed: Error | undefined;\n let rejectFailure!: (error: Error) => void;\n const failure = new Promise<void>((_resolve, reject) => {\n rejectFailure = reject;\n });\n const fail = (error: Error): void => {\n if (failed !== undefined) return;\n failed = error;\n projection?.reject(error);\n rejectFailure(error);\n if (latency !== undefined && promptLatency === latency) {\n reportPromptLatency('failed');\n promptLatency = undefined;\n }\n };\n const cancel = (): void => {\n if (failed !== undefined) return;\n fail(new Error('The session prompt was cancelled', { cause: context.abortSignal?.reason }));\n if (submitted && waitFor === 'settled') void options.runtime.abort().catch(() => undefined);\n };\n const guardPrompt = (): void => {\n if (failed !== undefined) throw failed;\n guardContext(context);\n };\n const submit = async () => {\n guardPrompt();\n submitted = true;\n const submission = await options.runtime.submitPrompt(args.message, args.images);\n observe(submission.settled);\n guardPrompt();\n return submission;\n };\n const span = <T>(name: string, callback: () => Promise<T>): Promise<T> => {\n const operation = options.telemetry\n ? options.telemetry.runInSpan(name, { session_id: options.sessionId }, callback)\n : callback();\n observe(operation);\n return operation;\n };\n const run = async (): Promise<void> => {\n guardPrompt();\n const lifecycle = await options.runtime.readLifecycle();\n guardPrompt();\n if (lifecycle.operation !== null || settlers.size > 0) {\n if (isSelectionCommand(args.message)) {\n const handled = await options.runtime.dispatchCommand(args.message);\n guardPrompt();\n if (handled) return;\n }\n throw new Error('A turn is already running');\n }\n if (waitFor === 'accepted' && !options.telemetry) {\n await submit();\n return;\n }\n const startedAt = Date.now();\n latency = promptLatency = { startedAt, lastStageAt: startedAt, reported: new Set() };\n const settled = (projection = awaitSettled());\n let resolveAdmission: (() => void) | undefined;\n const admitted =\n waitFor === 'accepted'\n ? new Promise<void>((resolve) => {\n resolveAdmission = resolve;\n })\n : undefined;\n const completion = span('doompi_server.prompt_to_settled', async () => {\n const submission = await span('doompi_server.prompt_admission', submit);\n guardPrompt();\n if (submission.handledCommand) settled.resolve();\n reportPromptLatency('accepted');\n resolveAdmission?.();\n await Promise.all([\n span('doompi_server.prompt_engine_settlement', () => submission.settled),\n span('doompi_server.prompt_projection_settlement', () => settled.promise),\n ]);\n }).catch((error: unknown) => {\n const cause = error instanceof Error ? error : new Error(String(error));\n fail(cause);\n throw cause;\n });\n if (admitted) await Promise.race([admitted, completion]);\n else await completion;\n };\n promptFailures.add(fail);\n context.abortSignal?.addEventListener('abort', cancel, { once: true });\n try {\n await Promise.race([run(), failure]);\n } catch (error) {\n const cause = error instanceof Error ? error : new Error(String(error));\n fail(cause);\n throw cause;\n } finally {\n promptFailures.delete(fail);\n context.abortSignal?.removeEventListener('abort', cancel);\n }\n },\n async steer(text: string | SessionMessageArgs) {\n requireLive();\n const args = messageArgs(text);\n await options.runtime.steer(args.message, args.images);\n },\n async abort() {\n requireLive();\n await options.runtime.abort((await options.runtime.readLifecycle()).operation?.id);\n },\n async abortOperation(args) {\n requireLive();\n if (!args || typeof args.operationId !== 'string' || !args.operationId)\n throw new Error('Invalid operation identity');\n await options.runtime.abort(args.operationId);\n },\n async setModel(model, context) {\n guardContext(context);\n if (!model || typeof model.provider !== 'string' || typeof model.id !== 'string')\n throw new Error('Invalid model');\n await options.runtime.setModel(model);\n },\n async setFastMode(enabled, context) {\n guardContext(context);\n if (typeof enabled !== 'boolean') throw new Error('Invalid fast mode');\n await options.runtime.setFastMode(enabled);\n state.change(context, (draft) => {\n draft.snapshot.fastMode = enabled;\n });\n },\n async setThinking(thinkingLevel, context) {\n guardContext(context);\n if (!['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'].includes(thinkingLevel))\n throw new Error('Invalid thinking level');\n await options.runtime.setThinkingLevel(thinkingLevel);\n },\n async followUp(args, context) {\n guardContext(context);\n const message = messageArgs(args);\n await options.runtime.followUp(message.message, message.images);\n },\n async enqueueAutomatic(args, context) {\n guardContext(context);\n const message = messageArgs(args);\n return options.runtime.enqueueAutomatic(message.message, message.images);\n },\n async removeQueued(args, context) {\n guardContext(context);\n if (!args || typeof args.id !== 'string' || !args.id) throw new Error('Invalid queue identity');\n return options.runtime.removeQueued(args.id);\n },\n async promoteQueued(args, context) {\n guardContext(context);\n if (\n !args ||\n typeof args.id !== 'string' ||\n !args.id ||\n (args.operationId !== undefined && (typeof args.operationId !== 'string' || !args.operationId))\n )\n throw new Error('Invalid queue promotion');\n return options.runtime.promoteQueued(args.id, args.operationId);\n },\n async resumeQueue(context) {\n guardContext(context);\n await options.runtime.resumeQueue();\n },\n async clearQueue(context) {\n guardContext(context);\n return options.runtime.clearQueue();\n },\n async rewind(args, context) {\n guardContext(context);\n if (!args || typeof args.itemId !== 'string' || !args.itemId) throw new Error('Invalid rewind identity');\n const { entries } = await options.runtime.readEntries();\n const entry = entries.toReversed().find((candidate) => {\n if (candidate.type !== 'message' || typeof candidate.id !== 'string') return false;\n const message = candidate.message;\n if (!message || typeof message !== 'object' || Array.isArray(message)) return false;\n const record = message as unknown as Record<string, unknown>;\n return (\n candidate.id === args.itemId ||\n record.id === args.itemId ||\n (record.role === 'user' && typeof record.timestamp === 'number' && args.itemId === `user-${record.timestamp}`)\n );\n });\n if (!entry) throw new Error('The selected message is not in the active session tree.');\n const result = await options.runtime.navigateTree(entry.id, {\n ...(args.summarize === undefined ? {} : { summarize: args.summarize }),\n ...(args.customInstructions === undefined ? {} : { customInstructions: args.customInstructions }),\n ...(args.replaceInstructions === undefined ? {} : { replaceInstructions: args.replaceInstructions }),\n ...(args.label === undefined ? {} : { label: args.label }),\n });\n if (!result.cancelled) await hydrate();\n return result as RewindResult;\n },\n async extensionUiResponse(response, context) {\n guardContext(context);\n if (\n !response ||\n typeof response.id !== 'string' ||\n !response.id ||\n !(\n ('value' in response && typeof response.value === 'string') ||\n ('confirmed' in response && typeof response.confirmed === 'boolean') ||\n ('cancelled' in response && response.cancelled === true)\n )\n )\n throw new Error('Invalid extension UI response');\n if (!options.respondToExtensionUi?.({ ...response, type: 'extension_ui_response' }))\n throw new Error(`No pending extension UI request: ${response.id}`);\n present({ type: 'extension_ui_answered', id: response.id });\n state.change(context, () => undefined);\n },\n async getState(context) {\n guardContext(context);\n const runtimeState = await options.runtime.readState();\n return { ...runtimeState, fastMode: runtimeState.fastMode === true } as unknown as SessionStateInfo;\n },\n async getSessionStats(context) {\n guardContext(context);\n return sessionStats(options.runtime, options.sessionId);\n },\n async getCommands(context) {\n guardContext(context);\n return options.runtime.listCommands() as SessionCommand[];\n },\n async getAvailableModels(context) {\n guardContext(context);\n return (await options.runtime.availableModels()).map((model) => ({\n provider: model.provider,\n id: model.id,\n })) as ModelRef[];\n },\n async getAvailableThinkingLevels(context) {\n guardContext(context);\n return (await options.runtime.availableThinkingLevels()) as ThinkingLevel[];\n },\n async compact(args, context) {\n guardContext(context);\n await options.runtime.compact(args.customInstructions);\n return null;\n },\n async setName(name, context) {\n guardContext(context);\n if (typeof name !== 'string' || name.length > 256) throw new Error('Invalid session name');\n await options.runtime.setName(name);\n },\n async dispose() {\n terminate(new Error('The session runtime is disposed'));\n },\n };\n}\n\nexport interface AgentServerServiceOptions extends AgentSessionRuntimeOptions {\n createdAt: number;\n}\n\nexport interface DoomSessionMetadata {\n id: string;\n createdAt: number;\n storageVersion: number;\n cwd: string;\n sessionName: string;\n}\n\nfunction endpointAttachment(endpoint: RemoteServiceEndpoint): {\n invokeService: RemoteServiceEndpoint['invoke'];\n release(): void;\n} {\n return {\n invokeService: (call, publish, context) => endpoint.invoke(call, publish, context),\n release: () => endpoint.dispose(),\n };\n}\n\nfunction managementHost(): RoutedServerServiceHost {\n return {\n attachClient(presentation) {\n const provider = new RemoteServiceProvider([{ service: DoomSessionManagementService, mode: 'singleton' }]);\n provider.provide(DoomSessionManagementService, {\n attach: (sessionId, context) => presentation.attachSession(sessionId, context),\n detach: (context) => presentation.detachSession(context),\n });\n return endpointAttachment(createRemoteServiceEndpoint(provider));\n },\n };\n}\n\n/** Creates the 0.85 routed host for one supervised DoomPi session. */\nexport function createAgentServerService(options: AgentServerServiceOptions): ServerHost<DoomSessionMetadata> {\n const metadata: DoomSessionMetadata = {\n id: options.sessionId,\n createdAt: options.createdAt,\n storageVersion: 1,\n cwd: options.cwd,\n sessionName: options.sessionName,\n };\n const runtime = createAgentSessionRuntime(options);\n let closed = false;\n\n return {\n serverServices: managementHost(),\n async resolveSession(sessionId) {\n if (sessionId !== metadata.id) throw new SessionNotFoundError(`No session ${sessionId}`);\n return metadata;\n },\n async openSession() {\n if (closed) throw new SessionNotFoundError('The session service is closed');\n await runtime.initialize();\n const provider = new RemoteServiceProvider([{ service: DoomSessionService, mode: 'singleton' }]);\n provider.provide(DoomSessionService, runtime);\n const handle: RoutedSessionHandle = {\n attachClient: () => endpointAttachment(createRemoteServiceEndpoint(provider)),\n async close() {\n if (closed) return;\n closed = true;\n provider.dispose();\n await runtime.dispose();\n },\n };\n return handle;\n },\n };\n}\n\nexport type { SessionSnapshot };\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"piSessionRuntime.d.mts","names":[],"sources":["../../../src/pi/piSessionRuntime.ts"],"mappings":";;;;;;;;iBAwEiB;EACf,SAAS;EACT;EACA;EACA;EACA,YAAY;;EAEZ,uBAAuB,WAAW,OAAO;;EAEzC,wBAAwB,OAAO;;EAE/B,aAAa;EACb,wBACE,kBACA,SAAS,uBACT,SAAS,YACN,QAAQ;;iBAGE,4BAA4B;WAClC,OAAO,uBAAuB;EACvC,cAAc;EACd,WAAW;;;wBAIG,0BAA0B,SAAS,6BAA6B;
|
|
1
|
+
{"version":3,"file":"piSessionRuntime.d.mts","names":[],"sources":["../../../src/pi/piSessionRuntime.ts"],"mappings":";;;;;;;;iBAwEiB;EACf,SAAS;EACT;EACA;EACA;EACA,YAAY;;EAEZ,uBAAuB,WAAW,OAAO;;EAEzC,wBAAwB,OAAO;;EAE/B,aAAa;EACb,wBACE,kBACA,SAAS,uBACT,SAAS,YACN,QAAQ;;iBAGE,4BAA4B;WAClC,OAAO,uBAAuB;EACvC,cAAc;EACd,WAAW;;;wBAIG,0BAA0B,SAAS,6BAA6B;iBA+iB/D,kCAAkC;EACjD;;iBAGe;EACf;EACA;EACA;EACA;EACA;;;wBA2Bc,yBAAyB,SAAS,4BAA4B,WAAW"}
|
|
@@ -409,10 +409,7 @@ function createAgentSessionRuntime(options) {
|
|
|
409
409
|
async steer(text) {
|
|
410
410
|
requireLive();
|
|
411
411
|
const args = messageArgs(text);
|
|
412
|
-
|
|
413
|
-
type: "error",
|
|
414
|
-
error: String(error)
|
|
415
|
-
}));
|
|
412
|
+
await options.runtime.steer(args.message, args.images);
|
|
416
413
|
},
|
|
417
414
|
async abort() {
|
|
418
415
|
requireLive();
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"piSessionRuntime.mjs","names":[],"sources":["../../../src/pi/piSessionRuntime.ts"],"sourcesContent":["import {\n createRemoteServiceEndpoint,\n RemoteServiceProvider,\n replicatedState,\n type Context,\n type MutableReplicatedState,\n type RemoteServiceEndpoint,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { RoutedServerServiceHost, RoutedSessionHandle, ServerHost } from '@earendil-works/pi-server';\nimport { SessionNotFoundError } from '@earendil-works/pi-server';\n\nimport {\n DoomSessionManagementService,\n DoomSessionService,\n type SessionService,\n type SessionMessageArgs,\n type PromptArgs,\n type SessionServiceState,\n type SessionSnapshot,\n type SessionLifecycle,\n type TranscriptItem,\n type TranscriptPage,\n type TranscriptPageRequest,\n type RewindResult,\n type SessionStateInfo,\n type SessionStats,\n type SessionCommand,\n type ModelRef,\n type ThinkingLevel,\n} from '../exports/sessionProtocol';\nimport { createAcpSessionUpdateProjection } from '../services/acpSessionUpdates';\nimport { createRpcTranscript, type RpcTranscript } from '../services/rpcTranscript';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { createSessionPresentation } from '../services/sessionPresentation';\nimport { readTranscriptPage, transcriptCursor } from '../services/transcriptPages';\nimport type { DirectHarnessRuntime, DirectHarnessFrame } from '../types/server/directHarnessRuntime';\n\nconst SETTLED = 'agent_settled';\nconst PROMPT_LATENCY_EVENT = 'doompi_server.prompt_latency';\nconst SELECTION_COMMANDS = new Set(['mode', 'domains', 'profile', 'minor']);\n\nfunction isSelectionCommand(text: string): boolean {\n const match = /^\\/(\\S+)/.exec(text);\n return match !== null && SELECTION_COMMANDS.has(match[1]!);\n}\n\ntype PromptLatency = {\n readonly startedAt: number;\n lastStageAt: number;\n readonly reported: Set<string>;\n};\n\nasync function sessionStats(runtime: DirectHarnessRuntime, sessionId: string): Promise<SessionStats> {\n const stored = await runtime.getSessionStats();\n const { contextUsage, sessionFile } = stored;\n return {\n sessionId,\n ...(sessionFile === undefined ? {} : { sessionFile }),\n totalMessages: stored.messageCount,\n tokens: {\n input: stored.usage.input,\n output: stored.usage.output,\n cacheRead: stored.usage.cacheRead,\n cacheWrite: stored.usage.cacheWrite,\n total: stored.usage.totalTokens,\n },\n cost: stored.usage.cost.total,\n ...(contextUsage === undefined ? {} : { contextUsage }),\n };\n}\n\nexport interface AgentSessionRuntimeOptions {\n runtime: DirectHarnessRuntime;\n sessionId: string;\n sessionName: string;\n cwd: string;\n telemetry?: ServerTelemetry;\n /** Subscribes to the combined harness and headless presentation projection. */\n onPresentationFrame?: (listener: (frame: DirectHarnessFrame) => void) => () => void;\n /** Delivers one answered extension UI request to the session-scoped headless host. */\n respondToExtensionUi?: (frame: DirectHarnessFrame) => boolean;\n /** Test seam for the projection. */\n transcript?: RpcTranscript;\n readThreadTranscript?: (\n threadId: string,\n request: TranscriptPageRequest,\n context: Context,\n ) => Promise<TranscriptPage>;\n}\n\nexport interface AgentSessionRuntime extends SessionService {\n readonly state: MutableReplicatedState<SessionServiceState>;\n initialize(): Promise<void>;\n dispose(): Promise<void>;\n}\n\n/** Projects one in-process harness runtime as a Chord session service. */\nexport function createAgentSessionRuntime(options: AgentSessionRuntimeOptions): AgentSessionRuntime {\n const transcript =\n options.transcript ??\n createRpcTranscript({\n id: options.sessionId,\n cwd: options.cwd,\n name: options.sessionName,\n now: Date.now,\n retainEntries: 0,\n });\n const presentation = createSessionPresentation();\n const acpUpdates = createAcpSessionUpdateProjection();\n let updateSequence = 0;\n const inFlight = new Map<string, TranscriptItem>();\n let historyGeneration = 0;\n const summary = (snapshot: SessionSnapshot): Omit<SessionSnapshot, 'transcript'> => {\n const { transcript: _history, ...value } = snapshot;\n return value;\n };\n const state = replicatedState<SessionServiceState>({\n snapshot: { ...summary(transcript.snapshot()), fastMode: false },\n progress: null,\n updates: [],\n presentation: { revision: 0, dropped: 0, events: [], projections: [] },\n });\n void options.runtime\n .readState()\n .then((runtimeState) => {\n if (!disposed)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.snapshot.fastMode = runtimeState.fastMode === true;\n });\n })\n .catch((error) => {\n if (!disposed) present({ type: 'error', error: String(error) });\n });\n const present = (frame: Record<string, unknown>): boolean => {\n if (frame.type === 'fast_mode_changed' && typeof frame.enabled === 'boolean')\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.snapshot.fastMode = frame.enabled as boolean;\n });\n const entry = frame.entry as { seq?: number } | undefined;\n if (frame.type === 'entry_appended' && typeof entry?.seq === 'number')\n frame = {\n ...frame,\n transcriptCursor: transcriptCursor(options.sessionId, options.runtime.laneName, historyGeneration, entry.seq),\n };\n const next = presentation.record(frame);\n if (next)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.presentation = next;\n });\n return next !== undefined;\n };\n const settlers = new Set<{ resolve(): void; reject(error: Error): void }>();\n const promptFailures = new Set<(error: Error) => void>();\n let promptLatency: PromptLatency | undefined;\n let lastToolResultAt: number | undefined;\n let assistantMessageStartedAt: number | undefined;\n let disposed = false;\n const reportPromptLatency = (phase: string): void => {\n const active = promptLatency;\n if (active === undefined || active.reported.has(phase) || options.telemetry === undefined) return;\n const now = Date.now();\n active.reported.add(phase);\n observe(\n options.telemetry.recordEvent(PROMPT_LATENCY_EVENT, {\n session_id: options.sessionId,\n phase,\n duration_ms: now - active.startedAt,\n stage_duration_ms: now - active.lastStageAt,\n }),\n );\n active.lastStageAt = now;\n };\n const rejectSettlers = (error: Error): void => {\n for (const waiter of settlers) waiter.reject(error);\n settlers.clear();\n };\n\n const subscribePresentation =\n options.onPresentationFrame ??\n ((listener: (frame: DirectHarnessFrame) => void) => options.runtime.onPresentationFrame(listener));\n const unsubscribePresentation = subscribePresentation((frame) => {\n if (disposed) return;\n const message =\n typeof frame.message === 'object' && frame.message !== null ? (frame.message as { role?: unknown }) : undefined;\n if (frame.type === 'message_end' && message?.role === 'toolResult') lastToolResultAt = Date.now();\n if (frame.type === 'message_start' && message?.role === 'assistant') {\n const now = Date.now();\n assistantMessageStartedAt = now;\n if (lastToolResultAt !== undefined && options.telemetry) {\n observe(\n options.telemetry.recordEvent('doompi_server.tool_result_to_response', {\n session_id: options.sessionId,\n duration_ms: now - lastToolResultAt,\n }),\n );\n }\n lastToolResultAt = undefined;\n }\n if (frame.type === 'message_end' && message?.role === 'assistant') {\n if (assistantMessageStartedAt !== undefined && options.telemetry)\n observe(\n options.telemetry.recordEvent('doompi_server.assistant_message', {\n session_id: options.sessionId,\n duration_ms: Date.now() - assistantMessageStartedAt,\n }),\n );\n assistantMessageStartedAt = undefined;\n }\n if (frame.type === 'agent_start') reportPromptLatency('agent_started');\n else if (frame.type === 'message_start' && message?.role === 'assistant') reportPromptLatency('response_started');\n else if (frame.type === 'message_update' && message?.role === 'assistant') reportPromptLatency('first_response');\n else if (frame.type === 'message_end' && message?.role === 'assistant') reportPromptLatency('response_completed');\n const reductionStartedAt = performance.now();\n const reduction = transcript.apply(frame);\n if (frame.type === 'lifecycle_update' && frame.lifecycle !== undefined)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n const lifecycle = frame.lifecycle as SessionLifecycle;\n if ((draft.snapshot.lifecycle?.revision ?? -1) <= lifecycle.revision) draft.snapshot.lifecycle = lifecycle;\n });\n const updates = acpUpdates.apply(frame, reduction);\n const reductionDurationMs = performance.now() - reductionStartedAt;\n if (reduction.aggregate && options.telemetry) {\n observe(\n options.telemetry.recordEvent('doompi_server.transcript.aggregate', {\n session_id: options.sessionId,\n ...reduction.aggregate,\n }),\n );\n }\n if (reduction.snapshot || updates.length > 0) {\n state.change(BACKGROUND_CONTEXT, (draft) => {\n if (reduction.snapshot)\n draft.snapshot = {\n ...summary(reduction.snapshot),\n fastMode: draft.snapshot.fastMode ?? false,\n ...(draft.snapshot.lifecycle === undefined ? {} : { lifecycle: draft.snapshot.lifecycle }),\n };\n if (updates.length > 0) {\n const events = draft.updates ?? [];\n for (const update of updates) events.push({ sequence: ++updateSequence, update });\n if (events.length > 128) events.splice(0, events.length - 128);\n draft.updates = events;\n }\n });\n }\n if (reduction.progress) {\n const progress = reduction.progress;\n if (progress.type === 'item_finished') inFlight.delete(progress.item.id);\n else inFlight.set(progress.item.id, progress.item);\n }\n if (state.value.snapshot.phase === 'idle') inFlight.clear();\n if (frame.type === 'navigation_end') historyGeneration += 1;\n const changed = present(frame);\n const publishStartedAt = performance.now();\n void (reduction.snapshot || reduction.progress || updates.length > 0 || changed);\n const publishDurationMs = performance.now() - publishStartedAt;\n if (options.telemetry && (reductionDurationMs >= 50 || publishDurationMs >= 50 || frame.type === SETTLED))\n observe(\n options.telemetry.recordEvent('doompi_server.presentation_frame', {\n session_id: options.sessionId,\n 'frame.type': frame.type,\n phase: 'reduce_and_publish',\n duration_ms: reductionDurationMs + publishDurationMs,\n }),\n );\n if (frame.type === SETTLED) {\n lastToolResultAt = undefined;\n assistantMessageStartedAt = undefined;\n reportPromptLatency('settled');\n promptLatency = undefined;\n const waiting = [...settlers];\n settlers.clear();\n for (const settle of waiting) settle.resolve();\n }\n });\n\n const terminate = (error: Error): void => {\n if (disposed) return;\n disposed = true;\n for (const fail of promptFailures) fail(error);\n promptFailures.clear();\n rejectSettlers(error);\n unsubscribePresentation();\n };\n observe(\n options.runtime.exited.then(\n () => terminate(new Error('The session runtime exited')),\n (error: unknown) => terminate(error instanceof Error ? error : new Error(String(error))),\n ),\n );\n const requireLive = (): void => {\n if (disposed) throw new Error('The session runtime is disposed');\n };\n const guardContext = (context: Context): void => {\n requireLive();\n context.abortSignal?.throwIfAborted();\n };\n const awaitSettled = (): { promise: Promise<void>; resolve(): void; reject(error: Error): void } => {\n let fail!: (error: Error) => void;\n let finish!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const waiter = {\n resolve: () => {\n settlers.delete(waiter);\n resolve();\n },\n reject: (error: Error) => {\n settlers.delete(waiter);\n reject(error);\n },\n };\n fail = waiter.reject;\n finish = waiter.resolve;\n settlers.add(waiter);\n });\n observe(promise);\n return { promise, resolve: finish, reject: fail };\n };\n const messageArgs = (\n input: string | SessionMessageArgs,\n ): { message: string; images?: SessionMessageArgs['images'] } => {\n const args = typeof input === 'string' ? { text: input } : input;\n if (!args || typeof args.text !== 'string') throw new Error('Prompt message must be a string');\n if (\n args.images !== undefined &&\n (!Array.isArray(args.images) ||\n !args.images.every(\n (image) => image?.type === 'image' && typeof image.data === 'string' && typeof image.mimeType === 'string',\n ))\n )\n throw new Error('Invalid message images');\n return { message: args.text, ...(args.images === undefined ? {} : { images: args.images }) };\n };\n const hydrate = async (): Promise<void> => {\n const lifecycle = await options.runtime.readLifecycle();\n if (disposed) return;\n state.change(BACKGROUND_CONTEXT, (draft) => {\n if ((draft.snapshot.lifecycle?.revision ?? -1) <= lifecycle.revision) draft.snapshot.lifecycle = lifecycle;\n draft.presentation = presentation.resetCustomEntries();\n });\n };\n let initializing: Promise<void> | undefined;\n\n return {\n state,\n async readTranscriptPage(args, context) {\n guardContext(context);\n if (args.threadId !== undefined) {\n if (!options.readThreadTranscript) throw new Error('Child transcript reader is unavailable');\n return options.readThreadTranscript(args.threadId, args, context);\n }\n const generation = historyGeneration;\n const revision = state.value.presentation?.revision ?? 0;\n const drafts = [...inFlight.values()];\n const started = performance.now();\n let snapshot: ReturnType<DirectHarnessRuntime['readEntries']> | undefined;\n const readEntries = () => (snapshot ??= options.runtime.readEntries());\n const page = await readTranscriptPage(\n {\n sessionId: options.runtime.sessionId,\n laneName: options.runtime.laneName,\n lane: {\n getTipId: async () => (await readEntries()).leafId,\n findEntries: async (query) => {\n let entries = (await readEntries()).entries;\n if (query.type) entries = entries.filter((e) => e.type === query.type);\n if (query.customType)\n entries = entries.filter((e) => e.type === 'custom' && e.customType === query.customType);\n if (query.cursor)\n entries = entries.filter((e) =>\n query.order === 'oldestFirst' ? e.seq > query.cursor!.seq : e.seq < query.cursor!.seq,\n );\n if (query.order === 'newestFirst') entries = entries.toReversed();\n return query.limit === undefined ? entries : entries.slice(0, query.limit);\n },\n },\n },\n args,\n generation,\n context,\n );\n if (options.telemetry)\n observe(\n options.telemetry.recordEvent('doompi_server.transcript_page', {\n session_id: options.sessionId,\n phase: args.direction ?? 'latest',\n duration_ms: performance.now() - started,\n count: page.entries.length,\n }),\n );\n if (generation !== historyGeneration) throw new Error('STALE_TRANSCRIPT_CURSOR');\n return { ...page, revision, drafts };\n },\n initialize() {\n initializing ??= hydrate().catch((error: unknown) => {\n initializing = undefined;\n throw error;\n });\n return initializing;\n },\n async prompt(text: string | PromptArgs, context) {\n guardContext(context);\n const args = messageArgs(text);\n const waitFor = typeof text === 'string' ? 'settled' : (text.waitFor ?? 'settled');\n if (waitFor !== 'accepted' && waitFor !== 'settled') throw new Error('Invalid prompt acknowledgement mode');\n let projection: ReturnType<typeof awaitSettled> | undefined;\n let latency: PromptLatency | undefined;\n let submitted = false;\n let failed: Error | undefined;\n let rejectFailure!: (error: Error) => void;\n const failure = new Promise<void>((_resolve, reject) => {\n rejectFailure = reject;\n });\n const fail = (error: Error): void => {\n if (failed !== undefined) return;\n failed = error;\n projection?.reject(error);\n rejectFailure(error);\n if (latency !== undefined && promptLatency === latency) {\n reportPromptLatency('failed');\n promptLatency = undefined;\n }\n };\n const cancel = (): void => {\n if (failed !== undefined) return;\n fail(new Error('The session prompt was cancelled', { cause: context.abortSignal?.reason }));\n if (submitted && waitFor === 'settled') void options.runtime.abort().catch(() => undefined);\n };\n const guardPrompt = (): void => {\n if (failed !== undefined) throw failed;\n guardContext(context);\n };\n const submit = async () => {\n guardPrompt();\n submitted = true;\n const submission = await options.runtime.submitPrompt(args.message, args.images);\n observe(submission.settled);\n guardPrompt();\n return submission;\n };\n const span = <T>(name: string, callback: () => Promise<T>): Promise<T> => {\n const operation = options.telemetry\n ? options.telemetry.runInSpan(name, { session_id: options.sessionId }, callback)\n : callback();\n observe(operation);\n return operation;\n };\n const run = async (): Promise<void> => {\n guardPrompt();\n const lifecycle = await options.runtime.readLifecycle();\n guardPrompt();\n if (lifecycle.operation !== null || settlers.size > 0) {\n if (isSelectionCommand(args.message)) {\n const handled = await options.runtime.dispatchCommand(args.message);\n guardPrompt();\n if (handled) return;\n }\n throw new Error('A turn is already running');\n }\n if (waitFor === 'accepted' && !options.telemetry) {\n await submit();\n return;\n }\n const startedAt = Date.now();\n latency = promptLatency = { startedAt, lastStageAt: startedAt, reported: new Set() };\n const settled = (projection = awaitSettled());\n let resolveAdmission: (() => void) | undefined;\n const admitted =\n waitFor === 'accepted'\n ? new Promise<void>((resolve) => {\n resolveAdmission = resolve;\n })\n : undefined;\n const completion = span('doompi_server.prompt_to_settled', async () => {\n const submission = await span('doompi_server.prompt_admission', submit);\n guardPrompt();\n if (submission.handledCommand) settled.resolve();\n reportPromptLatency('accepted');\n resolveAdmission?.();\n await Promise.all([\n span('doompi_server.prompt_engine_settlement', () => submission.settled),\n span('doompi_server.prompt_projection_settlement', () => settled.promise),\n ]);\n }).catch((error: unknown) => {\n const cause = error instanceof Error ? error : new Error(String(error));\n fail(cause);\n throw cause;\n });\n if (admitted) await Promise.race([admitted, completion]);\n else await completion;\n };\n promptFailures.add(fail);\n context.abortSignal?.addEventListener('abort', cancel, { once: true });\n try {\n await Promise.race([run(), failure]);\n } catch (error) {\n const cause = error instanceof Error ? error : new Error(String(error));\n fail(cause);\n throw cause;\n } finally {\n promptFailures.delete(fail);\n context.abortSignal?.removeEventListener('abort', cancel);\n }\n },\n async steer(text: string | SessionMessageArgs) {\n requireLive();\n const args = messageArgs(text);\n const submission = await options.runtime.submitUserPrompt(args.message, args.images);\n void submission.settled.catch((error: unknown) => present({ type: 'error', error: String(error) }));\n },\n async abort() {\n requireLive();\n await options.runtime.abort((await options.runtime.readLifecycle()).operation?.id);\n },\n async abortOperation(args) {\n requireLive();\n if (!args || typeof args.operationId !== 'string' || !args.operationId)\n throw new Error('Invalid operation identity');\n await options.runtime.abort(args.operationId);\n },\n async setModel(model, context) {\n guardContext(context);\n if (!model || typeof model.provider !== 'string' || typeof model.id !== 'string')\n throw new Error('Invalid model');\n await options.runtime.setModel(model);\n },\n async setFastMode(enabled, context) {\n guardContext(context);\n if (typeof enabled !== 'boolean') throw new Error('Invalid fast mode');\n await options.runtime.setFastMode(enabled);\n state.change(context, (draft) => {\n draft.snapshot.fastMode = enabled;\n });\n },\n async setThinking(thinkingLevel, context) {\n guardContext(context);\n if (!['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'].includes(thinkingLevel))\n throw new Error('Invalid thinking level');\n await options.runtime.setThinkingLevel(thinkingLevel);\n },\n async followUp(args, context) {\n guardContext(context);\n const message = messageArgs(args);\n await options.runtime.followUp(message.message, message.images);\n },\n async enqueueAutomatic(args, context) {\n guardContext(context);\n const message = messageArgs(args);\n return options.runtime.enqueueAutomatic(message.message, message.images);\n },\n async removeQueued(args, context) {\n guardContext(context);\n if (!args || typeof args.id !== 'string' || !args.id) throw new Error('Invalid queue identity');\n return options.runtime.removeQueued(args.id);\n },\n async promoteQueued(args, context) {\n guardContext(context);\n if (\n !args ||\n typeof args.id !== 'string' ||\n !args.id ||\n (args.operationId !== undefined && (typeof args.operationId !== 'string' || !args.operationId))\n )\n throw new Error('Invalid queue promotion');\n return options.runtime.promoteQueued(args.id, args.operationId);\n },\n async resumeQueue(context) {\n guardContext(context);\n await options.runtime.resumeQueue();\n },\n async clearQueue(context) {\n guardContext(context);\n return options.runtime.clearQueue();\n },\n async rewind(args, context) {\n guardContext(context);\n if (!args || typeof args.itemId !== 'string' || !args.itemId) throw new Error('Invalid rewind identity');\n const { entries } = await options.runtime.readEntries();\n const entry = entries.toReversed().find((candidate) => {\n if (candidate.type !== 'message' || typeof candidate.id !== 'string') return false;\n const message = candidate.message;\n if (!message || typeof message !== 'object' || Array.isArray(message)) return false;\n const record = message as unknown as Record<string, unknown>;\n return (\n candidate.id === args.itemId ||\n record.id === args.itemId ||\n (record.role === 'user' && typeof record.timestamp === 'number' && args.itemId === `user-${record.timestamp}`)\n );\n });\n if (!entry) throw new Error('The selected message is not in the active session tree.');\n const result = await options.runtime.navigateTree(entry.id, {\n ...(args.summarize === undefined ? {} : { summarize: args.summarize }),\n ...(args.customInstructions === undefined ? {} : { customInstructions: args.customInstructions }),\n ...(args.replaceInstructions === undefined ? {} : { replaceInstructions: args.replaceInstructions }),\n ...(args.label === undefined ? {} : { label: args.label }),\n });\n if (!result.cancelled) await hydrate();\n return result as RewindResult;\n },\n async extensionUiResponse(response, context) {\n guardContext(context);\n if (\n !response ||\n typeof response.id !== 'string' ||\n !response.id ||\n !(\n ('value' in response && typeof response.value === 'string') ||\n ('confirmed' in response && typeof response.confirmed === 'boolean') ||\n ('cancelled' in response && response.cancelled === true)\n )\n )\n throw new Error('Invalid extension UI response');\n if (!options.respondToExtensionUi?.({ ...response, type: 'extension_ui_response' }))\n throw new Error(`No pending extension UI request: ${response.id}`);\n present({ type: 'extension_ui_answered', id: response.id });\n state.change(context, () => undefined);\n },\n async getState(context) {\n guardContext(context);\n const runtimeState = await options.runtime.readState();\n return { ...runtimeState, fastMode: runtimeState.fastMode === true } as unknown as SessionStateInfo;\n },\n async getSessionStats(context) {\n guardContext(context);\n return sessionStats(options.runtime, options.sessionId);\n },\n async getCommands(context) {\n guardContext(context);\n return options.runtime.listCommands() as SessionCommand[];\n },\n async getAvailableModels(context) {\n guardContext(context);\n return (await options.runtime.availableModels()).map((model) => ({\n provider: model.provider,\n id: model.id,\n })) as ModelRef[];\n },\n async getAvailableThinkingLevels(context) {\n guardContext(context);\n return (await options.runtime.availableThinkingLevels()) as ThinkingLevel[];\n },\n async compact(args, context) {\n guardContext(context);\n await options.runtime.compact(args.customInstructions);\n return null;\n },\n async setName(name, context) {\n guardContext(context);\n if (typeof name !== 'string' || name.length > 256) throw new Error('Invalid session name');\n await options.runtime.setName(name);\n },\n async dispose() {\n terminate(new Error('The session runtime is disposed'));\n },\n };\n}\n\nexport interface AgentServerServiceOptions extends AgentSessionRuntimeOptions {\n createdAt: number;\n}\n\nexport interface DoomSessionMetadata {\n id: string;\n createdAt: number;\n storageVersion: number;\n cwd: string;\n sessionName: string;\n}\n\nfunction endpointAttachment(endpoint: RemoteServiceEndpoint): {\n invokeService: RemoteServiceEndpoint['invoke'];\n release(): void;\n} {\n return {\n invokeService: (call, publish, context) => endpoint.invoke(call, publish, context),\n release: () => endpoint.dispose(),\n };\n}\n\nfunction managementHost(): RoutedServerServiceHost {\n return {\n attachClient(presentation) {\n const provider = new RemoteServiceProvider([{ service: DoomSessionManagementService, mode: 'singleton' }]);\n provider.provide(DoomSessionManagementService, {\n attach: (sessionId, context) => presentation.attachSession(sessionId, context),\n detach: (context) => presentation.detachSession(context),\n });\n return endpointAttachment(createRemoteServiceEndpoint(provider));\n },\n };\n}\n\n/** Creates the 0.85 routed host for one supervised DoomPi session. */\nexport function createAgentServerService(options: AgentServerServiceOptions): ServerHost<DoomSessionMetadata> {\n const metadata: DoomSessionMetadata = {\n id: options.sessionId,\n createdAt: options.createdAt,\n storageVersion: 1,\n cwd: options.cwd,\n sessionName: options.sessionName,\n };\n const runtime = createAgentSessionRuntime(options);\n let closed = false;\n\n return {\n serverServices: managementHost(),\n async resolveSession(sessionId) {\n if (sessionId !== metadata.id) throw new SessionNotFoundError(`No session ${sessionId}`);\n return metadata;\n },\n async openSession() {\n if (closed) throw new SessionNotFoundError('The session service is closed');\n await runtime.initialize();\n const provider = new RemoteServiceProvider([{ service: DoomSessionService, mode: 'singleton' }]);\n provider.provide(DoomSessionService, runtime);\n const handle: RoutedSessionHandle = {\n attachClient: () => endpointAttachment(createRemoteServiceEndpoint(provider)),\n async close() {\n if (closed) return;\n closed = true;\n provider.dispose();\n await runtime.dispose();\n },\n };\n return handle;\n },\n };\n}\n\nexport type { SessionSnapshot };\n"],"mappings":"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"}
|
|
1
|
+
{"version":3,"file":"piSessionRuntime.mjs","names":[],"sources":["../../../src/pi/piSessionRuntime.ts"],"sourcesContent":["import {\n createRemoteServiceEndpoint,\n RemoteServiceProvider,\n replicatedState,\n type Context,\n type MutableReplicatedState,\n type RemoteServiceEndpoint,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { RoutedServerServiceHost, RoutedSessionHandle, ServerHost } from '@earendil-works/pi-server';\nimport { SessionNotFoundError } from '@earendil-works/pi-server';\n\nimport {\n DoomSessionManagementService,\n DoomSessionService,\n type SessionService,\n type SessionMessageArgs,\n type PromptArgs,\n type SessionServiceState,\n type SessionSnapshot,\n type SessionLifecycle,\n type TranscriptItem,\n type TranscriptPage,\n type TranscriptPageRequest,\n type RewindResult,\n type SessionStateInfo,\n type SessionStats,\n type SessionCommand,\n type ModelRef,\n type ThinkingLevel,\n} from '../exports/sessionProtocol';\nimport { createAcpSessionUpdateProjection } from '../services/acpSessionUpdates';\nimport { createRpcTranscript, type RpcTranscript } from '../services/rpcTranscript';\nimport { observe, type ServerTelemetry } from '../services/serverTelemetry';\nimport { createSessionPresentation } from '../services/sessionPresentation';\nimport { readTranscriptPage, transcriptCursor } from '../services/transcriptPages';\nimport type { DirectHarnessRuntime, DirectHarnessFrame } from '../types/server/directHarnessRuntime';\n\nconst SETTLED = 'agent_settled';\nconst PROMPT_LATENCY_EVENT = 'doompi_server.prompt_latency';\nconst SELECTION_COMMANDS = new Set(['mode', 'domains', 'profile', 'minor']);\n\nfunction isSelectionCommand(text: string): boolean {\n const match = /^\\/(\\S+)/.exec(text);\n return match !== null && SELECTION_COMMANDS.has(match[1]!);\n}\n\ntype PromptLatency = {\n readonly startedAt: number;\n lastStageAt: number;\n readonly reported: Set<string>;\n};\n\nasync function sessionStats(runtime: DirectHarnessRuntime, sessionId: string): Promise<SessionStats> {\n const stored = await runtime.getSessionStats();\n const { contextUsage, sessionFile } = stored;\n return {\n sessionId,\n ...(sessionFile === undefined ? {} : { sessionFile }),\n totalMessages: stored.messageCount,\n tokens: {\n input: stored.usage.input,\n output: stored.usage.output,\n cacheRead: stored.usage.cacheRead,\n cacheWrite: stored.usage.cacheWrite,\n total: stored.usage.totalTokens,\n },\n cost: stored.usage.cost.total,\n ...(contextUsage === undefined ? {} : { contextUsage }),\n };\n}\n\nexport interface AgentSessionRuntimeOptions {\n runtime: DirectHarnessRuntime;\n sessionId: string;\n sessionName: string;\n cwd: string;\n telemetry?: ServerTelemetry;\n /** Subscribes to the combined harness and headless presentation projection. */\n onPresentationFrame?: (listener: (frame: DirectHarnessFrame) => void) => () => void;\n /** Delivers one answered extension UI request to the session-scoped headless host. */\n respondToExtensionUi?: (frame: DirectHarnessFrame) => boolean;\n /** Test seam for the projection. */\n transcript?: RpcTranscript;\n readThreadTranscript?: (\n threadId: string,\n request: TranscriptPageRequest,\n context: Context,\n ) => Promise<TranscriptPage>;\n}\n\nexport interface AgentSessionRuntime extends SessionService {\n readonly state: MutableReplicatedState<SessionServiceState>;\n initialize(): Promise<void>;\n dispose(): Promise<void>;\n}\n\n/** Projects one in-process harness runtime as a Chord session service. */\nexport function createAgentSessionRuntime(options: AgentSessionRuntimeOptions): AgentSessionRuntime {\n const transcript =\n options.transcript ??\n createRpcTranscript({\n id: options.sessionId,\n cwd: options.cwd,\n name: options.sessionName,\n now: Date.now,\n retainEntries: 0,\n });\n const presentation = createSessionPresentation();\n const acpUpdates = createAcpSessionUpdateProjection();\n let updateSequence = 0;\n const inFlight = new Map<string, TranscriptItem>();\n let historyGeneration = 0;\n const summary = (snapshot: SessionSnapshot): Omit<SessionSnapshot, 'transcript'> => {\n const { transcript: _history, ...value } = snapshot;\n return value;\n };\n const state = replicatedState<SessionServiceState>({\n snapshot: { ...summary(transcript.snapshot()), fastMode: false },\n progress: null,\n updates: [],\n presentation: { revision: 0, dropped: 0, events: [], projections: [] },\n });\n void options.runtime\n .readState()\n .then((runtimeState) => {\n if (!disposed)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.snapshot.fastMode = runtimeState.fastMode === true;\n });\n })\n .catch((error) => {\n if (!disposed) present({ type: 'error', error: String(error) });\n });\n const present = (frame: Record<string, unknown>): boolean => {\n if (frame.type === 'fast_mode_changed' && typeof frame.enabled === 'boolean')\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.snapshot.fastMode = frame.enabled as boolean;\n });\n const entry = frame.entry as { seq?: number } | undefined;\n if (frame.type === 'entry_appended' && typeof entry?.seq === 'number')\n frame = {\n ...frame,\n transcriptCursor: transcriptCursor(options.sessionId, options.runtime.laneName, historyGeneration, entry.seq),\n };\n const next = presentation.record(frame);\n if (next)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n draft.presentation = next;\n });\n return next !== undefined;\n };\n const settlers = new Set<{ resolve(): void; reject(error: Error): void }>();\n const promptFailures = new Set<(error: Error) => void>();\n let promptLatency: PromptLatency | undefined;\n let lastToolResultAt: number | undefined;\n let assistantMessageStartedAt: number | undefined;\n let disposed = false;\n const reportPromptLatency = (phase: string): void => {\n const active = promptLatency;\n if (active === undefined || active.reported.has(phase) || options.telemetry === undefined) return;\n const now = Date.now();\n active.reported.add(phase);\n observe(\n options.telemetry.recordEvent(PROMPT_LATENCY_EVENT, {\n session_id: options.sessionId,\n phase,\n duration_ms: now - active.startedAt,\n stage_duration_ms: now - active.lastStageAt,\n }),\n );\n active.lastStageAt = now;\n };\n const rejectSettlers = (error: Error): void => {\n for (const waiter of settlers) waiter.reject(error);\n settlers.clear();\n };\n\n const subscribePresentation =\n options.onPresentationFrame ??\n ((listener: (frame: DirectHarnessFrame) => void) => options.runtime.onPresentationFrame(listener));\n const unsubscribePresentation = subscribePresentation((frame) => {\n if (disposed) return;\n const message =\n typeof frame.message === 'object' && frame.message !== null ? (frame.message as { role?: unknown }) : undefined;\n if (frame.type === 'message_end' && message?.role === 'toolResult') lastToolResultAt = Date.now();\n if (frame.type === 'message_start' && message?.role === 'assistant') {\n const now = Date.now();\n assistantMessageStartedAt = now;\n if (lastToolResultAt !== undefined && options.telemetry) {\n observe(\n options.telemetry.recordEvent('doompi_server.tool_result_to_response', {\n session_id: options.sessionId,\n duration_ms: now - lastToolResultAt,\n }),\n );\n }\n lastToolResultAt = undefined;\n }\n if (frame.type === 'message_end' && message?.role === 'assistant') {\n if (assistantMessageStartedAt !== undefined && options.telemetry)\n observe(\n options.telemetry.recordEvent('doompi_server.assistant_message', {\n session_id: options.sessionId,\n duration_ms: Date.now() - assistantMessageStartedAt,\n }),\n );\n assistantMessageStartedAt = undefined;\n }\n if (frame.type === 'agent_start') reportPromptLatency('agent_started');\n else if (frame.type === 'message_start' && message?.role === 'assistant') reportPromptLatency('response_started');\n else if (frame.type === 'message_update' && message?.role === 'assistant') reportPromptLatency('first_response');\n else if (frame.type === 'message_end' && message?.role === 'assistant') reportPromptLatency('response_completed');\n const reductionStartedAt = performance.now();\n const reduction = transcript.apply(frame);\n if (frame.type === 'lifecycle_update' && frame.lifecycle !== undefined)\n state.change(BACKGROUND_CONTEXT, (draft) => {\n const lifecycle = frame.lifecycle as SessionLifecycle;\n if ((draft.snapshot.lifecycle?.revision ?? -1) <= lifecycle.revision) draft.snapshot.lifecycle = lifecycle;\n });\n const updates = acpUpdates.apply(frame, reduction);\n const reductionDurationMs = performance.now() - reductionStartedAt;\n if (reduction.aggregate && options.telemetry) {\n observe(\n options.telemetry.recordEvent('doompi_server.transcript.aggregate', {\n session_id: options.sessionId,\n ...reduction.aggregate,\n }),\n );\n }\n if (reduction.snapshot || updates.length > 0) {\n state.change(BACKGROUND_CONTEXT, (draft) => {\n if (reduction.snapshot)\n draft.snapshot = {\n ...summary(reduction.snapshot),\n fastMode: draft.snapshot.fastMode ?? false,\n ...(draft.snapshot.lifecycle === undefined ? {} : { lifecycle: draft.snapshot.lifecycle }),\n };\n if (updates.length > 0) {\n const events = draft.updates ?? [];\n for (const update of updates) events.push({ sequence: ++updateSequence, update });\n if (events.length > 128) events.splice(0, events.length - 128);\n draft.updates = events;\n }\n });\n }\n if (reduction.progress) {\n const progress = reduction.progress;\n if (progress.type === 'item_finished') inFlight.delete(progress.item.id);\n else inFlight.set(progress.item.id, progress.item);\n }\n if (state.value.snapshot.phase === 'idle') inFlight.clear();\n if (frame.type === 'navigation_end') historyGeneration += 1;\n const changed = present(frame);\n const publishStartedAt = performance.now();\n void (reduction.snapshot || reduction.progress || updates.length > 0 || changed);\n const publishDurationMs = performance.now() - publishStartedAt;\n if (options.telemetry && (reductionDurationMs >= 50 || publishDurationMs >= 50 || frame.type === SETTLED))\n observe(\n options.telemetry.recordEvent('doompi_server.presentation_frame', {\n session_id: options.sessionId,\n 'frame.type': frame.type,\n phase: 'reduce_and_publish',\n duration_ms: reductionDurationMs + publishDurationMs,\n }),\n );\n if (frame.type === SETTLED) {\n lastToolResultAt = undefined;\n assistantMessageStartedAt = undefined;\n reportPromptLatency('settled');\n promptLatency = undefined;\n const waiting = [...settlers];\n settlers.clear();\n for (const settle of waiting) settle.resolve();\n }\n });\n\n const terminate = (error: Error): void => {\n if (disposed) return;\n disposed = true;\n for (const fail of promptFailures) fail(error);\n promptFailures.clear();\n rejectSettlers(error);\n unsubscribePresentation();\n };\n observe(\n options.runtime.exited.then(\n () => terminate(new Error('The session runtime exited')),\n (error: unknown) => terminate(error instanceof Error ? error : new Error(String(error))),\n ),\n );\n const requireLive = (): void => {\n if (disposed) throw new Error('The session runtime is disposed');\n };\n const guardContext = (context: Context): void => {\n requireLive();\n context.abortSignal?.throwIfAborted();\n };\n const awaitSettled = (): { promise: Promise<void>; resolve(): void; reject(error: Error): void } => {\n let fail!: (error: Error) => void;\n let finish!: () => void;\n const promise = new Promise<void>((resolve, reject) => {\n const waiter = {\n resolve: () => {\n settlers.delete(waiter);\n resolve();\n },\n reject: (error: Error) => {\n settlers.delete(waiter);\n reject(error);\n },\n };\n fail = waiter.reject;\n finish = waiter.resolve;\n settlers.add(waiter);\n });\n observe(promise);\n return { promise, resolve: finish, reject: fail };\n };\n const messageArgs = (\n input: string | SessionMessageArgs,\n ): { message: string; images?: SessionMessageArgs['images'] } => {\n const args = typeof input === 'string' ? { text: input } : input;\n if (!args || typeof args.text !== 'string') throw new Error('Prompt message must be a string');\n if (\n args.images !== undefined &&\n (!Array.isArray(args.images) ||\n !args.images.every(\n (image) => image?.type === 'image' && typeof image.data === 'string' && typeof image.mimeType === 'string',\n ))\n )\n throw new Error('Invalid message images');\n return { message: args.text, ...(args.images === undefined ? {} : { images: args.images }) };\n };\n const hydrate = async (): Promise<void> => {\n const lifecycle = await options.runtime.readLifecycle();\n if (disposed) return;\n state.change(BACKGROUND_CONTEXT, (draft) => {\n if ((draft.snapshot.lifecycle?.revision ?? -1) <= lifecycle.revision) draft.snapshot.lifecycle = lifecycle;\n draft.presentation = presentation.resetCustomEntries();\n });\n };\n let initializing: Promise<void> | undefined;\n\n return {\n state,\n async readTranscriptPage(args, context) {\n guardContext(context);\n if (args.threadId !== undefined) {\n if (!options.readThreadTranscript) throw new Error('Child transcript reader is unavailable');\n return options.readThreadTranscript(args.threadId, args, context);\n }\n const generation = historyGeneration;\n const revision = state.value.presentation?.revision ?? 0;\n const drafts = [...inFlight.values()];\n const started = performance.now();\n let snapshot: ReturnType<DirectHarnessRuntime['readEntries']> | undefined;\n const readEntries = () => (snapshot ??= options.runtime.readEntries());\n const page = await readTranscriptPage(\n {\n sessionId: options.runtime.sessionId,\n laneName: options.runtime.laneName,\n lane: {\n getTipId: async () => (await readEntries()).leafId,\n findEntries: async (query) => {\n let entries = (await readEntries()).entries;\n if (query.type) entries = entries.filter((e) => e.type === query.type);\n if (query.customType)\n entries = entries.filter((e) => e.type === 'custom' && e.customType === query.customType);\n if (query.cursor)\n entries = entries.filter((e) =>\n query.order === 'oldestFirst' ? e.seq > query.cursor!.seq : e.seq < query.cursor!.seq,\n );\n if (query.order === 'newestFirst') entries = entries.toReversed();\n return query.limit === undefined ? entries : entries.slice(0, query.limit);\n },\n },\n },\n args,\n generation,\n context,\n );\n if (options.telemetry)\n observe(\n options.telemetry.recordEvent('doompi_server.transcript_page', {\n session_id: options.sessionId,\n phase: args.direction ?? 'latest',\n duration_ms: performance.now() - started,\n count: page.entries.length,\n }),\n );\n if (generation !== historyGeneration) throw new Error('STALE_TRANSCRIPT_CURSOR');\n return { ...page, revision, drafts };\n },\n initialize() {\n initializing ??= hydrate().catch((error: unknown) => {\n initializing = undefined;\n throw error;\n });\n return initializing;\n },\n async prompt(text: string | PromptArgs, context) {\n guardContext(context);\n const args = messageArgs(text);\n const waitFor = typeof text === 'string' ? 'settled' : (text.waitFor ?? 'settled');\n if (waitFor !== 'accepted' && waitFor !== 'settled') throw new Error('Invalid prompt acknowledgement mode');\n let projection: ReturnType<typeof awaitSettled> | undefined;\n let latency: PromptLatency | undefined;\n let submitted = false;\n let failed: Error | undefined;\n let rejectFailure!: (error: Error) => void;\n const failure = new Promise<void>((_resolve, reject) => {\n rejectFailure = reject;\n });\n const fail = (error: Error): void => {\n if (failed !== undefined) return;\n failed = error;\n projection?.reject(error);\n rejectFailure(error);\n if (latency !== undefined && promptLatency === latency) {\n reportPromptLatency('failed');\n promptLatency = undefined;\n }\n };\n const cancel = (): void => {\n if (failed !== undefined) return;\n fail(new Error('The session prompt was cancelled', { cause: context.abortSignal?.reason }));\n if (submitted && waitFor === 'settled') void options.runtime.abort().catch(() => undefined);\n };\n const guardPrompt = (): void => {\n if (failed !== undefined) throw failed;\n guardContext(context);\n };\n const submit = async () => {\n guardPrompt();\n submitted = true;\n const submission = await options.runtime.submitPrompt(args.message, args.images);\n observe(submission.settled);\n guardPrompt();\n return submission;\n };\n const span = <T>(name: string, callback: () => Promise<T>): Promise<T> => {\n const operation = options.telemetry\n ? options.telemetry.runInSpan(name, { session_id: options.sessionId }, callback)\n : callback();\n observe(operation);\n return operation;\n };\n const run = async (): Promise<void> => {\n guardPrompt();\n const lifecycle = await options.runtime.readLifecycle();\n guardPrompt();\n if (lifecycle.operation !== null || settlers.size > 0) {\n if (isSelectionCommand(args.message)) {\n const handled = await options.runtime.dispatchCommand(args.message);\n guardPrompt();\n if (handled) return;\n }\n throw new Error('A turn is already running');\n }\n if (waitFor === 'accepted' && !options.telemetry) {\n await submit();\n return;\n }\n const startedAt = Date.now();\n latency = promptLatency = { startedAt, lastStageAt: startedAt, reported: new Set() };\n const settled = (projection = awaitSettled());\n let resolveAdmission: (() => void) | undefined;\n const admitted =\n waitFor === 'accepted'\n ? new Promise<void>((resolve) => {\n resolveAdmission = resolve;\n })\n : undefined;\n const completion = span('doompi_server.prompt_to_settled', async () => {\n const submission = await span('doompi_server.prompt_admission', submit);\n guardPrompt();\n if (submission.handledCommand) settled.resolve();\n reportPromptLatency('accepted');\n resolveAdmission?.();\n await Promise.all([\n span('doompi_server.prompt_engine_settlement', () => submission.settled),\n span('doompi_server.prompt_projection_settlement', () => settled.promise),\n ]);\n }).catch((error: unknown) => {\n const cause = error instanceof Error ? error : new Error(String(error));\n fail(cause);\n throw cause;\n });\n if (admitted) await Promise.race([admitted, completion]);\n else await completion;\n };\n promptFailures.add(fail);\n context.abortSignal?.addEventListener('abort', cancel, { once: true });\n try {\n await Promise.race([run(), failure]);\n } catch (error) {\n const cause = error instanceof Error ? error : new Error(String(error));\n fail(cause);\n throw cause;\n } finally {\n promptFailures.delete(fail);\n context.abortSignal?.removeEventListener('abort', cancel);\n }\n },\n async steer(text: string | SessionMessageArgs) {\n requireLive();\n const args = messageArgs(text);\n await options.runtime.steer(args.message, args.images);\n },\n async abort() {\n requireLive();\n await options.runtime.abort((await options.runtime.readLifecycle()).operation?.id);\n },\n async abortOperation(args) {\n requireLive();\n if (!args || typeof args.operationId !== 'string' || !args.operationId)\n throw new Error('Invalid operation identity');\n await options.runtime.abort(args.operationId);\n },\n async setModel(model, context) {\n guardContext(context);\n if (!model || typeof model.provider !== 'string' || typeof model.id !== 'string')\n throw new Error('Invalid model');\n await options.runtime.setModel(model);\n },\n async setFastMode(enabled, context) {\n guardContext(context);\n if (typeof enabled !== 'boolean') throw new Error('Invalid fast mode');\n await options.runtime.setFastMode(enabled);\n state.change(context, (draft) => {\n draft.snapshot.fastMode = enabled;\n });\n },\n async setThinking(thinkingLevel, context) {\n guardContext(context);\n if (!['off', 'minimal', 'low', 'medium', 'high', 'xhigh', 'max'].includes(thinkingLevel))\n throw new Error('Invalid thinking level');\n await options.runtime.setThinkingLevel(thinkingLevel);\n },\n async followUp(args, context) {\n guardContext(context);\n const message = messageArgs(args);\n await options.runtime.followUp(message.message, message.images);\n },\n async enqueueAutomatic(args, context) {\n guardContext(context);\n const message = messageArgs(args);\n return options.runtime.enqueueAutomatic(message.message, message.images);\n },\n async removeQueued(args, context) {\n guardContext(context);\n if (!args || typeof args.id !== 'string' || !args.id) throw new Error('Invalid queue identity');\n return options.runtime.removeQueued(args.id);\n },\n async promoteQueued(args, context) {\n guardContext(context);\n if (\n !args ||\n typeof args.id !== 'string' ||\n !args.id ||\n (args.operationId !== undefined && (typeof args.operationId !== 'string' || !args.operationId))\n )\n throw new Error('Invalid queue promotion');\n return options.runtime.promoteQueued(args.id, args.operationId);\n },\n async resumeQueue(context) {\n guardContext(context);\n await options.runtime.resumeQueue();\n },\n async clearQueue(context) {\n guardContext(context);\n return options.runtime.clearQueue();\n },\n async rewind(args, context) {\n guardContext(context);\n if (!args || typeof args.itemId !== 'string' || !args.itemId) throw new Error('Invalid rewind identity');\n const { entries } = await options.runtime.readEntries();\n const entry = entries.toReversed().find((candidate) => {\n if (candidate.type !== 'message' || typeof candidate.id !== 'string') return false;\n const message = candidate.message;\n if (!message || typeof message !== 'object' || Array.isArray(message)) return false;\n const record = message as unknown as Record<string, unknown>;\n return (\n candidate.id === args.itemId ||\n record.id === args.itemId ||\n (record.role === 'user' && typeof record.timestamp === 'number' && args.itemId === `user-${record.timestamp}`)\n );\n });\n if (!entry) throw new Error('The selected message is not in the active session tree.');\n const result = await options.runtime.navigateTree(entry.id, {\n ...(args.summarize === undefined ? {} : { summarize: args.summarize }),\n ...(args.customInstructions === undefined ? {} : { customInstructions: args.customInstructions }),\n ...(args.replaceInstructions === undefined ? {} : { replaceInstructions: args.replaceInstructions }),\n ...(args.label === undefined ? {} : { label: args.label }),\n });\n if (!result.cancelled) await hydrate();\n return result as RewindResult;\n },\n async extensionUiResponse(response, context) {\n guardContext(context);\n if (\n !response ||\n typeof response.id !== 'string' ||\n !response.id ||\n !(\n ('value' in response && typeof response.value === 'string') ||\n ('confirmed' in response && typeof response.confirmed === 'boolean') ||\n ('cancelled' in response && response.cancelled === true)\n )\n )\n throw new Error('Invalid extension UI response');\n if (!options.respondToExtensionUi?.({ ...response, type: 'extension_ui_response' }))\n throw new Error(`No pending extension UI request: ${response.id}`);\n present({ type: 'extension_ui_answered', id: response.id });\n state.change(context, () => undefined);\n },\n async getState(context) {\n guardContext(context);\n const runtimeState = await options.runtime.readState();\n return { ...runtimeState, fastMode: runtimeState.fastMode === true } as unknown as SessionStateInfo;\n },\n async getSessionStats(context) {\n guardContext(context);\n return sessionStats(options.runtime, options.sessionId);\n },\n async getCommands(context) {\n guardContext(context);\n return options.runtime.listCommands() as SessionCommand[];\n },\n async getAvailableModels(context) {\n guardContext(context);\n return (await options.runtime.availableModels()).map((model) => ({\n provider: model.provider,\n id: model.id,\n })) as ModelRef[];\n },\n async getAvailableThinkingLevels(context) {\n guardContext(context);\n return (await options.runtime.availableThinkingLevels()) as ThinkingLevel[];\n },\n async compact(args, context) {\n guardContext(context);\n await options.runtime.compact(args.customInstructions);\n return null;\n },\n async setName(name, context) {\n guardContext(context);\n if (typeof name !== 'string' || name.length > 256) throw new Error('Invalid session name');\n await options.runtime.setName(name);\n },\n async dispose() {\n terminate(new Error('The session runtime is disposed'));\n },\n };\n}\n\nexport interface AgentServerServiceOptions extends AgentSessionRuntimeOptions {\n createdAt: number;\n}\n\nexport interface DoomSessionMetadata {\n id: string;\n createdAt: number;\n storageVersion: number;\n cwd: string;\n sessionName: string;\n}\n\nfunction endpointAttachment(endpoint: RemoteServiceEndpoint): {\n invokeService: RemoteServiceEndpoint['invoke'];\n release(): void;\n} {\n return {\n invokeService: (call, publish, context) => endpoint.invoke(call, publish, context),\n release: () => endpoint.dispose(),\n };\n}\n\nfunction managementHost(): RoutedServerServiceHost {\n return {\n attachClient(presentation) {\n const provider = new RemoteServiceProvider([{ service: DoomSessionManagementService, mode: 'singleton' }]);\n provider.provide(DoomSessionManagementService, {\n attach: (sessionId, context) => presentation.attachSession(sessionId, context),\n detach: (context) => presentation.detachSession(context),\n });\n return endpointAttachment(createRemoteServiceEndpoint(provider));\n },\n };\n}\n\n/** Creates the 0.85 routed host for one supervised DoomPi session. */\nexport function createAgentServerService(options: AgentServerServiceOptions): ServerHost<DoomSessionMetadata> {\n const metadata: DoomSessionMetadata = {\n id: options.sessionId,\n createdAt: options.createdAt,\n storageVersion: 1,\n cwd: options.cwd,\n sessionName: options.sessionName,\n };\n const runtime = createAgentSessionRuntime(options);\n let closed = false;\n\n return {\n serverServices: managementHost(),\n async resolveSession(sessionId) {\n if (sessionId !== metadata.id) throw new SessionNotFoundError(`No session ${sessionId}`);\n return metadata;\n },\n async openSession() {\n if (closed) throw new SessionNotFoundError('The session service is closed');\n await runtime.initialize();\n const provider = new RemoteServiceProvider([{ service: DoomSessionService, mode: 'singleton' }]);\n provider.provide(DoomSessionService, runtime);\n const handle: RoutedSessionHandle = {\n attachClient: () => endpointAttachment(createRemoteServiceEndpoint(provider)),\n async close() {\n if (closed) return;\n closed = true;\n provider.dispose();\n await runtime.dispose();\n },\n };\n return handle;\n },\n };\n}\n\nexport type { SessionSnapshot };\n"],"mappings":"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"}
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"headless.cjs","names":[],"sources":["../../../src/schemas/headless.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport type { ThinkingLevel } from '@earendil-works/pi-agent-core';\nimport type { CallToolResult, Tool } from '@modelcontextprotocol/server';\nimport type { Static, TSchema } from 'typebox';\n\nimport type { DoomSessionContext } from './hubChannel';\nimport type { DoomNotificationRequest } from './notification';\nimport type { DoomServerBundleEntry } from './serverBundle';\n\n/** Session-only contributions. This is not a Pi ExtensionAPI or a TUI adapter. */\nexport const DOOM_HEADLESS_HOST_SERVICE = 'doom/headless-host';\nexport const DOOM_HEADLESS_OWNER = Symbol.for('doom/headless-owner');\n\nexport interface DoomHeadlessSelection {\n readonly majorMode: string;\n readonly activeLayers: readonly string[];\n readonly domains: readonly string[];\n readonly profile?: string;\n /** Feature-owned activation sets, keyed by the contributing capability. */\n readonly state?: Readonly<Record<string, readonly string[]>>;\n}\n\n/** One package-owned selection transition. Server facets change exactly one axis per operation. */\nexport type DoomHeadlessSelectionChange =\n | { readonly axis: 'majorMode'; readonly majorMode: string }\n | { readonly axis: 'domains'; readonly domains: readonly string[] }\n | { readonly axis: 'profile'; readonly profile?: string }\n | { readonly axis: 'state'; readonly key: string; readonly values: readonly string[] };\n\nexport function readDoomHeadlessOwner(context: Context): DoomServerBundleEntry | undefined {\n return (context as Context & { [DOOM_HEADLESS_OWNER]?: DoomServerBundleEntry })[DOOM_HEADLESS_OWNER];\n}\n\nexport interface DoomHeadlessRegistration {\n dispose(): void;\n}\n\nexport type DoomHeadlessContent = { type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string };\n\nexport interface DoomHeadlessToolResult {\n content: DoomHeadlessContent[];\n /** Public MCP result data. Internal renderer details are not a remote result contract. */\n structuredContent?: Record<string, unknown>;\n /** Component-only MCP metadata, never inferred from internal renderer details. */\n _meta?: CallToolResult['_meta'];\n details?: unknown;\n isError?: boolean;\n}\n\n/**\n * Narrows a Pi tool result to the headless contract. Pi types `structuredContent` as any JSON\n * value, while MCP only accepts an object, so anything else is dropped rather than forwarded.\n */\nexport function toDoomHeadlessToolResult(result: {\n readonly content: DoomHeadlessContent[];\n readonly details?: unknown;\n readonly structuredContent?: unknown;\n readonly isError?: boolean;\n}): DoomHeadlessToolResult {\n const { structuredContent } = result;\n return {\n content: result.content,\n details: result.details,\n ...(typeof structuredContent === 'object' && structuredContent !== null && !Array.isArray(structuredContent)\n ? { structuredContent: structuredContent as Record<string, unknown> }\n : {}),\n ...(result.isError === undefined ? {} : { isError: result.isError }),\n };\n}\n\nexport interface DoomHeadlessClientRequest {\n kind: 'confirm' | 'select' | 'input';\n title: string;\n message?: string;\n options?: readonly { label: string; description?: string; value: string }[];\n initialValue?: string;\n multiline?: boolean;\n}\n\nexport interface DoomHeadlessClient {\n /**\n * Operator-facing surface only: the body is flattened to one line and capped at 4096 characters\n * by schemas/notification.ts:73-83, and the model never sees it. Use session.admitPrompt to\n * reach the model.\n */\n notify(request: DoomNotificationRequest): void | Promise<void>;\n request(request: DoomHeadlessClientRequest, signal?: AbortSignal): Promise<unknown>;\n setStatus(source: string, text: string | undefined): void;\n appendComposerText?(text: string): void;\n}\n\nexport interface DoomHeadlessModelSettings {\n model?: { provider: string; id: string };\n thinkingLevel: ThinkingLevel;\n}\n\nexport interface DoomHeadlessSession {\n readModelSettings?(): Promise<DoomHeadlessModelSettings>;\n setFastMode?(enabled: boolean): Promise<void>;\n setModelSettings?(settings: Partial<DoomHeadlessModelSettings>): Promise<void>;\n /** Query durable history on demand; hosts do not retain the entire transcript. */\n entries(query?: {\n type?: 'custom' | 'message';\n customType?: string;\n limit?: number;\n }): readonly Record<string, unknown>[] | Promise<readonly Record<string, unknown>[]>;\n appendCustomEntry(type: string, data: unknown): Promise<void>;\n /**\n * Delivers and awaits the turn. 'steer' and 'followUp' only enqueue into a running turn; they do\n * NOT wake an idle agent.\n */\n prompt(text: string, delivery?: 'prompt' | 'steer' | 'followUp'): Promise<void>;\n /**\n * Resolves when accepted by the session, before the agent turn settles. Here 'steer' describes\n * how to deliver IF a turn is already running; an idle agent is woken either way, matching Pi's\n * ExtensionAPI.sendMessage({ triggerTurn: true, deliverAs: 'steer' }). 'interrupt' cancels the\n * active run and directly admits this user input without releasing retained queued work.\n */\n admitPrompt?(text: string, delivery?: 'prompt' | 'steer' | 'followUp' | 'interrupt'): Promise<void>;\n abort(): Promise<void>;\n compact(instructions?: string): Promise<void>;\n activity(): Promise<{ hasPendingMessages: boolean; isIdle: boolean }>;\n /** Renames the durable session and publishes the updated title to presentation clients. */\n setName?(name: string): Promise<void>;\n /** Capture the current persisted branch for an in-process child fork. */\n forkSource?(): Promise<{ kind: 'v4-fork'; sessionFile: string; branch: string; entryId?: string }>;\n}\n\n/** A grant-filtered skill view available only during one remote MCP tool invocation. */\nexport interface DoomMcpSkillAccess {\n list(): Promise<readonly { name: string; description: string }[]>;\n read(name: string): Promise<string>;\n}\n\n/** A stateless auxiliary request. These tools are private to this request, never registered on the agent. */\nexport interface DoomHeadlessToolCompletionRequest {\n systemPrompt: string;\n input: string;\n maxTokens: number;\n cacheRetention?: 'none' | 'short' | 'long';\n signal?: AbortSignal;\n tools: readonly Pick<DoomHeadlessTool, 'name' | 'description' | 'parameters'>[];\n}\n\nexport interface DoomHeadlessToolCompletionResult {\n toolCalls: readonly { id: string; name: string; arguments: unknown }[];\n usage: { totalTokens: number };\n}\n\nexport interface DoomHeadlessExecutionContext {\n readonly cwd: string;\n /** The checkout the session runs in, distinct from the tool execution directory. */\n readonly repoRoot: string;\n readonly sessionId: string;\n /** The session's baseline context, when its host knows its workspace. */\n readonly sessionContext?: DoomSessionContext;\n /** Immutable session configuration. Facets must not read or mutate process.env. */\n readonly environment: Readonly<Record<string, string | undefined>>;\n readonly client: DoomHeadlessClient;\n readonly session: DoomHeadlessSession;\n readonly model?: { provider: string; id: string };\n readonly textCompletion?: {\n available(reference: string): boolean;\n complete(\n reference: string,\n request: {\n systemPrompt: string;\n input: string;\n maxTokens: number;\n cacheRetention?: 'none' | 'short' | 'long';\n signal?: AbortSignal;\n },\n ): Promise<string>;\n };\n readonly toolCompletion?: {\n complete(reference: string, request: DoomHeadlessToolCompletionRequest): Promise<DoomHeadlessToolCompletionResult>;\n };\n readonly selection: DoomHeadlessSelection;\n /** Present only while an authenticated remote MCP tool is running. */\n readonly mcpSkills?: DoomMcpSkillAccess;\n shutdown(): void;\n}\n\n/** Conditions narrow an eligible owner's contributions; they can never restore a disabled owner. */\nexport interface DoomHeadlessCondition {\n state?: Readonly<Record<string, string>>;\n attribution?: { kind: 'minor' | 'domain'; mode: string; label?: string };\n domain?: string;\n}\n\nexport interface DoomHeadlessToolRestriction {\n when?: DoomHeadlessCondition;\n /** Optional capability ceiling. An empty list disables every tool. */\n allowedTools?: readonly string[];\n /**\n * Narrow exclusions without disabling unrelated tools. Exclude a tool your package owns, or a\n * specific foreign tool the mode exists to withdraw. Never enumerate an allowlist here.\n */\n excludedTools?: readonly string[];\n}\n\nexport interface DoomHeadlessTool<TParameters extends TSchema = TSchema> {\n when?: DoomHeadlessCondition;\n name: string;\n label?: string;\n description: string;\n parameters: TParameters;\n annotations?: Tool['annotations'];\n outputSchema?: Tool['outputSchema'];\n /** Remote presentation only. Component tool access must be explicitly opted into. */\n _meta?: Tool['_meta'] & {\n ui?: {\n resourceUri?: string;\n visibility?: ('model' | 'app')[];\n };\n };\n promptSnippet?: string;\n promptGuidelines?: readonly string[];\n executionMode?: 'parallel' | 'serial';\n execute(\n toolCallId: string,\n parameters: Static<TParameters>,\n signal: AbortSignal | undefined,\n onUpdate: ((result: DoomHeadlessToolResult) => void) | undefined,\n context: DoomHeadlessExecutionContext,\n ): Promise<DoomHeadlessToolResult>;\n}\n\n/**\n * One package contribution to the session's resource surface.\n *\n * `kind` decides what the model is billed for, and the difference is large:\n * - `context` is EAGER. `read()` runs on every prompt build and the text is pasted\n * into the system prompt verbatim. Reserve it for small live session state that\n * exists nowhere on disk. Never use it for a file the package ships: a README\n * registered this way costs its full length on every single turn.\n * - `skill` is LAZY. Only `name`, `description` and `path` reach the prompt; the\n * agent reads the file itself when the description matches the task.\n * - `prompt` is inert until the user invokes it by name.\n *\n * The rule in one line: if it is a file the package ships, it is a `skill`.\n */\nexport interface DoomHeadlessResource {\n when?: DoomHeadlessCondition;\n name: string;\n /** Model-visible selection signal. A `skill` without one tells the agent nothing. */\n description?: string;\n /** Absolute path of the file `read()` returns, so an advertised skill is one the agent can open. */\n path?: string;\n kind: 'prompt' | 'skill' | 'context';\n read(context: DoomHeadlessExecutionContext): string | Promise<string>;\n}\n\nexport interface DoomHeadlessCommand {\n when?: DoomHeadlessCondition;\n name: string;\n description: string;\n execute(args: string, context: DoomHeadlessExecutionContext): void | Promise<void>;\n}\n\nexport type DoomHeadlessEventName =\n | 'session_start'\n | 'session_shutdown'\n | 'session_tree'\n | 'before_agent_start'\n | 'agent_start'\n | 'agent_settled'\n | 'turn_start'\n | 'turn_end'\n | 'context'\n | 'before_provider_request'\n | 'message_start'\n | 'message_update'\n | 'message_end'\n | 'tool_call'\n | 'tool_execution_start'\n | 'tool_execution_update'\n | 'tool_execution_end'\n | 'tool_result'\n | 'model_select'\n | 'session_before_compact'\n | 'session_compact';\n\nexport type DoomHeadlessHookEvent<E extends DoomHeadlessEventName> = E extends 'before_provider_request'\n ? { lane: string; runId: string; model: { provider: string; id: string }; payload: unknown }\n : E extends 'session_before_compact'\n ? { reason: string; preparation: unknown; instructions?: string; customInstructions?: string }\n : E extends 'model_select'\n ? { model: { provider: string; id: string } }\n : Readonly<Record<string, unknown>>;\n\nexport interface DoomHeadlessCompactionResult {\n summary: string;\n tokensBefore: number;\n retainedTail: Record<string, unknown>[];\n usage?: Record<string, unknown>;\n details?: unknown;\n}\n\nexport type DoomHeadlessHookResult<E extends DoomHeadlessEventName> = E extends 'before_provider_request'\n ? { payload: unknown } | void\n : E extends 'session_before_compact'\n ? { cancel?: boolean; decline?: boolean; compaction?: DoomHeadlessCompactionResult } | void\n : E extends 'context'\n ? { messages?: unknown[]; systemPrompt?: string } | void\n : E extends 'before_agent_start'\n ? { systemPrompt?: string } | void\n : E extends 'tool_call'\n ? { args?: Record<string, unknown>; block?: { reason: string; terminate?: boolean } } | void\n : E extends 'tool_result'\n ? {\n content?: DoomHeadlessContent[];\n details?: unknown;\n isError?: boolean;\n usage?: Record<string, unknown>;\n terminate?: boolean;\n } | void\n : unknown;\n\nexport type DoomHeadlessHook<E extends DoomHeadlessEventName = DoomHeadlessEventName> = E extends DoomHeadlessEventName\n ? {\n when?: DoomHeadlessCondition;\n event: E;\n handle(\n event: Readonly<DoomHeadlessHookEvent<E>>,\n context: DoomHeadlessExecutionContext,\n ): DoomHeadlessHookResult<E> | Promise<DoomHeadlessHookResult<E>>;\n }\n : never;\n\n/** A retained facet can register activity without starting disabled watchers or services. */\nexport interface DoomHeadlessActivity {\n when?: DoomHeadlessCondition;\n name: string;\n start(context: DoomHeadlessExecutionContext): (() => void | Promise<void>) | Promise<() => void | Promise<void>>;\n}\n\n/** Read-only metadata for the currently applied session, never executable declarations or resource bodies. */\nexport interface DoomHeadlessCapability {\n readonly source: string;\n readonly name: string;\n readonly kind: 'tool' | 'skill';\n readonly when?: DoomHeadlessCondition;\n readonly active: boolean;\n readonly discoverable: boolean;\n readonly reason?: 'inactive' | 'restricted' | 'shadowed' | 'unavailable' | 'not-discoverable';\n}\n\nexport interface DoomHeadlessCapabilitySnapshot {\n readonly revision: number;\n readonly ready: boolean;\n readonly capabilities: readonly DoomHeadlessCapability[];\n}\n\n/** Registrations inherit package ownership from the caller's Cordis facet. */\n/**\n * The tool a server session loads skills through. When a session carries it, the prompt lists\n * every skill by name and points here, so a skill needs no file the agent could read.\n */\nexport const DOOM_LOAD_SKILL_TOOL = 'load_skill';\n\nexport interface DoomHeadlessHostService {\n readonly context: DoomHeadlessExecutionContext;\n /** The instructions of an applied skill by exact name, or undefined when none is applied. */\n readSkill(name: string): string | undefined;\n changeSelection(change: DoomHeadlessSelectionChange): Promise<void>;\n assertActive(source?: string): void;\n subscribeSelection(listener: (selection: DoomHeadlessSelection) => void | Promise<void>): () => void;\n /** Inspect only a coherently applied generation. A transition returns ready=false and no partial inventory. */\n inspectCapabilities(): DoomHeadlessCapabilitySnapshot;\n registerToolRestriction(restriction: DoomHeadlessToolRestriction): DoomHeadlessRegistration;\n registerTool<TParameters extends TSchema>(tool: DoomHeadlessTool<TParameters>): DoomHeadlessRegistration;\n registerResource(resource: DoomHeadlessResource): DoomHeadlessRegistration;\n registerCommand(command: DoomHeadlessCommand): DoomHeadlessRegistration;\n registerHook(hook: DoomHeadlessHook): DoomHeadlessRegistration;\n registerActivity(activity: DoomHeadlessActivity): DoomHeadlessRegistration;\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'doom/headless-host': DoomHeadlessHostService;\n }\n}\n\nexport function readDoomHeadlessHost(context: Context): DoomHeadlessHostService | undefined {\n return context.get(DOOM_HEADLESS_HOST_SERVICE) as DoomHeadlessHostService | undefined;\n}\n\nexport function requireDoomHeadlessHost(context: Context): DoomHeadlessHostService {\n const host = readDoomHeadlessHost(context);\n if (!host) throw new Error('This contribution requires the Doom headless session host.');\n return host;\n}\n"],"mappings":";;AAUA,MAAa,6BAA6B;AAC1C,MAAa,sBAAsB,OAAO,IAAI,qBAAqB;AAkBnE,SAAgB,sBAAsB,SAAqD;CACzF,OAAQ,QAAwE;AAClF;;;;;AAsBA,SAAgB,yBAAyB,QAKd;CACzB,MAAM,EAAE,sBAAsB;CAC9B,OAAO;EACL,SAAS,OAAO;EAChB,SAAS,OAAO;EAChB,GAAI,OAAO,sBAAsB,YAAY,sBAAsB,QAAQ,CAAC,MAAM,QAAQ,iBAAiB,IACvG,EAAqB,kBAA6C,IAClE,CAAC;EACL,GAAI,OAAO,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;CACpE;AACF;;;;;;AAmSA,MAAa,uBAAuB;AAyBpC,SAAgB,qBAAqB,SAAuD;CAC1F,OAAO,QAAQ,IAAI,0BAA0B;AAC/C;AAEA,SAAgB,wBAAwB,SAA2C;CACjF,MAAM,OAAO,qBAAqB,OAAO;CACzC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,4DAA4D;CACvF,OAAO;AACT"}
|
|
1
|
+
{"version":3,"file":"headless.cjs","names":[],"sources":["../../../src/schemas/headless.ts"],"sourcesContent":["import type { Context } from '@deepseek-ai/cordis';\nimport type { ThinkingLevel } from '@earendil-works/pi-agent-core';\nimport type { CallToolResult, Tool } from '@modelcontextprotocol/server';\nimport type { Static, TSchema } from 'typebox';\n\nimport type { DoomSessionContext } from './hubChannel';\nimport type { DoomNotificationRequest } from './notification';\nimport type { DoomServerBundleEntry } from './serverBundle';\n\n/** Session-only contributions. This is not a Pi ExtensionAPI or a TUI adapter. */\nexport const DOOM_HEADLESS_HOST_SERVICE = 'doom/headless-host';\nexport const DOOM_HEADLESS_OWNER = Symbol.for('doom/headless-owner');\n\nexport interface DoomHeadlessSelection {\n readonly majorMode: string;\n readonly activeLayers: readonly string[];\n readonly domains: readonly string[];\n readonly profile?: string;\n /** Feature-owned activation sets, keyed by the contributing capability. */\n readonly state?: Readonly<Record<string, readonly string[]>>;\n}\n\n/** One package-owned selection transition. Server facets change exactly one axis per operation. */\nexport type DoomHeadlessSelectionChange =\n | { readonly axis: 'majorMode'; readonly majorMode: string }\n | { readonly axis: 'domains'; readonly domains: readonly string[] }\n | { readonly axis: 'profile'; readonly profile?: string }\n | { readonly axis: 'state'; readonly key: string; readonly values: readonly string[] };\n\nexport function readDoomHeadlessOwner(context: Context): DoomServerBundleEntry | undefined {\n return (context as Context & { [DOOM_HEADLESS_OWNER]?: DoomServerBundleEntry })[DOOM_HEADLESS_OWNER];\n}\n\nexport interface DoomHeadlessRegistration {\n dispose(): void;\n}\n\nexport type DoomHeadlessContent = { type: 'text'; text: string } | { type: 'image'; data: string; mimeType: string };\n\nexport interface DoomHeadlessToolResult {\n content: DoomHeadlessContent[];\n /** Public MCP result data. Internal renderer details are not a remote result contract. */\n structuredContent?: Record<string, unknown>;\n /** Component-only MCP metadata, never inferred from internal renderer details. */\n _meta?: CallToolResult['_meta'];\n details?: unknown;\n isError?: boolean;\n}\n\n/**\n * Narrows a Pi tool result to the headless contract. Pi types `structuredContent` as any JSON\n * value, while MCP only accepts an object, so anything else is dropped rather than forwarded.\n */\nexport function toDoomHeadlessToolResult(result: {\n readonly content: DoomHeadlessContent[];\n readonly details?: unknown;\n readonly structuredContent?: unknown;\n readonly isError?: boolean;\n}): DoomHeadlessToolResult {\n const { structuredContent } = result;\n return {\n content: result.content,\n details: result.details,\n ...(typeof structuredContent === 'object' && structuredContent !== null && !Array.isArray(structuredContent)\n ? { structuredContent: structuredContent as Record<string, unknown> }\n : {}),\n ...(result.isError === undefined ? {} : { isError: result.isError }),\n };\n}\n\nexport interface DoomHeadlessClientRequest {\n kind: 'confirm' | 'select' | 'input';\n title: string;\n message?: string;\n options?: readonly { label: string; description?: string; value: string }[];\n initialValue?: string;\n multiline?: boolean;\n}\n\nexport interface DoomHeadlessClient {\n /**\n * Operator-facing surface only: the body is flattened to one line and capped at 4096 characters\n * by schemas/notification.ts:73-83, and the model never sees it. Use session.admitPrompt to\n * reach the model.\n */\n notify(request: DoomNotificationRequest): void | Promise<void>;\n request(request: DoomHeadlessClientRequest, signal?: AbortSignal): Promise<unknown>;\n setStatus(source: string, text: string | undefined): void;\n appendComposerText?(text: string): void;\n}\n\nexport interface DoomHeadlessModelSettings {\n model?: { provider: string; id: string };\n thinkingLevel: ThinkingLevel;\n}\n\nexport interface DoomHeadlessSession {\n readModelSettings?(): Promise<DoomHeadlessModelSettings>;\n setFastMode?(enabled: boolean): Promise<void>;\n setModelSettings?(settings: Partial<DoomHeadlessModelSettings>): Promise<void>;\n /** Query durable history on demand; hosts do not retain the entire transcript. */\n entries(query?: {\n type?: 'custom' | 'message';\n customType?: string;\n limit?: number;\n }): readonly Record<string, unknown>[] | Promise<readonly Record<string, unknown>[]>;\n appendCustomEntry(type: string, data: unknown): Promise<void>;\n /**\n * Delivers host-generated input and awaits its turn without using the operator queue.\n * An idle agent is woken; busy delivery uses Durable steering or follow-up.\n */\n prompt(text: string, delivery?: 'prompt' | 'steer' | 'followUp'): Promise<void>;\n /**\n * Admits host-generated input without awaiting its turn. Internal input never changes the\n * operator queue. Voice capture can explicitly select operator origin; 'interrupt' cancels\n * the active run and admits operator input while preserving retained queued work.\n */\n admitPrompt?(\n text: string,\n delivery?: 'prompt' | 'steer' | 'followUp' | 'interrupt',\n origin?: 'operator',\n ): Promise<void>;\n abort(): Promise<void>;\n compact(instructions?: string): Promise<void>;\n activity(): Promise<{ hasPendingMessages: boolean; isIdle: boolean }>;\n /** Renames the durable session and publishes the updated title to presentation clients. */\n setName?(name: string): Promise<void>;\n /** Capture the current persisted branch for an in-process child fork. */\n forkSource?(): Promise<{ kind: 'v4-fork'; sessionFile: string; branch: string; entryId?: string }>;\n}\n\n/** A grant-filtered skill view available only during one remote MCP tool invocation. */\nexport interface DoomMcpSkillAccess {\n list(): Promise<readonly { name: string; description: string }[]>;\n read(name: string): Promise<string>;\n}\n\n/** A stateless auxiliary request. These tools are private to this request, never registered on the agent. */\nexport interface DoomHeadlessToolCompletionRequest {\n systemPrompt: string;\n input: string;\n maxTokens: number;\n cacheRetention?: 'none' | 'short' | 'long';\n signal?: AbortSignal;\n tools: readonly Pick<DoomHeadlessTool, 'name' | 'description' | 'parameters'>[];\n}\n\nexport interface DoomHeadlessToolCompletionResult {\n toolCalls: readonly { id: string; name: string; arguments: unknown }[];\n usage: { totalTokens: number };\n}\n\nexport interface DoomHeadlessExecutionContext {\n readonly cwd: string;\n /** The checkout the session runs in, distinct from the tool execution directory. */\n readonly repoRoot: string;\n readonly sessionId: string;\n /** The session's baseline context, when its host knows its workspace. */\n readonly sessionContext?: DoomSessionContext;\n /** Immutable session configuration. Facets must not read or mutate process.env. */\n readonly environment: Readonly<Record<string, string | undefined>>;\n readonly client: DoomHeadlessClient;\n readonly session: DoomHeadlessSession;\n readonly model?: { provider: string; id: string };\n readonly textCompletion?: {\n available(reference: string): boolean;\n complete(\n reference: string,\n request: {\n systemPrompt: string;\n input: string;\n maxTokens: number;\n cacheRetention?: 'none' | 'short' | 'long';\n signal?: AbortSignal;\n },\n ): Promise<string>;\n };\n readonly toolCompletion?: {\n complete(reference: string, request: DoomHeadlessToolCompletionRequest): Promise<DoomHeadlessToolCompletionResult>;\n };\n readonly selection: DoomHeadlessSelection;\n /** Present only while an authenticated remote MCP tool is running. */\n readonly mcpSkills?: DoomMcpSkillAccess;\n shutdown(): void;\n}\n\n/** Conditions narrow an eligible owner's contributions; they can never restore a disabled owner. */\nexport interface DoomHeadlessCondition {\n state?: Readonly<Record<string, string>>;\n attribution?: { kind: 'minor' | 'domain'; mode: string; label?: string };\n domain?: string;\n}\n\nexport interface DoomHeadlessToolRestriction {\n when?: DoomHeadlessCondition;\n /** Optional capability ceiling. An empty list disables every tool. */\n allowedTools?: readonly string[];\n /**\n * Narrow exclusions without disabling unrelated tools. Exclude a tool your package owns, or a\n * specific foreign tool the mode exists to withdraw. Never enumerate an allowlist here.\n */\n excludedTools?: readonly string[];\n}\n\nexport interface DoomHeadlessTool<TParameters extends TSchema = TSchema> {\n when?: DoomHeadlessCondition;\n name: string;\n label?: string;\n description: string;\n parameters: TParameters;\n annotations?: Tool['annotations'];\n outputSchema?: Tool['outputSchema'];\n /** Remote presentation only. Component tool access must be explicitly opted into. */\n _meta?: Tool['_meta'] & {\n ui?: {\n resourceUri?: string;\n visibility?: ('model' | 'app')[];\n };\n };\n promptSnippet?: string;\n promptGuidelines?: readonly string[];\n executionMode?: 'parallel' | 'serial';\n execute(\n toolCallId: string,\n parameters: Static<TParameters>,\n signal: AbortSignal | undefined,\n onUpdate: ((result: DoomHeadlessToolResult) => void) | undefined,\n context: DoomHeadlessExecutionContext,\n ): Promise<DoomHeadlessToolResult>;\n}\n\n/**\n * One package contribution to the session's resource surface.\n *\n * `kind` decides what the model is billed for, and the difference is large:\n * - `context` is EAGER. `read()` runs on every prompt build and the text is pasted\n * into the system prompt verbatim. Reserve it for small live session state that\n * exists nowhere on disk. Never use it for a file the package ships: a README\n * registered this way costs its full length on every single turn.\n * - `skill` is LAZY. Only `name`, `description` and `path` reach the prompt; the\n * agent reads the file itself when the description matches the task.\n * - `prompt` is inert until the user invokes it by name.\n *\n * The rule in one line: if it is a file the package ships, it is a `skill`.\n */\nexport interface DoomHeadlessResource {\n when?: DoomHeadlessCondition;\n name: string;\n /** Model-visible selection signal. A `skill` without one tells the agent nothing. */\n description?: string;\n /** Absolute path of the file `read()` returns, so an advertised skill is one the agent can open. */\n path?: string;\n kind: 'prompt' | 'skill' | 'context';\n read(context: DoomHeadlessExecutionContext): string | Promise<string>;\n}\n\nexport interface DoomHeadlessCommand {\n when?: DoomHeadlessCondition;\n name: string;\n description: string;\n execute(args: string, context: DoomHeadlessExecutionContext): void | Promise<void>;\n}\n\nexport type DoomHeadlessEventName =\n | 'session_start'\n | 'session_shutdown'\n | 'session_tree'\n | 'before_agent_start'\n | 'agent_start'\n | 'agent_settled'\n | 'turn_start'\n | 'turn_end'\n | 'context'\n | 'before_provider_request'\n | 'message_start'\n | 'message_update'\n | 'message_end'\n | 'tool_call'\n | 'tool_execution_start'\n | 'tool_execution_update'\n | 'tool_execution_end'\n | 'tool_result'\n | 'model_select'\n | 'session_before_compact'\n | 'session_compact';\n\nexport type DoomHeadlessHookEvent<E extends DoomHeadlessEventName> = E extends 'before_provider_request'\n ? { lane: string; runId: string; model: { provider: string; id: string }; payload: unknown }\n : E extends 'session_before_compact'\n ? { reason: string; preparation: unknown; instructions?: string; customInstructions?: string }\n : E extends 'model_select'\n ? { model: { provider: string; id: string } }\n : Readonly<Record<string, unknown>>;\n\nexport interface DoomHeadlessCompactionResult {\n summary: string;\n tokensBefore: number;\n retainedTail: Record<string, unknown>[];\n usage?: Record<string, unknown>;\n details?: unknown;\n}\n\nexport type DoomHeadlessHookResult<E extends DoomHeadlessEventName> = E extends 'before_provider_request'\n ? { payload: unknown } | void\n : E extends 'session_before_compact'\n ? { cancel?: boolean; decline?: boolean; compaction?: DoomHeadlessCompactionResult } | void\n : E extends 'context'\n ? { messages?: unknown[]; systemPrompt?: string } | void\n : E extends 'before_agent_start'\n ? { systemPrompt?: string } | void\n : E extends 'tool_call'\n ? { args?: Record<string, unknown>; block?: { reason: string; terminate?: boolean } } | void\n : E extends 'tool_result'\n ? {\n content?: DoomHeadlessContent[];\n details?: unknown;\n isError?: boolean;\n usage?: Record<string, unknown>;\n terminate?: boolean;\n } | void\n : unknown;\n\nexport type DoomHeadlessHook<E extends DoomHeadlessEventName = DoomHeadlessEventName> = E extends DoomHeadlessEventName\n ? {\n when?: DoomHeadlessCondition;\n event: E;\n handle(\n event: Readonly<DoomHeadlessHookEvent<E>>,\n context: DoomHeadlessExecutionContext,\n ): DoomHeadlessHookResult<E> | Promise<DoomHeadlessHookResult<E>>;\n }\n : never;\n\n/** A retained facet can register activity without starting disabled watchers or services. */\nexport interface DoomHeadlessActivity {\n when?: DoomHeadlessCondition;\n name: string;\n start(context: DoomHeadlessExecutionContext): (() => void | Promise<void>) | Promise<() => void | Promise<void>>;\n}\n\n/** Read-only metadata for the currently applied session, never executable declarations or resource bodies. */\nexport interface DoomHeadlessCapability {\n readonly source: string;\n readonly name: string;\n readonly kind: 'tool' | 'skill';\n readonly when?: DoomHeadlessCondition;\n readonly active: boolean;\n readonly discoverable: boolean;\n readonly reason?: 'inactive' | 'restricted' | 'shadowed' | 'unavailable' | 'not-discoverable';\n}\n\nexport interface DoomHeadlessCapabilitySnapshot {\n readonly revision: number;\n readonly ready: boolean;\n readonly capabilities: readonly DoomHeadlessCapability[];\n}\n\n/** Registrations inherit package ownership from the caller's Cordis facet. */\n/**\n * The tool a server session loads skills through. When a session carries it, the prompt lists\n * every skill by name and points here, so a skill needs no file the agent could read.\n */\nexport const DOOM_LOAD_SKILL_TOOL = 'load_skill';\n\nexport interface DoomHeadlessHostService {\n readonly context: DoomHeadlessExecutionContext;\n /** The instructions of an applied skill by exact name, or undefined when none is applied. */\n readSkill(name: string): string | undefined;\n changeSelection(change: DoomHeadlessSelectionChange): Promise<void>;\n assertActive(source?: string): void;\n subscribeSelection(listener: (selection: DoomHeadlessSelection) => void | Promise<void>): () => void;\n /** Inspect only a coherently applied generation. A transition returns ready=false and no partial inventory. */\n inspectCapabilities(): DoomHeadlessCapabilitySnapshot;\n registerToolRestriction(restriction: DoomHeadlessToolRestriction): DoomHeadlessRegistration;\n registerTool<TParameters extends TSchema>(tool: DoomHeadlessTool<TParameters>): DoomHeadlessRegistration;\n registerResource(resource: DoomHeadlessResource): DoomHeadlessRegistration;\n registerCommand(command: DoomHeadlessCommand): DoomHeadlessRegistration;\n registerHook(hook: DoomHeadlessHook): DoomHeadlessRegistration;\n registerActivity(activity: DoomHeadlessActivity): DoomHeadlessRegistration;\n}\n\ndeclare module '@deepseek-ai/cordis' {\n interface Context {\n 'doom/headless-host': DoomHeadlessHostService;\n }\n}\n\nexport function readDoomHeadlessHost(context: Context): DoomHeadlessHostService | undefined {\n return context.get(DOOM_HEADLESS_HOST_SERVICE) as DoomHeadlessHostService | undefined;\n}\n\nexport function requireDoomHeadlessHost(context: Context): DoomHeadlessHostService {\n const host = readDoomHeadlessHost(context);\n if (!host) throw new Error('This contribution requires the Doom headless session host.');\n return host;\n}\n"],"mappings":";;AAUA,MAAa,6BAA6B;AAC1C,MAAa,sBAAsB,OAAO,IAAI,qBAAqB;AAkBnE,SAAgB,sBAAsB,SAAqD;CACzF,OAAQ,QAAwE;AAClF;;;;;AAsBA,SAAgB,yBAAyB,QAKd;CACzB,MAAM,EAAE,sBAAsB;CAC9B,OAAO;EACL,SAAS,OAAO;EAChB,SAAS,OAAO;EAChB,GAAI,OAAO,sBAAsB,YAAY,sBAAsB,QAAQ,CAAC,MAAM,QAAQ,iBAAiB,IACvG,EAAqB,kBAA6C,IAClE,CAAC;EACL,GAAI,OAAO,YAAY,KAAA,IAAY,CAAC,IAAI,EAAE,SAAS,OAAO,QAAQ;CACpE;AACF;;;;;;AAsSA,MAAa,uBAAuB;AAyBpC,SAAgB,qBAAqB,SAAuD;CAC1F,OAAO,QAAQ,IAAI,0BAA0B;AAC/C;AAEA,SAAgB,wBAAwB,SAA2C;CACjF,MAAM,OAAO,qBAAqB,OAAO;CACzC,IAAI,CAAC,MAAM,MAAM,IAAI,MAAM,4DAA4D;CACvF,OAAO;AACT"}
|
|
@@ -105,17 +105,16 @@ export interface DoomHeadlessSession {
|
|
|
105
105
|
}): readonly Record<string, unknown>[] | Promise<readonly Record<string, unknown>[]>;
|
|
106
106
|
appendCustomEntry(type: string, data: unknown): Promise<void>;
|
|
107
107
|
/**
|
|
108
|
-
* Delivers and awaits
|
|
109
|
-
*
|
|
108
|
+
* Delivers host-generated input and awaits its turn without using the operator queue.
|
|
109
|
+
* An idle agent is woken; busy delivery uses Durable steering or follow-up.
|
|
110
110
|
*/
|
|
111
111
|
prompt(text: string, delivery?: 'prompt' | 'steer' | 'followUp'): Promise<void>;
|
|
112
112
|
/**
|
|
113
|
-
*
|
|
114
|
-
*
|
|
115
|
-
*
|
|
116
|
-
* active run and directly admits this user input without releasing retained queued work.
|
|
113
|
+
* Admits host-generated input without awaiting its turn. Internal input never changes the
|
|
114
|
+
* operator queue. Voice capture can explicitly select operator origin; 'interrupt' cancels
|
|
115
|
+
* the active run and admits operator input while preserving retained queued work.
|
|
117
116
|
*/
|
|
118
|
-
admitPrompt?(text: string, delivery?: 'prompt' | 'steer' | 'followUp' | 'interrupt'): Promise<void>;
|
|
117
|
+
admitPrompt?(text: string, delivery?: 'prompt' | 'steer' | 'followUp' | 'interrupt', origin?: 'operator'): Promise<void>;
|
|
119
118
|
abort(): Promise<void>;
|
|
120
119
|
compact(instructions?: string): Promise<void>;
|
|
121
120
|
activity(): Promise<{
|