@ai-ecoverse/slicc-agent 3.46.0 → 3.47.1

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 CHANGED
@@ -459,7 +459,7 @@ The process table is the worker's root client's `ps()`. Each process is named af
459
459
  - **Users mode:** the human's panel is root's, so it sees every process. A cone's bound client would see only its own, by the kernel's hidepid.
460
460
 
461
461
  **The port.** `createAgentModel()` returns a `MonitorAdapter`. Its first `snapshot` listener opens the lease (with a resync), and its last one closes it.
462
- - **Vitals:** the Adobe budget, spend (or tokens when every model is free) with its hourly rate, active agents, running tools and tasks, processes, process memory and the fullest context.
462
+ - **Vitals:** the Adobe budget, spend (or tokens when every model is free) with its hourly rate, active agents, running tools and tasks, processes, process memory, CPU and the fullest context.
463
463
  - **Alerts:**
464
464
 
465
465
  | Alert | Warn | Error |
@@ -476,10 +476,12 @@ The process table is the worker's root client's `ps()`. Each process is named af
476
476
  | Context | 80% | |
477
477
  | A paused scheduler | always | |
478
478
 
479
+ An alert that suggests a command, such as a runaway's `kill -- -412`, a background process's `kill 52` or a zombie's parent, keeps its `detail` a full sentence and puts the plain command in `command`, with the lead-in for it, such as "To stop it, run", in `commandLabel`. Spectrum shows the label and the command as a code chip after the detail; an older spectrum shows only the detail. A process row takes the severity of its alerts, so it's red only when its alert is at error.
480
+
479
481
  - **Sections:** cones and scoops, tasks as a tree per cone, processes, recent problems, pending changes and sprinkles. Each row has an `id`, and agents and tasks have a `depth` (at most 6), which spectrum (≥ 1.57.0) draws as indentation.
480
482
  - **More sections:** `createAgentModel(connection, { monitor: { extra } })` adds the page's own sections, such as terminals, browser tabs and tray followers.
481
483
 
482
- **CPU.** From slicc-kernel 1.67.1, `ps()` entries carry `utime` and `stime`, each process's CPU time in milliseconds. The feed passes them on, and each process's `cpu` is its share of one core between the last two polls: `null` on the first poll, or when a pid is restarted or reused. An agent's `cpu` sums its processes. The adapter remembers since when each agent's process group has been at 90% of a core or more, and raises `runaway-cpu-<pgid>`, "research is using a lot of CPU", once that has lasted 2 min. With CPU times, an idle long-running process raises no alert. On older kernels, none of these fields appear, and the age alert stays.
484
+ **CPU.** From slicc-kernel 1.67.1, `ps()` entries carry `utime` and `stime`, each process's CPU time in milliseconds. The feed passes them on, and each process's `cpu` is its share of one core between the last two polls: `null` on the first poll, or when a pid is restarted or reused. An agent's `cpu` sums its processes. The adapter remembers since when each agent's process group has been at 90% of a core or more, and raises `runaway-cpu-<pgid>`, "research is using a lot of CPU", once that has lasted 2 min. Process rows and agent rows end their meta with the share, rounded like top (`97% CPU`, `140% CPU`, with a non-breaking space), unless it's unknown or under 1%. The CPU vital is the agents' summed share (`97%`, "of one core"), with the last 30 feeds as its series and no meter, since a share of one core has no ceiling. With CPU times, an idle long-running process raises no alert. On older kernels, none of these fields appear, and the age alert stays.
483
485
 
484
486
  **Memory.** From slicc-kernel 1.61.0, `ps()` entries carry `rss`, each process's wasm memory. When they do, the monitor shows a Process memory vital and each process row's size. On older kernels, both are left out. `/proc/meminfo`'s `MemTotal` is a placeholder. The tray chip gets no `spent` or `rate`, so spectrum (≥ 1.57.0) shows only what's known.
485
487
 
@@ -555,7 +557,7 @@ The agent never holds a secret's value. Values live in the vault (`vault.sliccy.
555
557
 
556
558
  ## The kernel
557
559
 
558
- `@ai-ecoverse/slicc-kernel` is a peer dependency (`>=1.47.1 <2`, the first kernel with users and the H1 wasm commands; until 3.31.0 the floor was 1.26.3): the agent only calls `attachKernel`, the client end of the page kernel's port, so it must match the kernel the page runs. Seven chooses that version: slicc-bios pins the certified kernel next to the agent in `src/packages/agent/package.json`, and pnpm fills the peer from that pin. The devDependency is the lowest certified kernel the range allows (1.47.1), and the unit and integration tests run on it with the H1 wasm commands as devDependencies. A second CI job reruns the integration tests on the newest certified kernel (`NEWEST_CERTIFIED_KERNEL` in `.github/workflows/ci.yml`), with the wasm commands certified for it (`NEWEST_CERTIFIED_WASM`). Today the floor is 1.47.1 and the newest certified kernel 1.67.1; the second job moves by hand to each newer certified kernel, so both ends of the range are tested. If the port protocol ever breaks within 1.x, a patch release narrows the upper bound. Renovate opens PRs for the kernel, `wasi-pnpm`, the `wasm-*` packages and `slicc-cdp` but never merges them, because they move only after the homescoop coordinator certifies them.
560
+ `@ai-ecoverse/slicc-kernel` is a peer dependency (`>=1.47.1 <2`, the first kernel with users and the H1 wasm commands; until 3.31.0 the floor was 1.26.3): the agent only calls `attachKernel`, the client end of the page kernel's port, so it must match the kernel the page runs. Seven chooses that version: slicc-bios pins the certified kernel next to the agent in `src/packages/agent/package.json`, and pnpm fills the peer from that pin. The devDependency is the lowest certified kernel the range allows (1.47.1), and the unit and integration tests run on it with the H1 wasm commands as devDependencies. A second CI job reruns the integration tests on the newest certified kernel (`NEWEST_CERTIFIED_KERNEL` in `.github/workflows/ci.yml`), with the wasm commands certified for it (`NEWEST_CERTIFIED_WASM`). Today the floor is 1.47.1 and the newest certified kernel 1.70.0; the second job moves by hand to each newer certified kernel, so both ends of the range are tested. If the port protocol ever breaks within 1.x, a patch release narrows the upper bound. Renovate opens PRs for the kernel, `wasi-pnpm`, the `wasm-*` packages and `slicc-cdp` but never merges them, because they move only after the homescoop coordinator certifies them.
559
561
 
560
562
  ## Patched dependencies
561
563
 
@@ -176,8 +176,8 @@ function origins(entries) {
176
176
  const out = /* @__PURE__ */ new Map();
177
177
  for (const entry of entries)
178
178
  if (entry.kind === FROM_KIND) {
179
- const note = entry.data;
180
- out.set(note.entry, note);
179
+ const note2 = entry.data;
180
+ out.set(note2.entry, note2);
181
181
  }
182
182
  return out;
183
183
  }
@@ -222,10 +222,58 @@ function tools(messages) {
222
222
  }
223
223
  return found;
224
224
  }
225
- function settle(calls, result) {
225
+ const RANK = ["error", "warn", "info"];
226
+ const LINE = /^\[(error|warn|info)\] (.*)$/;
227
+ function rendered(diagnostics) {
228
+ return `<harness>
229
+ ${diagnostics.map((item) => `[${item.severity}] ${item.message}`).join("\n")}
230
+ </harness>`;
231
+ }
232
+ function parsed(text) {
233
+ const body = /^<harness>\n([\s\S]*)\n<\/harness>$/.exec(text)?.[1];
234
+ if (body === void 0) return void 0;
235
+ const found = body.split("\n").map((line) => LINE.exec(line));
236
+ if (!found.every((match) => match !== null)) return void 0;
237
+ return found.map(([, severity, message]) => ({ severity, message }));
238
+ }
239
+ function harness(content, data) {
240
+ const last = Array.isArray(content) ? content.at(-1) : void 0;
241
+ const stored = data?.diagnostics;
242
+ const listed = Array.isArray(stored) ? stored : parsed(last?.text ?? "");
243
+ if (!listed?.length || last?.type !== "text" || last.text !== rendered(listed))
244
+ return { content, diagnostics: [] };
245
+ return { content: content.slice(0, -1), diagnostics: listed };
246
+ }
247
+ const count = (value) => Number(value).toLocaleString("en");
248
+ const ends = { end: " from the start", beginning: " from the end" };
249
+ const phrasings = [
250
+ [/^Command exited with code (-?\d+)$/, (match) => `Exited with code ${match[1]}`],
251
+ [/^Command timed out after (.+)$/, (match) => `Timed out after ${match[1]}`],
252
+ [/^Command aborted$/, () => "Aborted"],
253
+ [/^Full output: (.+)$/, (match) => `Full output in ${match[1]}`],
254
+ [
255
+ /^Output truncated(?: to its (beginning|end))?: (\d+) lines, (\d+) bytes dropped$/,
256
+ (match) => `Output truncated: ${count(match[2])} lines and ${count(match[3])} bytes dropped${ends[match[1] ?? ""] ?? ""}`
257
+ ]
258
+ ];
259
+ function phrased(message) {
260
+ const line = message.replace(/\n[\s\S]*$/, "").trim().replace(/\.$/, "");
261
+ for (const [pattern, phrase] of phrasings) {
262
+ const match = pattern.exec(line);
263
+ if (match) return phrase(match);
264
+ }
265
+ return line;
266
+ }
267
+ function note(diagnostic) {
268
+ return { severity: diagnostic.severity, text: phrased(diagnostic.message) };
269
+ }
270
+ function settle(calls, result, data) {
226
271
  const call = calls.get(result.toolCallId ?? "");
227
272
  if (!call) return;
228
- call.output = textOf(result.content);
273
+ const split = harness(result.content, data);
274
+ call.output = textOf(split.content);
275
+ if (split.diagnostics.length)
276
+ call.notes = split.diagnostics.map(note).sort((a, b) => RANK.indexOf(a.severity) - RANK.indexOf(b.severity));
229
277
  call.status = result.isError ? "error" : "done";
230
278
  const image = Array.isArray(result.content) ? result.content.find(
231
279
  (part2) => part2.type === "image" && part2.data && part2.mimeType
@@ -291,7 +339,7 @@ function entryMessage(entry, out, calls, delivered, notes) {
291
339
  const message = assistant(id, model);
292
340
  out.push(withoutLickTools(message));
293
341
  for (const [key, value] of tools([message])) calls.set(key, value);
294
- } else if (entry.kind === "pi.tool-result" && model) settle(calls, model);
342
+ } else if (entry.kind === "pi.tool-result" && model) settle(calls, model, entry.data);
295
343
  else if (entry.kind === "pi.compaction") out.push(system(id, entry, textOf(model?.content)));
296
344
  }
297
345
  const slotStatus = {
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "version": 3,
3
3
  "sources": ["../../src/spectrum/messages.ts"],
4
- "sourcesContent": ["import type {\n AssistantMessage,\n AssistantStatus,\n ErrorAction,\n LickMessage,\n Message,\n MessagePart,\n SystemMessage,\n ToolCall,\n ToolStatus,\n Usage,\n UserMessage,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport type { ConversationView, EntryRecord } from '@earendil-works/pi-durable';\nimport { parseLick } from '../licks/lick.ts';\nimport { entryLick, LICK_TOOLS, type LickDecision, lickDecisions } from '../licks/state.ts';\nimport { mcpLabel } from '../mcp/label.ts';\nimport { FROM_KIND, type From } from '../scoops/from.ts';\nimport type { SecretName } from '../secrets/names.ts';\nimport { listedLine, SECRETS_KIND } from '../secrets/view.ts';\nimport type { Delivered } from '../services.ts';\nimport { SPRINKLE_KIND } from '../sprinkles/kind.ts';\n\ntype Json = Record<string, unknown>;\n\ninterface Block {\n type: string;\n text?: string;\n thinking?: string;\n id?: string;\n name?: string;\n arguments?: Json;\n}\n\ninterface ModelMessage {\n role: string;\n content?: string | Block[];\n timestamp?: number;\n stopReason?: string;\n errorMessage?: string;\n provider?: string;\n model?: string;\n usage?: {\n input?: number;\n output?: number;\n cacheRead?: number;\n cacheWrite?: number;\n cost?: { total?: number };\n };\n toolCallId?: string;\n isError?: boolean;\n details?: { patch?: unknown };\n}\n\ninterface Slot {\n callId: string;\n status: string;\n output?: string;\n}\n\ninterface Live {\n run?: unknown;\n generation?: { message?: ModelMessage; retry?: { at: number; error: string } };\n tools?: Slot[];\n compactions?: { taskId: number; reason: string }[];\n}\n\nexport function textOf(content: ModelMessage['content']): string {\n if (typeof content === 'string') return content;\n return (content ?? []).map((block) => (block.type === 'text' ? (block.text ?? '') : '')).join('');\n}\n\nconst paths = (args: Json | undefined): string[] =>\n typeof args?.path === 'string' ? [args.path] : [];\n\nfunction title(args: Json | undefined): string {\n const subject = args?.command ?? args?.path;\n return typeof subject === 'string' ? subject : '';\n}\n\ninterface Replacement {\n oldText?: string;\n newText?: string;\n}\n\nconst GAP = '\u2026';\n\nfunction seconds(value: unknown): string | undefined {\n return typeof value === 'number' ? `timeout ${value}s` : undefined;\n}\n\nfunction lines(args: Json): string | undefined {\n const { offset, limit } = args as { offset?: number; limit?: number };\n if (typeof offset === 'number' && typeof limit === 'number')\n return `lines ${offset}\u2013${offset + limit - 1}`;\n if (typeof offset === 'number') return `from line ${offset}`;\n return typeof limit === 'number' ? `first ${limit} lines` : undefined;\n}\n\nfunction edits(args: Json): ToolCall['diff'] {\n const list = Array.isArray(args.edits) ? (args.edits as Replacement[]) : [];\n if (list.length === 0) return undefined;\n return {\n before: list.map((edit) => edit.oldText ?? '').join(`\\n${GAP}\\n`),\n after: list.map((edit) => edit.newText ?? '').join(`\\n${GAP}\\n`),\n };\n}\n\nexport function fromPatch(patch: string): ToolCall['diff'] {\n const before: string[] = [];\n const after: string[] = [];\n let hunks = 0;\n for (const line of patch.split('\\n')) {\n if (line.startsWith('@@')) {\n if (hunks++ > 0) {\n before.push(GAP);\n after.push(GAP);\n }\n continue;\n }\n if (hunks === 0 || line === '' || line.startsWith('\\\\')) continue;\n const text = line.slice(1);\n if (line.startsWith('-')) before.push(text);\n else if (line.startsWith('+')) after.push(text);\n else {\n before.push(text);\n after.push(text);\n }\n }\n return hunks ? { before: before.join('\\n'), after: after.join('\\n') } : undefined;\n}\n\nfunction shape(name: string, args: Json): Pick<ToolCall, 'input' | 'meta' | 'diff'> {\n const path = typeof args.path === 'string' ? args.path : '';\n const meta = name === 'bash' ? seconds(args.timeout) : name === 'read' ? lines(args) : undefined;\n const base = meta ? { meta } : {};\n if (name === 'bash' && typeof args.command === 'string') return { input: args.command, ...base };\n if (name === 'read' || name === 'write') return { input: path, ...base };\n if (name === 'edit') {\n const diff = edits(args);\n return { input: path, ...(diff ? { diff } : {}) };\n }\n return { input: JSON.stringify(args, null, 2) };\n}\n\nfunction toolCall(block: Block): ToolCall {\n const args = block.arguments ?? {};\n return {\n id: block.id ?? '',\n name: block.name ?? 'tool',\n title: mcpLabel(block.name ?? '') ?? title(block.arguments),\n ...shape(block.name ?? 'tool', args),\n output: '',\n status: 'running',\n paths: paths(block.arguments),\n };\n}\n\nfunction part(block: Block): MessagePart | undefined {\n if (block.type === 'text') return { type: 'text', text: block.text ?? '' };\n if (block.type === 'thinking') return { type: 'thinking', text: block.thinking ?? '' };\n if (block.type === 'toolCall') return { type: 'tool', tool: toolCall(block) };\n return undefined;\n}\n\nfunction usage(message: ModelMessage): Usage | undefined {\n const used = message.usage;\n if (!used) return undefined;\n return {\n input: used.input ?? 0,\n output: used.output ?? 0,\n cost: used.cost?.total ?? 0,\n cacheRead: used.cacheRead ?? 0,\n cacheWrite: used.cacheWrite ?? 0,\n };\n}\n\nconst statuses: Record<string, AssistantStatus> = { error: 'error', aborted: 'stopped' };\n\nconst credentials =\n /security token|unrecognizedclient|not authori[sz]ed|unauthori[sz]ed|forbidden|\\b40[13]\\b|api key|credential|bearer/i;\nconst models = /model/i;\nconst unavailable =\n /access|invalid|not found|identifier|unsupported|not supported|isn['\u2019]t supported|not available|isn['\u2019]t available/i;\n\nconst providerNames: Record<string, string> = { 'amazon-bedrock': 'Bedrock' };\nconst filtered =\n /Provider (?:stopped with|finish_reason): (?:content_filter(?:ed)?|guardrail_intervened|sensitive)|content[_ ]filter(?:ed|ing)?\\b|guardrail[_ ]intervened/i;\nconst refused =\n /refused to complete the request|Provider (?:stopped with|finish_reason): refusal|\\bstop_?reason\\W+refusal\\b/i;\nconst missing = /no api key|missing|not configured|no credentials/i;\n\nexport function errorPart(error: string, provider?: string): MessagePart {\n const action = errorAction(error);\n if (action === 'drop-turn') {\n return {\n type: 'error',\n message: filtered.test(error)\n ? \"The model's content filter stopped this reply.\"\n : 'The model refused to answer this turn.',\n detail: error,\n action,\n };\n }\n if (action === 'settings' && provider === 'adobe') {\n return {\n type: 'error',\n message: 'Your Adobe session has expired.',\n detail: error,\n action: 'login',\n };\n }\n const name = providerNames[provider ?? ''] ?? 'The provider';\n const lead =\n action === 'settings'\n ? missing.test(error)\n ? `${name} needs an API key.`\n : `${name} rejected the API key.`\n : action === 'change-model'\n ? \"This model isn't available with the current account.\"\n : null;\n return lead\n ? { type: 'error', message: lead, detail: error, action }\n : { type: 'error', message: error, action };\n}\n\nexport function errorAction(message: string): ErrorAction {\n if (filtered.test(message) || refused.test(message)) return 'drop-turn';\n if (credentials.test(message)) return 'settings';\n if (models.test(message) && unavailable.test(message)) return 'change-model';\n return 'retry';\n}\n\nfunction sprinkleMessage(id: string, entry: EntryRecord): AssistantMessage {\n const data = (entry.data ?? {}) as { sprinkle?: unknown; at?: unknown };\n return {\n id,\n role: 'assistant',\n parts: [{ type: 'sprinkle', sprinkle: String(data.sprinkle ?? '') }],\n status: 'done',\n createdAt: typeof data.at === 'number' ? data.at : 0,\n };\n}\n\nexport function assistant(\n id: string,\n message: ModelMessage,\n status?: AssistantStatus\n): AssistantMessage {\n const blocks = Array.isArray(message.content) ? message.content : [];\n const parts = blocks.map(part).filter((item): item is MessagePart => item !== undefined);\n if (message.errorMessage) parts.push(errorPart(message.errorMessage, message.provider));\n const used = usage(message);\n return {\n id,\n role: 'assistant',\n parts,\n status: status ?? statuses[message.stopReason ?? ''] ?? 'done',\n createdAt: message.timestamp ?? 0,\n ...(message.provider && message.model ? { model: `${message.provider}/${message.model}` } : {}),\n ...(used ? { usage: used } : {}),\n };\n}\n\nfunction user(\n id: string,\n message: ModelMessage,\n delivered: Delivered | undefined,\n from: From | undefined\n): UserMessage {\n return {\n id,\n role: 'user',\n text: textOf(message.content),\n createdAt: message.timestamp ?? 0,\n ...(delivered ? { delivered } : {}),\n ...(from ? { from: from.from } : {}),\n ...(from?.agent ? { origin: 'agent' as const } : {}),\n };\n}\n\nexport function origins(entries: readonly EntryRecord[]): Map<number, From> {\n const out = new Map<number, From>();\n for (const entry of entries)\n if (entry.kind === FROM_KIND) {\n const note = entry.data as From;\n out.set(note.entry, note);\n }\n return out;\n}\n\nfunction lickMessage(\n id: string,\n entry: EntryRecord,\n decisions: ReadonlyMap<string, LickDecision>\n): LickMessage | undefined {\n const lick = entryLick(entry);\n if (!lick) return undefined;\n const state = lick.actions?.length ? (decisions.get(lick.id) ?? 'pending') : undefined;\n return {\n id,\n role: 'lick',\n channel: lick.channel,\n title: lick.title,\n text: lick.text,\n createdAt: lick.at,\n ...(lick.body ? { body: lick.body } : {}),\n ...(lick.count > 1 ? { count: lick.count } : {}),\n ...(state ? { state } : {}),\n ...(lick.severity ? { severity: lick.severity } : {}),\n };\n}\n\nfunction withoutLickTools(message: AssistantMessage): AssistantMessage {\n const parts = message.parts.filter((item) => item.type !== 'tool' || !LICK_TOOLS[item.tool.name]);\n return parts.length === message.parts.length ? message : { ...message, parts };\n}\n\nfunction system(id: string, entry: EntryRecord, text: string): SystemMessage {\n const reason = (entry.data as Json | undefined)?.reason as SystemMessage['trigger'] | undefined;\n return {\n id,\n role: 'system',\n kind: 'compaction',\n text,\n createdAt: 0,\n state: 'summarized',\n ...(reason ? { trigger: reason } : {}),\n };\n}\n\nfunction tools(messages: Message[]): Map<string, ToolCall> {\n const found = new Map<string, ToolCall>();\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const item of message.parts) if (item.type === 'tool') found.set(item.tool.id, item.tool);\n }\n return found;\n}\n\nfunction settle(calls: Map<string, ToolCall>, result: ModelMessage): void {\n const call = calls.get(result.toolCallId ?? '');\n if (!call) return;\n call.output = textOf(result.content);\n call.status = result.isError ? 'error' : 'done';\n const image = Array.isArray(result.content)\n ? (result.content as { type: string; data?: string; mimeType?: string }[]).find(\n (part) => part.type === 'image' && part.data && part.mimeType\n )\n : undefined;\n if (image) call.image = `data:${image.mimeType};base64,${image.data}`;\n const patch = result.details?.patch;\n const diff = typeof patch === 'string' ? fromPatch(patch) : undefined;\n if (diff) call.diff = diff;\n else if (result.isError) delete call.diff;\n}\n\nfunction rewound(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { stopped?: string[]; restored?: string[]; files?: boolean };\n const notes = [\n 'Its prompt is back in the composer.',\n ...(data.stopped?.length\n ? [`Stopped ${data.stopped.map((name) => `scoop ${name}`).join(', ')}.`]\n : []),\n ...(data.restored?.length\n ? [`Restored ${data.restored.map((name) => `scoop ${name}`).join(', ')}.`]\n : []),\n ...(data.files ? ['Changed files stay; use Changes or git to revert them.'] : []),\n ];\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: 'Rewound 1 turn',\n text: notes.join(' '),\n createdAt: 0,\n };\n}\n\nfunction thawed(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { name?: string; kind?: string };\n const what = data.kind === 'agent' ? 'agent run' : 'scoop';\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: `Thawed from ${what} ${data.name ?? ''}`.trim(),\n text: textOf(entry.model?.[0]?.content ?? ''),\n createdAt: entry.model?.[0]?.timestamp ?? 0,\n };\n}\n\nfunction secrets(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { names?: SecretName[] };\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: 'Secrets listed',\n text: listedLine(data.names ?? []),\n createdAt: entry.model?.[0]?.timestamp ?? 0,\n };\n}\n\nfunction entryMessage(\n entry: EntryRecord,\n out: Message[],\n calls: Map<string, ToolCall>,\n delivered: Delivered | undefined,\n notes: { decisions: ReadonlyMap<string, LickDecision>; origins: ReadonlyMap<number, From> }\n): void {\n const id = `e${entry.id}`;\n const model = entry.model?.[0] as ModelMessage | undefined;\n if (entry.kind === 'slicc.rewound') out.push(rewound(id, entry));\n if (entry.kind === 'slicc.thawed') out.push(thawed(id, entry));\n else if (entry.kind === SECRETS_KIND) out.push(secrets(id, entry));\n else if (entry.kind === SPRINKLE_KIND) out.push(sprinkleMessage(id, entry));\n else if (entry.kind === 'pi.user' && model)\n out.push(\n lickMessage(id, entry, notes.decisions) ??\n user(id, model, delivered, notes.origins.get(entry.id))\n );\n else if (entry.kind === 'pi.assistant' && model) {\n const message = assistant(id, model);\n out.push(withoutLickTools(message));\n for (const [key, value] of tools([message])) calls.set(key, value);\n } else if (entry.kind === 'pi.tool-result' && model) settle(calls, model);\n else if (entry.kind === 'pi.compaction') out.push(system(id, entry, textOf(model?.content)));\n}\n\nconst slotStatus: Record<string, ToolStatus> = {\n pending: 'running',\n running: 'running',\n done: 'done',\n};\n\nfunction live(view: ConversationView, out: Message[], calls: Map<string, ToolCall>): void {\n const state = view.docs['pi.live'] as Live | undefined;\n for (const slot of state?.tools ?? []) {\n const call = calls.get(slot.callId);\n if (call && call.status === 'running') {\n call.status = slotStatus[slot.status] ?? 'running';\n call.output = slot.output ?? call.output;\n }\n }\n const partial = state?.generation?.message;\n if (partial) out.push(assistant('live', partial, 'streaming'));\n for (const compaction of state?.compactions ?? []) {\n out.push({\n id: `compaction-${compaction.taskId}`,\n role: 'system',\n kind: 'compaction',\n text: '',\n createdAt: 0,\n state: 'summarizing',\n trigger: compaction.reason as SystemMessage['trigger'],\n });\n }\n const retry = state?.generation?.retry;\n if (retry)\n out.push({\n id: 'retry',\n role: 'system',\n kind: 'notice',\n text: retry.error,\n createdAt: retry.at,\n });\n}\n\nexport function toMessages(\n view: ConversationView | undefined,\n deliveries: Readonly<Record<string, Delivered>> = {}\n): Message[] {\n const out: Message[] = [];\n if (!view) return out;\n const calls = new Map<string, ToolCall>();\n const notes = { decisions: lickDecisions(view.entries), origins: origins(view.entries) };\n let previous: EntryRecord | undefined;\n for (const entry of view.entries) {\n const steered = previous?.kind === 'pi.tool-result' ? 'steer' : undefined;\n entryMessage(entry, out, calls, deliveries[String(entry.id)] ?? steered, notes);\n previous = entry;\n }\n live(view, out, calls);\n return out;\n}\n\nexport function isBusy(view: ConversationView | undefined): boolean {\n return Boolean((view?.docs['pi.live'] as Live | undefined)?.run);\n}\n\nexport function queued(view: ConversationView | undefined): UserMessage[] {\n const items = ((view?.docs['pi.inbox'] as { items?: Json[] } | undefined)?.items ?? []) as {\n id: number;\n mode: string;\n content?: ModelMessage['content'];\n }[];\n return items\n .filter((item) => item.mode !== 'write' && !parseLick(textOf(item.content)))\n .map((item) => ({\n id: `q${item.id}`,\n role: 'user',\n text: textOf(item.content),\n createdAt: 0,\n queued: true,\n mode: item.mode === 'steer' ? 'steer' : 'queue',\n }));\n}\n"],
5
- "mappings": "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",
6
- "names": ["part"]
4
+ "sourcesContent": ["import type {\n AssistantMessage,\n AssistantStatus,\n ErrorAction,\n LickMessage,\n Message,\n MessagePart,\n SystemMessage,\n ToolCall,\n ToolStatus,\n Usage,\n UserMessage,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport type { ConversationView, EntryRecord } from '@earendil-works/pi-durable';\nimport { parseLick } from '../licks/lick.ts';\nimport { entryLick, LICK_TOOLS, type LickDecision, lickDecisions } from '../licks/state.ts';\nimport { mcpLabel } from '../mcp/label.ts';\nimport { FROM_KIND, type From } from '../scoops/from.ts';\nimport type { SecretName } from '../secrets/names.ts';\nimport { listedLine, SECRETS_KIND } from '../secrets/view.ts';\nimport type { Delivered } from '../services.ts';\nimport { SPRINKLE_KIND } from '../sprinkles/kind.ts';\n\ntype Json = Record<string, unknown>;\n\ninterface Block {\n type: string;\n text?: string;\n thinking?: string;\n id?: string;\n name?: string;\n arguments?: Json;\n}\n\ninterface ModelMessage {\n role: string;\n content?: string | Block[];\n timestamp?: number;\n stopReason?: string;\n errorMessage?: string;\n provider?: string;\n model?: string;\n usage?: {\n input?: number;\n output?: number;\n cacheRead?: number;\n cacheWrite?: number;\n cost?: { total?: number };\n };\n toolCallId?: string;\n isError?: boolean;\n details?: { patch?: unknown };\n}\n\ninterface Slot {\n callId: string;\n status: string;\n output?: string;\n}\n\ninterface Live {\n run?: unknown;\n generation?: { message?: ModelMessage; retry?: { at: number; error: string } };\n tools?: Slot[];\n compactions?: { taskId: number; reason: string }[];\n}\n\nexport function textOf(content: ModelMessage['content']): string {\n if (typeof content === 'string') return content;\n return (content ?? []).map((block) => (block.type === 'text' ? (block.text ?? '') : '')).join('');\n}\n\nconst paths = (args: Json | undefined): string[] =>\n typeof args?.path === 'string' ? [args.path] : [];\n\nfunction title(args: Json | undefined): string {\n const subject = args?.command ?? args?.path;\n return typeof subject === 'string' ? subject : '';\n}\n\ninterface Replacement {\n oldText?: string;\n newText?: string;\n}\n\nconst GAP = '\u2026';\n\nfunction seconds(value: unknown): string | undefined {\n return typeof value === 'number' ? `timeout ${value}s` : undefined;\n}\n\nfunction lines(args: Json): string | undefined {\n const { offset, limit } = args as { offset?: number; limit?: number };\n if (typeof offset === 'number' && typeof limit === 'number')\n return `lines ${offset}\u2013${offset + limit - 1}`;\n if (typeof offset === 'number') return `from line ${offset}`;\n return typeof limit === 'number' ? `first ${limit} lines` : undefined;\n}\n\nfunction edits(args: Json): ToolCall['diff'] {\n const list = Array.isArray(args.edits) ? (args.edits as Replacement[]) : [];\n if (list.length === 0) return undefined;\n return {\n before: list.map((edit) => edit.oldText ?? '').join(`\\n${GAP}\\n`),\n after: list.map((edit) => edit.newText ?? '').join(`\\n${GAP}\\n`),\n };\n}\n\nexport function fromPatch(patch: string): ToolCall['diff'] {\n const before: string[] = [];\n const after: string[] = [];\n let hunks = 0;\n for (const line of patch.split('\\n')) {\n if (line.startsWith('@@')) {\n if (hunks++ > 0) {\n before.push(GAP);\n after.push(GAP);\n }\n continue;\n }\n if (hunks === 0 || line === '' || line.startsWith('\\\\')) continue;\n const text = line.slice(1);\n if (line.startsWith('-')) before.push(text);\n else if (line.startsWith('+')) after.push(text);\n else {\n before.push(text);\n after.push(text);\n }\n }\n return hunks ? { before: before.join('\\n'), after: after.join('\\n') } : undefined;\n}\n\nfunction shape(name: string, args: Json): Pick<ToolCall, 'input' | 'meta' | 'diff'> {\n const path = typeof args.path === 'string' ? args.path : '';\n const meta = name === 'bash' ? seconds(args.timeout) : name === 'read' ? lines(args) : undefined;\n const base = meta ? { meta } : {};\n if (name === 'bash' && typeof args.command === 'string') return { input: args.command, ...base };\n if (name === 'read' || name === 'write') return { input: path, ...base };\n if (name === 'edit') {\n const diff = edits(args);\n return { input: path, ...(diff ? { diff } : {}) };\n }\n return { input: JSON.stringify(args, null, 2) };\n}\n\nfunction toolCall(block: Block): ToolCall {\n const args = block.arguments ?? {};\n return {\n id: block.id ?? '',\n name: block.name ?? 'tool',\n title: mcpLabel(block.name ?? '') ?? title(block.arguments),\n ...shape(block.name ?? 'tool', args),\n output: '',\n status: 'running',\n paths: paths(block.arguments),\n };\n}\n\nfunction part(block: Block): MessagePart | undefined {\n if (block.type === 'text') return { type: 'text', text: block.text ?? '' };\n if (block.type === 'thinking') return { type: 'thinking', text: block.thinking ?? '' };\n if (block.type === 'toolCall') return { type: 'tool', tool: toolCall(block) };\n return undefined;\n}\n\nfunction usage(message: ModelMessage): Usage | undefined {\n const used = message.usage;\n if (!used) return undefined;\n return {\n input: used.input ?? 0,\n output: used.output ?? 0,\n cost: used.cost?.total ?? 0,\n cacheRead: used.cacheRead ?? 0,\n cacheWrite: used.cacheWrite ?? 0,\n };\n}\n\nconst statuses: Record<string, AssistantStatus> = { error: 'error', aborted: 'stopped' };\n\nconst credentials =\n /security token|unrecognizedclient|not authori[sz]ed|unauthori[sz]ed|forbidden|\\b40[13]\\b|api key|credential|bearer/i;\nconst models = /model/i;\nconst unavailable =\n /access|invalid|not found|identifier|unsupported|not supported|isn['\u2019]t supported|not available|isn['\u2019]t available/i;\n\nconst providerNames: Record<string, string> = { 'amazon-bedrock': 'Bedrock' };\nconst filtered =\n /Provider (?:stopped with|finish_reason): (?:content_filter(?:ed)?|guardrail_intervened|sensitive)|content[_ ]filter(?:ed|ing)?\\b|guardrail[_ ]intervened/i;\nconst refused =\n /refused to complete the request|Provider (?:stopped with|finish_reason): refusal|\\bstop_?reason\\W+refusal\\b/i;\nconst missing = /no api key|missing|not configured|no credentials/i;\n\nexport function errorPart(error: string, provider?: string): MessagePart {\n const action = errorAction(error);\n if (action === 'drop-turn') {\n return {\n type: 'error',\n message: filtered.test(error)\n ? \"The model's content filter stopped this reply.\"\n : 'The model refused to answer this turn.',\n detail: error,\n action,\n };\n }\n if (action === 'settings' && provider === 'adobe') {\n return {\n type: 'error',\n message: 'Your Adobe session has expired.',\n detail: error,\n action: 'login',\n };\n }\n const name = providerNames[provider ?? ''] ?? 'The provider';\n const lead =\n action === 'settings'\n ? missing.test(error)\n ? `${name} needs an API key.`\n : `${name} rejected the API key.`\n : action === 'change-model'\n ? \"This model isn't available with the current account.\"\n : null;\n return lead\n ? { type: 'error', message: lead, detail: error, action }\n : { type: 'error', message: error, action };\n}\n\nexport function errorAction(message: string): ErrorAction {\n if (filtered.test(message) || refused.test(message)) return 'drop-turn';\n if (credentials.test(message)) return 'settings';\n if (models.test(message) && unavailable.test(message)) return 'change-model';\n return 'retry';\n}\n\nfunction sprinkleMessage(id: string, entry: EntryRecord): AssistantMessage {\n const data = (entry.data ?? {}) as { sprinkle?: unknown; at?: unknown };\n return {\n id,\n role: 'assistant',\n parts: [{ type: 'sprinkle', sprinkle: String(data.sprinkle ?? '') }],\n status: 'done',\n createdAt: typeof data.at === 'number' ? data.at : 0,\n };\n}\n\nexport function assistant(\n id: string,\n message: ModelMessage,\n status?: AssistantStatus\n): AssistantMessage {\n const blocks = Array.isArray(message.content) ? message.content : [];\n const parts = blocks.map(part).filter((item): item is MessagePart => item !== undefined);\n if (message.errorMessage) parts.push(errorPart(message.errorMessage, message.provider));\n const used = usage(message);\n return {\n id,\n role: 'assistant',\n parts,\n status: status ?? statuses[message.stopReason ?? ''] ?? 'done',\n createdAt: message.timestamp ?? 0,\n ...(message.provider && message.model ? { model: `${message.provider}/${message.model}` } : {}),\n ...(used ? { usage: used } : {}),\n };\n}\n\nfunction user(\n id: string,\n message: ModelMessage,\n delivered: Delivered | undefined,\n from: From | undefined\n): UserMessage {\n return {\n id,\n role: 'user',\n text: textOf(message.content),\n createdAt: message.timestamp ?? 0,\n ...(delivered ? { delivered } : {}),\n ...(from ? { from: from.from } : {}),\n ...(from?.agent ? { origin: 'agent' as const } : {}),\n };\n}\n\nexport function origins(entries: readonly EntryRecord[]): Map<number, From> {\n const out = new Map<number, From>();\n for (const entry of entries)\n if (entry.kind === FROM_KIND) {\n const note = entry.data as From;\n out.set(note.entry, note);\n }\n return out;\n}\n\nfunction lickMessage(\n id: string,\n entry: EntryRecord,\n decisions: ReadonlyMap<string, LickDecision>\n): LickMessage | undefined {\n const lick = entryLick(entry);\n if (!lick) return undefined;\n const state = lick.actions?.length ? (decisions.get(lick.id) ?? 'pending') : undefined;\n return {\n id,\n role: 'lick',\n channel: lick.channel,\n title: lick.title,\n text: lick.text,\n createdAt: lick.at,\n ...(lick.body ? { body: lick.body } : {}),\n ...(lick.count > 1 ? { count: lick.count } : {}),\n ...(state ? { state } : {}),\n ...(lick.severity ? { severity: lick.severity } : {}),\n };\n}\n\nfunction withoutLickTools(message: AssistantMessage): AssistantMessage {\n const parts = message.parts.filter((item) => item.type !== 'tool' || !LICK_TOOLS[item.tool.name]);\n return parts.length === message.parts.length ? message : { ...message, parts };\n}\n\nfunction system(id: string, entry: EntryRecord, text: string): SystemMessage {\n const reason = (entry.data as Json | undefined)?.reason as SystemMessage['trigger'] | undefined;\n return {\n id,\n role: 'system',\n kind: 'compaction',\n text,\n createdAt: 0,\n state: 'summarized',\n ...(reason ? { trigger: reason } : {}),\n };\n}\n\nfunction tools(messages: Message[]): Map<string, ToolCall> {\n const found = new Map<string, ToolCall>();\n for (const message of messages) {\n if (message.role !== 'assistant') continue;\n for (const item of message.parts) if (item.type === 'tool') found.set(item.tool.id, item.tool);\n }\n return found;\n}\n\ninterface Diagnostic {\n severity: string;\n message: string;\n}\n\ninterface Note {\n severity: 'error' | 'warn' | 'info';\n text: string;\n}\n\ntype Card = ToolCall & { notes?: Note[] };\n\nconst RANK: Note['severity'][] = ['error', 'warn', 'info'];\n\nconst LINE = /^\\[(error|warn|info)\\] (.*)$/;\n\nfunction rendered(diagnostics: readonly Diagnostic[]): string {\n return `<harness>\\n${diagnostics.map((item) => `[${item.severity}] ${item.message}`).join('\\n')}\\n</harness>`;\n}\n\nfunction parsed(text: string): Diagnostic[] | undefined {\n const body = /^<harness>\\n([\\s\\S]*)\\n<\\/harness>$/.exec(text)?.[1];\n if (body === undefined) return undefined;\n const found = body.split('\\n').map((line) => LINE.exec(line));\n if (!found.every((match): match is RegExpExecArray => match !== null)) return undefined;\n return found.map(([, severity, message]) => ({ severity, message }) as Diagnostic);\n}\n\nfunction harness(\n content: ModelMessage['content'],\n data: unknown\n): { content: ModelMessage['content']; diagnostics: Diagnostic[] } {\n const last = Array.isArray(content) ? content.at(-1) : undefined;\n const stored = (data as { diagnostics?: unknown } | undefined)?.diagnostics;\n const listed = Array.isArray(stored) ? (stored as Diagnostic[]) : parsed(last?.text ?? '');\n if (!listed?.length || last?.type !== 'text' || last.text !== rendered(listed))\n return { content, diagnostics: [] };\n return { content: (content as Block[]).slice(0, -1), diagnostics: listed };\n}\n\nconst count = (value: string | undefined): string => Number(value).toLocaleString('en');\n\nconst ends: Record<string, string> = { end: ' from the start', beginning: ' from the end' };\n\nconst phrasings: [RegExp, (match: RegExpExecArray) => string][] = [\n [/^Command exited with code (-?\\d+)$/, (match) => `Exited with code ${match[1]}`],\n [/^Command timed out after (.+)$/, (match) => `Timed out after ${match[1]}`],\n [/^Command aborted$/, () => 'Aborted'],\n [/^Full output: (.+)$/, (match) => `Full output in ${match[1]}`],\n [\n /^Output truncated(?: to its (beginning|end))?: (\\d+) lines, (\\d+) bytes dropped$/,\n (match) =>\n `Output truncated: ${count(match[2])} lines and ${count(match[3])} bytes dropped${ends[match[1] ?? ''] ?? ''}`,\n ],\n];\n\nfunction phrased(message: string): string {\n const line = message\n .replace(/\\n[\\s\\S]*$/, '')\n .trim()\n .replace(/\\.$/, '');\n for (const [pattern, phrase] of phrasings) {\n const match = pattern.exec(line);\n if (match) return phrase(match);\n }\n return line;\n}\n\nfunction note(diagnostic: Diagnostic): Note {\n return { severity: diagnostic.severity as Note['severity'], text: phrased(diagnostic.message) };\n}\n\nfunction settle(calls: Map<string, ToolCall>, result: ModelMessage, data?: unknown): void {\n const call = calls.get(result.toolCallId ?? '') as Card | undefined;\n if (!call) return;\n const split = harness(result.content, data);\n call.output = textOf(split.content);\n if (split.diagnostics.length)\n call.notes = split.diagnostics\n .map(note)\n .sort((a, b) => RANK.indexOf(a.severity) - RANK.indexOf(b.severity));\n call.status = result.isError ? 'error' : 'done';\n const image = Array.isArray(result.content)\n ? (result.content as { type: string; data?: string; mimeType?: string }[]).find(\n (part) => part.type === 'image' && part.data && part.mimeType\n )\n : undefined;\n if (image) call.image = `data:${image.mimeType};base64,${image.data}`;\n const patch = result.details?.patch;\n const diff = typeof patch === 'string' ? fromPatch(patch) : undefined;\n if (diff) call.diff = diff;\n else if (result.isError) delete call.diff;\n}\n\nfunction rewound(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { stopped?: string[]; restored?: string[]; files?: boolean };\n const notes = [\n 'Its prompt is back in the composer.',\n ...(data.stopped?.length\n ? [`Stopped ${data.stopped.map((name) => `scoop ${name}`).join(', ')}.`]\n : []),\n ...(data.restored?.length\n ? [`Restored ${data.restored.map((name) => `scoop ${name}`).join(', ')}.`]\n : []),\n ...(data.files ? ['Changed files stay; use Changes or git to revert them.'] : []),\n ];\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: 'Rewound 1 turn',\n text: notes.join(' '),\n createdAt: 0,\n };\n}\n\nfunction thawed(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { name?: string; kind?: string };\n const what = data.kind === 'agent' ? 'agent run' : 'scoop';\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: `Thawed from ${what} ${data.name ?? ''}`.trim(),\n text: textOf(entry.model?.[0]?.content ?? ''),\n createdAt: entry.model?.[0]?.timestamp ?? 0,\n };\n}\n\nfunction secrets(id: string, entry: EntryRecord): SystemMessage {\n const data = (entry.data ?? {}) as { names?: SecretName[] };\n return {\n id,\n role: 'system',\n kind: 'notice',\n title: 'Secrets listed',\n text: listedLine(data.names ?? []),\n createdAt: entry.model?.[0]?.timestamp ?? 0,\n };\n}\n\nfunction entryMessage(\n entry: EntryRecord,\n out: Message[],\n calls: Map<string, ToolCall>,\n delivered: Delivered | undefined,\n notes: { decisions: ReadonlyMap<string, LickDecision>; origins: ReadonlyMap<number, From> }\n): void {\n const id = `e${entry.id}`;\n const model = entry.model?.[0] as ModelMessage | undefined;\n if (entry.kind === 'slicc.rewound') out.push(rewound(id, entry));\n if (entry.kind === 'slicc.thawed') out.push(thawed(id, entry));\n else if (entry.kind === SECRETS_KIND) out.push(secrets(id, entry));\n else if (entry.kind === SPRINKLE_KIND) out.push(sprinkleMessage(id, entry));\n else if (entry.kind === 'pi.user' && model)\n out.push(\n lickMessage(id, entry, notes.decisions) ??\n user(id, model, delivered, notes.origins.get(entry.id))\n );\n else if (entry.kind === 'pi.assistant' && model) {\n const message = assistant(id, model);\n out.push(withoutLickTools(message));\n for (const [key, value] of tools([message])) calls.set(key, value);\n } else if (entry.kind === 'pi.tool-result' && model) settle(calls, model, entry.data);\n else if (entry.kind === 'pi.compaction') out.push(system(id, entry, textOf(model?.content)));\n}\n\nconst slotStatus: Record<string, ToolStatus> = {\n pending: 'running',\n running: 'running',\n done: 'done',\n};\n\nfunction live(view: ConversationView, out: Message[], calls: Map<string, ToolCall>): void {\n const state = view.docs['pi.live'] as Live | undefined;\n for (const slot of state?.tools ?? []) {\n const call = calls.get(slot.callId);\n if (call && call.status === 'running') {\n call.status = slotStatus[slot.status] ?? 'running';\n call.output = slot.output ?? call.output;\n }\n }\n const partial = state?.generation?.message;\n if (partial) out.push(assistant('live', partial, 'streaming'));\n for (const compaction of state?.compactions ?? []) {\n out.push({\n id: `compaction-${compaction.taskId}`,\n role: 'system',\n kind: 'compaction',\n text: '',\n createdAt: 0,\n state: 'summarizing',\n trigger: compaction.reason as SystemMessage['trigger'],\n });\n }\n const retry = state?.generation?.retry;\n if (retry)\n out.push({\n id: 'retry',\n role: 'system',\n kind: 'notice',\n text: retry.error,\n createdAt: retry.at,\n });\n}\n\nexport function toMessages(\n view: ConversationView | undefined,\n deliveries: Readonly<Record<string, Delivered>> = {}\n): Message[] {\n const out: Message[] = [];\n if (!view) return out;\n const calls = new Map<string, ToolCall>();\n const notes = { decisions: lickDecisions(view.entries), origins: origins(view.entries) };\n let previous: EntryRecord | undefined;\n for (const entry of view.entries) {\n const steered = previous?.kind === 'pi.tool-result' ? 'steer' : undefined;\n entryMessage(entry, out, calls, deliveries[String(entry.id)] ?? steered, notes);\n previous = entry;\n }\n live(view, out, calls);\n return out;\n}\n\nexport function isBusy(view: ConversationView | undefined): boolean {\n return Boolean((view?.docs['pi.live'] as Live | undefined)?.run);\n}\n\nexport function queued(view: ConversationView | undefined): UserMessage[] {\n const items = ((view?.docs['pi.inbox'] as { items?: Json[] } | undefined)?.items ?? []) as {\n id: number;\n mode: string;\n content?: ModelMessage['content'];\n }[];\n return items\n .filter((item) => item.mode !== 'write' && !parseLick(textOf(item.content)))\n .map((item) => ({\n id: `q${item.id}`,\n role: 'user',\n text: textOf(item.content),\n createdAt: 0,\n queued: true,\n mode: item.mode === 'steer' ? 'steer' : 'queue',\n }));\n}\n"],
5
+ "mappings": "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",
6
+ "names": ["note", "part"]
7
7
  }
@@ -3,6 +3,8 @@ import { Emitter } from "./emitter.js";
3
3
  const RENEW_MS = 1e4;
4
4
  const ROWS_MAX = 200;
5
5
  const HISTORY = 24;
6
+ const CPU_HISTORY = 30;
7
+ const CPU_QUIET = 0.01;
6
8
  const BUDGET_WARN = 80;
7
9
  const BUDGET_ERROR = 95;
8
10
  const RETRY_WARN = 3;
@@ -55,6 +57,27 @@ function bytes(value) {
55
57
  }
56
58
  return `${size.toFixed(size < 10 ? 1 : 0)} ${units[unit]}`;
57
59
  }
60
+ function cpuText(share) {
61
+ if (typeof share !== "number" || share < CPU_QUIET) return null;
62
+ return `${Math.round(share * 100)}%\xA0CPU`;
63
+ }
64
+ function agentsCpu(feed) {
65
+ const shares = feed.agents.map((agent) => agent.cpu).filter((share) => typeof share === "number");
66
+ return shares.length ? shares.reduce((sum, share) => sum + share, 0) : null;
67
+ }
68
+ function cpuVital(feed, history) {
69
+ const share = agentsCpu(feed);
70
+ if (share === null) return [];
71
+ return [
72
+ {
73
+ id: "cpu",
74
+ label: "CPU",
75
+ value: `${Math.round(share * 100)}%`,
76
+ unit: "of one core",
77
+ ...history.length > 1 ? { series: history.map((value) => Math.round(value * 100)) } : {}
78
+ }
79
+ ];
80
+ }
58
81
  function memoryVital(processes) {
59
82
  const measured = processes.filter((row) => typeof row.rss === "number");
60
83
  if (!measured.length) return [];
@@ -196,6 +219,7 @@ function vitals(input, feed) {
196
219
  } : feed.kernel === "checking" ? { id: "processes", label: "Processes", value: "\u2026", unit: "checking" } : { id: "processes", label: "Processes", value: "\u2014", unit: "kernel not reachable" }
197
220
  );
198
221
  out.push(...memoryVital(feed.processes ?? []));
222
+ out.push(...cpuVital(feed, input.cpu ?? []));
199
223
  const ratios = feed.agents.map((agent) => contextRatio(agent, input.models)).filter((ratio) => ratio !== null);
200
224
  if (ratios.length) {
201
225
  const fullest = Math.max(...ratios);
@@ -256,11 +280,25 @@ function cpuAlerts(input, processes, nameOf) {
256
280
  (group) => ({
257
281
  id: `runaway-cpu-${group.pgid}`,
258
282
  title: `${nameOf(group.agentId)} is using a lot of CPU`,
259
- detail: `${Math.round(group.share * 100)}% of one core for ${Math.floor(group.held / MINUTE)} minutes. Kill them with kill -- -${group.pgid}.`,
260
- severity: group.share >= CPU_SHARE * 2 || group.held >= CPU_SUSTAIN_MS * 2 ? "error" : "warn"
283
+ detail: `${Math.round(group.share * 100)}% of one core for ${Math.floor(group.held / MINUTE)} minutes.`,
284
+ command: `kill -- -${group.pgid}`,
285
+ commandLabel: "To stop it, run",
286
+ severity: cpuSeverity(group)
261
287
  })
262
288
  );
263
289
  }
290
+ function cpuSeverity(group) {
291
+ return group.share >= CPU_SHARE * 2 || group.held >= CPU_SUSTAIN_MS * 2 ? "error" : "warn";
292
+ }
293
+ function crowdSeverity(members) {
294
+ return members.length > GROUP_MAX * 2 ? "error" : "warn";
295
+ }
296
+ function staleSeverity(process, now) {
297
+ return now - process.started > STALE_MS * 2 ? "error" : "warn";
298
+ }
299
+ function worse(a, b) {
300
+ return a === "error" || b === "error" ? "error" : a ?? b;
301
+ }
264
302
  function resetLine(budget) {
265
303
  const resets = new Date(budget.resets);
266
304
  return Number.isNaN(resets.getTime()) ? `The ${budget.window} budget is nearly used up.` : `Resets ${resets.toISOString().slice(0, 16).replace("T", " ")} UTC.`;
@@ -324,8 +362,10 @@ function crowdAlerts(processes, nameOf) {
324
362
  out.push({
325
363
  id: `runaway-${pgid}`,
326
364
  title: `${nameOf(members[0].agentId)} has ${members.length} processes`,
327
- detail: `Kill them with kill -- -${pgid}.`,
328
- severity: members.length > GROUP_MAX * 2 ? "error" : "warn"
365
+ detail: "Something in it may be starting processes in a loop.",
366
+ command: `kill -- -${pgid}`,
367
+ commandLabel: "To stop them, run",
368
+ severity: crowdSeverity(members)
329
369
  });
330
370
  if (processes.length > TOTAL_MAX)
331
371
  out.push({
@@ -346,14 +386,17 @@ function processAlerts(input, feed, nameOf) {
346
386
  id: `zombie-${process.pid}`,
347
387
  title: `Process ${process.pid} is a zombie`,
348
388
  detail: `Its parent ${process.ppid} hasn't reaped it.`,
389
+ ...process.ppid > 1 ? { command: `kill ${process.ppid}`, commandLabel: "To clear it, stop the parent" } : {},
349
390
  severity: "warn"
350
391
  });
351
392
  if (stale(process, agents, input.now))
352
393
  out.push({
353
394
  id: `stale-${process.pid}`,
354
395
  title: `${process.command || `Process ${process.pid}`} has run for ${age(input.now - process.started)}`,
355
- detail: `${nameOf(process.agentId)} started it in the background. Kill it with kill ${process.pid}.`,
356
- severity: input.now - process.started > STALE_MS * 2 ? "error" : "warn"
396
+ detail: `${nameOf(process.agentId)} started it in the background.`,
397
+ command: `kill ${process.pid}`,
398
+ commandLabel: "To stop it, run",
399
+ severity: staleSeverity(process, input.now)
357
400
  });
358
401
  }
359
402
  return out;
@@ -395,7 +438,12 @@ function agentRow(agent, depth, models) {
395
438
  const word = agent.retry ? "retrying" : agent.running ? "running" : agent.failed ? "failed" : "idle";
396
439
  const status = agent.retry ? "warn" : agent.running ? "active" : agent.failed ? "error" : "idle";
397
440
  const model = models.find((choice) => choice.id === agent.model)?.label ?? agent.model;
398
- const meta = [word, model, ratio === null ? null : `${Math.round(ratio * 100)}% context`].filter(Boolean).join(" \xB7 ");
441
+ const meta = [
442
+ word,
443
+ model,
444
+ ratio === null ? null : `${Math.round(ratio * 100)}% context`,
445
+ cpuText(agent.cpu)
446
+ ].filter(Boolean).join(" \xB7 ");
399
447
  const badges = [
400
448
  ...agent.queued ? [`${agent.queued} queued`] : [],
401
449
  ...agent.tool ? [agent.tool] : [],
@@ -429,12 +477,16 @@ function taskRow(task, depth, nameOf, now) {
429
477
  }
430
478
  function processRows(input, feed) {
431
479
  const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));
432
- const crowded = /* @__PURE__ */ new Set();
480
+ const flagged = /* @__PURE__ */ new Map();
433
481
  for (const [pgid, members] of groups(feed.processes ?? []))
434
- if (members.length > GROUP_MAX) crowded.add(pgid);
435
- for (const group of busy(input, feed.processes ?? [])) crowded.add(group.pgid);
482
+ if (members.length > GROUP_MAX) flagged.set(pgid, crowdSeverity(members));
483
+ for (const group of busy(input, feed.processes ?? []))
484
+ flagged.set(group.pgid, worse(flagged.get(group.pgid), cpuSeverity(group)));
436
485
  return (feed.processes ?? []).map((process) => {
437
- const runaway = stale(process, agents, input.now) || crowded.has(process.pgid);
486
+ const runaway = worse(
487
+ flagged.get(process.pgid),
488
+ stale(process, agents, input.now) ? staleSeverity(process, input.now) : void 0
489
+ );
438
490
  const badges = [
439
491
  ...process.agentId ? [agents.get(process.agentId)?.name ?? process.agentId] : [],
440
492
  ...process.tty ? ["terminal"] : []
@@ -446,9 +498,10 @@ function processRows(input, feed) {
446
498
  `pid ${process.pid}`,
447
499
  process.user,
448
500
  typeof process.rss === "number" ? bytes(process.rss) : null,
501
+ cpuText(process.cpu),
449
502
  process.started ? age(input.now - process.started) : null
450
503
  ].filter(Boolean).join(" \xB7 "),
451
- status: runaway ? "error" : process.state === "Z" ? "warn" : "idle",
504
+ status: runaway ?? (process.state === "Z" ? "warn" : "idle"),
452
505
  ...badges.length ? { badges } : {}
453
506
  };
454
507
  });
@@ -555,6 +608,7 @@ class MonitorAdapter {
555
608
  #history = [];
556
609
  #hot = /* @__PURE__ */ new Map();
557
610
  #hotAt = -1;
611
+ #cpu = [];
558
612
  constructor(connection, options = {}) {
559
613
  this.#connection = connection;
560
614
  this.#extra = options.extra ?? (() => []);
@@ -590,7 +644,8 @@ class MonitorAdapter {
590
644
  extra: this.#extra(),
591
645
  history: this.#history,
592
646
  now: this.#now(),
593
- hot: this.#hot
647
+ hot: this.#hot,
648
+ cpu: this.#cpu
594
649
  });
595
650
  }
596
651
  resync() {
@@ -605,6 +660,7 @@ class MonitorAdapter {
605
660
  this.#history = [];
606
661
  this.#hot = /* @__PURE__ */ new Map();
607
662
  this.#hotAt = -1;
663
+ this.#cpu = [];
608
664
  void control.changesOpen(BACKGROUND_CONTEXT).catch(() => void 0);
609
665
  const lease = control.monitorOpen(null, true, BACKGROUND_CONTEXT).then(
610
666
  (opened) => opened.lease || null,
@@ -637,6 +693,10 @@ class MonitorAdapter {
637
693
  if (!feed?.open || feed.at === this.#hotAt) return;
638
694
  this.#hotAt = feed.at;
639
695
  this.#hot = hotGroups(feed.processes ?? [], feed.at, this.#hot);
696
+ const share = agentsCpu(feed);
697
+ if (share === null) return;
698
+ this.#cpu.push(share);
699
+ if (this.#cpu.length > CPU_HISTORY) this.#cpu.shift();
640
700
  }
641
701
  #update() {
642
702
  if (!this.#listeners) return;
@@ -651,6 +711,8 @@ export {
651
711
  BUDGET_ERROR,
652
712
  BUDGET_WARN,
653
713
  CONTEXT_WARN,
714
+ CPU_HISTORY,
715
+ CPU_QUIET,
654
716
  CPU_SHARE,
655
717
  CPU_SUSTAIN_MS,
656
718
  DEPTH_MAX,
@@ -667,8 +729,10 @@ export {
667
729
  TOTAL_MAX,
668
730
  ZOMBIE_MS,
669
731
  age,
732
+ agentsCpu,
670
733
  bytes,
671
734
  count,
735
+ cpuText,
672
736
  globalIntervals,
673
737
  groupCpu,
674
738
  hotGroups,
@@ -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 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 ROWS_MAX = 200;\nexport const HISTORY = 24;\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;\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}\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\nfunction memoryVital(processes: readonly MonitorProcess[]): MonitorVital[] {\n const measured = processes.filter((row) => typeof row.rss === 'number');\n if (!measured.length) return [];\n const total = measured.reduce((sum, row) => sum + (row.rss as number), 0);\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 },\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 contextRatio(agent: MonitorAgent, models: readonly ModelChoice[]): number | null {\n const window = models.find((model) => model.id === agent.model)?.contextWindow;\n if (!agent.context || !window) return null;\n return Math.min(1, agent.context / window);\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\nfunction budgetVital(budget: BudgetState): 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 : { unit: `resets ${resets.toISOString().slice(0, 16).replace('T', ' ')} UTC` }),\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 ...(series.length > 1 ? { series } : {}),\n });\n }\n const active = feed.agents.filter((agent) => agent.running).length;\n const actives = input.history.map((sample) => sample.active);\n out.push({\n id: 'agents',\n label: 'Active agents',\n value: String(active),\n unit: `of ${feed.agents.length}`,\n ...(actives.length > 1 ? { series: actives } : {}),\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 }\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 ?? []));\n const ratios = feed.agents\n .map((agent) => contextRatio(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 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): MonitorAlert => ({\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. Kill them with kill -- -${group.pgid}.`,\n severity: group.share >= CPU_SHARE * 2 || group.held >= CPU_SUSTAIN_MS * 2 ? 'error' : 'warn',\n })\n );\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): MonitorAlert[] {\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): MonitorAlert[] {\n const out: MonitorAlert[] = [];\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): MonitorAlert[] {\n const out: MonitorAlert[] = [];\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): MonitorAlert[] {\n const out: MonitorAlert[] = [];\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: `Kill them with kill -- -${pgid}.`,\n severity: members.length > GROUP_MAX * 2 ? 'error' : 'warn',\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): MonitorAlert[] {\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 (process.zombie !== null && input.now - process.zombie > ZOMBIE_MS)\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 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. Kill it with kill ${process.pid}.`,\n severity: input.now - process.started > STALE_MS * 2 ? 'error' : 'warn',\n });\n }\n return out;\n}\n\nfunction contextAlerts(input: MonitorInput, feed: MonitorFeed): MonitorAlert[] {\n const out: MonitorAlert[] = [];\n for (const agent of feed.agents) {\n const ratio = contextRatio(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): MonitorAlert[] {\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 agentRow(agent: MonitorAgent, depth: number, models: readonly ModelChoice[]): MonitorRow {\n const ratio = contextRatio(agent, models);\n const word = agent.retry\n ? 'retrying'\n : agent.running\n ? 'running'\n : agent.failed\n ? 'failed'\n : 'idle';\n const status: MonitorStatus = agent.retry\n ? 'warn'\n : agent.running\n ? 'active'\n : agent.failed\n ? 'error'\n : 'idle';\n const model = models.find((choice) => choice.id === agent.model)?.label ?? agent.model;\n const meta = [word, model, ratio === null ? null : `${Math.round(ratio * 100)}% context`]\n .filter(Boolean)\n .join(' \u00B7 ');\n const badges = [\n ...(agent.queued ? [`${agent.queued} queued`] : []),\n ...(agent.tool ? [agent.tool] : []),\n ...(agent.retry ? [`retry ${agent.retry.attempt}`] : []),\n ];\n return {\n id: agent.id,\n name: agent.name,\n meta,\n status,\n depth,\n ...(badges.length ? { badges } : {}),\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 processRows(input: MonitorInput, feed: MonitorFeed): MonitorRow[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const crowded = new Set<number>();\n for (const [pgid, members] of groups(feed.processes ?? []))\n if (members.length > GROUP_MAX) crowded.add(pgid);\n for (const group of busy(input, feed.processes ?? [])) crowded.add(group.pgid);\n return (feed.processes ?? []).map((process) => {\n const runaway = stale(process, agents, input.now) || crowded.has(process.pgid);\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 process.started ? age(input.now - process.started) : null,\n ]\n .filter(Boolean)\n .join(' \u00B7 '),\n status: runaway ? 'error' : process.state === 'Z' ? 'warn' : 'idle',\n ...(badges.length ? { badges } : {}),\n };\n });\n}\n\nconst PROBLEM_KINDS = { task: 'task failed', retry: 'retry', turn: 'turn failed' } as const;\n\nfunction depthOf(agents: ReadonlyMap<string, MonitorAgent>, agent: MonitorAgent): number {\n const visited = new Set<string>();\n let depth = 0;\n let current = agent;\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 depth++;\n current = parent;\n }\n return depth;\n}\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: 'agents',\n label: 'Cones and scoops',\n rows: ordered(feed).map((agent) =>\n agentRow(agent, Math.min(depthOf(agents, agent), DEPTH_MAX), input.models)\n ),\n },\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 {\n id: 'sprinkles',\n label: 'Sprinkles',\n rows: input.sprinkles.map((sprinkle) => ({\n name: sprinkle.title,\n meta: sprinkle.name,\n status: 'idle',\n })),\n },\n ...input.extra,\n ];\n}\n\nexport function monitorSnapshot(input: MonitorInput): MonitorSnapshot {\n const budget = input.budget ? [budgetVital(input.budget)] : [];\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 intervals?: Intervals;\n now?: () => number;\n}\n\ninterface Open {\n lease: Promise<string | null>;\n timer: 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 #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\n constructor(connection: AgentConnection, options: MonitorAdapterOptions = {}) {\n this.#connection = connection;\n this.#extra = options.extra ?? (() => []);\n this.#renewMs = options.renewMs ?? RENEW_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 connection.sprinkles?.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 sprinkles: this.#connection.sprinkles?.value ?? [],\n extra: this.#extra(),\n history: this.#history,\n now: this.#now(),\n hot: this.#hot,\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 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 = { lease, timer: this.#intervals.every(renew, this.#renewMs) };\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 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 this.#history.push({\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 if (this.#history.length > HISTORY) this.#history.shift();\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 }\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": "AAUA,SAAS,0BAA0B;AAUnC,SAAS,eAAe;AAEjB,MAAM,WAAW;AACjB,MAAM,WAAW;AACjB,MAAM,UAAU;AAChB,MAAM,cAAc;AACpB,MAAM,eAAe;AACrB,MAAM,aAAa;AACnB,MAAM,cAAc;AACpB,MAAM,gBAAgB;AACtB,MAAM,YAAY;AAClB,MAAM,WAAW;AACjB,MAAM,eAAe;AACrB,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,YAAY;AAClB,MAAM,WAAW;AACjB,MAAM,YAAY;AAClB,MAAM,iBAAiB;AACvB,MAAM,eAAe;AACrB,MAAM,YAAY;AACzB,MAAM,SAAS;AACf,MAAM,OAAO;AAqBb,MAAM,QAAgC;AAAA,EACpC,iBAAiB;AAAA,EACjB,iBAAiB;AAAA,EACjB,cAAc;AAAA,EACd,oBAAoB;AAAA,EACpB,wBAAwB;AAAA,EACxB,wBAAwB;AAC1B;AAEO,SAAS,IAAI,IAAoB;AACtC,QAAM,UAAU,KAAK,IAAI,GAAG,KAAK,MAAM,KAAK,GAAI,CAAC;AACjD,MAAI,UAAU,GAAI,QAAO,GAAG,OAAO;AACnC,MAAI,UAAU,KAAM,QAAO,GAAG,KAAK,MAAM,UAAU,EAAE,CAAC;AACtD,SAAO,GAAG,KAAK,MAAM,UAAU,IAAI,CAAC;AACtC;AAEO,SAAS,MAAM,OAAuB;AAC3C,MAAI,QAAQ,KAAK,QAAQ,KAAM,QAAO;AACtC,SAAO,IAAI,MAAM,QAAQ,CAAC,CAAC;AAC7B;AAEO,SAAS,MAAM,OAAuB;AAC3C,MAAI,QAAQ,IAAM,QAAO,OAAO,KAAK;AACrC,MAAI,QAAQ,IAAS,QAAO,IAAI,QAAQ,KAAM,QAAQ,CAAC,CAAC;AACxD,SAAO,IAAI,QAAQ,KAAS,QAAQ,CAAC,CAAC;AACxC;AAEO,SAAS,MAAM,OAAuB;AAC3C,MAAI,QAAQ,KAAM,QAAO,GAAG,KAAK;AACjC,QAAM,QAAQ,CAAC,OAAO,OAAO,OAAO,KAAK;AACzC,MAAI,OAAO,QAAQ;AACnB,MAAI,OAAO;AACX,SAAO,QAAQ,QAAQ,OAAO,MAAM,SAAS,GAAG;AAC9C,YAAQ;AACR;AAAA,EACF;AACA,SAAO,GAAG,KAAK,QAAQ,OAAO,KAAK,IAAI,CAAC,CAAC,IAAI,MAAM,IAAI,CAAC;AAC1D;AAEA,SAAS,YAAY,WAAsD;AACzE,QAAM,WAAW,UAAU,OAAO,CAAC,QAAQ,OAAO,IAAI,QAAQ,QAAQ;AACtE,MAAI,CAAC,SAAS,OAAQ,QAAO,CAAC;AAC9B,QAAM,QAAQ,SAAS,OAAO,CAAC,KAAK,QAAQ,MAAO,IAAI,KAAgB,CAAC;AACxE,QAAM,SAAS,SACZ,OAAO,CAAC,QAAQ,IAAI,OAAO,EAC3B,OAAO,CAAC,KAAK,QAAQ,MAAO,IAAI,KAAgB,CAAC;AACpD,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO,MAAM,KAAK;AAAA,MAClB,MAAM,GAAG,MAAM,MAAM,CAAC;AAAA,IACxB;AAAA,EACF;AACF;AAEO,SAAS,UAAU,MAA2B;AACnD,MAAI,KAAK,SAAS,UAAW,QAAO,KAAK,SAAS,QAAQ,KAAK,MAAM,KAAK;AAC1E,MAAI,KAAK,SAAS,qBAAsB,QAAO,KAAK,SAAS,SAAS,KAAK,MAAM,KAAK;AACtF,SAAO,MAAM,KAAK,IAAI,KAAK,KAAK;AAClC;AAEA,SAAS,OAAO,QAA2C,IAAkC;AAC3F,QAAM,UAAU,oBAAI,IAAY;AAChC,MAAI,UAAU,OAAO,OAAO,SAAY,OAAO,IAAI,EAAE;AACrD,SAAO,SAAS,YAAY,CAAC,QAAQ,IAAI,QAAQ,EAAE,GAAG;AACpD,YAAQ,IAAI,QAAQ,EAAE;AACtB,UAAM,SAAS,OAAO,IAAI,QAAQ,QAAQ;AAC1C,QAAI,CAAC,OAAQ;AACb,cAAU;AAAA,EACZ;AACA,SAAO,UAAU,QAAQ,KAAK;AAChC;AAEA,SAAS,QAAQ,MAAmC;AAClD,QAAM,OAAO,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AAClE,QAAM,MAAsB,CAAC;AAC7B,aAAW,QAAQ,KAAK,OAAO,OAAO,CAAC,UAAU,MAAM,SAAS,MAAM,GAAG;AACvE,QAAI,KAAK,IAAI;AACb,eAAW,SAAS,KAAK;AACvB,UAAI,MAAM,SAAS,WAAW,OAAO,MAAM,MAAM,EAAE,MAAM,KAAK,GAAI,KAAI,KAAK,KAAK;AAAA,EACpF;AACA,aAAW,SAAS,KAAK,OAAQ,KAAI,CAAC,IAAI,SAAS,KAAK,EAAG,KAAI,KAAK,KAAK;AACzE,SAAO;AACT;AAEO,SAAS,SAAS,MAA2D;AAClF,QAAM,SAAS,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AACpE,QAAM,QAAQ,QAAQ,IAAI,EAAE,IAAI,CAAC,UAAU,MAAM,EAAE;AACnD,QAAM,OAAO,CAAC,SAAsB;AAClC,UAAM,KAAK,KAAK,YAAY,OAAO,KAAK,MAAM,QAAQ,KAAK,OAAO;AAClE,WAAO,KAAK,IAAI,MAAM,SAAS;AAAA,EACjC;AACA,QAAM,UAAU,CAAC,SAAsB,OAAO,QAAQ,KAAK,OAAO,KAAK;AACvE,QAAM,OAAO,IAAI,IAAI,KAAK,MAAM,IAAI,CAAC,SAAS,CAAC,KAAK,IAAI,IAAI,CAAC,CAAC;AAC9D,QAAM,WAAW,oBAAI,IAA2B;AAChD,QAAM,QAAuB,CAAC;AAC9B,aAAW,QAAQ,KAAK,OAAO;AAC7B,UAAM,QAAQ,KAAK,UAAU,OAAO,SAAY,KAAK,IAAI,KAAK,KAAK;AACnE,QAAI,SAAS,QAAQ,KAAK,MAAM,QAAQ,IAAI,GAAG;AAC7C,YAAM,OAAO,SAAS,IAAI,MAAM,EAAE,KAAK,CAAC;AACxC,WAAK,KAAK,IAAI;AACd,eAAS,IAAI,MAAM,IAAI,IAAI;AAAA,IAC7B,MAAO,OAAM,KAAK,IAAI;AAAA,EACxB;AACA,QAAM,OAAO,CAAC,SACZ,KAAK,KAAK,CAAC,GAAG,MAAM,KAAK,CAAC,IAAI,KAAK,CAAC,KAAK,OAAO,EAAE,EAAE,IAAI,OAAO,EAAE,EAAE,CAAC;AACtE,QAAM,MAA8C,CAAC;AACrD,QAAM,QAAQ,CAAC,MAAmB,UAAkB;AAClD,QAAI,KAAK,EAAE,MAAM,MAAM,CAAC;AACxB,eAAW,SAAS,KAAK,SAAS,IAAI,KAAK,EAAE,KAAK,CAAC,CAAC,EAAG,OAAM,OAAO,QAAQ,CAAC;AAAA,EAC/E;AACA,aAAW,QAAQ,KAAK,KAAK,EAAG,OAAM,MAAM,CAAC;AAC7C,SAAO;AACT;AAEA,SAAS,OAAO,MAAkC;AAChD,MAAI,KAAK,UAAU,SAAU,QAAO;AACpC,QAAM,QAAQ,KAAK,MAAM,GAAG,WAAW,CAAC;AACxC,SAAO;AAAA,IACL,GAAG;AAAA,IACH,EAAE,IAAI,QAAQ,MAAM,IAAI,KAAK,SAAS,MAAM,MAAM,SAAS,MAAM,IAAI,QAAQ,OAAO;AAAA,EACtF;AACF;AAEA,SAAS,aAAa,OAAqB,QAA+C;AACxF,QAAM,SAAS,OAAO,KAAK,CAAC,UAAU,MAAM,OAAO,MAAM,KAAK,GAAG;AACjE,MAAI,CAAC,MAAM,WAAW,CAAC,OAAQ,QAAO;AACtC,SAAO,KAAK,IAAI,GAAG,MAAM,UAAU,MAAM;AAC3C;AAEA,SAAS,KAAK,SAA4B,MAAiD;AACzF,QAAM,QAAQ,QAAQ,CAAC;AACvB,QAAM,OAAO,QAAQ,GAAG,EAAE;AAC1B,MAAI,CAAC,SAAS,CAAC,QAAQ,KAAK,KAAK,MAAM,KAAK,OAAQ,QAAO;AAC3D,UAAS,KAAK,IAAI,IAAI,KAAK,KAAK,MAAM,KAAK,KAAK,MAAM,MAAO;AAC/D;AAEA,SAAS,YAAY,QAAmC;AACtD,QAAM,SAAS,IAAI,KAAK,OAAO,MAAM;AACrC,SAAO;AAAA,IACL,IAAI;AAAA,IACJ,OAAO,WAAW,OAAO,MAAM;AAAA,IAC/B,OAAO,GAAG,OAAO,OAAO;AAAA,IACxB,GAAI,OAAO,MAAM,OAAO,QAAQ,CAAC,IAC7B,CAAC,IACD,EAAE,MAAM,UAAU,OAAO,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,KAAK,GAAG,CAAC,OAAO;AAAA,IAChF,OAAO,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,UAAU,GAAG,CAAC;AAAA,EACtD;AACF;AAEA,SAAS,OAAO,OAAqB,MAAmC;AACtE,QAAM,MAAsB,CAAC;AAC7B,MAAI,KAAK,OAAO;AACd,UAAM,OAAO,KAAK,MAAM;AACxB,UAAM,OAAO,CAAC,WAAoB,OAAO,OAAO,SAAS,OAAO;AAChE,UAAM,UAAU,KAAK,MAAM,SAAS,IAAI;AACxC,UAAM,SAAS,MAAM,QAAQ,IAAI,IAAI;AACrC,QAAI,KAAK;AAAA,MACP,IAAI;AAAA,MACJ,OAAO,OAAO,WAAW;AAAA,MACzB,OAAO,OAAO,MAAM,KAAK,MAAM,MAAM,IAAI,MAAM,KAAK,MAAM,IAAI;AAAA,MAC9D,MAAM,OAAO,WAAW,GAAG,MAAM,KAAK,MAAM,MAAM,CAAC;AAAA,MACnD,GAAI,YAAY,OAAO,CAAC,IAAI,EAAE,OAAO,GAAG,OAAO,MAAM,OAAO,IAAI,MAAM,OAAO,CAAC,KAAK;AAAA,MACnF,GAAI,OAAO,SAAS,IAAI,EAAE,OAAO,IAAI,CAAC;AAAA,IACxC,CAAC;AAAA,EACH;AACA,QAAM,SAAS,KAAK,OAAO,OAAO,CAAC,UAAU,MAAM,OAAO,EAAE;AAC5D,QAAM,UAAU,MAAM,QAAQ,IAAI,CAAC,WAAW,OAAO,MAAM;AAC3D,MAAI,KAAK;AAAA,IACP,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO,OAAO,MAAM;AAAA,IACpB,MAAM,MAAM,KAAK,OAAO,MAAM;AAAA,IAC9B,GAAI,QAAQ,SAAS,IAAI,EAAE,QAAQ,QAAQ,IAAI,CAAC;AAAA,EAClD,CAAC;AACD,QAAM,QAAQ,KAAK,MAAM;AAAA,IACvB,CAAC,SAAS,KAAK,SAAS,aAAa,KAAK,WAAW;AAAA,EACvD,EAAE;AACF,MAAI,KAAK;AAAA,IACP,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,OAAO,OAAO,KAAK;AAAA,IACnB,MAAM,GAAG,UAAU,IAAI,SAAS,OAAO,SAAM,KAAK,MAAM,MAAM,IAAI,KAAK,MAAM,WAAW,IAAI,SAAS,OAAO;AAAA,EAC9G,CAAC;AACD,MAAI;AAAA,IACF,KAAK,YACD;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO,OAAO,KAAK,UAAU,MAAM;AAAA,MACnC,MAAM,GAAG,KAAK,UAAU,OAAO,CAAC,QAAQ,IAAI,OAAO,EAAE,MAAM;AAAA,IAC7D,IACA,KAAK,WAAW,aACd,EAAE,IAAI,aAAa,OAAO,aAAa,OAAO,UAAK,MAAM,WAAW,IACpE,EAAE,IAAI,aAAa,OAAO,aAAa,OAAO,UAAK,MAAM,uBAAuB;AAAA,EACxF;AACA,MAAI,KAAK,GAAG,YAAY,KAAK,aAAa,CAAC,CAAC,CAAC;AAC7C,QAAM,SAAS,KAAK,OACjB,IAAI,CAAC,UAAU,aAAa,OAAO,MAAM,MAAM,CAAC,EAChD,OAAO,CAAC,UAA2B,UAAU,IAAI;AACpD,MAAI,OAAO,QAAQ;AACjB,UAAM,UAAU,KAAK,IAAI,GAAG,MAAM;AAClC,QAAI,KAAK;AAAA,MACP,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,OAAO,GAAG,KAAK,MAAM,UAAU,GAAG,CAAC;AAAA,MACnC,OAAO;AAAA,IACT,CAAC;AAAA,EACH;AACA,SAAO;AACT;AAEA,SAAS,MAAM,SAAyB,QAA2C,KAAa;AAC9F,MAAI,CAAC,QAAQ,WAAW,QAAQ,UAAU,OAAO,CAAC,QAAQ,QAAS,QAAO;AAC1E,MAAI,OAAO,QAAQ,UAAU,SAAU,QAAO;AAC9C,MAAI,OAAO,IAAI,QAAQ,OAAO,GAAG,SAAS,OAAQ,QAAO;AACzD,SAAO,MAAM,QAAQ,UAAU;AACjC;AAEA,SAAS,OAAO,WAAqE;AACnF,QAAM,MAAM,oBAAI,IAA8B;AAC9C,aAAW,WAAW,WAAW;AAC/B,QAAI,CAAC,QAAQ,QAAS;AACtB,UAAM,OAAO,IAAI,IAAI,QAAQ,IAAI,KAAK,CAAC;AACvC,SAAK,KAAK,OAAO;AACjB,QAAI,IAAI,QAAQ,MAAM,IAAI;AAAA,EAC5B;AACA,SAAO;AACT;AAIO,SAAS,SACd,WACiD;AACjD,QAAM,MAAM,oBAAI,IAAgD;AAChE,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,SAAS,GAAG;AAC/C,UAAM,WAAW,QAAQ,OAAO,CAAC,QAAQ,OAAO,IAAI,QAAQ,QAAQ;AACpE,QAAI,CAAC,SAAS,OAAQ;AACtB,UAAM,QAAQ,SAAS,OAAO,CAAC,KAAK,QAAQ,MAAO,IAAI,KAAgB,CAAC;AACxE,QAAI,IAAI,MAAM,EAAE,SAAU,QAAQ,CAAC,EAAqB,SAAmB,MAAM,CAAC;AAAA,EACpF;AACA,SAAO;AACT;AAEO,SAAS,UACd,WACA,IACA,UACqB;AACrB,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,CAAC,MAAM,EAAE,MAAM,CAAC,KAAK,SAAS,SAAS;AAChD,QAAI,SAAS,UAAW,KAAI,IAAI,MAAM,SAAS,IAAI,IAAI,KAAK,EAAE;AAChE,SAAO;AACT;AAEA,SAAS,KAAK,OAAqB,WAAsC;AACvE,QAAM,SAAS,SAAS,SAAS;AACjC,QAAM,MAAwE,CAAC;AAC/E,aAAW,CAAC,MAAM,KAAK,KAAK,MAAM,OAAO,CAAC,GAAG;AAC3C,UAAM,QAAQ,OAAO,IAAI,IAAI;AAC7B,UAAM,OAAO,MAAM,MAAM;AACzB,QAAI,SAAS,MAAM,SAAS,aAAa,QAAQ;AAC/C,UAAI,KAAK,EAAE,MAAM,GAAG,OAAO,KAAK,CAAC;AAAA,EACrC;AACA,SAAO;AACT;AAEA,SAAS,UAAU,OAAqB,WAAsC,QAAe;AAC3F,SAAO,KAAK,OAAO,SAAS,EAAE;AAAA,IAC5B,CAAC,WAAyB;AAAA,MACxB,IAAI,eAAe,MAAM,IAAI;AAAA,MAC7B,OAAO,GAAG,OAAO,MAAM,OAAO,CAAC;AAAA,MAC/B,QAAQ,GAAG,KAAK,MAAM,MAAM,QAAQ,GAAG,CAAC,qBAAqB,KAAK,MAAM,MAAM,OAAO,MAAM,CAAC,qCAAqC,MAAM,IAAI;AAAA,MAC3I,UAAU,MAAM,SAAS,YAAY,KAAK,MAAM,QAAQ,iBAAiB,IAAI,UAAU;AAAA,IACzF;AAAA,EACF;AACF;AAEA,SAAS,UAAU,QAA6B;AAC9C,QAAM,SAAS,IAAI,KAAK,OAAO,MAAM;AACrC,SAAO,OAAO,MAAM,OAAO,QAAQ,CAAC,IAChC,OAAO,OAAO,MAAM,+BACpB,UAAU,OAAO,YAAY,EAAE,MAAM,GAAG,EAAE,EAAE,QAAQ,KAAK,GAAG,CAAC;AACnE;AAEA,SAAS,aAAa,QAAwD;AAC5E,MAAI,CAAC,UAAU,OAAO,UAAU,YAAa,QAAO,CAAC;AACrD,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,OAAO,UAAU,OAAO,OAAO;AAAA,MAC/B,QAAQ,UAAU,MAAM;AAAA,MACxB,UAAU,OAAO,WAAW,eAAe,UAAU;AAAA,IACvD;AAAA,EACF;AACF;AAEA,SAAS,YAAY,OAAqB,MAAmC;AAC3E,QAAM,MAAsB,CAAC;AAC7B,aAAW,SAAS,KAAK,QAAQ;AAC/B,UAAM,QAAQ,MAAM;AACpB,QAAI,UAAU,MAAM,WAAW,cAAc,MAAM,MAAM,MAAM,QAAQ;AACrE,UAAI,KAAK;AAAA,QACP,IAAI,SAAS,MAAM,EAAE;AAAA,QACrB,OAAO,GAAG,MAAM,IAAI,yBAAyB,MAAM,OAAO;AAAA,QAC1D,QAAQ,MAAM;AAAA,QACd,UAAU,MAAM,WAAW,cAAc,UAAU;AAAA,MACrD,CAAC;AACH,QAAI,MAAM,UAAU,CAAC,MAAM;AACzB,UAAI,KAAK;AAAA,QACP,IAAI,QAAQ,MAAM,EAAE;AAAA,QACpB,OAAO,GAAG,MAAM,IAAI;AAAA,QACpB,QAAQ,MAAM;AAAA,QACd,UAAU;AAAA,MACZ,CAAC;AAAA,EACL;AACA,SAAO;AACT;AAEA,SAAS,WAAW,OAAqB,MAAmB,QAA+B;AACzF,QAAM,MAAsB,CAAC;AAC7B,aAAW,WAAW,KAAK;AACzB,QAAI,QAAQ,SAAS,UAAU,MAAM,MAAM,QAAQ,KAAK;AACtD,UAAI,KAAK;AAAA,QACP,IAAI,UAAU,QAAQ,EAAE;AAAA,QACxB,OAAO,aAAa,OAAO,QAAQ,OAAO,CAAC;AAAA,QAC3C,QAAQ,QAAQ;AAAA,QAChB,UAAU;AAAA,MACZ,CAAC;AACL,aAAW,QAAQ,KAAK;AACtB,QAAI,KAAK,aAAa,QAAQ,MAAM,MAAM,KAAK,WAAW;AACxD,UAAI,KAAK;AAAA,QACP,IAAI,SAAS,KAAK,EAAE;AAAA,QACpB,OAAO,6BAA6B,UAAU,IAAI,CAAC;AAAA,QACnD,QAAQ,GAAG,OAAO,KAAK,OAAO,CAAC,qBAAqB,IAAI,MAAM,MAAM,KAAK,QAAQ,CAAC;AAAA,QAClF,UAAU;AAAA,MACZ,CAAC;AACL,SAAO;AACT;AAEA,SAAS,YAAY,WAAsC,QAA+B;AACxF,QAAM,MAAsB,CAAC;AAC7B,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,SAAS;AAC5C,QAAI,QAAQ,SAAS;AACnB,UAAI,KAAK;AAAA,QACP,IAAI,WAAW,IAAI;AAAA,QACnB,OAAO,GAAG,OAAQ,QAAQ,CAAC,EAAqB,OAAO,CAAC,QAAQ,QAAQ,MAAM;AAAA,QAC9E,QAAQ,2BAA2B,IAAI;AAAA,QACvC,UAAU,QAAQ,SAAS,YAAY,IAAI,UAAU;AAAA,MACvD,CAAC;AACL,MAAI,UAAU,SAAS;AACrB,QAAI,KAAK;AAAA,MACP,IAAI;AAAA,MACJ,OAAO,kBAAkB,UAAU,MAAM;AAAA,MACzC,QAAQ;AAAA,MACR,UAAU,UAAU,SAAS,YAAY,IAAI,UAAU;AAAA,IACzD,CAAC;AACH,SAAO;AACT;AAEA,SAAS,cAAc,OAAqB,MAAmB,QAA+B;AAC5F,QAAM,YAAY,KAAK,aAAa,CAAC;AACrC,QAAM,SAAS,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AACpE,QAAM,MAAM,CAAC,GAAG,YAAY,WAAW,MAAM,GAAG,GAAG,UAAU,OAAO,WAAW,MAAM,CAAC;AACtF,aAAW,WAAW,WAAW;AAC/B,QAAI,QAAQ,WAAW,QAAQ,MAAM,MAAM,QAAQ,SAAS;AAC1D,UAAI,KAAK;AAAA,QACP,IAAI,UAAU,QAAQ,GAAG;AAAA,QACzB,OAAO,WAAW,QAAQ,GAAG;AAAA,QAC7B,QAAQ,cAAc,QAAQ,IAAI;AAAA,QAClC,UAAU;AAAA,MACZ,CAAC;AACH,QAAI,MAAM,SAAS,QAAQ,MAAM,GAAG;AAClC,UAAI,KAAK;AAAA,QACP,IAAI,SAAS,QAAQ,GAAG;AAAA,QACxB,OAAO,GAAG,QAAQ,WAAW,WAAW,QAAQ,GAAG,EAAE,gBAAgB,IAAI,MAAM,MAAM,QAAQ,OAAO,CAAC;AAAA,QACrG,QAAQ,GAAG,OAAO,QAAQ,OAAO,CAAC,oDAAoD,QAAQ,GAAG;AAAA,QACjG,UAAU,MAAM,MAAM,QAAQ,UAAU,WAAW,IAAI,UAAU;AAAA,MACnE,CAAC;AAAA,EACL;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAAqB,MAAmC;AAC7E,QAAM,MAAsB,CAAC;AAC7B,aAAW,SAAS,KAAK,QAAQ;AAC/B,UAAM,QAAQ,aAAa,OAAO,MAAM,MAAM;AAC9C,QAAI,UAAU,QAAQ,SAAS;AAC7B,UAAI,KAAK;AAAA,QACP,IAAI,WAAW,MAAM,EAAE;AAAA,QACvB,OAAO,GAAG,MAAM,IAAI,OAAO,KAAK,MAAM,QAAQ,GAAG,CAAC;AAAA,QAClD,QAAQ;AAAA,QACR,UAAU;AAAA,MACZ,CAAC;AAAA,EACL;AACA,MAAI,KAAK;AACP,QAAI,KAAK;AAAA,MACP,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,QAAQ;AAAA,MACR,UAAU;AAAA,IACZ,CAAC;AACH,SAAO;AACT;AAEA,SAAS,OAAO,OAAqB,MAAmC;AACtE,QAAM,SAAS,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AACpE,QAAM,SAAgB,CAAC,OAAQ,KAAM,OAAO,IAAI,EAAE,GAAG,QAAQ,KAAM;AACnE,SAAO;AAAA,IACL,GAAG,aAAa,MAAM,MAAM;AAAA,IAC5B,GAAG,YAAY,OAAO,IAAI;AAAA,IAC1B,GAAG,WAAW,OAAO,MAAM,MAAM;AAAA,IACjC,GAAG,cAAc,OAAO,MAAM,MAAM;AAAA,IACpC,GAAG,cAAc,OAAO,IAAI;AAAA,EAC9B;AACF;AAEA,SAAS,SAAS,OAAqB,OAAe,QAA4C;AAChG,QAAM,QAAQ,aAAa,OAAO,MAAM;AACxC,QAAM,OAAO,MAAM,QACf,aACA,MAAM,UACJ,YACA,MAAM,SACJ,WACA;AACR,QAAM,SAAwB,MAAM,QAChC,SACA,MAAM,UACJ,WACA,MAAM,SACJ,UACA;AACR,QAAM,QAAQ,OAAO,KAAK,CAAC,WAAW,OAAO,OAAO,MAAM,KAAK,GAAG,SAAS,MAAM;AACjF,QAAM,OAAO,CAAC,MAAM,OAAO,UAAU,OAAO,OAAO,GAAG,KAAK,MAAM,QAAQ,GAAG,CAAC,WAAW,EACrF,OAAO,OAAO,EACd,KAAK,QAAK;AACb,QAAM,SAAS;AAAA,IACb,GAAI,MAAM,SAAS,CAAC,GAAG,MAAM,MAAM,SAAS,IAAI,CAAC;AAAA,IACjD,GAAI,MAAM,OAAO,CAAC,MAAM,IAAI,IAAI,CAAC;AAAA,IACjC,GAAI,MAAM,QAAQ,CAAC,SAAS,MAAM,MAAM,OAAO,EAAE,IAAI,CAAC;AAAA,EACxD;AACA,SAAO;AAAA,IACL,IAAI,MAAM;AAAA,IACV,MAAM,MAAM;AAAA,IACZ;AAAA,IACA;AAAA,IACA;AAAA,IACA,GAAI,OAAO,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EACpC;AACF;AAEA,SAAS,QACP,MACA,OACA,QACA,KACY;AACZ,QAAM,WAAW,KAAK,aAAa,QAAQ,MAAM,KAAK,WAAW;AACjE,QAAM,SAAwB,WAC1B,SACA,KAAK,WAAW,aAAa,KAAK,WAAW,eAC3C,WACA;AACN,QAAM,SAAS;AAAA,IACb,GAAI,KAAK,aAAa,CAAC,YAAY,IAAI,CAAC;AAAA,IACxC,GAAI,KAAK,aAAa,OAAO,CAAC,UAAU,IAAI,CAAC;AAAA,IAC7C,GAAI,KAAK,QAAQ,CAAC,YAAY,KAAK,KAAK,EAAE,IAAI,CAAC;AAAA,EACjD;AACA,SAAO;AAAA,IACL,IAAI,KAAK;AAAA,IACT,MAAM,UAAU,IAAI;AAAA,IACpB,OAAO,KAAK,IAAI,OAAO,SAAS;AAAA,IAChC,MAAM,CAAC,OAAO,KAAK,OAAO,GAAG,KAAK,OAAO,IAAI,MAAM,KAAK,KAAK,CAAC,EAAE,OAAO,OAAO,EAAE,KAAK,QAAK;AAAA,IAC1F;AAAA,IACA,GAAI,OAAO,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,EACpC;AACF;AAEA,SAAS,YAAY,OAAqB,MAAiC;AACzE,QAAM,SAAS,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AACpE,QAAM,UAAU,oBAAI,IAAY;AAChC,aAAW,CAAC,MAAM,OAAO,KAAK,OAAO,KAAK,aAAa,CAAC,CAAC;AACvD,QAAI,QAAQ,SAAS,UAAW,SAAQ,IAAI,IAAI;AAClD,aAAW,SAAS,KAAK,OAAO,KAAK,aAAa,CAAC,CAAC,EAAG,SAAQ,IAAI,MAAM,IAAI;AAC7E,UAAQ,KAAK,aAAa,CAAC,GAAG,IAAI,CAAC,YAAY;AAC7C,UAAM,UAAU,MAAM,SAAS,QAAQ,MAAM,GAAG,KAAK,QAAQ,IAAI,QAAQ,IAAI;AAC7E,UAAM,SAAS;AAAA,MACb,GAAI,QAAQ,UAAU,CAAC,OAAO,IAAI,QAAQ,OAAO,GAAG,QAAQ,QAAQ,OAAO,IAAI,CAAC;AAAA,MAChF,GAAI,QAAQ,MAAM,CAAC,UAAU,IAAI,CAAC;AAAA,IACpC;AACA,WAAO;AAAA,MACL,IAAI,OAAO,QAAQ,GAAG;AAAA,MACtB,MAAM,QAAQ,WAAW,IAAI,QAAQ,GAAG;AAAA,MACxC,MAAM;AAAA,QACJ,OAAO,QAAQ,GAAG;AAAA,QAClB,QAAQ;AAAA,QACR,OAAO,QAAQ,QAAQ,WAAW,MAAM,QAAQ,GAAG,IAAI;AAAA,QACvD,QAAQ,UAAU,IAAI,MAAM,MAAM,QAAQ,OAAO,IAAI;AAAA,MACvD,EACG,OAAO,OAAO,EACd,KAAK,QAAK;AAAA,MACb,QAAQ,UAAU,UAAU,QAAQ,UAAU,MAAM,SAAS;AAAA,MAC7D,GAAI,OAAO,SAAS,EAAE,OAAO,IAAI,CAAC;AAAA,IACpC;AAAA,EACF,CAAC;AACH;AAEA,MAAM,gBAAgB,EAAE,MAAM,eAAe,OAAO,SAAS,MAAM,cAAc;AAEjF,SAAS,QAAQ,QAA2C,OAA6B;AACvF,QAAM,UAAU,oBAAI,IAAY;AAChC,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,SAAO,QAAQ,YAAY,CAAC,QAAQ,IAAI,QAAQ,EAAE,GAAG;AACnD,YAAQ,IAAI,QAAQ,EAAE;AACtB,UAAM,SAAS,OAAO,IAAI,QAAQ,QAAQ;AAC1C,QAAI,CAAC,OAAQ;AACb;AACA,cAAU;AAAA,EACZ;AACA,SAAO;AACT;AAEA,SAAS,SAAS,OAAqB,MAAqC;AAC1E,QAAM,SAAS,IAAI,IAAI,KAAK,OAAO,IAAI,CAAC,UAAU,CAAC,MAAM,IAAI,KAAK,CAAC,CAAC;AACpE,QAAM,SAAS,CAAC,OAAuB,KAAM,OAAO,IAAI,EAAE,GAAG,QAAQ,KAAM;AAC3E,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM,QAAQ,IAAI,EAAE;AAAA,QAAI,CAAC,UACvB,SAAS,OAAO,KAAK,IAAI,QAAQ,QAAQ,KAAK,GAAG,SAAS,GAAG,MAAM,MAAM;AAAA,MAC3E;AAAA,IACF;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM;AAAA,QACJ,SAAS,IAAI,EAAE,IAAI,CAAC,EAAE,MAAM,MAAM,MAAM,QAAQ,MAAM,OAAO,QAAQ,MAAM,GAAG,CAAC;AAAA,MACjF;AAAA,IACF;AAAA,IACA,EAAE,IAAI,aAAa,OAAO,aAAa,MAAM,OAAO,YAAY,OAAO,IAAI,CAAC,EAAE;AAAA,IAC9E;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM,KAAK,SAAS,IAAI,CAAC,aAAa;AAAA,QACpC,IAAI,QAAQ;AAAA,QACZ,MAAM,GAAG,OAAO,QAAQ,OAAO,CAAC,SAAM,cAAc,QAAQ,IAAI,CAAC;AAAA,QACjE,MAAM,QAAQ;AAAA,QACd,QAAQ,QAAQ,SAAS,UAAU,SAAS;AAAA,MAC9C,EAAE;AAAA,IACJ;AAAA,EACF;AACF;AAEA,SAAS,aAAa,OAAuC;AAC3D,SAAO;AAAA,IACL;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM,MAAM,QAAQ,IAAI,CAAC,YAAY;AAAA,QACnC,IAAI,OAAO;AAAA,QACX,MAAM,OAAO;AAAA,QACb,MAAM,OAAO;AAAA,QACb,QAAQ;AAAA,MACV,EAAE;AAAA,IACJ;AAAA,IACA;AAAA,MACE,IAAI;AAAA,MACJ,OAAO;AAAA,MACP,MAAM,MAAM,UAAU,IAAI,CAAC,cAAc;AAAA,QACvC,MAAM,SAAS;AAAA,QACf,MAAM,SAAS;AAAA,QACf,QAAQ;AAAA,MACV,EAAE;AAAA,IACJ;AAAA,IACA,GAAG,MAAM;AAAA,EACX;AACF;AAEO,SAAS,gBAAgB,OAAsC;AACpE,QAAM,SAAS,MAAM,SAAS,CAAC,YAAY,MAAM,MAAM,CAAC,IAAI,CAAC;AAC7D,QAAM,OAAO,MAAM;AACnB,MAAI,CAAC,MAAM;AACT,WAAO;AAAA,MACL,QAAQ;AAAA,MACR,QAAQ,CAAC;AAAA,MACT,UAAU,aAAa,KAAK;AAAA,MAC5B,WAAW,MAAM;AAAA,IACnB;AACF,SAAO;AAAA,IACL,QAAQ,CAAC,GAAG,QAAQ,GAAG,OAAO,OAAO,IAAI,CAAC;AAAA,IAC1C,QAAQ,OAAO,OAAO,IAAI;AAAA,IAC1B,UAAU,CAAC,GAAG,SAAS,OAAO,IAAI,GAAG,GAAG,aAAa,KAAK,CAAC;AAAA,IAC3D,WAAW,KAAK;AAAA,EAClB;AACF;AAOO,MAAM,kBAA6B;AAAA,EACxC,OAAO,CAAC,KAAK,OAAO,YAAY,KAAK,EAAE;AAAA,EACvC,MAAM,CAAC,WAAW,cAAc,MAAwC;AAC1E;AAcO,MAAM,eAAsC;AAAA,EACxC;AAAA,EACA,WAAW,IAAI,QAAuB;AAAA,EACtC;AAAA,EACA;AAAA,EACA;AAAA,EACA;AAAA,EACT,aAAa;AAAA,EACb;AAAA,EACA,WAAqB,CAAC;AAAA,EACtB,OAAO,oBAAI,IAAoB;AAAA,EAC/B,SAAS;AAAA,EAET,YAAY,YAA6B,UAAiC,CAAC,GAAG;AAC5E,SAAK,cAAc;AACnB,SAAK,SAAS,QAAQ,UAAU,MAAM,CAAC;AACvC,SAAK,WAAW,QAAQ,WAAW;AACnC,SAAK,aAAa,QAAQ,aAAa;AACvC,SAAK,OAAO,QAAQ,OAAO,KAAK;AAChC,eAAW,SAAS,UAAU,MAAM,KAAK,QAAQ,CAAC;AAClD,eAAW,SAAS,MAAM,UAAU,MAAM,KAAK,QAAQ,CAAC;AACxD,eAAW,SAAS,UAAU,MAAM,KAAK,QAAQ,CAAC;AAClD,eAAW,WAAW,UAAU,MAAM,KAAK,QAAQ,CAAC;AAAA,EACtD;AAAA,EAEA,GACE,MACA,UACY;AACZ,UAAM,MAAM,KAAK,SAAS,GAAG,MAAM,QAAQ;AAC3C,SAAK;AACL,QAAI,KAAK,eAAe,EAAG,MAAK,OAAO;AACvC,QAAI,OAAO;AACX,WAAO,MAAM;AACX,UAAI,KAAM;AACV,aAAO;AACP,UAAI;AACJ,WAAK;AACL,UAAI,CAAC,KAAK,WAAY,MAAK,MAAM;AAAA,IACnC;AAAA,EACF;AAAA,EAEA,WAA4B;AAC1B,UAAM,WAAW,KAAK,YAAY,SAAS,MAAM;AACjD,WAAO,gBAAgB;AAAA,MACrB,MAAM,KAAK,YAAY,SAAS;AAAA,MAChC,QAAQ,UAAU;AAAA,MAClB,QAAQ,UAAU,UAAU,CAAC;AAAA,MAC7B,SAAS,KAAK,YAAY,SAAS,OAAO,WAAW,CAAC;AAAA,MACtD,WAAW,KAAK,YAAY,WAAW,SAAS,CAAC;AAAA,MACjD,OAAO,KAAK,OAAO;AAAA,MACnB,SAAS,KAAK;AAAA,MACd,KAAK,KAAK,KAAK;AAAA,MACf,KAAK,KAAK;AAAA,IACZ,CAAC;AAAA,EACH;AAAA,EAEA,SAAe;AACb,UAAM,OAAO,KAAK;AAClB,UAAM,UAAU,KAAK,YAAY;AACjC,QAAI;AACF,WAAK,KAAK,MACP,KAAK,CAAC,UAAW,QAAQ,QAAQ,YAAY,OAAO,MAAM,kBAAkB,IAAI,MAAU,EAC1F,MAAM,MAAM,MAAS;AAC1B,SAAK,SAAS,KAAK,YAAY,KAAK,SAAS,CAAC;AAAA,EAChD;AAAA,EAEA,SAAe;AACb,UAAM,UAAU,KAAK,YAAY;AACjC,SAAK,WAAW,CAAC;AACjB,SAAK,OAAO,oBAAI,IAAI;AACpB,SAAK,SAAS;AACd,SAAK,QAAQ,YAAY,kBAAkB,EAAE,MAAM,MAAM,MAAS;AAClE,UAAM,QAAQ,QAAQ,YAAY,MAAM,MAAM,kBAAkB,EAAE;AAAA,MAChE,CAAC,WAAW,OAAO,SAAS;AAAA,MAC5B,MAAM;AAAA,IACR;AACA,UAAM,QAAQ,MACZ,KAAK,MACF,KAAK,CAAC,SAAU,OAAO,QAAQ,YAAY,MAAM,OAAO,kBAAkB,IAAI,MAAU,EACxF,MAAM,MAAM,MAAS;AAC1B,SAAK,QAAQ,EAAE,OAAO,OAAO,KAAK,WAAW,MAAM,OAAO,KAAK,QAAQ,EAAE;AAAA,EAC3E;AAAA,EAEA,QAAc;AACZ,UAAM,OAAO,KAAK;AAClB,QAAI,CAAC,KAAM;AACX,SAAK,QAAQ;AACb,SAAK,WAAW,KAAK,KAAK,KAAK;AAC/B,UAAM,UAAU,KAAK,YAAY;AACjC,SAAK,KAAK,MACP,KAAK,CAAC,SAAU,OAAO,QAAQ,aAAa,MAAM,kBAAkB,IAAI,MAAU,EAClF,MAAM,MAAM,MAAS;AAAA,EAC1B;AAAA,EAEA,UAAgB;AACd,UAAM,OAAO,KAAK,YAAY,SAAS;AACvC,QAAI,CAAC,MAAM,QAAQ,CAAC,KAAK,SAAS,KAAK,SAAS,GAAG,EAAE,GAAG,OAAO,KAAK,GAAI;AACxE,SAAK,SAAS,KAAK;AAAA,MACjB,IAAI,KAAK;AAAA,MACT,MAAM,KAAK,MAAM;AAAA,MACjB,QAAQ,KAAK,MAAM;AAAA,MACnB,QAAQ,KAAK,OAAO,OAAO,CAAC,UAAU,MAAM,OAAO,EAAE;AAAA,IACvD,CAAC;AACD,QAAI,KAAK,SAAS,SAAS,QAAS,MAAK,SAAS,MAAM;AAAA,EAC1D;AAAA,EAEA,SAAe;AACb,UAAM,OAAO,KAAK,YAAY,SAAS;AACvC,QAAI,CAAC,MAAM,QAAQ,KAAK,OAAO,KAAK,OAAQ;AAC5C,SAAK,SAAS,KAAK;AACnB,SAAK,OAAO,UAAU,KAAK,aAAa,CAAC,GAAG,KAAK,IAAI,KAAK,IAAI;AAAA,EAChE;AAAA,EAEA,UAAgB;AACd,QAAI,CAAC,KAAK,WAAY;AACtB,SAAK,QAAQ;AACb,SAAK,OAAO;AACZ,SAAK,SAAS,KAAK,YAAY,KAAK,SAAS,CAAC;AAAA,EAChD;AACF;",
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 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 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;\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}\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 ...(history.length > 1 ? { series: history.map((value) => Math.round(value * 100)) } : {}),\n },\n ];\n}\n\nfunction memoryVital(processes: readonly MonitorProcess[]): MonitorVital[] {\n const measured = processes.filter((row) => typeof row.rss === 'number');\n if (!measured.length) return [];\n const total = measured.reduce((sum, row) => sum + (row.rss as number), 0);\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 },\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 contextRatio(agent: MonitorAgent, models: readonly ModelChoice[]): number | null {\n const window = models.find((model) => model.id === agent.model)?.contextWindow;\n if (!agent.context || !window) return null;\n return Math.min(1, agent.context / window);\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\nfunction budgetVital(budget: BudgetState): 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 : { unit: `resets ${resets.toISOString().slice(0, 16).replace('T', ' ')} UTC` }),\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 ...(series.length > 1 ? { series } : {}),\n });\n }\n const active = feed.agents.filter((agent) => agent.running).length;\n const actives = input.history.map((sample) => sample.active);\n out.push({\n id: 'agents',\n label: 'Active agents',\n value: String(active),\n unit: `of ${feed.agents.length}`,\n ...(actives.length > 1 ? { series: actives } : {}),\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 }\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 ?? []));\n out.push(...cpuVital(feed, input.cpu ?? []));\n const ratios = feed.agents\n .map((agent) => contextRatio(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 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 (process.zombie !== null && input.now - process.zombie > ZOMBIE_MS)\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 = contextRatio(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 agentRow(agent: MonitorAgent, depth: number, models: readonly ModelChoice[]): MonitorRow {\n const ratio = contextRatio(agent, models);\n const word = agent.retry\n ? 'retrying'\n : agent.running\n ? 'running'\n : agent.failed\n ? 'failed'\n : 'idle';\n const status: MonitorStatus = agent.retry\n ? 'warn'\n : agent.running\n ? 'active'\n : agent.failed\n ? 'error'\n : 'idle';\n const model = models.find((choice) => choice.id === agent.model)?.label ?? agent.model;\n const meta = [\n word,\n model,\n ratio === null ? null : `${Math.round(ratio * 100)}% context`,\n cpuText(agent.cpu),\n ]\n .filter(Boolean)\n .join(' \u00B7 ');\n const badges = [\n ...(agent.queued ? [`${agent.queued} queued`] : []),\n ...(agent.tool ? [agent.tool] : []),\n ...(agent.retry ? [`retry ${agent.retry.attempt}`] : []),\n ];\n return {\n id: agent.id,\n name: agent.name,\n meta,\n status,\n depth,\n ...(badges.length ? { badges } : {}),\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 processRows(input: MonitorInput, feed: MonitorFeed): MonitorRow[] {\n const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));\n const flagged = new Map<number, 'warn' | 'error'>();\n for (const [pgid, members] of groups(feed.processes ?? []))\n if (members.length > GROUP_MAX) flagged.set(pgid, crowdSeverity(members));\n for (const group of busy(input, feed.processes ?? []))\n flagged.set(group.pgid, worse(flagged.get(group.pgid), cpuSeverity(group)) as 'warn' | 'error');\n return (feed.processes ?? []).map((process) => {\n const runaway = worse(\n flagged.get(process.pgid),\n stale(process, agents, input.now) ? staleSeverity(process, input.now) : 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 ?? (process.state === 'Z' ? 'warn' : 'idle'),\n ...(badges.length ? { badges } : {}),\n };\n });\n}\n\nconst PROBLEM_KINDS = { task: 'task failed', retry: 'retry', turn: 'turn failed' } as const;\n\nfunction depthOf(agents: ReadonlyMap<string, MonitorAgent>, agent: MonitorAgent): number {\n const visited = new Set<string>();\n let depth = 0;\n let current = agent;\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 depth++;\n current = parent;\n }\n return depth;\n}\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: 'agents',\n label: 'Cones and scoops',\n rows: ordered(feed).map((agent) =>\n agentRow(agent, Math.min(depthOf(agents, agent), DEPTH_MAX), input.models)\n ),\n },\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 {\n id: 'sprinkles',\n label: 'Sprinkles',\n rows: input.sprinkles.map((sprinkle) => ({\n name: sprinkle.title,\n meta: sprinkle.name,\n status: 'idle',\n })),\n },\n ...input.extra,\n ];\n}\n\nexport function monitorSnapshot(input: MonitorInput): MonitorSnapshot {\n const budget = input.budget ? [budgetVital(input.budget)] : [];\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 intervals?: Intervals;\n now?: () => number;\n}\n\ninterface Open {\n lease: Promise<string | null>;\n timer: 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 #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\n constructor(connection: AgentConnection, options: MonitorAdapterOptions = {}) {\n this.#connection = connection;\n this.#extra = options.extra ?? (() => []);\n this.#renewMs = options.renewMs ?? RENEW_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 connection.sprinkles?.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 sprinkles: this.#connection.sprinkles?.value ?? [],\n extra: this.#extra(),\n history: this.#history,\n now: this.#now(),\n hot: this.#hot,\n cpu: this.#cpu,\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 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 = { lease, timer: this.#intervals.every(renew, this.#renewMs) };\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 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 this.#history.push({\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 if (this.#history.length > HISTORY) this.#history.shift();\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) return;\n this.#cpu.push(share);\n if (this.#cpu.length > CPU_HISTORY) this.#cpu.shift();\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
  }
@@ -1,9 +1,11 @@
1
- import type { MonitorEvents, MonitorPort, MonitorSection, MonitorSnapshot } from '@ai-ecoverse/slicc-spectrum/ui';
1
+ import type { MonitorAlert, MonitorEvents, MonitorPort, MonitorSection, MonitorSnapshot } from '@ai-ecoverse/slicc-spectrum/ui';
2
2
  import type { AgentConnection } from '../client.ts';
3
3
  import type { BudgetState, ModelChoice, MonitorFeed, MonitorProcess, MonitorTask } from '../services.ts';
4
4
  export declare const RENEW_MS = 10000;
5
5
  export declare const ROWS_MAX = 200;
6
6
  export declare const HISTORY = 24;
7
+ export declare const CPU_HISTORY = 30;
8
+ export declare const CPU_QUIET = 0.01;
7
9
  export declare const BUDGET_WARN = 80;
8
10
  export declare const BUDGET_ERROR = 95;
9
11
  export declare const RETRY_WARN = 3;
@@ -20,6 +22,10 @@ export declare const CPU_SHARE = 0.9;
20
22
  export declare const CPU_SUSTAIN_MS = 120000;
21
23
  export declare const CONTEXT_WARN = 0.8;
22
24
  export declare const DEPTH_MAX = 6;
25
+ export type AgentMonitorAlert = MonitorAlert & {
26
+ command?: string;
27
+ commandLabel?: string;
28
+ };
23
29
  export interface Sample {
24
30
  at: number;
25
31
  cost: number;
@@ -42,11 +48,14 @@ export interface MonitorInput {
42
48
  history: readonly Sample[];
43
49
  now: number;
44
50
  hot?: ReadonlyMap<number, number>;
51
+ cpu?: readonly number[];
45
52
  }
46
53
  export declare function age(ms: number): string;
47
54
  export declare function money(value: number): string;
48
55
  export declare function count(value: number): string;
49
56
  export declare function bytes(value: number): string;
57
+ export declare function cpuText(share: number | null | undefined): string | null;
58
+ export declare function agentsCpu(feed: MonitorFeed): number | null;
50
59
  export declare function taskLabel(task: MonitorTask): string;
51
60
  export declare function taskTree(feed: MonitorFeed): {
52
61
  task: MonitorTask;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@ai-ecoverse/slicc-agent",
3
- "version": "3.46.0",
3
+ "version": "3.47.1",
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,7 +63,7 @@
63
63
  "devDependencies": {
64
64
  "@ai-ecoverse/slicc-kernel": "1.47.1",
65
65
  "@ai-ecoverse/slicc-shared-web": "1.13.1",
66
- "@ai-ecoverse/slicc-spectrum": "1.62.1",
66
+ "@ai-ecoverse/slicc-spectrum": "1.64.0",
67
67
  "@ai-ecoverse/wasm-bash": "5.3.0-17",
68
68
  "@ai-ecoverse/wasm-coreutils": "9.12.0-5",
69
69
  "@ai-ecoverse/wasm-git": "2.55.0-15",