@ai-ecoverse/slicc-agent 5.8.3 → 5.9.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.
Files changed (47) hide show
  1. package/README.md +18 -11
  2. package/bin/agent +3 -1
  3. package/dist/gelatiere/index.js +16 -19
  4. package/dist/gelatiere/index.js.map +2 -2
  5. package/dist/kernel/agent-users.js +11 -0
  6. package/dist/kernel/agent-users.js.map +2 -2
  7. package/dist/licks/boot.js +10 -1
  8. package/dist/licks/boot.js.map +2 -2
  9. package/dist/licks/config.js +0 -37
  10. package/dist/licks/config.js.map +3 -3
  11. package/dist/licks/crontab.js +141 -0
  12. package/dist/licks/crontab.js.map +7 -0
  13. package/dist/licks/extension.js +4 -69
  14. package/dist/licks/extension.js.map +2 -2
  15. package/dist/licks/index.js +3 -5
  16. package/dist/licks/index.js.map +2 -2
  17. package/dist/licks/sources.js +42 -14
  18. package/dist/licks/sources.js.map +2 -2
  19. package/dist/main.js +1 -1
  20. package/dist/main.js.map +2 -2
  21. package/dist/scoops/cli.js +32 -0
  22. package/dist/scoops/cli.js.map +2 -2
  23. package/dist/scoops/index.js +7 -5
  24. package/dist/scoops/index.js.map +2 -2
  25. package/dist/scoops/requests.js +22 -7
  26. package/dist/scoops/requests.js.map +2 -2
  27. package/dist/spectrum/monitor-port.js +0 -1
  28. package/dist/spectrum/monitor-port.js.map +2 -2
  29. package/dist/types/gelatiere/index.d.ts +2 -1
  30. package/dist/types/kernel/agent-users.d.ts +2 -0
  31. package/dist/types/licks/boot.d.ts +12 -1
  32. package/dist/types/licks/config.d.ts +0 -7
  33. package/dist/types/licks/crontab.d.ts +37 -0
  34. package/dist/types/licks/extension.d.ts +1 -17
  35. package/dist/types/licks/index.d.ts +1 -1
  36. package/dist/types/licks/sources.d.ts +1 -3
  37. package/dist/types/scoops/cli.d.ts +2 -0
  38. package/dist/types/scoops/requests.d.ts +5 -1
  39. package/package.json +5 -5
  40. package/packages/vfs-root/skills/gelatiere/SKILL.md +2 -2
  41. package/packages/vfs-root/skills/licks/SKILL.md +16 -12
  42. package/dist/licks/cron.js +0 -120
  43. package/dist/licks/cron.js.map +0 -7
  44. package/dist/licks/schedules.js +0 -50
  45. package/dist/licks/schedules.js.map +0 -7
  46. package/dist/types/licks/cron.d.ts +0 -16
  47. package/dist/types/licks/schedules.d.ts +0 -25
@@ -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', 'memory', 'gelatiere', 'freezer', 'models', 'panel']);\n\nexport interface Request {\n id: string;\n as: 'agent' | 'subagent' | '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 user?: 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 user?: string;\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 parsed = parseRequest(id, bytes.value);\n const request = parsed && options.user ? { ...parsed, user: options.user } : parsed;\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": "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",
4
+ "sourcesContent": ["import type { Context } from '@earendil-works/chord';\nimport type { ExecutionEnv, FileWatcher } from '@earendil-works/pi-durable/env';\nimport type { CronRun } from '../licks/crontab.ts';\nimport type { Answer } from './service.ts';\n\nexport const CONTROL_DIR = '/var/lib/slicc/agent/requests';\nexport const PROTOCOL = 'slicc-agent/2';\nexport const PROTOCOL_MARK = 'slicc-agent/';\nexport const STALE_MS = 10 * 60_000;\nconst COMMAND_NAMES = new Set(['subagent', 'memory', 'gelatiere', 'freezer', 'models', 'panel']);\n\nexport interface Request {\n id: string;\n as: 'agent' | 'subagent' | '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 user?: string;\n cron?: CronRun;\n}\n\nconst HEADERS: Record<string, number> = { 'slicc-agent/1': 6, [PROTOCOL]: 7 };\n\nexport function cronOf(field: string): CronRun | undefined {\n const [job, due, missed, extra] = field.split(' ');\n const count = Number(missed);\n if (!job || !due || extra !== undefined || !Number.isInteger(count) || count < 0)\n return undefined;\n return { job, due, missed: count };\n}\n\nexport function parseRequest(id: string, bytes: Uint8Array): Request | undefined {\n const decoder = new TextDecoder();\n const fields: string[] = [];\n let at = 0;\n let header = 1;\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 header = HEADERS[fields[0] as string] ?? 0;\n }\n if (!header) return undefined;\n const [, as, caller, cwd, pid] = fields;\n const cron = header === 7 ? cronOf(fields[5] as string) : undefined;\n const argc = Number(fields.at(-1));\n if (!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 ...(cron ? { cron } : {}),\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 user?: string;\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 parsed = parseRequest(id, bytes.value);\n const request = parsed && options.user ? { ...parsed, user: options.user } : parsed;\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": "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",
6
6
  "names": []
7
7
  }
@@ -36,7 +36,6 @@ function trend(series) {
36
36
  const KINDS = {
37
37
  "pi.generation": "generating",
38
38
  "pi.compaction": "compacting",
39
- "slicc.cron": "cron",
40
39
  "slicc.scoop-wait": "agent wait",
41
40
  "slicc.scoop-reporter": "report",
42
41
  "slicc.memory-extract": "memory extraction"
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/spectrum/monitor-port.ts"],
4
- "sourcesContent": ["import type {\n MonitorAlert,\n MonitorEvents,\n MonitorPort,\n MonitorRow,\n MonitorSection,\n MonitorSnapshot,\n MonitorStatus,\n MonitorVital,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentConnection } from '../client.ts';\nimport { contextRatio } from '../context.ts';\nimport type {\n BudgetState,\n ModelChoice,\n MonitorAgent,\n MonitorFeed,\n MonitorProcess,\n MonitorTask,\n} from '../services.ts';\nimport { Emitter } from './emitter.ts';\n\nexport const RENEW_MS = 10000;\nexport const SAMPLE_MS = 2000;\nexport const ROWS_MAX = 200;\nexport const HISTORY = 24;\nexport const CPU_HISTORY = 30;\nexport const CPU_QUIET = 0.01;\nexport const BUDGET_WARN = 80;\nexport const BUDGET_ERROR = 95;\nexport const RETRY_WARN = 3;\nexport const RETRY_ERROR = 6;\nexport const RETRY_SLOW_MS = 120000;\nexport const FAILED_MS = 600000;\nexport const ABORT_MS = 30000;\nexport const ABORT_ROW_MS = 10000;\nexport const GROUP_MAX = 32;\nexport const TOTAL_MAX = 128;\nexport const ZOMBIE_MS = 60000;\nexport const STALE_MS = 1800000;\nexport const CPU_SHARE = 0.9;\nexport const CPU_SUSTAIN_MS = 120000;\nexport const CONTEXT_WARN = 0.8;\nexport const DEPTH_MAX = 6;\nconst MINUTE = 60000;\nconst HOUR = 3600000;\nconst DAY = 86400000;\n\nexport type AgentMonitorAlert = MonitorAlert & { command?: string; commandLabel?: string };\n\nexport interface Sample {\n at: number;\n cost: number;\n tokens: number;\n active: number;\n}\n\nexport interface MonitorInput {\n feed: MonitorFeed | undefined;\n budget: BudgetState | null | undefined;\n models: readonly ModelChoice[];\n changes: readonly { path: string; status: string }[];\n sprinkles?: readonly { name: string; title: string }[];\n extra: readonly MonitorSection[];\n history: readonly Sample[];\n now: number;\n hot?: ReadonlyMap<number, number>;\n cpu?: readonly number[];\n processes?: readonly number[];\n memory?: readonly number[];\n}\n\nexport function record<T>(list: T[], value: T, max: number): void {\n list.push(value);\n if (list.length > max) list.shift();\n}\n\nfunction trend(series: readonly number[] | undefined): { series?: number[] } {\n return series && series.length > 1 ? { series: [...series] } : {};\n}\n\nconst KINDS: Record<string, string> = {\n 'pi.generation': 'generating',\n 'pi.compaction': 'compacting',\n 'slicc.cron': 'cron',\n 'slicc.scoop-wait': 'agent wait',\n 'slicc.scoop-reporter': 'report',\n 'slicc.memory-extract': 'memory extraction',\n};\n\nexport function age(ms: number): string {\n const seconds = Math.max(0, Math.round(ms / 1000));\n if (seconds < 60) return `${seconds}s`;\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;\n return `${Math.floor(seconds / 3600)}h`;\n}\n\nexport function money(value: number): string {\n if (value > 0 && value < 0.01) return '<$0.01';\n return `$${value.toFixed(2)}`;\n}\n\nexport function count(value: number): string {\n if (value < 1000) return String(value);\n if (value < 1000000) return `${(value / 1000).toFixed(1)}k`;\n return `${(value / 1000000).toFixed(1)}M`;\n}\n\nexport function bytes(value: number): string {\n if (value < 1024) return `${value} B`;\n const units = ['KiB', 'MiB', 'GiB', 'TiB'];\n let size = value / 1024;\n let unit = 0;\n while (size >= 1024 && unit < units.length - 1) {\n size /= 1024;\n unit++;\n }\n return `${size.toFixed(size < 10 ? 1 : 0)} ${units[unit]}`;\n}\n\nexport function cpuText(share: number | null | undefined): string | null {\n if (typeof share !== 'number' || share < CPU_QUIET) return null;\n return `${Math.round(share * 100)}%\\u00a0CPU`;\n}\n\nexport function agentsCpu(feed: MonitorFeed): number | null {\n const shares = feed.agents\n .map((agent) => agent.cpu)\n .filter((share): share is number => typeof share === 'number');\n return shares.length ? shares.reduce((sum, share) => sum + share, 0) : null;\n}\n\nfunction cpuVital(feed: MonitorFeed, history: readonly number[]): MonitorVital[] {\n const share = agentsCpu(feed);\n if (share === null) return [];\n return [\n {\n id: 'cpu',\n label: 'CPU',\n value: `${Math.round(share * 100)}%`,\n unit: 'of one core',\n ...trend(history.map((value) => Math.round(value * 100))),\n },\n ];\n}\n\nfunction measuredOf(processes: readonly MonitorProcess[]): MonitorProcess[] {\n return processes.filter((row) => typeof row.rss === 'number');\n}\n\nexport function memoryTotal(processes: readonly MonitorProcess[]): number | null {\n const measured = measuredOf(processes);\n return measured.length ? measured.reduce((sum, row) => sum + (row.rss as number), 0) : null;\n}\n\nfunction memoryVital(\n processes: readonly MonitorProcess[],\n history: readonly number[] | undefined\n): MonitorVital[] {\n const total = memoryTotal(processes);\n if (total === null) return [];\n const measured = measuredOf(processes);\n const agents = measured\n .filter((row) => row.agentId)\n .reduce((sum, row) => sum + (row.rss as number), 0);\n return [\n {\n id: 'memory',\n label: 'Process memory',\n value: bytes(total),\n unit: `${bytes(agents)} by agents`,\n ...trend(history),\n },\n ];\n}\n\nexport function taskLabel(task: MonitorTask): string {\n if (task.kind === 'pi.tool') return task.detail ? `tool ${task.detail}` : 'tool';\n if (task.kind === 'slicc.scoop-anchor') return task.detail ? `scoop ${task.detail}` : 'scoop';\n return KINDS[task.kind] ?? task.kind;\n}\n\nfunction coneOf(agents: ReadonlyMap<string, MonitorAgent>, id: string | null): string | null {\n const visited = new Set<string>();\n let current = id === null ? undefined : agents.get(id);\n while (current?.parentId && !visited.has(current.id)) {\n visited.add(current.id);\n const parent = agents.get(current.parentId);\n if (!parent) break;\n current = parent;\n }\n return current ? current.id : null;\n}\n\nfunction ordered(feed: MonitorFeed): MonitorAgent[] {\n const byId = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const out: MonitorAgent[] = [];\n for (const cone of feed.agents.filter((agent) => agent.kind === 'cone')) {\n out.push(cone);\n for (const agent of feed.agents)\n if (agent.kind === 'scoop' && coneOf(byId, agent.id) === cone.id) out.push(agent);\n }\n for (const agent of feed.agents) if (!out.includes(agent)) out.push(agent);\n return out;\n}\n\nexport function taskTree(feed: MonitorFeed): { task: MonitorTask; depth: number }[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const order = ordered(feed).map((agent) => agent.id);\n const rank = (task: MonitorTask) => {\n const at = task.agentId === null ? -1 : order.indexOf(task.agentId);\n return at < 0 ? order.length : at;\n };\n const groupOf = (task: MonitorTask) => coneOf(agents, task.agentId) ?? '';\n const byId = new Map(feed.tasks.map((task) => [task.id, task]));\n const children = new Map<string, MonitorTask[]>();\n const roots: MonitorTask[] = [];\n for (const task of feed.tasks) {\n const owner = task.owner === null ? undefined : byId.get(task.owner);\n if (owner && groupOf(owner) === groupOf(task)) {\n const list = children.get(owner.id) ?? [];\n list.push(task);\n children.set(owner.id, list);\n } else roots.push(task);\n }\n const sort = (list: MonitorTask[]) =>\n list.sort((a, b) => rank(a) - rank(b) || Number(a.id) - Number(b.id));\n const out: { task: MonitorTask; depth: number }[] = [];\n const visit = (task: MonitorTask, depth: number) => {\n out.push({ task, depth });\n for (const child of sort(children.get(task.id) ?? [])) visit(child, depth + 1);\n };\n for (const root of sort(roots)) visit(root, 0);\n return out;\n}\n\nfunction capped(rows: MonitorRow[]): MonitorRow[] {\n if (rows.length <= ROWS_MAX) return rows;\n const shown = rows.slice(0, ROWS_MAX - 1);\n return [\n ...shown,\n { id: 'more', name: `+${rows.length - shown.length} more`, meta: '', status: 'idle' },\n ];\n}\n\nfunction agentContext(agent: MonitorAgent, models: readonly ModelChoice[]): number | null {\n return contextRatio(agent.context, agent.model, models);\n}\n\nfunction rate(history: readonly Sample[], pick: (sample: Sample) => number): number | null {\n const first = history[0];\n const last = history.at(-1);\n if (!first || !last || last.at - first.at < MINUTE) return null;\n return ((pick(last) - pick(first)) / (last.at - first.at)) * HOUR;\n}\n\nconst RELATIVE = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });\n\nfunction resetsIn(at: number, now: number): string {\n const ms = at - now;\n if (ms <= 0) return 'resets soon';\n if (ms >= DAY)\n return `resets ${RELATIVE.format(Math.floor(at / DAY) - Math.floor(now / DAY), 'day')}`;\n if (ms >= HOUR) return `resets ${RELATIVE.format(Math.floor(ms / HOUR), 'hour')}`;\n return `resets ${RELATIVE.format(Math.ceil(ms / MINUTE), 'minute')}`;\n}\n\nfunction budgetVital(budget: BudgetState, now: number): MonitorVital {\n const resets = new Date(budget.resets);\n return {\n id: 'budget',\n label: `Budget (${budget.window})`,\n value: `${budget.percent}%`,\n ...(Number.isNaN(resets.getTime())\n ? {}\n : {\n unit: resetsIn(resets.getTime(), now),\n hint: `resets ${resets.toISOString().slice(0, 16).replace('T', ' ')} UTC`,\n }),\n ratio: Math.min(1, Math.max(0, budget.percent / 100)),\n };\n}\n\nfunction vitals(input: MonitorInput, feed: MonitorFeed): MonitorVital[] {\n const out: MonitorVital[] = [];\n if (feed.usage) {\n const free = feed.usage.free;\n const pick = (sample: Sample) => (free ? sample.tokens : sample.cost);\n const perHour = rate(input.history, pick);\n const series = input.history.map(pick);\n out.push({\n id: 'spend',\n label: free ? 'Tokens' : 'Spend',\n value: free ? count(feed.usage.tokens) : money(feed.usage.cost),\n unit: free ? 'tokens' : `${count(feed.usage.tokens)} tokens`,\n ...(perHour === null ? {} : { delta: `${free ? count(perHour) : money(perHour)}/h` }),\n ...trend(series),\n });\n }\n const active = feed.agents.filter((agent) => agent.running).length;\n out.push({\n id: 'agents',\n label: 'Active agents',\n value: String(active),\n unit: `of ${feed.agents.length}`,\n ...trend(input.history.map((sample) => sample.active)),\n });\n const tools = feed.tasks.filter(\n (task) => task.kind === 'pi.tool' && task.status === 'running'\n ).length;\n out.push({\n id: 'tasks',\n label: 'Running',\n value: String(tools),\n unit: `${tools === 1 ? 'tool' : 'tools'} \u00B7 ${feed.tasks.length} ${feed.tasks.length === 1 ? 'task' : 'tasks'}`,\n });\n out.push(\n feed.processes\n ? {\n id: 'processes',\n label: 'Processes',\n value: String(feed.processes.length),\n unit: `${feed.processes.filter((row) => row.agentId).length} by agents`,\n ...trend(input.processes),\n }\n : feed.kernel === 'checking'\n ? { id: 'processes', label: 'Processes', value: '\u2026', unit: 'checking' }\n : { id: 'processes', label: 'Processes', value: '\u2014', unit: 'kernel not reachable' }\n );\n out.push(...memoryVital(feed.processes ?? [], input.memory));\n out.push(...cpuVital(feed, input.cpu ?? []));\n const ratios = feed.agents\n .map((agent) => agentContext(agent, input.models))\n .filter((ratio): ratio is number => ratio !== null);\n if (ratios.length) {\n const fullest = Math.max(...ratios);\n out.push({\n id: 'context',\n label: 'Fullest context',\n value: `${Math.round(fullest * 100)}%`,\n ratio: fullest,\n });\n }\n return out;\n}\n\nfunction stale(process: MonitorProcess, agents: ReadonlyMap<string, MonitorAgent>, now: number) {\n if (!process.agentId || process.state === 'Z' || !process.started) return false;\n if (typeof process.utime === 'number') return false;\n if (agents.get(process.agentId)?.tool === 'bash') return false;\n return now - process.started > STALE_MS;\n}\n\nfunction zombied(process: MonitorProcess, now: number): boolean {\n return process.zombie !== null && now - process.zombie > ZOMBIE_MS;\n}\n\nfunction groups(processes: readonly MonitorProcess[]): Map<number, MonitorProcess[]> {\n const out = new Map<number, MonitorProcess[]>();\n for (const process of processes) {\n if (!process.agentId) continue;\n const list = out.get(process.pgid) ?? [];\n list.push(process);\n out.set(process.pgid, list);\n }\n return out;\n}\n\ntype Names = (id: string | null) => string;\n\nexport function groupCpu(\n processes: readonly MonitorProcess[]\n): Map<number, { agentId: string; share: number }> {\n const out = new Map<number, { agentId: string; share: number }>();\n for (const [pgid, members] of groups(processes)) {\n const measured = members.filter((row) => typeof row.cpu === 'number');\n if (!measured.length) continue;\n const share = measured.reduce((sum, row) => sum + (row.cpu as number), 0);\n out.set(pgid, { agentId: (members[0] as MonitorProcess).agentId as string, share });\n }\n return out;\n}\n\nexport function hotGroups(\n processes: readonly MonitorProcess[],\n at: number,\n previous: ReadonlyMap<number, number>\n): Map<number, number> {\n const out = new Map<number, number>();\n for (const [pgid, { share }] of groupCpu(processes))\n if (share >= CPU_SHARE) out.set(pgid, previous.get(pgid) ?? at);\n return out;\n}\n\nfunction busy(input: MonitorInput, processes: readonly MonitorProcess[]) {\n const shares = groupCpu(processes);\n const out: { pgid: number; agentId: string; share: number; held: number }[] = [];\n for (const [pgid, since] of input.hot ?? []) {\n const group = shares.get(pgid);\n const held = input.now - since;\n if (group && group.share >= CPU_SHARE && held >= CPU_SUSTAIN_MS)\n out.push({ pgid, ...group, held });\n }\n return out;\n}\n\nfunction cpuAlerts(input: MonitorInput, processes: readonly MonitorProcess[], nameOf: Names) {\n return busy(input, processes).map(\n (group): AgentMonitorAlert => ({\n id: `runaway-cpu-${group.pgid}`,\n title: `${nameOf(group.agentId)} is using a lot of CPU`,\n detail: `${Math.round(group.share * 100)}% of one core for ${Math.floor(group.held / MINUTE)} minutes.`,\n command: `kill -- -${group.pgid}`,\n commandLabel: 'To stop it, run',\n severity: cpuSeverity(group),\n })\n );\n}\n\nfunction cpuSeverity(group: { share: number; held: number }): 'warn' | 'error' {\n return group.share >= CPU_SHARE * 2 || group.held >= CPU_SUSTAIN_MS * 2 ? 'error' : 'warn';\n}\n\nfunction crowdSeverity(members: readonly MonitorProcess[]): 'warn' | 'error' {\n return members.length > GROUP_MAX * 2 ? 'error' : 'warn';\n}\n\nfunction staleSeverity(process: MonitorProcess, now: number): 'warn' | 'error' {\n return now - process.started > STALE_MS * 2 ? 'error' : 'warn';\n}\n\nfunction worse(\n a: 'warn' | 'error' | undefined,\n b: 'warn' | 'error' | undefined\n): 'warn' | 'error' | undefined {\n return a === 'error' || b === 'error' ? 'error' : (a ?? b);\n}\n\nfunction resetLine(budget: BudgetState): string {\n const resets = new Date(budget.resets);\n return Number.isNaN(resets.getTime())\n ? `The ${budget.window} budget is nearly used up.`\n : `Resets ${resets.toISOString().slice(0, 16).replace('T', ' ')} UTC.`;\n}\n\nfunction budgetAlerts(budget: BudgetState | null | undefined): AgentMonitorAlert[] {\n if (!budget || budget.percent < BUDGET_WARN) return [];\n return [\n {\n id: 'budget',\n title: `Budget ${budget.percent}% used`,\n detail: resetLine(budget),\n severity: budget.percent >= BUDGET_ERROR ? 'error' : 'warn',\n },\n ];\n}\n\nfunction agentAlerts(input: MonitorInput, feed: MonitorFeed): AgentMonitorAlert[] {\n const out: AgentMonitorAlert[] = [];\n for (const agent of feed.agents) {\n const retry = agent.retry;\n if (retry && (retry.attempt >= RETRY_WARN || input.now - retry.since > RETRY_SLOW_MS))\n out.push({\n id: `retry-${agent.id}`,\n title: `${agent.name} is retrying (attempt ${retry.attempt})`,\n detail: retry.error,\n severity: retry.attempt >= RETRY_ERROR ? 'error' : 'warn',\n });\n if (agent.failed && !agent.running)\n out.push({\n id: `turn-${agent.id}`,\n title: `${agent.name}'s last turn failed`,\n detail: agent.failed,\n severity: 'error',\n });\n }\n return out;\n}\n\nfunction taskAlerts(input: MonitorInput, feed: MonitorFeed, nameOf: Names): AgentMonitorAlert[] {\n const out: AgentMonitorAlert[] = [];\n for (const problem of feed.problems)\n if (problem.kind === 'task' && input.now - problem.at < FAILED_MS)\n out.push({\n id: `failed-${problem.id}`,\n title: `A task of ${nameOf(problem.agentId)} failed`,\n detail: problem.message,\n severity: 'error',\n });\n for (const task of feed.tasks)\n if (task.aborting !== null && input.now - task.aborting > ABORT_MS)\n out.push({\n id: `abort-${task.id}`,\n title: `Stop is still waiting for ${taskLabel(task)}`,\n detail: `${nameOf(task.agentId)} asked it to stop ${age(input.now - task.aborting)} ago.`,\n severity: 'warn',\n });\n return out;\n}\n\nfunction crowdAlerts(processes: readonly MonitorProcess[], nameOf: Names): AgentMonitorAlert[] {\n const out: AgentMonitorAlert[] = [];\n for (const [pgid, members] of groups(processes))\n if (members.length > GROUP_MAX)\n out.push({\n id: `runaway-${pgid}`,\n title: `${nameOf((members[0] as MonitorProcess).agentId)} has ${members.length} processes`,\n detail: 'Something in it may be starting processes in a loop.',\n command: `kill -- -${pgid}`,\n commandLabel: 'To stop them, run',\n severity: crowdSeverity(members),\n });\n if (processes.length > TOTAL_MAX)\n out.push({\n id: 'runaway-total',\n title: `The kernel has ${processes.length} processes`,\n detail: 'Something may be starting processes in a loop.',\n severity: processes.length > TOTAL_MAX * 2 ? 'error' : 'warn',\n });\n return out;\n}\n\nfunction processAlerts(input: MonitorInput, feed: MonitorFeed, nameOf: Names): AgentMonitorAlert[] {\n const processes = feed.processes ?? [];\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const out = [...crowdAlerts(processes, nameOf), ...cpuAlerts(input, processes, nameOf)];\n for (const process of processes) {\n if (zombied(process, input.now))\n out.push({\n id: `zombie-${process.pid}`,\n title: `Process ${process.pid} is a zombie`,\n detail: `Its parent ${process.ppid} hasn't reaped it.`,\n ...(process.ppid > 1\n ? { command: `kill ${process.ppid}`, commandLabel: 'To clear it, stop the parent' }\n : {}),\n severity: 'warn',\n });\n if (stale(process, agents, input.now))\n out.push({\n id: `stale-${process.pid}`,\n title: `${process.command || `Process ${process.pid}`} has run for ${age(input.now - process.started)}`,\n detail: `${nameOf(process.agentId)} started it in the background.`,\n command: `kill ${process.pid}`,\n commandLabel: 'To stop it, run',\n severity: staleSeverity(process, input.now),\n });\n }\n return out;\n}\n\nfunction contextAlerts(input: MonitorInput, feed: MonitorFeed): AgentMonitorAlert[] {\n const out: AgentMonitorAlert[] = [];\n for (const agent of feed.agents) {\n const ratio = agentContext(agent, input.models);\n if (ratio !== null && ratio >= CONTEXT_WARN)\n out.push({\n id: `context-${agent.id}`,\n title: `${agent.name} is ${Math.round(ratio * 100)}% full`,\n detail: 'Compact it soon to keep replies fast.',\n severity: 'warn',\n });\n }\n if (feed.paused)\n out.push({\n id: 'scheduler',\n title: \"The agent isn't scheduling work\",\n detail: 'Its scheduler is paused.',\n severity: 'warn',\n });\n return out;\n}\n\nfunction alerts(input: MonitorInput, feed: MonitorFeed): AgentMonitorAlert[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const nameOf: Names = (id) => (id ? (agents.get(id)?.name ?? id) : 'the session');\n return [\n ...budgetAlerts(input.budget),\n ...agentAlerts(input, feed),\n ...taskAlerts(input, feed, nameOf),\n ...processAlerts(input, feed, nameOf),\n ...contextAlerts(input, feed),\n ];\n}\n\nfunction taskRow(\n task: MonitorTask,\n depth: number,\n nameOf: (id: string | null) => string,\n now: number\n): MonitorRow {\n const aborting = task.aborting !== null && now - task.aborting > ABORT_ROW_MS;\n const status: MonitorStatus = aborting\n ? 'warn'\n : task.status === 'running' || task.status === 'completing'\n ? 'active'\n : 'idle';\n const badges = [\n ...(task.background ? ['background'] : []),\n ...(task.aborting !== null ? ['aborting'] : []),\n ...(task.waits ? [`waits on ${task.waits}`] : []),\n ];\n return {\n id: task.id,\n name: taskLabel(task),\n depth: Math.min(depth, DEPTH_MAX),\n meta: [nameOf(task.agentId), task.phase, age(now - task.since)].filter(Boolean).join(' \u00B7 '),\n status,\n ...(badges.length ? { badges } : {}),\n };\n}\n\nfunction drivers(members: readonly MonitorProcess[]): MonitorProcess[] {\n const hot = members.filter((row) => (row.cpu ?? 0) >= CPU_SHARE);\n if (hot.length) return hot;\n const top = members.reduce((best, row) => ((row.cpu ?? 0) > (best.cpu ?? 0) ? row : best));\n return [top];\n}\n\nfunction processRows(input: MonitorInput, feed: MonitorFeed): MonitorRow[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const members = groups(feed.processes ?? []);\n const flagged = new Map<number, 'warn' | 'error'>();\n for (const group of busy(input, feed.processes ?? []))\n for (const row of drivers(members.get(group.pgid) as MonitorProcess[]))\n flagged.set(row.pid, cpuSeverity(group));\n return (feed.processes ?? []).map((process) => {\n const runaway = worse(\n worse(\n flagged.get(process.pid),\n stale(process, agents, input.now) ? staleSeverity(process, input.now) : undefined\n ),\n zombied(process, input.now) ? 'warn' : undefined\n );\n const badges = [\n ...(process.agentId ? [agents.get(process.agentId)?.name ?? process.agentId] : []),\n ...(process.tty ? ['terminal'] : []),\n ];\n return {\n id: String(process.pid),\n name: process.command || `[${process.pid}]`,\n meta: [\n `pid ${process.pid}`,\n process.user,\n typeof process.rss === 'number' ? bytes(process.rss) : null,\n cpuText(process.cpu),\n process.started ? age(input.now - process.started) : null,\n ]\n .filter(Boolean)\n .join(' \u00B7 '),\n status: runaway ?? 'idle',\n ...(badges.length ? { badges } : {}),\n };\n });\n}\n\nconst PROBLEM_KINDS = { task: 'task failed', retry: 'retry', turn: 'turn failed' } as const;\n\nfunction sections(input: MonitorInput, feed: MonitorFeed): MonitorSection[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const nameOf = (id: string | null) => (id ? (agents.get(id)?.name ?? id) : 'session');\n return [\n {\n id: 'tasks',\n label: 'Tasks',\n rows: capped(\n taskTree(feed).map(({ task, depth }) => taskRow(task, depth, nameOf, input.now))\n ),\n },\n { id: 'processes', label: 'Processes', rows: capped(processRows(input, feed)) },\n {\n id: 'problems',\n label: 'Recent problems',\n rows: feed.problems.map((problem) => ({\n id: problem.id,\n name: `${nameOf(problem.agentId)} \u00B7 ${PROBLEM_KINDS[problem.kind]}`,\n meta: problem.message,\n status: problem.kind === 'retry' ? 'warn' : 'error',\n })),\n },\n ];\n}\n\nfunction pageSections(input: MonitorInput): MonitorSection[] {\n return [\n {\n id: 'changes',\n label: 'Pending changes',\n rows: input.changes.map((change) => ({\n id: change.path,\n name: change.path,\n meta: change.status,\n status: 'warn',\n })),\n },\n ...input.extra,\n ];\n}\n\nexport function monitorSnapshot(input: MonitorInput): MonitorSnapshot {\n const budget = input.budget ? [budgetVital(input.budget, input.now)] : [];\n const feed = input.feed;\n if (!feed?.at)\n return {\n vitals: budget,\n alerts: [],\n sections: pageSections(input),\n updatedAt: input.now,\n };\n return {\n vitals: [...budget, ...vitals(input, feed)],\n alerts: alerts(input, feed),\n sections: [...sections(input, feed), ...pageSections(input)],\n updatedAt: feed.at,\n };\n}\n\nexport interface Intervals {\n every(run: () => void, ms: number): unknown;\n stop(handle: unknown): void;\n}\n\nexport const globalIntervals: Intervals = {\n every: (run, ms) => setInterval(run, ms),\n stop: (handle) => clearInterval(handle as ReturnType<typeof setInterval>),\n};\n\nexport interface MonitorAdapterOptions {\n extra?: () => readonly MonitorSection[];\n renewMs?: number;\n sampleMs?: number;\n intervals?: Intervals;\n now?: () => number;\n}\n\ninterface Open {\n lease: Promise<string | null>;\n timer: unknown;\n sampler: unknown;\n}\n\nexport class MonitorAdapter implements MonitorPort {\n readonly #connection: AgentConnection;\n readonly #emitter = new Emitter<MonitorEvents>();\n readonly #extra: () => readonly MonitorSection[];\n readonly #renewMs: number;\n readonly #sampleMs: number;\n readonly #intervals: Intervals;\n readonly #now: () => number;\n #listeners = 0;\n #open: Open | undefined;\n #history: Sample[] = [];\n #hot = new Map<number, number>();\n #hotAt = -1;\n #cpu: number[] = [];\n #processes: number[] = [];\n #memory: number[] = [];\n\n constructor(connection: AgentConnection, options: MonitorAdapterOptions = {}) {\n this.#connection = connection;\n this.#extra = options.extra ?? (() => []);\n this.#renewMs = options.renewMs ?? RENEW_MS;\n this.#sampleMs = options.sampleMs ?? SAMPLE_MS;\n this.#intervals = options.intervals ?? globalIntervals;\n this.#now = options.now ?? Date.now;\n connection.monitor?.subscribe(() => this.#update());\n connection.settings.state.subscribe(() => this.#update());\n connection.changes?.subscribe(() => this.#update());\n }\n\n on<K extends keyof MonitorEvents>(\n type: K,\n listener: (detail: MonitorEvents[K]) => void\n ): () => void {\n const off = this.#emitter.on(type, listener);\n this.#listeners++;\n if (this.#listeners === 1) this.#start();\n let done = false;\n return () => {\n if (done) return;\n done = true;\n off();\n this.#listeners--;\n if (!this.#listeners) this.#stop();\n };\n }\n\n snapshot(): MonitorSnapshot {\n const settings = this.#connection.settings.state.value;\n return monitorSnapshot({\n feed: this.#connection.monitor?.value,\n budget: settings?.budget,\n models: settings?.models ?? [],\n changes: this.#connection.changes?.value?.changes ?? [],\n extra: this.#extra(),\n history: this.#history,\n now: this.#now(),\n hot: this.#hot,\n cpu: this.#cpu,\n processes: this.#processes,\n memory: this.#memory,\n });\n }\n\n resync(): void {\n const open = this.#open;\n const control = this.#connection.control;\n if (open)\n void open.lease\n .then((lease) => (lease ? control.monitorOpen(lease, true, BACKGROUND_CONTEXT) : undefined))\n .catch(() => undefined);\n this.#emitter.emit('snapshot', this.snapshot());\n }\n\n #start(): void {\n const control = this.#connection.control;\n this.#history = [];\n this.#hot = new Map();\n this.#hotAt = -1;\n this.#cpu = [];\n this.#processes = [];\n this.#memory = [];\n void control.changesOpen(BACKGROUND_CONTEXT).catch(() => undefined);\n const lease = control.monitorOpen(null, true, BACKGROUND_CONTEXT).then(\n (opened) => opened.lease || null,\n () => null\n );\n const renew = () =>\n void lease\n .then((held) => (held ? control.monitorOpen(held, false, BACKGROUND_CONTEXT) : undefined))\n .catch(() => undefined);\n this.#open = {\n lease,\n timer: this.#intervals.every(renew, this.#renewMs),\n sampler: this.#intervals.every(() => this.#poll(), this.#sampleMs),\n };\n }\n\n #stop(): void {\n const open = this.#open;\n if (!open) return;\n this.#open = undefined;\n this.#intervals.stop(open.timer);\n this.#intervals.stop(open.sampler);\n const control = this.#connection.control;\n void open.lease\n .then((held) => (held ? control.monitorClose(held, BACKGROUND_CONTEXT) : undefined))\n .catch(() => undefined);\n }\n\n #sample(): void {\n const feed = this.#connection.monitor?.value;\n if (!feed?.open || !feed.usage || this.#history.at(-1)?.at === feed.at) return;\n record(\n this.#history,\n {\n at: feed.at,\n cost: feed.usage.cost,\n tokens: feed.usage.tokens,\n active: feed.agents.filter((agent) => agent.running).length,\n },\n HISTORY\n );\n }\n\n #track(): void {\n const feed = this.#connection.monitor?.value;\n if (!feed?.open || feed.at === this.#hotAt) return;\n this.#hotAt = feed.at;\n this.#hot = hotGroups(feed.processes ?? [], feed.at, this.#hot);\n const share = agentsCpu(feed);\n if (share !== null) record(this.#cpu, share, CPU_HISTORY);\n }\n\n #poll(): void {\n const feed = this.#connection.monitor?.value;\n if (!feed?.open || !feed.processes) return;\n record(this.#processes, feed.processes.length, CPU_HISTORY);\n const memory = memoryTotal(feed.processes);\n if (memory !== null) record(this.#memory, memory, CPU_HISTORY);\n this.#emitter.emit('snapshot', this.snapshot());\n }\n\n #update(): void {\n if (!this.#listeners) return;\n this.#sample();\n this.#track();\n this.#emitter.emit('snapshot', this.snapshot());\n }\n}\n"],
5
- "mappings": "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",
4
+ "sourcesContent": ["import type {\n MonitorAlert,\n MonitorEvents,\n MonitorPort,\n MonitorRow,\n MonitorSection,\n MonitorSnapshot,\n MonitorStatus,\n MonitorVital,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentConnection } from '../client.ts';\nimport { contextRatio } from '../context.ts';\nimport type {\n BudgetState,\n ModelChoice,\n MonitorAgent,\n MonitorFeed,\n MonitorProcess,\n MonitorTask,\n} from '../services.ts';\nimport { Emitter } from './emitter.ts';\n\nexport const RENEW_MS = 10000;\nexport const SAMPLE_MS = 2000;\nexport const ROWS_MAX = 200;\nexport const HISTORY = 24;\nexport const CPU_HISTORY = 30;\nexport const CPU_QUIET = 0.01;\nexport const BUDGET_WARN = 80;\nexport const BUDGET_ERROR = 95;\nexport const RETRY_WARN = 3;\nexport const RETRY_ERROR = 6;\nexport const RETRY_SLOW_MS = 120000;\nexport const FAILED_MS = 600000;\nexport const ABORT_MS = 30000;\nexport const ABORT_ROW_MS = 10000;\nexport const GROUP_MAX = 32;\nexport const TOTAL_MAX = 128;\nexport const ZOMBIE_MS = 60000;\nexport const STALE_MS = 1800000;\nexport const CPU_SHARE = 0.9;\nexport const CPU_SUSTAIN_MS = 120000;\nexport const CONTEXT_WARN = 0.8;\nexport const DEPTH_MAX = 6;\nconst MINUTE = 60000;\nconst HOUR = 3600000;\nconst DAY = 86400000;\n\nexport type AgentMonitorAlert = MonitorAlert & { command?: string; commandLabel?: string };\n\nexport interface Sample {\n at: number;\n cost: number;\n tokens: number;\n active: number;\n}\n\nexport interface MonitorInput {\n feed: MonitorFeed | undefined;\n budget: BudgetState | null | undefined;\n models: readonly ModelChoice[];\n changes: readonly { path: string; status: string }[];\n sprinkles?: readonly { name: string; title: string }[];\n extra: readonly MonitorSection[];\n history: readonly Sample[];\n now: number;\n hot?: ReadonlyMap<number, number>;\n cpu?: readonly number[];\n processes?: readonly number[];\n memory?: readonly number[];\n}\n\nexport function record<T>(list: T[], value: T, max: number): void {\n list.push(value);\n if (list.length > max) list.shift();\n}\n\nfunction trend(series: readonly number[] | undefined): { series?: number[] } {\n return series && series.length > 1 ? { series: [...series] } : {};\n}\n\nconst KINDS: Record<string, string> = {\n 'pi.generation': 'generating',\n 'pi.compaction': 'compacting',\n 'slicc.scoop-wait': 'agent wait',\n 'slicc.scoop-reporter': 'report',\n 'slicc.memory-extract': 'memory extraction',\n};\n\nexport function age(ms: number): string {\n const seconds = Math.max(0, Math.round(ms / 1000));\n if (seconds < 60) return `${seconds}s`;\n if (seconds < 3600) return `${Math.floor(seconds / 60)}m`;\n return `${Math.floor(seconds / 3600)}h`;\n}\n\nexport function money(value: number): string {\n if (value > 0 && value < 0.01) return '<$0.01';\n return `$${value.toFixed(2)}`;\n}\n\nexport function count(value: number): string {\n if (value < 1000) return String(value);\n if (value < 1000000) return `${(value / 1000).toFixed(1)}k`;\n return `${(value / 1000000).toFixed(1)}M`;\n}\n\nexport function bytes(value: number): string {\n if (value < 1024) return `${value} B`;\n const units = ['KiB', 'MiB', 'GiB', 'TiB'];\n let size = value / 1024;\n let unit = 0;\n while (size >= 1024 && unit < units.length - 1) {\n size /= 1024;\n unit++;\n }\n return `${size.toFixed(size < 10 ? 1 : 0)} ${units[unit]}`;\n}\n\nexport function cpuText(share: number | null | undefined): string | null {\n if (typeof share !== 'number' || share < CPU_QUIET) return null;\n return `${Math.round(share * 100)}%\\u00a0CPU`;\n}\n\nexport function agentsCpu(feed: MonitorFeed): number | null {\n const shares = feed.agents\n .map((agent) => agent.cpu)\n .filter((share): share is number => typeof share === 'number');\n return shares.length ? shares.reduce((sum, share) => sum + share, 0) : null;\n}\n\nfunction cpuVital(feed: MonitorFeed, history: readonly number[]): MonitorVital[] {\n const share = agentsCpu(feed);\n if (share === null) return [];\n return [\n {\n id: 'cpu',\n label: 'CPU',\n value: `${Math.round(share * 100)}%`,\n unit: 'of one core',\n ...trend(history.map((value) => Math.round(value * 100))),\n },\n ];\n}\n\nfunction measuredOf(processes: readonly MonitorProcess[]): MonitorProcess[] {\n return processes.filter((row) => typeof row.rss === 'number');\n}\n\nexport function memoryTotal(processes: readonly MonitorProcess[]): number | null {\n const measured = measuredOf(processes);\n return measured.length ? measured.reduce((sum, row) => sum + (row.rss as number), 0) : null;\n}\n\nfunction memoryVital(\n processes: readonly MonitorProcess[],\n history: readonly number[] | undefined\n): MonitorVital[] {\n const total = memoryTotal(processes);\n if (total === null) return [];\n const measured = measuredOf(processes);\n const agents = measured\n .filter((row) => row.agentId)\n .reduce((sum, row) => sum + (row.rss as number), 0);\n return [\n {\n id: 'memory',\n label: 'Process memory',\n value: bytes(total),\n unit: `${bytes(agents)} by agents`,\n ...trend(history),\n },\n ];\n}\n\nexport function taskLabel(task: MonitorTask): string {\n if (task.kind === 'pi.tool') return task.detail ? `tool ${task.detail}` : 'tool';\n if (task.kind === 'slicc.scoop-anchor') return task.detail ? `scoop ${task.detail}` : 'scoop';\n return KINDS[task.kind] ?? task.kind;\n}\n\nfunction coneOf(agents: ReadonlyMap<string, MonitorAgent>, id: string | null): string | null {\n const visited = new Set<string>();\n let current = id === null ? undefined : agents.get(id);\n while (current?.parentId && !visited.has(current.id)) {\n visited.add(current.id);\n const parent = agents.get(current.parentId);\n if (!parent) break;\n current = parent;\n }\n return current ? current.id : null;\n}\n\nfunction ordered(feed: MonitorFeed): MonitorAgent[] {\n const byId = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const out: MonitorAgent[] = [];\n for (const cone of feed.agents.filter((agent) => agent.kind === 'cone')) {\n out.push(cone);\n for (const agent of feed.agents)\n if (agent.kind === 'scoop' && coneOf(byId, agent.id) === cone.id) out.push(agent);\n }\n for (const agent of feed.agents) if (!out.includes(agent)) out.push(agent);\n return out;\n}\n\nexport function taskTree(feed: MonitorFeed): { task: MonitorTask; depth: number }[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const order = ordered(feed).map((agent) => agent.id);\n const rank = (task: MonitorTask) => {\n const at = task.agentId === null ? -1 : order.indexOf(task.agentId);\n return at < 0 ? order.length : at;\n };\n const groupOf = (task: MonitorTask) => coneOf(agents, task.agentId) ?? '';\n const byId = new Map(feed.tasks.map((task) => [task.id, task]));\n const children = new Map<string, MonitorTask[]>();\n const roots: MonitorTask[] = [];\n for (const task of feed.tasks) {\n const owner = task.owner === null ? undefined : byId.get(task.owner);\n if (owner && groupOf(owner) === groupOf(task)) {\n const list = children.get(owner.id) ?? [];\n list.push(task);\n children.set(owner.id, list);\n } else roots.push(task);\n }\n const sort = (list: MonitorTask[]) =>\n list.sort((a, b) => rank(a) - rank(b) || Number(a.id) - Number(b.id));\n const out: { task: MonitorTask; depth: number }[] = [];\n const visit = (task: MonitorTask, depth: number) => {\n out.push({ task, depth });\n for (const child of sort(children.get(task.id) ?? [])) visit(child, depth + 1);\n };\n for (const root of sort(roots)) visit(root, 0);\n return out;\n}\n\nfunction capped(rows: MonitorRow[]): MonitorRow[] {\n if (rows.length <= ROWS_MAX) return rows;\n const shown = rows.slice(0, ROWS_MAX - 1);\n return [\n ...shown,\n { id: 'more', name: `+${rows.length - shown.length} more`, meta: '', status: 'idle' },\n ];\n}\n\nfunction agentContext(agent: MonitorAgent, models: readonly ModelChoice[]): number | null {\n return contextRatio(agent.context, agent.model, models);\n}\n\nfunction rate(history: readonly Sample[], pick: (sample: Sample) => number): number | null {\n const first = history[0];\n const last = history.at(-1);\n if (!first || !last || last.at - first.at < MINUTE) return null;\n return ((pick(last) - pick(first)) / (last.at - first.at)) * HOUR;\n}\n\nconst RELATIVE = new Intl.RelativeTimeFormat('en', { numeric: 'auto' });\n\nfunction resetsIn(at: number, now: number): string {\n const ms = at - now;\n if (ms <= 0) return 'resets soon';\n if (ms >= DAY)\n return `resets ${RELATIVE.format(Math.floor(at / DAY) - Math.floor(now / DAY), 'day')}`;\n if (ms >= HOUR) return `resets ${RELATIVE.format(Math.floor(ms / HOUR), 'hour')}`;\n return `resets ${RELATIVE.format(Math.ceil(ms / MINUTE), 'minute')}`;\n}\n\nfunction budgetVital(budget: BudgetState, now: number): MonitorVital {\n const resets = new Date(budget.resets);\n return {\n id: 'budget',\n label: `Budget (${budget.window})`,\n value: `${budget.percent}%`,\n ...(Number.isNaN(resets.getTime())\n ? {}\n : {\n unit: resetsIn(resets.getTime(), now),\n hint: `resets ${resets.toISOString().slice(0, 16).replace('T', ' ')} UTC`,\n }),\n ratio: Math.min(1, Math.max(0, budget.percent / 100)),\n };\n}\n\nfunction vitals(input: MonitorInput, feed: MonitorFeed): MonitorVital[] {\n const out: MonitorVital[] = [];\n if (feed.usage) {\n const free = feed.usage.free;\n const pick = (sample: Sample) => (free ? sample.tokens : sample.cost);\n const perHour = rate(input.history, pick);\n const series = input.history.map(pick);\n out.push({\n id: 'spend',\n label: free ? 'Tokens' : 'Spend',\n value: free ? count(feed.usage.tokens) : money(feed.usage.cost),\n unit: free ? 'tokens' : `${count(feed.usage.tokens)} tokens`,\n ...(perHour === null ? {} : { delta: `${free ? count(perHour) : money(perHour)}/h` }),\n ...trend(series),\n });\n }\n const active = feed.agents.filter((agent) => agent.running).length;\n out.push({\n id: 'agents',\n label: 'Active agents',\n value: String(active),\n unit: `of ${feed.agents.length}`,\n ...trend(input.history.map((sample) => sample.active)),\n });\n const tools = feed.tasks.filter(\n (task) => task.kind === 'pi.tool' && task.status === 'running'\n ).length;\n out.push({\n id: 'tasks',\n label: 'Running',\n value: String(tools),\n unit: `${tools === 1 ? 'tool' : 'tools'} \u00B7 ${feed.tasks.length} ${feed.tasks.length === 1 ? 'task' : 'tasks'}`,\n });\n out.push(\n feed.processes\n ? {\n id: 'processes',\n label: 'Processes',\n value: String(feed.processes.length),\n unit: `${feed.processes.filter((row) => row.agentId).length} by agents`,\n ...trend(input.processes),\n }\n : feed.kernel === 'checking'\n ? { id: 'processes', label: 'Processes', value: '\u2026', unit: 'checking' }\n : { id: 'processes', label: 'Processes', value: '\u2014', unit: 'kernel not reachable' }\n );\n out.push(...memoryVital(feed.processes ?? [], input.memory));\n out.push(...cpuVital(feed, input.cpu ?? []));\n const ratios = feed.agents\n .map((agent) => agentContext(agent, input.models))\n .filter((ratio): ratio is number => ratio !== null);\n if (ratios.length) {\n const fullest = Math.max(...ratios);\n out.push({\n id: 'context',\n label: 'Fullest context',\n value: `${Math.round(fullest * 100)}%`,\n ratio: fullest,\n });\n }\n return out;\n}\n\nfunction stale(process: MonitorProcess, agents: ReadonlyMap<string, MonitorAgent>, now: number) {\n if (!process.agentId || process.state === 'Z' || !process.started) return false;\n if (typeof process.utime === 'number') return false;\n if (agents.get(process.agentId)?.tool === 'bash') return false;\n return now - process.started > STALE_MS;\n}\n\nfunction zombied(process: MonitorProcess, now: number): boolean {\n return process.zombie !== null && now - process.zombie > ZOMBIE_MS;\n}\n\nfunction groups(processes: readonly MonitorProcess[]): Map<number, MonitorProcess[]> {\n const out = new Map<number, MonitorProcess[]>();\n for (const process of processes) {\n if (!process.agentId) continue;\n const list = out.get(process.pgid) ?? [];\n list.push(process);\n out.set(process.pgid, list);\n }\n return out;\n}\n\ntype Names = (id: string | null) => string;\n\nexport function groupCpu(\n processes: readonly MonitorProcess[]\n): Map<number, { agentId: string; share: number }> {\n const out = new Map<number, { agentId: string; share: number }>();\n for (const [pgid, members] of groups(processes)) {\n const measured = members.filter((row) => typeof row.cpu === 'number');\n if (!measured.length) continue;\n const share = measured.reduce((sum, row) => sum + (row.cpu as number), 0);\n out.set(pgid, { agentId: (members[0] as MonitorProcess).agentId as string, share });\n }\n return out;\n}\n\nexport function hotGroups(\n processes: readonly MonitorProcess[],\n at: number,\n previous: ReadonlyMap<number, number>\n): Map<number, number> {\n const out = new Map<number, number>();\n for (const [pgid, { share }] of groupCpu(processes))\n if (share >= CPU_SHARE) out.set(pgid, previous.get(pgid) ?? at);\n return out;\n}\n\nfunction busy(input: MonitorInput, processes: readonly MonitorProcess[]) {\n const shares = groupCpu(processes);\n const out: { pgid: number; agentId: string; share: number; held: number }[] = [];\n for (const [pgid, since] of input.hot ?? []) {\n const group = shares.get(pgid);\n const held = input.now - since;\n if (group && group.share >= CPU_SHARE && held >= CPU_SUSTAIN_MS)\n out.push({ pgid, ...group, held });\n }\n return out;\n}\n\nfunction cpuAlerts(input: MonitorInput, processes: readonly MonitorProcess[], nameOf: Names) {\n return busy(input, processes).map(\n (group): AgentMonitorAlert => ({\n id: `runaway-cpu-${group.pgid}`,\n title: `${nameOf(group.agentId)} is using a lot of CPU`,\n detail: `${Math.round(group.share * 100)}% of one core for ${Math.floor(group.held / MINUTE)} minutes.`,\n command: `kill -- -${group.pgid}`,\n commandLabel: 'To stop it, run',\n severity: cpuSeverity(group),\n })\n );\n}\n\nfunction cpuSeverity(group: { share: number; held: number }): 'warn' | 'error' {\n return group.share >= CPU_SHARE * 2 || group.held >= CPU_SUSTAIN_MS * 2 ? 'error' : 'warn';\n}\n\nfunction crowdSeverity(members: readonly MonitorProcess[]): 'warn' | 'error' {\n return members.length > GROUP_MAX * 2 ? 'error' : 'warn';\n}\n\nfunction staleSeverity(process: MonitorProcess, now: number): 'warn' | 'error' {\n return now - process.started > STALE_MS * 2 ? 'error' : 'warn';\n}\n\nfunction worse(\n a: 'warn' | 'error' | undefined,\n b: 'warn' | 'error' | undefined\n): 'warn' | 'error' | undefined {\n return a === 'error' || b === 'error' ? 'error' : (a ?? b);\n}\n\nfunction resetLine(budget: BudgetState): string {\n const resets = new Date(budget.resets);\n return Number.isNaN(resets.getTime())\n ? `The ${budget.window} budget is nearly used up.`\n : `Resets ${resets.toISOString().slice(0, 16).replace('T', ' ')} UTC.`;\n}\n\nfunction budgetAlerts(budget: BudgetState | null | undefined): AgentMonitorAlert[] {\n if (!budget || budget.percent < BUDGET_WARN) return [];\n return [\n {\n id: 'budget',\n title: `Budget ${budget.percent}% used`,\n detail: resetLine(budget),\n severity: budget.percent >= BUDGET_ERROR ? 'error' : 'warn',\n },\n ];\n}\n\nfunction agentAlerts(input: MonitorInput, feed: MonitorFeed): AgentMonitorAlert[] {\n const out: AgentMonitorAlert[] = [];\n for (const agent of feed.agents) {\n const retry = agent.retry;\n if (retry && (retry.attempt >= RETRY_WARN || input.now - retry.since > RETRY_SLOW_MS))\n out.push({\n id: `retry-${agent.id}`,\n title: `${agent.name} is retrying (attempt ${retry.attempt})`,\n detail: retry.error,\n severity: retry.attempt >= RETRY_ERROR ? 'error' : 'warn',\n });\n if (agent.failed && !agent.running)\n out.push({\n id: `turn-${agent.id}`,\n title: `${agent.name}'s last turn failed`,\n detail: agent.failed,\n severity: 'error',\n });\n }\n return out;\n}\n\nfunction taskAlerts(input: MonitorInput, feed: MonitorFeed, nameOf: Names): AgentMonitorAlert[] {\n const out: AgentMonitorAlert[] = [];\n for (const problem of feed.problems)\n if (problem.kind === 'task' && input.now - problem.at < FAILED_MS)\n out.push({\n id: `failed-${problem.id}`,\n title: `A task of ${nameOf(problem.agentId)} failed`,\n detail: problem.message,\n severity: 'error',\n });\n for (const task of feed.tasks)\n if (task.aborting !== null && input.now - task.aborting > ABORT_MS)\n out.push({\n id: `abort-${task.id}`,\n title: `Stop is still waiting for ${taskLabel(task)}`,\n detail: `${nameOf(task.agentId)} asked it to stop ${age(input.now - task.aborting)} ago.`,\n severity: 'warn',\n });\n return out;\n}\n\nfunction crowdAlerts(processes: readonly MonitorProcess[], nameOf: Names): AgentMonitorAlert[] {\n const out: AgentMonitorAlert[] = [];\n for (const [pgid, members] of groups(processes))\n if (members.length > GROUP_MAX)\n out.push({\n id: `runaway-${pgid}`,\n title: `${nameOf((members[0] as MonitorProcess).agentId)} has ${members.length} processes`,\n detail: 'Something in it may be starting processes in a loop.',\n command: `kill -- -${pgid}`,\n commandLabel: 'To stop them, run',\n severity: crowdSeverity(members),\n });\n if (processes.length > TOTAL_MAX)\n out.push({\n id: 'runaway-total',\n title: `The kernel has ${processes.length} processes`,\n detail: 'Something may be starting processes in a loop.',\n severity: processes.length > TOTAL_MAX * 2 ? 'error' : 'warn',\n });\n return out;\n}\n\nfunction processAlerts(input: MonitorInput, feed: MonitorFeed, nameOf: Names): AgentMonitorAlert[] {\n const processes = feed.processes ?? [];\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const out = [...crowdAlerts(processes, nameOf), ...cpuAlerts(input, processes, nameOf)];\n for (const process of processes) {\n if (zombied(process, input.now))\n out.push({\n id: `zombie-${process.pid}`,\n title: `Process ${process.pid} is a zombie`,\n detail: `Its parent ${process.ppid} hasn't reaped it.`,\n ...(process.ppid > 1\n ? { command: `kill ${process.ppid}`, commandLabel: 'To clear it, stop the parent' }\n : {}),\n severity: 'warn',\n });\n if (stale(process, agents, input.now))\n out.push({\n id: `stale-${process.pid}`,\n title: `${process.command || `Process ${process.pid}`} has run for ${age(input.now - process.started)}`,\n detail: `${nameOf(process.agentId)} started it in the background.`,\n command: `kill ${process.pid}`,\n commandLabel: 'To stop it, run',\n severity: staleSeverity(process, input.now),\n });\n }\n return out;\n}\n\nfunction contextAlerts(input: MonitorInput, feed: MonitorFeed): AgentMonitorAlert[] {\n const out: AgentMonitorAlert[] = [];\n for (const agent of feed.agents) {\n const ratio = agentContext(agent, input.models);\n if (ratio !== null && ratio >= CONTEXT_WARN)\n out.push({\n id: `context-${agent.id}`,\n title: `${agent.name} is ${Math.round(ratio * 100)}% full`,\n detail: 'Compact it soon to keep replies fast.',\n severity: 'warn',\n });\n }\n if (feed.paused)\n out.push({\n id: 'scheduler',\n title: \"The agent isn't scheduling work\",\n detail: 'Its scheduler is paused.',\n severity: 'warn',\n });\n return out;\n}\n\nfunction alerts(input: MonitorInput, feed: MonitorFeed): AgentMonitorAlert[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const nameOf: Names = (id) => (id ? (agents.get(id)?.name ?? id) : 'the session');\n return [\n ...budgetAlerts(input.budget),\n ...agentAlerts(input, feed),\n ...taskAlerts(input, feed, nameOf),\n ...processAlerts(input, feed, nameOf),\n ...contextAlerts(input, feed),\n ];\n}\n\nfunction taskRow(\n task: MonitorTask,\n depth: number,\n nameOf: (id: string | null) => string,\n now: number\n): MonitorRow {\n const aborting = task.aborting !== null && now - task.aborting > ABORT_ROW_MS;\n const status: MonitorStatus = aborting\n ? 'warn'\n : task.status === 'running' || task.status === 'completing'\n ? 'active'\n : 'idle';\n const badges = [\n ...(task.background ? ['background'] : []),\n ...(task.aborting !== null ? ['aborting'] : []),\n ...(task.waits ? [`waits on ${task.waits}`] : []),\n ];\n return {\n id: task.id,\n name: taskLabel(task),\n depth: Math.min(depth, DEPTH_MAX),\n meta: [nameOf(task.agentId), task.phase, age(now - task.since)].filter(Boolean).join(' \u00B7 '),\n status,\n ...(badges.length ? { badges } : {}),\n };\n}\n\nfunction drivers(members: readonly MonitorProcess[]): MonitorProcess[] {\n const hot = members.filter((row) => (row.cpu ?? 0) >= CPU_SHARE);\n if (hot.length) return hot;\n const top = members.reduce((best, row) => ((row.cpu ?? 0) > (best.cpu ?? 0) ? row : best));\n return [top];\n}\n\nfunction processRows(input: MonitorInput, feed: MonitorFeed): MonitorRow[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const members = groups(feed.processes ?? []);\n const flagged = new Map<number, 'warn' | 'error'>();\n for (const group of busy(input, feed.processes ?? []))\n for (const row of drivers(members.get(group.pgid) as MonitorProcess[]))\n flagged.set(row.pid, cpuSeverity(group));\n return (feed.processes ?? []).map((process) => {\n const runaway = worse(\n worse(\n flagged.get(process.pid),\n stale(process, agents, input.now) ? staleSeverity(process, input.now) : undefined\n ),\n zombied(process, input.now) ? 'warn' : undefined\n );\n const badges = [\n ...(process.agentId ? [agents.get(process.agentId)?.name ?? process.agentId] : []),\n ...(process.tty ? ['terminal'] : []),\n ];\n return {\n id: String(process.pid),\n name: process.command || `[${process.pid}]`,\n meta: [\n `pid ${process.pid}`,\n process.user,\n typeof process.rss === 'number' ? bytes(process.rss) : null,\n cpuText(process.cpu),\n process.started ? age(input.now - process.started) : null,\n ]\n .filter(Boolean)\n .join(' \u00B7 '),\n status: runaway ?? 'idle',\n ...(badges.length ? { badges } : {}),\n };\n });\n}\n\nconst PROBLEM_KINDS = { task: 'task failed', retry: 'retry', turn: 'turn failed' } as const;\n\nfunction sections(input: MonitorInput, feed: MonitorFeed): MonitorSection[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const nameOf = (id: string | null) => (id ? (agents.get(id)?.name ?? id) : 'session');\n return [\n {\n id: 'tasks',\n label: 'Tasks',\n rows: capped(\n taskTree(feed).map(({ task, depth }) => taskRow(task, depth, nameOf, input.now))\n ),\n },\n { id: 'processes', label: 'Processes', rows: capped(processRows(input, feed)) },\n {\n id: 'problems',\n label: 'Recent problems',\n rows: feed.problems.map((problem) => ({\n id: problem.id,\n name: `${nameOf(problem.agentId)} \u00B7 ${PROBLEM_KINDS[problem.kind]}`,\n meta: problem.message,\n status: problem.kind === 'retry' ? 'warn' : 'error',\n })),\n },\n ];\n}\n\nfunction pageSections(input: MonitorInput): MonitorSection[] {\n return [\n {\n id: 'changes',\n label: 'Pending changes',\n rows: input.changes.map((change) => ({\n id: change.path,\n name: change.path,\n meta: change.status,\n status: 'warn',\n })),\n },\n ...input.extra,\n ];\n}\n\nexport function monitorSnapshot(input: MonitorInput): MonitorSnapshot {\n const budget = input.budget ? [budgetVital(input.budget, input.now)] : [];\n const feed = input.feed;\n if (!feed?.at)\n return {\n vitals: budget,\n alerts: [],\n sections: pageSections(input),\n updatedAt: input.now,\n };\n return {\n vitals: [...budget, ...vitals(input, feed)],\n alerts: alerts(input, feed),\n sections: [...sections(input, feed), ...pageSections(input)],\n updatedAt: feed.at,\n };\n}\n\nexport interface Intervals {\n every(run: () => void, ms: number): unknown;\n stop(handle: unknown): void;\n}\n\nexport const globalIntervals: Intervals = {\n every: (run, ms) => setInterval(run, ms),\n stop: (handle) => clearInterval(handle as ReturnType<typeof setInterval>),\n};\n\nexport interface MonitorAdapterOptions {\n extra?: () => readonly MonitorSection[];\n renewMs?: number;\n sampleMs?: number;\n intervals?: Intervals;\n now?: () => number;\n}\n\ninterface Open {\n lease: Promise<string | null>;\n timer: unknown;\n sampler: unknown;\n}\n\nexport class MonitorAdapter implements MonitorPort {\n readonly #connection: AgentConnection;\n readonly #emitter = new Emitter<MonitorEvents>();\n readonly #extra: () => readonly MonitorSection[];\n readonly #renewMs: number;\n readonly #sampleMs: number;\n readonly #intervals: Intervals;\n readonly #now: () => number;\n #listeners = 0;\n #open: Open | undefined;\n #history: Sample[] = [];\n #hot = new Map<number, number>();\n #hotAt = -1;\n #cpu: number[] = [];\n #processes: number[] = [];\n #memory: number[] = [];\n\n constructor(connection: AgentConnection, options: MonitorAdapterOptions = {}) {\n this.#connection = connection;\n this.#extra = options.extra ?? (() => []);\n this.#renewMs = options.renewMs ?? RENEW_MS;\n this.#sampleMs = options.sampleMs ?? SAMPLE_MS;\n this.#intervals = options.intervals ?? globalIntervals;\n this.#now = options.now ?? Date.now;\n connection.monitor?.subscribe(() => this.#update());\n connection.settings.state.subscribe(() => this.#update());\n connection.changes?.subscribe(() => this.#update());\n }\n\n on<K extends keyof MonitorEvents>(\n type: K,\n listener: (detail: MonitorEvents[K]) => void\n ): () => void {\n const off = this.#emitter.on(type, listener);\n this.#listeners++;\n if (this.#listeners === 1) this.#start();\n let done = false;\n return () => {\n if (done) return;\n done = true;\n off();\n this.#listeners--;\n if (!this.#listeners) this.#stop();\n };\n }\n\n snapshot(): MonitorSnapshot {\n const settings = this.#connection.settings.state.value;\n return monitorSnapshot({\n feed: this.#connection.monitor?.value,\n budget: settings?.budget,\n models: settings?.models ?? [],\n changes: this.#connection.changes?.value?.changes ?? [],\n extra: this.#extra(),\n history: this.#history,\n now: this.#now(),\n hot: this.#hot,\n cpu: this.#cpu,\n processes: this.#processes,\n memory: this.#memory,\n });\n }\n\n resync(): void {\n const open = this.#open;\n const control = this.#connection.control;\n if (open)\n void open.lease\n .then((lease) => (lease ? control.monitorOpen(lease, true, BACKGROUND_CONTEXT) : undefined))\n .catch(() => undefined);\n this.#emitter.emit('snapshot', this.snapshot());\n }\n\n #start(): void {\n const control = this.#connection.control;\n this.#history = [];\n this.#hot = new Map();\n this.#hotAt = -1;\n this.#cpu = [];\n this.#processes = [];\n this.#memory = [];\n void control.changesOpen(BACKGROUND_CONTEXT).catch(() => undefined);\n const lease = control.monitorOpen(null, true, BACKGROUND_CONTEXT).then(\n (opened) => opened.lease || null,\n () => null\n );\n const renew = () =>\n void lease\n .then((held) => (held ? control.monitorOpen(held, false, BACKGROUND_CONTEXT) : undefined))\n .catch(() => undefined);\n this.#open = {\n lease,\n timer: this.#intervals.every(renew, this.#renewMs),\n sampler: this.#intervals.every(() => this.#poll(), this.#sampleMs),\n };\n }\n\n #stop(): void {\n const open = this.#open;\n if (!open) return;\n this.#open = undefined;\n this.#intervals.stop(open.timer);\n this.#intervals.stop(open.sampler);\n const control = this.#connection.control;\n void open.lease\n .then((held) => (held ? control.monitorClose(held, BACKGROUND_CONTEXT) : undefined))\n .catch(() => undefined);\n }\n\n #sample(): void {\n const feed = this.#connection.monitor?.value;\n if (!feed?.open || !feed.usage || this.#history.at(-1)?.at === feed.at) return;\n record(\n this.#history,\n {\n at: feed.at,\n cost: feed.usage.cost,\n tokens: feed.usage.tokens,\n active: feed.agents.filter((agent) => agent.running).length,\n },\n HISTORY\n );\n }\n\n #track(): void {\n const feed = this.#connection.monitor?.value;\n if (!feed?.open || feed.at === this.#hotAt) return;\n this.#hotAt = feed.at;\n this.#hot = hotGroups(feed.processes ?? [], feed.at, this.#hot);\n const share = agentsCpu(feed);\n if (share !== null) record(this.#cpu, share, CPU_HISTORY);\n }\n\n #poll(): void {\n const feed = this.#connection.monitor?.value;\n if (!feed?.open || !feed.processes) return;\n record(this.#processes, feed.processes.length, CPU_HISTORY);\n const memory = memoryTotal(feed.processes);\n if (memory !== null) record(this.#memory, memory, CPU_HISTORY);\n this.#emitter.emit('snapshot', this.snapshot());\n }\n\n #update(): void {\n if (!this.#listeners) return;\n this.#sample();\n this.#track();\n this.#emitter.emit('snapshot', this.snapshot());\n }\n}\n"],
5
+ "mappings": "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",
6
6
  "names": []
7
7
  }
@@ -31,6 +31,7 @@ export interface GelatiereAttach {
31
31
  profile?: string;
32
32
  shared?: string;
33
33
  as?: (caller: string | null, context: Context) => Promise<Caller | undefined>;
34
+ cronUser?: (folder: string) => Promise<string>;
34
35
  }
35
36
  export interface Caller {
36
37
  env: ExecutionEnv;
@@ -42,7 +43,7 @@ export interface GelatiereRuntime {
42
43
  readonly seeded: Promise<Seeded>;
43
44
  }
44
45
  export declare const USAGE = "usage:\n gelatiere init start the gelatiere scoop and its nightly crontab line\n gelatiere run ask the gelatiere for a pass now\n gelatiere suggest <file> fold a JSON array of suggestions into the store\n gelatiere deliver lick each cone with the suggestions that are new for it\n gelatiere catalog [--refresh] [--all] [--json]\n rank the www.sliccy.com skill and use-case catalog for this user\n gelatiere install <id> install a suggested skill with upskill into ~/.pi/agent/skills\n gelatiere list [--all] [--json]\n gelatiere dismiss <id> mark a suggestion as not wanted\n gelatiere status\n\nThe store is /home/.gelatiere/suggestions.json; the suggestions sprinkle shows it.\n";
45
- export declare function scheduleOf(entry: string): string | undefined;
46
+ export declare const PASS = "Nightly pass: read ~/.pi/agent/GELATIERE.md and follow it.";
46
47
  export declare const SHIPPED: string[];
47
48
  export type Seeded = 'written' | 'updated' | 'current' | 'kept' | 'none';
48
49
  export declare const INSTALLER = "https://raw.githubusercontent.com/ai-ecoverse/gh-upskill/main/install.sh";
@@ -2,6 +2,7 @@ import type { Context } from '@earendil-works/chord';
2
2
  import type { Agents, AgentsState } from '../agents.ts';
3
3
  import type { GelatiereAttach } from '../gelatiere/index.ts';
4
4
  import { type Layout } from '../layout.ts';
5
+ import type { LickTarget } from '../licks/lick.ts';
5
6
  import type { LickDir } from '../licks/sources.ts';
6
7
  import type { Spools } from '../scoops/index.ts';
7
8
  import type { SkillPeople } from '../skills/index.ts';
@@ -21,6 +22,7 @@ export interface AgentUsers {
21
22
  reconcile?(context: Context): Promise<void>;
22
23
  }[]): void;
23
24
  lickDirs(): Promise<LickDir[]>;
25
+ cronUser(target: LickTarget, place: LickDir): string | undefined;
24
26
  sprinklePlaces(): SprinklePlace[];
25
27
  sprinkles(): Partial<SprinklesAttach>;
26
28
  envOfAgent(agentId: string): Promise<SliccKernelEnv | undefined>;
@@ -1,9 +1,20 @@
1
1
  import type { Context } from '@earendil-works/chord';
2
- import type { Conversation, EntryRecord, Harness } from '@earendil-works/pi-durable';
2
+ import { type Conversation, type EntryRecord, type Harness } from '@earendil-works/pi-durable';
3
3
  import type { Deliver } from './fswatch.ts';
4
+ type HostState = {
5
+ cron: Record<string, {
6
+ task: number;
7
+ }>;
8
+ agent: string | null;
9
+ boot: string | null;
10
+ mark: number;
11
+ upgrades: number;
12
+ };
13
+ export declare const LicksHostDoc: import("@earendil-works/pi-durable").SessionDocToken<HostState>;
4
14
  export interface BootFacts {
5
15
  version: string;
6
16
  boot: string | null;
7
17
  }
8
18
  export declare function bashCommands(entries: readonly EntryRecord[], after: number): string[];
9
19
  export declare function bootLicks(harness: Harness, cone: Conversation, deliver: Deliver, facts: BootFacts, context: Context): Promise<void>;
20
+ export {};
@@ -1,10 +1,4 @@
1
1
  import type { LickTarget } from './lick.ts';
2
- export interface CronEntry {
3
- name: string;
4
- schedule: string;
5
- target: LickTarget;
6
- message: string;
7
- }
8
2
  export interface WatchEntry {
9
3
  name: string;
10
4
  path: string;
@@ -31,7 +25,6 @@ export interface Parsed<T> {
31
25
  }
32
26
  export declare function isName(value: string): boolean;
33
27
  export declare function isTarget(value: string): value is LickTarget;
34
- export declare function parseCrontab(file: string, text: string): Parsed<CronEntry>;
35
28
  export declare function nameOf(file: string): string;
36
29
  export declare function parseWatch(file: string, source: string, home: string): WatchEntry;
37
30
  export declare function parseWebhook(file: string, source: string): WebhookEntry;
@@ -0,0 +1,37 @@
1
+ import type { Context } from '@earendil-works/chord';
2
+ import type { ExecutionEnv } from '@earendil-works/pi-durable/env';
3
+ import type { LickTarget } from './lick.ts';
4
+ import type { LickEvent } from './licks.ts';
5
+ export interface CronJob {
6
+ name: string;
7
+ schedule: string;
8
+ command: string;
9
+ line?: number;
10
+ }
11
+ export interface CronProblem {
12
+ line?: number;
13
+ error: string;
14
+ }
15
+ export interface LegacyJob {
16
+ name: string;
17
+ schedule: string;
18
+ target: LickTarget;
19
+ message: string;
20
+ line: number;
21
+ }
22
+ export declare function legacyJobs(text: string): {
23
+ jobs: LegacyJob[];
24
+ problems: CronProblem[];
25
+ };
26
+ export declare function sendCommand(target: LickTarget, message: string): string;
27
+ export declare function readTable(env: ExecutionEnv, user: string, context: Context): Promise<string | CronProblem>;
28
+ export declare function withoutJobs(table: string, names: ReadonlySet<string>): string[];
29
+ export declare function scheduleOf(table: string, name: string): string | undefined;
30
+ export declare function installJobs(env: ExecutionEnv, user: string, jobs: readonly CronJob[], context: Context): Promise<CronProblem[]>;
31
+ export interface CronRun {
32
+ job: string;
33
+ due: string;
34
+ missed: number;
35
+ }
36
+ export declare function cronText(run: CronRun, at: number): string;
37
+ export declare function cronLick(run: CronRun, target: LickTarget, message: string): LickEvent;
@@ -1,22 +1,6 @@
1
1
  import type { Context } from '@earendil-works/chord';
2
2
  import { type Conversation, type ConversationId } from '@earendil-works/pi-durable';
3
- import { type Missed } from './cron.ts';
4
- import type { LickTarget } from './lick.ts';
5
3
  import type { Licks } from './licks.ts';
6
4
  export declare const LICKS_SECTION: string;
7
5
  export type ConversationLookup = (id: ConversationId, context: Context) => Promise<Conversation>;
8
- export interface CronInput {
9
- name: string;
10
- schedule: string;
11
- target: LickTarget;
12
- message: string;
13
- from: number;
14
- }
15
- type CronState = {
16
- phase: 'wait';
17
- at: number | null;
18
- };
19
- export declare function cronText(schedule: string, at: number, missed: Missed): string;
20
- export declare function cronTask(licks: Licks): import("@earendil-works/pi-durable").Task<CronInput, CronState, null, object>;
21
- export declare function licksExtension(licks: Licks, conversation: ConversationLookup, cron?: ReturnType<typeof cronTask>): import("@earendil-works/pi-durable").Extension<import("@earendil-works/pi-durable").ToolRegistration>;
22
- export {};
6
+ export declare function licksExtension(licks: Licks, conversation: ConversationLookup): import("@earendil-works/pi-durable").Extension<import("@earendil-works/pi-durable").ToolRegistration>;
@@ -18,10 +18,10 @@ export interface LicksSetup {
18
18
  attach(agent: LicksAgent, options: {
19
19
  env: ExecutionEnv;
20
20
  home: string;
21
- now?: () => number;
22
21
  flushEvery?: number;
23
22
  activity?: Activity;
24
23
  dirs?: () => Promise<readonly LickDir[]>;
24
+ cronUser?: (target: LickTarget, place: LickDir) => string | undefined;
25
25
  }): LickSources;
26
26
  }
27
27
  export declare function setupLicks(registry: Registry): LicksSetup;
@@ -4,7 +4,6 @@ import type { ExecutionEnv } from '@earendil-works/pi-durable/env';
4
4
  import type { Activity } from '../kernel/activity.ts';
5
5
  import { type BootFacts } from './boot.ts';
6
6
  import { type ConfigError, type WebhookEntry } from './config.ts';
7
- import type { cronTask } from './extension.ts';
8
7
  import type { LickTarget } from './lick.ts';
9
8
  import type { LickEvent, Licks } from './licks.ts';
10
9
  export declare const SLICC_DIR = ".slicc";
@@ -15,11 +14,10 @@ export interface LickSourcesOptions {
15
14
  env: ExecutionEnv;
16
15
  home: string;
17
16
  licks: Licks;
18
- cron: ReturnType<typeof cronTask>;
19
- now?: () => number;
20
17
  flushEvery?: number;
21
18
  activity?: Activity;
22
19
  dirs?: () => readonly LickDir[] | Promise<readonly LickDir[]>;
20
+ cronUser?: (target: LickTarget, place: LickDir) => string | undefined;
23
21
  }
24
22
  export interface LickDir {
25
23
  dir: string;
@@ -3,6 +3,7 @@ import type { Harness } from '@earendil-works/pi-durable';
3
3
  import type { ExecutionEnv } from '@earendil-works/pi-durable/env';
4
4
  import type { Agents, AgentsState } from '../agents.ts';
5
5
  import { type Layout } from '../layout.ts';
6
+ import type { Licks } from '../licks/licks.ts';
6
7
  import { type Roles } from '../roles/roles.ts';
7
8
  import type { Request, Runner } from './requests.ts';
8
9
  import { type Answer, type Scoops } from './service.ts';
@@ -26,6 +27,7 @@ export interface CliOptions {
26
27
  models?: (argv: readonly string[], caller: string | null, context: Context) => Promise<Answer>;
27
28
  layout?: Layout;
28
29
  panel?: (argv: readonly string[], caller: PanelCaller, context: Context) => Promise<Answer>;
30
+ licks?: Pick<Licks, 'deliver'>;
29
31
  }
30
32
  export interface PanelCaller {
31
33
  agentId: string | null;
@@ -1,8 +1,10 @@
1
1
  import type { Context } from '@earendil-works/chord';
2
2
  import type { ExecutionEnv } from '@earendil-works/pi-durable/env';
3
+ import type { CronRun } from '../licks/crontab.ts';
3
4
  import type { Answer } from './service.ts';
4
5
  export declare const CONTROL_DIR = "/var/lib/slicc/agent/requests";
5
- export declare const PROTOCOL = "slicc-agent/1";
6
+ export declare const PROTOCOL = "slicc-agent/2";
7
+ export declare const PROTOCOL_MARK = "slicc-agent/";
6
8
  export declare const STALE_MS: number;
7
9
  export interface Request {
8
10
  id: string;
@@ -14,7 +16,9 @@ export interface Request {
14
16
  argv: string[];
15
17
  stdin: string;
16
18
  user?: string;
19
+ cron?: CronRun;
17
20
  }
21
+ export declare function cronOf(field: string): CronRun | undefined;
18
22
  export declare function parseRequest(id: string, bytes: Uint8Array): Request | undefined;
19
23
  export interface Runner {
20
24
  run(request: Request, context: Context): Promise<Answer>;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-agent",
3
- "version": "5.8.3",
3
+ "version": "5.9.0",
4
4
  "description": "SLICC's agent core on pi durable: an agent worker, session storage, remoting and pi extensions",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -63,10 +63,10 @@
63
63
  "release": "semantic-release"
64
64
  },
65
65
  "devDependencies": {
66
- "@ai-ecoverse/slicc-kernel": "1.103.4",
66
+ "@ai-ecoverse/slicc-kernel": "1.110.0",
67
67
  "@ai-ecoverse/slicc-scrub": "1.0.0",
68
- "@ai-ecoverse/slicc-shared-web": "1.21.1",
69
- "@ai-ecoverse/slicc-spectrum": "1.84.0",
68
+ "@ai-ecoverse/slicc-shared-web": "1.22.0",
69
+ "@ai-ecoverse/slicc-spectrum": "1.84.1",
70
70
  "@ai-ecoverse/wasm-bash": "5.3.0-18",
71
71
  "@ai-ecoverse/wasm-coreutils": "9.12.0-8",
72
72
  "@ai-ecoverse/wasm-git": "2.55.0-15",
@@ -92,7 +92,7 @@
92
92
  "typebox": "1.3.36"
93
93
  },
94
94
  "peerDependencies": {
95
- "@ai-ecoverse/slicc-kernel": ">=1.90.0 <2",
95
+ "@ai-ecoverse/slicc-kernel": ">=1.110.0 <2",
96
96
  "@ai-ecoverse/slicc-spectrum": "^1.84.0"
97
97
  },
98
98
  "peerDependenciesMeta": {
@@ -5,7 +5,7 @@ description: Use this when you receive a <lick channel="sprinkle" source="sprink
5
5
 
6
6
  # Gelatiere
7
7
 
8
- The gelatiere is a scoop with the `gelatiere` role. Each night, and whenever someone runs `gelatiere run`, it reviews memory, skills and setup, and folds a few suggestions into `/home/.gelatiere/suggestions.json`. The suggestions sprinkle shows the open ones as cards. `gelatiere init` starts it and adds its crontab line; the user can change its pass in `~/.pi/agent/GELATIERE.md`.
8
+ The gelatiere is a scoop with the `gelatiere` role. Each night, and whenever someone runs `gelatiere run`, it reviews memory, skills and setup, and folds a few suggestions into `/home/.gelatiere/suggestions.json`. The suggestions sprinkle shows the open ones as cards. `gelatiere init` starts it and puts its nightly line in the scoop's own crontab; the user can change its pass in `~/.pi/agent/GELATIERE.md`.
9
9
 
10
10
  ## A `gelatiere-suggestions` lick arrived
11
11
 
@@ -21,7 +21,7 @@ Its body lists the new suggestions for your cone. Reply with one short sentence:
21
21
 
22
22
  ## The `gelatiere` command
23
23
 
24
- - `gelatiere init` starts the gelatiere scoop and its nightly crontab line.
24
+ - `gelatiere init` starts the gelatiere scoop and puts its nightly line in the scoop's crontab.
25
25
  - `gelatiere run` asks it for a pass now.
26
26
  - `gelatiere list [--all] [--json]` lists the open suggestions, or all of them.
27
27
  - `gelatiere install <id>` installs a suggested skill.