@dudousxd/nestjs-agent-dashboard 0.13.1 → 0.14.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 +29 -4
- package/dist/client/agent-client.d.ts +111 -1
- package/dist/client/agent-client.d.ts.map +1 -1
- package/dist/client/agent-client.js +27 -1
- package/dist/client/agent-client.js.map +1 -1
- package/dist/client/describe-error.d.ts +30 -0
- package/dist/client/describe-error.d.ts.map +1 -0
- package/dist/client/describe-error.js +63 -0
- package/dist/client/describe-error.js.map +1 -0
- package/dist/client/format-day.d.ts +19 -0
- package/dist/client/format-day.d.ts.map +1 -0
- package/dist/client/format-day.js +38 -0
- package/dist/client/format-day.js.map +1 -0
- package/dist/client/trend-summary.d.ts +33 -0
- package/dist/client/trend-summary.d.ts.map +1 -0
- package/dist/client/trend-summary.js +33 -0
- package/dist/client/trend-summary.js.map +1 -0
- package/dist/server/index.cjs +170 -2
- package/dist/server/index.cjs.map +1 -1
- package/dist/server/index.d.cts +62 -4
- package/dist/server/index.d.ts +62 -4
- package/dist/server/index.js +181 -13
- package/dist/server/index.js.map +1 -1
- package/dist/spa/assets/base-ui-CKhU3I2F.js +55 -0
- package/dist/spa/assets/index-CO6XH1b7.css +1 -0
- package/dist/spa/assets/index-Cvgm9m_c.js +1 -0
- package/dist/spa/assets/index-Dr3vAOUw.js +25 -0
- package/dist/spa/assets/preview-BdD_YKne.js +1 -0
- package/dist/spa/assets/recharts-CPMXF7sD.js +69 -0
- package/dist/spa/index.html +5 -3
- package/dist/spa/preview.html +5 -3
- package/package.json +9 -3
- package/dist/client/run-trend-path.d.ts +0 -30
- package/dist/client/run-trend-path.d.ts.map +0 -1
- package/dist/client/run-trend-path.js +0 -36
- package/dist/client/run-trend-path.js.map +0 -1
- package/dist/client/trend-path.d.ts +0 -27
- package/dist/client/trend-path.d.ts.map +0 -1
- package/dist/client/trend-path.js +0 -25
- package/dist/client/trend-path.js.map +0 -1
- package/dist/spa/assets/index-C42SW8IV.js +0 -1
- package/dist/spa/assets/index-DMBWMAsE.css +0 -1
- package/dist/spa/assets/index-DZVPxvtJ.js +0 -49
- package/dist/spa/assets/preview-DhDnTjWH.js +0 -1
package/README.md
CHANGED
|
@@ -198,19 +198,37 @@ Mounted at `apiBasePath`:
|
|
|
198
198
|
| `GET` | `/spend?from=YYYY-MM-DD&to=YYYY-MM-DD` | `{ byModel: ModelSpendRow[], byActor: ActorSpendRow[], trend: UsageTrendPoint[] }` (defaults to the last 30 days) |
|
|
199
199
|
| `GET` | `/tool-calls?limit=` | `ToolCallActivityRow[]` (default 50, max 200) |
|
|
200
200
|
| `GET` | `/threads?limit=` | `ThreadActivityRow[]` (default 50, max 200) |
|
|
201
|
+
| `GET` | `/<runs\|threads\|tool-calls\|approvals>-page?page=&limit=&where[…]=` | `GovernancePage<Row>` — `{ rows, total, page, pageSize }` |
|
|
202
|
+
| `GET` | `/runs/:runId` | `RunDetail` — the run, its thread's headline and its tool calls. `404`s on an unknown id |
|
|
203
|
+
| `GET` | `/threads/:threadId?messages=&runs=` | `ThreadDetail` — the thread, its lifetime usage rollup, newest runs and newest messages |
|
|
201
204
|
| `GET` | `/stream` | SSE of live `aviary:agent:*` events (`{ event, ts, payload }`) |
|
|
202
205
|
|
|
203
206
|
## SPA sections
|
|
204
207
|
|
|
205
|
-
- **Spend & usage** — headline $ + tokens, by-model donut + legend, daily trend (cost/tokens toggle).
|
|
208
|
+
- **Spend & usage** — headline $ + tokens, by-model donut + legend, daily trend (cost/tokens toggle), top threads by cost.
|
|
206
209
|
- **Models** — per-model requests / in+out tokens / cost / share.
|
|
207
210
|
- **Actors & budgets** — spend per acting ref; usage-vs-budget bar when a daily limit is known.
|
|
208
|
-
- **Runs & tools** — recent tool calls (with a denied/forbidden banner) and recent threads.
|
|
211
|
+
- **Runs & tools** — recent tool calls (with a denied/forbidden banner) and recent threads, both paged and filterable.
|
|
212
|
+
- **Reliability** — success/error rate, retries, p50+p95 duration, failures by error code, run/failure trend, and a paged recent-runs table.
|
|
213
|
+
- **Approvals** — the cross-thread HITL inbox, paged, reporting the full backlog (`N of M`) rather than a silent cap.
|
|
214
|
+
- **Tools** — per-tool volume, failure/rejection rate, and **both** latency percentiles (p50 next to p95 — p95 alone cannot tell an occasionally-hanging tool from a uniformly slow one).
|
|
215
|
+
- **Pricing** — the current per-model rate table plus an upsert form; renders its own "no pricing store bound" state when the host 501s.
|
|
209
216
|
- **Live** — the diagnostics SSE feed, newest-first, with quota/denied events flagged.
|
|
210
217
|
|
|
218
|
+
Rows are not dead ends: a run, a tool call, a thread and an approval all open a drill-down drawer over the table, and a thread's drawer deep-links to `#/reliability?threadId=…` for every run it made.
|
|
219
|
+
|
|
220
|
+
### How the SPA is wired
|
|
221
|
+
|
|
222
|
+
Worth knowing before changing it, because two of these are the reason the console behaves the way it does:
|
|
223
|
+
|
|
224
|
+
- **One container per section, each owning its own reads** (`src/app/containers/`). Sections that are not on screen issue no requests. The shell keeps exactly two data sources of its own, both because they must outlive the section being viewed: the SSE subscription, and the pending-approvals *count* behind the nav badge.
|
|
225
|
+
- **An error boundary per section** (`SectionBoundary`), so a failing read names itself and offers a retry instead of rendering an empty state that reads as "there is no data". Paged tables render their failures inline instead, next to the last rows that did load.
|
|
226
|
+
- **Freshness is `staleTime`, not an interval.** There is no `refetchInterval`; react-query's `refetchOnWindowFocus` is left on, and the per-query `STALE` values in `src/app/use-governance.ts` decide what that refetches. Aggregates are a minute stale, activity lists fifteen seconds, the approvals queue always.
|
|
227
|
+
- **Suspense reads waterfall.** Two `useSuspenseQuery` calls in one component serialise — the first throws and the second never runs. Reads of equal standing go through `useSuspenseQueries`; see the note in `use-governance.ts`.
|
|
228
|
+
|
|
211
229
|
## Typed client
|
|
212
230
|
|
|
213
|
-
For your own front-end, `@dudousxd/nestjs-agent-dashboard/client` exports `agentClient` (`spend`, `toolCalls`, `threads`, `streamEvents`) with the response types — dependency-free.
|
|
231
|
+
For your own front-end, `@dudousxd/nestjs-agent-dashboard/client` exports `agentClient` (`spend`, `toolCalls`, `threads`, the `*Page` reads, `runDetail`, `threadDetail`, `streamEvents`) with the response types — dependency-free.
|
|
214
232
|
|
|
215
233
|
```ts
|
|
216
234
|
import { agentClient } from '@dudousxd/nestjs-agent-dashboard/client';
|
|
@@ -222,7 +240,14 @@ const overview = await agentClient.spend({ fromDay: '2026-06-01', toDay: '2026-0
|
|
|
222
240
|
|
|
223
241
|
`vite build && tsup && tsc -p tsconfig.client.json` — the SPA compiles to `dist/spa`, the NestJS server to `dist/server` (dual ESM + CJS with decorator metadata + `import.meta.url` shim), and the client types to `dist/client`. The bundled SPA ships in the package, so the UI controller serves it with no extra assets.
|
|
224
242
|
|
|
225
|
-
`preview.html` renders every section against mock data (no backend) for visual verification.
|
|
243
|
+
`preview.html` renders every section against mock data (no backend) for visual verification — including the drill-down drawers and the failure/loading states, which are otherwise the states a backend-less check can never reach.
|
|
244
|
+
|
|
245
|
+
### Charts
|
|
246
|
+
|
|
247
|
+
The trend charts and share donuts are [recharts](https://recharts.org), themed against the console's CSS
|
|
248
|
+
custom properties in `src/app/chart-ui.tsx`. Recharts is a real dependency of this package and is bundled
|
|
249
|
+
into `dist/spa` (its own `recharts-*.js` chunk); it is deliberately **not** reachable from the `./react`
|
|
250
|
+
entry, so a host that imports `<OpenAgentConsoleButton />` never pulls a charting library into its build.
|
|
226
251
|
|
|
227
252
|
## License
|
|
228
253
|
|
|
@@ -46,6 +46,8 @@ export interface ToolCallActivityRow {
|
|
|
46
46
|
status: string;
|
|
47
47
|
threadId: string;
|
|
48
48
|
createdAt: string;
|
|
49
|
+
/** The run this call belongs to, for a trace deep-link; `null` for a call recorded before this shipped. */
|
|
50
|
+
runId: string | null;
|
|
49
51
|
}
|
|
50
52
|
/** A recent thread with rolled-up activity. */
|
|
51
53
|
export interface ThreadActivityRow {
|
|
@@ -115,6 +117,8 @@ export interface PendingApprovalRow {
|
|
|
115
117
|
agentName: string | null;
|
|
116
118
|
/** ISO timestamp. */
|
|
117
119
|
requestedAt: string;
|
|
120
|
+
/** The run this call belongs to, for a trace deep-link; `null` for a pre-rollout row. */
|
|
121
|
+
runId: string | null;
|
|
118
122
|
}
|
|
119
123
|
/** Body for `POST <api>/approvals/:toolCallId` — decide a pending HITL tool call. */
|
|
120
124
|
export interface ApprovalDecisionInput {
|
|
@@ -160,6 +164,19 @@ export interface RunWhere {
|
|
|
160
164
|
agentName?: string;
|
|
161
165
|
status?: string;
|
|
162
166
|
errorCode?: string;
|
|
167
|
+
/** Every run on one thread — the follow-up query a drill-down leads to. */
|
|
168
|
+
threadId?: string;
|
|
169
|
+
fromDay?: string;
|
|
170
|
+
toDay?: string;
|
|
171
|
+
}
|
|
172
|
+
/** Filters for `GET approvals-page` (the paged approvals inbox). */
|
|
173
|
+
export interface ApprovalWhere {
|
|
174
|
+
toolName?: string;
|
|
175
|
+
threadId?: string;
|
|
176
|
+
/** The requesting thread's owner. */
|
|
177
|
+
actorRef?: string;
|
|
178
|
+
agentName?: string;
|
|
179
|
+
/** Inclusive UTC day bounds on when the approval was requested, `YYYY-MM-DD`. */
|
|
163
180
|
fromDay?: string;
|
|
164
181
|
toDay?: string;
|
|
165
182
|
}
|
|
@@ -170,9 +187,85 @@ export interface ToolStatRow {
|
|
|
170
187
|
calls: number;
|
|
171
188
|
failed: number;
|
|
172
189
|
rejected: number;
|
|
190
|
+
/**
|
|
191
|
+
* p50 (median) of executionMs across calls that recorded one; null when none carry it. Paired with
|
|
192
|
+
* p95 rather than a mean — tool latency is long-tailed, so "typical" and "tail" are two numbers.
|
|
193
|
+
*/
|
|
194
|
+
p50ExecutionMs: number | null;
|
|
173
195
|
/** p95 of executionMs across executed calls; null when none carry it. */
|
|
174
196
|
p95ExecutionMs: number | null;
|
|
175
197
|
}
|
|
198
|
+
/** One tool call inside a `RunDetail`, with the execution outcome a list row can't afford to carry. */
|
|
199
|
+
export interface RunToolCallRow {
|
|
200
|
+
toolCallId: string;
|
|
201
|
+
toolName: string;
|
|
202
|
+
toolType: string;
|
|
203
|
+
status: string;
|
|
204
|
+
/** Wall time of the execution; null for a call that never executed. */
|
|
205
|
+
executionMs: number | null;
|
|
206
|
+
/** Who executed/decided it, when the store recorded an attribution. */
|
|
207
|
+
executedByRef: string | null;
|
|
208
|
+
/** The failure text for a `failed` call; null otherwise. */
|
|
209
|
+
error: string | null;
|
|
210
|
+
createdAt: string;
|
|
211
|
+
}
|
|
212
|
+
/** The owning thread's headline, carried on a drill-down so it can be named without a second read. */
|
|
213
|
+
export interface DetailThreadRef {
|
|
214
|
+
threadId: string;
|
|
215
|
+
title: string;
|
|
216
|
+
actorRef: string;
|
|
217
|
+
/** True when the thread is soft-deleted — its history is still readable, the thread is not. */
|
|
218
|
+
deleted: boolean;
|
|
219
|
+
/** Human-readable label resolved from `actorRef` (an `ActorDirectory`), when one is bound server-side. */
|
|
220
|
+
actorLabel: string | null;
|
|
221
|
+
}
|
|
222
|
+
/**
|
|
223
|
+
* The `GET <api>/runs/:runId` response. `toolCalls` is empty for a run recorded before tool calls
|
|
224
|
+
* carried a run id — indistinguishable, from here, from a run that called no tools. There is no cost
|
|
225
|
+
* figure: the token ledger has no run column, so per-run spend is not attributable.
|
|
226
|
+
*/
|
|
227
|
+
export interface RunDetail {
|
|
228
|
+
run: RecentRunRow;
|
|
229
|
+
thread: DetailThreadRef;
|
|
230
|
+
/** The run's tool calls, oldest first — the order they were requested in. */
|
|
231
|
+
toolCalls: RunToolCallRow[];
|
|
232
|
+
}
|
|
233
|
+
/** One message inside a `ThreadDetail`. `content` is capped server-side. */
|
|
234
|
+
export interface ThreadMessageRow {
|
|
235
|
+
messageId: string;
|
|
236
|
+
role: string;
|
|
237
|
+
/** Message text, capped server-side; see `truncated`. */
|
|
238
|
+
content: string;
|
|
239
|
+
/** True when `content` was cut — render an explicit "…" rather than implying the tail. */
|
|
240
|
+
truncated: boolean;
|
|
241
|
+
agentName: string | null;
|
|
242
|
+
/** How many tool calls this message requested. */
|
|
243
|
+
toolCallCount: number;
|
|
244
|
+
createdAt: string;
|
|
245
|
+
}
|
|
246
|
+
/** Token/cost rollup across a thread's whole ledger (lifetime, not range-scoped). */
|
|
247
|
+
export interface ThreadUsageRollup {
|
|
248
|
+
/** Ledger rows, i.e. billed turns. */
|
|
249
|
+
requests: number;
|
|
250
|
+
inputTokens: number;
|
|
251
|
+
outputTokens: number;
|
|
252
|
+
totalTokens: number;
|
|
253
|
+
costUsd: number;
|
|
254
|
+
}
|
|
255
|
+
/** The `GET <api>/threads/:threadId` response. */
|
|
256
|
+
export interface ThreadDetail {
|
|
257
|
+
/** The thread's activity row (`messageCount` is the thread total, not the `messages` cap below). */
|
|
258
|
+
thread: ThreadActivityRow;
|
|
259
|
+
/** True when the thread is soft-deleted. */
|
|
260
|
+
deleted: boolean;
|
|
261
|
+
usage: ThreadUsageRollup;
|
|
262
|
+
/** The thread's runs, newest first, capped by the `runs` query param. */
|
|
263
|
+
runs: RecentRunRow[];
|
|
264
|
+
/** Runs on this thread in total — `runs.length < runTotal` means the cap bit. */
|
|
265
|
+
runTotal: number;
|
|
266
|
+
/** The thread's messages, newest first, capped by the `messages` query param. */
|
|
267
|
+
messages: ThreadMessageRow[];
|
|
268
|
+
}
|
|
176
269
|
/** The `GET <api>/reliability` response. */
|
|
177
270
|
export interface ReliabilityOverview {
|
|
178
271
|
metrics: RunMetrics;
|
|
@@ -230,8 +323,25 @@ export declare const agentClient: {
|
|
|
230
323
|
toolCalls(limit?: number): Promise<ToolCallActivityRow[]>;
|
|
231
324
|
/** A page of tool calls, filtered by `where` — the Runs & tools tool-calls table. */
|
|
232
325
|
toolCallsPage(query: GovernancePageQuery<ToolCallWhere>): Promise<GovernancePage<ToolCallActivityRow>>;
|
|
233
|
-
/**
|
|
326
|
+
/**
|
|
327
|
+
* Tool calls sitting `pending_approval`, oldest first (default 50) — the approvals inbox.
|
|
328
|
+
*
|
|
329
|
+
* Capped with NO total: a backlog past `limit` is invisible in this response. Prefer
|
|
330
|
+
* {@link agentClient.approvalsPage}, which reports how many are off-screen.
|
|
331
|
+
*/
|
|
234
332
|
approvals(limit?: number): Promise<PendingApprovalRow[]>;
|
|
333
|
+
/** A page of the approvals inbox with the backlog `total` — oldest first, filtered by `where`. */
|
|
334
|
+
approvalsPage(query: GovernancePageQuery<ApprovalWhere>): Promise<GovernancePage<PendingApprovalRow>>;
|
|
335
|
+
/** One run with its thread and its tool calls, in one request. Rejects with `404 …` if unknown. */
|
|
336
|
+
runDetail(runId: string): Promise<RunDetail>;
|
|
337
|
+
/**
|
|
338
|
+
* One thread with its lifetime usage rollup, newest runs and newest messages, in one request.
|
|
339
|
+
* `messages`/`runs` cap the two lists (server clamps to 1..200). Rejects with `404 …` if unknown.
|
|
340
|
+
*/
|
|
341
|
+
threadDetail(threadId: string, opts?: {
|
|
342
|
+
messages?: number;
|
|
343
|
+
runs?: number;
|
|
344
|
+
}): Promise<ThreadDetail>;
|
|
235
345
|
/**
|
|
236
346
|
* Decide a pending HITL tool call. 501s (a plain `Error` whose message starts with `501`, like
|
|
237
347
|
* `upsertPrice` below) if the host has no `AGENT_APPROVAL_PORT` bound — the approvals inbox reads
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-client.d.ts","sourceRoot":"","sources":["../../src/client/agent-client.ts"],"names":[],"mappings":"AAIA,kDAAkD;AAGlD,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,EAChB,KAAK,kBAAkB,GACxB,MAAM,sBAAsB,CAAC;AAE9B,MAAM,WAAW,eAAe;IAC9B,OAAO,EAAE,MAAM,CAAC;IAChB,KAAK,EAAE,MAAM,CAAC;CACf;AAED,uDAAuD;AACvD,MAAM,WAAW,aAAa;IAC5B,OAAO,EAAE,MAAM,CAAC;IAChB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,YAAY,EAAE,MAAM,CAAC;IACrB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,0EAA0E;AAC1E,MAAM,WAAW,aAAa;IAC5B,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,0GAA0G;IAC1G,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,wDAAwD;AACxD,MAAM,WAAW,cAAc;IAC7B,QAAQ,EAAE,MAAM,CAAC;IACjB,KAAK,EAAE,MAAM,CAAC;IACd,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;IAChB,0GAA0G;IAC1G,UAAU,EAAE,MAAM,GAAG,IAAI,CAAC;CAC3B;AAED,+CAA+C;AAC/C,MAAM,WAAW,eAAe;IAC9B,GAAG,EAAE,MAAM,CAAC;IACZ,WAAW,EAAE,MAAM,CAAC;IACpB,OAAO,EAAE,MAAM,CAAC;CACjB;AAED,gDAAgD;AAChD,MAAM,WAAW,mBAAmB;IAClC,UAAU,EAAE,MAAM,CAAC;IACnB,QAAQ,EAAE,MAAM,CAAC;IACjB,QAAQ,EAAE,MAAM,CAAC;IACjB,MAAM,EAAE,MAAM,CAAC;IACf,QAAQ,EAAE,MAAM,CAAC;IACjB,SAAS,EAAE,MAAM,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-client.d.ts","sourceRoot":"","sources":["../../src/client/agent-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -56,10 +56,36 @@ export const agentClient = {
|
|
|
56
56
|
toolCallsPage(query) {
|
|
57
57
|
return http(`/tool-calls-page?${pageQueryParams(query)}`);
|
|
58
58
|
},
|
|
59
|
-
/**
|
|
59
|
+
/**
|
|
60
|
+
* Tool calls sitting `pending_approval`, oldest first (default 50) — the approvals inbox.
|
|
61
|
+
*
|
|
62
|
+
* Capped with NO total: a backlog past `limit` is invisible in this response. Prefer
|
|
63
|
+
* {@link agentClient.approvalsPage}, which reports how many are off-screen.
|
|
64
|
+
*/
|
|
60
65
|
approvals(limit = 50) {
|
|
61
66
|
return http(`/approvals?limit=${limit}`);
|
|
62
67
|
},
|
|
68
|
+
/** A page of the approvals inbox with the backlog `total` — oldest first, filtered by `where`. */
|
|
69
|
+
approvalsPage(query) {
|
|
70
|
+
return http(`/approvals-page?${pageQueryParams(query)}`);
|
|
71
|
+
},
|
|
72
|
+
/** One run with its thread and its tool calls, in one request. Rejects with `404 …` if unknown. */
|
|
73
|
+
runDetail(runId) {
|
|
74
|
+
return http(`/runs/${encodeURIComponent(runId)}`);
|
|
75
|
+
},
|
|
76
|
+
/**
|
|
77
|
+
* One thread with its lifetime usage rollup, newest runs and newest messages, in one request.
|
|
78
|
+
* `messages`/`runs` cap the two lists (server clamps to 1..200). Rejects with `404 …` if unknown.
|
|
79
|
+
*/
|
|
80
|
+
threadDetail(threadId, opts = {}) {
|
|
81
|
+
const q = new URLSearchParams();
|
|
82
|
+
if (opts.messages !== undefined)
|
|
83
|
+
q.set('messages', `${opts.messages}`);
|
|
84
|
+
if (opts.runs !== undefined)
|
|
85
|
+
q.set('runs', `${opts.runs}`);
|
|
86
|
+
const suffix = q.size > 0 ? `?${q.toString()}` : '';
|
|
87
|
+
return http(`/threads/${encodeURIComponent(threadId)}${suffix}`);
|
|
88
|
+
},
|
|
63
89
|
/**
|
|
64
90
|
* Decide a pending HITL tool call. 501s (a plain `Error` whose message starts with `501`, like
|
|
65
91
|
* `upsertPrice` below) if the host has no `AGENT_APPROVAL_PORT` bound — the approvals inbox reads
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"agent-client.js","sourceRoot":"","sources":["../../src/client/agent-client.ts"],"names":[],"mappings":"AAAA,mGAAmG;AACnG,uGAAuG;AACvG,gFAAgF;AAEhF,kDAAkD;AAClD,gGAAgG;AAChG,8EAA8E;AAC9E,OAAO,EACL,mBAAmB,EACnB,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,gBAAgB,GAEjB,MAAM,sBAAsB,CAAC;
|
|
1
|
+
{"version":3,"file":"agent-client.js","sourceRoot":"","sources":["../../src/client/agent-client.ts"],"names":[],"mappings":"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"}
|
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Turn whatever a governance query threw into the two things an operator needs on screen: what went
|
|
3
|
+
* wrong, and whether it is worth pressing retry.
|
|
4
|
+
*
|
|
5
|
+
* A red box that says "error" is barely better than the blank section it replaced — the whole point
|
|
6
|
+
* of surfacing a failure in a governance console is that "the API is down" and "you are signed out"
|
|
7
|
+
* and "this host bound no pricing store" lead to three completely different next actions.
|
|
8
|
+
*
|
|
9
|
+
* `agentClient` throws `new Error(`${status} ${statusText}`)` for a non-2xx response, so the status
|
|
10
|
+
* is recoverable from the message. A `fetch` that never got a response throws a `TypeError` with no
|
|
11
|
+
* status at all — that is the "unreachable", not "refused", case.
|
|
12
|
+
*/
|
|
13
|
+
export interface DescribedError {
|
|
14
|
+
/** The HTTP status the API answered with, or `null` when the request never got a response. */
|
|
15
|
+
status: number | null;
|
|
16
|
+
/** The raw thrown message, shown verbatim — never swallow the thing the server actually said. */
|
|
17
|
+
message: string;
|
|
18
|
+
/** What to do about it, in one sentence. Empty when there is nothing honest to suggest. */
|
|
19
|
+
hint: string;
|
|
20
|
+
/**
|
|
21
|
+
* Whether pressing retry could plausibly change the answer. `false` for a `501` (the host is not
|
|
22
|
+
* configured for this read) — offering retry there just teaches operators the button is a lie.
|
|
23
|
+
*/
|
|
24
|
+
retryable: boolean;
|
|
25
|
+
}
|
|
26
|
+
/** The status a `fetch` rejection carries in its message, or `null` when it never reached the API. */
|
|
27
|
+
export declare function errorStatus(error: unknown): number | null;
|
|
28
|
+
/** Describe a thrown query error for display. See {@link DescribedError}. */
|
|
29
|
+
export declare function describeError(error: unknown): DescribedError;
|
|
30
|
+
//# sourceMappingURL=describe-error.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe-error.d.ts","sourceRoot":"","sources":["../../src/client/describe-error.ts"],"names":[],"mappings":"AAAA;;;;;;;;;;;GAWG;AACH,MAAM,WAAW,cAAc;IAC7B,8FAA8F;IAC9F,MAAM,EAAE,MAAM,GAAG,IAAI,CAAC;IACtB,iGAAiG;IACjG,OAAO,EAAE,MAAM,CAAC;IAChB,2FAA2F;IAC3F,IAAI,EAAE,MAAM,CAAC;IACb;;;OAGG;IACH,SAAS,EAAE,OAAO,CAAC;CACpB;AAID,sGAAsG;AACtG,wBAAgB,WAAW,CAAC,KAAK,EAAE,OAAO,GAAG,MAAM,GAAG,IAAI,CAIzD;AAED,6EAA6E;AAC7E,wBAAgB,aAAa,CAAC,KAAK,EAAE,OAAO,GAAG,cAAc,CAuD5D"}
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
const STATUS_PREFIX = /^(\d{3})\b/;
|
|
2
|
+
/** The status a `fetch` rejection carries in its message, or `null` when it never reached the API. */
|
|
3
|
+
export function errorStatus(error) {
|
|
4
|
+
const message = error instanceof Error ? error.message : String(error);
|
|
5
|
+
const matched = STATUS_PREFIX.exec(message);
|
|
6
|
+
return matched?.[1] === undefined ? null : Number(matched[1]);
|
|
7
|
+
}
|
|
8
|
+
/** Describe a thrown query error for display. See {@link DescribedError}. */
|
|
9
|
+
export function describeError(error) {
|
|
10
|
+
const message = error instanceof Error && error.message !== ''
|
|
11
|
+
? error.message
|
|
12
|
+
: typeof error === 'string' && error !== ''
|
|
13
|
+
? error
|
|
14
|
+
: 'Unknown error';
|
|
15
|
+
const status = errorStatus(error);
|
|
16
|
+
if (status === null) {
|
|
17
|
+
return {
|
|
18
|
+
status: null,
|
|
19
|
+
message,
|
|
20
|
+
hint: 'The API did not answer at all — it may be down, or a proxy in front of it may be blocking the request.',
|
|
21
|
+
retryable: true,
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
if (status === 401 || status === 403) {
|
|
25
|
+
return {
|
|
26
|
+
status,
|
|
27
|
+
message,
|
|
28
|
+
hint: 'The console session was rejected. Reload the page to sign in again.',
|
|
29
|
+
retryable: false,
|
|
30
|
+
};
|
|
31
|
+
}
|
|
32
|
+
if (status === 404) {
|
|
33
|
+
return {
|
|
34
|
+
status,
|
|
35
|
+
message,
|
|
36
|
+
hint: 'The API answered, but not on this route — check that the dashboard module is mounted where the SPA thinks it is.',
|
|
37
|
+
retryable: false,
|
|
38
|
+
};
|
|
39
|
+
}
|
|
40
|
+
if (status === 501) {
|
|
41
|
+
return {
|
|
42
|
+
status,
|
|
43
|
+
message,
|
|
44
|
+
hint: 'This host has not bound the store this read needs, so there is nothing to retry — it is a configuration answer, not a failure.',
|
|
45
|
+
retryable: false,
|
|
46
|
+
};
|
|
47
|
+
}
|
|
48
|
+
if (status >= 500) {
|
|
49
|
+
return {
|
|
50
|
+
status,
|
|
51
|
+
message,
|
|
52
|
+
hint: 'The API reached this read and it failed. The server logs will say why.',
|
|
53
|
+
retryable: true,
|
|
54
|
+
};
|
|
55
|
+
}
|
|
56
|
+
return {
|
|
57
|
+
status,
|
|
58
|
+
message,
|
|
59
|
+
hint: 'The API rejected this request. If a filter is set, it may be the filter.',
|
|
60
|
+
retryable: true,
|
|
61
|
+
};
|
|
62
|
+
}
|
|
63
|
+
//# sourceMappingURL=describe-error.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"describe-error.js","sourceRoot":"","sources":["../../src/client/describe-error.ts"],"names":[],"mappings":"AA0BA,MAAM,aAAa,GAAG,YAAY,CAAC;AAEnC,sGAAsG;AACtG,MAAM,UAAU,WAAW,CAAC,KAAc;IACxC,MAAM,OAAO,GAAG,KAAK,YAAY,KAAK,CAAC,CAAC,CAAC,KAAK,CAAC,OAAO,CAAC,CAAC,CAAC,MAAM,CAAC,KAAK,CAAC,CAAC;IACvE,MAAM,OAAO,GAAG,aAAa,CAAC,IAAI,CAAC,OAAO,CAAC,CAAC;IAC5C,OAAO,OAAO,EAAE,CAAC,CAAC,CAAC,KAAK,SAAS,CAAC,CAAC,CAAC,IAAI,CAAC,CAAC,CAAC,MAAM,CAAC,OAAO,CAAC,CAAC,CAAC,CAAC,CAAC;AAChE,CAAC;AAED,6EAA6E;AAC7E,MAAM,UAAU,aAAa,CAAC,KAAc;IAC1C,MAAM,OAAO,GACX,KAAK,YAAY,KAAK,IAAI,KAAK,CAAC,OAAO,KAAK,EAAE;QAC5C,CAAC,CAAC,KAAK,CAAC,OAAO;QACf,CAAC,CAAC,OAAO,KAAK,KAAK,QAAQ,IAAI,KAAK,KAAK,EAAE;YACzC,CAAC,CAAC,KAAK;YACP,CAAC,CAAC,eAAe,CAAC;IACxB,MAAM,MAAM,GAAG,WAAW,CAAC,KAAK,CAAC,CAAC;IAElC,IAAI,MAAM,KAAK,IAAI,EAAE,CAAC;QACpB,OAAO;YACL,MAAM,EAAE,IAAI;YACZ,OAAO;YACP,IAAI,EAAE,wGAAwG;YAC9G,SAAS,EAAE,IAAI;SAChB,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACrC,OAAO;YACL,MAAM;YACN,OAAO;YACP,IAAI,EAAE,qEAAqE;YAC3E,SAAS,EAAE,KAAK;SACjB,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO;YACL,MAAM;YACN,OAAO;YACP,IAAI,EAAE,kHAAkH;YACxH,SAAS,EAAE,KAAK;SACjB,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,KAAK,GAAG,EAAE,CAAC;QACnB,OAAO;YACL,MAAM;YACN,OAAO;YACP,IAAI,EAAE,gIAAgI;YACtI,SAAS,EAAE,KAAK;SACjB,CAAC;IACJ,CAAC;IACD,IAAI,MAAM,IAAI,GAAG,EAAE,CAAC;QAClB,OAAO;YACL,MAAM;YACN,OAAO;YACP,IAAI,EAAE,wEAAwE;YAC9E,SAAS,EAAE,IAAI;SAChB,CAAC;IACJ,CAAC;IACD,OAAO;QACL,MAAM;QACN,OAAO;QACP,IAAI,EAAE,0EAA0E;QAChF,SAAS,EAAE,IAAI;KAChB,CAAC;AACJ,CAAC"}
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Day-label formatting for the trend charts. Pure; unit-tested.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately does NOT go through `Date`. The governance read-model hands back calendar days as
|
|
5
|
+
* `YYYY-MM-DD` strings, and `new Date('2026-07-12')` parses as UTC midnight — so any browser west of
|
|
6
|
+
* Greenwich renders that day as "Jul 11". A chart axis that is off by one day is worse than an
|
|
7
|
+
* unformatted one, so the string is split by hand and never becomes an instant.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Short axis tick: `2026-07-12` -> `Jul 12`. Anything that is not a calendar day is passed through
|
|
11
|
+
* untouched so an unexpected key still labels itself rather than rendering as `Invalid Date`.
|
|
12
|
+
*/
|
|
13
|
+
export declare function formatDayTick(day: string): string;
|
|
14
|
+
/**
|
|
15
|
+
* Longer label for tooltips and captions: `2026-07-12` -> `Jul 12, 2026`. Same pass-through rule as
|
|
16
|
+
* {@link formatDayTick}; an empty string stays empty so a caption can render nothing at all.
|
|
17
|
+
*/
|
|
18
|
+
export declare function formatDayLabel(day: string): string;
|
|
19
|
+
//# sourceMappingURL=format-day.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-day.d.ts","sourceRoot":"","sources":["../../src/client/format-day.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAoBH;;;GAGG;AACH,wBAAgB,aAAa,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGjD;AAED;;;GAGG;AACH,wBAAgB,cAAc,CAAC,GAAG,EAAE,MAAM,GAAG,MAAM,CAGlD"}
|
|
@@ -0,0 +1,38 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Day-label formatting for the trend charts. Pure; unit-tested.
|
|
3
|
+
*
|
|
4
|
+
* Deliberately does NOT go through `Date`. The governance read-model hands back calendar days as
|
|
5
|
+
* `YYYY-MM-DD` strings, and `new Date('2026-07-12')` parses as UTC midnight — so any browser west of
|
|
6
|
+
* Greenwich renders that day as "Jul 11". A chart axis that is off by one day is worse than an
|
|
7
|
+
* unformatted one, so the string is split by hand and never becomes an instant.
|
|
8
|
+
*/
|
|
9
|
+
const MONTHS = ['Jan', 'Feb', 'Mar', 'Apr', 'May', 'Jun', 'Jul', 'Aug', 'Sep', 'Oct', 'Nov', 'Dec'];
|
|
10
|
+
function parseDay(day) {
|
|
11
|
+
const match = /^(\d{4})-(\d{2})-(\d{2})$/.exec(day);
|
|
12
|
+
if (!match)
|
|
13
|
+
return null;
|
|
14
|
+
const [, year, month, dayOfMonth] = match;
|
|
15
|
+
if (!year || !month || !dayOfMonth)
|
|
16
|
+
return null;
|
|
17
|
+
const monthName = MONTHS[Number(month) - 1];
|
|
18
|
+
if (!monthName)
|
|
19
|
+
return null;
|
|
20
|
+
return { year, month: monthName, day: Number(dayOfMonth) };
|
|
21
|
+
}
|
|
22
|
+
/**
|
|
23
|
+
* Short axis tick: `2026-07-12` -> `Jul 12`. Anything that is not a calendar day is passed through
|
|
24
|
+
* untouched so an unexpected key still labels itself rather than rendering as `Invalid Date`.
|
|
25
|
+
*/
|
|
26
|
+
export function formatDayTick(day) {
|
|
27
|
+
const parsed = parseDay(day);
|
|
28
|
+
return parsed ? `${parsed.month} ${parsed.day}` : day;
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Longer label for tooltips and captions: `2026-07-12` -> `Jul 12, 2026`. Same pass-through rule as
|
|
32
|
+
* {@link formatDayTick}; an empty string stays empty so a caption can render nothing at all.
|
|
33
|
+
*/
|
|
34
|
+
export function formatDayLabel(day) {
|
|
35
|
+
const parsed = parseDay(day);
|
|
36
|
+
return parsed ? `${parsed.month} ${parsed.day}, ${parsed.year}` : day;
|
|
37
|
+
}
|
|
38
|
+
//# sourceMappingURL=format-day.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"format-day.js","sourceRoot":"","sources":["../../src/client/format-day.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,MAAM,MAAM,GAAG,CAAC,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,EAAE,KAAK,CAAC,CAAC;AAQpG,SAAS,QAAQ,CAAC,GAAW;IAC3B,MAAM,KAAK,GAAG,2BAA2B,CAAC,IAAI,CAAC,GAAG,CAAC,CAAC;IACpD,IAAI,CAAC,KAAK;QAAE,OAAO,IAAI,CAAC;IACxB,MAAM,CAAC,EAAE,IAAI,EAAE,KAAK,EAAE,UAAU,CAAC,GAAG,KAAK,CAAC;IAC1C,IAAI,CAAC,IAAI,IAAI,CAAC,KAAK,IAAI,CAAC,UAAU;QAAE,OAAO,IAAI,CAAC;IAChD,MAAM,SAAS,GAAG,MAAM,CAAC,MAAM,CAAC,KAAK,CAAC,GAAG,CAAC,CAAC,CAAC;IAC5C,IAAI,CAAC,SAAS;QAAE,OAAO,IAAI,CAAC;IAC5B,OAAO,EAAE,IAAI,EAAE,KAAK,EAAE,SAAS,EAAE,GAAG,EAAE,MAAM,CAAC,UAAU,CAAC,EAAE,CAAC;AAC7D,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,aAAa,CAAC,GAAW;IACvC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AACxD,CAAC;AAED;;;GAGG;AACH,MAAM,UAAU,cAAc,CAAC,GAAW;IACxC,MAAM,MAAM,GAAG,QAAQ,CAAC,GAAG,CAAC,CAAC;IAC7B,OAAO,MAAM,CAAC,CAAC,CAAC,GAAG,MAAM,CAAC,KAAK,IAAI,MAAM,CAAC,GAAG,KAAK,MAAM,CAAC,IAAI,EAAE,CAAC,CAAC,CAAC,GAAG,CAAC;AACxE,CAAC"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Summary statistics for a daily trend series. Pure; unit-tested.
|
|
3
|
+
*
|
|
4
|
+
* This replaced `trend-path.ts` / `run-trend-path.ts`, which existed only to project a series into
|
|
5
|
+
* SVG path strings. Recharts owns that projection now, so the geometry went away — but the numbers a
|
|
6
|
+
* reader still wants at a glance (the range it covers, where it peaked) are not something a chart
|
|
7
|
+
* library computes for you, and they stay worth testing.
|
|
8
|
+
*/
|
|
9
|
+
/** Which series the daily usage chart plots. */
|
|
10
|
+
export type TrendMetric = 'costUsd' | 'totalTokens';
|
|
11
|
+
/** The at-a-glance facts a trend caption states, so the chart is legible without hovering it. */
|
|
12
|
+
export interface SeriesSummary {
|
|
13
|
+
/** First day in the series, or `''` when there is nothing to plot. */
|
|
14
|
+
first: string;
|
|
15
|
+
/** Last day in the series, or `''` when there is nothing to plot. */
|
|
16
|
+
last: string;
|
|
17
|
+
/** Highest value in the series (0 for an empty series). */
|
|
18
|
+
peak: number;
|
|
19
|
+
/** The day the peak occurred on — the FIRST such day when several tie. `''` when empty. */
|
|
20
|
+
peakDay: string;
|
|
21
|
+
/** Sum across the series. */
|
|
22
|
+
total: number;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* Summarize a day-keyed series. `value` picks the number to summarize, so the same function serves
|
|
26
|
+
* the cost/token trend and either leg of the run/failure trend. Assumes the series is already in
|
|
27
|
+
* chronological order — the read-model returns it that way, and re-sorting here would quietly
|
|
28
|
+
* disagree with the order the chart draws.
|
|
29
|
+
*/
|
|
30
|
+
export declare function summarizeSeries<T extends {
|
|
31
|
+
day: string;
|
|
32
|
+
}>(points: readonly T[], value: (point: T) => number): SeriesSummary;
|
|
33
|
+
//# sourceMappingURL=trend-summary.d.ts.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trend-summary.d.ts","sourceRoot":"","sources":["../../src/client/trend-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAEH,gDAAgD;AAChD,MAAM,MAAM,WAAW,GAAG,SAAS,GAAG,aAAa,CAAC;AAEpD,iGAAiG;AACjG,MAAM,WAAW,aAAa;IAC5B,sEAAsE;IACtE,KAAK,EAAE,MAAM,CAAC;IACd,qEAAqE;IACrE,IAAI,EAAE,MAAM,CAAC;IACb,2DAA2D;IAC3D,IAAI,EAAE,MAAM,CAAC;IACb,2FAA2F;IAC3F,OAAO,EAAE,MAAM,CAAC;IAChB,6BAA6B;IAC7B,KAAK,EAAE,MAAM,CAAC;CACf;AAED;;;;;GAKG;AACH,wBAAgB,eAAe,CAAC,CAAC,SAAS;IAAE,GAAG,EAAE,MAAM,CAAA;CAAE,EACvD,MAAM,EAAE,SAAS,CAAC,EAAE,EACpB,KAAK,EAAE,CAAC,KAAK,EAAE,CAAC,KAAK,MAAM,GAC1B,aAAa,CAkBf"}
|
|
@@ -0,0 +1,33 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Summary statistics for a daily trend series. Pure; unit-tested.
|
|
3
|
+
*
|
|
4
|
+
* This replaced `trend-path.ts` / `run-trend-path.ts`, which existed only to project a series into
|
|
5
|
+
* SVG path strings. Recharts owns that projection now, so the geometry went away — but the numbers a
|
|
6
|
+
* reader still wants at a glance (the range it covers, where it peaked) are not something a chart
|
|
7
|
+
* library computes for you, and they stay worth testing.
|
|
8
|
+
*/
|
|
9
|
+
/**
|
|
10
|
+
* Summarize a day-keyed series. `value` picks the number to summarize, so the same function serves
|
|
11
|
+
* the cost/token trend and either leg of the run/failure trend. Assumes the series is already in
|
|
12
|
+
* chronological order — the read-model returns it that way, and re-sorting here would quietly
|
|
13
|
+
* disagree with the order the chart draws.
|
|
14
|
+
*/
|
|
15
|
+
export function summarizeSeries(points, value) {
|
|
16
|
+
const first = points[0];
|
|
17
|
+
const last = points[points.length - 1];
|
|
18
|
+
if (!first || !last)
|
|
19
|
+
return { first: '', last: '', peak: 0, peakDay: '', total: 0 };
|
|
20
|
+
let peak = Number.NEGATIVE_INFINITY;
|
|
21
|
+
let peakDay = first.day;
|
|
22
|
+
let total = 0;
|
|
23
|
+
for (const point of points) {
|
|
24
|
+
const current = value(point);
|
|
25
|
+
total += current;
|
|
26
|
+
if (current > peak) {
|
|
27
|
+
peak = current;
|
|
28
|
+
peakDay = point.day;
|
|
29
|
+
}
|
|
30
|
+
}
|
|
31
|
+
return { first: first.day, last: last.day, peak, peakDay, total };
|
|
32
|
+
}
|
|
33
|
+
//# sourceMappingURL=trend-summary.js.map
|
|
@@ -0,0 +1 @@
|
|
|
1
|
+
{"version":3,"file":"trend-summary.js","sourceRoot":"","sources":["../../src/client/trend-summary.ts"],"names":[],"mappings":"AAAA;;;;;;;GAOG;AAmBH;;;;;GAKG;AACH,MAAM,UAAU,eAAe,CAC7B,MAAoB,EACpB,KAA2B;IAE3B,MAAM,KAAK,GAAG,MAAM,CAAC,CAAC,CAAC,CAAC;IACxB,MAAM,IAAI,GAAG,MAAM,CAAC,MAAM,CAAC,MAAM,GAAG,CAAC,CAAC,CAAC;IACvC,IAAI,CAAC,KAAK,IAAI,CAAC,IAAI;QAAE,OAAO,EAAE,KAAK,EAAE,EAAE,EAAE,IAAI,EAAE,EAAE,EAAE,IAAI,EAAE,CAAC,EAAE,OAAO,EAAE,EAAE,EAAE,KAAK,EAAE,CAAC,EAAE,CAAC;IAEpF,IAAI,IAAI,GAAG,MAAM,CAAC,iBAAiB,CAAC;IACpC,IAAI,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC;IACxB,IAAI,KAAK,GAAG,CAAC,CAAC;IACd,KAAK,MAAM,KAAK,IAAI,MAAM,EAAE,CAAC;QAC3B,MAAM,OAAO,GAAG,KAAK,CAAC,KAAK,CAAC,CAAC;QAC7B,KAAK,IAAI,OAAO,CAAC;QACjB,IAAI,OAAO,GAAG,IAAI,EAAE,CAAC;YACnB,IAAI,GAAG,OAAO,CAAC;YACf,OAAO,GAAG,KAAK,CAAC,GAAG,CAAC;QACtB,CAAC;IACH,CAAC;IAED,OAAO,EAAE,KAAK,EAAE,KAAK,CAAC,GAAG,EAAE,IAAI,EAAE,IAAI,CAAC,GAAG,EAAE,IAAI,EAAE,OAAO,EAAE,KAAK,EAAE,CAAC;AACpE,CAAC"}
|