[OMP] Late-bound task context breaks prompt-cache prefix stability in 0.6.16
Bug Description
Trellis 0.6.16 的 OMP extension 会在每次 context hook 中同步当前 task context。若 OMP session 在 session_start 时尚未绑定 task、之后才通过常规 task.py create / task.py start 绑定,历史中不存在持久化的 trellis-task-context,当前实现会执行:
if (replacement && !replaced) projectedMessages.push(replacement)这会把非持久化 task context 追加到每次 provider payload 的当前尾部。随着持久历史增长,相邻请求变为:
request 1: history H + task context C
request 2: history H + new message N + task context C因此 request 1 不再是 request 2 的前缀,破坏 OMP/OpenAI Responses prompt cache 所需的 append-only prefix stability,造成缓存命中率下降、输入成本和延迟增加。
这不是罕见的手工操作:Trellis 的 active task 是 session-scoped,常规流程通常是在已经启动的 OMP session 中创建并自动激活 task,因此 task 天然是在 session_start 之后绑定。
该问题可能是 #533 的 task-context freshness 修复引入的副作用:task context 现在可以刷新,但缺失 context 的首次同步使用了移动的尾部位置。
Steps to Reproduce
使用同一个 Trellis OMP extension 实例进行生命周期测试,不需要调用模型或 provider:
- 启动 OMP session,此时对应 session runtime mapping 中没有
current_task。 - 触发
session_start,确认没有持久化trellis-task-context。 - 在该 session 的
.trellis/.runtime/sessions/<context-key>.json中绑定一个有效 task,等价于在会话内执行常规task.py create/task.py start。 - 使用持久消息历史调用一次
contexthook,记录返回的 projected messages。 - 向持久消息历史追加一个合成消息。
- 再次调用同一个 extension 实例的
contexthook。 - 比较两次 projected messages 的 item 顺序和前缀关系。
Observed with 0.6.16:
late-bound task:
projected item count: 4 -> 5
task context index: 3 -> 4
request 1 is a prefix of request 2: falseControls:
0.6.16, task already bound at session_start:
projected item count: 4 -> 5
request 1 is a prefix of request 2: true
0.6.15, late-bound task:
projected item count: 3 -> 4
moving task context injection: absent
request 1 is a prefix of request 2: trueThe comparison uses synthetic messages only. No production prompt, response, credentials, cache key, session ID, request body, or provider call is required.
Expected Behavior
Binding a task after session_start should refresh/inject task context without moving an earlier request item on every subsequent provider call.
Possible fixes:
- persist the task context once when a task first becomes bound;
- reserve a stable context slot and replace that slot in projections;
- otherwise ensure adjacent provider payloads remain append-only after the one-time task transition.
Archiving or switching tasks may reasonably invalidate the cache once, but should not cause the task context to move to a new tail position on every API call.
Temporary workaround: immediately after binding a task, exit and resume the same OMP session so session_start runs again with the same session identity and persists the task context before long tool loops begin.
Trellis Version
0.6.16
Regression control: 0.6.15 does not reproduce the moving-tail behavior.
Node.js Version
v24.14.1
Operating System
macOS 26.6.2
Source: mindfold-ai/Trellis