@qwen-code/qwen-code 0.18.2 → 0.18.3-preview.0

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.
Files changed (35) hide show
  1. package/chunks/{agent-P5U6QLWL.js → agent-X42UKL4M.js} +2 -2
  2. package/chunks/{agent-headless-24356DC7.js → agent-headless-7FQ7NX6G.js} +2 -2
  3. package/chunks/{chunk-QFJ67S5R.js → chunk-3U2ZIZDP.js} +5 -5
  4. package/chunks/{chunk-M7OBURJM.js → chunk-6X6PTTH3.js} +1 -1
  5. package/chunks/{chunk-NGDXHX3A.js → chunk-JHSQY3J5.js} +1 -1
  6. package/chunks/{chunk-25FFAMED.js → chunk-P5CE42XM.js} +3 -3
  7. package/chunks/{chunk-JZEKEWO5.js → chunk-U62OHNQR.js} +3 -3
  8. package/chunks/{chunk-EQ5NHJBY.js → chunk-VFW7VM7A.js} +25 -25
  9. package/chunks/{computer-use-EGW2I2HZ.js → computer-use-WHPP33BI.js} +2 -2
  10. package/chunks/{contextCommand-HI2X2Y7I.js → contextCommand-WP7BU7IY.js} +4 -4
  11. package/chunks/{edit-FJSOCDO2.js → edit-V22UFE4F.js} +2 -2
  12. package/chunks/{enter-worktree-X6MVFDLR.js → enter-worktree-HYS5U3QO.js} +2 -2
  13. package/chunks/{enterPlanMode-MZAEQZH3.js → enterPlanMode-UR2KPB4Y.js} +2 -2
  14. package/chunks/{exit-worktree-RM2UPOYQ.js → exit-worktree-JNIUZIZ3.js} +2 -2
  15. package/chunks/{exitPlanMode-7BVY3CWJ.js → exitPlanMode-NJY3Y6XQ.js} +6 -5
  16. package/chunks/{geminiContentGenerator-A6JHLUHK.js → geminiContentGenerator-SDUMCYHD.js} +1 -1
  17. package/chunks/{glob-L3AZLCV6.js → glob-Z6UYFZCH.js} +2 -2
  18. package/chunks/{grep-SNCPCXIP.js → grep-WHWDB2HD.js} +2 -2
  19. package/chunks/{monitor-TS6WL6DN.js → monitor-F4V4YEE4.js} +2 -2
  20. package/chunks/{notebook-edit-26RNH24J.js → notebook-edit-P45433KC.js} +2 -2
  21. package/chunks/{openaiContentGenerator-7CA63X5G.js → openaiContentGenerator-DRXB5MSN.js} +2 -2
  22. package/chunks/{qwenContentGenerator-4WJTJXFZ.js → qwenContentGenerator-3XZMXLHX.js} +3 -3
  23. package/chunks/{read-file-EUIHK6HD.js → read-file-WQPROSSJ.js} +1 -1
  24. package/chunks/{ripGrep-7J5B22W2.js → ripGrep-EAE7GW6T.js} +2 -2
  25. package/chunks/{scheduler-J3OUGTTS.js → scheduler-WCMRRLYM.js} +2 -2
  26. package/chunks/{serve-VF4ZNUJP.js → serve-BVDNMP5D.js} +4 -4
  27. package/chunks/{shell-G6XCJAG3.js → shell-W4LWEOQL.js} +2 -2
  28. package/chunks/{skill-7OVC6JIH.js → skill-VTJI4OPM.js} +1 -1
  29. package/chunks/{src-XV5MLRND.js → src-E42UOH5I.js} +2 -2
  30. package/chunks/{team-create-JXSC7ROC.js → team-create-OAGMFFDJ.js} +2 -2
  31. package/chunks/{tool-search-YRWSWA2H.js → tool-search-XZPD5EPI.js} +1 -1
  32. package/chunks/{workflow-ZN3DYFMU.js → workflow-AIC3XOX5.js} +3 -3
  33. package/chunks/{write-file-355M4V7Z.js → write-file-6GIRRW43.js} +2 -2
  34. package/cli.js +238 -55
  35. package/package.json +2 -2
package/cli.js CHANGED
@@ -92,7 +92,7 @@ import {
92
92
  updateOutputLanguageFile,
93
93
  validateCustomTheme,
94
94
  writeOutputLanguageAndRegisterPath
95
- } from "./chunks/chunk-QFJ67S5R.js";
95
+ } from "./chunks/chunk-3U2ZIZDP.js";
96
96
  import {
97
97
  AgentSideConnection,
98
98
  PROTOCOL_VERSION,
@@ -105,7 +105,7 @@ import {
105
105
  formatContextUsageText,
106
106
  isTerminalGoalStatusKind,
107
107
  require_react
108
- } from "./chunks/chunk-JZEKEWO5.js";
108
+ } from "./chunks/chunk-U62OHNQR.js";
109
109
  import {
110
110
  SUPPORTED_LANGUAGES,
111
111
  clearScreen,
@@ -118,7 +118,7 @@ import {
118
118
  ta,
119
119
  writeStderrLine,
120
120
  writeStdoutLine
121
- } from "./chunks/chunk-M7OBURJM.js";
121
+ } from "./chunks/chunk-6X6PTTH3.js";
122
122
  import {
123
123
  noteInteraction
124
124
  } from "./chunks/chunk-MRO43B25.js";
@@ -342,7 +342,7 @@ import {
342
342
  writeRuntimeStatus,
343
343
  writeWorktreeSession,
344
344
  writeWorktreeSessionMarker
345
- } from "./chunks/chunk-EQ5NHJBY.js";
345
+ } from "./chunks/chunk-VFW7VM7A.js";
346
346
  import {
347
347
  external_exports
348
348
  } from "./chunks/chunk-K5PGHDBN.js";
@@ -418,7 +418,7 @@ import {
418
418
  stripRuntimeSnapshotPrefix,
419
419
  uiTelemetryService,
420
420
  withInteractionSpan
421
- } from "./chunks/chunk-25FFAMED.js";
421
+ } from "./chunks/chunk-P5CE42XM.js";
422
422
  import "./chunks/chunk-3PJXIDKI.js";
423
423
  import "./chunks/chunk-UWCTAVOD.js";
424
424
  import {
@@ -59189,7 +59189,7 @@ var serveCommand = {
59189
59189
  process.exit(1);
59190
59190
  }
59191
59191
  }
59192
- const { runQwenServe } = await import("./chunks/serve-VF4ZNUJP.js");
59192
+ const { runQwenServe } = await import("./chunks/serve-BVDNMP5D.js");
59193
59193
  try {
59194
59194
  await runQwenServe({
59195
59195
  port: argv.port,
@@ -72034,7 +72034,7 @@ async function extractMetadata(conversation, config) {
72034
72034
  const gitBranch = firstRecord?.gitBranch;
72035
72035
  let gitRepo;
72036
72036
  if (cwd5) {
72037
- const { getGitRepoName } = await import("./chunks/src-XV5MLRND.js");
72037
+ const { getGitRepoName } = await import("./chunks/src-E42UOH5I.js");
72038
72038
  gitRepo = getGitRepoName(cwd5);
72039
72039
  }
72040
72040
  let model;
@@ -84233,7 +84233,7 @@ var SystemController = class extends BaseController {
84233
84233
  throw new Error("Request aborted");
84234
84234
  }
84235
84235
  try {
84236
- const mod = await import("./chunks/contextCommand-HI2X2Y7I.js");
84236
+ const mod = await import("./chunks/contextCommand-WP7BU7IY.js");
84237
84237
  if (signal.aborted) {
84238
84238
  throw new Error("Request aborted");
84239
84239
  }
@@ -122011,6 +122011,10 @@ var PrepareLabel = import_react152.default.memo(_PrepareLabel);
122011
122011
  // packages/cli/src/ui/components/SuggestionsDisplay.tsx
122012
122012
  var import_jsx_runtime150 = __toESM(require_jsx_runtime(), 1);
122013
122013
  var MAX_SUGGESTIONS_TO_SHOW = 8;
122014
+ function normalizeDescription(description) {
122015
+ return description.replace(/\s+/g, " ").trim();
122016
+ }
122017
+ __name(normalizeDescription, "normalizeDescription");
122014
122018
  function SuggestionsDisplay({
122015
122019
  suggestions,
122016
122020
  activeIndex,
@@ -122087,7 +122091,7 @@ function SuggestionsDisplay({
122087
122091
  flexGrow: 1,
122088
122092
  flexShrink: 1,
122089
122093
  paddingLeft: 2,
122090
- children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Text, { color: textColor, wrap: "wrap", children: suggestion.description })
122094
+ children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Text, { color: textColor, wrap: "truncate-end", children: normalizeDescription(suggestion.description) })
122091
122095
  }
122092
122096
  ),
122093
122097
  isActive && isLong && /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Box_default, { children: /* @__PURE__ */ (0, import_jsx_runtime150.jsx)(Text, { color: Colors.Gray, children: isExpanded ? " \u2190 " : " \u2192 " }) })
@@ -143744,9 +143748,10 @@ __name(toPermissionOptions, "toPermissionOptions");
143744
143748
  // packages/cli/src/acp-integration/session/SubAgentTracker.ts
143745
143749
  var debugLogger75 = createDebugLogger("ACP_SUBAGENT_TRACKER");
143746
143750
  var SubAgentTracker = class {
143747
- constructor(ctx, client, parentToolCallId, subagentType) {
143751
+ constructor(ctx, client, parentToolCallId, subagentType, onAskUserQuestionCancel) {
143748
143752
  this.ctx = ctx;
143749
143753
  this.client = client;
143754
+ this.onAskUserQuestionCancel = onAskUserQuestionCancel;
143750
143755
  this.toolCallEmitter = new ToolCallEmitter(ctx);
143751
143756
  this.messageEmitter = new MessageEmitter(ctx);
143752
143757
  this.subagentMeta = { parentToolCallId, subagentType };
@@ -143876,12 +143881,25 @@ var SubAgentTracker = class {
143876
143881
  await event.respond(outcome, {
143877
143882
  answers: "answers" in output ? output.answers : void 0
143878
143883
  });
143884
+ if (outcome === "cancel" /* Cancel */ && event.name === ToolNames.ASK_USER_QUESTION) {
143885
+ this.onAskUserQuestionCancel?.();
143886
+ }
143879
143887
  } catch (error) {
143880
143888
  debugLogger75.error(
143881
143889
  `Permission request failed for subagent tool ${event.name}:`,
143882
143890
  error
143883
143891
  );
143884
- await event.respond("cancel" /* Cancel */);
143892
+ if (event.name === ToolNames.ASK_USER_QUESTION) {
143893
+ this.onAskUserQuestionCancel?.();
143894
+ }
143895
+ try {
143896
+ await event.respond("cancel" /* Cancel */);
143897
+ } catch (respondError) {
143898
+ debugLogger75.error(
143899
+ `Failed to cancel subagent tool ${event.name} after permission request failure:`,
143900
+ respondError
143901
+ );
143902
+ }
143885
143903
  }
143886
143904
  };
143887
143905
  }
@@ -144247,6 +144265,7 @@ function maskApiKeyForDisplay(apiKey) {
144247
144265
  return `${trimmed.slice(0, 3)}...${trimmed.slice(-4)}`;
144248
144266
  }
144249
144267
  __name(maskApiKeyForDisplay, "maskApiKeyForDisplay");
144268
+ var ASK_USER_QUESTION_CANCEL_SKIP_MESSAGE = "Skipped because ask_user_question was cancelled before the user answered; user input is required before continuing.";
144250
144269
  var MID_TURN_QUEUE_DRAIN_TIMEOUT_MS = 2e3;
144251
144270
  var MID_TURN_QUEUE_DRAIN_MAX_TIMEOUT_STRIKES = 3;
144252
144271
  var MidTurnDrainTimeoutError = class extends Error {
@@ -145045,15 +145064,21 @@ ${this.pendingWorktreeNotice}
145045
145064
  );
145046
145065
  }
145047
145066
  if (functionCalls.length > 0) {
145048
- const toolResponseParts = await this.runToolCalls(
145067
+ const toolRun = await this.runToolCalls(
145049
145068
  pendingSend.signal,
145050
145069
  promptId,
145051
145070
  functionCalls
145052
145071
  );
145072
+ if (toolRun.stopAfterUserQuestionCancel) {
145073
+ await this.#preserveCancelledAskUserQuestionToolRun(
145074
+ toolRun
145075
+ );
145076
+ return { stopReason: "end_turn" };
145077
+ }
145053
145078
  nextMessage = {
145054
145079
  role: "user",
145055
145080
  parts: [
145056
- ...toolResponseParts,
145081
+ ...toolRun.parts,
145057
145082
  ...await this.#drainMidTurnUserMessages()
145058
145083
  ]
145059
145084
  };
@@ -145231,15 +145256,19 @@ ${this.pendingWorktreeNotice}
145231
145256
  );
145232
145257
  }
145233
145258
  if (functionCalls.length > 0) {
145234
- const toolResponseParts = await this.runToolCalls(
145259
+ const toolRun = await this.runToolCalls(
145235
145260
  pendingSend.signal,
145236
145261
  promptId,
145237
145262
  functionCalls
145238
145263
  );
145264
+ if (toolRun.stopAfterUserQuestionCancel) {
145265
+ await this.#preserveCancelledAskUserQuestionToolRun(toolRun);
145266
+ return { stopReason: "end_turn" };
145267
+ }
145239
145268
  nextMessage = {
145240
145269
  role: "user",
145241
145270
  parts: [
145242
- ...toolResponseParts,
145271
+ ...toolRun.parts,
145243
145272
  ...await this.#drainMidTurnUserMessages()
145244
145273
  ]
145245
145274
  };
@@ -145363,6 +145392,16 @@ ${this.pendingWorktreeNotice}
145363
145392
  });
145364
145393
  }
145365
145394
  }
145395
+ async #preserveCancelledAskUserQuestionToolRun(toolRun) {
145396
+ this.#preserveUnsentMessageHistory(
145397
+ {
145398
+ role: "user",
145399
+ parts: [...toolRun.parts, ...await this.#drainMidTurnUserMessages()]
145400
+ },
145401
+ true
145402
+ );
145403
+ await this.messageRewriter?.waitForPendingRewrites();
145404
+ }
145366
145405
  #recordCompressionTokenCount(info) {
145367
145406
  this.#syncPromptTokenCountWithCurrentChat();
145368
145407
  const tokenCount = this.#extractCompressionTokenCount(info);
@@ -145642,15 +145681,21 @@ ${this.pendingWorktreeNotice}
145642
145681
  );
145643
145682
  }
145644
145683
  if (functionCalls.length > 0) {
145645
- const toolResponseParts = await this.runToolCalls(
145684
+ const toolRun = await this.runToolCalls(
145646
145685
  ac.signal,
145647
145686
  promptId,
145648
145687
  functionCalls
145649
145688
  );
145689
+ if (toolRun.stopAfterUserQuestionCancel) {
145690
+ await this.#preserveCancelledAskUserQuestionToolRun(
145691
+ toolRun
145692
+ );
145693
+ return;
145694
+ }
145650
145695
  nextMessage = {
145651
145696
  role: "user",
145652
145697
  parts: [
145653
- ...toolResponseParts,
145698
+ ...toolRun.parts,
145654
145699
  ...await this.#drainMidTurnUserMessages()
145655
145700
  ]
145656
145701
  };
@@ -145871,15 +145916,20 @@ ${this.pendingWorktreeNotice}
145871
145916
  );
145872
145917
  }
145873
145918
  if (functionCalls.length > 0) {
145874
- const toolResponseParts = await this.runToolCalls(
145919
+ const toolRun = await this.runToolCalls(
145875
145920
  ac.signal,
145876
145921
  promptId,
145877
145922
  functionCalls
145878
145923
  );
145924
+ if (toolRun.stopAfterUserQuestionCancel) {
145925
+ await this.#preserveCancelledAskUserQuestionToolRun(toolRun);
145926
+ await this.#emitBackgroundNotificationEndTurn("end_turn");
145927
+ return;
145928
+ }
145879
145929
  nextMessage = {
145880
145930
  role: "user",
145881
145931
  parts: [
145882
- ...toolResponseParts,
145932
+ ...toolRun.parts,
145883
145933
  ...await this.#drainMidTurnUserMessages()
145884
145934
  ]
145885
145935
  };
@@ -146116,8 +146166,9 @@ ${this.pendingWorktreeNotice}
146116
146166
  * on. Response-part ordering matches the original `functionCalls` order.
146117
146167
  */
146118
146168
  async runToolCalls(abortSignal, promptId, functionCalls) {
146169
+ const dedupedFunctionCalls = dedupeToolCallsById(functionCalls);
146119
146170
  const batches = [];
146120
- for (const fc of dedupeToolCallsById(functionCalls)) {
146171
+ for (const fc of dedupedFunctionCalls) {
146121
146172
  const isAgent = fc.name === ToolNames.AGENT;
146122
146173
  const last = batches[batches.length - 1];
146123
146174
  if (isAgent && last?.concurrent) {
@@ -146126,7 +146177,45 @@ ${this.pendingWorktreeNotice}
146126
146177
  batches.push({ concurrent: isAgent, calls: [fc] });
146127
146178
  }
146128
146179
  }
146129
- const runBounded = /* @__PURE__ */ __name(async (calls) => {
146180
+ let skippedToolCallCounter = 0;
146181
+ const recordSkippedToolCall = /* @__PURE__ */ __name(async (fc) => {
146182
+ const toolName = fc.name ?? "unknown_tool";
146183
+ const callId = fc.id ?? `${toolName}-skip-${++skippedToolCallCounter}`;
146184
+ const part = {
146185
+ functionResponse: {
146186
+ id: callId,
146187
+ name: toolName,
146188
+ response: { error: ASK_USER_QUESTION_CANCEL_SKIP_MESSAGE }
146189
+ }
146190
+ };
146191
+ const error = new Error(ASK_USER_QUESTION_CANCEL_SKIP_MESSAGE);
146192
+ try {
146193
+ this.config.getChatRecordingService()?.recordToolResult([part], {
146194
+ callId,
146195
+ status: "error",
146196
+ resultDisplay: void 0,
146197
+ error,
146198
+ errorType: void 0
146199
+ });
146200
+ await this.toolCallEmitter.emitStart({
146201
+ callId,
146202
+ toolName,
146203
+ args: fc.args ?? {},
146204
+ status: "pending"
146205
+ });
146206
+ await this.toolCallEmitter.emitError(callId, toolName, error);
146207
+ } catch (recordError) {
146208
+ debugLogger78.error("Failed to record skipped tool call:", recordError);
146209
+ }
146210
+ return part;
146211
+ }, "recordSkippedToolCall");
146212
+ const appendSkippedAfter = /* @__PURE__ */ __name(async (parts2, fc) => {
146213
+ const startIndex = dedupedFunctionCalls.indexOf(fc) + 1;
146214
+ for (const remainingCall of dedupedFunctionCalls.slice(startIndex)) {
146215
+ parts2.push(await recordSkippedToolCall(remainingCall));
146216
+ }
146217
+ }, "appendSkippedAfter");
146218
+ const runBounded = /* @__PURE__ */ __name(async (calls, runAbortSignal, onStopAfterUserQuestionCancel, shouldSkipUnstarted) => {
146130
146219
  const parsed = parseInt(
146131
146220
  process.env["QWEN_CODE_MAX_TOOL_CONCURRENCY"] || "",
146132
146221
  10
@@ -146136,7 +146225,19 @@ ${this.pendingWorktreeNotice}
146136
146225
  const executing = /* @__PURE__ */ new Set();
146137
146226
  for (let i = 0; i < calls.length; i++) {
146138
146227
  const idx = i;
146139
- const p = this.runTool(abortSignal, promptId, calls[idx]).then((r) => {
146228
+ if (runAbortSignal.aborted && shouldSkipUnstarted?.()) {
146229
+ results[idx] = {
146230
+ parts: [await recordSkippedToolCall(calls[idx])],
146231
+ stopAfterUserQuestionCancel: false
146232
+ };
146233
+ continue;
146234
+ }
146235
+ const p = this.runTool(
146236
+ runAbortSignal,
146237
+ promptId,
146238
+ calls[idx],
146239
+ onStopAfterUserQuestionCancel
146240
+ ).then((r) => {
146140
146241
  results[idx] = r;
146141
146242
  }).finally(() => {
146142
146243
  executing.delete(p);
@@ -146152,16 +146253,54 @@ ${this.pendingWorktreeNotice}
146152
146253
  const parts = [];
146153
146254
  for (const batch of batches) {
146154
146255
  if (batch.concurrent && batch.calls.length > 1) {
146155
- const results = await runBounded(batch.calls);
146156
- for (const r of results) parts.push(...r);
146256
+ const batchAbortController = new AbortController();
146257
+ let batchStopAfterUserQuestionCancel = false;
146258
+ const propagateAbort = /* @__PURE__ */ __name(() => {
146259
+ batchAbortController.abort(abortSignal.reason);
146260
+ }, "propagateAbort");
146261
+ if (abortSignal.aborted) {
146262
+ propagateAbort();
146263
+ } else {
146264
+ abortSignal.addEventListener("abort", propagateAbort, {
146265
+ once: true
146266
+ });
146267
+ }
146268
+ const stopBatchAfterUserQuestionCancel = /* @__PURE__ */ __name(() => {
146269
+ batchStopAfterUserQuestionCancel = true;
146270
+ batchAbortController.abort(USER_CANCEL_ABORT_REASON);
146271
+ }, "stopBatchAfterUserQuestionCancel");
146272
+ let results;
146273
+ try {
146274
+ results = await runBounded(
146275
+ batch.calls,
146276
+ batchAbortController.signal,
146277
+ stopBatchAfterUserQuestionCancel,
146278
+ () => batchStopAfterUserQuestionCancel
146279
+ );
146280
+ } finally {
146281
+ abortSignal.removeEventListener("abort", propagateAbort);
146282
+ }
146283
+ let shouldStop = false;
146284
+ for (const r of results) {
146285
+ parts.push(...r.parts);
146286
+ shouldStop ||= r.stopAfterUserQuestionCancel;
146287
+ }
146288
+ if (shouldStop) {
146289
+ await appendSkippedAfter(parts, batch.calls[batch.calls.length - 1]);
146290
+ return { parts, stopAfterUserQuestionCancel: true };
146291
+ }
146157
146292
  } else {
146158
146293
  for (const fc of batch.calls) {
146159
146294
  const r = await this.runTool(abortSignal, promptId, fc);
146160
- parts.push(...r);
146295
+ parts.push(...r.parts);
146296
+ if (r.stopAfterUserQuestionCancel) {
146297
+ await appendSkippedAfter(parts, fc);
146298
+ return { parts, stopAfterUserQuestionCancel: true };
146299
+ }
146161
146300
  }
146162
146301
  }
146163
146302
  }
146164
- return parts;
146303
+ return { parts, stopAfterUserQuestionCancel: false };
146165
146304
  }
146166
146305
  /**
146167
146306
  * Assemble the per-turn system reminders the model needs to see at the
@@ -146193,11 +146332,15 @@ ${this.pendingWorktreeNotice}
146193
146332
  }
146194
146333
  return reminders;
146195
146334
  }
146196
- async runTool(abortSignal, promptId, fc) {
146335
+ async runTool(abortSignal, promptId, fc, onStopAfterUserQuestionCancel) {
146197
146336
  const callId = fc.id ?? `${fc.name}-${Date.now()}`;
146198
146337
  let args = fc.args ?? {};
146199
146338
  const startTime = Date.now();
146200
146339
  let spanError;
146340
+ let activeToolAbortSignal = abortSignal;
146341
+ let nestedAskUserQuestionCancelled = false;
146342
+ let agentToolAbortController;
146343
+ let removeAgentToolAbortPropagation;
146201
146344
  const errorResponse = /* @__PURE__ */ __name((error) => {
146202
146345
  const durationMs = Date.now() - startTime;
146203
146346
  logToolCall(this.config, {
@@ -146208,7 +146351,7 @@ ${this.pendingWorktreeNotice}
146208
146351
  function_args: args,
146209
146352
  duration_ms: durationMs,
146210
146353
  // An aborted signal means the call was cancelled, not a genuine error.
146211
- status: abortSignal.aborted ? "cancelled" : "error",
146354
+ status: activeToolAbortSignal.aborted ? "cancelled" : "error",
146212
146355
  success: false,
146213
146356
  error: error.message,
146214
146357
  tool_type: typeof tool !== "undefined" && tool instanceof DiscoveredMCPTool ? "mcp" : "native"
@@ -146223,8 +146366,9 @@ ${this.pendingWorktreeNotice}
146223
146366
  }
146224
146367
  ];
146225
146368
  }, "errorResponse");
146226
- const earlyErrorResponse = /* @__PURE__ */ __name(async (error, toolName2 = fc.name ?? "unknown_tool") => {
146369
+ const earlyErrorResponse = /* @__PURE__ */ __name(async (error, toolName2 = fc.name ?? "unknown_tool", opts) => {
146227
146370
  spanError = error.message;
146371
+ removeAgentToolAbortPropagation?.();
146228
146372
  if (toolName2 !== ToolNames.TODO_WRITE) {
146229
146373
  await this.toolCallEmitter.emitError(callId, toolName2, error);
146230
146374
  }
@@ -146236,7 +146380,10 @@ ${this.pendingWorktreeNotice}
146236
146380
  error,
146237
146381
  errorType: void 0
146238
146382
  });
146239
- return errorParts;
146383
+ return {
146384
+ parts: errorParts,
146385
+ stopAfterUserQuestionCancel: opts?.stopAfterUserQuestionCancel ?? false
146386
+ };
146240
146387
  }, "earlyErrorResponse");
146241
146388
  if (!fc.name) {
146242
146389
  return earlyErrorResponse(new Error("Missing function name"));
@@ -146271,6 +146418,23 @@ ${this.pendingWorktreeNotice}
146271
146418
  const isAgentTool = tool.name === ToolNames.AGENT;
146272
146419
  const isExitPlanModeTool = tool.name === ToolNames.EXIT_PLAN_MODE;
146273
146420
  const isEnterPlanModeTool = tool.name === ToolNames.ENTER_PLAN_MODE;
146421
+ if (isAgentTool) {
146422
+ agentToolAbortController = new AbortController();
146423
+ activeToolAbortSignal = agentToolAbortController.signal;
146424
+ const propagateAbort = /* @__PURE__ */ __name(() => {
146425
+ agentToolAbortController?.abort(abortSignal.reason);
146426
+ }, "propagateAbort");
146427
+ if (abortSignal.aborted) {
146428
+ propagateAbort();
146429
+ } else {
146430
+ abortSignal.addEventListener("abort", propagateAbort, {
146431
+ once: true
146432
+ });
146433
+ removeAgentToolAbortPropagation = /* @__PURE__ */ __name(() => {
146434
+ abortSignal.removeEventListener("abort", propagateAbort);
146435
+ }, "removeAgentToolAbortPropagation");
146436
+ }
146437
+ }
146274
146438
  let subAgentCleanupFunctions = [];
146275
146439
  const toolUseId = generateToolUseId();
146276
146440
  const approvalMode = this.config.getApprovalMode();
@@ -146284,11 +146448,16 @@ ${this.pendingWorktreeNotice}
146284
146448
  this,
146285
146449
  this.client,
146286
146450
  parentToolCallId,
146287
- subagentType
146451
+ subagentType,
146452
+ () => {
146453
+ nestedAskUserQuestionCancelled = true;
146454
+ agentToolAbortController?.abort(USER_CANCEL_ABORT_REASON);
146455
+ onStopAfterUserQuestionCancel?.();
146456
+ }
146288
146457
  );
146289
146458
  subAgentCleanupFunctions = subSubAgentTracker.setup(
146290
146459
  taskEventEmitter,
146291
- abortSignal
146460
+ activeToolAbortSignal
146292
146461
  );
146293
146462
  }
146294
146463
  const isAskUserQuestionTool = toolName === ToolNames.ASK_USER_QUESTION;
@@ -146506,9 +146675,15 @@ ${this.pendingWorktreeNotice}
146506
146675
  }
146507
146676
  switch (outcome) {
146508
146677
  case "cancel" /* Cancel */:
146678
+ if (toolName === ToolNames.ASK_USER_QUESTION) {
146679
+ onStopAfterUserQuestionCancel?.();
146680
+ }
146509
146681
  return earlyErrorResponse(
146510
146682
  new Error(`Tool "${toolName}" was canceled by the user.`),
146511
- toolName
146683
+ toolName,
146684
+ {
146685
+ stopAfterUserQuestionCancel: toolName === ToolNames.ASK_USER_QUESTION
146686
+ }
146512
146687
  );
146513
146688
  case "proceed_once" /* ProceedOnce */:
146514
146689
  case "proceed_always" /* ProceedAlways */:
@@ -146545,7 +146720,7 @@ ${this.pendingWorktreeNotice}
146545
146720
  args,
146546
146721
  toolUseId,
146547
146722
  permissionMode,
146548
- abortSignal
146723
+ activeToolAbortSignal
146549
146724
  );
146550
146725
  if (!preHookResult.shouldProceed) {
146551
146726
  const blockReason = preHookResult.blockReason || "Blocked by PreToolUse hook";
@@ -146568,11 +146743,11 @@ ${this.pendingWorktreeNotice}
146568
146743
  `Qwen Code is executing tool ${toolName}`
146569
146744
  );
146570
146745
  try {
146571
- toolResult = await invocation.execute(abortSignal);
146746
+ toolResult = await invocation.execute(activeToolAbortSignal);
146572
146747
  } finally {
146573
146748
  sleepInhibitorHandle.release();
146574
146749
  }
146575
- const aborted2 = abortSignal.aborted;
146750
+ const aborted2 = activeToolAbortSignal.aborted;
146576
146751
  endToolExecutionSpan(execSpan, {
146577
146752
  success: !toolResult.error && !aborted2,
146578
146753
  error: aborted2 ? "tool_cancelled" : toolResult.error ? "tool_error" : void 0,
@@ -146581,12 +146756,13 @@ ${this.pendingWorktreeNotice}
146581
146756
  } catch (execError) {
146582
146757
  endToolExecutionSpan(execSpan, {
146583
146758
  success: false,
146584
- error: abortSignal.aborted ? "tool_cancelled" : "tool_exception",
146585
- cancelled: abortSignal.aborted
146759
+ error: activeToolAbortSignal.aborted ? "tool_cancelled" : "tool_exception",
146760
+ cancelled: activeToolAbortSignal.aborted
146586
146761
  });
146587
146762
  throw execError;
146588
146763
  }
146589
146764
  subAgentCleanupFunctions.forEach((cleanup) => cleanup());
146765
+ removeAgentToolAbortPropagation?.();
146590
146766
  if ((isEnterPlanModeTool || isExitPlanModeTool) && !didRequestPermission && !toolResult.error && this.config.getApprovalMode() !== approvalMode) {
146591
146767
  await this.sendUpdate({
146592
146768
  sessionUpdate: "current_mode_update",
@@ -146598,7 +146774,10 @@ ${this.pendingWorktreeNotice}
146598
146774
  callId,
146599
146775
  toolResult.llmContent
146600
146776
  );
146601
- if (hooksEnabledForTool && messageBusForTool && !toolResult.error) {
146777
+ const aborted = activeToolAbortSignal.aborted;
146778
+ const status = aborted ? "cancelled" : toolResult.error ? "error" : "success";
146779
+ const succeeded = status === "success";
146780
+ if (hooksEnabledForTool && messageBusForTool && !toolResult.error && !aborted && !nestedAskUserQuestionCancelled) {
146602
146781
  const toolResponse = {
146603
146782
  llmContent: toolResult.llmContent,
146604
146783
  returnDisplay: toolResult.returnDisplay
@@ -146610,7 +146789,7 @@ ${this.pendingWorktreeNotice}
146610
146789
  toolResponse,
146611
146790
  toolUseId,
146612
146791
  permissionMode,
146613
- abortSignal
146792
+ activeToolAbortSignal
146614
146793
  );
146615
146794
  if (postHookResult.shouldStop) {
146616
146795
  const stopMessage = postHookResult.stopReason || "Execution stopped by PostToolUse hook";
@@ -146623,17 +146802,17 @@ ${this.pendingWorktreeNotice}
146623
146802
  const contextPart = { text: postHookResult.additionalContext };
146624
146803
  responseParts.push(contextPart);
146625
146804
  }
146626
- } else if (hooksEnabledForTool && messageBusForTool && toolResult.error) {
146805
+ } else if (hooksEnabledForTool && messageBusForTool && (toolResult.error || aborted)) {
146806
+ const isInterrupt = aborted;
146627
146807
  const failureHookResult = await firePostToolUseFailureHook(
146628
146808
  messageBusForTool,
146629
146809
  toolUseId,
146630
146810
  toolName,
146631
146811
  args,
146632
- toolResult.error.message,
146633
- false,
146634
- // not an interrupt
146812
+ toolResult.error?.message ?? "Tool execution was cancelled",
146813
+ isInterrupt,
146635
146814
  permissionMode,
146636
- abortSignal
146815
+ activeToolAbortSignal
146637
146816
  );
146638
146817
  if (failureHookResult.additionalContext) {
146639
146818
  debugLogger78.debug(
@@ -146641,9 +146820,6 @@ ${this.pendingWorktreeNotice}
146641
146820
  );
146642
146821
  }
146643
146822
  }
146644
- const aborted = abortSignal.aborted;
146645
- const status = aborted ? "cancelled" : toolResult.error ? "error" : "success";
146646
- const succeeded = status === "success";
146647
146823
  if (isTodoWriteTool) {
146648
146824
  const todos = this.planEmitter.extractTodos(
146649
146825
  toolResult.returnDisplay,
@@ -146691,14 +146867,18 @@ ${this.pendingWorktreeNotice}
146691
146867
  } else if (aborted) {
146692
146868
  spanError = "Tool execution was cancelled";
146693
146869
  }
146694
- return responseParts;
146870
+ return {
146871
+ parts: responseParts,
146872
+ stopAfterUserQuestionCancel: nestedAskUserQuestionCancelled
146873
+ };
146695
146874
  } catch (e) {
146696
146875
  subAgentCleanupFunctions.forEach((cleanup) => cleanup());
146876
+ removeAgentToolAbortPropagation?.();
146697
146877
  const error = e instanceof Error ? e : new Error(String(e));
146698
146878
  spanError = error.message;
146699
146879
  const hooksEnabledForError = !this.config.getDisableAllHooks?.();
146700
146880
  const messageBusForError = this.config.getMessageBus?.();
146701
- const isInterrupt = abortSignal.aborted;
146881
+ const isInterrupt = activeToolAbortSignal.aborted;
146702
146882
  if (hooksEnabledForError && messageBusForError) {
146703
146883
  const failureHookResult = await firePostToolUseFailureHook(
146704
146884
  messageBusForError,
@@ -146708,7 +146888,7 @@ ${this.pendingWorktreeNotice}
146708
146888
  error.message,
146709
146889
  isInterrupt,
146710
146890
  String(approvalMode),
146711
- abortSignal
146891
+ activeToolAbortSignal
146712
146892
  );
146713
146893
  if (failureHookResult.additionalContext) {
146714
146894
  debugLogger78.debug(
@@ -146730,12 +146910,15 @@ ${this.pendingWorktreeNotice}
146730
146910
  callId,
146731
146911
  // A throw caused by abort (e.g. AbortError) is a cancellation, not
146732
146912
  // a genuine tool error — keep it consistent with the success path.
146733
- status: abortSignal.aborted ? "cancelled" : "error",
146913
+ status: activeToolAbortSignal.aborted ? "cancelled" : "error",
146734
146914
  resultDisplay: void 0,
146735
146915
  error,
146736
146916
  errorType: void 0
146737
146917
  });
146738
- return errorResponse(error);
146918
+ return {
146919
+ parts: errorResponse(error),
146920
+ stopAfterUserQuestionCancel: nestedAskUserQuestionCancelled
146921
+ };
146739
146922
  }
146740
146923
  });
146741
146924
  } finally {
@@ -148782,7 +148965,7 @@ var QwenAgent = class {
148782
148965
  async initialize(args) {
148783
148966
  this.clientCapabilities = args.clientCapabilities;
148784
148967
  const authMethods = buildAuthMethods();
148785
- const version = "0.18.2";
148968
+ const version = "0.18.3-preview.0";
148786
148969
  return {
148787
148970
  protocolVersion: PROTOCOL_VERSION,
148788
148971
  agentInfo: {
@@ -152870,7 +153053,7 @@ ${finalArgs[promptIndex + 1]}`;
152870
153053
  process.exit(0);
152871
153054
  }
152872
153055
  if (config.isInteractive()) {
152873
- void import("./chunks/scheduler-J3OUGTTS.js").then((m) => m.startBackgroundHousekeeping(config, settings)).catch((err) => {
153056
+ void import("./chunks/scheduler-WCMRRLYM.js").then((m) => m.startBackgroundHousekeeping(config, settings)).catch((err) => {
152874
153057
  debugLogger80.warn("failed to start background housekeeping:", err);
152875
153058
  });
152876
153059
  }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@qwen-code/qwen-code",
3
- "version": "0.18.2",
3
+ "version": "0.18.3-preview.0",
4
4
  "description": "Qwen Code - AI-powered coding assistant",
5
5
  "repository": {
6
6
  "type": "git",
@@ -25,7 +25,7 @@
25
25
  "bundled"
26
26
  ],
27
27
  "config": {
28
- "sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.18.2"
28
+ "sandboxImageUri": "ghcr.io/qwenlm/qwen-code:0.18.3-preview.0"
29
29
  },
30
30
  "dependencies": {},
31
31
  "optionalDependencies": {