@qilin-agent/client-ui-trajectory 3.1.3 → 3.1.4

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 CHANGED
@@ -5,51 +5,51 @@
5
5
  /:
6
6
  en: 9e8cf8f505740df9
7
7
  zh: ce5eda3f87570baf
8
- /qilin-client-ui-trajectory:
9
- en: fb20e7b922f0f731
10
- zh: 987ca19ee4d52646
11
- /qilin-client-ui-trajectory/summary:
8
+ /qilin-agent-client-ui-trajectory:
9
+ en: 81250b716b1c11d9
10
+ zh: 5cc8452664d26739
11
+ /qilin-agent-client-ui-trajectory/summary:
12
12
  en: 44c94ae942ec0e48
13
13
  zh: 228a55690253f89f
14
- /qilin-client-ui-trajectory/table-of-contents:
14
+ /qilin-agent-client-ui-trajectory/table-of-contents:
15
15
  en: d152484eb41ac6b4
16
16
  zh: 09388d293f9be9cb
17
- /qilin-client-ui-trajectory/use-this-package:
17
+ /qilin-agent-client-ui-trajectory/use-this-package:
18
18
  en: d8bfe28896432de7
19
19
  zh: 27c883954a31f68f
20
- /qilin-client-ui-trajectory/use-this-package/inspecting-records:
21
- en: f739d398277793f6
22
- zh: 1b8b4c7d9df17f1f
23
- /qilin-client-ui-trajectory/use-this-package/the-timing-overview:
20
+ /qilin-agent-client-ui-trajectory/use-this-package/inspecting-records:
21
+ en: b62f418514e57a53
22
+ zh: 94b532cfb9e6e1d4
23
+ /qilin-agent-client-ui-trajectory/use-this-package/the-timing-overview:
24
24
  en: ed6608646aa6f081
25
25
  zh: 00755f8b4da6018e
26
- /qilin-client-ui-trajectory/use-this-package/the-graph-view:
26
+ /qilin-agent-client-ui-trajectory/use-this-package/the-graph-view:
27
27
  en: eb406a5bbe187f0c
28
28
  zh: 60261fefa130800c
29
- /qilin-client-ui-trajectory/understand-the-implementation:
30
- en: 25d6535322df684f
31
- zh: d60d3bd4201e65ce
32
- /qilin-client-ui-trajectory/understand-the-implementation/the-graph-projection:
29
+ /qilin-agent-client-ui-trajectory/understand-the-implementation:
30
+ en: 9f2ca8fa5fa608f1
31
+ zh: 893c0c6d9be59b3c
32
+ /qilin-agent-client-ui-trajectory/understand-the-implementation/the-graph-projection:
33
33
  en: 06806617ca60efd4
34
34
  zh: 5596f32b758ee42f
35
- /qilin-client-ui-trajectory/understand-the-implementation/virtual-rows:
35
+ /qilin-agent-client-ui-trajectory/understand-the-implementation/virtual-rows:
36
36
  en: c85e342bc7eee4e6
37
37
  zh: 3120813991ee7b4c
38
- /qilin-client-ui-trajectory/understand-the-implementation/layout:
38
+ /qilin-agent-client-ui-trajectory/understand-the-implementation/layout:
39
39
  en: d7128b491c4f7d83
40
40
  zh: 2b5153f5f8ffc0a5
41
- /qilin-client-ui-trajectory/further-exploration:
41
+ /qilin-agent-client-ui-trajectory/further-exploration:
42
42
  en: 988b0137733592a2
43
43
  zh: 676c63da1da83fe9
44
- /qilin-client-ui-trajectory/model-experience:
44
+ /qilin-agent-client-ui-trajectory/model-experience:
45
45
  en: 3120df665299c634
46
46
  zh: 1d9f365d091d0d2a
47
- /qilin-client-ui-trajectory/model-experience/kv-cache-effect:
47
+ /qilin-agent-client-ui-trajectory/model-experience/kv-cache-effect:
48
48
  en: ca75c51c89c2c9b0
49
49
  zh: de54f3467ef3b9be
50
- /qilin-client-ui-trajectory/known-limitations-and-deferred-work:
50
+ /qilin-agent-client-ui-trajectory/known-limitations-and-deferred-work:
51
51
  en: 8db16dd7764e28b3
52
52
  zh: 1a8ad2cbd3bd9ae1
53
- /qilin-client-ui-trajectory/known-limitations-and-deferred-work/dev-note:
53
+ /qilin-agent-client-ui-trajectory/known-limitations-and-deferred-work/dev-note:
54
54
  en: e67f633dc6fe7773
55
55
  zh: 3bb0c20c93f16f98
package/README.md CHANGED
@@ -35,6 +35,10 @@ 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
+
40
+ Streaming replies retain their known start time and TTFT. After settlement, token timestamps provide generation duration, and throughput additionally requires recorded usage.
41
+
38
42
  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
43
 
40
44
  ### The timing overview
@@ -55,7 +59,7 @@ The Trajectory graph page opens from the guide box's `trajectory-graph` entry an
55
59
 
56
60
  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.
57
61
 
58
- Tool records begin at durable tool/call events and use complete arguments. Chat's transient preparing stage does not create Trajectory tool rows or alter historical tool timing.
62
+ Tool records begin at durable tool/call events and use complete arguments. Trajectory retains each native and nested Tool result's event presentation metadata, so historical file and command locations come from the operation itself. Chat's transient preparing stage does not create Trajectory tool rows or alter historical tool timing.
59
63
 
60
64
  A complete appended prompt without a loaded request header appears as a standalone system row; only its known text is available, with no inferred request options or tool catalog. Prepending its request history replaces that standalone presentation without duplicating the prompt. In-history system prompt changes compare against the most recent request state, including earlier prompt updates without a new request header. Each request retains the prompt and change that applied at its own position. Surface replacements, including compaction, restore the last nonempty surviving system prompt even without a new system event; an unloaded prompt remains unavailable until its page arrives.
61
65
 
package/README.zh.md CHANGED
@@ -35,6 +35,10 @@ kind: "package-reference"
35
35
 
36
36
  概述与预览共用正文之后的有序附件列表,保留重复引用。每行展示完整缩放的图片缩略图或文件类型图标、已记录的文件名(未命名图片使用本地化的编号名称),以及可用的已记录大小、类型和图片尺寸。零字节文件保留大小显示,截断的文件名通过提示显示完整名称。图片打开现有灯箱。原始内容保留内容块顺序和未渲染文本,图片与文件使用默认折叠的展开项,包含完整的已记录字段。
37
37
 
38
+ 请求在等待输出、流式生成或重试期间保持等待状态。尚无助手输出的请求不提供结果链接;中断的输出仍可检查,请求和助手记录都显示失败,即使步骤起点位于已加载历史之外。恢复后仍可查看重试次数与上次尝试错误;这些历史信息不改变请求当前的状态。模型回复完成并不表示其工具或轮次已经结束。
39
+
40
+ 流式回复保留已知的开始时间与 TTFT。结算后由 token 时间戳给出生成耗时,吞吐量还要求已记录 usage。
41
+
38
42
  检查器中的思考内容使用紧凑 Markdown,沿用检查器固定的 13px 字号和 20px 行高,不受内容字号设置影响。标题只加粗,不放大字号或行高。助手输出保留常规 Markdown 排版。
39
43
 
40
44
  ### 时间概览
@@ -55,7 +59,7 @@ kind: "package-reference"
55
59
 
56
60
  视图是纯投影:Trajectory 自有的 Definition 从共享 Session 窗口组装业务记录——包括持久化的取消定稿前缀、只能从分片恢复的打断前缀与被打断的工具记录——因此 Trajectory 既不读取也不改变 Chat 会话快照。其 steering 分类器通过持久 splice state 只保留 next-step Inbox ID,并让后续 Context 共享当前 claimed batch。
57
61
 
58
- 工具记录从持久 tool/call 事件开始,使用完整参数。Chat 的瞬态 preparing 阶段不创建 Trajectory 工具行,也不改变历史工具计时。
62
+ 工具记录从持久 tool/call 事件开始,使用完整参数。Trajectory 保留每个原生与嵌套工具结果事件中的展示元数据,因此历史文件与命令位置来自执行本身。Chat 的瞬态 preparing 阶段不创建 Trajectory 工具行,也不改变历史工具计时。
59
63
 
60
64
  完整的追加提示词在请求头未加载时显示为独立系统行;仅提供已知文本,不推断请求选项或工具目录。补入其请求历史后,该独立展示被替代而不重复提示词。历史中的系统提示词变更与最近的请求状态比较,包括没有新请求头的先前提示词更新。每个请求保留其所在位置生效的提示词与变更。包括压缩在内的 surface 替换会恢复最后一个非空的存活系统提示词,即使没有新的系统事件;未加载的提示词在对应分页到达前仍不可用。
61
65
 
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": "已压缩",
@@ -488,9 +488,9 @@ window.__ModuleLoader__.load({
488
488
  "details.toolCalls": "Tool calls",
489
489
  "details.subtoolCalls": "Subtool calls",
490
490
  "details.error": "Error",
491
+ "details.lastAttemptError": "Last attempt error",
491
492
  "details.failure.auth": "API key is invalid",
492
493
  "details.retry": "Retry",
493
- "details.scheduled": "Scheduled",
494
494
  "details.retryDelay": "Retry delay",
495
495
  "details.result": "Result",
496
496
  "details.compacted": "Compacted",
@@ -1502,7 +1502,6 @@ window.__ModuleLoader__.load({
1502
1502
  startSeq,
1503
1503
  startTime,
1504
1504
  started,
1505
- sawChunk: false,
1506
1505
  blocks: [],
1507
1506
  visibleBlocks: 0,
1508
1507
  firstVisibleSeq: void 0,
@@ -1545,7 +1544,6 @@ window.__ModuleLoader__.load({
1545
1544
  function updateChunk(state, chunk, seq, time) {
1546
1545
  if (chunk.type === "usage") return {
1547
1546
  ...state,
1548
- sawChunk: true,
1549
1547
  usage: addUsage$1(state.usage, chunk.usage)
1550
1548
  };
1551
1549
  const blocks = [...state.blocks];
@@ -1600,15 +1598,11 @@ window.__ModuleLoader__.load({
1600
1598
  previousVisible = blockIsVisible(blocks[chunk.index]);
1601
1599
  blocks[chunk.index] = toAssistantBlock(chunk.block);
1602
1600
  break;
1603
- default: return {
1604
- ...state,
1605
- sawChunk: true
1606
- };
1601
+ default: return state;
1607
1602
  }
1608
1603
  const visibleBlocks = state.visibleBlocks - Number(previousVisible) + Number(blockIsVisible(blocks[changedIndex]));
1609
1604
  return {
1610
1605
  ...state,
1611
- sawChunk: true,
1612
1606
  blocks,
1613
1607
  visibleBlocks,
1614
1608
  ...visibleBlocks > 0 && state.firstVisibleSeq === void 0 ? {
@@ -1629,7 +1623,6 @@ window.__ModuleLoader__.load({
1629
1623
  const blocks = toAssistantBlocks(event.data.message.content);
1630
1624
  return {
1631
1625
  ...settleTiming(state, event),
1632
- sawChunk: false,
1633
1626
  blocks,
1634
1627
  visibleBlocks: countVisibleBlocks(blocks),
1635
1628
  final: match,
@@ -1703,7 +1696,7 @@ window.__ModuleLoader__.load({
1703
1696
  }
1704
1697
  function assistantRequest(state, node, boundary) {
1705
1698
  if (!state.started) return void 0;
1706
- const status = node !== void 0 && node.interrupted !== true ? "complete" : state.retry !== void 0 || boundary !== void 0 ? "error" : "running";
1699
+ const status = node !== void 0 ? node.interrupted === true ? "error" : "complete" : boundary !== void 0 ? "error" : "running";
1707
1700
  return {
1708
1701
  purpose: "assistant",
1709
1702
  startSeq: state.startSeq,
@@ -1780,10 +1773,14 @@ window.__ModuleLoader__.load({
1780
1773
  if (state === void 0) return null;
1781
1774
  const node = finalNode(state, context);
1782
1775
  const boundary = closedBoundary(context);
1783
- const partial = node === void 0 && boundary === void 0 && state.sawChunk ? {
1776
+ const partial = node === void 0 && boundary === void 0 && state.blocks.length > 0 ? {
1784
1777
  turn: state.turn,
1785
1778
  step: state.step,
1786
- blocks: compactBlocks(state.blocks)
1779
+ blocks: compactBlocks(state.blocks),
1780
+ timing: {
1781
+ stepStartTime: state.started ? state.startTime : null,
1782
+ firstTokenTime: state.firstTokenTime ?? null
1783
+ }
1787
1784
  } : null;
1788
1785
  const request = assistantRequest(state, node, boundary);
1789
1786
  if (node === void 0 && partial === null && request === void 0) return null;
@@ -2527,6 +2524,7 @@ window.__ModuleLoader__.load({
2527
2524
  },
2528
2525
  callTime: previous === void 0 || "kind" in previous ? null : previous.time,
2529
2526
  content: data.content ?? [],
2527
+ meta: data.meta,
2530
2528
  isError: data.isError === true,
2531
2529
  ...data.error === void 0 ? {} : { error: data.error },
2532
2530
  subCalls: []
@@ -6415,7 +6413,7 @@ window.__ModuleLoader__.load({
6415
6413
  const selectedState = selected === void 0 ? void 0 : stateOf(selected);
6416
6414
  const selectedRequestInfo = selectedRequest === null ? void 0 : sessionRequestNumbers?.find((request) => requestIdentity(request) === selectedRequest.identity);
6417
6415
  const selectedRequestRecords = (0, react.useMemo)(() => selectedRequestInfo === void 0 ? [] : allRecords.filter((record) => record.turn === selectedRequestInfo.turn && record.group === selectedRequestInfo.group), [allRecords, selectedRequestInfo]).map(currentRecord);
6418
- const selectedRequestAssistant = selectedRequestRecords.find((record) => record.cell.kind === "message");
6416
+ const selectedRequestAssistant = selectedRequestRecords.find((record) => record.cell.kind === "message" && record.cell.requestOnly !== true);
6419
6417
  const selectedRequestAnchor = selectedRequestAssistant ?? selectedRequestRecords[0];
6420
6418
  const selectedRequestNumber = selectedRequestInfo?.number;
6421
6419
  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");
@@ -7067,18 +7065,14 @@ window.__ModuleLoader__.load({
7067
7065
  (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 })] }),
7068
7066
  (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 })] }),
7069
7067
  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 })] }),
7070
- 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", {
7071
- className: TrajectoryTable_module_css_default.error,
7068
+ 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", {
7069
+ className: selectedRequestState === "error" ? TrajectoryTable_module_css_default.error : void 0,
7072
7070
  children: requestErrorMessage(selectedRequestInfo, t)
7073
7071
  })] }),
7074
- 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.jsxs)("dd", { children: [
7075
- t("details.scheduled"),
7076
- " ",
7077
- selectedRequestInfo.maxRetries === void 0 ? selectedRequestInfo.retry : t("request.retryProgress", {
7078
- retry: selectedRequestInfo.retry,
7079
- maximum: selectedRequestInfo.maxRetries
7080
- })
7081
- ] })] }),
7072
+ 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", {
7073
+ retry: selectedRequestInfo.retry,
7074
+ maximum: selectedRequestInfo.maxRetries
7075
+ }) })] }),
7082
7076
  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) })] }),
7083
7077
  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", {
7084
7078
  className: TrajectoryTable_module_css_default.overviewParentLinks,
@@ -8527,7 +8521,10 @@ window.__ModuleLoader__.load({
8527
8521
  turn: partial.turn,
8528
8522
  step: partial.step,
8529
8523
  blocks: partial.blocks
8530
- }, index + 1, prevAbsTime, resultByCall, callStartById, callById, t, { streaming: true }), t);
8524
+ }, index + 1, prevAbsTime, resultByCall, callStartById, callById, t, {
8525
+ streaming: true,
8526
+ timing: partial.timing
8527
+ }), t);
8531
8528
  if (partial.step > 0) pushStep(partial.turn, partial.step, laidList);
8532
8529
  else for (const laid of laidList) pushMessage(partial.turn, laid);
8533
8530
  const last = laidList[laidList.length - 1];
@@ -8690,7 +8687,8 @@ window.__ModuleLoader__.load({
8690
8687
  let index = startIndex - 1;
8691
8688
  const usage = node.usage;
8692
8689
  const streaming = opts?.streaming === true;
8693
- const recordedStart = finiteTime(node.timing?.stepStartTime);
8690
+ const timing = opts?.timing ?? node.timing;
8691
+ const recordedStart = finiteTime(timing?.stepStartTime);
8694
8692
  const messageDuration = streaming ? null : durationSeconds(node.time, recordedStart ?? prevAbsTime);
8695
8693
  const nodeAbs = streaming ? null : finiteTime(node.time);
8696
8694
  const messageText = node.blocks.filter((block) => block.kind === "text" && (!streaming || block.text !== "")).map((block) => block.kind === "text" ? block.text : "").join("\n\n");
@@ -8705,14 +8703,15 @@ window.__ModuleLoader__.load({
8705
8703
  ...messageText !== "" ? { outputDetail: messageText } : {},
8706
8704
  ...thinkingText !== "" ? { thinkingDetail: thinkingText } : {},
8707
8705
  sourceBlocks: node.blocks.map((block) => assistantSourceBlock(block)),
8706
+ ...node.interrupted === true ? { isError: true } : {},
8708
8707
  timeSeconds: messageDuration,
8709
8708
  startedAt: recordedStart
8710
8709
  };
8711
8710
  attachUsage(message, usage);
8712
8711
  message.assistantMetrics = {
8713
- timingRecorded: node.timing !== void 0,
8714
- stepStartTime: node.timing?.stepStartTime ?? null,
8715
- firstTokenTime: node.timing?.firstTokenTime ?? null,
8712
+ timingRecorded: timing !== void 0,
8713
+ stepStartTime: timing?.stepStartTime ?? null,
8714
+ firstTokenTime: timing?.firstTokenTime ?? null,
8716
8715
  completedTime: streaming ? null : finiteTime(node.time),
8717
8716
  usageProvided: usage !== void 0,
8718
8717
  outputTokens: Number.isFinite(usage?.outputTokens) ? usage?.outputTokens ?? null : null
@@ -9271,18 +9270,21 @@ window.__ModuleLoader__.load({
9271
9270
  const provider = request?.providerMetadata?.provider ?? node?.providerMetadata?.provider;
9272
9271
  const model = request?.providerMetadata?.model ?? node?.providerMetadata?.model;
9273
9272
  const requestConfig = request?.requestConfig ?? node?.requestConfig;
9273
+ const startedAt = request?.startedAt ?? node?.timing?.stepStartTime;
9274
+ const completedAt = request === void 0 ? node?.time : request.completedAt;
9275
+ const resultSeq = request?.resultSeq ?? node?.seq;
9274
9276
  numbered.push({
9275
9277
  seq: entry.seq,
9276
9278
  turn,
9277
9279
  step,
9278
9280
  group: t("group.step", { step }),
9279
9281
  number: index + 1,
9280
- ...request?.status === void 0 ? {} : { status: request.status },
9281
- ...request?.startedAt === void 0 ? {} : { startedAt: request.startedAt },
9282
- ...request?.completedAt === void 0 ? {} : { completedAt: request.completedAt },
9282
+ status: request?.status ?? (node?.interrupted === true ? "error" : "complete"),
9283
+ ...startedAt == null ? {} : { startedAt },
9284
+ ...completedAt === void 0 ? {} : { completedAt },
9283
9285
  ...request?.error === void 0 ? {} : { error: request.error },
9284
9286
  ...request?.errorCode === void 0 ? {} : { errorCode: request.errorCode },
9285
- ...request?.resultSeq === void 0 ? {} : { resultSeq: request.resultSeq },
9287
+ ...resultSeq === void 0 ? {} : { resultSeq },
9286
9288
  ...request?.retry === void 0 ? {} : { retry: request.retry },
9287
9289
  ...request?.maxRetries === void 0 ? {} : { maxRetries: request.maxRetries },
9288
9290
  ...request?.retryDelayMs === void 0 ? {} : { retryDelayMs: request.retryDelayMs },
@@ -9352,14 +9354,20 @@ window.__ModuleLoader__.load({
9352
9354
  callSchemas,
9353
9355
  t
9354
9356
  ]);
9357
+ const timelinePartialSignature = partialStructureSignature(partial);
9358
+ const partialStartTime = partial?.timing?.stepStartTime;
9359
+ const partialFirstTokenTime = partial?.timing?.firstTokenTime;
9355
9360
  const timelinePartial = (0, react.useMemo)(() => partial === null ? null : {
9356
9361
  turn: partial.turn,
9357
9362
  step: partial.step,
9358
- blocks: partial.blocks.map((block) => timelineBlock(block))
9363
+ blocks: partial.blocks.map((block) => timelineBlock(block)),
9364
+ ...partial.timing === void 0 ? {} : { timing: partial.timing }
9359
9365
  }, [
9360
9366
  partialStep,
9361
9367
  partialTurn,
9362
- partialStructureSignature(partial)
9368
+ timelinePartialSignature,
9369
+ partialStartTime,
9370
+ partialFirstTokenTime
9363
9371
  ]);
9364
9372
  const timelineTurns = (0, react.useMemo)(() => appendTrajectoryPartialLayout(finalized.turns, timelinePartial, finalized.lastIndex, t), [
9365
9373
  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': "已压缩";
@@ -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<NonNullable<AssistantMessageNode['timing']>, '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: PartialAssistant | null;
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: PartialAssistant | null;
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
- /** Tool-only result failure state. */
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": "@qilin-agent/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": "3.1.3",
4
+ "version": "3.1.4",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -52,25 +52,25 @@
52
52
  "react-dom": "^18.2.0",
53
53
  "@tanstack/react-virtual": "^3.14.9",
54
54
  "diff": "^9.0.0",
55
- "@qilin-agent/agent": "3.1.3",
56
- "@qilin-agent/client-locale": "3.1.3",
57
- "@qilin-agent/client-test-runtime": "3.1.3",
58
- "@qilin-agent/client-ui-conversation": "3.1.3",
59
- "@qilin-agent/client-ui-slots": "3.1.3",
60
- "@qilin-agent/client-ui-primitives": "3.1.3",
61
- "@qilin-agent/compaction": "3.1.3",
62
- "@qilin-agent/tools": "3.1.3",
63
- "@qilin-agent/client-store": "3.1.3",
64
- "@qilin-agent/client-ui-chat": "3.1.3",
55
+ "@qilin-agent/agent": "3.1.4",
56
+ "@qilin-agent/client-ui-primitives": "3.1.4",
57
+ "@qilin-agent/client-locale": "3.1.4",
58
+ "@qilin-agent/client-test-runtime": "3.1.4",
59
+ "@qilin-agent/client-ui-slots": "3.1.4",
60
+ "@qilin-agent/client-ui-conversation": "3.1.4",
61
+ "@qilin-agent/compaction": "3.1.4",
62
+ "@qilin-agent/tools": "3.1.4",
65
63
  "@qilin-agent/kylin": "~4.0.3",
66
- "@qilin-agent/api-session-controller": "3.1.3",
67
- "@qilin-agent/client-ui-renderer": "3.1.3",
68
- "@qilin-agent/client-ui-session": "3.1.3",
69
- "@qilin-agent/llm": "3.1.3",
70
- "@qilin-agent/client-ui-sidebar-right": "3.1.3",
71
- "@qilin-agent/attachment": "3.1.3",
72
- "@qilin-agent/session": "3.1.3",
73
- "@qilin-agent/util-values": "3.1.3"
64
+ "@qilin-agent/client-ui-chat": "3.1.4",
65
+ "@qilin-agent/client-store": "3.1.4",
66
+ "@qilin-agent/session": "3.1.4",
67
+ "@qilin-agent/api-session-controller": "3.1.4",
68
+ "@qilin-agent/client-ui-renderer": "3.1.4",
69
+ "@qilin-agent/client-ui-session": "3.1.4",
70
+ "@qilin-agent/client-ui-sidebar-right": "3.1.4",
71
+ "@qilin-agent/llm": "3.1.4",
72
+ "@qilin-agent/attachment": "3.1.4",
73
+ "@qilin-agent/util-values": "3.1.4"
74
74
  },
75
75
  "files": [
76
76
  "lib/index.js",