ContextManager 是 Session 内原始 History 的唯一结构化所有者。它按最旧到最新保存 ResponseItem,同时持有 token usage、History version、TurnContext 引用项和 World State baseline。调用方可以克隆快照用于请求,却不应绕过它直接改 Session History。
Arc 提供写时复制快照
History items 存在 Arc<Vec<ResponseItem>> 中。clone_history() 只克隆 Arc 和元数据,多个只读消费者共享同一向量;真正追加、删除或规范化时通过 Arc::make_mut 复制。这样一次采样可以拿稳定快照,而 Session 继续接收事件时不会修改已经交给请求构造器的向量。
class ContextManager:
def __init__(self):
self._items: PersistentVector[ResponseItem] = PersistentVector()
self.history_version = 0
self.token_info = None
self.reference_context_item = None
self.world_state_baseline = None
def snapshot(self) -> "ContextManager":
return shallow_copy_sharing_items(self)
Python 复刻不必模拟 Rust Arc,可以在 Session 锁内复制不可变 tuple,或让 History actor 串行处理命令。关键契约是“请求快照一旦捕获就不被活动 Session 原地改变”。
原始历史与 Prompt 投影
raw_items() 返回持久化语义下的真实项目;for_prompt() 消费一个 ContextManager 快照,在副本上补配对、删孤儿、降级媒体,最终返回模型可接受项目。合成修复不写回原始 History。
def for_prompt(snapshot, modalities):
items = list(snapshot.raw_items)
ensure_call_outputs_present(items)
remove_orphan_outputs(items)
normalize_media(items, modalities)
return items
附属状态为什么也归它所有
Token usage 必须与 History 边界一起更新,World State baseline 必须在 History 重写时清空,reference context item 又决定下一 Turn 能否发差异。若分散在多个互不协调对象里,压缩只替换 items 却忘记清基线,就会产生模型视图缺口。
源码与测试锚点
codex-rs/core/src/context_manager/history.rs::ContextManager。codex-rs/core/src/session/mod.rs::clone_history。codex-rs/core/src/context_manager/history_tests.rs:快照、baseline 与规范化。
评论
登录后即可评论