@deepseek-ai/dsh-plan-mode 0.2.1-alpha.2 → 0.2.1-alpha.4

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/README.i18n.yaml CHANGED
@@ -27,8 +27,8 @@
27
27
  en: 2d300cdb883352ec
28
28
  zh: 5a81be005b3716d3
29
29
  /deepseek-ai-dsh-plan-mode/use-this-package/the-reviewed-exit:
30
- en: ffc56477380b9411
31
- zh: 17cac060f2252d78
30
+ en: dbf12997d2359e81
31
+ zh: 120a91554d2154f4
32
32
  /deepseek-ai-dsh-plan-mode/use-this-package/observing-plan-state:
33
33
  en: b44e92bc38406015
34
34
  zh: ed56190bee5d71a4
@@ -90,8 +90,8 @@
90
90
  en: 9622e96bdc01276d
91
91
  zh: 53801e68a49f3d1d
92
92
  /deepseek-ai-dsh-plan-mode/model-experience/exit-tool-schema-and-review-exchange/what-the-model-sees:
93
- en: 3768d0189f9f13af
94
- zh: 2168a9b24551b7c6
93
+ en: 16c57e8e64ad5a85
94
+ zh: d81932553025c875
95
95
  /deepseek-ai-dsh-plan-mode/model-experience/exit-tool-schema-and-review-exchange/token-effect:
96
96
  en: d1b1418f20ee119d
97
97
  zh: c2b89ea3cae57175
package/README.md CHANGED
@@ -60,7 +60,7 @@ You can attach images and generic files to a `/plan` message, and they are inclu
60
60
 
61
61
  When the agent has a finished plan, it calls `exit_plan_mode` with the plan written as markdown and starting with a heading. You review that exact plan and choose `Approve` to leave plan mode, or `Keep planning` to send the agent back with feedback.
62
62
 
63
- Choosing `Keep planning` (optionally with free-text feedback) sends the agent back to revise the plan; closing the review to type a message instead tells the agent to wait for your next message. If no interactive review is available, `exit_plan_mode` cannot run and you can still leave plan mode with `/plan off`.
63
+ Choosing `Keep planning` (optionally with free-text feedback) sends the agent back to revise the plan; closing the review to type a message instead ends the agent's turn, and your next message starts the next request. If no interactive review is available, `exit_plan_mode` cannot run and you can still leave plan mode with `/plan off`.
64
64
 
65
65
  ### Observing plan state
66
66
 
@@ -164,7 +164,7 @@ The user block is append-only conversation growth. Entering or leaving plan mode
164
164
 
165
165
  #### What the model sees
166
166
 
167
- The [`exit_plan_mode` schema](../../../docs/tool-catalog.md#deepseek-aidsh-plan-mode) remains available in both states; execution outside plan mode fails, while an approved in-mode review returns the canonical `{ approved: true }` value and renders the existing confirmation text. Rejection remains a failed call carrying review feedback, and a dismissed review a failed call naming the user's takeover.
167
+ The [`exit_plan_mode` schema](../../../docs/tool-catalog.md#deepseek-aidsh-plan-mode) remains available in both states; execution outside plan mode fails, while an approved in-mode review returns the canonical `{ approved: true }` value and renders the existing confirmation text. Rejection remains a failed call carrying review feedback. A dismissed review returns `{ approved: false }`, renders a note that the user will reply, and concludes the turn without another model request.
168
168
 
169
169
  #### Token effect
170
170
 
package/README.zh.md CHANGED
@@ -60,7 +60,7 @@ kind: "package-reference"
60
60
 
61
61
  agent 完成计划后,会以 markdown 形式、从标题开头书写计划并调用 `exit_plan_mode`。你评审该计划的原文,选择 `Approve` 离开计划模式,或选择 `Keep planning` 带反馈把 agent 送回去。
62
62
 
63
- 选择 `Keep planning`(可附自由文本反馈)会让 agent 回去修订计划;关闭评审改为发言,则告知 agent 等待你的下一条消息。若没有可用的交互评审,`exit_plan_mode` 无法运行,你仍可用 `/plan off` 离开计划模式。
63
+ 选择 `Keep planning`(可附自由文本反馈)会让 agent 回去修订计划;关闭评审改为发言,则结束 agent 当前轮次,你的下一条消息开始下一次请求。若没有可用的交互评审,`exit_plan_mode` 无法运行,你仍可用 `/plan off` 离开计划模式。
64
64
 
65
65
  ### 观察计划状态
66
66
 
@@ -164,7 +164,7 @@ You are in plan mode. Explore and design before presenting the complete plan thr
164
164
 
165
165
  #### 模型看到什么
166
166
 
167
- [`exit_plan_mode` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-plan-mode) 在两种状态下均可用;在计划模式之外执行会失败,而计划模式内经批准的评审返回规范的 `{ approved: true }` 值,并渲染既有的确认文本。拒绝仍是携带评审反馈的失败调用,放弃评审则是一次指明用户接手的失败调用。
167
+ [`exit_plan_mode` schema](../../../docs/tool-catalog.zh.md#deepseek-aidsh-plan-mode) 在两种状态下均可用;在计划模式之外执行会失败,而计划模式内经批准的评审返回规范的 `{ approved: true }` 值,并渲染既有的确认文本。拒绝仍是携带评审反馈的失败调用。放弃评审返回 `{ approved: false }`,渲染一条说明用户将自行回复的文本,并结束当前轮次,不再发起模型请求。
168
168
 
169
169
  #### Token 影响
170
170
 
package/lib/index.js CHANGED
@@ -241,13 +241,12 @@ var PlanModeController = class extends Service {
241
241
  additionalProperties: false,
242
242
  properties: { approved: {
243
243
  type: "boolean",
244
- const: true,
245
244
  required: true
246
245
  } }
247
246
  },
248
- render: () => [{
247
+ render: (_args, { approved }) => [{
249
248
  type: "text",
250
- text: "Plan approved — plan mode exited; carry out the plan starting with your next step."
249
+ text: approved ? "Plan approved — plan mode exited; carry out the plan starting with your next step." : "The user dismissed the plan review to reply in their own words; plan mode remains active."
251
250
  }]
252
251
  },
253
252
  execute: async (args, exec) => {
@@ -257,31 +256,37 @@ var PlanModeController = class extends Service {
257
256
  if (!/^#\s+\S/.test(args.plan.trim())) throw new Error(`${EXIT_PLAN_MODE} requires a non-empty markdown plan starting with a # heading`);
258
257
  const interaction = ctx.get("userQuestions");
259
258
  if (interaction === void 0) throw new Error("no user-questions channel is available to review the plan; ask the user to switch the session mode instead");
260
- const answer = await interaction.ask({
261
- questions: [{
262
- id: REVIEW_ID,
263
- header: "Plan review",
264
- question: "Approve this plan and leave plan mode?",
265
- detail: args.plan,
266
- options: [{
267
- label: APPROVE_LABEL,
268
- description: "Leave plan mode; the plan is carried out from the next step."
269
- }, {
270
- label: KEEP_PLANNING_LABEL,
271
- description: "Stay in plan mode; feedback goes back to the model."
259
+ let answer;
260
+ try {
261
+ answer = await interaction.ask({
262
+ questions: [{
263
+ id: REVIEW_ID,
264
+ header: "Plan review",
265
+ question: "Approve this plan and leave plan mode?",
266
+ detail: args.plan,
267
+ options: [{
268
+ label: APPROVE_LABEL,
269
+ description: "Leave plan mode; the plan is carried out from the next step."
270
+ }, {
271
+ label: KEEP_PLANNING_LABEL,
272
+ description: "Stay in plan mode; feedback goes back to the model."
273
+ }],
274
+ intent: {
275
+ kind: "plan-review",
276
+ approve: APPROVE_LABEL,
277
+ callId: exec.callId
278
+ }
272
279
  }],
273
- intent: {
274
- kind: "plan-review",
275
- approve: APPROVE_LABEL,
276
- callId: exec.callId
277
- }
278
- }],
279
- agent,
280
- signal: exec.signal
281
- }).catch((cause) => {
282
- if (cause instanceof UserQuestionError && cause.code === "ASK_CANCELLED") throw new Error("The user dismissed the plan review to speak instead; stay in plan mode, stop here, and wait for their message.");
280
+ agent,
281
+ signal: exec.signal
282
+ });
283
+ } catch (cause) {
284
+ if (cause instanceof UserQuestionError && cause.code === "ASK_CANCELLED") {
285
+ exec.concludeTurn();
286
+ return { approved: false };
287
+ }
283
288
  throw cause;
284
- });
289
+ }
285
290
  if (disposed) throw new Error("the plan-mode service was reloaded while the plan was under review; present the plan again");
286
291
  const reviewItems = answer.answers.filter((entry) => entry.id === REVIEW_ID);
287
292
  const item = reviewItems.length === 1 ? reviewItems[0] : void 0;
@@ -230,10 +230,15 @@ export class PlanModeController extends Service {
230
230
  type: 'object',
231
231
  additionalProperties: false,
232
232
  properties: {
233
- approved: { type: 'boolean', const: true, required: true },
233
+ approved: { type: 'boolean', required: true },
234
234
  },
235
235
  },
236
- render: () => [{ type: 'text', text: 'Plan approved — plan mode exited; carry out the plan starting with your next step.' }],
236
+ render: (_args, { approved }) => [{
237
+ type: 'text',
238
+ text: approved
239
+ ? 'Plan approved — plan mode exited; carry out the plan starting with your next step.'
240
+ : 'The user dismissed the plan review to reply in their own words; plan mode remains active.',
241
+ }],
237
242
  },
238
243
  execute: async (args, exec) => {
239
244
  const agent = exec.agent;
@@ -249,35 +254,38 @@ export class PlanModeController extends Service {
249
254
  if (interaction === undefined) {
250
255
  throw new Error('no user-questions channel is available to review the plan; ask the user to switch the session mode instead');
251
256
  }
252
- const answer = await interaction.ask({
253
- questions: [{
254
- id: REVIEW_ID,
255
- header: 'Plan review',
256
- question: 'Approve this plan and leave plan mode?',
257
- detail: args.plan,
258
- options: [
259
- { label: APPROVE_LABEL, description: 'Leave plan mode; the plan is carried out from the next step.' },
260
- { label: KEEP_PLANNING_LABEL, description: 'Stay in plan mode; feedback goes back to the model.' },
261
- ],
262
- // Presentation only: a capable UI renders the plan as a review
263
- // decision instead of a generic question, and answers with one of
264
- // the labels above either way.
265
- intent: { kind: 'plan-review', approve: APPROVE_LABEL, callId: exec.callId },
266
- }],
267
- agent,
268
- signal: exec.signal,
269
- }).catch((cause) => {
257
+ let answer;
258
+ try {
259
+ answer = await interaction.ask({
260
+ questions: [{
261
+ id: REVIEW_ID,
262
+ header: 'Plan review',
263
+ question: 'Approve this plan and leave plan mode?',
264
+ detail: args.plan,
265
+ options: [
266
+ { label: APPROVE_LABEL, description: 'Leave plan mode; the plan is carried out from the next step.' },
267
+ { label: KEEP_PLANNING_LABEL, description: 'Stay in plan mode; feedback goes back to the model.' },
268
+ ],
269
+ // Presentation only: a capable UI renders the plan as a review
270
+ // decision instead of a generic question, and answers with one of
271
+ // the labels above either way.
272
+ intent: { kind: 'plan-review', approve: APPROVE_LABEL, callId: exec.callId },
273
+ }],
274
+ agent,
275
+ signal: exec.signal,
276
+ });
277
+ }
278
+ catch (cause) {
270
279
  // A dismissed review is not a failed one: the user took the turn back
271
- // to say something the two options do not cover. Say so, because the
272
- // generic channel message names ask_user_question, which the model
273
- // never called. An abort (turn cancel, provider teardown) keeps its
274
- // own message — there is no user to wait for.
280
+ // to say something the two options do not cover, so the turn ends
281
+ // here instead of spending a model request on waiting. An abort (turn
282
+ // cancel, provider teardown) keeps its own failure.
275
283
  if (cause instanceof UserQuestionError && cause.code === 'ASK_CANCELLED') {
276
- throw new Error('The user dismissed the plan review to speak instead; '
277
- + 'stay in plan mode, stop here, and wait for their message.');
284
+ exec.concludeTurn();
285
+ return { approved: false };
278
286
  }
279
287
  throw cause;
280
- });
288
+ }
281
289
  // A review may outlive this plugin fiber. Without its pre-step listener,
282
290
  // an approved selection could never be appended, so fail and keep planning.
283
291
  if (disposed) {
package/locale/en.json ADDED
@@ -0,0 +1,5 @@
1
+ {
2
+ "meta": {
3
+ "title": "plan-mode"
4
+ }
5
+ }
package/locale/zh.json ADDED
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "计划模式",
4
+ "description": "让 AI 先制定计划,并在用户审阅后切换到执行。"
5
+ }
6
+ }
package/package.json CHANGED
@@ -1,7 +1,7 @@
1
1
  {
2
2
  "name": "@deepseek-ai/dsh-plan-mode",
3
3
  "description": "Logged per-agent plan mode with deployment guidance, a direct slash command, and a user-reviewed exit",
4
- "version": "0.2.1-alpha.2",
4
+ "version": "0.2.1-alpha.4",
5
5
  "publishConfig": {
6
6
  "access": "public"
7
7
  },
@@ -27,24 +27,26 @@
27
27
  "default": "./lib/types/client.js"
28
28
  },
29
29
  "./src/*": "./src/*",
30
- "./package.json": "./package.json"
30
+ "./package.json": "./package.json",
31
+ "./locale/*.json": "./locale/*.json"
31
32
  },
32
33
  "files": [
34
+ "locale/*.json",
33
35
  "lib/index.js",
34
36
  "lib/types/**/*.js",
35
37
  "lib/types/**/*.d.ts"
36
38
  ],
37
39
  "license": "MIT",
38
40
  "peerDependencies": {
39
- "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
40
- "@deepseek-ai/dsh-commands": "0.2.1-alpha.2",
41
- "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
42
- "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
43
- "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
44
- "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.2",
45
- "@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
46
- "@deepseek-ai/dsh-user-questions": "0.2.1-alpha.2",
47
- "@deepseek-ai/cordis": "~4.0.5-alpha.1"
41
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.4",
42
+ "@deepseek-ai/dsh-commands": "0.2.1-alpha.4",
43
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.4",
44
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.4",
45
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.4",
46
+ "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4",
47
+ "@deepseek-ai/dsh-tools": "0.2.1-alpha.4",
48
+ "@deepseek-ai/dsh-user-questions": "0.2.1-alpha.4",
49
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2"
48
50
  },
49
51
  "peerDependenciesMeta": {
50
52
  "@deepseek-ai/dsh-commands": {
@@ -52,21 +54,21 @@
52
54
  }
53
55
  },
54
56
  "dependencies": {
55
- "@deepseek-ai/dsh-brand": "0.2.1-alpha.2",
56
- "zod": "^4.4.3"
57
+ "@deepseek-ai/dsh-brand": "0.2.1-alpha.4",
58
+ "zod": "4.4.3"
57
59
  },
58
60
  "devDependencies": {
59
- "@deepseek-ai/dsh-agent": "0.2.1-alpha.2",
60
- "@deepseek-ai/dsh-agent-loop": "0.2.1-alpha.2",
61
- "@deepseek-ai/dsh-ptc-runtime": "0.2.1-alpha.2",
62
- "@deepseek-ai/dsh-commands": "0.2.1-alpha.2",
63
- "@deepseek-ai/dsh-llm": "0.2.1-alpha.2",
64
- "@deepseek-ai/dsh-session": "0.2.1-alpha.2",
65
- "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.2",
66
- "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.2",
67
- "@deepseek-ai/dsh-tools": "0.2.1-alpha.2",
68
- "@deepseek-ai/dsh-user-questions": "0.2.1-alpha.2",
69
- "@deepseek-ai/cordis": "~4.0.5-alpha.1",
70
- "@deepseek-ai/dsh-agent-loop-testkit": "0.2.1-alpha.2"
61
+ "@deepseek-ai/dsh-agent": "0.2.1-alpha.4",
62
+ "@deepseek-ai/dsh-agent-loop": "0.2.1-alpha.4",
63
+ "@deepseek-ai/dsh-ptc-runtime": "0.2.1-alpha.4",
64
+ "@deepseek-ai/dsh-commands": "0.2.1-alpha.4",
65
+ "@deepseek-ai/dsh-llm": "0.2.1-alpha.4",
66
+ "@deepseek-ai/dsh-session": "0.2.1-alpha.4",
67
+ "@deepseek-ai/dsh-session-projection": "0.2.1-alpha.4",
68
+ "@deepseek-ai/dsh-system-prompt": "0.2.1-alpha.4",
69
+ "@deepseek-ai/dsh-tools": "0.2.1-alpha.4",
70
+ "@deepseek-ai/dsh-user-questions": "0.2.1-alpha.4",
71
+ "@deepseek-ai/cordis": "~4.0.5-alpha.2",
72
+ "@deepseek-ai/dsh-agent-loop-testkit": "0.2.1-alpha.4"
71
73
  }
72
74
  }