@deepseek-ai/dsh-experimental-client-ui-stats 0.0.0-stage → 0.2.2-alpha.2

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.
@@ -0,0 +1,282 @@
1
+ /** Published performance model: per-step metrics, per-turn aggregates, and marker contributions. */
2
+ import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
3
+ import type { ConversationLocation, ConversationViewNode } from '@deepseek-ai/dsh-client-ui-conversation/client';
4
+ /** Outcome of one older-history request. */
5
+ export type LoadOlderResult = 'grew' | 'exhausted' | 'retry';
6
+ /** Token usage counts one assistant message reported. */
7
+ export interface StatsUsage {
8
+ readonly inputTokens?: number;
9
+ readonly outputTokens?: number;
10
+ readonly cacheReadTokens?: number;
11
+ readonly cacheWriteTokens?: number;
12
+ }
13
+ /** One recorded tool call of a step, including its result size and preview. */
14
+ export interface StatsCall {
15
+ readonly callId: string;
16
+ readonly seq: number;
17
+ readonly name: string | null;
18
+ readonly hint: string | null;
19
+ readonly chars: number | null;
20
+ readonly lines: number | null;
21
+ readonly error: boolean;
22
+ readonly added: number | null;
23
+ readonly removed: number | null;
24
+ readonly before: string | null;
25
+ readonly after: string | null;
26
+ readonly args: string | null;
27
+ /** Code-Mode dispatch recorded inside a `run_code` call. */
28
+ readonly inner: boolean;
29
+ /** Result text kept for the accordion panel. */
30
+ readonly text: string | null;
31
+ readonly truncated: boolean;
32
+ /** Measured tool duration, or null while the result is missing. */
33
+ readonly ms: number | null;
34
+ /** Wall-clock start of the call, for the non-overlapping tool-span union. */
35
+ readonly startedAt: number | null;
36
+ /** Wall-clock end of the call, present only after its result settled. */
37
+ readonly endedAt: number | null;
38
+ }
39
+ /** Tool call tally shown as one pill. */
40
+ export interface StatsToolCount {
41
+ readonly name: string;
42
+ readonly count: number;
43
+ }
44
+ /** Per-step state folded from the event stream. */
45
+ export interface StatsStepState {
46
+ readonly turn: number;
47
+ readonly step: number;
48
+ readonly startSeq: number | null;
49
+ readonly startTime: number | null;
50
+ readonly endTime: number | null;
51
+ readonly ended: boolean;
52
+ readonly firstTokenTime: number | null;
53
+ readonly messageTime: number | null;
54
+ readonly usage: StatsUsage | null;
55
+ readonly interrupted: boolean;
56
+ readonly toolPairs: number;
57
+ readonly toolMs: number;
58
+ readonly toolOpen: number;
59
+ readonly toolMissing: number;
60
+ readonly pending: Readonly<Record<string, number>> | null;
61
+ readonly tools: Readonly<Record<string, number>> | null;
62
+ readonly calls: Readonly<Record<string, StatsCall>> | null;
63
+ readonly starts: Readonly<Record<string, number>> | null;
64
+ readonly retries: number;
65
+ readonly toolErrors: number;
66
+ /** Turn-level marker kind; step states leave this null. */
67
+ readonly mark: 'prompt' | 'end' | null;
68
+ readonly prompt: string | null;
69
+ /** Durable image references the prompt attached, in message order. */
70
+ readonly images: readonly ImageAttachmentRef[];
71
+ readonly closed: boolean;
72
+ readonly closeKind: string | null;
73
+ /** Producer source kind of the trigger prompt Context. */
74
+ readonly trigger: string | null;
75
+ /** Sender agent name parsed from a team/agent message, or null. */
76
+ readonly triggerSender: string | null;
77
+ /** Trimmed one-message answer text, for the Did column preview. */
78
+ readonly answer: string | null;
79
+ /** Full answer body kept for expansion, bounded by the fold budget. */
80
+ readonly answerBody: string | null;
81
+ /** Whether the stored answer body lost trailing characters. */
82
+ readonly answerTruncated: boolean;
83
+ }
84
+ /** Measured metrics of one step. */
85
+ export interface StatsStepMetrics {
86
+ readonly turn: number;
87
+ readonly step: number;
88
+ readonly startTime: number | null;
89
+ readonly endTime: number | null;
90
+ readonly context: number | null;
91
+ readonly ttft: number | null;
92
+ readonly model: number | null;
93
+ readonly decode: number | null;
94
+ readonly tps: number | null;
95
+ readonly output: number | null;
96
+ readonly tool: number | null;
97
+ /** Union of the paired calls' wall intervals; tool calls may run in parallel. */
98
+ readonly toolWall: number | null;
99
+ readonly tools: readonly StatsToolCount[];
100
+ readonly calls: readonly StatsCall[];
101
+ readonly toolOutput: number | null;
102
+ readonly retries: number;
103
+ readonly toolErrors: number;
104
+ /** Trimmed one-line answer preview of the settled assistant message, or null. */
105
+ readonly answer: string | null;
106
+ /** Full answer body kept for expansion, or null. */
107
+ readonly answerBody: string | null;
108
+ /** Whether the stored answer body lost trailing characters. */
109
+ readonly answerTruncated: boolean;
110
+ readonly cacheRead: number | null;
111
+ readonly cacheWrite: number | null;
112
+ readonly cacheHit: number | null;
113
+ readonly wall: number | null;
114
+ readonly toolPending: number;
115
+ readonly running: boolean;
116
+ readonly interrupted: boolean;
117
+ readonly aborted: boolean;
118
+ readonly ttftPending?: number;
119
+ readonly mark?: 'prompt' | 'end' | null;
120
+ readonly prompt?: string | null;
121
+ readonly images?: readonly ImageAttachmentRef[];
122
+ readonly closed?: boolean;
123
+ readonly closeKind?: string | null;
124
+ }
125
+ /** Aggregate of one turn. */
126
+ export interface StatsTurnMetrics {
127
+ readonly turn: number;
128
+ readonly steps: readonly StatsStepMetrics[];
129
+ readonly startTime: number | null;
130
+ readonly context: number | null;
131
+ readonly ttft: number | null;
132
+ readonly ttftPending: number;
133
+ readonly model: number | null;
134
+ readonly modelPending: number;
135
+ readonly decode: number | null;
136
+ readonly tps: number | null;
137
+ readonly output: number | null;
138
+ readonly tool: number | null;
139
+ /** Union of the turn's step tool spans; steps never overlap. */
140
+ readonly toolWall: number | null;
141
+ readonly toolPending: number;
142
+ readonly tools: readonly StatsToolCount[];
143
+ /** Token-weighted cache-read share across the steps that reported usage. */
144
+ readonly cacheHit: number | null;
145
+ /** Cache-read tokens summed across the steps that reported usage. */
146
+ readonly cacheRead: number | null;
147
+ /** Cache-write tokens summed across the steps that reported usage. */
148
+ readonly cacheWrite: number | null;
149
+ /** Prompt tokens summed across the steps that reported usage; the weight of `cacheHit`. */
150
+ readonly cacheContext: number | null;
151
+ readonly retries: number;
152
+ readonly toolErrors: number;
153
+ readonly toolOutput: number;
154
+ readonly lastStepWall: number | null;
155
+ readonly running: boolean;
156
+ readonly interrupted: boolean;
157
+ readonly aborted: boolean;
158
+ readonly wall: number | null;
159
+ /** Compaction transactions recorded in this turn, in start order. */
160
+ readonly compactions: readonly StatsCompactionMetrics[];
161
+ /** Non-step event rows recorded in this turn, in event order. */
162
+ readonly events: readonly StatsEventMetrics[];
163
+ readonly prompt: string | null;
164
+ /** Durable image references the prompt attached, in message order. */
165
+ readonly promptImages: readonly ImageAttachmentRef[];
166
+ /** Producer source kind that opened the turn (`user`, `agent-message`, ...). */
167
+ readonly promptSource: string | null;
168
+ /** Sender agent name of an automated trigger, or null. */
169
+ readonly promptSender: string | null;
170
+ /** Last answer preview measured in the turn. */
171
+ readonly answer: string | null;
172
+ }
173
+ /** Non-step event kinds the Statistics table can explain. */
174
+ export type StatsEventKind = 'request-header' | 'system-prompt' | 'tool-set' | 'context-prune' | 'request-context' | 'model-retry' | 'model-attempt' | 'context-refresh' | 'approval';
175
+ /** One synthetic event row: request admission, prompt/tool changes, or a model-free prune. */
176
+ export interface StatsEventMetrics {
177
+ readonly kind: StatsEventKind;
178
+ readonly turn: number | null;
179
+ readonly step: number | null;
180
+ readonly time: number;
181
+ readonly reason: string | null;
182
+ readonly series: boolean;
183
+ readonly provider: string | null;
184
+ readonly model: string | null;
185
+ readonly toolCount: number | null;
186
+ readonly surfaceOp: 'append' | 'replace' | 'clear' | null;
187
+ readonly chars: number | null;
188
+ readonly added: readonly string[];
189
+ readonly removed: readonly string[];
190
+ readonly shadowedTokens: number | null;
191
+ readonly status: string | null;
192
+ readonly retry: number | null;
193
+ readonly delayMs: number | null;
194
+ readonly error: string | null;
195
+ readonly label: string | null;
196
+ }
197
+ /** One completed or running compaction transaction with its model-call facts. */
198
+ export interface StatsCompactionMetrics {
199
+ readonly compactionId: string;
200
+ readonly turn: number | null;
201
+ readonly startTime: number;
202
+ readonly endTime: number | null;
203
+ readonly wall: number | null;
204
+ readonly running: boolean;
205
+ readonly context: number | null;
206
+ readonly output: number | null;
207
+ readonly cacheHit: number | null;
208
+ readonly cacheRead: number | null;
209
+ readonly cacheWrite: number | null;
210
+ readonly provider: string | null;
211
+ readonly model: string | null;
212
+ readonly shadowedTokens: number | null;
213
+ readonly summaryChars: number | null;
214
+ readonly error: string | null;
215
+ }
216
+ /** Per-turn compaction rows shown between the step rows. */
217
+ export interface StatsCompactionState {
218
+ readonly compactionId: string;
219
+ readonly turn: number | null;
220
+ readonly startSeq: number;
221
+ readonly startTime: number;
222
+ readonly summarySeq: number | null;
223
+ readonly endSeq: number | null;
224
+ readonly endTime: number | null;
225
+ readonly error: string | null;
226
+ readonly provider: string | null;
227
+ readonly model: string | null;
228
+ readonly usage: StatsUsage | null;
229
+ readonly shadowedTokens: number | null;
230
+ readonly summaryChars: number | null;
231
+ readonly checkpointSeq: number | null;
232
+ }
233
+ /** One published node: a step's metrics or a turn-level marker. */
234
+ export type StatsContribution = {
235
+ readonly kind: 'step';
236
+ readonly metrics: StatsStepMetrics;
237
+ } | {
238
+ /** Inner tool calls one Code-Mode root call dispatched; merged into its step. */
239
+ readonly kind: 'inner';
240
+ readonly turn: number;
241
+ readonly step: number;
242
+ readonly calls: readonly StatsCall[];
243
+ } | {
244
+ readonly kind: 'prompt';
245
+ readonly turn: number;
246
+ readonly prompt: string | null;
247
+ /** Durable image references the prompt attached, in message order. */
248
+ readonly images: readonly ImageAttachmentRef[];
249
+ /** Producer source kind of the triggering user message. */
250
+ readonly source: string;
251
+ /** Sender agent name of a team/agent message, or null. */
252
+ readonly sender: string | null;
253
+ } | {
254
+ readonly kind: 'compaction';
255
+ readonly metrics: StatsCompactionMetrics;
256
+ } | {
257
+ readonly kind: 'event';
258
+ readonly metrics: StatsEventMetrics;
259
+ } | {
260
+ readonly kind: 'end';
261
+ readonly turn: number;
262
+ readonly closeKind: string | null;
263
+ readonly endTime: number | null;
264
+ };
265
+ /** View node carried from the Definitions into the target builder. */
266
+ export interface StatsViewNode extends ConversationViewNode {
267
+ readonly anchorSeq: number;
268
+ readonly location: ConversationLocation;
269
+ readonly data: StatsContribution;
270
+ }
271
+ /** Snapshot published to the view component. */
272
+ export interface StatsSnapshot {
273
+ readonly turns: readonly StatsTurnMetrics[];
274
+ readonly stepCount: number;
275
+ }
276
+ declare module '@deepseek-ai/dsh-client-ui-conversation/client' {
277
+ interface ConversationViewSnapshotMap {
278
+ /** Turn and step metrics this target assembles. */
279
+ stats: StatsSnapshot;
280
+ }
281
+ }
282
+ //# sourceMappingURL=stats-contract.d.ts.map
@@ -0,0 +1,20 @@
1
+ /**
2
+ * Conversation Definitions producing the performance target's nodes: one step
3
+ * context per `step/start`, one prompt context per user message, one end marker
4
+ * per turn, and one context per Code-Mode root call for its inner dispatches.
5
+ *
6
+ * Every callback is a pure function of the events it receives: turn and step
7
+ * identity comes from the engine's match location, never from module state, so
8
+ * one Definition set serves every Session binding and history paging
9
+ * (`replaceWindow`/`prepend`) cannot misattribute events.
10
+ */
11
+ import type { Context } from '@deepseek-ai/cordis';
12
+ /** Target name shared by every Definition and the view builder. */
13
+ export declare const TARGET = "stats";
14
+ /**
15
+ * Register the six Definitions. Each registration rides the caller's fiber
16
+ * effect, so unloading the plugin removes the nodes with it.
17
+ * @param ctx - client root context.
18
+ */
19
+ export declare function registerStatsDefinitions(ctx: Context): void;
20
+ //# sourceMappingURL=stats-definition.d.ts.map
@@ -0,0 +1,23 @@
1
+ /** Non-step event rows: request admission, prompt/tool changes, and model-free prunes. */
2
+ import type { ConversationLocation, ConversationNodeDefinition } from '@deepseek-ai/dsh-client-ui-conversation/client';
3
+ import type { StatsEventMetrics } from './stats-contract.ts';
4
+ /** Event shape a Conversation Definition receives. */
5
+ type MatchEvent = Parameters<ConversationNodeDefinition['match']>[0];
6
+ /**
7
+ * Turn and step a Location resolves.
8
+ * @param location - engine Location of a match.
9
+ * @returns the resolved turn and step, or null when the window lost them.
10
+ */
11
+ export declare function locationTurnStep(location: ConversationLocation | undefined): {
12
+ readonly turn: number;
13
+ readonly step: number | null;
14
+ } | null;
15
+ /**
16
+ * Normalize one non-step event into row values.
17
+ * @param event - a session event seen by the Definition match.
18
+ * @param location - engine Location of the event, for turn and step.
19
+ * @returns row metrics, or null for events the table does not explain.
20
+ */
21
+ export declare function eventMetrics(event: MatchEvent, location: ConversationLocation | undefined): StatsEventMetrics | null;
22
+ export {};
23
+ //# sourceMappingURL=stats-event.d.ts.map
@@ -0,0 +1,68 @@
1
+ /** Event folding and per-step metric derivation for the Statistics table. */
2
+ import type { SessionEventLike } from '@deepseek-ai/dsh-api-session-controller/client';
3
+ import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
4
+ import type { UserMessage } from '@deepseek-ai/dsh-llm';
5
+ import type { StatsCall, StatsStepMetrics, StatsStepState } from './stats-contract.ts';
6
+ /** Calls listed per step. */
7
+ export declare const CALL_LIMIT = 12;
8
+ /**
9
+ * Whether one tool name is the Code-Mode runner; its real tools run inside it.
10
+ * @param name - tool name, or null for a nameless call.
11
+ * @returns true when the name is the Code-Mode runner.
12
+ */
13
+ export declare function isCodeMode(name: string | null): boolean;
14
+ /**
15
+ * Sender agent name of a teammate/agent notification, parsed from its body prefix.
16
+ * @param message - waking user message stamped with its producer source.
17
+ * @returns the readable member name, or null when the frame omits it or carries an opaque session id.
18
+ */
19
+ export declare function triggerSenderOf(message: UserMessage): string | null;
20
+ /**
21
+ * Initial state of one step or one turn-level marker.
22
+ * @param turn - turn number.
23
+ * @param step - step number, or the marker's pseudo step.
24
+ * @param mark - marker kind; steps pass null.
25
+ * @returns the empty state.
26
+ */
27
+ export declare function newState(turn: number, step: number, mark?: StatsStepState['mark']): StatsStepState;
28
+ /**
29
+ * User question: only a human-typed `user` source is the text the user wrote.
30
+ * @param message - one user-role message from the Session log.
31
+ * @returns the one-line question and the durable images it attached.
32
+ */
33
+ export declare function promptOf(message: UserMessage): {
34
+ text: string | null;
35
+ images: readonly ImageAttachmentRef[];
36
+ };
37
+ /**
38
+ * Fold one session event into the step state. Events other than `step/start`
39
+ * create a state when the window starts mid-step, so context and throughput
40
+ * still show while start-dependent metrics stay unrecorded.
41
+ * @param state - current state, or undefined before the first foldable event.
42
+ * @param event - one durable or client-only session event.
43
+ * @returns the next state, or undefined when the event needs a start it lacks.
44
+ */
45
+ export declare function foldEvent(state: StatsStepState | undefined, event: SessionEventLike): StatsStepState | undefined;
46
+ /**
47
+ * Wall span covered by calls that both started and settled; overlaps count once.
48
+ * @param calls - calls with their paired start and end times.
49
+ * @returns the span in milliseconds, or null when no call is paired.
50
+ */
51
+ export declare function toolSpanUnion(calls: readonly StatsCall[]): number | null;
52
+ /**
53
+ * Measured metrics of one step.
54
+ * @param state - folded step state.
55
+ * @returns the row values the table renders.
56
+ */
57
+ export declare function stepMetrics(state: StatsStepState): StatsStepMetrics;
58
+ /**
59
+ * State rebuilt from the matches a window still holds when its state is absent.
60
+ * Event order is preserved, so `step/start` and `step/end` restore the
61
+ * boundaries whenever they survived.
62
+ * @param matches - accepted matches in ascending sequence order.
63
+ * @returns the folded state, or undefined when nothing was foldable.
64
+ */
65
+ export declare function fallbackState(matches: readonly {
66
+ readonly event: SessionEventLike;
67
+ }[]): StatsStepState | undefined;
68
+ //# sourceMappingURL=stats-fold.d.ts.map
@@ -0,0 +1,85 @@
1
+ /** Display formatting for the Statistics table. */
2
+ /** Placeholder for a value the event stream did not record. */
3
+ export declare const DASH = "\u2014";
4
+ /**
5
+ * Duration: minutes past one minute, seconds past one second, milliseconds below.
6
+ * @param value - duration in milliseconds.
7
+ * @returns formatted duration, or the dash placeholder.
8
+ */
9
+ export declare function formatMs(value: number | null): string;
10
+ /**
11
+ * Token count with thousands separators, for tooltips.
12
+ * @param value - token count.
13
+ * @returns grouped digits, or the dash placeholder.
14
+ */
15
+ export declare function formatTokens(value: number | null): string;
16
+ /**
17
+ * Token count in K, switching to M once the value reaches ten million.
18
+ * @param value - token count, or null when unrecorded.
19
+ * @returns the K/M-suffixed count, or the dash placeholder.
20
+ */
21
+ export declare function formatTokensShort(value: number | null): string;
22
+ /**
23
+ * Signed context delta, using the same K scale as the counts it belongs to.
24
+ * @param value - token delta; null produces an empty string.
25
+ * @returns signed K-suffixed delta.
26
+ */
27
+ export declare function formatTokensDelta(value: number | null): string;
28
+ /**
29
+ * Character count of tool output, collapsed to K past one thousand.
30
+ * @param value - character count.
31
+ * @returns formatted size, or the dash placeholder.
32
+ */
33
+ export declare function formatChars(value: number | null): string;
34
+ /**
35
+ * Output speed in tokens per second.
36
+ * @param value - tokens per second.
37
+ * @returns one-decimal speed, or the dash placeholder.
38
+ */
39
+ export declare function formatTps(value: number | null): string;
40
+ /**
41
+ * Share as a two-decimal percentage.
42
+ * @param value - share in [0, 1].
43
+ * @returns percentage text, or the dash placeholder.
44
+ */
45
+ export declare function formatPercent(value: number | null): string;
46
+ /**
47
+ * Local wall-clock time of day, so a row lines up with logs.
48
+ * @param value - epoch milliseconds.
49
+ * @returns `HH:MM:SS`, or the dash placeholder.
50
+ */
51
+ export declare function formatClock(value: number | null): string;
52
+ /**
53
+ * Compact month-day clock for the turn scope cell; tooltips carry the full date.
54
+ * @param value - epoch milliseconds.
55
+ * @returns `MM-DD HH:MM`, or the dash placeholder.
56
+ */
57
+ export declare function formatDateTimeShort(value: number | null): string;
58
+ /**
59
+ * Full timestamp with milliseconds for tooltips.
60
+ * @param value - epoch milliseconds.
61
+ * @returns `YYYY-MM-DD HH:MM:SS.mmm`, or the dash placeholder.
62
+ */
63
+ export declare function formatDateTimeMs(value: number | null): string;
64
+ /**
65
+ * Step start timestamp with date and milliseconds for the trigger column.
66
+ * @param value - epoch milliseconds.
67
+ * @returns `MM-DD HH:MM:SS.mmm`, or the dash placeholder.
68
+ */
69
+ export declare function formatStepClock(value: number | null): string;
70
+ /**
71
+ * Date and time of day: the table shows the clock, tooltips add the date.
72
+ * @param value - epoch milliseconds.
73
+ * @returns `YYYY-MM-DD HH:MM:SS`, or the dash placeholder.
74
+ */
75
+ export declare function formatDateTime(value: number | null): string;
76
+ /**
77
+ * Bar length on a square-root scale: a linear scale collapses short steps into
78
+ * slivers, and a logarithmic one flattens the differences the column exists to
79
+ * show. The longest member of the comparison group fills the bar.
80
+ * @param total - measured duration.
81
+ * @param scale - longest duration of the comparison group.
82
+ * @returns fill share in [0, 1].
83
+ */
84
+ export declare function barShare(total: number, scale: number): number;
85
+ //# sourceMappingURL=stats-format.d.ts.map
@@ -0,0 +1,15 @@
1
+ /** View target builder turning published nodes into turn rows. */
2
+ import type { Context } from '@deepseek-ai/cordis';
3
+ import type { ConversationViewDefinition } from '@deepseek-ai/dsh-client-ui-conversation/client';
4
+ import type { StatsSnapshot, StatsViewNode } from './stats-contract.ts';
5
+ /** Stable snapshot used before a Session assembled any performance node. */
6
+ export declare const EMPTY_STATS_SNAPSHOT: StatsSnapshot;
7
+ /** The `stats` target every Definition publishes into. */
8
+ export declare const statsViewDefinition: ConversationViewDefinition<StatsViewNode, StatsSnapshot>;
9
+ /**
10
+ * Register the target builder. The registration rides the caller's fiber
11
+ * effect, so unloading the plugin drops the target with it.
12
+ * @param ctx - client root context.
13
+ */
14
+ export declare function registerStatsConversationView(ctx: Context): void;
15
+ //# sourceMappingURL=stats-snapshot-builder.d.ts.map
@@ -0,0 +1,12 @@
1
+ /** Whole-session totals from the host projections that survive client paging. */
2
+ import type { SessionStatsProjection } from '@deepseek-ai/dsh-session-stats/types';
3
+ import type { TokenUsageProjection } from '@deepseek-ai/dsh-token-meter/client';
4
+ import type { StatsTotals } from './stats-aggregate.ts';
5
+ /**
6
+ * Map the whole-session stats and token-usage projections onto the totals row.
7
+ * @param stats - whole-log turn/step and wall-time projection.
8
+ * @param usage - whole-log prompt and output token projection.
9
+ * @returns totals over the complete session, or null while either projection is absent.
10
+ */
11
+ export declare function totalsFromProjections(stats: SessionStatsProjection | undefined, usage: TokenUsageProjection | undefined): StatsTotals | null;
12
+ //# sourceMappingURL=stats-totals.d.ts.map
@@ -0,0 +1,39 @@
1
+ /** Token accounting helpers shared by the Statistics table's step and turn levels. */
2
+ import type { StatsUsage } from './stats-contract.ts';
3
+ /**
4
+ * Whether a value is a finite number.
5
+ * @param value - candidate value.
6
+ * @returns true when the value is a finite number.
7
+ */
8
+ export declare function isNumber(value: unknown): value is number;
9
+ /**
10
+ * Prompt length: input, cache read, and cache write do not overlap.
11
+ * @param usage - usage reported by one assistant message.
12
+ * @returns prompt token count, or null when nothing was reported.
13
+ */
14
+ export declare function contextTokens(usage: StatsUsage | null): number | null;
15
+ /**
16
+ * Output tokens reported by one usage object.
17
+ * @param usage - usage reported by one assistant message.
18
+ * @returns output token count, or null when unreported.
19
+ */
20
+ export declare function outputTokens(usage: StatsUsage | null): number | null;
21
+ /**
22
+ * Cache-read tokens reported by one usage object.
23
+ * @param usage - usage reported by one assistant message.
24
+ * @returns cache-read token count, or null when unreported.
25
+ */
26
+ export declare function cacheReadTokens(usage: StatsUsage | null): number | null;
27
+ /**
28
+ * Cache-write tokens reported by one usage object.
29
+ * @param usage - usage reported by one assistant message.
30
+ * @returns cache-write token count, or null when unreported.
31
+ */
32
+ export declare function cacheWriteTokens(usage: StatsUsage | null): number | null;
33
+ /**
34
+ * Share of the prompt served from cache; null when nothing was reported.
35
+ * @param usage - usage reported by one assistant message.
36
+ * @returns cache hit rate in [0, 1], or null when it cannot be derived.
37
+ */
38
+ export declare function cacheHitRate(usage: StatsUsage | null): number | null;
39
+ //# sourceMappingURL=stats-usage.d.ts.map
@@ -0,0 +1,4 @@
1
+ /** Host loader entry for the browser-only performance plugin. */
2
+ /** Provides no host-side behavior. */
3
+ export declare function apply(): void;
4
+ //# sourceMappingURL=index.d.ts.map
package/locale/de.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Statistikansicht",
4
+ "description": "Kontext, Zeit, Cache und Tool-Kosten pro Turn und Schritt neben dem Chat anzeigen."
5
+ }
6
+ }
package/locale/en.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Statistics view",
4
+ "description": "Show per-turn and per-step context, timing, cache, and tool cost beside Chat."
5
+ }
6
+ }
package/locale/es.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Vista de estadísticas",
4
+ "description": "Muestra contexto, tiempos, caché y coste de herramientas por turno y paso junto al chat."
5
+ }
6
+ }
package/locale/fr.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Vue statistiques",
4
+ "description": "Affiche le contexte, les durées, le cache et le coût des outils par tour et par étape à côté du chat."
5
+ }
6
+ }
package/locale/ja.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "統計ビュー",
4
+ "description": "チャットの横にターン/ステップごとのコンテキスト、時間、キャッシュ、ツールコストを表示します。"
5
+ }
6
+ }
package/locale/pt.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Visão de estatísticas",
4
+ "description": "Mostra contexto, tempos, cache e custo de ferramentas por turno e passo ao lado do chat."
5
+ }
6
+ }
package/locale/ru.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Статистика",
4
+ "description": "Показывает контекст, время, кэш и стоимость инструментов по ходам и шагам рядом с чатом."
5
+ }
6
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "统计视图",
4
+ "description": "在对话旁展示每轮/每步的上下文、耗时、缓存和工具成本。"
5
+ }
6
+ }