@sentry/junior 0.202.0 → 0.204.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (174) hide show
  1. package/dist/agent-CMyTD4DD.js +17509 -0
  2. package/dist/agent-hooks-Bbcp9e33.js +4040 -0
  3. package/dist/agent-runner-DNb1A49M.js +678 -0
  4. package/dist/api/schema.d.ts +2728 -2639
  5. package/dist/api/schema.js +4 -169
  6. package/dist/api.d.ts +23 -17
  7. package/dist/api.js +3881 -5326
  8. package/dist/app-B1TOqBI8.d.ts +246 -0
  9. package/dist/app.d.ts +4 -520
  10. package/dist/app.js +9522 -11875
  11. package/dist/auth-pause-state-DosEalIG.js +168 -0
  12. package/dist/catalog-runtime-BReos-D4.js +7 -0
  13. package/dist/checkpoint-CNrPyRJN.js +2450 -0
  14. package/dist/cli/chat.d.ts +20 -0
  15. package/dist/cli/chat.js +229 -336
  16. package/dist/cli/check.d.ts +8 -0
  17. package/dist/cli/check.js +513 -806
  18. package/dist/cli/env.d.ts +13 -0
  19. package/dist/cli/env.js +63 -12
  20. package/dist/cli/init.d.ts +3 -0
  21. package/dist/cli/init.js +90 -159
  22. package/dist/cli/main.d.ts +6 -0
  23. package/dist/cli/main.js +43 -64
  24. package/dist/cli/plugins.d.ts +13 -0
  25. package/dist/cli/plugins.js +148 -227
  26. package/dist/cli/run.d.ts +16 -0
  27. package/dist/cli/run.js +52 -8
  28. package/dist/cli/snapshot-create.d.ts +4 -0
  29. package/dist/cli/snapshot-create.js +71 -125
  30. package/dist/cli/upgrade.d.ts +15 -0
  31. package/dist/cli/upgrade.js +232 -335
  32. package/dist/config-nGCW1OTG.js +941 -0
  33. package/dist/context-B45_WqVX.js +298 -0
  34. package/dist/conversation-privacy-B4voFRSm.js +182 -0
  35. package/dist/conversation-work-C6y3T5Hx.js +51 -0
  36. package/dist/credential-sync-kXr1hvO1.js +2660 -0
  37. package/dist/db-BeyXKJOI.d.ts +5 -0
  38. package/dist/destinations-BeBiJeEM.js +29 -0
  39. package/dist/execution-stats-DWfSihcH.js +373 -0
  40. package/dist/executor-DcMSlI5c.js +721 -0
  41. package/dist/experimental-CIXf7Uye.js +46 -0
  42. package/dist/history-ClE4toxe.d.ts +32 -0
  43. package/dist/history-CqTuSAdI.js +441 -0
  44. package/dist/instrumentation.d.ts +3 -3
  45. package/dist/instrumentation.js +130 -176
  46. package/dist/job-queue-Drn_LXlM.js +63 -0
  47. package/dist/logging-BzAk1S_s.js +1210 -0
  48. package/dist/model-profile-CZmVoGdX.js +49 -0
  49. package/dist/nitro.d.ts +31 -36
  50. package/dist/nitro.js +275 -456
  51. package/dist/oauth-callback-server-JiftokvA.js +130 -0
  52. package/dist/oauth-relay-CdCnu80W.js +62 -0
  53. package/dist/package-discovery-7a9YqLhE.js +455 -0
  54. package/dist/pending-auth-CWmSdZVg.js +185 -0
  55. package/dist/plugin-module-BKGOXca2.js +81 -0
  56. package/dist/plugins-BI9A1vKA.d.ts +95 -0
  57. package/dist/plugins-egKWjgue.js +99 -0
  58. package/dist/private-trace-result-BLvBjy_e.js +16 -0
  59. package/dist/profile-CrT5nXbw.js +861 -0
  60. package/dist/registry-DH1xUo2N.js +1419 -0
  61. package/dist/reporting-schema-DosTN__Q.js +105 -0
  62. package/dist/resolve-CZHnfxaS.js +546 -0
  63. package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
  64. package/dist/runner-CZV2sC46.js +392 -0
  65. package/dist/sandbox-egress-signals-bHZfmhbd.js +46 -0
  66. package/dist/schema-Rn8-XEaN.js +1140 -0
  67. package/dist/sentry-CD3SdJl-.js +26 -0
  68. package/dist/skills-CIcDQSgM.js +316 -0
  69. package/dist/spawn-DdkUFRmq.js +29 -0
  70. package/dist/stats-DTUbAb88.js +2634 -0
  71. package/dist/store-C5qxF2ac.d.ts +208 -0
  72. package/dist/task-queue-CJIR4RF7.js +136 -0
  73. package/dist/task-runner-D-O3A-Cp.js +639 -0
  74. package/dist/thread-state-CRc9jTJS.js +431 -0
  75. package/dist/turn-execution-BkinIdJF.js +47 -0
  76. package/dist/turn-lifecycle-DQV19VTW.js +54 -0
  77. package/dist/usage-D3EbSO7w.js +296 -0
  78. package/dist/usage-schema-CKaDkH_j.js +20 -0
  79. package/dist/validation-C2CR-OX3.js +40 -0
  80. package/dist/vercel-queue-DIkVcfK4.js +167 -0
  81. package/dist/vercel.d.ts +6 -6
  82. package/dist/vercel.js +14 -6
  83. package/dist/version-CnXZ614E.d.ts +5 -0
  84. package/dist/version-DxcWdoKa.js +8 -0
  85. package/dist/version.d.ts +2 -4
  86. package/dist/version.js +2 -6
  87. package/dist/web-authorization-RMBxAR_t.js +76 -0
  88. package/dist/web-input-3EPfpf55.js +494 -0
  89. package/dist/work-fGofI7Op.js +509 -0
  90. package/dist/worker-CsOLq-mR.js +625 -0
  91. package/package.json +9 -9
  92. package/dist/agent-hooks-UXITLYOK.js +0 -51
  93. package/dist/catalog-runtime-BG3JLLK2.js +0 -14
  94. package/dist/chunk-2LYHWMR4.js +0 -46
  95. package/dist/chunk-2MK3QBGA.js +0 -321
  96. package/dist/chunk-3PGQSKJV.js +0 -692
  97. package/dist/chunk-3UI3WFTX.js +0 -519
  98. package/dist/chunk-3Y47VMHV.js +0 -6
  99. package/dist/chunk-4UO6FK4G.js +0 -64
  100. package/dist/chunk-5NOPO64K.js +0 -198
  101. package/dist/chunk-5PKWYPFT.js +0 -2943
  102. package/dist/chunk-63NKKFJL.js +0 -1228
  103. package/dist/chunk-6AYH6252.js +0 -787
  104. package/dist/chunk-6Y5B5PEX.js +0 -80
  105. package/dist/chunk-7DHZP5KJ.js +0 -333
  106. package/dist/chunk-7H2VZTWN.js +0 -103
  107. package/dist/chunk-7NL7T6VU.js +0 -406
  108. package/dist/chunk-A76OIMYN.js +0 -102
  109. package/dist/chunk-AWMS3SPP.js +0 -58
  110. package/dist/chunk-B3LY5RCL.js +0 -229
  111. package/dist/chunk-BD2KT3OB.js +0 -36
  112. package/dist/chunk-BXCX5QKA.js +0 -2086
  113. package/dist/chunk-C6VVF43U.js +0 -81
  114. package/dist/chunk-CEMMLV5L.js +0 -98
  115. package/dist/chunk-CM5HNV2W.js +0 -131
  116. package/dist/chunk-DA2KGZZI.js +0 -13
  117. package/dist/chunk-DBVY6HLX.js +0 -64
  118. package/dist/chunk-DIB4GX3G.js +0 -8
  119. package/dist/chunk-DKIJ2RP5.js +0 -68
  120. package/dist/chunk-DL2KLKVH.js +0 -931
  121. package/dist/chunk-DWPN6SCH.js +0 -172
  122. package/dist/chunk-ELWOYVOY.js +0 -206
  123. package/dist/chunk-EWT7H65X.js +0 -506
  124. package/dist/chunk-FA6POGLH.js +0 -70
  125. package/dist/chunk-HMREVIO2.js +0 -135
  126. package/dist/chunk-IIWUT4FO.js +0 -820
  127. package/dist/chunk-JAL3CH4G.js +0 -27
  128. package/dist/chunk-JSJQEWBJ.js +0 -3295
  129. package/dist/chunk-KHKKHDLD.js +0 -387
  130. package/dist/chunk-LA6R4A7Q.js +0 -706
  131. package/dist/chunk-LOOU2DUR.js +0 -20428
  132. package/dist/chunk-M6FHWXE3.js +0 -700
  133. package/dist/chunk-M76HMB7M.js +0 -1856
  134. package/dist/chunk-MAGNK5J4.js +0 -1520
  135. package/dist/chunk-MTM5IFCY.js +0 -1190
  136. package/dist/chunk-N7TMSOZH.js +0 -235
  137. package/dist/chunk-NHJU2ZAL.js +0 -56
  138. package/dist/chunk-NSXKRGRT.js +0 -717
  139. package/dist/chunk-OWMPFXJA.js +0 -1764
  140. package/dist/chunk-PDO5BLNM.js +0 -22
  141. package/dist/chunk-PEQXYSSE.js +0 -45
  142. package/dist/chunk-PW4P4JYF.js +0 -1135
  143. package/dist/chunk-QB54UQUS.js +0 -320
  144. package/dist/chunk-QP3OGJXF.js +0 -105
  145. package/dist/chunk-RC745GGZ.js +0 -122
  146. package/dist/chunk-REOIRYPR.js +0 -37
  147. package/dist/chunk-SCOZRLZ4.js +0 -164
  148. package/dist/chunk-TXJSXBV5.js +0 -1433
  149. package/dist/chunk-TXKUKMVO.js +0 -417
  150. package/dist/chunk-U2GPUYAL.js +0 -3656
  151. package/dist/chunk-UIE3R5XU.js +0 -17
  152. package/dist/chunk-UXPG6ZIN.js +0 -84
  153. package/dist/chunk-VFUK3X5B.js +0 -50
  154. package/dist/chunk-WQSHDTTI.js +0 -1163
  155. package/dist/chunk-X6GDDWQH.js +0 -60
  156. package/dist/chunk-Y2CM7HXH.js +0 -111
  157. package/dist/chunk-Y7X25LFY.js +0 -15
  158. package/dist/chunk-YDUR3ZYW.js +0 -10
  159. package/dist/conversation-work-VIOQ5ZF3.js +0 -54
  160. package/dist/db-3L2MCVRI.js +0 -26
  161. package/dist/discovery-DWVDM7UK.js +0 -44
  162. package/dist/experimental-P5FZM4CU.js +0 -12
  163. package/dist/oauth-callback-server-YVV6C6T2.js +0 -243
  164. package/dist/oauth-relay-5XPVRPYB.js +0 -8
  165. package/dist/plugins-YTYJMMJF.js +0 -14
  166. package/dist/runner-LQ7RETDP.js +0 -522
  167. package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
  168. package/dist/sentry-MB3NL3IR.js +0 -42
  169. package/dist/skills-XRWYEDCD.js +0 -27
  170. package/dist/spawn-RC6SJUAI.js +0 -42
  171. package/dist/task-runner-7DY7ARYH.js +0 -36
  172. package/dist/validation-7MNQGCJA.js +0 -17
  173. package/dist/work-COALHUCG.js +0 -51
  174. package/dist/worker-6MURZIPD.js +0 -24
@@ -1,1520 +0,0 @@
1
- import {
2
- captureException,
3
- captureMessage,
4
- getActiveSpan,
5
- getTraceData,
6
- logger,
7
- setTag,
8
- setUser,
9
- spanToJSON,
10
- startSpan,
11
- withScope
12
- } from "./chunk-PEQXYSSE.js";
13
- import {
14
- JUNIOR_VERSION
15
- } from "./chunk-HMREVIO2.js";
16
-
17
- // src/deployment.ts
18
- var JUNIOR_HEARTBEAT_ROUTE = "/api/internal/heartbeat";
19
- var JUNIOR_HEARTBEAT_CRON_SCHEDULE = "* * * * *";
20
- var JUNIOR_RETENTION_ROUTE = "/api/internal/retention";
21
- var JUNIOR_RETENTION_CRON_SCHEDULE = "0 4 * * *";
22
- var JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE = "/api/internal/agent/continue";
23
- var JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE = "/api/internal/plugin/tasks";
24
- var JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE = "/api/internal/workspace/snapshots";
25
- var LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION = "api/internal/agent/continue.ts";
26
- function toOptionalTrimmed(value) {
27
- const trimmed = value?.trim();
28
- return trimmed ? trimmed : void 0;
29
- }
30
- function getDeploymentServiceVersion() {
31
- const configuredRelease = toOptionalTrimmed(process.env.SENTRY_RELEASE);
32
- if (configuredRelease) {
33
- return configuredRelease;
34
- }
35
- const deploymentRevision = toOptionalTrimmed(
36
- process.env.VERCEL_GIT_COMMIT_SHA
37
- );
38
- return deploymentRevision ? `${JUNIOR_VERSION}+${deploymentRevision}` : void 0;
39
- }
40
- function getDeploymentTelemetryAttributes() {
41
- const attributes = {};
42
- const serviceVersion = getDeploymentServiceVersion();
43
- const deploymentId = toOptionalTrimmed(process.env.VERCEL_DEPLOYMENT_ID);
44
- attributes["app.junior.version"] = JUNIOR_VERSION;
45
- if (serviceVersion) {
46
- attributes["service.version"] = serviceVersion;
47
- }
48
- if (deploymentId) {
49
- attributes["deployment.id"] = deploymentId;
50
- }
51
- return attributes;
52
- }
53
-
54
- // src/chat/logging.ts
55
- import path from "path";
56
- import { styleText } from "util";
57
- import {
58
- ConfigError,
59
- configureSync,
60
- getConfig,
61
- getLogger
62
- } from "@logtape/logtape";
63
-
64
- // src/chat/coerce.ts
65
- function toOptionalString(value) {
66
- return typeof value === "string" && value.trim() ? value : void 0;
67
- }
68
- function toOptionalNumber(value) {
69
- return typeof value === "number" && Number.isFinite(value) ? value : void 0;
70
- }
71
- function isRecord(value) {
72
- return typeof value === "object" && value !== null;
73
- }
74
-
75
- // src/chat/log-context.ts
76
- import { AsyncLocalStorage } from "async_hooks";
77
- var logContextStorage = new AsyncLocalStorage();
78
- var typedLogContextStorage = new AsyncLocalStorage();
79
- function definedLogContext(context) {
80
- return Object.fromEntries(
81
- Object.entries(context).filter(([, value]) => value !== void 0)
82
- );
83
- }
84
- function definedAttributes(attributes) {
85
- return Object.fromEntries(
86
- Object.entries(attributes).filter(
87
- (entry) => entry[1] !== void 0
88
- )
89
- );
90
- }
91
- function logContextToAttributes(context) {
92
- return definedAttributes({
93
- "gen_ai.conversation.id": context.conversationId,
94
- "app.platform": context.platform,
95
- "app.request.id": context.requestId,
96
- "messaging.system": context.platform === "slack" ? "slack" : context.platform,
97
- "messaging.message.conversation_id": context.messageConversationId,
98
- "messaging.destination.name": context.destinationName,
99
- "enduser.id": context.userId,
100
- "enduser.pseudo.id": context.userName,
101
- "app.run.id": context.runId,
102
- "app.actor.type": context.actorType,
103
- "app.actor.id": context.actorId,
104
- "gen_ai.agent.name": context.assistantUserName,
105
- "gen_ai.request.model": context.modelId,
106
- "app.skill.name": context.skillName,
107
- "http.request.method": context.httpMethod,
108
- "url.path": context.httpPath,
109
- "url.full": context.urlFull,
110
- "user_agent.original": context.userAgent
111
- });
112
- }
113
- function runWithLogContext(context, attributes, callback) {
114
- return typedLogContextStorage.run(
115
- {
116
- ...typedLogContextStorage.getStore(),
117
- ...definedLogContext(context)
118
- },
119
- () => logContextStorage.run(
120
- { ...logContextStorage.getStore(), ...attributes },
121
- callback
122
- )
123
- );
124
- }
125
- function updateLogContext(context, attributes) {
126
- const currentContext = typedLogContextStorage.getStore();
127
- if (currentContext) {
128
- Object.assign(currentContext, definedLogContext(context));
129
- }
130
- const currentAttributes = logContextStorage.getStore();
131
- if (currentAttributes) {
132
- Object.assign(currentAttributes, attributes);
133
- }
134
- }
135
- function getBoundLogContext() {
136
- return typedLogContextStorage.getStore() ?? {};
137
- }
138
- function getBoundLogAttributes() {
139
- return logContextStorage.getStore() ?? {};
140
- }
141
-
142
- // src/chat/identities/identity.ts
143
- function normalizeIdentityEmail(email) {
144
- const normalized = email?.trim().toLowerCase();
145
- return normalized || void 0;
146
- }
147
-
148
- // src/chat/logging.ts
149
- var MAX_STRING_VALUE = 1200;
150
- var EVENT_NAME_PATTERN = /^[a-z][a-z0-9_]*(?:\.[a-z][a-z0-9_]*)+$/;
151
- var SECRETS_RE = [
152
- /\b(sk-[A-Za-z0-9_-]{20,})\b/g,
153
- /\b(xox[baprs]-[A-Za-z0-9-]{10,})\b/g,
154
- /\bBearer\s+([A-Za-z0-9._\-+=]{20,})\b/gi,
155
- /\b[A-Z0-9_]+(?:KEY|TOKEN|SECRET|PASSWORD|PASSWD)\s*[=:]\s*([^\s"']{8,})/gi
156
- ];
157
- var LEGACY_KEY_MAP = {
158
- error: "exception.message",
159
- "error.stack": "exception.stacktrace",
160
- "gen_ai.system": "gen_ai.provider.name",
161
- "gen_ai.request.messages": "gen_ai.input.messages",
162
- "gen_ai.response.text": "gen_ai.output.messages",
163
- "messaging.conversation.id": "messaging.message.conversation_id",
164
- bytes: "file.size",
165
- media_type: "app.file.mime_type",
166
- skillDir: "file.path",
167
- root: "file.directory",
168
- originalLength: "app.output.original_length",
169
- parsedLength: "app.output.parsed_length",
170
- directiveMode: "app.output.directive_mode",
171
- fileCount: "app.output.file_count",
172
- attempt: "app.retry.attempt",
173
- steps: "app.ai.steps",
174
- toolCalls: "app.ai.tool_calls",
175
- toolResults: "app.ai.tool_results",
176
- finishReason: "gen_ai.response.finish_reasons",
177
- sources: "app.ai.sources",
178
- generatedFiles: "app.ai.generated_files",
179
- resultFiles: "app.ai.result_files",
180
- responseMessages: "app.ai.response_messages",
181
- stepDiagnostics: "app.ai.step_diagnostics",
182
- inferredSkill: "app.skill.name",
183
- inferredScore: "app.skill.score"
184
- };
185
- function normalizeGenAiFinishReason(reason) {
186
- return reason === "toolUse" ? "tool_call" : reason;
187
- }
188
- function summarizeMessageText(text) {
189
- const normalized = text.trim().replace(/\s+/g, " ");
190
- if (!normalized) {
191
- return "[empty]";
192
- }
193
- return normalized.length > 1200 ? `${normalized.slice(0, 1200)}...` : normalized;
194
- }
195
- function normalizeGenAiFinishReasons(value) {
196
- if (typeof value === "string" && value.trim()) {
197
- return [normalizeGenAiFinishReason(value)];
198
- }
199
- if (!Array.isArray(value)) {
200
- return value;
201
- }
202
- return value.map(
203
- (reason) => typeof reason === "string" ? normalizeGenAiFinishReason(reason) : reason
204
- );
205
- }
206
- var logRecordSinks = /* @__PURE__ */ new Set();
207
- var deploymentLogAttributes = getDeploymentTelemetryAttributes();
208
- var LOGTAPE_BODY_KEY = "__logtape_body";
209
- var ROOT_LOGGER_CATEGORY = ["junior"];
210
- var CONSOLE_PRIORITY_KEYS = [
211
- "gen_ai.conversation.id",
212
- "event.name",
213
- "app.log.source",
214
- "exception.message",
215
- "messaging.message.id",
216
- "trace_id",
217
- "span_id",
218
- "messaging.message.conversation_id",
219
- "messaging.destination.name",
220
- "app.run.id",
221
- "app.message.kind"
222
- ];
223
- var CONSOLE_PRIORITY_INDEX = new Map(
224
- CONSOLE_PRIORITY_KEYS.map((key, index) => [key, index])
225
- );
226
- var CONSOLE_ALWAYS_HIDDEN_KEYS = /* @__PURE__ */ new Set([
227
- "gen_ai.agent.name",
228
- "app.platform",
229
- "enduser.id",
230
- "enduser.pseudo.id",
231
- "http.request.method",
232
- "messaging.system",
233
- "url.full",
234
- "url.path",
235
- "user_agent.original"
236
- ]);
237
- var CONSOLE_DROP_WHEN_COUNTED_KEYS = /* @__PURE__ */ new Set(["app.config.keys"]);
238
- var CONSOLE_PREVIEW_KEYS = /* @__PURE__ */ new Set([
239
- "gen_ai.input.messages",
240
- "gen_ai.output.messages",
241
- "gen_ai.tool.call.arguments",
242
- "gen_ai.tool.call.result"
243
- ]);
244
- var SENTRY_TAG_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
245
- "app.platform",
246
- "messaging.system",
247
- "app.actor.type",
248
- "gen_ai.agent.name",
249
- "gen_ai.request.model",
250
- "app.skill.name",
251
- "http.request.method",
252
- "url.path"
253
- ]);
254
- function getSentryEnvironment() {
255
- return (process.env.SENTRY_ENVIRONMENT ?? process.env.VERCEL_ENV ?? process.env.NODE_ENV ?? "").trim().toLowerCase();
256
- }
257
- function shouldSuppressInfoLog(level) {
258
- return getSentryEnvironment() === "production" && level === "info";
259
- }
260
- function shouldEmitConsole(level) {
261
- if (process.env.NODE_ENV === "test") {
262
- return level === "error";
263
- }
264
- return true;
265
- }
266
- function isDevelopmentLoggingMode() {
267
- if (process.env.NODE_ENV !== "development") {
268
- return false;
269
- }
270
- if (process.env.CI) {
271
- return false;
272
- }
273
- return true;
274
- }
275
- function shouldUseDevelopmentConsoleFormat() {
276
- if (!isDevelopmentLoggingMode()) {
277
- return false;
278
- }
279
- return process.env.JUNIOR_LOG_FORMAT?.trim().toLowerCase() !== "structured";
280
- }
281
- function shouldUsePrettyConsole(level) {
282
- if (level === "warn" || level === "error") {
283
- return false;
284
- }
285
- return shouldUseDevelopmentConsoleFormat();
286
- }
287
- function shouldUseConsoleColor() {
288
- if (!shouldUseDevelopmentConsoleFormat()) {
289
- return false;
290
- }
291
- if (process.env.NO_COLOR) {
292
- return false;
293
- }
294
- return process.env.FORCE_COLOR?.trim() === "1" || Boolean(process.stdout?.isTTY) || Boolean(process.stderr?.isTTY);
295
- }
296
- function formatConsoleTimestamp(timestamp) {
297
- if (shouldUseDevelopmentConsoleFormat()) {
298
- return timestamp.toTimeString().slice(0, 8);
299
- }
300
- return timestamp.toISOString();
301
- }
302
- function findNextBlankLineBoundary(input, start) {
303
- const lfBoundary = input.indexOf("\n\n", start);
304
- const crlfBoundary = input.indexOf("\r\n\r\n", start);
305
- if (lfBoundary === -1 && crlfBoundary === -1) {
306
- return null;
307
- }
308
- if (lfBoundary === -1) {
309
- return { start: crlfBoundary, end: crlfBoundary + 4 };
310
- }
311
- if (crlfBoundary === -1 || lfBoundary < crlfBoundary) {
312
- return { start: lfBoundary, end: lfBoundary + 2 };
313
- }
314
- return { start: crlfBoundary, end: crlfBoundary + 4 };
315
- }
316
- function redactPrivateKeyBlocks(input) {
317
- const beginPrefix = "-----BEGIN ";
318
- const footerMarker = "-----";
319
- let cursor = 0;
320
- let output = "";
321
- while (cursor < input.length) {
322
- const begin = input.indexOf(beginPrefix, cursor);
323
- if (begin === -1) {
324
- output += input.slice(cursor);
325
- break;
326
- }
327
- const labelStart = begin + beginPrefix.length;
328
- const labelEnd = input.indexOf(footerMarker, labelStart);
329
- if (labelEnd === -1) {
330
- output += input.slice(cursor);
331
- break;
332
- }
333
- const label = input.slice(labelStart, labelEnd);
334
- if (!label.endsWith("PRIVATE KEY")) {
335
- output += input.slice(cursor, labelEnd + footerMarker.length);
336
- cursor = labelEnd + footerMarker.length;
337
- continue;
338
- }
339
- const header = input.slice(begin, labelEnd + footerMarker.length);
340
- const footer = `-----END ${label}-----`;
341
- const footerStart = input.indexOf(footer, labelEnd + footerMarker.length);
342
- if (footerStart === -1) {
343
- const resumeBoundary = findNextBlankLineBoundary(
344
- input,
345
- labelEnd + footerMarker.length
346
- );
347
- output += input.slice(cursor, begin);
348
- output += `${header}
349
- ...redacted...`;
350
- if (!resumeBoundary) {
351
- break;
352
- }
353
- output += input.slice(resumeBoundary.start, resumeBoundary.end);
354
- cursor = resumeBoundary.end;
355
- continue;
356
- }
357
- output += input.slice(cursor, begin);
358
- output += `${header}
359
- ...redacted...
360
- ${footer}`;
361
- cursor = footerStart + footer.length;
362
- }
363
- return output;
364
- }
365
- function redactSecrets(input) {
366
- let out = redactPrivateKeyBlocks(input);
367
- for (const pattern of SECRETS_RE) {
368
- out = out.replace(pattern, (full, token) => {
369
- if (typeof token !== "string") {
370
- return "***";
371
- }
372
- if (token.length < 12) {
373
- return full.replace(token, "***");
374
- }
375
- return full.replace(token, `${token.slice(0, 4)}...${token.slice(-4)}`);
376
- });
377
- }
378
- return out;
379
- }
380
- function toSnakeCase(value) {
381
- return value.replace(/([a-z0-9])([A-Z])/g, "$1_$2").replace(/[^a-zA-Z0-9_]+/g, "_").replace(/^_+|_+$/g, "").toLowerCase();
382
- }
383
- function normalizeEventName(value) {
384
- const segments = value.trim().split(".").map(toSnakeCase).filter(Boolean);
385
- const normalized = segments.length === 0 ? "log.record.emitted" : segments.length === 1 ? `app.${segments[0]}` : segments.join(".");
386
- if (process.env.NODE_ENV !== "production" && (!EVENT_NAME_PATTERN.test(value) || value !== normalized)) {
387
- throw new Error(
388
- `Invalid log event name "${value}"; use lowercase dot-delimited namespaces`
389
- );
390
- }
391
- return normalized;
392
- }
393
- function isSemanticKey(key) {
394
- return /^[a-z][a-z0-9_]*(\.[a-z0-9_][a-z0-9_-]*)+$/.test(key);
395
- }
396
- function normalizeAttributeKey(key) {
397
- const mapped = LEGACY_KEY_MAP[key];
398
- if (mapped) {
399
- return mapped;
400
- }
401
- if (key === "trace_id" || key === "span_id" || key === "trace_flags") {
402
- return key;
403
- }
404
- if (isSemanticKey(key)) {
405
- return key;
406
- }
407
- if (key === "platform") return "app.platform";
408
- if (key === "request.id") return "app.request.id";
409
- const snake = toSnakeCase(key);
410
- if (!snake) {
411
- return "app.attribute";
412
- }
413
- return `app.${snake}`;
414
- }
415
- function sanitizePrimitive(value) {
416
- if (value === null || value === void 0) return void 0;
417
- if (typeof value === "string") {
418
- const trimmed = value.trim();
419
- if (!trimmed) return void 0;
420
- const redacted = redactSecrets(trimmed);
421
- return redacted.length > MAX_STRING_VALUE ? `${redacted.slice(0, MAX_STRING_VALUE)}...` : redacted;
422
- }
423
- if (typeof value === "number") {
424
- return Number.isFinite(value) ? value : void 0;
425
- }
426
- if (typeof value === "boolean") return value;
427
- if (value instanceof Error) {
428
- return redactSecrets(value.message);
429
- }
430
- try {
431
- const json = JSON.stringify(value);
432
- if (!json) return void 0;
433
- const redacted = redactSecrets(json);
434
- return redacted.length > MAX_STRING_VALUE ? `${redacted.slice(0, MAX_STRING_VALUE)}...` : redacted;
435
- } catch {
436
- return void 0;
437
- }
438
- }
439
- function sanitizeValue(value) {
440
- if (Array.isArray(value)) {
441
- const sanitized = value.filter((entry) => typeof entry === "string").map((entry) => sanitizePrimitive(entry)).filter((entry) => typeof entry === "string");
442
- return sanitized.length > 0 ? sanitized : void 0;
443
- }
444
- return sanitizePrimitive(value);
445
- }
446
- function contextToAttributes(context) {
447
- return mergeAttributes(logContextToAttributes(context));
448
- }
449
- function getTraceCorrelationAttributes() {
450
- try {
451
- const span = getActiveSpan();
452
- if (!span) return {};
453
- const json = spanToJSON(span);
454
- const attrs = {};
455
- if (json.trace_id) attrs.trace_id = json.trace_id;
456
- if (json.span_id) attrs.span_id = json.span_id;
457
- return attrs;
458
- } catch {
459
- return {};
460
- }
461
- }
462
- function mergeAttributes(...maps) {
463
- const merged = {};
464
- for (const map of maps) {
465
- if (!map) continue;
466
- for (const [rawKey, rawValue] of Object.entries(map)) {
467
- const key = normalizeAttributeKey(rawKey);
468
- const value = sanitizeValue(
469
- key === "gen_ai.response.finish_reasons" ? normalizeGenAiFinishReasons(rawValue) : rawValue
470
- );
471
- if (value !== void 0) {
472
- merged[key] = value;
473
- }
474
- }
475
- }
476
- return merged;
477
- }
478
- function fromLogTapeLevel(level) {
479
- if (level === "warning") {
480
- return "warn";
481
- }
482
- if (level === "fatal") {
483
- return "error";
484
- }
485
- if (level === "trace") {
486
- return "debug";
487
- }
488
- return level;
489
- }
490
- function getLogSource(category) {
491
- if (category.length <= ROOT_LOGGER_CATEGORY.length) {
492
- return void 0;
493
- }
494
- const sourceParts = category.slice(ROOT_LOGGER_CATEGORY.length);
495
- return sourceParts.length > 0 ? sourceParts.join(".") : void 0;
496
- }
497
- function toEmittedLogRecord(record) {
498
- const properties = { ...record.properties };
499
- const rawBody = properties[LOGTAPE_BODY_KEY];
500
- delete properties[LOGTAPE_BODY_KEY];
501
- const attributes = mergeAttributes(properties);
502
- const source = getLogSource(record.category);
503
- if (source && attributes["app.log.source"] === void 0) {
504
- attributes["app.log.source"] = source;
505
- }
506
- const body = toOptionalString(rawBody) ?? record.message.map(
507
- (segment) => typeof segment === "string" ? segment : String(segment ?? "")
508
- ).join("");
509
- const eventName = toOptionalString(attributes["event.name"]) ?? "log.record.emitted";
510
- return {
511
- level: fromLogTapeLevel(record.level),
512
- eventName,
513
- body,
514
- attributes
515
- };
516
- }
517
- function createConsoleSink() {
518
- return (record) => {
519
- const emitted = toEmittedLogRecord(record);
520
- emitConsole(
521
- emitted.level,
522
- emitted.eventName,
523
- emitted.body,
524
- emitted.attributes
525
- );
526
- };
527
- }
528
- function createSentrySink() {
529
- return (record) => {
530
- const emitted = toEmittedLogRecord(record);
531
- emitSentry(emitted.level, emitted.body, emitted.attributes);
532
- };
533
- }
534
- function createRecordSink() {
535
- return (record) => {
536
- const emitted = toEmittedLogRecord(record);
537
- for (const sink of logRecordSinks) {
538
- try {
539
- sink(emitted);
540
- } catch {
541
- }
542
- }
543
- };
544
- }
545
- var rootLogger;
546
- var ownsLogTapeBackend = false;
547
- var usesDirectEmissionFallback = false;
548
- function ensureLoggerBackend() {
549
- if (rootLogger || usesDirectEmissionFallback) {
550
- return;
551
- }
552
- if (getConfig() !== null) {
553
- usesDirectEmissionFallback = true;
554
- return;
555
- }
556
- try {
557
- configureSync({
558
- sinks: {
559
- console: createConsoleSink(),
560
- sentry: createSentrySink(),
561
- records: createRecordSink()
562
- },
563
- loggers: [
564
- {
565
- category: [...ROOT_LOGGER_CATEGORY],
566
- sinks: ["console", "sentry", "records"],
567
- lowestLevel: "debug"
568
- },
569
- {
570
- category: ["logtape"],
571
- sinks: ["console"],
572
- lowestLevel: "error"
573
- }
574
- ],
575
- contextLocalStorage: logContextStorage
576
- });
577
- ownsLogTapeBackend = true;
578
- rootLogger = getLogger([...ROOT_LOGGER_CATEGORY]);
579
- } catch (error) {
580
- if (error instanceof ConfigError && getConfig() !== null) {
581
- usesDirectEmissionFallback = true;
582
- return;
583
- }
584
- throw error;
585
- }
586
- }
587
- function getLogTapeLogger(category = []) {
588
- ensureLoggerBackend();
589
- if (!rootLogger) {
590
- throw new Error("LogTape backend is unavailable");
591
- }
592
- let logger2 = rootLogger;
593
- for (const part of category) {
594
- logger2 = logger2.getChild(part);
595
- }
596
- return logger2;
597
- }
598
- function emitSentry(level, body, attributes) {
599
- if (shouldSuppressInfoLog(level)) {
600
- return;
601
- }
602
- const loggerFn = logger?.[level];
603
- if (typeof loggerFn === "function") {
604
- loggerFn(body, attributes);
605
- return;
606
- }
607
- const sentryLevel = level === "warn" ? "warning" : level;
608
- withScope((scope) => {
609
- for (const [key, value] of Object.entries(attributes)) {
610
- scope.setExtra(key, value);
611
- }
612
- captureMessage(body, sentryLevel);
613
- });
614
- }
615
- function formatConsoleLevel(level) {
616
- if (level === "debug") return "DBG";
617
- if (level === "info") return "INF";
618
- if (level === "warn") return "WRN";
619
- return "ERR";
620
- }
621
- function consoleLevelStyle(level) {
622
- if (level === "error") return "red";
623
- if (level === "warn") return "yellow";
624
- if (level === "info") return "green";
625
- return "blue";
626
- }
627
- function quoteConsoleValue(value) {
628
- return `"${value.replace(/\\/g, "\\\\").replace(/"/g, '\\"')}"`;
629
- }
630
- function formatConsoleValue(value) {
631
- if (typeof value === "number" || typeof value === "boolean") {
632
- return String(value);
633
- }
634
- if (Array.isArray(value)) {
635
- return quoteConsoleValue(JSON.stringify(value));
636
- }
637
- if (/^[A-Za-z0-9._:/@+-]+$/.test(value)) {
638
- return value;
639
- }
640
- return quoteConsoleValue(value);
641
- }
642
- function shouldShowConsoleDestinationName(eventName) {
643
- return /^(app_home|oauth|queue|slash_command|slack|webhook)\./.test(
644
- eventName
645
- );
646
- }
647
- function shouldShowConsoleModel(level, eventName) {
648
- if (level === "warn" || level === "error") {
649
- return true;
650
- }
651
- return eventName.startsWith("ai.") || eventName.startsWith("assistant.") || eventName === "agent.turn.started" || eventName === "agent.turn.completed" || eventName === "agent.turn.provider_error";
652
- }
653
- function shouldHideConsoleAttribute(level, eventName, key, attributes) {
654
- if (CONSOLE_ALWAYS_HIDDEN_KEYS.has(key)) {
655
- return true;
656
- }
657
- if (CONSOLE_DROP_WHEN_COUNTED_KEYS.has(key)) {
658
- return true;
659
- }
660
- if (key === "messaging.message.conversation_id" && attributes[key] === attributes["gen_ai.conversation.id"]) {
661
- return true;
662
- }
663
- if (key === "app.message.id" && attributes[key] === attributes["messaging.message.id"]) {
664
- return true;
665
- }
666
- if (key === "messaging.destination.name" && !shouldShowConsoleDestinationName(eventName)) {
667
- return true;
668
- }
669
- if (key === "gen_ai.request.model" && !shouldShowConsoleModel(level, eventName)) {
670
- return true;
671
- }
672
- if (key === "gen_ai.provider.name" && eventName.startsWith("agent.tool_call.") && level !== "warn" && level !== "error") {
673
- return true;
674
- }
675
- if (key === "gen_ai.operation.name" && eventName.startsWith("agent.tool_call.")) {
676
- return true;
677
- }
678
- return false;
679
- }
680
- function summarizeConsoleString(value, maxChars) {
681
- const collapsed = value.replace(/\s+/g, " ").trim();
682
- if (collapsed.length <= maxChars) {
683
- return collapsed;
684
- }
685
- return `${collapsed.slice(0, maxChars)}... [${collapsed.length} chars]`;
686
- }
687
- function abbreviateConsoleId(value) {
688
- if (value.length <= 20) {
689
- return value;
690
- }
691
- return `${value.slice(0, 12)}...${value.slice(-4)}`;
692
- }
693
- function toRelativeConsolePath(value) {
694
- const normalized = value.trim();
695
- if (!normalized) {
696
- return normalized;
697
- }
698
- try {
699
- const relative = path.relative(process.cwd(), normalized);
700
- if (relative.length > 0 && !relative.startsWith("..") && !path.isAbsolute(relative)) {
701
- return relative;
702
- }
703
- } catch {
704
- }
705
- return normalized;
706
- }
707
- function pushPrettyConsoleToken(tokens, token) {
708
- if (!token || tokens.includes(token)) {
709
- return;
710
- }
711
- tokens.push(token);
712
- }
713
- function numericConsoleToken(label, value) {
714
- return typeof value === "number" ? `${label}=${value}` : void 0;
715
- }
716
- function stringConsoleToken(label, value) {
717
- const normalized = toOptionalString(value);
718
- return normalized ? `${label}=${normalized}` : void 0;
719
- }
720
- function booleanConsoleToken(label, value) {
721
- return typeof value === "boolean" ? `${label}=${value ? "yes" : "no"}` : void 0;
722
- }
723
- function shouldShowPrettyCorrelation(eventName) {
724
- return !(eventName === "plugin.loaded" || eventName === "startup.discovery.completed" || eventName.endsWith(".loaded"));
725
- }
726
- function getPrettyConsoleSummaryTokens(level, eventName, attributes) {
727
- const tokens = [];
728
- pushPrettyConsoleToken(
729
- tokens,
730
- toOptionalString(attributes["app.log.source"]) ?? void 0
731
- );
732
- pushPrettyConsoleToken(
733
- tokens,
734
- eventName.startsWith("plugin.heartbeat.") ? stringConsoleToken("plugin", attributes["app.plugin.name"]) : toOptionalString(attributes["app.plugin.name"]) ?? void 0
735
- );
736
- pushPrettyConsoleToken(
737
- tokens,
738
- numericConsoleToken("config", attributes["app.plugin.config_key_count"])
739
- );
740
- pushPrettyConsoleToken(
741
- tokens,
742
- booleanConsoleToken("mcp", attributes["app.plugin.has_mcp"])
743
- );
744
- pushPrettyConsoleToken(
745
- tokens,
746
- numericConsoleToken("plugins", attributes["app.plugin.count"])
747
- );
748
- pushPrettyConsoleToken(
749
- tokens,
750
- numericConsoleToken("dispatches", attributes["app.dispatch.count"])
751
- );
752
- pushPrettyConsoleToken(
753
- tokens,
754
- numericConsoleToken("skills", attributes["app.skill.count"])
755
- );
756
- pushPrettyConsoleToken(
757
- tokens,
758
- numericConsoleToken("config", attributes["app.config.key_count"])
759
- );
760
- pushPrettyConsoleToken(
761
- tokens,
762
- numericConsoleToken("chars", attributes["app.message.length"])
763
- );
764
- pushPrettyConsoleToken(
765
- tokens,
766
- numericConsoleToken(
767
- "attachments",
768
- attributes["app.message.attachment_count"]
769
- )
770
- );
771
- const rawAttachmentCount = toOptionalNumber(
772
- attributes["app.message.attachment_count"]
773
- );
774
- const promptAttachmentCount = toOptionalNumber(
775
- attributes["app.message.prompt_attachment_count"]
776
- );
777
- if (promptAttachmentCount !== void 0 && promptAttachmentCount !== rawAttachmentCount) {
778
- pushPrettyConsoleToken(
779
- tokens,
780
- numericConsoleToken("prompt_attachments", promptAttachmentCount)
781
- );
782
- }
783
- const filePath = toOptionalString(attributes["file.path"]);
784
- if (filePath && eventName.endsWith(".loaded")) {
785
- pushPrettyConsoleToken(tokens, toRelativeConsolePath(filePath));
786
- }
787
- if (shouldShowPrettyCorrelation(eventName)) {
788
- const conversationId = toOptionalString(
789
- attributes["gen_ai.conversation.id"]
790
- );
791
- const messageId = toOptionalString(attributes["messaging.message.id"]);
792
- if (conversationId) {
793
- pushPrettyConsoleToken(
794
- tokens,
795
- `conv=${abbreviateConsoleId(conversationId)}`
796
- );
797
- }
798
- if (messageId) {
799
- pushPrettyConsoleToken(tokens, `msg=${abbreviateConsoleId(messageId)}`);
800
- }
801
- }
802
- const model = toOptionalString(attributes["gen_ai.request.model"]);
803
- if (model && shouldShowConsoleModel(level, eventName)) {
804
- pushPrettyConsoleToken(tokens, `model=${model}`);
805
- }
806
- return tokens;
807
- }
808
- function projectConsoleValue(level, key, value) {
809
- if ((level === "debug" || level === "info") && CONSOLE_PREVIEW_KEYS.has(key) && typeof value === "string") {
810
- return summarizeConsoleString(
811
- value,
812
- key === "gen_ai.tool.call.result" ? 220 : 140
813
- );
814
- }
815
- return value;
816
- }
817
- function projectConsoleAttributes(level, eventName, attributes) {
818
- const projected = {};
819
- for (const [key, value] of Object.entries(attributes)) {
820
- if (shouldHideConsoleAttribute(level, eventName, key, attributes)) {
821
- continue;
822
- }
823
- const nextValue = projectConsoleValue(level, key, value);
824
- if (nextValue !== void 0) {
825
- projected[key] = nextValue;
826
- }
827
- }
828
- return projected;
829
- }
830
- function formatConsoleLine(level, eventName, body, attributes) {
831
- const timestamp = /* @__PURE__ */ new Date();
832
- const useColor = shouldUseConsoleColor();
833
- const levelStyle = consoleLevelStyle(level);
834
- const colorize = (text, style) => useColor ? styleText(style, text) : text;
835
- if (shouldUsePrettyConsole(level)) {
836
- const summaryTokens = getPrettyConsoleSummaryTokens(
837
- level,
838
- eventName,
839
- attributes
840
- );
841
- const summary = [body, ...summaryTokens].join(" ");
842
- return [
843
- colorize(formatConsoleTimestamp(timestamp), "gray"),
844
- colorize(formatConsoleLevel(level), levelStyle),
845
- summary
846
- ].join(" ");
847
- }
848
- const parts = [
849
- `${colorize(formatConsoleTimestamp(timestamp), "gray")} ${colorize(formatConsoleLevel(level), levelStyle)} ${body}`
850
- ];
851
- const projectedAttributes = projectConsoleAttributes(
852
- level,
853
- eventName,
854
- attributes
855
- );
856
- const sortedAttributes = Object.entries(projectedAttributes).sort(
857
- ([left], [right]) => {
858
- const leftRank = CONSOLE_PRIORITY_INDEX.get(left);
859
- const rightRank = CONSOLE_PRIORITY_INDEX.get(right);
860
- if (leftRank !== void 0 || rightRank !== void 0) {
861
- if (leftRank === void 0) return 1;
862
- if (rightRank === void 0) return -1;
863
- return leftRank - rightRank;
864
- }
865
- return left.localeCompare(right);
866
- }
867
- );
868
- for (const [key, value] of sortedAttributes) {
869
- const rendered = `${colorize(key, "cyan")}=${colorize(formatConsoleValue(value), "dim")}`;
870
- parts.push(rendered);
871
- }
872
- return parts.join(" ");
873
- }
874
- function emitConsole(level, eventName, body, attributes) {
875
- if (!shouldEmitConsole(level)) {
876
- return;
877
- }
878
- const line = formatConsoleLine(level, eventName, body, attributes);
879
- if (level === "error") {
880
- console.error(line);
881
- return;
882
- }
883
- if (level === "warn") {
884
- console.warn(line);
885
- return;
886
- }
887
- if (level === "info") {
888
- console.info(line);
889
- return;
890
- }
891
- console.debug(line);
892
- }
893
- function emitDirect(level, eventName, body, attributes) {
894
- for (const sink of logRecordSinks) {
895
- try {
896
- sink({
897
- level,
898
- eventName,
899
- body,
900
- attributes
901
- });
902
- } catch {
903
- }
904
- }
905
- emitConsole(level, eventName, body, attributes);
906
- emitSentry(level, body, attributes);
907
- }
908
- function emitRecord(category, level, eventName, attrs = {}, body) {
909
- ensureLoggerBackend();
910
- const traceAttributes = getTraceCorrelationAttributes();
911
- const normalizedEventName = normalizeEventName(eventName);
912
- const message = body ? redactSecrets(body) : normalizedEventName;
913
- const source = getLogSource([...ROOT_LOGGER_CATEGORY, ...category]);
914
- const contextAttributes = ownsLogTapeBackend ? void 0 : getBoundLogAttributes();
915
- const attributes = mergeAttributes(
916
- contextAttributes,
917
- traceAttributes,
918
- {
919
- "event.name": normalizedEventName,
920
- ...source ? { "app.log.source": source } : void 0,
921
- ...attrs
922
- },
923
- // Deployment identity is process-owned and must win over event-local attrs.
924
- deploymentLogAttributes
925
- );
926
- if (usesDirectEmissionFallback) {
927
- emitDirect(level, normalizedEventName, message, attributes);
928
- return;
929
- }
930
- const logger2 = getLogTapeLogger(category);
931
- const properties = {
932
- [LOGTAPE_BODY_KEY]: message,
933
- ...attributes
934
- };
935
- if (level === "error") {
936
- logger2.error(`{${LOGTAPE_BODY_KEY}}`, properties);
937
- return;
938
- }
939
- if (level === "warn") {
940
- logger2.warn(`{${LOGTAPE_BODY_KEY}}`, properties);
941
- return;
942
- }
943
- if (level === "info") {
944
- logger2.info(`{${LOGTAPE_BODY_KEY}}`, properties);
945
- return;
946
- }
947
- logger2.debug(`{${LOGTAPE_BODY_KEY}}`, properties);
948
- }
949
- function emit(level, eventName, attrs = {}, body) {
950
- emitRecord([], level, eventName, attrs, body);
951
- }
952
- var log = {
953
- debug(eventName, attrs = {}, body) {
954
- emit("debug", eventName, attrs, body);
955
- },
956
- info(eventName, attrs = {}, body) {
957
- emit("info", eventName, attrs, body);
958
- },
959
- warn(eventName, attrs = {}, body) {
960
- emit("warn", eventName, attrs, body);
961
- },
962
- error(eventName, attrs = {}, body) {
963
- emit("error", eventName, attrs, body);
964
- },
965
- exception(eventName, error, attrs = {}, body) {
966
- const normalizedError = error instanceof Error ? error : new Error(String(error));
967
- emit(
968
- "error",
969
- eventName,
970
- {
971
- ...attrs,
972
- "error.type": normalizedError.name,
973
- "exception.type": normalizedError.name,
974
- "exception.message": normalizedError.message,
975
- "exception.stacktrace": normalizedError.stack
976
- },
977
- body
978
- );
979
- let eventId;
980
- withScope((scope) => {
981
- setSentryScopeContext(scope, getBoundLogContext());
982
- const mergedAttributes = mergeAttributes(getBoundLogAttributes(), attrs);
983
- for (const [key, value] of Object.entries(mergedAttributes)) {
984
- scope.setExtra(key, value);
985
- if (SENTRY_TAG_ATTRIBUTE_KEYS.has(key) && typeof value === "string" && value.length > 0) {
986
- scope.setTag(key, value);
987
- }
988
- }
989
- const capturedEventId = captureException(normalizedError);
990
- eventId = typeof capturedEventId === "string" ? capturedEventId : void 0;
991
- });
992
- return eventId;
993
- }
994
- };
995
- var CHAT_SDK_LEVEL_PRIORITY = {
996
- debug: 10,
997
- info: 20,
998
- warn: 30,
999
- error: 40
1000
- };
1001
- function resolveChatSdkLogLevel() {
1002
- if (isDevelopmentLoggingMode()) {
1003
- return "warn";
1004
- }
1005
- return "info";
1006
- }
1007
- function shouldEmitChatSdkLevel(level, minimumLevel) {
1008
- if (minimumLevel === "silent") {
1009
- return false;
1010
- }
1011
- return CHAT_SDK_LEVEL_PRIORITY[level] >= CHAT_SDK_LEVEL_PRIORITY[minimumLevel];
1012
- }
1013
- function renderChatSdkArgument(value) {
1014
- if (value === null || value === void 0) {
1015
- return "";
1016
- }
1017
- if (typeof value === "string") {
1018
- return value;
1019
- }
1020
- if (value instanceof Error) {
1021
- return value.message;
1022
- }
1023
- try {
1024
- return JSON.stringify(value);
1025
- } catch {
1026
- return String(value);
1027
- }
1028
- }
1029
- function formatChatSdkBody(message, args) {
1030
- const renderedArgs = args.map((arg) => renderChatSdkArgument(arg).trim()).filter((arg) => arg.length > 0);
1031
- if (renderedArgs.length === 0) {
1032
- return message;
1033
- }
1034
- return `${message} ${renderedArgs.join(" ")}`;
1035
- }
1036
- function createChatSdkLoggerImpl(category, minimumLevel) {
1037
- const emitChatSdkLog = (level, message, args) => {
1038
- if (!shouldEmitChatSdkLevel(level, minimumLevel)) {
1039
- return;
1040
- }
1041
- emitRecord(
1042
- category,
1043
- level === "warn" ? "warn" : level,
1044
- level === "error" ? "chat_sdk.log.error" : level === "warn" ? "chat_sdk.log.warn" : "chat_sdk.log",
1045
- args.length > 0 ? {
1046
- "app.log.args": args.length === 1 ? args[0] : args
1047
- } : {},
1048
- formatChatSdkBody(message, args)
1049
- );
1050
- };
1051
- return {
1052
- child(prefix) {
1053
- return createChatSdkLoggerImpl([...category, prefix], minimumLevel);
1054
- },
1055
- debug(message, ...args) {
1056
- emitChatSdkLog("debug", message, args);
1057
- },
1058
- info(message, ...args) {
1059
- emitChatSdkLog("info", message, args);
1060
- },
1061
- warn(message, ...args) {
1062
- emitChatSdkLog("warn", message, args);
1063
- },
1064
- error(message, ...args) {
1065
- emitChatSdkLog("error", message, args);
1066
- }
1067
- };
1068
- }
1069
- function createChatSdkLogger() {
1070
- return createChatSdkLoggerImpl(["chat-sdk"], resolveChatSdkLogLevel());
1071
- }
1072
- function withLogContext(context, callback) {
1073
- return runWithLogContext(
1074
- context,
1075
- contextToAttributes(context),
1076
- callback
1077
- );
1078
- }
1079
- function getLogContextAttributes() {
1080
- return getBoundLogAttributes();
1081
- }
1082
- function getLogContextAttributesForSpan(op) {
1083
- const attributes = { ...getLogContextAttributes() };
1084
- if (op === "gen_ai.invoke_agent" || op === "gen_ai.execute_tool") {
1085
- delete attributes["gen_ai.request.model"];
1086
- return attributes;
1087
- }
1088
- if (op === "gen_ai.chat" || op === "gen_ai.embeddings") {
1089
- delete attributes["gen_ai.agent.name"];
1090
- delete attributes["gen_ai.request.model"];
1091
- return attributes;
1092
- }
1093
- delete attributes["gen_ai.agent.name"];
1094
- delete attributes["gen_ai.request.model"];
1095
- return attributes;
1096
- }
1097
- function createLogContextFromRequest(request, context = {}) {
1098
- const url = new URL(request.url);
1099
- return {
1100
- ...context,
1101
- requestId: context.requestId ?? request.headers.get("x-request-id") ?? void 0,
1102
- httpMethod: request.method,
1103
- httpPath: url.pathname,
1104
- urlFull: url.toString(),
1105
- userAgent: request.headers.get("user-agent") ?? void 0
1106
- };
1107
- }
1108
- function setSentryTagsFromContext(context) {
1109
- const attrs = contextToAttributes(context);
1110
- for (const [key, value] of Object.entries(attrs)) {
1111
- if (!SENTRY_TAG_ATTRIBUTE_KEYS.has(key)) {
1112
- continue;
1113
- }
1114
- if (typeof value === "string" && value.length > 0) {
1115
- setTag(key, value);
1116
- }
1117
- }
1118
- }
1119
- function sentryUserIdentityFromContext(context) {
1120
- if (context.userId) {
1121
- const email = normalizeIdentityEmail(context.userEmail);
1122
- return {
1123
- id: context.userId,
1124
- ...context.userName ? { username: context.userName } : void 0,
1125
- ...email ? { email } : void 0
1126
- };
1127
- }
1128
- return void 0;
1129
- }
1130
- function sentryUserFromIdentity(identity) {
1131
- return {
1132
- id: identity.id,
1133
- ip_address: null,
1134
- ...identity.username ? { username: identity.username } : void 0,
1135
- ...identity.email ? { email: identity.email } : void 0
1136
- };
1137
- }
1138
- function setSentryUser(identity) {
1139
- if (!identity) return;
1140
- setUser(sentryUserFromIdentity(identity));
1141
- }
1142
- function setSentryScopeContext(scope, context) {
1143
- const attrs = contextToAttributes(context);
1144
- for (const [key, value] of Object.entries(attrs)) {
1145
- if (!SENTRY_TAG_ATTRIBUTE_KEYS.has(key)) {
1146
- continue;
1147
- }
1148
- if (typeof value === "string" && value.length > 0) {
1149
- scope.setTag(key, value);
1150
- }
1151
- }
1152
- const identity = sentryUserIdentityFromContext(context);
1153
- if (identity) {
1154
- scope.setUser(sentryUserFromIdentity(identity));
1155
- }
1156
- scope.setContext("app", attrs);
1157
- }
1158
- function toSpanAttributeValue(value) {
1159
- if (typeof value === "string" || typeof value === "number" || typeof value === "boolean") {
1160
- return value;
1161
- }
1162
- if (!Array.isArray(value)) {
1163
- return void 0;
1164
- }
1165
- const sanitized = value.filter(
1166
- (entry) => typeof entry === "string"
1167
- );
1168
- return sanitized.length > 0 ? sanitized : void 0;
1169
- }
1170
- function normalizeSpanAttributes(attributes) {
1171
- const normalized = {};
1172
- for (const [rawKey, value] of Object.entries(attributes)) {
1173
- const key = normalizeAttributeKey(rawKey);
1174
- const normalizedValue = toSpanAttributeValue(
1175
- key === "gen_ai.response.finish_reasons" ? normalizeGenAiFinishReasons(value) : value
1176
- );
1177
- if (normalizedValue !== void 0) {
1178
- normalized[key] = normalizedValue;
1179
- }
1180
- }
1181
- return normalized;
1182
- }
1183
- function setAttributesOnSpan(span, attributes) {
1184
- for (const [key, value] of Object.entries(
1185
- normalizeSpanAttributes(attributes)
1186
- )) {
1187
- span.setAttribute(key, value);
1188
- }
1189
- }
1190
- function logInfo(eventName, attributes = {}) {
1191
- log.info(eventName, attributes);
1192
- }
1193
- function logWarn(eventName, attributes = {}) {
1194
- log.warn(eventName, attributes);
1195
- }
1196
- function logError(eventName, attributes = {}) {
1197
- log.error(eventName, attributes);
1198
- }
1199
- function logException(error, eventName, attributes = {}) {
1200
- const normalizedError = error instanceof Error ? error : new Error(String(error));
1201
- return log.exception(eventName, normalizedError, attributes);
1202
- }
1203
- async function runBestEffort(operation, eventName, attributes = {}) {
1204
- try {
1205
- await operation();
1206
- } catch (error) {
1207
- logException(error, eventName, attributes);
1208
- }
1209
- }
1210
- function setTags(context = {}) {
1211
- updateLogContext(context, contextToAttributes(context));
1212
- setSentryTagsFromContext(context);
1213
- setSentryUser(sentryUserIdentityFromContext(context));
1214
- }
1215
- function createRequestContext(request, context = {}) {
1216
- return createLogContextFromRequest(request, context);
1217
- }
1218
- async function withContext(context, callback) {
1219
- return withLogContext(context, callback);
1220
- }
1221
- async function withSpan(name, op, context, callback, attributes = {}) {
1222
- const normalizedAttributes = normalizeSpanAttributes(attributes);
1223
- return withLogContext(context, () => {
1224
- const inheritedAttributes = getLogContextAttributesForSpan(op);
1225
- return startSpan(
1226
- {
1227
- name,
1228
- op,
1229
- attributes: {
1230
- ...inheritedAttributes,
1231
- ...normalizedAttributes
1232
- }
1233
- },
1234
- async (span) => {
1235
- try {
1236
- return await callback(
1237
- (attributes2) => setAttributesOnSpan(span, attributes2)
1238
- );
1239
- } catch (error) {
1240
- setAttributesOnSpan(span, {
1241
- "error.type": error instanceof Error ? error.name : typeof error
1242
- });
1243
- throw error;
1244
- }
1245
- }
1246
- );
1247
- });
1248
- }
1249
- function getTracePropagationHeaders() {
1250
- const traceData = getTraceData({ propagateTraceparent: true });
1251
- if (!traceData) {
1252
- return {};
1253
- }
1254
- const headers = {};
1255
- for (const key of ["sentry-trace", "baggage", "traceparent"]) {
1256
- const value = traceData[key];
1257
- if (typeof value === "string" && value.trim()) {
1258
- headers[key] = value;
1259
- }
1260
- }
1261
- return headers;
1262
- }
1263
- function setSpanAttributes(attributes) {
1264
- const span = getActiveSpan();
1265
- if (!span) {
1266
- return;
1267
- }
1268
- setAttributesOnSpan(span, attributes);
1269
- }
1270
- function setSpanStatus(status) {
1271
- const span = getActiveSpan();
1272
- if (!span) {
1273
- return;
1274
- }
1275
- span.setStatus(
1276
- status === "ok" ? { code: 1 } : { code: 2, message: "internal_error" }
1277
- );
1278
- }
1279
- function getActiveTraceId() {
1280
- try {
1281
- const span = getActiveSpan();
1282
- if (!span) {
1283
- return void 0;
1284
- }
1285
- return toOptionalString(spanToJSON(span).trace_id);
1286
- } catch {
1287
- return void 0;
1288
- }
1289
- }
1290
- var TURN_FAILURE_RESPONSE_TEMPLATE = "I ran into an internal error while processing that. Reference: `event_id={eventId}`.";
1291
- function buildTurnFailureResponse(eventId) {
1292
- return TURN_FAILURE_RESPONSE_TEMPLATE.replace("{eventId}", eventId);
1293
- }
1294
- var GEN_AI_DEFAULT_MAX_ATTRIBUTE_CHARS = 1e5;
1295
- var GEN_AI_MAX_ARRAY_ITEMS = 50;
1296
- var GEN_AI_MAX_OBJECT_KEYS = 50;
1297
- function truncateGenAiString(value, maxChars) {
1298
- return value.length > maxChars ? "" : value;
1299
- }
1300
- function sanitizeGenAiValue(value, seen, depth, keyName) {
1301
- if (value === null || value === void 0) {
1302
- return void 0;
1303
- }
1304
- if (typeof value === "string") {
1305
- const shouldTreatAsBlob = (keyName === "data" || keyName === "base64" || keyName?.endsWith("_base64") === true) && value.length > 256;
1306
- if (shouldTreatAsBlob) {
1307
- return `[omitted:${value.length}]`;
1308
- }
1309
- return redactSecrets(value);
1310
- }
1311
- if (typeof value === "number") {
1312
- return Number.isFinite(value) ? value : void 0;
1313
- }
1314
- if (typeof value === "boolean") {
1315
- return value;
1316
- }
1317
- if (depth >= 8) {
1318
- return "[depth_limit]";
1319
- }
1320
- if (Array.isArray(value)) {
1321
- return value.slice(0, GEN_AI_MAX_ARRAY_ITEMS).map((entry) => sanitizeGenAiValue(entry, seen, depth + 1)).filter((entry) => entry !== void 0);
1322
- }
1323
- if (typeof value !== "object") {
1324
- return redactSecrets(String(value));
1325
- }
1326
- if (seen.has(value)) {
1327
- return "[circular]";
1328
- }
1329
- seen.add(value);
1330
- const record = value;
1331
- const out = {};
1332
- for (const [key, entryValue] of Object.entries(record).slice(
1333
- 0,
1334
- GEN_AI_MAX_OBJECT_KEYS
1335
- )) {
1336
- const sanitized = sanitizeGenAiValue(entryValue, seen, depth + 1, key);
1337
- if (sanitized !== void 0) {
1338
- out[key] = sanitized;
1339
- }
1340
- }
1341
- return out;
1342
- }
1343
- function serializeGenAiAttribute(value, maxChars = GEN_AI_DEFAULT_MAX_ATTRIBUTE_CHARS) {
1344
- const sanitized = sanitizeGenAiValue(value, /* @__PURE__ */ new WeakSet(), 0);
1345
- if (sanitized === void 0) {
1346
- return void 0;
1347
- }
1348
- const serialized = typeof sanitized === "string" ? sanitized : JSON.stringify(sanitized);
1349
- if (!serialized) {
1350
- return void 0;
1351
- }
1352
- return truncateGenAiString(redactSecrets(serialized), maxChars) || void 0;
1353
- }
1354
- function asRecord(value) {
1355
- return value && typeof value === "object" ? value : void 0;
1356
- }
1357
- function toFiniteTokenCount(value) {
1358
- if (typeof value !== "number" || !Number.isFinite(value)) {
1359
- return void 0;
1360
- }
1361
- const rounded = Math.floor(value);
1362
- return rounded >= 0 ? rounded : void 0;
1363
- }
1364
- function toFiniteCost(value) {
1365
- return typeof value === "number" && Number.isFinite(value) && value >= 0 ? value : void 0;
1366
- }
1367
- function addCost(left, right) {
1368
- return Math.round(((left ?? 0) + right) * 1e12) / 1e12;
1369
- }
1370
- function sumTokenCounts(...values) {
1371
- let total = 0;
1372
- let hasValue = false;
1373
- for (const value of values) {
1374
- if (value === void 0) {
1375
- continue;
1376
- }
1377
- total += value;
1378
- hasValue = true;
1379
- }
1380
- return hasValue ? total : void 0;
1381
- }
1382
- var PI_USAGE_FIELDS = [
1383
- ["input", "inputTokens"],
1384
- ["output", "outputTokens"],
1385
- ["cacheRead", "cachedInputTokens"],
1386
- ["cacheWrite", "cacheCreationTokens"],
1387
- ["reasoning", "reasoningTokens"],
1388
- ["totalTokens", "totalTokens"]
1389
- ];
1390
- var PI_COST_FIELDS = [
1391
- "input",
1392
- "output",
1393
- "cacheRead",
1394
- "cacheWrite",
1395
- "total"
1396
- ];
1397
- function readPiUsage(source) {
1398
- const record = asRecord(source);
1399
- if (!record) {
1400
- return {};
1401
- }
1402
- const usage = asRecord(record.usage) ?? record;
1403
- const summary = {};
1404
- for (const [piKey, ourKey] of PI_USAGE_FIELDS) {
1405
- const value = toFiniteTokenCount(usage[piKey]) ?? toFiniteTokenCount(usage[ourKey]);
1406
- if (value !== void 0) {
1407
- summary[ourKey] = value;
1408
- }
1409
- }
1410
- const piCost = asRecord(usage.cost);
1411
- if (piCost) {
1412
- const cost = {};
1413
- for (const field of PI_COST_FIELDS) {
1414
- const value = toFiniteCost(piCost[field]);
1415
- if (value !== void 0) {
1416
- cost[field] = value;
1417
- }
1418
- }
1419
- if (Object.keys(cost).length > 0) {
1420
- summary.cost = cost;
1421
- }
1422
- }
1423
- return summary;
1424
- }
1425
- function extractGenAiUsageSummary(...sources) {
1426
- const summary = {};
1427
- const cost = {};
1428
- for (const source of sources) {
1429
- const single = readPiUsage(source);
1430
- for (const field of [
1431
- "inputTokens",
1432
- "outputTokens",
1433
- "cachedInputTokens",
1434
- "cacheCreationTokens",
1435
- "reasoningTokens",
1436
- "totalTokens"
1437
- ]) {
1438
- const value = single[field];
1439
- if (value === void 0) continue;
1440
- summary[field] = (summary[field] ?? 0) + value;
1441
- }
1442
- for (const field of PI_COST_FIELDS) {
1443
- const value = single.cost?.[field];
1444
- if (value === void 0) continue;
1445
- cost[field] = addCost(cost[field], value);
1446
- }
1447
- }
1448
- if (Object.keys(cost).length > 0) {
1449
- summary.cost = cost;
1450
- }
1451
- return summary;
1452
- }
1453
- function extractGenAiUsageAttributes(...sources) {
1454
- const {
1455
- inputTokens,
1456
- outputTokens,
1457
- cachedInputTokens,
1458
- cacheCreationTokens,
1459
- reasoningTokens,
1460
- cost
1461
- } = extractGenAiUsageSummary(...sources);
1462
- const semanticInputTokens = sumTokenCounts(
1463
- inputTokens,
1464
- cachedInputTokens,
1465
- cacheCreationTokens
1466
- );
1467
- return {
1468
- ...semanticInputTokens !== void 0 ? { "gen_ai.usage.input_tokens": semanticInputTokens } : void 0,
1469
- ...outputTokens !== void 0 ? { "gen_ai.usage.output_tokens": outputTokens } : void 0,
1470
- // OTel has no monetary cost attributes, so report accounting generically.
1471
- ...cachedInputTokens !== void 0 ? { "gen_ai.usage.cache_read.input_tokens": cachedInputTokens } : void 0,
1472
- ...cacheCreationTokens !== void 0 ? { "gen_ai.usage.cache_creation.input_tokens": cacheCreationTokens } : void 0,
1473
- ...reasoningTokens !== void 0 ? { "gen_ai.usage.reasoning.output_tokens": reasoningTokens } : void 0,
1474
- ...cost?.input !== void 0 ? { "app.cost.input_usd": cost.input } : void 0,
1475
- ...cost?.output !== void 0 ? { "app.cost.output_usd": cost.output } : void 0,
1476
- ...cost?.cacheRead !== void 0 ? { "app.cost.cache_read_usd": cost.cacheRead } : void 0,
1477
- ...cost?.cacheWrite !== void 0 ? { "app.cost.cache_write_usd": cost.cacheWrite } : void 0,
1478
- ...cost?.total !== void 0 ? { "app.cost.total_usd": cost.total } : void 0
1479
- };
1480
- }
1481
-
1482
- export {
1483
- toOptionalString,
1484
- toOptionalNumber,
1485
- isRecord,
1486
- normalizeIdentityEmail,
1487
- JUNIOR_HEARTBEAT_ROUTE,
1488
- JUNIOR_HEARTBEAT_CRON_SCHEDULE,
1489
- JUNIOR_RETENTION_ROUTE,
1490
- JUNIOR_RETENTION_CRON_SCHEDULE,
1491
- JUNIOR_CONVERSATION_WORK_CALLBACK_ROUTE,
1492
- JUNIOR_PLUGIN_TASK_CALLBACK_ROUTE,
1493
- JUNIOR_WORKSPACE_SNAPSHOT_JOB_CALLBACK_ROUTE,
1494
- LEGACY_JUNIOR_CONVERSATION_WORK_FUNCTION,
1495
- getDeploymentServiceVersion,
1496
- getDeploymentTelemetryAttributes,
1497
- normalizeGenAiFinishReason,
1498
- summarizeMessageText,
1499
- createChatSdkLogger,
1500
- withLogContext,
1501
- getLogContextAttributesForSpan,
1502
- setSentryUser,
1503
- logInfo,
1504
- logWarn,
1505
- logError,
1506
- logException,
1507
- runBestEffort,
1508
- setTags,
1509
- createRequestContext,
1510
- withContext,
1511
- withSpan,
1512
- getTracePropagationHeaders,
1513
- setSpanAttributes,
1514
- setSpanStatus,
1515
- getActiveTraceId,
1516
- buildTurnFailureResponse,
1517
- serializeGenAiAttribute,
1518
- extractGenAiUsageSummary,
1519
- extractGenAiUsageAttributes
1520
- };