@qwen-code/qwen-code 0.17.1 → 0.18.0-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 (120) hide show
  1. package/README.md +4 -6
  2. package/bundled/qc-helper/SKILL.md +30 -24
  3. package/bundled/qc-helper/docs/features/auto-mode.md +54 -9
  4. package/bundled/qc-helper/docs/features/commands.md +11 -11
  5. package/bundled/qc-helper/docs/features/markdown-rendering.md +21 -1
  6. package/bundled/qc-helper/docs/overview.md +4 -4
  7. package/bundled/qc-helper/docs/quickstart.md +4 -4
  8. package/bundled/qc-helper/docs/support/Uninstall.md +19 -1
  9. package/bundled/qc-helper/docs/support/troubleshooting.md +2 -1
  10. package/chunks/{agent-ZJHHICAC.js → agent-6J2FFD7S.js} +18 -22
  11. package/chunks/{anthropicContentGenerator-M45RXZVS.js → anthropicContentGenerator-4QBVSFSJ.js} +5 -5
  12. package/chunks/{askUserQuestion-TGRD7FNQ.js → askUserQuestion-NOOLRWCJ.js} +5 -7
  13. package/chunks/{ca-6RSCDYUS.js → ca-WRHFBIDH.js} +38 -3
  14. package/chunks/{chunk-C5CUHYSM.js → chunk-3H7ENG2Q.js} +821 -461
  15. package/chunks/{chunk-SOGUPKP6.js → chunk-5RNZ2QKF.js} +3 -5
  16. package/chunks/{chunk-GVWPJCXU.js → chunk-6VFG3EUJ.js} +1 -1
  17. package/chunks/{chunk-NQ3E7YLD.js → chunk-AVLOK27J.js} +42 -8
  18. package/chunks/{chunk-JBSYXHJF.js → chunk-BBTV54KB.js} +2 -2
  19. package/chunks/{chunk-X2474BTT.js → chunk-BPZQVC2P.js} +142 -9
  20. package/chunks/{chunk-2KEXT6RB.js → chunk-BUOJN3MM.js} +91245 -78527
  21. package/chunks/{chunk-3BJBCG2K.js → chunk-C6WMLUNB.js} +1 -1
  22. package/chunks/{chunk-TDZCEIK6.js → chunk-D46KOV3C.js} +1 -1
  23. package/chunks/{chunk-HX3JRTWL.js → chunk-F5ORN4YO.js} +1 -1
  24. package/chunks/{chunk-JKUAX6UT.js → chunk-G763GDO6.js} +125 -12
  25. package/chunks/{chunk-OIL7KDWV.js → chunk-GBEPNWYB.js} +1 -1
  26. package/chunks/{chunk-5JBZM7FZ.js → chunk-IKOMHTCC.js} +6 -6
  27. package/chunks/{chunk-G4K6P5KN.js → chunk-JMLIPZUU.js} +3 -3
  28. package/chunks/{chunk-OJFMTECH.js → chunk-JSYEZAYV.js} +2 -2
  29. package/chunks/{chunk-AKBFRR6J.js → chunk-K5PGHDBN.js} +132 -112
  30. package/chunks/{chunk-QVJ33ZBG.js → chunk-MVX64PNU.js} +1 -1
  31. package/chunks/{chunk-EY6BDW7Y.js → chunk-PLYZAP4W.js} +45 -9
  32. package/chunks/{chunk-ACBGEKB7.js → chunk-R5PDRHEF.js} +2 -1
  33. package/chunks/{chunk-6O244QKR.js → chunk-SCHRFI7O.js} +1 -1
  34. package/chunks/{chunk-GJHMAWS7.js → chunk-SHUT5MQY.js} +1 -1
  35. package/chunks/{chunk-RQW7WUJR.js → chunk-UABFCMPA.js} +34 -6
  36. package/chunks/{chunk-33RDTIU6.js → chunk-UFC57OYT.js} +3 -5
  37. package/chunks/{chunk-PLYRQYKC.js → chunk-UQZQP5PA.js} +11 -11
  38. package/chunks/{chunk-NP3ICQCN.js → chunk-USE2VQ5P.js} +1 -1
  39. package/chunks/{chunk-NJJER6E2.js → chunk-UXBKX55L.js} +10 -6
  40. package/chunks/{chunk-QWSRH265.js → chunk-WFVXF3OM.js} +776 -776
  41. package/chunks/{computer-use-NAHQPV2L.js → computer-use-6LZXL3UW.js} +51 -18
  42. package/chunks/contextCommand-ZV5QQ2LA.js +46 -0
  43. package/chunks/{cron-create-V3UK2SJN.js → cron-create-PIPMXQN4.js} +5 -7
  44. package/chunks/{cron-delete-MANALPCP.js → cron-delete-6Y5XIDMS.js} +5 -7
  45. package/chunks/{cron-list-UDIYK3B3.js → cron-list-A4WNRUWZ.js} +5 -7
  46. package/chunks/{de-APURNJ3I.js → de-M5RPB2NB.js} +38 -3
  47. package/chunks/{dist-XTTPOFAH.js → dist-BXDUQ2QY.js} +3 -4
  48. package/chunks/{dist-AHZNZWRI.js → dist-R2SXPG74.js} +4 -5
  49. package/chunks/{dist-ATAKC63R.js → dist-TE5QKMGR.js} +3 -4
  50. package/chunks/{dist-6RUZ2JD6.js → dist-ZMQ4TXD5.js} +3 -4
  51. package/chunks/{edit-JWXCQ4KK.js → edit-J7D6VMPQ.js} +22 -27
  52. package/chunks/{en-FYO57HJW.js → en-UMYKQAZE.js} +46 -3
  53. package/chunks/{enter-worktree-G4CJXPT4.js → enter-worktree-NDJTVGYJ.js} +20 -25
  54. package/chunks/{exit-worktree-MYZ2FGU2.js → exit-worktree-UB6XYYAX.js} +20 -25
  55. package/chunks/{exitPlanMode-ELJ6FSMU.js → exitPlanMode-V6X2KL4X.js} +20 -25
  56. package/chunks/{fr-32YHQZIS.js → fr-MPYXXXPW.js} +38 -3
  57. package/chunks/{geminiContentGenerator-3LR7MKCQ.js → geminiContentGenerator-3AKHMB3P.js} +5 -5
  58. package/chunks/{getMachineId-bsd-GS3V2GK7.js → getMachineId-bsd-F7GNPTER.js} +1 -1
  59. package/chunks/{getMachineId-darwin-ZQB4Q7EW.js → getMachineId-darwin-T73DJL27.js} +1 -1
  60. package/chunks/{getMachineId-linux-JQ4NN4DN.js → getMachineId-linux-MKQTFPQM.js} +1 -1
  61. package/chunks/{getMachineId-unsupported-U7H4V4HJ.js → getMachineId-unsupported-MUR5KOQE.js} +1 -1
  62. package/chunks/{getMachineId-win-VHUZGBQ3.js → getMachineId-win-CDYFC6ZM.js} +1 -1
  63. package/chunks/{glob-CANUAUTC.js → glob-PBG5DRG4.js} +20 -25
  64. package/chunks/{grep-WZWNJRDX.js → grep-VQ56EWQ7.js} +20 -25
  65. package/chunks/{ja-PEUXN4XT.js → ja-NFZ32AB3.js} +38 -3
  66. package/chunks/{keychain-token-storage-3552ENXE.js → keychain-token-storage-UHGOCDD6.js} +3 -3
  67. package/chunks/{ls-T4SVZWR6.js → ls-34DLNYCD.js} +6 -8
  68. package/chunks/{lsp-U4ZQLNIS.js → lsp-NCDEHH3V.js} +5 -7
  69. package/chunks/{monitor-CCKNOUFG.js → monitor-J3YCSOEH.js} +20 -25
  70. package/chunks/{notebook-edit-XDUY5Q4I.js → notebook-edit-AL3CBYJ6.js} +21 -26
  71. package/chunks/{openaiContentGenerator-N3O3MYIT.js → openaiContentGenerator-3U6UARHS.js} +12 -14
  72. package/chunks/{pt-2INS7YVC.js → pt-BR43FRBA.js} +38 -3
  73. package/chunks/{qwenContentGenerator-DEOIWKVH.js → qwenContentGenerator-JRFHJRH6.js} +20 -24
  74. package/chunks/{qwenOAuth2-LKXG7XVO.js → qwenOAuth2-KRJT35QH.js} +5 -5
  75. package/chunks/{read-file-BRNXGILN.js → read-file-ZF6EIVE3.js} +9 -11
  76. package/chunks/ripGrep-N2ZT7M6Z.js +42 -0
  77. package/chunks/{ru-6CQ5HNHB.js → ru-DQCW2KHD.js} +38 -3
  78. package/chunks/{scheduler-SSFABMN5.js → scheduler-OS37FUFT.js} +18 -22
  79. package/chunks/{send-message-GFYV7WLL.js → send-message-YYF56TS7.js} +5 -7
  80. package/chunks/{serve-B5O72CRN.js → serve-ABOLLDNN.js} +21 -25
  81. package/chunks/{shell-SGYNBVMK.js → shell-XGN7IDUS.js} +18 -22
  82. package/chunks/{skill-V7Y6DOFB.js → skill-YQQ6CR4U.js} +88 -25
  83. package/chunks/{src-OKFFQGXB.js → src-LORPPHWB.js} +86 -33
  84. package/chunks/{syntheticOutput-DM43O6TY.js → syntheticOutput-T5SWX3YF.js} +4 -5
  85. package/chunks/{task-stop-WKP5OB3V.js → task-stop-3VHAQMYM.js} +5 -7
  86. package/chunks/{todoWrite-GHL6DCLP.js → todoWrite-EAGJGKO5.js} +7 -9
  87. package/chunks/{tool-search-7MHT3HGM.js → tool-search-PDOJPXJJ.js} +27 -15
  88. package/chunks/{web-fetch-SZIV74ZX.js → web-fetch-SS6IKK6N.js} +7 -9
  89. package/chunks/{write-file-ARS2Z6BJ.js → write-file-VWWCN7LI.js} +23 -28
  90. package/chunks/{zh-ZHZCMIRG.js → zh-6VFXOAR5.js} +49 -3
  91. package/chunks/{zh-TW-SSL3ATVZ.js → zh-TW-IQZ4AD5M.js} +45 -3
  92. package/cli.js +8143 -4150
  93. package/examples/agent/agents/diary.md +86 -0
  94. package/examples/agent/qwen-extension.json +4 -0
  95. package/examples/commands/commands/fs/grep-code.md +3 -0
  96. package/examples/commands/qwen-extension.json +4 -0
  97. package/examples/context/QWEN.md +8 -0
  98. package/examples/context/qwen-extension.json +4 -0
  99. package/examples/mcp-server/example.ts +60 -0
  100. package/examples/mcp-server/package.json +18 -0
  101. package/examples/mcp-server/qwen-extension.json +11 -0
  102. package/examples/mcp-server/tsconfig.json +13 -0
  103. package/examples/skills/qwen-extension.json +4 -0
  104. package/examples/skills/skills/synonyms/SKILL.md +48 -0
  105. package/locales/ca.js +64 -4
  106. package/locales/de.js +63 -4
  107. package/locales/en.js +75 -4
  108. package/locales/fr.js +65 -4
  109. package/locales/ja.js +61 -4
  110. package/locales/pt.js +64 -4
  111. package/locales/ru.js +62 -4
  112. package/locales/zh-TW.js +70 -4
  113. package/locales/zh.js +74 -4
  114. package/package.json +3 -2
  115. package/chunks/chunk-24YKA2DA.js +0 -233
  116. package/chunks/chunk-6RQTH7UQ.js +0 -115
  117. package/chunks/chunk-7TQVELRB.js +0 -10412
  118. package/chunks/chunk-W57YDFU5.js +0 -41
  119. package/chunks/contextCommand-7KJT3UJS.js +0 -50
  120. package/chunks/ripGrep-ZRY5PKUZ.js +0 -46
@@ -14,30 +14,25 @@ import {
14
14
  import {
15
15
  require_hasown
16
16
  } from "./chunk-UWCTAVOD.js";
17
- import {
18
- safeJsonStringify
19
- } from "./chunk-W57YDFU5.js";
20
17
  import {
21
18
  DEFAULT_QWEN_MODEL,
22
19
  MAINLINE_CODER_MODEL
23
20
  } from "./chunk-OFEVLU4C.js";
24
21
  import {
25
- isAutoMemPath
26
- } from "./chunk-NQ3E7YLD.js";
22
+ isAnyAutoMemPath
23
+ } from "./chunk-AVLOK27J.js";
27
24
  import {
28
25
  InstallationManager
29
- } from "./chunk-OJFMTECH.js";
26
+ } from "./chunk-JSYEZAYV.js";
30
27
  import {
31
28
  STRUCTURED_OUTPUT_REDACTED_ARGS
32
- } from "./chunk-SOGUPKP6.js";
29
+ } from "./chunk-5RNZ2QKF.js";
33
30
  import {
31
+ BaseDeclarativeTool,
32
+ BaseToolInvocation,
34
33
  ToolDisplayNames,
35
34
  ToolNames
36
- } from "./chunk-6RQTH7UQ.js";
37
- import {
38
- BaseDeclarativeTool,
39
- BaseToolInvocation
40
- } from "./chunk-JKUAX6UT.js";
35
+ } from "./chunk-G763GDO6.js";
41
36
  import {
42
37
  DEFAULT_OPENAI_BASE_URL,
43
38
  convertSchema,
@@ -45,7 +40,7 @@ import {
45
40
  runtimeDiagnostics,
46
41
  safeJsonParse,
47
42
  tokenLimit
48
- } from "./chunk-TDZCEIK6.js";
43
+ } from "./chunk-D46KOV3C.js";
49
44
  import {
50
45
  FinishReason,
51
46
  GenerateContentResponse
@@ -65,7 +60,7 @@ import {
65
60
  setSessionContext,
66
61
  shortenPath,
67
62
  unescapePath
68
- } from "./chunk-ACBGEKB7.js";
63
+ } from "./chunk-R5PDRHEF.js";
69
64
  import {
70
65
  require_dist
71
66
  } from "./chunk-ZERZSAZL.js";
@@ -86,7 +81,7 @@ import {
86
81
  isSpanContextValid,
87
82
  metrics,
88
83
  trace
89
- } from "./chunk-QWSRH265.js";
84
+ } from "./chunk-WFVXF3OM.js";
90
85
  import {
91
86
  __qwen_dirname,
92
87
  init_esbuild_shims
@@ -48138,19 +48133,19 @@ var require_getMachineId = __commonJS({
48138
48133
  if (!getMachineIdImpl) {
48139
48134
  switch (process3.platform) {
48140
48135
  case "darwin":
48141
- getMachineIdImpl = (await import("./getMachineId-darwin-ZQB4Q7EW.js")).getMachineId;
48136
+ getMachineIdImpl = (await import("./getMachineId-darwin-T73DJL27.js")).getMachineId;
48142
48137
  break;
48143
48138
  case "linux":
48144
- getMachineIdImpl = (await import("./getMachineId-linux-JQ4NN4DN.js")).getMachineId;
48139
+ getMachineIdImpl = (await import("./getMachineId-linux-MKQTFPQM.js")).getMachineId;
48145
48140
  break;
48146
48141
  case "freebsd":
48147
- getMachineIdImpl = (await import("./getMachineId-bsd-GS3V2GK7.js")).getMachineId;
48142
+ getMachineIdImpl = (await import("./getMachineId-bsd-F7GNPTER.js")).getMachineId;
48148
48143
  break;
48149
48144
  case "win32":
48150
- getMachineIdImpl = (await import("./getMachineId-win-VHUZGBQ3.js")).getMachineId;
48145
+ getMachineIdImpl = (await import("./getMachineId-win-CDYFC6ZM.js")).getMachineId;
48151
48146
  break;
48152
48147
  default:
48153
- getMachineIdImpl = (await import("./getMachineId-unsupported-U7H4V4HJ.js")).getMachineId;
48148
+ getMachineIdImpl = (await import("./getMachineId-unsupported-MUR5KOQE.js")).getMachineId;
48154
48149
  break;
48155
48150
  }
48156
48151
  }
@@ -62731,6 +62726,7 @@ var EVENT_IDE_CONNECTION = "qwen-code.ide_connection";
62731
62726
  var EVENT_CHAT_COMPRESSION = "qwen-code.chat_compression";
62732
62727
  var EVENT_CONTENT_RETRY = "qwen-code.chat.content_retry";
62733
62728
  var EVENT_CONTENT_RETRY_FAILURE = "qwen-code.chat.content_retry_failure";
62729
+ var EVENT_API_RETRY = "qwen-code.api_retry";
62734
62730
  var EVENT_CONVERSATION_FINISHED = "qwen-code.conversation_finished";
62735
62731
  var EVENT_FILE_OPERATION = "qwen-code.file_operation";
62736
62732
  var EVENT_MODEL_SLASH_COMMAND = "qwen-code.slash_command.model";
@@ -62752,6 +62748,7 @@ var SPAN_TOOL = "qwen-code.tool";
62752
62748
  var SPAN_TOOL_EXECUTION = "qwen-code.tool.execution";
62753
62749
  var SPAN_TOOL_BLOCKED_ON_USER = "qwen-code.tool.blocked_on_user";
62754
62750
  var SPAN_HOOK = "qwen-code.hook";
62751
+ var SPAN_SUBAGENT = "qwen-code.subagent";
62755
62752
 
62756
62753
  // packages/core/src/telemetry/metrics.ts
62757
62754
  var TOOL_CALL_COUNT = `${SERVICE_NAME}.tool.call.count`;
@@ -62764,6 +62761,7 @@ var FILE_OPERATION_COUNT = `${SERVICE_NAME}.file.operation.count`;
62764
62761
  var INVALID_CHUNK_COUNT = `${SERVICE_NAME}.chat.invalid_chunk.count`;
62765
62762
  var CONTENT_RETRY_COUNT = `${SERVICE_NAME}.chat.content_retry.count`;
62766
62763
  var CONTENT_RETRY_FAILURE_COUNT = `${SERVICE_NAME}.chat.content_retry_failure.count`;
62764
+ var API_RETRY_COUNT = `${SERVICE_NAME}.api.retry.count`;
62767
62765
  var MODEL_SLASH_COMMAND_CALL_COUNT = `${SERVICE_NAME}.slash_command.model.call_count`;
62768
62766
  var SUBAGENT_EXECUTION_COUNT = `${SERVICE_NAME}.subagent.execution.count`;
62769
62767
  var ARENA_SESSION_COUNT = `${SERVICE_NAME}.arena.session.count`;
@@ -62853,6 +62851,12 @@ var COUNTER_DEFINITIONS = {
62853
62851
  assign: /* @__PURE__ */ __name((c) => contentRetryFailureCounter = c, "assign"),
62854
62852
  attributes: {}
62855
62853
  },
62854
+ [API_RETRY_COUNT]: {
62855
+ description: "Counts HTTP-status retries (429/5xx) at LLM call sites, emitted by retryWithBackoff onRetry callback.",
62856
+ valueType: ValueType.INT,
62857
+ assign: /* @__PURE__ */ __name((c) => apiRetryCounter = c, "assign"),
62858
+ attributes: {}
62859
+ },
62856
62860
  [MODEL_SLASH_COMMAND_CALL_COUNT]: {
62857
62861
  description: "Counts model slash command calls.",
62858
62862
  valueType: ValueType.INT,
@@ -63010,6 +63014,7 @@ var chatCompressionCounter;
63010
63014
  var invalidChunkCounter;
63011
63015
  var contentRetryCounter;
63012
63016
  var contentRetryFailureCounter;
63017
+ var apiRetryCounter;
63013
63018
  var subagentExecutionCounter;
63014
63019
  var modelSlashCommandCallCounter;
63015
63020
  var startupTimeHistogram;
@@ -63216,6 +63221,14 @@ function recordContentRetryFailure(config) {
63216
63221
  );
63217
63222
  }
63218
63223
  __name(recordContentRetryFailure, "recordContentRetryFailure");
63224
+ function recordApiRetry(config, attributes) {
63225
+ if (!apiRetryCounter || !isMetricsInitialized) return;
63226
+ apiRetryCounter.add(1, {
63227
+ ...baseMetricDefinition.getCommonAttributes(config),
63228
+ ...attributes
63229
+ });
63230
+ }
63231
+ __name(recordApiRetry, "recordApiRetry");
63219
63232
  function recordModelSlashCommand(config, event) {
63220
63233
  if (!modelSlashCommandCallCounter || !isMetricsInitialized) return;
63221
63234
  modelSlashCommandCallCounter.add(1, {
@@ -63591,6 +63604,30 @@ function isInternalPromptId(promptId) {
63591
63604
  }
63592
63605
  __name(isInternalPromptId, "isInternalPromptId");
63593
63606
 
63607
+ // packages/core/src/utils/safeJsonStringify.ts
63608
+ init_esbuild_shims();
63609
+ function safeJsonStringify(obj, space) {
63610
+ const ancestors = [];
63611
+ return JSON.stringify(
63612
+ obj,
63613
+ function(_key, value) {
63614
+ if (typeof value !== "object" || value === null) {
63615
+ return value;
63616
+ }
63617
+ while (ancestors.length > 0 && ancestors[ancestors.length - 1] !== this) {
63618
+ ancestors.pop();
63619
+ }
63620
+ if (ancestors.includes(value)) {
63621
+ return "[Circular]";
63622
+ }
63623
+ ancestors.push(value);
63624
+ return value;
63625
+ },
63626
+ space
63627
+ );
63628
+ }
63629
+ __name(safeJsonStringify, "safeJsonStringify");
63630
+
63594
63631
  // packages/core/src/telemetry/qwen-logger/qwen-logger.ts
63595
63632
  init_esbuild_shims();
63596
63633
  var import_https_proxy_agent = __toESM(require_dist(), 1);
@@ -64738,6 +64775,50 @@ var ContentRetryEvent = class {
64738
64775
  this.model = model;
64739
64776
  }
64740
64777
  };
64778
+ var ApiRetryEvent = class {
64779
+ static {
64780
+ __name(this, "ApiRetryEvent");
64781
+ }
64782
+ "event.name";
64783
+ "event.timestamp";
64784
+ // ISO 8601
64785
+ model;
64786
+ prompt_id;
64787
+ attempt_number;
64788
+ // 1-based monotonic counter (matches ALS retryContext.attempt)
64789
+ error_type;
64790
+ error_message;
64791
+ status_code;
64792
+ retry_delay_ms;
64793
+ /**
64794
+ * Reports the backoff delay following this failed attempt (NOT the attempt's
64795
+ * own duration — that lives on the corresponding `qwen-code.llm_request`
64796
+ * span's `duration_ms` attribute). Set equal to `retry_delay_ms` so the
64797
+ * LogToSpanProcessor bridge span visualises the sleep window between the
64798
+ * failed and next attempt in the trace timeline.
64799
+ */
64800
+ duration_ms;
64801
+ /**
64802
+ * Name of the subagent that issued the retrying request, or undefined when
64803
+ * the request originates from the main conversation. Read from
64804
+ * `subagentNameContext.getStore()` at the caller site (subagentNameContext
64805
+ * is still active inside `retry.ts`'s catch block where `onRetry` fires).
64806
+ */
64807
+ subagent_name;
64808
+ constructor(opts) {
64809
+ this["event.name"] = "api_retry";
64810
+ this["event.timestamp"] = (/* @__PURE__ */ new Date()).toISOString();
64811
+ this.model = opts.model;
64812
+ this.prompt_id = opts.promptId;
64813
+ this.attempt_number = opts.attemptNumber;
64814
+ this.error_message = opts.error instanceof Error ? opts.error.message : String(opts.error ?? "unknown error");
64815
+ this.error_type = opts.error instanceof Error ? opts.error.constructor.name : void 0;
64816
+ this.status_code = opts.statusCode;
64817
+ this.retry_delay_ms = opts.retryDelayMs;
64818
+ this.duration_ms = opts.retryDelayMs;
64819
+ this.subagent_name = opts.subagentName;
64820
+ }
64821
+ };
64741
64822
  var ContentRetryFailureEvent = class {
64742
64823
  static {
64743
64824
  __name(this, "ContentRetryFailureEvent");
@@ -66692,367 +66773,6 @@ function randomHexString(length) {
66692
66773
  }
66693
66774
  __name(randomHexString, "randomHexString");
66694
66775
 
66695
- // packages/core/src/telemetry/log-to-span-processor.ts
66696
- var EXPORT_TIMEOUT_MS = 3e4;
66697
- var DEFAULT_MAX_BUFFER_SIZE = 1e4;
66698
- var BUFFER_OVERFLOW_WARNING_INTERVAL_MS = 3e4;
66699
- var LOG_EVENT_ERROR_STATUS_MESSAGE = "Log event recorded error";
66700
- var DEFAULT_LOG_SPAN_NAME = "log.event";
66701
- var MAX_SPAN_NAME_LENGTH = 128;
66702
- var SENSITIVE_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
66703
- "error",
66704
- "error.message",
66705
- "error_message",
66706
- "prompt",
66707
- "function_args",
66708
- "response_text"
66709
- ]);
66710
- var defaultDiagnosticsSink = /* @__PURE__ */ __name((message) => {
66711
- process.stderr.write(`${message}
66712
- `);
66713
- }, "defaultDiagnosticsSink");
66714
- var LogToSpanProcessor = class {
66715
- constructor(spanExporter, flushIntervalMsOrOptions = 5e3, maxBufferSize = DEFAULT_MAX_BUFFER_SIZE) {
66716
- this.spanExporter = spanExporter;
66717
- if (typeof flushIntervalMsOrOptions === "number") {
66718
- this.flushIntervalMs = flushIntervalMsOrOptions;
66719
- this.includeSensitiveSpanAttributes = false;
66720
- this.maxBufferSize = normalizeMaxBufferSize(maxBufferSize);
66721
- this.diagnosticsSink = defaultDiagnosticsSink;
66722
- } else {
66723
- this.flushIntervalMs = flushIntervalMsOrOptions.flushIntervalMs ?? 5e3;
66724
- this.includeSensitiveSpanAttributes = flushIntervalMsOrOptions.includeSensitiveSpanAttributes ?? false;
66725
- this.maxBufferSize = normalizeMaxBufferSize(
66726
- flushIntervalMsOrOptions.maxBufferSize
66727
- );
66728
- this.diagnosticsSink = flushIntervalMsOrOptions.diagnosticsSink ?? defaultDiagnosticsSink;
66729
- }
66730
- this.flushTimer = setInterval(() => {
66731
- void this.flush();
66732
- }, this.flushIntervalMs);
66733
- this.flushTimer.unref();
66734
- }
66735
- static {
66736
- __name(this, "LogToSpanProcessor");
66737
- }
66738
- buffer = [];
66739
- flushTimer;
66740
- inFlightExport;
66741
- flushIntervalMs;
66742
- cachedSessionId;
66743
- cachedTraceId;
66744
- includeSensitiveSpanAttributes;
66745
- maxBufferSize;
66746
- diagnosticsSink;
66747
- lastBufferOverflowWarningMs;
66748
- droppedSpansSinceLastBufferWarning = 0;
66749
- totalDroppedSpans = 0;
66750
- isShutdown = false;
66751
- onEmit(logRecord) {
66752
- if (this.isShutdown) {
66753
- return;
66754
- }
66755
- const name = deriveSpanName(logRecord);
66756
- const startTime = logRecord.hrTime;
66757
- const attributes = {};
66758
- if (logRecord.attributes) {
66759
- for (const [key, value] of Object.entries(logRecord.attributes)) {
66760
- if (value !== void 0 && value !== null && (this.includeSensitiveSpanAttributes || !SENSITIVE_ATTRIBUTE_KEYS.has(key))) {
66761
- attributes[key] = typeof value === "object" ? safeStringify(value) : value;
66762
- }
66763
- }
66764
- }
66765
- attributes["log.bridge"] = true;
66766
- if (logRecord.severityNumber !== void 0) {
66767
- attributes["log.severity_number"] = logRecord.severityNumber;
66768
- }
66769
- if (logRecord.severityText) {
66770
- attributes["log.severity_text"] = logRecord.severityText;
66771
- }
66772
- let endTime = startTime;
66773
- const durationMs = logRecord.attributes?.["duration_ms"];
66774
- if (typeof durationMs === "number" && Number.isFinite(durationMs) && durationMs > 0) {
66775
- const [secs, nanos] = startTime;
66776
- const durationNanos = durationMs * 1e6;
66777
- const endNanos = nanos + durationNanos;
66778
- endTime = [secs + Math.floor(endNanos / 1e9), endNanos % 1e9];
66779
- }
66780
- const parentSpanContext = getValidParentSpanContext(logRecord.spanContext);
66781
- const sessionId = logRecord.attributes?.["session.id"] || getCurrentSessionId();
66782
- let traceId;
66783
- if (parentSpanContext) {
66784
- traceId = parentSpanContext.traceId;
66785
- } else if (sessionId) {
66786
- const sid = String(sessionId);
66787
- if (sid !== this.cachedSessionId) {
66788
- this.cachedSessionId = sid;
66789
- this.cachedTraceId = deriveTraceId(sid);
66790
- }
66791
- traceId = this.cachedTraceId;
66792
- } else {
66793
- traceId = randomHexString(32);
66794
- }
66795
- const spanId = randomSpanId();
66796
- this.buffer.push({
66797
- name,
66798
- kind: SpanKind.INTERNAL,
66799
- spanContext: /* @__PURE__ */ __name(() => ({
66800
- traceId,
66801
- spanId,
66802
- traceFlags: parentSpanContext?.traceFlags ?? TraceFlags.SAMPLED
66803
- }), "spanContext"),
66804
- startTime,
66805
- endTime,
66806
- duration: hrTimeDiff(startTime, endTime),
66807
- attributes,
66808
- status: deriveSpanStatus(logRecord.attributes),
66809
- events: [],
66810
- links: [],
66811
- resource: logRecord.resource ?? (0, import_resources.resourceFromAttributes)({}),
66812
- instrumentationScope: logRecord.instrumentationScope ?? {
66813
- name: SERVICE_NAME,
66814
- version: ""
66815
- },
66816
- ended: true,
66817
- parentSpanContext,
66818
- droppedAttributesCount: 0,
66819
- droppedEventsCount: 0,
66820
- droppedLinksCount: 0,
66821
- recordException: /* @__PURE__ */ __name(() => {
66822
- }, "recordException")
66823
- });
66824
- if (this.buffer.length > this.maxBufferSize) {
66825
- const droppedSpanCount = this.buffer.length - this.maxBufferSize;
66826
- this.buffer.splice(0, droppedSpanCount);
66827
- this.warnBufferOverflow(droppedSpanCount);
66828
- }
66829
- }
66830
- warnBufferOverflow(droppedSpanCount) {
66831
- this.droppedSpansSinceLastBufferWarning += droppedSpanCount;
66832
- this.totalDroppedSpans += droppedSpanCount;
66833
- const now = Date.now();
66834
- if (this.lastBufferOverflowWarningMs !== void 0 && now - this.lastBufferOverflowWarningMs < BUFFER_OVERFLOW_WARNING_INTERVAL_MS) {
66835
- return;
66836
- }
66837
- this.emitBufferOverflowWarning(now);
66838
- }
66839
- emitBufferOverflowWarning(now = Date.now()) {
66840
- if (this.droppedSpansSinceLastBufferWarning === 0) {
66841
- return;
66842
- }
66843
- const droppedSinceLastWarning = this.droppedSpansSinceLastBufferWarning;
66844
- this.droppedSpansSinceLastBufferWarning = 0;
66845
- this.lastBufferOverflowWarningMs = now;
66846
- this.emitDiagnostic(
66847
- `[LogToSpan] buffer exceeded max size (${this.maxBufferSize}); dropped ${droppedSinceLastWarning} oldest span(s) since last warning, ${this.totalDroppedSpans} total`
66848
- );
66849
- }
66850
- /**
66851
- * Route a diagnostic message to the configured sink, swallowing any sink
66852
- * error so a misbehaving sink can never interrupt telemetry ingestion.
66853
- *
66854
- * Tradeoff: when the sink itself is broken (e.g. file-logger failing on
66855
- * EACCES), bridge-specific diagnostics go dark. We accept that — the host
66856
- * surfaces overall logging health via `isDebugLoggingDegraded()`, and
66857
- * falling back to stderr here would re-introduce the TUI-pollution this
66858
- * sink injection was added to prevent.
66859
- */
66860
- emitDiagnostic(message) {
66861
- try {
66862
- this.diagnosticsSink(message);
66863
- } catch {
66864
- }
66865
- }
66866
- flush() {
66867
- if (this.inFlightExport) return this.inFlightExport;
66868
- if (this.buffer.length === 0) return Promise.resolve();
66869
- const spans = this.buffer.splice(0);
66870
- const exportPromise = new Promise((resolve2) => {
66871
- const timeout = setTimeout(() => {
66872
- this.emitDiagnostic(
66873
- `[LogToSpan] export timeout after ${EXPORT_TIMEOUT_MS}ms (${spans.length} span(s))`
66874
- );
66875
- resolve2();
66876
- }, EXPORT_TIMEOUT_MS);
66877
- timeout.unref();
66878
- try {
66879
- this.spanExporter.export(
66880
- spans,
66881
- (result) => {
66882
- clearTimeout(timeout);
66883
- if (result.code !== 0) {
66884
- this.emitDiagnostic(
66885
- `[LogToSpan] export failed: code=${result.code} ${formatExportError(result.error)}`
66886
- );
66887
- }
66888
- resolve2();
66889
- }
66890
- );
66891
- } catch (err) {
66892
- clearTimeout(timeout);
66893
- const detail = err instanceof Error ? formatExportError(err) : `error=${JSON.stringify(String(err))}`;
66894
- this.emitDiagnostic(`[LogToSpan] export threw: ${detail}`);
66895
- resolve2();
66896
- }
66897
- });
66898
- this.inFlightExport = exportPromise.finally(() => {
66899
- this.inFlightExport = void 0;
66900
- });
66901
- return this.inFlightExport;
66902
- }
66903
- async shutdown() {
66904
- if (this.isShutdown) {
66905
- return;
66906
- }
66907
- this.isShutdown = true;
66908
- if (this.flushTimer) {
66909
- clearInterval(this.flushTimer);
66910
- this.flushTimer = void 0;
66911
- }
66912
- if (this.inFlightExport) {
66913
- await this.inFlightExport;
66914
- }
66915
- await this.flush();
66916
- this.emitBufferOverflowWarning();
66917
- await this.spanExporter.shutdown();
66918
- }
66919
- async forceFlush() {
66920
- if (this.isShutdown) {
66921
- return;
66922
- }
66923
- if (this.inFlightExport) {
66924
- await this.inFlightExport;
66925
- }
66926
- await this.flush();
66927
- await this.spanExporter.forceFlush?.();
66928
- }
66929
- };
66930
- function normalizeMaxBufferSize(value) {
66931
- if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
66932
- return DEFAULT_MAX_BUFFER_SIZE;
66933
- }
66934
- return Math.floor(value);
66935
- }
66936
- __name(normalizeMaxBufferSize, "normalizeMaxBufferSize");
66937
- function deriveSpanName(logRecord) {
66938
- const eventName = logRecord.attributes?.["event.name"] ?? logRecord.eventName;
66939
- if (typeof eventName === "string" && eventName.trim().length > 0) {
66940
- return sanitizeSpanName(eventName);
66941
- }
66942
- return DEFAULT_LOG_SPAN_NAME;
66943
- }
66944
- __name(deriveSpanName, "deriveSpanName");
66945
- function sanitizeSpanName(body) {
66946
- const rawName = String(body ?? "unknown");
66947
- return rawName.length > MAX_SPAN_NAME_LENGTH ? `${rawName.slice(0, MAX_SPAN_NAME_LENGTH)}...` : rawName;
66948
- }
66949
- __name(sanitizeSpanName, "sanitizeSpanName");
66950
- function getValidParentSpanContext(spanContext) {
66951
- if (!spanContext || !isSpanContextValid(spanContext)) {
66952
- return void 0;
66953
- }
66954
- return spanContext;
66955
- }
66956
- __name(getValidParentSpanContext, "getValidParentSpanContext");
66957
- function safeStringify(value) {
66958
- try {
66959
- return JSON.stringify(value);
66960
- } catch {
66961
- return "[unserializable]";
66962
- }
66963
- }
66964
- __name(safeStringify, "safeStringify");
66965
- function deriveSpanStatus(attrs) {
66966
- if (!attrs) return { code: SpanStatusCode.OK };
66967
- if (!!attrs["error"] || !!attrs["error.message"] || !!attrs["error_message"] || !!attrs["error_type"]) {
66968
- return {
66969
- code: SpanStatusCode.ERROR,
66970
- message: LOG_EVENT_ERROR_STATUS_MESSAGE
66971
- };
66972
- }
66973
- return { code: SpanStatusCode.OK };
66974
- }
66975
- __name(deriveSpanStatus, "deriveSpanStatus");
66976
- function formatExportError(err) {
66977
- if (!err) return 'error="unknown"';
66978
- const extra = err;
66979
- const msg = err.message || err.name || "unknown";
66980
- const parts = [`error=${JSON.stringify(msg)}`];
66981
- if (typeof extra.code === "number") parts.push(`httpCode=${extra.code}`);
66982
- if (typeof extra.data === "string" && extra.data.length > 0) {
66983
- parts.push(`data=${JSON.stringify(extra.data.slice(0, 200))}`);
66984
- }
66985
- return parts.join(" ");
66986
- }
66987
- __name(formatExportError, "formatExportError");
66988
- function hrTimeDiff(start, end) {
66989
- let secs = end[0] - start[0];
66990
- let nanos = end[1] - start[1];
66991
- if (nanos < 0) {
66992
- secs -= 1;
66993
- nanos += 1e9;
66994
- }
66995
- return [secs, nanos];
66996
- }
66997
- __name(hrTimeDiff, "hrTimeDiff");
66998
-
66999
- // packages/core/src/telemetry/tracer.ts
67000
- init_esbuild_shims();
67001
- init_esm();
67002
- var tracer = trace.getTracer(SERVICE_NAME);
67003
- var debugLogger7 = createDebugLogger("OTEL_TRACER");
67004
- var TELEMETRY_WARNING_INTERVAL_MS = 3e4;
67005
- var API_CALL_FAILED_SPAN_STATUS_MESSAGE = "API call failed";
67006
- var API_CALL_ABORTED_SPAN_STATUS_MESSAGE = "API call aborted";
67007
- var lastTelemetryWarningMs;
67008
- var suppressedTelemetryWarnings = 0;
67009
- function warnTelemetryOperationFailed(operation, error) {
67010
- const now = Date.now();
67011
- if (lastTelemetryWarningMs !== void 0 && now - lastTelemetryWarningMs < TELEMETRY_WARNING_INTERVAL_MS) {
67012
- suppressedTelemetryWarnings += 1;
67013
- return;
67014
- }
67015
- const suppressedSuffix = suppressedTelemetryWarnings > 0 ? `; suppressed ${suppressedTelemetryWarnings} similar warning(s)` : "";
67016
- suppressedTelemetryWarnings = 0;
67017
- lastTelemetryWarningMs = now;
67018
- try {
67019
- debugLogger7.warn(
67020
- `OTel span ${operation} failed: ${error instanceof Error ? error.message : String(error)}${suppressedSuffix}`
67021
- );
67022
- } catch {
67023
- }
67024
- }
67025
- __name(warnTelemetryOperationFailed, "warnTelemetryOperationFailed");
67026
- function safeSetStatus(span, status) {
67027
- try {
67028
- span.setStatus(status);
67029
- } catch (error) {
67030
- warnTelemetryOperationFailed("setStatus", error);
67031
- }
67032
- }
67033
- __name(safeSetStatus, "safeSetStatus");
67034
- function shouldForceSampled() {
67035
- const sampler = process.env["OTEL_TRACES_SAMPLER"]?.trim().toLowerCase() ?? "";
67036
- if (!sampler || sampler.startsWith("parentbased_")) {
67037
- if (sampler.includes("always_off")) return false;
67038
- return true;
67039
- }
67040
- return sampler === "always_on";
67041
- }
67042
- __name(shouldForceSampled, "shouldForceSampled");
67043
- function createSessionRootContext(sessionId) {
67044
- const traceId = deriveTraceId(sessionId);
67045
- const spanId = randomSpanId();
67046
- const rootSpan = trace.wrapSpanContext({
67047
- traceId,
67048
- spanId,
67049
- traceFlags: shouldForceSampled() ? TraceFlags.SAMPLED : TraceFlags.NONE,
67050
- isRemote: false
67051
- });
67052
- return trace.setSpan(ROOT_CONTEXT, rootSpan);
67053
- }
67054
- __name(createSessionRootContext, "createSessionRootContext");
67055
-
67056
66776
  // packages/core/src/telemetry/session-tracing.ts
67057
66777
  init_esbuild_shims();
67058
66778
  init_esm();
@@ -67200,7 +66920,7 @@ function clearDetailedSpanState() {
67200
66920
  __name(clearDetailedSpanState, "clearDetailedSpanState");
67201
66921
 
67202
66922
  // packages/core/src/telemetry/session-tracing.ts
67203
- var debugLogger8 = createDebugLogger("SESSION_TRACING");
66923
+ var debugLogger7 = createDebugLogger("SESSION_TRACING");
67204
66924
  function resolveParentContext(parent) {
67205
66925
  if (parent) {
67206
66926
  return trace.setSpan(context.active(), parent.span);
@@ -67219,54 +66939,85 @@ var NOOP_SPAN = trace.wrapSpanContext({
67219
66939
  });
67220
66940
  var interactionContext = new AsyncLocalStorage3();
67221
66941
  var toolContext = new AsyncLocalStorage3();
66942
+ var subagentContext = new AsyncLocalStorage3();
66943
+ function isInNativeSubagentSpan() {
66944
+ const ctx = subagentContext.getStore();
66945
+ return ctx !== void 0 && !ctx.ended;
66946
+ }
66947
+ __name(isInNativeSubagentSpan, "isInNativeSubagentSpan");
67222
66948
  var activeSpans = /* @__PURE__ */ new Map();
67223
66949
  var strongSpans = /* @__PURE__ */ new Map();
67224
66950
  var interactionSequence = 0;
67225
66951
  var lastInteractionCtx;
67226
66952
  var cleanupIntervalStarted = false;
67227
- var SPAN_TTL_MS = 30 * 60 * 1e3;
66953
+ var SPAN_TTL_MS_DEFAULT = 30 * 60 * 1e3;
66954
+ var SPAN_TTL_MS_LONG = 4 * 60 * 60 * 1e3;
66955
+ var LONG_TTL_SUBAGENT_KINDS = /* @__PURE__ */ new Set([
66956
+ "fork",
66957
+ "background"
66958
+ ]);
66959
+ function ttlFor(ctx) {
66960
+ if (ctx.type === "subagent") {
66961
+ const kind = ctx.attributes["qwen-code.subagent.invocation_kind"];
66962
+ if (typeof kind === "string" && LONG_TTL_SUBAGENT_KINDS.has(kind)) {
66963
+ return SPAN_TTL_MS_LONG;
66964
+ }
66965
+ }
66966
+ return SPAN_TTL_MS_DEFAULT;
66967
+ }
66968
+ __name(ttlFor, "ttlFor");
67228
66969
  function sweepStaleSpans(now) {
67229
- const cutoff = now - SPAN_TTL_MS;
67230
66970
  for (const [spanId, weakRef] of activeSpans) {
67231
66971
  const ctx = weakRef.deref();
67232
66972
  if (ctx === void 0) {
67233
66973
  activeSpans.delete(spanId);
67234
66974
  strongSpans.delete(spanId);
67235
- } else if (ctx.startTime < cutoff) {
67236
- if (!ctx.ended) {
67237
- ctx.ended = true;
67238
- const ageMs = now - ctx.startTime;
67239
- const toolName = ctx.attributes["tool.name"];
67240
- const callId = ctx.attributes["tool.call_id"];
67241
- try {
67242
- ctx.span.setAttributes({
67243
- "qwen-code.span.ttl_expired": true,
67244
- "qwen-code.span.duration_ms": ageMs,
67245
- ...ctx.type === "tool.blocked_on_user" ? {
67246
- decision: "aborted",
67247
- source: "system"
67248
- } : {}
67249
- });
67250
- } catch (error) {
67251
- debugLogger8.warn(
67252
- `Failed to stamp TTL attrs on stale span ${spanId}: ${error instanceof Error ? error.message : String(error)}`
67253
- );
67254
- }
67255
- const ctxLabel = toolName && callId ? `${ctx.type} (tool.name=${toolName}, tool.call_id=${callId})` : ctx.type;
67256
- debugLogger8.warn(
67257
- `Stale ${ctxLabel} span ended by TTL safety net (age=${ageMs}ms, spanId=${spanId})`
66975
+ continue;
66976
+ }
66977
+ if (now - ctx.startTime < ttlFor(ctx)) continue;
66978
+ if (!ctx.ended) {
66979
+ ctx.ended = true;
66980
+ const ageMs = now - ctx.startTime;
66981
+ const toolName = ctx.attributes["tool.name"];
66982
+ const callId = ctx.attributes["tool.call_id"];
66983
+ try {
66984
+ ctx.span.setAttributes({
66985
+ "qwen-code.span.ttl_expired": true,
66986
+ "qwen-code.span.duration_ms": ageMs,
66987
+ ...ctx.type === "tool.blocked_on_user" ? {
66988
+ decision: "aborted",
66989
+ source: "system"
66990
+ } : {},
66991
+ ...ctx.type === "subagent" ? {
66992
+ "qwen-code.subagent.status": "aborted",
66993
+ "qwen-code.subagent.terminate_reason": "ttl_swept",
66994
+ // Mirror the subagent-specific duration_ms key that
66995
+ // endSubagentSpan stamps so dashboards querying that
66996
+ // namespace see TTL-swept spans too (they currently
66997
+ // only get the generic qwen-code.span.duration_ms
66998
+ // above). wenshao @ #4410.
66999
+ "qwen-code.subagent.duration_ms": ageMs
67000
+ } : {}
67001
+ });
67002
+ } catch (error) {
67003
+ debugLogger7.warn(
67004
+ `Failed to stamp TTL attrs on stale span ${spanId}: ${error instanceof Error ? error.message : String(error)}`
67005
+ );
67006
+ }
67007
+ const ctxLabel = toolName && callId ? `${ctx.type} (tool.name=${toolName}, tool.call_id=${callId})` : ctx.type;
67008
+ debugLogger7.warn(
67009
+ `Stale ${ctxLabel} span ended by TTL safety net (age=${ageMs}ms, spanId=${spanId})`
67010
+ );
67011
+ try {
67012
+ ctx.span.end();
67013
+ } catch (error) {
67014
+ debugLogger7.warn(
67015
+ `Failed to end stale span ${spanId}: ${error instanceof Error ? error.message : String(error)}`
67258
67016
  );
67259
- try {
67260
- ctx.span.end();
67261
- } catch (error) {
67262
- debugLogger8.warn(
67263
- `Failed to end stale span ${spanId}: ${error instanceof Error ? error.message : String(error)}`
67264
- );
67265
- }
67266
67017
  }
67267
- activeSpans.delete(spanId);
67268
- strongSpans.delete(spanId);
67269
67018
  }
67019
+ activeSpans.delete(spanId);
67020
+ strongSpans.delete(spanId);
67270
67021
  }
67271
67022
  }
67272
67023
  __name(sweepStaleSpans, "sweepStaleSpans");
@@ -67329,7 +67080,13 @@ function startInteractionSpan(config, options) {
67329
67080
  __name(startInteractionSpan, "startInteractionSpan");
67330
67081
  function endInteractionSpan(status, metadata) {
67331
67082
  const spanCtx = interactionContext.getStore() ?? lastInteractionCtx;
67332
- if (!spanCtx || spanCtx.ended) return;
67083
+ if (!spanCtx) return;
67084
+ if (spanCtx.ended) {
67085
+ debugLogger7.debug(
67086
+ `endInteractionSpan: span ${getSpanId(spanCtx.span)} already ended (possible TTL sweep race)`
67087
+ );
67088
+ return;
67089
+ }
67333
67090
  spanCtx.ended = true;
67334
67091
  lastInteractionCtx = void 0;
67335
67092
  const duration = Date.now() - spanCtx.startTime;
@@ -67356,12 +67113,12 @@ function startLLMRequestSpan(model, promptId) {
67356
67113
  if (!isTelemetrySdkInitialized()) {
67357
67114
  return NOOP_SPAN;
67358
67115
  }
67359
- const parentCtx = interactionContext.getStore();
67116
+ const parentCtx = subagentContext.getStore() ?? interactionContext.getStore();
67360
67117
  const ctx = resolveParentContext(parentCtx);
67361
67118
  const attributes = {
67362
67119
  "qwen-code.model": model,
67363
67120
  "qwen-code.prompt_id": promptId,
67364
- "llm_request.context": parentCtx ? "interaction" : "standalone",
67121
+ "llm_request.context": subagentContext.getStore() ? "subagent" : interactionContext.getStore() ? "interaction" : "standalone",
67365
67122
  // Dual-emit OTel GenAI semantic convention (Stable). Private name
67366
67123
  // (qwen-code.model) remains authoritative; gen_ai.* is a compat layer
67367
67124
  // for spec-aware backends. See docs/design/telemetry-llm-request-timing-design.md (D8).
@@ -67387,7 +67144,13 @@ __name(startLLMRequestSpan, "startLLMRequestSpan");
67387
67144
  function endLLMRequestSpan(span, metadata) {
67388
67145
  const spanId = getSpanId(span);
67389
67146
  const spanCtx = activeSpans.get(spanId)?.deref();
67390
- if (!spanCtx || spanCtx.ended) return;
67147
+ if (!spanCtx) return;
67148
+ if (spanCtx.ended) {
67149
+ debugLogger7.debug(
67150
+ `endLLMRequestSpan: span ${spanId} already ended (possible TTL sweep race)`
67151
+ );
67152
+ return;
67153
+ }
67391
67154
  spanCtx.ended = true;
67392
67155
  try {
67393
67156
  const duration = metadata?.durationMs ?? Date.now() - spanCtx.startTime;
@@ -67419,10 +67182,7 @@ function endLLMRequestSpan(span, metadata) {
67419
67182
  endAttributes["retry_total_delay_ms"] = metadata.retryTotalDelayMs;
67420
67183
  }
67421
67184
  if (metadata.ttftMs !== void 0) {
67422
- const samplingMs = Math.max(
67423
- 0,
67424
- duration - metadata.ttftMs - (metadata.requestSetupMs ?? 0)
67425
- );
67185
+ const samplingMs = Math.max(0, duration - metadata.ttftMs);
67426
67186
  endAttributes["sampling_ms"] = samplingMs;
67427
67187
  if (samplingMs > 0 && metadata.outputTokens !== void 0) {
67428
67188
  endAttributes["output_tokens_per_second"] = Math.round(metadata.outputTokens / (samplingMs / 1e3) * 100) / 100;
@@ -67442,14 +67202,14 @@ function endLLMRequestSpan(span, metadata) {
67442
67202
  });
67443
67203
  }
67444
67204
  } catch (error) {
67445
- debugLogger8.warn(
67205
+ debugLogger7.warn(
67446
67206
  `Failed to update LLM request span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67447
67207
  );
67448
67208
  }
67449
67209
  try {
67450
67210
  spanCtx.span.end();
67451
67211
  } catch (error) {
67452
- debugLogger8.warn(
67212
+ debugLogger7.warn(
67453
67213
  `Failed to end LLM request span: ${error instanceof Error ? error.message : String(error)}`
67454
67214
  );
67455
67215
  }
@@ -67461,7 +67221,7 @@ function startToolSpan(toolName, attrs) {
67461
67221
  if (!isTelemetrySdkInitialized()) {
67462
67222
  return NOOP_SPAN;
67463
67223
  }
67464
- const parentCtx = interactionContext.getStore();
67224
+ const parentCtx = subagentContext.getStore() ?? interactionContext.getStore();
67465
67225
  const ctx = resolveParentContext(parentCtx);
67466
67226
  const attributes = {
67467
67227
  "tool.name": toolName,
@@ -67495,7 +67255,13 @@ __name(runInToolSpanContext, "runInToolSpanContext");
67495
67255
  function endToolSpan(span, metadata) {
67496
67256
  const spanId = getSpanId(span);
67497
67257
  const spanCtx = activeSpans.get(spanId)?.deref();
67498
- if (!spanCtx || spanCtx.ended) return;
67258
+ if (!spanCtx) return;
67259
+ if (spanCtx.ended) {
67260
+ debugLogger7.debug(
67261
+ `endToolSpan: span ${spanId} already ended (possible TTL sweep race)`
67262
+ );
67263
+ return;
67264
+ }
67499
67265
  spanCtx.ended = true;
67500
67266
  try {
67501
67267
  const duration = Date.now() - spanCtx.startTime;
@@ -67518,14 +67284,14 @@ function endToolSpan(span, metadata) {
67518
67284
  }
67519
67285
  }
67520
67286
  } catch (error) {
67521
- debugLogger8.warn(
67287
+ debugLogger7.warn(
67522
67288
  `Failed to update tool span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67523
67289
  );
67524
67290
  }
67525
67291
  try {
67526
67292
  spanCtx.span.end();
67527
67293
  } catch (error) {
67528
- debugLogger8.warn(
67294
+ debugLogger7.warn(
67529
67295
  `Failed to end tool span: ${error instanceof Error ? error.message : String(error)}`
67530
67296
  );
67531
67297
  }
@@ -67539,7 +67305,7 @@ function startToolExecutionSpan() {
67539
67305
  }
67540
67306
  const parentCtx = toolContext.getStore();
67541
67307
  if (!parentCtx) {
67542
- debugLogger8.warn(
67308
+ debugLogger7.warn(
67543
67309
  "startToolExecutionSpan called outside runInToolSpanContext \u2014 span will not be parented to tool span"
67544
67310
  );
67545
67311
  }
@@ -67564,7 +67330,13 @@ __name(startToolExecutionSpan, "startToolExecutionSpan");
67564
67330
  function endToolExecutionSpan(span, metadata) {
67565
67331
  const spanId = getSpanId(span);
67566
67332
  const spanCtx = activeSpans.get(spanId)?.deref();
67567
- if (!spanCtx || spanCtx.ended) return;
67333
+ if (!spanCtx) return;
67334
+ if (spanCtx.ended) {
67335
+ debugLogger7.debug(
67336
+ `endToolExecutionSpan: span ${spanId} already ended (possible TTL sweep race)`
67337
+ );
67338
+ return;
67339
+ }
67568
67340
  spanCtx.ended = true;
67569
67341
  try {
67570
67342
  const duration = Date.now() - spanCtx.startTime;
@@ -67587,14 +67359,14 @@ function endToolExecutionSpan(span, metadata) {
67587
67359
  }
67588
67360
  }
67589
67361
  } catch (error) {
67590
- debugLogger8.warn(
67362
+ debugLogger7.warn(
67591
67363
  `Failed to update tool execution span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67592
67364
  );
67593
67365
  }
67594
67366
  try {
67595
67367
  spanCtx.span.end();
67596
67368
  } catch (error) {
67597
- debugLogger8.warn(
67369
+ debugLogger7.warn(
67598
67370
  `Failed to end tool execution span: ${error instanceof Error ? error.message : String(error)}`
67599
67371
  );
67600
67372
  }
@@ -67610,7 +67382,7 @@ function startToolBlockedOnUserSpan(toolSpan, attrs) {
67610
67382
  const parentSpanId = getSpanId(toolSpan);
67611
67383
  const parentSpanCtx = activeSpans.get(parentSpanId)?.deref();
67612
67384
  if (!parentSpanCtx) {
67613
- debugLogger8.debug(
67385
+ debugLogger7.debug(
67614
67386
  "startToolBlockedOnUserSpan: tool span not in activeSpans (already ended?) \u2014 using resolveParentContext fallback"
67615
67387
  );
67616
67388
  }
@@ -67638,7 +67410,13 @@ __name(startToolBlockedOnUserSpan, "startToolBlockedOnUserSpan");
67638
67410
  function endToolBlockedOnUserSpan(span, metadata) {
67639
67411
  const spanId = getSpanId(span);
67640
67412
  const spanCtx = activeSpans.get(spanId)?.deref();
67641
- if (!spanCtx || spanCtx.ended) return;
67413
+ if (!spanCtx) return;
67414
+ if (spanCtx.ended) {
67415
+ debugLogger7.debug(
67416
+ `endToolBlockedOnUserSpan: span ${spanId} already ended (possible TTL sweep race)`
67417
+ );
67418
+ return;
67419
+ }
67642
67420
  spanCtx.ended = true;
67643
67421
  try {
67644
67422
  const duration = Date.now() - spanCtx.startTime;
@@ -67649,14 +67427,14 @@ function endToolBlockedOnUserSpan(span, metadata) {
67649
67427
  endAttributes["source"] = metadata.source;
67650
67428
  spanCtx.span.setAttributes(endAttributes);
67651
67429
  } catch (error) {
67652
- debugLogger8.warn(
67430
+ debugLogger7.warn(
67653
67431
  `Failed to update blocked_on_user span attributes: ${error instanceof Error ? error.message : String(error)}`
67654
67432
  );
67655
67433
  }
67656
67434
  try {
67657
67435
  spanCtx.span.end();
67658
67436
  } catch (error) {
67659
- debugLogger8.warn(
67437
+ debugLogger7.warn(
67660
67438
  `Failed to end blocked_on_user span: ${error instanceof Error ? error.message : String(error)}`
67661
67439
  );
67662
67440
  }
@@ -67669,7 +67447,7 @@ function startHookSpan(opts) {
67669
67447
  return NOOP_SPAN;
67670
67448
  }
67671
67449
  ensureCleanupInterval();
67672
- const parentCtx = toolContext.getStore() ?? interactionContext.getStore() ?? void 0;
67450
+ const parentCtx = toolContext.getStore() ?? subagentContext.getStore() ?? interactionContext.getStore() ?? void 0;
67673
67451
  const ctx = resolveParentContext(parentCtx);
67674
67452
  const attributes = {
67675
67453
  hook_event: opts.hookEvent,
@@ -67698,7 +67476,13 @@ __name(startHookSpan, "startHookSpan");
67698
67476
  function endHookSpan(span, metadata) {
67699
67477
  const spanId = getSpanId(span);
67700
67478
  const spanCtx = activeSpans.get(spanId)?.deref();
67701
- if (!spanCtx || spanCtx.ended) return;
67479
+ if (!spanCtx) return;
67480
+ if (spanCtx.ended) {
67481
+ debugLogger7.debug(
67482
+ `endHookSpan: span ${spanId} already ended (possible TTL sweep race)`
67483
+ );
67484
+ return;
67485
+ }
67702
67486
  spanCtx.ended = true;
67703
67487
  try {
67704
67488
  const duration = Date.now() - spanCtx.startTime;
@@ -67731,14 +67515,14 @@ function endHookSpan(span, metadata) {
67731
67515
  });
67732
67516
  }
67733
67517
  } catch (error) {
67734
- debugLogger8.warn(
67518
+ debugLogger7.warn(
67735
67519
  `Failed to update hook span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67736
67520
  );
67737
67521
  }
67738
67522
  try {
67739
67523
  spanCtx.span.end();
67740
67524
  } catch (error) {
67741
- debugLogger8.warn(
67525
+ debugLogger7.warn(
67742
67526
  `Failed to end hook span: ${error instanceof Error ? error.message : String(error)}`
67743
67527
  );
67744
67528
  }
@@ -67746,6 +67530,139 @@ function endHookSpan(span, metadata) {
67746
67530
  strongSpans.delete(spanId);
67747
67531
  }
67748
67532
  __name(endHookSpan, "endHookSpan");
67533
+ function startSubagentSpan(opts) {
67534
+ if (!isTelemetrySdkInitialized()) return NOOP_SPAN;
67535
+ ensureCleanupInterval();
67536
+ const attributes = {
67537
+ // Spec-aligned (OTel GenAI Agent Spans, Development status).
67538
+ "gen_ai.operation.name": "invoke_agent",
67539
+ "gen_ai.provider.name": SERVICE_NAME,
67540
+ "gen_ai.agent.id": opts.agentId,
67541
+ "gen_ai.agent.name": opts.subagentName,
67542
+ "gen_ai.conversation.id": opts.sessionId,
67543
+ // Vendor (qwen-code-specific). Dual-emit id/name so dashboards already
67544
+ // querying spec keys still work.
67545
+ "qwen-code.subagent.id": opts.agentId,
67546
+ "qwen-code.subagent.name": opts.subagentName,
67547
+ "qwen-code.subagent.invocation_kind": opts.invocationKind,
67548
+ "qwen-code.subagent.is_built_in": opts.isBuiltIn,
67549
+ "qwen-code.subagent.depth": opts.depth
67550
+ };
67551
+ if (opts.modelOverride !== void 0) {
67552
+ attributes["gen_ai.request.model"] = opts.modelOverride;
67553
+ }
67554
+ if (opts.parentAgentId !== void 0) {
67555
+ attributes["qwen-code.subagent.parent_agent_id"] = opts.parentAgentId;
67556
+ }
67557
+ if (opts.invokingRequestId !== void 0) {
67558
+ attributes["qwen-code.subagent.invoking_request_id"] = opts.invokingRequestId;
67559
+ }
67560
+ const tracer2 = getTracer();
67561
+ let span;
67562
+ if (opts.invocationKind === "foreground") {
67563
+ span = tracer2.startSpan(SPAN_SUBAGENT, {
67564
+ kind: SpanKind.INTERNAL,
67565
+ attributes
67566
+ });
67567
+ } else {
67568
+ span = tracer2.startSpan(SPAN_SUBAGENT, {
67569
+ kind: SpanKind.INTERNAL,
67570
+ attributes,
67571
+ root: true,
67572
+ links: opts.invokerSpanContext ? [
67573
+ {
67574
+ context: opts.invokerSpanContext,
67575
+ attributes: { "qwen-code.link.kind": "invoker" }
67576
+ }
67577
+ ] : void 0
67578
+ });
67579
+ }
67580
+ const spanId = getSpanId(span);
67581
+ const spanContextObj = {
67582
+ span,
67583
+ startTime: Date.now(),
67584
+ attributes,
67585
+ type: "subagent"
67586
+ };
67587
+ activeSpans.set(spanId, new WeakRef(spanContextObj));
67588
+ strongSpans.set(spanId, spanContextObj);
67589
+ return span;
67590
+ }
67591
+ __name(startSubagentSpan, "startSubagentSpan");
67592
+ function runInSubagentSpanContext(span, fn) {
67593
+ const spanId = getSpanId(span);
67594
+ const spanCtx = activeSpans.get(spanId)?.deref();
67595
+ if (!spanCtx) return fn();
67596
+ const otelCtxWithSpan = trace.setSpan(context.active(), span);
67597
+ return subagentContext.run(
67598
+ spanCtx,
67599
+ () => toolContext.run(void 0, () => context.with(otelCtxWithSpan, fn))
67600
+ );
67601
+ }
67602
+ __name(runInSubagentSpanContext, "runInSubagentSpanContext");
67603
+ function endSubagentSpan(span, metadata) {
67604
+ const spanId = getSpanId(span);
67605
+ const spanCtx = activeSpans.get(spanId)?.deref();
67606
+ if (!spanCtx) {
67607
+ if (isTelemetrySdkInitialized()) {
67608
+ debugLogger7.warn(
67609
+ `endSubagentSpan: span ${spanId} not found in activeSpans (already swept?) \u2014 intended status=${metadata.status}, reason=${metadata.terminateReason ?? "none"}`
67610
+ );
67611
+ }
67612
+ return;
67613
+ }
67614
+ if (spanCtx.ended) {
67615
+ debugLogger7.warn(
67616
+ `endSubagentSpan: span ${spanId} already ended \u2014 intended status=${metadata.status}, reason=${metadata.terminateReason ?? "none"} (possible TTL sweep race)`
67617
+ );
67618
+ return;
67619
+ }
67620
+ spanCtx.ended = true;
67621
+ try {
67622
+ const duration = Date.now() - spanCtx.startTime;
67623
+ const endAttributes = {
67624
+ duration_ms: duration,
67625
+ "qwen-code.subagent.duration_ms": duration,
67626
+ "qwen-code.subagent.status": metadata.status
67627
+ };
67628
+ if (metadata.terminateReason !== void 0) {
67629
+ endAttributes["qwen-code.subagent.terminate_reason"] = metadata.terminateReason;
67630
+ }
67631
+ if (metadata.resultSummaryPresent !== void 0) {
67632
+ endAttributes["qwen-code.subagent.result_summary_present"] = metadata.resultSummaryPresent;
67633
+ }
67634
+ if (metadata.error !== void 0) {
67635
+ const truncated = truncateSpanError(metadata.error);
67636
+ endAttributes["exception.message"] = truncated;
67637
+ }
67638
+ if (metadata.errorType !== void 0) {
67639
+ endAttributes["error.type"] = metadata.errorType;
67640
+ }
67641
+ spanCtx.span.setAttributes(endAttributes);
67642
+ if (metadata.status === "completed") {
67643
+ spanCtx.span.setStatus({ code: SpanStatusCode.OK });
67644
+ } else if (metadata.status === "failed") {
67645
+ spanCtx.span.setStatus({
67646
+ code: SpanStatusCode.ERROR,
67647
+ message: metadata.error ? truncateSpanError(metadata.error) : "subagent failed"
67648
+ });
67649
+ }
67650
+ } catch (error) {
67651
+ debugLogger7.warn(
67652
+ `Failed to update subagent span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67653
+ );
67654
+ }
67655
+ try {
67656
+ spanCtx.span.end();
67657
+ } catch (error) {
67658
+ debugLogger7.warn(
67659
+ `Failed to end subagent span: ${error instanceof Error ? error.message : String(error)}`
67660
+ );
67661
+ }
67662
+ activeSpans.delete(spanId);
67663
+ strongSpans.delete(spanId);
67664
+ }
67665
+ __name(endSubagentSpan, "endSubagentSpan");
67749
67666
  function getActiveInteractionSpan() {
67750
67667
  const ctx = interactionContext.getStore() ?? lastInteractionCtx;
67751
67668
  if (!ctx || ctx.ended) return void 0;
@@ -67753,6 +67670,372 @@ function getActiveInteractionSpan() {
67753
67670
  }
67754
67671
  __name(getActiveInteractionSpan, "getActiveInteractionSpan");
67755
67672
 
67673
+ // packages/core/src/telemetry/log-to-span-processor.ts
67674
+ var BRIDGE_SKIP_EVENT_NAMES = /* @__PURE__ */ new Set([EVENT_SUBAGENT_EXECUTION]);
67675
+ var EXPORT_TIMEOUT_MS = 3e4;
67676
+ var DEFAULT_MAX_BUFFER_SIZE = 1e4;
67677
+ var BUFFER_OVERFLOW_WARNING_INTERVAL_MS = 3e4;
67678
+ var LOG_EVENT_ERROR_STATUS_MESSAGE = "Log event recorded error";
67679
+ var DEFAULT_LOG_SPAN_NAME = "log.event";
67680
+ var MAX_SPAN_NAME_LENGTH = 128;
67681
+ var SENSITIVE_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
67682
+ "error",
67683
+ "error.message",
67684
+ "error_message",
67685
+ "prompt",
67686
+ "function_args",
67687
+ "response_text"
67688
+ ]);
67689
+ var defaultDiagnosticsSink = /* @__PURE__ */ __name((message) => {
67690
+ process.stderr.write(`${message}
67691
+ `);
67692
+ }, "defaultDiagnosticsSink");
67693
+ var LogToSpanProcessor = class {
67694
+ constructor(spanExporter, flushIntervalMsOrOptions = 5e3, maxBufferSize = DEFAULT_MAX_BUFFER_SIZE) {
67695
+ this.spanExporter = spanExporter;
67696
+ if (typeof flushIntervalMsOrOptions === "number") {
67697
+ this.flushIntervalMs = flushIntervalMsOrOptions;
67698
+ this.includeSensitiveSpanAttributes = false;
67699
+ this.maxBufferSize = normalizeMaxBufferSize(maxBufferSize);
67700
+ this.diagnosticsSink = defaultDiagnosticsSink;
67701
+ } else {
67702
+ this.flushIntervalMs = flushIntervalMsOrOptions.flushIntervalMs ?? 5e3;
67703
+ this.includeSensitiveSpanAttributes = flushIntervalMsOrOptions.includeSensitiveSpanAttributes ?? false;
67704
+ this.maxBufferSize = normalizeMaxBufferSize(
67705
+ flushIntervalMsOrOptions.maxBufferSize
67706
+ );
67707
+ this.diagnosticsSink = flushIntervalMsOrOptions.diagnosticsSink ?? defaultDiagnosticsSink;
67708
+ }
67709
+ this.flushTimer = setInterval(() => {
67710
+ void this.flush();
67711
+ }, this.flushIntervalMs);
67712
+ this.flushTimer.unref();
67713
+ }
67714
+ static {
67715
+ __name(this, "LogToSpanProcessor");
67716
+ }
67717
+ buffer = [];
67718
+ flushTimer;
67719
+ inFlightExport;
67720
+ flushIntervalMs;
67721
+ cachedSessionId;
67722
+ cachedTraceId;
67723
+ includeSensitiveSpanAttributes;
67724
+ maxBufferSize;
67725
+ diagnosticsSink;
67726
+ lastBufferOverflowWarningMs;
67727
+ droppedSpansSinceLastBufferWarning = 0;
67728
+ totalDroppedSpans = 0;
67729
+ isShutdown = false;
67730
+ onEmit(logRecord) {
67731
+ if (this.isShutdown) {
67732
+ return;
67733
+ }
67734
+ const eventName = logRecord.attributes?.["event.name"];
67735
+ if (typeof eventName === "string" && BRIDGE_SKIP_EVENT_NAMES.has(eventName) && isInNativeSubagentSpan()) {
67736
+ return;
67737
+ }
67738
+ const name = deriveSpanName(logRecord);
67739
+ const startTime = logRecord.hrTime;
67740
+ const attributes = {};
67741
+ if (logRecord.attributes) {
67742
+ for (const [key, value] of Object.entries(logRecord.attributes)) {
67743
+ if (value !== void 0 && value !== null && (this.includeSensitiveSpanAttributes || !SENSITIVE_ATTRIBUTE_KEYS.has(key))) {
67744
+ attributes[key] = typeof value === "object" ? safeStringify(value) : value;
67745
+ }
67746
+ }
67747
+ }
67748
+ attributes["log.bridge"] = true;
67749
+ if (logRecord.severityNumber !== void 0) {
67750
+ attributes["log.severity_number"] = logRecord.severityNumber;
67751
+ }
67752
+ if (logRecord.severityText) {
67753
+ attributes["log.severity_text"] = logRecord.severityText;
67754
+ }
67755
+ let endTime = startTime;
67756
+ const durationMs = logRecord.attributes?.["duration_ms"];
67757
+ if (typeof durationMs === "number" && Number.isFinite(durationMs) && durationMs > 0) {
67758
+ const [secs, nanos] = startTime;
67759
+ const durationNanos = durationMs * 1e6;
67760
+ const endNanos = nanos + durationNanos;
67761
+ endTime = [secs + Math.floor(endNanos / 1e9), endNanos % 1e9];
67762
+ }
67763
+ const parentSpanContext = getValidParentSpanContext(logRecord.spanContext);
67764
+ const sessionId = logRecord.attributes?.["session.id"] || getCurrentSessionId();
67765
+ let traceId;
67766
+ if (parentSpanContext) {
67767
+ traceId = parentSpanContext.traceId;
67768
+ } else if (sessionId) {
67769
+ const sid = String(sessionId);
67770
+ if (sid !== this.cachedSessionId) {
67771
+ this.cachedSessionId = sid;
67772
+ this.cachedTraceId = deriveTraceId(sid);
67773
+ }
67774
+ traceId = this.cachedTraceId;
67775
+ } else {
67776
+ traceId = randomHexString(32);
67777
+ }
67778
+ const spanId = randomSpanId();
67779
+ this.buffer.push({
67780
+ name,
67781
+ kind: SpanKind.INTERNAL,
67782
+ spanContext: /* @__PURE__ */ __name(() => ({
67783
+ traceId,
67784
+ spanId,
67785
+ traceFlags: parentSpanContext?.traceFlags ?? TraceFlags.SAMPLED
67786
+ }), "spanContext"),
67787
+ startTime,
67788
+ endTime,
67789
+ duration: hrTimeDiff(startTime, endTime),
67790
+ attributes,
67791
+ status: deriveSpanStatus(logRecord.attributes),
67792
+ events: [],
67793
+ links: [],
67794
+ resource: logRecord.resource ?? (0, import_resources.resourceFromAttributes)({}),
67795
+ instrumentationScope: logRecord.instrumentationScope ?? {
67796
+ name: SERVICE_NAME,
67797
+ version: ""
67798
+ },
67799
+ ended: true,
67800
+ parentSpanContext,
67801
+ droppedAttributesCount: 0,
67802
+ droppedEventsCount: 0,
67803
+ droppedLinksCount: 0,
67804
+ recordException: /* @__PURE__ */ __name(() => {
67805
+ }, "recordException")
67806
+ });
67807
+ if (this.buffer.length > this.maxBufferSize) {
67808
+ const droppedSpanCount = this.buffer.length - this.maxBufferSize;
67809
+ this.buffer.splice(0, droppedSpanCount);
67810
+ this.warnBufferOverflow(droppedSpanCount);
67811
+ }
67812
+ }
67813
+ warnBufferOverflow(droppedSpanCount) {
67814
+ this.droppedSpansSinceLastBufferWarning += droppedSpanCount;
67815
+ this.totalDroppedSpans += droppedSpanCount;
67816
+ const now = Date.now();
67817
+ if (this.lastBufferOverflowWarningMs !== void 0 && now - this.lastBufferOverflowWarningMs < BUFFER_OVERFLOW_WARNING_INTERVAL_MS) {
67818
+ return;
67819
+ }
67820
+ this.emitBufferOverflowWarning(now);
67821
+ }
67822
+ emitBufferOverflowWarning(now = Date.now()) {
67823
+ if (this.droppedSpansSinceLastBufferWarning === 0) {
67824
+ return;
67825
+ }
67826
+ const droppedSinceLastWarning = this.droppedSpansSinceLastBufferWarning;
67827
+ this.droppedSpansSinceLastBufferWarning = 0;
67828
+ this.lastBufferOverflowWarningMs = now;
67829
+ this.emitDiagnostic(
67830
+ `[LogToSpan] buffer exceeded max size (${this.maxBufferSize}); dropped ${droppedSinceLastWarning} oldest span(s) since last warning, ${this.totalDroppedSpans} total`
67831
+ );
67832
+ }
67833
+ /**
67834
+ * Route a diagnostic message to the configured sink, swallowing any sink
67835
+ * error so a misbehaving sink can never interrupt telemetry ingestion.
67836
+ *
67837
+ * Tradeoff: when the sink itself is broken (e.g. file-logger failing on
67838
+ * EACCES), bridge-specific diagnostics go dark. We accept that — the host
67839
+ * surfaces overall logging health via `isDebugLoggingDegraded()`, and
67840
+ * falling back to stderr here would re-introduce the TUI-pollution this
67841
+ * sink injection was added to prevent.
67842
+ */
67843
+ emitDiagnostic(message) {
67844
+ try {
67845
+ this.diagnosticsSink(message);
67846
+ } catch {
67847
+ }
67848
+ }
67849
+ flush() {
67850
+ if (this.inFlightExport) return this.inFlightExport;
67851
+ if (this.buffer.length === 0) return Promise.resolve();
67852
+ const spans = this.buffer.splice(0);
67853
+ const exportPromise = new Promise((resolve2) => {
67854
+ const timeout = setTimeout(() => {
67855
+ this.emitDiagnostic(
67856
+ `[LogToSpan] export timeout after ${EXPORT_TIMEOUT_MS}ms (${spans.length} span(s))`
67857
+ );
67858
+ resolve2();
67859
+ }, EXPORT_TIMEOUT_MS);
67860
+ timeout.unref();
67861
+ try {
67862
+ this.spanExporter.export(
67863
+ spans,
67864
+ (result) => {
67865
+ clearTimeout(timeout);
67866
+ if (result.code !== 0) {
67867
+ this.emitDiagnostic(
67868
+ `[LogToSpan] export failed: code=${result.code} ${formatExportError(result.error)}`
67869
+ );
67870
+ }
67871
+ resolve2();
67872
+ }
67873
+ );
67874
+ } catch (err) {
67875
+ clearTimeout(timeout);
67876
+ const detail = err instanceof Error ? formatExportError(err) : `error=${JSON.stringify(String(err))}`;
67877
+ this.emitDiagnostic(`[LogToSpan] export threw: ${detail}`);
67878
+ resolve2();
67879
+ }
67880
+ });
67881
+ this.inFlightExport = exportPromise.finally(() => {
67882
+ this.inFlightExport = void 0;
67883
+ });
67884
+ return this.inFlightExport;
67885
+ }
67886
+ async shutdown() {
67887
+ if (this.isShutdown) {
67888
+ return;
67889
+ }
67890
+ this.isShutdown = true;
67891
+ if (this.flushTimer) {
67892
+ clearInterval(this.flushTimer);
67893
+ this.flushTimer = void 0;
67894
+ }
67895
+ if (this.inFlightExport) {
67896
+ await this.inFlightExport;
67897
+ }
67898
+ await this.flush();
67899
+ this.emitBufferOverflowWarning();
67900
+ await this.spanExporter.shutdown();
67901
+ }
67902
+ async forceFlush() {
67903
+ if (this.isShutdown) {
67904
+ return;
67905
+ }
67906
+ if (this.inFlightExport) {
67907
+ await this.inFlightExport;
67908
+ }
67909
+ await this.flush();
67910
+ await this.spanExporter.forceFlush?.();
67911
+ }
67912
+ };
67913
+ function normalizeMaxBufferSize(value) {
67914
+ if (typeof value !== "number" || !Number.isFinite(value) || value < 1) {
67915
+ return DEFAULT_MAX_BUFFER_SIZE;
67916
+ }
67917
+ return Math.floor(value);
67918
+ }
67919
+ __name(normalizeMaxBufferSize, "normalizeMaxBufferSize");
67920
+ function deriveSpanName(logRecord) {
67921
+ const eventName = logRecord.attributes?.["event.name"] ?? logRecord.eventName;
67922
+ if (typeof eventName === "string" && eventName.trim().length > 0) {
67923
+ return sanitizeSpanName(eventName);
67924
+ }
67925
+ return DEFAULT_LOG_SPAN_NAME;
67926
+ }
67927
+ __name(deriveSpanName, "deriveSpanName");
67928
+ function sanitizeSpanName(body) {
67929
+ const rawName = String(body ?? "unknown");
67930
+ return rawName.length > MAX_SPAN_NAME_LENGTH ? `${rawName.slice(0, MAX_SPAN_NAME_LENGTH)}...` : rawName;
67931
+ }
67932
+ __name(sanitizeSpanName, "sanitizeSpanName");
67933
+ function getValidParentSpanContext(spanContext) {
67934
+ if (!spanContext || !isSpanContextValid(spanContext)) {
67935
+ return void 0;
67936
+ }
67937
+ return spanContext;
67938
+ }
67939
+ __name(getValidParentSpanContext, "getValidParentSpanContext");
67940
+ function safeStringify(value) {
67941
+ try {
67942
+ return JSON.stringify(value);
67943
+ } catch {
67944
+ return "[unserializable]";
67945
+ }
67946
+ }
67947
+ __name(safeStringify, "safeStringify");
67948
+ function deriveSpanStatus(attrs) {
67949
+ if (!attrs) return { code: SpanStatusCode.OK };
67950
+ if (!!attrs["error"] || !!attrs["error.message"] || !!attrs["error_message"] || !!attrs["error_type"]) {
67951
+ return {
67952
+ code: SpanStatusCode.ERROR,
67953
+ message: LOG_EVENT_ERROR_STATUS_MESSAGE
67954
+ };
67955
+ }
67956
+ return { code: SpanStatusCode.OK };
67957
+ }
67958
+ __name(deriveSpanStatus, "deriveSpanStatus");
67959
+ function formatExportError(err) {
67960
+ if (!err) return 'error="unknown"';
67961
+ const extra = err;
67962
+ const msg = err.message || err.name || "unknown";
67963
+ const parts = [`error=${JSON.stringify(msg)}`];
67964
+ if (typeof extra.code === "number") parts.push(`httpCode=${extra.code}`);
67965
+ if (typeof extra.data === "string" && extra.data.length > 0) {
67966
+ parts.push(`data=${JSON.stringify(extra.data.slice(0, 200))}`);
67967
+ }
67968
+ return parts.join(" ");
67969
+ }
67970
+ __name(formatExportError, "formatExportError");
67971
+ function hrTimeDiff(start, end) {
67972
+ let secs = end[0] - start[0];
67973
+ let nanos = end[1] - start[1];
67974
+ if (nanos < 0) {
67975
+ secs -= 1;
67976
+ nanos += 1e9;
67977
+ }
67978
+ return [secs, nanos];
67979
+ }
67980
+ __name(hrTimeDiff, "hrTimeDiff");
67981
+
67982
+ // packages/core/src/telemetry/tracer.ts
67983
+ init_esbuild_shims();
67984
+ init_esm();
67985
+ var tracer = trace.getTracer(SERVICE_NAME);
67986
+ var debugLogger8 = createDebugLogger("OTEL_TRACER");
67987
+ var TELEMETRY_WARNING_INTERVAL_MS = 3e4;
67988
+ var API_CALL_FAILED_SPAN_STATUS_MESSAGE = "API call failed";
67989
+ var API_CALL_ABORTED_SPAN_STATUS_MESSAGE = "API call aborted";
67990
+ var lastTelemetryWarningMs;
67991
+ var suppressedTelemetryWarnings = 0;
67992
+ function warnTelemetryOperationFailed(operation, error) {
67993
+ const now = Date.now();
67994
+ if (lastTelemetryWarningMs !== void 0 && now - lastTelemetryWarningMs < TELEMETRY_WARNING_INTERVAL_MS) {
67995
+ suppressedTelemetryWarnings += 1;
67996
+ return;
67997
+ }
67998
+ const suppressedSuffix = suppressedTelemetryWarnings > 0 ? `; suppressed ${suppressedTelemetryWarnings} similar warning(s)` : "";
67999
+ suppressedTelemetryWarnings = 0;
68000
+ lastTelemetryWarningMs = now;
68001
+ try {
68002
+ debugLogger8.warn(
68003
+ `OTel span ${operation} failed: ${error instanceof Error ? error.message : String(error)}${suppressedSuffix}`
68004
+ );
68005
+ } catch {
68006
+ }
68007
+ }
68008
+ __name(warnTelemetryOperationFailed, "warnTelemetryOperationFailed");
68009
+ function safeSetStatus(span, status) {
68010
+ try {
68011
+ span.setStatus(status);
68012
+ } catch (error) {
68013
+ warnTelemetryOperationFailed("setStatus", error);
68014
+ }
68015
+ }
68016
+ __name(safeSetStatus, "safeSetStatus");
68017
+ function shouldForceSampled() {
68018
+ const sampler = process.env["OTEL_TRACES_SAMPLER"]?.trim().toLowerCase() ?? "";
68019
+ if (!sampler || sampler.startsWith("parentbased_")) {
68020
+ if (sampler.includes("always_off")) return false;
68021
+ return true;
68022
+ }
68023
+ return sampler === "always_on";
68024
+ }
68025
+ __name(shouldForceSampled, "shouldForceSampled");
68026
+ function createSessionRootContext(sessionId) {
68027
+ const traceId = deriveTraceId(sessionId);
68028
+ const spanId = randomSpanId();
68029
+ const rootSpan = trace.wrapSpanContext({
68030
+ traceId,
68031
+ spanId,
68032
+ traceFlags: shouldForceSampled() ? TraceFlags.SAMPLED : TraceFlags.NONE,
68033
+ isRemote: false
68034
+ });
68035
+ return trace.setSpan(ROOT_CONTEXT, rootSpan);
68036
+ }
68037
+ __name(createSessionRootContext, "createSessionRootContext");
68038
+
67756
68039
  // packages/core/src/telemetry/sdk.ts
67757
68040
  function createTelemetryDiagLogger() {
67758
68041
  const debugLogger12 = createDebugLogger("OTEL");
@@ -68540,7 +68823,21 @@ function isUserVisiblePart(part) {
68540
68823
  }
68541
68824
  __name(isUserVisiblePart, "isUserVisiblePart");
68542
68825
 
68826
+ // packages/core/src/utils/retryContext.ts
68827
+ init_esbuild_shims();
68828
+ import { AsyncLocalStorage as AsyncLocalStorage4 } from "node:async_hooks";
68829
+ var retryContext = new AsyncLocalStorage4();
68830
+
68543
68831
  // packages/core/src/core/loggingContentGenerator/loggingContentGenerator.ts
68832
+ function snapshotRetryMetadata() {
68833
+ const ctx = retryContext.getStore();
68834
+ return {
68835
+ attempt: ctx?.attempt ?? 1,
68836
+ requestSetupMs: ctx?.requestSetupMs,
68837
+ retryTotalDelayMs: ctx?.retryTotalDelayMs
68838
+ };
68839
+ }
68840
+ __name(snapshotRetryMetadata, "snapshotRetryMetadata");
68544
68841
  var debugLogger9 = createDebugLogger("LOGGING_CONTENT_GENERATOR");
68545
68842
  var MAX_RESPONSE_TEXT_LENGTH = 4096;
68546
68843
  var RESPONSE_TEXT_TRUNCATION_SUFFIX = "...[truncated]";
@@ -68638,6 +68935,7 @@ var LoggingContentGenerator = class {
68638
68935
  }
68639
68936
  }
68640
68937
  async generateContent(req, userPromptId) {
68938
+ const retrySnapshot = snapshotRetryMetadata();
68641
68939
  const llmSpan = startLLMRequestSpan(req.model, userPromptId);
68642
68940
  try {
68643
68941
  llmSpan.setAttribute("llm_request.stream", false);
@@ -68705,7 +69003,8 @@ var LoggingContentGenerator = class {
68705
69003
  inputTokens: response.usageMetadata?.promptTokenCount,
68706
69004
  outputTokens: response.usageMetadata?.candidatesTokenCount,
68707
69005
  cachedInputTokens: response.usageMetadata?.cachedContentTokenCount,
68708
- durationMs: Date.now() - startTime
69006
+ durationMs: Date.now() - startTime,
69007
+ ...retrySnapshot
68709
69008
  });
68710
69009
  return response;
68711
69010
  } catch (error) {
@@ -68714,7 +69013,8 @@ var LoggingContentGenerator = class {
68714
69013
  endLLMRequestSpan(llmSpan, {
68715
69014
  success: false,
68716
69015
  durationMs,
68717
- error: aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE
69016
+ error: aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE,
69017
+ ...retrySnapshot
68718
69018
  });
68719
69019
  await context.with(spanContext, async () => {
68720
69020
  this.safelyLogApiError("", durationMs, error, req.model, userPromptId);
@@ -68733,6 +69033,7 @@ var LoggingContentGenerator = class {
68733
69033
  }
68734
69034
  }
68735
69035
  async generateContentStream(req, userPromptId) {
69036
+ const retrySnapshot = snapshotRetryMetadata();
68736
69037
  const llmSpan = startLLMRequestSpan(req.model, userPromptId);
68737
69038
  try {
68738
69039
  llmSpan.setAttribute("llm_request.stream", true);
@@ -68782,7 +69083,8 @@ var LoggingContentGenerator = class {
68782
69083
  endLLMRequestSpan(llmSpan, {
68783
69084
  success: false,
68784
69085
  durationMs,
68785
- error: aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE
69086
+ error: aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE,
69087
+ ...retrySnapshot
68786
69088
  });
68787
69089
  try {
68788
69090
  await this.safelyLogOpenAIInteraction(
@@ -68814,7 +69116,8 @@ var LoggingContentGenerator = class {
68814
69116
  resolvedRequest,
68815
69117
  llmSpan,
68816
69118
  spanContext,
68817
- req.config?.abortSignal
69119
+ req.config?.abortSignal,
69120
+ retrySnapshot
68818
69121
  )
68819
69122
  );
68820
69123
  }
@@ -68828,7 +69131,7 @@ var LoggingContentGenerator = class {
68828
69131
  resolve: /* @__PURE__ */ __name(async (req) => this.openaiLogger ? captured ?? await this.buildOpenAIRequestForLogging(req) : void 0, "resolve")
68829
69132
  };
68830
69133
  }
68831
- async *loggingStreamWrapper(stream, startTime, userPromptId, model, openaiRequest, span, spanContext, abortSignal) {
69134
+ async *loggingStreamWrapper(stream, startTime, userPromptId, model, openaiRequest, span, spanContext, abortSignal, retrySnapshot) {
68832
69135
  const isInternal = isInternalPromptId(userPromptId);
68833
69136
  const shouldCollectResponses = !isInternal || !!this.openaiLogger;
68834
69137
  const responses = [];
@@ -68852,7 +69155,8 @@ var LoggingContentGenerator = class {
68852
69155
  endLLMRequestSpan(span, {
68853
69156
  success: false,
68854
69157
  durationMs: Date.now() - startTime,
68855
- error: "Stream span timed out (idle)"
69158
+ error: "Stream span timed out (idle)",
69159
+ ...retrySnapshot
68856
69160
  });
68857
69161
  spanEndedByTimeout = true;
68858
69162
  }, STREAM_IDLE_TIMEOUT_MS);
@@ -68945,7 +69249,8 @@ var LoggingContentGenerator = class {
68945
69249
  cachedInputTokens: lastUsageMetadata?.cachedContentTokenCount,
68946
69250
  ttftMs,
68947
69251
  durationMs: Date.now() - startTime,
68948
- error: errorOccurred ? aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE : void 0
69252
+ error: errorOccurred ? aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE : void 0,
69253
+ ...retrySnapshot
68949
69254
  });
68950
69255
  }
68951
69256
  }
@@ -69335,9 +69640,10 @@ var MODALITY_PATTERNS = [
69335
69640
  // -------------------
69336
69641
  // Alibaba / Qwen
69337
69642
  // -------------------
69338
- // Qwen3.5-Plus, Qwen3.6-Plus: image + video support
69643
+ // Qwen Plus models: image + video support (Max models are text-only)
69339
69644
  [/^qwen3\.5-plus/, { image: true, video: true }],
69340
69645
  [/^qwen3\.6-plus/, { image: true, video: true }],
69646
+ [/^qwen3\.7-plus/, { image: true, video: true }],
69341
69647
  [/^coder-model$/, { image: true, video: true }],
69342
69648
  // Qwen VL (vision-language) models: image + video
69343
69649
  [/^qwen-vl-/, { image: true, video: true }],
@@ -69836,6 +70142,17 @@ var ModelsConfig = class _ModelsConfig {
69836
70142
  getResolvedModel(authType, modelId) {
69837
70143
  return this.modelRegistry.getModel(authType, modelId);
69838
70144
  }
70145
+ /**
70146
+ * Get the display name for a model by its id.
70147
+ * Looks up the model in the registry using the current authType and returns
70148
+ * its resolved name. Falls back to the raw model id when the model is not
70149
+ * found in the registry (e.g. runtime models or unknown models).
70150
+ */
70151
+ getModelDisplayName(modelId) {
70152
+ if (!this.currentAuthType) return modelId;
70153
+ const resolved = this.modelRegistry.getModel(this.currentAuthType, modelId);
70154
+ return resolved?.name ?? modelId;
70155
+ }
69839
70156
  /**
69840
70157
  * Set model programmatically (e.g., VLM auto-switch, fallback).
69841
70158
  * Supports both registry models and raw model IDs.
@@ -70686,11 +71003,11 @@ async function createContentGenerator(generatorConfig, config, isInitialAuth) {
70686
71003
  }
70687
71004
  let baseGenerator;
70688
71005
  if (authType === "openai" /* USE_OPENAI */) {
70689
- const { createOpenAIContentGenerator } = await import("./openaiContentGenerator-N3O3MYIT.js");
71006
+ const { createOpenAIContentGenerator } = await import("./openaiContentGenerator-3U6UARHS.js");
70690
71007
  baseGenerator = createOpenAIContentGenerator(generatorConfig, config);
70691
71008
  } else if (authType === "qwen-oauth" /* QWEN_OAUTH */) {
70692
- const { getQwenOAuthClient: getQwenOauthClient } = await import("./qwenOAuth2-LKXG7XVO.js");
70693
- const { QwenContentGenerator } = await import("./qwenContentGenerator-DEOIWKVH.js");
71009
+ const { getQwenOAuthClient: getQwenOauthClient } = await import("./qwenOAuth2-KRJT35QH.js");
71010
+ const { QwenContentGenerator } = await import("./qwenContentGenerator-JRFHJRH6.js");
70694
71011
  try {
70695
71012
  const qwenClient = await getQwenOauthClient(
70696
71013
  config,
@@ -70707,10 +71024,10 @@ async function createContentGenerator(generatorConfig, config, isInitialAuth) {
70707
71024
  );
70708
71025
  }
70709
71026
  } else if (authType === "anthropic" /* USE_ANTHROPIC */) {
70710
- const { createAnthropicContentGenerator } = await import("./anthropicContentGenerator-M45RXZVS.js");
71027
+ const { createAnthropicContentGenerator } = await import("./anthropicContentGenerator-4QBVSFSJ.js");
70711
71028
  baseGenerator = createAnthropicContentGenerator(generatorConfig, config);
70712
71029
  } else if (authType === "gemini" /* USE_GEMINI */ || authType === "vertex-ai" /* USE_VERTEX_AI */) {
70713
- const { createGeminiContentGenerator } = await import("./geminiContentGenerator-3LR7MKCQ.js");
71030
+ const { createGeminiContentGenerator } = await import("./geminiContentGenerator-3AKHMB3P.js");
70714
71031
  baseGenerator = createGeminiContentGenerator(generatorConfig, config);
70715
71032
  } else {
70716
71033
  throw new Error(
@@ -71413,6 +71730,23 @@ var QwenLogger = class _QwenLogger {
71413
71730
  this.enqueueLogEvent(rumEvent);
71414
71731
  this.flushIfNeeded();
71415
71732
  }
71733
+ // Phase 4b — HTTP-status retry from retryWithBackoff (429/5xx). Distinct from
71734
+ // logContentRetryEvent which is fired by geminiChat's content-recovery loop.
71735
+ logApiRetryEvent(event) {
71736
+ const rumEvent = this.createActionEvent("misc", "api_retry", {
71737
+ properties: {
71738
+ model: event.model,
71739
+ prompt_id: event.prompt_id ?? "",
71740
+ attempt_number: event.attempt_number,
71741
+ error_type: event.error_type ?? "unknown",
71742
+ status_code: event.status_code !== void 0 ? String(event.status_code) : "",
71743
+ retry_delay_ms: event.retry_delay_ms,
71744
+ subagent_name: event.subagent_name ?? ""
71745
+ }
71746
+ });
71747
+ this.enqueueLogEvent(rumEvent);
71748
+ this.flushIfNeeded();
71749
+ }
71416
71750
  // arena events
71417
71751
  logArenaSessionStartedEvent(event) {
71418
71752
  const rumEvent = this.createActionEvent("arena", "arena_session_started", {
@@ -72018,6 +72352,23 @@ function logContentRetryFailure(config, event) {
72018
72352
  recordContentRetryFailure(config);
72019
72353
  }
72020
72354
  __name(logContentRetryFailure, "logContentRetryFailure");
72355
+ function logApiRetry(config, event) {
72356
+ QwenLogger.getInstance(config)?.logApiRetryEvent(event);
72357
+ if (!isTelemetrySdkInitialized()) return;
72358
+ const attributes = {
72359
+ ...getCommonAttributes(config),
72360
+ ...event,
72361
+ "event.name": EVENT_API_RETRY
72362
+ };
72363
+ const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
72364
+ const logRecord = {
72365
+ body: `API retry attempt ${event.attempt_number} for ${event.model} (status ${event.status_code ?? "unknown"}).`,
72366
+ attributes
72367
+ };
72368
+ logger.emit(logRecord);
72369
+ recordApiRetry(config, { model: event.model });
72370
+ }
72371
+ __name(logApiRetry, "logApiRetry");
72021
72372
  function logSubagentExecution(config, event) {
72022
72373
  QwenLogger.getInstance(config)?.logSubagentExecutionEvent(event);
72023
72374
  if (!isTelemetrySdkInitialized()) return;
@@ -72506,10 +72857,11 @@ var ReadFileToolInvocation = class extends BaseToolInvocation {
72506
72857
  ...this.config.storage.getUserSkillsDirs(),
72507
72858
  Storage.getUserExtensionsDir()
72508
72859
  ];
72509
- if (workspaceContext.isPathWithinWorkspace(filePath) || isSubpaths(allowedRoots, filePath) || // isAutoMemPath uses the narrower managed auto-memory root for this
72510
- // project not the broad getMemoryBaseDir() — to avoid exposing
72511
- // sensitive ~/.qwen files such as settings.json or OAuth credentials.
72512
- isAutoMemPath(filePath, this.config.getTargetDir())) {
72860
+ if (workspaceContext.isPathWithinWorkspace(filePath) || isSubpaths(allowedRoots, filePath) || // isAnyAutoMemPath narrows to the managed auto-memory roots
72861
+ // (per-project + user-level under ~/.qwen/memories/) — never the
72862
+ // broad getMemoryBaseDir() to avoid exposing sensitive ~/.qwen
72863
+ // files such as settings.json or OAuth credentials.
72864
+ isAnyAutoMemPath(filePath, this.config.getTargetDir())) {
72513
72865
  return "allow";
72514
72866
  }
72515
72867
  return "ask";
@@ -72517,7 +72869,7 @@ var ReadFileToolInvocation = class extends BaseToolInvocation {
72517
72869
  async execute() {
72518
72870
  const absPath = path7.resolve(this.params.file_path);
72519
72871
  const projectRoot = this.config.getTargetDir();
72520
- const isAutoMem = isAutoMemPath(absPath, projectRoot);
72872
+ const isAutoMem = isAnyAutoMemPath(absPath, projectRoot);
72521
72873
  const cacheEnabled = !this.config.getFileReadCacheDisabled();
72522
72874
  const useFastPath = cacheEnabled && !isAutoMem;
72523
72875
  const cache = this.config.getFileReadCache();
@@ -72736,6 +73088,7 @@ export {
72736
73088
  subagentNameContext,
72737
73089
  UiTelemetryService,
72738
73090
  uiTelemetryService,
73091
+ safeJsonStringify,
72739
73092
  require_safer,
72740
73093
  iconvEncode,
72741
73094
  iconvEncodingExists,
@@ -72802,6 +73155,7 @@ export {
72802
73155
  recordInvalidChunk,
72803
73156
  recordContentRetry,
72804
73157
  recordContentRetryFailure,
73158
+ recordApiRetry,
72805
73159
  recordStartupPerformance,
72806
73160
  recordMemoryUsage,
72807
73161
  recordCpuUsage,
@@ -72823,7 +73177,6 @@ export {
72823
73177
  SemanticAttributes,
72824
73178
  sanitizeHookName,
72825
73179
  QwenLogger,
72826
- safeSetStatus,
72827
73180
  truncateContent,
72828
73181
  addUserPromptAttributes,
72829
73182
  addSystemPromptAttributes,
@@ -72846,7 +73199,11 @@ export {
72846
73199
  endToolBlockedOnUserSpan,
72847
73200
  startHookSpan,
72848
73201
  endHookSpan,
73202
+ startSubagentSpan,
73203
+ runInSubagentSpanContext,
73204
+ endSubagentSpan,
72849
73205
  getActiveInteractionSpan,
73206
+ safeSetStatus,
72850
73207
  isTelemetrySdkInitialized,
72851
73208
  initializeTelemetry,
72852
73209
  refreshSessionContext,
@@ -72873,6 +73230,7 @@ export {
72873
73230
  logKittySequenceOverflow,
72874
73231
  logContentRetry,
72875
73232
  logContentRetryFailure,
73233
+ logApiRetry,
72876
73234
  logSubagentExecution,
72877
73235
  logModelSlashCommand,
72878
73236
  logHookCall,
@@ -72922,6 +73280,7 @@ export {
72922
73280
  KittySequenceOverflowEvent,
72923
73281
  FileOperationEvent,
72924
73282
  ContentRetryEvent,
73283
+ ApiRetryEvent,
72925
73284
  ContentRetryFailureEvent,
72926
73285
  ExtensionInstallEvent,
72927
73286
  ToolOutputTruncatedEvent,
@@ -72956,6 +73315,7 @@ export {
72956
73315
  TelemetryTarget,
72957
73316
  DEFAULT_TELEMETRY_TARGET,
72958
73317
  DEFAULT_OTLP_ENDPOINT,
73318
+ retryContext,
72959
73319
  defaultModalities,
72960
73320
  MODEL_GENERATION_CONFIG_FIELDS,
72961
73321
  AUTH_ENV_MAPPINGS,