@agimon-ai/po-log 0.0.0-alpha.73 → 0.0.0-alpha.75

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.
@@ -1,9 +1,501 @@
1
1
  import { defineNativePlugin, defineToolRenderer } from "@agimon-ai/po-core/native";
2
2
  import { View } from "react-native-unistyles/components/native/View";
3
3
  import { Text } from "react-native-unistyles/components/native/Text";
4
- import { CodeBlock, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, fontOf, toolTone } from "@agimon-ai/po-native-components";
4
+ import { Badge, CodeBlock, MessageItem, MessageItemBody, MessageItemHeader, MessageItemStatus, SectionLabel, StatusBadge, collapseLines, fontOf, toolTone } from "@agimon-ai/po-native-components";
5
5
  import { StyleSheet } from "react-native-unistyles";
6
6
  import { Fragment, jsx, jsxs } from "react/jsx-runtime";
7
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/agentDiagnosticView.ts
8
+ /** The diagnose_agent report as the card's lines: the tool's text output, blank lines dropped. */
9
+ function diagnosticLines(output) {
10
+ return output.split("\n").filter(Boolean);
11
+ }
12
+ /** Categories that are real failures of the run; the rest (caller errors, refusals, expected failures) are not. */
13
+ const FAILURE_CATEGORIES = /* @__PURE__ */ new Set([
14
+ "tool_failure",
15
+ "infrastructure_failure",
16
+ "api_error",
17
+ "api_retries_exhausted",
18
+ "log_error"
19
+ ]);
20
+ /** The sentence the empty state keeps from the report's limitations. */
21
+ const EMPTY_SENTENCE = /[^.]*empty data[^.]*\.?/i;
22
+ const isRecord = (value) => typeof value === "object" && value !== null && !Array.isArray(value);
23
+ const count$1 = (value) => typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
24
+ const text = (value) => typeof value === "string" && value.trim() !== "" ? value.trim() : void 0;
25
+ function categories(value) {
26
+ if (!isRecord(value)) return [];
27
+ return Object.entries(value).flatMap(([key, raw]) => {
28
+ const n = count$1(raw);
29
+ return n !== void 0 && n > 0 && key.trim() !== "" ? [{
30
+ key,
31
+ label: key.replaceAll("_", " "),
32
+ count: n,
33
+ failure: FAILURE_CATEGORIES.has(key)
34
+ }] : [];
35
+ }).sort((a, b) => b.count - a.count);
36
+ }
37
+ function tools(value) {
38
+ if (!Array.isArray(value)) return [];
39
+ return value.flatMap((raw) => {
40
+ if (!isRecord(raw)) return [];
41
+ const name = text(raw.name);
42
+ if (name === void 0) return [];
43
+ return [{
44
+ name,
45
+ invocations: count$1(raw.invocations),
46
+ p90TurnTokens: count$1(raw.p90TurnTokens)
47
+ }];
48
+ });
49
+ }
50
+ /**
51
+ * Parses the tool's JSON report at the card's boundary. Unknown or malformed
52
+ * fields are skipped; output that is not a JSON object, or carries none of the
53
+ * report's fields, returns null so the card falls back to the raw lines.
54
+ */
55
+ function parseDiagnosticReport(output) {
56
+ let raw;
57
+ try {
58
+ raw = JSON.parse(output);
59
+ } catch {
60
+ return null;
61
+ }
62
+ if (!isRecord(raw)) return null;
63
+ const usage = isRecord(raw.usage) ? raw.usage : {};
64
+ const report = {
65
+ scope: text(raw.scope),
66
+ period: text(raw.period),
67
+ evidence: text(raw.evidence),
68
+ code: text(raw.code),
69
+ capturedRecords: count$1(raw.capturedRecords),
70
+ capturedIssues: count$1(raw.capturedIssues),
71
+ categories: categories(raw.issuesByCategory),
72
+ inputTokens: count$1(usage.inputTokens),
73
+ outputTokens: count$1(usage.outputTokens),
74
+ tokenCoveragePercent: count$1(usage.tokenCoveragePercent),
75
+ tools: tools(raw.tools),
76
+ limitReached: typeof raw.limitReached === "boolean" ? raw.limitReached : void 0,
77
+ captureCompleteness: text(raw.captureCompleteness),
78
+ limitations: text(raw.limitations)
79
+ };
80
+ return Object.values(report).some((value) => Array.isArray(value) ? value.length > 0 : value !== void 0) ? report : null;
81
+ }
82
+ /** Token counts in a few characters: 182400 reads `182.4k`. */
83
+ function compactNumber(value) {
84
+ if (value >= 1e6) return `${(value / 1e6).toFixed(1)}M`;
85
+ if (value >= 1e3) return `${(value / 1e3).toFixed(1)}k`;
86
+ return String(Math.round(value));
87
+ }
88
+ const words = (value) => value.replaceAll(/[-_]/g, " ");
89
+ /** The header summary: the primary piece stays whole, the context may truncate. */
90
+ function diagnosticSummary(report) {
91
+ const context = [report.scope, report.period].flatMap((part) => part ? [words(part)] : []).join(" · ");
92
+ const issues = report.capturedIssues;
93
+ const primary = report.evidence === "unavailable" ? "Telemetry unavailable" : report.evidence === "empty" ? "Nothing captured" : issues === void 0 ? "Captured agent evidence" : issues === 0 ? "No issues" : `${String(issues)} ${issues === 1 ? "issue" : "issues"}`;
94
+ return context === "" ? { primary } : {
95
+ primary,
96
+ context
97
+ };
98
+ }
99
+ /** The key figures row; a figure the report did not send is left out rather than shown as zero. */
100
+ function diagnosticFigures(report) {
101
+ const figures = [];
102
+ if (report.capturedRecords !== void 0) figures.push({
103
+ label: "Records",
104
+ value: report.capturedRecords.toLocaleString("en-US"),
105
+ failure: false
106
+ });
107
+ if (report.capturedIssues !== void 0) {
108
+ const failing = report.capturedIssues > 0 && report.categories.some((category) => category.failure);
109
+ figures.push({
110
+ label: "Issues",
111
+ value: report.capturedIssues.toLocaleString("en-US"),
112
+ failure: failing
113
+ });
114
+ }
115
+ if (report.inputTokens !== void 0 || report.outputTokens !== void 0) {
116
+ const side = (value) => value === void 0 ? "?" : compactNumber(value);
117
+ figures.push({
118
+ label: "Tokens in / out",
119
+ value: `${side(report.inputTokens)} / ${side(report.outputTokens)}`,
120
+ failure: false
121
+ });
122
+ }
123
+ if (report.tokenCoveragePercent !== void 0) figures.push({
124
+ label: "Token coverage",
125
+ value: `${String(report.tokenCoveragePercent)}%`,
126
+ failure: false
127
+ });
128
+ return figures;
129
+ }
130
+ /** The quiet note at the bottom: capture completeness, then the report's limitations. */
131
+ function diagnosticNote(report) {
132
+ const parts = [report.captureCompleteness ? `Capture completeness: ${words(report.captureCompleteness)}.` : void 0, report.limitations].filter((part) => part !== void 0);
133
+ return parts.length > 0 ? parts.join(" ") : void 0;
134
+ }
135
+ /** The limitation sentence an empty report leads with, so an empty window never reads as a healthy run. */
136
+ function emptyLimitation(report) {
137
+ return report.limitations?.match(EMPTY_SENTENCE)?.[0].trim() ?? "Empty data is not proof of a healthy run.";
138
+ }
139
+ //#endregion
140
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/_components/AgentDiagnosticCard.native.tsx
141
+ const DEFAULT_SUMMARY = "Captured agent evidence";
142
+ /**
143
+ * The diagnose_agent tool's timeline item on native, as the web's: the report
144
+ * as a header summary and its key figures, with categories, tools and the
145
+ * limitations on expand. Output that does not parse keeps the raw lines. A
146
+ * failed read shows only its reason in red; the header carries the failure.
147
+ */
148
+ function AgentDiagnosticCard({ toolName, output, running, isError }) {
149
+ const tone = toolTone({
150
+ running,
151
+ isError
152
+ });
153
+ const report = running || isError ? null : parseDiagnosticReport(output);
154
+ if (report) return /* @__PURE__ */ jsx(ReportCard, {
155
+ toolName,
156
+ tone,
157
+ report
158
+ });
159
+ const lines = diagnosticLines(output);
160
+ if (isError) return /* @__PURE__ */ jsxs(MessageItem, {
161
+ tone,
162
+ children: [/* @__PURE__ */ jsx(MessageItemHeader, {
163
+ title: toolName,
164
+ children: DEFAULT_SUMMARY
165
+ }), lines.length > 0 ? /* @__PURE__ */ jsx(MessageItemBody, { children: /* @__PURE__ */ jsx(Text, {
166
+ selectable: true,
167
+ style: [styles$1.sans, styles$1.error],
168
+ children: lines.join("\n")
169
+ }) }) : null]
170
+ });
171
+ return /* @__PURE__ */ jsx(MessageItem, {
172
+ tone,
173
+ expandable: lines.length > 12,
174
+ children: ({ expanded }) => {
175
+ const view = collapseLines(lines, 12, expanded);
176
+ return /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
177
+ title: toolName,
178
+ children: DEFAULT_SUMMARY
179
+ }), view.shown.length > 0 || running ? /* @__PURE__ */ jsxs(MessageItemBody, { children: [
180
+ view.shown.map((line, index) => /* @__PURE__ */ jsx(Text, {
181
+ selectable: true,
182
+ style: [styles$1.sans, styles$1.text],
183
+ children: line
184
+ }, `${String(index)}-${line}`)),
185
+ view.hidden > 0 ? /* @__PURE__ */ jsxs(MessageItemStatus, {
186
+ expands: true,
187
+ children: [view.hidden, " more lines"]
188
+ }) : null,
189
+ running ? /* @__PURE__ */ jsx(MessageItemStatus, {
190
+ tone: "running",
191
+ children: "Reading session telemetry"
192
+ }) : null
193
+ ] }) : null] });
194
+ }
195
+ });
196
+ }
197
+ function ReportCard({ toolName, tone, report }) {
198
+ const summary = diagnosticSummary(report);
199
+ const figures = diagnosticFigures(report);
200
+ const note = diagnosticNote(report);
201
+ const empty = report.evidence === "empty";
202
+ const unavailable = report.evidence === "unavailable";
203
+ const sentence = emptyLimitation(report);
204
+ const extraNote = empty && note === sentence ? void 0 : note;
205
+ const quiet = empty || unavailable;
206
+ const details = quiet ? extraNote !== void 0 : report.categories.length > 0 || report.tools.length > 0 || note !== void 0;
207
+ return /* @__PURE__ */ jsx(MessageItem, {
208
+ tone: unavailable ? "neutral" : tone,
209
+ expandable: details,
210
+ children: ({ expanded }) => /* @__PURE__ */ jsxs(Fragment, { children: [/* @__PURE__ */ jsx(MessageItemHeader, {
211
+ title: toolName,
212
+ children: /* @__PURE__ */ jsx(View, {
213
+ style: styles$1.summary,
214
+ children: /* @__PURE__ */ jsx(Text, {
215
+ numberOfLines: 1,
216
+ style: [styles$1.sans, styles$1.primary],
217
+ children: summary.primary
218
+ })
219
+ })
220
+ }), /* @__PURE__ */ jsxs(MessageItemBody, {
221
+ style: styles$1.body,
222
+ children: [
223
+ unavailable ? /* @__PURE__ */ jsxs(View, {
224
+ style: styles$1.wrapRow,
225
+ children: [/* @__PURE__ */ jsx(Text, {
226
+ style: [styles$1.sans, styles$1.dim],
227
+ children: "The session's telemetry could not be read."
228
+ }), report.code ? /* @__PURE__ */ jsx(StatusBadge, {
229
+ size: "xs",
230
+ children: /* @__PURE__ */ jsx(Text, {
231
+ style: styles$1.code,
232
+ children: report.code
233
+ })
234
+ }) : null]
235
+ }) : empty ? /* @__PURE__ */ jsxs(View, {
236
+ style: styles$1.block,
237
+ children: [/* @__PURE__ */ jsx(Text, {
238
+ style: [styles$1.sans, styles$1.text],
239
+ children: "No records were captured in this window."
240
+ }), /* @__PURE__ */ jsx(Text, {
241
+ style: [styles$1.small, styles$1.dim],
242
+ children: sentence
243
+ })]
244
+ }) : figures.length > 0 ? /* @__PURE__ */ jsx(View, {
245
+ style: styles$1.figures,
246
+ children: figures.map((figure) => /* @__PURE__ */ jsxs(View, {
247
+ style: styles$1.figure,
248
+ children: [/* @__PURE__ */ jsx(Text, {
249
+ numberOfLines: 1,
250
+ style: [styles$1.small, styles$1.dim],
251
+ children: figure.label
252
+ }), /* @__PURE__ */ jsx(Text, {
253
+ numberOfLines: 1,
254
+ style: [styles$1.value, figure.failure ? styles$1.error : styles$1.hi],
255
+ children: figure.value
256
+ })]
257
+ }, figure.label))
258
+ }) : null,
259
+ expanded && !quiet && report.categories.length > 0 ? /* @__PURE__ */ jsxs(View, {
260
+ style: styles$1.section,
261
+ children: [/* @__PURE__ */ jsx(SectionLabel, { children: "Issues by category" }), /* @__PURE__ */ jsx(View, {
262
+ style: styles$1.wrapRow,
263
+ children: report.categories.map((category) => /* @__PURE__ */ jsxs(Badge, {
264
+ tone: category.failure ? "red" : "neutral",
265
+ children: [category.label, /* @__PURE__ */ jsx(Text, {
266
+ style: [
267
+ styles$1.small,
268
+ styles$1.count,
269
+ category.failure ? styles$1.error : styles$1.text
270
+ ],
271
+ children: String(category.count)
272
+ })]
273
+ }, category.key))
274
+ })]
275
+ }) : null,
276
+ expanded && !quiet && report.tools.length > 0 ? /* @__PURE__ */ jsxs(View, {
277
+ style: styles$1.section,
278
+ children: [
279
+ /* @__PURE__ */ jsx(SectionLabel, { children: "Tools" }),
280
+ /* @__PURE__ */ jsxs(View, {
281
+ style: styles$1.toolRow,
282
+ children: [
283
+ /* @__PURE__ */ jsx(Text, {
284
+ style: [
285
+ styles$1.small,
286
+ styles$1.dim,
287
+ styles$1.toolName
288
+ ],
289
+ children: "Name"
290
+ }),
291
+ /* @__PURE__ */ jsx(Text, {
292
+ style: [
293
+ styles$1.small,
294
+ styles$1.dim,
295
+ styles$1.toolCalls
296
+ ],
297
+ children: "Calls"
298
+ }),
299
+ /* @__PURE__ */ jsx(Text, {
300
+ style: [
301
+ styles$1.small,
302
+ styles$1.dim,
303
+ styles$1.toolTokens
304
+ ],
305
+ children: "p90 turn"
306
+ })
307
+ ]
308
+ }),
309
+ /* @__PURE__ */ jsx(View, { children: report.tools.map((tool) => /* @__PURE__ */ jsxs(View, {
310
+ style: [styles$1.toolRow, styles$1.toolDivided],
311
+ children: [
312
+ /* @__PURE__ */ jsx(Text, {
313
+ numberOfLines: 1,
314
+ style: [
315
+ styles$1.mono,
316
+ styles$1.text,
317
+ styles$1.toolName
318
+ ],
319
+ children: tool.name
320
+ }),
321
+ /* @__PURE__ */ jsx(Text, {
322
+ style: [
323
+ styles$1.sans,
324
+ styles$1.text,
325
+ styles$1.toolCalls
326
+ ],
327
+ children: tool.invocations === void 0 ? "?" : tool.invocations.toLocaleString("en-US")
328
+ }),
329
+ /* @__PURE__ */ jsx(Text, {
330
+ style: [
331
+ styles$1.sans,
332
+ styles$1.text,
333
+ styles$1.toolTokens
334
+ ],
335
+ children: tool.p90TurnTokens === void 0 ? "?" : compactNumber(tool.p90TurnTokens)
336
+ })
337
+ ]
338
+ }, tool.name)) }),
339
+ report.limitReached ? /* @__PURE__ */ jsxs(Text, {
340
+ style: [styles$1.small, styles$1.dim],
341
+ children: [
342
+ "Showing the first ",
343
+ report.tools.length,
344
+ " tools."
345
+ ]
346
+ }) : null
347
+ ]
348
+ }) : null,
349
+ expanded && extraNote ? /* @__PURE__ */ jsx(Text, {
350
+ style: [styles$1.small, styles$1.faint],
351
+ children: extraNote
352
+ }) : null
353
+ ]
354
+ })] })
355
+ });
356
+ }
357
+ /** Numbers line up down a column. */
358
+ const TABULAR = ["tabular-nums"];
359
+ /** The calls column fits four digits; the token column fits `182.4k`. */
360
+ const CALLS_WIDTH = 48;
361
+ const TOKENS_WIDTH = 72;
362
+ const styles$1 = StyleSheet.create((theme) => ({
363
+ summary: {
364
+ flex: 1,
365
+ flexDirection: "row",
366
+ alignItems: "center",
367
+ gap: theme.spacing(1.5),
368
+ minWidth: 0,
369
+ uni__dependencies: [0]
370
+ },
371
+ primary: {
372
+ flexShrink: 1,
373
+ color: theme.colors.text,
374
+ uni__dependencies: [0]
375
+ },
376
+ body: {
377
+ gap: theme.spacing(4),
378
+ uni__dependencies: [0]
379
+ },
380
+ block: {
381
+ gap: theme.spacing(1),
382
+ uni__dependencies: [0]
383
+ },
384
+ section: {
385
+ gap: theme.spacing(2),
386
+ uni__dependencies: [0]
387
+ },
388
+ wrapRow: {
389
+ flexDirection: "row",
390
+ flexWrap: "wrap",
391
+ alignItems: "center",
392
+ gap: theme.spacing(2),
393
+ uni__dependencies: [0]
394
+ },
395
+ figures: {
396
+ flexDirection: "row",
397
+ flexWrap: "wrap",
398
+ rowGap: theme.spacing(3),
399
+ uni__dependencies: [0]
400
+ },
401
+ figure: {
402
+ width: "50%",
403
+ gap: theme.spacing(.5),
404
+ paddingRight: theme.spacing(2),
405
+ uni__dependencies: [0]
406
+ },
407
+ toolRow: {
408
+ flexDirection: "row",
409
+ alignItems: "center",
410
+ gap: theme.spacing(3),
411
+ paddingVertical: theme.spacing(1),
412
+ uni__dependencies: [0]
413
+ },
414
+ toolDivided: {
415
+ borderTopWidth: 1,
416
+ borderTopColor: theme.colors["border-soft"],
417
+ uni__dependencies: [0]
418
+ },
419
+ toolName: {
420
+ flex: 1,
421
+ minWidth: 0
422
+ },
423
+ toolCalls: {
424
+ width: CALLS_WIDTH,
425
+ textAlign: "right",
426
+ fontVariant: TABULAR
427
+ },
428
+ toolTokens: {
429
+ width: TOKENS_WIDTH,
430
+ textAlign: "right",
431
+ fontVariant: TABULAR
432
+ },
433
+ sans: {
434
+ fontFamily: fontOf(theme.fontFamily.sans),
435
+ fontSize: theme.fontSize.base,
436
+ lineHeight: theme.lineHeight.base,
437
+ uni__dependencies: [0]
438
+ },
439
+ small: {
440
+ fontFamily: fontOf(theme.fontFamily.sans),
441
+ fontSize: theme.fontSize.sm,
442
+ lineHeight: theme.lineHeight.sm,
443
+ uni__dependencies: [0]
444
+ },
445
+ mono: {
446
+ fontFamily: fontOf(theme.fontFamily.mono),
447
+ fontSize: theme.fontSize.base,
448
+ lineHeight: theme.lineHeight.base,
449
+ uni__dependencies: [0]
450
+ },
451
+ code: {
452
+ fontFamily: fontOf(theme.fontFamily.mono),
453
+ fontSize: theme.fontSize.sm,
454
+ lineHeight: theme.lineHeight.sm,
455
+ color: theme.colors.faint,
456
+ uni__dependencies: [0]
457
+ },
458
+ value: {
459
+ fontFamily: fontOf(theme.fontFamily.sans),
460
+ fontSize: theme.fontSize.lg,
461
+ lineHeight: theme.lineHeight.lg,
462
+ fontWeight: theme.fontWeight.semibold,
463
+ fontVariant: TABULAR,
464
+ uni__dependencies: [0]
465
+ },
466
+ count: {
467
+ fontWeight: theme.fontWeight.semibold,
468
+ fontVariant: TABULAR,
469
+ uni__dependencies: [0]
470
+ },
471
+ text: {
472
+ color: theme.colors.text,
473
+ uni__dependencies: [0]
474
+ },
475
+ hi: {
476
+ color: theme.colors.hi,
477
+ uni__dependencies: [0]
478
+ },
479
+ dim: {
480
+ color: theme.colors.dim,
481
+ uni__dependencies: [0]
482
+ },
483
+ faint: {
484
+ color: theme.colors.faint,
485
+ uni__dependencies: [0]
486
+ },
487
+ error: {
488
+ color: theme.colors.red,
489
+ uni__dependencies: [0]
490
+ }
491
+ }));
492
+ //#endregion
493
+ //#region src/extensions/workspaces/sessions/(frontend)/tool/diagnose-agent.native.tsx
494
+ var diagnose_agent_native_default = defineToolRenderer({
495
+ tools: ["diagnose_agent"],
496
+ message: AgentDiagnosticCard
497
+ });
498
+ //#endregion
7
499
  //#region src/extensions/workspaces/sessions/(frontend)/tool/_lib/logsinkToolRender.ts
8
500
  const logsinkToolNames = [
9
501
  "logsink_status",
@@ -329,7 +821,7 @@ const via = (identity, value) => value === void 0 ? void 0 : {
329
821
  const nativePlugin = defineNativePlugin({
330
822
  id: "log",
331
823
  session: { get toolRenderers() {
332
- return [via({ tools: ["logsink"] }, logsink_native_default)];
824
+ return [via({ tools: ["diagnose_agent"] }, diagnose_agent_native_default), via({ tools: ["logsink"] }, logsink_native_default)];
333
825
  } }
334
826
  });
335
827
  //#endregion