@unbrained/pm-cli 2026.10.15 → 2026.10.18

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 (275) hide show
  1. package/.agents/skills/pm-developer/references/COMMAND_PLAYBOOK.md +1 -1
  2. package/.claude-plugin/marketplace.json +1 -1
  3. package/AGENTS.md +1 -0
  4. package/CHANGELOG.md +45 -0
  5. package/dist/cli/extension-command-options.d.ts +3 -1
  6. package/dist/cli/extension-command-options.js +1 -1
  7. package/dist/cli/help-content.js +2 -2
  8. package/dist/cli/register-list-query.js +2 -2
  9. package/dist/cli/register-mutation.js +2 -2
  10. package/dist/cli/register-operations.js +1 -1
  11. package/dist/cli/register-structured-mutation.d.ts +0 -5
  12. package/dist/cli/register-structured-mutation.js +1 -1
  13. package/dist/cli/runtime/invocation-options.js +1 -1
  14. package/dist/cli-bundle/bundle-manifest.json +1 -1
  15. package/dist/cli-bundle/chunks/{chunk-7VHINXZP.js → chunk-4GA4MUTE.js} +2 -2
  16. package/dist/cli-bundle/chunks/{chunk-RJ5N44WY.js → chunk-4V6ONLI6.js} +2 -2
  17. package/dist/cli-bundle/chunks/{chunk-LNKLQYBG.js → chunk-6VZKYJW7.js} +2 -2
  18. package/dist/cli-bundle/chunks/chunk-7PATQWTH.js +20 -0
  19. package/dist/cli-bundle/chunks/chunk-7WIEAGDS.js +2 -0
  20. package/dist/cli-bundle/chunks/{chunk-52EZH2QQ.js → chunk-AETP4JEM.js} +2 -2
  21. package/dist/cli-bundle/chunks/{chunk-WBBW3WQX.js → chunk-FIJOSX2C.js} +28 -28
  22. package/dist/cli-bundle/chunks/chunk-LUKVNL72.js +2 -0
  23. package/dist/cli-bundle/chunks/{chunk-NC3QVGDD.js → chunk-OJ77ZQN3.js} +2 -2
  24. package/dist/cli-bundle/chunks/chunk-PYRREEUB.js +30 -0
  25. package/dist/cli-bundle/chunks/chunk-RHQJ6VWC.js +237 -0
  26. package/dist/cli-bundle/chunks/{chunk-N56CAQBU.js → chunk-RNABUEFB.js} +52 -52
  27. package/dist/cli-bundle/chunks/chunk-TO6CIV4C.js +2 -0
  28. package/dist/cli-bundle/chunks/{chunk-JGKTOBVB.js → chunk-ZZED447K.js} +4 -4
  29. package/dist/cli-bundle/chunks/{register-list-query-FKKFQ66D.js → register-list-query-PUCVYYBD.js} +7 -7
  30. package/dist/cli-bundle/chunks/register-mutation-GGGVBXD5.js +20 -0
  31. package/dist/cli-bundle/chunks/{register-operations-GEQ2H7PS.js → register-operations-NRZ6Q4QE.js} +2 -2
  32. package/dist/cli-bundle/chunks/{register-setup-PSJTQBBO.js → register-setup-MV3P3YSF.js} +2 -2
  33. package/dist/cli-bundle/focused-chunks/chunk-2MPQUMTF.js +2 -0
  34. package/dist/cli-bundle/focused-chunks/{chunk-H3P77KVU.js → chunk-5UKCSZWT.js} +2 -2
  35. package/dist/cli-bundle/focused-chunks/{chunk-4KQFMOM7.js → chunk-A4ZHHTEX.js} +5 -5
  36. package/dist/cli-bundle/focused-chunks/{chunk-5OO54BIV.js → chunk-B4YLP5ZB.js} +3 -3
  37. package/dist/cli-bundle/focused-chunks/chunk-BFEMT5U3.js +20 -0
  38. package/dist/cli-bundle/focused-chunks/{chunk-THYQR3ON.js → chunk-FW7CSSKL.js} +61 -61
  39. package/dist/cli-bundle/focused-chunks/{chunk-3RNUMVK4.js → chunk-HYPRPSYD.js} +2 -2
  40. package/dist/cli-bundle/focused-chunks/{chunk-FQKPOZKS.js → chunk-IRVL4UXR.js} +2 -2
  41. package/dist/cli-bundle/focused-chunks/{chunk-Q4VNCTR2.js → chunk-L55KQ2KT.js} +2 -2
  42. package/dist/cli-bundle/focused-chunks/{chunk-52I2SNKJ.js → chunk-MASIOFPG.js} +2 -2
  43. package/dist/cli-bundle/focused-chunks/chunk-RJ3EIHDU.js +26 -0
  44. package/dist/cli-bundle/focused-chunks/chunk-SEL4Z2OO.js +167 -0
  45. package/dist/cli-bundle/focused-chunks/{chunk-TYLG5VEB.js → chunk-TB7F4FCR.js} +2 -2
  46. package/dist/cli-bundle/focused-chunks/{chunk-KIIFVULU.js → chunk-TZUIBG3P.js} +2 -2
  47. package/dist/cli-bundle/focused-chunks/{chunk-N6FUKTZS.js → chunk-Z7YIFCNE.js} +2 -2
  48. package/dist/cli-bundle/focused-chunks/{chunk-5KRACGBK.js → chunk-ZDBS2DCT.js} +3 -3
  49. package/dist/cli-bundle/main.js +27 -27
  50. package/dist/cli-bundle/sdk-authoring.js +1 -1
  51. package/dist/cli-bundle/sdk-contracts.js +2 -2
  52. package/dist/cli-bundle/sdk-core.js +23 -23
  53. package/dist/cli-bundle/sdk-governance.js +1 -1
  54. package/dist/cli-bundle/sdk-graph.js +1 -1
  55. package/dist/cli-bundle/sdk-merge.js +55 -54
  56. package/dist/cli-bundle/sdk-query.js +1 -1
  57. package/dist/cli-bundle/sdk-runtime.js +1 -1
  58. package/dist/cli-bundle/sdk-testing.js +1 -1
  59. package/dist/cli-bundle/sdk.js +7 -7
  60. package/dist/core/extensions/extension-types.d.ts +15 -0
  61. package/dist/core/extensions/extension-types.js +1 -1
  62. package/dist/core/extensions/flag-value-types.d.ts +16 -0
  63. package/dist/core/extensions/flag-value-types.js +1 -1
  64. package/dist/core/extensions/registration-contracts.js +1 -1
  65. package/dist/core/history/event-index.d.ts +8 -1
  66. package/dist/core/history/event-index.js +19 -18
  67. package/dist/core/item/item-format.js +3 -3
  68. package/dist/core/lock/lock.d.ts +8 -1
  69. package/dist/core/lock/lock.js +3 -3
  70. package/dist/core/output/mutation-projection.d.ts +0 -21
  71. package/dist/core/output/mutation-projection.js +1 -1
  72. package/dist/core/output/output.js +2 -2
  73. package/dist/core/schema/type-workflows.d.ts +1 -1
  74. package/dist/core/schema/type-workflows.js +1 -1
  75. package/dist/core/shared/text-normalization.d.ts +2 -0
  76. package/dist/core/shared/text-normalization.js +1 -1
  77. package/dist/core/store/item-mutation-precondition.d.ts +11 -0
  78. package/dist/core/store/item-mutation-precondition.js +2 -0
  79. package/dist/core/store/item-store.js +1 -1
  80. package/dist/core/store/paths.js +1 -1
  81. package/dist/core/telemetry/policy.d.ts +2 -0
  82. package/dist/core/telemetry/policy.js +1 -1
  83. package/dist/core/telemetry/runtime.d.ts +5 -3
  84. package/dist/core/telemetry/runtime.js +3 -3
  85. package/dist/mcp/server.js +1 -1
  86. package/dist/mcp/tool-definitions.js +1 -1
  87. package/dist/sdk/cli-contracts/agent-output-contracts.js +1 -1
  88. package/dist/sdk/cli-contracts/flag-contracts.js +1 -1
  89. package/dist/sdk/cli-contracts/flag-lexicon-contracts.js +1 -1
  90. package/dist/sdk/cli-contracts/registration-helpers.d.ts +1 -1
  91. package/dist/sdk/cli-contracts/registration-helpers.js +1 -1
  92. package/dist/sdk/cli-contracts/tool-schema.d.ts +2 -2
  93. package/dist/sdk/cli-contracts/tool-schema.js +1 -1
  94. package/dist/sdk/context-intent-contracts.js +1 -1
  95. package/dist/sdk/core.d.ts +2 -1
  96. package/dist/sdk/core.js +1 -1
  97. package/dist/sdk/generated/generated-error-code-catalog-part-1.js +1 -1
  98. package/dist/sdk/generated/generated-error-code-catalog-part-2.js +1 -1
  99. package/dist/sdk/governance/health/projection.d.ts +37 -0
  100. package/dist/sdk/governance/health/projection.js +2 -0
  101. package/dist/sdk/governance/health.d.ts +7 -18
  102. package/dist/sdk/governance/health.js +2 -2
  103. package/dist/sdk/guide-topics.js +1 -1
  104. package/dist/sdk/index.d.ts +2 -1
  105. package/dist/sdk/index.js +1 -1
  106. package/dist/sdk/item-transaction.d.ts +72 -9
  107. package/dist/sdk/item-transaction.js +1 -1
  108. package/dist/sdk/lifecycle/claim.d.ts +15 -1
  109. package/dist/sdk/lifecycle/claim.js +1 -1
  110. package/dist/sdk/lifecycle/close.d.ts +2 -8
  111. package/dist/sdk/lifecycle/close.js +1 -1
  112. package/dist/sdk/lifecycle/core-item-fields.d.ts +6 -0
  113. package/dist/sdk/lifecycle/core-item-fields.js +2 -0
  114. package/dist/sdk/lifecycle/mcp-actions.js +1 -1
  115. package/dist/sdk/lifecycle/mutation-option-validation.d.ts +2 -0
  116. package/dist/sdk/lifecycle/mutation-option-validation.js +2 -0
  117. package/dist/sdk/lifecycle/release-handoff.d.ts +12 -0
  118. package/dist/sdk/lifecycle/release-handoff.js +2 -0
  119. package/dist/sdk/lifecycle/structured-mutation-plan.d.ts +33 -0
  120. package/dist/sdk/lifecycle/structured-mutation-plan.js +2 -0
  121. package/dist/sdk/lifecycle/task-composition.d.ts +2 -2
  122. package/dist/sdk/lifecycle/task-composition.js +1 -1
  123. package/dist/sdk/lifecycle/update.d.ts +3 -11
  124. package/dist/sdk/lifecycle/update.js +1 -1
  125. package/dist/sdk/lifecycle/workflow-transition.d.ts +13 -0
  126. package/dist/sdk/lifecycle/workflow-transition.js +2 -0
  127. package/dist/sdk/lifecycle-policy.d.ts +12 -2
  128. package/dist/sdk/lifecycle-policy.js +1 -1
  129. package/dist/sdk/mutation-events.js +1 -1
  130. package/dist/sdk/public-surface.json +1 -1
  131. package/dist/sdk/query/list.d.ts +2 -0
  132. package/dist/sdk/query/list.js +1 -1
  133. package/dist/sdk/read-output-budget.js +1 -1
  134. package/dist/sdk/runtime-input.js +1 -1
  135. package/dist/sdk/runtime-primitives.d.ts +1 -1
  136. package/dist/sdk/runtime-primitives.js +1 -1
  137. package/dist/sdk/runtime.d.ts +8 -8
  138. package/dist/sdk/runtime.js +1 -1
  139. package/dist/sdk/structured-mutations.d.ts +52 -1
  140. package/dist/sdk/structured-mutations.js +1 -1
  141. package/dist/sdk/workspace-transaction.js +2 -2
  142. package/dist/types.d.ts +2 -2
  143. package/dist/types.js +1 -1
  144. package/docs/AGENT_GUIDE.md +33 -4
  145. package/docs/CLOSE_EVIDENCE_RECOVERY.md +16 -7
  146. package/docs/COMMANDS.md +111 -10
  147. package/docs/CONFIGURATION.md +22 -1
  148. package/docs/DEVELOPMENT_DEPENDENCY_SECURITY.md +22 -3
  149. package/docs/ECOSYSTEM_PLANNING_REVIEW.md +5 -1
  150. package/docs/EXTENSIONS.md +1 -1
  151. package/docs/OUTPUT_PROJECTION_CONTRACTS.md +10 -0
  152. package/docs/RELEASING.md +8 -1
  153. package/docs/SDK.md +114 -2
  154. package/docs/SDK_CONTEXT_COORDINATION.md +71 -7
  155. package/docs/SDK_STORAGE_LIFECYCLE.md +24 -2
  156. package/docs/TESTING.md +23 -0
  157. package/docs/examples/ci/github-actions-pm-extension-gate.yml +1 -1
  158. package/docs/examples/ci/gitlab-ci-pm-extension-gate.yml +1 -1
  159. package/docs/examples/ci/jenkins-pm-extension-gate.Jenkinsfile +1 -1
  160. package/docs/generated/FLAG_LEXICON_BUDGETS.md +1 -1
  161. package/docs/generated/REFUSAL_CLOSURE_CENSUS.md +16 -3
  162. package/marketplace.json +1 -1
  163. package/node_modules/@opentelemetry/core/package.json +2 -1
  164. package/node_modules/@opentelemetry/instrumentation/package.json +2 -1
  165. package/node_modules/@opentelemetry/resources/package.json +2 -1
  166. package/node_modules/@opentelemetry/sdk-trace/package.json +2 -1
  167. package/node_modules/@opentelemetry/sdk-trace-base/package.json +2 -1
  168. package/node_modules/@sentry/core/build/cjs/client.js +5 -4
  169. package/node_modules/@sentry/core/build/cjs/tracing/ai/gen-ai-attributes.js +0 -4
  170. package/node_modules/@sentry/core/build/cjs/tracing/ai/utils.js +33 -23
  171. package/node_modules/@sentry/core/build/cjs/tracing/anthropic-ai/index.js +7 -6
  172. package/node_modules/@sentry/core/build/cjs/tracing/anthropic-ai/streaming.js +3 -1
  173. package/node_modules/@sentry/core/build/cjs/tracing/google-genai/index.js +13 -14
  174. package/node_modules/@sentry/core/build/cjs/tracing/google-genai/streaming.js +6 -1
  175. package/node_modules/@sentry/core/build/cjs/tracing/langchain/utils.js +71 -21
  176. package/node_modules/@sentry/core/build/cjs/tracing/langgraph/utils.js +23 -33
  177. package/node_modules/@sentry/core/build/cjs/tracing/openai/streaming.js +6 -0
  178. package/node_modules/@sentry/core/build/cjs/tracing/openai/utils.js +11 -0
  179. package/node_modules/@sentry/core/build/cjs/tracing/workers-ai/utils.js +1 -1
  180. package/node_modules/@sentry/core/build/cjs/utils/eventUtils.js +4 -0
  181. package/node_modules/@sentry/core/build/cjs/utils/prepareEvent.js +2 -2
  182. package/node_modules/@sentry/core/build/cjs/utils/version.js +1 -1
  183. package/node_modules/@sentry/core/build/esm/client.js +6 -5
  184. package/node_modules/@sentry/core/build/esm/package.json +1 -1
  185. package/node_modules/@sentry/core/build/esm/tracing/ai/gen-ai-attributes.js +1 -3
  186. package/node_modules/@sentry/core/build/esm/tracing/ai/utils.js +34 -24
  187. package/node_modules/@sentry/core/build/esm/tracing/anthropic-ai/index.js +8 -7
  188. package/node_modules/@sentry/core/build/esm/tracing/anthropic-ai/streaming.js +3 -1
  189. package/node_modules/@sentry/core/build/esm/tracing/google-genai/index.js +15 -16
  190. package/node_modules/@sentry/core/build/esm/tracing/google-genai/streaming.js +6 -1
  191. package/node_modules/@sentry/core/build/esm/tracing/langchain/utils.js +73 -24
  192. package/node_modules/@sentry/core/build/esm/tracing/langgraph/utils.js +24 -34
  193. package/node_modules/@sentry/core/build/esm/tracing/openai/streaming.js +6 -0
  194. package/node_modules/@sentry/core/build/esm/tracing/openai/utils.js +11 -0
  195. package/node_modules/@sentry/core/build/esm/tracing/workers-ai/utils.js +2 -2
  196. package/node_modules/@sentry/core/build/esm/utils/eventUtils.js +4 -1
  197. package/node_modules/@sentry/core/build/esm/utils/prepareEvent.js +2 -2
  198. package/node_modules/@sentry/core/build/esm/utils/version.js +1 -1
  199. package/node_modules/@sentry/core/build/types/tracing/ai/utils.d.ts +3 -7
  200. package/node_modules/@sentry/core/build/types/tracing/anthropic-ai/types.d.ts +2 -2
  201. package/node_modules/@sentry/core/build/types/tracing/langchain/types.d.ts +15 -0
  202. package/node_modules/@sentry/core/build/types/tracing/langchain/utils.d.ts +1 -0
  203. package/node_modules/@sentry/core/build/types/tracing/langgraph/utils.d.ts +2 -0
  204. package/node_modules/@sentry/core/build/types/tracing/openai/types.d.ts +2 -0
  205. package/node_modules/@sentry/core/build/types/utils/eventUtils.d.ts +2 -1
  206. package/node_modules/@sentry/core/build/types-ts3.8/tracing/ai/utils.d.ts +3 -7
  207. package/node_modules/@sentry/core/build/types-ts3.8/tracing/anthropic-ai/types.d.ts +2 -2
  208. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langchain/types.d.ts +15 -0
  209. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langchain/utils.d.ts +1 -0
  210. package/node_modules/@sentry/core/build/types-ts3.8/tracing/langgraph/utils.d.ts +2 -0
  211. package/node_modules/@sentry/core/build/types-ts3.8/tracing/openai/types.d.ts +2 -0
  212. package/node_modules/@sentry/core/build/types-ts3.8/utils/eventUtils.d.ts +2 -1
  213. package/node_modules/@sentry/core/package.json +1 -1
  214. package/node_modules/@sentry/node/build/esm/package.json +1 -1
  215. package/node_modules/@sentry/node/package.json +5 -5
  216. package/node_modules/@sentry/node-core/build/cjs/integrations/anr/index.js +1 -1
  217. package/node_modules/@sentry/node-core/build/cjs/integrations/local-variables/local-variables-async.js +1 -1
  218. package/node_modules/@sentry/node-core/build/esm/integrations/anr/index.js +1 -1
  219. package/node_modules/@sentry/node-core/build/esm/integrations/anr/worker-script.js +2 -2
  220. package/node_modules/@sentry/node-core/build/esm/integrations/local-variables/local-variables-async.js +1 -1
  221. package/node_modules/@sentry/node-core/build/esm/integrations/local-variables/worker-script.js +1 -1
  222. package/node_modules/@sentry/node-core/build/esm/package.json +1 -1
  223. package/node_modules/@sentry/node-core/package.json +10 -4
  224. package/node_modules/@sentry/opentelemetry/build/esm/package.json +1 -1
  225. package/node_modules/@sentry/opentelemetry/package.json +5 -2
  226. package/node_modules/@sentry/server-utils/build/THIRD-PARTY-LICENSES.txt +55 -55
  227. package/node_modules/@sentry/server-utils/build/esm/package.json +1 -1
  228. package/node_modules/@sentry/server-utils/package.json +2 -2
  229. package/node_modules/@toon-format/toon/README.md +10 -41
  230. package/node_modules/@toon-format/toon/dist/index.d.mts +12 -36
  231. package/node_modules/@toon-format/toon/dist/index.mjs +134 -202
  232. package/node_modules/@toon-format/toon/package.json +2 -2
  233. package/node_modules/debug/package.json +3 -0
  234. package/node_modules/fdir/package.json +3 -0
  235. package/node_modules/has-flag/index.d.ts +39 -0
  236. package/node_modules/has-flag/index.js +8 -0
  237. package/node_modules/has-flag/license +9 -0
  238. package/node_modules/has-flag/package.json +46 -0
  239. package/node_modules/has-flag/readme.md +89 -0
  240. package/node_modules/supports-color/browser.js +5 -0
  241. package/node_modules/supports-color/index.js +135 -0
  242. package/node_modules/supports-color/license +9 -0
  243. package/node_modules/supports-color/package.json +53 -0
  244. package/node_modules/supports-color/readme.md +76 -0
  245. package/package.json +5 -4
  246. package/packages/pm-beads/package.json +1 -1
  247. package/packages/pm-calendar/package.json +1 -1
  248. package/packages/pm-command-kit/package.json +1 -1
  249. package/packages/pm-digital-twin/package.json +1 -1
  250. package/packages/pm-governance-audit/package.json +1 -1
  251. package/packages/pm-guide-shell/package.json +1 -1
  252. package/packages/pm-kanban/package.json +1 -1
  253. package/packages/pm-lifecycle-hooks/package.json +1 -1
  254. package/packages/pm-linked-test-adapters/package.json +1 -1
  255. package/packages/pm-search-advanced/package.json +1 -1
  256. package/packages/pm-templates/package.json +1 -1
  257. package/packages/pm-todos/package.json +1 -1
  258. package/packages/pm-vcs/package.json +1 -1
  259. package/plugins/pm-claude/.claude-plugin/plugin.json +1 -1
  260. package/plugins/pm-claude/package.json +1 -1
  261. package/plugins/pm-codex/.codex-plugin/plugin.json +1 -1
  262. package/plugins/pm-codex/package.json +1 -1
  263. package/plugins/pm-codex/plugin.json +1 -1
  264. package/runtime-dependencies.json +1 -1
  265. package/dist/cli-bundle/chunks/chunk-7OEGNA4X.js +0 -20
  266. package/dist/cli-bundle/chunks/chunk-EMEEHV2Y.js +0 -2
  267. package/dist/cli-bundle/chunks/chunk-JSUJWIHQ.js +0 -30
  268. package/dist/cli-bundle/chunks/chunk-VIMQCFCK.js +0 -2
  269. package/dist/cli-bundle/chunks/chunk-X2H6UR26.js +0 -236
  270. package/dist/cli-bundle/chunks/register-mutation-EWMMVZJB.js +0 -20
  271. package/dist/cli-bundle/focused-chunks/chunk-5TBAVZDR.js +0 -20
  272. package/dist/cli-bundle/focused-chunks/chunk-HTA3TNC3.js +0 -26
  273. package/dist/cli-bundle/focused-chunks/chunk-JKBH7YGX.js +0 -2
  274. package/dist/cli-bundle/focused-chunks/chunk-PDYE7QDX.js +0 -166
  275. package/docs/ecosystem-review-2026-09-28.json +0 -1
@@ -1,5 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
+ const attributes = require('@sentry/conventions/attributes');
3
4
  const semanticAttributes = require('../../semanticAttributes.js');
4
5
  const spanstatus = require('../spanstatus.js');
5
6
  const trace = require('../trace.js');
@@ -118,39 +119,14 @@ function extractToolCalls(messages) {
118
119
  return toolCalls.length > 0 ? toolCalls : null;
119
120
  }
120
121
  function extractTokenUsageFromMessage(message) {
121
- const msg = message;
122
- let inputTokens = 0;
123
- let outputTokens = 0;
124
- let totalTokens = 0;
125
- if (msg.usage_metadata && typeof msg.usage_metadata === "object") {
126
- const usage = msg.usage_metadata;
127
- if (typeof usage.input_tokens === "number") {
128
- inputTokens = usage.input_tokens;
129
- }
130
- if (typeof usage.output_tokens === "number") {
131
- outputTokens = usage.output_tokens;
132
- }
133
- if (typeof usage.total_tokens === "number") {
134
- totalTokens = usage.total_tokens;
135
- }
136
- return { inputTokens, outputTokens, totalTokens };
137
- }
138
- if (msg.response_metadata && typeof msg.response_metadata === "object") {
139
- const metadata = msg.response_metadata;
140
- if (metadata.tokenUsage && typeof metadata.tokenUsage === "object") {
141
- const tokenUsage = metadata.tokenUsage;
142
- if (typeof tokenUsage.promptTokens === "number") {
143
- inputTokens = tokenUsage.promptTokens;
144
- }
145
- if (typeof tokenUsage.completionTokens === "number") {
146
- outputTokens = tokenUsage.completionTokens;
147
- }
148
- if (typeof tokenUsage.totalTokens === "number") {
149
- totalTokens = tokenUsage.totalTokens;
150
- }
151
- }
152
- }
153
- return { inputTokens, outputTokens, totalTokens };
122
+ const attributes$1 = utils.extractMessageTokenUsageAttributes(message);
123
+ return {
124
+ inputTokens: attributes$1[genAiAttributes.GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] ?? 0,
125
+ outputTokens: attributes$1[genAiAttributes.GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] ?? 0,
126
+ totalTokens: attributes$1[genAiAttributes.GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] ?? 0,
127
+ cacheCreationInputTokens: attributes$1[attributes.GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS],
128
+ cacheReadInputTokens: attributes$1[attributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS]
129
+ };
154
130
  }
155
131
  function extractModelMetadata(span, message) {
156
132
  const msg = message;
@@ -198,11 +174,19 @@ function setResponseAttributes(span, inputMessages, result) {
198
174
  let totalInputTokens = 0;
199
175
  let totalOutputTokens = 0;
200
176
  let totalTokens = 0;
177
+ let cacheCreationInputTokens;
178
+ let cacheReadInputTokens;
201
179
  for (const message of newMessages) {
202
180
  const tokens = extractTokenUsageFromMessage(message);
203
181
  totalInputTokens += tokens.inputTokens;
204
182
  totalOutputTokens += tokens.outputTokens;
205
183
  totalTokens += tokens.totalTokens;
184
+ if (tokens.cacheCreationInputTokens !== void 0) {
185
+ cacheCreationInputTokens = (cacheCreationInputTokens ?? 0) + tokens.cacheCreationInputTokens;
186
+ }
187
+ if (tokens.cacheReadInputTokens !== void 0) {
188
+ cacheReadInputTokens = (cacheReadInputTokens ?? 0) + tokens.cacheReadInputTokens;
189
+ }
206
190
  extractModelMetadata(span, message);
207
191
  }
208
192
  if (totalInputTokens > 0) {
@@ -214,6 +198,12 @@ function setResponseAttributes(span, inputMessages, result) {
214
198
  if (totalTokens > 0) {
215
199
  span.setAttribute(genAiAttributes.GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, totalTokens);
216
200
  }
201
+ if (cacheCreationInputTokens !== void 0) {
202
+ span.setAttribute(attributes.GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, cacheCreationInputTokens);
203
+ }
204
+ if (cacheReadInputTokens !== void 0) {
205
+ span.setAttribute(attributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, cacheReadInputTokens);
206
+ }
217
207
  }
218
208
 
219
209
  exports.extractAgentNameFromParams = extractAgentNameFromParams;
@@ -33,6 +33,8 @@ function processChatCompletionChunk(chunk, state, recordOutputs) {
33
33
  state.promptTokens = chunk.usage.prompt_tokens;
34
34
  state.completionTokens = chunk.usage.completion_tokens;
35
35
  state.totalTokens = chunk.usage.total_tokens;
36
+ state.cacheReadInputTokens = chunk.usage.prompt_tokens_details?.cached_tokens ?? state.cacheReadInputTokens;
37
+ state.cacheCreationInputTokens = chunk.usage.prompt_tokens_details?.cache_write_tokens ?? state.cacheCreationInputTokens;
36
38
  }
37
39
  for (const choice of chunk.choices ?? []) {
38
40
  if (recordOutputs) {
@@ -86,6 +88,8 @@ function processResponsesApiEvent(streamEvent, state, recordOutputs, span) {
86
88
  state.promptTokens = response.usage.input_tokens;
87
89
  state.completionTokens = response.usage.output_tokens;
88
90
  state.totalTokens = response.usage.total_tokens;
91
+ state.cacheReadInputTokens = response.usage.input_tokens_details?.cached_tokens ?? state.cacheReadInputTokens;
92
+ state.cacheCreationInputTokens = response.usage.input_tokens_details?.cache_write_tokens ?? state.cacheCreationInputTokens;
89
93
  }
90
94
  if (response.status) {
91
95
  state.finishReasons.push(response.status);
@@ -105,6 +109,8 @@ async function* instrumentStream(stream, span, recordOutputs) {
105
109
  promptTokens: void 0,
106
110
  completionTokens: void 0,
107
111
  totalTokens: void 0,
112
+ cacheReadInputTokens: void 0,
113
+ cacheCreationInputTokens: void 0,
108
114
  chatCompletionToolCalls: {},
109
115
  responsesApiToolCalls: []
110
116
  };
@@ -1,5 +1,7 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
+ const attributes = require('@sentry/conventions/attributes');
4
+ const is = require('../../utils/is.js');
3
5
  const genAiAttributes = require('../ai/gen-ai-attributes.js');
4
6
 
5
7
  function isResponsesApiStreamEvent(event) {
@@ -34,6 +36,15 @@ function addResponseAttributes(span, result, recordOutputs) {
34
36
  if (typeof usage.total_tokens === "number") {
35
37
  attrs[genAiAttributes.GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = usage.total_tokens;
36
38
  }
39
+ const inputDetails = usage.prompt_tokens_details ?? usage.input_tokens_details;
40
+ if (is.isObjectLike(inputDetails)) {
41
+ if (typeof inputDetails.cached_tokens === "number") {
42
+ attrs[attributes.GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] = inputDetails.cached_tokens;
43
+ }
44
+ if (typeof inputDetails.cache_write_tokens === "number") {
45
+ attrs[attributes.GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS] = inputDetails.cache_write_tokens;
46
+ }
47
+ }
37
48
  }
38
49
  if (Array.isArray(response.choices)) {
39
50
  const choices = response.choices;
@@ -113,7 +113,7 @@ function addResponseAttributes(span, result, recordOutputs) {
113
113
  }
114
114
  const response = result;
115
115
  if (response.usage) {
116
- utils.setTokenUsageAttributes(span, response.usage.prompt_tokens, response.usage.completion_tokens);
116
+ span.setAttributes(utils.getTokenUsageAttributes(response.usage.prompt_tokens, response.usage.completion_tokens));
117
117
  }
118
118
  if (recordOutputs) {
119
119
  let responseText;
@@ -1,5 +1,8 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
+ function isInternalException(hint) {
4
+ return hint.data?.__sentry__ === true;
5
+ }
3
6
  function getPossibleEventMessages(event) {
4
7
  const possibleMessages = [];
5
8
  if (event.message) {
@@ -19,4 +22,5 @@ function getPossibleEventMessages(event) {
19
22
  }
20
23
 
21
24
  exports.getPossibleEventMessages = getPossibleEventMessages;
25
+ exports.isInternalException = isInternalException;
22
26
  //# sourceMappingURL=eventUtils.js.map
@@ -4,6 +4,7 @@ const constants = require('../constants.js');
4
4
  const eventProcessors = require('../eventProcessors.js');
5
5
  const scope = require('../scope.js');
6
6
  const debugIds = require('./debug-ids.js');
7
+ const eventUtils = require('./eventUtils.js');
7
8
  const misc = require('./misc.js');
8
9
  const normalize = require('./normalize.js');
9
10
  const scopeData = require('./scopeData.js');
@@ -43,8 +44,7 @@ function prepareEvent(options, event, hint, scope, client, isolationScope) {
43
44
  // Run scope event processors _after_ all other processors
44
45
  ...data.eventProcessors
45
46
  ];
46
- const isInternalException = hint.data && hint.data.__sentry__ === true;
47
- const result = isInternalException ? syncpromise.resolvedSyncPromise(prepared) : eventProcessors.notifyEventProcessors(eventProcessors$1, prepared, hint);
47
+ const result = eventUtils.isInternalException(hint) ? syncpromise.resolvedSyncPromise(prepared) : eventProcessors.notifyEventProcessors(eventProcessors$1, prepared, hint);
48
48
  return result.then((evt) => {
49
49
  if (evt) {
50
50
  applyDebugMeta(evt);
@@ -1,6 +1,6 @@
1
1
  Object.defineProperty(exports, Symbol.toStringTag, { value: 'Module' });
2
2
 
3
- const SDK_VERSION = "10.76.0" ;
3
+ const SDK_VERSION = "10.76.2" ;
4
4
 
5
5
  exports.SDK_VERSION = SDK_VERSION;
6
6
  //# sourceMappingURL=version.js.map
@@ -15,7 +15,7 @@ import { createClientReportEnvelope } from './utils/clientreport.js';
15
15
  import { debug } from './utils/debug-logger.js';
16
16
  import { makeDsn, dsnToString } from './utils/dsn.js';
17
17
  import { addItemToEnvelope, createAttachmentEnvelopeItem } from './utils/envelope.js';
18
- import { getPossibleEventMessages } from './utils/eventUtils.js';
18
+ import { isInternalException, getPossibleEventMessages } from './utils/eventUtils.js';
19
19
  import { isParameterizedString, isPrimitive, isObjectLike, isThenable, isPlainObject } from './utils/is.js';
20
20
  import { merge } from './utils/merge.js';
21
21
  import { uuid4, checkOrSetAlreadyCaught } from './utils/misc.js';
@@ -331,8 +331,10 @@ class Client {
331
331
  this.emit("beforeSendEvent", event, hint);
332
332
  const genAiSpanItem = extractGenAiSpansFromEvent(event, this);
333
333
  let env = createEventEnvelope(event, this._dsn, this._options._metadata, this._options.tunnel);
334
- for (const attachment of hint.attachments || []) {
335
- env = addItemToEnvelope(env, createAttachmentEnvelopeItem(attachment));
334
+ if (!isInternalException(hint)) {
335
+ for (const attachment of hint.attachments || []) {
336
+ env = addItemToEnvelope(env, createAttachmentEnvelopeItem(attachment));
337
+ }
336
338
  }
337
339
  if (genAiSpanItem) {
338
340
  env = addItemToEnvelope(env, genAiSpanItem);
@@ -586,8 +588,7 @@ class Client {
586
588
  this.recordDroppedEvent("event_processor", dataCategory);
587
589
  throw _makeDoNotSendEventError("An event processor returned `null`, will not send event.");
588
590
  }
589
- const isInternalException = hint.data?.__sentry__ === true;
590
- if (isInternalException) {
591
+ if (isInternalException(hint)) {
591
592
  return prepared;
592
593
  }
593
594
  const result = processBeforeSend(this, options, prepared, hint);
@@ -1 +1 @@
1
- {"type":"module","version":"10.76.0","sideEffects":false}
1
+ {"type":"module","version":"10.76.2","sideEffects":false}
@@ -29,8 +29,6 @@ const GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE = "gen_ai.response.tool_calls";
29
29
  const GEN_AI_AGENT_NAME_ATTRIBUTE = "gen_ai.agent.name";
30
30
  const GEN_AI_PIPELINE_NAME_ATTRIBUTE = "gen_ai.pipeline.name";
31
31
  const GEN_AI_CONVERSATION_ID_ATTRIBUTE = "gen_ai.conversation.id";
32
- const GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS_ATTRIBUTE = "gen_ai.usage.cache_creation_input_tokens";
33
- const GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS_ATTRIBUTE = "gen_ai.usage.cache_read_input_tokens";
34
32
  const GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE = "gen_ai.usage.input_tokens.cache_write";
35
33
  const GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE = "gen_ai.usage.input_tokens.cached";
36
34
  const GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE = "gen_ai.invoke_agent";
@@ -44,5 +42,5 @@ const GEN_AI_TOOL_INPUT_ATTRIBUTE = "gen_ai.tool.input";
44
42
  const GEN_AI_TOOL_OUTPUT_ATTRIBUTE = "gen_ai.tool.output";
45
43
  const GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE = "gen_ai.tool.description";
46
44
 
47
- export { GEN_AI_AGENT_NAME_ATTRIBUTE, GEN_AI_CONVERSATION_ID_ATTRIBUTE, GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE, GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE, GEN_AI_PIPELINE_NAME_ATTRIBUTE, GEN_AI_PROMPT_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_K_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_RESPONSE_STOP_REASON_ATTRIBUTE, GEN_AI_RESPONSE_STREAMING_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE, GEN_AI_TOOL_TYPE_ATTRIBUTE, GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE };
45
+ export { GEN_AI_AGENT_NAME_ATTRIBUTE, GEN_AI_CONVERSATION_ID_ATTRIBUTE, GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_EMBEDDINGS_OPERATION_ATTRIBUTE, GEN_AI_EXECUTE_TOOL_OPERATION_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_INVOKE_AGENT_OPERATION_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_OUTPUT_MESSAGES_ATTRIBUTE, GEN_AI_PIPELINE_NAME_ATTRIBUTE, GEN_AI_PROMPT_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_REQUEST_DIMENSIONS_ATTRIBUTE, GEN_AI_REQUEST_ENCODING_FORMAT_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_K_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_RESPONSE_STOP_REASON_ATTRIBUTE, GEN_AI_RESPONSE_STREAMING_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_TOOL_CALL_ID_ATTRIBUTE, GEN_AI_TOOL_DESCRIPTION_ATTRIBUTE, GEN_AI_TOOL_INPUT_ATTRIBUTE, GEN_AI_TOOL_NAME_ATTRIBUTE, GEN_AI_TOOL_OUTPUT_ATTRIBUTE, GEN_AI_TOOL_TYPE_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHED_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_CACHE_WRITE_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE };
48
46
  //# sourceMappingURL=gen-ai-attributes.js.map
@@ -1,7 +1,8 @@
1
+ import { GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS, GEN_AI_USAGE_REASONING_OUTPUT_TOKENS } from '@sentry/conventions/attributes';
1
2
  import { getClient } from '../../currentScopes.js';
2
3
  import { hasSpanStreamingEnabled } from '../spans/hasSpanStreamingEnabled.js';
3
4
  import { isThenable } from '../../utils/is.js';
4
- import { GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_RESPONSE_STREAMING_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE } from './gen-ai-attributes.js';
5
+ import { GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_RESPONSE_STREAMING_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE } from './gen-ai-attributes.js';
5
6
  import { truncateGenAiStringInput, truncateGenAiMessages } from './messageTruncation.js';
6
7
 
7
8
  function resolveAIRecordingOptions(options) {
@@ -25,23 +26,26 @@ function shouldEnableTruncation(enableTruncation) {
25
26
  function buildMethodPath(currentPath, prop) {
26
27
  return currentPath ? `${currentPath}.${prop}` : prop;
27
28
  }
28
- function setTokenUsageAttributes(span, promptTokens, completionTokens, cachedInputTokens, cachedOutputTokens) {
29
- if (promptTokens !== void 0) {
30
- span.setAttributes({
31
- [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: promptTokens
32
- });
33
- }
34
- if (completionTokens !== void 0) {
35
- span.setAttributes({
36
- [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: completionTokens
37
- });
38
- }
39
- if (promptTokens !== void 0 || completionTokens !== void 0 || cachedInputTokens !== void 0 || cachedOutputTokens !== void 0) {
40
- const totalTokens = (promptTokens ?? 0) + (completionTokens ?? 0) + (cachedInputTokens ?? 0) + (cachedOutputTokens ?? 0);
41
- span.setAttributes({
42
- [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: totalTokens
43
- });
29
+ function getTokenUsageAttributes(promptTokens, completionTokens, cacheCreationInputTokens, cacheReadInputTokens, totalTokens) {
30
+ const attributes = {};
31
+ if (typeof promptTokens === "number") {
32
+ attributes[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = promptTokens;
44
33
  }
34
+ if (typeof cacheCreationInputTokens === "number") {
35
+ attributes[GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS] = cacheCreationInputTokens;
36
+ }
37
+ if (typeof cacheReadInputTokens === "number") {
38
+ attributes[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] = cacheReadInputTokens;
39
+ }
40
+ if (typeof completionTokens === "number") {
41
+ attributes[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = completionTokens;
42
+ }
43
+ if (typeof totalTokens === "number") {
44
+ attributes[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = totalTokens;
45
+ } else if (typeof promptTokens === "number" || typeof completionTokens === "number") {
46
+ attributes[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = (typeof promptTokens === "number" ? promptTokens : 0) + (typeof completionTokens === "number" ? completionTokens : 0);
47
+ }
48
+ return attributes;
45
49
  }
46
50
  function endStreamSpan(span, state, recordOutputs) {
47
51
  if (!span.isRecording()) {
@@ -52,12 +56,18 @@ function endStreamSpan(span, state, recordOutputs) {
52
56
  };
53
57
  if (state.responseId) attrs[GEN_AI_RESPONSE_ID_ATTRIBUTE] = state.responseId;
54
58
  if (state.responseModel) attrs[GEN_AI_RESPONSE_MODEL_ATTRIBUTE] = state.responseModel;
55
- if (state.promptTokens !== void 0) attrs[GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE] = state.promptTokens;
56
- if (state.completionTokens !== void 0) attrs[GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE] = state.completionTokens;
57
- if (state.totalTokens !== void 0) {
58
- attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = state.totalTokens;
59
- } else if (state.promptTokens !== void 0 || state.completionTokens !== void 0 || state.cacheCreationInputTokens !== void 0 || state.cacheReadInputTokens !== void 0) {
60
- attrs[GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE] = (state.promptTokens ?? 0) + (state.completionTokens ?? 0) + (state.cacheCreationInputTokens ?? 0) + (state.cacheReadInputTokens ?? 0);
59
+ Object.assign(
60
+ attrs,
61
+ getTokenUsageAttributes(
62
+ state.promptTokens,
63
+ state.completionTokens,
64
+ state.cacheCreationInputTokens,
65
+ state.cacheReadInputTokens,
66
+ state.totalTokens
67
+ )
68
+ );
69
+ if (typeof state.reasoningOutputTokens === "number") {
70
+ attrs[GEN_AI_USAGE_REASONING_OUTPUT_TOKENS] = state.reasoningOutputTokens;
61
71
  }
62
72
  if (state.finishReasons.length) {
63
73
  attrs[GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE] = JSON.stringify(state.finishReasons);
@@ -130,5 +140,5 @@ function wrapPromiseWithMethods(originalPromiseLike, instrumentedPromise) {
130
140
  });
131
141
  }
132
142
 
133
- export { buildMethodPath, endStreamSpan, extractSystemInstructions, getTruncatedJsonString, resolveAIRecordingOptions, setTokenUsageAttributes, shouldEnableTruncation, wrapPromiseWithMethods };
143
+ export { buildMethodPath, endStreamSpan, extractSystemInstructions, getTokenUsageAttributes, getTruncatedJsonString, resolveAIRecordingOptions, shouldEnableTruncation, wrapPromiseWithMethods };
134
144
  //# sourceMappingURL=utils.js.map
@@ -2,7 +2,7 @@ import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes.js';
2
2
  import { SPAN_STATUS_ERROR } from '../spanstatus.js';
3
3
  import { startSpan, startSpanManual } from '../trace.js';
4
4
  import { GEN_AI_PROMPT_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_REQUEST_TOP_K_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
5
- import { resolveAIRecordingOptions, setTokenUsageAttributes, shouldEnableTruncation, wrapPromiseWithMethods } from '../ai/utils.js';
5
+ import { resolveAIRecordingOptions, getTokenUsageAttributes, shouldEnableTruncation, wrapPromiseWithMethods } from '../ai/utils.js';
6
6
  import { ANTHROPIC_METHOD_REGISTRY } from './constants.js';
7
7
  import { instrumentAsyncIterableStream, instrumentMessageStream } from './streaming.js';
8
8
  import { messagesFromParams, setMessagesAttribute, handleResponseError } from './utils.js';
@@ -75,12 +75,13 @@ function addMetadataAttributes(span, response) {
75
75
  [GEN_AI_RESPONSE_MODEL_ATTRIBUTE]: response.model
76
76
  });
77
77
  if ("usage" in response && response.usage) {
78
- setTokenUsageAttributes(
79
- span,
80
- response.usage.input_tokens,
81
- response.usage.output_tokens,
82
- response.usage.cache_creation_input_tokens,
83
- response.usage.cache_read_input_tokens
78
+ span.setAttributes(
79
+ getTokenUsageAttributes(
80
+ response.usage.input_tokens + (response.usage.cache_creation_input_tokens ?? 0) + (response.usage.cache_read_input_tokens ?? 0),
81
+ response.usage.output_tokens,
82
+ response.usage.cache_creation_input_tokens,
83
+ response.usage.cache_read_input_tokens
84
+ )
84
85
  );
85
86
  }
86
87
  }
@@ -26,7 +26,9 @@ function handleMessageMetadata(event, state) {
26
26
  if (message.id) state.responseId = message.id;
27
27
  if (message.model) state.responseModel = message.model;
28
28
  if (message.usage) {
29
- if (typeof message.usage.input_tokens === "number") state.promptTokens = message.usage.input_tokens;
29
+ if (typeof message.usage.input_tokens === "number") {
30
+ state.promptTokens = message.usage.input_tokens + (message.usage.cache_creation_input_tokens ?? 0) + (message.usage.cache_read_input_tokens ?? 0);
31
+ }
30
32
  if (typeof message.usage.cache_creation_input_tokens === "number")
31
33
  state.cacheCreationInputTokens = message.usage.cache_creation_input_tokens;
32
34
  if (typeof message.usage.cache_read_input_tokens === "number")
@@ -1,10 +1,11 @@
1
+ import { GEN_AI_USAGE_REASONING_OUTPUT_TOKENS } from '@sentry/conventions/attributes';
1
2
  import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes.js';
2
3
  import { stringify } from '../../utils/string.js';
3
4
  import { SPAN_STATUS_ERROR } from '../spanstatus.js';
4
5
  import { startSpanManual, startSpan } from '../trace.js';
5
6
  import { handleCallbackErrors } from '../../utils/handleCallbackErrors.js';
6
- import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_TOP_K_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
7
- import { extractSystemInstructions, getTruncatedJsonString, resolveAIRecordingOptions, shouldEnableTruncation, buildMethodPath } from '../ai/utils.js';
7
+ import { GEN_AI_EMBEDDINGS_INPUT_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_REQUEST_AVAILABLE_TOOLS_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_TOP_K_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
8
+ import { extractSystemInstructions, getTruncatedJsonString, getTokenUsageAttributes, resolveAIRecordingOptions, shouldEnableTruncation, buildMethodPath } from '../ai/utils.js';
8
9
  import { GOOGLE_GENAI_SYSTEM_NAME, GOOGLE_GENAI_METHOD_REGISTRY } from './constants.js';
9
10
  import { instrumentStream } from './streaming.js';
10
11
  import { contentUnionToMessages } from './utils.js';
@@ -112,20 +113,18 @@ function addResponseAttributes(span, response, recordOutputs) {
112
113
  }
113
114
  if (response.usageMetadata && typeof response.usageMetadata === "object") {
114
115
  const usage = response.usageMetadata;
115
- if (typeof usage.promptTokenCount === "number") {
116
- span.setAttributes({
117
- [GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE]: usage.promptTokenCount
118
- });
119
- }
120
- if (typeof usage.candidatesTokenCount === "number") {
121
- span.setAttributes({
122
- [GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE]: usage.candidatesTokenCount
123
- });
124
- }
125
- if (typeof usage.totalTokenCount === "number") {
126
- span.setAttributes({
127
- [GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE]: usage.totalTokenCount
128
- });
116
+ const hasOutput = typeof usage.candidatesTokenCount === "number" || typeof usage.thoughtsTokenCount === "number";
117
+ span.setAttributes(
118
+ getTokenUsageAttributes(
119
+ usage.promptTokenCount,
120
+ hasOutput ? (usage.candidatesTokenCount ?? 0) + (usage.thoughtsTokenCount ?? 0) : void 0,
121
+ void 0,
122
+ usage.cachedContentTokenCount,
123
+ usage.totalTokenCount
124
+ )
125
+ );
126
+ if (typeof usage.thoughtsTokenCount === "number") {
127
+ span.setAttribute(GEN_AI_USAGE_REASONING_OUTPUT_TOKENS, usage.thoughtsTokenCount);
129
128
  }
130
129
  }
131
130
  if (recordOutputs && Array.isArray(response.candidates) && response.candidates.length > 0) {
@@ -20,8 +20,13 @@ function handleResponseMetadata(chunk, state) {
20
20
  const usage = chunk.usageMetadata;
21
21
  if (usage) {
22
22
  if (typeof usage.promptTokenCount === "number") state.promptTokens = usage.promptTokenCount;
23
- if (typeof usage.candidatesTokenCount === "number") state.completionTokens = usage.candidatesTokenCount;
23
+ if (typeof usage.candidatesTokenCount === "number") state.candidateTokens = usage.candidatesTokenCount;
24
+ if (typeof usage.thoughtsTokenCount === "number") state.reasoningOutputTokens = usage.thoughtsTokenCount;
25
+ if (state.candidateTokens !== void 0 || state.reasoningOutputTokens !== void 0) {
26
+ state.completionTokens = (state.candidateTokens ?? 0) + (state.reasoningOutputTokens ?? 0);
27
+ }
24
28
  if (typeof usage.totalTokenCount === "number") state.totalTokens = usage.totalTokenCount;
29
+ if (typeof usage.cachedContentTokenCount === "number") state.cacheReadInputTokens = usage.cachedContentTokenCount;
25
30
  }
26
31
  }
27
32
  function handleCandidateContent(chunk, state, recordOutputs) {
@@ -1,8 +1,10 @@
1
+ import { GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS } from '@sentry/conventions/attributes';
1
2
  import { SEMANTIC_ATTRIBUTE_SENTRY_ORIGIN } from '../../semanticAttributes.js';
2
3
  import { stringify } from '../../utils/string.js';
3
- import { GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_STOP_REASON_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS_ATTRIBUTE, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_AGENT_NAME_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
4
+ import { isObjectLike } from '../../utils/is.js';
5
+ import { GEN_AI_RESPONSE_FINISH_REASONS_ATTRIBUTE, GEN_AI_RESPONSE_TEXT_ATTRIBUTE, GEN_AI_RESPONSE_STOP_REASON_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ATTRIBUTE, GEN_AI_INPUT_MESSAGES_ORIGINAL_LENGTH_ATTRIBUTE, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, GEN_AI_REQUEST_MODEL_ATTRIBUTE, GEN_AI_OPERATION_NAME_ATTRIBUTE, GEN_AI_SYSTEM_ATTRIBUTE, GEN_AI_REQUEST_STREAM_ATTRIBUTE, GEN_AI_REQUEST_TEMPERATURE_ATTRIBUTE, GEN_AI_REQUEST_MAX_TOKENS_ATTRIBUTE, GEN_AI_REQUEST_TOP_P_ATTRIBUTE, GEN_AI_REQUEST_FREQUENCY_PENALTY_ATTRIBUTE, GEN_AI_REQUEST_PRESENCE_PENALTY_ATTRIBUTE, GEN_AI_SYSTEM_INSTRUCTIONS_ATTRIBUTE, GEN_AI_RESPONSE_MODEL_ATTRIBUTE, GEN_AI_RESPONSE_ID_ATTRIBUTE, GEN_AI_AGENT_NAME_ATTRIBUTE } from '../ai/gen-ai-attributes.js';
4
6
  import { isContentMedia, stripInlineMediaFromSingleMessage } from '../ai/mediaStripping.js';
5
- import { extractSystemInstructions, getTruncatedJsonString } from '../ai/utils.js';
7
+ import { extractSystemInstructions, getTruncatedJsonString, getTokenUsageAttributes } from '../ai/utils.js';
6
8
  import { LANGCHAIN_ORIGIN, ROLE_MAP } from './constants.js';
7
9
 
8
10
  const setIfDefined = (target, key, value) => {
@@ -170,29 +172,76 @@ function addToolCallsAttributes(generations, attrs) {
170
172
  setIfDefined(attrs, GEN_AI_RESPONSE_TOOL_CALLS_ATTRIBUTE, stringify(toolCalls, String));
171
173
  }
172
174
  }
173
- function addTokenUsageAttributes(llmOutput, attrs) {
175
+ function extractMessageTokenUsageAttributes(message) {
176
+ const usage = message.usage_metadata;
177
+ if (isObjectLike(usage)) {
178
+ const details = isObjectLike(usage.input_token_details) ? usage.input_token_details : void 0;
179
+ return getTokenUsageAttributes(
180
+ usage.input_tokens,
181
+ usage.output_tokens,
182
+ details?.cache_creation,
183
+ details?.cache_read,
184
+ usage.total_tokens
185
+ );
186
+ }
187
+ const metadata = message.response_metadata;
188
+ const tokenUsage = isObjectLike(metadata) && isObjectLike(metadata.tokenUsage) ? metadata.tokenUsage : void 0;
189
+ return getTokenUsageAttributes(
190
+ tokenUsage?.promptTokens,
191
+ tokenUsage?.completionTokens,
192
+ void 0,
193
+ void 0,
194
+ tokenUsage?.totalTokens
195
+ );
196
+ }
197
+ function addTokenUsageAttributes(llmResult, attrs) {
198
+ const normalizedUsage = {};
199
+ const legacyMessageUsage = {};
200
+ for (const generations of llmResult.generations ?? []) {
201
+ const message = generations[0]?.message;
202
+ if (message) {
203
+ const usage = isObjectLike(message.usage_metadata) ? normalizedUsage : legacyMessageUsage;
204
+ for (const [key, value] of Object.entries(extractMessageTokenUsageAttributes(message))) {
205
+ usage[key] = (usage[key] ?? 0) + value;
206
+ }
207
+ }
208
+ }
209
+ Object.assign(attrs, Object.keys(normalizedUsage).length > 0 ? normalizedUsage : legacyMessageUsage);
210
+ const llmOutput = llmResult.llmOutput;
174
211
  if (!llmOutput) return;
175
212
  const tokenUsage = llmOutput.tokenUsage;
176
213
  const anthropicUsage = llmOutput.usage;
177
- if (tokenUsage) {
178
- setNumberIfDefined(attrs, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, tokenUsage.promptTokens);
179
- setNumberIfDefined(attrs, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, tokenUsage.completionTokens);
180
- setNumberIfDefined(attrs, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, tokenUsage.totalTokens);
181
- } else if (anthropicUsage) {
182
- setNumberIfDefined(attrs, GEN_AI_USAGE_INPUT_TOKENS_ATTRIBUTE, anthropicUsage.input_tokens);
183
- setNumberIfDefined(attrs, GEN_AI_USAGE_OUTPUT_TOKENS_ATTRIBUTE, anthropicUsage.output_tokens);
184
- const input = Number(anthropicUsage.input_tokens);
185
- const output = Number(anthropicUsage.output_tokens);
186
- const total = (Number.isNaN(input) ? 0 : input) + (Number.isNaN(output) ? 0 : output);
187
- if (total > 0) setNumberIfDefined(attrs, GEN_AI_USAGE_TOTAL_TOKENS_ATTRIBUTE, total);
188
- if (anthropicUsage.cache_creation_input_tokens !== void 0)
189
- setNumberIfDefined(
190
- attrs,
191
- GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS_ATTRIBUTE,
192
- anthropicUsage.cache_creation_input_tokens
193
- );
194
- if (anthropicUsage.cache_read_input_tokens !== void 0)
195
- setNumberIfDefined(attrs, GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS_ATTRIBUTE, anthropicUsage.cache_read_input_tokens);
214
+ if (anthropicUsage && Object.keys(normalizedUsage).length === 0 && Object.keys(legacyMessageUsage).length === 0) {
215
+ const { input_tokens, output_tokens, cache_creation_input_tokens, cache_read_input_tokens } = anthropicUsage;
216
+ const hasInput = input_tokens !== void 0 || cache_creation_input_tokens !== void 0 || cache_read_input_tokens !== void 0;
217
+ Object.assign(
218
+ attrs,
219
+ getTokenUsageAttributes(
220
+ hasInput ? (input_tokens ?? 0) + (cache_creation_input_tokens ?? 0) + (cache_read_input_tokens ?? 0) : void 0,
221
+ output_tokens,
222
+ cache_creation_input_tokens,
223
+ cache_read_input_tokens
224
+ )
225
+ );
226
+ } else if (tokenUsage && Object.keys(normalizedUsage).length === 0 && Object.keys(legacyMessageUsage).length === 0) {
227
+ Object.assign(
228
+ attrs,
229
+ getTokenUsageAttributes(
230
+ tokenUsage.promptTokens,
231
+ tokenUsage.completionTokens,
232
+ void 0,
233
+ void 0,
234
+ tokenUsage.totalTokens
235
+ )
236
+ );
237
+ }
238
+ if (anthropicUsage) {
239
+ if (typeof anthropicUsage.cache_creation_input_tokens === "number" && !(GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS in attrs)) {
240
+ attrs[GEN_AI_USAGE_CACHE_CREATION_INPUT_TOKENS] = anthropicUsage.cache_creation_input_tokens;
241
+ }
242
+ if (typeof anthropicUsage.cache_read_input_tokens === "number" && !(GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS in attrs)) {
243
+ attrs[GEN_AI_USAGE_CACHE_READ_INPUT_TOKENS] = anthropicUsage.cache_read_input_tokens;
244
+ }
196
245
  }
197
246
  }
198
247
  function extractLlmResponseAttributes(llmResult, recordOutputs) {
@@ -219,7 +268,7 @@ function extractLlmResponseAttributes(llmResult, recordOutputs) {
219
268
  }
220
269
  }
221
270
  }
222
- addTokenUsageAttributes(llmResult.llmOutput, attrs);
271
+ addTokenUsageAttributes(llmResult, attrs);
223
272
  const llmOutput = llmResult.llmOutput;
224
273
  const firstGeneration = llmResult.generations?.[0]?.[0];
225
274
  const v1Message = firstGeneration?.message;
@@ -288,5 +337,5 @@ function _INTERNAL_mergeLangChainCallbackHandler(existing, sentryHandler) {
288
337
  return [...handlers, sentryHandler];
289
338
  }
290
339
 
291
- export { _INTERNAL_mergeLangChainCallbackHandler, extractChatModelRequestAttributes, extractLLMRequestAttributes, extractLlmResponseAttributes, extractToolDefinitions, getAgentNameFromMetadata, getInvocationParams, normalizeLangChainMessages };
340
+ export { _INTERNAL_mergeLangChainCallbackHandler, extractChatModelRequestAttributes, extractLLMRequestAttributes, extractLlmResponseAttributes, extractMessageTokenUsageAttributes, extractToolDefinitions, getAgentNameFromMetadata, getInvocationParams, normalizeLangChainMessages };
292
341
  //# sourceMappingURL=utils.js.map