@deepseek-ai/dsh-client-ui-trajectory 0.2.1-alpha.1 → 0.2.1-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/README.i18n.yaml +6 -6
- package/README.md +4 -2
- package/README.zh.md +4 -2
- package/lib/client.js +60 -43
- package/lib/types/client/locales.d.ts +1 -1
- package/lib/types/client/trajectory-contract.d.ts +7 -3
- package/lib/types/client/trajectory-record.d.ts +1 -1
- package/package.json +21 -21
package/README.i18n.yaml
CHANGED
|
@@ -18,14 +18,14 @@
|
|
|
18
18
|
en: 4bd17d05b8385675
|
|
19
19
|
zh: 5174e27f754f2a03
|
|
20
20
|
/deepseek-ai-dsh-client-ui-trajectory/use-this-package/inspecting-records:
|
|
21
|
-
en:
|
|
22
|
-
zh:
|
|
21
|
+
en: e4ba2d9cab2fb258
|
|
22
|
+
zh: 7db041270420b2ba
|
|
23
23
|
/deepseek-ai-dsh-client-ui-trajectory/use-this-package/the-timing-overview:
|
|
24
|
-
en:
|
|
25
|
-
zh:
|
|
24
|
+
en: 0f4ee2189324ac06
|
|
25
|
+
zh: 12e76fed22c09bc1
|
|
26
26
|
/deepseek-ai-dsh-client-ui-trajectory/understand-the-implementation:
|
|
27
|
-
en:
|
|
28
|
-
zh:
|
|
27
|
+
en: 74cc8fc87241da34
|
|
28
|
+
zh: cd72ff9c0fdd2575
|
|
29
29
|
/deepseek-ai-dsh-client-ui-trajectory/understand-the-implementation/virtual-rows:
|
|
30
30
|
en: c85e342bc7eee4e6
|
|
31
31
|
zh: 9feab66ef1755b94
|
package/README.md
CHANGED
|
@@ -35,11 +35,13 @@ Selection, timeline navigation, folding, and search cover the React-visible wind
|
|
|
35
35
|
|
|
36
36
|
Summary and Preview share one ordered attachment list after the message text, preserving repeated references. Each row shows a contained image thumbnail or file-type icon, the recorded filename (a localized numbered label for unnamed images), and recorded size, type, and image dimensions where available. Zero-byte files retain their size, and truncated filenames expose the full name in a tooltip. Images open the existing lightbox. Raw keeps content-block order and unrendered text, with images and files in initially collapsed disclosures containing their complete recorded fields.
|
|
37
37
|
|
|
38
|
+
Requests remain pending while awaiting output, streaming, or retrying. A request without assistant output has no result link; interrupted output remains inspectable and both the request and assistant record show failure, including when the Step start is outside the loaded history. Retry counts and the last attempt error remain available after recovery; they do not change the current request status. A completed model response does not imply that its tools or turn have finished.
|
|
39
|
+
|
|
38
40
|
Thinking in the inspector uses compact Markdown at the inspector's fixed 13px size and 20px line height, independent of the content-size setting. Headings add bold weight without increasing size or line height. Assistant output keeps its regular Markdown typography.
|
|
39
41
|
|
|
40
42
|
### The timing overview
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
Streaming replies retain their known start time and TTFT. After settlement, token timestamps provide generation duration; throughput also requires recorded usage. Historical replies retain the same recorded timing. TTFT measures from the Step start to its first token, including output from an earlier retry attempt; an unloaded Step start or a stream without tokens leaves the corresponding metric unavailable.
|
|
43
45
|
|
|
44
46
|
A fixed Overview above the ledger projects real record start/duration timing from left to right; Assistant spans divide recorded TTFT from decoding, and a 500 ms hover reveals exact clock and duration details. Dragging an interval focuses the ledger on every record active at any point in that inclusive range; wheel gestures zoom the time domain; a right-button click clears the selected interval, and a right-button drag pans an already zoomed viewport. The initial view and streaming updates stay at the tail; scrolling upward suspends following so new records do not interrupt inspection of earlier rows.
|
|
45
47
|
|
|
@@ -53,7 +55,7 @@ A fixed Overview above the ledger projects real record start/duration timing fro
|
|
|
53
55
|
|
|
54
56
|
The view is a pure projection: Trajectory-owned Definitions assemble business records from the shared Session window — including durable cancellation-finalized prefixes, chunk-only interruption fallbacks, and interrupted Tool records — so Trajectory neither reads nor changes the Chat conversation snapshot. Its steering classifier retains only next-step Inbox IDs through persistent splice state and shares each current claimed batch across later Contexts.
|
|
55
57
|
|
|
56
|
-
Native and nested PTC Tool results retain their raw structured error details. Failed records show the error code in the ledger and the error name and code in the inspector.
|
|
58
|
+
Native and nested PTC Tool results retain their raw structured error details and presentation metadata. Failed records show the error code in the ledger and the error name and code in the inspector.
|
|
57
59
|
|
|
58
60
|
Tool records begin at durable tool/call events and retain complete argument text with a lazy `args` view, reused by paired results. Chat's transient preparing stage does not create Trajectory tool rows or alter historical tool timing.
|
|
59
61
|
|
package/README.zh.md
CHANGED
|
@@ -35,11 +35,13 @@ Trajectory 标签页让你以按轮次组织的事件记录表和交互式时间
|
|
|
35
35
|
|
|
36
36
|
概述与预览共用正文之后的有序附件列表,保留重复引用。每行展示完整缩放的图片缩略图或文件类型图标、已记录的文件名(未命名图片使用本地化的编号名称),以及可用的已记录大小、类型和图片尺寸。零字节文件保留大小显示,截断的文件名通过提示显示完整名称。图片打开现有灯箱。原始内容保留内容块顺序和未渲染文本,图片与文件使用默认折叠的展开项,包含完整的已记录字段。
|
|
37
37
|
|
|
38
|
+
请求在等待输出、流式生成或重试期间保持等待状态。尚无助手输出的请求不提供结果链接;中断的输出仍可检查,请求和助手记录都显示失败,即使步骤起点位于已加载历史之外。恢复后仍可查看重试次数与上次尝试错误;这些历史信息不改变请求当前的状态。模型回复完成并不表示其工具或轮次已经结束。
|
|
39
|
+
|
|
38
40
|
检查器中的思考内容使用紧凑 Markdown,沿用检查器固定的 13px 字号和 20px 行高,不受内容字号设置影响。标题只加粗,不放大字号或行高。助手输出保留常规 Markdown 排版。
|
|
39
41
|
|
|
40
42
|
### 时间概览
|
|
41
43
|
|
|
42
|
-
|
|
44
|
+
流式回复保留已知的开始时间与 TTFT。回复结束后,token 时间戳用于计算生成耗时;吞吐量还需要已记录的用量。历史回复保留相同的已记录计时。TTFT 从步骤开始计量到首个 token,包括更早重试尝试中的输出;步骤起点尚未加载或流中没有 token 时,对应指标保持不可用。
|
|
43
45
|
|
|
44
46
|
固定在记录表上方的 Overview 区域从左到右投影记录的真实开始时间与耗时;助手时间条区分记录到的 TTFT 与解码时间,悬停 500 ms 后可查看精确时刻与耗时详情。拖选区间会把记录表聚焦到该闭区间内任何时刻处于活动的记录;滚轮手势用于缩放时间域;右键单击会清除所选区间,在已放大的视口上按住右键拖动则会平移。初始视图与流式更新都停留在尾部;向上滚动会暂停跟随,因此新记录不会打断对旧记录的检查。
|
|
45
47
|
|
|
@@ -53,7 +55,7 @@ Trajectory 标签页让你以按轮次组织的事件记录表和交互式时间
|
|
|
53
55
|
|
|
54
56
|
视图是纯投影:Trajectory 自有的定义从共享会话窗口组装业务记录——包括因取消而定稿并持久保留的前缀、仅有分片时采用的中断回退记录,以及被中断的工具记录——因此 Trajectory 既不读取也不改变 Chat 会话快照。其 steering(中途引导)分类器通过持续保留的拼接状态只保留下一步的 Inbox ID,并让后续上下文共享当前已认领的每个批次。
|
|
55
57
|
|
|
56
|
-
原生与嵌套 PTC
|
|
58
|
+
原生与嵌套 PTC 工具结果保留原始结构化错误详情和展示元数据。失败记录在记录表中显示错误代码,在检查器中显示错误名称和代码。
|
|
57
59
|
|
|
58
60
|
工具记录从持久 tool/call 事件开始,保留完整参数文本和由配对结果复用的懒计算 `args` 视图。Chat 的瞬态 preparing 阶段不创建 Trajectory 工具行,也不改变历史工具计时。
|
|
59
61
|
|
package/lib/client.js
CHANGED
|
@@ -211,9 +211,9 @@ window.__ModuleLoader__.load({
|
|
|
211
211
|
"details.toolCalls": "工具调用",
|
|
212
212
|
"details.subtoolCalls": "子工具调用",
|
|
213
213
|
"details.error": "错误",
|
|
214
|
+
"details.lastAttemptError": "上次尝试错误",
|
|
214
215
|
"details.failure.auth": "API 密钥无效",
|
|
215
216
|
"details.retry": "重试",
|
|
216
|
-
"details.scheduled": "已计划",
|
|
217
217
|
"details.retryDelay": "重试延迟",
|
|
218
218
|
"details.result": "结果",
|
|
219
219
|
"details.compacted": "已压缩",
|
|
@@ -406,9 +406,9 @@ window.__ModuleLoader__.load({
|
|
|
406
406
|
"details.toolCalls": "Tool calls",
|
|
407
407
|
"details.subtoolCalls": "Subtool calls",
|
|
408
408
|
"details.error": "Error",
|
|
409
|
+
"details.lastAttemptError": "Last attempt error",
|
|
409
410
|
"details.failure.auth": "API key is invalid",
|
|
410
411
|
"details.retry": "Retry",
|
|
411
|
-
"details.scheduled": "Scheduled",
|
|
412
412
|
"details.retryDelay": "Retry delay",
|
|
413
413
|
"details.result": "Result",
|
|
414
414
|
"details.compacted": "Compacted",
|
|
@@ -1334,7 +1334,6 @@ window.__ModuleLoader__.load({
|
|
|
1334
1334
|
startSeq,
|
|
1335
1335
|
startTime,
|
|
1336
1336
|
started,
|
|
1337
|
-
sawChunk: false,
|
|
1338
1337
|
blocks: [],
|
|
1339
1338
|
visibleBlocks: 0,
|
|
1340
1339
|
firstVisibleSeq: void 0,
|
|
@@ -1377,7 +1376,6 @@ window.__ModuleLoader__.load({
|
|
|
1377
1376
|
function updateChunk(state, chunk, seq, time) {
|
|
1378
1377
|
if (chunk.type === "usage") return {
|
|
1379
1378
|
...state,
|
|
1380
|
-
sawChunk: true,
|
|
1381
1379
|
usage: addUsage$1(state.usage, chunk.usage)
|
|
1382
1380
|
};
|
|
1383
1381
|
const blocks = [...state.blocks];
|
|
@@ -1432,15 +1430,11 @@ window.__ModuleLoader__.load({
|
|
|
1432
1430
|
previousVisible = blockIsVisible(blocks[chunk.index]);
|
|
1433
1431
|
blocks[chunk.index] = toAssistantBlock(chunk.block);
|
|
1434
1432
|
break;
|
|
1435
|
-
default: return
|
|
1436
|
-
...state,
|
|
1437
|
-
sawChunk: true
|
|
1438
|
-
};
|
|
1433
|
+
default: return state;
|
|
1439
1434
|
}
|
|
1440
1435
|
const visibleBlocks = state.visibleBlocks - Number(previousVisible) + Number(blockIsVisible(blocks[changedIndex]));
|
|
1441
1436
|
return {
|
|
1442
1437
|
...state,
|
|
1443
|
-
sawChunk: true,
|
|
1444
1438
|
blocks,
|
|
1445
1439
|
visibleBlocks,
|
|
1446
1440
|
...visibleBlocks > 0 && state.firstVisibleSeq === void 0 ? {
|
|
@@ -1461,7 +1455,6 @@ window.__ModuleLoader__.load({
|
|
|
1461
1455
|
const blocks = toAssistantBlocks(event.data.message.content);
|
|
1462
1456
|
return {
|
|
1463
1457
|
...settleTiming(state, event),
|
|
1464
|
-
sawChunk: false,
|
|
1465
1458
|
blocks,
|
|
1466
1459
|
visibleBlocks: countVisibleBlocks(blocks),
|
|
1467
1460
|
final: match,
|
|
@@ -1535,7 +1528,7 @@ window.__ModuleLoader__.load({
|
|
|
1535
1528
|
}
|
|
1536
1529
|
function assistantRequest(state, node, boundary) {
|
|
1537
1530
|
if (!state.started) return void 0;
|
|
1538
|
-
const status = node !== void 0
|
|
1531
|
+
const status = node !== void 0 ? node.interrupted === true ? "error" : "complete" : boundary !== void 0 ? "error" : "running";
|
|
1539
1532
|
return {
|
|
1540
1533
|
purpose: "assistant",
|
|
1541
1534
|
startSeq: state.startSeq,
|
|
@@ -1612,10 +1605,14 @@ window.__ModuleLoader__.load({
|
|
|
1612
1605
|
if (state === void 0) return null;
|
|
1613
1606
|
const node = finalNode(state, context);
|
|
1614
1607
|
const boundary = closedBoundary(context);
|
|
1615
|
-
const partial = node === void 0 && boundary === void 0 && state.
|
|
1608
|
+
const partial = node === void 0 && boundary === void 0 && state.blocks.length > 0 ? {
|
|
1616
1609
|
turn: state.turn,
|
|
1617
1610
|
step: state.step,
|
|
1618
|
-
blocks: compactBlocks(state.blocks)
|
|
1611
|
+
blocks: compactBlocks(state.blocks),
|
|
1612
|
+
timing: {
|
|
1613
|
+
stepStartTime: state.started ? state.startTime : null,
|
|
1614
|
+
firstTokenTime: state.firstTokenTime ?? null
|
|
1615
|
+
}
|
|
1619
1616
|
} : null;
|
|
1620
1617
|
const request = assistantRequest(state, node, boundary);
|
|
1621
1618
|
if (node === void 0 && partial === null && request === void 0) return null;
|
|
@@ -2360,6 +2357,7 @@ window.__ModuleLoader__.load({
|
|
|
2360
2357
|
},
|
|
2361
2358
|
callTime: previous === void 0 || "kind" in previous ? null : previous.time,
|
|
2362
2359
|
content: data.content ?? [],
|
|
2360
|
+
meta: data.meta,
|
|
2363
2361
|
isError: data.isError === true,
|
|
2364
2362
|
...data.error === void 0 ? {} : { error: data.error },
|
|
2365
2363
|
subCalls: []
|
|
@@ -2540,7 +2538,7 @@ window.__ModuleLoader__.load({
|
|
|
2540
2538
|
ctx.uiConversation.events.register(trajectoryToolDefinition);
|
|
2541
2539
|
}
|
|
2542
2540
|
//#endregion
|
|
2543
|
-
//#region ../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.
|
|
2541
|
+
//#region ../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.8/node_modules/@tanstack/virtual-core/dist/esm/lazy-measurements.js
|
|
2544
2542
|
function createLazyMeasurementsView(count, flat, getItemKey) {
|
|
2545
2543
|
const cache = new Array(count);
|
|
2546
2544
|
return new Proxy(cache, { get(target, prop, receiver) {
|
|
@@ -2570,7 +2568,7 @@ window.__ModuleLoader__.load({
|
|
|
2570
2568
|
} });
|
|
2571
2569
|
}
|
|
2572
2570
|
//#endregion
|
|
2573
|
-
//#region ../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.
|
|
2571
|
+
//#region ../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.8/node_modules/@tanstack/virtual-core/dist/esm/utils.js
|
|
2574
2572
|
function memo$1(getDeps, fn, opts) {
|
|
2575
2573
|
let deps = opts.initialDeps ?? [];
|
|
2576
2574
|
let result;
|
|
@@ -2596,13 +2594,15 @@ window.__ModuleLoader__.load({
|
|
|
2596
2594
|
const approxEqual = (a, b) => Math.abs(a - b) < 1.01;
|
|
2597
2595
|
const debounce = (targetWindow, fn, ms) => {
|
|
2598
2596
|
let timeoutId;
|
|
2599
|
-
return function(...args) {
|
|
2597
|
+
return Object.assign(function(...args) {
|
|
2600
2598
|
targetWindow.clearTimeout(timeoutId);
|
|
2601
2599
|
timeoutId = targetWindow.setTimeout(() => fn.apply(this, args), ms);
|
|
2602
|
-
}
|
|
2600
|
+
}, { cancel: () => {
|
|
2601
|
+
targetWindow.clearTimeout(timeoutId);
|
|
2602
|
+
} });
|
|
2603
2603
|
};
|
|
2604
2604
|
//#endregion
|
|
2605
|
-
//#region ../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.
|
|
2605
|
+
//#region ../../../node_modules/.pnpm/@tanstack+virtual-core@3.17.8/node_modules/@tanstack/virtual-core/dist/esm/index.js
|
|
2606
2606
|
let _isIOSResult;
|
|
2607
2607
|
const isIOSWebKit = () => {
|
|
2608
2608
|
if (_isIOSResult !== void 0) return _isIOSResult;
|
|
@@ -2684,6 +2684,7 @@ window.__ModuleLoader__.load({
|
|
|
2684
2684
|
return () => {
|
|
2685
2685
|
element.removeEventListener("scroll", handler);
|
|
2686
2686
|
if (registerScrollendEvent) element.removeEventListener("scrollend", endHandler);
|
|
2687
|
+
fallback?.cancel();
|
|
2687
2688
|
};
|
|
2688
2689
|
};
|
|
2689
2690
|
const observeElementOffset = (instance, cb) => observeOffset(instance, cb, (el) => {
|
|
@@ -2765,6 +2766,7 @@ window.__ModuleLoader__.load({
|
|
|
2765
2766
|
}
|
|
2766
2767
|
return;
|
|
2767
2768
|
}
|
|
2769
|
+
if (!this.isIndexInRange(index)) return;
|
|
2768
2770
|
if (this.shouldMeasureDuringScroll(index)) this.resizeItem(index, this.options.measureElement(node, entry, this));
|
|
2769
2771
|
};
|
|
2770
2772
|
this.options.useAnimationFrameWithResizeObserver ? requestAnimationFrame(run) : run();
|
|
@@ -2908,6 +2910,8 @@ window.__ModuleLoader__.load({
|
|
|
2908
2910
|
this.rafId = null;
|
|
2909
2911
|
}
|
|
2910
2912
|
this.scrollState = null;
|
|
2913
|
+
this.isScrolling = false;
|
|
2914
|
+
this.scrollDirection = null;
|
|
2911
2915
|
this._iosDeferredAdjustment = 0;
|
|
2912
2916
|
this._iosTouching = false;
|
|
2913
2917
|
this._iosJustTouchEnded = false;
|
|
@@ -3060,6 +3064,7 @@ window.__ModuleLoader__.load({
|
|
|
3060
3064
|
gap
|
|
3061
3065
|
};
|
|
3062
3066
|
}, { key: false });
|
|
3067
|
+
this.isIndexInRange = (index) => index >= 0 && index < this.options.count;
|
|
3063
3068
|
this.getMeasurements = memo$1(() => [this.getMeasurementOptions(), this.itemSizeCacheVersion], ({ count, paddingStart, scrollMargin, getItemKey, enabled, lanes, laneAssignmentMode, gap }, _itemSizeCacheVersion) => {
|
|
3064
3069
|
const itemSizeCache = this.itemSizeCache;
|
|
3065
3070
|
if (!enabled) {
|
|
@@ -3258,6 +3263,7 @@ window.__ModuleLoader__.load({
|
|
|
3258
3263
|
return;
|
|
3259
3264
|
}
|
|
3260
3265
|
const index = this.indexFromElement(node);
|
|
3266
|
+
if (!this.isIndexInRange(index)) return;
|
|
3261
3267
|
const key = this.options.getItemKey(index);
|
|
3262
3268
|
const prevNode = this.elementsCache.get(key);
|
|
3263
3269
|
if (prevNode !== node) {
|
|
@@ -3269,7 +3275,7 @@ window.__ModuleLoader__.load({
|
|
|
3269
3275
|
};
|
|
3270
3276
|
this.resizeItem = (index, size) => {
|
|
3271
3277
|
var _a, _b;
|
|
3272
|
-
if (
|
|
3278
|
+
if (!this.isIndexInRange(index)) return;
|
|
3273
3279
|
let cachedSize;
|
|
3274
3280
|
let itemStart;
|
|
3275
3281
|
let key;
|
|
@@ -3616,7 +3622,7 @@ window.__ModuleLoader__.load({
|
|
|
3616
3622
|
};
|
|
3617
3623
|
}
|
|
3618
3624
|
//#endregion
|
|
3619
|
-
//#region ../../../node_modules/.pnpm/@tanstack+react-virtual@3.14.
|
|
3625
|
+
//#region ../../../node_modules/.pnpm/@tanstack+react-virtual@3.14.10_react-dom@18.3.1_react@18.3.1__react@18.3.1/node_modules/@tanstack/react-virtual/dist/esm/index.js
|
|
3620
3626
|
const useIsomorphicLayoutEffect = typeof document !== "undefined" ? react.useLayoutEffect : react.useEffect;
|
|
3621
3627
|
function useVirtualizerBase({ useFlushSync = true, directDomUpdates = false, directDomUpdatesMode = "transform", ...options }) {
|
|
3622
3628
|
const rerender = react.useReducer((x) => x + 1, 0)[1];
|
|
@@ -5056,6 +5062,7 @@ window.__ModuleLoader__.load({
|
|
|
5056
5062
|
function stateOf(record) {
|
|
5057
5063
|
if (record.cell.isError) return "error";
|
|
5058
5064
|
if (record.cell.kind === "compacted" && record.cell.timeSeconds === null) return "running";
|
|
5065
|
+
if (record.cell.assistantMetrics?.completedTime === null) return "running";
|
|
5059
5066
|
if ((record.cell.kind === "tool" || record.cell.kind === "subtool") && record.cell.outputDetail === void 0) return "running";
|
|
5060
5067
|
return "complete";
|
|
5061
5068
|
}
|
|
@@ -6216,7 +6223,7 @@ window.__ModuleLoader__.load({
|
|
|
6216
6223
|
const selectedState = selected === void 0 ? void 0 : stateOf(selected);
|
|
6217
6224
|
const selectedRequestInfo = selectedRequest === null ? void 0 : sessionRequestNumbers?.find((request) => requestIdentity(request) === selectedRequest.identity);
|
|
6218
6225
|
const selectedRequestRecords = (0, react.useMemo)(() => selectedRequestInfo === void 0 ? [] : allRecords.filter((record) => record.turn === selectedRequestInfo.turn && record.group === selectedRequestInfo.group), [allRecords, selectedRequestInfo]).map(currentRecord);
|
|
6219
|
-
const selectedRequestAssistant = selectedRequestRecords.find((record) => record.cell.kind === "message");
|
|
6226
|
+
const selectedRequestAssistant = selectedRequestRecords.find((record) => record.cell.kind === "message" && record.cell.requestOnly !== true);
|
|
6220
6227
|
const selectedRequestAnchor = selectedRequestAssistant ?? selectedRequestRecords[0];
|
|
6221
6228
|
const selectedRequestNumber = selectedRequestInfo?.number;
|
|
6222
6229
|
const selectedRequestState = selectedRequestInfo === void 0 ? void 0 : selectedRequestInfo.status ?? (selectedRequestAssistant?.cell.assistantMetrics?.completedTime === null ? "running" : selectedRequestAssistant === void 0 && selectedRequestRecords.some((record) => stateOf(record) === "running") ? "running" : "complete");
|
|
@@ -6862,18 +6869,14 @@ window.__ModuleLoader__.load({
|
|
|
6862
6869
|
(selectedRequestInfo.model ?? selectedRequestInfo.requestConfig?.model) !== void 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("details.model") }), (0, react_jsx_runtime.jsx)("dd", { children: selectedRequestInfo.model ?? selectedRequestInfo.requestConfig?.model })] }),
|
|
6863
6870
|
(0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("details.toolCalls") }), (0, react_jsx_runtime.jsx)("dd", { children: selectedRequestToolCalls })] }),
|
|
6864
6871
|
selectedRequestSubtoolCalls > 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("details.subtoolCalls") }), (0, react_jsx_runtime.jsx)("dd", { children: selectedRequestSubtoolCalls })] }),
|
|
6865
|
-
selectedRequestInfo.error !== void 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("details.error") }), (0, react_jsx_runtime.jsx)("dd", {
|
|
6866
|
-
className: TrajectoryTable_module_css_default.error,
|
|
6872
|
+
selectedRequestInfo.error !== void 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t(selectedRequestState !== "error" && selectedRequestInfo.retry !== void 0 ? "details.lastAttemptError" : "details.error") }), (0, react_jsx_runtime.jsx)("dd", {
|
|
6873
|
+
className: selectedRequestState === "error" ? TrajectoryTable_module_css_default.error : void 0,
|
|
6867
6874
|
children: requestErrorMessage(selectedRequestInfo, t)
|
|
6868
6875
|
})] }),
|
|
6869
|
-
selectedRequestInfo.retry !== void 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("details.retry") }), (0, react_jsx_runtime.
|
|
6870
|
-
|
|
6871
|
-
|
|
6872
|
-
|
|
6873
|
-
retry: selectedRequestInfo.retry,
|
|
6874
|
-
maximum: selectedRequestInfo.maxRetries
|
|
6875
|
-
})
|
|
6876
|
-
] })] }),
|
|
6876
|
+
selectedRequestInfo.retry !== void 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("details.retry") }), (0, react_jsx_runtime.jsx)("dd", { children: selectedRequestInfo.maxRetries === void 0 ? selectedRequestInfo.retry : t("request.retryProgress", {
|
|
6877
|
+
retry: selectedRequestInfo.retry,
|
|
6878
|
+
maximum: selectedRequestInfo.maxRetries
|
|
6879
|
+
}) })] }),
|
|
6877
6880
|
selectedRequestInfo.retryDelayMs !== void 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("details.retryDelay") }), (0, react_jsx_runtime.jsx)("dd", { children: formatDurationMs(selectedRequestInfo.retryDelayMs, t) })] }),
|
|
6878
6881
|
selectedRequestResult !== void 0 && (0, react_jsx_runtime.jsxs)("div", { children: [(0, react_jsx_runtime.jsx)("dt", { children: t("details.result") }), (0, react_jsx_runtime.jsx)("dd", {
|
|
6879
6882
|
className: TrajectoryTable_module_css_default.overviewParentLinks,
|
|
@@ -8322,7 +8325,10 @@ window.__ModuleLoader__.load({
|
|
|
8322
8325
|
turn: partial.turn,
|
|
8323
8326
|
step: partial.step,
|
|
8324
8327
|
blocks: partial.blocks
|
|
8325
|
-
}, index + 1, prevAbsTime, resultByCall, callStartById, callById, t, {
|
|
8328
|
+
}, index + 1, prevAbsTime, resultByCall, callStartById, callById, t, {
|
|
8329
|
+
streaming: true,
|
|
8330
|
+
timing: partial.timing
|
|
8331
|
+
}), t);
|
|
8326
8332
|
if (partial.step > 0) pushStep(partial.turn, partial.step, laidList);
|
|
8327
8333
|
else for (const laid of laidList) pushMessage(partial.turn, laid);
|
|
8328
8334
|
const last = laidList[laidList.length - 1];
|
|
@@ -8485,7 +8491,8 @@ window.__ModuleLoader__.load({
|
|
|
8485
8491
|
let index = startIndex - 1;
|
|
8486
8492
|
const usage = node.usage;
|
|
8487
8493
|
const streaming = opts?.streaming === true;
|
|
8488
|
-
const
|
|
8494
|
+
const timing = opts?.timing ?? node.timing;
|
|
8495
|
+
const recordedStart = finiteTime(timing?.stepStartTime);
|
|
8489
8496
|
const messageDuration = streaming ? null : durationSeconds(node.time, recordedStart ?? prevAbsTime);
|
|
8490
8497
|
const nodeAbs = streaming ? null : finiteTime(node.time);
|
|
8491
8498
|
const messageText = node.blocks.filter((block) => block.kind === "text" && (!streaming || block.text !== "")).map((block) => block.kind === "text" ? block.text : "").join("\n\n");
|
|
@@ -8500,14 +8507,15 @@ window.__ModuleLoader__.load({
|
|
|
8500
8507
|
...messageText !== "" ? { outputDetail: messageText } : {},
|
|
8501
8508
|
...thinkingText !== "" ? { thinkingDetail: thinkingText } : {},
|
|
8502
8509
|
sourceBlocks: node.blocks.map((block) => assistantSourceBlock(block)),
|
|
8510
|
+
...node.interrupted === true ? { isError: true } : {},
|
|
8503
8511
|
timeSeconds: messageDuration,
|
|
8504
8512
|
startedAt: recordedStart
|
|
8505
8513
|
};
|
|
8506
8514
|
attachUsage(message, usage);
|
|
8507
8515
|
message.assistantMetrics = {
|
|
8508
|
-
timingRecorded:
|
|
8509
|
-
stepStartTime:
|
|
8510
|
-
firstTokenTime:
|
|
8516
|
+
timingRecorded: timing !== void 0,
|
|
8517
|
+
stepStartTime: timing?.stepStartTime ?? null,
|
|
8518
|
+
firstTokenTime: timing?.firstTokenTime ?? null,
|
|
8511
8519
|
completedTime: streaming ? null : finiteTime(node.time),
|
|
8512
8520
|
usageProvided: usage !== void 0,
|
|
8513
8521
|
outputTokens: Number.isFinite(usage?.outputTokens) ? usage?.outputTokens ?? null : null
|
|
@@ -9060,18 +9068,21 @@ window.__ModuleLoader__.load({
|
|
|
9060
9068
|
const provider = request?.providerMetadata?.provider ?? node?.providerMetadata?.provider;
|
|
9061
9069
|
const model = request?.providerMetadata?.model ?? node?.providerMetadata?.model;
|
|
9062
9070
|
const requestConfig = request?.requestConfig ?? node?.requestConfig;
|
|
9071
|
+
const startedAt = request?.startedAt;
|
|
9072
|
+
const completedAt = request === void 0 ? node?.time : request.completedAt;
|
|
9073
|
+
const resultSeq = request?.resultSeq ?? node?.seq;
|
|
9063
9074
|
numbered.push({
|
|
9064
9075
|
seq: entry.seq,
|
|
9065
9076
|
turn,
|
|
9066
9077
|
step,
|
|
9067
9078
|
group: t("group.step", { step }),
|
|
9068
9079
|
number: index + 1,
|
|
9069
|
-
|
|
9070
|
-
...
|
|
9071
|
-
...
|
|
9080
|
+
status: request?.status ?? (node?.interrupted === true ? "error" : "complete"),
|
|
9081
|
+
...startedAt === void 0 ? {} : { startedAt },
|
|
9082
|
+
...completedAt === void 0 ? {} : { completedAt },
|
|
9072
9083
|
...request?.error === void 0 ? {} : { error: request.error },
|
|
9073
9084
|
...request?.errorCode === void 0 ? {} : { errorCode: request.errorCode },
|
|
9074
|
-
...
|
|
9085
|
+
...resultSeq === void 0 ? {} : { resultSeq },
|
|
9075
9086
|
...request?.retry === void 0 ? {} : { retry: request.retry },
|
|
9076
9087
|
...request?.maxRetries === void 0 ? {} : { maxRetries: request.maxRetries },
|
|
9077
9088
|
...request?.retryDelayMs === void 0 ? {} : { retryDelayMs: request.retryDelayMs },
|
|
@@ -9096,7 +9107,7 @@ window.__ModuleLoader__.load({
|
|
|
9096
9107
|
completedAt: request.completedAt,
|
|
9097
9108
|
...request.error === void 0 ? {} : { error: request.error },
|
|
9098
9109
|
...request.errorCode === void 0 ? {} : { errorCode: request.errorCode },
|
|
9099
|
-
resultSeq: request.startSeq,
|
|
9110
|
+
...request.status === "running" ? {} : { resultSeq: request.startSeq },
|
|
9100
9111
|
...request.providerMetadata?.provider === void 0 ? {} : { provider: request.providerMetadata.provider },
|
|
9101
9112
|
...request.providerMetadata?.model === void 0 ? {} : { model: request.providerMetadata.model },
|
|
9102
9113
|
...request.requestConfig === void 0 ? {} : { requestConfig: request.requestConfig },
|
|
@@ -9141,14 +9152,20 @@ window.__ModuleLoader__.load({
|
|
|
9141
9152
|
callSchemas,
|
|
9142
9153
|
t
|
|
9143
9154
|
]);
|
|
9155
|
+
const timelinePartialSignature = partialStructureSignature(partial);
|
|
9156
|
+
const partialStartTime = partial?.timing?.stepStartTime;
|
|
9157
|
+
const partialFirstTokenTime = partial?.timing?.firstTokenTime;
|
|
9144
9158
|
const timelinePartial = (0, react.useMemo)(() => partial === null ? null : {
|
|
9145
9159
|
turn: partial.turn,
|
|
9146
9160
|
step: partial.step,
|
|
9147
|
-
blocks: partial.blocks.map((block) => timelineBlock(block))
|
|
9161
|
+
blocks: partial.blocks.map((block) => timelineBlock(block)),
|
|
9162
|
+
...partial.timing === void 0 ? {} : { timing: partial.timing }
|
|
9148
9163
|
}, [
|
|
9149
9164
|
partialStep,
|
|
9150
9165
|
partialTurn,
|
|
9151
|
-
|
|
9166
|
+
timelinePartialSignature,
|
|
9167
|
+
partialStartTime,
|
|
9168
|
+
partialFirstTokenTime
|
|
9152
9169
|
]);
|
|
9153
9170
|
const timelineTurns = (0, react.useMemo)(() => appendTrajectoryPartialLayout(finalized.turns, timelinePartial, finalized.lastIndex, t), [
|
|
9154
9171
|
finalized,
|
|
@@ -158,9 +158,9 @@ export declare const zh: {
|
|
|
158
158
|
readonly 'details.toolCalls': "工具调用";
|
|
159
159
|
readonly 'details.subtoolCalls': "子工具调用";
|
|
160
160
|
readonly 'details.error': "错误";
|
|
161
|
+
readonly 'details.lastAttemptError': "上次尝试错误";
|
|
161
162
|
readonly 'details.failure.auth': "API 密钥无效";
|
|
162
163
|
readonly 'details.retry': "重试";
|
|
163
|
-
readonly 'details.scheduled': "已计划";
|
|
164
164
|
readonly 'details.retryDelay': "重试延迟";
|
|
165
165
|
readonly 'details.result': "结果";
|
|
166
166
|
readonly 'details.compacted': "已压缩";
|
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
import type { AssistantMessageNode, ConversationLocation, ConversationNode, ConversationPromptSnapshot, ConversationViewNode, MessageImagesOwnerProps, PartialAssistant, RequestPromptChange, RequestView, RunningToolCall, SystemPromptNode, ToolCallBlock } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
1
|
+
import type { AssistantMessageNode, AssistantTiming, ConversationLocation, ConversationNode, ConversationPromptSnapshot, ConversationViewNode, MessageImagesOwnerProps, PartialAssistant, RequestPromptChange, RequestView, RunningToolCall, SystemPromptNode, ToolCallBlock } from '@deepseek-ai/dsh-client-ui-conversation/client';
|
|
2
2
|
import type { SnapshotSelectorHook } from '@deepseek-ai/dsh-client-ui-slots';
|
|
3
3
|
/** Request-header facts retained by the Trajectory target. */
|
|
4
4
|
export interface TrajectoryRequestHeaderState {
|
|
@@ -8,6 +8,10 @@ export interface TrajectoryRequestHeaderState {
|
|
|
8
8
|
readonly change?: RequestPromptChange;
|
|
9
9
|
readonly location: ConversationLocation;
|
|
10
10
|
}
|
|
11
|
+
/** In-flight assistant output with the loaded Step start and first token timestamps. */
|
|
12
|
+
export interface TrajectoryPartialAssistant extends PartialAssistant {
|
|
13
|
+
readonly timing?: Pick<AssistantTiming, 'stepStartTime' | 'firstTokenTime'>;
|
|
14
|
+
}
|
|
11
15
|
/** One independently assembled contribution to the legacy Trajectory ledger. */
|
|
12
16
|
export type TrajectoryContribution = {
|
|
13
17
|
readonly kind: 'system-prompt';
|
|
@@ -18,7 +22,7 @@ export type TrajectoryContribution = {
|
|
|
18
22
|
} | {
|
|
19
23
|
readonly kind: 'assistant';
|
|
20
24
|
readonly node?: AssistantMessageNode;
|
|
21
|
-
readonly partial:
|
|
25
|
+
readonly partial: TrajectoryPartialAssistant | null;
|
|
22
26
|
readonly request?: Extract<RequestView, {
|
|
23
27
|
purpose: 'assistant';
|
|
24
28
|
}>;
|
|
@@ -59,7 +63,7 @@ export interface TrajectorySnapshot {
|
|
|
59
63
|
readonly eventLocations: ReadonlyMap<number, ConversationLocation>;
|
|
60
64
|
readonly requests: readonly RequestView[];
|
|
61
65
|
readonly callSchemas: ReadonlyMap<string, ConversationPromptSnapshot['tools'][number]>;
|
|
62
|
-
readonly partial:
|
|
66
|
+
readonly partial: TrajectoryPartialAssistant | null;
|
|
63
67
|
readonly runningCalls: readonly RunningToolCall[];
|
|
64
68
|
}
|
|
65
69
|
/** Selector hook over the current Conversation binding's Trajectory target. */
|
|
@@ -72,7 +72,7 @@ export interface TrajectoryCellProps extends HTMLAttributes<HTMLDivElement> {
|
|
|
72
72
|
callId?: string;
|
|
73
73
|
/** Recorded tool name; independent of the display summary. */
|
|
74
74
|
toolName?: string;
|
|
75
|
-
/**
|
|
75
|
+
/** Failed operation or interrupted assistant output. */
|
|
76
76
|
isError?: boolean;
|
|
77
77
|
/** Own duration in seconds, or `null` when no duration is known. */
|
|
78
78
|
timeSeconds: number | null;
|
package/package.json
CHANGED
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@deepseek-ai/dsh-client-ui-trajectory",
|
|
3
3
|
"description": "Trajectory event ledger with an interactive timing overview: pure-consumer plugin registering into the conversation ViewMap (no service)",
|
|
4
|
-
"version": "0.2.1-alpha.
|
|
4
|
+
"version": "0.2.1-alpha.2",
|
|
5
5
|
"publishConfig": {
|
|
6
6
|
"access": "public"
|
|
7
7
|
},
|
|
@@ -42,30 +42,30 @@
|
|
|
42
42
|
"@deepseek-ai/cordis": "~4.0.5-alpha.1"
|
|
43
43
|
},
|
|
44
44
|
"devDependencies": {
|
|
45
|
+
"@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
|
|
46
|
+
"@deepseek-ai/dsh-client-locale": "0.2.1-alpha.2",
|
|
47
|
+
"@deepseek-ai/dsh-client-test-runtime": "0.2.1-alpha.2",
|
|
48
|
+
"@deepseek-ai/dsh-client-ui-primitives": "0.2.1-alpha.2",
|
|
49
|
+
"@deepseek-ai/dsh-client-ui-conversation": "0.2.1-alpha.2",
|
|
50
|
+
"@deepseek-ai/dsh-util-values": "0.2.1-alpha.2",
|
|
51
|
+
"@deepseek-ai/dsh-client-ui-slots": "0.2.1-alpha.2",
|
|
52
|
+
"@deepseek-ai/dsh-compaction": "0.2.1-alpha.2",
|
|
53
|
+
"@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
|
|
45
54
|
"@types/react": "~18.3.1",
|
|
46
55
|
"@types/react-dom": "~18.3.0",
|
|
56
|
+
"@deepseek-ai/cordis": "~4.0.5-alpha.1",
|
|
47
57
|
"react": "^18.2.0",
|
|
48
58
|
"react-dom": "^18.2.0",
|
|
49
|
-
"@
|
|
50
|
-
"
|
|
51
|
-
"@deepseek-ai/dsh-
|
|
52
|
-
"@deepseek-ai/dsh-
|
|
53
|
-
"@deepseek-ai/dsh-client-
|
|
54
|
-
"@deepseek-ai/dsh-client-ui-
|
|
55
|
-
"@deepseek-ai/dsh-
|
|
56
|
-
"@deepseek-ai/dsh-
|
|
57
|
-
"@
|
|
58
|
-
"
|
|
59
|
-
"@deepseek-ai/dsh-tools": "0.2.1-alpha.1",
|
|
60
|
-
"@deepseek-ai/dsh-client-store": "0.2.1-alpha.1",
|
|
61
|
-
"@deepseek-ai/dsh-client-ui-chat": "0.2.1-alpha.1",
|
|
62
|
-
"@deepseek-ai/dsh-session": "0.2.1-alpha.1",
|
|
63
|
-
"@deepseek-ai/dsh-api-session-controller": "0.2.1-alpha.1",
|
|
64
|
-
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.1",
|
|
65
|
-
"@deepseek-ai/cordis": "~4.0.5-alpha.1",
|
|
66
|
-
"@deepseek-ai/dsh-attachment": "0.2.1-alpha.1",
|
|
67
|
-
"@deepseek-ai/dsh-client-ui-session": "0.2.1-alpha.1",
|
|
68
|
-
"@deepseek-ai/dsh-llm": "0.2.1-alpha.1"
|
|
59
|
+
"@deepseek-ai/dsh-client-store": "0.2.1-alpha.2",
|
|
60
|
+
"@deepseek-ai/dsh-client-ui-chat": "0.2.1-alpha.2",
|
|
61
|
+
"@deepseek-ai/dsh-session": "0.2.1-alpha.2",
|
|
62
|
+
"@deepseek-ai/dsh-api-session-controller": "0.2.1-alpha.2",
|
|
63
|
+
"@deepseek-ai/dsh-client-ui-renderer": "0.2.1-alpha.2",
|
|
64
|
+
"@deepseek-ai/dsh-client-ui-session": "0.2.1-alpha.2",
|
|
65
|
+
"@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
|
|
66
|
+
"@deepseek-ai/dsh-attachment": "0.2.1-alpha.2",
|
|
67
|
+
"@tanstack/react-virtual": "^3.14.10",
|
|
68
|
+
"diff": "^9.0.0"
|
|
69
69
|
},
|
|
70
70
|
"files": [
|
|
71
71
|
"lib/index.js",
|