Message 与 Part
读取 Active 与 Segment 历史,理解 Message、Part 和 sequence
Message 与 Part
session.messages() 返回当前 Active 的全部持久化 Message,不需要 limit。实时变化由 subscribe() 补充。
const page = await session.messages();
for (const message of page.items) {
render_message(message);
}返回结果为:
interface SessionMessagePage {
items: SessionMessage[];
total: number;
source: "active" | "segment";
start_sequence?: number;
end_sequence?: number;
next_before_sequence?: number;
has_more: boolean;
}total 是 Session 已创建的真实 Message 总数,不是当前 items.length。source 说明本次结果来自当前 Active 还是一个已关闭 Segment。
四类顶层 Message
type | 表示什么 | 常见展示 |
|---|---|---|
user | 用户输入或运行中 steering | 用户气泡、附件 |
assistant | 模型生成的一段回复 | 文本、推理、工具、文件 |
action | 模型切换、压缩等运行时操作 | 状态通知 |
error | Session 或 Turn 的可展示错误 | 错误提示与重试入口 |
Session 内只有一条按 sequence 排序的顶层 Message 序列。工具调用不是另一条 Timeline,也不是顶层 Message;它属于 Assistant Message 的 parts,因此 text -> tool -> text 会以真实生成顺序保存。
Assistant Part
type | 关键字段 | 说明 |
|---|---|---|
text | text, state | 用户可见输出,streaming -> done |
reasoning | text, state | 推理输出,是否展示由产品决定 |
tool | tool_call_id, tool_name, state | 工具输入、审批、运行和结果 |
file | url, media_type | Assistant 生成或引用的文件 |
data | data_type, data | 结构化 UI 数据 |
每个 Assistant Part 有稳定的 part_id 和不可变的内部 sequence。工具状态变化更新同一个 Part,不应在 UI 中创建“请求”和“结果”两个重复行。
顺序、版本与可见性
每条 Message 都有稳定 message_id、创建后不变的 sequence,以及随完整快照更新递增的 revision。客户端不能用较低 revision 覆盖较高 revision。
默认 messages() 只返回 visibility: "visible" 的 Message。调试或审计时可传 include_internal: true。Compact Summary 不是 Message,不占用 sequence,也不会出现在 messages() 结果中。
加载更早历史
第一次调用不传参数,得到 Active 全量。若 has_more 为 true,把 next_before_sequence 原样传回,会得到紧邻的前一个完整 Segment:
let page = await session.messages();
render_messages(page.items);
while (page.has_more && page.next_before_sequence !== undefined) {
page = await session.messages({
before_sequence: page.next_before_sequence,
});
prepend_messages(page.items);
}before_sequence 必须是正整数。每次历史读取返回一个完整 Segment,不支持 limit、cursor、offset 或 Segment 内切片。这样 UI 边界与物理 Compact 边界一致,也不会重复读取累计 Summary。
与实时 Mutation 配合
- 用
messages()建立 Active 初始状态。 - 用
message/partMutation 替换对应快照。 - 用
delta追加当前 Part 的新文本。 - 向上滚动时按
next_before_sequence逐个加载 Segment。 - 断线后重新读取 Active,并按
message_id + revision合并。