Sessions

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.lengthsource 说明本次结果来自当前 Active 还是一个已关闭 Segment。

四类顶层 Message

type表示什么常见展示
user用户输入或运行中 steering用户气泡、附件
assistant模型生成的一段回复文本、推理、工具、文件
action模型切换、压缩等运行时操作状态通知
errorSession 或 Turn 的可展示错误错误提示与重试入口

Session 内只有一条按 sequence 排序的顶层 Message 序列。工具调用不是另一条 Timeline,也不是顶层 Message;它属于 Assistant Message 的 parts,因此 text -> tool -> text 会以真实生成顺序保存。

Assistant Part

type关键字段说明
texttext, state用户可见输出,streaming -> done
reasoningtext, state推理输出,是否展示由产品决定
tooltool_call_id, tool_name, state工具输入、审批、运行和结果
fileurl, media_typeAssistant 生成或引用的文件
datadata_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_moretrue,把 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,不支持 limitcursor、offset 或 Segment 内切片。这样 UI 边界与物理 Compact 边界一致,也不会重复读取累计 Summary。

与实时 Mutation 配合

  1. messages() 建立 Active 初始状态。
  2. message / part Mutation 替换对应快照。
  3. delta 追加当前 Part 的新文本。
  4. 向上滚动时按 next_before_sequence 逐个加载 Segment。
  5. 断线后重新读取 Active,并按 message_id + revision 合并。

完整同步算法见 重连与同步,存储细节见 元数据与落盘