Four values complete the vocabulary, so the opaque body is reached only by producers that genuinely promise no shape. `snapshot` — current state a later snapshot supersedes. system-prompt now exposes `renderContextSections()`, the named contributions `renderContextSnapshot()` already joins for the model, so the body attributes each part to the subsystem that produced it instead of re-splitting joined prose. The runtime snapshot, time-context, and tmux-context declare it. `notice` — a one-off account of what just happened, declared by tool-tasks, goal state changes, tool-goal wrap-up, plan-mode switches, and repeat-tool-guard. Its `summary` rides the COLLAPSED row: these five are the majority of shipped producers and none of them needs expanding to be read. The task summary bounds itself because its inputs are unbounded caller text. `relay` — a message another agent addressed to this one; both subagent sources declare it and the body names the sender above what it said. `recall` — material lifted from another session's log. session-reference needed no new field: its references already record retained and omitted counts and the truncation flag, which the body shows first, because recalled context is bounded on the way in. `ContextFormed` is now discriminated by `form`, so a producer cannot declare a shape without the facts that shape is presented from — a notice without its summary, or a snapshot without its sections, fails to compile. Only the two hook bridges stay opaque, by design: their content is whatever an external program printed, so no shape can be promised for it. Unknown kinds and unreadable records land there too.
155 lines
5.6 KiB
Markdown
155 lines
5.6 KiB
Markdown
# 同会话目标
|
|
|
|
[English](goal.md) | 中文
|
|
|
|
事件溯源目标领域及其策略消费方共享的类型。[目标领域 Agent Note](../../.agents/notes/implemented/feature/2026-07-19-persisted-same-session-goal-domain.md)负责记录持久化与激活决策;本页记录 [`packages/goal/goal/src/types.ts`](../../packages/goal/goal/src/types.ts) 中的字面形态。
|
|
|
|
## 标识与生命周期
|
|
|
|
`GoalId` 是[品牌化 id](core.md#branded-ids)。调用方通过 `GoalRef` 修改一个确切修订版本;每次获准的持久变更都会递增修订号。
|
|
|
|
```ts type-equiv
|
|
/** Compare-and-set identity for one exact goal revision. */
|
|
interface GoalRef {
|
|
/** Stable goal identity. */
|
|
readonly id: GoalId
|
|
/** Positive revision; every durable mutation increments it. */
|
|
readonly revision: number
|
|
}
|
|
```
|
|
|
|
持久阶段回答目标发生了什么。进程本地激活状态则另行回答续跑消费方能否开始另一个 Round。
|
|
|
|
```ts type-equiv
|
|
/** Durable continuation phase. Activation is process-local and separate. */
|
|
type GoalPhase =
|
|
| 'active'
|
|
| 'paused'
|
|
| 'blocked'
|
|
| 'complete'
|
|
```
|
|
|
|
阻塞是唯一表示「因问题而停止」的持久状态。由策略负责的阻塞原因会携带一个用于路由、稳定且采用 lower-kebab-case 的代码,以及一段供人和模型阅读的自由文本说明。
|
|
|
|
```ts type-equiv
|
|
/** Machine-routable and human-readable explanation for a blocked goal. */
|
|
interface GoalBlockReason {
|
|
/** Stable lower-kebab-case classification chosen by the blocking policy. */
|
|
readonly code: string
|
|
/** Non-empty explanation shown to humans and models. */
|
|
readonly message: string
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Full durable state written by every non-clear goal mutation. */
|
|
interface GoalSnapshot extends GoalRef {
|
|
/** Human-requested completion objective. */
|
|
readonly objective: string
|
|
/** Durable lifecycle phase. */
|
|
readonly phase: GoalPhase
|
|
/** Present exactly while `phase` is `blocked`. */
|
|
readonly blockedReason?: GoalBlockReason
|
|
/** Total admitted goal-round cap. */
|
|
readonly maxGoalRounds: number
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Current goal projection, including values derived from the session log. */
|
|
interface GoalView extends GoalSnapshot {
|
|
/** Highest admitted round number for this goal. */
|
|
readonly roundsStarted: number
|
|
/** Epoch milliseconds of the create mutation. */
|
|
readonly createdAt: number
|
|
/** Epoch milliseconds of the latest mutation. */
|
|
readonly updatedAt: number
|
|
/** Process-local continuation eligibility; never persisted. */
|
|
readonly activation: GoalActivation
|
|
}
|
|
```
|
|
|
|
## 持久变更
|
|
|
|
每次变更都是 Round 编号为 0、来源为目标的 `user/message`,其元数据要么是完整快照,要么是清除墓碑。版本、元数据、目标来源和原样渲染的内容共同构成一项回放不变量。
|
|
|
|
```ts type-equiv
|
|
/** Full-snapshot goal mutation retained in a model-visible context event. */
|
|
interface GoalSnapshotChangeMeta {
|
|
readonly kind: 'goal/change'
|
|
readonly version: 1
|
|
readonly operation: Exclude<GoalOperation, 'clear'>
|
|
readonly goal: GoalSnapshot
|
|
readonly roundsStarted: number
|
|
readonly createdAt: number
|
|
readonly updatedAt: number
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Tombstone retained when the current goal is cleared. */
|
|
interface GoalClearChangeMeta {
|
|
readonly kind: 'goal/change'
|
|
readonly version: 1
|
|
readonly operation: 'clear'
|
|
readonly cleared: GoalRef
|
|
readonly clearedAt: number
|
|
}
|
|
```
|
|
|
|
目标状态变更使用 Round `0`。续跑消费方会为每个获准的用户消息轮次标注正数且连续的 Round 编号和当前修订号;回放会拒绝编号缺口、陈旧修订号、已停止阶段和超出上限。
|
|
|
|
```ts type-equiv
|
|
/** Message attribution for durable goal state and continuation rounds. */
|
|
interface GoalMessageSource {
|
|
readonly kind: 'goal'
|
|
/**
|
|
* Round-zero state changes are `notice`-form contexts; a continuation round
|
|
* carries the objective forward as ordinary context and declares no form.
|
|
*/
|
|
readonly form?: 'notice'
|
|
/** Present with `form`: one-line account of the mutation. */
|
|
readonly summary?: string
|
|
readonly goalId: GoalId
|
|
readonly revision: number
|
|
/** Zero for state changes; positive for admitted continuation rounds. */
|
|
readonly round: number
|
|
/** Complete durable mutation carried only by round-zero state-change messages. */
|
|
readonly change?: GoalChangeMeta
|
|
}
|
|
```
|
|
|
|
## 请求与通知
|
|
|
|
创建操作会区分调用方省略字段与采用部署配置值这两种情况,`create()` 会在内部解析后者。编辑是局部替换,其运行时校验器要求至少提供一个字段。每条变更通知都会携带获准的操作和确切修订号;清除操作不带 `goal`。
|
|
|
|
```ts type-equiv
|
|
/** Input whose omitted round cap is resolved by the service configuration. */
|
|
interface CreateGoalRequest {
|
|
readonly objective: string
|
|
readonly maxGoalRounds?: number
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Fields changed by an edit; at least one must be present. */
|
|
interface EditGoalRequest {
|
|
readonly objective?: string
|
|
readonly maxGoalRounds?: number
|
|
}
|
|
```
|
|
|
|
```ts type-equiv
|
|
/** Live notification after one goal mutation has been accepted for logging. */
|
|
interface GoalChanged {
|
|
readonly operation: GoalOperation
|
|
readonly ref: GoalRef
|
|
/** Absent for a clear tombstone. */
|
|
readonly goal?: GoalView
|
|
}
|
|
```
|
|
|
|
## 服务行为
|
|
|
|
[`GoalService`](../../packages/goal/goal/src/index.ts) 解析创建默认值、执行严格回放折叠、校验确切的活跃 agent 身份、以比较并设置方式执行变更、叠加待处理的注入变更,并发出 `goal/changed` 通知;监听器故障会被隔离。包 [README](../../packages/goal/goal/README.md) 负责记录可调用契约和面向模型的契约。
|