refactor(agent-loop): simplify message machine

This commit is contained in:
_Kerman
2026-07-30 13:49:57 +08:00
parent d554ae3019
commit f2e20c1ef0
212 files changed
+1326 -2382

No files matched your search

+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 docs/core-data-structures/core.md
core.md: b9df539136c2661537775ba9a425bdf7ef1fd958
core.zh.md: 1c75e8484dd1184077fe0194b2b6088230d1bbf5
core.md: d837fc0977615a3afe307c56f5c97065af4a3a26
core.zh.md: 797ec67ca0100cc44a088d453394c39cc1e343b0
+6 -64
View File
@@ -414,46 +414,12 @@ The twelve event variants (`turn/start`, `turn/end`, `step/start`, `step/end`, `
Source: [`packages/core/agent/src/types.ts`](../../packages/core/agent/src/types.ts)
```ts type-equiv
/**
* Which inbox queue a {@link Agent.send} item joins:
* - `next-turn` — the item becomes its own turn, claimed at a turn boundary.
* - `next-step` — during prompt admission or an open turn, the item stages for
* the next safe step boundary; otherwise it is promoted per its `wakeup`
* flag.
*/
type SendTarget = 'next-turn' | 'next-step'
```
```ts type-equiv
/** Resolved inbox placement reported when an accepted message is enqueued. */
type InboxPlacement = 'queued' | 'steering'
```
```ts type-equiv
/**
* Options for the unified {@link Agent.send} primitive over the
* (`target` × `wakeup`) matrix. Named presets: {@link Agent.followup}
* (`next-turn`/wakeup), {@link Agent.steer} (`next-step`/wakeup), and
* {@link Agent.inject} (`next-step`/no-wakeup).
*
* The object is complete so routing policy is explicit.
*/
interface SendOptions {
/** Queue the item joins. */
target: SendTarget
/**
* Whether this item makes the model run: wake a parked driver (`next-turn`)
* or force a continuation step (`next-step` while running). A `false`
* `next-turn` item queues without waking; a `false`
* `next-step` item attaches durable context without forcing another step
* (the injection preset).
*/
wakeup: boolean
}
```
The fixed-preset aliases own `target` and `wakeup`; their already identified `UserMessage` carries role, content, and provenance. Its `MessageId` remains stable across that message's `agent/inbox/*` events without being returned by the delivery methods. Injection bypasses the FIFOs and never appears on those events.
The delivery methods accept an already identified `UserMessage` carrying role, content, and provenance. Its `MessageId` remains stable across that message's `agent/inbox/*` events without being returned by the delivery methods. Injection bypasses the FIFOs and never appears on those events.
```ts type-equiv
/** Options for {@link Agent.cancel}. */
@@ -474,10 +440,10 @@ type AgentCancelCause =
| { readonly kind: 'parent' }
```
`Agent` is an interface over the public live-agent contract. Concrete drivers own the `followup`/`steer`/`inject` aliases and route them through `send`'s (`target` × `wakeup`) matrix.
`Agent` is an interface over the public live-agent contract. Concrete drivers implement `followup`, `steer`, and `inject`; routing policy remains private to the driver.
```ts type-equiv
/** Public live-agent handle with aliases over the unified delivery primitive. */
/** Public live-agent handle. */
interface Agent {
/** The single identity shared with {@link session}. */
readonly id: SessionId
@@ -496,28 +462,6 @@ interface Agent {
/** Agent-scoped context; its contributions are agent-local, unwind on disposal, and reject registration afterward. */
readonly ctx: Context
/**
* The unified delivery primitive over the (`target` × `wakeup`) matrix.
* It routes the caller's typed content and source as follows:
*
* - `next-turn` queues an item that becomes the sole ordinary message of its
* own FIFO-ordered turn; `wakeup:true` wakes a
* parked driver, while `wakeup:false` queues without waking.
* - `next-step` with `wakeup:true` stages steering during prompt admission
* or an open turn; outside that window it falls back to a woken
* `next-turn`.
* - `next-step` with `wakeup:false` injects durable model-facing context
* without running the model: admission or an open turn stages it for the
* next safe log position, while an injection outside that window appends
* immediately without opening a turn. If admission closes without a turn,
* a context-only boundary appends immediately; context staged beside
* steering remains pending with it.
* The agent publishes or queues the identified frozen message as-is.
* @param message - identified model-facing content and its producer provenance.
* @param options - target queue and wakeup decision.
*/
send(message: UserMessage, options: SendOptions): void
/**
* Clear queued and steering work — unless `keepInbox` — and abort the active
* turn. An effective call first emits `agent/cancel-requested` with the
@@ -533,16 +477,14 @@ interface Agent {
whenIdle(): Promise<void>
/**
* Queue an ordinary follow-up turn and wake the driver the
* `next-turn`/wakeup preset of {@link send}. The item becomes the sole
* ordinary message of its own turn.
* Queue an ordinary follow-up turn and wake the driver. The item becomes the
* sole ordinary message of its own turn.
* @param message - identified prompt content and its producer provenance.
*/
followup(message: UserMessage): void
/**
* Submit steering during prompt admission or an open turn — the
* `next-step`/wakeup preset of {@link send}. It stages for the next steering
* Submit steering during prompt admission or an open turn. It stages for the next steering
* checkpoint before a request or stop decision. If the activity fails before
* that boundary, the remainder stays staged without waking the agent; retry
* or a later prompt takes it. Outside that window steering falls back to a
+6 -64
View File
@@ -422,46 +422,12 @@ type SessionEvent<T extends SessionEventType = SessionEventType> = {
源码:[`packages/core/agent/src/types.ts`](../../packages/core/agent/src/types.ts)
```ts type-equiv
/**
* Which inbox queue a {@link Agent.send} item joins:
* - `next-turn` — the item becomes its own turn, claimed at a turn boundary.
* - `next-step` — during prompt admission or an open turn, the item stages for
* the next safe step boundary; otherwise it is promoted per its `wakeup`
* flag.
*/
type SendTarget = 'next-turn' | 'next-step'
```
```ts type-equiv
/** Resolved inbox placement reported when an accepted message is enqueued. */
type InboxPlacement = 'queued' | 'steering'
```
```ts type-equiv
/**
* Options for the unified {@link Agent.send} primitive over the
* (`target` × `wakeup`) matrix. Named presets: {@link Agent.followup}
* (`next-turn`/wakeup), {@link Agent.steer} (`next-step`/wakeup), and
* {@link Agent.inject} (`next-step`/no-wakeup).
*
* The object is complete so routing policy is explicit.
*/
interface SendOptions {
/** Queue the item joins. */
target: SendTarget
/**
* Whether this item makes the model run: wake a parked driver (`next-turn`)
* or force a continuation step (`next-step` while running). A `false`
* `next-turn` item queues without waking; a `false`
* `next-step` item attaches durable context without forcing another step
* (the injection preset).
*/
wakeup: boolean
}
```
固定预设的别名方法自带 `target` 与 `wakeup`;其已有标识的 `UserMessage` 会携带角色、内容与 provenance。投递方法不会返回其 `MessageId`,但该 id 在这条消息的各个 `agent/inbox/*` 事件中保持稳定。注入绕过两个 FIFO,从不出现在这些事件中。
投递方法接收已有标识的 `UserMessage`,由它携带角色、内容与 provenance。投递方法不会返回其 `MessageId`,但该 id 在这条消息的各个 `agent/inbox/*` 事件中保持稳定。注入绕过两个 FIFO,从不出现在这些事件中。
```ts type-equiv
/** Options for {@link Agent.cancel}. */
@@ -482,10 +448,10 @@ type AgentCancelCause =
| { readonly kind: 'parent' }
```
`Agent` 是覆盖公开活跃 agent 契约的接口。具体驱动器拥有 `followup`/`steer`/`inject` 别名方法,并将它们经由 `send` 的(`target` × `wakeup`)矩阵路由
`Agent` 是覆盖公开活跃 agent 契约的接口。具体驱动器实现 `followup``steer``inject`;路由策略仍为驱动器私有
```ts type-equiv
/** Public live-agent handle with aliases over the unified delivery primitive. */
/** Public live-agent handle. */
interface Agent {
/** The single identity shared with {@link session}. */
readonly id: SessionId
@@ -504,28 +470,6 @@ interface Agent {
/** Agent-scoped context; its contributions are agent-local, unwind on disposal, and reject registration afterward. */
readonly ctx: Context
/**
* The unified delivery primitive over the (`target` × `wakeup`) matrix.
* It routes the caller's typed content and source as follows:
*
* - `next-turn` queues an item that becomes the sole ordinary message of its
* own FIFO-ordered turn; `wakeup:true` wakes a
* parked driver, while `wakeup:false` queues without waking.
* - `next-step` with `wakeup:true` stages steering during prompt admission
* or an open turn; outside that window it falls back to a woken
* `next-turn`.
* - `next-step` with `wakeup:false` injects durable model-facing context
* without running the model: admission or an open turn stages it for the
* next safe log position, while an injection outside that window appends
* immediately without opening a turn. If admission closes without a turn,
* a context-only boundary appends immediately; context staged beside
* steering remains pending with it.
* The agent publishes or queues the identified frozen message as-is.
* @param message - identified model-facing content and its producer provenance.
* @param options - target queue and wakeup decision.
*/
send(message: UserMessage, options: SendOptions): void
/**
* Clear queued and steering work — unless `keepInbox` — and abort the active
* turn. An effective call first emits `agent/cancel-requested` with the
@@ -541,16 +485,14 @@ interface Agent {
whenIdle(): Promise<void>
/**
* Queue an ordinary follow-up turn and wake the driver the
* `next-turn`/wakeup preset of {@link send}. The item becomes the sole
* ordinary message of its own turn.
* Queue an ordinary follow-up turn and wake the driver. The item becomes the
* sole ordinary message of its own turn.
* @param message - identified prompt content and its producer provenance.
*/
followup(message: UserMessage): void
/**
* Submit steering during prompt admission or an open turn — the
* `next-step`/wakeup preset of {@link send}. It stages for the next steering
* Submit steering during prompt admission or an open turn. It stages for the next steering
* checkpoint before a request or stop decision. If the activity fails before
* that boundary, the remainder stays staged without waking the agent; retry
* or a later prompt takes it. Outside that window steering falls back to a