Sessions
构建聊天界面
将历史、流式文本、工具、审批、停止和重连组合成一个 Session 客户端
构建聊天界面
一个可用的 Session 聊天界面不需要维护第二份 Timeline。它只维护由 SessionMessage 构成的线性状态,并把 Mutation 合并进这份状态。
初始化
先订阅并缓冲,再加载快照,避免启动时丢失 Delta:
const buffered: SessionMutation[] = [];
let ready = false;
const unsubscribe = session.subscribe(async (mutation) => {
if (!ready) {
buffered.push(mutation);
return;
}
await apply_live_mutation(mutation);
});
const [page, info] = await Promise.all([
session.messages(),
session.get_info(),
]);
set_messages(page.items);
set_session_info(info);
for (const mutation of buffered) {
await apply_live_mutation(mutation);
}
ready = true;完整竞态处理见 重连与同步。
提交与停止
async function submit(query: string): Promise<void> {
const turn = await session.prompt({ query });
set_active_turn(turn.id);
const result = await turn.finished;
clear_active_turn(turn.id);
set_turn_status(turn.id, result.success ? "completed" : "failed");
}
async function stop(): Promise<void> {
const result = await session.stop();
if (result.cancelled_queued_prompts > 0) {
show_notice("未开始的输入已取消");
}
}发送按钮应在输入为空时禁用;停止按钮应由 turn Mutation 或 get_info().executing 驱动。
渲染规则
- 按顶层 Message 的
sequence渲染对话。 - Assistant 内按 Part 的
sequence渲染文本、工具、再文本。 - 一个 Assistant Message 只渲染一次角色标题;Tool Loop 和 Provider continuation 产生的新 Part 继续留在同一角色容器中。
text/reasoningDelta 追加到当前文本 Part,tool_inputDelta 追加到当前 Tool Part 的input_text。part用稳定part_id覆盖完整状态。message用message_id + revision覆盖完整 Message。- 顶层
errorMessage 是一次失败唯一的用户可见错误提示。 - Interaction Part 为
pending时显示交互控件;关联 Tool 为waiting-user时显示等待状态。
不要创建 Transcript Message DTO 或把工具调用平铺到第二份可持久化列表,也不要用最终 turn.text 覆盖已经按 Part 渲染的 Assistant Message。turn.finished.error 只用于控制流和日志;若已经渲染 error Message,不要再追加一条错误提示。
审批卡片
审批 UI 从 Interaction Part 或 session.interactions() 得到相同身份:
await session.respond({
interaction_id,
response: { kind: "approval", decision: "approved" },
});提交后保持等待下一条 Part Mutation。只有 SDK 发布 running、completed 或 failed 后才改变工具展示状态。
Session 切换与卸载
切换会话时按这个顺序:
unsubscribe()旧会话。- 清空旧会话的消息、Turn 与审批 UI 状态。
- 取到新 Session 后执行初始化流程。
- 不复用旧会话的
interaction_id、part_id或 Turn loading 状态。
这是避免“审批提交给错误会话”和“历史滚动显示旧 Delta”的必要边界。