fix inbox lifecycle downstream contracts

This commit is contained in:
_Kerman
2026-07-31 22:00:39 +08:00
parent 8e88b17c9f
commit afedf18ccf
219 changed files with 5660 additions and 4556 deletions
+2 -2
View File
@@ -2,5 +2,5 @@
# side as of the last confirmed-consistent state. Both languages carry equal authority;
# after editing either side, bring the other along and re-record with:
# pnpm run verify-translation-pairing --write packages/goal/tool-goal/README.md
README.md: aaed61dd517aeb2f94efa22c34c64d1068155d46
README.zh.md: 5365b64ef65fb3d3f00e19357327479ebd8285a8
README.md: a4742e4117ca89f4395a1c59264f6ea6c3ab8b96
README.zh.md: 48e89332db7dfbe746d1ba4e57077eb787a10a66
+3 -3
View File
@@ -61,15 +61,15 @@ Prefix-stable while the plugin scope, configured threshold, and guidance text ar
#### What the model sees
The generated [`get_goal`, `create_goal`, and `update_goal` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-goal). Successful results are compact JSON. Mutation results are followed by the goal domain's raw `<goal_state>` snapshot after the tool batch. `activation` in a result is a live observation and never becomes replay authority.
The generated [`get_goal`, `create_goal`, and `update_goal` schemas](../../../docs/tool-catalog.md#deepseek-aidsh-tool-goal). Successful results are compact JSON. A mutation queues the goal domain's raw `<goal_state>` snapshot after the tool batch; a later pre-step may admit it, while discarding the queued context does not roll back the durable mutation. `activation` in a result is a live observation and never becomes replay authority.
#### Token effect
Fixed schema cost plus one compact result per call. Mutations also retain the domain snapshot until compaction.
Fixed schema cost plus one compact result per call. An admitted mutation context retains the domain snapshot until compaction; one discarded before admission adds no model tokens.
#### KV Cache effect
Schemas are prefix-stable while their definitions and visibility are unchanged. Calls, results, and resulting goal snapshots append after the reusable request prefix without invalidating earlier entries.
Schemas are prefix-stable while their definitions and visibility are unchanged. Calls, results, and admitted goal snapshots append after the reusable request prefix without invalidating earlier entries.
## Known Limitations and Deferred Work
+3 -3
View File
@@ -61,15 +61,15 @@ Use goal tools for one long-running completion objective in the current session.
#### 模型看到的内容
生成的 [`get_goal`、`create_goal` 和 `update_goal` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-goal)。成功结果是紧凑 JSON。变更结果之后是工具批次结束后由 goal 领域产生的原始 `<goal_state>` 快照。结果中的 `activation` 是实时观察值,绝不会成为回放权限依据。
生成的 [`get_goal`、`create_goal` 和 `update_goal` schema](../../../docs/tool-catalog.md#deepseek-aidsh-tool-goal)。成功结果是紧凑 JSON。变更会在工具批次结束后将 goal 领域的原始 `<goal_state>` 快照排队;后续 pre-step 可以准入它,而丢弃已排队的上下文不会回滚持久变更。结果中的 `activation` 是实时观察值,绝不会成为回放权限依据。
#### Token 影响
固定 schema 成本,加上每次调用的一条紧凑结果。变更还会保留领域快照,直到压缩(compaction)。
固定 schema 成本,加上每次调用的一条紧凑结果。获准的变更上下文会保留领域快照,直到压缩(compaction);准入前被丢弃的上下文不增加模型 token。
#### KV Cache 影响
schema 的定义与可见性不变时,前缀保持稳定。调用、结果和生成的 goal 快照会追加到可复用请求前缀之后,不会使更早条目失效。
schema 的定义与可见性不变时,前缀保持稳定。调用、结果和已准入的 goal 快照会追加到可复用请求前缀之后,不会使更早条目失效。
## 已知限制与暂缓事项
@@ -21,7 +21,7 @@ interface StubAgent {
setStatus(status: AgentStatus): void
}
/** Build one registry-compatible live agent whose injections append in place. */
/** Build one registry-compatible live agent whose injections enter the durable inbox. */
function stubAgent(rawId: string, supplied?: Session): StubAgent {
const session = supplied ?? new Session(SessionId(rawId))
let status: AgentStatus = 'running'
@@ -36,7 +36,7 @@ function stubAgent(rawId: string, supplied?: Session): StubAgent {
followup: () => {},
steer: () => {},
inject(input) {
session.append('user/message', input, { surfaceOp: 'append' })
this.inbox.append('next-step', input)
},
cancel() {},
whenIdle() { return Promise.resolve() },
@@ -49,11 +49,17 @@ function openTurn(stub: StubAgent, source: MessageSource, text = 'prompt'): numb
const turn = stub.session.events
.filter(event => event.type === 'turn/start')
.reduce((max, event) => Math.max(max, event.data.turn), 0) + 1
stub.session.append('turn/start', { turn })
stub.session.append('user/message', createUserMessage({
const message = createUserMessage({
content: [{ type: 'text', text }],
source,
}), { surfaceOp: 'append' })
})
stub.agent.inbox.append('next-turn', message)
const claimed = stub.agent.inbox.claim('next-turn')
if (claimed.length === 0) throw new Error('expected queued turn input')
stub.session.append('turn/start', { turn })
for (const admitted of claimed) {
stub.session.append('user/message', admitted, { surfaceOp: 'append' })
}
return turn
}