@qwen-code/qwen-code 0.18.0-preview.2 → 0.18.1-nightly.20260616.a68b2e1e7

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 (145) hide show
  1. package/bundled/loop/SKILL.md +2 -1
  2. package/bundled/qc-helper/docs/_meta.ts +1 -0
  3. package/bundled/qc-helper/docs/common-workflow.md +4 -4
  4. package/bundled/qc-helper/docs/configuration/auth.md +1 -1
  5. package/bundled/qc-helper/docs/configuration/model-providers.md +13 -6
  6. package/bundled/qc-helper/docs/configuration/settings.md +90 -89
  7. package/bundled/qc-helper/docs/features/approval-mode.md +10 -14
  8. package/bundled/qc-helper/docs/features/commands.md +33 -11
  9. package/bundled/qc-helper/docs/features/dual-output.md +37 -3
  10. package/bundled/qc-helper/docs/features/followup-suggestions.md +2 -2
  11. package/bundled/qc-helper/docs/features/skills.md +29 -3
  12. package/bundled/qc-helper/docs/features/sub-agents.md +34 -12
  13. package/bundled/qc-helper/docs/qwen-serve-deploy-local.md +221 -0
  14. package/bundled/qc-helper/docs/qwen-serve.md +250 -31
  15. package/bundled/qc-helper/docs/reference/keyboard-shortcuts.md +30 -30
  16. package/chunks/{agent-QB7TZ4HW.js → agent-PXMT2XR5.js} +25 -24
  17. package/chunks/agent-headless-SY7VJUHV.js +51 -0
  18. package/chunks/{anthropicContentGenerator-M45EVVRM.js → anthropicContentGenerator-DCI26OQF.js} +7 -7
  19. package/chunks/{askUserQuestion-WM2KHM3K.js → askUserQuestion-NDNFGC35.js} +45 -3
  20. package/chunks/{ca-BARBRL6N.js → ca-RK4QPLIX.js} +18 -1
  21. package/chunks/{chunk-CNSMKPK6.js → chunk-26QELEL2.js} +1 -1
  22. package/chunks/{chunk-CWV3SJZS.js → chunk-3NRO6NHX.js} +2 -2
  23. package/chunks/{chunk-BNESGOSJ.js → chunk-55ZMG67I.js} +1 -1
  24. package/chunks/{chunk-2ZTWI7KH.js → chunk-6WPY6ES3.js} +62 -22
  25. package/chunks/{chunk-ZK4AMNIU.js → chunk-A3OEZT2F.js} +1294 -314
  26. package/chunks/{chunk-HXJE7VOG.js → chunk-ABRZC6FA.js} +1074 -144
  27. package/chunks/{chunk-JUGRPQAB.js → chunk-B4ZF2KSI.js} +1 -1
  28. package/chunks/chunk-BJ5HQ23U.js +178 -0
  29. package/chunks/{chunk-ICOI4E4S.js → chunk-CPVI5J2L.js} +101 -23
  30. package/chunks/{chunk-GX7VH5JQ.js → chunk-FIQECJTQ.js} +1 -1
  31. package/chunks/{chunk-QCG6KPNM.js → chunk-H4ZDM3N6.js} +18039 -11622
  32. package/chunks/{chunk-SZOEIL6S.js → chunk-H6BD2ELD.js} +1 -0
  33. package/chunks/{chunk-JXAZUMDW.js → chunk-HA2UEYZP.js} +7 -4
  34. package/chunks/{chunk-MVIVIPCU.js → chunk-IDYDPBBN.js} +361 -583
  35. package/chunks/{chunk-JVQOQ3OU.js → chunk-IQHSD7K5.js} +1 -1
  36. package/chunks/{chunk-CNHFPN7T.js → chunk-JZFEL3RB.js} +1 -1
  37. package/chunks/{chunk-UAMOBVVW.js → chunk-LXYWINWF.js} +1 -1
  38. package/chunks/{chunk-P4J26VDS.js → chunk-LYRSMKLS.js} +2 -2
  39. package/chunks/{chunk-Y7R6H6FT.js → chunk-LYSND7KR.js} +9 -4
  40. package/chunks/{chunk-AVW55ZCO.js → chunk-M5PJ5QAF.js} +37 -16
  41. package/chunks/{chunk-LR62TEET.js → chunk-NNIYWQIS.js} +1 -1
  42. package/chunks/chunk-OMX7CUOE.js +356 -0
  43. package/chunks/{chunk-HV3ZZ7G4.js → chunk-OT6JA3KQ.js} +2 -2
  44. package/chunks/{chunk-C6WMLUNB.js → chunk-QP4R5FTG.js} +1 -1
  45. package/chunks/chunk-QQDPRDVW.js +25 -0
  46. package/chunks/chunk-SFRV6BGY.js +243 -0
  47. package/chunks/{chunk-NW5QBUYO.js → chunk-TSBXGR73.js} +14 -14
  48. package/chunks/{chunk-7YKXFA3D.js → chunk-UOB6KPGG.js} +11 -11
  49. package/chunks/{chunk-USE2VQ5P.js → chunk-VU6A2OBJ.js} +41 -6
  50. package/chunks/{chunk-PAEBHDIO.js → chunk-VXHYMZXW.js} +1 -1
  51. package/chunks/{chunk-HGJPQK33.js → chunk-WPTCDQN6.js} +188 -534
  52. package/chunks/{chunk-WFVXF3OM.js → chunk-Z2Z3GUXZ.js} +1 -0
  53. package/chunks/{chunk-KC6ZMJ5X.js → chunk-ZMIBJS45.js} +1 -1
  54. package/chunks/chunk-ZOFNJQNJ.js +607 -0
  55. package/chunks/computer-use-7SEQDSHB.js +2052 -0
  56. package/chunks/contextCommand-KM5OWV65.js +53 -0
  57. package/chunks/cron-create-7CXEAJ2K.js +184 -0
  58. package/chunks/{cron-delete-ZGUXWBTG.js → cron-delete-2FQYYNQ6.js} +28 -5
  59. package/chunks/{cron-list-QNNZGMN3.js → cron-list-QCAJ73XE.js} +40 -7
  60. package/chunks/{de-YGKK2BC4.js → de-FGPM4KW5.js} +18 -1
  61. package/chunks/{devtools-IXE4UP72.js → devtools-FM6GJPYG.js} +1 -1
  62. package/chunks/{dist-R2SXPG74.js → dist-2UCAYOX7.js} +2 -2
  63. package/chunks/{dist-TE5QKMGR.js → dist-33LHH26D.js} +1 -1
  64. package/chunks/{dist-BXDUQ2QY.js → dist-KF43SZZV.js} +1 -1
  65. package/chunks/{dist-ZMQ4TXD5.js → dist-PF2IYSMD.js} +2 -2
  66. package/chunks/{edit-6UBTS2J5.js → edit-BMUKPLA7.js} +27 -28
  67. package/chunks/{en-HSQQNQUB.js → en-VP6XPGEC.js} +9 -2
  68. package/chunks/{enter-worktree-NN7LIXCM.js → enter-worktree-LXJ5WJ5A.js} +25 -24
  69. package/chunks/enterPlanMode-QWRZ54ZF.js +159 -0
  70. package/chunks/{exit-worktree-GGSS5KIE.js → exit-worktree-5HTQPNZO.js} +25 -24
  71. package/chunks/exitPlanMode-5WQAXNDA.js +743 -0
  72. package/chunks/{fr-JXBKPJKQ.js → fr-ATYBVCLT.js} +18 -1
  73. package/chunks/{geminiContentGenerator-I4H2NLJG.js → geminiContentGenerator-CAKHT5YE.js} +7 -7
  74. package/chunks/{getMachineId-bsd-F7GNPTER.js → getMachineId-bsd-4CASPIU4.js} +1 -1
  75. package/chunks/{getMachineId-darwin-T73DJL27.js → getMachineId-darwin-HPQPEMZR.js} +1 -1
  76. package/chunks/{getMachineId-linux-MKQTFPQM.js → getMachineId-linux-AUARKYHL.js} +1 -1
  77. package/chunks/{getMachineId-unsupported-MUR5KOQE.js → getMachineId-unsupported-S32ZDA2T.js} +1 -1
  78. package/chunks/{getMachineId-win-CDYFC6ZM.js → getMachineId-win-4EFLHYIJ.js} +1 -1
  79. package/chunks/{glob-OLCX57MD.js → glob-5DN6NSCD.js} +25 -24
  80. package/chunks/{grep-7HXIMDOW.js → grep-BJILOLCD.js} +37 -30
  81. package/chunks/{ja-TGPZSP2B.js → ja-W2QEA2OI.js} +18 -1
  82. package/chunks/{keychain-token-storage-LB46DAEK.js → keychain-token-storage-QSTRHKKL.js} +3 -3
  83. package/chunks/{ls-6PEZUK6O.js → ls-XVGXRYWD.js} +4 -4
  84. package/chunks/{lsp-JZSJOVT7.js → lsp-S6SHPULC.js} +3 -3
  85. package/chunks/{monitor-SQO7MVAV.js → monitor-SUEMSRN3.js} +25 -24
  86. package/chunks/{notebook-edit-72L3EBAL.js → notebook-edit-6F6Z5P6U.js} +26 -25
  87. package/chunks/{openaiContentGenerator-FTR7CDWF.js → openaiContentGenerator-DO27LL6O.js} +15 -15
  88. package/chunks/{pt-TIBG6BIO.js → pt-ZKEWJFBW.js} +18 -1
  89. package/chunks/{qwenContentGenerator-U5UFQ566.js → qwenContentGenerator-DQLGLQSH.js} +27 -26
  90. package/chunks/{qwenOAuth2-EFSECGHF.js → qwenOAuth2-KK433U33.js} +6 -5
  91. package/chunks/{read-file-UA64EEQC.js → read-file-3TBLYTOQ.js} +11 -11
  92. package/chunks/ripGrep-3INYT3QV.js +49 -0
  93. package/chunks/{ru-JBCHCK4L.js → ru-VEKTPJ74.js} +18 -1
  94. package/chunks/{scheduler-VBASHOCA.js → scheduler-23KQW6CX.js} +25 -24
  95. package/chunks/{send-message-OYJZ5TPG.js → send-message-SMNR5DBG.js} +3 -3
  96. package/chunks/{serve-A7E2OJDR.js → serve-Y5E4LKUI.js} +13164 -3840
  97. package/chunks/{shell-3NFOT6F5.js → shell-4H6XQXVY.js} +25 -24
  98. package/chunks/{skill-RA5YUREY.js → skill-SE6FECZR.js} +64 -113
  99. package/chunks/{src-NFCMARMT.js → src-76DUBH3A.js} +176 -44
  100. package/chunks/{syntheticOutput-DETQ2YM6.js → syntheticOutput-KMNF7YG6.js} +4 -4
  101. package/chunks/{task-create-Y3ZKTJIG.js → task-create-LIJHK75G.js} +8 -7
  102. package/chunks/{task-list-ONXJ3I3A.js → task-list-S4GNSILM.js} +7 -6
  103. package/chunks/{task-stop-UHDC4N5B.js → task-stop-3GBRYJHM.js} +3 -3
  104. package/chunks/{task-update-TCNOU3P5.js → task-update-F3UTVJMS.js} +21 -9
  105. package/chunks/{team-create-6SR4OVRG.js → team-create-Q5DTDDH4.js} +28 -26
  106. package/chunks/{team-delete-EJ4U4DDP.js → team-delete-54434EB7.js} +9 -6
  107. package/chunks/{todoWrite-TEYDRS5L.js → todoWrite-4ENGSBUX.js} +5 -5
  108. package/chunks/{tool-search-OD435A3X.js → tool-search-ABZMSDTU.js} +11 -11
  109. package/chunks/{web-fetch-6W67H5PO.js → web-fetch-RHZMF3MP.js} +5 -5
  110. package/chunks/workflow-NEMDQB75.js +1414 -0
  111. package/chunks/{write-file-475L5OPP.js → write-file-VAEHZPSL.js} +26 -25
  112. package/chunks/{zh-VCLWO26Y.js → zh-OIXDDQHB.js} +10 -3
  113. package/chunks/{zh-TW-G3HFHVVT.js → zh-TW-6YFNCKTA.js} +10 -3
  114. package/cli-entry.js +19 -0
  115. package/cli.js +11155 -6656
  116. package/examples/starter/QWEN.md +30 -0
  117. package/examples/starter/README.md +59 -0
  118. package/examples/starter/agents/diary.md +86 -0
  119. package/examples/starter/commands/writing/polish.md +13 -0
  120. package/examples/starter/example.ts +64 -0
  121. package/examples/starter/package.json +18 -0
  122. package/examples/starter/qwen-extension.json +12 -0
  123. package/examples/starter/skills/synonyms/SKILL.md +48 -0
  124. package/examples/starter/tsconfig.json +13 -0
  125. package/fzfWorker.js +1083 -0
  126. package/locales/ca.js +20 -2
  127. package/locales/de.js +21 -2
  128. package/locales/en.js +13 -4
  129. package/locales/fr.js +22 -2
  130. package/locales/ja.js +22 -2
  131. package/locales/pt.js +21 -2
  132. package/locales/ru.js +20 -2
  133. package/locales/zh-TW.js +11 -4
  134. package/locales/zh.js +11 -4
  135. package/package.json +5 -3
  136. package/chunks/agent-headless-APVHH7QM.js +0 -50
  137. package/chunks/chunk-AJIR24J2.js +0 -59
  138. package/chunks/chunk-SKBPNJEW.js +0 -45
  139. package/chunks/chunk-XBFVXFB2.js +0 -216
  140. package/chunks/computer-use-B7VIUI7F.js +0 -825
  141. package/chunks/contextCommand-63RZ3O5R.js +0 -52
  142. package/chunks/cron-create-FI5LJVUS.js +0 -140
  143. package/chunks/exitPlanMode-H323NHB2.js +0 -235
  144. package/chunks/ripGrep-WSYCWZVK.js +0 -48
  145. package/chunks/workflow-62DHH4EO.js +0 -708
@@ -20,19 +20,22 @@ import {
20
20
  } from "./chunk-OFEVLU4C.js";
21
21
  import {
22
22
  isAnyAutoMemPath
23
- } from "./chunk-JVQOQ3OU.js";
23
+ } from "./chunk-IQHSD7K5.js";
24
24
  import {
25
25
  InstallationManager
26
- } from "./chunk-P4J26VDS.js";
26
+ } from "./chunk-LYRSMKLS.js";
27
27
  import {
28
28
  STRUCTURED_OUTPUT_REDACTED_ARGS
29
- } from "./chunk-CNSMKPK6.js";
29
+ } from "./chunk-26QELEL2.js";
30
30
  import {
31
31
  BaseDeclarativeTool,
32
32
  BaseToolInvocation,
33
33
  ToolDisplayNames,
34
34
  ToolNames
35
- } from "./chunk-2ZTWI7KH.js";
35
+ } from "./chunk-6WPY6ES3.js";
36
+ import {
37
+ atomicWriteFile
38
+ } from "./chunk-LXYWINWF.js";
36
39
  import {
37
40
  DEFAULT_OPENAI_BASE_URL,
38
41
  convertSchema,
@@ -40,20 +43,21 @@ import {
40
43
  runtimeDiagnostics,
41
44
  safeJsonParse,
42
45
  tokenLimit
43
- } from "./chunk-Y7R6H6FT.js";
46
+ } from "./chunk-LYSND7KR.js";
44
47
  import {
45
48
  FinishReason,
46
49
  GenerateContentResponse
47
- } from "./chunk-BNESGOSJ.js";
50
+ } from "./chunk-55ZMG67I.js";
48
51
  import {
49
52
  FatalConfigError,
50
53
  Storage,
51
54
  createDebugLogger,
55
+ formatTraceparent,
56
+ getActiveSpanTraceContext,
52
57
  getCurrentSessionId,
53
58
  getErrorMessage,
54
59
  getErrorStatus,
55
60
  getErrorType,
56
- getSessionContext,
57
61
  isNodeError,
58
62
  isSubpaths,
59
63
  makeRelative,
@@ -61,7 +65,7 @@ import {
61
65
  setShellTracePropagation,
62
66
  shortenPath,
63
67
  unescapePath
64
- } from "./chunk-JXAZUMDW.js";
68
+ } from "./chunk-HA2UEYZP.js";
65
69
  import {
66
70
  require_dist
67
71
  } from "./chunk-ZERZSAZL.js";
@@ -81,8 +85,9 @@ import {
81
85
  init_esm,
82
86
  isSpanContextValid,
83
87
  metrics,
88
+ propagation,
84
89
  trace
85
- } from "./chunk-WFVXF3OM.js";
90
+ } from "./chunk-Z2Z3GUXZ.js";
86
91
  import {
87
92
  __qwen_dirname,
88
93
  init_esbuild_shims
@@ -17034,7 +17039,7 @@ var require_load_balancer_child_handler = __commonJS({
17034
17039
  createSubchannel(subchannelAddress, subchannelArgs) {
17035
17040
  return this.parent.channelControlHelper.createSubchannel(subchannelAddress, subchannelArgs);
17036
17041
  }
17037
- updateState(connectivityState, picker, errorMessage) {
17042
+ updateState(connectivityState, picker, errorMessage2) {
17038
17043
  var _a;
17039
17044
  if (this.calledByPendingChild()) {
17040
17045
  if (connectivityState === connectivity_state_1.ConnectivityState.CONNECTING) {
@@ -17046,7 +17051,7 @@ var require_load_balancer_child_handler = __commonJS({
17046
17051
  } else if (!this.calledByCurrentChild()) {
17047
17052
  return;
17048
17053
  }
17049
- this.parent.channelControlHelper.updateState(connectivityState, picker, errorMessage);
17054
+ this.parent.channelControlHelper.updateState(connectivityState, picker, errorMessage2);
17050
17055
  }
17051
17056
  requestReresolution() {
17052
17057
  var _a;
@@ -17280,11 +17285,11 @@ var require_resolving_load_balancer = __commonJS({
17280
17285
  this.updateResolution();
17281
17286
  }
17282
17287
  }, "requestReresolution"),
17283
- updateState: /* @__PURE__ */ __name((newState, picker, errorMessage) => {
17288
+ updateState: /* @__PURE__ */ __name((newState, picker, errorMessage2) => {
17284
17289
  this.latestChildState = newState;
17285
17290
  this.latestChildPicker = picker;
17286
- this.latestChildErrorMessage = errorMessage;
17287
- this.updateState(newState, picker, errorMessage);
17291
+ this.latestChildErrorMessage = errorMessage2;
17292
+ this.updateState(newState, picker, errorMessage2);
17288
17293
  }, "updateState"),
17289
17294
  addChannelzChild: channelControlHelper.addChannelzChild.bind(channelControlHelper),
17290
17295
  removeChannelzChild: channelControlHelper.removeChannelzChild.bind(channelControlHelper)
@@ -17350,13 +17355,13 @@ var require_resolving_load_balancer = __commonJS({
17350
17355
  }
17351
17356
  this.backoffTimeout.runOnce();
17352
17357
  }
17353
- updateState(connectivityState, picker, errorMessage) {
17358
+ updateState(connectivityState, picker, errorMessage2) {
17354
17359
  trace2((0, uri_parser_1.uriToString)(this.target) + " " + connectivity_state_1.ConnectivityState[this.currentState] + " -> " + connectivity_state_1.ConnectivityState[connectivityState]);
17355
17360
  if (connectivityState === connectivity_state_1.ConnectivityState.IDLE) {
17356
17361
  picker = new picker_1.QueuePicker(this, picker);
17357
17362
  }
17358
17363
  this.currentState = connectivityState;
17359
- this.channelControlHelper.updateState(connectivityState, picker, errorMessage);
17364
+ this.channelControlHelper.updateState(connectivityState, picker, errorMessage2);
17360
17365
  }
17361
17366
  handleResolutionFailure(error) {
17362
17367
  if (this.latestChildState === connectivity_state_1.ConnectivityState.IDLE) {
@@ -20117,13 +20122,13 @@ var require_path = __commonJS({
20117
20122
  "use strict";
20118
20123
  init_esbuild_shims();
20119
20124
  var path8 = exports;
20120
- var isAbsolute2 = (
20125
+ var isAbsolute3 = (
20121
20126
  /**
20122
20127
  * Tests if the specified path is absolute.
20123
20128
  * @param {string} path Path to test
20124
20129
  * @returns {boolean} `true` if path is absolute
20125
20130
  */
20126
- path8.isAbsolute = /* @__PURE__ */ __name(function isAbsolute3(path9) {
20131
+ path8.isAbsolute = /* @__PURE__ */ __name(function isAbsolute4(path9) {
20127
20132
  return /^(?:\/|\w+:)/.test(path9);
20128
20133
  }, "isAbsolute")
20129
20134
  );
@@ -20135,7 +20140,7 @@ var require_path = __commonJS({
20135
20140
  */
20136
20141
  path8.normalize = /* @__PURE__ */ __name(function normalize4(path9) {
20137
20142
  path9 = path9.replace(/\\/g, "/").replace(/\/{2,}/g, "/");
20138
- var parts = path9.split("/"), absolute = isAbsolute2(path9), prefix = "";
20143
+ var parts = path9.split("/"), absolute = isAbsolute3(path9), prefix = "";
20139
20144
  if (absolute)
20140
20145
  prefix = parts.shift() + "/";
20141
20146
  for (var i = 0; i < parts.length; ) {
@@ -20157,7 +20162,7 @@ var require_path = __commonJS({
20157
20162
  path8.resolve = /* @__PURE__ */ __name(function resolve2(originPath, includePath, alreadyNormalized) {
20158
20163
  if (!alreadyNormalized)
20159
20164
  includePath = normalize3(includePath);
20160
- if (isAbsolute2(includePath))
20165
+ if (isAbsolute3(includePath))
20161
20166
  return includePath;
20162
20167
  if (!alreadyNormalized)
20163
20168
  originPath = normalize3(originPath);
@@ -27641,13 +27646,13 @@ var require_subchannel = __commonJS({
27641
27646
  * @param newState The state to transition to
27642
27647
  * @returns True if the state changed, false otherwise
27643
27648
  */
27644
- transitionToState(oldStates, newState, errorMessage) {
27649
+ transitionToState(oldStates, newState, errorMessage2) {
27645
27650
  var _a, _b;
27646
27651
  if (oldStates.indexOf(this.connectivityState) === -1) {
27647
27652
  return false;
27648
27653
  }
27649
- if (errorMessage) {
27650
- this.trace(connectivity_state_1.ConnectivityState[this.connectivityState] + " -> " + connectivity_state_1.ConnectivityState[newState] + ' with error "' + errorMessage + '"');
27654
+ if (errorMessage2) {
27655
+ this.trace(connectivity_state_1.ConnectivityState[this.connectivityState] + " -> " + connectivity_state_1.ConnectivityState[newState] + ' with error "' + errorMessage2 + '"');
27651
27656
  } else {
27652
27657
  this.trace(connectivity_state_1.ConnectivityState[this.connectivityState] + " -> " + connectivity_state_1.ConnectivityState[newState]);
27653
27658
  }
@@ -27688,7 +27693,7 @@ var require_subchannel = __commonJS({
27688
27693
  throw new Error(`Invalid state: unknown ConnectivityState ${newState}`);
27689
27694
  }
27690
27695
  for (const listener of this.stateListeners) {
27691
- listener(this, previousState, newState, this.keepaliveTime, errorMessage);
27696
+ listener(this, previousState, newState, this.keepaliveTime, errorMessage2);
27692
27697
  }
27693
27698
  return true;
27694
27699
  }
@@ -29257,18 +29262,18 @@ var require_transport = __commonJS({
29257
29262
  setImmediate(() => {
29258
29263
  if (!reportedError) {
29259
29264
  reportedError = true;
29260
- reject(`${errorMessage.trim()} (${(/* @__PURE__ */ new Date()).toISOString()})`);
29265
+ reject(`${errorMessage2.trim()} (${(/* @__PURE__ */ new Date()).toISOString()})`);
29261
29266
  }
29262
29267
  });
29263
29268
  }, "closeHandler");
29264
29269
  const errorHandler = /* @__PURE__ */ __name((error) => {
29265
29270
  var _a;
29266
29271
  (_a = this.session) === null || _a === void 0 ? void 0 : _a.destroy();
29267
- errorMessage = error.message;
29268
- this.trace("connection failed with error " + errorMessage);
29272
+ errorMessage2 = error.message;
29273
+ this.trace("connection failed with error " + errorMessage2);
29269
29274
  if (!reportedError) {
29270
29275
  reportedError = true;
29271
- reject(`${errorMessage} (${(/* @__PURE__ */ new Date()).toISOString()})`);
29276
+ reject(`${errorMessage2} (${(/* @__PURE__ */ new Date()).toISOString()})`);
29272
29277
  }
29273
29278
  }, "errorHandler");
29274
29279
  const sessionOptions = {
@@ -29283,7 +29288,7 @@ var require_transport = __commonJS({
29283
29288
  }
29284
29289
  const session = http2.connect(`${scheme}://${targetPath}`, sessionOptions);
29285
29290
  this.session = session;
29286
- let errorMessage = "Failed to connect";
29291
+ let errorMessage2 = "Failed to connect";
29287
29292
  let reportedError = false;
29288
29293
  session.unref();
29289
29294
  session.once("remoteSettings", () => {
@@ -34699,8 +34704,8 @@ var require_load_balancer_pick_first = __commonJS({
34699
34704
  this.currentState = connectivity_state_1.ConnectivityState.IDLE;
34700
34705
  this.currentSubchannelIndex = 0;
34701
34706
  this.currentPick = null;
34702
- this.subchannelStateListener = (subchannel, previousState, newState, keepaliveTime, errorMessage) => {
34703
- this.onSubchannelStateUpdate(subchannel, previousState, newState, errorMessage);
34707
+ this.subchannelStateListener = (subchannel, previousState, newState, keepaliveTime, errorMessage2) => {
34708
+ this.onSubchannelStateUpdate(subchannel, previousState, newState, errorMessage2);
34704
34709
  };
34705
34710
  this.pickedSubchannelHealthListener = () => this.calculateAndReportNewState();
34706
34711
  this.stickyTransientFailureMode = false;
@@ -34722,26 +34727,26 @@ var require_load_balancer_pick_first = __commonJS({
34722
34727
  var _a;
34723
34728
  if (this.currentPick) {
34724
34729
  if (this.reportHealthStatus && !this.currentPick.isHealthy()) {
34725
- const errorMessage = `Picked subchannel ${this.currentPick.getAddress()} is unhealthy`;
34730
+ const errorMessage2 = `Picked subchannel ${this.currentPick.getAddress()} is unhealthy`;
34726
34731
  this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
34727
- details: errorMessage
34728
- }), errorMessage);
34732
+ details: errorMessage2
34733
+ }), errorMessage2);
34729
34734
  } else {
34730
34735
  this.updateState(connectivity_state_1.ConnectivityState.READY, new PickFirstPicker(this.currentPick), null);
34731
34736
  }
34732
34737
  } else if (((_a = this.latestAddressList) === null || _a === void 0 ? void 0 : _a.length) === 0) {
34733
- const errorMessage = `No connection established. Last error: ${this.lastError}`;
34738
+ const errorMessage2 = `No connection established. Last error: ${this.lastError}`;
34734
34739
  this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
34735
- details: errorMessage
34736
- }), errorMessage);
34740
+ details: errorMessage2
34741
+ }), errorMessage2);
34737
34742
  } else if (this.children.length === 0) {
34738
34743
  this.updateState(connectivity_state_1.ConnectivityState.IDLE, new picker_1.QueuePicker(this), null);
34739
34744
  } else {
34740
34745
  if (this.stickyTransientFailureMode) {
34741
- const errorMessage = `No connection established. Last error: ${this.lastError}`;
34746
+ const errorMessage2 = `No connection established. Last error: ${this.lastError}`;
34742
34747
  this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
34743
- details: errorMessage
34744
- }), errorMessage);
34748
+ details: errorMessage2
34749
+ }), errorMessage2);
34745
34750
  } else {
34746
34751
  this.updateState(connectivity_state_1.ConnectivityState.CONNECTING, new picker_1.QueuePicker(this), null);
34747
34752
  }
@@ -34775,7 +34780,7 @@ var require_load_balancer_pick_first = __commonJS({
34775
34780
  this.currentPick = null;
34776
34781
  }
34777
34782
  }
34778
- onSubchannelStateUpdate(subchannel, previousState, newState, errorMessage) {
34783
+ onSubchannelStateUpdate(subchannel, previousState, newState, errorMessage2) {
34779
34784
  var _a;
34780
34785
  if ((_a = this.currentPick) === null || _a === void 0 ? void 0 : _a.realSubchannelEquals(subchannel)) {
34781
34786
  if (newState !== connectivity_state_1.ConnectivityState.READY) {
@@ -34791,8 +34796,8 @@ var require_load_balancer_pick_first = __commonJS({
34791
34796
  }
34792
34797
  if (newState === connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE) {
34793
34798
  child.hasReportedTransientFailure = true;
34794
- if (errorMessage) {
34795
- this.lastError = errorMessage;
34799
+ if (errorMessage2) {
34800
+ this.lastError = errorMessage2;
34796
34801
  }
34797
34802
  this.maybeEnterStickyTransientFailureMode();
34798
34803
  if (index === this.currentSubchannelIndex) {
@@ -34857,10 +34862,10 @@ var require_load_balancer_pick_first = __commonJS({
34857
34862
  clearTimeout(this.connectionDelayTimeout);
34858
34863
  this.calculateAndReportNewState();
34859
34864
  }
34860
- updateState(newState, picker, errorMessage) {
34865
+ updateState(newState, picker, errorMessage2) {
34861
34866
  trace2(connectivity_state_1.ConnectivityState[this.currentState] + " -> " + connectivity_state_1.ConnectivityState[newState]);
34862
34867
  this.currentState = newState;
34863
- this.channelControlHelper.updateState(newState, picker, errorMessage);
34868
+ this.channelControlHelper.updateState(newState, picker, errorMessage2);
34864
34869
  }
34865
34870
  resetSubchannelList() {
34866
34871
  for (const child of this.children) {
@@ -34944,10 +34949,10 @@ var require_load_balancer_pick_first = __commonJS({
34944
34949
  this.options = options;
34945
34950
  this.latestState = connectivity_state_1.ConnectivityState.IDLE;
34946
34951
  const childChannelControlHelper = (0, load_balancer_1.createChildChannelControlHelper)(channelControlHelper, {
34947
- updateState: /* @__PURE__ */ __name((connectivityState, picker, errorMessage) => {
34952
+ updateState: /* @__PURE__ */ __name((connectivityState, picker, errorMessage2) => {
34948
34953
  this.latestState = connectivityState;
34949
34954
  this.latestPicker = picker;
34950
- channelControlHelper.updateState(connectivityState, picker, errorMessage);
34955
+ channelControlHelper.updateState(connectivityState, picker, errorMessage2);
34951
34956
  }, "updateState")
34952
34957
  });
34953
34958
  this.pickFirstBalancer = new PickFirstLoadBalancer(childChannelControlHelper);
@@ -35459,12 +35464,12 @@ var require_load_balancer_round_robin = __commonJS({
35459
35464
  this.updatesPaused = false;
35460
35465
  this.lastError = null;
35461
35466
  this.childChannelControlHelper = (0, load_balancer_1.createChildChannelControlHelper)(channelControlHelper, {
35462
- updateState: /* @__PURE__ */ __name((connectivityState, picker, errorMessage) => {
35467
+ updateState: /* @__PURE__ */ __name((connectivityState, picker, errorMessage2) => {
35463
35468
  if (this.currentState === connectivity_state_1.ConnectivityState.READY && connectivityState !== connectivity_state_1.ConnectivityState.READY) {
35464
35469
  this.channelControlHelper.requestReresolution();
35465
35470
  }
35466
- if (errorMessage) {
35467
- this.lastError = errorMessage;
35471
+ if (errorMessage2) {
35472
+ this.lastError = errorMessage2;
35468
35473
  }
35469
35474
  this.calculateAndUpdateState();
35470
35475
  }, "updateState")
@@ -35494,10 +35499,10 @@ var require_load_balancer_round_robin = __commonJS({
35494
35499
  } else if (this.countChildrenWithState(connectivity_state_1.ConnectivityState.CONNECTING) > 0) {
35495
35500
  this.updateState(connectivity_state_1.ConnectivityState.CONNECTING, new picker_1.QueuePicker(this), null);
35496
35501
  } else if (this.countChildrenWithState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE) > 0) {
35497
- const errorMessage = `round_robin: No connection established. Last error: ${this.lastError}`;
35502
+ const errorMessage2 = `round_robin: No connection established. Last error: ${this.lastError}`;
35498
35503
  this.updateState(connectivity_state_1.ConnectivityState.TRANSIENT_FAILURE, new picker_1.UnavailablePicker({
35499
- details: errorMessage
35500
- }), errorMessage);
35504
+ details: errorMessage2
35505
+ }), errorMessage2);
35501
35506
  } else {
35502
35507
  this.updateState(connectivity_state_1.ConnectivityState.IDLE, new picker_1.QueuePicker(this), null);
35503
35508
  }
@@ -35507,7 +35512,7 @@ var require_load_balancer_round_robin = __commonJS({
35507
35512
  }
35508
35513
  }
35509
35514
  }
35510
- updateState(newState, picker, errorMessage) {
35515
+ updateState(newState, picker, errorMessage2) {
35511
35516
  trace2(connectivity_state_1.ConnectivityState[this.currentState] + " -> " + connectivity_state_1.ConnectivityState[newState]);
35512
35517
  if (newState === connectivity_state_1.ConnectivityState.READY) {
35513
35518
  this.currentReadyPicker = picker;
@@ -35515,7 +35520,7 @@ var require_load_balancer_round_robin = __commonJS({
35515
35520
  this.currentReadyPicker = null;
35516
35521
  }
35517
35522
  this.currentState = newState;
35518
- this.channelControlHelper.updateState(newState, picker, errorMessage);
35523
+ this.channelControlHelper.updateState(newState, picker, errorMessage2);
35519
35524
  }
35520
35525
  resetSubchannelList() {
35521
35526
  for (const child of this.children) {
@@ -35830,11 +35835,11 @@ var require_load_balancer_outlier_detection = __commonJS({
35830
35835
  mapEntry === null || mapEntry === void 0 ? void 0 : mapEntry.subchannelWrappers.push(subchannelWrapper);
35831
35836
  return subchannelWrapper;
35832
35837
  }, "createSubchannel"),
35833
- updateState: /* @__PURE__ */ __name((connectivityState, picker, errorMessage) => {
35838
+ updateState: /* @__PURE__ */ __name((connectivityState, picker, errorMessage2) => {
35834
35839
  if (connectivityState === connectivity_state_1.ConnectivityState.READY) {
35835
- channelControlHelper.updateState(connectivityState, new OutlierDetectionPicker(picker, this.isCountingEnabled()), errorMessage);
35840
+ channelControlHelper.updateState(connectivityState, new OutlierDetectionPicker(picker, this.isCountingEnabled()), errorMessage2);
35836
35841
  } else {
35837
- channelControlHelper.updateState(connectivityState, picker, errorMessage);
35842
+ channelControlHelper.updateState(connectivityState, picker, errorMessage2);
35838
35843
  }
35839
35844
  }, "updateState")
35840
35845
  }));
@@ -40578,8 +40583,8 @@ var require_root2 = __commonJS({
40578
40583
  return metrics2;
40579
40584
  }();
40580
40585
  collector.logs = function() {
40581
- var logs2 = {};
40582
- logs2.v1 = function() {
40586
+ var logs3 = {};
40587
+ logs3.v1 = function() {
40583
40588
  var v1 = {};
40584
40589
  v1.LogsService = function() {
40585
40590
  function LogsService(rpcImpl, requestDelimited, responseDelimited) {
@@ -40923,7 +40928,7 @@ var require_root2 = __commonJS({
40923
40928
  }();
40924
40929
  return v1;
40925
40930
  }();
40926
- return logs2;
40931
+ return logs3;
40927
40932
  }();
40928
40933
  return collector;
40929
40934
  }();
@@ -44405,8 +44410,8 @@ var require_root2 = __commonJS({
44405
44410
  return metrics2;
44406
44411
  }();
44407
44412
  proto.logs = function() {
44408
- var logs2 = {};
44409
- logs2.v1 = function() {
44413
+ var logs3 = {};
44414
+ logs3.v1 = function() {
44410
44415
  var v1 = {};
44411
44416
  v1.LogsData = function() {
44412
44417
  function LogsData(properties) {
@@ -45348,7 +45353,7 @@ var require_root2 = __commonJS({
45348
45353
  }();
45349
45354
  return v1;
45350
45355
  }();
45351
- return logs2;
45356
+ return logs3;
45352
45357
  }();
45353
45358
  return proto;
45354
45359
  }();
@@ -48134,19 +48139,19 @@ var require_getMachineId = __commonJS({
48134
48139
  if (!getMachineIdImpl) {
48135
48140
  switch (process3.platform) {
48136
48141
  case "darwin":
48137
- getMachineIdImpl = (await import("./getMachineId-darwin-T73DJL27.js")).getMachineId;
48142
+ getMachineIdImpl = (await import("./getMachineId-darwin-HPQPEMZR.js")).getMachineId;
48138
48143
  break;
48139
48144
  case "linux":
48140
- getMachineIdImpl = (await import("./getMachineId-linux-MKQTFPQM.js")).getMachineId;
48145
+ getMachineIdImpl = (await import("./getMachineId-linux-AUARKYHL.js")).getMachineId;
48141
48146
  break;
48142
48147
  case "freebsd":
48143
- getMachineIdImpl = (await import("./getMachineId-bsd-F7GNPTER.js")).getMachineId;
48148
+ getMachineIdImpl = (await import("./getMachineId-bsd-4CASPIU4.js")).getMachineId;
48144
48149
  break;
48145
48150
  case "win32":
48146
- getMachineIdImpl = (await import("./getMachineId-win-CDYFC6ZM.js")).getMachineId;
48151
+ getMachineIdImpl = (await import("./getMachineId-win-4EFLHYIJ.js")).getMachineId;
48147
48152
  break;
48148
48153
  default:
48149
- getMachineIdImpl = (await import("./getMachineId-unsupported-MUR5KOQE.js")).getMachineId;
48154
+ getMachineIdImpl = (await import("./getMachineId-unsupported-S32ZDA2T.js")).getMachineId;
48150
48155
  break;
48151
48156
  }
48152
48157
  }
@@ -51706,8 +51711,8 @@ var require_ConsoleLogRecordExporter = __commonJS({
51706
51711
  * @param logs
51707
51712
  * @param resultCallback
51708
51713
  */
51709
- export(logs2, resultCallback) {
51710
- this._sendLogRecords(logs2, resultCallback);
51714
+ export(logs3, resultCallback) {
51715
+ this._sendLogRecords(logs3, resultCallback);
51711
51716
  }
51712
51717
  /**
51713
51718
  * Shutdown the exporter.
@@ -51824,14 +51829,14 @@ var require_InMemoryLogRecordExporter = __commonJS({
51824
51829
  * When false, exported log records will not be stored in-memory.
51825
51830
  */
51826
51831
  _stopped = false;
51827
- export(logs2, resultCallback) {
51832
+ export(logs3, resultCallback) {
51828
51833
  if (this._stopped) {
51829
51834
  return resultCallback({
51830
51835
  code: core_1.ExportResultCode.FAILED,
51831
51836
  error: new Error("Exporter has been stopped")
51832
51837
  });
51833
51838
  }
51834
- this._finishedLogRecords.push(...logs2);
51839
+ this._finishedLogRecords.push(...logs3);
51835
51840
  resultCallback({ code: core_1.ExportResultCode.SUCCESS });
51836
51841
  }
51837
51842
  shutdown() {
@@ -61212,7 +61217,12 @@ function setGeminiMdFilename(newFilename) {
61212
61217
  __name(setGeminiMdFilename, "setGeminiMdFilename");
61213
61218
  function getCurrentGeminiMdFilename() {
61214
61219
  if (Array.isArray(currentGeminiMdFilename)) {
61215
- return currentGeminiMdFilename[0];
61220
+ for (const entry of currentGeminiMdFilename) {
61221
+ if (typeof entry === "string" && entry.trim() !== "") {
61222
+ return entry.trim();
61223
+ }
61224
+ }
61225
+ return DEFAULT_CONTEXT_FILENAME;
61216
61226
  }
61217
61227
  return currentGeminiMdFilename;
61218
61228
  }
@@ -62678,12 +62688,12 @@ async function processSingleFileContent(filePath, config, offset, limit, pages)
62678
62688
  }
62679
62689
  }
62680
62690
  } catch (error) {
62681
- const errorMessage = error instanceof Error ? error.message : String(error);
62691
+ const errorMessage2 = error instanceof Error ? error.message : String(error);
62682
62692
  const displayPath = path2.relative(rootDirectory, filePath).replace(/\\/g, "/");
62683
62693
  return {
62684
- llmContent: `Error reading file ${displayPath}: ${errorMessage}`,
62685
- returnDisplay: `Error reading file ${displayPath}: ${errorMessage}`,
62686
- error: `Error reading file ${filePath}: ${errorMessage}`,
62694
+ llmContent: `Error reading file ${displayPath}: ${errorMessage2}`,
62695
+ returnDisplay: `Error reading file ${displayPath}: ${errorMessage2}`,
62696
+ error: `Error reading file ${filePath}: ${errorMessage2}`,
62687
62697
  errorType: "read_content_failure" /* READ_CONTENT_FAILURE */
62688
62698
  };
62689
62699
  }
@@ -63588,7 +63598,7 @@ __name(getProgrammingLanguage, "getProgrammingLanguage");
63588
63598
 
63589
63599
  // packages/core/src/telemetry/loggers.ts
63590
63600
  init_esbuild_shims();
63591
- var import_api_logs = __toESM(require_src2(), 1);
63601
+ var import_api_logs2 = __toESM(require_src2(), 1);
63592
63602
  init_esm2();
63593
63603
 
63594
63604
  // packages/core/src/utils/internalPromptIds.ts
@@ -63705,17 +63715,35 @@ init_esbuild_shims();
63705
63715
  import * as fs3 from "node:fs/promises";
63706
63716
  import * as path4 from "node:path";
63707
63717
  import * as crypto2 from "node:crypto";
63708
- async function truncateAndSaveToFile(content, fileName, projectTempDir, threshold, truncateLines) {
63718
+ var debugLogger3 = createDebugLogger("TRUNCATION");
63719
+ var PREVIEW_SIZE_CHARS = 2e3;
63720
+ var MAX_FILE_SIZE_BYTES = 50 * 1024 * 1024;
63721
+ var MAX_SESSION_BYTES = 500 * 1024 * 1024;
63722
+ var TOOL_OUTPUT_TRUNCATED_PREFIX = "Tool output was too large and has been truncated";
63723
+ async function truncateAndSaveToFile(content, fileName, projectTempDir, threshold, truncateLines, keep = "both") {
63724
+ if (content.length <= threshold && !Number.isFinite(truncateLines)) {
63725
+ return { content };
63726
+ }
63709
63727
  const lines = content.split("\n");
63710
63728
  if (content.length <= threshold && lines.length <= truncateLines) {
63711
63729
  return { content };
63712
63730
  }
63713
63731
  const effectiveLines = Math.min(truncateLines, lines.length);
63714
- const headCount = Math.max(Math.floor(effectiveLines / 5), 1);
63715
- const tailCount = effectiveLines - headCount;
63732
+ let headCount;
63733
+ let tailCount;
63734
+ if (keep === "head") {
63735
+ headCount = effectiveLines;
63736
+ tailCount = 0;
63737
+ } else if (keep === "tail") {
63738
+ headCount = 0;
63739
+ tailCount = effectiveLines;
63740
+ } else {
63741
+ headCount = Math.max(Math.floor(effectiveLines / 5), 1);
63742
+ tailCount = effectiveLines - headCount;
63743
+ }
63716
63744
  const separator = "\n\n---\n... [CONTENT TRUNCATED] ...\n---\n\n";
63717
63745
  const ellipsis = "...";
63718
- const headBudget = Math.floor(threshold / 5);
63746
+ const headBudget = keep === "head" ? threshold : keep === "tail" ? 0 : Math.floor(threshold / 5);
63719
63747
  const beginning = [];
63720
63748
  let headChars = 0;
63721
63749
  for (let i = 0; i < Math.min(headCount, lines.length); i++) {
@@ -63730,7 +63758,7 @@ async function truncateAndSaveToFile(content, fileName, projectTempDir, threshol
63730
63758
  beginning.push(lines[i]);
63731
63759
  headChars += lines[i].length + 1;
63732
63760
  }
63733
- const tailBudget = Math.max(threshold - headChars - separator.length, 0);
63761
+ const tailBudget = keep === "head" ? 0 : Math.max(threshold - headChars - separator.length, 0);
63734
63762
  const end = [];
63735
63763
  let tailChars = 0;
63736
63764
  const tailStart = Math.max(lines.length - tailCount, beginning.length);
@@ -63739,30 +63767,38 @@ async function truncateAndSaveToFile(content, fileName, projectTempDir, threshol
63739
63767
  if (remaining <= 0) break;
63740
63768
  if (lines[i].length + 1 > remaining) {
63741
63769
  const sliceLen = Math.max(remaining - ellipsis.length, 0);
63742
- end.unshift(ellipsis + lines[i].slice(-sliceLen));
63770
+ end.unshift(ellipsis + (sliceLen > 0 ? lines[i].slice(-sliceLen) : ""));
63743
63771
  tailChars = tailBudget;
63744
63772
  break;
63745
63773
  }
63746
63774
  end.unshift(lines[i]);
63747
63775
  tailChars += lines[i].length + 1;
63748
63776
  }
63749
- const truncatedContent = beginning.join("\n") + separator + end.join("\n");
63777
+ const truncatedContent = keep === "head" ? beginning.join("\n") + separator : keep === "tail" ? separator + end.join("\n") : beginning.join("\n") + separator + end.join("\n");
63750
63778
  const safeFileName = `${path4.basename(fileName)}.output`;
63751
63779
  const outputFile = path4.join(projectTempDir, safeFileName);
63752
- try {
63753
- await fs3.mkdir(projectTempDir, { recursive: true });
63754
- await fs3.writeFile(outputFile, content);
63755
- return {
63756
- content: `Tool output was too large and has been truncated.
63780
+ const wrappedMessage = `${TOOL_OUTPUT_TRUNCATED_PREFIX}.
63757
63781
  The full output has been saved to: ${outputFile}
63758
63782
  To read the complete output, use the ${ReadFileTool.Name} tool with the absolute file path above.
63759
63783
  The truncated output below shows the beginning and end of the content. The marker '... [CONTENT TRUNCATED] ...' indicates where content was removed.
63760
63784
 
63761
63785
  Truncated part of the output:
63762
- ${truncatedContent}`,
63786
+ ${truncatedContent}`;
63787
+ if (wrappedMessage.length >= content.length) {
63788
+ return { content };
63789
+ }
63790
+ try {
63791
+ await fs3.mkdir(projectTempDir, { recursive: true });
63792
+ await fs3.writeFile(outputFile, content, { mode: 384 });
63793
+ return {
63794
+ content: wrappedMessage,
63763
63795
  outputFile
63764
63796
  };
63765
- } catch (_error) {
63797
+ } catch (error) {
63798
+ debugLogger3.warn(
63799
+ `Failed to save truncated output to ${outputFile}:`,
63800
+ error
63801
+ );
63766
63802
  return {
63767
63803
  content: truncatedContent + `
63768
63804
  [Note: Could not save full output to file]`
@@ -63770,12 +63806,16 @@ ${truncatedContent}`,
63770
63806
  }
63771
63807
  }
63772
63808
  __name(truncateAndSaveToFile, "truncateAndSaveToFile");
63773
- async function truncateToolOutput(config, toolName, content) {
63774
- const threshold = config.getTruncateToolOutputThreshold();
63775
- const lines = config.getTruncateToolOutputLines();
63809
+ async function truncateToolOutput(config, toolName, content, limits, promptId) {
63810
+ const threshold = limits?.threshold ?? config.getTruncateToolOutputThreshold();
63811
+ const lines = limits?.lines ?? config.getTruncateToolOutputLines();
63812
+ const keep = limits?.keep ?? "both";
63776
63813
  if (threshold <= 0 || lines <= 0) {
63777
63814
  return { content };
63778
63815
  }
63816
+ if (content.length <= threshold && !Number.isFinite(lines)) {
63817
+ return { content };
63818
+ }
63779
63819
  const originalLength = content.length;
63780
63820
  const fileName = `${toolName}_${crypto2.randomBytes(6).toString("hex")}`;
63781
63821
  const result = await truncateAndSaveToFile(
@@ -63783,26 +63823,177 @@ async function truncateToolOutput(config, toolName, content) {
63783
63823
  fileName,
63784
63824
  config.storage.getProjectTempDir(),
63785
63825
  threshold,
63786
- lines
63826
+ lines,
63827
+ keep
63787
63828
  );
63788
63829
  if (result.outputFile) {
63789
- logToolOutputTruncated(
63790
- config,
63791
- new ToolOutputTruncatedEvent("", {
63792
- toolName,
63793
- originalContentLength: originalLength,
63794
- truncatedContentLength: result.content.length,
63795
- threshold,
63796
- lines
63797
- })
63798
- );
63830
+ try {
63831
+ logToolOutputTruncated(
63832
+ config,
63833
+ new ToolOutputTruncatedEvent(promptId ?? "", {
63834
+ toolName,
63835
+ originalContentLength: originalLength,
63836
+ truncatedContentLength: result.content.length,
63837
+ threshold,
63838
+ lines
63839
+ })
63840
+ );
63841
+ } catch {
63842
+ }
63799
63843
  }
63800
63844
  return result;
63801
63845
  }
63802
63846
  __name(truncateToolOutput, "truncateToolOutput");
63847
+ async function truncateLlmContent(config, toolName, content, limits, promptId) {
63848
+ if (typeof content === "string") {
63849
+ if (content.trim() === "") {
63850
+ return { content: `(${toolName} completed with no output)` };
63851
+ }
63852
+ if (content.startsWith(TOOL_OUTPUT_TRUNCATED_PREFIX)) {
63853
+ return { content };
63854
+ }
63855
+ return truncateToolOutput(config, toolName, content, limits, promptId);
63856
+ }
63857
+ const parts = (Array.isArray(content) ? content : [content]).map(
63858
+ (p) => typeof p === "string" ? { text: p } : p
63859
+ );
63860
+ const textParts = parts.filter((p) => p.text !== void 0);
63861
+ const mediaParts = parts.filter((p) => p.text === void 0);
63862
+ const combined = textParts.map((p) => p.text).join("\n");
63863
+ if (combined.trim() === "" && mediaParts.length === 0) {
63864
+ return { content: `(${toolName} completed with no output)` };
63865
+ }
63866
+ if (textParts.some((p) => p.text?.startsWith(TOOL_OUTPUT_TRUNCATED_PREFIX))) {
63867
+ return { content };
63868
+ }
63869
+ const result = await truncateToolOutput(
63870
+ config,
63871
+ toolName,
63872
+ combined,
63873
+ limits,
63874
+ promptId
63875
+ );
63876
+ if (result.content === combined) {
63877
+ return { content };
63878
+ }
63879
+ return {
63880
+ content: [{ text: result.content }, ...mediaParts],
63881
+ outputFile: result.outputFile
63882
+ };
63883
+ }
63884
+ __name(truncateLlmContent, "truncateLlmContent");
63885
+ function isAlreadyTruncated(content) {
63886
+ return content.includes("... [CONTENT TRUNCATED] ...") || content.startsWith("<persisted-output>");
63887
+ }
63888
+ __name(isAlreadyTruncated, "isAlreadyTruncated");
63889
+ function generatePreview(content) {
63890
+ let text = content.length <= PREVIEW_SIZE_CHARS ? content : (() => {
63891
+ const slice = content.slice(0, PREVIEW_SIZE_CHARS);
63892
+ const lastNewline = slice.lastIndexOf("\n");
63893
+ return (lastNewline > 0 ? slice.slice(0, lastNewline) : slice) + "\n...";
63894
+ })();
63895
+ text = text.replace(/<\/?persisted-output>/g, (m) => `&lt;${m.slice(1, -1)}&gt;`).replace(/<\/?system-reminder>/g, (m) => `&lt;${m.slice(1, -1)}&gt;`);
63896
+ return text;
63897
+ }
63898
+ __name(generatePreview, "generatePreview");
63899
+ async function persistAndTruncateToolResult(callId, toolName, content, config) {
63900
+ const byteSize = Buffer.byteLength(content, "utf-8");
63901
+ if (byteSize > MAX_FILE_SIZE_BYTES) {
63902
+ debugLogger3.warn(
63903
+ `Tool result for ${toolName} exceeds ${MAX_FILE_SIZE_BYTES} bytes (${byteSize}), skipping disk persistence`
63904
+ );
63905
+ return {
63906
+ content: buildStub(content, byteSize, "(file too large to persist)"),
63907
+ bytesWritten: 0
63908
+ };
63909
+ }
63910
+ const budgetUsed = config.getToolResultBytesWritten();
63911
+ if (budgetUsed + byteSize > MAX_SESSION_BYTES) {
63912
+ debugLogger3.warn(
63913
+ `Session tool result budget exhausted (${budgetUsed} + ${byteSize} > ${MAX_SESSION_BYTES}), skipping disk persistence`
63914
+ );
63915
+ return {
63916
+ content: buildStub(
63917
+ content,
63918
+ byteSize,
63919
+ "(session disk budget exhausted)"
63920
+ ),
63921
+ bytesWritten: 0
63922
+ };
63923
+ }
63924
+ config.trackToolResultBytes(byteSize);
63925
+ const safeCallId = path4.basename(callId).replace(/\x00/g, "_");
63926
+ if (!safeCallId || safeCallId === "." || safeCallId === "..") {
63927
+ debugLogger3.warn(`Invalid callId for disk persistence: ${JSON.stringify(callId)}`);
63928
+ config.trackToolResultBytes(-byteSize);
63929
+ return {
63930
+ content: buildStub(content, byteSize, "(invalid callId)"),
63931
+ bytesWritten: 0
63932
+ };
63933
+ }
63934
+ const toolResultsDir = config.storage.getToolResultsDir();
63935
+ const outputFile = path4.join(toolResultsDir, `${safeCallId}.txt`);
63936
+ try {
63937
+ await fs3.mkdir(toolResultsDir, { recursive: true });
63938
+ await atomicWriteFile(outputFile, content, {
63939
+ mode: 384,
63940
+ forceMode: true,
63941
+ noFollow: true,
63942
+ flush: false
63943
+ });
63944
+ return {
63945
+ content: buildStub(content, byteSize, outputFile),
63946
+ outputFile,
63947
+ bytesWritten: byteSize
63948
+ };
63949
+ } catch (error) {
63950
+ config.trackToolResultBytes(-byteSize);
63951
+ debugLogger3.warn(
63952
+ `Failed to persist tool result to ${outputFile}:`,
63953
+ error
63954
+ );
63955
+ try {
63956
+ const fallback = await truncateAndSaveToFile(
63957
+ content,
63958
+ `${toolName}_${crypto2.randomBytes(6).toString("hex")}`,
63959
+ config.storage.getProjectTempDir(),
63960
+ config.getTruncateToolOutputThreshold(),
63961
+ config.getTruncateToolOutputLines()
63962
+ );
63963
+ return { content: fallback.content, bytesWritten: 0 };
63964
+ } catch (fallbackError) {
63965
+ debugLogger3.warn("Fallback truncation also failed:", fallbackError);
63966
+ return {
63967
+ content: buildStub(content, byteSize, "(disk persistence unavailable)"),
63968
+ bytesWritten: 0
63969
+ };
63970
+ }
63971
+ }
63972
+ }
63973
+ __name(persistAndTruncateToolResult, "persistAndTruncateToolResult");
63974
+ function buildStub(content, byteSize, filePathOrNote) {
63975
+ const preview = generatePreview(content);
63976
+ const sizeKb = Math.round(byteSize / 1024);
63977
+ const isFilePath = path4.isAbsolute(filePathOrNote);
63978
+ if (isFilePath) {
63979
+ return `<persisted-output>
63980
+ Output too large (${sizeKb} KB). Full output saved to: ${filePathOrNote}
63981
+ Note: this file may be cleaned up after 24 hours.
63982
+ To read the complete output, use the ${ReadFileTool.Name} tool with the absolute file path above.
63983
+
63984
+ Preview (up to ${PREVIEW_SIZE_CHARS} chars):
63985
+ ${preview}
63986
+ </persisted-output>`;
63987
+ }
63988
+ return `Output too large (${sizeKb} KB). ${filePathOrNote}
63989
+
63990
+ Preview (up to ${PREVIEW_SIZE_CHARS} chars):
63991
+ ${preview}`;
63992
+ }
63993
+ __name(buildStub, "buildStub");
63803
63994
 
63804
63995
  // packages/core/src/tools/mcp-tool.ts
63805
- var debugLogger3 = createDebugLogger("MCP_TOOL");
63996
+ var debugLogger4 = createDebugLogger("MCP_TOOL");
63806
63997
  var DiscoveredMCPToolInvocation = class _DiscoveredMCPToolInvocation extends BaseToolInvocation {
63807
63998
  constructor(mcpTool, serverName, serverToolName, displayName, trust, params = {}, cliConfig, mcpClient, mcpTimeout, annotations, retryCount = 0) {
63808
63999
  super(params);
@@ -63853,8 +64044,7 @@ var DiscoveredMCPToolInvocation = class _DiscoveredMCPToolInvocation extends Bas
63853
64044
  };
63854
64045
  return confirmationDetails;
63855
64046
  }
63856
- // Determine if the response contains tool errors
63857
- // This is needed because CallToolResults should return errors inside the response.
64047
+ // MCP spec: errors are returned inside the CallToolResult, not as exceptions.
63858
64048
  // ref: https://modelcontextprotocol.io/specification/2025-06-18/schema#calltoolresult
63859
64049
  isMCPToolError(rawResponseParts) {
63860
64050
  const functionResponse = rawResponseParts?.[0]?.functionResponse;
@@ -63873,7 +64063,7 @@ var DiscoveredMCPToolInvocation = class _DiscoveredMCPToolInvocation extends Bas
63873
64063
  return null;
63874
64064
  }
63875
64065
  try {
63876
- debugLogger3.info(
64066
+ debugLogger4.info(
63877
64067
  `Attempting to reconnect MCP server '${this.serverName}'...`
63878
64068
  );
63879
64069
  const toolRegistry = this.cliConfig.getToolRegistry();
@@ -63882,23 +64072,23 @@ var DiscoveredMCPToolInvocation = class _DiscoveredMCPToolInvocation extends Bas
63882
64072
  `mcp__${this.serverName}__${this.serverToolName}`
63883
64073
  );
63884
64074
  if (newTool instanceof DiscoveredMCPTool) {
63885
- debugLogger3.info(
64075
+ debugLogger4.info(
63886
64076
  `Successfully reconnected to MCP server '${this.serverName}'`
63887
64077
  );
63888
64078
  return newTool;
63889
64079
  }
63890
64080
  return null;
63891
64081
  } catch (error) {
63892
- debugLogger3.error(
64082
+ debugLogger4.error(
63893
64083
  `Failed to reconnect MCP server '${this.serverName}': ${error}`
63894
64084
  );
63895
64085
  return null;
63896
64086
  }
63897
64087
  }
63898
64088
  async handleReconnectOnError(error, signal, updateOutput) {
63899
- debugLogger3.error(`MCP server error '${this.serverName}': ${error}`);
64089
+ debugLogger4.error(`MCP server error '${this.serverName}': ${error}`);
63900
64090
  if (this.retryCount < _DiscoveredMCPToolInvocation.MAX_RECONNECT_RETRIES) {
63901
- debugLogger3.info(
64091
+ debugLogger4.info(
63902
64092
  `Reconnection attempt ${this.retryCount + 1}/${_DiscoveredMCPToolInvocation.MAX_RECONNECT_RETRIES} for MCP server '${this.serverName}'`
63903
64093
  );
63904
64094
  const newTool = await this.attemptReconnect();
@@ -63919,7 +64109,7 @@ var DiscoveredMCPToolInvocation = class _DiscoveredMCPToolInvocation extends Bas
63919
64109
  return newInvocation.execute(signal, updateOutput);
63920
64110
  }
63921
64111
  } else if (this.retryCount >= _DiscoveredMCPToolInvocation.MAX_RECONNECT_RETRIES) {
63922
- debugLogger3.error(
64112
+ debugLogger4.error(
63923
64113
  `Max reconnection attempts (${_DiscoveredMCPToolInvocation.MAX_RECONNECT_RETRIES}) reached for MCP server '${this.serverName}'`
63924
64114
  );
63925
64115
  }
@@ -63966,15 +64156,15 @@ var DiscoveredMCPToolInvocation = class _DiscoveredMCPToolInvocation extends Bas
63966
64156
  callToolResult
63967
64157
  );
63968
64158
  if (this.isMCPToolError(rawResponseParts)) {
63969
- const errorMessage = `MCP tool '${this.serverToolName}' reported tool error for function call: ${safeJsonStringify({
64159
+ const errorMessage2 = `MCP tool '${this.serverToolName}' reported tool error for function call: ${safeJsonStringify({
63970
64160
  name: this.serverToolName,
63971
64161
  args: this.params
63972
64162
  })} with response: ${safeJsonStringify(rawResponseParts)}`;
63973
64163
  return {
63974
- llmContent: errorMessage,
64164
+ llmContent: errorMessage2,
63975
64165
  returnDisplay: `Error: MCP tool '${this.serverToolName}' reported an error.`,
63976
64166
  error: {
63977
- message: errorMessage,
64167
+ message: errorMessage2,
63978
64168
  type: "mcp_tool_error" /* MCP_TOOL_ERROR */
63979
64169
  }
63980
64170
  };
@@ -64027,14 +64217,14 @@ var DiscoveredMCPToolInvocation = class _DiscoveredMCPToolInvocation extends Bas
64027
64217
  });
64028
64218
  });
64029
64219
  if (this.isMCPToolError(rawResponseParts)) {
64030
- const errorMessage = `MCP tool '${this.serverToolName}' reported tool error for function call: ${safeJsonStringify(
64220
+ const errorMessage2 = `MCP tool '${this.serverToolName}' reported tool error for function call: ${safeJsonStringify(
64031
64221
  functionCalls[0]
64032
64222
  )} with response: ${safeJsonStringify(rawResponseParts)}`;
64033
64223
  return {
64034
- llmContent: errorMessage,
64224
+ llmContent: errorMessage2,
64035
64225
  returnDisplay: `Error: MCP tool '${this.serverToolName}' reported an error.`,
64036
64226
  error: {
64037
- message: errorMessage,
64227
+ message: errorMessage2,
64038
64228
  type: "mcp_tool_error" /* MCP_TOOL_ERROR */
64039
64229
  }
64040
64230
  };
@@ -64063,7 +64253,14 @@ var DiscoveredMCPToolInvocation = class _DiscoveredMCPToolInvocation extends Bas
64063
64253
  const truncated = await truncateToolOutput(
64064
64254
  this.cliConfig,
64065
64255
  `mcp__${this.serverName}__${this.serverToolName}`,
64066
- part.text
64256
+ part.text,
64257
+ // Per-tool char budget; mirrors DiscoveredMCPTool.maxOutputChars
64258
+ // (10x the global default, since MCP servers return large structured
64259
+ // output). char-only (lines: Infinity) so the global line cap can't
64260
+ // undercut the 500k char budget — many short lines (structured JSON,
64261
+ // tables) would otherwise truncate while chars remain. Consistent
64262
+ // with the shell tool's in-tool truncation.
64263
+ { threshold: 5e5, lines: Number.POSITIVE_INFINITY }
64067
64264
  );
64068
64265
  result.push({ text: truncated.content });
64069
64266
  } else {
@@ -64110,6 +64307,12 @@ var DiscoveredMCPTool = class _DiscoveredMCPTool extends BaseDeclarativeTool {
64110
64307
  static {
64111
64308
  __name(this, "DiscoveredMCPTool");
64112
64309
  }
64310
+ // MCP servers often return large structured payloads; allow 10x the global
64311
+ // budget (mirrors Claude Code's MCP `maxResultSizeChars`) before the
64312
+ // scheduler offloads. truncateTextParts uses the same ceiling per text part.
64313
+ get maxOutputChars() {
64314
+ return 5e5;
64315
+ }
64113
64316
  asFullyQualifiedTool() {
64114
64317
  return new _DiscoveredMCPTool(
64115
64318
  this.mcpTool,
@@ -64125,6 +64328,40 @@ var DiscoveredMCPTool = class _DiscoveredMCPTool extends BaseDeclarativeTool {
64125
64328
  this.annotations
64126
64329
  );
64127
64330
  }
64331
+ /**
64332
+ * Return a clone of this tool with a different `trust` value while
64333
+ * keeping every other field (including the shared underlying
64334
+ * `CallableTool` / MCP transport) identical.
64335
+ *
64336
+ * pool path: a single shared pool entry produces one
64337
+ * `DiscoveredMCPTool` snapshot; each `SessionMcpView` clones with
64338
+ * its own per-session trust before registering into its session's
64339
+ * `ToolRegistry`. Without this clone, mutating `trust` on the shared
64340
+ * instance would cross-contaminate sessions.
64341
+ *
64342
+ * Trust is the only field that legitimately varies per session;
64343
+ * everything else (transport, schema, name) is transport-level.
64344
+ */
64345
+ withTrust(trust) {
64346
+ if (trust === this.trust) return this;
64347
+ return new _DiscoveredMCPTool(
64348
+ this.mcpTool,
64349
+ this.serverName,
64350
+ this.serverToolName,
64351
+ this.description,
64352
+ this.parameterSchema,
64353
+ trust,
64354
+ // Preserve the original name (do NOT re-call generateValidName)
64355
+ // — equal-by-name is the registry's deduplication key, and a
64356
+ // different name would race-register two tools in the same
64357
+ // session.
64358
+ this.name,
64359
+ this.cliConfig,
64360
+ this.mcpClient,
64361
+ this.mcpTimeout,
64362
+ this.annotations
64363
+ );
64364
+ }
64128
64365
  createInvocation(params) {
64129
64366
  return new DiscoveredMCPToolInvocation(
64130
64367
  this.mcpTool,
@@ -65289,7 +65526,7 @@ init_esbuild_shims();
65289
65526
 
65290
65527
  // packages/core/src/core/openaiContentGenerator/taggedThinkingParser.ts
65291
65528
  init_esbuild_shims();
65292
- var debugLogger4 = createDebugLogger("TAGGED_THINKING_PARSER");
65529
+ var debugLogger5 = createDebugLogger("TAGGED_THINKING_PARSER");
65293
65530
  var OPEN_TAGS = ["<think>", "<thinking>"];
65294
65531
  var CLOSE_TAGS = ["</think>", "</thinking>"];
65295
65532
  var MAX_TAG_LENGTH = Math.max(
@@ -65330,7 +65567,7 @@ var TaggedThinkingParser = class {
65330
65567
  const activeTags = this.mode === "text" ? OPEN_TAGS : CLOSE_TAGS;
65331
65568
  const matchedTag = findMatchingTag(lower, index, activeTags);
65332
65569
  if (matchedTag) {
65333
- debugLogger4.debug(
65570
+ debugLogger5.debug(
65334
65571
  `taggedThinking: detected tag "${matchedTag}" at offset ${index}`
65335
65572
  );
65336
65573
  appendPart(parts, segment, this.mode);
@@ -65348,19 +65585,19 @@ var TaggedThinkingParser = class {
65348
65585
  if (index < this.buffer.length) {
65349
65586
  appendPart(parts, segment, this.mode);
65350
65587
  this.buffer = this.buffer.slice(index);
65351
- debugLogger4.debug(
65588
+ debugLogger5.debug(
65352
65589
  `taggedThinking: emitted ${parts.length} part(s), buffered ${this.buffer.length} char(s)`
65353
65590
  );
65354
65591
  return parts;
65355
65592
  }
65356
65593
  this.buffer = "";
65357
65594
  if (this.mode === "thought" && segment) {
65358
- debugLogger4.warn(
65595
+ debugLogger5.warn(
65359
65596
  `taggedThinking: flushing ${segment.length} chars of unclosed thought on stream end`
65360
65597
  );
65361
65598
  }
65362
65599
  appendPart(parts, segment, this.mode);
65363
- debugLogger4.debug(
65600
+ debugLogger5.debug(
65364
65601
  `taggedThinking: emitted ${parts.length} part(s), flush complete`
65365
65602
  );
65366
65603
  return parts;
@@ -65372,7 +65609,7 @@ function parseTaggedThinkingText(text) {
65372
65609
  __name(parseTaggedThinkingText, "parseTaggedThinkingText");
65373
65610
 
65374
65611
  // packages/core/src/core/openaiContentGenerator/converter.ts
65375
- var debugLogger5 = createDebugLogger("CONVERTER");
65612
+ var debugLogger6 = createDebugLogger("CONVERTER");
65376
65613
  var SPLIT_TOOL_MEDIA_TEXT = "(attached media from previous tool call)";
65377
65614
  var CUMULATIVE_DELTA_EXACT_REPEAT_MIN_LENGTH = 64;
65378
65615
  var CUMULATIVE_DETECTION_WINDOW_BYTES = 1024;
@@ -65393,12 +65630,12 @@ function normalizeStreamingTextDelta(rawDelta, state) {
65393
65630
  return suffix;
65394
65631
  }
65395
65632
  if (state.emittedText.startsWith(rawDelta)) {
65396
- debugLogger5.debug(
65633
+ debugLogger6.debug(
65397
65634
  `normalizeStreamingTextDelta: cumulative rewind suppression (emitted=${state.emittedText.length}b, chunk=${rawDelta.length}b)`
65398
65635
  );
65399
65636
  return "";
65400
65637
  }
65401
- debugLogger5.debug(
65638
+ debugLogger6.debug(
65402
65639
  "normalizeStreamingTextDelta: exiting cumulative mode (chunk does not match prior accumulated text)"
65403
65640
  );
65404
65641
  state.cumulativeMode = false;
@@ -65415,7 +65652,7 @@ function normalizeStreamingTextDelta(rawDelta, state) {
65415
65652
  state.emittedText = rawDelta;
65416
65653
  state.emittedLength = rawDelta.length;
65417
65654
  state.cumulativeMode = true;
65418
- debugLogger5.debug(
65655
+ debugLogger6.debug(
65419
65656
  `normalizeStreamingTextDelta: entered cumulative mode (prefix overlap, baseline=${baselineLen}b sliceFrom=${sliceFrom}b -> curr=${rawDelta.length}b)`
65420
65657
  );
65421
65658
  return suffix;
@@ -65424,7 +65661,7 @@ function normalizeStreamingTextDelta(rawDelta, state) {
65424
65661
  if (rawDelta === state.emittedText) {
65425
65662
  if (rawDelta.length >= CUMULATIVE_DELTA_EXACT_REPEAT_MIN_LENGTH) {
65426
65663
  state.cumulativeMode = true;
65427
- debugLogger5.debug(
65664
+ debugLogger6.debug(
65428
65665
  `normalizeStreamingTextDelta: entered cumulative mode (exact repeat, ${rawDelta.length}b)`
65429
65666
  );
65430
65667
  return "";
@@ -65644,6 +65881,8 @@ function processContent(content, messages, requestContext) {
65644
65881
  const reasoningParts = [];
65645
65882
  const toolCalls = [];
65646
65883
  let toolCallIndex = 0;
65884
+ const emittedFunctionCallIds = /* @__PURE__ */ new Set();
65885
+ const emittedFunctionResponseIds = /* @__PURE__ */ new Set();
65647
65886
  const accumulatedSplitMedia = [];
65648
65887
  for (const part of parts) {
65649
65888
  if (typeof part === "string") {
@@ -65663,8 +65902,18 @@ function processContent(content, messages, requestContext) {
65663
65902
  contentParts.push(mediaPart);
65664
65903
  }
65665
65904
  if ("functionCall" in part && part.functionCall && role === "assistant") {
65905
+ const callId = part.functionCall.id;
65906
+ if (callId) {
65907
+ if (emittedFunctionCallIds.has(callId)) {
65908
+ debugLogger6.debug(
65909
+ `Dropping duplicate functionCall id=${callId} while converting content`
65910
+ );
65911
+ continue;
65912
+ }
65913
+ emittedFunctionCallIds.add(callId);
65914
+ }
65666
65915
  toolCalls.push({
65667
- id: part.functionCall.id || `call_${toolCallIndex}`,
65916
+ id: callId || `call_${toolCallIndex}`,
65668
65917
  type: "function",
65669
65918
  function: {
65670
65919
  name: part.functionCall.name || "",
@@ -65674,6 +65923,13 @@ function processContent(content, messages, requestContext) {
65674
65923
  toolCallIndex += 1;
65675
65924
  }
65676
65925
  if (part.functionResponse && role === "user") {
65926
+ const responseId = part.functionResponse.id;
65927
+ if (responseId) {
65928
+ if (emittedFunctionResponseIds.has(responseId)) {
65929
+ continue;
65930
+ }
65931
+ emittedFunctionResponseIds.add(responseId);
65932
+ }
65677
65933
  const toolMessage = createToolMessage(
65678
65934
  part.functionResponse,
65679
65935
  requestContext
@@ -65933,7 +66189,7 @@ function createMediaContentPart(part, requestContext) {
65933
66189
  }
65934
66190
  __name(createMediaContentPart, "createMediaContentPart");
65935
66191
  function unsupportedModalityPlaceholder(modality, displayName, requestContext) {
65936
- debugLogger5.warn(
66192
+ debugLogger6.warn(
65937
66193
  `Model '${requestContext.model}' does not support ${modality} input. Replacing with text placeholder: ${displayName}`
65938
66194
  );
65939
66195
  let hint;
@@ -66257,16 +66513,27 @@ function isSplitToolMediaMessage(message) {
66257
66513
  __name(isSplitToolMediaMessage, "isSplitToolMediaMessage");
66258
66514
  function cleanOrphanedToolCalls(messages) {
66259
66515
  const cleaned = [];
66260
- const adjacentToolResponseIdsByAssistant = /* @__PURE__ */ new Map();
66516
+ const validToolCallsByAssistant = /* @__PURE__ */ new Map();
66261
66517
  const validToolResponseIndexesByAssistant = /* @__PURE__ */ new Map();
66262
66518
  const splitMediaIndexesByAssistant = /* @__PURE__ */ new Map();
66263
66519
  const emittedWithAssistant = /* @__PURE__ */ new Set();
66520
+ const survivingToolCallIds = /* @__PURE__ */ new Set();
66264
66521
  for (let index = 0; index < messages.length; index += 1) {
66265
66522
  const message = messages[index];
66266
66523
  if (hasToolCalls(message)) {
66267
- const toolCallIds = new Set(
66268
- message.tool_calls.map((toolCall) => toolCall.id).filter((id) => Boolean(id))
66269
- );
66524
+ const candidateToolCalls = [];
66525
+ const candidateToolCallIds = /* @__PURE__ */ new Set();
66526
+ for (const toolCall of message.tool_calls) {
66527
+ const id = toolCall.id;
66528
+ if (!id || survivingToolCallIds.has(id)) {
66529
+ continue;
66530
+ }
66531
+ if (candidateToolCallIds.has(id)) {
66532
+ continue;
66533
+ }
66534
+ candidateToolCallIds.add(id);
66535
+ candidateToolCalls.push(toolCall);
66536
+ }
66270
66537
  const adjacentToolResponseIds = /* @__PURE__ */ new Set();
66271
66538
  const toolResponseIndexes = [];
66272
66539
  const splitMediaIndexes = [];
@@ -66278,7 +66545,7 @@ function cleanOrphanedToolCalls(messages) {
66278
66545
  lastToolResponseMatchesAssistant = false;
66279
66546
  continue;
66280
66547
  }
66281
- if (toolCallIds.has(nextMessage.tool_call_id)) {
66548
+ if (candidateToolCallIds.has(nextMessage.tool_call_id) && !adjacentToolResponseIds.has(nextMessage.tool_call_id)) {
66282
66549
  adjacentToolResponseIds.add(nextMessage.tool_call_id);
66283
66550
  toolResponseIndexes.push(nextIndex);
66284
66551
  lastToolResponseMatchesAssistant = true;
@@ -66298,7 +66565,13 @@ function cleanOrphanedToolCalls(messages) {
66298
66565
  }
66299
66566
  break;
66300
66567
  }
66301
- adjacentToolResponseIdsByAssistant.set(index, adjacentToolResponseIds);
66568
+ const validToolCalls = candidateToolCalls.filter(
66569
+ (toolCall) => adjacentToolResponseIds.has(toolCall.id)
66570
+ );
66571
+ for (const toolCall of validToolCalls) {
66572
+ survivingToolCallIds.add(toolCall.id);
66573
+ }
66574
+ validToolCallsByAssistant.set(index, validToolCalls);
66302
66575
  validToolResponseIndexesByAssistant.set(index, toolResponseIndexes);
66303
66576
  splitMediaIndexesByAssistant.set(index, splitMediaIndexes);
66304
66577
  }
@@ -66310,10 +66583,7 @@ function cleanOrphanedToolCalls(messages) {
66310
66583
  const message = messages[index];
66311
66584
  if (hasToolCalls(message)) {
66312
66585
  const reasoningContent = message.reasoning_content;
66313
- const adjacentToolResponseIds = adjacentToolResponseIdsByAssistant.get(index) ?? /* @__PURE__ */ new Set();
66314
- const validToolCalls = message.tool_calls.filter(
66315
- (toolCall) => toolCall.id && adjacentToolResponseIds.has(toolCall.id)
66316
- );
66586
+ const validToolCalls = validToolCallsByAssistant.get(index) ?? [];
66317
66587
  if (validToolCalls.length > 0) {
66318
66588
  const cleanedMessage = { ...message };
66319
66589
  cleanedMessage.tool_calls = validToolCalls;
@@ -66339,16 +66609,16 @@ function cleanOrphanedToolCalls(messages) {
66339
66609
  delete cleanedMessage.tool_calls;
66340
66610
  cleaned.push(cleanedMessage);
66341
66611
  } else {
66342
- debugLogger5.debug(
66612
+ debugLogger6.debug(
66343
66613
  `cleanOrphanedToolCalls: dropping assistant with ${message.tool_calls.length} orphaned tool call(s) and no text/reasoning content`
66344
66614
  );
66345
66615
  }
66346
66616
  } else if (message.role === "tool" && "tool_call_id" in message) {
66347
- debugLogger5.debug(
66617
+ debugLogger6.debug(
66348
66618
  `cleanOrphanedToolCalls: dropping orphaned tool response ${message.tool_call_id || "<empty>"}`
66349
66619
  );
66350
66620
  } else if (isSplitToolMediaMessage(message)) {
66351
- debugLogger5.debug(
66621
+ debugLogger6.debug(
66352
66622
  "cleanOrphanedToolCalls: dropping orphaned split tool media message"
66353
66623
  );
66354
66624
  } else {
@@ -66476,7 +66746,7 @@ var v4_default = v4;
66476
66746
 
66477
66747
  // packages/core/src/utils/openaiLogger.ts
66478
66748
  import * as os2 from "os";
66479
- var debugLogger6 = createDebugLogger("OPENAI_LOGGER");
66749
+ var debugLogger7 = createDebugLogger("OPENAI_LOGGER");
66480
66750
  var MAIN_SESSION_PROMPT_ID_DELIMITER = "########";
66481
66751
  var UUID_PATTERN = /^[0-9a-f]{8}-[0-9a-f]{4}-[1-5][0-9a-f]{3}-[89ab][0-9a-f]{3}-[0-9a-f]{12}$/i;
66482
66752
  function resolveOpenAILogDir(customLogDir, cwd) {
@@ -66572,7 +66842,7 @@ var OpenAILogger = class {
66572
66842
  await fs4.mkdir(this.logDir, { recursive: true });
66573
66843
  this.initialized = true;
66574
66844
  } catch (error) {
66575
- debugLogger6.error("Failed to initialize OpenAI logger:", error);
66845
+ debugLogger7.error("Failed to initialize OpenAI logger:", error);
66576
66846
  throw new Error(`Failed to initialize OpenAI logger: ${error}`);
66577
66847
  }
66578
66848
  }
@@ -66614,7 +66884,7 @@ var OpenAILogger = class {
66614
66884
  await fs4.writeFile(filePath, JSON.stringify(logData, null, 2), "utf-8");
66615
66885
  return filePath;
66616
66886
  } catch (writeError) {
66617
- debugLogger6.error("Failed to write OpenAI log file:", writeError);
66887
+ debugLogger7.error("Failed to write OpenAI log file:", writeError);
66618
66888
  throw new Error(`Failed to write OpenAI log file: ${writeError}`);
66619
66889
  }
66620
66890
  }
@@ -66635,7 +66905,7 @@ var OpenAILogger = class {
66635
66905
  if (error.code === "ENOENT") {
66636
66906
  return [];
66637
66907
  }
66638
- debugLogger6.error("Failed to read OpenAI log directory:", error);
66908
+ debugLogger7.error("Failed to read OpenAI log directory:", error);
66639
66909
  return [];
66640
66910
  }
66641
66911
  }
@@ -66649,7 +66919,7 @@ var OpenAILogger = class {
66649
66919
  const content = await fs4.readFile(filePath, "utf-8");
66650
66920
  return JSON.parse(content);
66651
66921
  } catch (error) {
66652
- debugLogger6.error(`Failed to read log file ${filePath}:`, error);
66922
+ debugLogger7.error(`Failed to read log file ${filePath}:`, error);
66653
66923
  throw new Error(`Failed to read log file: ${error}`);
66654
66924
  }
66655
66925
  }
@@ -66718,8 +66988,8 @@ var FileLogExporter = class extends FileExporter {
66718
66988
  static {
66719
66989
  __name(this, "FileLogExporter");
66720
66990
  }
66721
- export(logs2, resultCallback) {
66722
- const data = logs2.map((log) => this.serialize(log)).join("");
66991
+ export(logs3, resultCallback) {
66992
+ const data = logs3.map((log) => this.serialize(log)).join("");
66723
66993
  this.writeStream.write(data, (err) => {
66724
66994
  resultCallback({
66725
66995
  code: err ? import_core3.ExportResultCode.FAILED : import_core3.ExportResultCode.SUCCESS,
@@ -66921,16 +67191,12 @@ function clearDetailedSpanState() {
66921
67191
  __name(clearDetailedSpanState, "clearDetailedSpanState");
66922
67192
 
66923
67193
  // packages/core/src/telemetry/session-tracing.ts
66924
- var debugLogger7 = createDebugLogger("SESSION_TRACING");
67194
+ var debugLogger8 = createDebugLogger("SESSION_TRACING");
66925
67195
  function resolveParentContext(parent) {
66926
67196
  if (parent) {
66927
67197
  return trace.setSpan(context.active(), parent.span);
66928
67198
  }
66929
- const active = context.active();
66930
- if (trace.getSpan(active)) {
66931
- return active;
66932
- }
66933
- return getSessionContext() ?? active;
67199
+ return context.active();
66934
67200
  }
66935
67201
  __name(resolveParentContext, "resolveParentContext");
66936
67202
  var NOOP_SPAN = trace.wrapSpanContext({
@@ -66946,6 +67212,11 @@ function isInNativeSubagentSpan() {
66946
67212
  return ctx !== void 0 && !ctx.ended;
66947
67213
  }
66948
67214
  __name(isInNativeSubagentSpan, "isInNativeSubagentSpan");
67215
+ function resolveSessionId(parentCtx) {
67216
+ const fromParent = parentCtx?.attributes?.["session.id"];
67217
+ return typeof fromParent === "string" && fromParent ? fromParent : getCurrentSessionId();
67218
+ }
67219
+ __name(resolveSessionId, "resolveSessionId");
66949
67220
  var activeSpans = /* @__PURE__ */ new Map();
66950
67221
  var strongSpans = /* @__PURE__ */ new Map();
66951
67222
  var interactionSequence = 0;
@@ -67001,18 +67272,18 @@ function sweepStaleSpans(now) {
67001
67272
  } : {}
67002
67273
  });
67003
67274
  } catch (error) {
67004
- debugLogger7.warn(
67275
+ debugLogger8.warn(
67005
67276
  `Failed to stamp TTL attrs on stale span ${spanId}: ${error instanceof Error ? error.message : String(error)}`
67006
67277
  );
67007
67278
  }
67008
67279
  const ctxLabel = toolName && callId ? `${ctx.type} (tool.name=${toolName}, tool.call_id=${callId})` : ctx.type;
67009
- debugLogger7.warn(
67280
+ debugLogger8.warn(
67010
67281
  `Stale ${ctxLabel} span ended by TTL safety net (age=${ageMs}ms, spanId=${spanId})`
67011
67282
  );
67012
67283
  try {
67013
67284
  ctx.span.end();
67014
67285
  } catch (error) {
67015
- debugLogger7.warn(
67286
+ debugLogger8.warn(
67016
67287
  `Failed to end stale span ${spanId}: ${error instanceof Error ? error.message : String(error)}`
67017
67288
  );
67018
67289
  }
@@ -67060,11 +67331,10 @@ function startInteractionSpan(config, options) {
67060
67331
  "qwen-code.approval_mode": config.getApprovalMode(),
67061
67332
  "interaction.sequence": interactionSequence
67062
67333
  };
67063
- const sessionCtx = getSessionContext() ?? context.active();
67064
67334
  const span = getTracer().startSpan(
67065
67335
  SPAN_INTERACTION,
67066
67336
  { kind: SpanKind.INTERNAL, attributes },
67067
- sessionCtx
67337
+ ROOT_CONTEXT
67068
67338
  );
67069
67339
  const spanId = getSpanId(span);
67070
67340
  const spanContextObj = {
@@ -67083,7 +67353,7 @@ function endInteractionSpan(status, metadata) {
67083
67353
  const spanCtx = interactionContext.getStore() ?? lastInteractionCtx;
67084
67354
  if (!spanCtx) return;
67085
67355
  if (spanCtx.ended) {
67086
- debugLogger7.debug(
67356
+ debugLogger8.debug(
67087
67357
  `endInteractionSpan: span ${getSpanId(spanCtx.span)} already ended (possible TTL sweep race)`
67088
67358
  );
67089
67359
  return;
@@ -67110,13 +67380,90 @@ function endInteractionSpan(status, metadata) {
67110
67380
  interactionContext.enterWith(void 0);
67111
67381
  }
67112
67382
  __name(endInteractionSpan, "endInteractionSpan");
67383
+ async function withInteractionSpan(config, options, fn, getResultStatus) {
67384
+ if (!isTelemetrySdkInitialized()) return await fn();
67385
+ ensureCleanupInterval();
67386
+ interactionSequence++;
67387
+ const attributes = {
67388
+ "session.id": config.getSessionId(),
67389
+ "qwen-code.prompt_id": options.promptId,
67390
+ "qwen-code.message_type": options.messageType,
67391
+ "qwen-code.model": options.model,
67392
+ "qwen-code.approval_mode": config.getApprovalMode(),
67393
+ "interaction.sequence": interactionSequence
67394
+ };
67395
+ const parentContext = options.parentContext ?? ROOT_CONTEXT;
67396
+ const span = getTracer().startSpan(
67397
+ SPAN_INTERACTION,
67398
+ {
67399
+ kind: SpanKind.INTERNAL,
67400
+ attributes
67401
+ },
67402
+ parentContext
67403
+ );
67404
+ const spanId = getSpanId(span);
67405
+ const spanContextObj = {
67406
+ span,
67407
+ startTime: Date.now(),
67408
+ attributes,
67409
+ type: "interaction"
67410
+ };
67411
+ activeSpans.set(spanId, new WeakRef(spanContextObj));
67412
+ strongSpans.set(spanId, spanContextObj);
67413
+ const activeContext = trace.setSpan(parentContext, span);
67414
+ return await context.with(
67415
+ activeContext,
67416
+ async () => interactionContext.run(spanContextObj, async () => {
67417
+ let terminalStatus = "ok";
67418
+ let errorStatusSet = false;
67419
+ try {
67420
+ const result = await fn();
67421
+ terminalStatus = getResultStatus?.(result) ?? "ok";
67422
+ return result;
67423
+ } catch (error) {
67424
+ terminalStatus = "error";
67425
+ span.setStatus({
67426
+ code: SpanStatusCode.ERROR,
67427
+ message: truncateSpanError(
67428
+ error instanceof Error ? error.message : String(error)
67429
+ )
67430
+ });
67431
+ errorStatusSet = true;
67432
+ throw error;
67433
+ } finally {
67434
+ if (!spanContextObj.ended) {
67435
+ spanContextObj.ended = true;
67436
+ const duration = Date.now() - spanContextObj.startTime;
67437
+ span.setAttributes({
67438
+ "interaction.duration_ms": duration,
67439
+ "qwen-code.turn_status": terminalStatus
67440
+ });
67441
+ if (terminalStatus === "ok") {
67442
+ span.setStatus({ code: SpanStatusCode.OK });
67443
+ } else if (terminalStatus === "error" && !errorStatusSet) {
67444
+ span.setStatus({
67445
+ code: SpanStatusCode.ERROR,
67446
+ message: "interaction error"
67447
+ });
67448
+ }
67449
+ span.end();
67450
+ activeSpans.delete(spanId);
67451
+ strongSpans.delete(spanId);
67452
+ }
67453
+ }
67454
+ })
67455
+ );
67456
+ }
67457
+ __name(withInteractionSpan, "withInteractionSpan");
67113
67458
  function startLLMRequestSpan(model, promptId) {
67114
67459
  if (!isTelemetrySdkInitialized()) {
67115
67460
  return NOOP_SPAN;
67116
67461
  }
67117
67462
  const parentCtx = subagentContext.getStore() ?? interactionContext.getStore();
67118
67463
  const ctx = resolveParentContext(parentCtx);
67464
+ const sessionId = resolveSessionId(parentCtx);
67119
67465
  const attributes = {
67466
+ ...sessionId ? { "session.id": sessionId } : {},
67120
67467
  "qwen-code.model": model,
67121
67468
  "qwen-code.prompt_id": promptId,
67122
67469
  "llm_request.context": subagentContext.getStore() ? "subagent" : interactionContext.getStore() ? "interaction" : "standalone",
@@ -67147,7 +67494,7 @@ function endLLMRequestSpan(span, metadata) {
67147
67494
  const spanCtx = activeSpans.get(spanId)?.deref();
67148
67495
  if (!spanCtx) return;
67149
67496
  if (spanCtx.ended) {
67150
- debugLogger7.debug(
67497
+ debugLogger8.debug(
67151
67498
  `endLLMRequestSpan: span ${spanId} already ended (possible TTL sweep race)`
67152
67499
  );
67153
67500
  return;
@@ -67192,6 +67539,30 @@ function endLLMRequestSpan(span, metadata) {
67192
67539
  endAttributes["success"] = metadata.success;
67193
67540
  if (metadata.error !== void 0)
67194
67541
  endAttributes["error"] = truncateSpanError(metadata.error);
67542
+ if (metadata.responseId !== void 0) {
67543
+ endAttributes["response_id"] = metadata.responseId;
67544
+ endAttributes["gen_ai.response.id"] = metadata.responseId;
67545
+ }
67546
+ if (metadata.finishReason !== void 0) {
67547
+ endAttributes["finish_reason"] = metadata.finishReason;
67548
+ endAttributes["gen_ai.response.finish_reasons"] = [
67549
+ metadata.finishReason
67550
+ ];
67551
+ }
67552
+ if (metadata.thoughtsTokenCount !== void 0) {
67553
+ endAttributes["thoughts_token_count"] = metadata.thoughtsTokenCount;
67554
+ endAttributes["gen_ai.usage.reasoning_tokens"] = metadata.thoughtsTokenCount;
67555
+ }
67556
+ if (metadata.subagentName !== void 0) {
67557
+ endAttributes["subagent_name"] = metadata.subagentName;
67558
+ }
67559
+ if (metadata.errorType !== void 0) {
67560
+ endAttributes["error_type"] = metadata.errorType;
67561
+ endAttributes["error.type"] = metadata.errorType;
67562
+ }
67563
+ if (metadata.errorStatusCode !== void 0) {
67564
+ endAttributes["error_status_code"] = metadata.errorStatusCode;
67565
+ }
67195
67566
  }
67196
67567
  spanCtx.span.setAttributes(endAttributes);
67197
67568
  if (metadata === void 0 || metadata.success) {
@@ -67203,14 +67574,14 @@ function endLLMRequestSpan(span, metadata) {
67203
67574
  });
67204
67575
  }
67205
67576
  } catch (error) {
67206
- debugLogger7.warn(
67577
+ debugLogger8.warn(
67207
67578
  `Failed to update LLM request span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67208
67579
  );
67209
67580
  }
67210
67581
  try {
67211
67582
  spanCtx.span.end();
67212
67583
  } catch (error) {
67213
- debugLogger7.warn(
67584
+ debugLogger8.warn(
67214
67585
  `Failed to end LLM request span: ${error instanceof Error ? error.message : String(error)}`
67215
67586
  );
67216
67587
  }
@@ -67224,7 +67595,9 @@ function startToolSpan(toolName, attrs) {
67224
67595
  }
67225
67596
  const parentCtx = subagentContext.getStore() ?? interactionContext.getStore();
67226
67597
  const ctx = resolveParentContext(parentCtx);
67598
+ const sessionId = resolveSessionId(parentCtx);
67227
67599
  const attributes = {
67600
+ ...sessionId ? { "session.id": sessionId } : {},
67228
67601
  "tool.name": toolName,
67229
67602
  ...attrs
67230
67603
  };
@@ -67258,7 +67631,7 @@ function endToolSpan(span, metadata) {
67258
67631
  const spanCtx = activeSpans.get(spanId)?.deref();
67259
67632
  if (!spanCtx) return;
67260
67633
  if (spanCtx.ended) {
67261
- debugLogger7.debug(
67634
+ debugLogger8.debug(
67262
67635
  `endToolSpan: span ${spanId} already ended (possible TTL sweep race)`
67263
67636
  );
67264
67637
  return;
@@ -67285,14 +67658,14 @@ function endToolSpan(span, metadata) {
67285
67658
  }
67286
67659
  }
67287
67660
  } catch (error) {
67288
- debugLogger7.warn(
67661
+ debugLogger8.warn(
67289
67662
  `Failed to update tool span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67290
67663
  );
67291
67664
  }
67292
67665
  try {
67293
67666
  spanCtx.span.end();
67294
67667
  } catch (error) {
67295
- debugLogger7.warn(
67668
+ debugLogger8.warn(
67296
67669
  `Failed to end tool span: ${error instanceof Error ? error.message : String(error)}`
67297
67670
  );
67298
67671
  }
@@ -67306,21 +67679,27 @@ function startToolExecutionSpan() {
67306
67679
  }
67307
67680
  const parentCtx = toolContext.getStore();
67308
67681
  if (!parentCtx) {
67309
- debugLogger7.warn(
67682
+ debugLogger8.warn(
67310
67683
  "startToolExecutionSpan called outside runInToolSpanContext \u2014 span will not be parented to tool span"
67311
67684
  );
67312
67685
  }
67313
67686
  const ctx = resolveParentContext(parentCtx);
67687
+ const sessionId = resolveSessionId(
67688
+ parentCtx ?? interactionContext.getStore()
67689
+ );
67314
67690
  const span = getTracer().startSpan(
67315
67691
  SPAN_TOOL_EXECUTION,
67316
- { kind: SpanKind.INTERNAL },
67692
+ {
67693
+ kind: SpanKind.INTERNAL,
67694
+ attributes: sessionId ? { "session.id": sessionId } : {}
67695
+ },
67317
67696
  ctx
67318
67697
  );
67319
67698
  const spanId = getSpanId(span);
67320
67699
  const spanContextObj = {
67321
67700
  span,
67322
67701
  startTime: Date.now(),
67323
- attributes: {},
67702
+ attributes: sessionId ? { "session.id": sessionId } : {},
67324
67703
  type: "tool.execution"
67325
67704
  };
67326
67705
  activeSpans.set(spanId, new WeakRef(spanContextObj));
@@ -67333,7 +67712,7 @@ function endToolExecutionSpan(span, metadata) {
67333
67712
  const spanCtx = activeSpans.get(spanId)?.deref();
67334
67713
  if (!spanCtx) return;
67335
67714
  if (spanCtx.ended) {
67336
- debugLogger7.debug(
67715
+ debugLogger8.debug(
67337
67716
  `endToolExecutionSpan: span ${spanId} already ended (possible TTL sweep race)`
67338
67717
  );
67339
67718
  return;
@@ -67360,14 +67739,14 @@ function endToolExecutionSpan(span, metadata) {
67360
67739
  }
67361
67740
  }
67362
67741
  } catch (error) {
67363
- debugLogger7.warn(
67742
+ debugLogger8.warn(
67364
67743
  `Failed to update tool execution span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67365
67744
  );
67366
67745
  }
67367
67746
  try {
67368
67747
  spanCtx.span.end();
67369
67748
  } catch (error) {
67370
- debugLogger7.warn(
67749
+ debugLogger8.warn(
67371
67750
  `Failed to end tool execution span: ${error instanceof Error ? error.message : String(error)}`
67372
67751
  );
67373
67752
  }
@@ -67383,12 +67762,16 @@ function startToolBlockedOnUserSpan(toolSpan, attrs) {
67383
67762
  const parentSpanId = getSpanId(toolSpan);
67384
67763
  const parentSpanCtx = activeSpans.get(parentSpanId)?.deref();
67385
67764
  if (!parentSpanCtx) {
67386
- debugLogger7.debug(
67765
+ debugLogger8.debug(
67387
67766
  "startToolBlockedOnUserSpan: tool span not in activeSpans (already ended?) \u2014 using resolveParentContext fallback"
67388
67767
  );
67389
67768
  }
67390
67769
  const ctx = parentSpanCtx ? trace.setSpan(context.active(), parentSpanCtx.span) : resolveParentContext(void 0);
67391
- const attributes = {};
67770
+ const sessionParentCtx = parentSpanCtx ?? subagentContext.getStore() ?? interactionContext.getStore() ?? void 0;
67771
+ const sessionId = resolveSessionId(sessionParentCtx);
67772
+ const attributes = {
67773
+ ...sessionId ? { "session.id": sessionId } : {}
67774
+ };
67392
67775
  if (attrs?.tool_name !== void 0) attributes["tool.name"] = attrs.tool_name;
67393
67776
  if (attrs?.call_id !== void 0) attributes["tool.call_id"] = attrs.call_id;
67394
67777
  const span = getTracer().startSpan(
@@ -67413,7 +67796,7 @@ function endToolBlockedOnUserSpan(span, metadata) {
67413
67796
  const spanCtx = activeSpans.get(spanId)?.deref();
67414
67797
  if (!spanCtx) return;
67415
67798
  if (spanCtx.ended) {
67416
- debugLogger7.debug(
67799
+ debugLogger8.debug(
67417
67800
  `endToolBlockedOnUserSpan: span ${spanId} already ended (possible TTL sweep race)`
67418
67801
  );
67419
67802
  return;
@@ -67428,14 +67811,14 @@ function endToolBlockedOnUserSpan(span, metadata) {
67428
67811
  endAttributes["source"] = metadata.source;
67429
67812
  spanCtx.span.setAttributes(endAttributes);
67430
67813
  } catch (error) {
67431
- debugLogger7.warn(
67814
+ debugLogger8.warn(
67432
67815
  `Failed to update blocked_on_user span attributes: ${error instanceof Error ? error.message : String(error)}`
67433
67816
  );
67434
67817
  }
67435
67818
  try {
67436
67819
  spanCtx.span.end();
67437
67820
  } catch (error) {
67438
- debugLogger7.warn(
67821
+ debugLogger8.warn(
67439
67822
  `Failed to end blocked_on_user span: ${error instanceof Error ? error.message : String(error)}`
67440
67823
  );
67441
67824
  }
@@ -67450,7 +67833,9 @@ function startHookSpan(opts) {
67450
67833
  ensureCleanupInterval();
67451
67834
  const parentCtx = toolContext.getStore() ?? subagentContext.getStore() ?? interactionContext.getStore() ?? void 0;
67452
67835
  const ctx = resolveParentContext(parentCtx);
67836
+ const sessionId = resolveSessionId(parentCtx);
67453
67837
  const attributes = {
67838
+ ...sessionId ? { "session.id": sessionId } : {},
67454
67839
  hook_event: opts.hookEvent,
67455
67840
  "tool.name": opts.toolName
67456
67841
  };
@@ -67479,7 +67864,7 @@ function endHookSpan(span, metadata) {
67479
67864
  const spanCtx = activeSpans.get(spanId)?.deref();
67480
67865
  if (!spanCtx) return;
67481
67866
  if (spanCtx.ended) {
67482
- debugLogger7.debug(
67867
+ debugLogger8.debug(
67483
67868
  `endHookSpan: span ${spanId} already ended (possible TTL sweep race)`
67484
67869
  );
67485
67870
  return;
@@ -67516,14 +67901,14 @@ function endHookSpan(span, metadata) {
67516
67901
  });
67517
67902
  }
67518
67903
  } catch (error) {
67519
- debugLogger7.warn(
67904
+ debugLogger8.warn(
67520
67905
  `Failed to update hook span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67521
67906
  );
67522
67907
  }
67523
67908
  try {
67524
67909
  spanCtx.span.end();
67525
67910
  } catch (error) {
67526
- debugLogger7.warn(
67911
+ debugLogger8.warn(
67527
67912
  `Failed to end hook span: ${error instanceof Error ? error.message : String(error)}`
67528
67913
  );
67529
67914
  }
@@ -67606,14 +67991,14 @@ function endSubagentSpan(span, metadata) {
67606
67991
  const spanCtx = activeSpans.get(spanId)?.deref();
67607
67992
  if (!spanCtx) {
67608
67993
  if (isTelemetrySdkInitialized()) {
67609
- debugLogger7.warn(
67994
+ debugLogger8.warn(
67610
67995
  `endSubagentSpan: span ${spanId} not found in activeSpans (already swept?) \u2014 intended status=${metadata.status}, reason=${metadata.terminateReason ?? "none"}`
67611
67996
  );
67612
67997
  }
67613
67998
  return;
67614
67999
  }
67615
68000
  if (spanCtx.ended) {
67616
- debugLogger7.warn(
68001
+ debugLogger8.warn(
67617
68002
  `endSubagentSpan: span ${spanId} already ended \u2014 intended status=${metadata.status}, reason=${metadata.terminateReason ?? "none"} (possible TTL sweep race)`
67618
68003
  );
67619
68004
  return;
@@ -67649,14 +68034,14 @@ function endSubagentSpan(span, metadata) {
67649
68034
  });
67650
68035
  }
67651
68036
  } catch (error) {
67652
- debugLogger7.warn(
68037
+ debugLogger8.warn(
67653
68038
  `Failed to update subagent span attributes/status: ${error instanceof Error ? error.message : String(error)}`
67654
68039
  );
67655
68040
  }
67656
68041
  try {
67657
68042
  spanCtx.span.end();
67658
68043
  } catch (error) {
67659
- debugLogger7.warn(
68044
+ debugLogger8.warn(
67660
68045
  `Failed to end subagent span: ${error instanceof Error ? error.message : String(error)}`
67661
68046
  );
67662
68047
  }
@@ -67984,7 +68369,7 @@ __name(hrTimeDiff, "hrTimeDiff");
67984
68369
  init_esbuild_shims();
67985
68370
  init_esm();
67986
68371
  var tracer = trace.getTracer(SERVICE_NAME);
67987
- var debugLogger8 = createDebugLogger("OTEL_TRACER");
68372
+ var debugLogger9 = createDebugLogger("OTEL_TRACER");
67988
68373
  var TELEMETRY_WARNING_INTERVAL_MS = 3e4;
67989
68374
  var API_CALL_FAILED_SPAN_STATUS_MESSAGE = "API call failed";
67990
68375
  var API_CALL_ABORTED_SPAN_STATUS_MESSAGE = "API call aborted";
@@ -68000,7 +68385,7 @@ function warnTelemetryOperationFailed(operation, error) {
68000
68385
  suppressedTelemetryWarnings = 0;
68001
68386
  lastTelemetryWarningMs = now;
68002
68387
  try {
68003
- debugLogger8.warn(
68388
+ debugLogger9.warn(
68004
68389
  `OTel span ${operation} failed: ${error instanceof Error ? error.message : String(error)}${suppressedSuffix}`
68005
68390
  );
68006
68391
  } catch {
@@ -68039,13 +68424,13 @@ __name(createSessionRootContext, "createSessionRootContext");
68039
68424
 
68040
68425
  // packages/core/src/telemetry/sdk.ts
68041
68426
  function createTelemetryDiagLogger() {
68042
- const debugLogger12 = createDebugLogger("OTEL");
68427
+ const debugLogger13 = createDebugLogger("OTEL");
68043
68428
  return {
68044
- error: /* @__PURE__ */ __name((message, ...args) => debugLogger12.error(message, ...args), "error"),
68045
- warn: /* @__PURE__ */ __name((message, ...args) => debugLogger12.warn(message, ...args), "warn"),
68046
- info: /* @__PURE__ */ __name((message, ...args) => debugLogger12.info(message, ...args), "info"),
68047
- debug: /* @__PURE__ */ __name((message, ...args) => debugLogger12.debug(message, ...args), "debug"),
68048
- verbose: /* @__PURE__ */ __name((message, ...args) => debugLogger12.debug(message, ...args), "verbose")
68429
+ error: /* @__PURE__ */ __name((message, ...args) => debugLogger13.error(message, ...args), "error"),
68430
+ warn: /* @__PURE__ */ __name((message, ...args) => debugLogger13.warn(message, ...args), "warn"),
68431
+ info: /* @__PURE__ */ __name((message, ...args) => debugLogger13.info(message, ...args), "info"),
68432
+ debug: /* @__PURE__ */ __name((message, ...args) => debugLogger13.debug(message, ...args), "debug"),
68433
+ verbose: /* @__PURE__ */ __name((message, ...args) => debugLogger13.debug(message, ...args), "verbose")
68049
68434
  };
68050
68435
  }
68051
68436
  __name(createTelemetryDiagLogger, "createTelemetryDiagLogger");
@@ -68080,6 +68465,7 @@ var NOOP_PROPAGATOR = {
68080
68465
  var sdk;
68081
68466
  var telemetryInitialized = false;
68082
68467
  var telemetryShutdownPromise;
68468
+ var activeMetricReader;
68083
68469
  function isTelemetrySdkInitialized() {
68084
68470
  return telemetryInitialized;
68085
68471
  }
@@ -68122,11 +68508,32 @@ function validateUrl(url) {
68122
68508
  }
68123
68509
  }
68124
68510
  __name(validateUrl, "validateUrl");
68511
+ var SessionIdSpanProcessor = class {
68512
+ static {
68513
+ __name(this, "SessionIdSpanProcessor");
68514
+ }
68515
+ onStart(span) {
68516
+ try {
68517
+ if (span.attributes?.["session.id"]) return;
68518
+ const sessionId = getCurrentSessionId();
68519
+ if (sessionId) {
68520
+ span.setAttribute("session.id", sessionId);
68521
+ }
68522
+ } catch {
68523
+ }
68524
+ }
68525
+ onEnd(_span) {
68526
+ }
68527
+ async shutdown() {
68528
+ }
68529
+ async forceFlush() {
68530
+ }
68531
+ };
68125
68532
  function initializeTelemetry(config) {
68126
68533
  if (telemetryInitialized || !config.getTelemetryEnabled()) {
68127
68534
  return;
68128
68535
  }
68129
- const debugLogger12 = createDebugLogger("OTEL");
68536
+ const debugLogger13 = createDebugLogger("OTEL");
68130
68537
  const userAttrs = config.getTelemetryResourceAttributes() ?? {};
68131
68538
  const userServiceName = userAttrs["service.name"];
68132
68539
  const {
@@ -68175,7 +68582,7 @@ function initializeTelemetry(config) {
68175
68582
  const metricsUrl = validateUrl(
68176
68583
  config.getTelemetryOtlpMetricsEndpoint() ?? (parsedEndpoint ? resolveHttpOtlpUrl(parsedEndpoint, "metrics") : void 0)
68177
68584
  );
68178
- debugLogger12.debug(
68585
+ debugLogger13.debug(
68179
68586
  `OTLP HTTP endpoints: traces=${tracesUrl ?? "none"}, logs=${logsUrl ?? "none"}, metrics=${metricsUrl ?? "none"}`
68180
68587
  );
68181
68588
  if (tracesUrl) {
@@ -68191,7 +68598,7 @@ function initializeTelemetry(config) {
68191
68598
  // In interactive (TUI) mode, route bridge diagnostics to the OTEL
68192
68599
  // debug log file so they don't break out of the Ink render area
68193
68600
  // via raw stderr. In non-interactive mode, leave the default sink
68194
- // alone so CI / scripts can still see export failures on stderr
68601
+ // alone so CI / scripts can still see export failures on stderr
68195
68602
  // the canonical diagnostic channel for batch runs.
68196
68603
  //
68197
68604
  // Caveat for interactive mode: when the user has explicitly
@@ -68200,7 +68607,7 @@ function initializeTelemetry(config) {
68200
68607
  // trade-off, since falling back to stderr would re-introduce the
68201
68608
  // TUI pollution this injection was added to prevent.
68202
68609
  ...config.isInteractive() && {
68203
- diagnosticsSink: /* @__PURE__ */ __name((message) => debugLogger12.warn(message), "diagnosticsSink")
68610
+ diagnosticsSink: /* @__PURE__ */ __name((message) => debugLogger13.warn(message), "diagnosticsSink")
68204
68611
  }
68205
68612
  }
68206
68613
  );
@@ -68215,7 +68622,7 @@ function initializeTelemetry(config) {
68215
68622
  if (!parsedEndpoint) {
68216
68623
  const warning = 'Per-signal OTLP endpoints are only supported with HTTP protocol. Set otlpProtocol to "http" or provide a base otlpEndpoint for gRPC. Telemetry SDK startup was skipped because no supported gRPC endpoint was configured.';
68217
68624
  diag.warn(warning);
68218
- debugLogger12.warn(warning);
68625
+ debugLogger13.warn(warning);
68219
68626
  return;
68220
68627
  } else {
68221
68628
  spanExporter = new import_exporter_trace_otlp_grpc.OTLPTraceExporter({
@@ -68292,15 +68699,14 @@ function initializeTelemetry(config) {
68292
68699
  // before the detectors settle (e.g. during HttpInstrumentation span creation).
68293
68700
  autoDetectResources: false,
68294
68701
  ...textMapPropagator && { textMapPropagator },
68295
- spanProcessors: spanExporter ? [new import_sdk_trace_node.BatchSpanProcessor(spanExporter)] : [],
68702
+ spanProcessors: spanExporter ? [new SessionIdSpanProcessor(), new import_sdk_trace_node.BatchSpanProcessor(spanExporter)] : [],
68296
68703
  logRecordProcessors: logExporter ? [new import_sdk_logs.BatchLogRecordProcessor(logExporter)] : logToSpanProcessor ? [logToSpanProcessor] : [],
68297
68704
  ...metricReader && { metricReader },
68298
68705
  instrumentations: [
68299
68706
  new import_instrumentation_http.HttpInstrumentation({
68300
68707
  // OTLP HTTP exporter uses node:http (patched here, not by undici).
68301
68708
  // Without this, every OTLP upload batch creates a parasitic client
68302
- // span that itself gets exported → feedback loop. See PR #4390
68303
- // review feedback (wenshao).
68709
+ // span that itself gets exported → feedback loop.
68304
68710
  ignoreOutgoingRequestHook: /* @__PURE__ */ __name((req) => {
68305
68711
  if (otlpUrlPrefixes.length === 0) return false;
68306
68712
  const proto = req.protocol ? String(req.protocol).replace(/:$/, "") : void 0;
@@ -68338,8 +68744,9 @@ function initializeTelemetry(config) {
68338
68744
  });
68339
68745
  try {
68340
68746
  sdk.start();
68341
- debugLogger12.debug("OpenTelemetry SDK started successfully.");
68747
+ debugLogger13.debug("OpenTelemetry SDK started successfully.");
68342
68748
  telemetryInitialized = true;
68749
+ activeMetricReader = metricReader;
68343
68750
  const sessionId = config.getSessionId();
68344
68751
  setSessionContext(createSessionRootContext(sessionId), sessionId);
68345
68752
  setShellTracePropagation(
@@ -68347,7 +68754,7 @@ function initializeTelemetry(config) {
68347
68754
  );
68348
68755
  initializeMetrics(config);
68349
68756
  } catch (error) {
68350
- debugLogger12.error("Error starting OpenTelemetry SDK:", error);
68757
+ debugLogger13.error("Error starting OpenTelemetry SDK:", error);
68351
68758
  }
68352
68759
  }
68353
68760
  __name(initializeTelemetry, "initializeTelemetry");
@@ -68369,7 +68776,7 @@ async function shutdownTelemetry() {
68369
68776
  }
68370
68777
  endInteractionSpan("cancelled");
68371
68778
  const currentSdk = sdk;
68372
- const debugLogger12 = createDebugLogger("OTEL");
68779
+ const debugLogger13 = createDebugLogger("OTEL");
68373
68780
  telemetryShutdownPromise = (async () => {
68374
68781
  let timer;
68375
68782
  let timedOut = false;
@@ -68377,7 +68784,7 @@ async function shutdownTelemetry() {
68377
68784
  const sdkShutdown = Promise.resolve(currentSdk.shutdown());
68378
68785
  sdkShutdown.catch((err) => {
68379
68786
  if (timedOut) {
68380
- debugLogger12.warn(
68787
+ debugLogger13.warn(
68381
68788
  "SDK shutdown rejected after timeout:",
68382
68789
  err instanceof Error ? err.message : err
68383
68790
  );
@@ -68395,17 +68802,18 @@ async function shutdownTelemetry() {
68395
68802
  if (result === "timeout") {
68396
68803
  const msg = `Telemetry shutdown timed out after ${SHUTDOWN_TIMEOUT_MS}ms.`;
68397
68804
  diag.warn(msg);
68398
- debugLogger12.warn(msg);
68805
+ debugLogger13.warn(msg);
68399
68806
  } else {
68400
- debugLogger12.debug("OpenTelemetry SDK shut down successfully.");
68807
+ debugLogger13.debug("OpenTelemetry SDK shut down successfully.");
68401
68808
  }
68402
68809
  } catch (error) {
68403
68810
  clearTimeout(timer);
68404
68811
  diag.error("Error shutting down SDK:", error);
68405
- debugLogger12.error("Error shutting down SDK:", error);
68812
+ debugLogger13.error("Error shutting down SDK:", error);
68406
68813
  } finally {
68407
68814
  telemetryInitialized = false;
68408
68815
  sdk = void 0;
68816
+ activeMetricReader = void 0;
68409
68817
  telemetryShutdownPromise = void 0;
68410
68818
  setSessionContext(void 0);
68411
68819
  setShellTracePropagation(false);
@@ -68414,6 +68822,31 @@ async function shutdownTelemetry() {
68414
68822
  return telemetryShutdownPromise;
68415
68823
  }
68416
68824
  __name(shutdownTelemetry, "shutdownTelemetry");
68825
+ var FORCE_FLUSH_TIMEOUT_MS = 2e3;
68826
+ async function forceFlushMetrics() {
68827
+ if (!telemetryInitialized || !activeMetricReader) return;
68828
+ const flush = activeMetricReader.forceFlush();
68829
+ flush.catch(() => {
68830
+ });
68831
+ let timer;
68832
+ const timeout = new Promise((_, reject) => {
68833
+ timer = setTimeout(
68834
+ () => reject(
68835
+ new Error(
68836
+ `forceFlushMetrics timed out after ${FORCE_FLUSH_TIMEOUT_MS}ms`
68837
+ )
68838
+ ),
68839
+ FORCE_FLUSH_TIMEOUT_MS
68840
+ );
68841
+ timer.unref?.();
68842
+ });
68843
+ try {
68844
+ await Promise.race([flush, timeout]);
68845
+ } finally {
68846
+ clearTimeout(timer);
68847
+ }
68848
+ }
68849
+ __name(forceFlushMetrics, "forceFlushMetrics");
68417
68850
 
68418
68851
  // packages/core/src/telemetry/config.ts
68419
68852
  init_esbuild_shims();
@@ -68655,27 +69088,24 @@ var createInitialMetrics = /* @__PURE__ */ __name(() => ({
68655
69088
  totalLinesRemoved: 0
68656
69089
  }
68657
69090
  }), "createInitialMetrics");
68658
- var UiTelemetryService = class extends EventEmitter {
69091
+ var UiTelemetryService = class _UiTelemetryService extends EventEmitter {
68659
69092
  static {
68660
69093
  __name(this, "UiTelemetryService");
68661
69094
  }
69095
+ static #MAX_CLOSED_SESSIONS = 1e3;
68662
69096
  #metrics = createInitialMetrics();
69097
+ #sessionMetrics = /* @__PURE__ */ new Map();
69098
+ #closedSessions = /* @__PURE__ */ new Set();
68663
69099
  #lastPromptTokenCount = 0;
68664
69100
  #lastCachedContentTokenCount = 0;
68665
69101
  #sessionStartTime = /* @__PURE__ */ new Date();
68666
- addEvent(event) {
68667
- switch (event["event.name"]) {
68668
- case EVENT_API_RESPONSE:
68669
- this.processApiResponse(event);
68670
- break;
68671
- case EVENT_API_ERROR:
68672
- this.processApiError(event);
68673
- break;
68674
- case EVENT_TOOL_CALL:
68675
- this.processToolCall(event);
68676
- break;
68677
- default:
68678
- return;
69102
+ addEvent(event, sessionId) {
69103
+ if (!this.#accumulateEvent(this.#metrics, event)) return;
69104
+ if (sessionId && !this.#closedSessions.has(sessionId)) {
69105
+ if (!this.#sessionMetrics.has(sessionId)) {
69106
+ this.#sessionMetrics.set(sessionId, createInitialMetrics());
69107
+ }
69108
+ this.#accumulateEvent(this.#sessionMetrics.get(sessionId), event);
68679
69109
  }
68680
69110
  this.emit("update", {
68681
69111
  metrics: this.#metrics,
@@ -68685,6 +69115,9 @@ var UiTelemetryService = class extends EventEmitter {
68685
69115
  getMetrics() {
68686
69116
  return this.#metrics;
68687
69117
  }
69118
+ getMetricsForSession(sessionId) {
69119
+ return this.#sessionMetrics.get(sessionId) ?? createInitialMetrics();
69120
+ }
68688
69121
  getLastPromptTokenCount() {
68689
69122
  return this.#lastPromptTokenCount;
68690
69123
  }
@@ -68709,6 +69142,8 @@ var UiTelemetryService = class extends EventEmitter {
68709
69142
  */
68710
69143
  reset() {
68711
69144
  this.#metrics = createInitialMetrics();
69145
+ this.#sessionMetrics.clear();
69146
+ this.#closedSessions.clear();
68712
69147
  this.#lastPromptTokenCount = 0;
68713
69148
  this.#lastCachedContentTokenCount = 0;
68714
69149
  this.#sessionStartTime = /* @__PURE__ */ new Date();
@@ -68717,21 +69152,36 @@ var UiTelemetryService = class extends EventEmitter {
68717
69152
  lastPromptTokenCount: this.#lastPromptTokenCount
68718
69153
  });
68719
69154
  }
68720
- getOrCreateModelMetrics(modelName) {
68721
- if (!this.#metrics.models[modelName]) {
68722
- this.#metrics.models[modelName] = createInitialModelMetrics();
69155
+ resetSession(sessionId) {
69156
+ this.#sessionMetrics.set(sessionId, createInitialMetrics());
69157
+ this.#closedSessions.delete(sessionId);
69158
+ }
69159
+ removeSession(sessionId) {
69160
+ this.#sessionMetrics.delete(sessionId);
69161
+ this.#closedSessions.add(sessionId);
69162
+ if (this.#closedSessions.size > _UiTelemetryService.#MAX_CLOSED_SESSIONS) {
69163
+ const oldest = this.#closedSessions.values().next().value;
69164
+ if (oldest) this.#closedSessions.delete(oldest);
68723
69165
  }
68724
- return this.#metrics.models[modelName];
68725
69166
  }
68726
- getOrCreateSourceMetrics(modelMetrics, source) {
68727
- if (!modelMetrics.bySource[source]) {
68728
- modelMetrics.bySource[source] = createInitialModelMetricsCore();
69167
+ #accumulateEvent(metrics2, event) {
69168
+ switch (event["event.name"]) {
69169
+ case EVENT_API_RESPONSE:
69170
+ this.#accumulateApiResponse(metrics2, event);
69171
+ return true;
69172
+ case EVENT_API_ERROR:
69173
+ this.#accumulateApiError(metrics2, event);
69174
+ return true;
69175
+ case EVENT_TOOL_CALL:
69176
+ this.#accumulateToolCall(metrics2, event);
69177
+ return true;
69178
+ default:
69179
+ return false;
68729
69180
  }
68730
- return modelMetrics.bySource[source];
68731
69181
  }
68732
- processApiResponse(event) {
68733
- const modelMetrics = this.getOrCreateModelMetrics(event.model);
68734
- const sourceMetrics = this.getOrCreateSourceMetrics(
69182
+ #accumulateApiResponse(metrics2, event) {
69183
+ const modelMetrics = this.#getOrCreateModelMetrics(metrics2, event.model);
69184
+ const sourceMetrics = this.#getOrCreateSourceMetrics(
68735
69185
  modelMetrics,
68736
69186
  event.subagent_name ?? MAIN_SOURCE
68737
69187
  );
@@ -68745,9 +69195,9 @@ var UiTelemetryService = class extends EventEmitter {
68745
69195
  bucket.tokens.thoughts += event.thoughts_token_count;
68746
69196
  }
68747
69197
  }
68748
- processApiError(event) {
68749
- const modelMetrics = this.getOrCreateModelMetrics(event.model);
68750
- const sourceMetrics = this.getOrCreateSourceMetrics(
69198
+ #accumulateApiError(metrics2, event) {
69199
+ const modelMetrics = this.#getOrCreateModelMetrics(metrics2, event.model);
69200
+ const sourceMetrics = this.#getOrCreateSourceMetrics(
68751
69201
  modelMetrics,
68752
69202
  event.subagent_name ?? MAIN_SOURCE
68753
69203
  );
@@ -68757,8 +69207,8 @@ var UiTelemetryService = class extends EventEmitter {
68757
69207
  bucket.api.totalLatencyMs += event.duration_ms;
68758
69208
  }
68759
69209
  }
68760
- processToolCall(event) {
68761
- const { tools, files } = this.#metrics;
69210
+ #accumulateToolCall(metrics2, event) {
69211
+ const { tools, files } = metrics2;
68762
69212
  tools.totalCalls++;
68763
69213
  tools.totalDurationMs += event.duration_ms;
68764
69214
  if (event.success) {
@@ -68801,9 +69251,476 @@ var UiTelemetryService = class extends EventEmitter {
68801
69251
  }
68802
69252
  }
68803
69253
  }
69254
+ #getOrCreateModelMetrics(metrics2, modelName) {
69255
+ if (!metrics2.models[modelName]) {
69256
+ metrics2.models[modelName] = createInitialModelMetrics();
69257
+ }
69258
+ return metrics2.models[modelName];
69259
+ }
69260
+ #getOrCreateSourceMetrics(modelMetrics, source) {
69261
+ if (!modelMetrics.bySource[source]) {
69262
+ modelMetrics.bySource[source] = createInitialModelMetricsCore();
69263
+ }
69264
+ return modelMetrics.bySource[source];
69265
+ }
68804
69266
  };
68805
69267
  var uiTelemetryService = new UiTelemetryService();
68806
69268
 
69269
+ // packages/core/src/telemetry/daemon-tracing.ts
69270
+ init_esbuild_shims();
69271
+ init_esm();
69272
+ var import_api_logs = __toESM(require_src2(), 1);
69273
+ import { createHash as createHash3 } from "node:crypto";
69274
+ var DAEMON_TRACEPARENT_META_KEY = "qwen.telemetry.traceparent";
69275
+ var DAEMON_TRACESTATE_META_KEY = "qwen.telemetry.tracestate";
69276
+ var SPAN_DAEMON_REQUEST = "qwen-code.daemon.request";
69277
+ var SPAN_DAEMON_BRIDGE = "qwen-code.daemon.bridge";
69278
+ var EVENT_DAEMON_ERROR = "qwen-code.daemon.error";
69279
+ function errorMessage(error) {
69280
+ if (error instanceof Error) return error.message;
69281
+ return String(error);
69282
+ }
69283
+ __name(errorMessage, "errorMessage");
69284
+ function errorType(error) {
69285
+ if (error instanceof Error) return error.name || "Error";
69286
+ return typeof error;
69287
+ }
69288
+ __name(errorType, "errorType");
69289
+ var INVALID_TRACE_ID = "0".repeat(32);
69290
+ var INVALID_SPAN_ID = "0".repeat(16);
69291
+ function stripReservedTraceMeta(meta) {
69292
+ if (!meta || typeof meta !== "object" || Array.isArray(meta)) return {};
69293
+ const record = meta;
69294
+ if (!(DAEMON_TRACEPARENT_META_KEY in record) && !(DAEMON_TRACESTATE_META_KEY in record)) {
69295
+ return { ...record };
69296
+ }
69297
+ const out = { ...record };
69298
+ delete out[DAEMON_TRACEPARENT_META_KEY];
69299
+ delete out[DAEMON_TRACESTATE_META_KEY];
69300
+ return out;
69301
+ }
69302
+ __name(stripReservedTraceMeta, "stripReservedTraceMeta");
69303
+ function hashDaemonWorkspace(workspace) {
69304
+ return createHash3("sha256").update(workspace).digest("hex").slice(0, 16);
69305
+ }
69306
+ __name(hashDaemonWorkspace, "hashDaemonWorkspace");
69307
+ async function withDaemonSpan(name, attributes, fn, options = {}) {
69308
+ if (!isTelemetrySdkInitialized()) {
69309
+ return await fn(void 0);
69310
+ }
69311
+ const autoOkOnSuccess = options.autoOkOnSuccess ?? true;
69312
+ const tracer2 = trace.getTracer(SERVICE_NAME);
69313
+ return await tracer2.startActiveSpan(
69314
+ name,
69315
+ { kind: SpanKind.INTERNAL, attributes },
69316
+ async (span) => {
69317
+ try {
69318
+ const result = await fn(span);
69319
+ if (autoOkOnSuccess) {
69320
+ span.setStatus({ code: SpanStatusCode.OK });
69321
+ }
69322
+ return result;
69323
+ } catch (error) {
69324
+ recordDaemonError(span, error);
69325
+ throw error;
69326
+ } finally {
69327
+ span.end();
69328
+ }
69329
+ }
69330
+ );
69331
+ }
69332
+ __name(withDaemonSpan, "withDaemonSpan");
69333
+ async function withDaemonRequestSpan(options, fn) {
69334
+ return await withDaemonSpan(
69335
+ SPAN_DAEMON_REQUEST,
69336
+ {
69337
+ "http.request.method": options.method,
69338
+ "http.route": options.route,
69339
+ "qwen-code.daemon.operation": "http_request",
69340
+ ...options.workspaceHash ? { "qwen-code.workspace.hash": options.workspaceHash } : {},
69341
+ ...options.sessionId ? { "session.id": options.sessionId } : {},
69342
+ ...options.clientId ? { "qwen-code.client_id": options.clientId } : {},
69343
+ ...options.permissionRequestId ? {
69344
+ "qwen-code.daemon.permission.request_id": options.permissionRequestId
69345
+ } : {}
69346
+ },
69347
+ fn,
69348
+ { autoOkOnSuccess: false }
69349
+ );
69350
+ }
69351
+ __name(withDaemonRequestSpan, "withDaemonRequestSpan");
69352
+ async function withDaemonBridgeSpan(operation, attributes, fn) {
69353
+ return await withDaemonSpan(
69354
+ SPAN_DAEMON_BRIDGE,
69355
+ {
69356
+ "qwen-code.daemon.operation": operation,
69357
+ ...attributes
69358
+ },
69359
+ async () => await fn()
69360
+ );
69361
+ }
69362
+ __name(withDaemonBridgeSpan, "withDaemonBridgeSpan");
69363
+ function recordDaemonHttpResponse(span, statusCode) {
69364
+ try {
69365
+ span?.setAttribute("http.response.status_code", statusCode);
69366
+ } catch {
69367
+ }
69368
+ }
69369
+ __name(recordDaemonHttpResponse, "recordDaemonHttpResponse");
69370
+ function addDaemonRequestAttribute(key, value) {
69371
+ try {
69372
+ trace.getSpan(context.active())?.setAttribute(key, value);
69373
+ } catch {
69374
+ }
69375
+ }
69376
+ __name(addDaemonRequestAttribute, "addDaemonRequestAttribute");
69377
+ function recordDaemonError(span, error, attributes = {}) {
69378
+ const target = span ?? trace.getSpan(context.active());
69379
+ if (!target) return;
69380
+ try {
69381
+ const message = truncateSpanError(errorMessage(error));
69382
+ target.recordException(error instanceof Error ? error : new Error(message));
69383
+ target.setAttributes({
69384
+ "error.type": errorType(error),
69385
+ "error.message": message,
69386
+ ...attributes
69387
+ });
69388
+ target.setStatus({ code: SpanStatusCode.ERROR, message });
69389
+ } catch {
69390
+ }
69391
+ }
69392
+ __name(recordDaemonError, "recordDaemonError");
69393
+ function emitDaemonLog(body, attributes = {}, options) {
69394
+ if (!isTelemetrySdkInitialized()) return;
69395
+ try {
69396
+ import_api_logs.logs.getLogger(SERVICE_NAME).emit({
69397
+ body,
69398
+ timestamp: /* @__PURE__ */ new Date(),
69399
+ attributes: {
69400
+ "event.name": options?.eventName ?? EVENT_DAEMON_ERROR,
69401
+ ...attributes
69402
+ },
69403
+ ...options?.severityNumber != null ? { severityNumber: options.severityNumber } : {}
69404
+ });
69405
+ } catch {
69406
+ }
69407
+ }
69408
+ __name(emitDaemonLog, "emitDaemonLog");
69409
+ function captureDaemonTelemetryContext() {
69410
+ return { context: context.active() };
69411
+ }
69412
+ __name(captureDaemonTelemetryContext, "captureDaemonTelemetryContext");
69413
+ async function runWithDaemonTelemetryContext(captured, fn) {
69414
+ const ctx = captured && typeof captured === "object" && "context" in captured && captured.context ? captured.context : void 0;
69415
+ if (!ctx) return await fn();
69416
+ return await context.with(ctx, fn);
69417
+ }
69418
+ __name(runWithDaemonTelemetryContext, "runWithDaemonTelemetryContext");
69419
+ function injectDaemonTraceContext(request4) {
69420
+ const currentMeta = request4._meta;
69421
+ const nextMeta = stripReservedTraceMeta(currentMeta);
69422
+ try {
69423
+ const ctx = getActiveSpanTraceContext();
69424
+ if (ctx) {
69425
+ nextMeta[DAEMON_TRACEPARENT_META_KEY] = formatTraceparent(ctx);
69426
+ }
69427
+ } catch {
69428
+ }
69429
+ if (!currentMeta && !nextMeta[DAEMON_TRACEPARENT_META_KEY]) {
69430
+ return request4;
69431
+ }
69432
+ return {
69433
+ ...request4,
69434
+ _meta: nextMeta
69435
+ };
69436
+ }
69437
+ __name(injectDaemonTraceContext, "injectDaemonTraceContext");
69438
+ function extractDaemonTraceContext(source) {
69439
+ const meta = source?._meta;
69440
+ if (!meta || typeof meta !== "object" || Array.isArray(meta)) {
69441
+ return void 0;
69442
+ }
69443
+ const record = meta;
69444
+ const traceparent = record[DAEMON_TRACEPARENT_META_KEY];
69445
+ if (typeof traceparent !== "string" || traceparent.length === 0) {
69446
+ return void 0;
69447
+ }
69448
+ const carrier = { traceparent };
69449
+ const tracestate = record[DAEMON_TRACESTATE_META_KEY];
69450
+ if (typeof tracestate === "string" && tracestate.length > 0) {
69451
+ carrier["tracestate"] = tracestate;
69452
+ }
69453
+ const extracted = propagation.extract(ROOT_CONTEXT, carrier);
69454
+ if (trace.getSpanContext(extracted)) return extracted;
69455
+ const parts = traceparent.split("-");
69456
+ const traceId = parts[1];
69457
+ const spanId = parts[2];
69458
+ const flags = parts[3];
69459
+ if (parts[0] !== "00" || !traceId?.match(/^[0-9a-f]{32}$/) || !spanId?.match(/^[0-9a-f]{16}$/) || !flags?.match(/^[0-9a-f]{2}$/) || traceId === INVALID_TRACE_ID || spanId === INVALID_SPAN_ID) {
69460
+ return void 0;
69461
+ }
69462
+ return trace.setSpan(
69463
+ ROOT_CONTEXT,
69464
+ trace.wrapSpanContext({
69465
+ traceId,
69466
+ spanId,
69467
+ traceFlags: Number.parseInt(flags, 16),
69468
+ isRemote: true
69469
+ })
69470
+ );
69471
+ }
69472
+ __name(extractDaemonTraceContext, "extractDaemonTraceContext");
69473
+ function createDaemonBridgeTelemetry() {
69474
+ return {
69475
+ captureContext: captureDaemonTelemetryContext,
69476
+ runWithContext: runWithDaemonTelemetryContext,
69477
+ withSpan: withDaemonBridgeSpan,
69478
+ event(name, attributes) {
69479
+ if (!isTelemetrySdkInitialized()) return;
69480
+ try {
69481
+ const activeSpan = trace.getSpan(context.active());
69482
+ if (activeSpan) {
69483
+ activeSpan.addEvent(name, attributes);
69484
+ return;
69485
+ }
69486
+ const span = trace.getTracer(SERVICE_NAME).startSpan(SPAN_DAEMON_BRIDGE, {
69487
+ kind: SpanKind.INTERNAL,
69488
+ attributes: {
69489
+ "event.name": name,
69490
+ "qwen-code.daemon.operation": `event.${name}`,
69491
+ ...attributes
69492
+ }
69493
+ });
69494
+ span.addEvent(name, attributes);
69495
+ span.setStatus({ code: SpanStatusCode.OK });
69496
+ span.end();
69497
+ } catch {
69498
+ }
69499
+ },
69500
+ injectPromptContext: injectDaemonTraceContext
69501
+ };
69502
+ }
69503
+ __name(createDaemonBridgeTelemetry, "createDaemonBridgeTelemetry");
69504
+
69505
+ // packages/core/src/telemetry/daemon-metrics.ts
69506
+ init_esbuild_shims();
69507
+ init_esm();
69508
+ var DAEMON_HTTP_REQUEST_COUNT = `${SERVICE_NAME}.daemon.http.request.count`;
69509
+ var DAEMON_HTTP_REQUEST_DURATION = `${SERVICE_NAME}.daemon.http.request.duration`;
69510
+ var DAEMON_SESSION_ACTIVE = `${SERVICE_NAME}.daemon.session.active`;
69511
+ var DAEMON_SESSION_LIFECYCLE = `${SERVICE_NAME}.daemon.session.lifecycle`;
69512
+ var DAEMON_CHANNEL_LIFECYCLE = `${SERVICE_NAME}.daemon.channel.lifecycle`;
69513
+ var DAEMON_PROMPT_QUEUE_WAIT = `${SERVICE_NAME}.daemon.prompt.queue_wait`;
69514
+ var DAEMON_PROMPT_DURATION = `${SERVICE_NAME}.daemon.prompt.duration`;
69515
+ var DAEMON_BRIDGE_ERROR_COUNT = `${SERVICE_NAME}.daemon.bridge.error.count`;
69516
+ var DAEMON_CANCEL_COUNT = `${SERVICE_NAME}.daemon.cancel.count`;
69517
+ var DAEMON_SSE_ACTIVE = `${SERVICE_NAME}.daemon.sse.active`;
69518
+ var DAEMON_PROCESS_HEAP_USED = `${SERVICE_NAME}.daemon.process.heap_used`;
69519
+ var KNOWN_ERROR_TYPES = /* @__PURE__ */ new Set([
69520
+ "SessionNotFoundError",
69521
+ "WorkspaceMismatchError",
69522
+ "InvalidClientIdError",
69523
+ "SessionLimitExceededError",
69524
+ "RestoreInProgressError",
69525
+ "InvalidSessionScopeError",
69526
+ "TrustGateError",
69527
+ "WorkspaceInitConflictError",
69528
+ "WorkspaceInitPathEscapeError",
69529
+ "WorkspaceInitSymlinkError",
69530
+ "WorkspaceInitRaceError",
69531
+ "McpServerNotFoundError",
69532
+ "McpServerRestartFailedError",
69533
+ "PromptDeadlineExceededError",
69534
+ "InvalidSessionMetadataError",
69535
+ "SubscriberLimitExceededError",
69536
+ "BridgeChannelClosedError",
69537
+ "BridgeTimeoutError",
69538
+ "PermissionForbiddenError"
69539
+ ]);
69540
+ var initialized = false;
69541
+ var httpRequestCounter;
69542
+ var httpRequestDurationHistogram;
69543
+ var sessionLifecycleCounter;
69544
+ var channelLifecycleCounter;
69545
+ var promptQueueWaitHistogram;
69546
+ var promptDurationHistogram;
69547
+ var bridgeErrorCounter;
69548
+ var cancelCounter;
69549
+ function normalizeErrorType(err) {
69550
+ const name = err instanceof Error ? err.name : typeof err;
69551
+ return KNOWN_ERROR_TYPES.has(name) ? name : "unknown";
69552
+ }
69553
+ __name(normalizeErrorType, "normalizeErrorType");
69554
+ function initializeDaemonMetrics() {
69555
+ if (initialized) return;
69556
+ const meter = getMeter();
69557
+ if (!meter) return;
69558
+ httpRequestCounter = meter.createCounter(DAEMON_HTTP_REQUEST_COUNT, {
69559
+ description: "Daemon HTTP request count by route and status class.",
69560
+ valueType: ValueType.INT
69561
+ });
69562
+ httpRequestDurationHistogram = meter.createHistogram(
69563
+ DAEMON_HTTP_REQUEST_DURATION,
69564
+ {
69565
+ description: "Daemon HTTP request duration in milliseconds.",
69566
+ unit: "ms",
69567
+ valueType: ValueType.DOUBLE,
69568
+ advice: {
69569
+ explicitBucketBoundaries: [
69570
+ 1,
69571
+ 2,
69572
+ 5,
69573
+ 10,
69574
+ 25,
69575
+ 50,
69576
+ 100,
69577
+ 250,
69578
+ 500,
69579
+ 1e3,
69580
+ 2500,
69581
+ 5e3,
69582
+ 1e4,
69583
+ 3e4
69584
+ ]
69585
+ }
69586
+ }
69587
+ );
69588
+ sessionLifecycleCounter = meter.createCounter(DAEMON_SESSION_LIFECYCLE, {
69589
+ description: "Daemon session lifecycle events (spawn, close, die).",
69590
+ valueType: ValueType.INT
69591
+ });
69592
+ channelLifecycleCounter = meter.createCounter(DAEMON_CHANNEL_LIFECYCLE, {
69593
+ description: "Daemon ACP channel lifecycle events (spawn, exit).",
69594
+ valueType: ValueType.INT
69595
+ });
69596
+ promptQueueWaitHistogram = meter.createHistogram(DAEMON_PROMPT_QUEUE_WAIT, {
69597
+ description: "Time a prompt waited in the per-session FIFO queue.",
69598
+ unit: "ms",
69599
+ valueType: ValueType.DOUBLE,
69600
+ advice: {
69601
+ explicitBucketBoundaries: [
69602
+ 1,
69603
+ 5,
69604
+ 10,
69605
+ 50,
69606
+ 100,
69607
+ 500,
69608
+ 1e3,
69609
+ 5e3,
69610
+ 1e4,
69611
+ 3e4,
69612
+ 6e4
69613
+ ]
69614
+ }
69615
+ });
69616
+ promptDurationHistogram = meter.createHistogram(DAEMON_PROMPT_DURATION, {
69617
+ description: "End-to-end prompt duration from dispatch to completion.",
69618
+ unit: "ms",
69619
+ valueType: ValueType.DOUBLE,
69620
+ advice: {
69621
+ explicitBucketBoundaries: [
69622
+ 100,
69623
+ 500,
69624
+ 1e3,
69625
+ 2500,
69626
+ 5e3,
69627
+ 1e4,
69628
+ 3e4,
69629
+ 6e4,
69630
+ 12e4,
69631
+ 3e5,
69632
+ 6e5
69633
+ ]
69634
+ }
69635
+ });
69636
+ bridgeErrorCounter = meter.createCounter(DAEMON_BRIDGE_ERROR_COUNT, {
69637
+ description: "Daemon bridge error count by normalized error type.",
69638
+ valueType: ValueType.INT
69639
+ });
69640
+ cancelCounter = meter.createCounter(DAEMON_CANCEL_COUNT, {
69641
+ description: "Daemon cancel request count.",
69642
+ valueType: ValueType.INT
69643
+ });
69644
+ initialized = true;
69645
+ }
69646
+ __name(initializeDaemonMetrics, "initializeDaemonMetrics");
69647
+ var gaugesRegistered = false;
69648
+ function registerDaemonGaugeCallbacks(callbacks) {
69649
+ if (gaugesRegistered) return;
69650
+ const meter = getMeter();
69651
+ if (!meter) return;
69652
+ meter.createObservableGauge(DAEMON_SESSION_ACTIVE, {
69653
+ description: "Current number of active daemon sessions.",
69654
+ valueType: ValueType.INT
69655
+ }).addCallback((result) => {
69656
+ try {
69657
+ result.observe(callbacks.sessionCount());
69658
+ } catch {
69659
+ }
69660
+ });
69661
+ meter.createObservableGauge(DAEMON_SSE_ACTIVE, {
69662
+ description: "Current number of active SSE connections.",
69663
+ valueType: ValueType.INT
69664
+ }).addCallback((result) => {
69665
+ try {
69666
+ result.observe(callbacks.sseCount());
69667
+ } catch {
69668
+ }
69669
+ });
69670
+ meter.createObservableGauge(DAEMON_PROCESS_HEAP_USED, {
69671
+ description: "Daemon process heap memory usage in bytes.",
69672
+ unit: "bytes",
69673
+ valueType: ValueType.INT
69674
+ }).addCallback((result) => {
69675
+ try {
69676
+ result.observe(callbacks.heapUsed());
69677
+ } catch {
69678
+ }
69679
+ });
69680
+ gaugesRegistered = true;
69681
+ }
69682
+ __name(registerDaemonGaugeCallbacks, "registerDaemonGaugeCallbacks");
69683
+ function recordDaemonHttpRequest(durationMs, route, statusCode) {
69684
+ if (!initialized) return;
69685
+ const statusClass = `${Math.floor(statusCode / 100)}xx`;
69686
+ httpRequestCounter?.add(1, { route, status_class: statusClass });
69687
+ httpRequestDurationHistogram?.record(durationMs, { route });
69688
+ }
69689
+ __name(recordDaemonHttpRequest, "recordDaemonHttpRequest");
69690
+ function recordDaemonSessionLifecycle(action) {
69691
+ if (!initialized) return;
69692
+ sessionLifecycleCounter?.add(1, { action });
69693
+ }
69694
+ __name(recordDaemonSessionLifecycle, "recordDaemonSessionLifecycle");
69695
+ function recordDaemonChannelLifecycle(action, expected) {
69696
+ if (!initialized) return;
69697
+ channelLifecycleCounter?.add(1, {
69698
+ action,
69699
+ ...expected != null ? { expected } : {}
69700
+ });
69701
+ }
69702
+ __name(recordDaemonChannelLifecycle, "recordDaemonChannelLifecycle");
69703
+ function recordDaemonPromptQueueWait(durationMs) {
69704
+ if (!initialized) return;
69705
+ promptQueueWaitHistogram?.record(durationMs);
69706
+ }
69707
+ __name(recordDaemonPromptQueueWait, "recordDaemonPromptQueueWait");
69708
+ function recordDaemonPromptDuration(durationMs) {
69709
+ if (!initialized) return;
69710
+ promptDurationHistogram?.record(durationMs);
69711
+ }
69712
+ __name(recordDaemonPromptDuration, "recordDaemonPromptDuration");
69713
+ function recordDaemonBridgeError(err) {
69714
+ if (!initialized) return;
69715
+ bridgeErrorCounter?.add(1, { error_type: normalizeErrorType(err) });
69716
+ }
69717
+ __name(recordDaemonBridgeError, "recordDaemonBridgeError");
69718
+ function recordDaemonCancel() {
69719
+ if (!initialized) return;
69720
+ cancelCounter?.add(1);
69721
+ }
69722
+ __name(recordDaemonCancel, "recordDaemonCancel");
69723
+
68807
69724
  // packages/core/src/telemetry/index.ts
68808
69725
  var TelemetryTarget = /* @__PURE__ */ ((TelemetryTarget2) => {
68809
69726
  TelemetryTarget2["GCP"] = "gcp";
@@ -68848,7 +69765,7 @@ function snapshotRetryMetadata() {
68848
69765
  };
68849
69766
  }
68850
69767
  __name(snapshotRetryMetadata, "snapshotRetryMetadata");
68851
- var debugLogger9 = createDebugLogger("LOGGING_CONTENT_GENERATOR");
69768
+ var debugLogger10 = createDebugLogger("LOGGING_CONTENT_GENERATOR");
68852
69769
  var MAX_RESPONSE_TEXT_LENGTH = 4096;
68853
69770
  var RESPONSE_TEXT_TRUNCATION_SUFFIX = "...[truncated]";
68854
69771
  var MAX_RESPONSE_TEXT_PREFIX_LENGTH = MAX_RESPONSE_TEXT_LENGTH - RESPONSE_TEXT_TRUNCATION_SUFFIX.length;
@@ -68906,8 +69823,8 @@ var LoggingContentGenerator = class {
68906
69823
  );
68907
69824
  }
68908
69825
  _logApiError(responseId, durationMs, error, model, prompt_id) {
68909
- const errorMessage = getErrorMessage(error);
68910
- const errorType = getErrorType(error);
69826
+ const errorMessage2 = getErrorMessage(error);
69827
+ const errorType2 = getErrorType(error);
68911
69828
  const errorResponseId = error?.requestID || error?.request_id || responseId;
68912
69829
  const errorStatus = getErrorStatus(error);
68913
69830
  logApiError(
@@ -68918,8 +69835,8 @@ var LoggingContentGenerator = class {
68918
69835
  durationMs,
68919
69836
  promptId: prompt_id,
68920
69837
  authType: this.generatorAuthType,
68921
- errorMessage,
68922
- errorType,
69838
+ errorMessage: errorMessage2,
69839
+ errorType: errorType2,
68923
69840
  statusCode: errorStatus,
68924
69841
  subagentName: subagentNameContext.getStore()
68925
69842
  })
@@ -68929,7 +69846,7 @@ var LoggingContentGenerator = class {
68929
69846
  try {
68930
69847
  this._logApiError(responseId, durationMs, error, model, prompt_id);
68931
69848
  } catch (loggingError) {
68932
- debugLogger9.warn("Failed to log API error:", loggingError);
69849
+ debugLogger10.warn("Failed to log API error:", loggingError);
68933
69850
  }
68934
69851
  }
68935
69852
  safelyLogApiResponse(responseId, durationMs, model, prompt_id, usageMetadata, responseText) {
@@ -68943,7 +69860,7 @@ var LoggingContentGenerator = class {
68943
69860
  responseText
68944
69861
  );
68945
69862
  } catch (loggingError) {
68946
- debugLogger9.warn("Failed to log API response:", loggingError);
69863
+ debugLogger10.warn("Failed to log API response:", loggingError);
68947
69864
  }
68948
69865
  }
68949
69866
  async generateContent(req, userPromptId) {
@@ -69006,7 +69923,7 @@ var LoggingContentGenerator = class {
69006
69923
  userPromptId
69007
69924
  );
69008
69925
  } catch (loggingError) {
69009
- debugLogger9.warn("Failed to log OpenAI interaction:", loggingError);
69926
+ debugLogger10.warn("Failed to log OpenAI interaction:", loggingError);
69010
69927
  }
69011
69928
  return result;
69012
69929
  });
@@ -69016,6 +69933,10 @@ var LoggingContentGenerator = class {
69016
69933
  outputTokens: response.usageMetadata?.candidatesTokenCount,
69017
69934
  cachedInputTokens: response.usageMetadata?.cachedContentTokenCount,
69018
69935
  durationMs: Date.now() - startTime,
69936
+ responseId: response.responseId || void 0,
69937
+ finishReason: response.candidates?.[0]?.finishReason || void 0,
69938
+ thoughtsTokenCount: response.usageMetadata?.thoughtsTokenCount,
69939
+ subagentName: subagentNameContext.getStore() || void 0,
69019
69940
  ...retrySnapshot
69020
69941
  });
69021
69942
  return response;
@@ -69026,6 +69947,9 @@ var LoggingContentGenerator = class {
69026
69947
  success: false,
69027
69948
  durationMs,
69028
69949
  error: aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE,
69950
+ errorType: getErrorType(error),
69951
+ errorStatusCode: getErrorStatus(error),
69952
+ subagentName: subagentNameContext.getStore() || void 0,
69029
69953
  ...retrySnapshot
69030
69954
  });
69031
69955
  await context.with(spanContext, async () => {
@@ -69038,7 +69962,7 @@ var LoggingContentGenerator = class {
69038
69962
  userPromptId
69039
69963
  );
69040
69964
  } catch (loggingError) {
69041
- debugLogger9.warn("Failed to log OpenAI interaction:", loggingError);
69965
+ debugLogger10.warn("Failed to log OpenAI interaction:", loggingError);
69042
69966
  }
69043
69967
  });
69044
69968
  throw error;
@@ -69096,6 +70020,9 @@ var LoggingContentGenerator = class {
69096
70020
  success: false,
69097
70021
  durationMs,
69098
70022
  error: aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE,
70023
+ errorType: getErrorType(error),
70024
+ errorStatusCode: getErrorStatus(error),
70025
+ subagentName: subagentNameContext.getStore() || void 0,
69099
70026
  ...retrySnapshot
69100
70027
  });
69101
70028
  try {
@@ -69106,7 +70033,7 @@ var LoggingContentGenerator = class {
69106
70033
  userPromptId
69107
70034
  );
69108
70035
  } catch (loggingError) {
69109
- debugLogger9.warn("Failed to log OpenAI interaction:", loggingError);
70036
+ debugLogger10.warn("Failed to log OpenAI interaction:", loggingError);
69110
70037
  }
69111
70038
  throw error;
69112
70039
  }
@@ -69115,7 +70042,7 @@ var LoggingContentGenerator = class {
69115
70042
  try {
69116
70043
  resolvedRequest = await session.resolve(req);
69117
70044
  } catch (loggingError) {
69118
- debugLogger9.warn("Failed to resolve OpenAI request:", loggingError);
70045
+ debugLogger10.warn("Failed to resolve OpenAI request:", loggingError);
69119
70046
  }
69120
70047
  }
69121
70048
  return context.with(
@@ -69151,6 +70078,9 @@ var LoggingContentGenerator = class {
69151
70078
  let firstModelVersion = "";
69152
70079
  let lastUsageMetadata;
69153
70080
  let errorOccurred = false;
70081
+ let lastFinishReason;
70082
+ let lastError;
70083
+ const subagentName = subagentNameContext.getStore();
69154
70084
  let ttftMs;
69155
70085
  let spanEndedByTimeout = false;
69156
70086
  const runInSpan = /* @__PURE__ */ __name((fn) => spanContext ? context.with(spanContext, fn) : fn(), "runInSpan");
@@ -69168,6 +70098,8 @@ var LoggingContentGenerator = class {
69168
70098
  success: false,
69169
70099
  durationMs: Date.now() - startTime,
69170
70100
  error: "Stream span timed out (idle)",
70101
+ responseId: firstResponseId || void 0,
70102
+ subagentName: subagentName || void 0,
69171
70103
  ...retrySnapshot
69172
70104
  });
69173
70105
  spanEndedByTimeout = true;
@@ -69189,6 +70121,10 @@ var LoggingContentGenerator = class {
69189
70121
  if (response.usageMetadata) {
69190
70122
  lastUsageMetadata = response.usageMetadata;
69191
70123
  }
70124
+ const candidate = response.candidates?.[0];
70125
+ if (candidate?.finishReason) {
70126
+ lastFinishReason = candidate.finishReason;
70127
+ }
69192
70128
  if (ttftMs === void 0 && hasUserVisibleContent(response)) {
69193
70129
  ttftMs = Date.now() - startTime;
69194
70130
  }
@@ -69227,6 +70163,7 @@ var LoggingContentGenerator = class {
69227
70163
  }
69228
70164
  } catch (error) {
69229
70165
  errorOccurred = true;
70166
+ lastError = error;
69230
70167
  if (!spanEndedByTimeout) {
69231
70168
  const durationMs = Date.now() - startTime;
69232
70169
  runInSpan(
@@ -69262,6 +70199,12 @@ var LoggingContentGenerator = class {
69262
70199
  ttftMs,
69263
70200
  durationMs: Date.now() - startTime,
69264
70201
  error: errorOccurred ? aborted ? API_CALL_ABORTED_SPAN_STATUS_MESSAGE : API_CALL_FAILED_SPAN_STATUS_MESSAGE : void 0,
70202
+ responseId: firstResponseId || void 0,
70203
+ finishReason: lastFinishReason,
70204
+ thoughtsTokenCount: lastUsageMetadata?.thoughtsTokenCount,
70205
+ subagentName: subagentName || void 0,
70206
+ errorType: lastError ? getErrorType(lastError) : void 0,
70207
+ errorStatusCode: lastError ? getErrorStatus(lastError) : void 0,
69265
70208
  ...retrySnapshot
69266
70209
  });
69267
70210
  }
@@ -69333,7 +70276,7 @@ var LoggingContentGenerator = class {
69333
70276
  try {
69334
70277
  await this.logOpenAIInteraction(openaiRequest, response, error, promptId);
69335
70278
  } catch (loggingError) {
69336
- debugLogger9.warn("Failed to log OpenAI interaction:", loggingError);
70279
+ debugLogger10.warn("Failed to log OpenAI interaction:", loggingError);
69337
70280
  }
69338
70281
  }
69339
70282
  convertGeminiResponseToOpenAIForLogging(response, openaiRequest) {
@@ -69802,7 +70745,7 @@ var QWEN_OAUTH_ALLOWED_MODELS = QWEN_OAUTH_MODELS.map(
69802
70745
  );
69803
70746
 
69804
70747
  // packages/core/src/models/modelRegistry.ts
69805
- var debugLogger10 = createDebugLogger("MODEL_REGISTRY");
70748
+ var debugLogger11 = createDebugLogger("MODEL_REGISTRY");
69806
70749
  function validateAuthTypeKey(key) {
69807
70750
  if (Object.values(AuthType).includes(key)) {
69808
70751
  return key;
@@ -69840,7 +70783,7 @@ var ModelRegistry = class {
69840
70783
  for (const [rawKey, models] of Object.entries(modelProvidersConfig)) {
69841
70784
  const authType = validateAuthTypeKey(rawKey);
69842
70785
  if (!authType) {
69843
- debugLogger10.warn(
70786
+ debugLogger11.warn(
69844
70787
  `Invalid authType key "${rawKey}" in modelProviders config. Expected one of: ${Object.values(AuthType).join(", ")}. Skipping.`
69845
70788
  );
69846
70789
  continue;
@@ -69863,7 +70806,7 @@ var ModelRegistry = class {
69863
70806
  for (const config of models) {
69864
70807
  const key = modelRegistryKey(config.id, config.baseUrl);
69865
70808
  if (modelMap.has(key)) {
69866
- debugLogger10.warn(
70809
+ debugLogger11.warn(
69867
70810
  `Duplicate model id "${config.id}"${config.baseUrl ? ` with baseUrl "${config.baseUrl}"` : ""} for authType "${authType}". Using the first registered config.`
69868
70811
  );
69869
70812
  continue;
@@ -69978,7 +70921,7 @@ var ModelRegistry = class {
69978
70921
  for (const [rawKey, models] of Object.entries(modelProvidersConfig)) {
69979
70922
  const authType = validateAuthTypeKey(rawKey);
69980
70923
  if (!authType) {
69981
- debugLogger10.warn(
70924
+ debugLogger11.warn(
69982
70925
  `Invalid authType key "${rawKey}" in modelProviders config. Expected one of: ${Object.values(AuthType).join(", ")}. Skipping.`
69983
70926
  );
69984
70927
  continue;
@@ -71061,11 +72004,11 @@ async function createContentGenerator(generatorConfig, config, isInitialAuth) {
71061
72004
  let baseGenerator;
71062
72005
  try {
71063
72006
  if (authType === "openai" /* USE_OPENAI */) {
71064
- const { createOpenAIContentGenerator } = await import("./openaiContentGenerator-FTR7CDWF.js");
72007
+ const { createOpenAIContentGenerator } = await import("./openaiContentGenerator-DO27LL6O.js");
71065
72008
  baseGenerator = createOpenAIContentGenerator(generatorConfig, config);
71066
72009
  } else if (authType === "qwen-oauth" /* QWEN_OAUTH */) {
71067
- const { getQwenOAuthClient: getQwenOauthClient } = await import("./qwenOAuth2-EFSECGHF.js");
71068
- const { QwenContentGenerator } = await import("./qwenContentGenerator-U5UFQ566.js");
72010
+ const { getQwenOAuthClient: getQwenOauthClient } = await import("./qwenOAuth2-KK433U33.js");
72011
+ const { QwenContentGenerator } = await import("./qwenContentGenerator-DQLGLQSH.js");
71069
72012
  try {
71070
72013
  const qwenClient = await getQwenOauthClient(
71071
72014
  config,
@@ -71083,10 +72026,10 @@ async function createContentGenerator(generatorConfig, config, isInitialAuth) {
71083
72026
  throw new Error(error instanceof Error ? error.message : String(error));
71084
72027
  }
71085
72028
  } else if (authType === "anthropic" /* USE_ANTHROPIC */) {
71086
- const { createAnthropicContentGenerator } = await import("./anthropicContentGenerator-M45EVVRM.js");
72029
+ const { createAnthropicContentGenerator } = await import("./anthropicContentGenerator-DCI26OQF.js");
71087
72030
  baseGenerator = createAnthropicContentGenerator(generatorConfig, config);
71088
72031
  } else if (authType === "gemini" /* USE_GEMINI */ || authType === "vertex-ai" /* USE_VERTEX_AI */) {
71089
- const { createGeminiContentGenerator } = await import("./geminiContentGenerator-I4H2NLJG.js");
72032
+ const { createGeminiContentGenerator } = await import("./geminiContentGenerator-CAKHT5YE.js");
71090
72033
  baseGenerator = createGeminiContentGenerator(generatorConfig, config);
71091
72034
  } else {
71092
72035
  throw new Error(
@@ -71961,7 +72904,7 @@ function logStartSession(config, event) {
71961
72904
  skills: event.skills,
71962
72905
  subagents: event.subagents
71963
72906
  };
71964
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
72907
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
71965
72908
  const logRecord = {
71966
72909
  body: "CLI configuration loaded.",
71967
72910
  attributes
@@ -71985,7 +72928,7 @@ function logUserPrompt(config, event) {
71985
72928
  if (shouldLogUserPrompts(config)) {
71986
72929
  attributes["prompt"] = event.prompt;
71987
72930
  }
71988
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
72931
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
71989
72932
  const logRecord = {
71990
72933
  body: `User prompt. Length: ${event.prompt_length}.`,
71991
72934
  attributes
@@ -72002,7 +72945,7 @@ function logUserRetry(config, event) {
72002
72945
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
72003
72946
  prompt_id: event.prompt_id
72004
72947
  };
72005
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
72948
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72006
72949
  const logRecord = {
72007
72950
  body: `User retry.`,
72008
72951
  attributes
@@ -72016,7 +72959,7 @@ function logToolCall(config, event) {
72016
72959
  "event.name": EVENT_TOOL_CALL,
72017
72960
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72018
72961
  };
72019
- uiTelemetryService.addEvent(uiEvent);
72962
+ uiTelemetryService.addEvent(uiEvent, config.getSessionId());
72020
72963
  if (!isInternalPromptId(event.prompt_id)) {
72021
72964
  config.getChatRecordingService()?.recordUiTelemetryEvent(uiEvent);
72022
72965
  }
@@ -72035,7 +72978,7 @@ function logToolCall(config, event) {
72035
72978
  attributes["error.type"] = event.error_type;
72036
72979
  }
72037
72980
  }
72038
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
72981
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72039
72982
  const logRecord = {
72040
72983
  body: `Tool call: ${event.function_name}${event.decision ? `. Decision: ${event.decision}` : ""}. Success: ${event.success}. Duration: ${event.duration_ms}ms.`,
72041
72984
  attributes
@@ -72058,7 +73001,7 @@ function logToolOutputTruncated(config, event) {
72058
73001
  "event.name": "tool_output_truncated",
72059
73002
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72060
73003
  };
72061
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73004
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72062
73005
  const logRecord = {
72063
73006
  body: `Tool output truncated for ${event.tool_name}.`,
72064
73007
  attributes
@@ -72088,7 +73031,7 @@ function logFileOperation(config, event) {
72088
73031
  if (event.programming_language) {
72089
73032
  attributes["programming_language"] = event.programming_language;
72090
73033
  }
72091
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73034
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72092
73035
  const logRecord = {
72093
73036
  body: `File operation: ${event.operation}. Lines: ${event.lines}.`,
72094
73037
  attributes
@@ -72111,7 +73054,7 @@ function logApiRequest(config, event) {
72111
73054
  "event.name": EVENT_API_REQUEST,
72112
73055
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72113
73056
  };
72114
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73057
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72115
73058
  const logRecord = {
72116
73059
  body: `API request to ${event.model}.`,
72117
73060
  attributes
@@ -72128,7 +73071,7 @@ function logFlashFallback(config, event) {
72128
73071
  "event.name": EVENT_FLASH_FALLBACK,
72129
73072
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72130
73073
  };
72131
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73074
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72132
73075
  const logRecord = {
72133
73076
  body: `Switching to flash as Fallback.`,
72134
73077
  attributes
@@ -72145,7 +73088,7 @@ function logRipgrepFallback(config, event) {
72145
73088
  "event.name": EVENT_RIPGREP_FALLBACK,
72146
73089
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72147
73090
  };
72148
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73091
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72149
73092
  const logRecord = {
72150
73093
  body: `Switching to grep as fallback.`,
72151
73094
  attributes
@@ -72159,7 +73102,7 @@ function logApiError(config, event) {
72159
73102
  "event.name": EVENT_API_ERROR,
72160
73103
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72161
73104
  };
72162
- uiTelemetryService.addEvent(uiEvent);
73105
+ uiTelemetryService.addEvent(uiEvent, config.getSessionId());
72163
73106
  if (!isInternalPromptId(event.prompt_id)) {
72164
73107
  config.getChatRecordingService()?.recordUiTelemetryEvent(uiEvent);
72165
73108
  }
@@ -72180,7 +73123,7 @@ function logApiError(config, event) {
72180
73123
  if (typeof event.status_code === "number") {
72181
73124
  attributes[SemanticAttributes.HTTP_STATUS_CODE] = event.status_code;
72182
73125
  }
72183
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73126
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72184
73127
  const logRecord = {
72185
73128
  body: `API error for ${event.model}. Error: ${event.error_message}. Duration: ${event.duration_ms}ms.`,
72186
73129
  attributes
@@ -72199,7 +73142,7 @@ function logApiCancel(config, event) {
72199
73142
  "event.name": EVENT_API_CANCEL,
72200
73143
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72201
73144
  };
72202
- uiTelemetryService.addEvent(uiEvent);
73145
+ uiTelemetryService.addEvent(uiEvent, config.getSessionId());
72203
73146
  QwenLogger.getInstance(config)?.logApiCancelEvent(event);
72204
73147
  if (!isTelemetrySdkInitialized()) return;
72205
73148
  const attributes = {
@@ -72209,7 +73152,7 @@ function logApiCancel(config, event) {
72209
73152
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString(),
72210
73153
  model_name: event.model
72211
73154
  };
72212
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73155
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72213
73156
  const logRecord = {
72214
73157
  body: `API request cancelled for ${event.model}.`,
72215
73158
  attributes
@@ -72223,7 +73166,7 @@ function logApiResponse(config, event) {
72223
73166
  "event.name": EVENT_API_RESPONSE,
72224
73167
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72225
73168
  };
72226
- uiTelemetryService.addEvent(uiEvent);
73169
+ uiTelemetryService.addEvent(uiEvent, config.getSessionId());
72227
73170
  if (!isInternalPromptId(event.prompt_id)) {
72228
73171
  config.getChatRecordingService()?.recordUiTelemetryEvent(uiEvent);
72229
73172
  }
@@ -72243,7 +73186,7 @@ function logApiResponse(config, event) {
72243
73186
  attributes[SemanticAttributes.HTTP_STATUS_CODE] = event.status_code;
72244
73187
  }
72245
73188
  }
72246
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73189
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72247
73190
  const logRecord = {
72248
73191
  body: `API response from ${event.model}. Status: ${event.status_code || "N/A"}. Duration: ${event.duration_ms}ms.`,
72249
73192
  attributes
@@ -72278,7 +73221,7 @@ function logLoopDetected(config, event) {
72278
73221
  ...getCommonAttributes(config),
72279
73222
  ...event
72280
73223
  };
72281
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73224
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72282
73225
  const logRecord = {
72283
73226
  body: `Loop detected. Type: ${event.loop_type}.`,
72284
73227
  attributes
@@ -72298,7 +73241,7 @@ function logNextSpeakerCheck(config, event) {
72298
73241
  ...event,
72299
73242
  "event.name": EVENT_NEXT_SPEAKER_CHECK
72300
73243
  };
72301
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73244
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72302
73245
  const logRecord = {
72303
73246
  body: `Next speaker check.`,
72304
73247
  attributes
@@ -72314,7 +73257,7 @@ function logSlashCommand(config, event) {
72314
73257
  ...event,
72315
73258
  "event.name": EVENT_SLASH_COMMAND
72316
73259
  };
72317
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73260
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72318
73261
  const logRecord = {
72319
73262
  body: `Slash command: ${event.command}.`,
72320
73263
  attributes
@@ -72330,7 +73273,7 @@ function logIdeConnection(config, event) {
72330
73273
  ...event,
72331
73274
  "event.name": EVENT_IDE_CONNECTION
72332
73275
  };
72333
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73276
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72334
73277
  const logRecord = {
72335
73278
  body: `Ide connection. Type: ${event.connection_type}.`,
72336
73279
  attributes
@@ -72346,7 +73289,7 @@ function logConversationFinishedEvent(config, event) {
72346
73289
  ...event,
72347
73290
  "event.name": EVENT_CONVERSATION_FINISHED
72348
73291
  };
72349
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73292
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72350
73293
  const logRecord = {
72351
73294
  body: `Conversation finished.`,
72352
73295
  attributes
@@ -72361,7 +73304,7 @@ function logChatCompression(config, event) {
72361
73304
  ...event,
72362
73305
  "event.name": EVENT_CHAT_COMPRESSION
72363
73306
  };
72364
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73307
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72365
73308
  const logRecord = {
72366
73309
  body: `Chat compression (Saved ${event.tokens_before - event.tokens_after} tokens)`,
72367
73310
  attributes
@@ -72380,7 +73323,7 @@ function logKittySequenceOverflow(config, event) {
72380
73323
  ...getCommonAttributes(config),
72381
73324
  ...event
72382
73325
  };
72383
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73326
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72384
73327
  const logRecord = {
72385
73328
  body: `Kitty sequence buffer overflow: ${event.sequence_length} bytes`,
72386
73329
  attributes
@@ -72396,7 +73339,7 @@ function logContentRetry(config, event) {
72396
73339
  ...event,
72397
73340
  "event.name": EVENT_CONTENT_RETRY
72398
73341
  };
72399
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73342
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72400
73343
  const logRecord = {
72401
73344
  body: `Content retry attempt ${event.attempt_number} due to ${event.error_type}.`,
72402
73345
  attributes
@@ -72413,7 +73356,7 @@ function logContentRetryFailure(config, event) {
72413
73356
  ...event,
72414
73357
  "event.name": EVENT_CONTENT_RETRY_FAILURE
72415
73358
  };
72416
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73359
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72417
73360
  const logRecord = {
72418
73361
  body: `All content retries failed after ${event.total_attempts} attempts.`,
72419
73362
  attributes
@@ -72430,7 +73373,7 @@ function logApiRetry(config, event) {
72430
73373
  ...event,
72431
73374
  "event.name": EVENT_API_RETRY
72432
73375
  };
72433
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73376
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72434
73377
  const logRecord = {
72435
73378
  body: `API retry attempt ${event.attempt_number} for ${event.model} (status ${event.status_code ?? "unknown"}).`,
72436
73379
  attributes
@@ -72448,7 +73391,7 @@ function logSubagentExecution(config, event) {
72448
73391
  "event.name": EVENT_SUBAGENT_EXECUTION,
72449
73392
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72450
73393
  };
72451
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73394
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72452
73395
  const logRecord = {
72453
73396
  body: `Subagent execution: ${event.subagent_name}.`,
72454
73397
  attributes
@@ -72470,7 +73413,7 @@ function logModelSlashCommand(config, event) {
72470
73413
  ...event,
72471
73414
  "event.name": EVENT_MODEL_SLASH_COMMAND
72472
73415
  };
72473
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73416
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72474
73417
  const logRecord = {
72475
73418
  body: `Model slash command. Model: ${event.model_name}`,
72476
73419
  attributes
@@ -72496,7 +73439,7 @@ function logExtensionInstallEvent(config, event) {
72496
73439
  extension_source: event.extension_source,
72497
73440
  status: event.status
72498
73441
  };
72499
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73442
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72500
73443
  const logRecord = {
72501
73444
  body: `Installed extension ${event.extension_name}`,
72502
73445
  attributes
@@ -72513,7 +73456,7 @@ function logExtensionUninstall(config, event) {
72513
73456
  "event.name": EVENT_EXTENSION_UNINSTALL,
72514
73457
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72515
73458
  };
72516
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73459
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72517
73460
  const logRecord = {
72518
73461
  body: `Uninstalled extension ${event.extension_name}`,
72519
73462
  attributes
@@ -72534,7 +73477,7 @@ async function logExtensionUpdateEvent(config, event) {
72534
73477
  extension_version: event.extension_version,
72535
73478
  extension_source: event.extension_source
72536
73479
  };
72537
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73480
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72538
73481
  const logRecord = {
72539
73482
  body: `Updated extension ${event.extension_name} from ${event.extension_previous_version} to ${event.extension_version}`,
72540
73483
  attributes
@@ -72551,7 +73494,7 @@ function logExtensionEnable(config, event) {
72551
73494
  "event.name": EVENT_EXTENSION_ENABLE,
72552
73495
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72553
73496
  };
72554
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73497
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72555
73498
  const logRecord = {
72556
73499
  body: `Enabled extension ${event.extension_name}`,
72557
73500
  attributes
@@ -72568,7 +73511,7 @@ function logExtensionDisable(config, event) {
72568
73511
  "event.name": EVENT_EXTENSION_DISABLE,
72569
73512
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72570
73513
  };
72571
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73514
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72572
73515
  const logRecord = {
72573
73516
  body: `Disabled extension ${event.extension_name}`,
72574
73517
  attributes
@@ -72591,7 +73534,7 @@ function logAuth(config, event) {
72591
73534
  if (event.error_message) {
72592
73535
  attributes["error.message"] = event.error_message;
72593
73536
  }
72594
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73537
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72595
73538
  const logRecord = {
72596
73539
  body: `Auth event: ${event.action_type} ${event.status} for ${event.auth_type}`,
72597
73540
  attributes
@@ -72608,7 +73551,7 @@ function logSkillLaunch(config, event) {
72608
73551
  "event.name": EVENT_SKILL_LAUNCH,
72609
73552
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72610
73553
  };
72611
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73554
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72612
73555
  const logRecord = {
72613
73556
  body: `Skill launch: ${event.skill_name}. Success: ${event.success}.`,
72614
73557
  attributes
@@ -72622,7 +73565,7 @@ function logUserFeedback(config, event) {
72622
73565
  "event.name": EVENT_USER_FEEDBACK,
72623
73566
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72624
73567
  };
72625
- uiTelemetryService.addEvent(uiEvent);
73568
+ uiTelemetryService.addEvent(uiEvent, config.getSessionId());
72626
73569
  config.getChatRecordingService()?.recordUiTelemetryEvent(uiEvent);
72627
73570
  QwenLogger.getInstance(config)?.logUserFeedbackEvent(event);
72628
73571
  if (!isTelemetrySdkInitialized()) return;
@@ -72632,7 +73575,7 @@ function logUserFeedback(config, event) {
72632
73575
  "event.name": EVENT_USER_FEEDBACK,
72633
73576
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72634
73577
  };
72635
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73578
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72636
73579
  const logRecord = {
72637
73580
  body: `User feedback: Rating ${event.rating} for session ${event.session_id}.`,
72638
73581
  attributes
@@ -72650,7 +73593,7 @@ function logArenaSessionStarted(config, event) {
72650
73593
  "event.name": EVENT_ARENA_SESSION_STARTED,
72651
73594
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72652
73595
  };
72653
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73596
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72654
73597
  const logRecord = {
72655
73598
  body: `Arena session started. Agents: ${event.model_ids.length}.`,
72656
73599
  attributes
@@ -72668,7 +73611,7 @@ function logArenaAgentCompleted(config, event) {
72668
73611
  "event.name": EVENT_ARENA_AGENT_COMPLETED,
72669
73612
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72670
73613
  };
72671
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73614
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72672
73615
  const logRecord = {
72673
73616
  body: `Arena agent ${event.agent_model_id} ${event.status}. Duration: ${event.duration_ms}ms. Tokens: ${event.total_tokens}.`,
72674
73617
  attributes
@@ -72693,7 +73636,7 @@ function logArenaSessionEnded(config, event) {
72693
73636
  "event.name": EVENT_ARENA_SESSION_ENDED,
72694
73637
  "event.timestamp": (/* @__PURE__ */ new Date()).toISOString()
72695
73638
  };
72696
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73639
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72697
73640
  const logRecord = {
72698
73641
  body: `Arena session ended: ${event.status}.${event.winner_model_id ? ` Winner: ${event.winner_model_id}.` : ""}`,
72699
73642
  attributes
@@ -72743,7 +73686,7 @@ function logPromptSuggestion(config, event) {
72743
73686
  if (event.reason) {
72744
73687
  attributes["reason"] = event.reason;
72745
73688
  }
72746
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73689
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72747
73690
  const logRecord = {
72748
73691
  body: `Prompt suggestion: ${event.outcome}.`,
72749
73692
  attributes
@@ -72767,7 +73710,7 @@ function logSpeculation(config, event) {
72767
73710
  if (event.boundary_type) {
72768
73711
  attributes["boundary_type"] = event.boundary_type;
72769
73712
  }
72770
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73713
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72771
73714
  const logRecord = {
72772
73715
  body: `Speculation: ${event.outcome}.`,
72773
73716
  attributes
@@ -72790,7 +73733,7 @@ function logMemoryExtract(config, event) {
72790
73733
  if (event.skipped_reason) {
72791
73734
  attributes["skipped_reason"] = event.skipped_reason;
72792
73735
  }
72793
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73736
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72794
73737
  logger.emit({
72795
73738
  body: `Memory extract: ${event.status}. Patches: ${event.patches_count}. Topics: ${event.touched_topics || "none"}.`,
72796
73739
  attributes
@@ -72815,7 +73758,7 @@ function logMemoryDream(config, event) {
72815
73758
  touched_topics: event.touched_topics,
72816
73759
  duration_ms: event.duration_ms
72817
73760
  };
72818
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73761
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72819
73762
  logger.emit({
72820
73763
  body: `Memory dream: ${event.status}. Deduped: ${event.deduped_entries}. Topics: ${event.touched_topics || "none"}.`,
72821
73764
  attributes
@@ -72839,7 +73782,7 @@ function logMemoryRecall(config, event) {
72839
73782
  strategy: event.strategy,
72840
73783
  duration_ms: event.duration_ms
72841
73784
  };
72842
- const logger = import_api_logs.logs.getLogger(SERVICE_NAME);
73785
+ const logger = import_api_logs2.logs.getLogger(SERVICE_NAME);
72843
73786
  logger.emit({
72844
73787
  body: `Memory recall: strategy=${event.strategy}. Selected ${event.docs_selected}/${event.docs_scanned} docs.`,
72845
73788
  attributes
@@ -72879,7 +73822,7 @@ function memoryFreshnessNote(mtimeMs) {
72879
73822
  __name(memoryFreshnessNote, "memoryFreshnessNote");
72880
73823
 
72881
73824
  // packages/core/src/tools/read-file.ts
72882
- var debugLogger11 = createDebugLogger("READ_FILE_CACHE");
73825
+ var debugLogger12 = createDebugLogger("READ_FILE_CACHE");
72883
73826
  var ReadFileToolInvocation = class extends BaseToolInvocation {
72884
73827
  constructor(config, params) {
72885
73828
  super(params);
@@ -72948,7 +73891,7 @@ var ReadFileToolInvocation = class extends BaseToolInvocation {
72948
73891
  try {
72949
73892
  stats = await fs7.stat(absPath);
72950
73893
  } catch (err) {
72951
- debugLogger11.debug("stat-failed", {
73894
+ debugLogger12.debug("stat-failed", {
72952
73895
  path: absPath,
72953
73896
  code: err.code
72954
73897
  });
@@ -72958,10 +73901,10 @@ var ReadFileToolInvocation = class extends BaseToolInvocation {
72958
73901
  if (status.state === "fresh" && status.entry.lastReadAt !== void 0 && status.entry.lastReadWasFull && status.entry.lastReadCacheable && // Only quote-back if that read is still in history (issue
72959
73902
  // #4239: idle microcompaction flips this off when it blanks it).
72960
73903
  status.entry.readResidentInHistory && (status.entry.lastWriteAt === void 0 || status.entry.lastReadAt > status.entry.lastWriteAt)) {
72961
- debugLogger11.debug("hit", { path: absPath });
73904
+ debugLogger12.debug("hit", { path: absPath });
72962
73905
  return this.unchangedResult(absPath);
72963
73906
  }
72964
- debugLogger11.debug("miss", { path: absPath, state: status.state });
73907
+ debugLogger12.debug("miss", { path: absPath, state: status.state });
72965
73908
  }
72966
73909
  const result = await processSingleFileContent(
72967
73910
  this.params.file_path,
@@ -73100,6 +74043,13 @@ var ReadFileTool = class _ReadFileTool extends BaseDeclarativeTool {
73100
74043
  __name(this, "ReadFileTool");
73101
74044
  }
73102
74045
  static Name = ToolNames.READ_FILE;
74046
+ // Self-managed: ReadFile controls its own size via line-based paging
74047
+ // (offset/limit, default 2000 lines), so it is exempt from the scheduler's
74048
+ // char-based truncation. Oversized reads are bounded by the per-message
74049
+ // batch budget instead.
74050
+ get maxOutputChars() {
74051
+ return Number.POSITIVE_INFINITY;
74052
+ }
73103
74053
  validateToolParamValues(params) {
73104
74054
  const filePath = unescapePath(params.file_path.trim());
73105
74055
  params.file_path = filePath;
@@ -73258,6 +74208,7 @@ export {
73258
74208
  truncateSpanError,
73259
74209
  startInteractionSpan,
73260
74210
  endInteractionSpan,
74211
+ withInteractionSpan,
73261
74212
  startLLMRequestSpan,
73262
74213
  endLLMRequestSpan,
73263
74214
  startToolSpan,
@@ -73278,6 +74229,7 @@ export {
73278
74229
  initializeTelemetry,
73279
74230
  refreshSessionContext,
73280
74231
  shutdownTelemetry,
74232
+ forceFlushMetrics,
73281
74233
  logStartSession,
73282
74234
  logUserPrompt,
73283
74235
  logUserRetry,
@@ -73323,7 +74275,11 @@ export {
73323
74275
  memoryAge,
73324
74276
  memoryFreshnessText,
73325
74277
  ReadFileTool,
74278
+ TOOL_OUTPUT_TRUNCATED_PREFIX,
73326
74279
  truncateToolOutput,
74280
+ truncateLlmContent,
74281
+ isAlreadyTruncated,
74282
+ persistAndTruncateToolResult,
73327
74283
  DiscoveredMCPTool,
73328
74284
  generateValidName,
73329
74285
  StartSessionEvent,
@@ -73382,6 +74338,30 @@ export {
73382
74338
  parseBooleanEnvFlag,
73383
74339
  parseTelemetryTargetValue,
73384
74340
  resolveTelemetrySettings,
74341
+ DAEMON_TRACEPARENT_META_KEY,
74342
+ DAEMON_TRACESTATE_META_KEY,
74343
+ hashDaemonWorkspace,
74344
+ withDaemonSpan,
74345
+ withDaemonRequestSpan,
74346
+ withDaemonBridgeSpan,
74347
+ recordDaemonHttpResponse,
74348
+ addDaemonRequestAttribute,
74349
+ recordDaemonError,
74350
+ emitDaemonLog,
74351
+ captureDaemonTelemetryContext,
74352
+ runWithDaemonTelemetryContext,
74353
+ injectDaemonTraceContext,
74354
+ extractDaemonTraceContext,
74355
+ createDaemonBridgeTelemetry,
74356
+ initializeDaemonMetrics,
74357
+ registerDaemonGaugeCallbacks,
74358
+ recordDaemonHttpRequest,
74359
+ recordDaemonSessionLifecycle,
74360
+ recordDaemonChannelLifecycle,
74361
+ recordDaemonPromptQueueWait,
74362
+ recordDaemonPromptDuration,
74363
+ recordDaemonBridgeError,
74364
+ recordDaemonCancel,
73385
74365
  TelemetryTarget,
73386
74366
  DEFAULT_TELEMETRY_TARGET,
73387
74367
  DEFAULT_OTLP_ENDPOINT,