共享历史不等于共享活会话
三个层级
| 层级 | 含义 | 能不能做到 |
|---|---|---|
| ① 同一历史会话 | 用同一个 threadId / 会话记录 | 可以 |
| ② 同一运行中 turn | 手机发消息进入同一个常驻 runtime,实时收 delta | 可以(需常驻 app-server) |
| ③ 同一电脑界面 | 手机发的消息直接出现在已打开的 Desktop/CLI 窗口里 | 最难,取决于该界面是否连同一个 runtime |
「新进程 + resume threadId」的迷惑性
codex exec resume <threadId> "..." 是每条消息新起一个一次性进程,只是带着上次的 thread id。所以:
- 手机能看到上文 → 因为 resume 带了历史,不是因为进程还活着。
- 它属于「① 共享历史」,不是「② 共享活会话」。
- 副作用:
codex exec本来就是一次性进程,退出码异常时桥接服务会当成错误 → 手机上表现为「卡在生成中 / code exit」。
判据:如果每发一条消息电脑上就多一个 codex exec 子进程,那就只是共享历史。
「引用会话」也不等于「在该会话上继续」。 手机端引用一个已导入的会话、然后从引用卡片开始新对话时,平台是新建一个会话(历史消息只是被读进来当上下文),消息记在新会话里,原会话保持不动。所以「我在那个会话里发了消息」和「那个会话里多了我的消息」是两件事 —— 想真正接续,要在会话列表里打开原会话再发。
独立 app-server 也能实现层级 ②,但必须成为唯一真源
官方 remote-control 会被「第三方 key 不能用」卡住,所以另起一个独立 app-server 是对的。但独立 app-server 要真同步,前提是电脑端和手机端都走这同一个 app-server:
电脑端输入/界面 ─┐
├─→ 同一个 owned app-server ─→ 事件广播给所有客户端
手机端输入/界面 ─┘
硬边界:如果电脑端仍用官方 Desktop 作为主界面,而它不连这个 owned app-server,那独立 app-server 看不到它的实时流。 想同步,电脑端入口也得改走同一个 bridge(本地 Web UI / menubar companion / CLI wrapper 皆可)。
第三条路线:原生会话镜像器(文件 watcher)
如果坚持「电脑端继续用原生 Codex CLI / Desktop,不改输入入口」,那就不是 owned runtime,而是镜像器:
原生 Codex CLI / Desktop
→ 写 ~/.codex/session_index.jsonl、~/.codex/sessions/**/*.jsonl
codex-server.mjs
→ 监听文件变化 → 增量解析 user / assistant 可见消息 → 推给手机 App
手机 App → 展示历史;要续聊时用 threadId resume
它的能力边界很干净:
| 能力 | 能否 |
|---|---|
| 电脑发消息、手机同步 | 能(加强现有导入逻辑) |
| 准实时同步 | 能 —— 前提是原生运行时会边跑边写 JSONL;若只在结束后落盘,就只能结束后同步 |
| 手机接续(resume) | 能 |
| 手机中断 / 接管电脑原生正在跑的 turn | 一般不行 —— 那个进程不是 bridge 启动的 |
判断依据:真源(谁拥有正在跑的那个 turn)决定实时性上限。 想让电脑原生输入也被实时同步,只有两条路——要么电脑端入口改走同一个 bridge(= owned app-server),要么退化成文件镜像器(准实时 + 不能接管)。
不做通用 engine 的判断
要不要抽象出统一 Engine,按「要覆盖多少个 provider × 多少个平台」定价:只有 Claude Code + Codex 两个 provider、电脑 server + 手机 App 两个入口时,做完整 engine(provider 切换、平台 adapter、command engine)是过度设计。保留两个原生 bridge,只抽很小的共享层(bridge-events.mjs / thread-store.mjs 这类)即可。参见 Agent编排层薄自建优先于重型框架。
相关
- 远程控制本机Agent要让bridge跑在本机
- 远程Agent控制要定义执行协议与状态模型
- 终端画面同步Agent状态不稳定 —— 想连「界面」一起同步时的另一条路线(tmux)
- Agent编排层薄自建优先于重型框架
- 上下文按卡片切换会话记忆按账号共享 —— 同一条「共享」谱系:会话记忆按账号共享,上下文按卡片切换
- 同名provider冲突会让模型路由漂移 —— 同一会话的另一处坑:导入只带消息不带 provider 归属,续聊时会解析到错误的供应商