@linxiraos/pi-stats 1.3.2 → 1.4.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/CHANGELOG.md +10 -0
- package/README.md +2 -0
- package/dist/client/index.css +1 -1
- package/dist/client/index.js +88 -88
- package/dist/types/client/i18n/messages/en.d.ts +72 -0
- package/dist/types/client/i18n/messages/frustration.d.ts +72 -0
- package/dist/types/client/i18n/messages/zh-CN.d.ts +1 -1
- package/dist/types/db.d.ts +34 -1
- package/dist/types/model-identity.d.ts +29 -0
- package/dist/types/model-metrics.d.ts +53 -0
- package/dist/types/model-side.d.ts +6 -0
- package/dist/types/parser.d.ts +2 -1
- package/dist/types/shared-types.d.ts +88 -0
- package/dist/types/types.d.ts +47 -1
- package/dist/types/user-metrics.d.ts +22 -2
- package/package.json +4 -4
- package/src/aggregator.ts +1 -0
- package/src/client/i18n/messages/frustration.ts +77 -0
- package/src/client/routes/FrustrationRoute.tsx +439 -4
- package/src/client/routes/frustration.css +13 -0
- package/src/db.ts +321 -2
- package/src/frustration.ts +8 -33
- package/src/model-identity.ts +61 -0
- package/src/model-metrics.ts +153 -0
- package/src/model-side.ts +77 -0
- package/src/parser.ts +104 -11
- package/src/shared-types.ts +93 -0
- package/src/types.ts +48 -1
- package/src/user-metrics.ts +9 -7
|
@@ -546,6 +546,42 @@ export declare const enMessages: {
|
|
|
546
546
|
readonly "frustration.cancelled": "Cancelled";
|
|
547
547
|
readonly "frustration.failed": "Failed";
|
|
548
548
|
readonly "frustration.done": "Done";
|
|
549
|
+
readonly "frustration.model-side-title": "AI breakdown";
|
|
550
|
+
readonly "frustration.model-side-description": "How the model's own replies read, per model version, in {window}.";
|
|
551
|
+
readonly "frustration.model-turns": "Assistant turns";
|
|
552
|
+
readonly "frustration.model-turns-title": "Assistant replies with text in range; tool-call-only replies and thinking blocks are not analyzed";
|
|
553
|
+
readonly "frustration.model-breakdown": "Breakdown rate";
|
|
554
|
+
readonly "frustration.model-breakdown-title": "Share of analyzed turns with at least one breakdown signal";
|
|
555
|
+
readonly "frustration.model-mean": "Signals / turn";
|
|
556
|
+
readonly "frustration.model-mean-title": "Average per-turn aggregate: text markers plus capped failed tool results";
|
|
557
|
+
readonly "frustration.model-self-blame": "Self-blame";
|
|
558
|
+
readonly "frustration.model-self-blame-title": "Turns containing an apology or admission";
|
|
559
|
+
readonly "frustration.model-restatement": "Restatement";
|
|
560
|
+
readonly "frustration.model-restatement-title": "Turns repeating earlier content, by explicit marker or near-duplicate reply";
|
|
561
|
+
readonly "frustration.model-hedge": "Hedged";
|
|
562
|
+
readonly "frustration.model-hedge-title": "Turns with hedged fallbacks: uncertainty or suggested alternatives";
|
|
563
|
+
readonly "frustration.model-spiral": "Tool spirals";
|
|
564
|
+
readonly "frustration.model-spiral-title": "Turns following three or more failed tool results";
|
|
565
|
+
readonly "frustration.model-rambling": "Rambling";
|
|
566
|
+
readonly "frustration.model-rambling-title": "Turns past the verbosity threshold";
|
|
567
|
+
readonly "frustration.model-unscored-line": "Turns in a language without a lexicon: {count} — unscored, not calm.";
|
|
568
|
+
readonly "frustration.model-by-model": "AI breakdown by model version";
|
|
569
|
+
readonly "frustration.model-table-title": "Model breakdown detail";
|
|
570
|
+
readonly "frustration.model-by-model-description": "Share of each model's analyzed turns carrying a breakdown signal. Hue = model family.";
|
|
571
|
+
readonly "frustration.model-over-time": "AI breakdown over time";
|
|
572
|
+
readonly "frustration.model-over-time-description": "Breakdown rate per bucket: turns with a signal over analyzed turns. Gaps are buckets with no turns.";
|
|
573
|
+
readonly "frustration.model-sessions": "Sessions by breakdown";
|
|
574
|
+
readonly "frustration.model-sessions-description": "Sessions with the most analyzed assistant turns.";
|
|
575
|
+
readonly "frustration.model-table-description": "Rates are shares of analyzed assistant turns.";
|
|
576
|
+
readonly "frustration.column-session": "Session";
|
|
577
|
+
readonly "frustration.column-turns": "Turns";
|
|
578
|
+
readonly "frustration.column-mean": "Signals/turn";
|
|
579
|
+
readonly "frustration.column-tool-errors": "Tool errors";
|
|
580
|
+
readonly "frustration.model-no-turns": "No assistant turns with text in this range";
|
|
581
|
+
readonly "frustration.model-try-longer-range": "Try a longer range.";
|
|
582
|
+
readonly "frustration.model-legend-breakdown": "Breakdown rate";
|
|
583
|
+
readonly "frustration.turns-n": "{count} turns";
|
|
584
|
+
readonly "frustration.model-hint-mean": "{value} signals per turn on average";
|
|
549
585
|
readonly "projects.title": "Projects";
|
|
550
586
|
readonly "projects.description": "Usage by session folder in {window}.";
|
|
551
587
|
readonly "projects.folders": "Folders";
|
|
@@ -1175,6 +1211,42 @@ export declare const enLocale: {
|
|
|
1175
1211
|
readonly "frustration.cancelled": "Cancelled";
|
|
1176
1212
|
readonly "frustration.failed": "Failed";
|
|
1177
1213
|
readonly "frustration.done": "Done";
|
|
1214
|
+
readonly "frustration.model-side-title": "AI breakdown";
|
|
1215
|
+
readonly "frustration.model-side-description": "How the model's own replies read, per model version, in {window}.";
|
|
1216
|
+
readonly "frustration.model-turns": "Assistant turns";
|
|
1217
|
+
readonly "frustration.model-turns-title": "Assistant replies with text in range; tool-call-only replies and thinking blocks are not analyzed";
|
|
1218
|
+
readonly "frustration.model-breakdown": "Breakdown rate";
|
|
1219
|
+
readonly "frustration.model-breakdown-title": "Share of analyzed turns with at least one breakdown signal";
|
|
1220
|
+
readonly "frustration.model-mean": "Signals / turn";
|
|
1221
|
+
readonly "frustration.model-mean-title": "Average per-turn aggregate: text markers plus capped failed tool results";
|
|
1222
|
+
readonly "frustration.model-self-blame": "Self-blame";
|
|
1223
|
+
readonly "frustration.model-self-blame-title": "Turns containing an apology or admission";
|
|
1224
|
+
readonly "frustration.model-restatement": "Restatement";
|
|
1225
|
+
readonly "frustration.model-restatement-title": "Turns repeating earlier content, by explicit marker or near-duplicate reply";
|
|
1226
|
+
readonly "frustration.model-hedge": "Hedged";
|
|
1227
|
+
readonly "frustration.model-hedge-title": "Turns with hedged fallbacks: uncertainty or suggested alternatives";
|
|
1228
|
+
readonly "frustration.model-spiral": "Tool spirals";
|
|
1229
|
+
readonly "frustration.model-spiral-title": "Turns following three or more failed tool results";
|
|
1230
|
+
readonly "frustration.model-rambling": "Rambling";
|
|
1231
|
+
readonly "frustration.model-rambling-title": "Turns past the verbosity threshold";
|
|
1232
|
+
readonly "frustration.model-unscored-line": "Turns in a language without a lexicon: {count} — unscored, not calm.";
|
|
1233
|
+
readonly "frustration.model-by-model": "AI breakdown by model version";
|
|
1234
|
+
readonly "frustration.model-table-title": "Model breakdown detail";
|
|
1235
|
+
readonly "frustration.model-by-model-description": "Share of each model's analyzed turns carrying a breakdown signal. Hue = model family.";
|
|
1236
|
+
readonly "frustration.model-over-time": "AI breakdown over time";
|
|
1237
|
+
readonly "frustration.model-over-time-description": "Breakdown rate per bucket: turns with a signal over analyzed turns. Gaps are buckets with no turns.";
|
|
1238
|
+
readonly "frustration.model-sessions": "Sessions by breakdown";
|
|
1239
|
+
readonly "frustration.model-sessions-description": "Sessions with the most analyzed assistant turns.";
|
|
1240
|
+
readonly "frustration.model-table-description": "Rates are shares of analyzed assistant turns.";
|
|
1241
|
+
readonly "frustration.column-session": "Session";
|
|
1242
|
+
readonly "frustration.column-turns": "Turns";
|
|
1243
|
+
readonly "frustration.column-mean": "Signals/turn";
|
|
1244
|
+
readonly "frustration.column-tool-errors": "Tool errors";
|
|
1245
|
+
readonly "frustration.model-no-turns": "No assistant turns with text in this range";
|
|
1246
|
+
readonly "frustration.model-try-longer-range": "Try a longer range.";
|
|
1247
|
+
readonly "frustration.model-legend-breakdown": "Breakdown rate";
|
|
1248
|
+
readonly "frustration.turns-n": "{count} turns";
|
|
1249
|
+
readonly "frustration.model-hint-mean": "{value} signals per turn on average";
|
|
1178
1250
|
readonly "projects.title": "Projects";
|
|
1179
1251
|
readonly "projects.description": "Usage by session folder in {window}.";
|
|
1180
1252
|
readonly "projects.folders": "Folders";
|
|
@@ -97,6 +97,42 @@ export declare const frustration: {
|
|
|
97
97
|
readonly "frustration.cancelled": "Cancelled";
|
|
98
98
|
readonly "frustration.failed": "Failed";
|
|
99
99
|
readonly "frustration.done": "Done";
|
|
100
|
+
readonly "frustration.model-side-title": "AI breakdown";
|
|
101
|
+
readonly "frustration.model-side-description": "How the model's own replies read, per model version, in {window}.";
|
|
102
|
+
readonly "frustration.model-turns": "Assistant turns";
|
|
103
|
+
readonly "frustration.model-turns-title": "Assistant replies with text in range; tool-call-only replies and thinking blocks are not analyzed";
|
|
104
|
+
readonly "frustration.model-breakdown": "Breakdown rate";
|
|
105
|
+
readonly "frustration.model-breakdown-title": "Share of analyzed turns with at least one breakdown signal";
|
|
106
|
+
readonly "frustration.model-mean": "Signals / turn";
|
|
107
|
+
readonly "frustration.model-mean-title": "Average per-turn aggregate: text markers plus capped failed tool results";
|
|
108
|
+
readonly "frustration.model-self-blame": "Self-blame";
|
|
109
|
+
readonly "frustration.model-self-blame-title": "Turns containing an apology or admission";
|
|
110
|
+
readonly "frustration.model-restatement": "Restatement";
|
|
111
|
+
readonly "frustration.model-restatement-title": "Turns repeating earlier content, by explicit marker or near-duplicate reply";
|
|
112
|
+
readonly "frustration.model-hedge": "Hedged";
|
|
113
|
+
readonly "frustration.model-hedge-title": "Turns with hedged fallbacks: uncertainty or suggested alternatives";
|
|
114
|
+
readonly "frustration.model-spiral": "Tool spirals";
|
|
115
|
+
readonly "frustration.model-spiral-title": "Turns following three or more failed tool results";
|
|
116
|
+
readonly "frustration.model-rambling": "Rambling";
|
|
117
|
+
readonly "frustration.model-rambling-title": "Turns past the verbosity threshold";
|
|
118
|
+
readonly "frustration.model-unscored-line": "Turns in a language without a lexicon: {count} — unscored, not calm.";
|
|
119
|
+
readonly "frustration.model-by-model": "AI breakdown by model version";
|
|
120
|
+
readonly "frustration.model-table-title": "Model breakdown detail";
|
|
121
|
+
readonly "frustration.model-by-model-description": "Share of each model's analyzed turns carrying a breakdown signal. Hue = model family.";
|
|
122
|
+
readonly "frustration.model-over-time": "AI breakdown over time";
|
|
123
|
+
readonly "frustration.model-over-time-description": "Breakdown rate per bucket: turns with a signal over analyzed turns. Gaps are buckets with no turns.";
|
|
124
|
+
readonly "frustration.model-sessions": "Sessions by breakdown";
|
|
125
|
+
readonly "frustration.model-sessions-description": "Sessions with the most analyzed assistant turns.";
|
|
126
|
+
readonly "frustration.model-table-description": "Rates are shares of analyzed assistant turns.";
|
|
127
|
+
readonly "frustration.column-session": "Session";
|
|
128
|
+
readonly "frustration.column-turns": "Turns";
|
|
129
|
+
readonly "frustration.column-mean": "Signals/turn";
|
|
130
|
+
readonly "frustration.column-tool-errors": "Tool errors";
|
|
131
|
+
readonly "frustration.model-no-turns": "No assistant turns with text in this range";
|
|
132
|
+
readonly "frustration.model-try-longer-range": "Try a longer range.";
|
|
133
|
+
readonly "frustration.model-legend-breakdown": "Breakdown rate";
|
|
134
|
+
readonly "frustration.turns-n": "{count} turns";
|
|
135
|
+
readonly "frustration.model-hint-mean": "{value} signals per turn on average";
|
|
100
136
|
};
|
|
101
137
|
readonly "zh-CN": {
|
|
102
138
|
readonly "frustration.estimate-note": "内容相同的消息共用一份结论,且结论会被缓存,因此后续运行只为新消息付费。在你开始之前不会产生任何费用。";
|
|
@@ -187,5 +223,41 @@ export declare const frustration: {
|
|
|
187
223
|
readonly "frustration.cancelled": "已取消";
|
|
188
224
|
readonly "frustration.failed": "失败";
|
|
189
225
|
readonly "frustration.done": "完成";
|
|
226
|
+
readonly "frustration.model-side-title": "AI 崩溃度";
|
|
227
|
+
readonly "frustration.model-side-description": "各模型版本自身回复的读感,统计窗口:{window}。";
|
|
228
|
+
readonly "frustration.model-turns": "助手回合";
|
|
229
|
+
readonly "frustration.model-turns-title": "时间范围内带文本的助手回复;仅含工具调用的回复与思考块不参与分析";
|
|
230
|
+
readonly "frustration.model-breakdown": "崩溃率";
|
|
231
|
+
readonly "frustration.model-breakdown-title": "至少带一个崩溃信号的已分析回合占比";
|
|
232
|
+
readonly "frustration.model-mean": "信号 / 回合";
|
|
233
|
+
readonly "frustration.model-mean-title": "每回合聚合均值:文本标记加上封顶的工具失败数";
|
|
234
|
+
readonly "frustration.model-self-blame": "自责";
|
|
235
|
+
readonly "frustration.model-self-blame-title": "包含道歉或认错的回合";
|
|
236
|
+
readonly "frustration.model-restatement": "重复陈述";
|
|
237
|
+
readonly "frustration.model-restatement-title": "以显式标记或与上一条回复高度相似的方式重复先前内容的回合";
|
|
238
|
+
readonly "frustration.model-hedge": "含糊兜底";
|
|
239
|
+
readonly "frustration.model-hedge-title": "带有含糊兜底的回合:不确定表述或建议替代方案";
|
|
240
|
+
readonly "frustration.model-spiral": "工具失败螺旋";
|
|
241
|
+
readonly "frustration.model-spiral-title": "紧随三个及以上工具失败之后的回合";
|
|
242
|
+
readonly "frustration.model-rambling": "冗长";
|
|
243
|
+
readonly "frustration.model-rambling-title": "超过冗长阈值的回合";
|
|
244
|
+
readonly "frustration.model-unscored-line": "使用无词典语言的回合:{count} — 未评分,而非平静。";
|
|
245
|
+
readonly "frustration.model-by-model": "各模型版本的 AI 崩溃度";
|
|
246
|
+
readonly "frustration.model-table-title": "模型崩溃明细";
|
|
247
|
+
readonly "frustration.model-by-model-description": "每个模型已分析回合中带崩溃信号的占比。色相 = 模型家族。";
|
|
248
|
+
readonly "frustration.model-over-time": "AI 崩溃度随时间变化";
|
|
249
|
+
readonly "frustration.model-over-time-description": "每个时间桶的崩溃率:带信号的回合除以已分析回合。空白表示该桶没有回合。";
|
|
250
|
+
readonly "frustration.model-sessions": "按崩溃度查看会话";
|
|
251
|
+
readonly "frustration.model-sessions-description": "已分析助手回合最多的会话。";
|
|
252
|
+
readonly "frustration.model-table-description": "比例为已分析助手回合的占比。";
|
|
253
|
+
readonly "frustration.column-session": "会话";
|
|
254
|
+
readonly "frustration.column-turns": "回合数";
|
|
255
|
+
readonly "frustration.column-mean": "信号/回合";
|
|
256
|
+
readonly "frustration.column-tool-errors": "工具错误";
|
|
257
|
+
readonly "frustration.model-no-turns": "该时间范围内没有带文本的助手回合";
|
|
258
|
+
readonly "frustration.model-try-longer-range": "试试更长的时间范围。";
|
|
259
|
+
readonly "frustration.model-legend-breakdown": "崩溃率";
|
|
260
|
+
readonly "frustration.turns-n": "{count} 个回合";
|
|
261
|
+
readonly "frustration.model-hint-mean": "平均每回合 {value} 个信号";
|
|
190
262
|
};
|
|
191
263
|
};
|
|
@@ -9,5 +9,5 @@ export declare const zhCNMessages: Partial<Record<MessageKey, string>>;
|
|
|
9
9
|
/** The Simplified Chinese locale pack. */
|
|
10
10
|
export declare const zhCNLocale: {
|
|
11
11
|
readonly id: "zh-CN";
|
|
12
|
-
readonly messages: Partial<Record<"common.aborted" | "common.average" | "common.cache-read" | "common.cache-write" | "common.cancel" | "common.close" | "common.copied" | "common.copy" | "common.cost" | "common.duration" | "common.entry-id" | "common.error" | "common.error-rate" | "common.failed" | "common.filter" | "common.input" | "common.model" | "common.models" | "common.no-data-in-range" | "common.nothing-here-yet" | "common.other-n" | "common.output" | "common.output-message" | "common.output-tokens-per-second" | "common.pages" | "common.premium" | "common.premium-requests" | "common.project" | "common.provider" | "common.providers" | "common.range-1h" | "common.range-24h" | "common.range-30d" | "common.range-7d" | "common.range-90d" | "common.range-all" | "common.request" | "common.request-id" | "common.requests" | "common.root" | "common.session-entry" | "common.share" | "common.show-more" | "common.started" | "common.time-range" | "common.tokens" | "common.tokens-per-second" | "common.total" | "common.unknown" | "common.window-1h" | "common.window-24h" | "common.window-30d" | "common.window-7d" | "common.window-90d" | "common.window-all" | "costs.active-days-n" | "costs.active-days-one" | "costs.all-priced" | "costs.api-equivalent-estimate" | "costs.api-estimate-title" | "costs.average-per-day" | "costs.average-per-day-title" | "costs.by-component" | "costs.by-model" | "costs.by-model-description" | "costs.daily-by-component" | "costs.daily-by-model" | "costs.daily-estimate" | "costs.description" | "costs.empty-hint" | "costs.estimate" | "costs.estimate-by-component" | "costs.estimate-title" | "costs.no-priced-usage" | "costs.no-usage-in-range" | "costs.nothing-priced-yet" | "costs.per-priced-request" | "costs.per-priced-request-title" | "costs.per-request" | "costs.per-request-title" | "costs.priced-n" | "costs.requests-n" | "costs.split" | "costs.split-by" | "costs.split-title" | "costs.title" | "costs.top-model" | "costs.top-model-hint" | "costs.unpriced" | "costs.unpriced-column-title" | "costs.unpriced-hint" | "costs.unpriced-note-n" | "costs.unpriced-note-one" | "costs.unpriced-requests" | "costs.unpriced-title" | "costs.where-it-went" | "errors.affected-models" | "errors.by-model" | "errors.by-model-description" | "errors.cost-hint" | "errors.description" | "errors.empty-all-succeeded" | "errors.empty-no-affected-models" | "errors.empty-no-failures" | "errors.error-signatures" | "errors.failures" | "errors.filtered-of-total" | "errors.footer" | "errors.group-meta" | "errors.hint-in-window" | "errors.hint-latest-loaded" | "errors.last-failure" | "errors.last-seen" | "errors.load-latest" | "errors.loading" | "errors.loading-failures" | "errors.more-models" | "errors.no-match" | "errors.no-match-hint" | "errors.none-in-window" | "errors.open-latest" | "errors.search-placeholder" | "errors.signature" | "errors.signatures" | "errors.signatures-card-description" | "errors.signatures-hint" | "errors.signatures-top" | "errors.title" | "errors.unknown-error" | "errors.when" | "frustration.all-classes" | "frustration.all-judged" | "frustration.angry" | "frustration.angry-title" | "frustration.annoyed" | "frustration.annoyed-title" | "frustration.at-assistant" | "frustration.at-assistant-title" | "frustration.by-model" | "frustration.by-model-description" | "frustration.cancel-run" | "frustration.cancelled" | "frustration.cancelling" | "frustration.classify" | "frustration.column-judged" | "frustration.column-messages" | "frustration.column-model-ids" | "frustration.cost-so-far" | "frustration.coverage-hint" | "frustration.coverage-unscored" | "frustration.description" | "frustration.done" | "frustration.elapsed" | "frustration.estimate-note" | "frustration.estimated-cost" | "frustration.estimating" | "frustration.every-model-class" | "frustration.failed" | "frustration.failed-n" | "frustration.failed-suffix" | "frustration.hatch-title" | "frustration.hide-regex-title" | "frustration.in-flight" | "frustration.in-time" | "frustration.include-small" | "frustration.input-tokens" | "frustration.judge-coverage" | "frustration.judge-coverage-title" | "frustration.judge-description" | "frustration.judge-model" | "frustration.judge-panel" | "frustration.judge-running" | "frustration.judge-with" | "frustration.last-run-cancelled" | "frustration.last-run-done" | "frustration.last-run-failed" | "frustration.legend-angry" | "frustration.legend-annoyed-any" | "frustration.legend-assistant" | "frustration.legend-hatched" | "frustration.legend-hatched-run" | "frustration.legend-hue" | "frustration.legend-other" | "frustration.legend-trend" | "frustration.messages-n" | "frustration.messages-progress" | "frustration.model-class" | "frustration.model-versions" | "frustration.mostly-regex" | "frustration.no-messages" | "frustration.no-model-match" | "frustration.no-run-yet" | "frustration.not-run-yet" | "frustration.proceed" | "frustration.prose-chars" | "frustration.quote-title" | "frustration.regex-badge" | "frustration.regex-only" | "frustration.row-mostly-regex" | "frustration.run-cancelled-after" | "frustration.run-cancelled-line" | "frustration.run-done-line" | "frustration.run-failed-after" | "frustration.run-failed-line" | "frustration.run-judged" | "frustration.running" | "frustration.small-models-title" | "frustration.stack-relation" | "frustration.starting" | "frustration.table-description" | "frustration.title" | "frustration.try-longer-range" | "frustration.unclassified" | "frustration.unjudged-messages" | "frustration.unknown-error" | "frustration.unscored-line" | "frustration.user-messages" | "frustration.user-messages-title" | "gain.all-projects" | "gain.by-source" | "gain.by-source-description" | "gain.cumulative" | "gain.description" | "gain.description-scoped" | "gain.empty-hint-all" | "gain.empty-hint-longer-range" | "gain.empty-title" | "gain.empty-title-scoped" | "gain.hits" | "gain.reduction" | "gain.reduction-title" | "gain.reduction-unknown" | "gain.saved-bytes" | "gain.saved-per-day" | "gain.saved-per-hit" | "gain.saved-tokens" | "gain.savings-over-time" | "gain.savings-over-time-description" | "gain.source" | "gain.title" | "models.across-providers" | "models.across-providers-one" | "models.all-models" | "models.api-cost" | "models.api-cost-title" | "models.avg-duration" | "models.avg-ttft" | "models.bucket-5m" | "models.bucket-day" | "models.bucket-hour" | "models.cache-rate" | "models.cache-savings" | "models.cache-title" | "models.cost-title" | "models.count-desc" | "models.efficiency" | "models.empty-hint" | "models.empty-title" | "models.errors" | "models.failed-n" | "models.first-last-seen" | "models.latency" | "models.most-used" | "models.most-used-hint" | "models.no-samples-hint" | "models.no-samples-title" | "models.performance-per-bucket" | "models.request-share" | "models.share-desc" | "models.share-mode-aria" | "models.subtitle" | "models.table-desc" | "models.tok-per-second" | "models.tokens-title" | "models.tps-title" | "models.trend" | "models.trend-title" | "models.ttft" | "models.ttft-title" | "models.uncached-input" | "models.unpriced-n" | "models.used" | "nav.activity" | "nav.breadcrumb-stats" | "nav.costs" | "nav.dashboard" | "nav.errors" | "nav.frustration" | "nav.gain" | "nav.insights" | "nav.models" | "nav.open-navigation" | "nav.overview" | "nav.pages" | "nav.projects" | "nav.providers" | "nav.requests" | "nav.tools" | "nav.traces" | "nav.usage" | "overview.activity" | "overview.advisor" | "overview.all-requests" | "overview.api-cost-title" | "overview.api-equivalent" | "overview.api-equivalent-cost" | "overview.avg-latency" | "overview.avg-ttft" | "overview.by-agent" | "overview.cache-rate" | "overview.cache-rate-title" | "overview.cache-saved" | "overview.conversation-tokens" | "overview.description" | "overview.failed-n" | "overview.latest-requests" | "overview.latest-requests-description" | "overview.main-agent" | "overview.ok" | "overview.output-n" | "overview.per-5m" | "overview.per-day" | "overview.per-hour" | "overview.requests-short" | "overview.status" | "overview.subagents" | "overview.succeeded" | "overview.succeeded-n" | "overview.title" | "overview.token-mix" | "overview.token-mix-description" | "overview.tokens-title" | "overview.uncached-input" | "overview.unpriced-n" | "overview.when" | "projects.api-equivalent-cost" | "projects.api-equivalent-cost-hint" | "projects.api-equivalent-cost-rates" | "projects.avg-duration" | "projects.cache-rate" | "projects.cache-rate-hint" | "projects.cache-rate-hint-all" | "projects.cache-savings" | "projects.cache-savings-hint" | "projects.conversation-tokens" | "projects.conversation-tokens-hint" | "projects.description" | "projects.empty-no-folders" | "projects.empty-no-match" | "projects.empty-only-temporary" | "projects.errors" | "projects.failed-n" | "projects.filter-placeholder" | "projects.folder" | "projects.folders" | "projects.folders-n" | "projects.folders-of-n" | "projects.hide-temporary" | "projects.hide-temporary-hint" | "projects.hint-longer-range" | "projects.hint-temporary-hidden" | "projects.last-active" | "projects.share-of-cost" | "projects.share-of-requests" | "projects.temp" | "projects.temporary-n" | "projects.title" | "projects.top-by-cost" | "projects.top-by-cost-description" | "projects.top-by-requests" | "projects.top-by-requests-description" | "projects.unpriced-n" | "providers.account" | "providers.accounts" | "providers.accounts-needed" | "providers.accounts-needed-title" | "providers.accounts-title" | "providers.all-providers" | "providers.api-cost-title" | "providers.api-equivalent-cost" | "providers.bucket-5m" | "providers.bucket-day" | "providers.bucket-hour" | "providers.burn" | "providers.burn-description" | "providers.burn-estimate-description" | "providers.cost-title" | "providers.description" | "providers.exhausted" | "providers.exhausted-n" | "providers.exhaustions" | "providers.exhaustions-title" | "providers.failed-n" | "providers.high" | "providers.hours-description" | "providers.ideal-accounts" | "providers.latest-used" | "providers.models-title" | "providers.most-tokens" | "providers.no-activity-in-range" | "providers.no-provider-activity" | "providers.no-reading" | "providers.no-requests-in-range" | "providers.no-snapshots-in-range" | "providers.no-utilization-readings" | "providers.peak-burn-hours" | "providers.peak-hours-description" | "providers.peak-in-range" | "providers.peak-utilization" | "providers.peak-utilization-title" | "providers.premium-title" | "providers.recorded" | "providers.resets" | "providers.resets-title" | "providers.share-title" | "providers.snapshot-hint" | "providers.snapshots" | "providers.status" | "providers.subscription-windows" | "providers.subscription-windows-description" | "providers.succeeded-n" | "providers.tokens-peak-hour" | "providers.tokens-per-window" | "providers.tokens-per-window-title" | "providers.tokens-title" | "providers.too-little-consumed" | "providers.totals" | "providers.totals-description" | "providers.totals-description-unpriced-n" | "providers.totals-description-unpriced-one" | "providers.tps-title" | "providers.unpriced-n" | "providers.utilization" | "providers.utilization-description" | "providers.utilization-description-plain" | "providers.window" | "providers.windows-burned" | "providers.windows-burned-title" | "requests.api-equivalent-cost" | "requests.cache-read-title" | "requests.cache-write" | "requests.cost-estimate" | "requests.cost-hint" | "requests.description" | "requests.empty-in-window" | "requests.empty-no-match" | "requests.empty-no-match-hint" | "requests.failed-hint" | "requests.footer" | "requests.load-latest" | "requests.loading" | "requests.log-count-in-window" | "requests.log-count-latest" | "requests.log-loading" | "requests.log-title" | "requests.median-duration" | "requests.median-ttft" | "requests.none-in-window" | "requests.p95" | "requests.search-placeholder" | "requests.since" | "requests.status" | "requests.status-all" | "requests.tokens-hint" | "requests.ttft" | "requests.ttft-hint" | "requests.uncached-input" | "requests.unpriced-n" | "requests.when" | "shell.building-rollups" | "shell.dark-theme" | "shell.indexing" | "shell.ingesting" | "shell.jump-hint" | "shell.just-now" | "shell.light-theme" | "shell.live" | "shell.lost-connection" | "shell.range-suffix" | "shell.reconnecting" | "shell.sync-failed" | "shell.sync-now" | "shell.syncing" | "shell.system-theme" | "tools.all-tools" | "tools.api-equivalent" | "tools.args" | "tools.args-chars-title" | "tools.attr-cost" | "tools.attr-tokens" | "tools.attributed-cost" | "tools.attributed-tokens" | "tools.attribution-estimate" | "tools.attribution-note" | "tools.avg-args-per-call" | "tools.avg-result-per-call" | "tools.bucket-5m" | "tools.bucket-day" | "tools.bucket-hour" | "tools.by-tool" | "tools.by-tool-and-model" | "tools.by-tool-and-model-description" | "tools.by-tool-description" | "tools.call-arguments" | "tools.calls" | "tools.calls-over-time" | "tools.chars" | "tools.chart-description" | "tools.clear-tool-filter" | "tools.description" | "tools.distinct-tools" | "tools.error-rate-title" | "tools.errors" | "tools.errors-over-time" | "tools.errors-title" | "tools.failed-n" | "tools.filter-by-tool" | "tools.last-used" | "tools.most-used" | "tools.no-calls-to-tool" | "tools.no-tool-calls" | "tools.no-tool-errors" | "tools.result" | "tools.result-chars-title" | "tools.result-per-call" | "tools.result-per-call-title" | "tools.result-text" | "tools.share-of-calls" | "tools.share-of-cost" | "tools.share-of-tokens" | "tools.succeeded-n" | "tools.title" | "tools.tokens-output" | "tools.tool" | "tools.tool-calls" | "tools.trend" | "tools.trend-title" | "tools.unpriced-requests-n" | "trace.agent" | "trace.agents" | "trace.args" | "trace.avg" | "trace.axis-mode" | "trace.background" | "trace.bg" | "trace.calls" | "trace.canvas-aria" | "trace.collapse-all" | "trace.collapse-track" | "trace.compress-idle" | "trace.copy-json" | "trace.description" | "trace.empty-hint" | "trace.empty-title" | "trace.error-message" | "trace.errors" | "trace.expand-all" | "trace.expand-track" | "trace.failed-n" | "trace.filter-placeholder" | "trace.idle" | "trace.io-cached" | "trace.load-failed" | "trace.max" | "trace.minimap-aria" | "trace.mode-calls-title" | "trace.mode-time-title" | "trace.mode-turns-title" | "trace.model-time" | "trace.most-recent" | "trace.most-recent-filtered" | "trace.next-match" | "trace.no-matching-events" | "trace.no-matching-hint" | "trace.no-matching-title" | "trace.of-wall" | "trace.open-child-track" | "trace.previous-match" | "trace.raw-entry" | "trace.refresh" | "trace.search-placeholder" | "trace.session" | "trace.sessions" | "trace.start" | "trace.stop-reason" | "trace.task" | "trace.text" | "trace.thinking" | "trace.timeline" | "trace.timeline-hint" | "trace.title" | "trace.tok" | "trace.tool" | "trace.tool-aggregates" | "trace.tool-aggregates-desc" | "trace.tool-calls-n" | "trace.tool-time" | "trace.tools" | "trace.track" | "trace.transcript" | "trace.transcript-description" | "trace.ttft" | "trace.turns" | "trace.unterminated" | "trace.wall-time" | "ui.api" | "ui.delta-new" | "ui.json" | "ui.open-trace" | "ui.retry" | "ui.section-cost" | "ui.section-identity" | "ui.section-timing" | "ui.session-file" | "ui.show-fewer" | "ui.stats-row" | "ui.status-ok" | "ui.stop-reason" | "ui.table-shown-of" | "ui.time-to-first-token" | "ui.trace" | "ui.uncached-input", string>>;
|
|
12
|
+
readonly messages: Partial<Record<"common.aborted" | "common.average" | "common.cache-read" | "common.cache-write" | "common.cancel" | "common.close" | "common.copied" | "common.copy" | "common.cost" | "common.duration" | "common.entry-id" | "common.error" | "common.error-rate" | "common.failed" | "common.filter" | "common.input" | "common.model" | "common.models" | "common.no-data-in-range" | "common.nothing-here-yet" | "common.other-n" | "common.output" | "common.output-message" | "common.output-tokens-per-second" | "common.pages" | "common.premium" | "common.premium-requests" | "common.project" | "common.provider" | "common.providers" | "common.range-1h" | "common.range-24h" | "common.range-30d" | "common.range-7d" | "common.range-90d" | "common.range-all" | "common.request" | "common.request-id" | "common.requests" | "common.root" | "common.session-entry" | "common.share" | "common.show-more" | "common.started" | "common.time-range" | "common.tokens" | "common.tokens-per-second" | "common.total" | "common.unknown" | "common.window-1h" | "common.window-24h" | "common.window-30d" | "common.window-7d" | "common.window-90d" | "common.window-all" | "costs.active-days-n" | "costs.active-days-one" | "costs.all-priced" | "costs.api-equivalent-estimate" | "costs.api-estimate-title" | "costs.average-per-day" | "costs.average-per-day-title" | "costs.by-component" | "costs.by-model" | "costs.by-model-description" | "costs.daily-by-component" | "costs.daily-by-model" | "costs.daily-estimate" | "costs.description" | "costs.empty-hint" | "costs.estimate" | "costs.estimate-by-component" | "costs.estimate-title" | "costs.no-priced-usage" | "costs.no-usage-in-range" | "costs.nothing-priced-yet" | "costs.per-priced-request" | "costs.per-priced-request-title" | "costs.per-request" | "costs.per-request-title" | "costs.priced-n" | "costs.requests-n" | "costs.split" | "costs.split-by" | "costs.split-title" | "costs.title" | "costs.top-model" | "costs.top-model-hint" | "costs.unpriced" | "costs.unpriced-column-title" | "costs.unpriced-hint" | "costs.unpriced-note-n" | "costs.unpriced-note-one" | "costs.unpriced-requests" | "costs.unpriced-title" | "costs.where-it-went" | "errors.affected-models" | "errors.by-model" | "errors.by-model-description" | "errors.cost-hint" | "errors.description" | "errors.empty-all-succeeded" | "errors.empty-no-affected-models" | "errors.empty-no-failures" | "errors.error-signatures" | "errors.failures" | "errors.filtered-of-total" | "errors.footer" | "errors.group-meta" | "errors.hint-in-window" | "errors.hint-latest-loaded" | "errors.last-failure" | "errors.last-seen" | "errors.load-latest" | "errors.loading" | "errors.loading-failures" | "errors.more-models" | "errors.no-match" | "errors.no-match-hint" | "errors.none-in-window" | "errors.open-latest" | "errors.search-placeholder" | "errors.signature" | "errors.signatures" | "errors.signatures-card-description" | "errors.signatures-hint" | "errors.signatures-top" | "errors.title" | "errors.unknown-error" | "errors.when" | "frustration.all-classes" | "frustration.all-judged" | "frustration.angry" | "frustration.angry-title" | "frustration.annoyed" | "frustration.annoyed-title" | "frustration.at-assistant" | "frustration.at-assistant-title" | "frustration.by-model" | "frustration.by-model-description" | "frustration.cancel-run" | "frustration.cancelled" | "frustration.cancelling" | "frustration.classify" | "frustration.column-judged" | "frustration.column-mean" | "frustration.column-messages" | "frustration.column-model-ids" | "frustration.column-session" | "frustration.column-tool-errors" | "frustration.column-turns" | "frustration.cost-so-far" | "frustration.coverage-hint" | "frustration.coverage-unscored" | "frustration.description" | "frustration.done" | "frustration.elapsed" | "frustration.estimate-note" | "frustration.estimated-cost" | "frustration.estimating" | "frustration.every-model-class" | "frustration.failed" | "frustration.failed-n" | "frustration.failed-suffix" | "frustration.hatch-title" | "frustration.hide-regex-title" | "frustration.in-flight" | "frustration.in-time" | "frustration.include-small" | "frustration.input-tokens" | "frustration.judge-coverage" | "frustration.judge-coverage-title" | "frustration.judge-description" | "frustration.judge-model" | "frustration.judge-panel" | "frustration.judge-running" | "frustration.judge-with" | "frustration.last-run-cancelled" | "frustration.last-run-done" | "frustration.last-run-failed" | "frustration.legend-angry" | "frustration.legend-annoyed-any" | "frustration.legend-assistant" | "frustration.legend-hatched" | "frustration.legend-hatched-run" | "frustration.legend-hue" | "frustration.legend-other" | "frustration.legend-trend" | "frustration.messages-n" | "frustration.messages-progress" | "frustration.model-breakdown" | "frustration.model-breakdown-title" | "frustration.model-by-model" | "frustration.model-by-model-description" | "frustration.model-class" | "frustration.model-hedge" | "frustration.model-hedge-title" | "frustration.model-hint-mean" | "frustration.model-legend-breakdown" | "frustration.model-mean" | "frustration.model-mean-title" | "frustration.model-no-turns" | "frustration.model-over-time" | "frustration.model-over-time-description" | "frustration.model-rambling" | "frustration.model-rambling-title" | "frustration.model-restatement" | "frustration.model-restatement-title" | "frustration.model-self-blame" | "frustration.model-self-blame-title" | "frustration.model-sessions" | "frustration.model-sessions-description" | "frustration.model-side-description" | "frustration.model-side-title" | "frustration.model-spiral" | "frustration.model-spiral-title" | "frustration.model-table-description" | "frustration.model-table-title" | "frustration.model-try-longer-range" | "frustration.model-turns" | "frustration.model-turns-title" | "frustration.model-unscored-line" | "frustration.model-versions" | "frustration.mostly-regex" | "frustration.no-messages" | "frustration.no-model-match" | "frustration.no-run-yet" | "frustration.not-run-yet" | "frustration.proceed" | "frustration.prose-chars" | "frustration.quote-title" | "frustration.regex-badge" | "frustration.regex-only" | "frustration.row-mostly-regex" | "frustration.run-cancelled-after" | "frustration.run-cancelled-line" | "frustration.run-done-line" | "frustration.run-failed-after" | "frustration.run-failed-line" | "frustration.run-judged" | "frustration.running" | "frustration.small-models-title" | "frustration.stack-relation" | "frustration.starting" | "frustration.table-description" | "frustration.title" | "frustration.try-longer-range" | "frustration.turns-n" | "frustration.unclassified" | "frustration.unjudged-messages" | "frustration.unknown-error" | "frustration.unscored-line" | "frustration.user-messages" | "frustration.user-messages-title" | "gain.all-projects" | "gain.by-source" | "gain.by-source-description" | "gain.cumulative" | "gain.description" | "gain.description-scoped" | "gain.empty-hint-all" | "gain.empty-hint-longer-range" | "gain.empty-title" | "gain.empty-title-scoped" | "gain.hits" | "gain.reduction" | "gain.reduction-title" | "gain.reduction-unknown" | "gain.saved-bytes" | "gain.saved-per-day" | "gain.saved-per-hit" | "gain.saved-tokens" | "gain.savings-over-time" | "gain.savings-over-time-description" | "gain.source" | "gain.title" | "models.across-providers" | "models.across-providers-one" | "models.all-models" | "models.api-cost" | "models.api-cost-title" | "models.avg-duration" | "models.avg-ttft" | "models.bucket-5m" | "models.bucket-day" | "models.bucket-hour" | "models.cache-rate" | "models.cache-savings" | "models.cache-title" | "models.cost-title" | "models.count-desc" | "models.efficiency" | "models.empty-hint" | "models.empty-title" | "models.errors" | "models.failed-n" | "models.first-last-seen" | "models.latency" | "models.most-used" | "models.most-used-hint" | "models.no-samples-hint" | "models.no-samples-title" | "models.performance-per-bucket" | "models.request-share" | "models.share-desc" | "models.share-mode-aria" | "models.subtitle" | "models.table-desc" | "models.tok-per-second" | "models.tokens-title" | "models.tps-title" | "models.trend" | "models.trend-title" | "models.ttft" | "models.ttft-title" | "models.uncached-input" | "models.unpriced-n" | "models.used" | "nav.activity" | "nav.breadcrumb-stats" | "nav.costs" | "nav.dashboard" | "nav.errors" | "nav.frustration" | "nav.gain" | "nav.insights" | "nav.models" | "nav.open-navigation" | "nav.overview" | "nav.pages" | "nav.projects" | "nav.providers" | "nav.requests" | "nav.tools" | "nav.traces" | "nav.usage" | "overview.activity" | "overview.advisor" | "overview.all-requests" | "overview.api-cost-title" | "overview.api-equivalent" | "overview.api-equivalent-cost" | "overview.avg-latency" | "overview.avg-ttft" | "overview.by-agent" | "overview.cache-rate" | "overview.cache-rate-title" | "overview.cache-saved" | "overview.conversation-tokens" | "overview.description" | "overview.failed-n" | "overview.latest-requests" | "overview.latest-requests-description" | "overview.main-agent" | "overview.ok" | "overview.output-n" | "overview.per-5m" | "overview.per-day" | "overview.per-hour" | "overview.requests-short" | "overview.status" | "overview.subagents" | "overview.succeeded" | "overview.succeeded-n" | "overview.title" | "overview.token-mix" | "overview.token-mix-description" | "overview.tokens-title" | "overview.uncached-input" | "overview.unpriced-n" | "overview.when" | "projects.api-equivalent-cost" | "projects.api-equivalent-cost-hint" | "projects.api-equivalent-cost-rates" | "projects.avg-duration" | "projects.cache-rate" | "projects.cache-rate-hint" | "projects.cache-rate-hint-all" | "projects.cache-savings" | "projects.cache-savings-hint" | "projects.conversation-tokens" | "projects.conversation-tokens-hint" | "projects.description" | "projects.empty-no-folders" | "projects.empty-no-match" | "projects.empty-only-temporary" | "projects.errors" | "projects.failed-n" | "projects.filter-placeholder" | "projects.folder" | "projects.folders" | "projects.folders-n" | "projects.folders-of-n" | "projects.hide-temporary" | "projects.hide-temporary-hint" | "projects.hint-longer-range" | "projects.hint-temporary-hidden" | "projects.last-active" | "projects.share-of-cost" | "projects.share-of-requests" | "projects.temp" | "projects.temporary-n" | "projects.title" | "projects.top-by-cost" | "projects.top-by-cost-description" | "projects.top-by-requests" | "projects.top-by-requests-description" | "projects.unpriced-n" | "providers.account" | "providers.accounts" | "providers.accounts-needed" | "providers.accounts-needed-title" | "providers.accounts-title" | "providers.all-providers" | "providers.api-cost-title" | "providers.api-equivalent-cost" | "providers.bucket-5m" | "providers.bucket-day" | "providers.bucket-hour" | "providers.burn" | "providers.burn-description" | "providers.burn-estimate-description" | "providers.cost-title" | "providers.description" | "providers.exhausted" | "providers.exhausted-n" | "providers.exhaustions" | "providers.exhaustions-title" | "providers.failed-n" | "providers.high" | "providers.hours-description" | "providers.ideal-accounts" | "providers.latest-used" | "providers.models-title" | "providers.most-tokens" | "providers.no-activity-in-range" | "providers.no-provider-activity" | "providers.no-reading" | "providers.no-requests-in-range" | "providers.no-snapshots-in-range" | "providers.no-utilization-readings" | "providers.peak-burn-hours" | "providers.peak-hours-description" | "providers.peak-in-range" | "providers.peak-utilization" | "providers.peak-utilization-title" | "providers.premium-title" | "providers.recorded" | "providers.resets" | "providers.resets-title" | "providers.share-title" | "providers.snapshot-hint" | "providers.snapshots" | "providers.status" | "providers.subscription-windows" | "providers.subscription-windows-description" | "providers.succeeded-n" | "providers.tokens-peak-hour" | "providers.tokens-per-window" | "providers.tokens-per-window-title" | "providers.tokens-title" | "providers.too-little-consumed" | "providers.totals" | "providers.totals-description" | "providers.totals-description-unpriced-n" | "providers.totals-description-unpriced-one" | "providers.tps-title" | "providers.unpriced-n" | "providers.utilization" | "providers.utilization-description" | "providers.utilization-description-plain" | "providers.window" | "providers.windows-burned" | "providers.windows-burned-title" | "requests.api-equivalent-cost" | "requests.cache-read-title" | "requests.cache-write" | "requests.cost-estimate" | "requests.cost-hint" | "requests.description" | "requests.empty-in-window" | "requests.empty-no-match" | "requests.empty-no-match-hint" | "requests.failed-hint" | "requests.footer" | "requests.load-latest" | "requests.loading" | "requests.log-count-in-window" | "requests.log-count-latest" | "requests.log-loading" | "requests.log-title" | "requests.median-duration" | "requests.median-ttft" | "requests.none-in-window" | "requests.p95" | "requests.search-placeholder" | "requests.since" | "requests.status" | "requests.status-all" | "requests.tokens-hint" | "requests.ttft" | "requests.ttft-hint" | "requests.uncached-input" | "requests.unpriced-n" | "requests.when" | "shell.building-rollups" | "shell.dark-theme" | "shell.indexing" | "shell.ingesting" | "shell.jump-hint" | "shell.just-now" | "shell.light-theme" | "shell.live" | "shell.lost-connection" | "shell.range-suffix" | "shell.reconnecting" | "shell.sync-failed" | "shell.sync-now" | "shell.syncing" | "shell.system-theme" | "tools.all-tools" | "tools.api-equivalent" | "tools.args" | "tools.args-chars-title" | "tools.attr-cost" | "tools.attr-tokens" | "tools.attributed-cost" | "tools.attributed-tokens" | "tools.attribution-estimate" | "tools.attribution-note" | "tools.avg-args-per-call" | "tools.avg-result-per-call" | "tools.bucket-5m" | "tools.bucket-day" | "tools.bucket-hour" | "tools.by-tool" | "tools.by-tool-and-model" | "tools.by-tool-and-model-description" | "tools.by-tool-description" | "tools.call-arguments" | "tools.calls" | "tools.calls-over-time" | "tools.chars" | "tools.chart-description" | "tools.clear-tool-filter" | "tools.description" | "tools.distinct-tools" | "tools.error-rate-title" | "tools.errors" | "tools.errors-over-time" | "tools.errors-title" | "tools.failed-n" | "tools.filter-by-tool" | "tools.last-used" | "tools.most-used" | "tools.no-calls-to-tool" | "tools.no-tool-calls" | "tools.no-tool-errors" | "tools.result" | "tools.result-chars-title" | "tools.result-per-call" | "tools.result-per-call-title" | "tools.result-text" | "tools.share-of-calls" | "tools.share-of-cost" | "tools.share-of-tokens" | "tools.succeeded-n" | "tools.title" | "tools.tokens-output" | "tools.tool" | "tools.tool-calls" | "tools.trend" | "tools.trend-title" | "tools.unpriced-requests-n" | "trace.agent" | "trace.agents" | "trace.args" | "trace.avg" | "trace.axis-mode" | "trace.background" | "trace.bg" | "trace.calls" | "trace.canvas-aria" | "trace.collapse-all" | "trace.collapse-track" | "trace.compress-idle" | "trace.copy-json" | "trace.description" | "trace.empty-hint" | "trace.empty-title" | "trace.error-message" | "trace.errors" | "trace.expand-all" | "trace.expand-track" | "trace.failed-n" | "trace.filter-placeholder" | "trace.idle" | "trace.io-cached" | "trace.load-failed" | "trace.max" | "trace.minimap-aria" | "trace.mode-calls-title" | "trace.mode-time-title" | "trace.mode-turns-title" | "trace.model-time" | "trace.most-recent" | "trace.most-recent-filtered" | "trace.next-match" | "trace.no-matching-events" | "trace.no-matching-hint" | "trace.no-matching-title" | "trace.of-wall" | "trace.open-child-track" | "trace.previous-match" | "trace.raw-entry" | "trace.refresh" | "trace.search-placeholder" | "trace.session" | "trace.sessions" | "trace.start" | "trace.stop-reason" | "trace.task" | "trace.text" | "trace.thinking" | "trace.timeline" | "trace.timeline-hint" | "trace.title" | "trace.tok" | "trace.tool" | "trace.tool-aggregates" | "trace.tool-aggregates-desc" | "trace.tool-calls-n" | "trace.tool-time" | "trace.tools" | "trace.track" | "trace.transcript" | "trace.transcript-description" | "trace.ttft" | "trace.turns" | "trace.unterminated" | "trace.wall-time" | "ui.api" | "ui.delta-new" | "ui.json" | "ui.open-trace" | "ui.retry" | "ui.section-cost" | "ui.section-identity" | "ui.section-timing" | "ui.session-file" | "ui.show-fewer" | "ui.stats-row" | "ui.status-ok" | "ui.stop-reason" | "ui.table-shown-of" | "ui.time-to-first-token" | "ui.trace" | "ui.uncached-input", string>>;
|
|
13
13
|
};
|
package/dist/types/db.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import { Database } from "bun:sqlite";
|
|
2
2
|
import { type ParseSessionResult, type SessionParserState } from "./parser.js";
|
|
3
|
-
import type { DailyActivityPoint, FrustrationCounts, MessageStats, MessageStatsInput, ToolCallStats, ToolResultLink, UserMessageLink, UserMessageStats } from "./types.js";
|
|
3
|
+
import type { AssistantTextStats, DailyActivityPoint, FrustrationCounts, MessageStats, MessageStatsInput, ModelSideCounts, ModelSideTimeSeriesPoint, ToolCallStats, ToolResultLink, UserMessageLink, UserMessageStats } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Predicate counting one stored request as "unpriced" — the public rate card
|
|
6
6
|
* has no charge for it, so its zero is unknown spend rather than free usage.
|
|
@@ -116,6 +116,13 @@ export declare function markSessionBackfillsComplete(): void;
|
|
|
116
116
|
* `(entry_id, timestamp)` must not land twice across different session files.
|
|
117
117
|
*/
|
|
118
118
|
export declare function insertUserMessageStats(stats: Iterable<UserMessageStats>): number;
|
|
119
|
+
/**
|
|
120
|
+
* Insert model-side assistant turns. Idempotent via UNIQUE(session_file,
|
|
121
|
+
* entry_id); the `WHERE NOT EXISTS` guard mirrors {@link insertUserMessageStats}
|
|
122
|
+
* because a fork deep-copies assistant entries into the child transcript under
|
|
123
|
+
* the same entry id and timestamp.
|
|
124
|
+
*/
|
|
125
|
+
export declare function insertAssistantText(stats: Iterable<AssistantTextStats>): number;
|
|
119
126
|
/**
|
|
120
127
|
* Backfill the responding `model`/`provider` on user-message rows that were
|
|
121
128
|
* persisted before their assistant reply was parsed by an incremental tail
|
|
@@ -157,6 +164,32 @@ export declare function getFrustrationOverall(cutoff?: number | null): Frustrati
|
|
|
157
164
|
* messages that never got a reply (null model) are only in the overall tally.
|
|
158
165
|
*/
|
|
159
166
|
export declare function getFrustrationByModel(cutoff?: number | null): FrustrationModelRow[];
|
|
167
|
+
/** Model-side tallies of one responding (model, provider) pair, before identity merging. */
|
|
168
|
+
export interface ModelSideModelRow extends ModelSideCounts {
|
|
169
|
+
model: string;
|
|
170
|
+
provider: string;
|
|
171
|
+
/** Earliest analyzed turn timestamp (ms) in range. */
|
|
172
|
+
firstSeen: number;
|
|
173
|
+
}
|
|
174
|
+
/** Model-side tallies of one session, before the dashboard's top-N cut. */
|
|
175
|
+
export interface ModelSideSessionRow extends ModelSideCounts {
|
|
176
|
+
sessionFile: string;
|
|
177
|
+
folder: string;
|
|
178
|
+
models: string[];
|
|
179
|
+
firstSeen: number;
|
|
180
|
+
lastSeen: number;
|
|
181
|
+
}
|
|
182
|
+
/** Model-side tallies over every analyzed assistant turn in range. */
|
|
183
|
+
export declare function getModelSideOverall(cutoff?: number | null): ModelSideCounts;
|
|
184
|
+
/** Model-side tallies per responding (model, provider) over the range. */
|
|
185
|
+
export declare function getModelSideByModel(cutoff?: number | null): ModelSideModelRow[];
|
|
186
|
+
/** Model-side tallies per session, busiest first. */
|
|
187
|
+
export declare function getModelSideBySession(cutoff?: number | null, limit?: number): ModelSideSessionRow[];
|
|
188
|
+
/** Model-side tallies per time bucket, ascending. */
|
|
189
|
+
export declare function getModelSideTimeSeries({ cutoff, bucketMs, }: {
|
|
190
|
+
cutoff?: number | null;
|
|
191
|
+
bucketMs: number;
|
|
192
|
+
}): ModelSideTimeSeriesPoint[];
|
|
160
193
|
/** Unique prose texts in range that have no cached verdict yet. */
|
|
161
194
|
export declare function getPendingFrustrationProse(cutoff?: number | null): PendingProse[];
|
|
162
195
|
/** Count and total characters of {@link getPendingFrustrationProse} without loading the text. */
|
|
@@ -0,0 +1,29 @@
|
|
|
1
|
+
export interface ModelIdentity {
|
|
2
|
+
/** Stable key: `class/family/revision` when classified, else the raw model id. */
|
|
3
|
+
key: string;
|
|
4
|
+
/** Display label, e.g. `opus 4.5`; the raw model id when unclassified. */
|
|
5
|
+
label: string;
|
|
6
|
+
/** Catalog identity class, e.g. `anthropic`; `unknown` when unclassified. */
|
|
7
|
+
modelClass: string;
|
|
8
|
+
/** Catalog family within the class, e.g. `opus`. */
|
|
9
|
+
family: string | null;
|
|
10
|
+
/** Canonical `major.minor.patch`, e.g. `4.5.0`; null when unclassified. */
|
|
11
|
+
revision: string | null;
|
|
12
|
+
}
|
|
13
|
+
/** Resolve the display identity of one persisted (provider, model) pair. */
|
|
14
|
+
export declare function modelIdentityOf(provider: string | null, model: string): ModelIdentity;
|
|
15
|
+
/**
|
|
16
|
+
* Sort order shared by every model table: classified rows by class, then
|
|
17
|
+
* revision ascending, then family; unclassified rows follow by first use.
|
|
18
|
+
*/
|
|
19
|
+
export declare function compareModelIdentity(a: {
|
|
20
|
+
modelClass: string;
|
|
21
|
+
family: string | null;
|
|
22
|
+
revision: string | null;
|
|
23
|
+
firstSeen: number;
|
|
24
|
+
}, b: {
|
|
25
|
+
modelClass: string;
|
|
26
|
+
family: string | null;
|
|
27
|
+
revision: string | null;
|
|
28
|
+
firstSeen: number;
|
|
29
|
+
}): number;
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
export interface AssistantMessageMetrics {
|
|
2
|
+
/** Characters of analyzed prose (code and markup stripped, capped). */
|
|
3
|
+
chars: number;
|
|
4
|
+
/** Whitespace-delimited words of analyzed prose. */
|
|
5
|
+
words: number;
|
|
6
|
+
/** Apology / self-blame markers. */
|
|
7
|
+
selfBlame: number;
|
|
8
|
+
/** Repeated-restatement markers plus near-duplicate previous turn. */
|
|
9
|
+
restatement: number;
|
|
10
|
+
/** Hedged fallback markers. */
|
|
11
|
+
hedge: number;
|
|
12
|
+
/** 1 when the turn is long-winded (see {@link VERBOSE_WORD_THRESHOLD}). */
|
|
13
|
+
verbose: number;
|
|
14
|
+
/** Failed tool results preceding this turn, as counted at ingest. */
|
|
15
|
+
toolErrors: number;
|
|
16
|
+
/** 1 when {@link toolErrors} reaches {@link TOOL_SPIRAL_THRESHOLD}. */
|
|
17
|
+
toolSpiral: number;
|
|
18
|
+
/** Per-turn aggregate (see the module docs). */
|
|
19
|
+
collapse: number;
|
|
20
|
+
/** 1 when the prose leans on a script no lexicon covers; such rows are unscored, not calm. */
|
|
21
|
+
unsupportedScript: number;
|
|
22
|
+
}
|
|
23
|
+
/**
|
|
24
|
+
* Words past which a reply counts as long-winded. Coding-agent answers usually
|
|
25
|
+
* land well under this; a 400-word turn is the point where the model is
|
|
26
|
+
* explaining at the user instead of answering.
|
|
27
|
+
*/
|
|
28
|
+
export declare const VERBOSE_WORD_THRESHOLD = 400;
|
|
29
|
+
/**
|
|
30
|
+
* Character floor for the same signal. Chinese prose has no spaces, so
|
|
31
|
+
* `WORD_RE` sees one "word" per line; roughly 1.5 characters per word makes
|
|
32
|
+
* this the equivalent of {@link VERBOSE_WORD_THRESHOLD}.
|
|
33
|
+
*/
|
|
34
|
+
export declare const VERBOSE_CHAR_THRESHOLD = 2400;
|
|
35
|
+
/** Consecutive failed tool results that make a turn part of a failure spiral. */
|
|
36
|
+
export declare const TOOL_SPIRAL_THRESHOLD = 3;
|
|
37
|
+
/** Failed tool results beyond this many add no further weight to `collapse`. */
|
|
38
|
+
export declare const TOOL_ERROR_COLLAPSE_CAP = 10;
|
|
39
|
+
/** Empty metrics constant for callers that need a default. */
|
|
40
|
+
export declare const EMPTY_ASSISTANT_METRICS: AssistantMessageMetrics;
|
|
41
|
+
/**
|
|
42
|
+
* Compute behavioral metrics for one assistant turn.
|
|
43
|
+
*
|
|
44
|
+
* `text` is the turn's analysis prose (see {@link analysisProse}) — the parser
|
|
45
|
+
* strips thinking blocks and structured content before calling this. Empty or
|
|
46
|
+
* whitespace-only input returns zeros.
|
|
47
|
+
*/
|
|
48
|
+
export declare function computeAssistantMessageMetrics(text: string, options?: {
|
|
49
|
+
/** The previous prose-bearing assistant turn in the same session, for restatement. */
|
|
50
|
+
prevText?: string;
|
|
51
|
+
/** Failed tool results since the previous assistant turn. */
|
|
52
|
+
toolErrors?: number;
|
|
53
|
+
}): AssistantMessageMetrics;
|
|
@@ -0,0 +1,6 @@
|
|
|
1
|
+
import { type ModelSideModelRow } from "./db.js";
|
|
2
|
+
import type { ModelSideDashboardStats, ModelSideModelStats } from "./shared-types.js";
|
|
3
|
+
/** Merge per-(model, provider) rows into catalog identities, same grouping as the user side. */
|
|
4
|
+
export declare function mergeModelSideRows(rows: readonly ModelSideModelRow[]): ModelSideModelStats[];
|
|
5
|
+
/** Model-side section of `GET /api/stats/frustration`. */
|
|
6
|
+
export declare function getModelSideDashboardStats(range?: string | null): Promise<ModelSideDashboardStats>;
|
package/dist/types/parser.d.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type * as nodeFs from "node:fs";
|
|
2
2
|
import { type ServiceTierByFamily } from "@linxiraos/pi-ai";
|
|
3
|
-
import type { AgentType, MessageStatsInput, SessionEntry, ToolCallStats, ToolResultLink, UserMessageLink, UserMessageStats } from "./types.js";
|
|
3
|
+
import type { AgentType, AssistantTextStats, MessageStatsInput, SessionEntry, ToolCallStats, ToolResultLink, UserMessageLink, UserMessageStats } from "./types.js";
|
|
4
4
|
/**
|
|
5
5
|
* Classify which agent produced a transcript from its path within the sessions
|
|
6
6
|
* directory. Layout: `<sessionsDir>/<project>/<file>.jsonl` is the `main`
|
|
@@ -60,6 +60,7 @@ export interface SessionParserState {
|
|
|
60
60
|
export interface ParseSessionResult {
|
|
61
61
|
stats: MessageStatsInput[];
|
|
62
62
|
userStats: UserMessageStats[];
|
|
63
|
+
assistantTexts: AssistantTextStats[];
|
|
63
64
|
userLinks: UserMessageLink[];
|
|
64
65
|
toolCalls: ToolCallStats[];
|
|
65
66
|
toolResults: ToolResultLink[];
|
|
@@ -181,6 +181,92 @@ export interface AgentTypeStats {
|
|
|
181
181
|
/** Total cost */
|
|
182
182
|
totalCost: number;
|
|
183
183
|
}
|
|
184
|
+
/**
|
|
185
|
+
* Model-side tallies over assistant turns. Every field except `messages`,
|
|
186
|
+
* `collapse`, `words` and `toolErrors` counts turns carrying the signal, so
|
|
187
|
+
* `blamed / messages` is a share. `collapse` and `words` are sums: their means
|
|
188
|
+
* are `collapse / messages` and `words / messages`.
|
|
189
|
+
*
|
|
190
|
+
* Coverage is textual: only turns that produced prose are analyzed, so
|
|
191
|
+
* tool-call-only replies and thinking blocks are outside the denominator.
|
|
192
|
+
* `unscored` counts turns whose prose leans on a script no lexicon covers -
|
|
193
|
+
* their zero signal counts mean "unscored", not "calm".
|
|
194
|
+
*/
|
|
195
|
+
export interface ModelSideCounts {
|
|
196
|
+
/** Assistant turns with stored prose. */
|
|
197
|
+
messages: number;
|
|
198
|
+
/** Turns with an apology or admission. */
|
|
199
|
+
blamed: number;
|
|
200
|
+
/** Turns restating earlier content. */
|
|
201
|
+
restated: number;
|
|
202
|
+
/** Turns with a hedged fallback. */
|
|
203
|
+
hedged: number;
|
|
204
|
+
/** Turns past the verbosity threshold. */
|
|
205
|
+
verbose: number;
|
|
206
|
+
/** Turns following a tool-failure spiral. */
|
|
207
|
+
spiraled: number;
|
|
208
|
+
/** Turns with a non-zero per-turn aggregate. */
|
|
209
|
+
breakdown: number;
|
|
210
|
+
/** Sum of per-turn aggregate values. */
|
|
211
|
+
collapse: number;
|
|
212
|
+
/** Sum of analyzed words. */
|
|
213
|
+
words: number;
|
|
214
|
+
/** Sum of failed tool results preceding the turns. */
|
|
215
|
+
toolErrors: number;
|
|
216
|
+
/** Turns in a script no lexicon covers. */
|
|
217
|
+
unscored: number;
|
|
218
|
+
}
|
|
219
|
+
/** Model-side tallies for one model version, merged by catalog identity. */
|
|
220
|
+
export interface ModelSideModelStats extends ModelSideCounts {
|
|
221
|
+
/** Stable key: `class/family/revision` when classified, else the raw model id. */
|
|
222
|
+
key: string;
|
|
223
|
+
/** Display label, e.g. `opus 4.5`; the raw model id when unclassified. */
|
|
224
|
+
label: string;
|
|
225
|
+
/** Catalog identity class, e.g. `anthropic`; `unknown` when unclassified. */
|
|
226
|
+
modelClass: string;
|
|
227
|
+
/** Catalog family within the class, e.g. `opus`. */
|
|
228
|
+
family: string | null;
|
|
229
|
+
/** Canonical `major.minor.patch`, e.g. `4.5.0`. */
|
|
230
|
+
revision: string | null;
|
|
231
|
+
/** Raw model ids merged into this row. */
|
|
232
|
+
models: string[];
|
|
233
|
+
/** Earliest turn timestamp (ms) in range. */
|
|
234
|
+
firstSeen: number;
|
|
235
|
+
}
|
|
236
|
+
/** One bucket of the model-side time series. */
|
|
237
|
+
export interface ModelSideTimeSeriesPoint {
|
|
238
|
+
/** Bucket start (Unix ms). */
|
|
239
|
+
timestamp: number;
|
|
240
|
+
messages: number;
|
|
241
|
+
breakdown: number;
|
|
242
|
+
blamed: number;
|
|
243
|
+
restated: number;
|
|
244
|
+
hedged: number;
|
|
245
|
+
spiraled: number;
|
|
246
|
+
collapse: number;
|
|
247
|
+
}
|
|
248
|
+
/** Model-side tallies for one session, busiest first in the dashboard payload. */
|
|
249
|
+
export interface ModelSideSessionStats extends ModelSideCounts {
|
|
250
|
+
/** Absolute transcript path. */
|
|
251
|
+
sessionFile: string;
|
|
252
|
+
/** Project folder the transcript belongs to. */
|
|
253
|
+
folder: string;
|
|
254
|
+
/** Distinct model ids in the session. */
|
|
255
|
+
models: string[];
|
|
256
|
+
/** Earliest and latest analyzed turn (ms). */
|
|
257
|
+
firstSeen: number;
|
|
258
|
+
lastSeen: number;
|
|
259
|
+
}
|
|
260
|
+
/** Payload of the model-side section of `GET /api/stats/frustration`. */
|
|
261
|
+
export interface ModelSideDashboardStats {
|
|
262
|
+
overall: ModelSideCounts;
|
|
263
|
+
/** Every model with analyzed turns in range. */
|
|
264
|
+
byModel: ModelSideModelStats[];
|
|
265
|
+
/** Bucketed trend over the active range. */
|
|
266
|
+
series: ModelSideTimeSeriesPoint[];
|
|
267
|
+
/** Sessions with the most analyzed turns, capped for payload size. */
|
|
268
|
+
bySession: ModelSideSessionStats[];
|
|
269
|
+
}
|
|
184
270
|
/**
|
|
185
271
|
* Frustration tallies over a set of user messages. Each message counts once,
|
|
186
272
|
* classified by its cached judge verdict when one exists, else by the regex
|
|
@@ -253,6 +339,8 @@ export interface FrustrationDashboardStats {
|
|
|
253
339
|
overall: FrustrationCounts;
|
|
254
340
|
/** Every model with messages in range, ordered by class, then revision, then family. */
|
|
255
341
|
byModel: FrustrationModelStats[];
|
|
342
|
+
/** Model-side (AI breakdown) analysis alongside the user-side tallies. */
|
|
343
|
+
modelSide: ModelSideDashboardStats;
|
|
256
344
|
/** Whether this dashboard host can run the judge (standalone `omp-stats` cannot). */
|
|
257
345
|
judgeAvailable: boolean;
|
|
258
346
|
job: FrustrationJobStatus;
|
package/dist/types/types.d.ts
CHANGED
|
@@ -174,11 +174,57 @@ export interface UserMessageStats {
|
|
|
174
174
|
emphasis: number;
|
|
175
175
|
/** 1 when the prose leans on a script no lexicon covers; such rows are unscored, not calm. */
|
|
176
176
|
unsupportedScript: number;
|
|
177
|
-
/** Judge-facing prose (see `
|
|
177
|
+
/** Judge-facing prose (see `analysisProse`); empty when the message was all markup. */
|
|
178
178
|
prose: string;
|
|
179
179
|
/** Hex `Bun.hash` of `prose`, keying the shared verdict cache; empty when `prose` is. */
|
|
180
180
|
proseHash: string;
|
|
181
181
|
}
|
|
182
|
+
/**
|
|
183
|
+
* Model-side analysis for one assistant turn: the text body stored for
|
|
184
|
+
* offline analysis plus the signals computed from it at ingest (see
|
|
185
|
+
* `model-metrics.ts`). Keyed like `user_messages` by (session_file, entry_id).
|
|
186
|
+
* Turns without prose (tool-call-only replies) emit no row.
|
|
187
|
+
*/
|
|
188
|
+
export interface AssistantTextStats {
|
|
189
|
+
/** Database ID */
|
|
190
|
+
id?: number;
|
|
191
|
+
/** Session file path */
|
|
192
|
+
sessionFile: string;
|
|
193
|
+
/** Assistant message entry ID within the session */
|
|
194
|
+
entryId: string;
|
|
195
|
+
/** Folder/project path (extracted from session filename) */
|
|
196
|
+
folder: string;
|
|
197
|
+
/** Unix timestamp in ms */
|
|
198
|
+
timestamp: number;
|
|
199
|
+
/** Model that produced the turn */
|
|
200
|
+
model: string;
|
|
201
|
+
/** Provider that served the turn */
|
|
202
|
+
provider: string;
|
|
203
|
+
/** Which agent produced the turn (main agent, task subagent, advisor) */
|
|
204
|
+
agentType: AgentType;
|
|
205
|
+
/** Analyzed-prose characters (code and markup stripped, capped) */
|
|
206
|
+
chars: number;
|
|
207
|
+
/** Analyzed-prose words */
|
|
208
|
+
words: number;
|
|
209
|
+
/** Apology / self-blame markers */
|
|
210
|
+
selfBlame: number;
|
|
211
|
+
/** Repeated-restatement markers plus near-duplicate previous turn */
|
|
212
|
+
restatement: number;
|
|
213
|
+
/** Hedged fallback markers */
|
|
214
|
+
hedge: number;
|
|
215
|
+
/** 1 when the turn is long-winded */
|
|
216
|
+
verbose: number;
|
|
217
|
+
/** Failed tool results preceding the turn */
|
|
218
|
+
toolErrors: number;
|
|
219
|
+
/** 1 when the preceding failures form a spiral */
|
|
220
|
+
toolSpiral: number;
|
|
221
|
+
/** Per-turn aggregate (see `AssistantMessageMetrics`) */
|
|
222
|
+
collapse: number;
|
|
223
|
+
/** 1 when the prose leans on a script no lexicon covers */
|
|
224
|
+
unsupportedScript: number;
|
|
225
|
+
/** Stored analysis prose (see `analysisProse`); never empty for an emitted row. */
|
|
226
|
+
prose: string;
|
|
227
|
+
}
|
|
182
228
|
/**
|
|
183
229
|
* Pair emitted by the parser when it sees an assistant message whose
|
|
184
230
|
* `parentId` points to a user message that wasn't parsed in the same pass
|