@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.
- package/LICENSE +21 -0
- package/README.i18n.yaml +43 -0
- package/README.md +120 -2
- package/README.zh.md +121 -0
- package/lib/client.js +6272 -0
- package/lib/index.js +6 -0
- package/lib/types/client/StatsTable.d.ts +120 -0
- package/lib/types/client/StatsView.d.ts +13 -0
- package/lib/types/client/index.d.ts +17 -0
- package/lib/types/client/locales.d.ts +208 -0
- package/lib/types/client/stats-aggregate.d.ts +53 -0
- package/lib/types/client/stats-compaction.d.ts +32 -0
- package/lib/types/client/stats-contract.d.ts +282 -0
- package/lib/types/client/stats-definition.d.ts +20 -0
- package/lib/types/client/stats-event.d.ts +23 -0
- package/lib/types/client/stats-fold.d.ts +68 -0
- package/lib/types/client/stats-format.d.ts +85 -0
- package/lib/types/client/stats-snapshot-builder.d.ts +15 -0
- package/lib/types/client/stats-totals.d.ts +12 -0
- package/lib/types/client/stats-usage.d.ts +39 -0
- package/lib/types/index.d.ts +4 -0
- package/locale/de.json +6 -0
- package/locale/en.json +6 -0
- package/locale/es.json +6 -0
- package/locale/fr.json +6 -0
- package/locale/ja.json +6 -0
- package/locale/pt.json +6 -0
- package/locale/ru.json +6 -0
- package/locale/zh.json +6 -0
- package/package.json +76 -3
package/lib/index.js
ADDED
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Statistics table for one conversation: per-turn aggregates, expandable step
|
|
3
|
+
* rows, the time-composition bars, and the per-step tool-call accordion.
|
|
4
|
+
*/
|
|
5
|
+
import { type ReactElement, type ReactNode } from 'react';
|
|
6
|
+
import type { ImageAttachmentRef } from '@deepseek-ai/dsh-attachment';
|
|
7
|
+
import type { ObservableSnapshot } from '@deepseek-ai/dsh-client-store';
|
|
8
|
+
import type { ConvViewProps } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
9
|
+
import type { InjectFace, PropsLocale } from '@deepseek-ai/dsh-client-ui-slots';
|
|
10
|
+
import type { StatsSnapshot, LoadOlderResult, StatsTurnMetrics } from './stats-contract.ts';
|
|
11
|
+
import { type ContextMode, type StatsTotals } from './stats-aggregate.ts';
|
|
12
|
+
import type { StatsTranslate } from './locales.ts';
|
|
13
|
+
/** Distance from the scroll top, in pixels, that requests one older history page. */
|
|
14
|
+
export declare const LOAD_OLDER_THRESHOLD = 64;
|
|
15
|
+
/** Numeric columns in table order. */
|
|
16
|
+
export declare const COLUMNS: readonly ["context", "output", "cache", "ttft", "model", "tps", "tool"];
|
|
17
|
+
/** Business face injected by the browser plugin. */
|
|
18
|
+
export interface StatsViewInjected {
|
|
19
|
+
/** Snapshot sources bound by InjectFace. */
|
|
20
|
+
hooks: {
|
|
21
|
+
/** This target's snapshot; InjectFace exposes it as `useStats`. */
|
|
22
|
+
stats: ObservableSnapshot<StatsSnapshot>;
|
|
23
|
+
};
|
|
24
|
+
/**
|
|
25
|
+
* Load one older history page into the published window.
|
|
26
|
+
* @returns whether the page grew, exhausted history, or must be retried.
|
|
27
|
+
*/
|
|
28
|
+
loadOlder: () => Promise<LoadOlderResult>;
|
|
29
|
+
/** Cancel a pending open-window wait when this view unmounts. */
|
|
30
|
+
cancel: () => void;
|
|
31
|
+
/**
|
|
32
|
+
* Resolve one durable prompt image through the shared Conversation image cache.
|
|
33
|
+
* @param attachment - image reference the user message recorded.
|
|
34
|
+
* @returns browser URL owned by the cache for the Session binding's lifetime.
|
|
35
|
+
*/
|
|
36
|
+
loadImage: (attachment: ImageAttachmentRef) => Promise<string>;
|
|
37
|
+
}
|
|
38
|
+
/** Full props of the performance conversation View. */
|
|
39
|
+
export type StatsViewProps = ConvViewProps & InjectFace<StatsViewInjected> & PropsLocale<'stats'>;
|
|
40
|
+
/** Resolve one durable prompt image to a browser URL. */
|
|
41
|
+
type LoadImage = StatsViewInjected['loadImage'];
|
|
42
|
+
/** Open/closed default for turns the user never toggled explicitly. */
|
|
43
|
+
type ViewMode = 'newest' | 'all' | 'none';
|
|
44
|
+
/** Step-list presentation of one turn: newest slice or all steps, plus filters. */
|
|
45
|
+
export interface StepViewState {
|
|
46
|
+
readonly mode?: 'tail' | 'all';
|
|
47
|
+
readonly filter?: string | null;
|
|
48
|
+
readonly open?: Readonly<Record<number, boolean>>;
|
|
49
|
+
readonly raw?: Readonly<Record<string, boolean>>;
|
|
50
|
+
readonly wrap?: boolean;
|
|
51
|
+
}
|
|
52
|
+
/** Component-local table state: turn folds and per-turn step state. */
|
|
53
|
+
export interface ViewState {
|
|
54
|
+
readonly mode: ViewMode;
|
|
55
|
+
readonly openTurns: Readonly<Record<number, boolean>>;
|
|
56
|
+
readonly stepViews: Readonly<Record<number, StepViewState>>;
|
|
57
|
+
readonly showTotals: boolean;
|
|
58
|
+
readonly showEvents: boolean;
|
|
59
|
+
readonly showContextDelta: boolean;
|
|
60
|
+
readonly contextMode: ContextMode;
|
|
61
|
+
}
|
|
62
|
+
/** Fields the time-composition bar reads from a turn or step row. */
|
|
63
|
+
interface TimeState {
|
|
64
|
+
readonly running: boolean;
|
|
65
|
+
readonly startTime: number | null;
|
|
66
|
+
readonly wall: number | null;
|
|
67
|
+
readonly ttft: number | null;
|
|
68
|
+
readonly model: number | null;
|
|
69
|
+
readonly tool: number | null;
|
|
70
|
+
/** Non-overlapping union of the paired tool calls; the bar prefers it over `tool`. */
|
|
71
|
+
readonly toolWall: number | null;
|
|
72
|
+
}
|
|
73
|
+
/** Table state shared by one turn's rendered rows. */
|
|
74
|
+
interface TurnRowsOptions {
|
|
75
|
+
readonly turn: StatsTurnMetrics;
|
|
76
|
+
readonly t: StatsTranslate;
|
|
77
|
+
readonly loadImage: LoadImage;
|
|
78
|
+
readonly now: number;
|
|
79
|
+
readonly open: boolean;
|
|
80
|
+
readonly state: StepViewState;
|
|
81
|
+
readonly turnScale: number;
|
|
82
|
+
readonly contextMode: ContextMode;
|
|
83
|
+
readonly showEvents: boolean;
|
|
84
|
+
readonly showContextDelta: boolean;
|
|
85
|
+
readonly contextDelta: number | null;
|
|
86
|
+
readonly onToggle: () => void;
|
|
87
|
+
readonly onToggleDetail: (stepNumber: number) => void;
|
|
88
|
+
readonly onControl: (patch: Partial<StepViewState>) => void;
|
|
89
|
+
}
|
|
90
|
+
/** Props of the pagination/expand footer button. */
|
|
91
|
+
interface TableButtonProps {
|
|
92
|
+
readonly caption: string;
|
|
93
|
+
readonly enabled: boolean;
|
|
94
|
+
readonly onClick: () => void;
|
|
95
|
+
}
|
|
96
|
+
/** Empty per-turn step state, shared so unexpanded turns allocate nothing. */
|
|
97
|
+
export declare const EMPTY_STEP_VIEW: StepViewState;
|
|
98
|
+
/** Whether a row is running with no measured wall time yet. */
|
|
99
|
+
export declare function isTimeRunning(value: TimeState): boolean;
|
|
100
|
+
/** Measured span; a running row falls back to the elapsed time at `now`. */
|
|
101
|
+
export declare function totalSpan(value: TimeState, now: number): number | null;
|
|
102
|
+
/** Default fold state of a turn the user never toggled. */
|
|
103
|
+
export declare function defaultTurnOpen(mode: ViewMode, turnNumber: number, latestTurn: number | null): boolean;
|
|
104
|
+
/** Fresh table state: follow the newest turn's open default. */
|
|
105
|
+
export declare function createViewState(): ViewState;
|
|
106
|
+
/** Props of the totals row. */
|
|
107
|
+
interface TotalsRowProps {
|
|
108
|
+
readonly totals: StatsTotals;
|
|
109
|
+
readonly full: boolean;
|
|
110
|
+
readonly t: StatsTranslate;
|
|
111
|
+
readonly now: number;
|
|
112
|
+
}
|
|
113
|
+
/** Bottom row summing the turns loaded in the current window. */
|
|
114
|
+
export declare function TotalsRow({ totals, full, t, now }: TotalsRowProps): ReactElement;
|
|
115
|
+
/** All rows of one turn: the clickable header, then the expanded body. */
|
|
116
|
+
export declare function turnRows(options: TurnRowsOptions): ReactNode[];
|
|
117
|
+
/** Footer button that switches between enabled and disabled styling. */
|
|
118
|
+
export declare function TableButton({ caption, enabled, onClick }: TableButtonProps): ReactElement;
|
|
119
|
+
export {};
|
|
120
|
+
//# sourceMappingURL=StatsTable.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
/** Statistics view entry: scrolling table, paging state, and footer controls. */
|
|
2
|
+
import { type ReactElement } from 'react';
|
|
3
|
+
import { type StatsViewProps, type StatsViewInjected } from './StatsTable.tsx';
|
|
4
|
+
export type { StatsViewInjected, StatsViewProps };
|
|
5
|
+
/**
|
|
6
|
+
* Render the Statistics table of the current conversation view target. The
|
|
7
|
+
* table owns the viewport scroll: reaching the top asks the injected loader
|
|
8
|
+
* for one older page while the already published turns stay in place.
|
|
9
|
+
* @param props - composed conversation View props: the stats snapshot hook, the older-page loader, and the locale seat.
|
|
10
|
+
* @returns the scrolling table, its empty state, and the expand/collapse footer.
|
|
11
|
+
*/
|
|
12
|
+
export declare function StatsView(props: StatsViewProps): ReactElement;
|
|
13
|
+
//# sourceMappingURL=StatsView.d.ts.map
|
|
@@ -0,0 +1,17 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Browser performance plugin contributing one entry to the conversation view
|
|
3
|
+
* slot: per-turn and per-step context, timing, cache, and tool-cost columns.
|
|
4
|
+
*/
|
|
5
|
+
import type { Context } from '@deepseek-ai/cordis';
|
|
6
|
+
export type { StatsKey } from './locales.ts';
|
|
7
|
+
export type { StatsCall, StatsSnapshot, StatsStepMetrics, StatsTurnMetrics } from './stats-contract.ts';
|
|
8
|
+
/** Required services: the conversation slot and view registries, Session paging, and the locale service. */
|
|
9
|
+
export declare const inject: string[];
|
|
10
|
+
/**
|
|
11
|
+
* Client plugin body: register the locale dictionaries, the event Definitions,
|
|
12
|
+
* the view target, and the tab itself. Every registration rides the caller's
|
|
13
|
+
* fiber effect, so unloading the plugin removes the tab with it.
|
|
14
|
+
* @param ctx - client root context.
|
|
15
|
+
*/
|
|
16
|
+
export declare function apply(ctx: Context): void;
|
|
17
|
+
//# sourceMappingURL=index.d.ts.map
|
|
@@ -0,0 +1,208 @@
|
|
|
1
|
+
/** `stats` namespace dictionaries for the Statistics table. */
|
|
2
|
+
/** Dictionary namespace owned by this plugin. */
|
|
3
|
+
export declare const NS = "stats";
|
|
4
|
+
/** Simplified Chinese dictionary (the key-set source of truth). */
|
|
5
|
+
export declare const zh: {
|
|
6
|
+
readonly 'view.stats': "统计";
|
|
7
|
+
readonly 'column.scope': "轮次 / 步骤";
|
|
8
|
+
readonly 'column.scope.title': "轮次行是该轮的合计;点一行展开或折叠它的每一步";
|
|
9
|
+
readonly 'column.prompt': "触发";
|
|
10
|
+
readonly 'column.prompt.title': "这一轮是由什么触发的;人写的提示词显示正文,自动触发显示来源标签";
|
|
11
|
+
readonly 'trigger.agent-message': "智能体消息";
|
|
12
|
+
readonly 'trigger.team-message': "团队消息";
|
|
13
|
+
readonly 'trigger.schedule': "定时触发";
|
|
14
|
+
readonly 'trigger.webhook': "Webhook";
|
|
15
|
+
readonly 'trigger.tool-jobs': "后台任务";
|
|
16
|
+
readonly 'trigger.cordis-host-runner': "插件触发";
|
|
17
|
+
readonly 'trigger.subagent-settled': "子代理完成";
|
|
18
|
+
readonly 'trigger.goal': "目标轮次";
|
|
19
|
+
readonly 'trigger.context': "上下文唤醒";
|
|
20
|
+
readonly 'trigger.other': "自动触发";
|
|
21
|
+
readonly 'column.did': "执行内容";
|
|
22
|
+
readonly 'column.did.title': "该步调用的工具与次数;没有工具调用的步显示回答正文的摘要";
|
|
23
|
+
readonly 'column.context': "上下文";
|
|
24
|
+
readonly 'column.context.title': "该步 usage 的输入词数 + 缓存读 + 缓存写";
|
|
25
|
+
readonly 'column.output': "输出";
|
|
26
|
+
readonly 'column.output.title': "该步 usage 的输出词数";
|
|
27
|
+
readonly 'column.cache': "缓存命中";
|
|
28
|
+
readonly 'column.cache.title': "缓存读 ÷(输入 + 缓存读 + 缓存写):提示词里命中缓存的比例";
|
|
29
|
+
readonly 'cache.detail': "缓存读 {read} · 输入 {input} · 缓存写 {write}";
|
|
30
|
+
readonly 'column.ttft': "首 token";
|
|
31
|
+
readonly 'column.ttft.title': "步开始到第一个输出片段(TTFT)";
|
|
32
|
+
readonly 'column.model': "模型用时";
|
|
33
|
+
readonly 'column.model.title': "步开始到收到完整回复(含首 token 延迟)";
|
|
34
|
+
readonly 'column.tps': "输出速度";
|
|
35
|
+
readonly 'column.tps.title': "输出词数 ÷ 生成秒数(TPS,tok/s)";
|
|
36
|
+
readonly 'column.tool': "工具用时";
|
|
37
|
+
readonly 'column.tool.title': "该步内每次工具调用到拿到结果的耗时之和;还没有结果的调用不计";
|
|
38
|
+
readonly 'column.time': "总用时";
|
|
39
|
+
readonly 'column.time.title': "总用时拆分:浅蓝 首 token、蓝 生成、橙 工具调用、灰 其余。条长按平方根刻度,步只和同一轮的步比,轮只和轮比";
|
|
40
|
+
readonly 'turn.label': "第 {turn} 轮";
|
|
41
|
+
readonly 'step.label': "第 {step} 步";
|
|
42
|
+
readonly 'step.toggle.aria': "展开或折叠第 {step} 步的工具详情";
|
|
43
|
+
readonly 'step.partial': "起止未知";
|
|
44
|
+
readonly 'step.started.title': "步骤开始于 {time}";
|
|
45
|
+
readonly 'compaction.label': "压缩";
|
|
46
|
+
readonly 'compaction.running': "压缩中…";
|
|
47
|
+
readonly 'compaction.shadowed': "压缩 {tokens} tokens 历史";
|
|
48
|
+
readonly 'compaction.summary': "摘要 {chars} 字符";
|
|
49
|
+
readonly 'compaction.title': "压缩调用单独展示,不并入轮次的步骤合计";
|
|
50
|
+
readonly 'event.show': "显示事件行(含压缩)";
|
|
51
|
+
readonly 'context.delta.show': "显示上下文增量";
|
|
52
|
+
readonly 'context.delta.title': "相对同轮上一步的提示词增量;负值表示上下文减少(如压缩)";
|
|
53
|
+
readonly 'event.request-header': "请求头";
|
|
54
|
+
readonly 'event.system-prompt': "系统提示词";
|
|
55
|
+
readonly 'event.tool-set': "工具集变更";
|
|
56
|
+
readonly 'event.context-prune': "上下文裁剪";
|
|
57
|
+
readonly 'event.request-context': "路由能力";
|
|
58
|
+
readonly 'event.model-retry': "模型重试";
|
|
59
|
+
readonly 'event.model-attempt': "模型尝试";
|
|
60
|
+
readonly 'event.context-refresh': "上下文刷新";
|
|
61
|
+
readonly 'event.approval': "审批";
|
|
62
|
+
readonly 'event.context.detail': "{provider} / {model} · 提示词模式 {mode}";
|
|
63
|
+
readonly 'event.retry.detail': "第 {retry} 次重试 · 等待 {delay}";
|
|
64
|
+
readonly 'event.attempt.detail': "未提交消息的模型尝试";
|
|
65
|
+
readonly 'event.refresh.detail': "{source} · {chars} 字符";
|
|
66
|
+
readonly 'event.approval.detail': "{tool} · {status}";
|
|
67
|
+
readonly 'event.source.runtime': "运行时上下文";
|
|
68
|
+
readonly 'event.source.time': "时间上下文";
|
|
69
|
+
readonly 'event.approval.asked': "等待审批";
|
|
70
|
+
readonly 'event.approval.allowed': "允许一次";
|
|
71
|
+
readonly 'event.approval.rejected': "拒绝";
|
|
72
|
+
readonly 'event.approval.cancelled': "取消";
|
|
73
|
+
readonly 'event.approval.unavailable': "不可用";
|
|
74
|
+
readonly 'event.title': "非步骤事件行:解释请求、提示词、工具集、重试、上下文刷新、审批和裁剪变化,不计入轮次的步骤合计";
|
|
75
|
+
readonly 'event.reason.initial': "初始";
|
|
76
|
+
readonly 'event.reason.resume': "恢复";
|
|
77
|
+
readonly 'event.reason.change': "变更";
|
|
78
|
+
readonly 'event.reason.series': "新序列";
|
|
79
|
+
readonly 'event.header.detail': "{reason} · {tools} 个工具";
|
|
80
|
+
readonly 'event.series': "新序列";
|
|
81
|
+
readonly 'event.system.append': "追加";
|
|
82
|
+
readonly 'event.system.replace': "替换";
|
|
83
|
+
readonly 'event.system.clear': "清空";
|
|
84
|
+
readonly 'event.system.detail': "{action} · {chars} 字符";
|
|
85
|
+
readonly 'event.tools.added': "新增 {tools}";
|
|
86
|
+
readonly 'event.tools.removed': "移除 {tools}";
|
|
87
|
+
readonly 'event.prune.detail': "裁剪 {tokens} tokens";
|
|
88
|
+
readonly 'step.partial.title': "这一步的开始与结束事件不在当前事件窗口里(页签重连或窗口重建时被截断),首 token、模型用时、总用时都没有起点可以相减;重新加载页签会从完整窗口重新装配";
|
|
89
|
+
readonly 'state.running': "进行中";
|
|
90
|
+
readonly 'state.interrupted': "中断";
|
|
91
|
+
readonly 'state.cacheMiss': "缓存未命中";
|
|
92
|
+
readonly 'state.cacheMiss.title': "这一步的提示词几乎没命中缓存:进程重启、会话恢复后的第一次请求都是这样,输入按全价计";
|
|
93
|
+
readonly 'state.aborted': "未完成";
|
|
94
|
+
readonly 'state.aborted.title': "该步已经结束,但没有收到完整回复(多为被取消或失败)";
|
|
95
|
+
readonly unknown: "未记录";
|
|
96
|
+
readonly partial: "还有 {count} 次工具调用没有拿到结果,这里是已知耗时的下限";
|
|
97
|
+
readonly empty: "当前窗口里还没有可以测量的步骤。";
|
|
98
|
+
readonly loadOlder: "加载更早";
|
|
99
|
+
readonly 'loadOlder.loading': "正在加载更早的轮次…";
|
|
100
|
+
readonly 'loadOlder.done': "已经是最早的记录";
|
|
101
|
+
readonly 'loadOlder.failed': "加载失败,重试";
|
|
102
|
+
readonly summary: "{turns} 轮 · {steps} 步";
|
|
103
|
+
readonly 'table.showTotals': "显示合计行";
|
|
104
|
+
readonly 'contextMode.label': "上下文口径";
|
|
105
|
+
readonly 'contextMode.latest': "最新";
|
|
106
|
+
readonly 'contextMode.latest.title': "轮次行显示最后一步的提示词大小(最终上下文);合计行始终为累计值";
|
|
107
|
+
readonly 'contextMode.cumulative': "累计";
|
|
108
|
+
readonly 'contextMode.cumulative.title': "轮次行显示该轮各步提示词大小之和(累计处理量);合计行始终为累计值";
|
|
109
|
+
readonly 'totals.full': "全量合计";
|
|
110
|
+
readonly 'totals.full.title': "整段会话合计;总用时为模型用时 + 工具用时(不含跨轮空隙)";
|
|
111
|
+
readonly 'totals.window': "本窗口合计";
|
|
112
|
+
readonly 'totals.window.title': "当前已加载窗口的合计;上下文为各步累计值";
|
|
113
|
+
readonly 'expand.all': "展开全部";
|
|
114
|
+
readonly 'collapse.all': "折叠全部";
|
|
115
|
+
readonly 'turn.expand': "展开";
|
|
116
|
+
readonly 'turn.collapse': "折叠";
|
|
117
|
+
readonly 'turn.toggle.title': "展开或折叠这一轮的每一步";
|
|
118
|
+
readonly 'turn.toggle.aria': "展开或折叠第 {turn} 轮";
|
|
119
|
+
readonly 'did.answer': "回答";
|
|
120
|
+
readonly 'did.working': "生成中";
|
|
121
|
+
readonly 'did.aborted': "中断";
|
|
122
|
+
readonly 'did.more': "其他 {count} 项";
|
|
123
|
+
readonly 'did.rest': "还有 {count} 次调用";
|
|
124
|
+
readonly 'did.title': "共调用 {calls} 次:{tools}";
|
|
125
|
+
readonly 'did.retry': "重试 {count} 次";
|
|
126
|
+
readonly 'did.lines': "{lines} 行";
|
|
127
|
+
readonly 'did.lines.unit': "行";
|
|
128
|
+
readonly 'did.chars': "{chars} 字符";
|
|
129
|
+
readonly 'did.output': "→ {chars} 字符";
|
|
130
|
+
readonly 'did.total': "本步工具输出合计 {chars} 字符,会进入下一步的上下文";
|
|
131
|
+
readonly 'detail.show': "详情";
|
|
132
|
+
readonly 'detail.hide': "收起";
|
|
133
|
+
readonly 'detail.title': "点这一行展开或收起工具详情";
|
|
134
|
+
readonly 'detail.calls': "{count} 次工具调用";
|
|
135
|
+
readonly 'detail.answer': "回答";
|
|
136
|
+
readonly 'detail.answer.truncated': "回答过长,仅展示前 16,000 字符";
|
|
137
|
+
readonly 'detail.code.title': "代码块";
|
|
138
|
+
readonly 'detail.code.wrap': "自动换行";
|
|
139
|
+
readonly 'detail.code.unwrap': "不换行";
|
|
140
|
+
readonly 'detail.footnotes': "脚注";
|
|
141
|
+
readonly 'detail.copy': "复制";
|
|
142
|
+
readonly 'detail.copy.title': "复制这段正文";
|
|
143
|
+
readonly 'detail.copied': "已复制";
|
|
144
|
+
readonly 'detail.copyFailed': "复制失败";
|
|
145
|
+
readonly 'detail.chars': "{chars} 字符";
|
|
146
|
+
readonly 'detail.lines': "{lines} 行";
|
|
147
|
+
readonly 'detail.file': "文件";
|
|
148
|
+
readonly 'detail.diff': "改动对比";
|
|
149
|
+
readonly 'detail.emptyBody': "这条调用没有留下正文";
|
|
150
|
+
readonly 'detail.hidden': "还有 {count} 次调用没有列出(一步最多列 {limit} 次)";
|
|
151
|
+
readonly 'detail.args': "原始参数";
|
|
152
|
+
readonly 'detail.wrap': "换行";
|
|
153
|
+
readonly 'detail.wrap.title': "长行换行显示,不出现横向滚动";
|
|
154
|
+
readonly 'detail.raw.title': "查看原始 JSON 参数";
|
|
155
|
+
readonly 'detail.lineCap': "只显示前 {shown} 行,共 {total} 行";
|
|
156
|
+
readonly 'detail.truncated': "内容过长,这里只保留了前 {chars} 字符";
|
|
157
|
+
readonly 'tool.failed': "失败 {count}";
|
|
158
|
+
readonly 'tool.failed.title': "该步有 {count} 次工具调用返回错误结果";
|
|
159
|
+
readonly 'bar.ttft': "首 token {value}";
|
|
160
|
+
readonly 'bar.gen': "生成 {value}";
|
|
161
|
+
readonly 'bar.tool': "工具调用 {value}";
|
|
162
|
+
readonly 'bar.rest': "其余 {value}";
|
|
163
|
+
readonly 'bar.wall': "总用时 {value}";
|
|
164
|
+
readonly 'bar.running': "还没结束,这是已用时间";
|
|
165
|
+
readonly 'bar.gap': "距上一步 {value}";
|
|
166
|
+
readonly 'bar.start': "开始于 {clock}";
|
|
167
|
+
readonly 'turn.started': "这一轮开始于 {time}";
|
|
168
|
+
readonly 'turn.images': "{count} 张图";
|
|
169
|
+
readonly 'imagePreview.hint': "悬停或聚焦预览这一轮的图片,点击查看大图";
|
|
170
|
+
readonly 'imagePreview.dialog': "图片预览";
|
|
171
|
+
readonly 'imagePreview.open': "查看第 {index} 张图(共 {count} 张)";
|
|
172
|
+
readonly 'imagePreview.alt': "第 {index} 张图";
|
|
173
|
+
readonly 'imagePreview.loading': "图片加载中…";
|
|
174
|
+
readonly 'imagePreview.failed': "图片加载失败";
|
|
175
|
+
readonly 'imagePreview.retry': "重试";
|
|
176
|
+
readonly 'imagePreview.close': "关闭图片预览";
|
|
177
|
+
readonly 'steps.total': "共 {total} 步";
|
|
178
|
+
readonly 'steps.tail': "只看最新 {limit} 步";
|
|
179
|
+
readonly 'steps.all': "显示全部 {total} 步";
|
|
180
|
+
readonly 'steps.filter': "只看 {tool}";
|
|
181
|
+
readonly 'steps.clear': "取消筛选";
|
|
182
|
+
readonly 'steps.matched': "{count} 步用到 {tool}";
|
|
183
|
+
};
|
|
184
|
+
/** The performance dictionary key union. */
|
|
185
|
+
export type StatsKey = keyof typeof zh;
|
|
186
|
+
declare module '@deepseek-ai/dsh-client-ui-slots' {
|
|
187
|
+
interface LocaleNamespaceMap {
|
|
188
|
+
/** Turn and step Statistics table copy. */
|
|
189
|
+
stats: StatsKey;
|
|
190
|
+
}
|
|
191
|
+
}
|
|
192
|
+
/** Namespace-bound translator threaded through the Statistics table. */
|
|
193
|
+
export type StatsTranslate = import('@deepseek-ai/dsh-client-ui-slots').TranslateNS<typeof NS>;
|
|
194
|
+
/** English dictionary, checked complete against the Chinese source of truth. */
|
|
195
|
+
export declare const en: Record<StatsKey, string>;
|
|
196
|
+
/** Japanese dictionary, checked complete against the Chinese source of truth. */
|
|
197
|
+
export declare const ja: Record<StatsKey, string>;
|
|
198
|
+
/** Spanish dictionary. */
|
|
199
|
+
export declare const es: Record<StatsKey, string>;
|
|
200
|
+
/** French dictionary. */
|
|
201
|
+
export declare const fr: Record<StatsKey, string>;
|
|
202
|
+
/** German dictionary. */
|
|
203
|
+
export declare const de: Record<StatsKey, string>;
|
|
204
|
+
/** Russian dictionary. */
|
|
205
|
+
export declare const ru: Record<StatsKey, string>;
|
|
206
|
+
/** Portuguese dictionary. */
|
|
207
|
+
export declare const pt: Record<StatsKey, string>;
|
|
208
|
+
//# sourceMappingURL=locales.d.ts.map
|
|
@@ -0,0 +1,53 @@
|
|
|
1
|
+
/** Turn aggregation over the step metrics a window holds. */
|
|
2
|
+
import type { StatsStepMetrics, StatsTurnMetrics, StatsViewNode } from './stats-contract.ts';
|
|
3
|
+
/**
|
|
4
|
+
* Aggregate one turn's steps into the row values the table shows.
|
|
5
|
+
* @param turn - turn number.
|
|
6
|
+
* @param steps - the turn's step metrics in step order.
|
|
7
|
+
* @returns the turn row.
|
|
8
|
+
*/
|
|
9
|
+
export declare function aggregateTurn(turn: number, steps: readonly StatsStepMetrics[]): StatsTurnMetrics;
|
|
10
|
+
/**
|
|
11
|
+
* Group published nodes into ordered turns, closing each turn with its markers.
|
|
12
|
+
* Code-Mode contributions merge into the step that dispatched them, identified
|
|
13
|
+
* by the root call id the node carries.
|
|
14
|
+
* @param nodes - every node the target builder currently holds.
|
|
15
|
+
* @returns turn rows ordered oldest first.
|
|
16
|
+
*/
|
|
17
|
+
export declare function buildTurns(nodes: Iterable<StatsViewNode>): StatsTurnMetrics[];
|
|
18
|
+
/** How a turn or window aggregates prompt sizes: final prompt or cumulative processing. */
|
|
19
|
+
export type ContextMode = 'latest' | 'cumulative';
|
|
20
|
+
/** Totals over the turns loaded in the current window. */
|
|
21
|
+
export interface StatsTotals {
|
|
22
|
+
readonly turnCount: number;
|
|
23
|
+
readonly stepCount: number;
|
|
24
|
+
readonly context: number | null;
|
|
25
|
+
readonly output: number | null;
|
|
26
|
+
readonly cacheHit: number | null;
|
|
27
|
+
readonly cacheRead: number | null;
|
|
28
|
+
readonly cacheWrite: number | null;
|
|
29
|
+
readonly cacheContext: number | null;
|
|
30
|
+
readonly ttft: number | null;
|
|
31
|
+
readonly ttftPending: number;
|
|
32
|
+
readonly model: number | null;
|
|
33
|
+
readonly modelPending: number;
|
|
34
|
+
readonly tps: number | null;
|
|
35
|
+
readonly tool: number | null;
|
|
36
|
+
readonly toolPending: number;
|
|
37
|
+
readonly toolWall: number | null;
|
|
38
|
+
readonly wall: number | null;
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* Context of one turn under the selected basis.
|
|
42
|
+
* @param turn - aggregated turn.
|
|
43
|
+
* @param mode - latest final prompt size, or the sum of its step prompt sizes.
|
|
44
|
+
* @returns the context tokens, or null when no step measured one.
|
|
45
|
+
*/
|
|
46
|
+
export declare function turnContext(turn: StatsTurnMetrics, mode: ContextMode): number | null;
|
|
47
|
+
/**
|
|
48
|
+
* Aggregate the loaded turns into one totals row.
|
|
49
|
+
* @param turns - aggregated turns in display order.
|
|
50
|
+
* @returns summed metrics; the context column is always the cumulative step context.
|
|
51
|
+
*/
|
|
52
|
+
export declare function aggregateTotals(turns: readonly StatsTurnMetrics[]): StatsTotals;
|
|
53
|
+
//# sourceMappingURL=stats-aggregate.d.ts.map
|
|
@@ -0,0 +1,32 @@
|
|
|
1
|
+
/** Compaction transaction state and its presentation as a synthetic step row. */
|
|
2
|
+
import type { ConversationNodeDefinition } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
3
|
+
import type { StatsCompactionMetrics, StatsCompactionState } from './stats-contract.ts';
|
|
4
|
+
/** Event shape a Conversation Definition receives. */
|
|
5
|
+
type MatchEvent = Parameters<ConversationNodeDefinition['match']>[0];
|
|
6
|
+
/**
|
|
7
|
+
* Compaction id an event names.
|
|
8
|
+
* @param event - event seen by the Definition match.
|
|
9
|
+
* @returns the nonempty compaction id, or null for events outside a transaction.
|
|
10
|
+
*/
|
|
11
|
+
export declare function compactionEventId(event: MatchEvent): string | null;
|
|
12
|
+
/**
|
|
13
|
+
* Start state for one `compaction/start`.
|
|
14
|
+
* @param event - the start event.
|
|
15
|
+
* @returns state that later summary and end events refine.
|
|
16
|
+
*/
|
|
17
|
+
export declare function newCompactionState(event: MatchEvent): StatsCompactionState;
|
|
18
|
+
/**
|
|
19
|
+
* Fold the summary or end of a compaction into its state.
|
|
20
|
+
* @param state - state opened by compaction/start.
|
|
21
|
+
* @param event - a matching compaction event.
|
|
22
|
+
* @returns state after the event, or the same state for unrelated events.
|
|
23
|
+
*/
|
|
24
|
+
export declare function foldCompaction(state: StatsCompactionState, event: MatchEvent): StatsCompactionState;
|
|
25
|
+
/**
|
|
26
|
+
* View metrics of one compaction transaction.
|
|
27
|
+
* @param state - folded compaction state.
|
|
28
|
+
* @returns the row values; unavailable measurements stay null.
|
|
29
|
+
*/
|
|
30
|
+
export declare function compactionMetrics(state: StatsCompactionState): StatsCompactionMetrics;
|
|
31
|
+
export {};
|
|
32
|
+
//# sourceMappingURL=stats-compaction.d.ts.map
|