feat(plan): keep exit_plan_mode declared after the first plan-mode entry
Disclose the exit tool progressively instead of following every plan-mode transition. The plan projection records whether a logged plan/mode ever activated plan mode (stateVersion 4), and the tool's condition admits it for a step whose selected state is active or once the Session has entered plan mode. Leaving plan mode now changes only the guidance section, so an addition-only route no longer drops a declaration from its cached prefix. A call while plan mode is not committed still fails as unavailable outside plan mode, and a Session that never entered plan mode does not list the tool. The Web plan-review fixtures return to master's recording because the request tool lists no longer change on exit.
This commit is contained in:
1 parent
85b29bbcea
commit
752cc5c0c0
21 files changed
+98
-67
No files matched your search
@@ -2465,7 +2465,7 @@ export interface Config {
|
||||
## `@deepseek-ai/dsh-plan-mode`
|
||||
|
||||
- `inject`: `tools` · `systemPrompt` · `sessionProjections` · `agents`
|
||||
- `source`: [`packages/plan/plan-mode/src/index.ts:66`](../packages/plan/plan-mode/src/index.ts)
|
||||
- `source`: [`packages/plan/plan-mode/src/index.ts:67`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Deployment-owned plan guidance. */
|
||||
|
||||
@@ -2467,7 +2467,7 @@ export interface Config {
|
||||
## `@deepseek-ai/dsh-plan-mode`
|
||||
|
||||
- `inject`: `tools` · `systemPrompt` · `sessionProjections` · `agents`
|
||||
- `source`: [`packages/plan/plan-mode/src/index.ts:66`](../packages/plan/plan-mode/src/index.ts)
|
||||
- `source`: [`packages/plan/plan-mode/src/index.ts:67`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
```ts config-catalog
|
||||
/** Deployment-owned plan guidance. */
|
||||
|
||||
@@ -153,8 +153,8 @@
|
||||
en: 4294f78d26ed985b
|
||||
zh: 4294f78d26ed985b
|
||||
/session-persistence-event-catalog/events/plan/plan-mode-log-only:
|
||||
en: 862175bfe8692ef7
|
||||
zh: a8ab123bf674cf77
|
||||
en: 9ae5537eeae238de
|
||||
zh: 6be761c7fd83fdce
|
||||
/session-persistence-event-catalog/events/request:
|
||||
en: a8df82440ebdf5f8
|
||||
zh: a8df82440ebdf5f8
|
||||
@@ -1398,8 +1398,8 @@
|
||||
en: a74e3dfa51c987af
|
||||
zh: 6c3c87974d7a7260
|
||||
/session-persistence-event-catalog/resolved-persistence-types/active~2:
|
||||
en: a3de6a6fe9672c7a
|
||||
zh: a357481e27b3b81f
|
||||
en: c861888d6239b700
|
||||
zh: a9b2271d3c6b8737
|
||||
/session-persistence-event-catalog/resolved-persistence-types/agentpreset:
|
||||
en: 1afbe8196f161601
|
||||
zh: a320a36a8928817c
|
||||
|
||||
@@ -735,7 +735,7 @@ Source: [`packages/interaction/permission-presets/src/index.ts:52`](../packages/
|
||||
'plan/mode': { active: boolean }
|
||||
```
|
||||
|
||||
Source: [`packages/plan/plan-mode/src/index.ts:52`](../packages/plan/plan-mode/src/index.ts)
|
||||
Source: [`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
### `request/*`
|
||||
|
||||
@@ -5769,7 +5769,7 @@ Array of `unknown` (opaque).
|
||||
|
||||
SHA-256: `20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5`
|
||||
|
||||
Sources: [`packages/plan/plan-mode/src/index.ts:52`](../packages/plan/plan-mode/src/index.ts)
|
||||
Sources: [`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
| Property | Presence | Type |
|
||||
|---|---|---|
|
||||
|
||||
@@ -737,7 +737,7 @@ export type SessionEvent<T extends SessionEventType = SessionEventType> = {
|
||||
'plan/mode': { active: boolean }
|
||||
```
|
||||
|
||||
来源:[`packages/plan/plan-mode/src/index.ts:52`](../packages/plan/plan-mode/src/index.ts)
|
||||
来源:[`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
### `request/*`
|
||||
|
||||
@@ -5771,7 +5771,7 @@ SHA-256: `b1664fa89f8eab49a14e7e3168d8bc4da4aa9fd76332f6c4a053d839e5276ae7`
|
||||
|
||||
SHA-256: `20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5`
|
||||
|
||||
来源:[`packages/plan/plan-mode/src/index.ts:52`](../packages/plan/plan-mode/src/index.ts)
|
||||
来源:[`packages/plan/plan-mode/src/index.ts:53`](../packages/plan/plan-mode/src/index.ts)
|
||||
|
||||
| 属性 | 存在性 | 类型 |
|
||||
|---|---|---|
|
||||
|
||||
Generated
+1
-1
@@ -153,7 +153,7 @@
|
||||
{"digest":"1f1385dbc3e875c021e387c7096d671d606f22daec51b25c80348735b6bbfa10","names":[],"sources":[]},
|
||||
{"digest":"1f8c126cfab3df812cd115cfc23e3256f0fa2383400f4ce91ecad313577e59b0","names":["packages/core/session/src/types.ts#TurnEndCancelCause"],"sources":["packages/core/session/src/types.ts:197"]},
|
||||
{"digest":"1fdad624334d354820dfb3a26e28d0bc9fc1b62a33f87bab63f715b3f4391bfd","names":[],"sources":[]},
|
||||
{"digest":"20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5","names":[],"sources":["packages/plan/plan-mode/src/index.ts:52"]},
|
||||
{"digest":"20a57544bbf204dacd1ae6beb2ab29444365c3c869f2afdf489dcdcbc3d9c8c5","names":[],"sources":["packages/plan/plan-mode/src/index.ts:53"]},
|
||||
{"digest":"2142e391b9ccb60d487afcf373ce74db98d952f69e8289eddb352a7e16e996c5","names":[],"sources":[]},
|
||||
{"digest":"2152caf1a71e588e4df2358a806dea24936c1c47131134f01a12939d12cdc0c0","names":["packages/experimental/agent-team/src/types.ts#TeamMessageSource"],"sources":["packages/experimental/agent-team/src/types.ts:138"]},
|
||||
{"digest":"21fb6a90d5068f6a0003b7ab316ed2f56342477146a65c00db0f13c4d8df667d","names":[],"sources":[]},
|
||||
|
||||
@@ -15,8 +15,8 @@
|
||||
en: ee04468005fae8e1
|
||||
zh: 1347d554102951f2
|
||||
/plan-mode/the-exit-tool-and-the-plan-command:
|
||||
en: 9f2a549447f8d374
|
||||
zh: 8f3064e31d514702
|
||||
en: 32ecfb7086dd1578
|
||||
zh: 0aaeaa69bb63f255
|
||||
/plan-mode/the-service:
|
||||
en: f3e6d5a7fe0b67f0
|
||||
zh: 774cc97e493991fa
|
||||
@@ -30,7 +30,7 @@ A missing, blank, or non-string `section` and any unknown key fail at plugin loa
|
||||
|
||||
## The exit tool and the `/plan` command
|
||||
|
||||
[`exit_plan_mode`](../tool-catalog.md#deepseek-aidsh-plan-mode) is admitted only for steps whose selected plan state is active, so entering or leaving plan mode changes the request tool declarations and the plan guidance together; Native and PTC execution use the same admitted set, and a call outside plan mode returns `UNKNOWN_TOOL`. In plan mode it requires a complete markdown plan starting with a `#` heading and presents it for review through the [user-questions seam](user-questions.md). Approval returns `{ approved: true }` and records a silent (non-narrated) pending exit that is appended at the next accepted in-turn pre-step. Plan guidance therefore remains active for the rest of the assistant's current tool batch, and the tool result itself reports the transition. Keep-planning is a failed call carrying the user's feedback, so the model revises and presents again. A dismissed review returns `{ approved: false }` and concludes the turn, so plan mode stays active until the user's next message. A missing interaction channel and a service reload during review also fail the call rather than silently leaving plan mode.
|
||||
[`exit_plan_mode`](../tool-catalog.md#deepseek-aidsh-plan-mode) is disclosed progressively: it is admitted from the first step whose selected plan state is active and stays admitted for the rest of the Session, so the first plan-mode entry adds it to the request tool declarations and later transitions change only the plan guidance. Native and PTC execution use the same admitted set; a call before the first entry returns `UNKNOWN_TOOL`, and a call while plan mode is not committed fails. In plan mode it requires a complete markdown plan starting with a `#` heading and presents it for review through the [user-questions seam](user-questions.md). Approval returns `{ approved: true }` and records a silent (non-narrated) pending exit that is appended at the next accepted in-turn pre-step. Plan guidance therefore remains active for the rest of the assistant's current tool batch, and the tool result itself reports the transition. Keep-planning is a failed call carrying the user's feedback, so the model revises and presents again. A dismissed review returns `{ approved: false }` and concludes the turn, so plan mode stays active until the user's next message. A missing interaction channel and a service reload during review also fail the call rather than silently leaving plan mode.
|
||||
|
||||
When [`ctx.commands`](commands.md) is composed, the plugin registers `/plan [off|message]`: bare `/plan` selects plan mode, any other non-empty message selects it and then submits the text through `agent.steer()` so it becomes the next step's ordinary logged user message under plan guidance, and the exact argument `off` selects inactive, which also cancels a pending entry before it is appended and becomes visible to a request.
|
||||
|
||||
|
||||
@@ -30,7 +30,7 @@ interface PlanModeConfig {
|
||||
|
||||
## 退出工具与 `/plan` 命令
|
||||
|
||||
[`exit_plan_mode`](../tool-catalog.zh.md#deepseek-aidsh-plan-mode) 只在已选计划状态为激活的步骤中准入,因此进入或离开计划模式会同时改变请求的工具声明与计划指引;原生与 PTC 执行使用同一准入集合,在计划模式之外调用会返回 `UNKNOWN_TOOL`。在计划模式中,它要求一份以 `#` 标题开头的完整 markdown 计划,并通过[用户交互 seam](user-questions.zh.md) 呈交评审。批准返回 `{ approved: true }`,并记录一个静默(不叙述)的待生效退出,由下一个被接受的轮内 pre-step 追加。因此,计划指引在 assistant 当前这批工具调用的剩余部分继续生效,而工具结果本身会报告这次转换。「继续规划」则是一次携带用户反馈的失败调用,模型据此修订并再次呈交。放弃评审返回 `{ approved: false }` 并结束当前轮次,计划模式保持激活,直到用户发出下一条消息。评审期间交互通道缺失或服务重载同样使调用失败,而不是静默离开计划模式。
|
||||
[`exit_plan_mode`](../tool-catalog.zh.md#deepseek-aidsh-plan-mode) 采用渐进式披露:从已选计划状态首次为激活的步骤起准入,并在会话剩余部分保持准入,因此首次进入计划模式时它进入请求的工具声明,之后的切换只改变计划指引。原生与 PTC 执行使用同一准入集合;首次进入之前调用返回 `UNKNOWN_TOOL`,计划模式未提交时调用会失败。在计划模式中,它要求一份以 `#` 标题开头的完整 markdown 计划,并通过[用户交互 seam](user-questions.zh.md) 呈交评审。批准返回 `{ approved: true }`,并记录一个静默(不叙述)的待生效退出,由下一个被接受的轮内 pre-step 追加。因此,计划指引在 assistant 当前这批工具调用的剩余部分继续生效,而工具结果本身会报告这次转换。「继续规划」则是一次携带用户反馈的失败调用,模型据此修订并再次呈交。放弃评审返回 `{ approved: false }` 并结束当前轮次,计划模式保持激活,直到用户发出下一条消息。评审期间交互通道缺失或服务重载同样使调用失败,而不是静默离开计划模式。
|
||||
|
||||
当 [`ctx.commands`](commands.zh.md) 被组合时,插件注册 `/plan [off|message]`:单独的 `/plan` 选择计划模式;任何其他非空消息先选择计划模式,再通过 `agent.steer()` 提交该文本,使其在计划指引下成为下一步骤的普通已记录用户消息;确切参数 `off` 选择未激活,这还会在待生效条目被追加并对请求可见之前将其取消。
|
||||
|
||||
|
||||
@@ -3,14 +3,14 @@
|
||||
# After editing either side, bring the other along and re-record with:
|
||||
# pnpm run verify-translation-pairing --write docs/upgrade-guide/v0.2.1-rc.2/conditional-tools/guide.md
|
||||
/:
|
||||
en: 759962a4bf2e454f
|
||||
zh: df802b222d1a46f3
|
||||
en: 1dc343c5aa10de02
|
||||
zh: 59ac1c2052255919
|
||||
/declare-conditional-tools-through-step-admission:
|
||||
en: 4edb4c80b402de77
|
||||
zh: 856160ec69c515ea
|
||||
/declare-conditional-tools-through-step-admission/change:
|
||||
en: ba47cb460364f666
|
||||
zh: 1b5db25e4fb99ac2
|
||||
en: 71aba6399833cd1d
|
||||
zh: b820e301baf72e4e
|
||||
/declare-conditional-tools-through-step-admission/migration:
|
||||
en: 676839aab96dcd2d
|
||||
zh: eae3c9a6795f8d6e
|
||||
en: 943671c4348031bb
|
||||
zh: 0e44d7b29eab0168
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "Tool declarations come only from step-admitted registrations: `system-prompt/assemble` no longer carries tools, conditional tools need a resolved step set, and `exit_plan_mode` is declared only in plan mode."
|
||||
description: "Tool declarations come only from step-admitted registrations: `system-prompt/assemble` no longer carries tools, conditional tools need a resolved step set, and `exit_plan_mode` is declared only after a Session first enters plan mode."
|
||||
---
|
||||
|
||||
# Declare conditional tools through step admission
|
||||
@@ -15,11 +15,11 @@ The `system-prompt/assemble` waterfall now receives sections, contexts, and vari
|
||||
|
||||
Model tool calls run only through their step's admitted set. A call to a conditional tool without a resolved set, a call after the set is disposed, and a pending call whose registration was replaced or removed during the step return `UNKNOWN_TOOL` instead of running.
|
||||
|
||||
`exit_plan_mode` is declared only for steps whose selected plan state is active, so the request tool list changes when plan mode starts or ends. Existing Sessions require no format migration.
|
||||
`exit_plan_mode` is declared from the first step whose selected plan state is active and stays declared for the rest of the Session, so requests of a Session that never entered plan mode no longer list it. Existing Sessions require no format migration.
|
||||
|
||||
## Migration
|
||||
|
||||
1. Replace tool filtering in `system-prompt/assemble` listeners with a `when` condition on the registration; read the step's provider, model, and reasoning effort from the condition's `modelSelection`. Keep only section, context, and variable changes in the waterfall.
|
||||
2. Make tool guidance follow the same admission: section callbacks pass `context.toolSet` to `ctx.tools.get()` or `ctx.tools.schemas()`.
|
||||
3. For programmatic calls of conditional tools, call `ctx.tools.resolve({ agent, modelSelection, signal })`, pass the returned `toolSet` to `assemble()` and `ctx.tools.execute()`, and dispose it after the batch settles.
|
||||
4. Update expectations that listed `exit_plan_mode` outside plan mode. Verify that a disabled tool is absent from the request, that calling its name returns `UNKNOWN_TOOL` without reaching the implementation, and that a failing condition ends the turn with `TOOL_ACTIVATION_FAILED`.
|
||||
4. Update expectations that listed `exit_plan_mode` before a Session entered plan mode. Verify that a disabled tool is absent from the request, that calling its name returns `UNKNOWN_TOOL` without reaching the implementation, and that a failing condition ends the turn with `TOOL_ACTIVATION_FAILED`.
|
||||
@@ -1,6 +1,6 @@
|
||||
---
|
||||
kind: upgrade-guide
|
||||
description: "工具声明只来自步骤准入的注册:`system-prompt/assemble` 不再携带工具,条件工具需要已解析的步骤集合,`exit_plan_mode` 只在计划模式下声明。"
|
||||
description: "工具声明只来自步骤准入的注册:`system-prompt/assemble` 不再携带工具,条件工具需要已解析的步骤集合,`exit_plan_mode` 只在会话首次进入计划模式后声明。"
|
||||
---
|
||||
|
||||
# 通过步骤准入声明条件工具
|
||||
@@ -15,11 +15,11 @@ description: "工具声明只来自步骤准入的注册:`system-prompt/assemb
|
||||
|
||||
模型的工具调用只通过所属步骤的准入集合执行。没有已解析集合的条件工具调用、集合释放之后的调用,以及注册在步骤内被替换或移除时尚未开始的调用,都会返回 `UNKNOWN_TOOL`,不会执行。
|
||||
|
||||
`exit_plan_mode` 只在已选计划状态为激活的步骤中声明,因此进入或离开计划模式时请求的工具列表会变化。现有 Session 无需格式迁移。
|
||||
`exit_plan_mode` 从已选计划状态首次为激活的步骤起声明,并在会话剩余部分保持声明,因此从未进入计划模式的会话,其请求不再列出它。现有 Session 无需格式迁移。
|
||||
|
||||
## 迁移
|
||||
|
||||
1. 把 `system-prompt/assemble` 监听器中的工具过滤改为注册时的 `when` 条件;从条件的 `modelSelection` 读取该步骤的提供方、模型与推理强度。waterfall 中只保留段落、上下文与变量的修改。
|
||||
2. 让工具指引跟随同一准入:段落回调把 `context.toolSet` 传给 `ctx.tools.get()` 或 `ctx.tools.schemas()`。
|
||||
3. 程序化调用条件工具时,调用 `ctx.tools.resolve({ agent, modelSelection, signal })`,把返回的 `toolSet` 传给 `assemble()` 与 `ctx.tools.execute()`,并在批次结束后释放。
|
||||
4. 更新在计划模式之外仍列出 `exit_plan_mode` 的期望。验证被禁用的工具不出现在请求中,用其名称调用会返回 `UNKNOWN_TOOL` 且不进入实现,条件失败时轮次以 `TOOL_ACTIVATION_FAILED` 结束。
|
||||
4. 更新在会话进入计划模式之前仍列出 `exit_plan_mode` 的期望。验证被禁用的工具不出现在请求中,用其名称调用会返回 `UNKNOWN_TOOL` 且不进入实现,条件失败时轮次以 `TOOL_ACTIVATION_FAILED` 结束。
|
||||
Reference in new issue
Block a user