@ai-ecoverse/slicc-agent 3.45.2 → 3.47.0
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +11 -6
- package/dist/monitor/index.js +34 -2
- package/dist/monitor/index.js.map +2 -2
- package/dist/services.js.map +2 -2
- package/dist/spectrum/monitor-port.js +132 -11
- package/dist/spectrum/monitor-port.js.map +2 -2
- package/dist/types/monitor/index.d.ts +14 -1
- package/dist/types/services.d.ts +4 -0
- package/dist/types/spectrum/monitor-port.d.ts +19 -2
- package/package.json +2 -2
package/README.md
CHANGED
|
@@ -447,9 +447,9 @@ The process table is the worker's root client's `ps()`. Each process is named af
|
|
|
447
447
|
|
|
448
448
|
**The feed.** The transcript service adds `monitor`, a `MonitorFeed` with these parts:
|
|
449
449
|
- `usage`;
|
|
450
|
-
- `agents`, each with running, queued, tool, retry, last error, model and
|
|
450
|
+
- `agents`, each with running, queued, tool, retry, last error, model, context tokens and, on kernels that report CPU times, the CPU share of its processes;
|
|
451
451
|
- `tasks`;
|
|
452
|
-
- `processes
|
|
452
|
+
- `processes`, with each one's CPU times and share of a core on kernels that report them (see CPU);
|
|
453
453
|
- `problems`, the newest 50 failed tasks, retries and failed turns since the panel opened;
|
|
454
454
|
- `paused`.
|
|
455
455
|
|
|
@@ -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 |
|
|
@@ -471,14 +471,19 @@ The process table is the worker's root client's `ps()`. Each process is named af
|
|
|
471
471
|
| Processes in one agent's group | over 32 | over 64 |
|
|
472
472
|
| Processes in the kernel | over 128 | over 256 |
|
|
473
473
|
| A zombie | after 60 s | |
|
|
474
|
-
| A background process of an agent | after 30 min | after an hour |
|
|
474
|
+
| A background process of an agent, on kernels without CPU times | after 30 min | after an hour |
|
|
475
|
+
| An agent's process group at 90% of a core or more, on kernels with CPU times | for 2 min | for 4 min, or at 180% |
|
|
475
476
|
| Context | 80% | |
|
|
476
477
|
| A paused scheduler | always | |
|
|
477
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
|
+
|
|
478
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.
|
|
479
482
|
- **More sections:** `createAgentModel(connection, { monitor: { extra } })` adds the page's own sections, such as terminals, browser tabs and tray followers.
|
|
480
483
|
|
|
481
|
-
**
|
|
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.
|
|
485
|
+
|
|
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.
|
|
482
487
|
|
|
483
488
|
### Sprinkles
|
|
484
489
|
|
|
@@ -552,7 +557,7 @@ The agent never holds a secret's value. Values live in the vault (`vault.sliccy.
|
|
|
552
557
|
|
|
553
558
|
## The kernel
|
|
554
559
|
|
|
555
|
-
`@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.
|
|
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.69.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.
|
|
556
561
|
|
|
557
562
|
## Patched dependencies
|
|
558
563
|
|
package/dist/monitor/index.js
CHANGED
|
@@ -4,6 +4,30 @@ import {
|
|
|
4
4
|
import { BACKGROUND_CONTEXT } from "@earendil-works/chord/context";
|
|
5
5
|
import { live } from "../agents.js";
|
|
6
6
|
import { commandLine, program, redacted } from "./redact.js";
|
|
7
|
+
function timed(entry) {
|
|
8
|
+
return typeof entry.utime === "number" && typeof entry.stime === "number";
|
|
9
|
+
}
|
|
10
|
+
function cpuShares(entries, previous, at) {
|
|
11
|
+
const marks = /* @__PURE__ */ new Map();
|
|
12
|
+
const shares = /* @__PURE__ */ new Map();
|
|
13
|
+
for (const entry of entries) {
|
|
14
|
+
if (!timed(entry)) continue;
|
|
15
|
+
const mark = { started: entry.started ?? 0, total: entry.utime + entry.stime, at };
|
|
16
|
+
const last = previous.get(entry.pid);
|
|
17
|
+
marks.set(entry.pid, mark);
|
|
18
|
+
shares.set(
|
|
19
|
+
entry.pid,
|
|
20
|
+
last && last.started === mark.started && mark.total >= last.total && at > last.at ? Math.round((mark.total - last.total) / (at - last.at) * 1e3) / 1e3 : null
|
|
21
|
+
);
|
|
22
|
+
}
|
|
23
|
+
return { marks, shares };
|
|
24
|
+
}
|
|
25
|
+
function agentCpu(processes, agentId) {
|
|
26
|
+
if (!processes.some((row) => typeof row.cpu === "number")) return null;
|
|
27
|
+
let sum = 0;
|
|
28
|
+
for (const row of processes) if (row.agentId === agentId) sum += row.cpu ?? 0;
|
|
29
|
+
return Math.round(sum * 1e3) / 1e3;
|
|
30
|
+
}
|
|
7
31
|
const TTL_MS = 3e4;
|
|
8
32
|
const PS_MS = 2e3;
|
|
9
33
|
const PS_TIMEOUT_MS = 5e3;
|
|
@@ -97,6 +121,7 @@ class Session {
|
|
|
97
121
|
#graph = { tasks: {} };
|
|
98
122
|
#usage = null;
|
|
99
123
|
#processes = null;
|
|
124
|
+
#cpu = { marks: /* @__PURE__ */ new Map(), shares: /* @__PURE__ */ new Map() };
|
|
100
125
|
#kernel;
|
|
101
126
|
#users = /* @__PURE__ */ new Map();
|
|
102
127
|
#paused = false;
|
|
@@ -201,6 +226,7 @@ class Session {
|
|
|
201
226
|
this.#settings.timers.clear(timeout);
|
|
202
227
|
this.#handles.delete(timeout);
|
|
203
228
|
this.#processes = entries;
|
|
229
|
+
if (entries) this.#cpu = cpuShares(entries, this.#cpu.marks, this.#settings.now());
|
|
204
230
|
this.#kernel = entries ? "ok" : "unreachable";
|
|
205
231
|
this.schedule();
|
|
206
232
|
this.#later(() => this.#poll(), this.#settings.psMs);
|
|
@@ -329,7 +355,8 @@ class Session {
|
|
|
329
355
|
started: entry.started ?? 0,
|
|
330
356
|
zombie: zombie ? this.#since(`zombie:${entry.pid}`) : null,
|
|
331
357
|
tty: Boolean(entry.tty),
|
|
332
|
-
rss: typeof entry.rss === "number" ? entry.rss : null
|
|
358
|
+
rss: typeof entry.rss === "number" ? entry.rss : null,
|
|
359
|
+
...timed(entry) ? { utime: entry.utime, stime: entry.stime, cpu: this.#cpu.shares.get(entry.pid) ?? null } : {}
|
|
333
360
|
};
|
|
334
361
|
}
|
|
335
362
|
#emit() {
|
|
@@ -353,7 +380,10 @@ class Session {
|
|
|
353
380
|
for (const pgid of this.#options.groups?.owned(agent.conversation) ?? [])
|
|
354
381
|
groups.set(pgid, agent.id);
|
|
355
382
|
const programs = /* @__PURE__ */ new Map();
|
|
356
|
-
const
|
|
383
|
+
const entries = this.#processes;
|
|
384
|
+
const processes = entries?.map((entry) => this.#process(entry, groups, programs)) ?? null;
|
|
385
|
+
if (entries?.some(timed))
|
|
386
|
+
for (const row of rows) row.cpu = agentCpu(processes, row.id);
|
|
357
387
|
this.#seen = this.#next;
|
|
358
388
|
const feed = {
|
|
359
389
|
open: true,
|
|
@@ -449,6 +479,8 @@ export {
|
|
|
449
479
|
THROTTLE_MS,
|
|
450
480
|
TTL_MS,
|
|
451
481
|
USAGE_MS,
|
|
482
|
+
agentCpu,
|
|
483
|
+
cpuShares,
|
|
452
484
|
createMonitor,
|
|
453
485
|
emptyFeed,
|
|
454
486
|
globalTimers,
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../../src/monitor/index.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type Context,\n type JsonValue,\n type ReplicatedState,\n replicatedState,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type {\n CommitPublication,\n ConversationView,\n Harness,\n TaskGraph,\n TaskGraphNode,\n TaskGraphWatch,\n TaskRecord,\n UsageState,\n} from '@earendil-works/pi-durable';\nimport { type AgentsState, live } from '../agents.ts';\nimport type {\n MonitorAgent,\n MonitorFeed,\n MonitorLease,\n MonitorProblem,\n MonitorProcess,\n MonitorTask,\n} from '../services.ts';\nimport { commandLine, program, redacted } from './redact.ts';\n\nexport interface PsEntry {\n pid: number;\n ppid?: number;\n pgid?: number;\n argv?: readonly string[];\n tty?: unknown;\n started?: number;\n state?: string;\n uid?: number;\n rss?: number;\n}\n\nexport interface Timers {\n set(run: () => void, ms: number): unknown;\n clear(handle: unknown): void;\n}\n\nexport interface MonitorOptions {\n harness: Pick<Harness, 'watchTaskGraph' | 'usage' | 'subscribeCommits' | 'inspect'>;\n agents: { state(): Readonly<AgentsState>; onChange(listener: () => void): () => void };\n views: ReplicatedState<Record<string, ConversationView>>;\n kernel?: { ps?(): Promise<readonly PsEntry[]> };\n groups?: { owned(owner: number): number[] };\n users?: () => Promise<readonly { name: string; uid: number }[]>;\n secrets?: () => readonly string[];\n now?: () => number;\n timers?: Timers;\n ttlMs?: number;\n psMs?: number;\n psTimeoutMs?: number;\n throttleMs?: number;\n usageMs?: number;\n context?: Context;\n}\n\nexport interface Monitor {\n readonly state: ReplicatedState<MonitorFeed>;\n readonly viewState: ReplicatedState<MonitorFeed>;\n open(lease: string | null, resync: boolean, context: Context): Promise<MonitorLease>;\n close(lease: string, context: Context): Promise<void>;\n active(): boolean;\n dispose(): Promise<void>;\n}\n\nexport const TTL_MS = 30000;\nexport const PS_MS = 2000;\nexport const PS_TIMEOUT_MS = 5000;\nexport const THROTTLE_MS = 1000;\nexport const USAGE_MS = 2000;\nexport const PROBLEMS_MAX = 50;\n\nexport const globalTimers: Timers = {\n set: (run, ms) => setTimeout(run, ms),\n clear: (handle) => clearTimeout(handle as ReturnType<typeof setTimeout>),\n};\n\nexport function emptyFeed(): MonitorFeed {\n return {\n open: false,\n at: 0,\n usage: null,\n agents: [],\n tasks: [],\n processes: null,\n kernel: 'checking',\n problems: [],\n paused: false,\n };\n}\n\ninterface Live {\n run?: unknown;\n generation?: { attempt: number; retry?: { at: number; error: string } };\n tools?: { name: string; status: string; taskId?: unknown }[];\n}\n\ninterface ModelMessage {\n stopReason?: string;\n errorMessage?: string;\n usage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number };\n}\n\nexport function totals(usage: UsageState): { tokens: number; cost: number; free: boolean } {\n let tokens = 0;\n let cost = 0;\n for (const bucket of [usage.models, usage.tools])\n for (const entry of Object.values(bucket)) {\n tokens += entry.totalTokens ?? 0;\n cost += entry.cost?.total ?? 0;\n }\n return { tokens, cost, free: cost === 0 };\n}\n\nfunction phaseOf(node: TaskGraphNode): string {\n return 'phase' in node.state ? node.state.phase : node.state.outcome;\n}\n\nfunction contextOf(message: ModelMessage): number | null {\n const usage = message.usage;\n if (!usage) return null;\n const parts = [usage.input, usage.output, usage.cacheRead, usage.cacheWrite];\n const total = parts.reduce<number>((sum, part) => sum + (part ?? 0), 0);\n return total > 0 ? total : null;\n}\n\nfunction lastAssistant(view: ConversationView | undefined) {\n const entries = view?.entries ?? [];\n for (let at = entries.length - 1; at >= 0; at--) {\n const entry = entries[at] as (typeof entries)[number];\n if (entry.kind === 'pi.assistant')\n return { id: String(entry.id), message: (entry.model?.[0] ?? {}) as ModelMessage };\n }\n return undefined;\n}\n\nfunction conversations(state: Readonly<AgentsState>): Map<number, string> {\n const out = new Map<number, string>();\n for (const [id, scoop] of Object.entries(state.scoops)) out.set(scoop.conversation, id);\n for (const [id, cone] of Object.entries(state.cones)) out.set(cone.conversation, id);\n return out;\n}\n\nfunction liveAgents(state: Readonly<AgentsState>) {\n const cones = Object.entries(state.cones).map(([id, cone]) => ({\n id,\n name: cone.name,\n kind: 'cone' as const,\n parentId: null,\n conversation: cone.conversation,\n }));\n const scoops = Object.entries(state.scoops)\n .filter(([, scoop]) => live(scoop))\n .map(([id, scoop]) => ({\n id,\n name: scoop.name,\n kind: 'scoop' as const,\n parentId: scoop.parent,\n conversation: scoop.conversation,\n }));\n return [...cones, ...scoops];\n}\n\nexport function narrowed(feed: MonitorFeed, programs: ReadonlyMap<number, string>): MonitorFeed {\n if (!feed.processes) return feed;\n return {\n ...feed,\n processes: feed.processes.map((row) => ({ ...row, command: programs.get(row.pid) ?? '' })),\n };\n}\n\ninterface Settings {\n now: () => number;\n timers: Timers;\n context: Context;\n psMs: number;\n psTimeoutMs: number;\n throttleMs: number;\n usageMs: number;\n secrets: () => readonly string[];\n}\n\ntype Agent = ReturnType<typeof liveAgents>[number];\n\nclass Session {\n stopped = false;\n readonly #options: MonitorOptions;\n readonly #settings: Settings;\n readonly #publish: (feed: MonitorFeed, view: MonitorFeed) => void;\n readonly #off: (() => void)[] = [];\n readonly #handles = new Set<unknown>();\n #watch: TaskGraphWatch | undefined;\n #graph: TaskGraph = { tasks: {} };\n #usage: UsageState | null = null;\n #processes: readonly PsEntry[] | null = null;\n #kernel: MonitorFeed['kernel'];\n #users = new Map<number, string>();\n #paused = false;\n #problems: MonitorProblem[] = [];\n #seen = new Map<string, number>();\n #next = new Map<string, number>();\n #build: unknown;\n #usageTimer: unknown;\n #lastBuild = Number.NEGATIVE_INFINITY;\n #last = '';\n\n constructor(\n options: MonitorOptions,\n settings: Settings,\n publish: (feed: MonitorFeed, view: MonitorFeed) => void\n ) {\n this.#options = options;\n this.#settings = settings;\n this.#publish = publish;\n this.#kernel = options.kernel?.ps ? 'checking' : 'unreachable';\n }\n\n start(): void {\n const options = this.#options;\n this.#off.push(\n options.harness.subscribeCommits((publication) => this.#commit(publication)),\n options.agents.onChange(() => this.schedule()),\n options.views.subscribe(() => this.schedule())\n );\n void options.harness.watchTaskGraph(this.#settings.context).then(\n (watch) => this.#watching(watch),\n () => undefined\n );\n void options.users?.().then(\n (list) => {\n this.#users = new Map(list.map((user) => [user.uid, user.name]));\n this.schedule();\n },\n () => undefined\n );\n this.#poll();\n this.refresh();\n }\n\n stop(): void {\n this.stopped = true;\n for (const off of this.#off) off();\n for (const handle of this.#handles) this.#settings.timers.clear(handle);\n this.#handles.clear();\n void this.#watch?.stop();\n }\n\n refresh(): void {\n void this.#readUsage();\n void this.#options.harness.inspect(this.#settings.context).then(\n (inspection) => {\n this.#paused = inspection.scheduling === 'paused';\n this.schedule();\n },\n () => undefined\n );\n this.schedule();\n }\n\n schedule(): void {\n if (this.stopped || this.#build !== undefined) return;\n const wait = Math.max(0, this.#lastBuild + this.#settings.throttleMs - this.#settings.now());\n this.#build = this.#later(() => {\n this.#build = undefined;\n this.#emit();\n }, wait);\n }\n\n #later(task: () => void, ms: number): unknown {\n if (this.stopped) return undefined;\n const handle = this.#settings.timers.set(() => {\n this.#handles.delete(handle);\n if (!this.stopped) task();\n }, ms);\n this.#handles.add(handle);\n return handle;\n }\n\n #watching(watch: TaskGraphWatch): void {\n if (this.stopped) {\n void watch.stop();\n return;\n }\n this.#watch = watch;\n this.#graph = watch.value;\n this.schedule();\n watch.start(async (graph) => {\n this.#graph = graph;\n this.schedule();\n });\n }\n\n #readUsage(): Promise<void> {\n return this.#options.harness.usage(this.#settings.context).then(\n (usage) => {\n this.#usage = usage;\n this.schedule();\n },\n () => undefined\n );\n }\n\n #poll(): void {\n const kernel = this.#options.kernel;\n if (!kernel?.ps) return;\n let settled = false;\n const settle = (entries: readonly PsEntry[] | null) => {\n if (settled || this.stopped) return;\n settled = true;\n this.#settings.timers.clear(timeout);\n this.#handles.delete(timeout);\n this.#processes = entries;\n this.#kernel = entries ? 'ok' : 'unreachable';\n this.schedule();\n this.#later(() => this.#poll(), this.#settings.psMs);\n };\n const timeout = this.#later(() => settle(null), this.#settings.psTimeoutMs);\n kernel.ps().then(settle, () => settle(null));\n }\n\n #problem(entry: MonitorProblem): void {\n if (this.#problems.some((known) => known.id === entry.id)) return;\n this.#problems.unshift(entry);\n this.#problems.length = Math.min(this.#problems.length, PROBLEMS_MAX);\n }\n\n #commit(publication: CommitPublication): void {\n let changed = false;\n for (const change of publication.changes) {\n if (change.type === 'task') changed = this.#failed(change.value) || changed;\n else if (change.type === 'document' && change.record.kind === 'pi.usage')\n this.#usageChanged();\n }\n if (changed) this.schedule();\n }\n\n #failed(task: TaskRecord<JsonValue, JsonValue, JsonValue>): boolean {\n if (task.state.status !== 'terminal') return false;\n const outcome = task.state.outcome;\n if (outcome.status !== 'faulted' && outcome.status !== 'orphaned') return false;\n this.#problem({\n id: `task:${task.id}`,\n at: this.#settings.now(),\n agentId: conversations(this.#options.agents.state()).get(task.conversationId) ?? null,\n kind: 'task',\n message: redacted(\n outcome.status === 'faulted' ? outcome.error.message : outcome.reason,\n this.#settings.secrets()\n ),\n });\n return true;\n }\n\n #usageChanged(): void {\n if (this.#usageTimer !== undefined) return;\n this.#usageTimer = this.#later(() => {\n this.#usageTimer = undefined;\n void this.#readUsage();\n }, this.#settings.usageMs);\n }\n\n #since(key: string): number {\n const at = this.#seen.get(key) ?? this.#settings.now();\n this.#next.set(key, at);\n return at;\n }\n\n #agent(agent: Agent, view: ConversationView | undefined, tools: Map<string, string>) {\n const secrets = this.#settings.secrets();\n const liveDoc = view?.docs['pi.live'] as Live | undefined;\n for (const slot of liveDoc?.tools ?? [])\n if (slot.taskId !== undefined) tools.set(String(slot.taskId), slot.name);\n const inbox = view?.docs['pi.inbox'] as { items?: unknown[] } | undefined;\n const doc = view?.docs['pi.agent'] as\n | { model?: { provider: string; modelId: string } }\n | undefined;\n const generation = liveDoc?.generation;\n const retry = generation?.retry\n ? {\n attempt: generation.attempt,\n since: this.#since(`retry:${agent.id}`),\n error: redacted(generation.retry.error, secrets),\n }\n : null;\n if (retry)\n this.#problem({\n id: `retry:${agent.id}:${retry.since}`,\n at: retry.since,\n agentId: agent.id,\n kind: 'retry',\n message: retry.error,\n });\n const last = lastAssistant(view);\n const failed =\n last?.message.stopReason === 'error'\n ? redacted(last.message.errorMessage || 'error', secrets)\n : null;\n if (failed && last)\n this.#problem({\n id: `turn:${last.id}`,\n at: this.#settings.now(),\n agentId: agent.id,\n kind: 'turn',\n message: failed,\n });\n return {\n id: agent.id,\n name: agent.name,\n kind: agent.kind,\n parentId: agent.parentId,\n model: doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : null,\n running: Boolean(liveDoc?.run),\n queued: inbox?.items?.length ?? 0,\n tool: liveDoc?.tools?.find((slot) => slot.status === 'running')?.name ?? null,\n retry,\n failed,\n context: last ? contextOf(last.message) : null,\n };\n }\n\n #task(node: TaskGraphNode, owners: Map<number, string>, details: Map<string, string>) {\n const id = String(node.id);\n const status = node.state.status;\n return {\n id,\n kind: node.kind,\n detail: details.get(id) ?? null,\n agentId: owners.get(node.conversationId) ?? null,\n owner: node.owner === undefined ? null : String(node.owner),\n status,\n phase: phaseOf(node),\n background: node.background,\n aborting: node.abortRequested ? this.#since(`abort:${id}`) : null,\n since: this.#since(`task:${id}:${status}`),\n waits: node.state.status === 'waiting' ? node.state.on.length : 0,\n };\n }\n\n #process(entry: PsEntry, groups: Map<number, string>, programs: Map<number, string>) {\n const argv = entry.argv ?? [];\n const pgid = entry.pgid ?? entry.pid;\n const zombie = entry.state === 'Z';\n programs.set(entry.pid, program(argv));\n const uid = entry.uid;\n return {\n pid: entry.pid,\n ppid: entry.ppid ?? 0,\n pgid,\n user:\n uid === undefined ? null : (this.#users.get(uid) ?? (uid === 0 ? 'root' : `uid ${uid}`)),\n agentId: groups.get(pgid) ?? null,\n command: commandLine(argv, this.#settings.secrets()),\n state: zombie ? ('Z' as const) : ('S' as const),\n started: entry.started ?? 0,\n zombie: zombie ? this.#since(`zombie:${entry.pid}`) : null,\n tty: Boolean(entry.tty),\n rss: typeof entry.rss === 'number' ? entry.rss : null,\n };\n }\n\n #emit(): void {\n this.#lastBuild = this.#settings.now();\n this.#next = new Map();\n const registry = this.#options.agents.state();\n const views = this.#options.views.value ?? {};\n const agents = liveAgents(registry);\n const details = new Map<string, string>();\n const rows: MonitorAgent[] = agents.map((agent) =>\n this.#agent(agent, views[agent.id], details)\n );\n for (const scoop of Object.values(registry.scoops))\n details.set(String(scoop.anchor), scoop.name);\n const owners = conversations(registry);\n const tasks: MonitorTask[] = Object.values(this.#graph.tasks).map((node) =>\n this.#task(node, owners, details)\n );\n const groups = new Map<number, string>();\n for (const agent of agents)\n for (const pgid of this.#options.groups?.owned(agent.conversation) ?? [])\n groups.set(pgid, agent.id);\n const programs = new Map<number, string>();\n const processes: MonitorProcess[] | null =\n this.#processes?.map((entry) => this.#process(entry, groups, programs)) ?? null;\n this.#seen = this.#next;\n const feed: MonitorFeed = {\n open: true,\n at: this.#lastBuild,\n usage: this.#usage ? totals(this.#usage) : null,\n agents: rows,\n tasks,\n processes,\n kernel: this.#kernel,\n problems: [...this.#problems],\n paused: this.#paused,\n };\n const key = JSON.stringify({ ...feed, at: 0 });\n if (key === this.#last) return;\n this.#last = key;\n this.#publish(feed, narrowed(feed, programs));\n }\n}\n\nexport function createMonitor(options: MonitorOptions): Monitor {\n const settings: Settings = {\n now: options.now ?? Date.now,\n timers: options.timers ?? globalTimers,\n context: options.context ?? BACKGROUND_CONTEXT,\n psMs: options.psMs ?? PS_MS,\n psTimeoutMs: options.psTimeoutMs ?? PS_TIMEOUT_MS,\n throttleMs: options.throttleMs ?? THROTTLE_MS,\n usageMs: options.usageMs ?? USAGE_MS,\n secrets: () => options.secrets?.() ?? [],\n };\n const { now, timers, context } = settings;\n const ttlMs = options.ttlMs ?? TTL_MS;\n const state = replicatedState<MonitorFeed>(emptyFeed());\n const viewState = replicatedState<MonitorFeed>(emptyFeed());\n const leases = new Map<string, number>();\n let session: Session | undefined;\n let sweep: unknown;\n const publish = (feed: MonitorFeed, view: MonitorFeed) => {\n state.replace(context, feed);\n viewState.replace(context, view);\n };\n const stop = () => {\n if (sweep !== undefined) timers.clear(sweep);\n sweep = undefined;\n const current = session;\n if (!current) return;\n session = undefined;\n current.stop();\n publish(\n { ...(state.value as MonitorFeed), open: false },\n { ...(viewState.value as MonitorFeed), open: false }\n );\n };\n const arm = () => {\n if (sweep !== undefined) timers.clear(sweep);\n sweep = timers.set(expire, Math.max(0, Math.min(...leases.values()) - now()));\n };\n const expire = () => {\n sweep = undefined;\n const at = now();\n for (const [lease, until] of [...leases]) if (until <= at) leases.delete(lease);\n if (leases.size) arm();\n else stop();\n };\n return {\n state,\n viewState,\n async open(lease, resync) {\n const id = lease ?? crypto.randomUUID();\n leases.set(id, now() + ttlMs);\n arm();\n if (!session) {\n session = new Session(options, settings, publish);\n session.start();\n } else if (resync) session.refresh();\n return { lease: id, ttlMs };\n },\n async close(lease) {\n if (!leases.delete(lease)) return;\n if (leases.size) arm();\n else stop();\n },\n active: () => session !== undefined,\n async dispose() {\n leases.clear();\n stop();\n },\n };\n}\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EAIE;AAAA,OACK;AACP,SAAS,0BAA0B;AAWnC,SAA2B,YAAY;AASvC,SAAS,aAAa,SAAS,gBAAgB;AA8CxC,MAAM,SAAS;AACf,MAAM,QAAQ;AACd,MAAM,gBAAgB;AACtB,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,eAAe;AAErB,MAAM,eAAuB;AAAA,EAClC,KAAK,CAAC,KAAK,OAAO,WAAW,KAAK,EAAE;AAAA,EACpC,OAAO,CAAC,WAAW,aAAa,MAAuC;AACzE;AAEO,SAAS,YAAyB;AACvC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ,CAAC;AAAA,IACT,OAAO,CAAC;AAAA,IACR,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,UAAU,CAAC;AAAA,IACX,QAAQ;AAAA,EACV;AACF;AAcO,SAAS,OAAO,OAAoE;AACzF,MAAI,SAAS;AACb,MAAI,OAAO;AACX,aAAW,UAAU,CAAC,MAAM,QAAQ,MAAM,KAAK;AAC7C,eAAW,SAAS,OAAO,OAAO,MAAM,GAAG;AACzC,gBAAU,MAAM,eAAe;AAC/B,cAAQ,MAAM,MAAM,SAAS;AAAA,IAC/B;AACF,SAAO,EAAE,QAAQ,MAAM,MAAM,SAAS,EAAE;AAC1C;AAEA,SAAS,QAAQ,MAA6B;AAC5C,SAAO,WAAW,KAAK,QAAQ,KAAK,MAAM,QAAQ,KAAK,MAAM;AAC/D;AAEA,SAAS,UAAU,SAAsC;AACvD,QAAM,QAAQ,QAAQ;AACtB,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,CAAC,MAAM,OAAO,MAAM,QAAQ,MAAM,WAAW,MAAM,UAAU;AAC3E,QAAM,QAAQ,MAAM,OAAe,CAAC,KAAK,SAAS,OAAO,QAAQ,IAAI,CAAC;AACtE,SAAO,QAAQ,IAAI,QAAQ;AAC7B;AAEA,SAAS,cAAc,MAAoC;AACzD,QAAM,UAAU,MAAM,WAAW,CAAC;AAClC,WAAS,KAAK,QAAQ,SAAS,GAAG,MAAM,GAAG,MAAM;AAC/C,UAAM,QAAQ,QAAQ,EAAE;AACxB,QAAI,MAAM,SAAS;AACjB,aAAO,EAAE,IAAI,OAAO,MAAM,EAAE,GAAG,SAAU,MAAM,QAAQ,CAAC,KAAK,CAAC,EAAmB;AAAA,EACrF;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAAmD;AACxE,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,MAAM,MAAM,EAAG,KAAI,IAAI,MAAM,cAAc,EAAE;AACtF,aAAW,CAAC,IAAI,IAAI,KAAK,OAAO,QAAQ,MAAM,KAAK,EAAG,KAAI,IAAI,KAAK,cAAc,EAAE;AACnF,SAAO;AACT;AAEA,SAAS,WAAW,OAA8B;AAChD,QAAM,QAAQ,OAAO,QAAQ,MAAM,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO;AAAA,IAC7D;AAAA,IACA,MAAM,KAAK;AAAA,IACX,MAAM;AAAA,IACN,UAAU;AAAA,IACV,cAAc,KAAK;AAAA,EACrB,EAAE;AACF,QAAM,SAAS,OAAO,QAAQ,MAAM,MAAM,EACvC,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC,EACjC,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;AAAA,IACrB;AAAA,IACA,MAAM,MAAM;AAAA,IACZ,MAAM;AAAA,IACN,UAAU,MAAM;AAAA,IAChB,cAAc,MAAM;AAAA,EACtB,EAAE;AACJ,SAAO,CAAC,GAAG,OAAO,GAAG,MAAM;AAC7B;AAEO,SAAS,SAAS,MAAmB,UAAoD;AAC9F,MAAI,CAAC,KAAK,UAAW,QAAO;AAC5B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW,KAAK,UAAU,IAAI,CAAC,SAAS,EAAE,GAAG,KAAK,SAAS,SAAS,IAAI,IAAI,GAAG,KAAK,GAAG,EAAE;AAAA,EAC3F;AACF;AAeA,MAAM,QAAQ;AAAA,EACZ,UAAU;AAAA,EACD;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAuB,CAAC;AAAA,EACxB,WAAW,oBAAI,IAAa;AAAA,EACrC;AAAA,EACA,SAAoB,EAAE,OAAO,CAAC,EAAE;AAAA,EAChC,SAA4B;AAAA,EAC5B,aAAwC;AAAA,EACxC;AAAA,EACA,SAAS,oBAAI,IAAoB;AAAA,EACjC,UAAU;AAAA,EACV,YAA8B,CAAC;AAAA,EAC/B,QAAQ,oBAAI,IAAoB;AAAA,EAChC,QAAQ,oBAAI,IAAoB;AAAA,EAChC;AAAA,EACA;AAAA,EACA,aAAa,OAAO;AAAA,EACpB,QAAQ;AAAA,EAER,YACE,SACA,UACA,SACA;AACA,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,WAAW;AAChB,SAAK,UAAU,QAAQ,QAAQ,KAAK,aAAa;AAAA,EACnD;AAAA,EAEA,QAAc;AACZ,UAAM,UAAU,KAAK;AACrB,SAAK,KAAK;AAAA,MACR,QAAQ,QAAQ,iBAAiB,CAAC,gBAAgB,KAAK,QAAQ,WAAW,CAAC;AAAA,MAC3E,QAAQ,OAAO,SAAS,MAAM,KAAK,SAAS,CAAC;AAAA,MAC7C,QAAQ,MAAM,UAAU,MAAM,KAAK,SAAS,CAAC;AAAA,IAC/C;AACA,SAAK,QAAQ,QAAQ,eAAe,KAAK,UAAU,OAAO,EAAE;AAAA,MAC1D,CAAC,UAAU,KAAK,UAAU,KAAK;AAAA,MAC/B,MAAM;AAAA,IACR;AACA,SAAK,QAAQ,QAAQ,EAAE;AAAA,MACrB,CAAC,SAAS;AACR,aAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC;AAC/D,aAAK,SAAS;AAAA,MAChB;AAAA,MACA,MAAM;AAAA,IACR;AACA,SAAK,MAAM;AACX,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,OAAa;AACX,SAAK,UAAU;AACf,eAAW,OAAO,KAAK,KAAM,KAAI;AACjC,eAAW,UAAU,KAAK,SAAU,MAAK,UAAU,OAAO,MAAM,MAAM;AACtE,SAAK,SAAS,MAAM;AACpB,SAAK,KAAK,QAAQ,KAAK;AAAA,EACzB;AAAA,EAEA,UAAgB;AACd,SAAK,KAAK,WAAW;AACrB,SAAK,KAAK,SAAS,QAAQ,QAAQ,KAAK,UAAU,OAAO,EAAE;AAAA,MACzD,CAAC,eAAe;AACd,aAAK,UAAU,WAAW,eAAe;AACzC,aAAK,SAAS;AAAA,MAChB;AAAA,MACA,MAAM;AAAA,IACR;AACA,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,WAAiB;AACf,QAAI,KAAK,WAAW,KAAK,WAAW,OAAW;AAC/C,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,aAAa,KAAK,UAAU,aAAa,KAAK,UAAU,IAAI,CAAC;AAC3F,SAAK,SAAS,KAAK,OAAO,MAAM;AAC9B,WAAK,SAAS;AACd,WAAK,MAAM;AAAA,IACb,GAAG,IAAI;AAAA,EACT;AAAA,EAEA,OAAO,MAAkB,IAAqB;AAC5C,QAAI,KAAK,QAAS,QAAO;AACzB,UAAM,SAAS,KAAK,UAAU,OAAO,IAAI,MAAM;AAC7C,WAAK,SAAS,OAAO,MAAM;AAC3B,UAAI,CAAC,KAAK,QAAS,MAAK;AAAA,IAC1B,GAAG,EAAE;AACL,SAAK,SAAS,IAAI,MAAM;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,OAA6B;AACrC,QAAI,KAAK,SAAS;AAChB,WAAK,MAAM,KAAK;AAChB;AAAA,IACF;AACA,SAAK,SAAS;AACd,SAAK,SAAS,MAAM;AACpB,SAAK,SAAS;AACd,UAAM,MAAM,OAAO,UAAU;AAC3B,WAAK,SAAS;AACd,WAAK,SAAS;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEA,aAA4B;AAC1B,WAAO,KAAK,SAAS,QAAQ,MAAM,KAAK,UAAU,OAAO,EAAE;AAAA,MACzD,CAAC,UAAU;AACT,aAAK,SAAS;AACd,aAAK,SAAS;AAAA,MAChB;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,UAAM,SAAS,KAAK,SAAS;AAC7B,QAAI,CAAC,QAAQ,GAAI;AACjB,QAAI,UAAU;AACd,UAAM,SAAS,CAAC,YAAuC;AACrD,UAAI,WAAW,KAAK,QAAS;AAC7B,gBAAU;AACV,WAAK,UAAU,OAAO,MAAM,OAAO;AACnC,WAAK,SAAS,OAAO,OAAO;AAC5B,WAAK,aAAa;AAClB,WAAK,UAAU,UAAU,OAAO;AAChC,WAAK,SAAS;AACd,WAAK,OAAO,MAAM,KAAK,MAAM,GAAG,KAAK,UAAU,IAAI;AAAA,IACrD;AACA,UAAM,UAAU,KAAK,OAAO,MAAM,OAAO,IAAI,GAAG,KAAK,UAAU,WAAW;AAC1E,WAAO,GAAG,EAAE,KAAK,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,EAC7C;AAAA,EAEA,SAAS,OAA6B;AACpC,QAAI,KAAK,UAAU,KAAK,CAAC,UAAU,MAAM,OAAO,MAAM,EAAE,EAAG;AAC3D,SAAK,UAAU,QAAQ,KAAK;AAC5B,SAAK,UAAU,SAAS,KAAK,IAAI,KAAK,UAAU,QAAQ,YAAY;AAAA,EACtE;AAAA,EAEA,QAAQ,aAAsC;AAC5C,QAAI,UAAU;AACd,eAAW,UAAU,YAAY,SAAS;AACxC,UAAI,OAAO,SAAS,OAAQ,WAAU,KAAK,QAAQ,OAAO,KAAK,KAAK;AAAA,eAC3D,OAAO,SAAS,cAAc,OAAO,OAAO,SAAS;AAC5D,aAAK,cAAc;AAAA,IACvB;AACA,QAAI,QAAS,MAAK,SAAS;AAAA,EAC7B;AAAA,EAEA,QAAQ,MAA4D;AAClE,QAAI,KAAK,MAAM,WAAW,WAAY,QAAO;AAC7C,UAAM,UAAU,KAAK,MAAM;AAC3B,QAAI,QAAQ,WAAW,aAAa,QAAQ,WAAW,WAAY,QAAO;AAC1E,SAAK,SAAS;AAAA,MACZ,IAAI,QAAQ,KAAK,EAAE;AAAA,MACnB,IAAI,KAAK,UAAU,IAAI;AAAA,MACvB,SAAS,cAAc,KAAK,SAAS,OAAO,MAAM,CAAC,EAAE,IAAI,KAAK,cAAc,KAAK;AAAA,MACjF,MAAM;AAAA,MACN,SAAS;AAAA,QACP,QAAQ,WAAW,YAAY,QAAQ,MAAM,UAAU,QAAQ;AAAA,QAC/D,KAAK,UAAU,QAAQ;AAAA,MACzB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,gBAAsB;AACpB,QAAI,KAAK,gBAAgB,OAAW;AACpC,SAAK,cAAc,KAAK,OAAO,MAAM;AACnC,WAAK,cAAc;AACnB,WAAK,KAAK,WAAW;AAAA,IACvB,GAAG,KAAK,UAAU,OAAO;AAAA,EAC3B;AAAA,EAEA,OAAO,KAAqB;AAC1B,UAAM,KAAK,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,UAAU,IAAI;AACrD,SAAK,MAAM,IAAI,KAAK,EAAE;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,OAAc,MAAoC,OAA4B;AACnF,UAAM,UAAU,KAAK,UAAU,QAAQ;AACvC,UAAM,UAAU,MAAM,KAAK,SAAS;AACpC,eAAW,QAAQ,SAAS,SAAS,CAAC;AACpC,UAAI,KAAK,WAAW,OAAW,OAAM,IAAI,OAAO,KAAK,MAAM,GAAG,KAAK,IAAI;AACzE,UAAM,QAAQ,MAAM,KAAK,UAAU;AACnC,UAAM,MAAM,MAAM,KAAK,UAAU;AAGjC,UAAM,aAAa,SAAS;AAC5B,UAAM,QAAQ,YAAY,QACtB;AAAA,MACE,SAAS,WAAW;AAAA,MACpB,OAAO,KAAK,OAAO,SAAS,MAAM,EAAE,EAAE;AAAA,MACtC,OAAO,SAAS,WAAW,MAAM,OAAO,OAAO;AAAA,IACjD,IACA;AACJ,QAAI;AACF,WAAK,SAAS;AAAA,QACZ,IAAI,SAAS,MAAM,EAAE,IAAI,MAAM,KAAK;AAAA,QACpC,IAAI,MAAM;AAAA,QACV,SAAS,MAAM;AAAA,QACf,MAAM;AAAA,QACN,SAAS,MAAM;AAAA,MACjB,CAAC;AACH,UAAM,OAAO,cAAc,IAAI;AAC/B,UAAM,SACJ,MAAM,QAAQ,eAAe,UACzB,SAAS,KAAK,QAAQ,gBAAgB,SAAS,OAAO,IACtD;AACN,QAAI,UAAU;AACZ,WAAK,SAAS;AAAA,QACZ,IAAI,QAAQ,KAAK,EAAE;AAAA,QACnB,IAAI,KAAK,UAAU,IAAI;AAAA,QACvB,SAAS,MAAM;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AACH,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,MACV,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAChB,OAAO,KAAK,QAAQ,GAAG,IAAI,MAAM,QAAQ,IAAI,IAAI,MAAM,OAAO,KAAK;AAAA,MACnE,SAAS,QAAQ,SAAS,GAAG;AAAA,MAC7B,QAAQ,OAAO,OAAO,UAAU;AAAA,MAChC,MAAM,SAAS,OAAO,KAAK,CAAC,SAAS,KAAK,WAAW,SAAS,GAAG,QAAQ;AAAA,MACzE;AAAA,MACA;AAAA,MACA,SAAS,OAAO,UAAU,KAAK,OAAO,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,MAAqB,QAA6B,SAA8B;AACpF,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,SAAS,KAAK,MAAM;AAC1B,WAAO;AAAA,MACL;AAAA,MACA,MAAM,KAAK;AAAA,MACX,QAAQ,QAAQ,IAAI,EAAE,KAAK;AAAA,MAC3B,SAAS,OAAO,IAAI,KAAK,cAAc,KAAK;AAAA,MAC5C,OAAO,KAAK,UAAU,SAAY,OAAO,OAAO,KAAK,KAAK;AAAA,MAC1D;AAAA,MACA,OAAO,QAAQ,IAAI;AAAA,MACnB,YAAY,KAAK;AAAA,MACjB,UAAU,KAAK,iBAAiB,KAAK,OAAO,SAAS,EAAE,EAAE,IAAI;AAAA,MAC7D,OAAO,KAAK,OAAO,QAAQ,EAAE,IAAI,MAAM,EAAE;AAAA,MACzC,OAAO,KAAK,MAAM,WAAW,YAAY,KAAK,MAAM,GAAG,SAAS;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,SAAS,OAAgB,QAA6B,UAA+B;AACnF,UAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,UAAM,OAAO,MAAM,QAAQ,MAAM;AACjC,UAAM,SAAS,MAAM,UAAU;AAC/B,aAAS,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC;AACrC,UAAM,MAAM,MAAM;AAClB,WAAO;AAAA,MACL,KAAK,MAAM;AAAA,MACX,MAAM,MAAM,QAAQ;AAAA,MACpB;AAAA,MACA,MACE,QAAQ,SAAY,OAAQ,KAAK,OAAO,IAAI,GAAG,MAAM,QAAQ,IAAI,SAAS,OAAO,GAAG;AAAA,MACtF,SAAS,OAAO,IAAI,IAAI,KAAK;AAAA,MAC7B,SAAS,YAAY,MAAM,KAAK,UAAU,QAAQ,CAAC;AAAA,MACnD,OAAO,SAAU,MAAiB;AAAA,MAClC,SAAS,MAAM,WAAW;AAAA,MAC1B,QAAQ,SAAS,KAAK,OAAO,UAAU,MAAM,GAAG,EAAE,IAAI;AAAA,MACtD,KAAK,QAAQ,MAAM,GAAG;AAAA,MACtB,KAAK,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM;AAAA,IACnD;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,aAAa,KAAK,UAAU,IAAI;AACrC,SAAK,QAAQ,oBAAI,IAAI;AACrB,UAAM,WAAW,KAAK,SAAS,OAAO,MAAM;AAC5C,UAAM,QAAQ,KAAK,SAAS,MAAM,SAAS,CAAC;AAC5C,UAAM,SAAS,WAAW,QAAQ;AAClC,UAAM,UAAU,oBAAI,IAAoB;AACxC,UAAM,OAAuB,OAAO;AAAA,MAAI,CAAC,UACvC,KAAK,OAAO,OAAO,MAAM,MAAM,EAAE,GAAG,OAAO;AAAA,IAC7C;AACA,eAAW,SAAS,OAAO,OAAO,SAAS,MAAM;AAC/C,cAAQ,IAAI,OAAO,MAAM,MAAM,GAAG,MAAM,IAAI;AAC9C,UAAM,SAAS,cAAc,QAAQ;AACrC,UAAM,QAAuB,OAAO,OAAO,KAAK,OAAO,KAAK,EAAE;AAAA,MAAI,CAAC,SACjE,KAAK,MAAM,MAAM,QAAQ,OAAO;AAAA,IAClC;AACA,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,SAAS;AAClB,iBAAW,QAAQ,KAAK,SAAS,QAAQ,MAAM,MAAM,YAAY,KAAK,CAAC;AACrE,eAAO,IAAI,MAAM,MAAM,EAAE;AAC7B,UAAM,WAAW,oBAAI,IAAoB;AACzC,UAAM,YACJ,KAAK,YAAY,IAAI,CAAC,UAAU,KAAK,SAAS,OAAO,QAAQ,QAAQ,CAAC,KAAK;AAC7E,SAAK,QAAQ,KAAK;AAClB,UAAM,OAAoB;AAAA,MACxB,MAAM;AAAA,MACN,IAAI,KAAK;AAAA,MACT,OAAO,KAAK,SAAS,OAAO,KAAK,MAAM,IAAI;AAAA,MAC3C,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,UAAU,CAAC,GAAG,KAAK,SAAS;AAAA,MAC5B,QAAQ,KAAK;AAAA,IACf;AACA,UAAM,MAAM,KAAK,UAAU,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;AAC7C,QAAI,QAAQ,KAAK,MAAO;AACxB,SAAK,QAAQ;AACb,SAAK,SAAS,MAAM,SAAS,MAAM,QAAQ,CAAC;AAAA,EAC9C;AACF;AAEO,SAAS,cAAc,SAAkC;AAC9D,QAAM,WAAqB;AAAA,IACzB,KAAK,QAAQ,OAAO,KAAK;AAAA,IACzB,QAAQ,QAAQ,UAAU;AAAA,IAC1B,SAAS,QAAQ,WAAW;AAAA,IAC5B,MAAM,QAAQ,QAAQ;AAAA,IACtB,aAAa,QAAQ,eAAe;AAAA,IACpC,YAAY,QAAQ,cAAc;AAAA,IAClC,SAAS,QAAQ,WAAW;AAAA,IAC5B,SAAS,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,EACzC;AACA,QAAM,EAAE,KAAK,QAAQ,QAAQ,IAAI;AACjC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ,gBAA6B,UAAU,CAAC;AACtD,QAAM,YAAY,gBAA6B,UAAU,CAAC;AAC1D,QAAM,SAAS,oBAAI,IAAoB;AACvC,MAAI;AACJ,MAAI;AACJ,QAAM,UAAU,CAAC,MAAmB,SAAsB;AACxD,UAAM,QAAQ,SAAS,IAAI;AAC3B,cAAU,QAAQ,SAAS,IAAI;AAAA,EACjC;AACA,QAAM,OAAO,MAAM;AACjB,QAAI,UAAU,OAAW,QAAO,MAAM,KAAK;AAC3C,YAAQ;AACR,UAAM,UAAU;AAChB,QAAI,CAAC,QAAS;AACd,cAAU;AACV,YAAQ,KAAK;AACb;AAAA,MACE,EAAE,GAAI,MAAM,OAAuB,MAAM,MAAM;AAAA,MAC/C,EAAE,GAAI,UAAU,OAAuB,MAAM,MAAM;AAAA,IACrD;AAAA,EACF;AACA,QAAM,MAAM,MAAM;AAChB,QAAI,UAAU,OAAW,QAAO,MAAM,KAAK;AAC3C,YAAQ,OAAO,IAAI,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;AAAA,EAC9E;AACA,QAAM,SAAS,MAAM;AACnB,YAAQ;AACR,UAAM,KAAK,IAAI;AACf,eAAW,CAAC,OAAO,KAAK,KAAK,CAAC,GAAG,MAAM,EAAG,KAAI,SAAS,GAAI,QAAO,OAAO,KAAK;AAC9E,QAAI,OAAO,KAAM,KAAI;AAAA,QAChB,MAAK;AAAA,EACZ;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,KAAK,OAAO,QAAQ;AACxB,YAAM,KAAK,SAAS,OAAO,WAAW;AACtC,aAAO,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,UAAI;AACJ,UAAI,CAAC,SAAS;AACZ,kBAAU,IAAI,QAAQ,SAAS,UAAU,OAAO;AAChD,gBAAQ,MAAM;AAAA,MAChB,WAAW,OAAQ,SAAQ,QAAQ;AACnC,aAAO,EAAE,OAAO,IAAI,MAAM;AAAA,IAC5B;AAAA,IACA,MAAM,MAAM,OAAO;AACjB,UAAI,CAAC,OAAO,OAAO,KAAK,EAAG;AAC3B,UAAI,OAAO,KAAM,KAAI;AAAA,UAChB,MAAK;AAAA,IACZ;AAAA,IACA,QAAQ,MAAM,YAAY;AAAA,IAC1B,MAAM,UAAU;AACd,aAAO,MAAM;AACb,WAAK;AAAA,IACP;AAAA,EACF;AACF;",
|
|
4
|
+
"sourcesContent": ["import {\n type Context,\n type JsonValue,\n type ReplicatedState,\n replicatedState,\n} from '@earendil-works/chord';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type {\n CommitPublication,\n ConversationView,\n Harness,\n TaskGraph,\n TaskGraphNode,\n TaskGraphWatch,\n TaskRecord,\n UsageState,\n} from '@earendil-works/pi-durable';\nimport { type AgentsState, live } from '../agents.ts';\nimport type {\n MonitorAgent,\n MonitorFeed,\n MonitorLease,\n MonitorProblem,\n MonitorProcess,\n MonitorTask,\n} from '../services.ts';\nimport { commandLine, program, redacted } from './redact.ts';\n\nexport interface PsEntry {\n pid: number;\n ppid?: number;\n pgid?: number;\n argv?: readonly string[];\n tty?: unknown;\n started?: number;\n state?: string;\n uid?: number;\n rss?: number;\n utime?: number;\n stime?: number;\n}\n\nexport interface CpuMark {\n started: number;\n total: number;\n at: number;\n}\n\nexport interface CpuReading {\n marks: Map<number, CpuMark>;\n shares: Map<number, number | null>;\n}\n\nfunction timed(entry: PsEntry): entry is PsEntry & { utime: number; stime: number } {\n return typeof entry.utime === 'number' && typeof entry.stime === 'number';\n}\n\nexport function cpuShares(\n entries: readonly PsEntry[],\n previous: ReadonlyMap<number, CpuMark>,\n at: number\n): CpuReading {\n const marks = new Map<number, CpuMark>();\n const shares = new Map<number, number | null>();\n for (const entry of entries) {\n if (!timed(entry)) continue;\n const mark = { started: entry.started ?? 0, total: entry.utime + entry.stime, at };\n const last = previous.get(entry.pid);\n marks.set(entry.pid, mark);\n shares.set(\n entry.pid,\n last && last.started === mark.started && mark.total >= last.total && at > last.at\n ? Math.round(((mark.total - last.total) / (at - last.at)) * 1000) / 1000\n : null\n );\n }\n return { marks, shares };\n}\n\nexport function agentCpu(processes: readonly MonitorProcess[], agentId: string): number | null {\n if (!processes.some((row) => typeof row.cpu === 'number')) return null;\n let sum = 0;\n for (const row of processes) if (row.agentId === agentId) sum += row.cpu ?? 0;\n return Math.round(sum * 1000) / 1000;\n}\n\nexport interface Timers {\n set(run: () => void, ms: number): unknown;\n clear(handle: unknown): void;\n}\n\nexport interface MonitorOptions {\n harness: Pick<Harness, 'watchTaskGraph' | 'usage' | 'subscribeCommits' | 'inspect'>;\n agents: { state(): Readonly<AgentsState>; onChange(listener: () => void): () => void };\n views: ReplicatedState<Record<string, ConversationView>>;\n kernel?: { ps?(): Promise<readonly PsEntry[]> };\n groups?: { owned(owner: number): number[] };\n users?: () => Promise<readonly { name: string; uid: number }[]>;\n secrets?: () => readonly string[];\n now?: () => number;\n timers?: Timers;\n ttlMs?: number;\n psMs?: number;\n psTimeoutMs?: number;\n throttleMs?: number;\n usageMs?: number;\n context?: Context;\n}\n\nexport interface Monitor {\n readonly state: ReplicatedState<MonitorFeed>;\n readonly viewState: ReplicatedState<MonitorFeed>;\n open(lease: string | null, resync: boolean, context: Context): Promise<MonitorLease>;\n close(lease: string, context: Context): Promise<void>;\n active(): boolean;\n dispose(): Promise<void>;\n}\n\nexport const TTL_MS = 30000;\nexport const PS_MS = 2000;\nexport const PS_TIMEOUT_MS = 5000;\nexport const THROTTLE_MS = 1000;\nexport const USAGE_MS = 2000;\nexport const PROBLEMS_MAX = 50;\n\nexport const globalTimers: Timers = {\n set: (run, ms) => setTimeout(run, ms),\n clear: (handle) => clearTimeout(handle as ReturnType<typeof setTimeout>),\n};\n\nexport function emptyFeed(): MonitorFeed {\n return {\n open: false,\n at: 0,\n usage: null,\n agents: [],\n tasks: [],\n processes: null,\n kernel: 'checking',\n problems: [],\n paused: false,\n };\n}\n\ninterface Live {\n run?: unknown;\n generation?: { attempt: number; retry?: { at: number; error: string } };\n tools?: { name: string; status: string; taskId?: unknown }[];\n}\n\ninterface ModelMessage {\n stopReason?: string;\n errorMessage?: string;\n usage?: { input?: number; output?: number; cacheRead?: number; cacheWrite?: number };\n}\n\nexport function totals(usage: UsageState): { tokens: number; cost: number; free: boolean } {\n let tokens = 0;\n let cost = 0;\n for (const bucket of [usage.models, usage.tools])\n for (const entry of Object.values(bucket)) {\n tokens += entry.totalTokens ?? 0;\n cost += entry.cost?.total ?? 0;\n }\n return { tokens, cost, free: cost === 0 };\n}\n\nfunction phaseOf(node: TaskGraphNode): string {\n return 'phase' in node.state ? node.state.phase : node.state.outcome;\n}\n\nfunction contextOf(message: ModelMessage): number | null {\n const usage = message.usage;\n if (!usage) return null;\n const parts = [usage.input, usage.output, usage.cacheRead, usage.cacheWrite];\n const total = parts.reduce<number>((sum, part) => sum + (part ?? 0), 0);\n return total > 0 ? total : null;\n}\n\nfunction lastAssistant(view: ConversationView | undefined) {\n const entries = view?.entries ?? [];\n for (let at = entries.length - 1; at >= 0; at--) {\n const entry = entries[at] as (typeof entries)[number];\n if (entry.kind === 'pi.assistant')\n return { id: String(entry.id), message: (entry.model?.[0] ?? {}) as ModelMessage };\n }\n return undefined;\n}\n\nfunction conversations(state: Readonly<AgentsState>): Map<number, string> {\n const out = new Map<number, string>();\n for (const [id, scoop] of Object.entries(state.scoops)) out.set(scoop.conversation, id);\n for (const [id, cone] of Object.entries(state.cones)) out.set(cone.conversation, id);\n return out;\n}\n\nfunction liveAgents(state: Readonly<AgentsState>) {\n const cones = Object.entries(state.cones).map(([id, cone]) => ({\n id,\n name: cone.name,\n kind: 'cone' as const,\n parentId: null,\n conversation: cone.conversation,\n }));\n const scoops = Object.entries(state.scoops)\n .filter(([, scoop]) => live(scoop))\n .map(([id, scoop]) => ({\n id,\n name: scoop.name,\n kind: 'scoop' as const,\n parentId: scoop.parent,\n conversation: scoop.conversation,\n }));\n return [...cones, ...scoops];\n}\n\nexport function narrowed(feed: MonitorFeed, programs: ReadonlyMap<number, string>): MonitorFeed {\n if (!feed.processes) return feed;\n return {\n ...feed,\n processes: feed.processes.map((row) => ({ ...row, command: programs.get(row.pid) ?? '' })),\n };\n}\n\ninterface Settings {\n now: () => number;\n timers: Timers;\n context: Context;\n psMs: number;\n psTimeoutMs: number;\n throttleMs: number;\n usageMs: number;\n secrets: () => readonly string[];\n}\n\ntype Agent = ReturnType<typeof liveAgents>[number];\n\nclass Session {\n stopped = false;\n readonly #options: MonitorOptions;\n readonly #settings: Settings;\n readonly #publish: (feed: MonitorFeed, view: MonitorFeed) => void;\n readonly #off: (() => void)[] = [];\n readonly #handles = new Set<unknown>();\n #watch: TaskGraphWatch | undefined;\n #graph: TaskGraph = { tasks: {} };\n #usage: UsageState | null = null;\n #processes: readonly PsEntry[] | null = null;\n #cpu: CpuReading = { marks: new Map(), shares: new Map() };\n #kernel: MonitorFeed['kernel'];\n #users = new Map<number, string>();\n #paused = false;\n #problems: MonitorProblem[] = [];\n #seen = new Map<string, number>();\n #next = new Map<string, number>();\n #build: unknown;\n #usageTimer: unknown;\n #lastBuild = Number.NEGATIVE_INFINITY;\n #last = '';\n\n constructor(\n options: MonitorOptions,\n settings: Settings,\n publish: (feed: MonitorFeed, view: MonitorFeed) => void\n ) {\n this.#options = options;\n this.#settings = settings;\n this.#publish = publish;\n this.#kernel = options.kernel?.ps ? 'checking' : 'unreachable';\n }\n\n start(): void {\n const options = this.#options;\n this.#off.push(\n options.harness.subscribeCommits((publication) => this.#commit(publication)),\n options.agents.onChange(() => this.schedule()),\n options.views.subscribe(() => this.schedule())\n );\n void options.harness.watchTaskGraph(this.#settings.context).then(\n (watch) => this.#watching(watch),\n () => undefined\n );\n void options.users?.().then(\n (list) => {\n this.#users = new Map(list.map((user) => [user.uid, user.name]));\n this.schedule();\n },\n () => undefined\n );\n this.#poll();\n this.refresh();\n }\n\n stop(): void {\n this.stopped = true;\n for (const off of this.#off) off();\n for (const handle of this.#handles) this.#settings.timers.clear(handle);\n this.#handles.clear();\n void this.#watch?.stop();\n }\n\n refresh(): void {\n void this.#readUsage();\n void this.#options.harness.inspect(this.#settings.context).then(\n (inspection) => {\n this.#paused = inspection.scheduling === 'paused';\n this.schedule();\n },\n () => undefined\n );\n this.schedule();\n }\n\n schedule(): void {\n if (this.stopped || this.#build !== undefined) return;\n const wait = Math.max(0, this.#lastBuild + this.#settings.throttleMs - this.#settings.now());\n this.#build = this.#later(() => {\n this.#build = undefined;\n this.#emit();\n }, wait);\n }\n\n #later(task: () => void, ms: number): unknown {\n if (this.stopped) return undefined;\n const handle = this.#settings.timers.set(() => {\n this.#handles.delete(handle);\n if (!this.stopped) task();\n }, ms);\n this.#handles.add(handle);\n return handle;\n }\n\n #watching(watch: TaskGraphWatch): void {\n if (this.stopped) {\n void watch.stop();\n return;\n }\n this.#watch = watch;\n this.#graph = watch.value;\n this.schedule();\n watch.start(async (graph) => {\n this.#graph = graph;\n this.schedule();\n });\n }\n\n #readUsage(): Promise<void> {\n return this.#options.harness.usage(this.#settings.context).then(\n (usage) => {\n this.#usage = usage;\n this.schedule();\n },\n () => undefined\n );\n }\n\n #poll(): void {\n const kernel = this.#options.kernel;\n if (!kernel?.ps) return;\n let settled = false;\n const settle = (entries: readonly PsEntry[] | null) => {\n if (settled || this.stopped) return;\n settled = true;\n this.#settings.timers.clear(timeout);\n this.#handles.delete(timeout);\n this.#processes = entries;\n if (entries) this.#cpu = cpuShares(entries, this.#cpu.marks, this.#settings.now());\n this.#kernel = entries ? 'ok' : 'unreachable';\n this.schedule();\n this.#later(() => this.#poll(), this.#settings.psMs);\n };\n const timeout = this.#later(() => settle(null), this.#settings.psTimeoutMs);\n kernel.ps().then(settle, () => settle(null));\n }\n\n #problem(entry: MonitorProblem): void {\n if (this.#problems.some((known) => known.id === entry.id)) return;\n this.#problems.unshift(entry);\n this.#problems.length = Math.min(this.#problems.length, PROBLEMS_MAX);\n }\n\n #commit(publication: CommitPublication): void {\n let changed = false;\n for (const change of publication.changes) {\n if (change.type === 'task') changed = this.#failed(change.value) || changed;\n else if (change.type === 'document' && change.record.kind === 'pi.usage')\n this.#usageChanged();\n }\n if (changed) this.schedule();\n }\n\n #failed(task: TaskRecord<JsonValue, JsonValue, JsonValue>): boolean {\n if (task.state.status !== 'terminal') return false;\n const outcome = task.state.outcome;\n if (outcome.status !== 'faulted' && outcome.status !== 'orphaned') return false;\n this.#problem({\n id: `task:${task.id}`,\n at: this.#settings.now(),\n agentId: conversations(this.#options.agents.state()).get(task.conversationId) ?? null,\n kind: 'task',\n message: redacted(\n outcome.status === 'faulted' ? outcome.error.message : outcome.reason,\n this.#settings.secrets()\n ),\n });\n return true;\n }\n\n #usageChanged(): void {\n if (this.#usageTimer !== undefined) return;\n this.#usageTimer = this.#later(() => {\n this.#usageTimer = undefined;\n void this.#readUsage();\n }, this.#settings.usageMs);\n }\n\n #since(key: string): number {\n const at = this.#seen.get(key) ?? this.#settings.now();\n this.#next.set(key, at);\n return at;\n }\n\n #agent(agent: Agent, view: ConversationView | undefined, tools: Map<string, string>) {\n const secrets = this.#settings.secrets();\n const liveDoc = view?.docs['pi.live'] as Live | undefined;\n for (const slot of liveDoc?.tools ?? [])\n if (slot.taskId !== undefined) tools.set(String(slot.taskId), slot.name);\n const inbox = view?.docs['pi.inbox'] as { items?: unknown[] } | undefined;\n const doc = view?.docs['pi.agent'] as\n | { model?: { provider: string; modelId: string } }\n | undefined;\n const generation = liveDoc?.generation;\n const retry = generation?.retry\n ? {\n attempt: generation.attempt,\n since: this.#since(`retry:${agent.id}`),\n error: redacted(generation.retry.error, secrets),\n }\n : null;\n if (retry)\n this.#problem({\n id: `retry:${agent.id}:${retry.since}`,\n at: retry.since,\n agentId: agent.id,\n kind: 'retry',\n message: retry.error,\n });\n const last = lastAssistant(view);\n const failed =\n last?.message.stopReason === 'error'\n ? redacted(last.message.errorMessage || 'error', secrets)\n : null;\n if (failed && last)\n this.#problem({\n id: `turn:${last.id}`,\n at: this.#settings.now(),\n agentId: agent.id,\n kind: 'turn',\n message: failed,\n });\n return {\n id: agent.id,\n name: agent.name,\n kind: agent.kind,\n parentId: agent.parentId,\n model: doc?.model ? `${doc.model.provider}/${doc.model.modelId}` : null,\n running: Boolean(liveDoc?.run),\n queued: inbox?.items?.length ?? 0,\n tool: liveDoc?.tools?.find((slot) => slot.status === 'running')?.name ?? null,\n retry,\n failed,\n context: last ? contextOf(last.message) : null,\n };\n }\n\n #task(node: TaskGraphNode, owners: Map<number, string>, details: Map<string, string>) {\n const id = String(node.id);\n const status = node.state.status;\n return {\n id,\n kind: node.kind,\n detail: details.get(id) ?? null,\n agentId: owners.get(node.conversationId) ?? null,\n owner: node.owner === undefined ? null : String(node.owner),\n status,\n phase: phaseOf(node),\n background: node.background,\n aborting: node.abortRequested ? this.#since(`abort:${id}`) : null,\n since: this.#since(`task:${id}:${status}`),\n waits: node.state.status === 'waiting' ? node.state.on.length : 0,\n };\n }\n\n #process(entry: PsEntry, groups: Map<number, string>, programs: Map<number, string>) {\n const argv = entry.argv ?? [];\n const pgid = entry.pgid ?? entry.pid;\n const zombie = entry.state === 'Z';\n programs.set(entry.pid, program(argv));\n const uid = entry.uid;\n return {\n pid: entry.pid,\n ppid: entry.ppid ?? 0,\n pgid,\n user:\n uid === undefined ? null : (this.#users.get(uid) ?? (uid === 0 ? 'root' : `uid ${uid}`)),\n agentId: groups.get(pgid) ?? null,\n command: commandLine(argv, this.#settings.secrets()),\n state: zombie ? ('Z' as const) : ('S' as const),\n started: entry.started ?? 0,\n zombie: zombie ? this.#since(`zombie:${entry.pid}`) : null,\n tty: Boolean(entry.tty),\n rss: typeof entry.rss === 'number' ? entry.rss : null,\n ...(timed(entry)\n ? { utime: entry.utime, stime: entry.stime, cpu: this.#cpu.shares.get(entry.pid) ?? null }\n : {}),\n };\n }\n\n #emit(): void {\n this.#lastBuild = this.#settings.now();\n this.#next = new Map();\n const registry = this.#options.agents.state();\n const views = this.#options.views.value ?? {};\n const agents = liveAgents(registry);\n const details = new Map<string, string>();\n const rows: MonitorAgent[] = agents.map((agent) =>\n this.#agent(agent, views[agent.id], details)\n );\n for (const scoop of Object.values(registry.scoops))\n details.set(String(scoop.anchor), scoop.name);\n const owners = conversations(registry);\n const tasks: MonitorTask[] = Object.values(this.#graph.tasks).map((node) =>\n this.#task(node, owners, details)\n );\n const groups = new Map<number, string>();\n for (const agent of agents)\n for (const pgid of this.#options.groups?.owned(agent.conversation) ?? [])\n groups.set(pgid, agent.id);\n const programs = new Map<number, string>();\n const entries = this.#processes;\n const processes: MonitorProcess[] | null =\n entries?.map((entry) => this.#process(entry, groups, programs)) ?? null;\n if (entries?.some(timed))\n for (const row of rows) row.cpu = agentCpu(processes as MonitorProcess[], row.id);\n this.#seen = this.#next;\n const feed: MonitorFeed = {\n open: true,\n at: this.#lastBuild,\n usage: this.#usage ? totals(this.#usage) : null,\n agents: rows,\n tasks,\n processes,\n kernel: this.#kernel,\n problems: [...this.#problems],\n paused: this.#paused,\n };\n const key = JSON.stringify({ ...feed, at: 0 });\n if (key === this.#last) return;\n this.#last = key;\n this.#publish(feed, narrowed(feed, programs));\n }\n}\n\nexport function createMonitor(options: MonitorOptions): Monitor {\n const settings: Settings = {\n now: options.now ?? Date.now,\n timers: options.timers ?? globalTimers,\n context: options.context ?? BACKGROUND_CONTEXT,\n psMs: options.psMs ?? PS_MS,\n psTimeoutMs: options.psTimeoutMs ?? PS_TIMEOUT_MS,\n throttleMs: options.throttleMs ?? THROTTLE_MS,\n usageMs: options.usageMs ?? USAGE_MS,\n secrets: () => options.secrets?.() ?? [],\n };\n const { now, timers, context } = settings;\n const ttlMs = options.ttlMs ?? TTL_MS;\n const state = replicatedState<MonitorFeed>(emptyFeed());\n const viewState = replicatedState<MonitorFeed>(emptyFeed());\n const leases = new Map<string, number>();\n let session: Session | undefined;\n let sweep: unknown;\n const publish = (feed: MonitorFeed, view: MonitorFeed) => {\n state.replace(context, feed);\n viewState.replace(context, view);\n };\n const stop = () => {\n if (sweep !== undefined) timers.clear(sweep);\n sweep = undefined;\n const current = session;\n if (!current) return;\n session = undefined;\n current.stop();\n publish(\n { ...(state.value as MonitorFeed), open: false },\n { ...(viewState.value as MonitorFeed), open: false }\n );\n };\n const arm = () => {\n if (sweep !== undefined) timers.clear(sweep);\n sweep = timers.set(expire, Math.max(0, Math.min(...leases.values()) - now()));\n };\n const expire = () => {\n sweep = undefined;\n const at = now();\n for (const [lease, until] of [...leases]) if (until <= at) leases.delete(lease);\n if (leases.size) arm();\n else stop();\n };\n return {\n state,\n viewState,\n async open(lease, resync) {\n const id = lease ?? crypto.randomUUID();\n leases.set(id, now() + ttlMs);\n arm();\n if (!session) {\n session = new Session(options, settings, publish);\n session.start();\n } else if (resync) session.refresh();\n return { lease: id, ttlMs };\n },\n async close(lease) {\n if (!leases.delete(lease)) return;\n if (leases.size) arm();\n else stop();\n },\n active: () => session !== undefined,\n async dispose() {\n leases.clear();\n stop();\n },\n };\n}\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EAIE;AAAA,OACK;AACP,SAAS,0BAA0B;AAWnC,SAA2B,YAAY;AASvC,SAAS,aAAa,SAAS,gBAAgB;AA2B/C,SAAS,MAAM,OAAqE;AAClF,SAAO,OAAO,MAAM,UAAU,YAAY,OAAO,MAAM,UAAU;AACnE;AAEO,SAAS,UACd,SACA,UACA,IACY;AACZ,QAAM,QAAQ,oBAAI,IAAqB;AACvC,QAAM,SAAS,oBAAI,IAA2B;AAC9C,aAAW,SAAS,SAAS;AAC3B,QAAI,CAAC,MAAM,KAAK,EAAG;AACnB,UAAM,OAAO,EAAE,SAAS,MAAM,WAAW,GAAG,OAAO,MAAM,QAAQ,MAAM,OAAO,GAAG;AACjF,UAAM,OAAO,SAAS,IAAI,MAAM,GAAG;AACnC,UAAM,IAAI,MAAM,KAAK,IAAI;AACzB,WAAO;AAAA,MACL,MAAM;AAAA,MACN,QAAQ,KAAK,YAAY,KAAK,WAAW,KAAK,SAAS,KAAK,SAAS,KAAK,KAAK,KAC3E,KAAK,OAAQ,KAAK,QAAQ,KAAK,UAAU,KAAK,KAAK,MAAO,GAAI,IAAI,MAClE;AAAA,IACN;AAAA,EACF;AACA,SAAO,EAAE,OAAO,OAAO;AACzB;AAEO,SAAS,SAAS,WAAsC,SAAgC;AAC7F,MAAI,CAAC,UAAU,KAAK,CAAC,QAAQ,OAAO,IAAI,QAAQ,QAAQ,EAAG,QAAO;AAClE,MAAI,MAAM;AACV,aAAW,OAAO,UAAW,KAAI,IAAI,YAAY,QAAS,QAAO,IAAI,OAAO;AAC5E,SAAO,KAAK,MAAM,MAAM,GAAI,IAAI;AAClC;AAkCO,MAAM,SAAS;AACf,MAAM,QAAQ;AACd,MAAM,gBAAgB;AACtB,MAAM,cAAc;AACpB,MAAM,WAAW;AACjB,MAAM,eAAe;AAErB,MAAM,eAAuB;AAAA,EAClC,KAAK,CAAC,KAAK,OAAO,WAAW,KAAK,EAAE;AAAA,EACpC,OAAO,CAAC,WAAW,aAAa,MAAuC;AACzE;AAEO,SAAS,YAAyB;AACvC,SAAO;AAAA,IACL,MAAM;AAAA,IACN,IAAI;AAAA,IACJ,OAAO;AAAA,IACP,QAAQ,CAAC;AAAA,IACT,OAAO,CAAC;AAAA,IACR,WAAW;AAAA,IACX,QAAQ;AAAA,IACR,UAAU,CAAC;AAAA,IACX,QAAQ;AAAA,EACV;AACF;AAcO,SAAS,OAAO,OAAoE;AACzF,MAAI,SAAS;AACb,MAAI,OAAO;AACX,aAAW,UAAU,CAAC,MAAM,QAAQ,MAAM,KAAK;AAC7C,eAAW,SAAS,OAAO,OAAO,MAAM,GAAG;AACzC,gBAAU,MAAM,eAAe;AAC/B,cAAQ,MAAM,MAAM,SAAS;AAAA,IAC/B;AACF,SAAO,EAAE,QAAQ,MAAM,MAAM,SAAS,EAAE;AAC1C;AAEA,SAAS,QAAQ,MAA6B;AAC5C,SAAO,WAAW,KAAK,QAAQ,KAAK,MAAM,QAAQ,KAAK,MAAM;AAC/D;AAEA,SAAS,UAAU,SAAsC;AACvD,QAAM,QAAQ,QAAQ;AACtB,MAAI,CAAC,MAAO,QAAO;AACnB,QAAM,QAAQ,CAAC,MAAM,OAAO,MAAM,QAAQ,MAAM,WAAW,MAAM,UAAU;AAC3E,QAAM,QAAQ,MAAM,OAAe,CAAC,KAAK,SAAS,OAAO,QAAQ,IAAI,CAAC;AACtE,SAAO,QAAQ,IAAI,QAAQ;AAC7B;AAEA,SAAS,cAAc,MAAoC;AACzD,QAAM,UAAU,MAAM,WAAW,CAAC;AAClC,WAAS,KAAK,QAAQ,SAAS,GAAG,MAAM,GAAG,MAAM;AAC/C,UAAM,QAAQ,QAAQ,EAAE;AACxB,QAAI,MAAM,SAAS;AACjB,aAAO,EAAE,IAAI,OAAO,MAAM,EAAE,GAAG,SAAU,MAAM,QAAQ,CAAC,KAAK,CAAC,EAAmB;AAAA,EACrF;AACA,SAAO;AACT;AAEA,SAAS,cAAc,OAAmD;AACxE,QAAM,MAAM,oBAAI,IAAoB;AACpC,aAAW,CAAC,IAAI,KAAK,KAAK,OAAO,QAAQ,MAAM,MAAM,EAAG,KAAI,IAAI,MAAM,cAAc,EAAE;AACtF,aAAW,CAAC,IAAI,IAAI,KAAK,OAAO,QAAQ,MAAM,KAAK,EAAG,KAAI,IAAI,KAAK,cAAc,EAAE;AACnF,SAAO;AACT;AAEA,SAAS,WAAW,OAA8B;AAChD,QAAM,QAAQ,OAAO,QAAQ,MAAM,KAAK,EAAE,IAAI,CAAC,CAAC,IAAI,IAAI,OAAO;AAAA,IAC7D;AAAA,IACA,MAAM,KAAK;AAAA,IACX,MAAM;AAAA,IACN,UAAU;AAAA,IACV,cAAc,KAAK;AAAA,EACrB,EAAE;AACF,QAAM,SAAS,OAAO,QAAQ,MAAM,MAAM,EACvC,OAAO,CAAC,CAAC,EAAE,KAAK,MAAM,KAAK,KAAK,CAAC,EACjC,IAAI,CAAC,CAAC,IAAI,KAAK,OAAO;AAAA,IACrB;AAAA,IACA,MAAM,MAAM;AAAA,IACZ,MAAM;AAAA,IACN,UAAU,MAAM;AAAA,IAChB,cAAc,MAAM;AAAA,EACtB,EAAE;AACJ,SAAO,CAAC,GAAG,OAAO,GAAG,MAAM;AAC7B;AAEO,SAAS,SAAS,MAAmB,UAAoD;AAC9F,MAAI,CAAC,KAAK,UAAW,QAAO;AAC5B,SAAO;AAAA,IACL,GAAG;AAAA,IACH,WAAW,KAAK,UAAU,IAAI,CAAC,SAAS,EAAE,GAAG,KAAK,SAAS,SAAS,IAAI,IAAI,GAAG,KAAK,GAAG,EAAE;AAAA,EAC3F;AACF;AAeA,MAAM,QAAQ;AAAA,EACZ,UAAU;AAAA,EACD;AAAA,EACA;AAAA,EACA;AAAA,EACA,OAAuB,CAAC;AAAA,EACxB,WAAW,oBAAI,IAAa;AAAA,EACrC;AAAA,EACA,SAAoB,EAAE,OAAO,CAAC,EAAE;AAAA,EAChC,SAA4B;AAAA,EAC5B,aAAwC;AAAA,EACxC,OAAmB,EAAE,OAAO,oBAAI,IAAI,GAAG,QAAQ,oBAAI,IAAI,EAAE;AAAA,EACzD;AAAA,EACA,SAAS,oBAAI,IAAoB;AAAA,EACjC,UAAU;AAAA,EACV,YAA8B,CAAC;AAAA,EAC/B,QAAQ,oBAAI,IAAoB;AAAA,EAChC,QAAQ,oBAAI,IAAoB;AAAA,EAChC;AAAA,EACA;AAAA,EACA,aAAa,OAAO;AAAA,EACpB,QAAQ;AAAA,EAER,YACE,SACA,UACA,SACA;AACA,SAAK,WAAW;AAChB,SAAK,YAAY;AACjB,SAAK,WAAW;AAChB,SAAK,UAAU,QAAQ,QAAQ,KAAK,aAAa;AAAA,EACnD;AAAA,EAEA,QAAc;AACZ,UAAM,UAAU,KAAK;AACrB,SAAK,KAAK;AAAA,MACR,QAAQ,QAAQ,iBAAiB,CAAC,gBAAgB,KAAK,QAAQ,WAAW,CAAC;AAAA,MAC3E,QAAQ,OAAO,SAAS,MAAM,KAAK,SAAS,CAAC;AAAA,MAC7C,QAAQ,MAAM,UAAU,MAAM,KAAK,SAAS,CAAC;AAAA,IAC/C;AACA,SAAK,QAAQ,QAAQ,eAAe,KAAK,UAAU,OAAO,EAAE;AAAA,MAC1D,CAAC,UAAU,KAAK,UAAU,KAAK;AAAA,MAC/B,MAAM;AAAA,IACR;AACA,SAAK,QAAQ,QAAQ,EAAE;AAAA,MACrB,CAAC,SAAS;AACR,aAAK,SAAS,IAAI,IAAI,KAAK,IAAI,CAAC,SAAS,CAAC,KAAK,KAAK,KAAK,IAAI,CAAC,CAAC;AAC/D,aAAK,SAAS;AAAA,MAChB;AAAA,MACA,MAAM;AAAA,IACR;AACA,SAAK,MAAM;AACX,SAAK,QAAQ;AAAA,EACf;AAAA,EAEA,OAAa;AACX,SAAK,UAAU;AACf,eAAW,OAAO,KAAK,KAAM,KAAI;AACjC,eAAW,UAAU,KAAK,SAAU,MAAK,UAAU,OAAO,MAAM,MAAM;AACtE,SAAK,SAAS,MAAM;AACpB,SAAK,KAAK,QAAQ,KAAK;AAAA,EACzB;AAAA,EAEA,UAAgB;AACd,SAAK,KAAK,WAAW;AACrB,SAAK,KAAK,SAAS,QAAQ,QAAQ,KAAK,UAAU,OAAO,EAAE;AAAA,MACzD,CAAC,eAAe;AACd,aAAK,UAAU,WAAW,eAAe;AACzC,aAAK,SAAS;AAAA,MAChB;AAAA,MACA,MAAM;AAAA,IACR;AACA,SAAK,SAAS;AAAA,EAChB;AAAA,EAEA,WAAiB;AACf,QAAI,KAAK,WAAW,KAAK,WAAW,OAAW;AAC/C,UAAM,OAAO,KAAK,IAAI,GAAG,KAAK,aAAa,KAAK,UAAU,aAAa,KAAK,UAAU,IAAI,CAAC;AAC3F,SAAK,SAAS,KAAK,OAAO,MAAM;AAC9B,WAAK,SAAS;AACd,WAAK,MAAM;AAAA,IACb,GAAG,IAAI;AAAA,EACT;AAAA,EAEA,OAAO,MAAkB,IAAqB;AAC5C,QAAI,KAAK,QAAS,QAAO;AACzB,UAAM,SAAS,KAAK,UAAU,OAAO,IAAI,MAAM;AAC7C,WAAK,SAAS,OAAO,MAAM;AAC3B,UAAI,CAAC,KAAK,QAAS,MAAK;AAAA,IAC1B,GAAG,EAAE;AACL,SAAK,SAAS,IAAI,MAAM;AACxB,WAAO;AAAA,EACT;AAAA,EAEA,UAAU,OAA6B;AACrC,QAAI,KAAK,SAAS;AAChB,WAAK,MAAM,KAAK;AAChB;AAAA,IACF;AACA,SAAK,SAAS;AACd,SAAK,SAAS,MAAM;AACpB,SAAK,SAAS;AACd,UAAM,MAAM,OAAO,UAAU;AAC3B,WAAK,SAAS;AACd,WAAK,SAAS;AAAA,IAChB,CAAC;AAAA,EACH;AAAA,EAEA,aAA4B;AAC1B,WAAO,KAAK,SAAS,QAAQ,MAAM,KAAK,UAAU,OAAO,EAAE;AAAA,MACzD,CAAC,UAAU;AACT,aAAK,SAAS;AACd,aAAK,SAAS;AAAA,MAChB;AAAA,MACA,MAAM;AAAA,IACR;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,UAAM,SAAS,KAAK,SAAS;AAC7B,QAAI,CAAC,QAAQ,GAAI;AACjB,QAAI,UAAU;AACd,UAAM,SAAS,CAAC,YAAuC;AACrD,UAAI,WAAW,KAAK,QAAS;AAC7B,gBAAU;AACV,WAAK,UAAU,OAAO,MAAM,OAAO;AACnC,WAAK,SAAS,OAAO,OAAO;AAC5B,WAAK,aAAa;AAClB,UAAI,QAAS,MAAK,OAAO,UAAU,SAAS,KAAK,KAAK,OAAO,KAAK,UAAU,IAAI,CAAC;AACjF,WAAK,UAAU,UAAU,OAAO;AAChC,WAAK,SAAS;AACd,WAAK,OAAO,MAAM,KAAK,MAAM,GAAG,KAAK,UAAU,IAAI;AAAA,IACrD;AACA,UAAM,UAAU,KAAK,OAAO,MAAM,OAAO,IAAI,GAAG,KAAK,UAAU,WAAW;AAC1E,WAAO,GAAG,EAAE,KAAK,QAAQ,MAAM,OAAO,IAAI,CAAC;AAAA,EAC7C;AAAA,EAEA,SAAS,OAA6B;AACpC,QAAI,KAAK,UAAU,KAAK,CAAC,UAAU,MAAM,OAAO,MAAM,EAAE,EAAG;AAC3D,SAAK,UAAU,QAAQ,KAAK;AAC5B,SAAK,UAAU,SAAS,KAAK,IAAI,KAAK,UAAU,QAAQ,YAAY;AAAA,EACtE;AAAA,EAEA,QAAQ,aAAsC;AAC5C,QAAI,UAAU;AACd,eAAW,UAAU,YAAY,SAAS;AACxC,UAAI,OAAO,SAAS,OAAQ,WAAU,KAAK,QAAQ,OAAO,KAAK,KAAK;AAAA,eAC3D,OAAO,SAAS,cAAc,OAAO,OAAO,SAAS;AAC5D,aAAK,cAAc;AAAA,IACvB;AACA,QAAI,QAAS,MAAK,SAAS;AAAA,EAC7B;AAAA,EAEA,QAAQ,MAA4D;AAClE,QAAI,KAAK,MAAM,WAAW,WAAY,QAAO;AAC7C,UAAM,UAAU,KAAK,MAAM;AAC3B,QAAI,QAAQ,WAAW,aAAa,QAAQ,WAAW,WAAY,QAAO;AAC1E,SAAK,SAAS;AAAA,MACZ,IAAI,QAAQ,KAAK,EAAE;AAAA,MACnB,IAAI,KAAK,UAAU,IAAI;AAAA,MACvB,SAAS,cAAc,KAAK,SAAS,OAAO,MAAM,CAAC,EAAE,IAAI,KAAK,cAAc,KAAK;AAAA,MACjF,MAAM;AAAA,MACN,SAAS;AAAA,QACP,QAAQ,WAAW,YAAY,QAAQ,MAAM,UAAU,QAAQ;AAAA,QAC/D,KAAK,UAAU,QAAQ;AAAA,MACzB;AAAA,IACF,CAAC;AACD,WAAO;AAAA,EACT;AAAA,EAEA,gBAAsB;AACpB,QAAI,KAAK,gBAAgB,OAAW;AACpC,SAAK,cAAc,KAAK,OAAO,MAAM;AACnC,WAAK,cAAc;AACnB,WAAK,KAAK,WAAW;AAAA,IACvB,GAAG,KAAK,UAAU,OAAO;AAAA,EAC3B;AAAA,EAEA,OAAO,KAAqB;AAC1B,UAAM,KAAK,KAAK,MAAM,IAAI,GAAG,KAAK,KAAK,UAAU,IAAI;AACrD,SAAK,MAAM,IAAI,KAAK,EAAE;AACtB,WAAO;AAAA,EACT;AAAA,EAEA,OAAO,OAAc,MAAoC,OAA4B;AACnF,UAAM,UAAU,KAAK,UAAU,QAAQ;AACvC,UAAM,UAAU,MAAM,KAAK,SAAS;AACpC,eAAW,QAAQ,SAAS,SAAS,CAAC;AACpC,UAAI,KAAK,WAAW,OAAW,OAAM,IAAI,OAAO,KAAK,MAAM,GAAG,KAAK,IAAI;AACzE,UAAM,QAAQ,MAAM,KAAK,UAAU;AACnC,UAAM,MAAM,MAAM,KAAK,UAAU;AAGjC,UAAM,aAAa,SAAS;AAC5B,UAAM,QAAQ,YAAY,QACtB;AAAA,MACE,SAAS,WAAW;AAAA,MACpB,OAAO,KAAK,OAAO,SAAS,MAAM,EAAE,EAAE;AAAA,MACtC,OAAO,SAAS,WAAW,MAAM,OAAO,OAAO;AAAA,IACjD,IACA;AACJ,QAAI;AACF,WAAK,SAAS;AAAA,QACZ,IAAI,SAAS,MAAM,EAAE,IAAI,MAAM,KAAK;AAAA,QACpC,IAAI,MAAM;AAAA,QACV,SAAS,MAAM;AAAA,QACf,MAAM;AAAA,QACN,SAAS,MAAM;AAAA,MACjB,CAAC;AACH,UAAM,OAAO,cAAc,IAAI;AAC/B,UAAM,SACJ,MAAM,QAAQ,eAAe,UACzB,SAAS,KAAK,QAAQ,gBAAgB,SAAS,OAAO,IACtD;AACN,QAAI,UAAU;AACZ,WAAK,SAAS;AAAA,QACZ,IAAI,QAAQ,KAAK,EAAE;AAAA,QACnB,IAAI,KAAK,UAAU,IAAI;AAAA,QACvB,SAAS,MAAM;AAAA,QACf,MAAM;AAAA,QACN,SAAS;AAAA,MACX,CAAC;AACH,WAAO;AAAA,MACL,IAAI,MAAM;AAAA,MACV,MAAM,MAAM;AAAA,MACZ,MAAM,MAAM;AAAA,MACZ,UAAU,MAAM;AAAA,MAChB,OAAO,KAAK,QAAQ,GAAG,IAAI,MAAM,QAAQ,IAAI,IAAI,MAAM,OAAO,KAAK;AAAA,MACnE,SAAS,QAAQ,SAAS,GAAG;AAAA,MAC7B,QAAQ,OAAO,OAAO,UAAU;AAAA,MAChC,MAAM,SAAS,OAAO,KAAK,CAAC,SAAS,KAAK,WAAW,SAAS,GAAG,QAAQ;AAAA,MACzE;AAAA,MACA;AAAA,MACA,SAAS,OAAO,UAAU,KAAK,OAAO,IAAI;AAAA,IAC5C;AAAA,EACF;AAAA,EAEA,MAAM,MAAqB,QAA6B,SAA8B;AACpF,UAAM,KAAK,OAAO,KAAK,EAAE;AACzB,UAAM,SAAS,KAAK,MAAM;AAC1B,WAAO;AAAA,MACL;AAAA,MACA,MAAM,KAAK;AAAA,MACX,QAAQ,QAAQ,IAAI,EAAE,KAAK;AAAA,MAC3B,SAAS,OAAO,IAAI,KAAK,cAAc,KAAK;AAAA,MAC5C,OAAO,KAAK,UAAU,SAAY,OAAO,OAAO,KAAK,KAAK;AAAA,MAC1D;AAAA,MACA,OAAO,QAAQ,IAAI;AAAA,MACnB,YAAY,KAAK;AAAA,MACjB,UAAU,KAAK,iBAAiB,KAAK,OAAO,SAAS,EAAE,EAAE,IAAI;AAAA,MAC7D,OAAO,KAAK,OAAO,QAAQ,EAAE,IAAI,MAAM,EAAE;AAAA,MACzC,OAAO,KAAK,MAAM,WAAW,YAAY,KAAK,MAAM,GAAG,SAAS;AAAA,IAClE;AAAA,EACF;AAAA,EAEA,SAAS,OAAgB,QAA6B,UAA+B;AACnF,UAAM,OAAO,MAAM,QAAQ,CAAC;AAC5B,UAAM,OAAO,MAAM,QAAQ,MAAM;AACjC,UAAM,SAAS,MAAM,UAAU;AAC/B,aAAS,IAAI,MAAM,KAAK,QAAQ,IAAI,CAAC;AACrC,UAAM,MAAM,MAAM;AAClB,WAAO;AAAA,MACL,KAAK,MAAM;AAAA,MACX,MAAM,MAAM,QAAQ;AAAA,MACpB;AAAA,MACA,MACE,QAAQ,SAAY,OAAQ,KAAK,OAAO,IAAI,GAAG,MAAM,QAAQ,IAAI,SAAS,OAAO,GAAG;AAAA,MACtF,SAAS,OAAO,IAAI,IAAI,KAAK;AAAA,MAC7B,SAAS,YAAY,MAAM,KAAK,UAAU,QAAQ,CAAC;AAAA,MACnD,OAAO,SAAU,MAAiB;AAAA,MAClC,SAAS,MAAM,WAAW;AAAA,MAC1B,QAAQ,SAAS,KAAK,OAAO,UAAU,MAAM,GAAG,EAAE,IAAI;AAAA,MACtD,KAAK,QAAQ,MAAM,GAAG;AAAA,MACtB,KAAK,OAAO,MAAM,QAAQ,WAAW,MAAM,MAAM;AAAA,MACjD,GAAI,MAAM,KAAK,IACX,EAAE,OAAO,MAAM,OAAO,OAAO,MAAM,OAAO,KAAK,KAAK,KAAK,OAAO,IAAI,MAAM,GAAG,KAAK,KAAK,IACvF,CAAC;AAAA,IACP;AAAA,EACF;AAAA,EAEA,QAAc;AACZ,SAAK,aAAa,KAAK,UAAU,IAAI;AACrC,SAAK,QAAQ,oBAAI,IAAI;AACrB,UAAM,WAAW,KAAK,SAAS,OAAO,MAAM;AAC5C,UAAM,QAAQ,KAAK,SAAS,MAAM,SAAS,CAAC;AAC5C,UAAM,SAAS,WAAW,QAAQ;AAClC,UAAM,UAAU,oBAAI,IAAoB;AACxC,UAAM,OAAuB,OAAO;AAAA,MAAI,CAAC,UACvC,KAAK,OAAO,OAAO,MAAM,MAAM,EAAE,GAAG,OAAO;AAAA,IAC7C;AACA,eAAW,SAAS,OAAO,OAAO,SAAS,MAAM;AAC/C,cAAQ,IAAI,OAAO,MAAM,MAAM,GAAG,MAAM,IAAI;AAC9C,UAAM,SAAS,cAAc,QAAQ;AACrC,UAAM,QAAuB,OAAO,OAAO,KAAK,OAAO,KAAK,EAAE;AAAA,MAAI,CAAC,SACjE,KAAK,MAAM,MAAM,QAAQ,OAAO;AAAA,IAClC;AACA,UAAM,SAAS,oBAAI,IAAoB;AACvC,eAAW,SAAS;AAClB,iBAAW,QAAQ,KAAK,SAAS,QAAQ,MAAM,MAAM,YAAY,KAAK,CAAC;AACrE,eAAO,IAAI,MAAM,MAAM,EAAE;AAC7B,UAAM,WAAW,oBAAI,IAAoB;AACzC,UAAM,UAAU,KAAK;AACrB,UAAM,YACJ,SAAS,IAAI,CAAC,UAAU,KAAK,SAAS,OAAO,QAAQ,QAAQ,CAAC,KAAK;AACrE,QAAI,SAAS,KAAK,KAAK;AACrB,iBAAW,OAAO,KAAM,KAAI,MAAM,SAAS,WAA+B,IAAI,EAAE;AAClF,SAAK,QAAQ,KAAK;AAClB,UAAM,OAAoB;AAAA,MACxB,MAAM;AAAA,MACN,IAAI,KAAK;AAAA,MACT,OAAO,KAAK,SAAS,OAAO,KAAK,MAAM,IAAI;AAAA,MAC3C,QAAQ;AAAA,MACR;AAAA,MACA;AAAA,MACA,QAAQ,KAAK;AAAA,MACb,UAAU,CAAC,GAAG,KAAK,SAAS;AAAA,MAC5B,QAAQ,KAAK;AAAA,IACf;AACA,UAAM,MAAM,KAAK,UAAU,EAAE,GAAG,MAAM,IAAI,EAAE,CAAC;AAC7C,QAAI,QAAQ,KAAK,MAAO;AACxB,SAAK,QAAQ;AACb,SAAK,SAAS,MAAM,SAAS,MAAM,QAAQ,CAAC;AAAA,EAC9C;AACF;AAEO,SAAS,cAAc,SAAkC;AAC9D,QAAM,WAAqB;AAAA,IACzB,KAAK,QAAQ,OAAO,KAAK;AAAA,IACzB,QAAQ,QAAQ,UAAU;AAAA,IAC1B,SAAS,QAAQ,WAAW;AAAA,IAC5B,MAAM,QAAQ,QAAQ;AAAA,IACtB,aAAa,QAAQ,eAAe;AAAA,IACpC,YAAY,QAAQ,cAAc;AAAA,IAClC,SAAS,QAAQ,WAAW;AAAA,IAC5B,SAAS,MAAM,QAAQ,UAAU,KAAK,CAAC;AAAA,EACzC;AACA,QAAM,EAAE,KAAK,QAAQ,QAAQ,IAAI;AACjC,QAAM,QAAQ,QAAQ,SAAS;AAC/B,QAAM,QAAQ,gBAA6B,UAAU,CAAC;AACtD,QAAM,YAAY,gBAA6B,UAAU,CAAC;AAC1D,QAAM,SAAS,oBAAI,IAAoB;AACvC,MAAI;AACJ,MAAI;AACJ,QAAM,UAAU,CAAC,MAAmB,SAAsB;AACxD,UAAM,QAAQ,SAAS,IAAI;AAC3B,cAAU,QAAQ,SAAS,IAAI;AAAA,EACjC;AACA,QAAM,OAAO,MAAM;AACjB,QAAI,UAAU,OAAW,QAAO,MAAM,KAAK;AAC3C,YAAQ;AACR,UAAM,UAAU;AAChB,QAAI,CAAC,QAAS;AACd,cAAU;AACV,YAAQ,KAAK;AACb;AAAA,MACE,EAAE,GAAI,MAAM,OAAuB,MAAM,MAAM;AAAA,MAC/C,EAAE,GAAI,UAAU,OAAuB,MAAM,MAAM;AAAA,IACrD;AAAA,EACF;AACA,QAAM,MAAM,MAAM;AAChB,QAAI,UAAU,OAAW,QAAO,MAAM,KAAK;AAC3C,YAAQ,OAAO,IAAI,QAAQ,KAAK,IAAI,GAAG,KAAK,IAAI,GAAG,OAAO,OAAO,CAAC,IAAI,IAAI,CAAC,CAAC;AAAA,EAC9E;AACA,QAAM,SAAS,MAAM;AACnB,YAAQ;AACR,UAAM,KAAK,IAAI;AACf,eAAW,CAAC,OAAO,KAAK,KAAK,CAAC,GAAG,MAAM,EAAG,KAAI,SAAS,GAAI,QAAO,OAAO,KAAK;AAC9E,QAAI,OAAO,KAAM,KAAI;AAAA,QAChB,MAAK;AAAA,EACZ;AACA,SAAO;AAAA,IACL;AAAA,IACA;AAAA,IACA,MAAM,KAAK,OAAO,QAAQ;AACxB,YAAM,KAAK,SAAS,OAAO,WAAW;AACtC,aAAO,IAAI,IAAI,IAAI,IAAI,KAAK;AAC5B,UAAI;AACJ,UAAI,CAAC,SAAS;AACZ,kBAAU,IAAI,QAAQ,SAAS,UAAU,OAAO;AAChD,gBAAQ,MAAM;AAAA,MAChB,WAAW,OAAQ,SAAQ,QAAQ;AACnC,aAAO,EAAE,OAAO,IAAI,MAAM;AAAA,IAC5B;AAAA,IACA,MAAM,MAAM,OAAO;AACjB,UAAI,CAAC,OAAO,OAAO,KAAK,EAAG;AAC3B,UAAI,OAAO,KAAM,KAAI;AAAA,UAChB,MAAK;AAAA,IACZ;AAAA,IACA,QAAQ,MAAM,YAAY;AAAA,IAC1B,MAAM,UAAU;AACd,aAAO,MAAM;AACb,WAAK;AAAA,IACP;AAAA,EACF;AACF;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
package/dist/services.js.map
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"version": 3,
|
|
3
3
|
"sources": ["../src/services.ts"],
|
|
4
|
-
"sourcesContent": ["import {\n type Context,\n defineService,\n type JsonValue,\n type ReplicatedState,\n} from '@earendil-works/chord';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { ChangesView } from './changes/git.ts';\nimport type { FrozenCone } from './freezer/index.ts';\nimport type { MemoryEntry, MemoryScope, MemoryTag } from './memory/format.ts';\nimport type { AgentRemote } from './remote/host.ts';\nimport type { AgentPages } from './remote/pages.ts';\nimport type { VaultState } from './secrets/vault.ts';\nimport type { Sprinkle } from './sprinkles/kind.ts';\n\nexport type SendMode = 'steer' | 'followUp' | 'reject';\n\nexport interface SendRequest {\n text: string;\n whenBusy: SendMode;\n requestId: string | null;\n agentId?: string | null;\n}\n\nexport interface OperationError {\n code: string;\n message: string;\n}\n\nexport type SendResponse =\n | { accepted: true; submissionId: string; error: null }\n | { accepted: false; submissionId: null; error: OperationError };\n\nexport type PromptResult =\n | { status: 'done'; text: string; reason: null }\n | { status: 'unanswered'; text: null; reason: string };\n\nexport interface AgentControl {\n send(request: SendRequest, context: Context): Promise<SendResponse>;\n wait(submissionId: string, context: Context): Promise<PromptResult>;\n withdraw(\n submissionId: string,\n context: Context\n ): Promise<{ outcome: 'withdrawn' | 'already_placed' | 'not_found' }>;\n abort(context: Context): Promise<void>;\n compact(instructions: string | null, context: Context): Promise<SendResponse>;\n compactAgent(\n agentId: string,\n instructions: string | null,\n context: Context\n ): Promise<SendResponse>;\n reset(handoff: string | null, context: Context): Promise<void>;\n configure(change: AgentSettingsChange, context: Context): Promise<void>;\n rewind(messageId: string | null, context: Context): Promise<Rewound>;\n rewindAgent(agentId: string, messageId: string | null, context: Context): Promise<Rewound>;\n resolveLick(\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved>;\n resolveAgentLick(\n agentId: string,\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved>;\n webhook(\n name: string,\n delivery: WebhookRequest,\n context: Context\n ): Promise<{ delivered: boolean }>;\n stopAgent(agentId: string, context: Context): Promise<void>;\n selectCone(agentId: string, context: Context): Promise<void>;\n createCone(name: string, context: Context): Promise<Created>;\n createScoop(parentId: string, name: string, context: Context): Promise<Created>;\n drop(agentId: string, context: Context): Promise<Created>;\n unqueue(\n agentId: string | null,\n submissionId: string,\n context: Context\n ): Promise<{ outcome: 'withdrawn' | 'already_placed' | 'not_found' }>;\n sprinkleSend(\n sprinkleId: string,\n payload: { action: string; data: JsonValue | null; target: string | null },\n context: Context\n ): Promise<{ delivered: boolean }>;\n sprinkleCall(\n sprinkleId: string,\n method: string,\n args: JsonValue[],\n context: Context\n ): Promise<JsonValue>;\n memorySave(draft: MemoryDraft, context: Context): Promise<MemoryEntry>;\n memoryRemove(id: string, context: Context): Promise<{ removed: boolean }>;\n freeze(agentId: string, context: Context): Promise<Created>;\n newChat(agentId: string, context: Context): Promise<Created>;\n thaw(frozenId: string, context: Context): Promise<Created>;\n discard(frozenId: string, context: Context): Promise<Created>;\n changesOpen(context: Context): Promise<void>;\n changeAccept(path: string, context: Context): Promise<Created>;\n changeRevert(path: string, context: Context): Promise<Created>;\n monitorOpen(lease: string | null, resync: boolean, context: Context): Promise<MonitorLease>;\n monitorClose(lease: string, context: Context): Promise<void>;\n}\n\nexport interface MonitorLease {\n lease: string;\n ttlMs: number;\n}\n\nexport interface MonitorAgent {\n id: string;\n name: string;\n kind: 'cone' | 'scoop';\n parentId: string | null;\n model: string | null;\n running: boolean;\n queued: number;\n tool: string | null;\n retry: { attempt: number; since: number; error: string } | null;\n failed: string | null;\n context: number | null;\n}\n\nexport interface MonitorTask {\n id: string;\n kind: string;\n detail: string | null;\n agentId: string | null;\n owner: string | null;\n status: 'pending' | 'running' | 'waiting' | 'completing';\n phase: string;\n background: boolean;\n aborting: number | null;\n since: number;\n waits: number;\n}\n\nexport interface MonitorProcess {\n pid: number;\n ppid: number;\n pgid: number;\n user: string | null;\n agentId: string | null;\n command: string;\n state: 'S' | 'Z';\n started: number;\n zombie: number | null;\n tty: boolean;\n rss: number | null;\n}\n\nexport interface MonitorProblem {\n id: string;\n at: number;\n agentId: string | null;\n kind: 'task' | 'retry' | 'turn';\n message: string;\n}\n\nexport interface MonitorFeed {\n open: boolean;\n at: number;\n usage: { tokens: number; cost: number; free: boolean } | null;\n agents: MonitorAgent[];\n tasks: MonitorTask[];\n processes: MonitorProcess[] | null;\n kernel: 'checking' | 'ok' | 'unreachable';\n problems: MonitorProblem[];\n paused: boolean;\n}\n\nexport interface MemoryDraft {\n id: string | null;\n scope: string;\n section: string;\n title: string;\n body: string;\n tag: MemoryTag | null;\n}\n\nexport type Created = { id: string; error: null } | { id: null; error: string };\n\nexport interface AgentSummary {\n id: string;\n name: string;\n kind: 'cone' | 'scoop';\n parentId: string | null;\n role: string | null;\n}\n\nexport interface AgentsSummary {\n active: string;\n agents: AgentSummary[];\n}\n\nexport type LickResolved =\n | { done: true; text: string; error: null }\n | { done: false; text: null; error: string };\n\nexport interface WebhookRequest {\n id: string | null;\n headers: Record<string, string>;\n body: string;\n}\n\nexport type Rewound =\n | { done: true; text: string; reason: null }\n | { done: false; text: null; reason: 'busy' | 'no-turn' };\n\nexport interface AgentSettingsChange {\n model: { provider: string; modelId: string } | null;\n thinkingLevel: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | null;\n agentId?: string | null;\n}\n\nexport const AgentControl = defineService<AgentControl>('slicc.agent.control');\n\nexport type Delivered = 'run' | 'steer' | 'follow-up';\n\nexport interface AgentTranscript {\n readonly state: ReplicatedState<ConversationView>;\n readonly deliveries: ReplicatedState<Record<string, Delivered>>;\n readonly agents: ReplicatedState<AgentsSummary>;\n readonly views: ReplicatedState<Record<string, ConversationView>>;\n readonly commands: ReplicatedState<Command[]>;\n readonly sprinkles: ReplicatedState<Sprinkle[]>;\n readonly memories: ReplicatedState<MemoryEntry[]>;\n readonly memoryScopes: ReplicatedState<MemoryScope[]>;\n readonly frozen: ReplicatedState<FrozenCone[]>;\n readonly changes: ReplicatedState<ChangesView>;\n readonly monitor: ReplicatedState<MonitorFeed>;\n readonly vault: ReplicatedState<VaultState>;\n}\n\nexport interface Command {\n name: string;\n description: string;\n kind: 'prompt' | 'skill' | 'action';\n}\n\nexport const AgentTranscript = defineService<AgentTranscript>('slicc.agent.transcript');\n\nexport interface AgentSessions {\n attach(sessionId: string, context: Context): Promise<void>;\n detach(context: Context): Promise<void>;\n}\n\nexport const AgentSessions = defineService<AgentSessions>('slicc.agent.sessions');\n\nexport const AgentRemoteService = defineService<AgentRemote>('slicc.agent.remote');\n\nexport const AgentPagesService = defineService<AgentPages>('slicc.agent.pages');\n\nexport const AGENT_SESSION = 'agent';\n\nexport interface ModelChoice {\n id: string;\n label: string;\n provider: string;\n kind: 'chat' | 'classifier';\n reasoning: boolean;\n images?: boolean;\n contextWindow: number;\n}\n\nexport interface AccountState {\n id: string;\n provider: string;\n identity: string;\n status: 'connected' | 'disconnected' | 'expired';\n auth: 'api-key' | 'oauth';\n needs: 'cors-free-transport' | null;\n group?: 'providers' | 'mcp';\n secret?: 'api-key' | 'token';\n}\n\nexport interface BudgetState {\n provider: string;\n percent: number;\n window: 'weekly';\n resets: string;\n}\n\nexport interface SignIn {\n clientId: string;\n scopes: string;\n imsEnvironment: string;\n}\n\nexport interface McpSignIn {\n url: string;\n state: string;\n}\n\nexport interface SettingsState {\n models: ModelChoice[];\n accounts: AccountState[];\n budget?: BudgetState | null;\n}\n\nexport interface AgentSettings {\n readonly state: ReplicatedState<SettingsState>;\n connect(\n providerId: string,\n secret: string,\n region: string | null,\n context: Context\n ): Promise<void>;\n disconnect(providerId: string, context: Context): Promise<void>;\n signIn(providerId: string, context: Context): Promise<SignIn | McpSignIn | null>;\n}\n\nexport const AgentSettings = defineService<AgentSettings>('slicc.agent.settings');\n"],
|
|
5
|
-
"mappings": "AAAA;AAAA,EAEE;AAAA,OAGK;
|
|
4
|
+
"sourcesContent": ["import {\n type Context,\n defineService,\n type JsonValue,\n type ReplicatedState,\n} from '@earendil-works/chord';\nimport type { ConversationView } from '@earendil-works/pi-durable';\nimport type { ChangesView } from './changes/git.ts';\nimport type { FrozenCone } from './freezer/index.ts';\nimport type { MemoryEntry, MemoryScope, MemoryTag } from './memory/format.ts';\nimport type { AgentRemote } from './remote/host.ts';\nimport type { AgentPages } from './remote/pages.ts';\nimport type { VaultState } from './secrets/vault.ts';\nimport type { Sprinkle } from './sprinkles/kind.ts';\n\nexport type SendMode = 'steer' | 'followUp' | 'reject';\n\nexport interface SendRequest {\n text: string;\n whenBusy: SendMode;\n requestId: string | null;\n agentId?: string | null;\n}\n\nexport interface OperationError {\n code: string;\n message: string;\n}\n\nexport type SendResponse =\n | { accepted: true; submissionId: string; error: null }\n | { accepted: false; submissionId: null; error: OperationError };\n\nexport type PromptResult =\n | { status: 'done'; text: string; reason: null }\n | { status: 'unanswered'; text: null; reason: string };\n\nexport interface AgentControl {\n send(request: SendRequest, context: Context): Promise<SendResponse>;\n wait(submissionId: string, context: Context): Promise<PromptResult>;\n withdraw(\n submissionId: string,\n context: Context\n ): Promise<{ outcome: 'withdrawn' | 'already_placed' | 'not_found' }>;\n abort(context: Context): Promise<void>;\n compact(instructions: string | null, context: Context): Promise<SendResponse>;\n compactAgent(\n agentId: string,\n instructions: string | null,\n context: Context\n ): Promise<SendResponse>;\n reset(handoff: string | null, context: Context): Promise<void>;\n configure(change: AgentSettingsChange, context: Context): Promise<void>;\n rewind(messageId: string | null, context: Context): Promise<Rewound>;\n rewindAgent(agentId: string, messageId: string | null, context: Context): Promise<Rewound>;\n resolveLick(\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved>;\n resolveAgentLick(\n agentId: string,\n lickId: string,\n state: 'confirmed' | 'dismissed',\n context: Context\n ): Promise<LickResolved>;\n webhook(\n name: string,\n delivery: WebhookRequest,\n context: Context\n ): Promise<{ delivered: boolean }>;\n stopAgent(agentId: string, context: Context): Promise<void>;\n selectCone(agentId: string, context: Context): Promise<void>;\n createCone(name: string, context: Context): Promise<Created>;\n createScoop(parentId: string, name: string, context: Context): Promise<Created>;\n drop(agentId: string, context: Context): Promise<Created>;\n unqueue(\n agentId: string | null,\n submissionId: string,\n context: Context\n ): Promise<{ outcome: 'withdrawn' | 'already_placed' | 'not_found' }>;\n sprinkleSend(\n sprinkleId: string,\n payload: { action: string; data: JsonValue | null; target: string | null },\n context: Context\n ): Promise<{ delivered: boolean }>;\n sprinkleCall(\n sprinkleId: string,\n method: string,\n args: JsonValue[],\n context: Context\n ): Promise<JsonValue>;\n memorySave(draft: MemoryDraft, context: Context): Promise<MemoryEntry>;\n memoryRemove(id: string, context: Context): Promise<{ removed: boolean }>;\n freeze(agentId: string, context: Context): Promise<Created>;\n newChat(agentId: string, context: Context): Promise<Created>;\n thaw(frozenId: string, context: Context): Promise<Created>;\n discard(frozenId: string, context: Context): Promise<Created>;\n changesOpen(context: Context): Promise<void>;\n changeAccept(path: string, context: Context): Promise<Created>;\n changeRevert(path: string, context: Context): Promise<Created>;\n monitorOpen(lease: string | null, resync: boolean, context: Context): Promise<MonitorLease>;\n monitorClose(lease: string, context: Context): Promise<void>;\n}\n\nexport interface MonitorLease {\n lease: string;\n ttlMs: number;\n}\n\nexport interface MonitorAgent {\n id: string;\n name: string;\n kind: 'cone' | 'scoop';\n parentId: string | null;\n model: string | null;\n running: boolean;\n queued: number;\n tool: string | null;\n retry: { attempt: number; since: number; error: string } | null;\n failed: string | null;\n context: number | null;\n cpu?: number | null;\n}\n\nexport interface MonitorTask {\n id: string;\n kind: string;\n detail: string | null;\n agentId: string | null;\n owner: string | null;\n status: 'pending' | 'running' | 'waiting' | 'completing';\n phase: string;\n background: boolean;\n aborting: number | null;\n since: number;\n waits: number;\n}\n\nexport interface MonitorProcess {\n pid: number;\n ppid: number;\n pgid: number;\n user: string | null;\n agentId: string | null;\n command: string;\n state: 'S' | 'Z';\n started: number;\n zombie: number | null;\n tty: boolean;\n rss: number | null;\n utime?: number;\n stime?: number;\n cpu?: number | null;\n}\n\nexport interface MonitorProblem {\n id: string;\n at: number;\n agentId: string | null;\n kind: 'task' | 'retry' | 'turn';\n message: string;\n}\n\nexport interface MonitorFeed {\n open: boolean;\n at: number;\n usage: { tokens: number; cost: number; free: boolean } | null;\n agents: MonitorAgent[];\n tasks: MonitorTask[];\n processes: MonitorProcess[] | null;\n kernel: 'checking' | 'ok' | 'unreachable';\n problems: MonitorProblem[];\n paused: boolean;\n}\n\nexport interface MemoryDraft {\n id: string | null;\n scope: string;\n section: string;\n title: string;\n body: string;\n tag: MemoryTag | null;\n}\n\nexport type Created = { id: string; error: null } | { id: null; error: string };\n\nexport interface AgentSummary {\n id: string;\n name: string;\n kind: 'cone' | 'scoop';\n parentId: string | null;\n role: string | null;\n}\n\nexport interface AgentsSummary {\n active: string;\n agents: AgentSummary[];\n}\n\nexport type LickResolved =\n | { done: true; text: string; error: null }\n | { done: false; text: null; error: string };\n\nexport interface WebhookRequest {\n id: string | null;\n headers: Record<string, string>;\n body: string;\n}\n\nexport type Rewound =\n | { done: true; text: string; reason: null }\n | { done: false; text: null; reason: 'busy' | 'no-turn' };\n\nexport interface AgentSettingsChange {\n model: { provider: string; modelId: string } | null;\n thinkingLevel: 'off' | 'minimal' | 'low' | 'medium' | 'high' | 'xhigh' | 'max' | null;\n agentId?: string | null;\n}\n\nexport const AgentControl = defineService<AgentControl>('slicc.agent.control');\n\nexport type Delivered = 'run' | 'steer' | 'follow-up';\n\nexport interface AgentTranscript {\n readonly state: ReplicatedState<ConversationView>;\n readonly deliveries: ReplicatedState<Record<string, Delivered>>;\n readonly agents: ReplicatedState<AgentsSummary>;\n readonly views: ReplicatedState<Record<string, ConversationView>>;\n readonly commands: ReplicatedState<Command[]>;\n readonly sprinkles: ReplicatedState<Sprinkle[]>;\n readonly memories: ReplicatedState<MemoryEntry[]>;\n readonly memoryScopes: ReplicatedState<MemoryScope[]>;\n readonly frozen: ReplicatedState<FrozenCone[]>;\n readonly changes: ReplicatedState<ChangesView>;\n readonly monitor: ReplicatedState<MonitorFeed>;\n readonly vault: ReplicatedState<VaultState>;\n}\n\nexport interface Command {\n name: string;\n description: string;\n kind: 'prompt' | 'skill' | 'action';\n}\n\nexport const AgentTranscript = defineService<AgentTranscript>('slicc.agent.transcript');\n\nexport interface AgentSessions {\n attach(sessionId: string, context: Context): Promise<void>;\n detach(context: Context): Promise<void>;\n}\n\nexport const AgentSessions = defineService<AgentSessions>('slicc.agent.sessions');\n\nexport const AgentRemoteService = defineService<AgentRemote>('slicc.agent.remote');\n\nexport const AgentPagesService = defineService<AgentPages>('slicc.agent.pages');\n\nexport const AGENT_SESSION = 'agent';\n\nexport interface ModelChoice {\n id: string;\n label: string;\n provider: string;\n kind: 'chat' | 'classifier';\n reasoning: boolean;\n images?: boolean;\n contextWindow: number;\n}\n\nexport interface AccountState {\n id: string;\n provider: string;\n identity: string;\n status: 'connected' | 'disconnected' | 'expired';\n auth: 'api-key' | 'oauth';\n needs: 'cors-free-transport' | null;\n group?: 'providers' | 'mcp';\n secret?: 'api-key' | 'token';\n}\n\nexport interface BudgetState {\n provider: string;\n percent: number;\n window: 'weekly';\n resets: string;\n}\n\nexport interface SignIn {\n clientId: string;\n scopes: string;\n imsEnvironment: string;\n}\n\nexport interface McpSignIn {\n url: string;\n state: string;\n}\n\nexport interface SettingsState {\n models: ModelChoice[];\n accounts: AccountState[];\n budget?: BudgetState | null;\n}\n\nexport interface AgentSettings {\n readonly state: ReplicatedState<SettingsState>;\n connect(\n providerId: string,\n secret: string,\n region: string | null,\n context: Context\n ): Promise<void>;\n disconnect(providerId: string, context: Context): Promise<void>;\n signIn(providerId: string, context: Context): Promise<SignIn | McpSignIn | null>;\n}\n\nexport const AgentSettings = defineService<AgentSettings>('slicc.agent.settings');\n"],
|
|
5
|
+
"mappings": "AAAA;AAAA,EAEE;AAAA,OAGK;AAuNA,MAAM,eAAe,cAA4B,qBAAqB;AAyBtE,MAAM,kBAAkB,cAA+B,wBAAwB;AAO/E,MAAM,gBAAgB,cAA6B,sBAAsB;AAEzE,MAAM,qBAAqB,cAA2B,oBAAoB;AAE1E,MAAM,oBAAoB,cAA0B,mBAAmB;AAEvE,MAAM,gBAAgB;AA2DtB,MAAM,gBAAgB,cAA6B,sBAAsB;",
|
|
6
6
|
"names": []
|
|
7
7
|
}
|
|
@@ -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;
|
|
@@ -15,6 +17,8 @@ const GROUP_MAX = 32;
|
|
|
15
17
|
const TOTAL_MAX = 128;
|
|
16
18
|
const ZOMBIE_MS = 6e4;
|
|
17
19
|
const STALE_MS = 18e5;
|
|
20
|
+
const CPU_SHARE = 0.9;
|
|
21
|
+
const CPU_SUSTAIN_MS = 12e4;
|
|
18
22
|
const CONTEXT_WARN = 0.8;
|
|
19
23
|
const DEPTH_MAX = 6;
|
|
20
24
|
const MINUTE = 6e4;
|
|
@@ -53,6 +57,27 @@ function bytes(value) {
|
|
|
53
57
|
}
|
|
54
58
|
return `${size.toFixed(size < 10 ? 1 : 0)} ${units[unit]}`;
|
|
55
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
|
+
}
|
|
56
81
|
function memoryVital(processes) {
|
|
57
82
|
const measured = processes.filter((row) => typeof row.rss === "number");
|
|
58
83
|
if (!measured.length) return [];
|
|
@@ -194,6 +219,7 @@ function vitals(input, feed) {
|
|
|
194
219
|
} : feed.kernel === "checking" ? { id: "processes", label: "Processes", value: "\u2026", unit: "checking" } : { id: "processes", label: "Processes", value: "\u2014", unit: "kernel not reachable" }
|
|
195
220
|
);
|
|
196
221
|
out.push(...memoryVital(feed.processes ?? []));
|
|
222
|
+
out.push(...cpuVital(feed, input.cpu ?? []));
|
|
197
223
|
const ratios = feed.agents.map((agent) => contextRatio(agent, input.models)).filter((ratio) => ratio !== null);
|
|
198
224
|
if (ratios.length) {
|
|
199
225
|
const fullest = Math.max(...ratios);
|
|
@@ -208,6 +234,7 @@ function vitals(input, feed) {
|
|
|
208
234
|
}
|
|
209
235
|
function stale(process, agents, now) {
|
|
210
236
|
if (!process.agentId || process.state === "Z" || !process.started) return false;
|
|
237
|
+
if (typeof process.utime === "number") return false;
|
|
211
238
|
if (agents.get(process.agentId)?.tool === "bash") return false;
|
|
212
239
|
return now - process.started > STALE_MS;
|
|
213
240
|
}
|
|
@@ -221,6 +248,57 @@ function groups(processes) {
|
|
|
221
248
|
}
|
|
222
249
|
return out;
|
|
223
250
|
}
|
|
251
|
+
function groupCpu(processes) {
|
|
252
|
+
const out = /* @__PURE__ */ new Map();
|
|
253
|
+
for (const [pgid, members] of groups(processes)) {
|
|
254
|
+
const measured = members.filter((row) => typeof row.cpu === "number");
|
|
255
|
+
if (!measured.length) continue;
|
|
256
|
+
const share = measured.reduce((sum, row) => sum + row.cpu, 0);
|
|
257
|
+
out.set(pgid, { agentId: members[0].agentId, share });
|
|
258
|
+
}
|
|
259
|
+
return out;
|
|
260
|
+
}
|
|
261
|
+
function hotGroups(processes, at, previous) {
|
|
262
|
+
const out = /* @__PURE__ */ new Map();
|
|
263
|
+
for (const [pgid, { share }] of groupCpu(processes))
|
|
264
|
+
if (share >= CPU_SHARE) out.set(pgid, previous.get(pgid) ?? at);
|
|
265
|
+
return out;
|
|
266
|
+
}
|
|
267
|
+
function busy(input, processes) {
|
|
268
|
+
const shares = groupCpu(processes);
|
|
269
|
+
const out = [];
|
|
270
|
+
for (const [pgid, since] of input.hot ?? []) {
|
|
271
|
+
const group = shares.get(pgid);
|
|
272
|
+
const held = input.now - since;
|
|
273
|
+
if (group && group.share >= CPU_SHARE && held >= CPU_SUSTAIN_MS)
|
|
274
|
+
out.push({ pgid, ...group, held });
|
|
275
|
+
}
|
|
276
|
+
return out;
|
|
277
|
+
}
|
|
278
|
+
function cpuAlerts(input, processes, nameOf) {
|
|
279
|
+
return busy(input, processes).map(
|
|
280
|
+
(group) => ({
|
|
281
|
+
id: `runaway-cpu-${group.pgid}`,
|
|
282
|
+
title: `${nameOf(group.agentId)} is using a lot of CPU`,
|
|
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)
|
|
287
|
+
})
|
|
288
|
+
);
|
|
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
|
+
}
|
|
224
302
|
function resetLine(budget) {
|
|
225
303
|
const resets = new Date(budget.resets);
|
|
226
304
|
return Number.isNaN(resets.getTime()) ? `The ${budget.window} budget is nearly used up.` : `Resets ${resets.toISOString().slice(0, 16).replace("T", " ")} UTC.`;
|
|
@@ -284,8 +362,10 @@ function crowdAlerts(processes, nameOf) {
|
|
|
284
362
|
out.push({
|
|
285
363
|
id: `runaway-${pgid}`,
|
|
286
364
|
title: `${nameOf(members[0].agentId)} has ${members.length} processes`,
|
|
287
|
-
detail:
|
|
288
|
-
|
|
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)
|
|
289
369
|
});
|
|
290
370
|
if (processes.length > TOTAL_MAX)
|
|
291
371
|
out.push({
|
|
@@ -299,21 +379,24 @@ function crowdAlerts(processes, nameOf) {
|
|
|
299
379
|
function processAlerts(input, feed, nameOf) {
|
|
300
380
|
const processes = feed.processes ?? [];
|
|
301
381
|
const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));
|
|
302
|
-
const out = crowdAlerts(processes, nameOf);
|
|
382
|
+
const out = [...crowdAlerts(processes, nameOf), ...cpuAlerts(input, processes, nameOf)];
|
|
303
383
|
for (const process of processes) {
|
|
304
384
|
if (process.zombie !== null && input.now - process.zombie > ZOMBIE_MS)
|
|
305
385
|
out.push({
|
|
306
386
|
id: `zombie-${process.pid}`,
|
|
307
387
|
title: `Process ${process.pid} is a zombie`,
|
|
308
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" } : {},
|
|
309
390
|
severity: "warn"
|
|
310
391
|
});
|
|
311
392
|
if (stale(process, agents, input.now))
|
|
312
393
|
out.push({
|
|
313
394
|
id: `stale-${process.pid}`,
|
|
314
395
|
title: `${process.command || `Process ${process.pid}`} has run for ${age(input.now - process.started)}`,
|
|
315
|
-
detail: `${nameOf(process.agentId)} started it in the background
|
|
316
|
-
|
|
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)
|
|
317
400
|
});
|
|
318
401
|
}
|
|
319
402
|
return out;
|
|
@@ -355,7 +438,12 @@ function agentRow(agent, depth, models) {
|
|
|
355
438
|
const word = agent.retry ? "retrying" : agent.running ? "running" : agent.failed ? "failed" : "idle";
|
|
356
439
|
const status = agent.retry ? "warn" : agent.running ? "active" : agent.failed ? "error" : "idle";
|
|
357
440
|
const model = models.find((choice) => choice.id === agent.model)?.label ?? agent.model;
|
|
358
|
-
const meta = [
|
|
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 ");
|
|
359
447
|
const badges = [
|
|
360
448
|
...agent.queued ? [`${agent.queued} queued`] : [],
|
|
361
449
|
...agent.tool ? [agent.tool] : [],
|
|
@@ -389,11 +477,16 @@ function taskRow(task, depth, nameOf, now) {
|
|
|
389
477
|
}
|
|
390
478
|
function processRows(input, feed) {
|
|
391
479
|
const agents = new Map(feed.agents.map((agent) => [agent.id, agent]));
|
|
392
|
-
const
|
|
480
|
+
const flagged = /* @__PURE__ */ new Map();
|
|
393
481
|
for (const [pgid, members] of groups(feed.processes ?? []))
|
|
394
|
-
if (members.length > GROUP_MAX)
|
|
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)));
|
|
395
485
|
return (feed.processes ?? []).map((process) => {
|
|
396
|
-
const runaway =
|
|
486
|
+
const runaway = worse(
|
|
487
|
+
flagged.get(process.pgid),
|
|
488
|
+
stale(process, agents, input.now) ? staleSeverity(process, input.now) : void 0
|
|
489
|
+
);
|
|
397
490
|
const badges = [
|
|
398
491
|
...process.agentId ? [agents.get(process.agentId)?.name ?? process.agentId] : [],
|
|
399
492
|
...process.tty ? ["terminal"] : []
|
|
@@ -405,9 +498,10 @@ function processRows(input, feed) {
|
|
|
405
498
|
`pid ${process.pid}`,
|
|
406
499
|
process.user,
|
|
407
500
|
typeof process.rss === "number" ? bytes(process.rss) : null,
|
|
501
|
+
cpuText(process.cpu),
|
|
408
502
|
process.started ? age(input.now - process.started) : null
|
|
409
503
|
].filter(Boolean).join(" \xB7 "),
|
|
410
|
-
status: runaway
|
|
504
|
+
status: runaway ?? (process.state === "Z" ? "warn" : "idle"),
|
|
411
505
|
...badges.length ? { badges } : {}
|
|
412
506
|
};
|
|
413
507
|
});
|
|
@@ -512,6 +606,9 @@ class MonitorAdapter {
|
|
|
512
606
|
#listeners = 0;
|
|
513
607
|
#open;
|
|
514
608
|
#history = [];
|
|
609
|
+
#hot = /* @__PURE__ */ new Map();
|
|
610
|
+
#hotAt = -1;
|
|
611
|
+
#cpu = [];
|
|
515
612
|
constructor(connection, options = {}) {
|
|
516
613
|
this.#connection = connection;
|
|
517
614
|
this.#extra = options.extra ?? (() => []);
|
|
@@ -546,7 +643,9 @@ class MonitorAdapter {
|
|
|
546
643
|
sprinkles: this.#connection.sprinkles?.value ?? [],
|
|
547
644
|
extra: this.#extra(),
|
|
548
645
|
history: this.#history,
|
|
549
|
-
now: this.#now()
|
|
646
|
+
now: this.#now(),
|
|
647
|
+
hot: this.#hot,
|
|
648
|
+
cpu: this.#cpu
|
|
550
649
|
});
|
|
551
650
|
}
|
|
552
651
|
resync() {
|
|
@@ -559,6 +658,9 @@ class MonitorAdapter {
|
|
|
559
658
|
#start() {
|
|
560
659
|
const control = this.#connection.control;
|
|
561
660
|
this.#history = [];
|
|
661
|
+
this.#hot = /* @__PURE__ */ new Map();
|
|
662
|
+
this.#hotAt = -1;
|
|
663
|
+
this.#cpu = [];
|
|
562
664
|
void control.changesOpen(BACKGROUND_CONTEXT).catch(() => void 0);
|
|
563
665
|
const lease = control.monitorOpen(null, true, BACKGROUND_CONTEXT).then(
|
|
564
666
|
(opened) => opened.lease || null,
|
|
@@ -586,9 +688,20 @@ class MonitorAdapter {
|
|
|
586
688
|
});
|
|
587
689
|
if (this.#history.length > HISTORY) this.#history.shift();
|
|
588
690
|
}
|
|
691
|
+
#track() {
|
|
692
|
+
const feed = this.#connection.monitor?.value;
|
|
693
|
+
if (!feed?.open || feed.at === this.#hotAt) return;
|
|
694
|
+
this.#hotAt = feed.at;
|
|
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();
|
|
700
|
+
}
|
|
589
701
|
#update() {
|
|
590
702
|
if (!this.#listeners) return;
|
|
591
703
|
this.#sample();
|
|
704
|
+
this.#track();
|
|
592
705
|
this.#emitter.emit("snapshot", this.snapshot());
|
|
593
706
|
}
|
|
594
707
|
}
|
|
@@ -598,6 +711,10 @@ export {
|
|
|
598
711
|
BUDGET_ERROR,
|
|
599
712
|
BUDGET_WARN,
|
|
600
713
|
CONTEXT_WARN,
|
|
714
|
+
CPU_HISTORY,
|
|
715
|
+
CPU_QUIET,
|
|
716
|
+
CPU_SHARE,
|
|
717
|
+
CPU_SUSTAIN_MS,
|
|
601
718
|
DEPTH_MAX,
|
|
602
719
|
FAILED_MS,
|
|
603
720
|
GROUP_MAX,
|
|
@@ -612,9 +729,13 @@ export {
|
|
|
612
729
|
TOTAL_MAX,
|
|
613
730
|
ZOMBIE_MS,
|
|
614
731
|
age,
|
|
732
|
+
agentsCpu,
|
|
615
733
|
bytes,
|
|
616
734
|
count,
|
|
735
|
+
cpuText,
|
|
617
736
|
globalIntervals,
|
|
737
|
+
groupCpu,
|
|
738
|
+
hotGroups,
|
|
618
739
|
money,
|
|
619
740
|
monitorSnapshot,
|
|
620
741
|
taskLabel,
|
|
@@ -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 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}\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 (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\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);\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 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\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 });\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 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 #update(): void {\n if (!this.#listeners) return;\n this.#sample();\n this.#emitter.emit('snapshot', this.snapshot());\n }\n}\n"],
|
|
5
|
-
"mappings": "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",
|
|
4
|
+
"sourcesContent": ["import type {\n MonitorAlert,\n MonitorEvents,\n MonitorPort,\n MonitorRow,\n MonitorSection,\n MonitorSnapshot,\n MonitorStatus,\n MonitorVital,\n} from '@ai-ecoverse/slicc-spectrum/ui';\nimport { BACKGROUND_CONTEXT } from '@earendil-works/chord/context';\nimport type { AgentConnection } from '../client.ts';\nimport 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,7 +1,7 @@
|
|
|
1
1
|
import { type Context, type ReplicatedState } from '@earendil-works/chord';
|
|
2
2
|
import type { ConversationView, Harness, UsageState } from '@earendil-works/pi-durable';
|
|
3
3
|
import { type AgentsState } from '../agents.ts';
|
|
4
|
-
import type { MonitorFeed, MonitorLease } from '../services.ts';
|
|
4
|
+
import type { MonitorFeed, MonitorLease, MonitorProcess } from '../services.ts';
|
|
5
5
|
export interface PsEntry {
|
|
6
6
|
pid: number;
|
|
7
7
|
ppid?: number;
|
|
@@ -12,7 +12,20 @@ export interface PsEntry {
|
|
|
12
12
|
state?: string;
|
|
13
13
|
uid?: number;
|
|
14
14
|
rss?: number;
|
|
15
|
+
utime?: number;
|
|
16
|
+
stime?: number;
|
|
15
17
|
}
|
|
18
|
+
export interface CpuMark {
|
|
19
|
+
started: number;
|
|
20
|
+
total: number;
|
|
21
|
+
at: number;
|
|
22
|
+
}
|
|
23
|
+
export interface CpuReading {
|
|
24
|
+
marks: Map<number, CpuMark>;
|
|
25
|
+
shares: Map<number, number | null>;
|
|
26
|
+
}
|
|
27
|
+
export declare function cpuShares(entries: readonly PsEntry[], previous: ReadonlyMap<number, CpuMark>, at: number): CpuReading;
|
|
28
|
+
export declare function agentCpu(processes: readonly MonitorProcess[], agentId: string): number | null;
|
|
16
29
|
export interface Timers {
|
|
17
30
|
set(run: () => void, ms: number): unknown;
|
|
18
31
|
clear(handle: unknown): void;
|
package/dist/types/services.d.ts
CHANGED
|
@@ -104,6 +104,7 @@ export interface MonitorAgent {
|
|
|
104
104
|
} | null;
|
|
105
105
|
failed: string | null;
|
|
106
106
|
context: number | null;
|
|
107
|
+
cpu?: number | null;
|
|
107
108
|
}
|
|
108
109
|
export interface MonitorTask {
|
|
109
110
|
id: string;
|
|
@@ -130,6 +131,9 @@ export interface MonitorProcess {
|
|
|
130
131
|
zombie: number | null;
|
|
131
132
|
tty: boolean;
|
|
132
133
|
rss: number | null;
|
|
134
|
+
utime?: number;
|
|
135
|
+
stime?: number;
|
|
136
|
+
cpu?: number | null;
|
|
133
137
|
}
|
|
134
138
|
export interface MonitorProblem {
|
|
135
139
|
id: string;
|
|
@@ -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
|
-
import type { BudgetState, ModelChoice, MonitorFeed, MonitorTask } from '../services.ts';
|
|
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;
|
|
@@ -16,8 +18,14 @@ export declare const GROUP_MAX = 32;
|
|
|
16
18
|
export declare const TOTAL_MAX = 128;
|
|
17
19
|
export declare const ZOMBIE_MS = 60000;
|
|
18
20
|
export declare const STALE_MS = 1800000;
|
|
21
|
+
export declare const CPU_SHARE = 0.9;
|
|
22
|
+
export declare const CPU_SUSTAIN_MS = 120000;
|
|
19
23
|
export declare const CONTEXT_WARN = 0.8;
|
|
20
24
|
export declare const DEPTH_MAX = 6;
|
|
25
|
+
export type AgentMonitorAlert = MonitorAlert & {
|
|
26
|
+
command?: string;
|
|
27
|
+
commandLabel?: string;
|
|
28
|
+
};
|
|
21
29
|
export interface Sample {
|
|
22
30
|
at: number;
|
|
23
31
|
cost: number;
|
|
@@ -39,16 +47,25 @@ export interface MonitorInput {
|
|
|
39
47
|
extra: readonly MonitorSection[];
|
|
40
48
|
history: readonly Sample[];
|
|
41
49
|
now: number;
|
|
50
|
+
hot?: ReadonlyMap<number, number>;
|
|
51
|
+
cpu?: readonly number[];
|
|
42
52
|
}
|
|
43
53
|
export declare function age(ms: number): string;
|
|
44
54
|
export declare function money(value: number): string;
|
|
45
55
|
export declare function count(value: number): string;
|
|
46
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;
|
|
47
59
|
export declare function taskLabel(task: MonitorTask): string;
|
|
48
60
|
export declare function taskTree(feed: MonitorFeed): {
|
|
49
61
|
task: MonitorTask;
|
|
50
62
|
depth: number;
|
|
51
63
|
}[];
|
|
64
|
+
export declare function groupCpu(processes: readonly MonitorProcess[]): Map<number, {
|
|
65
|
+
agentId: string;
|
|
66
|
+
share: number;
|
|
67
|
+
}>;
|
|
68
|
+
export declare function hotGroups(processes: readonly MonitorProcess[], at: number, previous: ReadonlyMap<number, number>): Map<number, number>;
|
|
52
69
|
export declare function monitorSnapshot(input: MonitorInput): MonitorSnapshot;
|
|
53
70
|
export interface Intervals {
|
|
54
71
|
every(run: () => void, ms: number): unknown;
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@ai-ecoverse/slicc-agent",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.47.0",
|
|
4
4
|
"description": "SLICC's agent core on pi durable: an agent worker, session storage, remoting and pi extensions",
|
|
5
5
|
"type": "module",
|
|
6
6
|
"license": "Apache-2.0",
|
|
@@ -63,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.
|
|
66
|
+
"@ai-ecoverse/slicc-spectrum": "1.62.2",
|
|
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",
|