@epoch-agent/view 0.1.0 → 0.3.1

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/dist/index.d.ts CHANGED
@@ -1,4 +1,4 @@
1
- import { ToolArtifact, AgentEvent } from '@epoch-agent/protocol';
1
+ import { WireSessionReference, WireFileReference, WireImageReference, ToolArtifact, AgentEvent } from '@epoch-agent/protocol';
2
2
 
3
3
  /**
4
4
  * 展示项类型 — 基于 Google Gemini CLI types.ts
@@ -42,6 +42,72 @@ interface HistoryItemBase {
42
42
  type HistoryItemUser = HistoryItemBase & {
43
43
  type: 'user';
44
44
  text: string;
45
+ /**
46
+ * 这条消息里 `@:` 引用到的那几段会话(方案 53 PR-4)。
47
+ *
48
+ * **缺席 = 这条消息里没有引用**,不是「有但没查到」—— 后者是数组里一条带
49
+ * `omitted` 的记录(那五个稳定错误码之一)。
50
+ *
51
+ * ## 为什么它挂在**展示项**上,而不是让浏览器自己去翻 `parts`
52
+ *
53
+ * 这一格有**两个**填它的地方,而它们拿到的东西不一样:
54
+ *
55
+ * | 谁填 | 从哪来 |
56
+ * | ------------------------ | --------------------------------------- |
57
+ * | 回放(`GET /messages`) | 那条消息的 `parts` 里 `type: 'session'` |
58
+ * | 刚发出去那一条 | `POST /messages` 的 202 上那个 `references` |
59
+ *
60
+ * 后者压根没有 `parts`(用户自己那条消息是本地乐观回显的,SSE 上不回它)。
61
+ * 两条路合到这一格之后,那张卡的渲染只有一处 —— 而它们要是各画一次,
62
+ * 刷新前后的同一条消息会长得不一样。
63
+ *
64
+ * ⚠️ **带不带正文这件事在契约那一层就定了**:`WireSessionReference` 是那个部件
65
+ * **摘掉 `text`**(判据在 protocol 的 `wire-rest.ts` 上),所以这一格上永远
66
+ * 没有另一段会话的转录 —— 那也是「这张卡不展开」的由来
67
+ * (`web/src/mention/reference-card.tsx` 的文件头)。
68
+ *
69
+ * TUI 那一侧今天不画它(方案 53 验收记录第六章:发出去之后屏幕上就是用户打的
70
+ * 那行字),所以这一格在那边恒缺席 —— 那是一次判断,不是漏接。
71
+ */
72
+ references?: readonly WireSessionReference[];
73
+ /**
74
+ * 这条消息里 `@路径` 附上的那几个文件(方案 63)。
75
+ *
76
+ * 缺席 / 两条路合到一格 / 不带正文的那三条判据**逐字同**上面 `references` 那一
77
+ * 格(`WireFileReference` 就是那个部件摘掉 `text`),这一格不再抄一遍。
78
+ * 差别只有填它的那个键:回放从 `parts` 里 `type: 'file'` 读,刚发出去那一条从
79
+ * 202 的 `files` 读(键不同、判据同一条)。
80
+ */
81
+ files?: readonly WireFileReference[];
82
+ /**
83
+ * 这条消息里附的那几张图(2026-09-01)。
84
+ *
85
+ * ## 这一格是 `state/types.ts` 和 `state/replay.ts` 记的同一笔债
86
+ *
87
+ * 两处逐字写着「`@epoch-agent/view` 的展示项里根本没有『图片』这一类,
88
+ * 真要画缩略图得先往 view 加类型」。这就是那次加类型。
89
+ *
90
+ * 在它之前,用户自己那条带图的消息在界面上是一行**文本占位符**
91
+ * (`[图片 image/jpeg]`,`contentToDisplayText` 的口径)—— 屏幕上说
92
+ * 「这里有张图」,但人看不到那张图,而它明明就在服务端的 artifact 目录里、
93
+ * 也已经有一个能取到它的端点。
94
+ *
95
+ * 缺席 / 两条路合到一格那两条判据**逐字同**上面 `references`:
96
+ *
97
+ * | 谁填 | 从哪来 |
98
+ * | --- | --- |
99
+ * | 回放(`GET /messages`) | 那条消息的 `parts` 里 `type: 'image'`(`image` 是服务端路径) |
100
+ * | 刚发出去那一条 | 浏览器自己刚读的那个文件(`image` 是 `data:` URL) |
101
+ *
102
+ * ⚠️ **和上面两格的区别:这一格带「内容」**。`WireImageReference` 只摘了 `type`、
103
+ * **没摘 `image`** —— 因为界面要的就是那张图。但那一格永远是**引用**
104
+ * (路径 / http URL / 本地 data URL),服务端绝不在这条线上发 base64,
105
+ * 判据全文在 `WireImageReference` 上。
106
+ *
107
+ * TUI 那一侧恒缺席 —— 终端里画不了图,它照旧走文本占位(同 `references`
108
+ * 那一格的处置,是一次判断不是漏接)。
109
+ */
110
+ images?: readonly WireImageReference[];
45
111
  };
46
112
  /**
47
113
  * 模型的回复正文。
package/dist/index.js CHANGED
@@ -75,8 +75,6 @@ function applyStreamEvent(state, event, meta) {
75
75
  ...rest,
76
76
  status: event.ok ? "done" : "error",
77
77
  result: event.output,
78
- // 空数组也不要落下去:`artifacts: []` 和「没有产物」在渲染上没区别,
79
- // 但会让 `formatArtifact` 那一层多一次判空
80
78
  ...event.artifacts && event.artifacts.length > 0 ? { artifacts: event.artifacts } : {}
81
79
  };
82
80
  });
@@ -96,9 +94,14 @@ function applyStreamEvent(state, event, meta) {
96
94
  ],
97
95
  thought
98
96
  };
97
+ case "notice":
98
+ return {
99
+ pending: [...pending, { type: "info", text: event.text, ...anchor(meta) }],
100
+ thought
101
+ };
99
102
  case "error":
100
103
  return {
101
- pending: [...pending, { type: "error", text: event.message || "\u9519\u8BEF", ...anchor(meta) }],
104
+ pending: [...pending, { type: "error", text: event.message, ...anchor(meta) }],
102
105
  thought
103
106
  };
104
107
  case "run-start":
@@ -113,7 +116,6 @@ function applyStreamEvent(state, event, meta) {
113
116
  }
114
117
  }
115
118
  }
116
-
117
119
  // src/diff-lines.ts
118
120
  var DIFF_MAX_LINES = 400;
119
121
  function splitLines(text) {
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@epoch-agent/view",
3
- "version": "0.1.0",
3
+ "version": "0.3.1",
4
4
  "private": false,
5
5
  "description": "epoch-agent 展示层纯逻辑:AgentEvent → 可渲染 item,tui 与 web 共用",
6
6
  "repository": {
@@ -22,7 +22,7 @@
22
22
  "dist"
23
23
  ],
24
24
  "dependencies": {
25
- "@epoch-agent/protocol": "0.1.0"
25
+ "@epoch-agent/protocol": "0.3.1"
26
26
  },
27
27
  "devDependencies": {
28
28
  "tsup": "^8.3.6",