@ai-ecoverse/slicc-agent 3.43.0 → 3.44.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +15 -5
- package/dist/agent.js +1 -0
- package/dist/agent.js.map +2 -2
- package/dist/browser/guard.js +19 -24
- package/dist/browser/guard.js.map +2 -2
- package/dist/browser/origins.js +7 -37
- package/dist/browser/origins.js.map +2 -2
- package/dist/client.js +3 -1
- package/dist/client.js.map +2 -2
- package/dist/codemode/index.js +2 -1
- package/dist/codemode/index.js.map +2 -2
- package/dist/control.js +13 -3
- package/dist/control.js.map +2 -2
- package/dist/freezer/index.js +5 -4
- package/dist/freezer/index.js.map +2 -2
- package/dist/host.js +13 -2
- package/dist/host.js.map +2 -2
- package/dist/kernel/env.js +55 -4
- package/dist/kernel/env.js.map +2 -2
- package/dist/kernel/exec.js +84 -16
- package/dist/kernel/exec.js.map +3 -3
- package/dist/licks/licks.js +17 -1
- package/dist/licks/licks.js.map +2 -2
- package/dist/main.js +29 -10
- package/dist/main.js.map +2 -2
- package/dist/mcp/content.js +3 -1
- package/dist/mcp/content.js.map +2 -2
- package/dist/mcp/tools.js +2 -1
- package/dist/mcp/tools.js.map +2 -2
- package/dist/memory/prompt.js +3 -2
- package/dist/memory/prompt.js.map +2 -2
- package/dist/memory/store.js +5 -3
- package/dist/memory/store.js.map +2 -2
- package/dist/remote/host.js +21 -1
- package/dist/remote/host.js.map +2 -2
- package/dist/secrets/extension.js +150 -0
- package/dist/secrets/extension.js.map +7 -0
- package/dist/secrets/names.js +72 -0
- package/dist/secrets/names.js.map +7 -0
- package/dist/secrets/scrub.js +36 -0
- package/dist/secrets/scrub.js.map +7 -0
- package/dist/secrets/vault.js +161 -0
- package/dist/secrets/vault.js.map +7 -0
- package/dist/services.js.map +2 -2
- package/dist/skills/index.js +8 -1
- package/dist/skills/index.js.map +2 -2
- package/dist/spectrum/agent-port.js +6 -2
- package/dist/spectrum/agent-port.js.map +2 -2
- package/dist/types/agent.d.ts +1 -0
- package/dist/types/browser/guard.d.ts +5 -3
- package/dist/types/browser/origins.d.ts +19 -4
- package/dist/types/client.d.ts +2 -0
- package/dist/types/control.d.ts +2 -1
- package/dist/types/host.d.ts +9 -1
- package/dist/types/kernel/env.d.ts +6 -0
- package/dist/types/kernel/exec.d.ts +8 -1
- package/dist/types/licks/licks.d.ts +1 -0
- package/dist/types/mcp/content.d.ts +1 -1
- package/dist/types/remote/host.d.ts +5 -1
- package/dist/types/secrets/extension.d.ts +31 -0
- package/dist/types/secrets/names.d.ts +24 -0
- package/dist/types/secrets/scrub.d.ts +21 -0
- package/dist/types/secrets/vault.d.ts +30 -0
- package/dist/types/services.d.ts +3 -1
- package/dist/types/skills/index.d.ts +1 -0
- package/dist/types/spectrum/agent-port.d.ts +2 -0
- package/package.json +4 -3
package/dist/control.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/control.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n type AgentChange,\n AssistantEntry,\n type Conversation,\n ConversationBusy,\n type ConversationView,\n type EntryId,\n type EntryRecord,\n type Harness,\n type SubmissionId,\n} from '@earendil-works/pi-durable';\nimport { answerText } from './agent.ts';\nimport type { Agents } from './agents.ts';\nimport type { ChangesRuntime } from './changes/index.ts';\nimport type { Cones } from './cone.ts';\nimport type { Deliveries } from './deliveries.ts';\nimport type { FreezerRuntime } from './freezer/index.ts';\nimport type { LickSources, Licks } from './licks/index.ts';\nimport { LICK_STATE_KIND } from './licks/state.ts';\nimport type { MemoryRuntime } from './memory/index.ts';\nimport type { Monitor } from './monitor/index.ts';\nimport type { Scoops, ScoopsRuntime } from './scoops/index.ts';\nimport type {\n AgentControl,\n Created,\n LickResolved,\n OperationError,\n Rewound,\n SendResponse,\n} from './services.ts';\nimport type { SkillsRuntime } from './skills/index.ts';\nimport type { SprinklesRuntime } from './sprinkles/index.ts';\n\nexport interface HostLicks {\n licks: Licks;\n sources: LickSources;\n}\n\nexport interface HostScoops {\n scoops: Scoops;\n runtime: ScoopsRuntime;\n}\n\ntype WithAgents = { agents?: Agents };\n\nexport function readable(out: string): string {\n const text = out.replace(/^(?:sub)?agent: /, '').trim();\n const sentence = text.charAt(0).toUpperCase() + text.slice(1);\n return /[.!?]$/.test(sentence) ? sentence : `${sentence}.`;\n}\n\nfunction created(run: () => Promise<string>): Promise<Created> {\n return run().then(\n (id) => ({ id, error: null }),\n (error: Error) => ({ id: null, error: error.message })\n );\n}\n\nfunction freezerControl(\n freezer: Pick<FreezerRuntime, 'freeze' | 'newChat' | 'thaw' | 'discard'> | undefined\n): Pick<AgentControl, 'freeze' | 'newChat' | 'thaw' | 'discard'> {\n const needed = () => {\n if (!freezer) throw new Error('This agent has no freezer.');\n return freezer;\n };\n return {\n freeze: (agentId, context) => created(async () => needed().freeze(agentId, context)),\n newChat: (agentId, context) =>\n created(async () => (await needed().newChat(agentId, context)) ?? ''),\n thaw: (id, context) => created(async () => needed().thaw(id, context)),\n discard: (id, context) =>\n created(async () => {\n await needed().discard(id, context);\n return id;\n }),\n };\n}\n\nfunction changesControl(\n changes: Pick<ChangesRuntime, 'open' | 'accept' | 'revert'> | undefined\n): Pick<AgentControl, 'changesOpen' | 'changeAccept' | 'changeRevert'> {\n const needed = () => {\n if (!changes) throw new Error('This agent tracks no changes.');\n return changes;\n };\n const done = (path: string, run: (runtime: NonNullable<typeof changes>) => Promise<void>) =>\n created(async () => {\n await run(needed());\n return path;\n });\n return {\n changesOpen: async (context) => changes?.open(context),\n changeAccept: (path, context) => done(path, (runtime) => runtime.accept(path, context)),\n changeRevert: (path, context) => done(path, (runtime) => runtime.revert(path, context)),\n };\n}\n\nfunction memoryControl(\n memory: Pick<MemoryRuntime, 'save' | 'remove'> | undefined\n): Pick<AgentControl, 'memorySave' | 'memoryRemove'> {\n return {\n async memorySave(draft, context) {\n if (!memory) throw new Error('This agent has no memory.');\n const { id, ...rest } = draft;\n return memory.save({ ...rest, ...(id ? { id } : {}) }, context);\n },\n async memoryRemove(id, context) {\n return { removed: memory ? await memory.remove(id, context) : false };\n },\n };\n}\n\nfunction sprinkleControl(\n sprinkles: Pick<SprinklesRuntime, 'send' | 'call'> | undefined\n): Pick<AgentControl, 'sprinkleSend' | 'sprinkleCall'> {\n return {\n sprinkleSend: async (id, payload, context) =>\n sprinkles ? sprinkles.send(id, payload, context) : { delivered: false },\n async sprinkleCall(id, method, args, context) {\n if (!sprinkles) throw new Error('This agent has no sprinkles.');\n return sprinkles.call(id, method, args, context);\n },\n };\n}\n\nexport function submissionId(value: string): SubmissionId | undefined {\n const id = Number(value);\n return /^[1-9][0-9]*$/.test(value) && Number.isSafeInteger(id) ? (id as SubmissionId) : undefined;\n}\n\nfunction operationError(error: unknown): OperationError {\n if (error instanceof ConversationBusy) return { code: 'busy', message: error.message };\n return { code: 'failed', message: error instanceof Error ? error.message : String(error) };\n}\n\nasync function accepted(operation: () => Promise<{ id: number } | number>): Promise<SendResponse> {\n try {\n const result = await operation();\n const id = typeof result === 'number' ? result : result.id;\n return { accepted: true, submissionId: String(id), error: null };\n } catch (error) {\n return { accepted: false, submissionId: null, error: operationError(error) };\n }\n}\n\nfunction cones(target: Conversation | Cones): Cones {\n if ('cone' in target) return target;\n return {\n cone: () => target,\n switchCone: async () => {\n throw new Error('this conversation has no cone to rewind');\n },\n };\n}\n\ninterface Turn {\n text: string;\n at: EntryId | null;\n files: boolean;\n}\n\ntype Block = { type?: string; name?: string };\n\nconst WRITERS = ['write', 'edit', 'bash', 'codemode'];\n\nfunction writesIn(entries: readonly EntryRecord[]): boolean {\n return entries.some((entry) =>\n (entry.model ?? []).some(\n (message) =>\n Array.isArray(message.content) &&\n (message.content as Block[]).some(\n (block) => block.type === 'toolCall' && WRITERS.includes(String(block.name))\n )\n )\n );\n}\n\nfunction lastTurn(view: ConversationView, messageId: string | null): Turn | null {\n const { entries } = view;\n const target = entries.findIndex((entry) => `e${entry.id}` === messageId);\n if (target < 0) return null;\n const turn = entries.slice(0, target).findLastIndex((entry) => entry.kind === 'pi.user');\n if (turn < 0) return null;\n const user = entries[turn] as EntryRecord;\n return {\n text: answerText(user.model?.[0]?.content),\n at: entries[turn - 1]?.id ?? null,\n files: writesIn(entries.slice(turn)),\n };\n}\n\nfunction busy(view: ConversationView): boolean {\n const live = view.docs['pi.live'] as { run?: unknown } | undefined;\n const inbox = view.docs['pi.inbox'] as { items?: unknown[] } | undefined;\n return Boolean(live?.run) || Boolean(inbox?.items?.length);\n}\n\ntype RewindDeps = {\n harness: Harness;\n agents?: Agents;\n cone: Cones;\n scoops?: HostScoops;\n};\n\nasync function turnIn(\n harness: Harness,\n conversation: Conversation,\n messageId: string | null,\n context: Context\n): Promise<{ turn: Turn; view: ConversationView } | Rewound> {\n const attached = await conversation.viewState(context);\n const view = attached.value;\n attached.dispose();\n const pending = (await harness.inspect(context)).submissions.some(\n (submission) => submission.conversationId === conversation.id\n );\n if (pending || busy(view)) return { done: false, text: null, reason: 'busy' };\n const turn = lastTurn(view, messageId);\n return turn ? { turn, view } : { done: false, text: null, reason: 'no-turn' };\n}\n\nasync function forkAt(\n harness: Harness,\n conversation: Conversation,\n found: { turn: Turn },\n context: Context\n): Promise<Conversation> {\n const ownership = { kind: 'ownerless' } as const;\n if (found.turn.at !== null) return conversation.fork(found.turn.at, { ownership }, context);\n const agent = await conversation.agent(context);\n const change: AgentChange = {\n model: agent.model ?? null,\n thinkingLevel: agent.thinkingLevel,\n extensions: agent.extensions,\n tools: agent.tools,\n instructions: agent.instructions ?? null,\n cwd: agent.cwd ?? null,\n };\n return harness.createConversation({ ownership, agent: change }, context);\n}\n\nasync function rewindAgent(\n deps: RewindDeps,\n agentId: string | null,\n messageId: string | null,\n context: Context\n): Promise<Rewound> {\n const { harness, agents, cone, scoops } = deps;\n const scoop = agentId && agents ? agents.state().scoops[agentId] : undefined;\n if (agentId && agents && !scoop && agentId !== agents.activeCone())\n await agents.selectCone(agentId, context);\n const conversation =\n scoop && agents\n ? ((await agents.conversation(agentId as string, context)) as Conversation)\n : cone.cone();\n const found = await turnIn(harness, conversation, messageId, context);\n if ('reason' in found) return found;\n const fork = await forkAt(harness, conversation, found, context);\n const changed =\n scoops && agents && !scoop\n ? await scoops.scoops.rewound(agents.activeCone(), fork, context)\n : { stopped: [], restored: [] };\n const files = found.turn.files;\n await fork.submit(\n { type: 'write', entry: { kind: 'slicc.rewound', data: { turns: 1, ...changed, files } } },\n context\n );\n if (scoop && agents)\n await agents.update((_tx, state) => {\n (state.scoops[agentId as string] as { conversation: number }).conversation = fork.id;\n }, context);\n else await cone.switchCone(fork, context);\n return { done: true, text: found.turn.text, reason: null };\n}\n\nexport function createAgentControl(\n harness: Harness,\n target: Conversation | Cones,\n deliveries?: Deliveries,\n licks?: HostLicks,\n scoops?: HostScoops,\n skills?: Pick<SkillsRuntime, 'expand'>,\n sprinkles?: Pick<SprinklesRuntime, 'send' | 'call'>,\n memory?: Pick<MemoryRuntime, 'save' | 'remove'>,\n freezer?: Pick<FreezerRuntime, 'freeze' | 'newChat' | 'thaw' | 'discard'>,\n changes?: Pick<ChangesRuntime, 'open' | 'accept' | 'revert'>,\n monitor?: Pick<Monitor, 'open' | 'close'>\n): AgentControl {\n const cone = cones(target);\n const current = () => cone.cone();\n const agents = (target as WithAgents).agents;\n const conversationFor = async (agentId: string | null | undefined, context: Context) => {\n if (!agentId || !agents) return current();\n const found = await agents.conversation(agentId, context);\n if (!found) throw new Error(`There is no agent ${agentId}.`);\n return found;\n };\n const withdraw = async (conversation: Conversation, id: string, context: Context) => {\n const parsed = submissionId(id);\n if (parsed === undefined) return { outcome: 'not_found' as const };\n const result = await harness.abortSubmission(parsed, context, conversation.id);\n if (result === 'aborted') return { outcome: 'withdrawn' as const };\n return {\n outcome: result === 'not_found' ? ('not_found' as const) : ('already_placed' as const),\n };\n };\n let lock: Promise<unknown> = Promise.resolve();\n const serial = <T>(operation: () => Promise<T>): Promise<T> => {\n const run = lock.then(operation, operation);\n lock = run.catch(() => undefined);\n return run;\n };\n const rewindIn = (agentId: string | null, messageId: string | null, context: Context) =>\n serial(() => rewindAgent({ harness, agents, cone, scoops }, agentId, messageId, context));\n const decide = (\n agentId: string | null,\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved> =>\n serial(async () => {\n if (!licks) return { done: false, text: null, error: 'this agent has no licks' };\n const action = state === 'confirmed' ? 'confirm' : 'dismiss';\n try {\n const conversation = await conversationFor(agentId, context);\n const text = await licks.licks.decide(conversation, lickId, action, undefined, context);\n await conversation.submit(\n {\n type: 'write',\n entry: {\n kind: LICK_STATE_KIND,\n data: { lick: lickId, state, by: 'user' },\n model: [\n {\n role: 'user',\n content: `The user ${state} lick ${lickId}: ${text}`,\n timestamp: Date.now(),\n },\n ],\n },\n },\n context\n );\n return { done: true, text, error: null };\n } catch (error) {\n return { done: false, text: null, error: (error as Error).message };\n }\n });\n return {\n send(request, context) {\n return serial(async () => {\n const text = skills ? await skills.expand(request.text, context) : request.text;\n const response = await accepted(async () =>\n (await conversationFor(request.agentId, context)).submit(\n {\n type: 'input',\n content: text,\n whenBusy: request.whenBusy,\n ...(request.requestId ? { requestId: request.requestId } : {}),\n },\n context\n )\n );\n const id = response.submissionId === null ? undefined : submissionId(response.submissionId);\n if (id !== undefined) deliveries?.expect(id, request.whenBusy);\n return response;\n });\n },\n rewind: (messageId, context) => rewindIn(null, messageId, context),\n rewindAgent: (agentId, messageId, context) => rewindIn(agentId, messageId, context),\n\n async wait(id, context) {\n const parsed = submissionId(id);\n const submission =\n parsed === undefined ? undefined : await harness.submission(parsed, context);\n if (!submission) throw new Error(`unknown submission ${id}`);\n const settled = await submission.wait(context);\n const { answer, reason } = settled as { answer?: EntryId; reason?: string };\n if (answer === undefined) return { status: 'unanswered', text: null, reason: String(reason) };\n const entry = await harness.commit((tx) => tx.entry(AssistantEntry, answer), context);\n return { status: 'done', text: answerText(entry?.model?.[0]?.content), reason: null };\n },\n withdraw: (id, context) => withdraw(current(), id, context),\n ...sprinkleControl(sprinkles),\n ...memoryControl(memory),\n ...freezerControl(freezer),\n ...changesControl(changes),\n monitorOpen: async (lease, resync, context) =>\n monitor ? monitor.open(lease, resync, context) : { lease: '', ttlMs: 0 },\n monitorClose: async (lease, context) => monitor?.close(lease, context),\n async unqueue(agentId, id, context) {\n return withdraw(await conversationFor(agentId, context), id, context);\n },\n abort: (context) => current().abort(context),\n compact: (instructions, context) =>\n accepted(() => current().compact(instructions ?? undefined, context)),\n compactAgent: (agentId, instructions, context) =>\n accepted(async () =>\n (await conversationFor(agentId, context)).compact(instructions ?? undefined, context)\n ),\n reset: (handoff, context) => current().reset(handoff ?? undefined, context),\n resolveLick: (lickId, state, context) => decide(null, lickId, state, context),\n resolveAgentLick: (agentId, lickId, state, context) => decide(agentId, lickId, state, context),\n async webhook(name, delivery, context) {\n const delivered = licks\n ? await licks.sources.webhook(\n name,\n {\n ...(delivery.id ? { id: delivery.id } : {}),\n headers: delivery.headers,\n body: delivery.body,\n },\n context\n )\n : false;\n return { delivered };\n },\n async stopAgent(agentId, context) {\n await (await conversationFor(agentId, context)).abort(context);\n },\n async selectCone(agentId, context) {\n await agents?.selectCone(agentId, context);\n },\n createCone(name, context) {\n return created(async () => {\n if (!agents) throw new Error('This agent has a single cone.');\n return agents.createCone(name, context);\n });\n },\n createScoop(parentId, name, context) {\n return created(async () => {\n if (!scoops) throw new Error('This agent has no scoops.');\n const roles = await scoops.runtime.roles(context);\n const answer = await scoops.scoops.spawn(\n { cone: parentId, name, prompts: [], fromAgent: false, limits: roles.limits },\n context\n );\n if (answer.code !== 0) throw new Error(readable(answer.out));\n return `scoop:${answer.out.trim()}`;\n });\n },\n drop(agentId, context) {\n return created(async () => {\n if (!scoops) throw new Error('This agent has no scoops.');\n const answer = await scoops.scoops.stop(agentId, false, context);\n if (answer.code !== 0) throw new Error(readable(answer.out));\n return agentId;\n });\n },\n configure: async (change, context) =>\n (await conversationFor(change.agentId, context)).configure(\n {\n ...(change.model ? { model: change.model } : {}),\n ...(change.thinkingLevel ? { thinkingLevel: change.thinkingLevel } : {}),\n },\n context\n ),\n };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n type AgentChange,\n AssistantEntry,\n type Conversation,\n ConversationBusy,\n type ConversationView,\n type EntryId,\n type EntryRecord,\n type Harness,\n type SubmissionId,\n} from '@earendil-works/pi-durable';\nimport { answerText } from './agent.ts';\nimport type { Agents } from './agents.ts';\nimport type { ChangesRuntime } from './changes/index.ts';\nimport type { Cones } from './cone.ts';\nimport type { Deliveries } from './deliveries.ts';\nimport type { FreezerRuntime } from './freezer/index.ts';\nimport type { LickSources, Licks } from './licks/index.ts';\nimport { LICK_STATE_KIND } from './licks/state.ts';\nimport type { MemoryRuntime } from './memory/index.ts';\nimport type { Monitor } from './monitor/index.ts';\nimport type { Scoops, ScoopsRuntime } from './scoops/index.ts';\nimport { pinned, SECRETS_COMMAND, secretsEntry } from './secrets/extension.ts';\nimport type { SecretName } from './secrets/names.ts';\nimport { scrubText } from './secrets/scrub.ts';\nimport type {\n AgentControl,\n Created,\n LickResolved,\n OperationError,\n Rewound,\n SendResponse,\n} from './services.ts';\nimport type { SkillsRuntime } from './skills/index.ts';\nimport type { SprinklesRuntime } from './sprinkles/index.ts';\n\nexport interface HostLicks {\n licks: Licks;\n sources: LickSources;\n}\n\nexport interface HostScoops {\n scoops: Scoops;\n runtime: ScoopsRuntime;\n}\n\ntype WithAgents = { agents?: Agents };\n\nexport function readable(out: string): string {\n const text = out.replace(/^(?:sub)?agent: /, '').trim();\n const sentence = text.charAt(0).toUpperCase() + text.slice(1);\n return /[.!?]$/.test(sentence) ? sentence : `${sentence}.`;\n}\n\nfunction created(run: () => Promise<string>): Promise<Created> {\n return run().then(\n (id) => ({ id, error: null }),\n (error: Error) => ({ id: null, error: error.message })\n );\n}\n\nfunction freezerControl(\n freezer: Pick<FreezerRuntime, 'freeze' | 'newChat' | 'thaw' | 'discard'> | undefined\n): Pick<AgentControl, 'freeze' | 'newChat' | 'thaw' | 'discard'> {\n const needed = () => {\n if (!freezer) throw new Error('This agent has no freezer.');\n return freezer;\n };\n return {\n freeze: (agentId, context) => created(async () => needed().freeze(agentId, context)),\n newChat: (agentId, context) =>\n created(async () => (await needed().newChat(agentId, context)) ?? ''),\n thaw: (id, context) => created(async () => needed().thaw(id, context)),\n discard: (id, context) =>\n created(async () => {\n await needed().discard(id, context);\n return id;\n }),\n };\n}\n\nfunction changesControl(\n changes: Pick<ChangesRuntime, 'open' | 'accept' | 'revert'> | undefined\n): Pick<AgentControl, 'changesOpen' | 'changeAccept' | 'changeRevert'> {\n const needed = () => {\n if (!changes) throw new Error('This agent tracks no changes.');\n return changes;\n };\n const done = (path: string, run: (runtime: NonNullable<typeof changes>) => Promise<void>) =>\n created(async () => {\n await run(needed());\n return path;\n });\n return {\n changesOpen: async (context) => changes?.open(context),\n changeAccept: (path, context) => done(path, (runtime) => runtime.accept(path, context)),\n changeRevert: (path, context) => done(path, (runtime) => runtime.revert(path, context)),\n };\n}\n\nfunction memoryControl(\n memory: Pick<MemoryRuntime, 'save' | 'remove'> | undefined\n): Pick<AgentControl, 'memorySave' | 'memoryRemove'> {\n return {\n async memorySave(draft, context) {\n if (!memory) throw new Error('This agent has no memory.');\n const { id, ...rest } = draft;\n return memory.save({ ...rest, ...(id ? { id } : {}) }, context);\n },\n async memoryRemove(id, context) {\n return { removed: memory ? await memory.remove(id, context) : false };\n },\n };\n}\n\nfunction sprinkleControl(\n sprinkles: Pick<SprinklesRuntime, 'send' | 'call'> | undefined\n): Pick<AgentControl, 'sprinkleSend' | 'sprinkleCall'> {\n return {\n sprinkleSend: async (id, payload, context) =>\n sprinkles ? sprinkles.send(id, payload, context) : { delivered: false },\n async sprinkleCall(id, method, args, context) {\n if (!sprinkles) throw new Error('This agent has no sprinkles.');\n return sprinkles.call(id, method, args, context);\n },\n };\n}\n\nexport function submissionId(value: string): SubmissionId | undefined {\n const id = Number(value);\n return /^[1-9][0-9]*$/.test(value) && Number.isSafeInteger(id) ? (id as SubmissionId) : undefined;\n}\n\nfunction operationError(error: unknown): OperationError {\n if (error instanceof ConversationBusy) return { code: 'busy', message: error.message };\n return { code: 'failed', message: error instanceof Error ? error.message : String(error) };\n}\n\nasync function accepted(operation: () => Promise<{ id: number } | number>): Promise<SendResponse> {\n try {\n const result = await operation();\n const id = typeof result === 'number' ? result : result.id;\n return { accepted: true, submissionId: String(id), error: null };\n } catch (error) {\n return { accepted: false, submissionId: null, error: operationError(error) };\n }\n}\n\nfunction cones(target: Conversation | Cones): Cones {\n if ('cone' in target) return target;\n return {\n cone: () => target,\n switchCone: async () => {\n throw new Error('this conversation has no cone to rewind');\n },\n };\n}\n\ninterface Turn {\n text: string;\n at: EntryId | null;\n files: boolean;\n}\n\ntype Block = { type?: string; name?: string };\n\nconst WRITERS = ['write', 'edit', 'bash', 'codemode'];\n\nfunction writesIn(entries: readonly EntryRecord[]): boolean {\n return entries.some((entry) =>\n (entry.model ?? []).some(\n (message) =>\n Array.isArray(message.content) &&\n (message.content as Block[]).some(\n (block) => block.type === 'toolCall' && WRITERS.includes(String(block.name))\n )\n )\n );\n}\n\nfunction lastTurn(view: ConversationView, messageId: string | null): Turn | null {\n const { entries } = view;\n const target = entries.findIndex((entry) => `e${entry.id}` === messageId);\n if (target < 0) return null;\n const turn = entries.slice(0, target).findLastIndex((entry) => entry.kind === 'pi.user');\n if (turn < 0) return null;\n const user = entries[turn] as EntryRecord;\n return {\n text: answerText(user.model?.[0]?.content),\n at: entries[turn - 1]?.id ?? null,\n files: writesIn(entries.slice(turn)),\n };\n}\n\nfunction busy(view: ConversationView): boolean {\n const live = view.docs['pi.live'] as { run?: unknown } | undefined;\n const inbox = view.docs['pi.inbox'] as { items?: unknown[] } | undefined;\n return Boolean(live?.run) || Boolean(inbox?.items?.length);\n}\n\ntype RewindDeps = {\n harness: Harness;\n agents?: Agents;\n cone: Cones;\n scoops?: HostScoops;\n};\n\nasync function turnIn(\n harness: Harness,\n conversation: Conversation,\n messageId: string | null,\n context: Context\n): Promise<{ turn: Turn; view: ConversationView } | Rewound> {\n const attached = await conversation.viewState(context);\n const view = attached.value;\n attached.dispose();\n const pending = (await harness.inspect(context)).submissions.some(\n (submission) => submission.conversationId === conversation.id\n );\n if (pending || busy(view)) return { done: false, text: null, reason: 'busy' };\n const turn = lastTurn(view, messageId);\n return turn ? { turn, view } : { done: false, text: null, reason: 'no-turn' };\n}\n\nasync function forkAt(\n harness: Harness,\n conversation: Conversation,\n found: { turn: Turn },\n context: Context\n): Promise<Conversation> {\n const ownership = { kind: 'ownerless' } as const;\n if (found.turn.at !== null) return conversation.fork(found.turn.at, { ownership }, context);\n const agent = await conversation.agent(context);\n const change: AgentChange = {\n model: agent.model ?? null,\n thinkingLevel: agent.thinkingLevel,\n extensions: agent.extensions,\n tools: agent.tools,\n instructions: agent.instructions ?? null,\n cwd: agent.cwd ?? null,\n };\n return harness.createConversation({ ownership, agent: pinned(change) }, context);\n}\n\nasync function rewindAgent(\n deps: RewindDeps,\n agentId: string | null,\n messageId: string | null,\n context: Context\n): Promise<Rewound> {\n const { harness, agents, cone, scoops } = deps;\n const scoop = agentId && agents ? agents.state().scoops[agentId] : undefined;\n if (agentId && agents && !scoop && agentId !== agents.activeCone())\n await agents.selectCone(agentId, context);\n const conversation =\n scoop && agents\n ? ((await agents.conversation(agentId as string, context)) as Conversation)\n : cone.cone();\n const found = await turnIn(harness, conversation, messageId, context);\n if ('reason' in found) return found;\n const fork = await forkAt(harness, conversation, found, context);\n const changed =\n scoops && agents && !scoop\n ? await scoops.scoops.rewound(agents.activeCone(), fork, context)\n : { stopped: [], restored: [] };\n const files = found.turn.files;\n await fork.submit(\n { type: 'write', entry: { kind: 'slicc.rewound', data: { turns: 1, ...changed, files } } },\n context\n );\n if (scoop && agents)\n await agents.update((_tx, state) => {\n (state.scoops[agentId as string] as { conversation: number }).conversation = fork.id;\n }, context);\n else await cone.switchCone(fork, context);\n return { done: true, text: found.turn.text, reason: null };\n}\n\nexport function createAgentControl(\n harness: Harness,\n target: Conversation | Cones,\n deliveries?: Deliveries,\n licks?: HostLicks,\n scoops?: HostScoops,\n skills?: Pick<SkillsRuntime, 'expand'>,\n sprinkles?: Pick<SprinklesRuntime, 'send' | 'call'>,\n memory?: Pick<MemoryRuntime, 'save' | 'remove'>,\n freezer?: Pick<FreezerRuntime, 'freeze' | 'newChat' | 'thaw' | 'discard'>,\n changes?: Pick<ChangesRuntime, 'open' | 'accept' | 'revert'>,\n monitor?: Pick<Monitor, 'open' | 'close'>,\n secrets?: () => readonly SecretName[]\n): AgentControl {\n const cone = cones(target);\n const current = () => cone.cone();\n const agents = (target as WithAgents).agents;\n const conversationFor = async (agentId: string | null | undefined, context: Context) => {\n if (!agentId || !agents) return current();\n const found = await agents.conversation(agentId, context);\n if (!found) throw new Error(`There is no agent ${agentId}.`);\n return found;\n };\n const withdraw = async (conversation: Conversation, id: string, context: Context) => {\n const parsed = submissionId(id);\n if (parsed === undefined) return { outcome: 'not_found' as const };\n const result = await harness.abortSubmission(parsed, context, conversation.id);\n if (result === 'aborted') return { outcome: 'withdrawn' as const };\n return {\n outcome: result === 'not_found' ? ('not_found' as const) : ('already_placed' as const),\n };\n };\n let lock: Promise<unknown> = Promise.resolve();\n const serial = <T>(operation: () => Promise<T>): Promise<T> => {\n const run = lock.then(operation, operation);\n lock = run.catch(() => undefined);\n return run;\n };\n const rewindIn = (agentId: string | null, messageId: string | null, context: Context) =>\n serial(() => rewindAgent({ harness, agents, cone, scoops }, agentId, messageId, context));\n const decide = (\n agentId: string | null,\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved> =>\n serial(async () => {\n if (!licks) return { done: false, text: null, error: 'this agent has no licks' };\n const action = state === 'confirmed' ? 'confirm' : 'dismiss';\n try {\n const conversation = await conversationFor(agentId, context);\n const text = await licks.licks.decide(conversation, lickId, action, undefined, context);\n await conversation.submit(\n {\n type: 'write',\n entry: {\n kind: LICK_STATE_KIND,\n data: { lick: lickId, state, by: 'user' },\n model: [\n {\n role: 'user',\n content: `The user ${state} lick ${lickId}: ${text}`,\n timestamp: Date.now(),\n },\n ],\n },\n },\n context\n );\n return { done: true, text, error: null };\n } catch (error) {\n return { done: false, text: null, error: (error as Error).message };\n }\n });\n return {\n send(request, context) {\n return serial(async () => {\n if (secrets && request.text.trim() === SECRETS_COMMAND)\n return accepted(async () =>\n (await conversationFor(request.agentId, context)).submit(\n { type: 'write', entry: secretsEntry(secrets()) },\n context\n )\n );\n const expanded = skills ? await skills.expand(request.text, context) : request.text;\n const text = await scrubText(expanded);\n const response = await accepted(async () =>\n (await conversationFor(request.agentId, context)).submit(\n {\n type: 'input',\n content: text,\n whenBusy: request.whenBusy,\n ...(request.requestId ? { requestId: request.requestId } : {}),\n },\n context\n )\n );\n const id = response.submissionId === null ? undefined : submissionId(response.submissionId);\n if (id !== undefined) deliveries?.expect(id, request.whenBusy);\n return response;\n });\n },\n rewind: (messageId, context) => rewindIn(null, messageId, context),\n rewindAgent: (agentId, messageId, context) => rewindIn(agentId, messageId, context),\n\n async wait(id, context) {\n const parsed = submissionId(id);\n const submission =\n parsed === undefined ? undefined : await harness.submission(parsed, context);\n if (!submission) throw new Error(`unknown submission ${id}`);\n const settled = await submission.wait(context);\n const { answer, reason } = settled as { answer?: EntryId; reason?: string };\n if (answer === undefined) return { status: 'unanswered', text: null, reason: String(reason) };\n const entry = await harness.commit((tx) => tx.entry(AssistantEntry, answer), context);\n return { status: 'done', text: answerText(entry?.model?.[0]?.content), reason: null };\n },\n withdraw: (id, context) => withdraw(current(), id, context),\n ...sprinkleControl(sprinkles),\n ...memoryControl(memory),\n ...freezerControl(freezer),\n ...changesControl(changes),\n monitorOpen: async (lease, resync, context) =>\n monitor ? monitor.open(lease, resync, context) : { lease: '', ttlMs: 0 },\n monitorClose: async (lease, context) => monitor?.close(lease, context),\n async unqueue(agentId, id, context) {\n return withdraw(await conversationFor(agentId, context), id, context);\n },\n abort: (context) => current().abort(context),\n compact: (instructions, context) =>\n accepted(() => current().compact(instructions ?? undefined, context)),\n compactAgent: (agentId, instructions, context) =>\n accepted(async () =>\n (await conversationFor(agentId, context)).compact(instructions ?? undefined, context)\n ),\n reset: (handoff, context) => current().reset(handoff ?? undefined, context),\n resolveLick: (lickId, state, context) => decide(null, lickId, state, context),\n resolveAgentLick: (agentId, lickId, state, context) => decide(agentId, lickId, state, context),\n async webhook(name, delivery, context) {\n const delivered = licks\n ? await licks.sources.webhook(\n name,\n {\n ...(delivery.id ? { id: delivery.id } : {}),\n headers: delivery.headers,\n body: delivery.body,\n },\n context\n )\n : false;\n return { delivered };\n },\n async stopAgent(agentId, context) {\n await (await conversationFor(agentId, context)).abort(context);\n },\n async selectCone(agentId, context) {\n await agents?.selectCone(agentId, context);\n },\n createCone(name, context) {\n return created(async () => {\n if (!agents) throw new Error('This agent has a single cone.');\n return agents.createCone(name, context);\n });\n },\n createScoop(parentId, name, context) {\n return created(async () => {\n if (!scoops) throw new Error('This agent has no scoops.');\n const roles = await scoops.runtime.roles(context);\n const answer = await scoops.scoops.spawn(\n { cone: parentId, name, prompts: [], fromAgent: false, limits: roles.limits },\n context\n );\n if (answer.code !== 0) throw new Error(readable(answer.out));\n return `scoop:${answer.out.trim()}`;\n });\n },\n drop(agentId, context) {\n return created(async () => {\n if (!scoops) throw new Error('This agent has no scoops.');\n const answer = await scoops.scoops.stop(agentId, false, context);\n if (answer.code !== 0) throw new Error(readable(answer.out));\n return agentId;\n });\n },\n configure: async (change, context) =>\n (await conversationFor(change.agentId, context)).configure(\n {\n ...(change.model ? { model: change.model } : {}),\n ...(change.thinkingLevel ? { thinkingLevel: change.thinkingLevel } : {}),\n },\n context\n ),\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/freezer/index.js
CHANGED
|
@@ -6,6 +6,7 @@ import {
|
|
|
6
6
|
} from "../agents.js";
|
|
7
7
|
import { HOME } from "../kernel/env.js";
|
|
8
8
|
import { SCOOPS_ROOT, workspace } from "../scoops/service.js";
|
|
9
|
+
import { pinned } from "../secrets/extension.js";
|
|
9
10
|
const THAWED_KIND = "slicc.thawed";
|
|
10
11
|
const USAGE = `usage:
|
|
11
12
|
freezer list every conversation: id, kind, name, title, messages, when
|
|
@@ -189,14 +190,14 @@ async function freshLike(harness, conversation, context) {
|
|
|
189
190
|
return harness.createConversation(
|
|
190
191
|
{
|
|
191
192
|
ownership: { kind: "ownerless" },
|
|
192
|
-
agent: {
|
|
193
|
+
agent: pinned({
|
|
193
194
|
model: agent.model,
|
|
194
195
|
thinkingLevel: agent.thinkingLevel,
|
|
195
196
|
extensions: agent.extensions,
|
|
196
197
|
tools: agent.tools,
|
|
197
198
|
instructions: agent.instructions ?? null,
|
|
198
199
|
cwd: agent.cwd ?? null
|
|
199
|
-
}
|
|
200
|
+
})
|
|
200
201
|
},
|
|
201
202
|
context
|
|
202
203
|
);
|
|
@@ -217,14 +218,14 @@ async function thawScoop(options, id, scoop, context) {
|
|
|
217
218
|
const cone = await (await activeCone(agents, context)).agent(context);
|
|
218
219
|
const created = {
|
|
219
220
|
ownership: { kind: "ownerless" },
|
|
220
|
-
agent: {
|
|
221
|
+
agent: pinned({
|
|
221
222
|
model: agent.model,
|
|
222
223
|
thinkingLevel: agent.thinkingLevel,
|
|
223
224
|
extensions: cone.extensions,
|
|
224
225
|
tools: cone.tools,
|
|
225
226
|
instructions: cone.instructions ?? null,
|
|
226
227
|
cwd: HOME
|
|
227
|
-
}
|
|
228
|
+
})
|
|
228
229
|
};
|
|
229
230
|
const fork = last ? await conversation.fork(last.id, created, context) : await harness.createConversation(created, context);
|
|
230
231
|
const folder = workspace(scoop.folder);
|
|
@@ -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 { LickTarget } from '../licks/lick.ts';\nimport { SCOOPS_ROOT, workspace } from '../scoops/service.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}\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): 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: {\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 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: {\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 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 = 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(kindOf(scoop), scoop.name, folder, kept),\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(`${SCOOPS_ROOT}/${scoop.folder}`, { recursive: true, force: true }, context);\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(`${SCOOPS_ROOT}/${folder}`, { recursive: true, force: true }, context);\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 FrozenRecord,\n live,\n type ScoopRecord,\n} from '../agents.ts';\nimport { HOME } from '../kernel/env.ts';\nimport type { LickTarget } from '../licks/lick.ts';\nimport { SCOOPS_ROOT, workspace } from '../scoops/service.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}\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): 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 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 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 = 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(kindOf(scoop), scoop.name, folder, kept),\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(`${SCOOPS_ROOT}/${scoop.folder}`, { recursive: true, force: true }, context);\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(`${SCOOPS_ROOT}/${folder}`, { recursive: true, force: true }, context);\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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",
|
|
6
6
|
"names": ["record", "item"]
|
|
7
7
|
}
|
package/dist/host.js
CHANGED
|
@@ -99,6 +99,13 @@ async function follow(agent, context) {
|
|
|
99
99
|
}
|
|
100
100
|
};
|
|
101
101
|
}
|
|
102
|
+
const idleVault = replicatedState({
|
|
103
|
+
port: "none",
|
|
104
|
+
needed: false,
|
|
105
|
+
version: 0,
|
|
106
|
+
locked: "no",
|
|
107
|
+
held: 0
|
|
108
|
+
});
|
|
102
109
|
async function hostAgent(agent, options = {}) {
|
|
103
110
|
const context = options.context ?? BACKGROUND_CONTEXT;
|
|
104
111
|
const serverId = options.serverId ?? crypto.randomUUID();
|
|
@@ -134,11 +141,13 @@ async function hostAgent(agent, options = {}) {
|
|
|
134
141
|
options.memory,
|
|
135
142
|
options.freezer,
|
|
136
143
|
options.changes,
|
|
137
|
-
monitor
|
|
144
|
+
monitor,
|
|
145
|
+
options.secrets?.list
|
|
138
146
|
);
|
|
139
147
|
const remote = createRemote({
|
|
140
148
|
harness: agent.harness,
|
|
141
149
|
send: (request, using) => control.send(request, using),
|
|
150
|
+
vault: options.secrets?.vault ?? idleVault,
|
|
142
151
|
async conversation(agentId, using) {
|
|
143
152
|
if (!agentId) return agent.cone();
|
|
144
153
|
const found = await agent.agents.conversation(agentId, using);
|
|
@@ -157,7 +166,8 @@ async function hostAgent(agent, options = {}) {
|
|
|
157
166
|
memoryScopes: options.memory?.scopes ?? replicatedState([]),
|
|
158
167
|
frozen: options.freezer?.frozen ?? replicatedState([]),
|
|
159
168
|
changes: options.changes?.view ?? replicatedState({ unavailable: null, changes: [] }),
|
|
160
|
-
monitor: monitor.state
|
|
169
|
+
monitor: monitor.state,
|
|
170
|
+
vault: options.secrets?.vault ?? idleVault
|
|
161
171
|
};
|
|
162
172
|
const settings = options.settings ?? noSettings;
|
|
163
173
|
const served = (served2) => {
|
|
@@ -231,6 +241,7 @@ async function hostAgent(agent, options = {}) {
|
|
|
231
241
|
mounted.dispose();
|
|
232
242
|
for (const off of untouch) off();
|
|
233
243
|
options.freezer?.close();
|
|
244
|
+
options.secrets?.close?.();
|
|
234
245
|
await options.changes?.close(context);
|
|
235
246
|
await options.memory?.close(context);
|
|
236
247
|
await options.sprinkles?.close(context);
|
package/dist/host.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/host.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type Context,\n createRemoteServiceEndpoint,\n RemoteServiceProvider,\n replicatedState,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport {\n type RoutedServerServiceHost,\n type RoutedSessionAttachment,\n type RoutedSessionHandle,\n Server,\n type ServerHost,\n SessionNotFoundError,\n} from '@earendil-works/pi-server';\nimport type { Agent } from './agent.ts';\nimport type { ChangesView } from './changes/git.ts';\nimport type { ChangesRuntime } from './changes/index.ts';\nimport { createAgentControl, type HostLicks, type HostScoops } from './control.ts';\nimport { trackDeliveries } from './deliveries.ts';\nimport type { FreezerRuntime, FrozenCone } from './freezer/index.ts';\nimport type { UserClients } from './kernel/users.ts';\nimport { PortListener } from './listener.ts';\nimport type { McpRuntime } from './mcp/index.ts';\nimport type { MemoryEntry, MemoryScope } from './memory/format.ts';\nimport type { MemoryRuntime } from './memory/index.ts';\nimport { createMonitor, type MonitorOptions } from './monitor/index.ts';\nimport { viewControl, viewPages, viewRemote, viewSettings } from './readonly.ts';\nimport { createRemote } from './remote/host.ts';\nimport { type AgentPages, createPages, ownedPages, type Pages } from './remote/pages.ts';\nimport {\n AGENT_SESSION,\n AgentControl,\n AgentPagesService,\n AgentRemoteService,\n AgentSessions,\n AgentSettings,\n AgentTranscript,\n type Command,\n} from './services.ts';\nimport type { SkillsRuntime } from './skills/index.ts';\nimport type { SprinklesRuntime } from './sprinkles/index.ts';\nimport type { Sprinkle } from './sprinkles/kind.ts';\nimport { agentViews } from './views.ts';\nimport type { PortEndpoint } from './wire.ts';\n\nexport interface ConnectOptions {\n readOnly?: boolean;\n pages?: boolean;\n}\n\nexport interface AgentHost {\n readonly serverId: string;\n readonly agent: Agent;\n readonly users?: UserClients;\n readonly pages: Pages;\n connect(endpoint: PortEndpoint, options?: ConnectOptions): void;\n close(): Promise<void>;\n}\n\nfunction endpointFor(provider: RemoteServiceProvider): RoutedSessionAttachment {\n const endpoint = createRemoteServiceEndpoint(provider);\n return {\n invokeService: (call, publish, context) =>\n endpoint.invoke(call, (id, update) => publish(id, update, context), context),\n release: () => endpoint.dispose(),\n };\n}\n\ntype Attached = { provider: RemoteServiceProvider; release(): void };\n\nfunction sessionServices(attach: () => Attached): RoutedSessionHandle {\n return {\n attachClient() {\n const attached = attach();\n const endpoint = endpointFor(attached.provider);\n return {\n invokeService: endpoint.invokeService,\n release(context) {\n endpoint.release(context);\n attached.release();\n },\n };\n },\n close: async () => {},\n };\n}\n\nfunction serverServices(): RoutedServerServiceHost {\n return {\n attachClient(presentation) {\n const provider = new RemoteServiceProvider([{ service: AgentSessions, mode: 'singleton' }]);\n provider.provide(AgentSessions, {\n attach: (sessionId, context) => presentation.attachSession(sessionId, context),\n detach: (context) => presentation.detachSession(context),\n });\n const attachment = endpointFor(provider);\n return {\n invokeService: attachment.invokeService,\n release(context) {\n attachment.release(context);\n provider.dispose();\n },\n };\n },\n };\n}\n\nconst noSettings: AgentSettings = {\n state: replicatedState({ models: [], accounts: [] }),\n connect: async () => {\n throw new Error('this agent has no accounts');\n },\n disconnect: async () => {},\n signIn: async () => null,\n};\n\nasync function follow(agent: Agent, context: Context) {\n let attached = await agent.cone().viewState(context);\n const state = replicatedState<ConversationView>(attached.value);\n const mirror = (value: ConversationView, from: Context) => state.replace(from, value);\n let off = attached.subscribe(mirror);\n const stop = agent.onCone(async (conversation) => {\n const next = await conversation.viewState(context);\n off();\n attached.dispose();\n attached = next;\n state.replace(context, next.value);\n off = next.subscribe(mirror);\n });\n return {\n state,\n dispose() {\n stop();\n off();\n attached.dispose();\n },\n };\n}\n\nexport async function hostAgent(\n agent: Agent,\n options: {\n serverId?: string;\n context?: Context;\n settings?: AgentSettings;\n licks?: HostLicks;\n scoops?: HostScoops;\n skills?: SkillsRuntime;\n sprinkles?: SprinklesRuntime;\n memory?: MemoryRuntime;\n freezer?: FreezerRuntime;\n changes?: ChangesRuntime;\n mcp?: Pick<McpRuntime, 'close'>;\n users?: UserClients;\n monitor?: Pick<MonitorOptions, 'kernel' | 'groups' | 'users' | 'secrets'>;\n pages?: Pages;\n } = {}\n): Promise<AgentHost> {\n const context = options.context ?? BACKGROUND_CONTEXT;\n const serverId = options.serverId ?? crypto.randomUUID();\n const transcript = await follow(agent, context);\n const { state } = transcript;\n const mounted = await agentViews(agent, context);\n const touch = () => options.freezer?.touch();\n const untouch = [state.subscribe(touch), mounted.views.subscribe(touch)];\n const catalogue = () =>\n new RemoteServiceProvider([\n { service: AgentControl, mode: 'singleton' },\n { service: AgentTranscript, mode: 'singleton' },\n { service: AgentSettings, mode: 'singleton' },\n { service: AgentRemoteService, mode: 'singleton' },\n { service: AgentPagesService, mode: 'singleton' },\n ]);\n const pages = options.pages ?? createPages();\n const deliveries = trackDeliveries(agent.harness, state, context);\n const monitor = createMonitor({\n ...options.monitor,\n harness: agent.harness,\n agents: agent.agents,\n views: mounted.views,\n context,\n });\n const control = createAgentControl(\n agent.harness,\n agent,\n deliveries,\n options.licks,\n options.scoops,\n options.skills,\n options.sprinkles,\n options.memory,\n options.freezer,\n options.changes,\n monitor\n );\n const remote = createRemote({\n harness: agent.harness,\n send: (request, using) => control.send(request, using),\n async conversation(agentId, using) {\n if (!agentId) return agent.cone();\n const found = await agent.agents.conversation(agentId, using);\n if (!found) throw new Error(`There is no agent ${agentId}.`);\n return found;\n },\n });\n const transcriptService = {\n state,\n deliveries: deliveries.state,\n agents: mounted.agents,\n views: mounted.views,\n commands: options.skills?.commands ?? replicatedState<Command[]>([]),\n sprinkles: options.sprinkles?.sprinkles ?? replicatedState<Sprinkle[]>([]),\n memories: options.memory?.memories ?? replicatedState<MemoryEntry[]>([]),\n memoryScopes: options.memory?.scopes ?? replicatedState<MemoryScope[]>([]),\n frozen: options.freezer?.frozen ?? replicatedState<FrozenCone[]>([]),\n changes:\n options.changes?.view ?? replicatedState<ChangesView>({ unavailable: null, changes: [] }),\n monitor: monitor.state,\n };\n const settings = options.settings ?? noSettings;\n const served = (served: AgentPages) => {\n const made = catalogue();\n made.provide(AgentControl, control);\n made.provide(AgentTranscript, transcriptService);\n made.provide(AgentSettings, settings);\n made.provide(AgentRemoteService, remote);\n made.provide(AgentPagesService, served);\n return made;\n };\n const owned = (): Attached => {\n const mine = ownedPages(pages);\n const made = served(mine);\n return {\n provider: made,\n release() {\n made.dispose();\n mine.release();\n },\n };\n };\n const follower = served(viewPages());\n const viewer = catalogue();\n viewer.provide(AgentControl, viewControl(control));\n viewer.provide(AgentTranscript, { ...transcriptService, monitor: monitor.viewState });\n viewer.provide(AgentSettings, viewSettings(settings));\n viewer.provide(AgentRemoteService, viewRemote(remote));\n viewer.provide(AgentPagesService, viewPages());\n const shared = (services: RemoteServiceProvider) => () => ({\n provider: services,\n release: () => undefined,\n });\n const serve = async (id: string, attach: () => Attached) => {\n const host: ServerHost = {\n serverServices: serverServices(),\n async resolveSession(sessionId) {\n if (sessionId !== AGENT_SESSION)\n throw new SessionNotFoundError(`unknown session ${sessionId}`);\n return { id: sessionId };\n },\n openSession: async () => sessionServices(attach),\n };\n const listener = new PortListener(id);\n const server = await new Server(host, { serverId: id, listeners: [listener] }).start();\n return { listener, server };\n };\n const full = await serve(serverId, owned);\n const view = await serve(crypto.randomUUID(), shared(viewer));\n const linked = await serve(crypto.randomUUID(), shared(follower));\n return {\n serverId,\n agent,\n pages,\n ...(options.users ? { users: options.users } : {}),\n connect(endpoint, connectOptions) {\n const chosen = connectOptions?.readOnly\n ? view\n : connectOptions?.pages === false\n ? linked\n : full;\n chosen.listener.connect(endpoint);\n },\n async close() {\n await full.server.close();\n await view.server.close();\n await linked.server.close();\n viewer.dispose();\n follower.dispose();\n await pages.dispose();\n await monitor.dispose();\n await remote.dispose();\n deliveries.dispose();\n transcript.dispose();\n mounted.dispose();\n for (const off of untouch) off();\n options.freezer?.close();\n await options.changes?.close(context);\n await options.memory?.close(context);\n await options.sprinkles?.close(context);\n await options.skills?.close(context);\n await options.mcp?.close(context);\n await options.scoops?.runtime.close(context);\n await options.licks?.sources.close(context);\n await agent.close();\n await options.users?.close();\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEE;AAAA,EACA;AAAA,
|
|
4
|
+
"sourcesContent": ["import {\n type Context,\n createRemoteServiceEndpoint,\n RemoteServiceProvider,\n type ReplicatedState,\n replicatedState,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport {\n type RoutedServerServiceHost,\n type RoutedSessionAttachment,\n type RoutedSessionHandle,\n Server,\n type ServerHost,\n SessionNotFoundError,\n} from '@earendil-works/pi-server';\nimport type { Agent } from './agent.ts';\nimport type { ChangesView } from './changes/git.ts';\nimport type { ChangesRuntime } from './changes/index.ts';\nimport { createAgentControl, type HostLicks, type HostScoops } from './control.ts';\nimport { trackDeliveries } from './deliveries.ts';\nimport type { FreezerRuntime, FrozenCone } from './freezer/index.ts';\nimport type { UserClients } from './kernel/users.ts';\nimport { PortListener } from './listener.ts';\nimport type { McpRuntime } from './mcp/index.ts';\nimport type { MemoryEntry, MemoryScope } from './memory/format.ts';\nimport type { MemoryRuntime } from './memory/index.ts';\nimport { createMonitor, type MonitorOptions } from './monitor/index.ts';\nimport { viewControl, viewPages, viewRemote, viewSettings } from './readonly.ts';\nimport { createRemote } from './remote/host.ts';\nimport { type AgentPages, createPages, ownedPages, type Pages } from './remote/pages.ts';\nimport type { SecretName } from './secrets/names.ts';\nimport type { VaultState } from './secrets/vault.ts';\nimport {\n AGENT_SESSION,\n AgentControl,\n AgentPagesService,\n AgentRemoteService,\n AgentSessions,\n AgentSettings,\n AgentTranscript,\n type Command,\n} from './services.ts';\nimport type { SkillsRuntime } from './skills/index.ts';\nimport type { SprinklesRuntime } from './sprinkles/index.ts';\nimport type { Sprinkle } from './sprinkles/kind.ts';\nimport { agentViews } from './views.ts';\nimport type { PortEndpoint } from './wire.ts';\n\nexport interface ConnectOptions {\n readOnly?: boolean;\n pages?: boolean;\n}\n\nexport interface AgentHost {\n readonly serverId: string;\n readonly agent: Agent;\n readonly users?: UserClients;\n readonly pages: Pages;\n connect(endpoint: PortEndpoint, options?: ConnectOptions): void;\n close(): Promise<void>;\n}\n\nfunction endpointFor(provider: RemoteServiceProvider): RoutedSessionAttachment {\n const endpoint = createRemoteServiceEndpoint(provider);\n return {\n invokeService: (call, publish, context) =>\n endpoint.invoke(call, (id, update) => publish(id, update, context), context),\n release: () => endpoint.dispose(),\n };\n}\n\ntype Attached = { provider: RemoteServiceProvider; release(): void };\n\nfunction sessionServices(attach: () => Attached): RoutedSessionHandle {\n return {\n attachClient() {\n const attached = attach();\n const endpoint = endpointFor(attached.provider);\n return {\n invokeService: endpoint.invokeService,\n release(context) {\n endpoint.release(context);\n attached.release();\n },\n };\n },\n close: async () => {},\n };\n}\n\nfunction serverServices(): RoutedServerServiceHost {\n return {\n attachClient(presentation) {\n const provider = new RemoteServiceProvider([{ service: AgentSessions, mode: 'singleton' }]);\n provider.provide(AgentSessions, {\n attach: (sessionId, context) => presentation.attachSession(sessionId, context),\n detach: (context) => presentation.detachSession(context),\n });\n const attachment = endpointFor(provider);\n return {\n invokeService: attachment.invokeService,\n release(context) {\n attachment.release(context);\n provider.dispose();\n },\n };\n },\n };\n}\n\nconst noSettings: AgentSettings = {\n state: replicatedState({ models: [], accounts: [] }),\n connect: async () => {\n throw new Error('this agent has no accounts');\n },\n disconnect: async () => {},\n signIn: async () => null,\n};\n\nasync function follow(agent: Agent, context: Context) {\n let attached = await agent.cone().viewState(context);\n const state = replicatedState<ConversationView>(attached.value);\n const mirror = (value: ConversationView, from: Context) => state.replace(from, value);\n let off = attached.subscribe(mirror);\n const stop = agent.onCone(async (conversation) => {\n const next = await conversation.viewState(context);\n off();\n attached.dispose();\n attached = next;\n state.replace(context, next.value);\n off = next.subscribe(mirror);\n });\n return {\n state,\n dispose() {\n stop();\n off();\n attached.dispose();\n },\n };\n}\n\nexport interface HostSecrets {\n vault: ReplicatedState<VaultState>;\n list(): readonly SecretName[];\n close?(): void;\n}\n\nconst idleVault = replicatedState<VaultState>({\n port: 'none',\n needed: false,\n version: 0,\n locked: 'no',\n held: 0,\n});\n\nexport async function hostAgent(\n agent: Agent,\n options: {\n serverId?: string;\n context?: Context;\n settings?: AgentSettings;\n licks?: HostLicks;\n scoops?: HostScoops;\n skills?: SkillsRuntime;\n sprinkles?: SprinklesRuntime;\n memory?: MemoryRuntime;\n freezer?: FreezerRuntime;\n changes?: ChangesRuntime;\n mcp?: Pick<McpRuntime, 'close'>;\n users?: UserClients;\n monitor?: Pick<MonitorOptions, 'kernel' | 'groups' | 'users' | 'secrets'>;\n pages?: Pages;\n secrets?: HostSecrets;\n } = {}\n): Promise<AgentHost> {\n const context = options.context ?? BACKGROUND_CONTEXT;\n const serverId = options.serverId ?? crypto.randomUUID();\n const transcript = await follow(agent, context);\n const { state } = transcript;\n const mounted = await agentViews(agent, context);\n const touch = () => options.freezer?.touch();\n const untouch = [state.subscribe(touch), mounted.views.subscribe(touch)];\n const catalogue = () =>\n new RemoteServiceProvider([\n { service: AgentControl, mode: 'singleton' },\n { service: AgentTranscript, mode: 'singleton' },\n { service: AgentSettings, mode: 'singleton' },\n { service: AgentRemoteService, mode: 'singleton' },\n { service: AgentPagesService, mode: 'singleton' },\n ]);\n const pages = options.pages ?? createPages();\n const deliveries = trackDeliveries(agent.harness, state, context);\n const monitor = createMonitor({\n ...options.monitor,\n harness: agent.harness,\n agents: agent.agents,\n views: mounted.views,\n context,\n });\n const control = createAgentControl(\n agent.harness,\n agent,\n deliveries,\n options.licks,\n options.scoops,\n options.skills,\n options.sprinkles,\n options.memory,\n options.freezer,\n options.changes,\n monitor,\n options.secrets?.list\n );\n const remote = createRemote({\n harness: agent.harness,\n send: (request, using) => control.send(request, using),\n vault: options.secrets?.vault ?? idleVault,\n async conversation(agentId, using) {\n if (!agentId) return agent.cone();\n const found = await agent.agents.conversation(agentId, using);\n if (!found) throw new Error(`There is no agent ${agentId}.`);\n return found;\n },\n });\n const transcriptService = {\n state,\n deliveries: deliveries.state,\n agents: mounted.agents,\n views: mounted.views,\n commands: options.skills?.commands ?? replicatedState<Command[]>([]),\n sprinkles: options.sprinkles?.sprinkles ?? replicatedState<Sprinkle[]>([]),\n memories: options.memory?.memories ?? replicatedState<MemoryEntry[]>([]),\n memoryScopes: options.memory?.scopes ?? replicatedState<MemoryScope[]>([]),\n frozen: options.freezer?.frozen ?? replicatedState<FrozenCone[]>([]),\n changes:\n options.changes?.view ?? replicatedState<ChangesView>({ unavailable: null, changes: [] }),\n monitor: monitor.state,\n vault: options.secrets?.vault ?? idleVault,\n };\n const settings = options.settings ?? noSettings;\n const served = (served: AgentPages) => {\n const made = catalogue();\n made.provide(AgentControl, control);\n made.provide(AgentTranscript, transcriptService);\n made.provide(AgentSettings, settings);\n made.provide(AgentRemoteService, remote);\n made.provide(AgentPagesService, served);\n return made;\n };\n const owned = (): Attached => {\n const mine = ownedPages(pages);\n const made = served(mine);\n return {\n provider: made,\n release() {\n made.dispose();\n mine.release();\n },\n };\n };\n const follower = served(viewPages());\n const viewer = catalogue();\n viewer.provide(AgentControl, viewControl(control));\n viewer.provide(AgentTranscript, { ...transcriptService, monitor: monitor.viewState });\n viewer.provide(AgentSettings, viewSettings(settings));\n viewer.provide(AgentRemoteService, viewRemote(remote));\n viewer.provide(AgentPagesService, viewPages());\n const shared = (services: RemoteServiceProvider) => () => ({\n provider: services,\n release: () => undefined,\n });\n const serve = async (id: string, attach: () => Attached) => {\n const host: ServerHost = {\n serverServices: serverServices(),\n async resolveSession(sessionId) {\n if (sessionId !== AGENT_SESSION)\n throw new SessionNotFoundError(`unknown session ${sessionId}`);\n return { id: sessionId };\n },\n openSession: async () => sessionServices(attach),\n };\n const listener = new PortListener(id);\n const server = await new Server(host, { serverId: id, listeners: [listener] }).start();\n return { listener, server };\n };\n const full = await serve(serverId, owned);\n const view = await serve(crypto.randomUUID(), shared(viewer));\n const linked = await serve(crypto.randomUUID(), shared(follower));\n return {\n serverId,\n agent,\n pages,\n ...(options.users ? { users: options.users } : {}),\n connect(endpoint, connectOptions) {\n const chosen = connectOptions?.readOnly\n ? view\n : connectOptions?.pages === false\n ? linked\n : full;\n chosen.listener.connect(endpoint);\n },\n async close() {\n await full.server.close();\n await view.server.close();\n await linked.server.close();\n viewer.dispose();\n follower.dispose();\n await pages.dispose();\n await monitor.dispose();\n await remote.dispose();\n deliveries.dispose();\n transcript.dispose();\n mounted.dispose();\n for (const off of untouch) off();\n options.freezer?.close();\n options.secrets?.close?.();\n await options.changes?.close(context);\n await options.memory?.close(context);\n await options.sprinkles?.close(context);\n await options.skills?.close(context);\n await options.mcp?.close(context);\n await options.scoops?.runtime.close(context);\n await options.licks?.sources.close(context);\n await agent.close();\n await options.users?.close();\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EAEE;AAAA,EACA;AAAA,EAEA;AAAA,OACK;AACP,SAAS,0BAA0B;AAEnC;AAAA,EAIE;AAAA,EAEA;AAAA,OACK;AAIP,SAAS,0BAA2D;AACpE,SAAS,uBAAuB;AAGhC,SAAS,oBAAoB;AAI7B,SAAS,qBAA0C;AACnD,SAAS,aAAa,WAAW,YAAY,oBAAoB;AACjE,SAAS,oBAAoB;AAC7B,SAA0B,aAAa,kBAA8B;AAGrE;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OAEK;AAIP,SAAS,kBAAkB;AAiB3B,SAAS,YAAY,UAA0D;AAC7E,QAAM,WAAW,4BAA4B,QAAQ;AACrD,SAAO;AAAA,IACL,eAAe,CAAC,MAAM,SAAS,YAC7B,SAAS,OAAO,MAAM,CAAC,IAAI,WAAW,QAAQ,IAAI,QAAQ,OAAO,GAAG,OAAO;AAAA,IAC7E,SAAS,MAAM,SAAS,QAAQ;AAAA,EAClC;AACF;AAIA,SAAS,gBAAgB,QAA6C;AACpE,SAAO;AAAA,IACL,eAAe;AACb,YAAM,WAAW,OAAO;AACxB,YAAM,WAAW,YAAY,SAAS,QAAQ;AAC9C,aAAO;AAAA,QACL,eAAe,SAAS;AAAA,QACxB,QAAQ,SAAS;AACf,mBAAS,QAAQ,OAAO;AACxB,mBAAS,QAAQ;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,IACA,OAAO,YAAY;AAAA,IAAC;AAAA,EACtB;AACF;AAEA,SAAS,iBAA0C;AACjD,SAAO;AAAA,IACL,aAAa,cAAc;AACzB,YAAM,WAAW,IAAI,sBAAsB,CAAC,EAAE,SAAS,eAAe,MAAM,YAAY,CAAC,CAAC;AAC1F,eAAS,QAAQ,eAAe;AAAA,QAC9B,QAAQ,CAAC,WAAW,YAAY,aAAa,cAAc,WAAW,OAAO;AAAA,QAC7E,QAAQ,CAAC,YAAY,aAAa,cAAc,OAAO;AAAA,MACzD,CAAC;AACD,YAAM,aAAa,YAAY,QAAQ;AACvC,aAAO;AAAA,QACL,eAAe,WAAW;AAAA,QAC1B,QAAQ,SAAS;AACf,qBAAW,QAAQ,OAAO;AAC1B,mBAAS,QAAQ;AAAA,QACnB;AAAA,MACF;AAAA,IACF;AAAA,EACF;AACF;AAEA,MAAM,aAA4B;AAAA,EAChC,OAAO,gBAAgB,EAAE,QAAQ,CAAC,GAAG,UAAU,CAAC,EAAE,CAAC;AAAA,EACnD,SAAS,YAAY;AACnB,UAAM,IAAI,MAAM,4BAA4B;AAAA,EAC9C;AAAA,EACA,YAAY,YAAY;AAAA,EAAC;AAAA,EACzB,QAAQ,YAAY;AACtB;AAEA,eAAe,OAAO,OAAc,SAAkB;AACpD,MAAI,WAAW,MAAM,MAAM,KAAK,EAAE,UAAU,OAAO;AACnD,QAAM,QAAQ,gBAAkC,SAAS,KAAK;AAC9D,QAAM,SAAS,CAAC,OAAyB,SAAkB,MAAM,QAAQ,MAAM,KAAK;AACpF,MAAI,MAAM,SAAS,UAAU,MAAM;AACnC,QAAM,OAAO,MAAM,OAAO,OAAO,iBAAiB;AAChD,UAAM,OAAO,MAAM,aAAa,UAAU,OAAO;AACjD,QAAI;AACJ,aAAS,QAAQ;AACjB,eAAW;AACX,UAAM,QAAQ,SAAS,KAAK,KAAK;AACjC,UAAM,KAAK,UAAU,MAAM;AAAA,EAC7B,CAAC;AACD,SAAO;AAAA,IACL;AAAA,IACA,UAAU;AACR,WAAK;AACL,UAAI;AACJ,eAAS,QAAQ;AAAA,IACnB;AAAA,EACF;AACF;AAQA,MAAM,YAAY,gBAA4B;AAAA,EAC5C,MAAM;AAAA,EACN,QAAQ;AAAA,EACR,SAAS;AAAA,EACT,QAAQ;AAAA,EACR,MAAM;AACR,CAAC;AAED,eAAsB,UACpB,OACA,UAgBI,CAAC,GACe;AACpB,QAAM,UAAU,QAAQ,WAAW;AACnC,QAAM,WAAW,QAAQ,YAAY,OAAO,WAAW;AACvD,QAAM,aAAa,MAAM,OAAO,OAAO,OAAO;AAC9C,QAAM,EAAE,MAAM,IAAI;AAClB,QAAM,UAAU,MAAM,WAAW,OAAO,OAAO;AAC/C,QAAM,QAAQ,MAAM,QAAQ,SAAS,MAAM;AAC3C,QAAM,UAAU,CAAC,MAAM,UAAU,KAAK,GAAG,QAAQ,MAAM,UAAU,KAAK,CAAC;AACvE,QAAM,YAAY,MAChB,IAAI,sBAAsB;AAAA,IACxB,EAAE,SAAS,cAAc,MAAM,YAAY;AAAA,IAC3C,EAAE,SAAS,iBAAiB,MAAM,YAAY;AAAA,IAC9C,EAAE,SAAS,eAAe,MAAM,YAAY;AAAA,IAC5C,EAAE,SAAS,oBAAoB,MAAM,YAAY;AAAA,IACjD,EAAE,SAAS,mBAAmB,MAAM,YAAY;AAAA,EAClD,CAAC;AACH,QAAM,QAAQ,QAAQ,SAAS,YAAY;AAC3C,QAAM,aAAa,gBAAgB,MAAM,SAAS,OAAO,OAAO;AAChE,QAAM,UAAU,cAAc;AAAA,IAC5B,GAAG,QAAQ;AAAA,IACX,SAAS,MAAM;AAAA,IACf,QAAQ,MAAM;AAAA,IACd,OAAO,QAAQ;AAAA,IACf;AAAA,EACF,CAAC;AACD,QAAM,UAAU;AAAA,IACd,MAAM;AAAA,IACN;AAAA,IACA;AAAA,IACA,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR,QAAQ;AAAA,IACR;AAAA,IACA,QAAQ,SAAS;AAAA,EACnB;AACA,QAAM,SAAS,aAAa;AAAA,IAC1B,SAAS,MAAM;AAAA,IACf,MAAM,CAAC,SAAS,UAAU,QAAQ,KAAK,SAAS,KAAK;AAAA,IACrD,OAAO,QAAQ,SAAS,SAAS;AAAA,IACjC,MAAM,aAAa,SAAS,OAAO;AACjC,UAAI,CAAC,QAAS,QAAO,MAAM,KAAK;AAChC,YAAM,QAAQ,MAAM,MAAM,OAAO,aAAa,SAAS,KAAK;AAC5D,UAAI,CAAC,MAAO,OAAM,IAAI,MAAM,qBAAqB,OAAO,GAAG;AAC3D,aAAO;AAAA,IACT;AAAA,EACF,CAAC;AACD,QAAM,oBAAoB;AAAA,IACxB;AAAA,IACA,YAAY,WAAW;AAAA,IACvB,QAAQ,QAAQ;AAAA,IAChB,OAAO,QAAQ;AAAA,IACf,UAAU,QAAQ,QAAQ,YAAY,gBAA2B,CAAC,CAAC;AAAA,IACnE,WAAW,QAAQ,WAAW,aAAa,gBAA4B,CAAC,CAAC;AAAA,IACzE,UAAU,QAAQ,QAAQ,YAAY,gBAA+B,CAAC,CAAC;AAAA,IACvE,cAAc,QAAQ,QAAQ,UAAU,gBAA+B,CAAC,CAAC;AAAA,IACzE,QAAQ,QAAQ,SAAS,UAAU,gBAA8B,CAAC,CAAC;AAAA,IACnE,SACE,QAAQ,SAAS,QAAQ,gBAA6B,EAAE,aAAa,MAAM,SAAS,CAAC,EAAE,CAAC;AAAA,IAC1F,SAAS,QAAQ;AAAA,IACjB,OAAO,QAAQ,SAAS,SAAS;AAAA,EACnC;AACA,QAAM,WAAW,QAAQ,YAAY;AACrC,QAAM,SAAS,CAACA,YAAuB;AACrC,UAAM,OAAO,UAAU;AACvB,SAAK,QAAQ,cAAc,OAAO;AAClC,SAAK,QAAQ,iBAAiB,iBAAiB;AAC/C,SAAK,QAAQ,eAAe,QAAQ;AACpC,SAAK,QAAQ,oBAAoB,MAAM;AACvC,SAAK,QAAQ,mBAAmBA,OAAM;AACtC,WAAO;AAAA,EACT;AACA,QAAM,QAAQ,MAAgB;AAC5B,UAAM,OAAO,WAAW,KAAK;AAC7B,UAAM,OAAO,OAAO,IAAI;AACxB,WAAO;AAAA,MACL,UAAU;AAAA,MACV,UAAU;AACR,aAAK,QAAQ;AACb,aAAK,QAAQ;AAAA,MACf;AAAA,IACF;AAAA,EACF;AACA,QAAM,WAAW,OAAO,UAAU,CAAC;AACnC,QAAM,SAAS,UAAU;AACzB,SAAO,QAAQ,cAAc,YAAY,OAAO,CAAC;AACjD,SAAO,QAAQ,iBAAiB,EAAE,GAAG,mBAAmB,SAAS,QAAQ,UAAU,CAAC;AACpF,SAAO,QAAQ,eAAe,aAAa,QAAQ,CAAC;AACpD,SAAO,QAAQ,oBAAoB,WAAW,MAAM,CAAC;AACrD,SAAO,QAAQ,mBAAmB,UAAU,CAAC;AAC7C,QAAM,SAAS,CAAC,aAAoC,OAAO;AAAA,IACzD,UAAU;AAAA,IACV,SAAS,MAAM;AAAA,EACjB;AACA,QAAM,QAAQ,OAAO,IAAY,WAA2B;AAC1D,UAAM,OAAmB;AAAA,MACvB,gBAAgB,eAAe;AAAA,MAC/B,MAAM,eAAe,WAAW;AAC9B,YAAI,cAAc;AAChB,gBAAM,IAAI,qBAAqB,mBAAmB,SAAS,EAAE;AAC/D,eAAO,EAAE,IAAI,UAAU;AAAA,MACzB;AAAA,MACA,aAAa,YAAY,gBAAgB,MAAM;AAAA,IACjD;AACA,UAAM,WAAW,IAAI,aAAa,EAAE;AACpC,UAAM,SAAS,MAAM,IAAI,OAAO,MAAM,EAAE,UAAU,IAAI,WAAW,CAAC,QAAQ,EAAE,CAAC,EAAE,MAAM;AACrF,WAAO,EAAE,UAAU,OAAO;AAAA,EAC5B;AACA,QAAM,OAAO,MAAM,MAAM,UAAU,KAAK;AACxC,QAAM,OAAO,MAAM,MAAM,OAAO,WAAW,GAAG,OAAO,MAAM,CAAC;AAC5D,QAAM,SAAS,MAAM,MAAM,OAAO,WAAW,GAAG,OAAO,QAAQ,CAAC;AAChE,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,QAAQ,QAAQ,EAAE,OAAO,QAAQ,MAAM,IAAI,CAAC;AAAA,IAChD,QAAQ,UAAU,gBAAgB;AAChC,YAAM,SAAS,gBAAgB,WAC3B,OACA,gBAAgB,UAAU,QACxB,SACA;AACN,aAAO,SAAS,QAAQ,QAAQ;AAAA,IAClC;AAAA,IACA,MAAM,QAAQ;AACZ,YAAM,KAAK,OAAO,MAAM;AACxB,YAAM,KAAK,OAAO,MAAM;AACxB,YAAM,OAAO,OAAO,MAAM;AAC1B,aAAO,QAAQ;AACf,eAAS,QAAQ;AACjB,YAAM,MAAM,QAAQ;AACpB,YAAM,QAAQ,QAAQ;AACtB,YAAM,OAAO,QAAQ;AACrB,iBAAW,QAAQ;AACnB,iBAAW,QAAQ;AACnB,cAAQ,QAAQ;AAChB,iBAAW,OAAO,QAAS,KAAI;AAC/B,cAAQ,SAAS,MAAM;AACvB,cAAQ,SAAS,QAAQ;AACzB,YAAM,QAAQ,SAAS,MAAM,OAAO;AACpC,YAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,YAAM,QAAQ,WAAW,MAAM,OAAO;AACtC,YAAM,QAAQ,QAAQ,MAAM,OAAO;AACnC,YAAM,QAAQ,KAAK,MAAM,OAAO;AAChC,YAAM,QAAQ,QAAQ,QAAQ,MAAM,OAAO;AAC3C,YAAM,QAAQ,OAAO,QAAQ,MAAM,OAAO;AAC1C,YAAM,MAAM,MAAM;AAClB,YAAM,QAAQ,OAAO,MAAM;AAAA,IAC7B;AAAA,EACF;AACF;",
|
|
6
6
|
"names": ["served"]
|
|
7
7
|
}
|
package/dist/kernel/env.js
CHANGED
|
@@ -3,10 +3,29 @@ import {
|
|
|
3
3
|
FileError,
|
|
4
4
|
ok
|
|
5
5
|
} from "@earendil-works/pi-durable/env";
|
|
6
|
+
import { mimeOf } from "../images/index.js";
|
|
6
7
|
import { execute } from "./exec.js";
|
|
7
8
|
import { attempt, info, KernelDirReader, SnapshotLines, SnapshotReader } from "./files.js";
|
|
8
9
|
import { dirname, normalize, resolve } from "./paths.js";
|
|
9
10
|
import { nativeWatch, pollWatch, RESCAN_MS } from "./watch.js";
|
|
11
|
+
const STREAMED_READ = 8 * 1024 * 1024;
|
|
12
|
+
const READ_CHUNK = 1024 * 1024;
|
|
13
|
+
async function scrubbedFile(scrub, bytes) {
|
|
14
|
+
if (mimeOf(bytes)) return bytes;
|
|
15
|
+
if (bytes.length <= STREAMED_READ) return (await scrub.texts([bytes]))[0];
|
|
16
|
+
const stream = scrub.stream();
|
|
17
|
+
const parts = [];
|
|
18
|
+
for (let at = 0; at < bytes.length; at += READ_CHUNK)
|
|
19
|
+
parts.push(await stream.push(bytes.subarray(at, at + READ_CHUNK)));
|
|
20
|
+
parts.push(await stream.end());
|
|
21
|
+
const all = new Uint8Array(parts.reduce((sum, part) => sum + part.length, 0));
|
|
22
|
+
let offset = 0;
|
|
23
|
+
for (const part of parts) {
|
|
24
|
+
all.set(part, offset);
|
|
25
|
+
offset += part.length;
|
|
26
|
+
}
|
|
27
|
+
return all;
|
|
28
|
+
}
|
|
10
29
|
function quote(value) {
|
|
11
30
|
return `'${value.replace(/'/g, "'\\''")}'`;
|
|
12
31
|
}
|
|
@@ -25,6 +44,8 @@ class SliccKernelEnv {
|
|
|
25
44
|
#groups;
|
|
26
45
|
#owner;
|
|
27
46
|
#exports;
|
|
47
|
+
#hooks;
|
|
48
|
+
#scrub;
|
|
28
49
|
constructor(client, options) {
|
|
29
50
|
this.#client = client;
|
|
30
51
|
this.cwd = options.cwd;
|
|
@@ -34,6 +55,12 @@ class SliccKernelEnv {
|
|
|
34
55
|
this.#groups = options.groups;
|
|
35
56
|
this.#owner = options.owner;
|
|
36
57
|
this.#exports = options.exports;
|
|
58
|
+
this.#scrub = options.scrub;
|
|
59
|
+
const scrub = options.scrub;
|
|
60
|
+
this.#hooks = {
|
|
61
|
+
...scrub ? { scrub: () => scrub.stream() } : {},
|
|
62
|
+
...options.spawn ? { spawn: options.spawn } : {}
|
|
63
|
+
};
|
|
37
64
|
}
|
|
38
65
|
#path(path) {
|
|
39
66
|
return resolve(this.cwd, path);
|
|
@@ -85,7 +112,10 @@ class SliccKernelEnv {
|
|
|
85
112
|
const stat = await this.#fs.stat(resolved);
|
|
86
113
|
if (stat.isDirectory) throw new FileError("is_directory", "Is a directory", resolved);
|
|
87
114
|
if (!stat.isFile) throw new FileError("invalid", "Not a regular file", resolved);
|
|
88
|
-
|
|
115
|
+
const bytes = await this.#fs.readFile(resolved);
|
|
116
|
+
if (!this.#scrub) return new SnapshotReader(bytes, info(resolved, stat));
|
|
117
|
+
const shown = await scrubbedFile(this.#scrub, bytes);
|
|
118
|
+
return new SnapshotReader(shown, { ...info(resolved, stat), size: shown.length });
|
|
89
119
|
});
|
|
90
120
|
}
|
|
91
121
|
writeFile(path, content, context) {
|
|
@@ -228,7 +258,16 @@ class SliccKernelEnv {
|
|
|
228
258
|
const groups = this.#groups;
|
|
229
259
|
const owner = this.#owner;
|
|
230
260
|
if (!groups || owner === void 0)
|
|
231
|
-
return execute(
|
|
261
|
+
return execute(
|
|
262
|
+
this.#client,
|
|
263
|
+
this.cwd,
|
|
264
|
+
line,
|
|
265
|
+
options,
|
|
266
|
+
context,
|
|
267
|
+
void 0,
|
|
268
|
+
void 0,
|
|
269
|
+
this.#hooks
|
|
270
|
+
).finally(ended);
|
|
232
271
|
return this.#grouped(groups, owner, line, options, context).finally(ended);
|
|
233
272
|
}
|
|
234
273
|
async #grouped(groups, owner, line, options, context) {
|
|
@@ -243,7 +282,16 @@ class SliccKernelEnv {
|
|
|
243
282
|
...pgid === void 0 ? {} : { pgid },
|
|
244
283
|
refused: (code) => groups.refused(owner, code)
|
|
245
284
|
} : void 0;
|
|
246
|
-
return execute(
|
|
285
|
+
return execute(
|
|
286
|
+
this.#client,
|
|
287
|
+
this.cwd,
|
|
288
|
+
line,
|
|
289
|
+
options,
|
|
290
|
+
context,
|
|
291
|
+
spawned,
|
|
292
|
+
join,
|
|
293
|
+
this.#hooks
|
|
294
|
+
).finally(release);
|
|
247
295
|
}
|
|
248
296
|
async cleanup(context) {
|
|
249
297
|
for (const watcher of [...this.#watchers]) await watcher.close(context);
|
|
@@ -263,9 +311,12 @@ function kernelEnvironment(client, options = {}) {
|
|
|
263
311
|
}
|
|
264
312
|
export {
|
|
265
313
|
HOME,
|
|
314
|
+
READ_CHUNK,
|
|
315
|
+
STREAMED_READ,
|
|
266
316
|
SliccKernelEnv,
|
|
267
317
|
kernelEnvironment,
|
|
268
318
|
prefixed,
|
|
269
|
-
quote
|
|
319
|
+
quote,
|
|
320
|
+
scrubbedFile
|
|
270
321
|
};
|
|
271
322
|
//# sourceMappingURL=env.js.map
|