@ai-ecoverse/slicc-agent 3.40.1 → 3.42.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 +25 -4
- package/bin/agent +9 -4
- package/dist/client.js +4 -1
- package/dist/client.js.map +2 -2
- package/dist/host.js +59 -21
- package/dist/host.js.map +3 -3
- package/dist/index.js +6 -0
- package/dist/index.js.map +2 -2
- package/dist/licks/config.js +20 -4
- package/dist/licks/config.js.map +2 -2
- package/dist/licks/fswatch.js +2 -1
- package/dist/licks/fswatch.js.map +2 -2
- package/dist/licks/licks.js +31 -4
- package/dist/licks/licks.js.map +3 -3
- package/dist/licks/sources.js +2 -1
- package/dist/licks/sources.js.map +2 -2
- package/dist/licks/triage.js +86 -0
- package/dist/licks/triage.js.map +7 -0
- package/dist/main.js +6 -0
- package/dist/main.js.map +2 -2
- package/dist/owner.js +2 -1
- package/dist/owner.js.map +2 -2
- package/dist/readonly.js +13 -0
- package/dist/readonly.js.map +2 -2
- package/dist/remote/host.js +10 -4
- package/dist/remote/host.js.map +2 -2
- package/dist/remote/pages.js +216 -0
- package/dist/remote/pages.js.map +7 -0
- package/dist/scoops/cli.js +17 -0
- package/dist/scoops/cli.js.map +2 -2
- package/dist/scoops/index.js +4 -2
- package/dist/scoops/index.js.map +2 -2
- package/dist/scoops/requests.js +14 -2
- package/dist/scoops/requests.js.map +2 -2
- package/dist/scoops/service.js.map +1 -1
- package/dist/services.js +2 -0
- package/dist/services.js.map +2 -2
- package/dist/spectrum/index.js +7 -0
- package/dist/spectrum/index.js.map +3 -3
- package/dist/spectrum/page-port.js +132 -0
- package/dist/spectrum/page-port.js.map +7 -0
- package/dist/sprinkles/index.js +1 -2
- package/dist/sprinkles/index.js.map +2 -2
- package/dist/types/client.d.ts +2 -0
- package/dist/types/host.d.ts +8 -3
- package/dist/types/index.d.ts +3 -2
- package/dist/types/licks/config.d.ts +2 -0
- package/dist/types/licks/licks.d.ts +3 -0
- package/dist/types/licks/triage.d.ts +42 -0
- package/dist/types/owner.d.ts +1 -0
- package/dist/types/readonly.d.ts +2 -0
- package/dist/types/remote/host.d.ts +10 -0
- package/dist/types/remote/pages.d.ts +76 -0
- package/dist/types/scoops/cli.d.ts +7 -0
- package/dist/types/scoops/index.d.ts +1 -0
- package/dist/types/scoops/requests.d.ts +2 -1
- package/dist/types/scoops/service.d.ts +1 -0
- package/dist/types/services.d.ts +2 -0
- package/dist/types/spectrum/index.d.ts +4 -0
- package/dist/types/spectrum/page-port.d.ts +32 -0
- package/dist/types/sprinkles/index.d.ts +1 -1
- package/dist/worker.js +2 -1
- package/dist/worker.js.map +2 -2
- package/package.json +1 -1
- package/packages/vfs-root/skills/agent/SKILL.md +2 -0
- package/packages/vfs-root/skills/sprinkles/SKILL.md +1 -1
package/dist/scoops/cli.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/scoops/cli.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Harness } from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport type { Agents, AgentsState } from '../agents.ts';\nimport { resolve } from '../kernel/paths.ts';\nimport { findRole, type Roles } from '../roles/roles.ts';\nimport type { Request, Runner } from './requests.ts';\nimport { type Answer, findScoop, modelOf, SCOOPS_ROOT, type Scoops } from './service.ts';\nimport { cancelSync, detachSync, runSync, type SyncState } from './sync.ts';\n\nexport const DEFAULT_WAIT_S = 30;\nexport const MAX_DEPTH = 3;\nexport const RUN_DIR = '/var/lib/slicc/agent/scoops';\n\nexport const THINKING = new Set(['off', 'minimal', 'low', 'medium', 'high', 'xhigh']);\nconst EFFORT: Record<string, string> = { low: 'low', medium: 'medium', high: 'high', max: 'xhigh' };\n\nexport const USAGE = `usage:\n agent [options] (--prompt <text> | --file <path> | -)... run a scoop, wait, print its answer\n agent --async [options] (--prompt <text> | --file <path> | -)... start a scoop, print its handle\n agent <cwd> <allowed-commands> <prompt> the same as a synchronous run, in v6's form\n agent list [--agents] | status <handle> | rename <handle> <name>\n agent send <handle> [--follow-up] (<message> | --file <path> | -)\n agent send parent <note> from a scoop: a progress note to its cone\n agent wait <handle>... [--timeout <seconds>] [--notify]\n agent stop <handle>\n\noptions:\n --name <name> --agent <role> --model <provider/model> --thinking <level> | --effort <low|medium|high|max>\n --tools <a,b> --read-only <path,path> --system-prompt <text> | --system-prompt-file <path>\n --background-after <seconds> --persist-session | --no-persist-session\n\nA synchronous run removes the scoop's folder afterwards. Its transcript is archived in\n/tmp/agent-sessions/<handle>.md, in /home/sessions/<handle>.md with --persist-session, or nowhere\nwith --no-persist-session. subagent is the same command: subagent spawn = agent --async.\n`;\n\nexport interface CliOptions {\n env: ExecutionEnv;\n harness: Harness;\n agents: Agents;\n scoops: Scoops;\n roles: () => Promise<Roles>;\n alive?: (pid: number) => Promise<boolean>;\n now?: () => number;\n sprinkle?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n memory?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n gelatiere?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n freezer?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n models?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n}\n\nexport type Deps = CliOptions & { now: () => number; sync: SyncState };\n\nexport interface Caller {\n id: string | null;\n cone: string;\n fromAgent: boolean;\n scoop: string | null;\n depth: number;\n}\n\nexport type Flags = { values: Map<string, string[]>; switches: Set<string>; rest: string[] };\n\nexport const ok = (out: string): Answer => ({ code: 0, out });\nexport const fail = (out: string, code = 1): Answer => ({ code, out: `agent: ${out}\\n` });\n\nexport function isAnswer(value: unknown): value is Answer {\n return typeof value === 'object' && value !== null && 'code' in value && 'out' in value;\n}\n\nexport function flags(argv: readonly string[], withValue: readonly string[]): Flags {\n const values = new Map<string, string[]>();\n const switches = new Set<string>();\n const rest: string[] = [];\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at] as string;\n if (withValue.includes(arg)) {\n const value = argv[at + 1];\n if (value === undefined) throw new Error(`${arg} needs a value`);\n values.set(arg, [...(values.get(arg) ?? []), value]);\n at++;\n } else if (arg.startsWith('--')) switches.add(arg);\n else rest.push(arg);\n }\n return { values, switches, rest };\n}\n\nexport function last(parsed: Flags, flag: string): string | undefined {\n return parsed.values.get(flag)?.at(-1);\n}\n\nexport function callerOf(agents: Agents, request: Request): Caller {\n const state = agents.state();\n if (request.caller.startsWith('cone:') && state.cones[request.caller.slice(5)]) {\n const cone = request.caller.slice(5);\n return { id: `cone:${cone}`, cone, fromAgent: true, scoop: null, depth: 0 };\n }\n const record = request.caller.startsWith('scoop:') ? state.scoops[request.caller] : undefined;\n if (record)\n return {\n id: request.caller,\n cone: record.cone,\n fromAgent: true,\n scoop: request.caller,\n depth: record.depth,\n };\n return { id: null, cone: agents.activeCone(), fromAgent: false, scoop: null, depth: 0 };\n}\n\nexport async function readText(\n deps: Deps,\n value: string,\n request: Request,\n context: Context\n): Promise<string> {\n const read = await deps.env.readTextFile(resolve(request.cwd, value), context);\n if (!read.ok) throw new Error(`can't read ${value}: ${read.error.message}`);\n return read.value;\n}\n\nexport async function prompts(\n deps: Deps,\n argv: readonly string[],\n request: Request,\n context: Context\n) {\n const out: string[] = [];\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at];\n if (arg === '--prompt') out.push(argv[++at] ?? '');\n else if (arg === '--file') out.push(await readText(deps, argv[++at] ?? '', request, context));\n else if (arg === '-') out.push(request.stdin);\n }\n return out.filter((prompt) => prompt.trim());\n}\n\nexport type Choice = {\n model?: { provider: string; modelId: string };\n thinking?: string;\n tools?: string[];\n};\n\nfunction toolList(listed: string | undefined): string[] | undefined {\n if (listed === undefined || listed === 'auto' || listed === 'full') return undefined;\n return listed\n .split(',')\n .map((tool) => tool.trim())\n .filter(Boolean);\n}\n\nexport function choices(parsed: Flags): Choice | Answer {\n const provider = last(parsed, '--provider');\n const modelText = last(parsed, '--model');\n const model = modelText\n ? provider\n ? { provider, modelId: modelText }\n : modelOf(modelText)\n : undefined;\n if (modelText && !model)\n return fail('--model needs provider/model, or --provider with --model', 2);\n const effort = last(parsed, '--effort');\n if (effort && !EFFORT[effort]) return fail('--effort must be low, medium, high or max', 2);\n const thinking = last(parsed, '--thinking') ?? (effort ? EFFORT[effort] : undefined);\n if (thinking && !THINKING.has(thinking))\n return fail(`--thinking must be one of ${[...THINKING].join(', ')}`, 2);\n if (last(parsed, '--tools') === 'output')\n return fail('--tools output needs --schema-b64, which is not supported in SLICC yet', 2);\n const tools = toolList(last(parsed, '--tools'));\n return {\n ...(model ? { model } : {}),\n ...(thinking ? { thinking } : {}),\n ...(tools ? { tools } : {}),\n };\n}\n\nexport async function role(deps: Deps, parsed: Flags) {\n const roles = await deps.roles();\n const name = last(parsed, '--agent');\n const found = name ? findRole(roles.roles, name) : undefined;\n if (name && !found)\n return {\n roles,\n error: fail(`there is no agent role ${name}; \\`agent list --agents\\` shows them`),\n };\n return { roles, role: found };\n}\n\nfunction handle(deps: Deps, who: Caller, name: string | undefined) {\n return name ? findScoop(deps.agents.state(), name, who.fromAgent ? who.cone : null) : undefined;\n}\n\nconst ASYNC_VALUES = [\n '--name',\n '--agent',\n '--provider',\n '--model',\n '--thinking',\n '--effort',\n '--tools',\n '--prompt',\n '--file',\n];\nconst ASYNC_SWITCHES = new Set(['--async', '--no-extensions', '--no-skills', '--no-context-files']);\nconst UNSUPPORTED = new Set([\n '--no-prompt-templates',\n '--session',\n '--resume',\n '--image',\n '--no-escalate',\n '--minimal',\n '--usage',\n '--schema-b64',\n '--cwd',\n]);\n\nexport function unsupported(argv: readonly string[]): Answer | undefined {\n const found = argv.find((arg) => UNSUPPORTED.has(arg) || arg.startsWith('--image='));\n return found ? fail(`${found} is not supported in SLICC yet`, 2) : undefined;\n}\n\nasync function spawnAsync(\n deps: Deps,\n request: Request,\n who: Caller,\n argv: readonly string[],\n context: Context\n) {\n if (who.scoop) return fail('a scoop cannot start async scoops; run agent without --async');\n const refused = unsupported(argv);\n if (refused) return refused;\n const parsed = flags(argv, ASYNC_VALUES);\n const unknown = [...parsed.switches].find((flag) => !ASYNC_SWITCHES.has(flag));\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const given = await prompts(deps, argv, request, context);\n if (!given.length) return fail('--async needs at least one --prompt, --file or -', 2);\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 return deps.scoops.spawn(\n {\n cone: who.cone,\n kind: 'async',\n name: last(parsed, '--name') ?? found.role?.name ?? 'scoop',\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: given,\n origin: request.cwd,\n fromAgent: who.fromAgent,\n request: request.id,\n limits: found.roles.limits,\n },\n context\n );\n}\n\nasync function listAgents(deps: Deps): Promise<Answer> {\n const roles = await deps.roles();\n const lines = roles.roles.map(\n (entry) =>\n `${entry.name}\\t${entry.source}\\t${entry.description}${entry.aliases.length ? ` (also ${entry.aliases.join(', ')})` : ''}`\n );\n return ok(\n `${[\n ...lines,\n '',\n 'Agent files are read from the built-in roles, installed packages (pi-subagents.agents) and ~/.pi/agent/agents.',\n \"A project's .pi/agents folder is read only once the folder is trusted, which SLICC doesn't support yet.\",\n ...roles.warnings.map((warning) => `warning: ${warning}`),\n ].join('\\n')}\\n`\n );\n}\n\nasync function list(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n if (request.argv.includes('--agents')) return listAgents(deps);\n const rows = await deps.scoops.list(who.cone, context);\n if (!rows.length) return ok('no scoops\\n');\n return ok(\n `${rows.map((row) => `${row.folder}\\t${row.name}\\t${row.role ?? '-'}\\t${row.busy ? 'working' : 'idle'}`).join('\\n')}\\n`\n );\n}\n\nasync function status(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n const [, record] = found;\n const busy = await deps.scoops.busy(record.conversation, context);\n return ok(\n `${[\n `handle: ${record.folder}`,\n `name: ${record.name}`,\n `role: ${record.role ?? '-'}`,\n `kind: ${record.kind}`,\n `state: ${busy ? 'working' : 'idle'}`,\n `folder: ${SCOOPS_ROOT}/${record.folder}`,\n `reports: ${SCOOPS_ROOT}/${record.folder}/reports`,\n ].join('\\n')}\\n`\n );\n}\n\nasync function message(\n deps: Deps,\n parsed: Flags,\n request: Request,\n context: Context\n): Promise<string> {\n const file = last(parsed, '--file');\n if (file) return readText(deps, file, request, context);\n return parsed.rest.includes('-') ? request.stdin : parsed.rest.join(' ');\n}\n\nasync function send(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n const parsed = flags(request.argv.slice(2), ['--file']);\n const unknown = [...parsed.switches].find((flag) => flag !== '--follow-up');\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const text = await message(deps, parsed, request, context);\n if (!text.trim()) return fail('send needs a message, --file or -', 2);\n if (request.argv[1] === 'parent') {\n if (!who.scoop) return fail('only a scoop has a parent to send to');\n return deps.scoops.note(who.scoop, text, context);\n }\n if (who.scoop) return fail('a scoop can only send to its parent');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n const followUp = parsed.switches.has('--follow-up');\n return deps.scoops.feed(\n found[0],\n text,\n { fromAgent: who.fromAgent, request: request.id, followUp, target: who.id },\n context\n );\n}\n\nasync function latest(deps: Deps, folder: string, context: Context): Promise<string> {\n const dir = `${SCOOPS_ROOT}/${folder}/reports`;\n const listed = await deps.env.listDir(dir, context);\n if (!listed.ok || !listed.value.length) return '(no answer yet)';\n const newest = [...listed.value].sort(\n (a, b) => Number.parseInt(b.name, 10) - Number.parseInt(a.name, 10)\n )[0];\n const read = await deps.env.readTextFile(`${dir}/${newest?.name}`, context);\n return read.ok ? read.value.trimEnd() : '(no answer yet)';\n}\n\nfunction waitTargets(deps: Deps, who: Caller, rest: readonly string[]): string[] | Answer {\n if (!rest.length) return fail('wait needs at least one handle', 2);\n const missing = rest.filter((name) => !handle(deps, who, name));\n if (missing.length)\n return fail(missing.map((name) => noScoop(deps.agents.state(), name)).join('; '));\n return rest.map((name) => (handle(deps, who, name) as [string, unknown])[0]);\n}\n\nasync function block(\n deps: Deps,\n ids: string[],\n seconds: number,\n context: Context\n): Promise<Answer> {\n const deadline = deps.now() + seconds * 1000;\n let open = await deps.scoops.working(ids, context);\n while (open.length && deps.now() < deadline) {\n await new Promise((done) => setTimeout(done, 200));\n open = await deps.scoops.working(ids, context);\n }\n const state = deps.agents.state();\n const sections: string[] = [];\n for (const id of ids) {\n const record = state.scoops[id];\n if (record)\n sections.push(\n `## ${record.folder}${open.includes(id) ? ' (still working)' : ''}\\n${await latest(deps, record.folder, context)}`\n );\n }\n const body = `${sections.join('\\n\\n')}\\n`;\n if (!open.length) return ok(body);\n const still = open.map((id) => state.scoops[id]?.folder).join(', ');\n return { code: 1, out: `${body}agent: timed out after ${seconds}s; still working: ${still}\\n` };\n}\n\nasync function wait(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n const parsed = flags(request.argv.slice(1), ['--timeout']);\n const unknown = [...parsed.switches].find((flag) => flag !== '--notify');\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const seconds = Number(last(parsed, '--timeout') ?? DEFAULT_WAIT_S);\n if (!Number.isInteger(seconds) || seconds <= 0)\n return fail('--timeout must be a positive whole number of seconds', 2);\n const ids = waitTargets(deps, who, parsed.rest);\n if (isAnswer(ids)) return ids;\n if (!parsed.switches.has('--notify')) return block(deps, ids, seconds, context);\n if (!who.fromAgent || who.scoop)\n return fail('wait --notify is for a cone; a terminal waits with agent wait');\n await deps.scoops.notifyWhenDone(who.cone, ids, deps.now() + seconds * 1000, context);\n return ok(`you'll get one scoop-wait lick when ${ids.length > 1 ? 'they are' : 'it is'} done\\n`);\n}\n\nasync function stop(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n if (who.scoop) return fail('a scoop cannot stop scoops');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n return deps.scoops.stop(found[0], who.fromAgent, context);\n}\n\nasync function rename(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n if (who.scoop) return fail('a scoop cannot rename scoops');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n return deps.scoops.rename(found[0], request.argv.slice(2).join(' '), context);\n}\n\ntype Verb = (deps: Deps, request: Request, who: Caller, context: Context) => Promise<Answer>;\n\nconst help: Verb = async () => ok(USAGE);\n\nconst VERBS: Record<string, Verb> = {\n list,\n status,\n send,\n wait,\n stop,\n rename,\n help,\n '--help': help,\n '-h': help,\n __cancel: (deps, request, _who, context) => cancelSync(deps, request.argv[1] ?? '', context),\n __detach: (deps, request, _who, context) => detachSync(deps, request.argv[1] ?? '', context),\n};\n\nexport function noScoop(state: Readonly<AgentsState>, name: string): string {\n const id = name.startsWith('scoop:') ? name : `scoop:${name}`;\n const record =\n state.scoops[id]?.frozen !== undefined\n ? state.scoops[id]\n : Object.values(state.scoops).find(\n (candidate) => candidate.frozen && candidate.name === name\n );\n const frozen = record?.frozen ? state.frozen?.[record.frozen] : undefined;\n if (frozen) return `scoop ${name} is frozen with cone ${frozen.name}; thaw the cone first`;\n return `there is no scoop ${name}`.trim();\n}\n\nasync function dispatch(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n if (request.as === 'sprinkle')\n return deps.sprinkle\n ? deps.sprinkle(request.argv, who.id, context)\n : fail('sprinkles are not available in this agent');\n if (request.as === 'memory')\n return deps.memory\n ? deps.memory(request.argv, who.id, context)\n : fail('memory is not available in this agent');\n if (request.as === 'gelatiere')\n return deps.gelatiere\n ? deps.gelatiere(request.argv, who.id, context)\n : fail('the gelatiere is not available in this agent');\n if (request.as === 'freezer')\n return deps.freezer\n ? deps.freezer(request.argv, who.id, context)\n : fail('the freezer is not available in this agent');\n if (request.as === 'models')\n return deps.models\n ? deps.models(request.argv, who.id, context)\n : fail('models is not available in this agent');\n const first = request.argv[0] ?? '';\n const verb = VERBS[first];\n if (verb) return verb(deps, request, who, context);\n if (request.as === 'subagent') {\n if (first === 'spawn') return spawnAsync(deps, request, who, request.argv.slice(1), context);\n return { code: 2, out: USAGE };\n }\n if (!request.argv.length) return { code: 2, out: USAGE };\n if (request.argv.includes('--async'))\n return spawnAsync(deps, request, who, request.argv, context);\n return runSync(deps, request, who, context);\n}\n\nconst BLOCKING = new Set([\n 'wait',\n 'list',\n 'status',\n 'help',\n '--help',\n '-h',\n '__cancel',\n '__detach',\n]);\n\nexport function createCli(options: CliOptions): Runner {\n const deps: Deps = { ...options, now: options.now ?? Date.now, sync: { pending: new Map() } };\n return {\n blocking(request) {\n const first = request.argv[0] ?? '';\n if (BLOCKING.has(first)) return true;\n return request.as === 'agent' && !VERBS[first] && !request.argv.includes('--async');\n },\n async run(request, context) {\n try {\n return await dispatch(deps, request, callerOf(options.agents, request), context);\n } catch (error) {\n return fail((error as Error).message);\n }\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Harness } from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport type { Agents, AgentsState } from '../agents.ts';\nimport { resolve } from '../kernel/paths.ts';\nimport { findRole, type Roles } from '../roles/roles.ts';\nimport type { Request, Runner } from './requests.ts';\nimport { type Answer, findScoop, modelOf, SCOOPS_ROOT, type Scoops } from './service.ts';\nimport { cancelSync, detachSync, runSync, type SyncState } from './sync.ts';\n\nexport const DEFAULT_WAIT_S = 30;\nexport const MAX_DEPTH = 3;\nexport const RUN_DIR = '/var/lib/slicc/agent/scoops';\n\nexport const THINKING = new Set(['off', 'minimal', 'low', 'medium', 'high', 'xhigh']);\nconst EFFORT: Record<string, string> = { low: 'low', medium: 'medium', high: 'high', max: 'xhigh' };\n\nexport const USAGE = `usage:\n agent [options] (--prompt <text> | --file <path> | -)... run a scoop, wait, print its answer\n agent --async [options] (--prompt <text> | --file <path> | -)... start a scoop, print its handle\n agent <cwd> <allowed-commands> <prompt> the same as a synchronous run, in v6's form\n agent list [--agents] | status <handle> | rename <handle> <name>\n agent send <handle> [--follow-up] (<message> | --file <path> | -)\n agent send parent <note> from a scoop: a progress note to its cone\n agent wait <handle>... [--timeout <seconds>] [--notify]\n agent stop <handle>\n\noptions:\n --name <name> --agent <role> --model <provider/model> --thinking <level> | --effort <low|medium|high|max>\n --tools <a,b> --read-only <path,path> --system-prompt <text> | --system-prompt-file <path>\n --background-after <seconds> --persist-session | --no-persist-session\n\nA synchronous run removes the scoop's folder afterwards. Its transcript is archived in\n/tmp/agent-sessions/<handle>.md, in /home/sessions/<handle>.md with --persist-session, or nowhere\nwith --no-persist-session. subagent is the same command: subagent spawn = agent --async.\n`;\n\nexport interface CliOptions {\n env: ExecutionEnv;\n harness: Harness;\n agents: Agents;\n scoops: Scoops;\n roles: () => Promise<Roles>;\n alive?: (pid: number) => Promise<boolean>;\n now?: () => number;\n sprinkle?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n memory?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n gelatiere?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n freezer?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n models?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;\n panel?: (argv: readonly string[], caller: PanelCaller, context: Context) => Promise<Answer>;\n}\n\nexport interface PanelCaller {\n agentId: string | null;\n cone: string;\n tab: string | null;\n}\n\nexport type Deps = CliOptions & { now: () => number; sync: SyncState };\n\nexport interface Caller {\n id: string | null;\n cone: string;\n fromAgent: boolean;\n scoop: string | null;\n depth: number;\n}\n\nexport type Flags = { values: Map<string, string[]>; switches: Set<string>; rest: string[] };\n\nexport const ok = (out: string): Answer => ({ code: 0, out });\nexport const fail = (out: string, code = 1): Answer => ({ code, out: `agent: ${out}\\n` });\n\nexport function isAnswer(value: unknown): value is Answer {\n return typeof value === 'object' && value !== null && 'code' in value && 'out' in value;\n}\n\nexport function flags(argv: readonly string[], withValue: readonly string[]): Flags {\n const values = new Map<string, string[]>();\n const switches = new Set<string>();\n const rest: string[] = [];\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at] as string;\n if (withValue.includes(arg)) {\n const value = argv[at + 1];\n if (value === undefined) throw new Error(`${arg} needs a value`);\n values.set(arg, [...(values.get(arg) ?? []), value]);\n at++;\n } else if (arg.startsWith('--')) switches.add(arg);\n else rest.push(arg);\n }\n return { values, switches, rest };\n}\n\nexport function last(parsed: Flags, flag: string): string | undefined {\n return parsed.values.get(flag)?.at(-1);\n}\n\nexport function callerOf(agents: Agents, request: Request): Caller {\n const state = agents.state();\n if (request.caller.startsWith('cone:') && state.cones[request.caller.slice(5)]) {\n const cone = request.caller.slice(5);\n return { id: `cone:${cone}`, cone, fromAgent: true, scoop: null, depth: 0 };\n }\n const record = request.caller.startsWith('scoop:') ? state.scoops[request.caller] : undefined;\n if (record)\n return {\n id: request.caller,\n cone: record.cone,\n fromAgent: true,\n scoop: request.caller,\n depth: record.depth,\n };\n return { id: null, cone: agents.activeCone(), fromAgent: false, scoop: null, depth: 0 };\n}\n\nexport async function readText(\n deps: Deps,\n value: string,\n request: Request,\n context: Context\n): Promise<string> {\n const read = await deps.env.readTextFile(resolve(request.cwd, value), context);\n if (!read.ok) throw new Error(`can't read ${value}: ${read.error.message}`);\n return read.value;\n}\n\nexport async function prompts(\n deps: Deps,\n argv: readonly string[],\n request: Request,\n context: Context\n) {\n const out: string[] = [];\n for (let at = 0; at < argv.length; at++) {\n const arg = argv[at];\n if (arg === '--prompt') out.push(argv[++at] ?? '');\n else if (arg === '--file') out.push(await readText(deps, argv[++at] ?? '', request, context));\n else if (arg === '-') out.push(request.stdin);\n }\n return out.filter((prompt) => prompt.trim());\n}\n\nexport type Choice = {\n model?: { provider: string; modelId: string };\n thinking?: string;\n tools?: string[];\n};\n\nfunction toolList(listed: string | undefined): string[] | undefined {\n if (listed === undefined || listed === 'auto' || listed === 'full') return undefined;\n return listed\n .split(',')\n .map((tool) => tool.trim())\n .filter(Boolean);\n}\n\nexport function choices(parsed: Flags): Choice | Answer {\n const provider = last(parsed, '--provider');\n const modelText = last(parsed, '--model');\n const model = modelText\n ? provider\n ? { provider, modelId: modelText }\n : modelOf(modelText)\n : undefined;\n if (modelText && !model)\n return fail('--model needs provider/model, or --provider with --model', 2);\n const effort = last(parsed, '--effort');\n if (effort && !EFFORT[effort]) return fail('--effort must be low, medium, high or max', 2);\n const thinking = last(parsed, '--thinking') ?? (effort ? EFFORT[effort] : undefined);\n if (thinking && !THINKING.has(thinking))\n return fail(`--thinking must be one of ${[...THINKING].join(', ')}`, 2);\n if (last(parsed, '--tools') === 'output')\n return fail('--tools output needs --schema-b64, which is not supported in SLICC yet', 2);\n const tools = toolList(last(parsed, '--tools'));\n return {\n ...(model ? { model } : {}),\n ...(thinking ? { thinking } : {}),\n ...(tools ? { tools } : {}),\n };\n}\n\nexport async function role(deps: Deps, parsed: Flags) {\n const roles = await deps.roles();\n const name = last(parsed, '--agent');\n const found = name ? findRole(roles.roles, name) : undefined;\n if (name && !found)\n return {\n roles,\n error: fail(`there is no agent role ${name}; \\`agent list --agents\\` shows them`),\n };\n return { roles, role: found };\n}\n\nfunction handle(deps: Deps, who: Caller, name: string | undefined) {\n return name ? findScoop(deps.agents.state(), name, who.fromAgent ? who.cone : null) : undefined;\n}\n\nconst ASYNC_VALUES = [\n '--name',\n '--agent',\n '--provider',\n '--model',\n '--thinking',\n '--effort',\n '--tools',\n '--prompt',\n '--file',\n];\nconst ASYNC_SWITCHES = new Set(['--async', '--no-extensions', '--no-skills', '--no-context-files']);\nconst UNSUPPORTED = new Set([\n '--no-prompt-templates',\n '--session',\n '--resume',\n '--image',\n '--no-escalate',\n '--minimal',\n '--usage',\n '--schema-b64',\n '--cwd',\n]);\n\nexport function unsupported(argv: readonly string[]): Answer | undefined {\n const found = argv.find((arg) => UNSUPPORTED.has(arg) || arg.startsWith('--image='));\n return found ? fail(`${found} is not supported in SLICC yet`, 2) : undefined;\n}\n\nasync function spawnAsync(\n deps: Deps,\n request: Request,\n who: Caller,\n argv: readonly string[],\n context: Context\n) {\n if (who.scoop) return fail('a scoop cannot start async scoops; run agent without --async');\n const refused = unsupported(argv);\n if (refused) return refused;\n const parsed = flags(argv, ASYNC_VALUES);\n const unknown = [...parsed.switches].find((flag) => !ASYNC_SWITCHES.has(flag));\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const given = await prompts(deps, argv, request, context);\n if (!given.length) return fail('--async needs at least one --prompt, --file or -', 2);\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 return deps.scoops.spawn(\n {\n cone: who.cone,\n kind: 'async',\n name: last(parsed, '--name') ?? found.role?.name ?? 'scoop',\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: given,\n origin: request.cwd,\n fromAgent: who.fromAgent,\n request: request.id,\n limits: found.roles.limits,\n },\n context\n );\n}\n\nasync function listAgents(deps: Deps): Promise<Answer> {\n const roles = await deps.roles();\n const lines = roles.roles.map(\n (entry) =>\n `${entry.name}\\t${entry.source}\\t${entry.description}${entry.aliases.length ? ` (also ${entry.aliases.join(', ')})` : ''}`\n );\n return ok(\n `${[\n ...lines,\n '',\n 'Agent files are read from the built-in roles, installed packages (pi-subagents.agents) and ~/.pi/agent/agents.',\n \"A project's .pi/agents folder is read only once the folder is trusted, which SLICC doesn't support yet.\",\n ...roles.warnings.map((warning) => `warning: ${warning}`),\n ].join('\\n')}\\n`\n );\n}\n\nasync function list(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n if (request.argv.includes('--agents')) return listAgents(deps);\n const rows = await deps.scoops.list(who.cone, context);\n if (!rows.length) return ok('no scoops\\n');\n return ok(\n `${rows.map((row) => `${row.folder}\\t${row.name}\\t${row.role ?? '-'}\\t${row.busy ? 'working' : 'idle'}`).join('\\n')}\\n`\n );\n}\n\nasync function status(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n const [, record] = found;\n const busy = await deps.scoops.busy(record.conversation, context);\n return ok(\n `${[\n `handle: ${record.folder}`,\n `name: ${record.name}`,\n `role: ${record.role ?? '-'}`,\n `kind: ${record.kind}`,\n `state: ${busy ? 'working' : 'idle'}`,\n `folder: ${SCOOPS_ROOT}/${record.folder}`,\n `reports: ${SCOOPS_ROOT}/${record.folder}/reports`,\n ].join('\\n')}\\n`\n );\n}\n\nasync function message(\n deps: Deps,\n parsed: Flags,\n request: Request,\n context: Context\n): Promise<string> {\n const file = last(parsed, '--file');\n if (file) return readText(deps, file, request, context);\n return parsed.rest.includes('-') ? request.stdin : parsed.rest.join(' ');\n}\n\nasync function send(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n const parsed = flags(request.argv.slice(2), ['--file']);\n const unknown = [...parsed.switches].find((flag) => flag !== '--follow-up');\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const text = await message(deps, parsed, request, context);\n if (!text.trim()) return fail('send needs a message, --file or -', 2);\n if (request.argv[1] === 'parent') {\n if (!who.scoop) return fail('only a scoop has a parent to send to');\n return deps.scoops.note(who.scoop, text, context);\n }\n if (who.scoop) return fail('a scoop can only send to its parent');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n const followUp = parsed.switches.has('--follow-up');\n return deps.scoops.feed(\n found[0],\n text,\n { fromAgent: who.fromAgent, request: request.id, followUp, target: who.id },\n context\n );\n}\n\nasync function latest(deps: Deps, folder: string, context: Context): Promise<string> {\n const dir = `${SCOOPS_ROOT}/${folder}/reports`;\n const listed = await deps.env.listDir(dir, context);\n if (!listed.ok || !listed.value.length) return '(no answer yet)';\n const newest = [...listed.value].sort(\n (a, b) => Number.parseInt(b.name, 10) - Number.parseInt(a.name, 10)\n )[0];\n const read = await deps.env.readTextFile(`${dir}/${newest?.name}`, context);\n return read.ok ? read.value.trimEnd() : '(no answer yet)';\n}\n\nfunction waitTargets(deps: Deps, who: Caller, rest: readonly string[]): string[] | Answer {\n if (!rest.length) return fail('wait needs at least one handle', 2);\n const missing = rest.filter((name) => !handle(deps, who, name));\n if (missing.length)\n return fail(missing.map((name) => noScoop(deps.agents.state(), name)).join('; '));\n return rest.map((name) => (handle(deps, who, name) as [string, unknown])[0]);\n}\n\nasync function block(\n deps: Deps,\n ids: string[],\n seconds: number,\n context: Context\n): Promise<Answer> {\n const deadline = deps.now() + seconds * 1000;\n let open = await deps.scoops.working(ids, context);\n while (open.length && deps.now() < deadline) {\n await new Promise((done) => setTimeout(done, 200));\n open = await deps.scoops.working(ids, context);\n }\n const state = deps.agents.state();\n const sections: string[] = [];\n for (const id of ids) {\n const record = state.scoops[id];\n if (record)\n sections.push(\n `## ${record.folder}${open.includes(id) ? ' (still working)' : ''}\\n${await latest(deps, record.folder, context)}`\n );\n }\n const body = `${sections.join('\\n\\n')}\\n`;\n if (!open.length) return ok(body);\n const still = open.map((id) => state.scoops[id]?.folder).join(', ');\n return { code: 1, out: `${body}agent: timed out after ${seconds}s; still working: ${still}\\n` };\n}\n\nasync function wait(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n const parsed = flags(request.argv.slice(1), ['--timeout']);\n const unknown = [...parsed.switches].find((flag) => flag !== '--notify');\n if (unknown) return fail(`unknown option ${unknown}`, 2);\n const seconds = Number(last(parsed, '--timeout') ?? DEFAULT_WAIT_S);\n if (!Number.isInteger(seconds) || seconds <= 0)\n return fail('--timeout must be a positive whole number of seconds', 2);\n const ids = waitTargets(deps, who, parsed.rest);\n if (isAnswer(ids)) return ids;\n if (!parsed.switches.has('--notify')) return block(deps, ids, seconds, context);\n if (!who.fromAgent || who.scoop)\n return fail('wait --notify is for a cone; a terminal waits with agent wait');\n await deps.scoops.notifyWhenDone(who.cone, ids, deps.now() + seconds * 1000, context);\n return ok(`you'll get one scoop-wait lick when ${ids.length > 1 ? 'they are' : 'it is'} done\\n`);\n}\n\nasync function stop(deps: Deps, request: Request, who: Caller, context: Context): Promise<Answer> {\n if (who.scoop) return fail('a scoop cannot stop scoops');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n return deps.scoops.stop(found[0], who.fromAgent, context);\n}\n\nasync function rename(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n if (who.scoop) return fail('a scoop cannot rename scoops');\n const found = handle(deps, who, request.argv[1]);\n if (!found) return fail(noScoop(deps.agents.state(), request.argv[1] ?? ''));\n return deps.scoops.rename(found[0], request.argv.slice(2).join(' '), context);\n}\n\ntype Verb = (deps: Deps, request: Request, who: Caller, context: Context) => Promise<Answer>;\n\nconst help: Verb = async () => ok(USAGE);\n\nconst VERBS: Record<string, Verb> = {\n list,\n status,\n send,\n wait,\n stop,\n rename,\n help,\n '--help': help,\n '-h': help,\n __cancel: (deps, request, _who, context) => cancelSync(deps, request.argv[1] ?? '', context),\n __detach: (deps, request, _who, context) => detachSync(deps, request.argv[1] ?? '', context),\n};\n\nexport function noScoop(state: Readonly<AgentsState>, name: string): string {\n const id = name.startsWith('scoop:') ? name : `scoop:${name}`;\n const record =\n state.scoops[id]?.frozen !== undefined\n ? state.scoops[id]\n : Object.values(state.scoops).find(\n (candidate) => candidate.frozen && candidate.name === name\n );\n const frozen = record?.frozen ? state.frozen?.[record.frozen] : undefined;\n if (frozen) return `scoop ${name} is frozen with cone ${frozen.name}; thaw the cone first`;\n return `there is no scoop ${name}`.trim();\n}\n\nexport function panelCaller(request: Request, who: Caller): PanelCaller {\n const agentId = who.scoop ?? (who.fromAgent ? who.cone : null);\n return { agentId, cone: who.cone, tab: agentId === null ? (request.tab ?? null) : null };\n}\n\nconst ALIASES = new Set(['open', 'close']);\n\nfunction panelArgv(request: Request): readonly string[] | undefined {\n if (request.as === 'panel') return request.argv;\n const [verb, name, ...rest] = request.argv;\n if (request.as !== 'sprinkle' || !ALIASES.has(verb ?? '')) return undefined;\n if (!name) return [verb as string];\n return [verb as string, name.startsWith('sprinkle:') ? name : `sprinkle:${name}`, ...rest];\n}\n\nasync function dispatch(\n deps: Deps,\n request: Request,\n who: Caller,\n context: Context\n): Promise<Answer> {\n const forwarded = panelArgv(request);\n if (forwarded)\n return deps.panel\n ? deps.panel(forwarded, panelCaller(request, who), context)\n : { code: 1, out: 'panel: panels are not available in this agent\\n' };\n if (request.as === 'sprinkle')\n return deps.sprinkle\n ? deps.sprinkle(request.argv, who.id, context)\n : fail('sprinkles are not available in this agent');\n if (request.as === 'memory')\n return deps.memory\n ? deps.memory(request.argv, who.id, context)\n : fail('memory is not available in this agent');\n if (request.as === 'gelatiere')\n return deps.gelatiere\n ? deps.gelatiere(request.argv, who.id, context)\n : fail('the gelatiere is not available in this agent');\n if (request.as === 'freezer')\n return deps.freezer\n ? deps.freezer(request.argv, who.id, context)\n : fail('the freezer is not available in this agent');\n if (request.as === 'models')\n return deps.models\n ? deps.models(request.argv, who.id, context)\n : fail('models is not available in this agent');\n const first = request.argv[0] ?? '';\n const verb = VERBS[first];\n if (verb) return verb(deps, request, who, context);\n if (request.as === 'subagent') {\n if (first === 'spawn') return spawnAsync(deps, request, who, request.argv.slice(1), context);\n return { code: 2, out: USAGE };\n }\n if (!request.argv.length) return { code: 2, out: USAGE };\n if (request.argv.includes('--async'))\n return spawnAsync(deps, request, who, request.argv, context);\n return runSync(deps, request, who, context);\n}\n\nconst BLOCKING = new Set([\n 'wait',\n 'list',\n 'status',\n 'help',\n '--help',\n '-h',\n '__cancel',\n '__detach',\n]);\n\nexport function createCli(options: CliOptions): Runner {\n const deps: Deps = { ...options, now: options.now ?? Date.now, sync: { pending: new Map() } };\n return {\n blocking(request) {\n if (panelArgv(request)) return true;\n const first = request.argv[0] ?? '';\n if (BLOCKING.has(first)) return true;\n return request.as === 'agent' && !VERBS[first] && !request.argv.includes('--async');\n },\n async run(request, context) {\n try {\n return await dispatch(deps, request, callerOf(options.agents, request), context);\n } catch (error) {\n return fail((error as Error).message);\n }\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/scoops/index.js
CHANGED
|
@@ -21,7 +21,8 @@ const COMMANDS = [
|
|
|
21
21
|
"memory",
|
|
22
22
|
"gelatiere",
|
|
23
23
|
"freezer",
|
|
24
|
-
"models"
|
|
24
|
+
"models",
|
|
25
|
+
"panel"
|
|
25
26
|
];
|
|
26
27
|
async function pnpmHomeOf(env, context) {
|
|
27
28
|
let out = "";
|
|
@@ -169,7 +170,8 @@ function setupScoops(registry, licks, fileTools = []) {
|
|
|
169
170
|
...options.memory ? { memory: options.memory } : {},
|
|
170
171
|
...options.gelatiere ? { gelatiere: options.gelatiere } : {},
|
|
171
172
|
...options.freezer ? { freezer: options.freezer } : {},
|
|
172
|
-
...options.models ? { models: options.models } : {}
|
|
173
|
+
...options.models ? { models: options.models } : {},
|
|
174
|
+
...options.panel ? { panel: options.panel } : {}
|
|
173
175
|
});
|
|
174
176
|
const plane = controlPlane(env, cli, {
|
|
175
177
|
...options.controlDir ? { dir: options.controlDir } : {},
|
package/dist/scoops/index.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/scoops/index.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Harness, Registry, ToolRegistration } from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { type Agents, live } from '../agents.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport { DEFAULT_LIMITS, loadRoles, packageDirs, type Roles } from '../roles/roles.ts';\nimport { type CliOptions, createCli, RUN_DIR } from './cli.ts';\nimport { guardExtension, scoopsExtension, scoopTasks } from './extension.ts';\nimport { type ControlPlane, controlPlane, PROTOCOL } from './requests.ts';\nimport { createScoops, type Scoops, type ScoopsHost } from './service.ts';\n\nexport const BUILTIN_ROLES = ['scout', 'worker', 'reviewer', 'oracle', 'delegate', 'gelatiere'];\nexport const PNPM_HOME = '/home/.local/share/pnpm';\nexport const BIN_DIR = '/usr/local/bin';\n\nexport type Assets = (path: string) => Promise<string>;\n\nexport function packageAssets(base: URL = new URL('../../', import.meta.url)): Assets {\n return async (path) => {\n const response = await fetch(new URL(path, base));\n if (!response.ok) throw new Error(`${path}: ${response.status}`);\n return response.text();\n };\n}\n\nexport interface AttachOptions {\n harness: Harness;\n agents: Agents;\n groups: ProcessGroups;\n env: ExecutionEnv;\n home: string;\n assets?: Assets;\n binDir?: string;\n controlDir?: string;\n sweepEvery?: number;\n alive?: (pid: number) => Promise<boolean>;\n reads: () => readonly string[];\n sprinkle?: CliOptions['sprinkle'];\n memory?: CliOptions['memory'];\n gelatiere?: CliOptions['gelatiere'];\n freezer?: CliOptions['freezer'];\n models?: CliOptions['models'];\n mcp?: (names: readonly string[]) => ToolRegistration[];\n}\n\nexport interface ScoopsRuntime {\n roles(context: Context): Promise<Roles>;\n plane: ControlPlane;\n close(context: Context): Promise<void>;\n}\n\nexport interface ScoopsSetup {\n scoops: Scoops;\n attach(options: AttachOptions, context: Context): Promise<ScoopsRuntime>;\n}\n\nexport const COMMANDS = [\n 'agent',\n 'subagent',\n 'sprinkle',\n 'memory',\n 'gelatiere',\n 'freezer',\n 'models',\n];\n\nexport async function pnpmHomeOf(env: ExecutionEnv, context: Context): Promise<string> {\n let out = '';\n const ran = await env\n .exec(\n 'printf %s \"$PNPM_HOME\"',\n {\n onOutput: (text) => {\n out += text;\n },\n },\n context\n )\n .catch(() => undefined);\n return ran?.ok && ran.value.exitCode === 0 && /^\\/\\S*$/.test(out) ? out : PNPM_HOME;\n}\n\nexport interface Installed {\n done: boolean;\n skipped: string[];\n}\n\nasync function theirs(env: ExecutionEnv, path: string, context: Context): Promise<boolean> {\n const found = await env.fileInfo(path, context);\n if (!found.ok) return found.error.code !== 'not_found';\n if (found.value.kind !== 'file') return true;\n const read = await env.readTextFile(path, context);\n return !read.ok || !read.value.includes(PROTOCOL);\n}\n\nasync function install(\n env: ExecutionEnv,\n script: string,\n binDir: string,\n context: Context\n): Promise<Installed> {\n const skipped: string[] = [];\n if (!(await env.createDir(binDir, { recursive: true }, context)).ok)\n return { done: false, skipped };\n for (const name of COMMANDS) {\n const path = `${binDir}/${name}`;\n if (await theirs(env, path, context)) {\n skipped.push(name);\n continue;\n }\n if (!(await env.writeFile(path, script, context)).ok) return { done: false, skipped };\n const mode = await env.exec(['chmod', '755', path], undefined, context);\n if (!mode.ok || mode.value.exitCode !== 0) return { done: false, skipped };\n }\n return { done: true, skipped };\n}\n\nexport async function installCommands(\n env: ExecutionEnv,\n script: string,\n binDir: string,\n context: Context,\n warn: (message: string) => void = (message) => console.warn(message)\n): Promise<Installed> {\n const installed = await install(env, script, binDir, context).catch(\n (): Installed => ({ done: false, skipped: [] })\n );\n if (installed.skipped.length) {\n const paths = installed.skipped.map((name) => `${binDir}/${name}`).join(', ');\n warn(`slicc-agent: left ${paths} alone, because it isn't slicc-agent's command`);\n }\n if (installed.done) await retire(env, binDir, context).catch(() => undefined);\n return installed;\n}\n\nexport async function retire(env: ExecutionEnv, binDir: string, context: Context) {\n const old = `${await pnpmHomeOf(env, context)}/bin`;\n if (old === binDir) return;\n for (const name of COMMANDS) {\n const path = `${old}/${name}`;\n const text = await env.readTextFile(path, context);\n if (text.ok && text.value.includes(PROTOCOL)) await env.remove(path, { force: true }, context);\n }\n}\n\nfunction mirror(agents: Agents, env: ExecutionEnv) {\n return async (context: Context) => {\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n const state = record.gone ? 'gone' : live(record) ? 'live' : 'stopped';\n const metadata = {\n handle: record.folder,\n id,\n name: record.name,\n role: record.role,\n cone: record.cone,\n state,\n };\n await env.writeFile(\n `${RUN_DIR}/${record.folder}/metadata.json`,\n `${JSON.stringify(metadata, null, 2)}\\n`,\n context\n );\n }\n };\n}\n\nexport function setupScoops(\n registry: Registry,\n licks: Licks,\n fileTools: readonly ToolRegistration[] = []\n): ScoopsSetup {\n let bind: (host: ScoopsHost) => void = () => undefined;\n const host = new Promise<ScoopsHost>((resolve) => {\n bind = resolve;\n });\n const lookup = () => host;\n const tasks = scoopTasks(lookup);\n const scoops = createScoops(host, () => tasks);\n let cached: Roles = { roles: [], warnings: [], limits: { ...DEFAULT_LIMITS } };\n registry.install(scoopsExtension(tasks));\n registry.install(guardExtension(lookup, fileTools));\n return {\n scoops,\n async attach(options, context) {\n const { harness, agents, groups, env, home } = options;\n const assets = options.assets ?? packageAssets();\n bind({\n harness,\n agents,\n licks,\n tools: fileTools,\n groups,\n reads: options.reads,\n files: env,\n ...(options.mcp ? { mcp: options.mcp } : {}),\n });\n const builtin = async () => {\n const out: { path: string; text: string }[] = [];\n for (const name of BUILTIN_ROLES) {\n const path = `packages/vfs-root/agents/${name}.md`;\n out.push({ path: `builtin:${name}`, text: await assets(path) });\n }\n return out;\n };\n const roles = async (using: Context) => {\n cached = await loadRoles(\n {\n files: env,\n builtin,\n dirs: [\n ...(await packageDirs(env, '/node_modules', using)).map((dir) => ({\n source: 'package' as const,\n dir,\n })),\n { source: 'user', dir: `${home}/.pi/agent/agents` },\n ],\n settingsPath: `${home}/.pi/agent/settings.json`,\n },\n using\n );\n return cached;\n };\n await roles(context).catch(() => cached);\n const script = await assets('bin/agent').catch(() => undefined);\n if (script) {\n const binDir = options.binDir ?? BIN_DIR;\n await installCommands(env, script, binDir, context);\n }\n const cli = createCli({\n env,\n harness,\n agents,\n scoops,\n roles: () => roles(context),\n ...(options.alive ? { alive: options.alive } : {}),\n ...(options.sprinkle ? { sprinkle: options.sprinkle } : {}),\n ...(options.memory ? { memory: options.memory } : {}),\n ...(options.gelatiere ? { gelatiere: options.gelatiere } : {}),\n ...(options.freezer ? { freezer: options.freezer } : {}),\n ...(options.models ? { models: options.models } : {}),\n });\n const plane = controlPlane(env, cli, {\n ...(options.controlDir ? { dir: options.controlDir } : {}),\n ...(options.sweepEvery ? { sweepEvery: options.sweepEvery } : {}),\n mirror: mirror(agents, env),\n });\n await plane.start(context);\n return { roles, plane, close: (using) => plane.close(using) };\n },\n };\n}\n\nexport type { Rewound, Scoops } from './service.ts';\n"],
|
|
5
|
-
"mappings": "AAGA,SAAsB,YAAY;AAGlC,SAAS,gBAAgB,WAAW,mBAA+B;AACnE,SAA0B,WAAW,eAAe;AACpD,SAAS,gBAAgB,iBAAiB,kBAAkB;AAC5D,SAA4B,cAAc,gBAAgB;AAC1D,SAAS,oBAAkD;AAEpD,MAAM,gBAAgB,CAAC,SAAS,UAAU,YAAY,UAAU,YAAY,WAAW;AACvF,MAAM,YAAY;AAClB,MAAM,UAAU;AAIhB,SAAS,cAAc,OAAY,IAAI,IAAI,UAAU,YAAY,GAAG,GAAW;AACpF,SAAO,OAAO,SAAS;AACrB,UAAM,WAAW,MAAM,MAAM,IAAI,IAAI,MAAM,IAAI,CAAC;AAChD,QAAI,CAAC,SAAS,GAAI,OAAM,IAAI,MAAM,GAAG,IAAI,KAAK,SAAS,MAAM,EAAE;AAC/D,WAAO,SAAS,KAAK;AAAA,EACvB;AACF;
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { Harness, Registry, ToolRegistration } from '@earendil-works/pi-durable';\nimport type { ExecutionEnv } from '@earendil-works/pi-durable/env';\nimport { type Agents, live } from '../agents.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport { DEFAULT_LIMITS, loadRoles, packageDirs, type Roles } from '../roles/roles.ts';\nimport { type CliOptions, createCli, RUN_DIR } from './cli.ts';\nimport { guardExtension, scoopsExtension, scoopTasks } from './extension.ts';\nimport { type ControlPlane, controlPlane, PROTOCOL } from './requests.ts';\nimport { createScoops, type Scoops, type ScoopsHost } from './service.ts';\n\nexport const BUILTIN_ROLES = ['scout', 'worker', 'reviewer', 'oracle', 'delegate', 'gelatiere'];\nexport const PNPM_HOME = '/home/.local/share/pnpm';\nexport const BIN_DIR = '/usr/local/bin';\n\nexport type Assets = (path: string) => Promise<string>;\n\nexport function packageAssets(base: URL = new URL('../../', import.meta.url)): Assets {\n return async (path) => {\n const response = await fetch(new URL(path, base));\n if (!response.ok) throw new Error(`${path}: ${response.status}`);\n return response.text();\n };\n}\n\nexport interface AttachOptions {\n harness: Harness;\n agents: Agents;\n groups: ProcessGroups;\n env: ExecutionEnv;\n home: string;\n assets?: Assets;\n binDir?: string;\n controlDir?: string;\n sweepEvery?: number;\n alive?: (pid: number) => Promise<boolean>;\n reads: () => readonly string[];\n sprinkle?: CliOptions['sprinkle'];\n memory?: CliOptions['memory'];\n gelatiere?: CliOptions['gelatiere'];\n freezer?: CliOptions['freezer'];\n models?: CliOptions['models'];\n panel?: CliOptions['panel'];\n mcp?: (names: readonly string[]) => ToolRegistration[];\n}\n\nexport interface ScoopsRuntime {\n roles(context: Context): Promise<Roles>;\n plane: ControlPlane;\n close(context: Context): Promise<void>;\n}\n\nexport interface ScoopsSetup {\n scoops: Scoops;\n attach(options: AttachOptions, context: Context): Promise<ScoopsRuntime>;\n}\n\nexport const COMMANDS = [\n 'agent',\n 'subagent',\n 'sprinkle',\n 'memory',\n 'gelatiere',\n 'freezer',\n 'models',\n 'panel',\n];\n\nexport async function pnpmHomeOf(env: ExecutionEnv, context: Context): Promise<string> {\n let out = '';\n const ran = await env\n .exec(\n 'printf %s \"$PNPM_HOME\"',\n {\n onOutput: (text) => {\n out += text;\n },\n },\n context\n )\n .catch(() => undefined);\n return ran?.ok && ran.value.exitCode === 0 && /^\\/\\S*$/.test(out) ? out : PNPM_HOME;\n}\n\nexport interface Installed {\n done: boolean;\n skipped: string[];\n}\n\nasync function theirs(env: ExecutionEnv, path: string, context: Context): Promise<boolean> {\n const found = await env.fileInfo(path, context);\n if (!found.ok) return found.error.code !== 'not_found';\n if (found.value.kind !== 'file') return true;\n const read = await env.readTextFile(path, context);\n return !read.ok || !read.value.includes(PROTOCOL);\n}\n\nasync function install(\n env: ExecutionEnv,\n script: string,\n binDir: string,\n context: Context\n): Promise<Installed> {\n const skipped: string[] = [];\n if (!(await env.createDir(binDir, { recursive: true }, context)).ok)\n return { done: false, skipped };\n for (const name of COMMANDS) {\n const path = `${binDir}/${name}`;\n if (await theirs(env, path, context)) {\n skipped.push(name);\n continue;\n }\n if (!(await env.writeFile(path, script, context)).ok) return { done: false, skipped };\n const mode = await env.exec(['chmod', '755', path], undefined, context);\n if (!mode.ok || mode.value.exitCode !== 0) return { done: false, skipped };\n }\n return { done: true, skipped };\n}\n\nexport async function installCommands(\n env: ExecutionEnv,\n script: string,\n binDir: string,\n context: Context,\n warn: (message: string) => void = (message) => console.warn(message)\n): Promise<Installed> {\n const installed = await install(env, script, binDir, context).catch(\n (): Installed => ({ done: false, skipped: [] })\n );\n if (installed.skipped.length) {\n const paths = installed.skipped.map((name) => `${binDir}/${name}`).join(', ');\n warn(`slicc-agent: left ${paths} alone, because it isn't slicc-agent's command`);\n }\n if (installed.done) await retire(env, binDir, context).catch(() => undefined);\n return installed;\n}\n\nexport async function retire(env: ExecutionEnv, binDir: string, context: Context) {\n const old = `${await pnpmHomeOf(env, context)}/bin`;\n if (old === binDir) return;\n for (const name of COMMANDS) {\n const path = `${old}/${name}`;\n const text = await env.readTextFile(path, context);\n if (text.ok && text.value.includes(PROTOCOL)) await env.remove(path, { force: true }, context);\n }\n}\n\nfunction mirror(agents: Agents, env: ExecutionEnv) {\n return async (context: Context) => {\n for (const [id, record] of Object.entries(agents.state().scoops)) {\n const state = record.gone ? 'gone' : live(record) ? 'live' : 'stopped';\n const metadata = {\n handle: record.folder,\n id,\n name: record.name,\n role: record.role,\n cone: record.cone,\n state,\n };\n await env.writeFile(\n `${RUN_DIR}/${record.folder}/metadata.json`,\n `${JSON.stringify(metadata, null, 2)}\\n`,\n context\n );\n }\n };\n}\n\nexport function setupScoops(\n registry: Registry,\n licks: Licks,\n fileTools: readonly ToolRegistration[] = []\n): ScoopsSetup {\n let bind: (host: ScoopsHost) => void = () => undefined;\n const host = new Promise<ScoopsHost>((resolve) => {\n bind = resolve;\n });\n const lookup = () => host;\n const tasks = scoopTasks(lookup);\n const scoops = createScoops(host, () => tasks);\n let cached: Roles = { roles: [], warnings: [], limits: { ...DEFAULT_LIMITS } };\n registry.install(scoopsExtension(tasks));\n registry.install(guardExtension(lookup, fileTools));\n return {\n scoops,\n async attach(options, context) {\n const { harness, agents, groups, env, home } = options;\n const assets = options.assets ?? packageAssets();\n bind({\n harness,\n agents,\n licks,\n tools: fileTools,\n groups,\n reads: options.reads,\n files: env,\n ...(options.mcp ? { mcp: options.mcp } : {}),\n });\n const builtin = async () => {\n const out: { path: string; text: string }[] = [];\n for (const name of BUILTIN_ROLES) {\n const path = `packages/vfs-root/agents/${name}.md`;\n out.push({ path: `builtin:${name}`, text: await assets(path) });\n }\n return out;\n };\n const roles = async (using: Context) => {\n cached = await loadRoles(\n {\n files: env,\n builtin,\n dirs: [\n ...(await packageDirs(env, '/node_modules', using)).map((dir) => ({\n source: 'package' as const,\n dir,\n })),\n { source: 'user', dir: `${home}/.pi/agent/agents` },\n ],\n settingsPath: `${home}/.pi/agent/settings.json`,\n },\n using\n );\n return cached;\n };\n await roles(context).catch(() => cached);\n const script = await assets('bin/agent').catch(() => undefined);\n if (script) {\n const binDir = options.binDir ?? BIN_DIR;\n await installCommands(env, script, binDir, context);\n }\n const cli = createCli({\n env,\n harness,\n agents,\n scoops,\n roles: () => roles(context),\n ...(options.alive ? { alive: options.alive } : {}),\n ...(options.sprinkle ? { sprinkle: options.sprinkle } : {}),\n ...(options.memory ? { memory: options.memory } : {}),\n ...(options.gelatiere ? { gelatiere: options.gelatiere } : {}),\n ...(options.freezer ? { freezer: options.freezer } : {}),\n ...(options.models ? { models: options.models } : {}),\n ...(options.panel ? { panel: options.panel } : {}),\n });\n const plane = controlPlane(env, cli, {\n ...(options.controlDir ? { dir: options.controlDir } : {}),\n ...(options.sweepEvery ? { sweepEvery: options.sweepEvery } : {}),\n mirror: mirror(agents, env),\n });\n await plane.start(context);\n return { roles, plane, close: (using) => plane.close(using) };\n },\n };\n}\n\nexport type { Rewound, Scoops } from './service.ts';\n"],
|
|
5
|
+
"mappings": "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",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/scoops/requests.js
CHANGED
|
@@ -1,7 +1,15 @@
|
|
|
1
1
|
const CONTROL_DIR = "/var/lib/slicc/agent/requests";
|
|
2
2
|
const PROTOCOL = "slicc-agent/1";
|
|
3
3
|
const STALE_MS = 10 * 6e4;
|
|
4
|
-
const COMMAND_NAMES = /* @__PURE__ */ new Set([
|
|
4
|
+
const COMMAND_NAMES = /* @__PURE__ */ new Set([
|
|
5
|
+
"subagent",
|
|
6
|
+
"sprinkle",
|
|
7
|
+
"memory",
|
|
8
|
+
"gelatiere",
|
|
9
|
+
"freezer",
|
|
10
|
+
"models",
|
|
11
|
+
"panel"
|
|
12
|
+
]);
|
|
5
13
|
const HEADER = 6;
|
|
6
14
|
function parseRequest(id, bytes) {
|
|
7
15
|
const decoder = new TextDecoder();
|
|
@@ -24,10 +32,12 @@ function parseRequest(id, bytes) {
|
|
|
24
32
|
at = end + 1;
|
|
25
33
|
}
|
|
26
34
|
const process = Number(pid);
|
|
35
|
+
const tab = caller.startsWith("tab:") ? caller.slice(4) : null;
|
|
27
36
|
return {
|
|
28
37
|
id,
|
|
29
38
|
as: COMMAND_NAMES.has(as) ? as : "agent",
|
|
30
|
-
caller,
|
|
39
|
+
caller: tab === null ? caller : "",
|
|
40
|
+
...tab ? { tab } : {},
|
|
31
41
|
cwd: cwd || "/",
|
|
32
42
|
pid: Number.isInteger(process) && process > 0 ? process : null,
|
|
33
43
|
argv,
|
|
@@ -50,6 +60,8 @@ function controlPlane(env, runner, options = {}) {
|
|
|
50
60
|
};
|
|
51
61
|
async function answer(id, result, context) {
|
|
52
62
|
await env.writeFile(`${responses}/${id}.out`, result.out, context);
|
|
63
|
+
if (result.err !== void 0)
|
|
64
|
+
await env.writeFile(`${responses}/${id}.err`, result.err, context);
|
|
53
65
|
await env.writeFile(`${responses}/${id}.code`, String(result.code), context);
|
|
54
66
|
await env.remove(`${requests}/${id}`, { force: true }, context);
|
|
55
67
|
await env.remove(`${responses}/${id}.ack`, { force: true }, context);
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/scoops/requests.ts"],
|
|
4
|
-
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { ExecutionEnv, FileWatcher } from '@earendil-works/pi-durable/env';\nimport type { Answer } from './service.ts';\n\nexport const CONTROL_DIR = '/var/lib/slicc/agent/requests';\nexport const PROTOCOL = 'slicc-agent/1';\nexport const STALE_MS = 10 * 60_000;\nconst COMMAND_NAMES = new Set(['subagent'
|
|
5
|
-
"mappings": "AAIO,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,WAAW,KAAK;AAC7B,MAAM,gBAAgB,oBAAI,IAAI,
|
|
4
|
+
"sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { ExecutionEnv, FileWatcher } from '@earendil-works/pi-durable/env';\nimport type { Answer } from './service.ts';\n\nexport const CONTROL_DIR = '/var/lib/slicc/agent/requests';\nexport const PROTOCOL = 'slicc-agent/1';\nexport const STALE_MS = 10 * 60_000;\nconst COMMAND_NAMES = new Set([\n 'subagent',\n 'sprinkle',\n 'memory',\n 'gelatiere',\n 'freezer',\n 'models',\n 'panel',\n]);\n\nexport interface Request {\n id: string;\n as: 'agent' | 'subagent' | 'sprinkle' | 'memory' | 'gelatiere' | 'freezer' | 'models' | 'panel';\n caller: string;\n tab?: string | null;\n cwd: string;\n pid: number | null;\n argv: string[];\n stdin: string;\n}\n\nconst HEADER = 6;\n\nexport function parseRequest(id: string, bytes: Uint8Array): Request | undefined {\n const decoder = new TextDecoder();\n const fields: string[] = [];\n let at = 0;\n while (fields.length < HEADER) {\n const end = bytes.indexOf(0, at);\n if (end < 0) return undefined;\n fields.push(decoder.decode(bytes.subarray(at, end)));\n at = end + 1;\n }\n const [version, as, caller, cwd, pid, count] = fields;\n const argc = Number(count);\n if (version !== PROTOCOL || !Number.isInteger(argc) || argc < 0) return undefined;\n const argv: string[] = [];\n while (argv.length < argc) {\n const end = bytes.indexOf(0, at);\n if (end < 0) return undefined;\n argv.push(decoder.decode(bytes.subarray(at, end)));\n at = end + 1;\n }\n const process = Number(pid);\n const tab = (caller as string).startsWith('tab:') ? (caller as string).slice(4) : null;\n return {\n id,\n as: COMMAND_NAMES.has(as as string) ? (as as Request['as']) : 'agent',\n caller: tab === null ? (caller as string) : '',\n ...(tab ? { tab } : {}),\n cwd: cwd || '/',\n pid: Number.isInteger(process) && process > 0 ? process : null,\n argv,\n stdin: decoder.decode(bytes.subarray(at)),\n };\n}\n\nexport interface Runner {\n run(request: Request, context: Context): Promise<Answer>;\n blocking(request: Request): boolean;\n}\n\nexport interface ControlPlane {\n start(context: Context): Promise<void>;\n sweep(context: Context): Promise<void>;\n close(context: Context): Promise<void>;\n}\n\nexport interface PlaneOptions {\n dir?: string;\n now?: () => number;\n sweepEvery?: number;\n mirror?: (context: Context) => Promise<void>;\n}\n\nexport function controlPlane(\n env: ExecutionEnv,\n runner: Runner,\n options: PlaneOptions = {}\n): ControlPlane {\n const dir = options.dir ?? CONTROL_DIR;\n const requests = `${dir}/in`;\n const responses = `${dir}/out`;\n const now = options.now ?? Date.now;\n const handled = new Set<string>();\n let watcher: FileWatcher | undefined;\n let timer: ReturnType<typeof setInterval> | undefined;\n let lock: Promise<unknown> = Promise.resolve();\n const serial = <T>(operation: () => Promise<T>): Promise<T> => {\n const next = lock.then(operation, operation);\n lock = next.catch(() => undefined);\n return next;\n };\n\n async function answer(id: string, result: Answer, context: Context) {\n await env.writeFile(`${responses}/${id}.out`, result.out, context);\n if (result.err !== undefined)\n await env.writeFile(`${responses}/${id}.err`, result.err, context);\n await env.writeFile(`${responses}/${id}.code`, String(result.code), context);\n await env.remove(`${requests}/${id}`, { force: true }, context);\n await env.remove(`${responses}/${id}.ack`, { force: true }, context);\n await options.mirror?.(context).catch(() => undefined);\n }\n\n async function handle(id: string, context: Context) {\n if (handled.has(id)) return;\n handled.add(id);\n try {\n const bytes = await env.readBinaryFile(`${requests}/${id}`, context);\n if (!bytes.ok) return;\n await env.writeFile(`${responses}/${id}.ack`, '', context);\n const request = parseRequest(id, bytes.value);\n if (!request) {\n await answer(\n id,\n { code: 2, out: 'agent: this request is not understood; update the agent command\\n' },\n context\n );\n return;\n }\n const result = runner.blocking(request)\n ? await runner.run(request, context)\n : await serial(() => runner.run(request, context));\n await answer(id, result, context);\n } finally {\n handled.delete(id);\n }\n }\n\n async function scan(context: Context) {\n const listed = await env.listDir(requests, context);\n if (!listed.ok) return;\n for (const entry of listed.value.sort((a, b) => a.name.localeCompare(b.name)))\n if (entry.kind === 'file' && !entry.name.startsWith('.'))\n void handle(entry.name, context).catch(() => undefined);\n }\n\n async function sweep(context: Context) {\n for (const folder of [requests, responses]) {\n const listed = await env.listDir(folder, context);\n if (!listed.ok) continue;\n for (const entry of listed.value) {\n const stale = now() - entry.mtimeMs > STALE_MS;\n const removable = folder === responses || entry.name.startsWith('.tmp-');\n if (stale && removable)\n await env.remove(`${folder}/${entry.name}`, { force: true }, context);\n }\n }\n }\n\n return {\n async start(context) {\n await env.createDir(requests, { recursive: true }, context);\n await env.createDir(responses, { recursive: true }, context);\n const leftovers = await env.listDir(requests, context);\n if (leftovers.ok)\n for (const entry of leftovers.value)\n if (entry.name.startsWith('.tmp-'))\n await env.remove(`${requests}/${entry.name}`, { force: true }, context);\n await sweep(context);\n const watched = await env.watch(\n [{ path: requests }],\n () => void scan(context).catch(() => undefined),\n context\n );\n if (watched.ok) watcher = watched.value;\n await scan(context);\n timer = setInterval(\n () => void sweep(context).catch(() => undefined),\n options.sweepEvery ?? 60_000\n );\n },\n sweep,\n async close(context) {\n clearInterval(timer);\n await watcher?.close(context);\n await lock;\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAIO,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,WAAW,KAAK;AAC7B,MAAM,gBAAgB,oBAAI,IAAI;AAAA,EAC5B;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACA;AACF,CAAC;AAaD,MAAM,SAAS;AAER,SAAS,aAAa,IAAY,OAAwC;AAC/E,QAAM,UAAU,IAAI,YAAY;AAChC,QAAM,SAAmB,CAAC;AAC1B,MAAI,KAAK;AACT,SAAO,OAAO,SAAS,QAAQ;AAC7B,UAAM,MAAM,MAAM,QAAQ,GAAG,EAAE;AAC/B,QAAI,MAAM,EAAG,QAAO;AACpB,WAAO,KAAK,QAAQ,OAAO,MAAM,SAAS,IAAI,GAAG,CAAC,CAAC;AACnD,SAAK,MAAM;AAAA,EACb;AACA,QAAM,CAAC,SAAS,IAAI,QAAQ,KAAK,KAAK,KAAK,IAAI;AAC/C,QAAM,OAAO,OAAO,KAAK;AACzB,MAAI,YAAY,YAAY,CAAC,OAAO,UAAU,IAAI,KAAK,OAAO,EAAG,QAAO;AACxE,QAAM,OAAiB,CAAC;AACxB,SAAO,KAAK,SAAS,MAAM;AACzB,UAAM,MAAM,MAAM,QAAQ,GAAG,EAAE;AAC/B,QAAI,MAAM,EAAG,QAAO;AACpB,SAAK,KAAK,QAAQ,OAAO,MAAM,SAAS,IAAI,GAAG,CAAC,CAAC;AACjD,SAAK,MAAM;AAAA,EACb;AACA,QAAM,UAAU,OAAO,GAAG;AAC1B,QAAM,MAAO,OAAkB,WAAW,MAAM,IAAK,OAAkB,MAAM,CAAC,IAAI;AAClF,SAAO;AAAA,IACL;AAAA,IACA,IAAI,cAAc,IAAI,EAAY,IAAK,KAAuB;AAAA,IAC9D,QAAQ,QAAQ,OAAQ,SAAoB;AAAA,IAC5C,GAAI,MAAM,EAAE,IAAI,IAAI,CAAC;AAAA,IACrB,KAAK,OAAO;AAAA,IACZ,KAAK,OAAO,UAAU,OAAO,KAAK,UAAU,IAAI,UAAU;AAAA,IAC1D;AAAA,IACA,OAAO,QAAQ,OAAO,MAAM,SAAS,EAAE,CAAC;AAAA,EAC1C;AACF;AAoBO,SAAS,aACd,KACA,QACA,UAAwB,CAAC,GACX;AACd,QAAM,MAAM,QAAQ,OAAO;AAC3B,QAAM,WAAW,GAAG,GAAG;AACvB,QAAM,YAAY,GAAG,GAAG;AACxB,QAAM,MAAM,QAAQ,OAAO,KAAK;AAChC,QAAM,UAAU,oBAAI,IAAY;AAChC,MAAI;AACJ,MAAI;AACJ,MAAI,OAAyB,QAAQ,QAAQ;AAC7C,QAAM,SAAS,CAAI,cAA4C;AAC7D,UAAM,OAAO,KAAK,KAAK,WAAW,SAAS;AAC3C,WAAO,KAAK,MAAM,MAAM,MAAS;AACjC,WAAO;AAAA,EACT;AAEA,iBAAe,OAAO,IAAY,QAAgB,SAAkB;AAClE,UAAM,IAAI,UAAU,GAAG,SAAS,IAAI,EAAE,QAAQ,OAAO,KAAK,OAAO;AACjE,QAAI,OAAO,QAAQ;AACjB,YAAM,IAAI,UAAU,GAAG,SAAS,IAAI,EAAE,QAAQ,OAAO,KAAK,OAAO;AACnE,UAAM,IAAI,UAAU,GAAG,SAAS,IAAI,EAAE,SAAS,OAAO,OAAO,IAAI,GAAG,OAAO;AAC3E,UAAM,IAAI,OAAO,GAAG,QAAQ,IAAI,EAAE,IAAI,EAAE,OAAO,KAAK,GAAG,OAAO;AAC9D,UAAM,IAAI,OAAO,GAAG,SAAS,IAAI,EAAE,QAAQ,EAAE,OAAO,KAAK,GAAG,OAAO;AACnE,UAAM,QAAQ,SAAS,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,EACvD;AAEA,iBAAe,OAAO,IAAY,SAAkB;AAClD,QAAI,QAAQ,IAAI,EAAE,EAAG;AACrB,YAAQ,IAAI,EAAE;AACd,QAAI;AACF,YAAM,QAAQ,MAAM,IAAI,eAAe,GAAG,QAAQ,IAAI,EAAE,IAAI,OAAO;AACnE,UAAI,CAAC,MAAM,GAAI;AACf,YAAM,IAAI,UAAU,GAAG,SAAS,IAAI,EAAE,QAAQ,IAAI,OAAO;AACzD,YAAM,UAAU,aAAa,IAAI,MAAM,KAAK;AAC5C,UAAI,CAAC,SAAS;AACZ,cAAM;AAAA,UACJ;AAAA,UACA,EAAE,MAAM,GAAG,KAAK,oEAAoE;AAAA,UACpF;AAAA,QACF;AACA;AAAA,MACF;AACA,YAAM,SAAS,OAAO,SAAS,OAAO,IAClC,MAAM,OAAO,IAAI,SAAS,OAAO,IACjC,MAAM,OAAO,MAAM,OAAO,IAAI,SAAS,OAAO,CAAC;AACnD,YAAM,OAAO,IAAI,QAAQ,OAAO;AAAA,IAClC,UAAE;AACA,cAAQ,OAAO,EAAE;AAAA,IACnB;AAAA,EACF;AAEA,iBAAe,KAAK,SAAkB;AACpC,UAAM,SAAS,MAAM,IAAI,QAAQ,UAAU,OAAO;AAClD,QAAI,CAAC,OAAO,GAAI;AAChB,eAAW,SAAS,OAAO,MAAM,KAAK,CAAC,GAAG,MAAM,EAAE,KAAK,cAAc,EAAE,IAAI,CAAC;AAC1E,UAAI,MAAM,SAAS,UAAU,CAAC,MAAM,KAAK,WAAW,GAAG;AACrD,aAAK,OAAO,MAAM,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,EAC5D;AAEA,iBAAe,MAAM,SAAkB;AACrC,eAAW,UAAU,CAAC,UAAU,SAAS,GAAG;AAC1C,YAAM,SAAS,MAAM,IAAI,QAAQ,QAAQ,OAAO;AAChD,UAAI,CAAC,OAAO,GAAI;AAChB,iBAAW,SAAS,OAAO,OAAO;AAChC,cAAM,QAAQ,IAAI,IAAI,MAAM,UAAU;AACtC,cAAM,YAAY,WAAW,aAAa,MAAM,KAAK,WAAW,OAAO;AACvE,YAAI,SAAS;AACX,gBAAM,IAAI,OAAO,GAAG,MAAM,IAAI,MAAM,IAAI,IAAI,EAAE,OAAO,KAAK,GAAG,OAAO;AAAA,MACxE;AAAA,IACF;AAAA,EACF;AAEA,SAAO;AAAA,IACL,MAAM,MAAM,SAAS;AACnB,YAAM,IAAI,UAAU,UAAU,EAAE,WAAW,KAAK,GAAG,OAAO;AAC1D,YAAM,IAAI,UAAU,WAAW,EAAE,WAAW,KAAK,GAAG,OAAO;AAC3D,YAAM,YAAY,MAAM,IAAI,QAAQ,UAAU,OAAO;AACrD,UAAI,UAAU;AACZ,mBAAW,SAAS,UAAU;AAC5B,cAAI,MAAM,KAAK,WAAW,OAAO;AAC/B,kBAAM,IAAI,OAAO,GAAG,QAAQ,IAAI,MAAM,IAAI,IAAI,EAAE,OAAO,KAAK,GAAG,OAAO;AAAA;AAC5E,YAAM,MAAM,OAAO;AACnB,YAAM,UAAU,MAAM,IAAI;AAAA,QACxB,CAAC,EAAE,MAAM,SAAS,CAAC;AAAA,QACnB,MAAM,KAAK,KAAK,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,QAC9C;AAAA,MACF;AACA,UAAI,QAAQ,GAAI,WAAU,QAAQ;AAClC,YAAM,KAAK,OAAO;AAClB,cAAQ;AAAA,QACN,MAAM,KAAK,MAAM,OAAO,EAAE,MAAM,MAAM,MAAS;AAAA,QAC/C,QAAQ,cAAc;AAAA,MACxB;AAAA,IACF;AAAA,IACA;AAAA,IACA,MAAM,MAAM,SAAS;AACnB,oBAAc,KAAK;AACnB,YAAM,SAAS,MAAM,OAAO;AAC5B,YAAM;AAAA,IACR;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -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 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 { CODEMODE } from '../codemode/index.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport { McpAllowDoc, mcpEntries } from '../mcp/index.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 mcp?: (names: readonly string[]) => ToolRegistration[];\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(\n tools: readonly ToolRegistration[] | undefined,\n names: string[] | undefined,\n mcp?: (names: readonly string[]) => ToolRegistration[]\n) {\n if (!names || !tools) return undefined;\n const picked = tools.filter((tool) => names.includes(tool.name));\n const entries = mcpEntries(names) ?? [];\n if (!entries.length) return picked;\n const codemode = tools.find((tool) => tool.name === CODEMODE);\n if (codemode && !picked.includes(codemode)) picked.push(codemode);\n return [...picked, ...(mcp?.(entries) ?? [])];\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 mcp?: (names: readonly string[]) => ToolRegistration[]\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, mcp);\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 narrowMcp(\n tx: Tx,\n state: Readonly<AgentsState>,\n cone: ConversationId,\n child: ConversationId,\n request: SpawnRequest\n): Promise<void> {\n const listed = mcpEntries(request.tools ?? request.role?.tools);\n const caller = state.scoops[request.parent ?? '']?.conversation as ConversationId | undefined;\n const inherited = (await tx.doc(McpAllowDoc, caller ?? cone)).allow;\n if (listed !== null || inherited !== null)\n (await tx.doc(McpAllowDoc, child)).allow = listed ?? inherited;\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, mcp } = 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, mcp));\n await narrowMcp(tx, doc, parent.id, child.id, request);\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"],
|
|
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 { CODEMODE } from '../codemode/index.ts';\nimport type { ProcessGroups } from '../kernel/groups.ts';\nimport type { Licks } from '../licks/licks.ts';\nimport { McpAllowDoc, mcpEntries } from '../mcp/index.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; err?: 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 mcp?: (names: readonly string[]) => ToolRegistration[];\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(\n tools: readonly ToolRegistration[] | undefined,\n names: string[] | undefined,\n mcp?: (names: readonly string[]) => ToolRegistration[]\n) {\n if (!names || !tools) return undefined;\n const picked = tools.filter((tool) => names.includes(tool.name));\n const entries = mcpEntries(names) ?? [];\n if (!entries.length) return picked;\n const codemode = tools.find((tool) => tool.name === CODEMODE);\n if (codemode && !picked.includes(codemode)) picked.push(codemode);\n return [...picked, ...(mcp?.(entries) ?? [])];\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 mcp?: (names: readonly string[]) => ToolRegistration[]\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, mcp);\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 narrowMcp(\n tx: Tx,\n state: Readonly<AgentsState>,\n cone: ConversationId,\n child: ConversationId,\n request: SpawnRequest\n): Promise<void> {\n const listed = mcpEntries(request.tools ?? request.role?.tools);\n const caller = state.scoops[request.parent ?? '']?.conversation as ConversationId | undefined;\n const inherited = (await tx.doc(McpAllowDoc, caller ?? cone)).allow;\n if (listed !== null || inherited !== null)\n (await tx.doc(McpAllowDoc, child)).allow = listed ?? inherited;\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, mcp } = 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, mcp));\n await narrowMcp(tx, doc, parent.id, child.id, request);\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
5
|
"mappings": "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",
|
|
6
6
|
"names": ["record", "feed"]
|
|
7
7
|
}
|
package/dist/services.js
CHANGED
|
@@ -5,11 +5,13 @@ const AgentControl = defineService("slicc.agent.control");
|
|
|
5
5
|
const AgentTranscript = defineService("slicc.agent.transcript");
|
|
6
6
|
const AgentSessions = defineService("slicc.agent.sessions");
|
|
7
7
|
const AgentRemoteService = defineService("slicc.agent.remote");
|
|
8
|
+
const AgentPagesService = defineService("slicc.agent.pages");
|
|
8
9
|
const AGENT_SESSION = "agent";
|
|
9
10
|
const AgentSettings = defineService("slicc.agent.settings");
|
|
10
11
|
export {
|
|
11
12
|
AGENT_SESSION,
|
|
12
13
|
AgentControl,
|
|
14
|
+
AgentPagesService,
|
|
13
15
|
AgentRemoteService,
|
|
14
16
|
AgentSessions,
|
|
15
17
|
AgentSettings,
|
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 { ChangesView } from './changes/git.ts';\nimport type { FrozenCone } from './freezer/index.ts';\nimport type { MemoryEntry, MemoryScope, MemoryTag } from './memory/format.ts';\nimport type { AgentRemote } from './remote/host.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 compactAgent(\n agentId: string,\n instructions: string | null,\n context: Context\n ): 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 rewindAgent(agentId: string, messageId: string | null, context: Context): Promise<Rewound>;\n resolveLick(\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved>;\n resolveAgentLick(\n agentId: string,\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 freeze(agentId: string, context: Context): Promise<Created>;\n newChat(agentId: string, context: Context): Promise<Created>;\n thaw(frozenId: string, context: Context): Promise<Created>;\n discard(frozenId: string, context: Context): Promise<Created>;\n changesOpen(context: Context): Promise<void>;\n changeAccept(path: string, context: Context): Promise<Created>;\n changeRevert(path: string, context: Context): Promise<Created>;\n monitorOpen(lease: string | null, resync: boolean, context: Context): Promise<MonitorLease>;\n monitorClose(lease: string, context: Context): Promise<void>;\n}\n\nexport interface MonitorLease {\n lease: string;\n ttlMs: number;\n}\n\nexport interface MonitorAgent {\n id: string;\n name: string;\n kind: 'cone' | 'scoop';\n parentId: string | null;\n model: string | null;\n running: boolean;\n queued: number;\n tool: string | null;\n retry: { attempt: number; since: number; error: string } | null;\n failed: string | null;\n context: number | null;\n}\n\nexport interface MonitorTask {\n id: string;\n kind: string;\n detail: string | null;\n agentId: string | null;\n owner: string | null;\n status: 'pending' | 'running' | 'waiting' | 'completing';\n phase: string;\n background: boolean;\n aborting: number | null;\n since: number;\n waits: number;\n}\n\nexport interface MonitorProcess {\n pid: number;\n ppid: number;\n pgid: number;\n user: string | null;\n agentId: string | null;\n command: string;\n state: 'S' | 'Z';\n started: number;\n zombie: number | null;\n tty: boolean;\n rss: number | null;\n}\n\nexport interface MonitorProblem {\n id: string;\n at: number;\n agentId: string | null;\n kind: 'task' | 'retry' | 'turn';\n message: string;\n}\n\nexport interface MonitorFeed {\n open: boolean;\n at: number;\n usage: { tokens: number; cost: number; free: boolean } | null;\n agents: MonitorAgent[];\n tasks: MonitorTask[];\n processes: MonitorProcess[] | null;\n problems: MonitorProblem[];\n paused: 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 readonly frozen: ReplicatedState<FrozenCone[]>;\n readonly changes: ReplicatedState<ChangesView>;\n readonly monitor: ReplicatedState<MonitorFeed>;\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 AgentRemoteService = defineService<AgentRemote>('slicc.agent.remote');\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 images?: boolean;\n contextWindow: number;\n}\n\nexport interface AccountState {\n id: string;\n provider: string;\n identity: string;\n status: 'connected' | 'disconnected' | 'expired';\n auth: 'api-key' | 'oauth';\n needs: 'cors-free-transport' | null;\n group?: 'providers' | 'mcp';\n secret?: 'api-key' | 'token';\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 McpSignIn {\n url: string;\n state: 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 | McpSignIn | 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 { ChangesView } from './changes/git.ts';\nimport type { FrozenCone } from './freezer/index.ts';\nimport type { MemoryEntry, MemoryScope, MemoryTag } from './memory/format.ts';\nimport type { AgentRemote } from './remote/host.ts';\nimport type { AgentPages } from './remote/pages.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 compactAgent(\n agentId: string,\n instructions: string | null,\n context: Context\n ): 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 rewindAgent(agentId: string, messageId: string | null, context: Context): Promise<Rewound>;\n resolveLick(\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved>;\n resolveAgentLick(\n agentId: string,\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 freeze(agentId: string, context: Context): Promise<Created>;\n newChat(agentId: string, context: Context): Promise<Created>;\n thaw(frozenId: string, context: Context): Promise<Created>;\n discard(frozenId: string, context: Context): Promise<Created>;\n changesOpen(context: Context): Promise<void>;\n changeAccept(path: string, context: Context): Promise<Created>;\n changeRevert(path: string, context: Context): Promise<Created>;\n monitorOpen(lease: string | null, resync: boolean, context: Context): Promise<MonitorLease>;\n monitorClose(lease: string, context: Context): Promise<void>;\n}\n\nexport interface MonitorLease {\n lease: string;\n ttlMs: number;\n}\n\nexport interface MonitorAgent {\n id: string;\n name: string;\n kind: 'cone' | 'scoop';\n parentId: string | null;\n model: string | null;\n running: boolean;\n queued: number;\n tool: string | null;\n retry: { attempt: number; since: number; error: string } | null;\n failed: string | null;\n context: number | null;\n}\n\nexport interface MonitorTask {\n id: string;\n kind: string;\n detail: string | null;\n agentId: string | null;\n owner: string | null;\n status: 'pending' | 'running' | 'waiting' | 'completing';\n phase: string;\n background: boolean;\n aborting: number | null;\n since: number;\n waits: number;\n}\n\nexport interface MonitorProcess {\n pid: number;\n ppid: number;\n pgid: number;\n user: string | null;\n agentId: string | null;\n command: string;\n state: 'S' | 'Z';\n started: number;\n zombie: number | null;\n tty: boolean;\n rss: number | null;\n}\n\nexport interface MonitorProblem {\n id: string;\n at: number;\n agentId: string | null;\n kind: 'task' | 'retry' | 'turn';\n message: string;\n}\n\nexport interface MonitorFeed {\n open: boolean;\n at: number;\n usage: { tokens: number; cost: number; free: boolean } | null;\n agents: MonitorAgent[];\n tasks: MonitorTask[];\n processes: MonitorProcess[] | null;\n problems: MonitorProblem[];\n paused: 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 readonly frozen: ReplicatedState<FrozenCone[]>;\n readonly changes: ReplicatedState<ChangesView>;\n readonly monitor: ReplicatedState<MonitorFeed>;\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 AgentRemoteService = defineService<AgentRemote>('slicc.agent.remote');\n\nexport const AgentPagesService = defineService<AgentPages>('slicc.agent.pages');\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 images?: boolean;\n contextWindow: number;\n}\n\nexport interface AccountState {\n id: string;\n provider: string;\n identity: string;\n status: 'connected' | 'disconnected' | 'expired';\n auth: 'api-key' | 'oauth';\n needs: 'cors-free-transport' | null;\n group?: 'providers' | 'mcp';\n secret?: 'api-key' | 'token';\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 McpSignIn {\n url: string;\n state: 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 | McpSignIn | null>;\n}\n\nexport const AgentSettings = defineService<AgentSettings>('slicc.agent.settings');\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EAEE;AAAA,OAGK;AAiNA,MAAM,eAAe,cAA4B,qBAAqB;AAwBtE,MAAM,kBAAkB,cAA+B,wBAAwB;AAO/E,MAAM,gBAAgB,cAA6B,sBAAsB;AAEzE,MAAM,qBAAqB,cAA2B,oBAAoB;AAE1E,MAAM,oBAAoB,cAA0B,mBAAmB;AAEvE,MAAM,gBAAgB;AA2DtB,MAAM,gBAAgB,cAA6B,sBAAsB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|