@ai-ecoverse/slicc-agent 3.50.2 → 3.52.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/freezer/index.ts"],
4
- "sourcesContent": ["import { type Context, type ReplicatedState, replicatedState } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type {\n Conversation,\n ConversationId,\n EntryRecord,\n Harness,\n} from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { answerText } from '../agent.ts';\nimport {\n type Agents,\n type AgentsState,\n type FrozenRecord,\n live,\n type ScoopRecord,\n} from '../agents.ts';\nimport { HOME } from '../kernel/env.ts';\nimport { type Layout, LEGACY } from '../layout.ts';\nimport type { LickTarget } from '../licks/lick.ts';\nimport { pinned } from '../secrets/extension.ts';\n\nexport type Answer = { code: number; out: string };\n\nexport type ConversationKind = 'cone' | 'scoop' | 'agent';\n\nexport interface FrozenCone {\n id: string;\n name: string;\n title: string;\n model: string;\n messages: number;\n frozenAt: number;\n kind: ConversationKind;\n live: boolean;\n thawedAs: string | null;\n}\n\nexport const THAWED_KIND = 'slicc.thawed';\n\nexport type Frozen = { id: string; name: string; at: number };\n\nexport interface FreezerAttach {\n harness: Harness;\n agents: Agents;\n env: Pick<ExecutionEnv, 'remove' | 'exists'>;\n title?: (transcript: string, model: string, context: Context) => Promise<string | undefined>;\n extract?: (\n conversation: number,\n tail: number,\n context: Context,\n cone: string\n ) => Promise<unknown>;\n now?: () => number;\n layout?: Layout;\n}\n\nexport interface FreezerRuntime {\n readonly frozen: ReplicatedState<FrozenCone[]>;\n freeze(agentId: string, context: Context): Promise<string>;\n newChat(agentId: string, context: Context): Promise<string | null>;\n thaw(id: string, context: Context): Promise<string>;\n discard(id: string, context: Context): Promise<void>;\n refresh(): Promise<readonly FrozenCone[]>;\n touch(): void;\n frozenTarget(target: LickTarget): Frozen | undefined;\n command(argv: readonly string[], caller: string | null, context: Context): Promise<Answer>;\n close(): void;\n}\n\nexport const USAGE = `usage:\n freezer list every conversation: id, kind, name, title, messages, when\n freezer show <id> a conversation as Markdown\n freezer thaw <id> continue a stopped conversation as a cone\n\nDelete a cone, or start a new conversation, from the chat toolbar or the command palette.\n`;\n\nconst TITLE_LENGTH = 60;\nexport const TOUCH_MS = 500;\n\nfunction textOf(entry: EntryRecord): string {\n return answerText(entry.model?.[0]?.content).trim();\n}\n\nexport function modelName(model: { provider: string; modelId: string } | undefined): string {\n return model ? `${model.provider}/${model.modelId}` : '';\n}\n\nexport function firstLine(entries: readonly EntryRecord[]): string {\n const first = entries.find((entry) => entry.kind === 'pi.user' && textOf(entry));\n const line = first ? (textOf(first).split('\\n')[0] as string).trim() : '';\n if (!line) return 'Untitled chat';\n return line.length > TITLE_LENGTH ? `${line.slice(0, TITLE_LENGTH - 1)}\u2026` : line;\n}\n\nfunction calls(entry: EntryRecord): string[] {\n const content = entry.model?.[0]?.content;\n if (!Array.isArray(content)) return [];\n return (content as { type: string; name?: string; arguments?: unknown }[])\n .filter((part) => part.type === 'toolCall')\n .map((part) => `- \\`${part.name}\\` ${JSON.stringify(part.arguments ?? {})}`);\n}\n\nexport function markdown(\n record: Pick<FrozenRecord, 'title' | 'name' | 'model' | 'frozenAt'>,\n entries: readonly EntryRecord[]\n): string {\n const out = [\n `# ${record.title}`,\n '',\n `${record.name} \u00B7 ${record.model} \u00B7 ${new Date(record.frozenAt).toISOString()}`,\n ];\n for (const entry of entries) {\n if (entry.kind === 'pi.user' && textOf(entry)) out.push('', '## User', '', textOf(entry));\n if (entry.kind !== 'pi.assistant') continue;\n const text = textOf(entry);\n const tools = calls(entry);\n if (!text && !tools.length) continue;\n out.push('', '## Assistant', '');\n if (text) out.push(text);\n if (tools.length) out.push(...(text ? [''] : []), ...tools);\n }\n return `${out.join('\\n')}\\n`;\n}\n\ntype Stats = Pick<FrozenCone, 'title' | 'model' | 'messages' | 'frozenAt'>;\n\nfunction counted(entries: readonly EntryRecord[]): number {\n return entries.filter((entry) => entry.kind === 'pi.user' || entry.kind === 'pi.assistant')\n .length;\n}\n\nfunction lastAt(entries: readonly EntryRecord[]): number {\n let at = 0;\n for (const entry of entries)\n for (const message of entry.model ?? []) {\n const stamp = (message as { timestamp?: unknown }).timestamp;\n if (typeof stamp === 'number' && stamp > at) at = stamp;\n }\n return at;\n}\n\nasync function statsOf(harness: Harness, id: number, context: Context): Promise<Stats> {\n const conversation = await harness.conversation(id as ConversationId, context);\n if (!conversation) return { title: firstLine([]), model: '', messages: 0, frozenAt: 0 };\n const view = await conversation.context(context);\n const agent = await conversation.agent(context);\n return {\n title: firstLine(view.entries),\n model: modelName(agent.model),\n messages: counted(view.entries),\n frozenAt: lastAt(view.entries),\n };\n}\n\nconst kindOf = (scoop: ScoopRecord): ConversationKind =>\n scoop.kind === 'sync' ? 'agent' : 'scoop';\n\nasync function rows(\n harness: Harness,\n state: Readonly<AgentsState>,\n cache: Map<number, Stats>,\n context: Context\n): Promise<FrozenCone[]> {\n const stats = async (conversation: number, stopped: boolean) => {\n const cached = stopped ? cache.get(conversation) : undefined;\n if (cached) return cached;\n const found = await statsOf(harness, conversation, context);\n if (stopped) cache.set(conversation, found);\n return found;\n };\n const out: FrozenCone[] = [];\n for (const [id, cone] of Object.entries(state.cones))\n out.push({\n id,\n name: cone.name,\n ...(await stats(cone.conversation, false)),\n kind: 'cone',\n live: true,\n thawedAs: null,\n });\n for (const [id, record] of Object.entries(state.frozen ?? {}))\n out.push({\n id,\n name: record.name,\n title: record.title,\n model: record.model,\n messages: record.messages,\n frozenAt: record.frozenAt,\n kind: 'cone',\n live: false,\n thawedAs: null,\n });\n for (const [id, scoop] of Object.entries(state.scoops)) {\n if (scoop.removed) continue;\n const running = live(scoop);\n out.push({\n id,\n name: scoop.name,\n ...(await stats(scoop.conversation, !running)),\n kind: kindOf(scoop),\n live: running,\n thawedAs: scoop.thawedAs ?? null,\n });\n }\n return out.sort((a, b) => Number(b.live) - Number(a.live) || b.frozenAt - a.frozenAt);\n}\n\nexport function thawedNote(\n kind: ConversationKind,\n name: string,\n folder: string,\n kept: boolean,\n home = HOME\n): string {\n const what = kind === 'agent' ? 'agent run' : kind;\n const place = kept\n ? `Its workspace ${folder} is still there.`\n : `Its workspace ${folder} was deleted when it stopped.`;\n return `This was ${what} ${name}'s conversation, thawed as a cone. ${place} You now work in ${home} as a cone, with a cone's tools.`;\n}\n\ntype Snapshot = { entries: readonly EntryRecord[]; record: Omit<FrozenRecord, 'scoops' | 'cone'> };\n\nasync function snapshot(\n conversation: Conversation,\n name: string,\n now: number,\n context: Context\n): Promise<Snapshot> {\n const view = await conversation.context(context);\n const agent = await conversation.agent(context);\n return {\n entries: view.entries,\n record: {\n name,\n conversation: conversation.id,\n title: firstLine(view.entries),\n model: modelName(agent.model),\n messages: counted(view.entries),\n frozenAt: now,\n },\n };\n}\n\nexport function frozenTarget(state: Readonly<AgentsState>, target: LickTarget): Frozen | undefined {\n const records = Object.entries(state.frozen ?? {});\n if (target.startsWith('cone:')) {\n const cone = target.slice('cone:'.length);\n if (state.cones[cone]) return undefined;\n const found = records\n .filter(([, record]) => record.cone === cone)\n .sort(([, a], [, b]) => b.frozenAt - a.frozenAt)[0];\n return found ? { id: found[0], name: found[1].name, at: found[1].frozenAt } : undefined;\n }\n const owner = state.scoops[target]?.frozen;\n const record = owner ? state.frozen?.[owner] : undefined;\n return owner && record ? { id: owner, name: record.name, at: record.frozenAt } : undefined;\n}\n\nasync function command(\n options: FreezerAttach,\n runtime: FreezerRuntime,\n argv: readonly string[],\n context: Context\n): Promise<Answer> {\n const verb = argv[0] ?? 'help';\n const listed = await runtime.refresh();\n if (verb === 'list') {\n const lines = listed.map(\n (item) =>\n `${item.id}\\t${item.kind}${item.live ? ' (live)' : ''}\\t${item.name}\\t${item.title}\\t${item.messages} messages\\t${new Date(item.frozenAt).toISOString()}`\n );\n return { code: 0, out: lines.length ? `${lines.join('\\n')}\\n` : 'no conversations\\n' };\n }\n if (verb !== 'show' && verb !== 'thaw')\n return { code: verb === 'help' || verb === '--help' ? 0 : 2, out: USAGE };\n const id = argv[1] ?? '';\n const item = listed.find((row) => row.id === id);\n if (!item) return { code: 1, out: `freezer: there is no conversation ${id}\\n` };\n if (verb === 'thaw') {\n if (item.live) return { code: 1, out: `freezer: ${item.name} is live; it needs no thawing\\n` };\n return { code: 0, out: `thawed ${id} as ${await runtime.thaw(id, context)}\\n` };\n }\n const state = options.agents.state();\n const conversationId =\n state.frozen?.[id]?.conversation ??\n state.cones[id]?.conversation ??\n state.scoops[id]?.conversation;\n const conversation = await options.harness.conversation(\n conversationId as ConversationId,\n context\n );\n const entries = conversation ? (await conversation.context(context)).entries : [];\n return { code: 0, out: markdown(item, entries) };\n}\n\nasync function freshLike(\n harness: Harness,\n conversation: Conversation,\n context: Context\n): Promise<Conversation> {\n const agent = await conversation.agent(context);\n return harness.createConversation(\n {\n ownership: { kind: 'ownerless' },\n agent: pinned({\n model: agent.model,\n thinkingLevel: agent.thinkingLevel,\n extensions: agent.extensions,\n tools: agent.tools,\n instructions: agent.instructions ?? null,\n cwd: agent.cwd ?? null,\n }),\n },\n context\n );\n}\n\nasync function activeCone(agents: Agents, context: Context): Promise<Conversation> {\n const conversation = await agents.conversation(agents.state().active, context);\n if (!conversation) throw new Error('There is no active cone.');\n return conversation;\n}\n\nasync function thawScoop(\n options: FreezerAttach & { now: () => number },\n id: string,\n scoop: ScoopRecord,\n context: Context\n): Promise<string> {\n const { harness, agents, env, now } = options;\n const layout = options.layout ?? LEGACY;\n if (scoop.removed) throw new Error(`There is no conversation ${id}.`);\n if (live(scoop)) throw new Error(`${scoop.name} is still running; open it instead.`);\n const conversation = await harness.conversation(scoop.conversation as ConversationId, context);\n if (!conversation) throw new Error(`There is no conversation ${id}.`);\n const last = (await conversation.context(context)).entries.at(-1);\n const agent = await conversation.agent(context);\n const cone = await (await activeCone(agents, context)).agent(context);\n const created = {\n ownership: { kind: 'ownerless' as const },\n agent: pinned({\n model: agent.model as NonNullable<typeof agent.model>,\n thinkingLevel: agent.thinkingLevel,\n extensions: cone.extensions,\n tools: cone.tools,\n instructions: cone.instructions ?? null,\n ...(layout.users ? {} : { cwd: HOME }),\n }),\n };\n const fork = last\n ? await conversation.fork(last.id, created, context)\n : await harness.createConversation(created, context);\n const folder = layout.workspace(scoop.folder);\n const exists = await env.exists(folder, context);\n const kept = exists.ok && exists.value;\n await fork.submit(\n {\n type: 'write',\n entry: {\n kind: THAWED_KIND,\n data: { scoop: id, name: scoop.name, kind: kindOf(scoop), workspace: folder, kept },\n model: [\n {\n role: 'user',\n content: thawedNote(\n kindOf(scoop),\n scoop.name,\n folder,\n kept,\n layout.users ? 'your own home' : HOME\n ),\n timestamp: now(),\n },\n ],\n },\n },\n context\n );\n const coneId = await agents.update((_tx, doc) => {\n const target = `cone-${doc.next}`;\n doc.next += 1;\n doc.cones[target] = { name: scoop.name, conversation: fork.id };\n (doc.scoops[id] as ScoopRecord).thawedAs = target;\n return target;\n }, context);\n await agents.selectCone(coneId, context);\n return coneId;\n}\n\nasync function removeScoop(\n options: FreezerAttach,\n id: string,\n scoop: ScoopRecord,\n context: Context\n): Promise<void> {\n const { agents, env } = options;\n if (live(scoop)) throw new Error(`${scoop.name} is still running; stop it first.`);\n await agents.update((_tx, doc) => {\n const entry = doc.scoops[id] as ScoopRecord;\n entry.removed = true;\n entry.gone = true;\n delete entry.frozen;\n }, context);\n await env.remove(\n (options.layout ?? LEGACY).scoopRoot(scoop.folder),\n {\n recursive: true,\n force: true,\n },\n context\n );\n}\n\nfunction listing(harness: Harness, agents: Agents) {\n const frozen = replicatedState<FrozenCone[]>([]);\n const cache = new Map<number, Stats>();\n let lock: Promise<readonly FrozenCone[]> = Promise.resolve([]);\n const refresh = () => {\n lock = lock\n .catch(() => [])\n .then(async () => {\n const listed = await rows(harness, agents.state(), cache, BACKGROUND_CONTEXT);\n frozen.replace(BACKGROUND_CONTEXT, listed);\n return listed;\n });\n return lock;\n };\n const quiet = () => void refresh().catch(() => undefined);\n quiet();\n const stop = agents.onChange(quiet);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const touch = () => {\n clearTimeout(timer);\n timer = setTimeout(quiet, TOUCH_MS);\n };\n const off = () => {\n clearTimeout(timer);\n stop();\n };\n return { frozen, refresh, touch, off };\n}\n\nasync function thawFrozen(agents: Agents, id: string, context: Context): Promise<string> {\n const coneId = await agents.update((_tx, doc) => {\n const record = doc.frozen?.[id];\n if (!record) throw new Error(`There is no frozen chat ${id}.`);\n const reuse = !doc.cones[record.cone];\n const target = reuse ? record.cone : `cone-${doc.next}`;\n if (!reuse) doc.next += 1;\n doc.cones[target] = { name: record.name, conversation: record.conversation };\n for (const scoop of record.scoops) {\n const entry = doc.scoops[scoop];\n if (!entry) continue;\n delete entry.frozen;\n entry.cone = target;\n }\n delete doc.frozen?.[id];\n return target;\n }, context);\n await agents.selectCone(coneId, context);\n return coneId;\n}\n\nasync function discardFrozen(options: FreezerAttach, id: string, context: Context) {\n const { agents, env } = options;\n const record = agents.state().frozen?.[id];\n if (!record) throw new Error(`There is no frozen chat ${id}.`);\n const folders = record.scoops\n .map((scoop) => agents.state().scoops[scoop]?.folder)\n .filter((folder): folder is string => Boolean(folder));\n await agents.update((_tx, doc) => {\n for (const scoop of record.scoops) {\n const entry = doc.scoops[scoop];\n if (!entry) continue;\n delete entry.frozen;\n entry.gone = true;\n }\n delete doc.frozen?.[id];\n }, context);\n for (const folder of folders)\n await env.remove(\n (options.layout ?? LEGACY).scoopRoot(folder),\n {\n recursive: true,\n force: true,\n },\n context\n );\n}\n\nexport function attachFreezer(options: FreezerAttach): FreezerRuntime {\n const { harness, agents } = options;\n const now = options.now ?? Date.now;\n const { frozen, refresh, touch, off } = listing(harness, agents);\n const conversationOf = async (agentId: string, context: Context) => {\n const conversation = await agents.conversation(agentId, context);\n if (!conversation) throw new Error(`There is no cone ${agentId}.`);\n return conversation;\n };\n const prepare = async (\n conversation: Conversation,\n entries: readonly EntryRecord[],\n cone: string,\n context: Context\n ) => {\n const tail = entries.at(-1)?.id ?? 0;\n await options.extract?.(conversation.id, tail, context, cone).catch(() => undefined);\n };\n const retitle = (\n id: string,\n model: string,\n entries: readonly EntryRecord[],\n context: Context\n ) => {\n if (!options.title) return;\n const transcript = entries\n .filter((entry) => entry.kind === 'pi.user' || entry.kind === 'pi.assistant')\n .map((entry) => `${entry.kind === 'pi.user' ? 'User' : 'Agent'}: ${textOf(entry)}`)\n .join('\\n')\n .slice(0, 4000);\n void options\n .title(transcript, model, context)\n .then(async (title) => {\n const clean = title\n ?.replace(/\\s+/g, ' ')\n .replace(/^[\"'\u201C\u201D]+|[\"'\u201C\u201D]+$/g, '')\n .replace(/\\.+$/, '')\n .trim();\n if (!clean) return;\n await agents.update((_tx, doc) => {\n const record = doc.frozen?.[id];\n if (record) record.title = clean.slice(0, TITLE_LENGTH);\n }, context);\n })\n .catch(() => undefined);\n };\n const replacement = async (coneId: string, context: Context) => {\n const state = agents.state();\n const other = Object.keys(state.cones).find((id) => id !== coneId);\n if (other) return { id: other, conversation: undefined };\n const current = await conversationOf(coneId, context);\n const conversation = await harness.createConversation(\n {\n ownership: { kind: 'ownerless' },\n agent: { model: (await current.agent(context)).model },\n },\n context\n );\n return { id: `cone-${state.next}`, conversation };\n };\n const runtime: FreezerRuntime = {\n frozen,\n async freeze(agentId, context) {\n const cone = agents.state().cones[agentId];\n if (!cone) throw new Error(`There is no cone ${agentId}.`);\n const conversation = await conversationOf(agentId, context);\n const { entries, record } = await snapshot(conversation, cone.name, now(), context);\n await prepare(conversation, entries, agentId, context);\n await conversation.abort(context, { background: true }).catch(() => undefined);\n const next =\n agents.state().active === agentId ? await replacement(agentId, context) : undefined;\n const { id, scoops } = await agents.update((_tx, doc) => {\n if (!doc.cones[agentId]) throw new Error(`There is no cone ${agentId}.`);\n const frozenId = `frozen-${doc.frozenNext ?? 1}`;\n const owned = Object.entries(doc.scoops)\n .filter(([, scoop]) => scoop.cone === agentId && live(scoop))\n .map(([scoop]) => scoop);\n doc.frozenNext = (doc.frozenNext ?? 1) + 1;\n doc.frozen ??= {};\n doc.frozen[frozenId] = { ...record, cone: agentId, scoops: owned };\n delete doc.cones[agentId];\n for (const scoop of owned) (doc.scoops[scoop] as { frozen?: string }).frozen = frozenId;\n if (next?.conversation) {\n doc.cones[next.id] = { name: record.name, conversation: next.conversation.id };\n doc.next += 1;\n }\n return { id: frozenId, scoops: owned };\n }, context);\n for (const scoop of scoops)\n await (await agents.conversation(scoop, context))?.abort(context).catch(() => undefined);\n if (next) await agents.selectCone(next.id, context);\n retitle(id, record.model, entries, context);\n return id;\n },\n async newChat(agentId, context) {\n const cone = agents.state().cones[agentId];\n const scoop = agents.state().scoops[agentId];\n if (!cone && scoop && live(scoop)) {\n await (await agents.conversation(agentId, context))?.reset(undefined, context);\n return null;\n }\n if (!cone) throw new Error(`There is no cone ${agentId}.`);\n const conversation = await conversationOf(agentId, context);\n const before = (await conversation.context(context)).entries;\n if (!before.some((entry) => entry.kind === 'pi.user')) return null;\n const fresh = await freshLike(harness, conversation, context);\n await agents.setConversation(agentId, fresh, context);\n await conversation.abort(context).catch(() => undefined);\n const { entries, record } = await snapshot(conversation, cone.name, now(), context);\n await prepare(conversation, entries, agentId, context);\n const id = await agents.update((_tx, doc) => {\n const frozenId = `frozen-${doc.frozenNext ?? 1}`;\n doc.frozenNext = (doc.frozenNext ?? 1) + 1;\n doc.frozen ??= {};\n doc.frozen[frozenId] = { ...record, cone: agentId, scoops: [] };\n return frozenId;\n }, context);\n retitle(id, record.model, entries, context);\n return id;\n },\n async thaw(id, context) {\n const state = agents.state();\n if (state.cones[id]) {\n await agents.selectCone(id, context);\n return id;\n }\n const scoop = state.scoops[id];\n if (scoop) return thawScoop({ ...options, now }, id, scoop, context);\n return thawFrozen(agents, id, context);\n },\n async discard(id, context) {\n const state = agents.state();\n const scoop = state.scoops[id];\n if (scoop) return removeScoop(options, id, scoop, context);\n const cone = state.cones[id];\n if (cone) throw new Error(`${cone.name} is live; delete the cone first.`);\n return discardFrozen(options, id, context);\n },\n refresh,\n touch,\n frozenTarget: (target) => frozenTarget(agents.state(), target),\n command: (argv, _caller, context) => command(options, runtime, argv, context),\n close: () => off(),\n };\n return runtime;\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import { type Context, type ReplicatedState, replicatedState } from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type {\n Conversation,\n ConversationId,\n EntryRecord,\n Harness,\n} from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { answerText } from '../agent.ts';\nimport {\n type Agents,\n type AgentsState,\n type ConeRecord,\n type FrozenRecord,\n live,\n type ScoopRecord,\n} from '../agents.ts';\nimport { HOME } from '../kernel/env.ts';\nimport { type Layout, LEGACY } from '../layout.ts';\nimport type { LickTarget } from '../licks/lick.ts';\nimport { redactSecrets } from '../memory/format.ts';\nimport { pinned } from '../secrets/extension.ts';\nimport { scrubText } from '../secrets/scrub.ts';\n\nexport type Answer = { code: number; out: string };\n\nexport type ConversationKind = 'cone' | 'scoop' | 'agent';\n\nexport interface FrozenCone {\n id: string;\n name: string;\n title: string;\n model: string;\n messages: number;\n frozenAt: number;\n kind: ConversationKind;\n live: boolean;\n thawedAs: string | null;\n}\n\nexport const THAWED_KIND = 'slicc.thawed';\n\nexport type Frozen = { id: string; name: string; at: number };\n\nexport interface FreezerAttach {\n harness: Harness;\n agents: Agents;\n env: Pick<ExecutionEnv, 'remove' | 'exists'>;\n title?: (transcript: string, model: string, context: Context) => Promise<string | undefined>;\n extract?: (\n conversation: number,\n tail: number,\n context: Context,\n cone: string\n ) => Promise<unknown>;\n now?: () => number;\n layout?: Layout;\n}\n\nexport interface FreezerRuntime {\n readonly frozen: ReplicatedState<FrozenCone[]>;\n freeze(agentId: string, context: Context): Promise<string>;\n newChat(agentId: string, context: Context): Promise<string | null>;\n thaw(id: string, context: Context): Promise<string>;\n discard(id: string, context: Context): Promise<void>;\n refresh(): Promise<readonly FrozenCone[]>;\n touch(): void;\n frozenTarget(target: LickTarget): Frozen | undefined;\n command(argv: readonly string[], caller: string | null, context: Context): Promise<Answer>;\n close(): void;\n}\n\nexport const USAGE = `usage:\n freezer list every conversation: id, kind, name, title, messages, when\n freezer show <id> a conversation as Markdown\n freezer thaw <id> continue a stopped conversation as a cone\n\nDelete a cone, or start a new conversation, from the chat toolbar or the command palette.\n`;\n\nconst TITLE_LENGTH = 60;\nconst TITLE_WORDS = 6;\nexport const TITLE_TURNS = [1, 3];\nconst TRIVIAL_WORDS = 4;\nconst TRANSCRIPT_LENGTH = 4000;\nexport const TOUCH_MS = 500;\n\nfunction textOf(entry: EntryRecord): string {\n return answerText(entry.model?.[0]?.content).trim();\n}\n\nexport function modelName(model: { provider: string; modelId: string } | undefined): string {\n return model ? `${model.provider}/${model.modelId}` : '';\n}\n\nexport function firstLine(entries: readonly EntryRecord[]): string {\n const first = entries.find((entry) => entry.kind === 'pi.user' && textOf(entry));\n const line = first ? (textOf(first).split('\\n')[0] as string).trim() : '';\n if (!line) return 'Untitled chat';\n return line.length > TITLE_LENGTH ? `${line.slice(0, TITLE_LENGTH - 1)}\u2026` : line;\n}\n\nfunction calls(entry: EntryRecord): string[] {\n const content = entry.model?.[0]?.content;\n if (!Array.isArray(content)) return [];\n return (content as { type: string; name?: string; arguments?: unknown }[])\n .filter((part) => part.type === 'toolCall')\n .map((part) => `- \\`${part.name}\\` ${JSON.stringify(part.arguments ?? {})}`);\n}\n\nexport function markdown(\n record: Pick<FrozenRecord, 'title' | 'name' | 'model' | 'frozenAt'>,\n entries: readonly EntryRecord[]\n): string {\n const out = [\n `# ${record.title}`,\n '',\n `${record.name} \u00B7 ${record.model} \u00B7 ${new Date(record.frozenAt).toISOString()}`,\n ];\n for (const entry of entries) {\n if (entry.kind === 'pi.user' && textOf(entry)) out.push('', '## User', '', textOf(entry));\n if (entry.kind !== 'pi.assistant') continue;\n const text = textOf(entry);\n const tools = calls(entry);\n if (!text && !tools.length) continue;\n out.push('', '## Assistant', '');\n if (text) out.push(text);\n if (tools.length) out.push(...(text ? [''] : []), ...tools);\n }\n return `${out.join('\\n')}\\n`;\n}\n\ntype Stats = Pick<FrozenCone, 'title' | 'model' | 'messages' | 'frozenAt'>;\n\nfunction counted(entries: readonly EntryRecord[]): number {\n return entries.filter((entry) => entry.kind === 'pi.user' || entry.kind === 'pi.assistant')\n .length;\n}\n\nfunction lastAt(entries: readonly EntryRecord[]): number {\n let at = 0;\n for (const entry of entries)\n for (const message of entry.model ?? []) {\n const stamp = (message as { timestamp?: unknown }).timestamp;\n if (typeof stamp === 'number' && stamp > at) at = stamp;\n }\n return at;\n}\n\ntype Inspected = { stats: Stats; entries: readonly EntryRecord[] };\n\nasync function inspect(harness: Harness, id: number, context: Context): Promise<Inspected> {\n const conversation = await harness.conversation(id as ConversationId, context);\n if (!conversation)\n return { stats: { title: firstLine([]), model: '', messages: 0, frozenAt: 0 }, entries: [] };\n const view = await conversation.context(context);\n const agent = await conversation.agent(context);\n return {\n stats: {\n title: firstLine(view.entries),\n model: modelName(agent.model),\n messages: counted(view.entries),\n frozenAt: lastAt(view.entries),\n },\n entries: view.entries,\n };\n}\n\nexport function trivial(text: string): boolean {\n const words = text\n .split(/\\s+/)\n .map((word) => word.replace(/\\p{P}|\\p{S}|\\u200d|\\ufe0f/gu, ''))\n .filter(Boolean);\n return (\n words.length < TRIVIAL_WORDS && !(words.length === 1 && [...(words[0] as string)].length >= 8)\n );\n}\n\nexport function titleDue(\n record: Pick<ConeRecord, 'titled'>,\n entries: readonly EntryRecord[],\n final = false\n): number | undefined {\n const last = entries.at(-1);\n const stop = (last?.model?.[0] as { stopReason?: unknown } | undefined)?.stopReason;\n if (last?.kind !== 'pi.assistant' || stop !== 'stop') return undefined;\n const said = entries.filter((entry) => entry.kind === 'pi.user' && textOf(entry));\n const greeting = !final && trivial(textOf(said[0] ?? ({} as EntryRecord)));\n const next = TITLE_TURNS.find((turn) => turn > (record.titled ?? 0) && !(greeting && turn === 1));\n return next !== undefined && said.length >= next ? said.length : undefined;\n}\n\nexport function cleanTitle(title: string | undefined): string | undefined {\n const clean = title\n ?.replace(/\\s+/g, ' ')\n .trim()\n .replace(/^[\"'\u201C\u201D]+|[\"'\u201C\u201D]+$/g, '')\n .replace(/\\.+$/, '')\n .trim()\n .split(' ')\n .slice(0, TITLE_WORDS)\n .join(' ');\n return clean ? clean.slice(0, TITLE_LENGTH) : undefined;\n}\n\nfunction transcriptOf(entries: readonly EntryRecord[]): string {\n return entries\n .filter((entry) => entry.kind === 'pi.user' || entry.kind === 'pi.assistant')\n .map((entry) => `${entry.kind === 'pi.user' ? 'User' : 'Agent'}: ${textOf(entry)}`)\n .join('\\n');\n}\n\ntype Titled = Pick<ConeRecord, 'conversation' | 'title' | 'titled'>;\n\ntype Seen = (\n id: string,\n record: Titled,\n entries: readonly EntryRecord[],\n model: string,\n final?: boolean\n) => void;\n\nconst kindOf = (scoop: ScoopRecord): ConversationKind =>\n scoop.kind === 'sync' ? 'agent' : 'scoop';\n\nasync function rows(\n harness: Harness,\n state: Readonly<AgentsState>,\n cache: Map<number, Stats>,\n context: Context,\n seen?: Seen\n): Promise<FrozenCone[]> {\n const stopped = async (conversation: number) => {\n const cached = cache.get(conversation);\n if (cached) return cached;\n const found = (await inspect(harness, conversation, context)).stats;\n cache.set(conversation, found);\n return found;\n };\n const ended = async (id: string, record: Titled) => {\n const stats = await stopped(record.conversation);\n if (seen && (record.titled ?? 0) < (TITLE_TURNS.at(-1) as number)) {\n const { entries } = await inspect(harness, record.conversation, context);\n seen(id, record, entries, stats.model, true);\n }\n return { ...stats, ...(record.title ? { title: record.title } : {}) };\n };\n const running = async (id: string, record: Titled) => {\n const { stats, entries } = await inspect(harness, record.conversation, context);\n seen?.(id, record, entries, stats.model);\n return { ...stats, ...(record.title ? { title: record.title } : {}) };\n };\n const out: FrozenCone[] = [];\n for (const [id, cone] of Object.entries(state.cones))\n out.push({\n id,\n name: cone.name,\n ...(await running(id, cone)),\n kind: 'cone',\n live: true,\n thawedAs: null,\n });\n for (const [id, record] of Object.entries(state.frozen ?? {}))\n out.push({\n id,\n name: record.name,\n title: record.title,\n model: record.model,\n messages: record.messages,\n frozenAt: record.frozenAt,\n kind: 'cone',\n live: false,\n thawedAs: null,\n });\n for (const [id, scoop] of Object.entries(state.scoops)) {\n if (scoop.removed) continue;\n const on = live(scoop);\n out.push({\n id,\n name: scoop.name,\n ...(on ? await running(id, scoop) : await ended(id, scoop)),\n kind: kindOf(scoop),\n live: on,\n thawedAs: scoop.thawedAs ?? null,\n });\n }\n return out.sort((a, b) => Number(b.live) - Number(a.live) || b.frozenAt - a.frozenAt);\n}\n\nexport function thawedNote(\n kind: ConversationKind,\n name: string,\n folder: string,\n kept: boolean,\n home = HOME\n): string {\n const what = kind === 'agent' ? 'agent run' : kind;\n const place = kept\n ? `Its workspace ${folder} is still there.`\n : `Its workspace ${folder} was deleted when it stopped.`;\n return `This was ${what} ${name}'s conversation, thawed as a cone. ${place} You now work in ${home} as a cone, with a cone's tools.`;\n}\n\ntype Snapshot = { entries: readonly EntryRecord[]; record: Omit<FrozenRecord, 'scoops' | 'cone'> };\n\nasync function snapshot(\n conversation: Conversation,\n name: string,\n now: number,\n context: Context,\n title?: string\n): Promise<Snapshot> {\n const view = await conversation.context(context);\n const agent = await conversation.agent(context);\n return {\n entries: view.entries,\n record: {\n name,\n conversation: conversation.id,\n title: title ?? firstLine(view.entries),\n model: modelName(agent.model),\n messages: counted(view.entries),\n frozenAt: now,\n },\n };\n}\n\nexport function frozenTarget(state: Readonly<AgentsState>, target: LickTarget): Frozen | undefined {\n const records = Object.entries(state.frozen ?? {});\n if (target.startsWith('cone:')) {\n const cone = target.slice('cone:'.length);\n if (state.cones[cone]) return undefined;\n const found = records\n .filter(([, record]) => record.cone === cone)\n .sort(([, a], [, b]) => b.frozenAt - a.frozenAt)[0];\n return found ? { id: found[0], name: found[1].name, at: found[1].frozenAt } : undefined;\n }\n const owner = state.scoops[target]?.frozen;\n const record = owner ? state.frozen?.[owner] : undefined;\n return owner && record ? { id: owner, name: record.name, at: record.frozenAt } : undefined;\n}\n\nasync function command(\n options: FreezerAttach,\n runtime: FreezerRuntime,\n argv: readonly string[],\n context: Context\n): Promise<Answer> {\n const verb = argv[0] ?? 'help';\n const listed = await runtime.refresh();\n if (verb === 'list') {\n const lines = listed.map(\n (item) =>\n `${item.id}\\t${item.kind}${item.live ? ' (live)' : ''}\\t${item.name}\\t${item.title}\\t${item.messages} messages\\t${new Date(item.frozenAt).toISOString()}`\n );\n return { code: 0, out: lines.length ? `${lines.join('\\n')}\\n` : 'no conversations\\n' };\n }\n if (verb !== 'show' && verb !== 'thaw')\n return { code: verb === 'help' || verb === '--help' ? 0 : 2, out: USAGE };\n const id = argv[1] ?? '';\n const item = listed.find((row) => row.id === id);\n if (!item) return { code: 1, out: `freezer: there is no conversation ${id}\\n` };\n if (verb === 'thaw') {\n if (item.live) return { code: 1, out: `freezer: ${item.name} is live; it needs no thawing\\n` };\n return { code: 0, out: `thawed ${id} as ${await runtime.thaw(id, context)}\\n` };\n }\n const state = options.agents.state();\n const conversationId =\n state.frozen?.[id]?.conversation ??\n state.cones[id]?.conversation ??\n state.scoops[id]?.conversation;\n const conversation = await options.harness.conversation(\n conversationId as ConversationId,\n context\n );\n const entries = conversation ? (await conversation.context(context)).entries : [];\n return { code: 0, out: markdown(item, entries) };\n}\n\nasync function freshLike(\n harness: Harness,\n conversation: Conversation,\n context: Context\n): Promise<Conversation> {\n const agent = await conversation.agent(context);\n return harness.createConversation(\n {\n ownership: { kind: 'ownerless' },\n agent: pinned({\n model: agent.model,\n thinkingLevel: agent.thinkingLevel,\n extensions: agent.extensions,\n tools: agent.tools,\n instructions: agent.instructions ?? null,\n cwd: agent.cwd ?? null,\n }),\n },\n context\n );\n}\n\nasync function activeCone(agents: Agents, context: Context): Promise<Conversation> {\n const conversation = await agents.conversation(agents.state().active, context);\n if (!conversation) throw new Error('There is no active cone.');\n return conversation;\n}\n\nasync function thawScoop(\n options: FreezerAttach & { now: () => number },\n id: string,\n scoop: ScoopRecord,\n context: Context\n): Promise<string> {\n const { harness, agents, env, now } = options;\n const layout = options.layout ?? LEGACY;\n if (scoop.removed) throw new Error(`There is no conversation ${id}.`);\n if (live(scoop)) throw new Error(`${scoop.name} is still running; open it instead.`);\n const conversation = await harness.conversation(scoop.conversation as ConversationId, context);\n if (!conversation) throw new Error(`There is no conversation ${id}.`);\n const last = (await conversation.context(context)).entries.at(-1);\n const agent = await conversation.agent(context);\n const cone = await (await activeCone(agents, context)).agent(context);\n const created = {\n ownership: { kind: 'ownerless' as const },\n agent: pinned({\n model: agent.model as NonNullable<typeof agent.model>,\n thinkingLevel: agent.thinkingLevel,\n extensions: cone.extensions,\n tools: cone.tools,\n instructions: cone.instructions ?? null,\n ...(layout.users ? {} : { cwd: HOME }),\n }),\n };\n const fork = last\n ? await conversation.fork(last.id, created, context)\n : await harness.createConversation(created, context);\n const folder = layout.workspace(scoop.folder);\n const exists = await env.exists(folder, context);\n const kept = exists.ok && exists.value;\n await fork.submit(\n {\n type: 'write',\n entry: {\n kind: THAWED_KIND,\n data: { scoop: id, name: scoop.name, kind: kindOf(scoop), workspace: folder, kept },\n model: [\n {\n role: 'user',\n content: thawedNote(\n kindOf(scoop),\n scoop.name,\n folder,\n kept,\n layout.users ? 'your own home' : HOME\n ),\n timestamp: now(),\n },\n ],\n },\n },\n context\n );\n const coneId = await agents.update((_tx, doc) => {\n const target = `cone-${doc.next}`;\n doc.next += 1;\n doc.cones[target] = {\n name: scoop.name,\n conversation: fork.id,\n ...(scoop.title ? { title: scoop.title, titled: scoop.titled as number } : {}),\n };\n (doc.scoops[id] as ScoopRecord).thawedAs = target;\n return target;\n }, context);\n await agents.selectCone(coneId, context);\n return coneId;\n}\n\nasync function removeScoop(\n options: FreezerAttach,\n id: string,\n scoop: ScoopRecord,\n context: Context\n): Promise<void> {\n const { agents, env } = options;\n if (live(scoop)) throw new Error(`${scoop.name} is still running; stop it first.`);\n await agents.update((_tx, doc) => {\n const entry = doc.scoops[id] as ScoopRecord;\n entry.removed = true;\n entry.gone = true;\n delete entry.frozen;\n }, context);\n await env.remove(\n (options.layout ?? LEGACY).scoopRoot(scoop.folder),\n {\n recursive: true,\n force: true,\n },\n context\n );\n}\n\nfunction listing(harness: Harness, agents: Agents, seen: Seen | undefined) {\n const frozen = replicatedState<FrozenCone[]>([]);\n const cache = new Map<number, Stats>();\n let lock: Promise<readonly FrozenCone[]> = Promise.resolve([]);\n const refresh = () => {\n lock = lock\n .catch(() => [])\n .then(async () => {\n const listed = await rows(harness, agents.state(), cache, BACKGROUND_CONTEXT, seen);\n frozen.replace(BACKGROUND_CONTEXT, listed);\n return listed;\n });\n return lock;\n };\n const quiet = () => void refresh().catch(() => undefined);\n quiet();\n const stop = agents.onChange(quiet);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const touch = () => {\n clearTimeout(timer);\n timer = setTimeout(quiet, TOUCH_MS);\n };\n const off = () => {\n clearTimeout(timer);\n stop();\n };\n return { frozen, refresh, touch, off };\n}\n\nasync function thawFrozen(agents: Agents, id: string, context: Context): Promise<string> {\n const coneId = await agents.update((_tx, doc) => {\n const record = doc.frozen?.[id];\n if (!record) throw new Error(`There is no frozen chat ${id}.`);\n const reuse = !doc.cones[record.cone];\n const target = reuse ? record.cone : `cone-${doc.next}`;\n if (!reuse) doc.next += 1;\n doc.cones[target] = {\n name: record.name,\n conversation: record.conversation,\n title: record.title,\n titled: TITLE_TURNS.at(-1) as number,\n };\n for (const scoop of record.scoops) {\n const entry = doc.scoops[scoop];\n if (!entry) continue;\n delete entry.frozen;\n entry.cone = target;\n }\n delete doc.frozen?.[id];\n return target;\n }, context);\n await agents.selectCone(coneId, context);\n return coneId;\n}\n\nasync function discardFrozen(options: FreezerAttach, id: string, context: Context) {\n const { agents, env } = options;\n const record = agents.state().frozen?.[id];\n if (!record) throw new Error(`There is no frozen chat ${id}.`);\n const folders = record.scoops\n .map((scoop) => agents.state().scoops[scoop]?.folder)\n .filter((folder): folder is string => Boolean(folder));\n await agents.update((_tx, doc) => {\n for (const scoop of record.scoops) {\n const entry = doc.scoops[scoop];\n if (!entry) continue;\n delete entry.frozen;\n entry.gone = true;\n }\n delete doc.frozen?.[id];\n }, context);\n for (const folder of folders)\n await env.remove(\n (options.layout ?? LEGACY).scoopRoot(folder),\n {\n recursive: true,\n force: true,\n },\n context\n );\n}\n\nfunction titling(options: FreezerAttach) {\n const { agents } = options;\n const pending = new Map<string, { token: symbol; conversation: number }>();\n const named = (entries: readonly EntryRecord[], model: string, context: Context) =>\n scrubText(redactSecrets(transcriptOf(entries)).text)\n .then((transcript) =>\n (options.title as NonNullable<FreezerAttach['title']>)(\n transcript.slice(0, TRANSCRIPT_LENGTH),\n model,\n context\n )\n )\n .then(cleanTitle)\n .catch(() => undefined);\n const write = (id: string, titled: Titled, turns: number, title: string | undefined) =>\n agents.update((_tx, doc) => {\n const record = doc.cones[id] ?? doc.scoops[id];\n if (record?.conversation !== titled.conversation) return;\n record.titled = turns;\n if (title) record.title = title;\n }, BACKGROUND_CONTEXT);\n const seen: Seen = (id, seenAs, entries, model, final) => {\n const state = agents.state();\n const titled = state.cones[id] ?? state.scoops[id];\n if (titled?.conversation !== seenAs.conversation) return;\n if (pending.get(id)?.conversation === titled.conversation) return;\n const turns = titleDue(titled, entries, final);\n const last = TITLE_TURNS.at(-1) as number;\n if (turns === undefined) {\n if (final) void write(id, titled, last, undefined).catch(() => undefined);\n return;\n }\n const token = Symbol(id);\n pending.set(id, { token, conversation: titled.conversation });\n void named(entries, model, BACKGROUND_CONTEXT)\n .then((title) =>\n pending.get(id)?.token === token\n ? write(id, titled, final ? last : turns, title)\n : undefined\n )\n .catch(() => undefined)\n .finally(() => {\n if (pending.get(id)?.token === token) pending.delete(id);\n });\n };\n return { pending, named, seen };\n}\n\nexport function attachFreezer(options: FreezerAttach): FreezerRuntime {\n const { harness, agents } = options;\n const now = options.now ?? Date.now;\n const { pending, named, seen } = titling(options);\n const { frozen, refresh, touch, off } = listing(\n harness,\n agents,\n options.title ? seen : undefined\n );\n const conversationOf = async (agentId: string, context: Context) => {\n const conversation = await agents.conversation(agentId, context);\n if (!conversation) throw new Error(`There is no cone ${agentId}.`);\n return conversation;\n };\n const prepare = async (\n conversation: Conversation,\n entries: readonly EntryRecord[],\n cone: string,\n context: Context\n ) => {\n const tail = entries.at(-1)?.id ?? 0;\n await options.extract?.(conversation.id, tail, context, cone).catch(() => undefined);\n };\n const retitle = (\n id: string,\n model: string,\n entries: readonly EntryRecord[],\n context: Context\n ) => {\n if (!options.title) return;\n void named(entries, model, context)\n .then(async (title) => {\n if (!title) return;\n await agents.update((_tx, doc) => {\n const record = doc.frozen?.[id];\n if (record) record.title = title;\n }, context);\n })\n .catch(() => undefined);\n };\n const replacement = async (coneId: string, context: Context) => {\n const state = agents.state();\n const other = Object.keys(state.cones).find((id) => id !== coneId);\n if (other) return { id: other, conversation: undefined };\n const current = await conversationOf(coneId, context);\n const conversation = await harness.createConversation(\n {\n ownership: { kind: 'ownerless' },\n agent: { model: (await current.agent(context)).model },\n },\n context\n );\n return { id: `cone-${state.next}`, conversation };\n };\n const runtime: FreezerRuntime = {\n frozen,\n async freeze(agentId, context) {\n const cone = agents.state().cones[agentId];\n if (!cone) throw new Error(`There is no cone ${agentId}.`);\n const conversation = await conversationOf(agentId, context);\n const { entries, record } = await snapshot(\n conversation,\n cone.name,\n now(),\n context,\n cone.title\n );\n await prepare(conversation, entries, agentId, context);\n await conversation.abort(context, { background: true }).catch(() => undefined);\n const next =\n agents.state().active === agentId ? await replacement(agentId, context) : undefined;\n const { id, scoops } = await agents.update((_tx, doc) => {\n if (!doc.cones[agentId]) throw new Error(`There is no cone ${agentId}.`);\n const frozenId = `frozen-${doc.frozenNext ?? 1}`;\n const owned = Object.entries(doc.scoops)\n .filter(([, scoop]) => scoop.cone === agentId && live(scoop))\n .map(([scoop]) => scoop);\n doc.frozenNext = (doc.frozenNext ?? 1) + 1;\n doc.frozen ??= {};\n doc.frozen[frozenId] = { ...record, cone: agentId, scoops: owned };\n delete doc.cones[agentId];\n for (const scoop of owned) (doc.scoops[scoop] as { frozen?: string }).frozen = frozenId;\n if (next?.conversation) {\n doc.cones[next.id] = { name: record.name, conversation: next.conversation.id };\n doc.next += 1;\n }\n return { id: frozenId, scoops: owned };\n }, context);\n for (const scoop of scoops)\n await (await agents.conversation(scoop, context))?.abort(context).catch(() => undefined);\n if (next) await agents.selectCone(next.id, context);\n retitle(id, record.model, entries, context);\n return id;\n },\n async newChat(agentId, context) {\n const cone = agents.state().cones[agentId];\n const scoop = agents.state().scoops[agentId];\n if (!cone && scoop && live(scoop)) {\n pending.delete(agentId);\n await (await agents.conversation(agentId, context))?.reset(undefined, context);\n await agents.update((_tx, doc) => {\n const record = doc.scoops[agentId] as ScoopRecord;\n delete record.title;\n delete record.titled;\n }, context);\n return null;\n }\n if (!cone) throw new Error(`There is no cone ${agentId}.`);\n const conversation = await conversationOf(agentId, context);\n const before = (await conversation.context(context)).entries;\n const title = cone.title;\n if (!before.some((entry) => entry.kind === 'pi.user')) return null;\n const fresh = await freshLike(harness, conversation, context);\n await agents.setConversation(agentId, fresh, context);\n await conversation.abort(context).catch(() => undefined);\n const { entries, record } = await snapshot(conversation, cone.name, now(), context, title);\n await prepare(conversation, entries, agentId, context);\n const id = await agents.update((_tx, doc) => {\n const frozenId = `frozen-${doc.frozenNext ?? 1}`;\n doc.frozenNext = (doc.frozenNext ?? 1) + 1;\n doc.frozen ??= {};\n doc.frozen[frozenId] = { ...record, cone: agentId, scoops: [] };\n return frozenId;\n }, context);\n retitle(id, record.model, entries, context);\n return id;\n },\n async thaw(id, context) {\n const state = agents.state();\n if (state.cones[id]) {\n await agents.selectCone(id, context);\n return id;\n }\n const scoop = state.scoops[id];\n if (scoop) return thawScoop({ ...options, now }, id, scoop, context);\n return thawFrozen(agents, id, context);\n },\n async discard(id, context) {\n const state = agents.state();\n const scoop = state.scoops[id];\n if (scoop) return removeScoop(options, id, scoop, context);\n const cone = state.cones[id];\n if (cone) throw new Error(`${cone.name} is live; delete the cone first.`);\n return discardFrozen(options, id, context);\n },\n refresh,\n touch,\n frozenTarget: (target) => frozenTarget(agents.state(), target),\n command: (argv, _caller, context) => command(options, runtime, argv, context),\n close: () => off(),\n };\n return runtime;\n}\n"],
5
+ "mappings": "AAAA,SAA6C,uBAAuB;AACpE,SAAS,0BAA0B;AAQnC,SAAS,kBAAkB;AAC3B;AAAA,EAKE;AAAA,OAEK;AACP,SAAS,YAAY;AACrB,SAAsB,cAAc;AAEpC,SAAS,qBAAqB;AAC9B,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAkBnB,MAAM,cAAc;AAgCpB,MAAM,QAAQ;AAAA;AAAA;AAAA;AAAA;AAAA;AAAA;AAQrB,MAAM,eAAe;AACrB,MAAM,cAAc;AACb,MAAM,cAAc,CAAC,GAAG,CAAC;AAChC,MAAM,gBAAgB;AACtB,MAAM,oBAAoB;AACnB,MAAM,WAAW;AAExB,SAAS,OAAO,OAA4B;AAC1C,SAAO,WAAW,MAAM,QAAQ,CAAC,GAAG,OAAO,EAAE,KAAK;AACpD;AAEO,SAAS,UAAU,OAAkE;AAC1F,SAAO,QAAQ,GAAG,MAAM,QAAQ,IAAI,MAAM,OAAO,KAAK;AACxD;AAEO,SAAS,UAAU,SAAyC;AACjE,QAAM,QAAQ,QAAQ,KAAK,CAAC,UAAU,MAAM,SAAS,aAAa,OAAO,KAAK,CAAC;AAC/E,QAAM,OAAO,QAAS,OAAO,KAAK,EAAE,MAAM,IAAI,EAAE,CAAC,EAAa,KAAK,IAAI;AACvE,MAAI,CAAC,KAAM,QAAO;AAClB,SAAO,KAAK,SAAS,eAAe,GAAG,KAAK,MAAM,GAAG,eAAe,CAAC,CAAC,WAAM;AAC9E;AAEA,SAAS,MAAM,OAA8B;AAC3C,QAAM,UAAU,MAAM,QAAQ,CAAC,GAAG;AAClC,MAAI,CAAC,MAAM,QAAQ,OAAO,EAAG,QAAO,CAAC;AACrC,SAAQ,QACL,OAAO,CAAC,SAAS,KAAK,SAAS,UAAU,EACzC,IAAI,CAAC,SAAS,OAAO,KAAK,IAAI,MAAM,KAAK,UAAU,KAAK,aAAa,CAAC,CAAC,CAAC,EAAE;AAC/E;AAEO,SAAS,SACd,QACA,SACQ;AACR,QAAM,MAAM;AAAA,IACV,KAAK,OAAO,KAAK;AAAA,IACjB;AAAA,IACA,GAAG,OAAO,IAAI,SAAM,OAAO,KAAK,SAAM,IAAI,KAAK,OAAO,QAAQ,EAAE,YAAY,CAAC;AAAA,EAC/E;AACA,aAAW,SAAS,SAAS;AAC3B,QAAI,MAAM,SAAS,aAAa,OAAO,KAAK,EAAG,KAAI,KAAK,IAAI,WAAW,IAAI,OAAO,KAAK,CAAC;AACxF,QAAI,MAAM,SAAS,eAAgB;AACnC,UAAM,OAAO,OAAO,KAAK;AACzB,UAAM,QAAQ,MAAM,KAAK;AACzB,QAAI,CAAC,QAAQ,CAAC,MAAM,OAAQ;AAC5B,QAAI,KAAK,IAAI,gBAAgB,EAAE;AAC/B,QAAI,KAAM,KAAI,KAAK,IAAI;AACvB,QAAI,MAAM,OAAQ,KAAI,KAAK,GAAI,OAAO,CAAC,EAAE,IAAI,CAAC,GAAI,GAAG,KAAK;AAAA,EAC5D;AACA,SAAO,GAAG,IAAI,KAAK,IAAI,CAAC;AAAA;AAC1B;AAIA,SAAS,QAAQ,SAAyC;AACxD,SAAO,QAAQ,OAAO,CAAC,UAAU,MAAM,SAAS,aAAa,MAAM,SAAS,cAAc,EACvF;AACL;AAEA,SAAS,OAAO,SAAyC;AACvD,MAAI,KAAK;AACT,aAAW,SAAS;AAClB,eAAW,WAAW,MAAM,SAAS,CAAC,GAAG;AACvC,YAAM,QAAS,QAAoC;AACnD,UAAI,OAAO,UAAU,YAAY,QAAQ,GAAI,MAAK;AAAA,IACpD;AACF,SAAO;AACT;AAIA,eAAe,QAAQ,SAAkB,IAAY,SAAsC;AACzF,QAAM,eAAe,MAAM,QAAQ,aAAa,IAAsB,OAAO;AAC7E,MAAI,CAAC;AACH,WAAO,EAAE,OAAO,EAAE,OAAO,UAAU,CAAC,CAAC,GAAG,OAAO,IAAI,UAAU,GAAG,UAAU,EAAE,GAAG,SAAS,CAAC,EAAE;AAC7F,QAAM,OAAO,MAAM,aAAa,QAAQ,OAAO;AAC/C,QAAM,QAAQ,MAAM,aAAa,MAAM,OAAO;AAC9C,SAAO;AAAA,IACL,OAAO;AAAA,MACL,OAAO,UAAU,KAAK,OAAO;AAAA,MAC7B,OAAO,UAAU,MAAM,KAAK;AAAA,MAC5B,UAAU,QAAQ,KAAK,OAAO;AAAA,MAC9B,UAAU,OAAO,KAAK,OAAO;AAAA,IAC/B;AAAA,IACA,SAAS,KAAK;AAAA,EAChB;AACF;AAEO,SAAS,QAAQ,MAAuB;AAC7C,QAAM,QAAQ,KACX,MAAM,KAAK,EACX,IAAI,CAAC,SAAS,KAAK,QAAQ,+BAA+B,EAAE,CAAC,EAC7D,OAAO,OAAO;AACjB,SACE,MAAM,SAAS,iBAAiB,EAAE,MAAM,WAAW,KAAK,CAAC,GAAI,MAAM,CAAC,CAAY,EAAE,UAAU;AAEhG;AAEO,SAAS,SACd,QACA,SACA,QAAQ,OACY;AACpB,QAAM,OAAO,QAAQ,GAAG,EAAE;AAC1B,QAAM,OAAQ,MAAM,QAAQ,CAAC,GAA4C;AACzE,MAAI,MAAM,SAAS,kBAAkB,SAAS,OAAQ,QAAO;AAC7D,QAAM,OAAO,QAAQ,OAAO,CAAC,UAAU,MAAM,SAAS,aAAa,OAAO,KAAK,CAAC;AAChF,QAAM,WAAW,CAAC,SAAS,QAAQ,OAAO,KAAK,CAAC,KAAM,CAAC,CAAiB,CAAC;AACzE,QAAM,OAAO,YAAY,KAAK,CAAC,SAAS,QAAQ,OAAO,UAAU,MAAM,EAAE,YAAY,SAAS,EAAE;AAChG,SAAO,SAAS,UAAa,KAAK,UAAU,OAAO,KAAK,SAAS;AACnE;AAEO,SAAS,WAAW,OAA+C;AACxE,QAAM,QAAQ,OACV,QAAQ,QAAQ,GAAG,EACpB,KAAK,EACL,QAAQ,sBAAsB,EAAE,EAChC,QAAQ,QAAQ,EAAE,EAClB,KAAK,EACL,MAAM,GAAG,EACT,MAAM,GAAG,WAAW,EACpB,KAAK,GAAG;AACX,SAAO,QAAQ,MAAM,MAAM,GAAG,YAAY,IAAI;AAChD;AAEA,SAAS,aAAa,SAAyC;AAC7D,SAAO,QACJ,OAAO,CAAC,UAAU,MAAM,SAAS,aAAa,MAAM,SAAS,cAAc,EAC3E,IAAI,CAAC,UAAU,GAAG,MAAM,SAAS,YAAY,SAAS,OAAO,KAAK,OAAO,KAAK,CAAC,EAAE,EACjF,KAAK,IAAI;AACd;AAYA,MAAM,SAAS,CAAC,UACd,MAAM,SAAS,SAAS,UAAU;AAEpC,eAAe,KACb,SACA,OACA,OACA,SACA,MACuB;AACvB,QAAM,UAAU,OAAO,iBAAyB;AAC9C,UAAM,SAAS,MAAM,IAAI,YAAY;AACrC,QAAI,OAAQ,QAAO;AACnB,UAAM,SAAS,MAAM,QAAQ,SAAS,cAAc,OAAO,GAAG;AAC9D,UAAM,IAAI,cAAc,KAAK;AAC7B,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,OAAO,IAAY,WAAmB;AAClD,UAAM,QAAQ,MAAM,QAAQ,OAAO,YAAY;AAC/C,QAAI,SAAS,OAAO,UAAU,KAAM,YAAY,GAAG,EAAE,GAAc;AACjE,YAAM,EAAE,QAAQ,IAAI,MAAM,QAAQ,SAAS,OAAO,cAAc,OAAO;AACvE,WAAK,IAAI,QAAQ,SAAS,MAAM,OAAO,IAAI;AAAA,IAC7C;AACA,WAAO,EAAE,GAAG,OAAO,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC,EAAG;AAAA,EACtE;AACA,QAAM,UAAU,OAAO,IAAY,WAAmB;AACpD,UAAM,EAAE,OAAO,QAAQ,IAAI,MAAM,QAAQ,SAAS,OAAO,cAAc,OAAO;AAC9E,WAAO,IAAI,QAAQ,SAAS,MAAM,KAAK;AACvC,WAAO,EAAE,GAAG,OAAO,GAAI,OAAO,QAAQ,EAAE,OAAO,OAAO,MAAM,IAAI,CAAC,EAAG;AAAA,EACtE;AACA,QAAM,MAAoB,CAAC;AAC3B,aAAW,CAAC,IAAI,IAAI,KAAK,OAAO,QAAQ,MAAM,KAAK;AACjD,QAAI,KAAK;AAAA,MACP;AAAA,MACA,MAAM,KAAK;AAAA,MACX,GAAI,MAAM,QAAQ,IAAI,IAAI;AAAA,MAC1B,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,IACZ,CAAC;AACH,aAAW,CAAC,IAAI,MAAM,KAAK,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC;AAC1D,QAAI,KAAK;AAAA,MACP;AAAA,MACA,MAAM,OAAO;AAAA,MACb,OAAO,OAAO;AAAA,MACd,OAAO,OAAO;AAAA,MACd,UAAU,OAAO;AAAA,MACjB,UAAU,OAAO;AAAA,MACjB,MAAM;AAAA,MACN,MAAM;AAAA,MACN,UAAU;AAAA,IACZ,CAAC;AACH,aAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,MAAM,MAAM,GAAG;AACtD,QAAI,MAAM,QAAS;AACnB,UAAM,KAAK,KAAK,KAAK;AACrB,QAAI,KAAK;AAAA,MACP;AAAA,MACA,MAAM,MAAM;AAAA,MACZ,GAAI,KAAK,MAAM,QAAQ,IAAI,KAAK,IAAI,MAAM,MAAM,IAAI,KAAK;AAAA,MACzD,MAAM,OAAO,KAAK;AAAA,MAClB,MAAM;AAAA,MACN,UAAU,MAAM,YAAY;AAAA,IAC9B,CAAC;AAAA,EACH;AACA,SAAO,IAAI,KAAK,CAAC,GAAG,MAAM,OAAO,EAAE,IAAI,IAAI,OAAO,EAAE,IAAI,KAAK,EAAE,WAAW,EAAE,QAAQ;AACtF;AAEO,SAAS,WACd,MACA,MACA,QACA,MACA,OAAO,MACC;AACR,QAAM,OAAO,SAAS,UAAU,cAAc;AAC9C,QAAM,QAAQ,OACV,iBAAiB,MAAM,qBACvB,iBAAiB,MAAM;AAC3B,SAAO,YAAY,IAAI,IAAI,IAAI,sCAAsC,KAAK,oBAAoB,IAAI;AACpG;AAIA,eAAe,SACb,cACA,MACA,KACA,SACA,OACmB;AACnB,QAAM,OAAO,MAAM,aAAa,QAAQ,OAAO;AAC/C,QAAM,QAAQ,MAAM,aAAa,MAAM,OAAO;AAC9C,SAAO;AAAA,IACL,SAAS,KAAK;AAAA,IACd,QAAQ;AAAA,MACN;AAAA,MACA,cAAc,aAAa;AAAA,MAC3B,OAAO,SAAS,UAAU,KAAK,OAAO;AAAA,MACtC,OAAO,UAAU,MAAM,KAAK;AAAA,MAC5B,UAAU,QAAQ,KAAK,OAAO;AAAA,MAC9B,UAAU;AAAA,IACZ;AAAA,EACF;AACF;AAEO,SAAS,aAAa,OAA8B,QAAwC;AACjG,QAAM,UAAU,OAAO,QAAQ,MAAM,UAAU,CAAC,CAAC;AACjD,MAAI,OAAO,WAAW,OAAO,GAAG;AAC9B,UAAM,OAAO,OAAO,MAAM,QAAQ,MAAM;AACxC,QAAI,MAAM,MAAM,IAAI,EAAG,QAAO;AAC9B,UAAM,QAAQ,QACX,OAAO,CAAC,CAAC,EAAEA,OAAM,MAAMA,QAAO,SAAS,IAAI,EAC3C,KAAK,CAAC,CAAC,EAAE,CAAC,GAAG,CAAC,EAAE,CAAC,MAAM,EAAE,WAAW,EAAE,QAAQ,EAAE,CAAC;AACpD,WAAO,QAAQ,EAAE,IAAI,MAAM,CAAC,GAAG,MAAM,MAAM,CAAC,EAAE,MAAM,IAAI,MAAM,CAAC,EAAE,SAAS,IAAI;AAAA,EAChF;AACA,QAAM,QAAQ,MAAM,OAAO,MAAM,GAAG;AACpC,QAAM,SAAS,QAAQ,MAAM,SAAS,KAAK,IAAI;AAC/C,SAAO,SAAS,SAAS,EAAE,IAAI,OAAO,MAAM,OAAO,MAAM,IAAI,OAAO,SAAS,IAAI;AACnF;AAEA,eAAe,QACb,SACA,SACA,MACA,SACiB;AACjB,QAAM,OAAO,KAAK,CAAC,KAAK;AACxB,QAAM,SAAS,MAAM,QAAQ,QAAQ;AACrC,MAAI,SAAS,QAAQ;AACnB,UAAM,QAAQ,OAAO;AAAA,MACnB,CAACC,UACC,GAAGA,MAAK,EAAE,IAAKA,MAAK,IAAI,GAAGA,MAAK,OAAO,YAAY,EAAE,IAAKA,MAAK,IAAI,IAAKA,MAAK,KAAK,IAAKA,MAAK,QAAQ,aAAc,IAAI,KAAKA,MAAK,QAAQ,EAAE,YAAY,CAAC;AAAA,IAC3J;AACA,WAAO,EAAE,MAAM,GAAG,KAAK,MAAM,SAAS,GAAG,MAAM,KAAK,IAAI,CAAC;AAAA,IAAO,qBAAqB;AAAA,EACvF;AACA,MAAI,SAAS,UAAU,SAAS;AAC9B,WAAO,EAAE,MAAM,SAAS,UAAU,SAAS,WAAW,IAAI,GAAG,KAAK,MAAM;AAC1E,QAAM,KAAK,KAAK,CAAC,KAAK;AACtB,QAAM,OAAO,OAAO,KAAK,CAAC,QAAQ,IAAI,OAAO,EAAE;AAC/C,MAAI,CAAC,KAAM,QAAO,EAAE,MAAM,GAAG,KAAK,qCAAqC,EAAE;AAAA,EAAK;AAC9E,MAAI,SAAS,QAAQ;AACnB,QAAI,KAAK,KAAM,QAAO,EAAE,MAAM,GAAG,KAAK,YAAY,KAAK,IAAI;AAAA,EAAkC;AAC7F,WAAO,EAAE,MAAM,GAAG,KAAK,UAAU,EAAE,OAAO,MAAM,QAAQ,KAAK,IAAI,OAAO,CAAC;AAAA,EAAK;AAAA,EAChF;AACA,QAAM,QAAQ,QAAQ,OAAO,MAAM;AACnC,QAAM,iBACJ,MAAM,SAAS,EAAE,GAAG,gBACpB,MAAM,MAAM,EAAE,GAAG,gBACjB,MAAM,OAAO,EAAE,GAAG;AACpB,QAAM,eAAe,MAAM,QAAQ,QAAQ;AAAA,IACzC;AAAA,IACA;AAAA,EACF;AACA,QAAM,UAAU,gBAAgB,MAAM,aAAa,QAAQ,OAAO,GAAG,UAAU,CAAC;AAChF,SAAO,EAAE,MAAM,GAAG,KAAK,SAAS,MAAM,OAAO,EAAE;AACjD;AAEA,eAAe,UACb,SACA,cACA,SACuB;AACvB,QAAM,QAAQ,MAAM,aAAa,MAAM,OAAO;AAC9C,SAAO,QAAQ;AAAA,IACb;AAAA,MACE,WAAW,EAAE,MAAM,YAAY;AAAA,MAC/B,OAAO,OAAO;AAAA,QACZ,OAAO,MAAM;AAAA,QACb,eAAe,MAAM;AAAA,QACrB,YAAY,MAAM;AAAA,QAClB,OAAO,MAAM;AAAA,QACb,cAAc,MAAM,gBAAgB;AAAA,QACpC,KAAK,MAAM,OAAO;AAAA,MACpB,CAAC;AAAA,IACH;AAAA,IACA;AAAA,EACF;AACF;AAEA,eAAe,WAAW,QAAgB,SAAyC;AACjF,QAAM,eAAe,MAAM,OAAO,aAAa,OAAO,MAAM,EAAE,QAAQ,OAAO;AAC7E,MAAI,CAAC,aAAc,OAAM,IAAI,MAAM,0BAA0B;AAC7D,SAAO;AACT;AAEA,eAAe,UACb,SACA,IACA,OACA,SACiB;AACjB,QAAM,EAAE,SAAS,QAAQ,KAAK,IAAI,IAAI;AACtC,QAAM,SAAS,QAAQ,UAAU;AACjC,MAAI,MAAM,QAAS,OAAM,IAAI,MAAM,4BAA4B,EAAE,GAAG;AACpE,MAAI,KAAK,KAAK,EAAG,OAAM,IAAI,MAAM,GAAG,MAAM,IAAI,qCAAqC;AACnF,QAAM,eAAe,MAAM,QAAQ,aAAa,MAAM,cAAgC,OAAO;AAC7F,MAAI,CAAC,aAAc,OAAM,IAAI,MAAM,4BAA4B,EAAE,GAAG;AACpE,QAAM,QAAQ,MAAM,aAAa,QAAQ,OAAO,GAAG,QAAQ,GAAG,EAAE;AAChE,QAAM,QAAQ,MAAM,aAAa,MAAM,OAAO;AAC9C,QAAM,OAAO,OAAO,MAAM,WAAW,QAAQ,OAAO,GAAG,MAAM,OAAO;AACpE,QAAM,UAAU;AAAA,IACd,WAAW,EAAE,MAAM,YAAqB;AAAA,IACxC,OAAO,OAAO;AAAA,MACZ,OAAO,MAAM;AAAA,MACb,eAAe,MAAM;AAAA,MACrB,YAAY,KAAK;AAAA,MACjB,OAAO,KAAK;AAAA,MACZ,cAAc,KAAK,gBAAgB;AAAA,MACnC,GAAI,OAAO,QAAQ,CAAC,IAAI,EAAE,KAAK,KAAK;AAAA,IACtC,CAAC;AAAA,EACH;AACA,QAAM,OAAO,OACT,MAAM,aAAa,KAAK,KAAK,IAAI,SAAS,OAAO,IACjD,MAAM,QAAQ,mBAAmB,SAAS,OAAO;AACrD,QAAM,SAAS,OAAO,UAAU,MAAM,MAAM;AAC5C,QAAM,SAAS,MAAM,IAAI,OAAO,QAAQ,OAAO;AAC/C,QAAM,OAAO,OAAO,MAAM,OAAO;AACjC,QAAM,KAAK;AAAA,IACT;AAAA,MACE,MAAM;AAAA,MACN,OAAO;AAAA,QACL,MAAM;AAAA,QACN,MAAM,EAAE,OAAO,IAAI,MAAM,MAAM,MAAM,MAAM,OAAO,KAAK,GAAG,WAAW,QAAQ,KAAK;AAAA,QAClF,OAAO;AAAA,UACL;AAAA,YACE,MAAM;AAAA,YACN,SAAS;AAAA,cACP,OAAO,KAAK;AAAA,cACZ,MAAM;AAAA,cACN;AAAA,cACA;AAAA,cACA,OAAO,QAAQ,kBAAkB;AAAA,YACnC;AAAA,YACA,WAAW,IAAI;AAAA,UACjB;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAAA,IACA;AAAA,EACF;AACA,QAAM,SAAS,MAAM,OAAO,OAAO,CAAC,KAAK,QAAQ;AAC/C,UAAM,SAAS,QAAQ,IAAI,IAAI;AAC/B,QAAI,QAAQ;AACZ,QAAI,MAAM,MAAM,IAAI;AAAA,MAClB,MAAM,MAAM;AAAA,MACZ,cAAc,KAAK;AAAA,MACnB,GAAI,MAAM,QAAQ,EAAE,OAAO,MAAM,OAAO,QAAQ,MAAM,OAAiB,IAAI,CAAC;AAAA,IAC9E;AACA,IAAC,IAAI,OAAO,EAAE,EAAkB,WAAW;AAC3C,WAAO;AAAA,EACT,GAAG,OAAO;AACV,QAAM,OAAO,WAAW,QAAQ,OAAO;AACvC,SAAO;AACT;AAEA,eAAe,YACb,SACA,IACA,OACA,SACe;AACf,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,MAAI,KAAK,KAAK,EAAG,OAAM,IAAI,MAAM,GAAG,MAAM,IAAI,mCAAmC;AACjF,QAAM,OAAO,OAAO,CAAC,KAAK,QAAQ;AAChC,UAAM,QAAQ,IAAI,OAAO,EAAE;AAC3B,UAAM,UAAU;AAChB,UAAM,OAAO;AACb,WAAO,MAAM;AAAA,EACf,GAAG,OAAO;AACV,QAAM,IAAI;AAAA,KACP,QAAQ,UAAU,QAAQ,UAAU,MAAM,MAAM;AAAA,IACjD;AAAA,MACE,WAAW;AAAA,MACX,OAAO;AAAA,IACT;AAAA,IACA;AAAA,EACF;AACF;AAEA,SAAS,QAAQ,SAAkB,QAAgB,MAAwB;AACzE,QAAM,SAAS,gBAA8B,CAAC,CAAC;AAC/C,QAAM,QAAQ,oBAAI,IAAmB;AACrC,MAAI,OAAuC,QAAQ,QAAQ,CAAC,CAAC;AAC7D,QAAM,UAAU,MAAM;AACpB,WAAO,KACJ,MAAM,MAAM,CAAC,CAAC,EACd,KAAK,YAAY;AAChB,YAAM,SAAS,MAAM,KAAK,SAAS,OAAO,MAAM,GAAG,OAAO,oBAAoB,IAAI;AAClF,aAAO,QAAQ,oBAAoB,MAAM;AACzC,aAAO;AAAA,IACT,CAAC;AACH,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,MAAM,KAAK,QAAQ,EAAE,MAAM,MAAM,MAAS;AACxD,QAAM;AACN,QAAM,OAAO,OAAO,SAAS,KAAK;AAClC,MAAI;AACJ,QAAM,QAAQ,MAAM;AAClB,iBAAa,KAAK;AAClB,YAAQ,WAAW,OAAO,QAAQ;AAAA,EACpC;AACA,QAAM,MAAM,MAAM;AAChB,iBAAa,KAAK;AAClB,SAAK;AAAA,EACP;AACA,SAAO,EAAE,QAAQ,SAAS,OAAO,IAAI;AACvC;AAEA,eAAe,WAAW,QAAgB,IAAY,SAAmC;AACvF,QAAM,SAAS,MAAM,OAAO,OAAO,CAAC,KAAK,QAAQ;AAC/C,UAAM,SAAS,IAAI,SAAS,EAAE;AAC9B,QAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,2BAA2B,EAAE,GAAG;AAC7D,UAAM,QAAQ,CAAC,IAAI,MAAM,OAAO,IAAI;AACpC,UAAM,SAAS,QAAQ,OAAO,OAAO,QAAQ,IAAI,IAAI;AACrD,QAAI,CAAC,MAAO,KAAI,QAAQ;AACxB,QAAI,MAAM,MAAM,IAAI;AAAA,MAClB,MAAM,OAAO;AAAA,MACb,cAAc,OAAO;AAAA,MACrB,OAAO,OAAO;AAAA,MACd,QAAQ,YAAY,GAAG,EAAE;AAAA,IAC3B;AACA,eAAW,SAAS,OAAO,QAAQ;AACjC,YAAM,QAAQ,IAAI,OAAO,KAAK;AAC9B,UAAI,CAAC,MAAO;AACZ,aAAO,MAAM;AACb,YAAM,OAAO;AAAA,IACf;AACA,WAAO,IAAI,SAAS,EAAE;AACtB,WAAO;AAAA,EACT,GAAG,OAAO;AACV,QAAM,OAAO,WAAW,QAAQ,OAAO;AACvC,SAAO;AACT;AAEA,eAAe,cAAc,SAAwB,IAAY,SAAkB;AACjF,QAAM,EAAE,QAAQ,IAAI,IAAI;AACxB,QAAM,SAAS,OAAO,MAAM,EAAE,SAAS,EAAE;AACzC,MAAI,CAAC,OAAQ,OAAM,IAAI,MAAM,2BAA2B,EAAE,GAAG;AAC7D,QAAM,UAAU,OAAO,OACpB,IAAI,CAAC,UAAU,OAAO,MAAM,EAAE,OAAO,KAAK,GAAG,MAAM,EACnD,OAAO,CAAC,WAA6B,QAAQ,MAAM,CAAC;AACvD,QAAM,OAAO,OAAO,CAAC,KAAK,QAAQ;AAChC,eAAW,SAAS,OAAO,QAAQ;AACjC,YAAM,QAAQ,IAAI,OAAO,KAAK;AAC9B,UAAI,CAAC,MAAO;AACZ,aAAO,MAAM;AACb,YAAM,OAAO;AAAA,IACf;AACA,WAAO,IAAI,SAAS,EAAE;AAAA,EACxB,GAAG,OAAO;AACV,aAAW,UAAU;AACnB,UAAM,IAAI;AAAA,OACP,QAAQ,UAAU,QAAQ,UAAU,MAAM;AAAA,MAC3C;AAAA,QACE,WAAW;AAAA,QACX,OAAO;AAAA,MACT;AAAA,MACA;AAAA,IACF;AACJ;AAEA,SAAS,QAAQ,SAAwB;AACvC,QAAM,EAAE,OAAO,IAAI;AACnB,QAAM,UAAU,oBAAI,IAAqD;AACzE,QAAM,QAAQ,CAAC,SAAiC,OAAe,YAC7D,UAAU,cAAc,aAAa,OAAO,CAAC,EAAE,IAAI,EAChD;AAAA,IAAK,CAAC,eACJ,QAAQ;AAAA,MACP,WAAW,MAAM,GAAG,iBAAiB;AAAA,MACrC;AAAA,MACA;AAAA,IACF;AAAA,EACF,EACC,KAAK,UAAU,EACf,MAAM,MAAM,MAAS;AAC1B,QAAM,QAAQ,CAAC,IAAY,QAAgB,OAAe,UACxD,OAAO,OAAO,CAAC,KAAK,QAAQ;AAC1B,UAAM,SAAS,IAAI,MAAM,EAAE,KAAK,IAAI,OAAO,EAAE;AAC7C,QAAI,QAAQ,iBAAiB,OAAO,aAAc;AAClD,WAAO,SAAS;AAChB,QAAI,MAAO,QAAO,QAAQ;AAAA,EAC5B,GAAG,kBAAkB;AACvB,QAAM,OAAa,CAAC,IAAI,QAAQ,SAAS,OAAO,UAAU;AACxD,UAAM,QAAQ,OAAO,MAAM;AAC3B,UAAM,SAAS,MAAM,MAAM,EAAE,KAAK,MAAM,OAAO,EAAE;AACjD,QAAI,QAAQ,iBAAiB,OAAO,aAAc;AAClD,QAAI,QAAQ,IAAI,EAAE,GAAG,iBAAiB,OAAO,aAAc;AAC3D,UAAM,QAAQ,SAAS,QAAQ,SAAS,KAAK;AAC7C,UAAM,OAAO,YAAY,GAAG,EAAE;AAC9B,QAAI,UAAU,QAAW;AACvB,UAAI,MAAO,MAAK,MAAM,IAAI,QAAQ,MAAM,MAAS,EAAE,MAAM,MAAM,MAAS;AACxE;AAAA,IACF;AACA,UAAM,QAAQ,OAAO,EAAE;AACvB,YAAQ,IAAI,IAAI,EAAE,OAAO,cAAc,OAAO,aAAa,CAAC;AAC5D,SAAK,MAAM,SAAS,OAAO,kBAAkB,EAC1C;AAAA,MAAK,CAAC,UACL,QAAQ,IAAI,EAAE,GAAG,UAAU,QACvB,MAAM,IAAI,QAAQ,QAAQ,OAAO,OAAO,KAAK,IAC7C;AAAA,IACN,EACC,MAAM,MAAM,MAAS,EACrB,QAAQ,MAAM;AACb,UAAI,QAAQ,IAAI,EAAE,GAAG,UAAU,MAAO,SAAQ,OAAO,EAAE;AAAA,IACzD,CAAC;AAAA,EACL;AACA,SAAO,EAAE,SAAS,OAAO,KAAK;AAChC;AAEO,SAAS,cAAc,SAAwC;AACpE,QAAM,EAAE,SAAS,OAAO,IAAI;AAC5B,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,EAAE,SAAS,OAAO,KAAK,IAAI,QAAQ,OAAO;AAChD,QAAM,EAAE,QAAQ,SAAS,OAAO,IAAI,IAAI;AAAA,IACtC;AAAA,IACA;AAAA,IACA,QAAQ,QAAQ,OAAO;AAAA,EACzB;AACA,QAAM,iBAAiB,OAAO,SAAiB,YAAqB;AAClE,UAAM,eAAe,MAAM,OAAO,aAAa,SAAS,OAAO;AAC/D,QAAI,CAAC,aAAc,OAAM,IAAI,MAAM,oBAAoB,OAAO,GAAG;AACjE,WAAO;AAAA,EACT;AACA,QAAM,UAAU,OACd,cACA,SACA,MACA,YACG;AACH,UAAM,OAAO,QAAQ,GAAG,EAAE,GAAG,MAAM;AACnC,UAAM,QAAQ,UAAU,aAAa,IAAI,MAAM,SAAS,IAAI,EAAE,MAAM,MAAM,MAAS;AAAA,EACrF;AACA,QAAM,UAAU,CACd,IACA,OACA,SACA,YACG;AACH,QAAI,CAAC,QAAQ,MAAO;AACpB,SAAK,MAAM,SAAS,OAAO,OAAO,EAC/B,KAAK,OAAO,UAAU;AACrB,UAAI,CAAC,MAAO;AACZ,YAAM,OAAO,OAAO,CAAC,KAAK,QAAQ;AAChC,cAAM,SAAS,IAAI,SAAS,EAAE;AAC9B,YAAI,OAAQ,QAAO,QAAQ;AAAA,MAC7B,GAAG,OAAO;AAAA,IACZ,CAAC,EACA,MAAM,MAAM,MAAS;AAAA,EAC1B;AACA,QAAM,cAAc,OAAO,QAAgB,YAAqB;AAC9D,UAAM,QAAQ,OAAO,MAAM;AAC3B,UAAM,QAAQ,OAAO,KAAK,MAAM,KAAK,EAAE,KAAK,CAAC,OAAO,OAAO,MAAM;AACjE,QAAI,MAAO,QAAO,EAAE,IAAI,OAAO,cAAc,OAAU;AACvD,UAAM,UAAU,MAAM,eAAe,QAAQ,OAAO;AACpD,UAAM,eAAe,MAAM,QAAQ;AAAA,MACjC;AAAA,QACE,WAAW,EAAE,MAAM,YAAY;AAAA,QAC/B,OAAO,EAAE,QAAQ,MAAM,QAAQ,MAAM,OAAO,GAAG,MAAM;AAAA,MACvD;AAAA,MACA;AAAA,IACF;AACA,WAAO,EAAE,IAAI,QAAQ,MAAM,IAAI,IAAI,aAAa;AAAA,EAClD;AACA,QAAM,UAA0B;AAAA,IAC9B;AAAA,IACA,MAAM,OAAO,SAAS,SAAS;AAC7B,YAAM,OAAO,OAAO,MAAM,EAAE,MAAM,OAAO;AACzC,UAAI,CAAC,KAAM,OAAM,IAAI,MAAM,oBAAoB,OAAO,GAAG;AACzD,YAAM,eAAe,MAAM,eAAe,SAAS,OAAO;AAC1D,YAAM,EAAE,SAAS,OAAO,IAAI,MAAM;AAAA,QAChC;AAAA,QACA,KAAK;AAAA,QACL,IAAI;AAAA,QACJ;AAAA,QACA,KAAK;AAAA,MACP;AACA,YAAM,QAAQ,cAAc,SAAS,SAAS,OAAO;AACrD,YAAM,aAAa,MAAM,SAAS,EAAE,YAAY,KAAK,CAAC,EAAE,MAAM,MAAM,MAAS;AAC7E,YAAM,OACJ,OAAO,MAAM,EAAE,WAAW,UAAU,MAAM,YAAY,SAAS,OAAO,IAAI;AAC5E,YAAM,EAAE,IAAI,OAAO,IAAI,MAAM,OAAO,OAAO,CAAC,KAAK,QAAQ;AACvD,YAAI,CAAC,IAAI,MAAM,OAAO,EAAG,OAAM,IAAI,MAAM,oBAAoB,OAAO,GAAG;AACvE,cAAM,WAAW,UAAU,IAAI,cAAc,CAAC;AAC9C,cAAM,QAAQ,OAAO,QAAQ,IAAI,MAAM,EACpC,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,MAAM,SAAS,WAAW,KAAK,KAAK,CAAC,EAC3D,IAAI,CAAC,CAAC,KAAK,MAAM,KAAK;AACzB,YAAI,cAAc,IAAI,cAAc,KAAK;AACzC,YAAI,WAAW,CAAC;AAChB,YAAI,OAAO,QAAQ,IAAI,EAAE,GAAG,QAAQ,MAAM,SAAS,QAAQ,MAAM;AACjE,eAAO,IAAI,MAAM,OAAO;AACxB,mBAAW,SAAS,MAAO,CAAC,IAAI,OAAO,KAAK,EAA0B,SAAS;AAC/E,YAAI,MAAM,cAAc;AACtB,cAAI,MAAM,KAAK,EAAE,IAAI,EAAE,MAAM,OAAO,MAAM,cAAc,KAAK,aAAa,GAAG;AAC7E,cAAI,QAAQ;AAAA,QACd;AACA,eAAO,EAAE,IAAI,UAAU,QAAQ,MAAM;AAAA,MACvC,GAAG,OAAO;AACV,iBAAW,SAAS;AAClB,eAAO,MAAM,OAAO,aAAa,OAAO,OAAO,IAAI,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AACzF,UAAI,KAAM,OAAM,OAAO,WAAW,KAAK,IAAI,OAAO;AAClD,cAAQ,IAAI,OAAO,OAAO,SAAS,OAAO;AAC1C,aAAO;AAAA,IACT;AAAA,IACA,MAAM,QAAQ,SAAS,SAAS;AAC9B,YAAM,OAAO,OAAO,MAAM,EAAE,MAAM,OAAO;AACzC,YAAM,QAAQ,OAAO,MAAM,EAAE,OAAO,OAAO;AAC3C,UAAI,CAAC,QAAQ,SAAS,KAAK,KAAK,GAAG;AACjC,gBAAQ,OAAO,OAAO;AACtB,eAAO,MAAM,OAAO,aAAa,SAAS,OAAO,IAAI,MAAM,QAAW,OAAO;AAC7E,cAAM,OAAO,OAAO,CAAC,KAAK,QAAQ;AAChC,gBAAMD,UAAS,IAAI,OAAO,OAAO;AACjC,iBAAOA,QAAO;AACd,iBAAOA,QAAO;AAAA,QAChB,GAAG,OAAO;AACV,eAAO;AAAA,MACT;AACA,UAAI,CAAC,KAAM,OAAM,IAAI,MAAM,oBAAoB,OAAO,GAAG;AACzD,YAAM,eAAe,MAAM,eAAe,SAAS,OAAO;AAC1D,YAAM,UAAU,MAAM,aAAa,QAAQ,OAAO,GAAG;AACrD,YAAM,QAAQ,KAAK;AACnB,UAAI,CAAC,OAAO,KAAK,CAAC,UAAU,MAAM,SAAS,SAAS,EAAG,QAAO;AAC9D,YAAM,QAAQ,MAAM,UAAU,SAAS,cAAc,OAAO;AAC5D,YAAM,OAAO,gBAAgB,SAAS,OAAO,OAAO;AACpD,YAAM,aAAa,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AACvD,YAAM,EAAE,SAAS,OAAO,IAAI,MAAM,SAAS,cAAc,KAAK,MAAM,IAAI,GAAG,SAAS,KAAK;AACzF,YAAM,QAAQ,cAAc,SAAS,SAAS,OAAO;AACrD,YAAM,KAAK,MAAM,OAAO,OAAO,CAAC,KAAK,QAAQ;AAC3C,cAAM,WAAW,UAAU,IAAI,cAAc,CAAC;AAC9C,YAAI,cAAc,IAAI,cAAc,KAAK;AACzC,YAAI,WAAW,CAAC;AAChB,YAAI,OAAO,QAAQ,IAAI,EAAE,GAAG,QAAQ,MAAM,SAAS,QAAQ,CAAC,EAAE;AAC9D,eAAO;AAAA,MACT,GAAG,OAAO;AACV,cAAQ,IAAI,OAAO,OAAO,SAAS,OAAO;AAC1C,aAAO;AAAA,IACT;AAAA,IACA,MAAM,KAAK,IAAI,SAAS;AACtB,YAAM,QAAQ,OAAO,MAAM;AAC3B,UAAI,MAAM,MAAM,EAAE,GAAG;AACnB,cAAM,OAAO,WAAW,IAAI,OAAO;AACnC,eAAO;AAAA,MACT;AACA,YAAM,QAAQ,MAAM,OAAO,EAAE;AAC7B,UAAI,MAAO,QAAO,UAAU,EAAE,GAAG,SAAS,IAAI,GAAG,IAAI,OAAO,OAAO;AACnE,aAAO,WAAW,QAAQ,IAAI,OAAO;AAAA,IACvC;AAAA,IACA,MAAM,QAAQ,IAAI,SAAS;AACzB,YAAM,QAAQ,OAAO,MAAM;AAC3B,YAAM,QAAQ,MAAM,OAAO,EAAE;AAC7B,UAAI,MAAO,QAAO,YAAY,SAAS,IAAI,OAAO,OAAO;AACzD,YAAM,OAAO,MAAM,MAAM,EAAE;AAC3B,UAAI,KAAM,OAAM,IAAI,MAAM,GAAG,KAAK,IAAI,kCAAkC;AACxE,aAAO,cAAc,SAAS,IAAI,OAAO;AAAA,IAC3C;AAAA,IACA;AAAA,IACA;AAAA,IACA,cAAc,CAAC,WAAW,aAAa,OAAO,MAAM,GAAG,MAAM;AAAA,IAC7D,SAAS,CAAC,MAAM,SAAS,YAAY,QAAQ,SAAS,SAAS,MAAM,OAAO;AAAA,IAC5E,OAAO,MAAM,IAAI;AAAA,EACnB;AACA,SAAO;AACT;",
6
6
  "names": ["record", "item"]
7
7
  }
@@ -1,5 +1,12 @@
1
1
  import { extractSettings } from "../memory/extract.js";
2
- const TITLE_PROMPT = "Give this chat a title of three to six words that says what it was about. Answer with the title only, without quotes.";
2
+ const TITLE_PROMPT = "Give this chat a title of three to six words that says what it is about, in the language the user writes in. Answer with the title only, without quotes.";
3
+ function titlesOn(text) {
4
+ try {
5
+ return JSON.parse(text ?? "{}").titles !== false;
6
+ } catch {
7
+ return true;
8
+ }
9
+ }
3
10
  function settingsText(env, home, dir = `${home}/.pi/agent`) {
4
11
  return async (context) => {
5
12
  const read = await env.readTextFile(`${dir}/settings.json`, context);
@@ -8,7 +15,9 @@ function settingsText(env, home, dir = `${home}/.pi/agent`) {
8
15
  }
9
16
  function titler(models, settings) {
10
17
  return async (transcript, model, context) => {
11
- const chosen = extractSettings(await settings(context)).model;
18
+ const text = await settings(context);
19
+ if (!titlesOn(text)) return void 0;
20
+ const chosen = extractSettings(text).model;
12
21
  const [provider, ...rest] = model.split("/");
13
22
  const ref = chosen ?? (provider && rest.length ? { provider, modelId: rest.join("/") } : null);
14
23
  const found = ref ? models.getModel(ref.provider, ref.modelId) : void 0;
@@ -35,6 +44,7 @@ ${transcript}` }],
35
44
  export {
36
45
  TITLE_PROMPT,
37
46
  settingsText,
38
- titler
47
+ titler,
48
+ titlesOn
39
49
  };
40
50
  //# sourceMappingURL=title.js.map
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/freezer/title.ts"],
4
- "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Message } from '@earendil-works/pi-ai';\nimport type { Models } from '@earendil-works/pi-ai/models';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { extractSettings } from '../memory/extract.ts';\n\nexport const TITLE_PROMPT =\n 'Give this chat a title of three to six words that says what it was about. Answer with the title only, without quotes.';\n\nexport function settingsText(\n env: Pick<ExecutionEnv, 'readTextFile'>,\n home: string,\n dir = `${home}/.pi/agent`\n): (context: Context) => Promise<string | undefined> {\n return async (context) => {\n const read = await env.readTextFile(`${dir}/settings.json`, context);\n return read.ok ? read.value : undefined;\n };\n}\n\nexport function titler(\n models: Models,\n settings: (context: Context) => Promise<string | undefined>\n) {\n return async (\n transcript: string,\n model: string,\n context: Context\n ): Promise<string | undefined> => {\n const chosen = extractSettings(await settings(context)).model;\n const [provider, ...rest] = model.split('/');\n const ref = chosen ?? (provider && rest.length ? { provider, modelId: rest.join('/') } : null);\n const found = ref ? models.getModel(ref.provider, ref.modelId) : undefined;\n if (!found || !transcript) return undefined;\n const message = await models.completeSimple(\n found,\n {\n messages: [\n {\n role: 'user',\n content: [{ type: 'text', text: `${TITLE_PROMPT}\\n\\n${transcript}` }],\n timestamp: Date.now(),\n } as Message,\n ],\n },\n { maxTokens: 40 }\n );\n if (message.stopReason === 'error') return undefined;\n return message.content\n .map((part) => (part.type === 'text' ? part.text : ''))\n .join('')\n .trim();\n };\n}\n"],
5
- "mappings": "AAIA,SAAS,uBAAuB;AAEzB,MAAM,eACX;AAEK,SAAS,aACd,KACA,MACA,MAAM,GAAG,IAAI,cACsC;AACnD,SAAO,OAAO,YAAY;AACxB,UAAM,OAAO,MAAM,IAAI,aAAa,GAAG,GAAG,kBAAkB,OAAO;AACnE,WAAO,KAAK,KAAK,KAAK,QAAQ;AAAA,EAChC;AACF;AAEO,SAAS,OACd,QACA,UACA;AACA,SAAO,OACL,YACA,OACA,YACgC;AAChC,UAAM,SAAS,gBAAgB,MAAM,SAAS,OAAO,CAAC,EAAE;AACxD,UAAM,CAAC,UAAU,GAAG,IAAI,IAAI,MAAM,MAAM,GAAG;AAC3C,UAAM,MAAM,WAAW,YAAY,KAAK,SAAS,EAAE,UAAU,SAAS,KAAK,KAAK,GAAG,EAAE,IAAI;AACzF,UAAM,QAAQ,MAAM,OAAO,SAAS,IAAI,UAAU,IAAI,OAAO,IAAI;AACjE,QAAI,CAAC,SAAS,CAAC,WAAY,QAAO;AAClC,UAAM,UAAU,MAAM,OAAO;AAAA,MAC3B;AAAA,MACA;AAAA,QACE,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,GAAG,YAAY;AAAA;AAAA,EAAO,UAAU,GAAG,CAAC;AAAA,YACpE,WAAW,KAAK,IAAI;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,WAAW,GAAG;AAAA,IAClB;AACA,QAAI,QAAQ,eAAe,QAAS,QAAO;AAC3C,WAAO,QAAQ,QACZ,IAAI,CAAC,SAAU,KAAK,SAAS,SAAS,KAAK,OAAO,EAAG,EACrD,KAAK,EAAE,EACP,KAAK;AAAA,EACV;AACF;",
4
+ "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Message } from '@earendil-works/pi-ai';\nimport type { Models } from '@earendil-works/pi-ai/models';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { extractSettings } from '../memory/extract.ts';\n\nexport const TITLE_PROMPT =\n 'Give this chat a title of three to six words that says what it is about, in the language the user writes in. Answer with the title only, without quotes.';\n\nexport function titlesOn(text: string | undefined): boolean {\n try {\n return (JSON.parse(text ?? '{}') as { titles?: unknown }).titles !== false;\n } catch {\n return true;\n }\n}\n\nexport function settingsText(\n env: Pick<ExecutionEnv, 'readTextFile'>,\n home: string,\n dir = `${home}/.pi/agent`\n): (context: Context) => Promise<string | undefined> {\n return async (context) => {\n const read = await env.readTextFile(`${dir}/settings.json`, context);\n return read.ok ? read.value : undefined;\n };\n}\n\nexport function titler(\n models: Models,\n settings: (context: Context) => Promise<string | undefined>\n) {\n return async (\n transcript: string,\n model: string,\n context: Context\n ): Promise<string | undefined> => {\n const text = await settings(context);\n if (!titlesOn(text)) return undefined;\n const chosen = extractSettings(text).model;\n const [provider, ...rest] = model.split('/');\n const ref = chosen ?? (provider && rest.length ? { provider, modelId: rest.join('/') } : null);\n const found = ref ? models.getModel(ref.provider, ref.modelId) : undefined;\n if (!found || !transcript) return undefined;\n const message = await models.completeSimple(\n found,\n {\n messages: [\n {\n role: 'user',\n content: [{ type: 'text', text: `${TITLE_PROMPT}\\n\\n${transcript}` }],\n timestamp: Date.now(),\n } as Message,\n ],\n },\n { maxTokens: 40 }\n );\n if (message.stopReason === 'error') return undefined;\n return message.content\n .map((part) => (part.type === 'text' ? part.text : ''))\n .join('')\n .trim();\n };\n}\n"],
5
+ "mappings": "AAIA,SAAS,uBAAuB;AAEzB,MAAM,eACX;AAEK,SAAS,SAAS,MAAmC;AAC1D,MAAI;AACF,WAAQ,KAAK,MAAM,QAAQ,IAAI,EAA2B,WAAW;AAAA,EACvE,QAAQ;AACN,WAAO;AAAA,EACT;AACF;AAEO,SAAS,aACd,KACA,MACA,MAAM,GAAG,IAAI,cACsC;AACnD,SAAO,OAAO,YAAY;AACxB,UAAM,OAAO,MAAM,IAAI,aAAa,GAAG,GAAG,kBAAkB,OAAO;AACnE,WAAO,KAAK,KAAK,KAAK,QAAQ;AAAA,EAChC;AACF;AAEO,SAAS,OACd,QACA,UACA;AACA,SAAO,OACL,YACA,OACA,YACgC;AAChC,UAAM,OAAO,MAAM,SAAS,OAAO;AACnC,QAAI,CAAC,SAAS,IAAI,EAAG,QAAO;AAC5B,UAAM,SAAS,gBAAgB,IAAI,EAAE;AACrC,UAAM,CAAC,UAAU,GAAG,IAAI,IAAI,MAAM,MAAM,GAAG;AAC3C,UAAM,MAAM,WAAW,YAAY,KAAK,SAAS,EAAE,UAAU,SAAS,KAAK,KAAK,GAAG,EAAE,IAAI;AACzF,UAAM,QAAQ,MAAM,OAAO,SAAS,IAAI,UAAU,IAAI,OAAO,IAAI;AACjE,QAAI,CAAC,SAAS,CAAC,WAAY,QAAO;AAClC,UAAM,UAAU,MAAM,OAAO;AAAA,MAC3B;AAAA,MACA;AAAA,QACE,UAAU;AAAA,UACR;AAAA,YACE,MAAM;AAAA,YACN,SAAS,CAAC,EAAE,MAAM,QAAQ,MAAM,GAAG,YAAY;AAAA;AAAA,EAAO,UAAU,GAAG,CAAC;AAAA,YACpE,WAAW,KAAK,IAAI;AAAA,UACtB;AAAA,QACF;AAAA,MACF;AAAA,MACA,EAAE,WAAW,GAAG;AAAA,IAClB;AACA,QAAI,QAAQ,eAAe,QAAS,QAAO;AAC3C,WAAO,QAAQ,QACZ,IAAI,CAAC,SAAU,KAAK,SAAS,SAAS,KAAK,OAAO,EAAG,EACrD,KAAK,EAAE,EACP,KAAK;AAAA,EACV;AACF;",
6
6
  "names": []
7
7
  }
@@ -45,6 +45,7 @@ class AgentAdapter extends Emitter {
45
45
  #notices = /* @__PURE__ */ new Map();
46
46
  #unread = /* @__PURE__ */ new Map();
47
47
  #seen = /* @__PURE__ */ new Map();
48
+ #queuedAt = /* @__PURE__ */ new Map();
48
49
  #opened = null;
49
50
  constructor(connection) {
50
51
  super();
@@ -88,6 +89,7 @@ class AgentAdapter extends Emitter {
88
89
  this.#active ??= this.#connection.agents?.value?.active ?? null;
89
90
  if (!this.#opened && (!this.#connection.agents || this.#connection.agents.value))
90
91
  this.#opened = new Set(this.#summary().map((summary) => summary.id));
92
+ for (const summary of this.#summary()) this.#stamp(summary.id, this.#view(summary.id));
91
93
  this.emit("agents", this.list());
92
94
  let unread = false;
93
95
  for (const summary of this.#summary()) unread = this.#update(summary.id) || unread;
@@ -97,6 +99,7 @@ class AgentAdapter extends Emitter {
97
99
  this.#notices.delete(id);
98
100
  this.#seen.delete(id);
99
101
  this.#unread.delete(id);
102
+ this.#queuedAt.delete(id);
100
103
  }
101
104
  if (unread) this.emit("agents", this.list());
102
105
  }
@@ -160,7 +163,7 @@ class AgentAdapter extends Emitter {
160
163
  return this.#summary().map((summary) => {
161
164
  const view = this.#view(summary.id);
162
165
  const doc = view?.docs["pi.agent"];
163
- const title = summary.kind === "cone" ? rows.find((row) => row.id === summary.id)?.title : void 0;
166
+ const title = rows.find((row) => row.id === summary.id)?.title;
164
167
  const model = doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : "";
165
168
  const models = this.#connection.settings?.state.value?.models ?? [];
166
169
  return {
@@ -229,6 +232,7 @@ class AgentAdapter extends Emitter {
229
232
  const pending = target && this.#held(target) ? this.#pending(target, outgoing) : void 0;
230
233
  if (pending) await pending.released;
231
234
  if (pending?.dropped) return this.#settle(pending);
235
+ const at = Date.now();
232
236
  const sent = await this.#connection.control.send(
233
237
  {
234
238
  text: outgoing.text,
@@ -240,6 +244,7 @@ class AgentAdapter extends Emitter {
240
244
  BACKGROUND_CONTEXT
241
245
  ).finally(() => pending && this.#settle(pending));
242
246
  if (!sent.accepted) throw new Error(sent.error.message);
247
+ this.#sent(target || agentId, `q${sent.submissionId}`, at);
243
248
  if (pending?.dropped)
244
249
  attempt(
245
250
  this.#connection.control.unqueue(pending.agentId, sent.submissionId, BACKGROUND_CONTEXT),
@@ -247,6 +252,24 @@ class AgentAdapter extends Emitter {
247
252
  this.#report(pending.agentId)
248
253
  );
249
254
  }
255
+ #stamps(agentId) {
256
+ const stamps = this.#queuedAt.get(agentId) ?? /* @__PURE__ */ new Map();
257
+ this.#queuedAt.set(agentId, stamps);
258
+ return stamps;
259
+ }
260
+ #sent(agentId, id, at) {
261
+ const stamps = this.#stamps(agentId);
262
+ const known = stamps.get(id);
263
+ stamps.set(id, { at: Math.min(at, known?.at ?? at), seen: known?.seen ?? false });
264
+ }
265
+ #stamp(agentId, view) {
266
+ const stamps = this.#stamps(agentId);
267
+ const ids = new Set(queued(view).map((message) => message.id));
268
+ const now = Date.now();
269
+ for (const id of ids) stamps.set(id, { at: stamps.get(id)?.at ?? now, seen: true });
270
+ for (const [id, stamp] of stamps)
271
+ if (!ids.has(id) && (stamp.seen || !ids.size && !isBusy(view))) stamps.delete(id);
272
+ }
250
273
  #pending(agentId, outgoing) {
251
274
  const id = `p${crypto.randomUUID()}`;
252
275
  const message = {
@@ -295,7 +318,9 @@ class AgentAdapter extends Emitter {
295
318
  }
296
319
  queue(agentId = this.active()) {
297
320
  const pending = [...this.#outbox.values()].filter((item) => item.agentId === agentId && !item.dropped).map((item) => item.message);
298
- return [...queued(this.#view(agentId)), ...pending];
321
+ const stamps = this.#queuedAt.get(agentId);
322
+ const at = (id) => stamps?.get(id)?.at ?? 0;
323
+ return [...queued(this.#view(agentId), at), ...pending];
299
324
  }
300
325
  unqueue(agentId, messageId) {
301
326
  const pending = this.#outbox.get(messageId);
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/spectrum/agent-port.ts"],
4
- "sourcesContent": ["import type {\n Agent,\n AgentEvents,\n AgentPort,\n AgentStatus,\n FrozenCone,\n Message,\n Outgoing,\n SlashCommand,\n SystemMessage,\n Thinking,\n UserMessage,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { AgentConnection } from '../client.ts';\nimport { contextRatio, contextTokens } from '../context.ts';\nimport { shrink } from '../images/fit.ts';\nimport { entryLick } from '../licks/state.ts';\nimport { type VaultHold, vaultHold } from '../secrets/view.ts';\nimport type { AgentSettingsChange, AgentSummary, Command } from '../services.ts';\nimport { attempt } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\nimport { isBusy, queued, toMessages } from './messages.ts';\nimport { readUrl, sendAttachments } from './outgoing.ts';\n\nexport const CONE = 'cone';\n\nconst thinking: Record<string, Thinking> = {\n off: 'off',\n minimal: 'low',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'high',\n max: 'high',\n};\n\ninterface AgentDoc {\n model?: { provider: string; modelId: string };\n thinkingLevel?: string;\n}\n\nfunction status(view: ConversationView | undefined, messages: readonly Message[]): AgentStatus {\n if (isBusy(view)) {\n const live = view?.docs['pi.live'] as { tools?: { status: string }[] } | undefined;\n return live?.tools?.some((slot) => slot.status === 'running') ? 'working' : 'thinking';\n }\n const last = messages.at(-1);\n return last?.role === 'assistant' && last.status === 'error' ? 'error' : 'idle';\n}\n\nfunction answers(messages: readonly Message[]): string[] {\n return messages\n .filter((message) => message.role === 'assistant' && message.status !== 'streaming')\n .map((message) => message.id);\n}\n\nexport function slashCommand({ kind, ...command }: Command): SlashCommand {\n return kind === 'action' ? command : { ...command, kind };\n}\n\nexport type AgentHold = VaultHold;\n\nexport type AgentAdapterEvents = AgentEvents & { hold: AgentHold | null };\n\nfunction sameHold(a: AgentHold | null, b: AgentHold | null): boolean {\n return a === b || (a !== null && b !== null && a.reason === b.reason && a.held === b.held);\n}\n\ninterface Pending {\n agentId: string;\n message: UserMessage;\n dropped: boolean;\n release(): void;\n released: Promise<void>;\n}\n\nexport class AgentAdapter extends Emitter<AgentAdapterEvents> implements AgentPort {\n readonly #connection: AgentConnection;\n readonly #ready: Promise<void>;\n readonly #messages = new Map<string, Message[]>();\n #active: string | null = null;\n #creating = new Map<string, Promise<string | null>>();\n #hold: AgentHold | null = null;\n readonly #outbox = new Map<string, Pending>();\n readonly #notices = new Map<string, { at: number; message: SystemMessage }[]>();\n readonly #unread = new Map<string, number>();\n readonly #seen = new Map<string, Set<string>>();\n #opened: ReadonlySet<string> | null = null;\n\n constructor(connection: AgentConnection) {\n super();\n this.#connection = connection;\n this.#hold = this.hold();\n connection.vault?.subscribe(() => {\n const next = this.hold();\n if (sameHold(next, this.#hold)) return;\n this.#hold = next;\n if (!next) for (const pending of this.#outbox.values()) pending.release();\n this.emit('hold', next);\n this.emit('agents', this.list());\n });\n connection.frozen?.subscribe(() => {\n this.emit('frozen', this.frozen());\n this.emit('agents', this.list());\n });\n this.#ready = new Promise((resolve) => {\n connection.transcript.subscribe(() => {\n this.#refresh();\n resolve();\n });\n connection.deliveries.subscribe(() => this.#refresh());\n connection.views?.subscribe(() => this.#refresh());\n connection.agents?.subscribe(() => this.#refresh());\n });\n connection.settings?.state.subscribe(() => this.emit('agents', this.list()));\n }\n\n #summary(): readonly AgentSummary[] {\n const agents = this.#connection.agents?.value?.agents;\n return agents?.length\n ? agents\n : [{ id: CONE, name: 'sliccy', kind: 'cone', parentId: null, role: null }];\n }\n\n #view(agentId: string = this.active()): ConversationView | undefined {\n const views = this.#connection.views?.value;\n const view = views?.[agentId];\n if (view) return view;\n const cone = this.#connection.agents?.value?.active ?? CONE;\n return agentId === cone ? this.#connection.transcript.value : undefined;\n }\n\n #refresh(): void {\n this.#active ??= this.#connection.agents?.value?.active ?? null;\n if (!this.#opened && (!this.#connection.agents || this.#connection.agents.value))\n this.#opened = new Set(this.#summary().map((summary) => summary.id));\n this.emit('agents', this.list());\n let unread = false;\n for (const summary of this.#summary()) unread = this.#update(summary.id) || unread;\n for (const id of [...this.#messages.keys(), ...this.#notices.keys(), ...this.#seen.keys()])\n if (!this.#summary().some((summary) => summary.id === id)) {\n this.#messages.delete(id);\n this.#notices.delete(id);\n this.#seen.delete(id);\n this.#unread.delete(id);\n }\n if (unread) this.emit('agents', this.list());\n }\n\n #count(agentId: string, view: ConversationView, messages: readonly Message[]): boolean {\n const ids = answers(messages);\n const known = this.#seen.get(agentId);\n if (agentId === this.active() || (!known && (!this.#opened || this.#opened.has(agentId)))) {\n this.#seen.set(agentId, new Set(ids));\n return false;\n }\n const seen = known ?? new Set<string>();\n this.#seen.set(agentId, seen);\n const fresh = isBusy(view) ? [] : ids.filter((id) => !seen.has(id));\n if (!fresh.length) return false;\n for (const id of fresh) seen.add(id);\n this.#unread.set(agentId, (this.#unread.get(agentId) ?? 0) + fresh.length);\n return true;\n }\n\n notify(text: string, agentId: string = this.active()): void {\n const notes = this.#notices.get(agentId) ?? [];\n notes.push({\n at: this.#messages.get(agentId)?.length ?? 0,\n message: {\n id: `n${crypto.randomUUID()}`,\n role: 'system',\n kind: 'notice',\n text,\n createdAt: Date.now(),\n },\n });\n this.#notices.set(agentId, notes);\n this.emit('messages', agentId);\n }\n\n #report(agentId: string): (text: string) => void {\n return (text) => this.notify(text, agentId);\n }\n\n #update(agentId: string): boolean {\n const view = this.#view(agentId);\n if (!view) return false;\n const before = this.#messages.get(agentId) ?? [];\n const after = toMessages(view, this.#connection.deliveries.value);\n this.#messages.set(agentId, after);\n if (before.length !== after.length) this.emit('messages', agentId);\n else {\n const changed = after.filter(\n (message, index) => JSON.stringify(message) !== JSON.stringify(before[index])\n );\n if (changed.length === 1) this.emit('message', { agentId, message: changed[0] as Message });\n else if (changed.length > 1) this.emit('messages', agentId);\n }\n return this.#count(agentId, view, after);\n }\n\n ready(): Promise<void> {\n return this.#ready;\n }\n\n hold(): AgentHold | null {\n return vaultHold(this.#connection.vault?.value);\n }\n\n list(): readonly Agent[] {\n const rows = this.#connection.frozen?.value ?? [];\n return this.#summary().map((summary) => {\n const view = this.#view(summary.id);\n const doc = view?.docs['pi.agent'] as AgentDoc | undefined;\n const title =\n summary.kind === 'cone' ? rows.find((row) => row.id === summary.id)?.title : undefined;\n const model = doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : '';\n const models = this.#connection.settings?.state.value?.models ?? [];\n return {\n id: summary.id,\n name: summary.role ? `${summary.name} \u00B7 ${summary.role}` : summary.name,\n kind: summary.kind,\n parentId: summary.parentId,\n status: this.#status(summary.id, status(view, this.#messages.get(summary.id) ?? [])),\n model,\n contextFill: contextRatio(contextTokens(view), model, models) ?? 0,\n unread: this.#unread.get(summary.id) ?? 0,\n thinking: thinking[doc?.thinkingLevel ?? 'off'] ?? 'off',\n ...(title ? { title } : {}),\n };\n });\n }\n\n active(): string {\n const known = this.#summary();\n if (this.#active && this.#creating.has(this.#active)) return this.#active;\n if (this.#active && known.some((summary) => summary.id === this.#active)) return this.#active;\n return this.#connection.agents?.value?.active ?? CONE;\n }\n\n select(id: string): void {\n if (this.#creating.has(id)) {\n this.#active = id;\n this.emit('active', id);\n return;\n }\n const found = this.#summary().find((summary) => summary.id === id);\n if (!found) return;\n this.#active = id;\n this.#seen.set(id, new Set(answers(this.#messages.get(id) ?? [])));\n const read = this.#unread.delete(id);\n if (found.kind === 'cone')\n attempt(\n this.#connection.control.selectCone(id, BACKGROUND_CONTEXT),\n 'switch cones',\n this.#report(id)\n );\n this.emit('active', id);\n this.emit('messages', id);\n if (read) this.emit('agents', this.list());\n }\n\n messages(agentId: string = this.active()): readonly Message[] {\n const shown = this.#messages.get(agentId) ?? [];\n const notes = this.#notices.get(agentId);\n if (!notes) return shown;\n const at = (index: number) => notes.filter((note) => note.at === index).map((n) => n.message);\n const late = notes.filter((note) => note.at >= shown.length).map((note) => note.message);\n return [...shown.flatMap((message, index) => [...at(index), message]), ...late];\n }\n\n async send(agentId: string, input: string | Outgoing): Promise<void> {\n const outgoing = typeof input === 'string' ? { text: input } : input;\n const attachments = outgoing.attachments?.length\n ? await sendAttachments(outgoing.attachments, readUrl, shrink, (ref) =>\n this.#connection.control.image(ref, BACKGROUND_CONTEXT)\n ).catch((error: Error) => {\n this.notify(error.message, agentId);\n return null;\n })\n : [];\n if (!attachments) return;\n const target = this.#creating.has(agentId) ? await this.#creating.get(agentId) : agentId;\n if (target === null) throw new Error('The scoop could not be created.');\n const pending = target && this.#held(target) ? this.#pending(target, outgoing) : undefined;\n if (pending) await pending.released;\n if (pending?.dropped) return this.#settle(pending);\n const sent = await this.#connection.control\n .send(\n {\n text: outgoing.text,\n whenBusy: outgoing.mode === 'queue' ? 'followUp' : 'steer',\n requestId: crypto.randomUUID(),\n agentId: target || null,\n ...(attachments.length ? { attachments } : {}),\n },\n BACKGROUND_CONTEXT\n )\n .finally(() => pending && this.#settle(pending));\n if (!sent.accepted) throw new Error(sent.error.message);\n if (pending?.dropped)\n attempt(\n this.#connection.control.unqueue(pending.agentId, sent.submissionId, BACKGROUND_CONTEXT),\n 'remove queued messages',\n this.#report(pending.agentId)\n );\n }\n\n #pending(agentId: string, outgoing: Outgoing): Pending {\n const id = `p${crypto.randomUUID()}`;\n const message: UserMessage = {\n id,\n role: 'user',\n text: outgoing.text,\n createdAt: Date.now(),\n ...(outgoing.attachments?.length ? { attachments: [...outgoing.attachments] } : {}),\n queued: true,\n mode: outgoing.mode === 'queue' ? 'queue' : 'steer',\n };\n const { promise: released, resolve: release } = Promise.withResolvers<void>();\n const pending = { agentId, message, dropped: false, release, released };\n this.#outbox.set(id, pending);\n this.emit('messages', agentId);\n return pending;\n }\n\n #settle(pending: Pending): void {\n this.#outbox.delete(pending.message.id);\n this.emit('messages', pending.agentId);\n }\n\n async rewind(agentId: string, messageId: string): Promise<Outgoing | null> {\n const rewound = await this.#connection.control.rewindAgent(\n agentId,\n messageId,\n BACKGROUND_CONTEXT\n );\n if (!rewound.done) return null;\n return rewound.attachments?.length\n ? { text: rewound.text, attachments: rewound.attachments }\n : { text: rewound.text };\n }\n\n stop(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.stopAgent(agentId, BACKGROUND_CONTEXT),\n 'stop agents',\n this.#report(agentId)\n );\n }\n\n busy(agentId: string = this.active()): boolean {\n return isBusy(this.#view(agentId)) || this.#held(agentId);\n }\n\n #status(agentId: string, shown: AgentStatus): AgentStatus {\n return shown === 'idle' && this.#held(agentId) ? 'working' : shown;\n }\n\n #held(agentId: string): boolean {\n return this.#hold !== null && agentId === (this.#connection.agents?.value?.active ?? CONE);\n }\n\n queue(agentId: string = this.active()): readonly UserMessage[] {\n const pending = [...this.#outbox.values()]\n .filter((item) => item.agentId === agentId && !item.dropped)\n .map((item) => item.message);\n return [...queued(this.#view(agentId)), ...pending];\n }\n\n unqueue(agentId: string, messageId: string): void {\n const pending = this.#outbox.get(messageId);\n if (pending) {\n pending.dropped = true;\n pending.release();\n this.emit('messages', pending.agentId);\n return;\n }\n attempt(\n this.#connection.control.unqueue(agentId, messageId.replace(/^q/, ''), BACKGROUND_CONTEXT),\n 'remove queued messages',\n this.#report(agentId)\n );\n }\n\n suggestion(): string | null {\n return null;\n }\n\n answer(): void {}\n\n resolveLick(agentId: string, messageId: string, state: 'confirmed' | 'dismissed'): void {\n const message = this.messages(agentId).find((candidate) => candidate.id === messageId);\n const entry = this.#view(agentId)?.entries.find(\n (candidate) => `e${candidate.id}` === messageId\n );\n const lick = message?.role === 'lick' && entry ? entryLick(entry) : undefined;\n if (lick)\n attempt(\n this.#connection.control.resolveAgentLick(agentId, lick.id, state, BACKGROUND_CONTEXT),\n 'answer licks',\n this.#report(agentId)\n );\n }\n\n compact(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.compactAgent(agentId, null, BACKGROUND_CONTEXT),\n 'compact conversations',\n this.#report(agentId)\n );\n }\n\n clear(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.newChat(agentId, BACKGROUND_CONTEXT),\n 'start new chats',\n this.#report(agentId)\n );\n }\n\n freeze(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.freeze(agentId, BACKGROUND_CONTEXT),\n 'freeze cones',\n this.#report(agentId)\n );\n }\n\n #configure(agentId: string, change: Partial<AgentSettingsChange>): void {\n attempt(\n this.#connection.control.configure(\n {\n model: change.model ?? null,\n thinkingLevel: change.thinkingLevel ?? null,\n agentId,\n },\n BACKGROUND_CONTEXT\n ),\n 'change agent settings',\n this.#report(agentId)\n );\n }\n\n setModel(agentId: string, model: string): void {\n const at = model.indexOf('/');\n if (at <= 0) return;\n this.#configure(agentId, {\n model: { provider: model.slice(0, at), modelId: model.slice(at + 1) },\n });\n }\n\n setThinking(agentId: string, level: Thinking): void {\n this.#configure(agentId, { thinkingLevel: level });\n }\n\n async older(): Promise<readonly Message[]> {\n return [];\n }\n\n commands(): readonly SlashCommand[] {\n return (this.#connection.commands?.value ?? []).map(slashCommand);\n }\n\n createScoop(parentId: string, name: string): Agent {\n const provisional = `scoop:creating-${crypto.randomUUID()}`;\n const created = this.#connection.control.createScoop(parentId, name, BACKGROUND_CONTEXT).then(\n (result) => result.id,\n () => null\n );\n this.#creating.set(provisional, created);\n void created.then((id) => {\n if (this.#active !== provisional) return;\n this.#active = id ?? parentId;\n this.emit('active', this.#active);\n this.emit('messages', this.#active);\n });\n return {\n id: provisional,\n name,\n kind: 'scoop',\n parentId,\n status: 'idle',\n model: '',\n contextFill: 0,\n unread: 0,\n };\n }\n\n async drop(agentId: string): Promise<void> {\n const parent = this.#summary().find((summary) => summary.id === agentId)?.parentId ?? CONE;\n const dropped = await this.#connection.control.drop(agentId, BACKGROUND_CONTEXT);\n if (dropped.error !== null) throw new Error(dropped.error);\n if (this.#active === agentId) this.select(parent);\n }\n\n async createCone(name: string): Promise<Agent> {\n const created = await this.#connection.control.createCone(name, BACKGROUND_CONTEXT);\n if (created.error !== null) throw new Error(created.error);\n return {\n id: created.id,\n name: name.trim(),\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: '',\n contextFill: 0,\n unread: 0,\n };\n }\n\n frozen(): readonly FrozenCone[] {\n return (this.#connection.frozen?.value ?? []).map(\n ({ id, name, title, model, messages, frozenAt, kind, live, thawedAs }) => ({\n id,\n name,\n title,\n model,\n messages,\n frozenAt,\n kind,\n live,\n ...(thawedAs ? { thawedAs } : {}),\n })\n );\n }\n\n thaw(id: string): Agent | null {\n const record = this.frozen().find((item) => item.id === id);\n if (!record) return null;\n if (record.live) {\n const running = this.list().find((agent) => agent.id === id) ?? null;\n if (running) this.select(id);\n return running;\n }\n const provisional = `thawing-${crypto.randomUUID()}`;\n const thawed = this.#connection.control.thaw(id, BACKGROUND_CONTEXT).then(\n (result) => result.id,\n () => null\n );\n this.#creating.set(provisional, thawed);\n void thawed.then((cone) => {\n if (this.#active !== provisional) return;\n this.#active = cone ?? CONE;\n this.emit('active', this.#active);\n this.emit('messages', this.#active);\n });\n return {\n id: provisional,\n name: record.name,\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: record.model,\n contextFill: 0,\n unread: 0,\n };\n }\n\n discard(id: string): void {\n attempt(\n this.#connection.control.discard(id, BACKGROUND_CONTEXT),\n 'discard frozen cones',\n this.#report(this.active())\n );\n }\n}\n"],
5
- "mappings": "AAaA,SAAS,0BAA0B;AAGnC,SAAS,cAAc,qBAAqB;AAC5C,SAAS,cAAc;AACvB,SAAS,iBAAiB;AAC1B,SAAyB,iBAAiB;AAE1C,SAAS,eAAe;AACxB,SAAS,eAAe;AACxB,SAAS,QAAQ,QAAQ,kBAAkB;AAC3C,SAAS,SAAS,uBAAuB;AAElC,MAAM,OAAO;AAEpB,MAAM,WAAqC;AAAA,EACzC,KAAK;AAAA,EACL,SAAS;AAAA,EACT,KAAK;AAAA,EACL,QAAQ;AAAA,EACR,MAAM;AAAA,EACN,OAAO;AAAA,EACP,KAAK;AACP;AAOA,SAAS,OAAO,MAAoC,UAA2C;AAC7F,MAAI,OAAO,IAAI,GAAG;AAChB,UAAM,OAAO,MAAM,KAAK,SAAS;AACjC,WAAO,MAAM,OAAO,KAAK,CAAC,SAAS,KAAK,WAAW,SAAS,IAAI,YAAY;AAAA,EAC9E;AACA,QAAM,OAAO,SAAS,GAAG,EAAE;AAC3B,SAAO,MAAM,SAAS,eAAe,KAAK,WAAW,UAAU,UAAU;AAC3E;AAEA,SAAS,QAAQ,UAAwC;AACvD,SAAO,SACJ,OAAO,CAAC,YAAY,QAAQ,SAAS,eAAe,QAAQ,WAAW,WAAW,EAClF,IAAI,CAAC,YAAY,QAAQ,EAAE;AAChC;AAEO,SAAS,aAAa,EAAE,MAAM,GAAG,QAAQ,GAA0B;AACxE,SAAO,SAAS,WAAW,UAAU,EAAE,GAAG,SAAS,KAAK;AAC1D;AAMA,SAAS,SAAS,GAAqB,GAA8B;AACnE,SAAO,MAAM,KAAM,MAAM,QAAQ,MAAM,QAAQ,EAAE,WAAW,EAAE,UAAU,EAAE,SAAS,EAAE;AACvF;AAUO,MAAM,qBAAqB,QAAiD;AAAA,EACxE;AAAA,EACA;AAAA,EACA,YAAY,oBAAI,IAAuB;AAAA,EAChD,UAAyB;AAAA,EACzB,YAAY,oBAAI,IAAoC;AAAA,EACpD,QAA0B;AAAA,EACjB,UAAU,oBAAI,IAAqB;AAAA,EACnC,WAAW,oBAAI,IAAsD;AAAA,EACrE,UAAU,oBAAI,IAAoB;AAAA,EAClC,QAAQ,oBAAI,IAAyB;AAAA,EAC9C,UAAsC;AAAA,EAEtC,YAAY,YAA6B;AACvC,UAAM;AACN,SAAK,cAAc;AACnB,SAAK,QAAQ,KAAK,KAAK;AACvB,eAAW,OAAO,UAAU,MAAM;AAChC,YAAM,OAAO,KAAK,KAAK;AACvB,UAAI,SAAS,MAAM,KAAK,KAAK,EAAG;AAChC,WAAK,QAAQ;AACb,UAAI,CAAC,KAAM,YAAW,WAAW,KAAK,QAAQ,OAAO,EAAG,SAAQ,QAAQ;AACxE,WAAK,KAAK,QAAQ,IAAI;AACtB,WAAK,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,IACjC,CAAC;AACD,eAAW,QAAQ,UAAU,MAAM;AACjC,WAAK,KAAK,UAAU,KAAK,OAAO,CAAC;AACjC,WAAK,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,IACjC,CAAC;AACD,SAAK,SAAS,IAAI,QAAQ,CAAC,YAAY;AACrC,iBAAW,WAAW,UAAU,MAAM;AACpC,aAAK,SAAS;AACd,gBAAQ;AAAA,MACV,CAAC;AACD,iBAAW,WAAW,UAAU,MAAM,KAAK,SAAS,CAAC;AACrD,iBAAW,OAAO,UAAU,MAAM,KAAK,SAAS,CAAC;AACjD,iBAAW,QAAQ,UAAU,MAAM,KAAK,SAAS,CAAC;AAAA,IACpD,CAAC;AACD,eAAW,UAAU,MAAM,UAAU,MAAM,KAAK,KAAK,UAAU,KAAK,KAAK,CAAC,CAAC;AAAA,EAC7E;AAAA,EAEA,WAAoC;AAClC,UAAM,SAAS,KAAK,YAAY,QAAQ,OAAO;AAC/C,WAAO,QAAQ,SACX,SACA,CAAC,EAAE,IAAI,MAAM,MAAM,UAAU,MAAM,QAAQ,UAAU,MAAM,MAAM,KAAK,CAAC;AAAA,EAC7E;AAAA,EAEA,MAAM,UAAkB,KAAK,OAAO,GAAiC;AACnE,UAAM,QAAQ,KAAK,YAAY,OAAO;AACtC,UAAM,OAAO,QAAQ,OAAO;AAC5B,QAAI,KAAM,QAAO;AACjB,UAAM,OAAO,KAAK,YAAY,QAAQ,OAAO,UAAU;AACvD,WAAO,YAAY,OAAO,KAAK,YAAY,WAAW,QAAQ;AAAA,EAChE;AAAA,EAEA,WAAiB;AACf,SAAK,YAAY,KAAK,YAAY,QAAQ,OAAO,UAAU;AAC3D,QAAI,CAAC,KAAK,YAAY,CAAC,KAAK,YAAY,UAAU,KAAK,YAAY,OAAO;AACxE,WAAK,UAAU,IAAI,IAAI,KAAK,SAAS,EAAE,IAAI,CAAC,YAAY,QAAQ,EAAE,CAAC;AACrE,SAAK,KAAK,UAAU,KAAK,KAAK,CAAC;AAC/B,QAAI,SAAS;AACb,eAAW,WAAW,KAAK,SAAS,EAAG,UAAS,KAAK,QAAQ,QAAQ,EAAE,KAAK;AAC5E,eAAW,MAAM,CAAC,GAAG,KAAK,UAAU,KAAK,GAAG,GAAG,KAAK,SAAS,KAAK,GAAG,GAAG,KAAK,MAAM,KAAK,CAAC;AACvF,UAAI,CAAC,KAAK,SAAS,EAAE,KAAK,CAAC,YAAY,QAAQ,OAAO,EAAE,GAAG;AACzD,aAAK,UAAU,OAAO,EAAE;AACxB,aAAK,SAAS,OAAO,EAAE;AACvB,aAAK,MAAM,OAAO,EAAE;AACpB,aAAK,QAAQ,OAAO,EAAE;AAAA,MACxB;AACF,QAAI,OAAQ,MAAK,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,EAC7C;AAAA,EAEA,OAAO,SAAiB,MAAwB,UAAuC;AACrF,UAAM,MAAM,QAAQ,QAAQ;AAC5B,UAAM,QAAQ,KAAK,MAAM,IAAI,OAAO;AACpC,QAAI,YAAY,KAAK,OAAO,KAAM,CAAC,UAAU,CAAC,KAAK,WAAW,KAAK,QAAQ,IAAI,OAAO,IAAK;AACzF,WAAK,MAAM,IAAI,SAAS,IAAI,IAAI,GAAG,CAAC;AACpC,aAAO;AAAA,IACT;AACA,UAAM,OAAO,SAAS,oBAAI,IAAY;AACtC,SAAK,MAAM,IAAI,SAAS,IAAI;AAC5B,UAAM,QAAQ,OAAO,IAAI,IAAI,CAAC,IAAI,IAAI,OAAO,CAAC,OAAO,CAAC,KAAK,IAAI,EAAE,CAAC;AAClE,QAAI,CAAC,MAAM,OAAQ,QAAO;AAC1B,eAAW,MAAM,MAAO,MAAK,IAAI,EAAE;AACnC,SAAK,QAAQ,IAAI,UAAU,KAAK,QAAQ,IAAI,OAAO,KAAK,KAAK,MAAM,MAAM;AACzE,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,MAAc,UAAkB,KAAK,OAAO,GAAS;AAC1D,UAAM,QAAQ,KAAK,SAAS,IAAI,OAAO,KAAK,CAAC;AAC7C,UAAM,KAAK;AAAA,MACT,IAAI,KAAK,UAAU,IAAI,OAAO,GAAG,UAAU;AAAA,MAC3C,SAAS;AAAA,QACP,IAAI,IAAI,OAAO,WAAW,CAAC;AAAA,QAC3B,MAAM;AAAA,QACN,MAAM;AAAA,QACN;AAAA,QACA,WAAW,KAAK,IAAI;AAAA,MACtB;AAAA,IACF,CAAC;AACD,SAAK,SAAS,IAAI,SAAS,KAAK;AAChC,SAAK,KAAK,YAAY,OAAO;AAAA,EAC/B;AAAA,EAEA,QAAQ,SAAyC;AAC/C,WAAO,CAAC,SAAS,KAAK,OAAO,MAAM,OAAO;AAAA,EAC5C;AAAA,EAEA,QAAQ,SAA0B;AAChC,UAAM,OAAO,KAAK,MAAM,OAAO;AAC/B,QAAI,CAAC,KAAM,QAAO;AAClB,UAAM,SAAS,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC;AAC/C,UAAM,QAAQ,WAAW,MAAM,KAAK,YAAY,WAAW,KAAK;AAChE,SAAK,UAAU,IAAI,SAAS,KAAK;AACjC,QAAI,OAAO,WAAW,MAAM,OAAQ,MAAK,KAAK,YAAY,OAAO;AAAA,SAC5D;AACH,YAAM,UAAU,MAAM;AAAA,QACpB,CAAC,SAAS,UAAU,KAAK,UAAU,OAAO,MAAM,KAAK,UAAU,OAAO,KAAK,CAAC;AAAA,MAC9E;AACA,UAAI,QAAQ,WAAW,EAAG,MAAK,KAAK,WAAW,EAAE,SAAS,SAAS,QAAQ,CAAC,EAAa,CAAC;AAAA,eACjF,QAAQ,SAAS,EAAG,MAAK,KAAK,YAAY,OAAO;AAAA,IAC5D;AACA,WAAO,KAAK,OAAO,SAAS,MAAM,KAAK;AAAA,EACzC;AAAA,EAEA,QAAuB;AACrB,WAAO,KAAK;AAAA,EACd;AAAA,EAEA,OAAyB;AACvB,WAAO,UAAU,KAAK,YAAY,OAAO,KAAK;AAAA,EAChD;AAAA,EAEA,OAAyB;AACvB,UAAM,OAAO,KAAK,YAAY,QAAQ,SAAS,CAAC;AAChD,WAAO,KAAK,SAAS,EAAE,IAAI,CAAC,YAAY;AACtC,YAAM,OAAO,KAAK,MAAM,QAAQ,EAAE;AAClC,YAAM,MAAM,MAAM,KAAK,UAAU;AACjC,YAAM,QACJ,QAAQ,SAAS,SAAS,KAAK,KAAK,CAAC,QAAQ,IAAI,OAAO,QAAQ,EAAE,GAAG,QAAQ;AAC/E,YAAM,QAAQ,KAAK,QAAQ,GAAG,IAAI,MAAM,QAAQ,IAAI,IAAI,MAAM,OAAO,KAAK;AAC1E,YAAM,SAAS,KAAK,YAAY,UAAU,MAAM,OAAO,UAAU,CAAC;AAClE,aAAO;AAAA,QACL,IAAI,QAAQ;AAAA,QACZ,MAAM,QAAQ,OAAO,GAAG,QAAQ,IAAI,SAAM,QAAQ,IAAI,KAAK,QAAQ;AAAA,QACnE,MAAM,QAAQ;AAAA,QACd,UAAU,QAAQ;AAAA,QAClB,QAAQ,KAAK,QAAQ,QAAQ,IAAI,OAAO,MAAM,KAAK,UAAU,IAAI,QAAQ,EAAE,KAAK,CAAC,CAAC,CAAC;AAAA,QACnF;AAAA,QACA,aAAa,aAAa,cAAc,IAAI,GAAG,OAAO,MAAM,KAAK;AAAA,QACjE,QAAQ,KAAK,QAAQ,IAAI,QAAQ,EAAE,KAAK;AAAA,QACxC,UAAU,SAAS,KAAK,iBAAiB,KAAK,KAAK;AAAA,QACnD,GAAI,QAAQ,EAAE,MAAM,IAAI,CAAC;AAAA,MAC3B;AAAA,IACF,CAAC;AAAA,EACH;AAAA,EAEA,SAAiB;AACf,UAAM,QAAQ,KAAK,SAAS;AAC5B,QAAI,KAAK,WAAW,KAAK,UAAU,IAAI,KAAK,OAAO,EAAG,QAAO,KAAK;AAClE,QAAI,KAAK,WAAW,MAAM,KAAK,CAAC,YAAY,QAAQ,OAAO,KAAK,OAAO,EAAG,QAAO,KAAK;AACtF,WAAO,KAAK,YAAY,QAAQ,OAAO,UAAU;AAAA,EACnD;AAAA,EAEA,OAAO,IAAkB;AACvB,QAAI,KAAK,UAAU,IAAI,EAAE,GAAG;AAC1B,WAAK,UAAU;AACf,WAAK,KAAK,UAAU,EAAE;AACtB;AAAA,IACF;AACA,UAAM,QAAQ,KAAK,SAAS,EAAE,KAAK,CAAC,YAAY,QAAQ,OAAO,EAAE;AACjE,QAAI,CAAC,MAAO;AACZ,SAAK,UAAU;AACf,SAAK,MAAM,IAAI,IAAI,IAAI,IAAI,QAAQ,KAAK,UAAU,IAAI,EAAE,KAAK,CAAC,CAAC,CAAC,CAAC;AACjE,UAAM,OAAO,KAAK,QAAQ,OAAO,EAAE;AACnC,QAAI,MAAM,SAAS;AACjB;AAAA,QACE,KAAK,YAAY,QAAQ,WAAW,IAAI,kBAAkB;AAAA,QAC1D;AAAA,QACA,KAAK,QAAQ,EAAE;AAAA,MACjB;AACF,SAAK,KAAK,UAAU,EAAE;AACtB,SAAK,KAAK,YAAY,EAAE;AACxB,QAAI,KAAM,MAAK,KAAK,UAAU,KAAK,KAAK,CAAC;AAAA,EAC3C;AAAA,EAEA,SAAS,UAAkB,KAAK,OAAO,GAAuB;AAC5D,UAAM,QAAQ,KAAK,UAAU,IAAI,OAAO,KAAK,CAAC;AAC9C,UAAM,QAAQ,KAAK,SAAS,IAAI,OAAO;AACvC,QAAI,CAAC,MAAO,QAAO;AACnB,UAAM,KAAK,CAAC,UAAkB,MAAM,OAAO,CAAC,SAAS,KAAK,OAAO,KAAK,EAAE,IAAI,CAAC,MAAM,EAAE,OAAO;AAC5F,UAAM,OAAO,MAAM,OAAO,CAAC,SAAS,KAAK,MAAM,MAAM,MAAM,EAAE,IAAI,CAAC,SAAS,KAAK,OAAO;AACvF,WAAO,CAAC,GAAG,MAAM,QAAQ,CAAC,SAAS,UAAU,CAAC,GAAG,GAAG,KAAK,GAAG,OAAO,CAAC,GAAG,GAAG,IAAI;AAAA,EAChF;AAAA,EAEA,MAAM,KAAK,SAAiB,OAAyC;AACnE,UAAM,WAAW,OAAO,UAAU,WAAW,EAAE,MAAM,MAAM,IAAI;AAC/D,UAAM,cAAc,SAAS,aAAa,SACtC,MAAM;AAAA,MAAgB,SAAS;AAAA,MAAa;AAAA,MAAS;AAAA,MAAQ,CAAC,QAC5D,KAAK,YAAY,QAAQ,MAAM,KAAK,kBAAkB;AAAA,IACxD,EAAE,MAAM,CAAC,UAAiB;AACxB,WAAK,OAAO,MAAM,SAAS,OAAO;AAClC,aAAO;AAAA,IACT,CAAC,IACD,CAAC;AACL,QAAI,CAAC,YAAa;AAClB,UAAM,SAAS,KAAK,UAAU,IAAI,OAAO,IAAI,MAAM,KAAK,UAAU,IAAI,OAAO,IAAI;AACjF,QAAI,WAAW,KAAM,OAAM,IAAI,MAAM,iCAAiC;AACtE,UAAM,UAAU,UAAU,KAAK,MAAM,MAAM,IAAI,KAAK,SAAS,QAAQ,QAAQ,IAAI;AACjF,QAAI,QAAS,OAAM,QAAQ;AAC3B,QAAI,SAAS,QAAS,QAAO,KAAK,QAAQ,OAAO;AACjD,UAAM,OAAO,MAAM,KAAK,YAAY,QACjC;AAAA,MACC;AAAA,QACE,MAAM,SAAS;AAAA,QACf,UAAU,SAAS,SAAS,UAAU,aAAa;AAAA,QACnD,WAAW,OAAO,WAAW;AAAA,QAC7B,SAAS,UAAU;AAAA,QACnB,GAAI,YAAY,SAAS,EAAE,YAAY,IAAI,CAAC;AAAA,MAC9C;AAAA,MACA;AAAA,IACF,EACC,QAAQ,MAAM,WAAW,KAAK,QAAQ,OAAO,CAAC;AACjD,QAAI,CAAC,KAAK,SAAU,OAAM,IAAI,MAAM,KAAK,MAAM,OAAO;AACtD,QAAI,SAAS;AACX;AAAA,QACE,KAAK,YAAY,QAAQ,QAAQ,QAAQ,SAAS,KAAK,cAAc,kBAAkB;AAAA,QACvF;AAAA,QACA,KAAK,QAAQ,QAAQ,OAAO;AAAA,MAC9B;AAAA,EACJ;AAAA,EAEA,SAAS,SAAiB,UAA6B;AACrD,UAAM,KAAK,IAAI,OAAO,WAAW,CAAC;AAClC,UAAM,UAAuB;AAAA,MAC3B;AAAA,MACA,MAAM;AAAA,MACN,MAAM,SAAS;AAAA,MACf,WAAW,KAAK,IAAI;AAAA,MACpB,GAAI,SAAS,aAAa,SAAS,EAAE,aAAa,CAAC,GAAG,SAAS,WAAW,EAAE,IAAI,CAAC;AAAA,MACjF,QAAQ;AAAA,MACR,MAAM,SAAS,SAAS,UAAU,UAAU;AAAA,IAC9C;AACA,UAAM,EAAE,SAAS,UAAU,SAAS,QAAQ,IAAI,QAAQ,cAAoB;AAC5E,UAAM,UAAU,EAAE,SAAS,SAAS,SAAS,OAAO,SAAS,SAAS;AACtE,SAAK,QAAQ,IAAI,IAAI,OAAO;AAC5B,SAAK,KAAK,YAAY,OAAO;AAC7B,WAAO;AAAA,EACT;AAAA,EAEA,QAAQ,SAAwB;AAC9B,SAAK,QAAQ,OAAO,QAAQ,QAAQ,EAAE;AACtC,SAAK,KAAK,YAAY,QAAQ,OAAO;AAAA,EACvC;AAAA,EAEA,MAAM,OAAO,SAAiB,WAA6C;AACzE,UAAM,UAAU,MAAM,KAAK,YAAY,QAAQ;AAAA,MAC7C;AAAA,MACA;AAAA,MACA;AAAA,IACF;AACA,QAAI,CAAC,QAAQ,KAAM,QAAO;AAC1B,WAAO,QAAQ,aAAa,SACxB,EAAE,MAAM,QAAQ,MAAM,aAAa,QAAQ,YAAY,IACvD,EAAE,MAAM,QAAQ,KAAK;AAAA,EAC3B;AAAA,EAEA,KAAK,UAAkB,KAAK,OAAO,GAAS;AAC1C;AAAA,MACE,KAAK,YAAY,QAAQ,UAAU,SAAS,kBAAkB;AAAA,MAC9D;AAAA,MACA,KAAK,QAAQ,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,KAAK,UAAkB,KAAK,OAAO,GAAY;AAC7C,WAAO,OAAO,KAAK,MAAM,OAAO,CAAC,KAAK,KAAK,MAAM,OAAO;AAAA,EAC1D;AAAA,EAEA,QAAQ,SAAiB,OAAiC;AACxD,WAAO,UAAU,UAAU,KAAK,MAAM,OAAO,IAAI,YAAY;AAAA,EAC/D;AAAA,EAEA,MAAM,SAA0B;AAC9B,WAAO,KAAK,UAAU,QAAQ,aAAa,KAAK,YAAY,QAAQ,OAAO,UAAU;AAAA,EACvF;AAAA,EAEA,MAAM,UAAkB,KAAK,OAAO,GAA2B;AAC7D,UAAM,UAAU,CAAC,GAAG,KAAK,QAAQ,OAAO,CAAC,EACtC,OAAO,CAAC,SAAS,KAAK,YAAY,WAAW,CAAC,KAAK,OAAO,EAC1D,IAAI,CAAC,SAAS,KAAK,OAAO;AAC7B,WAAO,CAAC,GAAG,OAAO,KAAK,MAAM,OAAO,CAAC,GAAG,GAAG,OAAO;AAAA,EACpD;AAAA,EAEA,QAAQ,SAAiB,WAAyB;AAChD,UAAM,UAAU,KAAK,QAAQ,IAAI,SAAS;AAC1C,QAAI,SAAS;AACX,cAAQ,UAAU;AAClB,cAAQ,QAAQ;AAChB,WAAK,KAAK,YAAY,QAAQ,OAAO;AACrC;AAAA,IACF;AACA;AAAA,MACE,KAAK,YAAY,QAAQ,QAAQ,SAAS,UAAU,QAAQ,MAAM,EAAE,GAAG,kBAAkB;AAAA,MACzF;AAAA,MACA,KAAK,QAAQ,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,aAA4B;AAC1B,WAAO;AAAA,EACT;AAAA,EAEA,SAAe;AAAA,EAAC;AAAA,EAEhB,YAAY,SAAiB,WAAmB,OAAwC;AACtF,UAAM,UAAU,KAAK,SAAS,OAAO,EAAE,KAAK,CAAC,cAAc,UAAU,OAAO,SAAS;AACrF,UAAM,QAAQ,KAAK,MAAM,OAAO,GAAG,QAAQ;AAAA,MACzC,CAAC,cAAc,IAAI,UAAU,EAAE,OAAO;AAAA,IACxC;AACA,UAAM,OAAO,SAAS,SAAS,UAAU,QAAQ,UAAU,KAAK,IAAI;AACpE,QAAI;AACF;AAAA,QACE,KAAK,YAAY,QAAQ,iBAAiB,SAAS,KAAK,IAAI,OAAO,kBAAkB;AAAA,QACrF;AAAA,QACA,KAAK,QAAQ,OAAO;AAAA,MACtB;AAAA,EACJ;AAAA,EAEA,QAAQ,UAAkB,KAAK,OAAO,GAAS;AAC7C;AAAA,MACE,KAAK,YAAY,QAAQ,aAAa,SAAS,MAAM,kBAAkB;AAAA,MACvE;AAAA,MACA,KAAK,QAAQ,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,MAAM,UAAkB,KAAK,OAAO,GAAS;AAC3C;AAAA,MACE,KAAK,YAAY,QAAQ,QAAQ,SAAS,kBAAkB;AAAA,MAC5D;AAAA,MACA,KAAK,QAAQ,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,OAAO,UAAkB,KAAK,OAAO,GAAS;AAC5C;AAAA,MACE,KAAK,YAAY,QAAQ,OAAO,SAAS,kBAAkB;AAAA,MAC3D;AAAA,MACA,KAAK,QAAQ,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,WAAW,SAAiB,QAA4C;AACtE;AAAA,MACE,KAAK,YAAY,QAAQ;AAAA,QACvB;AAAA,UACE,OAAO,OAAO,SAAS;AAAA,UACvB,eAAe,OAAO,iBAAiB;AAAA,UACvC;AAAA,QACF;AAAA,QACA;AAAA,MACF;AAAA,MACA;AAAA,MACA,KAAK,QAAQ,OAAO;AAAA,IACtB;AAAA,EACF;AAAA,EAEA,SAAS,SAAiB,OAAqB;AAC7C,UAAM,KAAK,MAAM,QAAQ,GAAG;AAC5B,QAAI,MAAM,EAAG;AACb,SAAK,WAAW,SAAS;AAAA,MACvB,OAAO,EAAE,UAAU,MAAM,MAAM,GAAG,EAAE,GAAG,SAAS,MAAM,MAAM,KAAK,CAAC,EAAE;AAAA,IACtE,CAAC;AAAA,EACH;AAAA,EAEA,YAAY,SAAiB,OAAuB;AAClD,SAAK,WAAW,SAAS,EAAE,eAAe,MAAM,CAAC;AAAA,EACnD;AAAA,EAEA,MAAM,QAAqC;AACzC,WAAO,CAAC;AAAA,EACV;AAAA,EAEA,WAAoC;AAClC,YAAQ,KAAK,YAAY,UAAU,SAAS,CAAC,GAAG,IAAI,YAAY;AAAA,EAClE;AAAA,EAEA,YAAY,UAAkB,MAAqB;AACjD,UAAM,cAAc,kBAAkB,OAAO,WAAW,CAAC;AACzD,UAAM,UAAU,KAAK,YAAY,QAAQ,YAAY,UAAU,MAAM,kBAAkB,EAAE;AAAA,MACvF,CAAC,WAAW,OAAO;AAAA,MACnB,MAAM;AAAA,IACR;AACA,SAAK,UAAU,IAAI,aAAa,OAAO;AACvC,SAAK,QAAQ,KAAK,CAAC,OAAO;AACxB,UAAI,KAAK,YAAY,YAAa;AAClC,WAAK,UAAU,MAAM;AACrB,WAAK,KAAK,UAAU,KAAK,OAAO;AAChC,WAAK,KAAK,YAAY,KAAK,OAAO;AAAA,IACpC,CAAC;AACD,WAAO;AAAA,MACL,IAAI;AAAA,MACJ;AAAA,MACA,MAAM;AAAA,MACN;AAAA,MACA,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,MAAM,KAAK,SAAgC;AACzC,UAAM,SAAS,KAAK,SAAS,EAAE,KAAK,CAAC,YAAY,QAAQ,OAAO,OAAO,GAAG,YAAY;AACtF,UAAM,UAAU,MAAM,KAAK,YAAY,QAAQ,KAAK,SAAS,kBAAkB;AAC/E,QAAI,QAAQ,UAAU,KAAM,OAAM,IAAI,MAAM,QAAQ,KAAK;AACzD,QAAI,KAAK,YAAY,QAAS,MAAK,OAAO,MAAM;AAAA,EAClD;AAAA,EAEA,MAAM,WAAW,MAA8B;AAC7C,UAAM,UAAU,MAAM,KAAK,YAAY,QAAQ,WAAW,MAAM,kBAAkB;AAClF,QAAI,QAAQ,UAAU,KAAM,OAAM,IAAI,MAAM,QAAQ,KAAK;AACzD,WAAO;AAAA,MACL,IAAI,QAAQ;AAAA,MACZ,MAAM,KAAK,KAAK;AAAA,MAChB,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO;AAAA,MACP,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,SAAgC;AAC9B,YAAQ,KAAK,YAAY,QAAQ,SAAS,CAAC,GAAG;AAAA,MAC5C,CAAC,EAAE,IAAI,MAAM,OAAO,OAAO,UAAU,UAAU,MAAM,MAAM,SAAS,OAAO;AAAA,QACzE;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA;AAAA,QACA,GAAI,WAAW,EAAE,SAAS,IAAI,CAAC;AAAA,MACjC;AAAA,IACF;AAAA,EACF;AAAA,EAEA,KAAK,IAA0B;AAC7B,UAAM,SAAS,KAAK,OAAO,EAAE,KAAK,CAAC,SAAS,KAAK,OAAO,EAAE;AAC1D,QAAI,CAAC,OAAQ,QAAO;AACpB,QAAI,OAAO,MAAM;AACf,YAAM,UAAU,KAAK,KAAK,EAAE,KAAK,CAAC,UAAU,MAAM,OAAO,EAAE,KAAK;AAChE,UAAI,QAAS,MAAK,OAAO,EAAE;AAC3B,aAAO;AAAA,IACT;AACA,UAAM,cAAc,WAAW,OAAO,WAAW,CAAC;AAClD,UAAM,SAAS,KAAK,YAAY,QAAQ,KAAK,IAAI,kBAAkB,EAAE;AAAA,MACnE,CAAC,WAAW,OAAO;AAAA,MACnB,MAAM;AAAA,IACR;AACA,SAAK,UAAU,IAAI,aAAa,MAAM;AACtC,SAAK,OAAO,KAAK,CAAC,SAAS;AACzB,UAAI,KAAK,YAAY,YAAa;AAClC,WAAK,UAAU,QAAQ;AACvB,WAAK,KAAK,UAAU,KAAK,OAAO;AAChC,WAAK,KAAK,YAAY,KAAK,OAAO;AAAA,IACpC,CAAC;AACD,WAAO;AAAA,MACL,IAAI;AAAA,MACJ,MAAM,OAAO;AAAA,MACb,MAAM;AAAA,MACN,UAAU;AAAA,MACV,QAAQ;AAAA,MACR,OAAO,OAAO;AAAA,MACd,aAAa;AAAA,MACb,QAAQ;AAAA,IACV;AAAA,EACF;AAAA,EAEA,QAAQ,IAAkB;AACxB;AAAA,MACE,KAAK,YAAY,QAAQ,QAAQ,IAAI,kBAAkB;AAAA,MACvD;AAAA,MACA,KAAK,QAAQ,KAAK,OAAO,CAAC;AAAA,IAC5B;AAAA,EACF;AACF;",
4
+ "sourcesContent": ["import type {\n Agent,\n AgentEvents,\n AgentPort,\n AgentStatus,\n FrozenCone,\n Message,\n Outgoing,\n SlashCommand,\n SystemMessage,\n Thinking,\n UserMessage,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { AgentConnection } from '../client.ts';\nimport { contextRatio, contextTokens } from '../context.ts';\nimport { shrink } from '../images/fit.ts';\nimport { entryLick } from '../licks/state.ts';\nimport { type VaultHold, vaultHold } from '../secrets/view.ts';\nimport type { AgentSettingsChange, AgentSummary, Command } from '../services.ts';\nimport { attempt } from './attempt.ts';\nimport { Emitter } from './emitter.ts';\nimport { isBusy, queued, toMessages } from './messages.ts';\nimport { readUrl, sendAttachments } from './outgoing.ts';\n\nexport const CONE = 'cone';\n\nconst thinking: Record<string, Thinking> = {\n off: 'off',\n minimal: 'low',\n low: 'low',\n medium: 'medium',\n high: 'high',\n xhigh: 'high',\n max: 'high',\n};\n\ninterface AgentDoc {\n model?: { provider: string; modelId: string };\n thinkingLevel?: string;\n}\n\nfunction status(view: ConversationView | undefined, messages: readonly Message[]): AgentStatus {\n if (isBusy(view)) {\n const live = view?.docs['pi.live'] as { tools?: { status: string }[] } | undefined;\n return live?.tools?.some((slot) => slot.status === 'running') ? 'working' : 'thinking';\n }\n const last = messages.at(-1);\n return last?.role === 'assistant' && last.status === 'error' ? 'error' : 'idle';\n}\n\nfunction answers(messages: readonly Message[]): string[] {\n return messages\n .filter((message) => message.role === 'assistant' && message.status !== 'streaming')\n .map((message) => message.id);\n}\n\nexport function slashCommand({ kind, ...command }: Command): SlashCommand {\n return kind === 'action' ? command : { ...command, kind };\n}\n\nexport type AgentHold = VaultHold;\n\nexport type AgentAdapterEvents = AgentEvents & { hold: AgentHold | null };\n\nfunction sameHold(a: AgentHold | null, b: AgentHold | null): boolean {\n return a === b || (a !== null && b !== null && a.reason === b.reason && a.held === b.held);\n}\n\ninterface Pending {\n agentId: string;\n message: UserMessage;\n dropped: boolean;\n release(): void;\n released: Promise<void>;\n}\n\nexport class AgentAdapter extends Emitter<AgentAdapterEvents> implements AgentPort {\n readonly #connection: AgentConnection;\n readonly #ready: Promise<void>;\n readonly #messages = new Map<string, Message[]>();\n #active: string | null = null;\n #creating = new Map<string, Promise<string | null>>();\n #hold: AgentHold | null = null;\n readonly #outbox = new Map<string, Pending>();\n readonly #notices = new Map<string, { at: number; message: SystemMessage }[]>();\n readonly #unread = new Map<string, number>();\n readonly #seen = new Map<string, Set<string>>();\n readonly #queuedAt = new Map<string, Map<string, { at: number; seen: boolean }>>();\n #opened: ReadonlySet<string> | null = null;\n\n constructor(connection: AgentConnection) {\n super();\n this.#connection = connection;\n this.#hold = this.hold();\n connection.vault?.subscribe(() => {\n const next = this.hold();\n if (sameHold(next, this.#hold)) return;\n this.#hold = next;\n if (!next) for (const pending of this.#outbox.values()) pending.release();\n this.emit('hold', next);\n this.emit('agents', this.list());\n });\n connection.frozen?.subscribe(() => {\n this.emit('frozen', this.frozen());\n this.emit('agents', this.list());\n });\n this.#ready = new Promise((resolve) => {\n connection.transcript.subscribe(() => {\n this.#refresh();\n resolve();\n });\n connection.deliveries.subscribe(() => this.#refresh());\n connection.views?.subscribe(() => this.#refresh());\n connection.agents?.subscribe(() => this.#refresh());\n });\n connection.settings?.state.subscribe(() => this.emit('agents', this.list()));\n }\n\n #summary(): readonly AgentSummary[] {\n const agents = this.#connection.agents?.value?.agents;\n return agents?.length\n ? agents\n : [{ id: CONE, name: 'sliccy', kind: 'cone', parentId: null, role: null }];\n }\n\n #view(agentId: string = this.active()): ConversationView | undefined {\n const views = this.#connection.views?.value;\n const view = views?.[agentId];\n if (view) return view;\n const cone = this.#connection.agents?.value?.active ?? CONE;\n return agentId === cone ? this.#connection.transcript.value : undefined;\n }\n\n #refresh(): void {\n this.#active ??= this.#connection.agents?.value?.active ?? null;\n if (!this.#opened && (!this.#connection.agents || this.#connection.agents.value))\n this.#opened = new Set(this.#summary().map((summary) => summary.id));\n for (const summary of this.#summary()) this.#stamp(summary.id, this.#view(summary.id));\n this.emit('agents', this.list());\n let unread = false;\n for (const summary of this.#summary()) unread = this.#update(summary.id) || unread;\n for (const id of [...this.#messages.keys(), ...this.#notices.keys(), ...this.#seen.keys()])\n if (!this.#summary().some((summary) => summary.id === id)) {\n this.#messages.delete(id);\n this.#notices.delete(id);\n this.#seen.delete(id);\n this.#unread.delete(id);\n this.#queuedAt.delete(id);\n }\n if (unread) this.emit('agents', this.list());\n }\n\n #count(agentId: string, view: ConversationView, messages: readonly Message[]): boolean {\n const ids = answers(messages);\n const known = this.#seen.get(agentId);\n if (agentId === this.active() || (!known && (!this.#opened || this.#opened.has(agentId)))) {\n this.#seen.set(agentId, new Set(ids));\n return false;\n }\n const seen = known ?? new Set<string>();\n this.#seen.set(agentId, seen);\n const fresh = isBusy(view) ? [] : ids.filter((id) => !seen.has(id));\n if (!fresh.length) return false;\n for (const id of fresh) seen.add(id);\n this.#unread.set(agentId, (this.#unread.get(agentId) ?? 0) + fresh.length);\n return true;\n }\n\n notify(text: string, agentId: string = this.active()): void {\n const notes = this.#notices.get(agentId) ?? [];\n notes.push({\n at: this.#messages.get(agentId)?.length ?? 0,\n message: {\n id: `n${crypto.randomUUID()}`,\n role: 'system',\n kind: 'notice',\n text,\n createdAt: Date.now(),\n },\n });\n this.#notices.set(agentId, notes);\n this.emit('messages', agentId);\n }\n\n #report(agentId: string): (text: string) => void {\n return (text) => this.notify(text, agentId);\n }\n\n #update(agentId: string): boolean {\n const view = this.#view(agentId);\n if (!view) return false;\n const before = this.#messages.get(agentId) ?? [];\n const after = toMessages(view, this.#connection.deliveries.value);\n this.#messages.set(agentId, after);\n if (before.length !== after.length) this.emit('messages', agentId);\n else {\n const changed = after.filter(\n (message, index) => JSON.stringify(message) !== JSON.stringify(before[index])\n );\n if (changed.length === 1) this.emit('message', { agentId, message: changed[0] as Message });\n else if (changed.length > 1) this.emit('messages', agentId);\n }\n return this.#count(agentId, view, after);\n }\n\n ready(): Promise<void> {\n return this.#ready;\n }\n\n hold(): AgentHold | null {\n return vaultHold(this.#connection.vault?.value);\n }\n\n list(): readonly Agent[] {\n const rows = this.#connection.frozen?.value ?? [];\n return this.#summary().map((summary) => {\n const view = this.#view(summary.id);\n const doc = view?.docs['pi.agent'] as AgentDoc | undefined;\n const title = rows.find((row) => row.id === summary.id)?.title;\n const model = doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : '';\n const models = this.#connection.settings?.state.value?.models ?? [];\n return {\n id: summary.id,\n name: summary.role ? `${summary.name} \u00B7 ${summary.role}` : summary.name,\n kind: summary.kind,\n parentId: summary.parentId,\n status: this.#status(summary.id, status(view, this.#messages.get(summary.id) ?? [])),\n model,\n contextFill: contextRatio(contextTokens(view), model, models) ?? 0,\n unread: this.#unread.get(summary.id) ?? 0,\n thinking: thinking[doc?.thinkingLevel ?? 'off'] ?? 'off',\n ...(title ? { title } : {}),\n };\n });\n }\n\n active(): string {\n const known = this.#summary();\n if (this.#active && this.#creating.has(this.#active)) return this.#active;\n if (this.#active && known.some((summary) => summary.id === this.#active)) return this.#active;\n return this.#connection.agents?.value?.active ?? CONE;\n }\n\n select(id: string): void {\n if (this.#creating.has(id)) {\n this.#active = id;\n this.emit('active', id);\n return;\n }\n const found = this.#summary().find((summary) => summary.id === id);\n if (!found) return;\n this.#active = id;\n this.#seen.set(id, new Set(answers(this.#messages.get(id) ?? [])));\n const read = this.#unread.delete(id);\n if (found.kind === 'cone')\n attempt(\n this.#connection.control.selectCone(id, BACKGROUND_CONTEXT),\n 'switch cones',\n this.#report(id)\n );\n this.emit('active', id);\n this.emit('messages', id);\n if (read) this.emit('agents', this.list());\n }\n\n messages(agentId: string = this.active()): readonly Message[] {\n const shown = this.#messages.get(agentId) ?? [];\n const notes = this.#notices.get(agentId);\n if (!notes) return shown;\n const at = (index: number) => notes.filter((note) => note.at === index).map((n) => n.message);\n const late = notes.filter((note) => note.at >= shown.length).map((note) => note.message);\n return [...shown.flatMap((message, index) => [...at(index), message]), ...late];\n }\n\n async send(agentId: string, input: string | Outgoing): Promise<void> {\n const outgoing = typeof input === 'string' ? { text: input } : input;\n const attachments = outgoing.attachments?.length\n ? await sendAttachments(outgoing.attachments, readUrl, shrink, (ref) =>\n this.#connection.control.image(ref, BACKGROUND_CONTEXT)\n ).catch((error: Error) => {\n this.notify(error.message, agentId);\n return null;\n })\n : [];\n if (!attachments) return;\n const target = this.#creating.has(agentId) ? await this.#creating.get(agentId) : agentId;\n if (target === null) throw new Error('The scoop could not be created.');\n const pending = target && this.#held(target) ? this.#pending(target, outgoing) : undefined;\n if (pending) await pending.released;\n if (pending?.dropped) return this.#settle(pending);\n const at = Date.now();\n const sent = await this.#connection.control\n .send(\n {\n text: outgoing.text,\n whenBusy: outgoing.mode === 'queue' ? 'followUp' : 'steer',\n requestId: crypto.randomUUID(),\n agentId: target || null,\n ...(attachments.length ? { attachments } : {}),\n },\n BACKGROUND_CONTEXT\n )\n .finally(() => pending && this.#settle(pending));\n if (!sent.accepted) throw new Error(sent.error.message);\n this.#sent(target || agentId, `q${sent.submissionId}`, at);\n if (pending?.dropped)\n attempt(\n this.#connection.control.unqueue(pending.agentId, sent.submissionId, BACKGROUND_CONTEXT),\n 'remove queued messages',\n this.#report(pending.agentId)\n );\n }\n\n #stamps(agentId: string): Map<string, { at: number; seen: boolean }> {\n const stamps = this.#queuedAt.get(agentId) ?? new Map();\n this.#queuedAt.set(agentId, stamps);\n return stamps;\n }\n\n #sent(agentId: string, id: string, at: number): void {\n const stamps = this.#stamps(agentId);\n const known = stamps.get(id);\n stamps.set(id, { at: Math.min(at, known?.at ?? at), seen: known?.seen ?? false });\n }\n\n #stamp(agentId: string, view: ConversationView | undefined): void {\n const stamps = this.#stamps(agentId);\n const ids = new Set(queued(view).map((message) => message.id));\n const now = Date.now();\n for (const id of ids) stamps.set(id, { at: stamps.get(id)?.at ?? now, seen: true });\n for (const [id, stamp] of stamps)\n if (!ids.has(id) && (stamp.seen || (!ids.size && !isBusy(view)))) stamps.delete(id);\n }\n\n #pending(agentId: string, outgoing: Outgoing): Pending {\n const id = `p${crypto.randomUUID()}`;\n const message: UserMessage = {\n id,\n role: 'user',\n text: outgoing.text,\n createdAt: Date.now(),\n ...(outgoing.attachments?.length ? { attachments: [...outgoing.attachments] } : {}),\n queued: true,\n mode: outgoing.mode === 'queue' ? 'queue' : 'steer',\n };\n const { promise: released, resolve: release } = Promise.withResolvers<void>();\n const pending = { agentId, message, dropped: false, release, released };\n this.#outbox.set(id, pending);\n this.emit('messages', agentId);\n return pending;\n }\n\n #settle(pending: Pending): void {\n this.#outbox.delete(pending.message.id);\n this.emit('messages', pending.agentId);\n }\n\n async rewind(agentId: string, messageId: string): Promise<Outgoing | null> {\n const rewound = await this.#connection.control.rewindAgent(\n agentId,\n messageId,\n BACKGROUND_CONTEXT\n );\n if (!rewound.done) return null;\n return rewound.attachments?.length\n ? { text: rewound.text, attachments: rewound.attachments }\n : { text: rewound.text };\n }\n\n stop(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.stopAgent(agentId, BACKGROUND_CONTEXT),\n 'stop agents',\n this.#report(agentId)\n );\n }\n\n busy(agentId: string = this.active()): boolean {\n return isBusy(this.#view(agentId)) || this.#held(agentId);\n }\n\n #status(agentId: string, shown: AgentStatus): AgentStatus {\n return shown === 'idle' && this.#held(agentId) ? 'working' : shown;\n }\n\n #held(agentId: string): boolean {\n return this.#hold !== null && agentId === (this.#connection.agents?.value?.active ?? CONE);\n }\n\n queue(agentId: string = this.active()): readonly UserMessage[] {\n const pending = [...this.#outbox.values()]\n .filter((item) => item.agentId === agentId && !item.dropped)\n .map((item) => item.message);\n const stamps = this.#queuedAt.get(agentId);\n const at = (id: string) => stamps?.get(id)?.at ?? 0;\n return [...queued(this.#view(agentId), at), ...pending];\n }\n\n unqueue(agentId: string, messageId: string): void {\n const pending = this.#outbox.get(messageId);\n if (pending) {\n pending.dropped = true;\n pending.release();\n this.emit('messages', pending.agentId);\n return;\n }\n attempt(\n this.#connection.control.unqueue(agentId, messageId.replace(/^q/, ''), BACKGROUND_CONTEXT),\n 'remove queued messages',\n this.#report(agentId)\n );\n }\n\n suggestion(): string | null {\n return null;\n }\n\n answer(): void {}\n\n resolveLick(agentId: string, messageId: string, state: 'confirmed' | 'dismissed'): void {\n const message = this.messages(agentId).find((candidate) => candidate.id === messageId);\n const entry = this.#view(agentId)?.entries.find(\n (candidate) => `e${candidate.id}` === messageId\n );\n const lick = message?.role === 'lick' && entry ? entryLick(entry) : undefined;\n if (lick)\n attempt(\n this.#connection.control.resolveAgentLick(agentId, lick.id, state, BACKGROUND_CONTEXT),\n 'answer licks',\n this.#report(agentId)\n );\n }\n\n compact(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.compactAgent(agentId, null, BACKGROUND_CONTEXT),\n 'compact conversations',\n this.#report(agentId)\n );\n }\n\n clear(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.newChat(agentId, BACKGROUND_CONTEXT),\n 'start new chats',\n this.#report(agentId)\n );\n }\n\n freeze(agentId: string = this.active()): void {\n attempt(\n this.#connection.control.freeze(agentId, BACKGROUND_CONTEXT),\n 'freeze cones',\n this.#report(agentId)\n );\n }\n\n #configure(agentId: string, change: Partial<AgentSettingsChange>): void {\n attempt(\n this.#connection.control.configure(\n {\n model: change.model ?? null,\n thinkingLevel: change.thinkingLevel ?? null,\n agentId,\n },\n BACKGROUND_CONTEXT\n ),\n 'change agent settings',\n this.#report(agentId)\n );\n }\n\n setModel(agentId: string, model: string): void {\n const at = model.indexOf('/');\n if (at <= 0) return;\n this.#configure(agentId, {\n model: { provider: model.slice(0, at), modelId: model.slice(at + 1) },\n });\n }\n\n setThinking(agentId: string, level: Thinking): void {\n this.#configure(agentId, { thinkingLevel: level });\n }\n\n async older(): Promise<readonly Message[]> {\n return [];\n }\n\n commands(): readonly SlashCommand[] {\n return (this.#connection.commands?.value ?? []).map(slashCommand);\n }\n\n createScoop(parentId: string, name: string): Agent {\n const provisional = `scoop:creating-${crypto.randomUUID()}`;\n const created = this.#connection.control.createScoop(parentId, name, BACKGROUND_CONTEXT).then(\n (result) => result.id,\n () => null\n );\n this.#creating.set(provisional, created);\n void created.then((id) => {\n if (this.#active !== provisional) return;\n this.#active = id ?? parentId;\n this.emit('active', this.#active);\n this.emit('messages', this.#active);\n });\n return {\n id: provisional,\n name,\n kind: 'scoop',\n parentId,\n status: 'idle',\n model: '',\n contextFill: 0,\n unread: 0,\n };\n }\n\n async drop(agentId: string): Promise<void> {\n const parent = this.#summary().find((summary) => summary.id === agentId)?.parentId ?? CONE;\n const dropped = await this.#connection.control.drop(agentId, BACKGROUND_CONTEXT);\n if (dropped.error !== null) throw new Error(dropped.error);\n if (this.#active === agentId) this.select(parent);\n }\n\n async createCone(name: string): Promise<Agent> {\n const created = await this.#connection.control.createCone(name, BACKGROUND_CONTEXT);\n if (created.error !== null) throw new Error(created.error);\n return {\n id: created.id,\n name: name.trim(),\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: '',\n contextFill: 0,\n unread: 0,\n };\n }\n\n frozen(): readonly FrozenCone[] {\n return (this.#connection.frozen?.value ?? []).map(\n ({ id, name, title, model, messages, frozenAt, kind, live, thawedAs }) => ({\n id,\n name,\n title,\n model,\n messages,\n frozenAt,\n kind,\n live,\n ...(thawedAs ? { thawedAs } : {}),\n })\n );\n }\n\n thaw(id: string): Agent | null {\n const record = this.frozen().find((item) => item.id === id);\n if (!record) return null;\n if (record.live) {\n const running = this.list().find((agent) => agent.id === id) ?? null;\n if (running) this.select(id);\n return running;\n }\n const provisional = `thawing-${crypto.randomUUID()}`;\n const thawed = this.#connection.control.thaw(id, BACKGROUND_CONTEXT).then(\n (result) => result.id,\n () => null\n );\n this.#creating.set(provisional, thawed);\n void thawed.then((cone) => {\n if (this.#active !== provisional) return;\n this.#active = cone ?? CONE;\n this.emit('active', this.#active);\n this.emit('messages', this.#active);\n });\n return {\n id: provisional,\n name: record.name,\n kind: 'cone',\n parentId: null,\n status: 'idle',\n model: record.model,\n contextFill: 0,\n unread: 0,\n };\n }\n\n discard(id: string): void {\n attempt(\n this.#connection.control.discard(id, BACKGROUND_CONTEXT),\n 'discard frozen cones',\n this.#report(this.active())\n );\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -415,13 +415,13 @@ function shownUser(content, prefix) {
415
415
  function isBusy(view) {
416
416
  return Boolean(view?.docs["pi.live"]?.run);
417
417
  }
418
- function queued(view) {
418
+ function queued(view, at = () => 0) {
419
419
  const items = view?.docs["pi.inbox"]?.items ?? [];
420
420
  return items.filter((item) => item.mode !== "write" && !parseLick(textOf(item.content))).map((item) => ({
421
421
  id: `q${item.id}`,
422
422
  role: "user",
423
423
  ...shownUser(item.content),
424
- createdAt: 0,
424
+ createdAt: at(`q${item.id}`),
425
425
  queued: true,
426
426
  mode: item.mode === "steer" ? "steer" : "queue"
427
427
  }));