@ai-ecoverse/slicc-agent 3.13.1 → 3.15.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 +22 -5
- package/bin/agent +1 -1
- package/dist/agents.js.map +2 -2
- package/dist/client.js +5 -1
- package/dist/client.js.map +2 -2
- package/dist/control.js +14 -1
- package/dist/control.js.map +2 -2
- package/dist/host.js +6 -2
- package/dist/host.js.map +2 -2
- package/dist/main.js +19 -2
- package/dist/main.js.map +2 -2
- package/dist/memory/context.js +91 -0
- package/dist/memory/context.js.map +7 -0
- package/dist/memory/format.js +251 -0
- package/dist/memory/format.js.map +7 -0
- package/dist/memory/index.js +32 -0
- package/dist/memory/index.js.map +7 -0
- package/dist/memory/prompt.js +175 -0
- package/dist/memory/prompt.js.map +7 -0
- package/dist/memory/runtime.js +194 -0
- package/dist/memory/runtime.js.map +7 -0
- package/dist/memory/store.js +153 -0
- package/dist/memory/store.js.map +7 -0
- package/dist/roles/frontmatter.js +9 -4
- package/dist/roles/frontmatter.js.map +2 -2
- package/dist/roles/roles.js +55 -11
- package/dist/roles/roles.js.map +2 -2
- package/dist/scoops/cli.js +3 -0
- package/dist/scoops/cli.js.map +2 -2
- package/dist/scoops/index.js +5 -3
- package/dist/scoops/index.js.map +2 -2
- package/dist/scoops/requests.js +1 -1
- package/dist/scoops/requests.js.map +2 -2
- package/dist/scoops/service.js +22 -4
- package/dist/scoops/service.js.map +2 -2
- package/dist/scoops/sync.js +1 -0
- package/dist/scoops/sync.js.map +2 -2
- 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/index.js +5 -1
- package/dist/spectrum/index.js.map +3 -3
- package/dist/spectrum/memory-port.js +64 -0
- package/dist/spectrum/memory-port.js.map +7 -0
- package/dist/types/agents.d.ts +7 -0
- package/dist/types/client.d.ts +3 -0
- package/dist/types/control.d.ts +2 -1
- package/dist/types/host.d.ts +2 -0
- package/dist/types/memory/context.d.ts +27 -0
- package/dist/types/memory/format.d.ts +67 -0
- package/dist/types/memory/index.d.ts +12 -0
- package/dist/types/memory/prompt.d.ts +48 -0
- package/dist/types/memory/runtime.d.ts +45 -0
- package/dist/types/memory/store.d.ts +41 -0
- package/dist/types/roles/frontmatter.d.ts +1 -1
- package/dist/types/roles/roles.d.ts +8 -0
- package/dist/types/scoops/cli.d.ts +1 -0
- package/dist/types/scoops/index.d.ts +1 -0
- package/dist/types/scoops/requests.d.ts +1 -1
- package/dist/types/scoops/service.d.ts +3 -0
- package/dist/types/services.d.ts +15 -0
- package/dist/types/spectrum/index.d.ts +3 -0
- package/dist/types/spectrum/memory-port.d.ts +12 -0
- package/package.json +4 -4
- package/packages/vfs-root/skills/memory/SKILL.md +48 -0
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/scoops/service.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n type AgentChange,\n type AnyTask,\n type Conversation,\n type ConversationId,\n configure,\n defineDoc,\n type Harness,\n type TaskId,\n type ToolRegistration,\n type Tx,\n} from '@earendil-works/pi-durable';\nimport {\n type Agents,\n type AgentsState,\n freeFolder,\n live,\n type Mark,\n type ScoopRecord,\n scoopId,\n} from '../agents.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport type { Role } from '../roles/roles.ts';\nimport { visible } from './visible.ts';\n\nexport const SCOOPS_ROOT = '/scoops';\nexport const LEDGER_SIZE = 512;\n\nexport type Feed = {\n scoop: string;\n created: Mark | null;\n report: boolean;\n target: string | null;\n channel: 'scoop-notify' | 'bash';\n from?: string;\n agent?: boolean;\n};\ntype Wait = { scoops: string[]; done: Record<string, string>; cone: string };\nexport type Answer = { code: number; out: string; tasks?: number[] };\ntype WorkState = {\n feeds: Record<string, Feed>;\n waits: Record<string, Wait>;\n ledger: Record<string, Answer>;\n turns: Record<string, { at: number; count: number }>;\n};\n\nexport const ScoopWorkDoc = defineDoc<WorkState>({\n kind: 'slicc.scoops.work',\n version: 1,\n scope: 'session',\n initial: () => ({ feeds: {}, waits: {}, ledger: {}, turns: {} }),\n});\n\nexport interface ScoopTasks {\n anchor: AnyTask;\n reporter: AnyTask;\n wait: AnyTask;\n}\n\nexport interface ScoopsHost {\n harness: Harness;\n agents: Agents;\n licks: Licks;\n groups?: ProcessGroups;\n tools?: readonly ToolRegistration[];\n reads?: () => readonly string[];\n}\n\nexport interface Rewound {\n stopped: string[];\n restored: string[];\n}\n\nexport interface ScoopSummary {\n id: string;\n folder: string;\n name: string;\n role: string | null;\n busy: boolean;\n}\n\nexport interface Limits {\n maxLiveScoops: number;\n maxPerTurn: number;\n}\n\nexport interface SpawnRequest {\n cone: string;\n kind?: 'async' | 'sync';\n parent?: string;\n depth?: number;\n roots?: { write: string[]; read: string[] };\n cwd?: string;\n instructions?: string;\n target?: string | null;\n asker?: string | null;\n name: string;\n role?: Role;\n model?: { provider: string; modelId: string };\n thinking?: AgentChange['thinkingLevel'];\n tools?: string[];\n prompts: string[];\n fromAgent: boolean;\n request?: string;\n limits: Limits;\n}\n\nexport function workspace(folder: string): string {\n return `${SCOOPS_ROOT}/${folder}/workspace`;\n}\n\nexport async function tail(conversation: Conversation, context: Context): Promise<Mark> {\n const { entries } = await conversation.context(context);\n return { in: conversation.id, at: Number(entries.at(-1)?.id ?? 0) };\n}\n\nexport async function turnStart(conversation: Conversation, context: Context): Promise<number> {\n const { entries } = await conversation.context(context);\n return Number(entries.findLast((entry) => entry.kind === 'pi.user')?.id ?? 0);\n}\n\nexport function coneOf(state: Readonly<AgentsState>, conversation: number): string | undefined {\n return Object.entries(state.cones).find(([, cone]) => cone.conversation === conversation)?.[0];\n}\n\nexport function findScoop(\n state: Readonly<AgentsState>,\n handle: string,\n cone: string | null\n): [string, ScoopRecord] | undefined {\n const id = handle.startsWith('scoop:') ? handle : scoopId(handle);\n const reachable = (record: ScoopRecord | undefined): record is ScoopRecord =>\n !!record && live(record) && (cone === null || record.cone === cone);\n const record = state.scoops[id];\n if (reachable(record)) return [id, record];\n return Object.entries(state.scoops).find(\n ([, candidate]) => reachable(candidate) && candidate.name === handle\n );\n}\n\nfunction remember(work: WorkState, request: string | undefined, answer: Answer): void {\n if (!request) return;\n work.ledger[request] = answer;\n const keys = Object.keys(work.ledger);\n for (const key of keys.slice(0, Math.max(0, keys.length - LEDGER_SIZE))) delete work.ledger[key];\n}\n\ntype Core = { host: Promise<ScoopsHost>; tasks: () => ScoopTasks };\n\nasync function coneOfId(core: Core, coneId: string, context: Context): Promise<Conversation> {\n const { agents } = await core.host;\n const found = await agents.conversation(coneId, context);\n if (!found) throw new Error(`There is no cone ${coneId}.`);\n return found;\n}\n\nasync function isBusy(core: Core, conversation: number, context: Context): Promise<boolean> {\n const { harness } = await core.host;\n const handle = await harness.conversation(conversation as ConversationId, context);\n const view = await handle?.viewState(context);\n const run = (view?.value.docs['pi.live'] as { run?: unknown } | undefined)?.run;\n view?.dispose();\n return Boolean(run);\n}\n\nasync function answered(\n core: Core,\n request: string | undefined,\n context: Context\n): Promise<Answer | undefined> {\n if (!request) return undefined;\n const { harness } = await core.host;\n return (await harness.snapshot(ScoopWorkDoc, context))?.ledger[request];\n}\n\ntype NewFeed = Omit<Feed, 'channel' | 'from'> & {\n from: string;\n agent: boolean;\n prompt: string;\n request?: string;\n followUp?: boolean;\n};\n\nasync function addFeed(core: Core, tx: Tx, parent: number, feed: NewFeed): Promise<number> {\n const task = await tx.createTask(\n core.tasks().reporter as never,\n {\n scoop: feed.scoop,\n prompt: feed.prompt,\n ...(feed.followUp ? { followUp: true } : {}),\n ...(feed.request ? { request: feed.request } : {}),\n },\n {\n ownership: { kind: 'conversation' },\n conversationId: parent as ConversationId,\n background: true,\n }\n );\n (await tx.doc(ScoopWorkDoc)).feeds[String(task)] = {\n scoop: feed.scoop,\n created: feed.created,\n report: feed.report,\n target: feed.target,\n channel: 'scoop-notify',\n from: feed.from,\n agent: feed.agent,\n };\n return Number(task);\n}\n\nfunction selection(tools: readonly ToolRegistration[] | undefined, names: string[] | undefined) {\n if (!names || !tools) return undefined;\n return tools.filter((tool) => names.includes(tool.name));\n}\n\nfunction liveCount(state: Readonly<AgentsState>, cone: string): number {\n return Object.values(state.scoops).filter((scoop) => scoop.cone === cone && live(scoop)).length;\n}\n\nfunction claimTurn(\n work: WorkState,\n request: SpawnRequest,\n turn: number | null\n): Answer | undefined {\n if (turn === null) return undefined;\n const counted = work.turns[request.cone];\n const count = counted && counted.at === turn ? counted.count : 0;\n if (count >= request.limits.maxPerTurn)\n return {\n code: 1,\n out: `subagent: this turn already started ${count} scoops (the limit is ${request.limits.maxPerTurn})\\n`,\n };\n work.turns[request.cone] = { at: turn, count: count + 1 };\n return undefined;\n}\n\nfunction agentChange(\n request: SpawnRequest,\n folder: string,\n tools: readonly ToolRegistration[] | undefined\n): AgentChange {\n const model = request.model ?? modelOf(request.role?.model);\n const thinking = request.thinking ?? request.role?.thinking;\n const chosen = selection(tools, request.tools ?? request.role?.tools);\n const instructions = [request.role?.prompt, request.instructions].filter(Boolean).join('\\n\\n');\n return {\n cwd: request.cwd ?? workspace(folder),\n ...(instructions ? { instructions } : {}),\n ...(model ? { model } : {}),\n ...(thinking ? { thinkingLevel: thinking as AgentChange['thinkingLevel'] } : {}),\n ...(chosen ? { tools: chosen } : {}),\n };\n}\n\nasync function spawn(core: Core, request: SpawnRequest, context: Context): Promise<Answer> {\n const done = await answered(core, request.request, context);\n if (done) return done;\n const { agents, tools } = await core.host;\n const parent = await coneOfId(core, request.cone, context);\n const count = liveCount(agents.state(), request.cone);\n if (count >= request.limits.maxLiveScoops)\n return {\n code: 1,\n out: `subagent: this cone already has ${count} live scoops (the limit is ${request.limits.maxLiveScoops}); stop one first\\n`,\n };\n const created = request.fromAgent ? await tail(parent, context) : null;\n const turn = request.fromAgent ? await turnStart(parent, context) : null;\n return agents.update(async (tx, doc) => {\n const work = await tx.doc(ScoopWorkDoc);\n const refused = claimTurn(work as WorkState, request, turn);\n if (refused) return refused;\n const folder = freeFolder(doc, request.name);\n const id = scoopId(folder);\n const anchor = await tx.createTask(core.tasks().anchor as never, null, {\n ownership: { kind: 'conversation' },\n conversationId: parent.id,\n background: true,\n });\n const child = await tx.createConversation({ ownership: { kind: 'task', taskId: anchor } });\n await configure(tx, child.id, agentChange(request, folder, tools));\n doc.scoops[id] = {\n name: request.name.trim() || folder,\n folder,\n cone: request.cone,\n conversation: child.id,\n anchor,\n role: request.role?.name ?? null,\n kind: request.kind ?? 'async',\n parent: request.parent ?? request.cone,\n depth: request.depth ?? 1,\n roots: request.roots ?? null,\n created,\n dropped: null,\n gone: false,\n };\n const target =\n request.target === undefined\n ? request.fromAgent\n ? `cone:${request.cone}`\n : null\n : request.target;\n const made: number[] = [];\n const asker = request.asker === undefined ? target : request.asker;\n const from = askerName(doc, asker);\n for (const prompt of request.prompts)\n made.push(\n await addFeed(core, tx, parent.id, {\n scoop: id,\n created,\n report: target !== null,\n target,\n from,\n agent: asker !== null,\n prompt,\n })\n );\n const answer = { code: 0, out: `${folder}\\n`, tasks: made };\n remember(work as WorkState, request.request, answer);\n return answer;\n }, context);\n}\n\nexport function askerName(state: Readonly<AgentsState>, asker: string | null): string {\n if (asker === null) return 'terminal';\n if (asker.startsWith('cone:')) return state.cones[asker.slice('cone:'.length)]?.name ?? asker;\n return state.scoops[asker]?.name ?? asker;\n}\n\nconst missing = (id: string): Answer => ({\n code: 1,\n out: `subagent: there is no scoop ${id.replace('scoop:', '')}\\n`,\n});\n\nasync function feed(\n core: Core,\n id: string,\n prompt: string,\n options: { fromAgent: boolean; request: string; followUp: boolean; target: string | null },\n context: Context\n): Promise<Answer> {\n const done = await answered(core, options.request, context);\n if (done) return done;\n const { harness, agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const parent = await coneOfId(core, record.cone, context);\n const created = options.fromAgent ? await tail(parent, context) : null;\n const { target } = options;\n return harness.commit(async (tx) => {\n await addFeed(core, tx, parent.id, {\n scoop: id,\n created,\n report: target !== null,\n target,\n from: askerName(agents.state(), target),\n agent: target !== null,\n prompt,\n followUp: options.followUp,\n request: options.request,\n });\n const answer = { code: 0, out: `sent to ${record.folder}\\n` };\n remember((await tx.doc(ScoopWorkDoc)) as WorkState, options.request, answer);\n return answer;\n }, context);\n}\n\nasync function signal(core: Core, record: ScoopRecord, context: Context): Promise<void> {\n const { harness, groups } = await core.host;\n const conversation = await harness.conversation(record.conversation as ConversationId, context);\n await conversation?.abort(context, { background: true });\n await groups?.signal(record.conversation);\n}\n\nasync function stopFeeds(\n core: Core,\n scoop: string,\n keep: (feed: Feed) => Promise<boolean>,\n context: Context\n) {\n const { harness } = await core.host;\n const work = (await harness.snapshot(ScoopWorkDoc, context)) ?? { feeds: {} };\n const dropped: string[] = [];\n for (const [task, entry] of Object.entries(work.feeds)) {\n if (entry.scoop !== scoop || (await keep(entry))) continue;\n const record = await harness.getTask(Number(task) as TaskId, context);\n if (record && record.state.status !== 'terminal')\n await harness.abortTask(Number(task) as TaskId, context);\n dropped.push(task);\n }\n if (dropped.length)\n await harness.commit(async (tx) => {\n const doc = await tx.doc(ScoopWorkDoc);\n for (const task of dropped) delete doc.feeds[task];\n }, context);\n return dropped.length;\n}\n\nasync function stop(core: Core, id: string, fromAgent: boolean, context: Context): Promise<Answer> {\n const { agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n await stopFeeds(core, id, async () => false, context);\n await signal(core, record, context);\n const mark = fromAgent\n ? await tail(await coneOfId(core, record.cone, context), context)\n : { in: 0, at: 0 };\n await agents.update((_tx, state) => {\n (state.scoops[id] as ScoopRecord).dropped = mark;\n }, context);\n return {\n code: 0,\n out: `stopped ${record.folder}; its transcript is kept, and its files stay in ${SCOOPS_ROOT}/${record.folder}\\n`,\n };\n}\n\nasync function rename(core: Core, id: string, name: string, context: Context): Promise<Answer> {\n const { agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const wanted = name.trim();\n if (!wanted) return { code: 2, out: 'subagent: rename needs a non-empty name\\n' };\n await agents.update((_tx, state) => {\n (state.scoops[id] as ScoopRecord).name = wanted;\n }, context);\n return { code: 0, out: `${record.folder} is now called ${wanted}\\n` };\n}\n\ntype Seen = (mark: Mark | null) => Promise<boolean>;\n\nasync function rewindOne(\n core: Core,\n coneId: string,\n id: string,\n record: ScoopRecord,\n seen: Seen,\n result: Rewound,\n context: Context\n): Promise<Partial<ScoopRecord> | undefined> {\n const { harness, licks } = await core.host;\n if (!(await seen(record.created))) {\n if (live(record)) {\n await stopFeeds(core, id, async () => false, context);\n await signal(core, record, context);\n result.stopped.push(record.name);\n }\n return { gone: true };\n }\n if (record.dropped !== null) {\n if (await seen(record.dropped)) return undefined;\n result.restored.push(record.name);\n return { dropped: null };\n }\n const withdrawn = await stopFeeds(core, id, (entry) => seen(entry.created), context);\n if (!withdrawn) return undefined;\n const conversation = await harness.conversation(record.conversation as ConversationId, context);\n await conversation?.abort(context);\n await licks.forget(`cone:${coneId}`, 'scoop-notify', id, context);\n return undefined;\n}\n\nasync function rewound(\n core: Core,\n coneId: string,\n fork: Conversation,\n context: Context\n): Promise<Rewound> {\n const { harness, agents } = await core.host;\n const read = (id: number) =>\n harness.commit((tx) => tx.conversation(id as ConversationId), context);\n const seen: Seen = async (mark) =>\n mark === null || mark.in === 0 || (await visible(read, fork.id, mark));\n const result: Rewound = { stopped: [], restored: [] };\n const changes: [string, Partial<ScoopRecord>][] = [];\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n if (record.cone !== coneId || record.gone) continue;\n const change = await rewindOne(core, coneId, id, record, seen, result, context);\n if (change) changes.push([id, change]);\n }\n if (changes.length)\n await agents.update((_tx, state) => {\n for (const [id, change] of changes) Object.assign(state.scoops[id] as ScoopRecord, change);\n }, context);\n return result;\n}\n\nasync function list(core: Core, coneId: string | null, context: Context): Promise<ScoopSummary[]> {\n const { agents } = await core.host;\n const out: ScoopSummary[] = [];\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n if ((coneId !== null && record.cone !== coneId) || !live(record)) continue;\n out.push({\n id,\n folder: record.folder,\n name: record.name,\n role: record.role,\n busy: await isBusy(core, record.conversation, context),\n });\n }\n return out;\n}\n\nasync function working(core: Core, ids: readonly string[], context: Context): Promise<string[]> {\n const { harness, agents } = await core.host;\n const feeds = Object.values((await harness.snapshot(ScoopWorkDoc, context))?.feeds ?? {});\n const out: string[] = [];\n for (const id of ids) {\n const record = agents.state().scoops[id];\n if (!record) continue;\n if (\n feeds.some((entry) => entry.scoop === id) ||\n (await isBusy(core, record.conversation, context))\n )\n out.push(id);\n }\n return out;\n}\n\nasync function notifyWhenDone(\n core: Core,\n coneId: string,\n ids: string[],\n deadline: number,\n context: Context\n) {\n const { harness } = await core.host;\n const parent = await coneOfId(core, coneId, context);\n await harness.commit(\n (tx) =>\n tx.createTask(\n core.tasks().wait as never,\n { scoops: ids, cone: coneId, deadline },\n { ownership: { kind: 'conversation' }, conversationId: parent.id, background: true }\n ),\n context\n );\n}\n\nasync function detach(core: Core, tasks: readonly number[], target: string, context: Context) {\n const { harness } = await core.host;\n await harness.commit(async (tx) => {\n const work = await tx.doc(ScoopWorkDoc);\n for (const task of tasks) {\n const entry = work.feeds[String(task)];\n if (!entry) continue;\n entry.report = true;\n entry.target = target;\n entry.channel = 'bash';\n }\n }, context);\n}\n\nasync function note(core: Core, id: string, text: string, context: Context): Promise<Answer> {\n const { agents, licks } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const label = `${record.name} (${record.role ?? 'scoop'})`;\n await licks.deliver(\n {\n channel: 'scoop-notify',\n source: `${id}#note`,\n title: label,\n text: `[scoop ${label} progress]`,\n body: text,\n target: `cone:${record.cone}`,\n },\n context\n );\n return { code: 0, out: 'note sent to the cone\\n' };\n}\n\nexport function createScoops(host: Promise<ScoopsHost>, tasks: () => ScoopTasks) {\n const core: Core = { host, tasks };\n return {\n detach: (made: readonly number[], target: string, context: Context) =>\n detach(core, made, target, context),\n note: (id: string, text: string, context: Context) => note(core, id, text, context),\n spawn: (request: SpawnRequest, context: Context) => spawn(core, request, context),\n feed: (\n id: string,\n prompt: string,\n options: { fromAgent: boolean; request: string; followUp: boolean; target: string | null },\n context: Context\n ) => feed(core, id, prompt, options, context),\n stop: (id: string, fromAgent: boolean, context: Context) => stop(core, id, fromAgent, context),\n rename: (id: string, name: string, context: Context) => rename(core, id, name, context),\n rewound: (coneId: string, fork: Conversation, context: Context) =>\n rewound(core, coneId, fork, context),\n list: (coneId: string | null, context: Context) => list(core, coneId, context),\n busy: (conversation: number, context: Context) => isBusy(core, conversation, context),\n working: (ids: readonly string[], context: Context) => working(core, ids, context),\n notifyWhenDone: (coneId: string, ids: string[], deadline: number, context: Context) =>\n notifyWhenDone(core, coneId, ids, deadline, context),\n };\n}\n\nexport function modelOf(\n value: string | undefined\n): { provider: string; modelId: string } | undefined {\n if (!value) return undefined;\n const at = value.indexOf('/');\n if (at <= 0) return undefined;\n return { provider: value.slice(0, at), modelId: value.slice(at + 1) };\n}\n\nexport type Scoops = ReturnType<typeof createScoops>;\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport {\n type AgentChange,\n type AnyTask,\n type Conversation,\n type ConversationId,\n configure,\n defineDoc,\n type Harness,\n type TaskId,\n type ToolRegistration,\n type Tx,\n} from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport {\n type Agents,\n type AgentsState,\n freeFolder,\n live,\n type Mark,\n type ScoopRecord,\n scoopId,\n} from '../agents.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport type { Role } from '../roles/roles.ts';\nimport { visible } from './visible.ts';\n\nexport const SCOOPS_ROOT = '/scoops';\nexport const LEDGER_SIZE = 512;\n\nexport type Feed = {\n scoop: string;\n created: Mark | null;\n report: boolean;\n target: string | null;\n channel: 'scoop-notify' | 'bash';\n from?: string;\n agent?: boolean;\n};\ntype Wait = { scoops: string[]; done: Record<string, string>; cone: string };\nexport type Answer = { code: number; out: string; tasks?: number[] };\ntype WorkState = {\n feeds: Record<string, Feed>;\n waits: Record<string, Wait>;\n ledger: Record<string, Answer>;\n turns: Record<string, { at: number; count: number }>;\n};\n\nexport const ScoopWorkDoc = defineDoc<WorkState>({\n kind: 'slicc.scoops.work',\n version: 1,\n scope: 'session',\n initial: () => ({ feeds: {}, waits: {}, ledger: {}, turns: {} }),\n});\n\nexport interface ScoopTasks {\n anchor: AnyTask;\n reporter: AnyTask;\n wait: AnyTask;\n}\n\nexport interface ScoopsHost {\n harness: Harness;\n agents: Agents;\n licks: Licks;\n groups?: ProcessGroups;\n tools?: readonly ToolRegistration[];\n reads?: () => readonly string[];\n files?: Pick<ExecutionEnv, 'remove' | 'createDir'>;\n}\n\nexport interface Rewound {\n stopped: string[];\n restored: string[];\n}\n\nexport interface ScoopSummary {\n id: string;\n folder: string;\n name: string;\n role: string | null;\n busy: boolean;\n}\n\nexport interface Limits {\n maxLiveScoops: number;\n maxPerTurn: number;\n}\n\nexport interface SpawnRequest {\n cone: string;\n kind?: 'async' | 'sync';\n parent?: string;\n depth?: number;\n roots?: { write: string[]; read: string[] };\n cwd?: string;\n origin?: string;\n instructions?: string;\n target?: string | null;\n asker?: string | null;\n name: string;\n role?: Role;\n model?: { provider: string; modelId: string };\n thinking?: AgentChange['thinkingLevel'];\n tools?: string[];\n prompts: string[];\n fromAgent: boolean;\n request?: string;\n limits: Limits;\n}\n\nexport function workspace(folder: string): string {\n return `${SCOOPS_ROOT}/${folder}/workspace`;\n}\n\nexport async function tail(conversation: Conversation, context: Context): Promise<Mark> {\n const { entries } = await conversation.context(context);\n return { in: conversation.id, at: Number(entries.at(-1)?.id ?? 0) };\n}\n\nexport async function turnStart(conversation: Conversation, context: Context): Promise<number> {\n const { entries } = await conversation.context(context);\n return Number(entries.findLast((entry) => entry.kind === 'pi.user')?.id ?? 0);\n}\n\nexport function coneOf(state: Readonly<AgentsState>, conversation: number): string | undefined {\n return Object.entries(state.cones).find(([, cone]) => cone.conversation === conversation)?.[0];\n}\n\nexport function findScoop(\n state: Readonly<AgentsState>,\n handle: string,\n cone: string | null\n): [string, ScoopRecord] | undefined {\n const id = handle.startsWith('scoop:') ? handle : scoopId(handle);\n const reachable = (record: ScoopRecord | undefined): record is ScoopRecord =>\n !!record && live(record) && (cone === null || record.cone === cone);\n const record = state.scoops[id];\n if (reachable(record)) return [id, record];\n return Object.entries(state.scoops).find(\n ([, candidate]) => reachable(candidate) && candidate.name === handle\n );\n}\n\nfunction remember(work: WorkState, request: string | undefined, answer: Answer): void {\n if (!request) return;\n work.ledger[request] = answer;\n const keys = Object.keys(work.ledger);\n for (const key of keys.slice(0, Math.max(0, keys.length - LEDGER_SIZE))) delete work.ledger[key];\n}\n\ntype Core = { host: Promise<ScoopsHost>; tasks: () => ScoopTasks };\n\nasync function coneOfId(core: Core, coneId: string, context: Context): Promise<Conversation> {\n const { agents } = await core.host;\n const found = await agents.conversation(coneId, context);\n if (!found) throw new Error(`There is no cone ${coneId}.`);\n return found;\n}\n\nasync function isBusy(core: Core, conversation: number, context: Context): Promise<boolean> {\n const { harness } = await core.host;\n const handle = await harness.conversation(conversation as ConversationId, context);\n const view = await handle?.viewState(context);\n const run = (view?.value.docs['pi.live'] as { run?: unknown } | undefined)?.run;\n view?.dispose();\n return Boolean(run);\n}\n\nasync function answered(\n core: Core,\n request: string | undefined,\n context: Context\n): Promise<Answer | undefined> {\n if (!request) return undefined;\n const { harness } = await core.host;\n return (await harness.snapshot(ScoopWorkDoc, context))?.ledger[request];\n}\n\ntype NewFeed = Omit<Feed, 'channel' | 'from'> & {\n from: string;\n agent: boolean;\n prompt: string;\n request?: string;\n followUp?: boolean;\n};\n\nasync function addFeed(core: Core, tx: Tx, parent: number, feed: NewFeed): Promise<number> {\n const task = await tx.createTask(\n core.tasks().reporter as never,\n {\n scoop: feed.scoop,\n prompt: feed.prompt,\n ...(feed.followUp ? { followUp: true } : {}),\n ...(feed.request ? { request: feed.request } : {}),\n },\n {\n ownership: { kind: 'conversation' },\n conversationId: parent as ConversationId,\n background: true,\n }\n );\n (await tx.doc(ScoopWorkDoc)).feeds[String(task)] = {\n scoop: feed.scoop,\n created: feed.created,\n report: feed.report,\n target: feed.target,\n channel: 'scoop-notify',\n from: feed.from,\n agent: feed.agent,\n };\n return Number(task);\n}\n\nfunction selection(tools: readonly ToolRegistration[] | undefined, names: string[] | undefined) {\n if (!names || !tools) return undefined;\n return tools.filter((tool) => names.includes(tool.name));\n}\n\nfunction liveCount(state: Readonly<AgentsState>, cone: string): number {\n return Object.values(state.scoops).filter((scoop) => scoop.cone === cone && live(scoop)).length;\n}\n\nfunction claimTurn(\n work: WorkState,\n request: SpawnRequest,\n turn: number | null\n): Answer | undefined {\n if (turn === null) return undefined;\n const counted = work.turns[request.cone];\n const count = counted && counted.at === turn ? counted.count : 0;\n if (count >= request.limits.maxPerTurn)\n return {\n code: 1,\n out: `subagent: this turn already started ${count} scoops (the limit is ${request.limits.maxPerTurn})\\n`,\n };\n work.turns[request.cone] = { at: turn, count: count + 1 };\n return undefined;\n}\n\nfunction agentChange(\n request: SpawnRequest,\n folder: string,\n tools: readonly ToolRegistration[] | undefined\n): AgentChange {\n const model = request.model ?? modelOf(request.role?.model);\n const thinking = request.thinking ?? request.role?.thinking;\n const chosen = selection(tools, request.tools ?? request.role?.tools);\n const instructions = [request.role?.prompt, request.instructions].filter(Boolean).join('\\n\\n');\n return {\n cwd: request.cwd ?? workspace(folder),\n ...(instructions ? { instructions } : {}),\n ...(model ? { model } : {}),\n ...(thinking ? { thinkingLevel: thinking as AgentChange['thinkingLevel'] } : {}),\n ...(chosen ? { tools: chosen } : {}),\n };\n}\n\nasync function spawn(core: Core, request: SpawnRequest, context: Context): Promise<Answer> {\n const done = await answered(core, request.request, context);\n if (done) return done;\n const { agents, tools } = await core.host;\n const parent = await coneOfId(core, request.cone, context);\n const count = liveCount(agents.state(), request.cone);\n if (count >= request.limits.maxLiveScoops)\n return {\n code: 1,\n out: `subagent: this cone already has ${count} live scoops (the limit is ${request.limits.maxLiveScoops}); stop one first\\n`,\n };\n const created = request.fromAgent ? await tail(parent, context) : null;\n const turn = request.fromAgent ? await turnStart(parent, context) : null;\n return agents.update(async (tx, doc) => {\n const work = await tx.doc(ScoopWorkDoc);\n const refused = claimTurn(work as WorkState, request, turn);\n if (refused) return refused;\n const folder = freeFolder(doc, request.name);\n const id = scoopId(folder);\n const anchor = await tx.createTask(core.tasks().anchor as never, null, {\n ownership: { kind: 'conversation' },\n conversationId: parent.id,\n background: true,\n });\n const child = await tx.createConversation({ ownership: { kind: 'task', taskId: anchor } });\n await configure(tx, child.id, agentChange(request, folder, tools));\n doc.scoops[id] = {\n name: request.name.trim() || folder,\n folder,\n cone: request.cone,\n conversation: child.id,\n anchor,\n role: request.role?.name ?? null,\n ...(request.role?.memory ? { memory: request.role.memory } : {}),\n ...(request.role?.memory && request.origin ? { origin: request.origin } : {}),\n ...(request.role?.context ? { context: request.role.context } : {}),\n kind: request.kind ?? 'async',\n parent: request.parent ?? request.cone,\n depth: request.depth ?? 1,\n roots: request.roots ?? null,\n created,\n dropped: null,\n gone: false,\n };\n const target =\n request.target === undefined\n ? request.fromAgent\n ? `cone:${request.cone}`\n : null\n : request.target;\n const made: number[] = [];\n const asker = request.asker === undefined ? target : request.asker;\n const from = askerName(doc, asker);\n for (const prompt of request.prompts)\n made.push(\n await addFeed(core, tx, parent.id, {\n scoop: id,\n created,\n report: target !== null,\n target,\n from,\n agent: asker !== null,\n prompt,\n })\n );\n const answer = { code: 0, out: `${folder}\\n`, tasks: made };\n remember(work as WorkState, request.request, answer);\n return answer;\n }, context);\n}\n\nexport function askerName(state: Readonly<AgentsState>, asker: string | null): string {\n if (asker === null) return 'terminal';\n if (asker.startsWith('cone:')) return state.cones[asker.slice('cone:'.length)]?.name ?? asker;\n return state.scoops[asker]?.name ?? asker;\n}\n\nconst missing = (id: string): Answer => ({\n code: 1,\n out: `subagent: there is no scoop ${id.replace('scoop:', '')}\\n`,\n});\n\nasync function feed(\n core: Core,\n id: string,\n prompt: string,\n options: { fromAgent: boolean; request: string; followUp: boolean; target: string | null },\n context: Context\n): Promise<Answer> {\n const done = await answered(core, options.request, context);\n if (done) return done;\n const { harness, agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const parent = await coneOfId(core, record.cone, context);\n const created = options.fromAgent ? await tail(parent, context) : null;\n const { target } = options;\n return harness.commit(async (tx) => {\n await addFeed(core, tx, parent.id, {\n scoop: id,\n created,\n report: target !== null,\n target,\n from: askerName(agents.state(), target),\n agent: target !== null,\n prompt,\n followUp: options.followUp,\n request: options.request,\n });\n const answer = { code: 0, out: `sent to ${record.folder}\\n` };\n remember((await tx.doc(ScoopWorkDoc)) as WorkState, options.request, answer);\n return answer;\n }, context);\n}\n\nasync function signal(core: Core, record: ScoopRecord, context: Context): Promise<void> {\n const { harness, groups } = await core.host;\n const conversation = await harness.conversation(record.conversation as ConversationId, context);\n await conversation?.abort(context, { background: true });\n await groups?.signal(record.conversation);\n}\n\nasync function stopFeeds(\n core: Core,\n scoop: string,\n keep: (feed: Feed) => Promise<boolean>,\n context: Context\n) {\n const { harness } = await core.host;\n const work = (await harness.snapshot(ScoopWorkDoc, context)) ?? { feeds: {} };\n const dropped: string[] = [];\n for (const [task, entry] of Object.entries(work.feeds)) {\n if (entry.scoop !== scoop || (await keep(entry))) continue;\n const record = await harness.getTask(Number(task) as TaskId, context);\n if (record && record.state.status !== 'terminal')\n await harness.abortTask(Number(task) as TaskId, context);\n dropped.push(task);\n }\n if (dropped.length)\n await harness.commit(async (tx) => {\n const doc = await tx.doc(ScoopWorkDoc);\n for (const task of dropped) delete doc.feeds[task];\n }, context);\n return dropped.length;\n}\n\nasync function stop(core: Core, id: string, fromAgent: boolean, context: Context): Promise<Answer> {\n const { agents, files } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n await stopFeeds(core, id, async () => false, context);\n await signal(core, record, context);\n const mark = fromAgent\n ? await tail(await coneOfId(core, record.cone, context), context)\n : { in: 0, at: 0 };\n await agents.update((_tx, state) => {\n (state.scoops[id] as ScoopRecord).dropped = mark;\n }, context);\n const removed = await files?.remove(\n workspace(record.folder),\n { recursive: true, force: true },\n context\n );\n const folder = removed?.ok\n ? `removed ${workspace(record.folder)}`\n : `kept ${workspace(record.folder)}`;\n return {\n code: 0,\n out: `stopped ${record.folder}; its transcript is kept, ${folder}, and its reports stay in ${SCOOPS_ROOT}/${record.folder}/reports\\n`,\n };\n}\n\nasync function rename(core: Core, id: string, name: string, context: Context): Promise<Answer> {\n const { agents } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const wanted = name.trim();\n if (!wanted) return { code: 2, out: 'subagent: rename needs a non-empty name\\n' };\n await agents.update((_tx, state) => {\n (state.scoops[id] as ScoopRecord).name = wanted;\n }, context);\n return { code: 0, out: `${record.folder} is now called ${wanted}\\n` };\n}\n\nasync function resetWorkspace(\n files: ScoopsHost['files'],\n folder: string,\n context: Context\n): Promise<boolean> {\n if (!files) return true;\n const cleared = await files.remove(workspace(folder), { recursive: true, force: true }, context);\n if (!cleared.ok) return false;\n return (await files.createDir(workspace(folder), { recursive: true }, context)).ok;\n}\n\ntype Seen = (mark: Mark | null) => Promise<boolean>;\n\nasync function rewindOne(\n core: Core,\n coneId: string,\n id: string,\n record: ScoopRecord,\n seen: Seen,\n result: Rewound,\n context: Context\n): Promise<Partial<ScoopRecord> | undefined> {\n const { harness, licks, files } = await core.host;\n if (!(await seen(record.created))) {\n if (live(record)) {\n await stopFeeds(core, id, async () => false, context);\n await signal(core, record, context);\n result.stopped.push(record.name);\n }\n return { gone: true };\n }\n if (record.dropped !== null) {\n if (await seen(record.dropped)) return undefined;\n const reset = await resetWorkspace(files, record.folder, context);\n result.restored.push(\n reset ? record.name : `${record.name} (its working folder could not be reset)`\n );\n return { dropped: null };\n }\n const withdrawn = await stopFeeds(core, id, (entry) => seen(entry.created), context);\n if (!withdrawn) return undefined;\n const conversation = await harness.conversation(record.conversation as ConversationId, context);\n await conversation?.abort(context);\n await licks.forget(`cone:${coneId}`, 'scoop-notify', id, context);\n return undefined;\n}\n\nasync function rewound(\n core: Core,\n coneId: string,\n fork: Conversation,\n context: Context\n): Promise<Rewound> {\n const { harness, agents } = await core.host;\n const read = (id: number) =>\n harness.commit((tx) => tx.conversation(id as ConversationId), context);\n const seen: Seen = async (mark) =>\n mark === null || mark.in === 0 || (await visible(read, fork.id, mark));\n const result: Rewound = { stopped: [], restored: [] };\n const changes: [string, Partial<ScoopRecord>][] = [];\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n if (record.cone !== coneId || record.gone) continue;\n const change = await rewindOne(core, coneId, id, record, seen, result, context);\n if (change) changes.push([id, change]);\n }\n if (changes.length)\n await agents.update((_tx, state) => {\n for (const [id, change] of changes) Object.assign(state.scoops[id] as ScoopRecord, change);\n }, context);\n return result;\n}\n\nasync function list(core: Core, coneId: string | null, context: Context): Promise<ScoopSummary[]> {\n const { agents } = await core.host;\n const out: ScoopSummary[] = [];\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n if ((coneId !== null && record.cone !== coneId) || !live(record)) continue;\n out.push({\n id,\n folder: record.folder,\n name: record.name,\n role: record.role,\n busy: await isBusy(core, record.conversation, context),\n });\n }\n return out;\n}\n\nasync function working(core: Core, ids: readonly string[], context: Context): Promise<string[]> {\n const { harness, agents } = await core.host;\n const feeds = Object.values((await harness.snapshot(ScoopWorkDoc, context))?.feeds ?? {});\n const out: string[] = [];\n for (const id of ids) {\n const record = agents.state().scoops[id];\n if (!record) continue;\n if (\n feeds.some((entry) => entry.scoop === id) ||\n (await isBusy(core, record.conversation, context))\n )\n out.push(id);\n }\n return out;\n}\n\nasync function notifyWhenDone(\n core: Core,\n coneId: string,\n ids: string[],\n deadline: number,\n context: Context\n) {\n const { harness } = await core.host;\n const parent = await coneOfId(core, coneId, context);\n await harness.commit(\n (tx) =>\n tx.createTask(\n core.tasks().wait as never,\n { scoops: ids, cone: coneId, deadline },\n { ownership: { kind: 'conversation' }, conversationId: parent.id, background: true }\n ),\n context\n );\n}\n\nasync function detach(core: Core, tasks: readonly number[], target: string, context: Context) {\n const { harness } = await core.host;\n await harness.commit(async (tx) => {\n const work = await tx.doc(ScoopWorkDoc);\n for (const task of tasks) {\n const entry = work.feeds[String(task)];\n if (!entry) continue;\n entry.report = true;\n entry.target = target;\n entry.channel = 'bash';\n }\n }, context);\n}\n\nasync function note(core: Core, id: string, text: string, context: Context): Promise<Answer> {\n const { agents, licks } = await core.host;\n const record = agents.state().scoops[id];\n if (!record || !live(record)) return missing(id);\n const label = `${record.name} (${record.role ?? 'scoop'})`;\n await licks.deliver(\n {\n channel: 'scoop-notify',\n source: `${id}#note`,\n title: label,\n text: `[scoop ${label} progress]`,\n body: text,\n target: `cone:${record.cone}`,\n },\n context\n );\n return { code: 0, out: 'note sent to the cone\\n' };\n}\n\nexport function createScoops(host: Promise<ScoopsHost>, tasks: () => ScoopTasks) {\n const core: Core = { host, tasks };\n return {\n detach: (made: readonly number[], target: string, context: Context) =>\n detach(core, made, target, context),\n note: (id: string, text: string, context: Context) => note(core, id, text, context),\n spawn: (request: SpawnRequest, context: Context) => spawn(core, request, context),\n feed: (\n id: string,\n prompt: string,\n options: { fromAgent: boolean; request: string; followUp: boolean; target: string | null },\n context: Context\n ) => feed(core, id, prompt, options, context),\n stop: (id: string, fromAgent: boolean, context: Context) => stop(core, id, fromAgent, context),\n rename: (id: string, name: string, context: Context) => rename(core, id, name, context),\n rewound: (coneId: string, fork: Conversation, context: Context) =>\n rewound(core, coneId, fork, context),\n list: (coneId: string | null, context: Context) => list(core, coneId, context),\n busy: (conversation: number, context: Context) => isBusy(core, conversation, context),\n working: (ids: readonly string[], context: Context) => working(core, ids, context),\n notifyWhenDone: (coneId: string, ids: string[], deadline: number, context: Context) =>\n notifyWhenDone(core, coneId, ids, deadline, context),\n };\n}\n\nexport function modelOf(\n value: string | undefined\n): { provider: string; modelId: string } | undefined {\n if (!value) return undefined;\n const at = value.indexOf('/');\n if (at <= 0) return undefined;\n return { provider: value.slice(0, at), modelId: value.slice(at + 1) };\n}\n\nexport type Scoops = ReturnType<typeof createScoops>;\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["record", "feed"]
|
|
7
7
|
}
|
package/dist/scoops/sync.js
CHANGED
|
@@ -206,6 +206,7 @@ async function runSync(deps, request, who, context) {
|
|
|
206
206
|
...chosen.thinking ? { thinking: chosen.thinking } : {},
|
|
207
207
|
...chosen.tools ? { tools: chosen.tools } : {},
|
|
208
208
|
prompts: planned.given,
|
|
209
|
+
origin: request.cwd,
|
|
209
210
|
fromAgent: who.fromAgent,
|
|
210
211
|
request: request.id,
|
|
211
212
|
limits: found.roles.limits
|
package/dist/scoops/sync.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/scoops/sync.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { ConversationId, EntryRecord, TaskId } from '@earendil-works/pi-durable';\nimport { answerText } from '../agent.ts';\nimport type { ScoopRecord } from '../agents.ts';\nimport { resolve } from '../kernel/paths.ts';\nimport {\n type Caller,\n choices,\n type Deps,\n fail,\n flags,\n isAnswer,\n last,\n MAX_DEPTH,\n prompts,\n readText,\n role,\n unsupported,\n} from './cli.ts';\nimport type { ReportResult } from './extension.ts';\nimport type { Request } from './requests.ts';\nimport { type Answer, SCOOPS_ROOT } from './service.ts';\n\nexport const SESSIONS = { tmp: '/tmp/agent-sessions', durable: '/home/sessions' };\n\ntype Ending = 'cancel' | 'detach';\n\ninterface Pending {\n end: (ending: Ending) => void;\n}\n\nexport interface SyncState {\n pending: Map<string, Pending>;\n}\n\nconst SYNC_VALUES = [\n '--name',\n '--agent',\n '--provider',\n '--model',\n '--thinking',\n '--effort',\n '--tools',\n '--prompt',\n '--file',\n '--read-only',\n '--system-prompt',\n '--system-prompt-file',\n '--background-after',\n];\nconst SYNC_SWITCHES = new Set([\n '--persist-session',\n '--no-persist-session',\n '--no-extensions',\n '--no-skills',\n '--no-context-files',\n]);\n\ntype Persist = 'tmp' | 'durable' | 'none';\n\nfunction persistOf(switches: Set<string>): Persist {\n if (switches.has('--no-persist-session')) return 'none';\n return switches.has('--persist-session') ? 'durable' : 'tmp';\n}\n\nfunction block(text: unknown): string {\n return typeof text === 'string' ? text : JSON.stringify(text, null, 2);\n}\n\nfunction entryMarkdown(entry: EntryRecord): string | undefined {\n const message = entry.model?.[0] as { content?: unknown; toolCallId?: string } | undefined;\n if (entry.kind === 'pi.user') return `## Request\\n\\n${answerText(message?.content)}`;\n if (entry.kind === 'pi.tool-result')\n return `### Result\\n\\n\\`\\`\\`\\n${answerText(message?.content)}\\n\\`\\`\\``;\n if (entry.kind !== 'pi.assistant') return undefined;\n const parts = Array.isArray(message?.content)\n ? (message.content as { type: string; name?: string; arguments?: unknown }[])\n : [];\n const calls = parts\n .filter((part) => part.type === 'toolCall')\n .map((part) => `\\`${part.name}\\` ${block(part.arguments)}`);\n return [`## Answer\\n\\n${answerText(message?.content)}`, ...calls].join('\\n\\n');\n}\n\nexport function transcript(record: ScoopRecord, entries: readonly EntryRecord[]): string {\n const body = entries.map(entryMarkdown).filter(Boolean);\n return `# ${record.name}${record.role ? ` (${record.role})` : ''}\\n\\n${body.join('\\n\\n')}\\n`;\n}\n\nasync function archive(\n deps: Deps,\n record: ScoopRecord,\n persist: Persist,\n context: Context\n): Promise<string | null> {\n if (persist === 'none') return null;\n const conversation = await deps.harness.conversation(\n record.conversation as ConversationId,\n context\n );\n if (!conversation) return null;\n const { entries } = await conversation.context(context);\n const path = `${SESSIONS[persist]}/${record.folder}.md`;\n await deps.env.writeFile(path, transcript(record, entries), context);\n return path;\n}\n\nasync function finish(deps: Deps, id: string, persist: Persist, context: Context): Promise<void> {\n const record = deps.agents.state().scoops[id];\n if (!record) return;\n await archive(deps, record, persist, context).catch(() => null);\n await deps.scoops.stop(id, false, context);\n await deps.env.remove(\n `${SCOOPS_ROOT}/${record.folder}`,\n { recursive: true, force: true },\n context\n );\n}\n\nasync function callerRunning(deps: Deps, who: Caller, context: Context): Promise<boolean> {\n if (!who.fromAgent) return false;\n const state = deps.agents.state();\n const conversation = who.scoop\n ? state.scoops[who.scoop]?.conversation\n : state.cones[who.cone]?.conversation;\n return conversation !== undefined && deps.scoops.busy(conversation, context);\n}\n\nasync function keep(\n deps: Deps,\n id: string,\n tasks: readonly number[],\n target: string | null,\n context: Context\n) {\n if (target) await deps.scoops.detach(tasks, target, context);\n await deps.agents.update((_tx, state) => {\n const record = state.scoops[id];\n if (record) record.kind = 'async';\n }, context);\n}\n\nfunction watchPid(deps: Deps, pid: number | null, end: (ending: Ending) => void): () => void {\n const alive = deps.alive;\n if (pid === null || !alive) return () => undefined;\n const timer = setInterval(() => {\n void alive(pid).then(\n (yes) => yes || end('cancel'),\n () => undefined\n );\n }, 1000);\n return () => clearInterval(timer);\n}\n\ninterface Plan {\n given: string[];\n workdir?: string;\n instructions: string;\n readOnly: string[];\n persist: Persist;\n}\n\nasync function plan(\n deps: Deps,\n request: Request,\n parsed: ReturnType<typeof flags>,\n context: Context\n) {\n const given = await prompts(deps, request.argv, request, context);\n let workdir: string | undefined;\n const notes: string[] = [];\n if (!given.length && parsed.rest.length === 3) {\n const [cwd, allowed, prompt] = parsed.rest as [string, string, string];\n workdir = resolve(request.cwd, cwd);\n if (allowed && allowed !== '*')\n notes.push(\n `Use only these commands in bash: ${allowed}. This is not enforced; keep to it anyway.`\n );\n given.push(prompt);\n } else if (parsed.rest.length) return fail(`unexpected argument ${parsed.rest[0]}`, 2);\n if (!given.length)\n return fail('agent needs --prompt, --file, - or <cwd> <allowed-commands> <prompt>', 2);\n const systemFile = last(parsed, '--system-prompt-file');\n const system =\n last(parsed, '--system-prompt') ??\n (systemFile ? await readText(deps, systemFile, request, context) : undefined);\n if (system) notes.push(system);\n if (workdir) notes.push(`Your working folder is ${workdir}; you may change files there.`);\n const readOnly = (last(parsed, '--read-only') ?? '')\n .split(',')\n .map((path) => path.trim())\n .filter(Boolean)\n .map((path) => resolve(request.cwd, path));\n const result: Plan = {\n given,\n instructions: notes.join('\\n\\n'),\n readOnly,\n persist: persistOf(parsed.switches),\n };\n if (workdir) result.workdir = workdir;\n return result;\n}\n\nasync function outcome(\n deps: Deps,\n tasks: readonly number[],\n context: Context\n): Promise<ReportResult> {\n let result: ReportResult = { text: '', failed: 'no request', path: null };\n for (const task of tasks) {\n const settled = await deps.harness.waitForTask(task as TaskId<ReportResult>, context);\n const outcome = settled.state.outcome;\n result =\n outcome.status === 'completed'\n ? outcome.result\n : { text: '', failed: outcome.status, path: null };\n }\n return result;\n}\n\nfunction answerOf(result: ReportResult): Answer {\n if (result.failed) return fail(`the scoop's request ended without an answer: ${result.failed}`);\n return { code: 0, out: result.text.endsWith('\\n') ? result.text : `${result.text}\\n` };\n}\n\nasync function settle(\n deps: Deps,\n who: Caller,\n id: string,\n tasks: readonly number[],\n ending: Ending,\n context: Context\n): Promise<Answer> {\n const handle = id.slice('scoop:'.length);\n if (ending === 'detach') {\n await keep(deps, id, tasks, who.id, context);\n const how = who.id ? 'its answer arrives as a lick' : `follow it with agent wait ${handle}`;\n return { code: 0, out: `${handle} continues in the background; ${how}\\n` };\n }\n if (await callerRunning(deps, who, context)) {\n await keep(deps, id, tasks, who.id, context);\n return {\n code: 143,\n out: `agent: the call was interrupted; ${handle} continues and its answer arrives as a lick\\n`,\n };\n }\n return { code: 130, out: 'agent: stopped\\n' };\n}\n\nexport async function runSync(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n const refused = unsupported(request.argv);\n if (refused) return refused;\n if (who.depth >= MAX_DEPTH) return fail(`agents nest at most ${MAX_DEPTH} deep`);\n const parsed = flags(request.argv, SYNC_VALUES);\n const unknown = [...parsed.switches].find((flag) => !SYNC_SWITCHES.has(flag));\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const planned = await plan(deps, request, parsed, context);\n if (isAnswer(planned)) return planned;\n const chosen = choices(parsed);\n if (isAnswer(chosen)) return chosen;\n const found = await role(deps, parsed);\n if (found.error) return found.error;\n const spawned = await deps.scoops.spawn(\n {\n cone: who.cone,\n kind: 'sync',\n parent: who.scoop ?? who.cone,\n depth: who.depth + 1,\n roots: { write: planned.workdir ? [planned.workdir] : [], read: planned.readOnly },\n ...(planned.workdir ? { cwd: planned.workdir } : {}),\n ...(planned.instructions ? { instructions: planned.instructions } : {}),\n target: null,\n asker: who.id,\n name: last(parsed, '--name') ?? found.role?.name ?? 'agent',\n ...(found.role ? { role: found.role } : {}),\n ...(chosen.model ? { model: chosen.model } : {}),\n ...(chosen.thinking ? { thinking: chosen.thinking as never } : {}),\n ...(chosen.tools ? { tools: chosen.tools } : {}),\n prompts: planned.given,\n fromAgent: who.fromAgent,\n request: request.id,\n limits: found.roles.limits,\n },\n context\n );\n if (spawned.code !== 0) return spawned;\n const id = `scoop:${spawned.out.trim()}`;\n const tasks = spawned.tasks ?? [];\n let end: (ending: Ending) => void = () => undefined;\n const ended = new Promise<Ending>((done) => {\n end = done;\n });\n deps.sync.pending.set(request.id, { end });\n const unwatch = watchPid(deps, request.pid, end);\n try {\n const raced = await Promise.race([outcome(deps, tasks, context), ended]);\n if (typeof raced === 'string') {\n const answer = await settle(deps, who, id, tasks, raced, context);\n if (answer.code === 130) await finish(deps, id, planned.persist, context);\n return answer;\n }\n await finish(deps, id, planned.persist, context);\n return answerOf(raced);\n } finally {\n unwatch();\n deps.sync.pending.delete(request.id);\n }\n}\n\nexport async function cancelSync(\n deps: Deps,\n requestId: string,\n _context: Context\n): Promise<Answer> {\n deps.sync.pending.get(requestId)?.end('cancel');\n return { code: 0, out: '' };\n}\n\nexport async function detachSync(\n deps: Deps,\n requestId: string,\n _context: Context\n): Promise<Answer> {\n deps.sync.pending.get(requestId)?.end('detach');\n return { code: 0, out: '' };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { ConversationId, EntryRecord, TaskId } from '@earendil-works/pi-durable';\nimport { answerText } from '../agent.ts';\nimport type { ScoopRecord } from '../agents.ts';\nimport { resolve } from '../kernel/paths.ts';\nimport {\n type Caller,\n choices,\n type Deps,\n fail,\n flags,\n isAnswer,\n last,\n MAX_DEPTH,\n prompts,\n readText,\n role,\n unsupported,\n} from './cli.ts';\nimport type { ReportResult } from './extension.ts';\nimport type { Request } from './requests.ts';\nimport { type Answer, SCOOPS_ROOT } from './service.ts';\n\nexport const SESSIONS = { tmp: '/tmp/agent-sessions', durable: '/home/sessions' };\n\ntype Ending = 'cancel' | 'detach';\n\ninterface Pending {\n end: (ending: Ending) => void;\n}\n\nexport interface SyncState {\n pending: Map<string, Pending>;\n}\n\nconst SYNC_VALUES = [\n '--name',\n '--agent',\n '--provider',\n '--model',\n '--thinking',\n '--effort',\n '--tools',\n '--prompt',\n '--file',\n '--read-only',\n '--system-prompt',\n '--system-prompt-file',\n '--background-after',\n];\nconst SYNC_SWITCHES = new Set([\n '--persist-session',\n '--no-persist-session',\n '--no-extensions',\n '--no-skills',\n '--no-context-files',\n]);\n\ntype Persist = 'tmp' | 'durable' | 'none';\n\nfunction persistOf(switches: Set<string>): Persist {\n if (switches.has('--no-persist-session')) return 'none';\n return switches.has('--persist-session') ? 'durable' : 'tmp';\n}\n\nfunction block(text: unknown): string {\n return typeof text === 'string' ? text : JSON.stringify(text, null, 2);\n}\n\nfunction entryMarkdown(entry: EntryRecord): string | undefined {\n const message = entry.model?.[0] as { content?: unknown; toolCallId?: string } | undefined;\n if (entry.kind === 'pi.user') return `## Request\\n\\n${answerText(message?.content)}`;\n if (entry.kind === 'pi.tool-result')\n return `### Result\\n\\n\\`\\`\\`\\n${answerText(message?.content)}\\n\\`\\`\\``;\n if (entry.kind !== 'pi.assistant') return undefined;\n const parts = Array.isArray(message?.content)\n ? (message.content as { type: string; name?: string; arguments?: unknown }[])\n : [];\n const calls = parts\n .filter((part) => part.type === 'toolCall')\n .map((part) => `\\`${part.name}\\` ${block(part.arguments)}`);\n return [`## Answer\\n\\n${answerText(message?.content)}`, ...calls].join('\\n\\n');\n}\n\nexport function transcript(record: ScoopRecord, entries: readonly EntryRecord[]): string {\n const body = entries.map(entryMarkdown).filter(Boolean);\n return `# ${record.name}${record.role ? ` (${record.role})` : ''}\\n\\n${body.join('\\n\\n')}\\n`;\n}\n\nasync function archive(\n deps: Deps,\n record: ScoopRecord,\n persist: Persist,\n context: Context\n): Promise<string | null> {\n if (persist === 'none') return null;\n const conversation = await deps.harness.conversation(\n record.conversation as ConversationId,\n context\n );\n if (!conversation) return null;\n const { entries } = await conversation.context(context);\n const path = `${SESSIONS[persist]}/${record.folder}.md`;\n await deps.env.writeFile(path, transcript(record, entries), context);\n return path;\n}\n\nasync function finish(deps: Deps, id: string, persist: Persist, context: Context): Promise<void> {\n const record = deps.agents.state().scoops[id];\n if (!record) return;\n await archive(deps, record, persist, context).catch(() => null);\n await deps.scoops.stop(id, false, context);\n await deps.env.remove(\n `${SCOOPS_ROOT}/${record.folder}`,\n { recursive: true, force: true },\n context\n );\n}\n\nasync function callerRunning(deps: Deps, who: Caller, context: Context): Promise<boolean> {\n if (!who.fromAgent) return false;\n const state = deps.agents.state();\n const conversation = who.scoop\n ? state.scoops[who.scoop]?.conversation\n : state.cones[who.cone]?.conversation;\n return conversation !== undefined && deps.scoops.busy(conversation, context);\n}\n\nasync function keep(\n deps: Deps,\n id: string,\n tasks: readonly number[],\n target: string | null,\n context: Context\n) {\n if (target) await deps.scoops.detach(tasks, target, context);\n await deps.agents.update((_tx, state) => {\n const record = state.scoops[id];\n if (record) record.kind = 'async';\n }, context);\n}\n\nfunction watchPid(deps: Deps, pid: number | null, end: (ending: Ending) => void): () => void {\n const alive = deps.alive;\n if (pid === null || !alive) return () => undefined;\n const timer = setInterval(() => {\n void alive(pid).then(\n (yes) => yes || end('cancel'),\n () => undefined\n );\n }, 1000);\n return () => clearInterval(timer);\n}\n\ninterface Plan {\n given: string[];\n workdir?: string;\n instructions: string;\n readOnly: string[];\n persist: Persist;\n}\n\nasync function plan(\n deps: Deps,\n request: Request,\n parsed: ReturnType<typeof flags>,\n context: Context\n) {\n const given = await prompts(deps, request.argv, request, context);\n let workdir: string | undefined;\n const notes: string[] = [];\n if (!given.length && parsed.rest.length === 3) {\n const [cwd, allowed, prompt] = parsed.rest as [string, string, string];\n workdir = resolve(request.cwd, cwd);\n if (allowed && allowed !== '*')\n notes.push(\n `Use only these commands in bash: ${allowed}. This is not enforced; keep to it anyway.`\n );\n given.push(prompt);\n } else if (parsed.rest.length) return fail(`unexpected argument ${parsed.rest[0]}`, 2);\n if (!given.length)\n return fail('agent needs --prompt, --file, - or <cwd> <allowed-commands> <prompt>', 2);\n const systemFile = last(parsed, '--system-prompt-file');\n const system =\n last(parsed, '--system-prompt') ??\n (systemFile ? await readText(deps, systemFile, request, context) : undefined);\n if (system) notes.push(system);\n if (workdir) notes.push(`Your working folder is ${workdir}; you may change files there.`);\n const readOnly = (last(parsed, '--read-only') ?? '')\n .split(',')\n .map((path) => path.trim())\n .filter(Boolean)\n .map((path) => resolve(request.cwd, path));\n const result: Plan = {\n given,\n instructions: notes.join('\\n\\n'),\n readOnly,\n persist: persistOf(parsed.switches),\n };\n if (workdir) result.workdir = workdir;\n return result;\n}\n\nasync function outcome(\n deps: Deps,\n tasks: readonly number[],\n context: Context\n): Promise<ReportResult> {\n let result: ReportResult = { text: '', failed: 'no request', path: null };\n for (const task of tasks) {\n const settled = await deps.harness.waitForTask(task as TaskId<ReportResult>, context);\n const outcome = settled.state.outcome;\n result =\n outcome.status === 'completed'\n ? outcome.result\n : { text: '', failed: outcome.status, path: null };\n }\n return result;\n}\n\nfunction answerOf(result: ReportResult): Answer {\n if (result.failed) return fail(`the scoop's request ended without an answer: ${result.failed}`);\n return { code: 0, out: result.text.endsWith('\\n') ? result.text : `${result.text}\\n` };\n}\n\nasync function settle(\n deps: Deps,\n who: Caller,\n id: string,\n tasks: readonly number[],\n ending: Ending,\n context: Context\n): Promise<Answer> {\n const handle = id.slice('scoop:'.length);\n if (ending === 'detach') {\n await keep(deps, id, tasks, who.id, context);\n const how = who.id ? 'its answer arrives as a lick' : `follow it with agent wait ${handle}`;\n return { code: 0, out: `${handle} continues in the background; ${how}\\n` };\n }\n if (await callerRunning(deps, who, context)) {\n await keep(deps, id, tasks, who.id, context);\n return {\n code: 143,\n out: `agent: the call was interrupted; ${handle} continues and its answer arrives as a lick\\n`,\n };\n }\n return { code: 130, out: 'agent: stopped\\n' };\n}\n\nexport async function runSync(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n const refused = unsupported(request.argv);\n if (refused) return refused;\n if (who.depth >= MAX_DEPTH) return fail(`agents nest at most ${MAX_DEPTH} deep`);\n const parsed = flags(request.argv, SYNC_VALUES);\n const unknown = [...parsed.switches].find((flag) => !SYNC_SWITCHES.has(flag));\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const planned = await plan(deps, request, parsed, context);\n if (isAnswer(planned)) return planned;\n const chosen = choices(parsed);\n if (isAnswer(chosen)) return chosen;\n const found = await role(deps, parsed);\n if (found.error) return found.error;\n const spawned = await deps.scoops.spawn(\n {\n cone: who.cone,\n kind: 'sync',\n parent: who.scoop ?? who.cone,\n depth: who.depth + 1,\n roots: { write: planned.workdir ? [planned.workdir] : [], read: planned.readOnly },\n ...(planned.workdir ? { cwd: planned.workdir } : {}),\n ...(planned.instructions ? { instructions: planned.instructions } : {}),\n target: null,\n asker: who.id,\n name: last(parsed, '--name') ?? found.role?.name ?? 'agent',\n ...(found.role ? { role: found.role } : {}),\n ...(chosen.model ? { model: chosen.model } : {}),\n ...(chosen.thinking ? { thinking: chosen.thinking as never } : {}),\n ...(chosen.tools ? { tools: chosen.tools } : {}),\n prompts: planned.given,\n origin: request.cwd,\n fromAgent: who.fromAgent,\n request: request.id,\n limits: found.roles.limits,\n },\n context\n );\n if (spawned.code !== 0) return spawned;\n const id = `scoop:${spawned.out.trim()}`;\n const tasks = spawned.tasks ?? [];\n let end: (ending: Ending) => void = () => undefined;\n const ended = new Promise<Ending>((done) => {\n end = done;\n });\n deps.sync.pending.set(request.id, { end });\n const unwatch = watchPid(deps, request.pid, end);\n try {\n const raced = await Promise.race([outcome(deps, tasks, context), ended]);\n if (typeof raced === 'string') {\n const answer = await settle(deps, who, id, tasks, raced, context);\n if (answer.code === 130) await finish(deps, id, planned.persist, context);\n return answer;\n }\n await finish(deps, id, planned.persist, context);\n return answerOf(raced);\n } finally {\n unwatch();\n deps.sync.pending.delete(request.id);\n }\n}\n\nexport async function cancelSync(\n deps: Deps,\n requestId: string,\n _context: Context\n): Promise<Answer> {\n deps.sync.pending.get(requestId)?.end('cancel');\n return { code: 0, out: '' };\n}\n\nexport async function detachSync(\n deps: Deps,\n requestId: string,\n _context: Context\n): Promise<Answer> {\n deps.sync.pending.get(requestId)?.end('detach');\n return { code: 0, out: '' };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": ["outcome"]
|
|
7
7
|
}
|
package/dist/services.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/services.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type Context,\n defineService,\n type JsonValue,\n type ReplicatedState,\n} from '@earendil-works/chord';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { Sprinkle } from './sprinkles/kind.ts';\n\nexport type SendMode = 'steer' | 'followUp' | 'reject';\n\nexport interface SendRequest {\n text: string;\n whenBusy: SendMode;\n requestId: string | null;\n agentId?: string | null;\n}\n\nexport interface OperationError {\n code: string;\n message: string;\n}\n\nexport type SendResponse =\n | { accepted: true; submissionId: string; error: null }\n | { accepted: false; submissionId: null; error: OperationError };\n\nexport type PromptResult =\n | { status: 'done'; text: string; reason: null }\n | { status: 'unanswered'; text: null; reason: string };\n\nexport interface AgentControl {\n send(request: SendRequest, context: Context): Promise<SendResponse>;\n wait(submissionId: string, context: Context): Promise<PromptResult>;\n withdraw(\n submissionId: string,\n context: Context\n ): Promise<{ outcome: 'withdrawn' | 'already_placed' | 'not_found' }>;\n abort(context: Context): Promise<void>;\n compact(instructions: string | null, context: Context): Promise<SendResponse>;\n reset(handoff: string | null, context: Context): Promise<void>;\n configure(change: AgentSettingsChange, context: Context): Promise<void>;\n rewind(messageId: string | null, context: Context): Promise<Rewound>;\n resolveLick(\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved>;\n webhook(\n name: string,\n delivery: WebhookRequest,\n context: Context\n ): Promise<{ delivered: boolean }>;\n stopAgent(agentId: string, context: Context): Promise<void>;\n selectCone(agentId: string, context: Context): Promise<void>;\n createCone(name: string, context: Context): Promise<Created>;\n createScoop(parentId: string, name: string, context: Context): Promise<Created>;\n drop(agentId: string, context: Context): Promise<Created>;\n unqueue(\n agentId: string | null,\n submissionId: string,\n context: Context\n ): Promise<{ outcome: 'withdrawn' | 'already_placed' | 'not_found' }>;\n sprinkleSend(\n sprinkleId: string,\n payload: { action: string; data: JsonValue | null; target: string | null },\n context: Context\n ): Promise<{ delivered: boolean }>;\n sprinkleCall(\n sprinkleId: string,\n method: string,\n args: JsonValue[],\n context: Context\n ): Promise<JsonValue>;\n}\n\nexport type Created = { id: string; error: null } | { id: null; error: string };\n\nexport interface AgentSummary {\n id: string;\n name: string;\n kind: 'cone' | 'scoop';\n parentId: string | null;\n role: string | null;\n}\n\nexport interface AgentsSummary {\n active: string;\n agents: AgentSummary[];\n}\n\nexport type LickResolved =\n | { done: true; text: string; error: null }\n | { done: false; text: null; error: string };\n\nexport interface WebhookRequest {\n id: string | null;\n headers: Record<string, string>;\n body: string;\n}\n\nexport type Rewound =\n | { done: true; text: string; reason: null }\n | { done: false; text: null; reason: 'busy' | 'no-turn' };\n\nexport interface AgentSettingsChange {\n model: { provider: string; modelId: string } | null;\n thinkingLevel: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | null;\n agentId?: string | null;\n}\n\nexport const AgentControl = defineService<AgentControl>('slicc.agent.control');\n\nexport type Delivered = 'run' | 'steer' | 'follow-up';\n\nexport interface AgentTranscript {\n readonly state: ReplicatedState<ConversationView>;\n readonly deliveries: ReplicatedState<Record<string, Delivered>>;\n readonly agents: ReplicatedState<AgentsSummary>;\n readonly views: ReplicatedState<Record<string, ConversationView>>;\n readonly commands: ReplicatedState<Command[]>;\n readonly sprinkles: ReplicatedState<Sprinkle[]>;\n}\n\nexport interface Command {\n name: string;\n description: string;\n kind: 'prompt' | 'skill';\n}\n\nexport const AgentTranscript = defineService<AgentTranscript>('slicc.agent.transcript');\n\nexport interface AgentSessions {\n attach(sessionId: string, context: Context): Promise<void>;\n detach(context: Context): Promise<void>;\n}\n\nexport const AgentSessions = defineService<AgentSessions>('slicc.agent.sessions');\n\nexport const AGENT_SESSION = 'agent';\n\nexport interface ModelChoice {\n id: string;\n label: string;\n provider: string;\n kind: 'chat' | 'classifier';\n reasoning: boolean;\n contextWindow: number;\n}\n\nexport interface AccountState {\n id: string;\n provider: string;\n identity: string;\n status: 'connected' | 'disconnected';\n auth: 'api-key' | 'oauth';\n needs: 'cors-free-transport' | null;\n}\n\nexport interface BudgetState {\n provider: string;\n percent: number;\n window: 'weekly';\n resets: string;\n}\n\nexport interface SignIn {\n clientId: string;\n scopes: string;\n imsEnvironment: string;\n}\n\nexport interface SettingsState {\n models: ModelChoice[];\n accounts: AccountState[];\n budget?: BudgetState | null;\n}\n\nexport interface AgentSettings {\n readonly state: ReplicatedState<SettingsState>;\n connect(\n providerId: string,\n secret: string,\n region: string | null,\n context: Context\n ): Promise<void>;\n disconnect(providerId: string, context: Context): Promise<void>;\n signIn(providerId: string, context: Context): Promise<SignIn | null>;\n}\n\nexport const AgentSettings = defineService<AgentSettings>('slicc.agent.settings');\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEE;AAAA,OAGK;
|
|
4
|
+
"sourcesContent": ["import {\n type Context,\n defineService,\n type JsonValue,\n type ReplicatedState,\n} from '@earendil-works/chord';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { MemoryEntry, MemoryScope, MemoryTag } from './memory/format.ts';\nimport type { Sprinkle } from './sprinkles/kind.ts';\n\nexport type SendMode = 'steer' | 'followUp' | 'reject';\n\nexport interface SendRequest {\n text: string;\n whenBusy: SendMode;\n requestId: string | null;\n agentId?: string | null;\n}\n\nexport interface OperationError {\n code: string;\n message: string;\n}\n\nexport type SendResponse =\n | { accepted: true; submissionId: string; error: null }\n | { accepted: false; submissionId: null; error: OperationError };\n\nexport type PromptResult =\n | { status: 'done'; text: string; reason: null }\n | { status: 'unanswered'; text: null; reason: string };\n\nexport interface AgentControl {\n send(request: SendRequest, context: Context): Promise<SendResponse>;\n wait(submissionId: string, context: Context): Promise<PromptResult>;\n withdraw(\n submissionId: string,\n context: Context\n ): Promise<{ outcome: 'withdrawn' | 'already_placed' | 'not_found' }>;\n abort(context: Context): Promise<void>;\n compact(instructions: string | null, context: Context): Promise<SendResponse>;\n reset(handoff: string | null, context: Context): Promise<void>;\n configure(change: AgentSettingsChange, context: Context): Promise<void>;\n rewind(messageId: string | null, context: Context): Promise<Rewound>;\n resolveLick(\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved>;\n webhook(\n name: string,\n delivery: WebhookRequest,\n context: Context\n ): Promise<{ delivered: boolean }>;\n stopAgent(agentId: string, context: Context): Promise<void>;\n selectCone(agentId: string, context: Context): Promise<void>;\n createCone(name: string, context: Context): Promise<Created>;\n createScoop(parentId: string, name: string, context: Context): Promise<Created>;\n drop(agentId: string, context: Context): Promise<Created>;\n unqueue(\n agentId: string | null,\n submissionId: string,\n context: Context\n ): Promise<{ outcome: 'withdrawn' | 'already_placed' | 'not_found' }>;\n sprinkleSend(\n sprinkleId: string,\n payload: { action: string; data: JsonValue | null; target: string | null },\n context: Context\n ): Promise<{ delivered: boolean }>;\n sprinkleCall(\n sprinkleId: string,\n method: string,\n args: JsonValue[],\n context: Context\n ): Promise<JsonValue>;\n memorySave(draft: MemoryDraft, context: Context): Promise<MemoryEntry>;\n memoryRemove(id: string, context: Context): Promise<{ removed: boolean }>;\n}\n\nexport interface MemoryDraft {\n id: string | null;\n scope: string;\n section: string;\n title: string;\n body: string;\n tag: MemoryTag | null;\n}\n\nexport type Created = { id: string; error: null } | { id: null; error: string };\n\nexport interface AgentSummary {\n id: string;\n name: string;\n kind: 'cone' | 'scoop';\n parentId: string | null;\n role: string | null;\n}\n\nexport interface AgentsSummary {\n active: string;\n agents: AgentSummary[];\n}\n\nexport type LickResolved =\n | { done: true; text: string; error: null }\n | { done: false; text: null; error: string };\n\nexport interface WebhookRequest {\n id: string | null;\n headers: Record<string, string>;\n body: string;\n}\n\nexport type Rewound =\n | { done: true; text: string; reason: null }\n | { done: false; text: null; reason: 'busy' | 'no-turn' };\n\nexport interface AgentSettingsChange {\n model: { provider: string; modelId: string } | null;\n thinkingLevel: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | null;\n agentId?: string | null;\n}\n\nexport const AgentControl = defineService<AgentControl>('slicc.agent.control');\n\nexport type Delivered = 'run' | 'steer' | 'follow-up';\n\nexport interface AgentTranscript {\n readonly state: ReplicatedState<ConversationView>;\n readonly deliveries: ReplicatedState<Record<string, Delivered>>;\n readonly agents: ReplicatedState<AgentsSummary>;\n readonly views: ReplicatedState<Record<string, ConversationView>>;\n readonly commands: ReplicatedState<Command[]>;\n readonly sprinkles: ReplicatedState<Sprinkle[]>;\n readonly memories: ReplicatedState<MemoryEntry[]>;\n readonly memoryScopes: ReplicatedState<MemoryScope[]>;\n}\n\nexport interface Command {\n name: string;\n description: string;\n kind: 'prompt' | 'skill';\n}\n\nexport const AgentTranscript = defineService<AgentTranscript>('slicc.agent.transcript');\n\nexport interface AgentSessions {\n attach(sessionId: string, context: Context): Promise<void>;\n detach(context: Context): Promise<void>;\n}\n\nexport const AgentSessions = defineService<AgentSessions>('slicc.agent.sessions');\n\nexport const AGENT_SESSION = 'agent';\n\nexport interface ModelChoice {\n id: string;\n label: string;\n provider: string;\n kind: 'chat' | 'classifier';\n reasoning: boolean;\n contextWindow: number;\n}\n\nexport interface AccountState {\n id: string;\n provider: string;\n identity: string;\n status: 'connected' | 'disconnected';\n auth: 'api-key' | 'oauth';\n needs: 'cors-free-transport' | null;\n}\n\nexport interface BudgetState {\n provider: string;\n percent: number;\n window: 'weekly';\n resets: string;\n}\n\nexport interface SignIn {\n clientId: string;\n scopes: string;\n imsEnvironment: string;\n}\n\nexport interface SettingsState {\n models: ModelChoice[];\n accounts: AccountState[];\n budget?: BudgetState | null;\n}\n\nexport interface AgentSettings {\n readonly state: ReplicatedState<SettingsState>;\n connect(\n providerId: string,\n secret: string,\n region: string | null,\n context: Context\n ): Promise<void>;\n disconnect(providerId: string, context: Context): Promise<void>;\n signIn(providerId: string, context: Context): Promise<SignIn | null>;\n}\n\nexport const AgentSettings = defineService<AgentSettings>('slicc.agent.settings');\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EAEE;AAAA,OAGK;AAsHA,MAAM,eAAe,cAA4B,qBAAqB;AAqBtE,MAAM,kBAAkB,cAA+B,wBAAwB;AAO/E,MAAM,gBAAgB,cAA6B,sBAAsB;AAEzE,MAAM,gBAAgB;AAmDtB,MAAM,gBAAgB,cAA6B,sBAAsB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/skills/index.js
CHANGED
|
@@ -10,7 +10,14 @@ import {
|
|
|
10
10
|
loadSkills
|
|
11
11
|
} from "./skills.js";
|
|
12
12
|
import { expandPromptTemplate, loadTemplates } from "./templates.js";
|
|
13
|
-
const BUILTIN_SKILLS = [
|
|
13
|
+
const BUILTIN_SKILLS = [
|
|
14
|
+
"agent",
|
|
15
|
+
"licks",
|
|
16
|
+
"memory",
|
|
17
|
+
"skill-authoring",
|
|
18
|
+
"sprinkles",
|
|
19
|
+
"welcome"
|
|
20
|
+
];
|
|
14
21
|
const BUILTIN_PROMPTS = ["parallel-review", "review-loop"];
|
|
15
22
|
const SKILLS_DIR = "/var/lib/slicc/agent/skills";
|
|
16
23
|
const PROMPTS_DIR = "/var/lib/slicc/agent/prompts";
|
package/dist/skills/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/skills/index.ts"],
|
|
4
|
-
"sourcesContent": ["import { type Context, type ReplicatedState, replicatedState } from '@earendil-works/chord';\nimport {\n defineExtension,\n type Extension,\n type Registry,\n section,\n} from '@earendil-works/pi-durable';\nimport type { ExecutionEnv, FileWatcher } from '@earendil-works/pi-durable/env';\nimport type { Licks } from '../licks/licks.ts';\nimport { manifestDirs } from '../roles/roles.ts';\nimport type { Command } from '../services.ts';\nimport {\n type Diagnostic,\n expandSkillCommand,\n formatSkillsForPrompt,\n loadSkills,\n type Skill,\n type SkillRoot,\n} from './skills.ts';\nimport { expandPromptTemplate, loadTemplates, type PromptTemplate } from './templates.ts';\n\nexport const BUILTIN_SKILLS = ['agent'
|
|
5
|
-
"mappings": "AAAA,SAA6C,uBAAuB;AACpE;AAAA,EACE;AAAA,EAGA;AAAA,OACK;AAGP,SAAS,oBAAoB;AAE7B;AAAA,EAEE;AAAA,EACA;AAAA,EACA;AAAA,OAGK;AACP,SAAS,sBAAsB,qBAA0C;AAElE,MAAM,iBAAiB,
|
|
4
|
+
"sourcesContent": ["import { type Context, type ReplicatedState, replicatedState } from '@earendil-works/chord';\nimport {\n defineExtension,\n type Extension,\n type Registry,\n section,\n} from '@earendil-works/pi-durable';\nimport type { ExecutionEnv, FileWatcher } from '@earendil-works/pi-durable/env';\nimport type { Licks } from '../licks/licks.ts';\nimport { manifestDirs } from '../roles/roles.ts';\nimport type { Command } from '../services.ts';\nimport {\n type Diagnostic,\n expandSkillCommand,\n formatSkillsForPrompt,\n loadSkills,\n type Skill,\n type SkillRoot,\n} from './skills.ts';\nimport { expandPromptTemplate, loadTemplates, type PromptTemplate } from './templates.ts';\n\nexport const BUILTIN_SKILLS = [\n 'agent',\n 'licks',\n 'memory',\n 'skill-authoring',\n 'sprinkles',\n 'welcome',\n];\nexport const BUILTIN_PROMPTS = ['parallel-review', 'review-loop'];\nexport const SKILLS_DIR = '/var/lib/slicc/agent/skills';\nexport const PROMPTS_DIR = '/var/lib/slicc/agent/prompts';\nexport const COMPAT_DIR = '/workspace/skills';\nexport const RELOAD_MS = 300;\n\nexport interface SkillsRuntime {\n readonly commands: ReplicatedState<Command[]>;\n skills(): readonly Skill[];\n dirs(): string[];\n templates(): readonly PromptTemplate[];\n expand(text: string, context: Context): Promise<string>;\n reload(context: Context): Promise<void>;\n close(context: Context): Promise<void>;\n}\n\nexport interface SkillsAttach {\n env: ExecutionEnv;\n home: string;\n assets?: (path: string) => Promise<string>;\n reloadMs: number;\n}\n\nexport interface SkillsSetup {\n extension: Extension;\n attach(options: SkillsAttach, context: Context): Promise<SkillsRuntime>;\n}\n\ntype Manifest = { pi?: { skills?: unknown; prompts?: unknown } };\n\nexport function piResources(dir: string, text: string, kind: 'skills' | 'prompts'): string[] {\n let manifest: Manifest;\n try {\n manifest = JSON.parse(text) as Manifest;\n } catch {\n return [];\n }\n const listed = manifest.pi?.[kind];\n const paths = Array.isArray(listed) ? listed : typeof listed === 'string' ? [listed] : [];\n return paths\n .filter((path): path is string => typeof path === 'string')\n .map((path) => `${dir}/${path.replace(/^\\.\\//, '').replace(/\\/$/, '')}`);\n}\n\nasync function packaged(env: ExecutionEnv, kind: 'skills' | 'prompts', context: Context) {\n const out: string[] = [];\n for (const dir of await manifestDirs(env, '/node_modules', context)) {\n const read = await env.readTextFile(`${dir}/package.json`, context);\n if (read.ok) out.push(...piResources(dir, read.value, kind));\n }\n return out;\n}\n\nasync function installBuiltins(\n env: ExecutionEnv,\n assets: (path: string) => Promise<string>,\n context: Context\n): Promise<void> {\n await env.remove(SKILLS_DIR, { recursive: true, force: true }, context);\n await env.remove(PROMPTS_DIR, { recursive: true, force: true }, context);\n for (const name of BUILTIN_SKILLS) {\n const text = await assets(`packages/vfs-root/skills/${name}/SKILL.md`).catch(() => undefined);\n if (text === undefined) continue;\n await env.createDir(`${SKILLS_DIR}/${name}`, { recursive: true }, context);\n await env.writeFile(`${SKILLS_DIR}/${name}/SKILL.md`, text, context);\n }\n await env.createDir(PROMPTS_DIR, { recursive: true }, context);\n for (const name of BUILTIN_PROMPTS) {\n const text = await assets(`packages/vfs-root/prompts/${name}.md`).catch(() => undefined);\n if (text !== undefined) await env.writeFile(`${PROMPTS_DIR}/${name}.md`, text, context);\n }\n}\n\nexport function problemLick(problem: Diagnostic, home: string) {\n const path = problem.path.startsWith(`${home}/`)\n ? `~${problem.path.slice(home.length)}`\n : problem.path;\n return {\n channel: 'fswatch' as const,\n source: `skills:${path}`,\n title: `Skill or prompt template problem: ${path}`,\n text: problem.message,\n body: 'The file is used with this problem, or skipped if it has no description.\\nThe rules are in the slicc-agent README.',\n target: 'cone' as const,\n severity: 'warn' as const,\n eventId: `${path}\\n${problem.message}`,\n };\n}\n\nexport function commandsOf(\n skills: readonly Skill[],\n templates: readonly PromptTemplate[]\n): Command[] {\n return [\n ...templates.map((template) => ({\n name: template.name,\n description: template.description,\n kind: 'prompt' as const,\n })),\n ...skills.map((skill) => ({\n name: `skill:${skill.name}`,\n description: skill.description,\n kind: 'skill' as const,\n })),\n ];\n}\n\nexport function setupSkills(registry: Registry, licks: Licks): SkillsSetup {\n let current: Skill[] = [];\n const extension = defineExtension({\n name: 'slicc-skills',\n sections: [section('skills', async () => formatSkillsForPrompt(current) || undefined)],\n });\n registry.install(extension);\n return {\n extension,\n async attach(options, context) {\n const { env, home } = options;\n if (options.assets)\n await installBuiltins(env, options.assets, context).catch(() => undefined);\n let templates: PromptTemplate[] = [];\n const commands = replicatedState<Command[]>([]);\n const reported = new Set<string>();\n const reload = async (using: Context) => {\n const roots: SkillRoot[] = [\n { dir: `${home}/.pi/agent/skills`, source: 'user' },\n { dir: `${home}/.agents/skills`, source: 'user' },\n { dir: COMPAT_DIR, source: 'compat' },\n ...(await packaged(env, 'skills', using)).map((dir) => ({\n dir,\n source: 'package' as const,\n })),\n { dir: SKILLS_DIR, source: 'builtin' },\n ];\n const loaded = await loadSkills(env, roots, using);\n const prompts = await loadTemplates(\n env,\n [`${home}/.pi/agent/prompts`, ...(await packaged(env, 'prompts', using)), PROMPTS_DIR],\n using\n );\n current = loaded.skills;\n templates = prompts.templates;\n commands.replace(using, commandsOf(current, templates));\n for (const problem of [...loaded.diagnostics, ...prompts.diagnostics]) {\n const key = `${problem.path}\\n${problem.message}`;\n if (reported.has(key)) continue;\n reported.add(key);\n await licks.deliver(problemLick(problem, home), using).catch(() => undefined);\n }\n };\n await reload(context);\n let timer: ReturnType<typeof setTimeout> | undefined;\n const schedule = () => {\n clearTimeout(timer);\n timer = setTimeout(() => void reload(context).catch(() => undefined), options.reloadMs);\n };\n const watched = await env.watch(\n [\n { path: `${home}/.pi/agent/skills`, recursive: true },\n { path: `${home}/.pi/agent/prompts` },\n { path: `${home}/.agents/skills`, recursive: true },\n { path: COMPAT_DIR, recursive: true },\n ],\n schedule,\n context\n );\n const watcher: FileWatcher | undefined = watched.ok ? watched.value : undefined;\n return {\n commands,\n skills: () => current,\n dirs: () => current.map((skill) => skill.baseDir),\n templates: () => templates,\n async expand(text, using) {\n const expanded = await expandSkillCommand(text, current, env, using);\n return expanded === text ? expandPromptTemplate(text, templates) : expanded;\n },\n reload,\n async close(using) {\n clearTimeout(timer);\n await watcher?.close(using);\n },\n };\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/spectrum/index.js
CHANGED
|
@@ -1,8 +1,10 @@
|
|
|
1
1
|
import { AgentAdapter } from "./agent-port.js";
|
|
2
|
+
import { MemoryAdapter } from "./memory-port.js";
|
|
2
3
|
import { SettingsAdapter } from "./settings-port.js";
|
|
3
4
|
import { SprinkleAdapter } from "./sprinkle-port.js";
|
|
4
5
|
import { TrayAdapter } from "./tray-port.js";
|
|
5
6
|
import { AgentAdapter as AgentAdapter2, CONE } from "./agent-port.js";
|
|
7
|
+
import { MemoryAdapter as MemoryAdapter2 } from "./memory-port.js";
|
|
6
8
|
import {
|
|
7
9
|
assistant,
|
|
8
10
|
errorAction,
|
|
@@ -26,12 +28,14 @@ function createAgentModel(connection, options = {}) {
|
|
|
26
28
|
options.login ?? null
|
|
27
29
|
),
|
|
28
30
|
tray: new TrayAdapter(connection.settings),
|
|
29
|
-
sprinkles: new SprinkleAdapter(connection)
|
|
31
|
+
sprinkles: new SprinkleAdapter(connection),
|
|
32
|
+
memory: new MemoryAdapter(connection)
|
|
30
33
|
};
|
|
31
34
|
}
|
|
32
35
|
export {
|
|
33
36
|
AgentAdapter2 as AgentAdapter,
|
|
34
37
|
CONE,
|
|
38
|
+
MemoryAdapter2 as MemoryAdapter,
|
|
35
39
|
SETTINGS_KEY,
|
|
36
40
|
SettingsAdapter2 as SettingsAdapter,
|
|
37
41
|
SprinkleAdapter2 as SprinkleAdapter,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/spectrum/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { AgentConnection } from '../client.ts';\nimport { AgentAdapter } from './agent-port.ts';\nimport { type Login, SettingsAdapter } from './settings-port.ts';\nimport { SprinkleAdapter } from './sprinkle-port.ts';\nimport { TrayAdapter } from './tray-port.ts';\n\nexport { AgentAdapter, CONE } from './agent-port.ts';\nexport {\n assistant,\n errorAction,\n errorPart,\n isBusy,\n queued,\n textOf,\n toMessages,\n} from './messages.ts';\nexport { type Login, SETTINGS_KEY, SettingsAdapter } from './settings-port.ts';\nexport { SprinkleAdapter } from './sprinkle-port.ts';\nexport { TrayAdapter } from './tray-port.ts';\n\nexport function createAgentModel(\n connection: AgentConnection,\n options: { storage?: Pick<Storage, 'getItem' | 'setItem'> | null; login?: Login } = {}\n): {\n agent: AgentAdapter;\n settings: SettingsAdapter;\n tray: TrayAdapter;\n sprinkles: SprinkleAdapter;\n} {\n const agent = new AgentAdapter(connection);\n return {\n agent,\n settings: new SettingsAdapter(\n connection.settings,\n agent,\n options.storage ?? null,\n options.login ?? null\n ),\n tray: new TrayAdapter(connection.settings),\n sprinkles: new SprinkleAdapter(connection),\n };\n}\n"],
|
|
5
|
-
"mappings": "AACA,SAAS,oBAAoB;AAC7B,SAAqB,uBAAuB;AAC5C,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAE5B,SAAS,gBAAAA,eAAc,YAAY;AACnC;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAqB,cAAc,mBAAAC,wBAAuB;AAC1D,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,eAAAC,oBAAmB;AAErB,SAAS,iBACd,YACA,UAAoF,CAAC,
|
|
6
|
-
"names": ["AgentAdapter", "SettingsAdapter", "SprinkleAdapter", "TrayAdapter"]
|
|
4
|
+
"sourcesContent": ["import type { AgentConnection } from '../client.ts';\nimport { AgentAdapter } from './agent-port.ts';\nimport { MemoryAdapter } from './memory-port.ts';\nimport { type Login, SettingsAdapter } from './settings-port.ts';\nimport { SprinkleAdapter } from './sprinkle-port.ts';\nimport { TrayAdapter } from './tray-port.ts';\n\nexport { AgentAdapter, CONE } from './agent-port.ts';\nexport { MemoryAdapter } from './memory-port.ts';\nexport {\n assistant,\n errorAction,\n errorPart,\n isBusy,\n queued,\n textOf,\n toMessages,\n} from './messages.ts';\nexport { type Login, SETTINGS_KEY, SettingsAdapter } from './settings-port.ts';\nexport { SprinkleAdapter } from './sprinkle-port.ts';\nexport { TrayAdapter } from './tray-port.ts';\n\nexport function createAgentModel(\n connection: AgentConnection,\n options: { storage?: Pick<Storage, 'getItem' | 'setItem'> | null; login?: Login } = {}\n): {\n agent: AgentAdapter;\n settings: SettingsAdapter;\n tray: TrayAdapter;\n sprinkles: SprinkleAdapter;\n memory: MemoryAdapter;\n} {\n const agent = new AgentAdapter(connection);\n return {\n agent,\n settings: new SettingsAdapter(\n connection.settings,\n agent,\n options.storage ?? null,\n options.login ?? null\n ),\n tray: new TrayAdapter(connection.settings),\n sprinkles: new SprinkleAdapter(connection),\n memory: new MemoryAdapter(connection),\n };\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,oBAAoB;AAC7B,SAAS,qBAAqB;AAC9B,SAAqB,uBAAuB;AAC5C,SAAS,uBAAuB;AAChC,SAAS,mBAAmB;AAE5B,SAAS,gBAAAA,eAAc,YAAY;AACnC,SAAS,iBAAAC,sBAAqB;AAC9B;AAAA,EACE;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,OACK;AACP,SAAqB,cAAc,mBAAAC,wBAAuB;AAC1D,SAAS,mBAAAC,wBAAuB;AAChC,SAAS,eAAAC,oBAAmB;AAErB,SAAS,iBACd,YACA,UAAoF,CAAC,GAOrF;AACA,QAAM,QAAQ,IAAI,aAAa,UAAU;AACzC,SAAO;AAAA,IACL;AAAA,IACA,UAAU,IAAI;AAAA,MACZ,WAAW;AAAA,MACX;AAAA,MACA,QAAQ,WAAW;AAAA,MACnB,QAAQ,SAAS;AAAA,IACnB;AAAA,IACA,MAAM,IAAI,YAAY,WAAW,QAAQ;AAAA,IACzC,WAAW,IAAI,gBAAgB,UAAU;AAAA,IACzC,QAAQ,IAAI,cAAc,UAAU;AAAA,EACtC;AACF;",
|
|
6
|
+
"names": ["AgentAdapter", "MemoryAdapter", "SettingsAdapter", "SprinkleAdapter", "TrayAdapter"]
|
|
7
7
|
}
|
|
@@ -0,0 +1,64 @@
|
|
|
1
|
+
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
|
2
|
+
import { slugOf as slug } from "../memory/format.js";
|
|
3
|
+
import { Emitter } from "./emitter.js";
|
|
4
|
+
class MemoryAdapter extends Emitter {
|
|
5
|
+
#connection;
|
|
6
|
+
#pending = /* @__PURE__ */ new Map();
|
|
7
|
+
constructor(connection) {
|
|
8
|
+
super();
|
|
9
|
+
this.#connection = connection;
|
|
10
|
+
connection.memories?.subscribe(() => {
|
|
11
|
+
this.#pending.clear();
|
|
12
|
+
this.emit("memories", this.list());
|
|
13
|
+
});
|
|
14
|
+
connection.memoryScopes?.subscribe(() => this.emit("memories", this.list()));
|
|
15
|
+
}
|
|
16
|
+
list() {
|
|
17
|
+
const stored = this.#connection.memories?.value ?? [];
|
|
18
|
+
if (!this.#pending.size) return stored;
|
|
19
|
+
const out = stored.filter((item) => !this.#pending.has(item.id));
|
|
20
|
+
for (const item of this.#pending.values()) if (item) out.push(item);
|
|
21
|
+
return out;
|
|
22
|
+
}
|
|
23
|
+
scopes() {
|
|
24
|
+
return this.#connection.memoryScopes?.value ?? [];
|
|
25
|
+
}
|
|
26
|
+
save(draft) {
|
|
27
|
+
const memory = {
|
|
28
|
+
...draft,
|
|
29
|
+
id: `${draft.scope}/${slug(draft.section)}/${slug(draft.title)}`,
|
|
30
|
+
updatedAt: Date.now(),
|
|
31
|
+
source: "entry"
|
|
32
|
+
};
|
|
33
|
+
if (draft.id && draft.id !== memory.id) this.#pending.set(draft.id, null);
|
|
34
|
+
this.#pending.set(memory.id, memory);
|
|
35
|
+
this.emit("memories", this.list());
|
|
36
|
+
void this.#connection.control.memorySave(
|
|
37
|
+
{
|
|
38
|
+
id: draft.id ?? null,
|
|
39
|
+
scope: draft.scope,
|
|
40
|
+
section: draft.section,
|
|
41
|
+
title: draft.title,
|
|
42
|
+
body: draft.body,
|
|
43
|
+
tag: draft.tag
|
|
44
|
+
},
|
|
45
|
+
BACKGROUND_CONTEXT
|
|
46
|
+
).catch(() => {
|
|
47
|
+
this.#pending.clear();
|
|
48
|
+
this.emit("memories", this.list());
|
|
49
|
+
});
|
|
50
|
+
return memory;
|
|
51
|
+
}
|
|
52
|
+
remove(id) {
|
|
53
|
+
this.#pending.set(id, null);
|
|
54
|
+
this.emit("memories", this.list());
|
|
55
|
+
void this.#connection.control.memoryRemove(id, BACKGROUND_CONTEXT).catch(() => {
|
|
56
|
+
this.#pending.delete(id);
|
|
57
|
+
this.emit("memories", this.list());
|
|
58
|
+
});
|
|
59
|
+
}
|
|
60
|
+
}
|
|
61
|
+
export {
|
|
62
|
+
MemoryAdapter
|
|
63
|
+
};
|
|
64
|
+
//# sourceMappingURL=memory-port.js.map
|
|
@@ -0,0 +1,7 @@
|
|
|
1
|
+
{
|
|
2
|
+
"version": 3,
|
|
3
|
+
"sources": ["../../src/spectrum/memory-port.ts"],
|
|
4
|
+
"sourcesContent": ["import type { Memory, MemoryDraft, MemoryEvents, MemoryPort } from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentConnection } from '../client.ts';\nimport { type MemoryScope, slugOf as slug } from '../memory/format.ts';\nimport { Emitter } from './emitter.ts';\n\ntype Local = Memory & { source?: 'entry' | 'notes' };\n\nexport class MemoryAdapter extends Emitter<MemoryEvents> implements MemoryPort {\n readonly #connection: AgentConnection;\n #pending = new Map<string, Local | null>();\n\n constructor(connection: AgentConnection) {\n super();\n this.#connection = connection;\n connection.memories?.subscribe(() => {\n this.#pending.clear();\n this.emit('memories', this.list());\n });\n connection.memoryScopes?.subscribe(() => this.emit('memories', this.list()));\n }\n\n list(): readonly Memory[] {\n const stored = (this.#connection.memories?.value ?? []) as Local[];\n if (!this.#pending.size) return stored;\n const out = stored.filter((item) => !this.#pending.has(item.id));\n for (const item of this.#pending.values()) if (item) out.push(item);\n return out;\n }\n\n scopes(): readonly MemoryScope[] {\n return this.#connection.memoryScopes?.value ?? [];\n }\n\n save(draft: MemoryDraft): Memory {\n const memory: Local = {\n ...draft,\n id: `${draft.scope}/${slug(draft.section)}/${slug(draft.title)}`,\n updatedAt: Date.now(),\n source: 'entry',\n };\n if (draft.id && draft.id !== memory.id) this.#pending.set(draft.id, null);\n this.#pending.set(memory.id, memory);\n this.emit('memories', this.list());\n void this.#connection.control\n .memorySave(\n {\n id: draft.id ?? null,\n scope: draft.scope,\n section: draft.section,\n title: draft.title,\n body: draft.body,\n tag: draft.tag,\n },\n BACKGROUND_CONTEXT\n )\n .catch(() => {\n this.#pending.clear();\n this.emit('memories', this.list());\n });\n return memory;\n }\n\n remove(id: string): void {\n this.#pending.set(id, null);\n this.emit('memories', this.list());\n void this.#connection.control.memoryRemove(id, BACKGROUND_CONTEXT).catch(() => {\n this.#pending.delete(id);\n this.emit('memories', this.list());\n });\n }\n}\n"],
|
|
5
|
+
"mappings": "AACA,SAAS,0BAA0B;AAEnC,SAA2B,UAAU,YAAY;AACjD,SAAS,eAAe;AAIjB,MAAM,sBAAsB,QAA4C;AAAA,EACpE;AAAA,EACT,WAAW,oBAAI,IAA0B;AAAA,EAEzC,YAAY,YAA6B;AACvC,UAAM;AACN,SAAK,cAAc;AACnB,eAAW,UAAU,UAAU,MAAM;AACnC,WAAK,SAAS,MAAM;AACpB,WAAK,KAAK,YAAY,KAAK,KAAK,CAAC;AAAA,IACnC,CAAC;AACD,eAAW,cAAc,UAAU,MAAM,KAAK,KAAK,YAAY,KAAK,KAAK,CAAC,CAAC;AAAA,EAC7E;AAAA,EAEA,OAA0B;AACxB,UAAM,SAAU,KAAK,YAAY,UAAU,SAAS,CAAC;AACrD,QAAI,CAAC,KAAK,SAAS,KAAM,QAAO;AAChC,UAAM,MAAM,OAAO,OAAO,CAAC,SAAS,CAAC,KAAK,SAAS,IAAI,KAAK,EAAE,CAAC;AAC/D,eAAW,QAAQ,KAAK,SAAS,OAAO,EAAG,KAAI,KAAM,KAAI,KAAK,IAAI;AAClE,WAAO;AAAA,EACT;AAAA,EAEA,SAAiC;AAC/B,WAAO,KAAK,YAAY,cAAc,SAAS,CAAC;AAAA,EAClD;AAAA,EAEA,KAAK,OAA4B;AAC/B,UAAM,SAAgB;AAAA,MACpB,GAAG;AAAA,MACH,IAAI,GAAG,MAAM,KAAK,IAAI,KAAK,MAAM,OAAO,CAAC,IAAI,KAAK,MAAM,KAAK,CAAC;AAAA,MAC9D,WAAW,KAAK,IAAI;AAAA,MACpB,QAAQ;AAAA,IACV;AACA,QAAI,MAAM,MAAM,MAAM,OAAO,OAAO,GAAI,MAAK,SAAS,IAAI,MAAM,IAAI,IAAI;AACxE,SAAK,SAAS,IAAI,OAAO,IAAI,MAAM;AACnC,SAAK,KAAK,YAAY,KAAK,KAAK,CAAC;AACjC,SAAK,KAAK,YAAY,QACnB;AAAA,MACC;AAAA,QACE,IAAI,MAAM,MAAM;AAAA,QAChB,OAAO,MAAM;AAAA,QACb,SAAS,MAAM;AAAA,QACf,OAAO,MAAM;AAAA,QACb,MAAM,MAAM;AAAA,QACZ,KAAK,MAAM;AAAA,MACb;AAAA,MACA;AAAA,IACF,EACC,MAAM,MAAM;AACX,WAAK,SAAS,MAAM;AACpB,WAAK,KAAK,YAAY,KAAK,KAAK,CAAC;AAAA,IACnC,CAAC;AACH,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,IAAkB;AACvB,SAAK,SAAS,IAAI,IAAI,IAAI;AAC1B,SAAK,KAAK,YAAY,KAAK,KAAK,CAAC;AACjC,SAAK,KAAK,YAAY,QAAQ,aAAa,IAAI,kBAAkB,EAAE,MAAM,MAAM;AAC7E,WAAK,SAAS,OAAO,EAAE;AACvB,WAAK,KAAK,YAAY,KAAK,KAAK,CAAC;AAAA,IACnC,CAAC;AAAA,EACH;AACF;",
|
|
6
|
+
"names": []
|
|
7
|
+
}
|
package/dist/types/agents.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import type { Context } from '@earendil-works/chord';
|
|
2
2
|
import { type Conversation, type Harness, type Tx } from '@earendil-works/pi-durable';
|
|
3
|
+
import type { RoleMemory } from './memory/store.ts';
|
|
3
4
|
export declare const FIRST_CONE = "cone";
|
|
4
5
|
export type ConeRecord = {
|
|
5
6
|
name: string;
|
|
@@ -16,6 +17,12 @@ export type ScoopRecord = {
|
|
|
16
17
|
conversation: number;
|
|
17
18
|
anchor: number;
|
|
18
19
|
role: string | null;
|
|
20
|
+
memory?: RoleMemory;
|
|
21
|
+
origin?: string;
|
|
22
|
+
context?: {
|
|
23
|
+
project: boolean;
|
|
24
|
+
global: boolean;
|
|
25
|
+
};
|
|
19
26
|
kind: 'async' | 'sync';
|
|
20
27
|
parent: string;
|
|
21
28
|
depth: number;
|
package/dist/types/client.d.ts
CHANGED
|
@@ -1,5 +1,6 @@
|
|
|
1
1
|
import { type Context, type ReplicatedState } from '@earendil-works/chord';
|
|
2
2
|
import type { ConversationView } from '@earendil-works/pi-durable';
|
|
3
|
+
import type { MemoryEntry, MemoryScope } from './memory/format.ts';
|
|
3
4
|
import { AgentControl, AgentSettings, type AgentsSummary, type Command, type Delivered, type SendMode } from './services.ts';
|
|
4
5
|
import type { Sprinkle } from './sprinkles/kind.ts';
|
|
5
6
|
import { type PortEndpoint } from './wire.ts';
|
|
@@ -12,6 +13,8 @@ export interface AgentConnection {
|
|
|
12
13
|
readonly views?: ReplicatedState<Record<string, ConversationView>>;
|
|
13
14
|
readonly commands?: ReplicatedState<Command[]>;
|
|
14
15
|
readonly sprinkles?: ReplicatedState<Sprinkle[]>;
|
|
16
|
+
readonly memories?: ReplicatedState<MemoryEntry[]>;
|
|
17
|
+
readonly memoryScopes?: ReplicatedState<MemoryScope[]>;
|
|
15
18
|
readonly settings: AgentSettings;
|
|
16
19
|
prompt(text: string, whenBusy?: SendMode): Promise<string>;
|
|
17
20
|
close(): Promise<void>;
|
package/dist/types/control.d.ts
CHANGED
|
@@ -2,6 +2,7 @@ import { type Conversation, type Harness, type SubmissionId } from '@earendil-wo
|
|
|
2
2
|
import type { Cones } from './cone.ts';
|
|
3
3
|
import type { Deliveries } from './deliveries.ts';
|
|
4
4
|
import type { LickSources, Licks } from './licks/index.ts';
|
|
5
|
+
import type { MemoryRuntime } from './memory/index.ts';
|
|
5
6
|
import type { Scoops, ScoopsRuntime } from './scoops/index.ts';
|
|
6
7
|
import type { AgentControl } from './services.ts';
|
|
7
8
|
import type { SkillsRuntime } from './skills/index.ts';
|
|
@@ -16,4 +17,4 @@ export interface HostScoops {
|
|
|
16
17
|
}
|
|
17
18
|
export declare function readable(out: string): string;
|
|
18
19
|
export declare function submissionId(value: string): SubmissionId | undefined;
|
|
19
|
-
export declare function createAgentControl(harness: Harness, target: Conversation | Cones, deliveries?: Deliveries, licks?: HostLicks, scoops?: HostScoops, skills?: Pick<SkillsRuntime, 'expand'>, sprinkles?: Pick<SprinklesRuntime, 'send' | 'call'>): AgentControl;
|
|
20
|
+
export declare function createAgentControl(harness: Harness, target: Conversation | Cones, deliveries?: Deliveries, licks?: HostLicks, scoops?: HostScoops, skills?: Pick<SkillsRuntime, 'expand'>, sprinkles?: Pick<SprinklesRuntime, 'send' | 'call'>, memory?: Pick<MemoryRuntime, 'save' | 'remove'>): AgentControl;
|
package/dist/types/host.d.ts
CHANGED
|
@@ -1,6 +1,7 @@
|
|
|
1
1
|
import { type Context } from '@earendil-works/chord';
|
|
2
2
|
import type { Agent } from './agent.ts';
|
|
3
3
|
import { type HostLicks, type HostScoops } from './control.ts';
|
|
4
|
+
import type { MemoryRuntime } from './memory/index.ts';
|
|
4
5
|
import { AgentSettings } from './services.ts';
|
|
5
6
|
import type { SkillsRuntime } from './skills/index.ts';
|
|
6
7
|
import type { SprinklesRuntime } from './sprinkles/index.ts';
|
|
@@ -19,4 +20,5 @@ export declare function hostAgent(agent: Agent, options?: {
|
|
|
19
20
|
scoops?: HostScoops;
|
|
20
21
|
skills?: SkillsRuntime;
|
|
21
22
|
sprinkles?: SprinklesRuntime;
|
|
23
|
+
memory?: MemoryRuntime;
|
|
22
24
|
}): Promise<AgentHost>;
|