@sentry/junior 0.101.0 → 0.102.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 (65) hide show
  1. package/dist/{agent-hooks-V6KU7PQN.js → agent-hooks-I4I2DHSW.js} +7 -7
  2. package/dist/api/people/schema.d.ts +13 -0
  3. package/dist/api/schema.d.ts +1 -1
  4. package/dist/api/schema.js +1 -1
  5. package/dist/api.js +14 -14
  6. package/dist/app.js +64 -53
  7. package/dist/{catalog-runtime-PFHVMHDR.js → catalog-runtime-5CVM2DOF.js} +2 -2
  8. package/dist/chat/agent/prompt.d.ts +1 -1
  9. package/dist/chat/agent-dispatch/validation.d.ts +1 -1
  10. package/dist/chat/conversation-privacy.d.ts +2 -6
  11. package/dist/chat/credentials/context.d.ts +33 -6
  12. package/dist/chat/credentials/subject.d.ts +15 -1
  13. package/dist/chat/logging.d.ts +4 -2
  14. package/dist/chat/mcp/tool-manager.d.ts +1 -1
  15. package/dist/chat/sandbox/egress/schemas.d.ts +13 -2
  16. package/dist/chat/services/context-compaction-marker.d.ts +8 -0
  17. package/dist/{chunk-XJA7BPHS.js → chunk-3OABPOHR.js} +3 -3
  18. package/dist/{chunk-EBFJOOUE.js → chunk-3UK5DFKW.js} +2 -2
  19. package/dist/{chunk-DBPLXSBK.js → chunk-4YN2ZXKB.js} +9 -1
  20. package/dist/{chunk-XVR4O24H.js → chunk-5K4N73TP.js} +4 -4
  21. package/dist/{chunk-LMJPRYHP.js → chunk-77LHNQK4.js} +32 -8
  22. package/dist/{chunk-I35CTGPO.js → chunk-AEWZ7F65.js} +41 -17
  23. package/dist/{chunk-IQIBZXGB.js → chunk-B5QS4AVO.js} +2 -2
  24. package/dist/{chunk-L2JIOAA2.js → chunk-DTUSCR2Y.js} +8 -11
  25. package/dist/{chunk-GEUUJRQF.js → chunk-E4EMFKGB.js} +1 -1
  26. package/dist/{chunk-VVIXK2BX.js → chunk-EMUZSROX.js} +2 -2
  27. package/dist/{chunk-IVXL57YF.js → chunk-EOB77KME.js} +4 -4
  28. package/dist/{chunk-PGGEOCQY.js → chunk-F4CQEUTP.js} +1 -1
  29. package/dist/{chunk-FP5N5OWZ.js → chunk-IQ36I3DF.js} +2 -2
  30. package/dist/{chunk-JSAANELJ.js → chunk-LJB2TLVT.js} +3 -3
  31. package/dist/{chunk-D5KZYS4T.js → chunk-MJSJAHBW.js} +1 -1
  32. package/dist/{chunk-VFBFK6EY.js → chunk-MR6H67P2.js} +2 -2
  33. package/dist/{chunk-5VGJJSSV.js → chunk-NSP6OGL2.js} +5 -5
  34. package/dist/{chunk-VHRM6GNH.js → chunk-QZGVPPIJ.js} +27 -3
  35. package/dist/{chunk-LVA4I4H7.js → chunk-RT5BUHR5.js} +15 -44
  36. package/dist/{chunk-A7X2FDUO.js → chunk-SHBPSE7A.js} +88 -66
  37. package/dist/{chunk-CM5EZD5F.js → chunk-UIE3R5XU.js} +1 -1
  38. package/dist/{chunk-JPQISMMJ.js → chunk-VSAFV2GI.js} +7 -6
  39. package/dist/{chunk-3ECW2K2O.js → chunk-WR7H7VLJ.js} +2 -2
  40. package/dist/{chunk-TPTJEHUE.js → chunk-X2IPNCB5.js} +61 -25
  41. package/dist/{chunk-UWGTSF5O.js → chunk-ZIX4PNBI.js} +129 -91
  42. package/dist/{chunk-PWC24W5F.js → chunk-ZSHL44IQ.js} +2 -2
  43. package/dist/cli/chat.js +21 -21
  44. package/dist/cli/check.js +3 -3
  45. package/dist/cli/plugins.js +9 -9
  46. package/dist/cli/snapshot-warmup.js +5 -5
  47. package/dist/cli/upgrade.js +85 -13
  48. package/dist/db/postgres-json.d.ts +5 -0
  49. package/dist/{db-RCZB7KNM.js → db-6QP6HY7U.js} +4 -4
  50. package/dist/{detail-4EPUMSDU.js → detail-OEIVZYXS.js} +11 -11
  51. package/dist/{detail-CD4SPJ4K.js → detail-U6IP2Z4N.js} +6 -6
  52. package/dist/instrumentation.js +2 -2
  53. package/dist/{legacy-import-VCYLWT2V.js → legacy-import-R3BMM2GH.js} +5 -5
  54. package/dist/{list-J6ROVH56.js → list-AJ6RWBOG.js} +7 -7
  55. package/dist/list-UMZKA5AI.js +121 -0
  56. package/dist/{list-7L5LY2WU.js → list-Z3CC52CZ.js} +6 -6
  57. package/dist/{plugin-conversations-JANXC4GA.js → plugin-conversations-F3IBVNFX.js} +7 -7
  58. package/dist/{profile-6NRWEKMZ.js → profile-CQMPFKED.js} +7 -7
  59. package/dist/{runner-CZIKSWGC.js → runner-C2ZTIOUD.js} +12 -12
  60. package/dist/{skills-MAZXZ2KE.js → skills-722AXRV5.js} +3 -3
  61. package/dist/{stats-Q5FRUXLY.js → stats-ZYFQFCTL.js} +5 -5
  62. package/dist/{subagent-YIINCFAS.js → subagent-X3ZWJHR4.js} +10 -10
  63. package/dist/{validation-FMEAEKCY.js → validation-EUI2UFRM.js} +3 -3
  64. package/package.json +5 -5
  65. package/dist/list-DA2ATOM4.js +0 -80
@@ -133,40 +133,6 @@ function getCurrentConversationPrivacy() {
133
133
  function runWithConversationPrivacy(privacy, callback) {
134
134
  return conversationPrivacyStorage.run(privacy, callback);
135
135
  }
136
- function contentMetadata(content) {
137
- if (typeof content === "string") {
138
- return [{ type: "text", chars: content.length }];
139
- }
140
- if (!Array.isArray(content)) {
141
- return { type: typeof content };
142
- }
143
- return content.map((part) => {
144
- if (!part || typeof part !== "object") {
145
- return { type: typeof part };
146
- }
147
- const record = part;
148
- const type = canonicalContentPartType(
149
- typeof record.type === "string" ? record.type : "unknown"
150
- );
151
- return {
152
- type,
153
- ...typeof record.text === "string" ? { chars: record.text.length } : typeof record.thinking === "string" && record.thinking.length > 0 ? { chars: record.thinking.length } : {},
154
- ...typeof record.mimeType === "string" ? { mimeType: record.mimeType } : {},
155
- ...typeof record.mediaType === "string" ? { mediaType: record.mediaType } : {},
156
- ...typeof record.data === "string" ? { dataChars: record.data.length } : {}
157
- };
158
- });
159
- }
160
- function toGenAiMessageMetadata(message) {
161
- const record = message && typeof message === "object" ? message : {};
162
- return {
163
- role: record.role,
164
- content: contentMetadata(record.content)
165
- };
166
- }
167
- function toGenAiTextMetadata(text) {
168
- return { type: "text", chars: text.length };
169
- }
170
136
  function payloadType(payload) {
171
137
  return Array.isArray(payload) ? "array" : typeof payload;
172
138
  }
@@ -245,7 +211,7 @@ function summarizeContent(content) {
245
211
  return { chars, partTypes: [...partTypes] };
246
212
  }
247
213
  function normalizeFinishReason(reason) {
248
- return reason === "toolUse" ? "tool_use" : reason;
214
+ return reason === "toolUse" ? "tool_call" : reason;
249
215
  }
250
216
  function canonicalContentPartType(type) {
251
217
  if (type === "thinking") return "reasoning";
@@ -258,7 +224,7 @@ function toCanonicalPart(part) {
258
224
  }
259
225
  if (part.type === "thinking") {
260
226
  if (part.redacted) {
261
- return { type: "reasoning", redacted: true };
227
+ return void 0;
262
228
  }
263
229
  return { type: "reasoning", content: part.thinking };
264
230
  }
@@ -270,26 +236,33 @@ function toCanonicalPart(part) {
270
236
  arguments: part.arguments
271
237
  };
272
238
  }
273
- return { type: "image", mimeType: part.mimeType };
239
+ return void 0;
240
+ }
241
+ function toCanonicalParts(parts) {
242
+ return parts.map(toCanonicalPart).filter((part) => part !== void 0);
274
243
  }
275
244
  function toCanonicalOutputMessage(message) {
276
245
  return {
277
246
  role: "assistant",
278
- parts: message.content.map(toCanonicalPart),
247
+ parts: toCanonicalParts(message.content),
279
248
  finish_reason: normalizeFinishReason(message.stopReason)
280
249
  };
281
250
  }
282
251
  function toCanonicalInputMessage(message) {
283
252
  if (message.role === "user") {
284
- const parts = typeof message.content === "string" ? [{ type: "text", content: message.content }] : message.content.map(toCanonicalPart);
253
+ const parts = typeof message.content === "string" ? [{ type: "text", content: message.content }] : toCanonicalParts(message.content);
285
254
  return { role: "user", parts };
286
255
  }
287
256
  if (message.role === "toolResult") {
288
257
  return {
289
258
  role: "tool",
290
- id: message.toolCallId,
291
- name: message.toolName,
292
- parts: message.content.map(toCanonicalPart)
259
+ parts: [
260
+ {
261
+ type: "tool_call_response",
262
+ id: message.toolCallId,
263
+ response: toCanonicalParts(message.content)
264
+ }
265
+ ]
293
266
  };
294
267
  }
295
268
  return toCanonicalOutputMessage(message);
@@ -330,8 +303,6 @@ export {
330
303
  canExposeConversationPayload,
331
304
  getCurrentConversationPrivacy,
332
305
  runWithConversationPrivacy,
333
- toGenAiMessageMetadata,
334
- toGenAiTextMetadata,
335
306
  toGenAiPayloadMetadata,
336
307
  toGenAiPayloadTraceAttributes,
337
308
  toCanonicalOutputMessage,
@@ -3,18 +3,16 @@ import {
3
3
  resolveConversationPrivacy,
4
4
  toCanonicalInputMessage,
5
5
  toCanonicalOutputMessage,
6
- toGenAiMessageMetadata,
7
- toGenAiMessagesTraceAttributes,
8
- toGenAiTextMetadata
9
- } from "./chunk-LVA4I4H7.js";
6
+ toGenAiMessagesTraceAttributes
7
+ } from "./chunk-RT5BUHR5.js";
10
8
  import {
11
9
  extractGenAiUsageAttributes,
12
10
  logException,
13
11
  logWarn,
12
+ normalizeGenAiFinishReason,
14
13
  serializeGenAiAttribute,
15
- setSpanAttributes,
16
14
  withSpan
17
- } from "./chunk-I35CTGPO.js";
15
+ } from "./chunk-AEWZ7F65.js";
18
16
 
19
17
  // src/chat/xml.ts
20
18
  function escapeXml(value) {
@@ -261,6 +259,29 @@ function nextProviderRetry(args) {
261
259
  return { delayMs, messages };
262
260
  }
263
261
 
262
+ // src/chat/services/context-compaction-marker.ts
263
+ var COMPACTION_SUMMARY_PREFIX = "Context compaction summary for future Junior turns:";
264
+ var LEGACY_COMPACTION_SUMMARY_PREFIX = "Context handoff summary for future Junior turns:";
265
+ var MODEL_HANDOFF_SUMMARY_PREFIX = "Model handoff checkpoint. Continue the outstanding request now using this summary as the complete prior context:";
266
+ function isCompactionSummaryText(text) {
267
+ const normalized = (unwrapCurrentInstruction(text) ?? text).trimStart();
268
+ return normalized.startsWith(COMPACTION_SUMMARY_PREFIX) || normalized.startsWith(LEGACY_COMPACTION_SUMMARY_PREFIX) || normalized.startsWith(MODEL_HANDOFF_SUMMARY_PREFIX);
269
+ }
270
+ function hasCompactedConversationContext(messages) {
271
+ return messages.some((message) => {
272
+ const content = message.content;
273
+ if (typeof content === "string") {
274
+ return isCompactionSummaryText(content);
275
+ }
276
+ if (!Array.isArray(content)) {
277
+ return false;
278
+ }
279
+ return content.some(
280
+ (part) => part && typeof part === "object" && part.type === "text" && typeof part.text === "string" && isCompactionSummaryText(part.text)
281
+ );
282
+ });
283
+ }
284
+
264
285
  // src/chat/pi/client.ts
265
286
  registerApiProvider({
266
287
  api: "anthropic-messages",
@@ -302,12 +323,8 @@ async function completeText(params) {
302
323
  }) ?? getCurrentConversationPrivacy();
303
324
  const effectivePrivacy = privacy ?? "private";
304
325
  const messageAttributeMode = params.messageAttributeMode ?? (effectivePrivacy === "public" ? "content" : "metadata");
305
- const requestMessagesAttribute = serializeGenAiAttribute(
306
- messageAttributeMode === "metadata" ? params.messages.map(toGenAiMessageMetadata) : params.messages.map(toCanonicalInputMessage)
307
- );
308
- const systemInstructionsAttribute = params.system ? serializeGenAiAttribute(
309
- messageAttributeMode === "metadata" ? [toGenAiTextMetadata(params.system)] : [{ type: "text", content: params.system }]
310
- ) : void 0;
326
+ const requestMessagesAttribute = messageAttributeMode === "content" ? serializeGenAiAttribute(params.messages.map(toCanonicalInputMessage)) : void 0;
327
+ const systemInstructionsAttribute = params.system && messageAttributeMode === "content" ? serializeGenAiAttribute([{ type: "text", content: params.system }]) : void 0;
311
328
  const baseAttributes = {
312
329
  "gen_ai.provider.name": GEN_AI_PROVIDER_NAME,
313
330
  "gen_ai.operation.name": GEN_AI_OPERATION_CHAT,
@@ -315,22 +332,25 @@ async function completeText(params) {
315
332
  "gen_ai.output.type": "text",
316
333
  "server.address": GEN_AI_SERVER_ADDRESS,
317
334
  "server.port": GEN_AI_SERVER_PORT,
335
+ ...hasCompactedConversationContext(params.messages) ? { "gen_ai.conversation.compacted": true } : {},
318
336
  "app.conversation.privacy": effectivePrivacy,
319
- ...params.thinkingLevel ? { "gen_ai.request.reasoning.level": params.thinkingLevel } : {}
337
+ ...params.thinkingLevel ? { "gen_ai.request.reasoning.level": params.thinkingLevel } : {},
338
+ ...params.temperature !== void 0 ? { "gen_ai.request.temperature": params.temperature } : {},
339
+ ...params.maxTokens !== void 0 ? { "gen_ai.request.max_tokens": params.maxTokens } : {}
320
340
  };
321
341
  const startAttributes = {
322
342
  ...baseAttributes,
323
- ...toGenAiMessagesTraceAttributes("app.ai.input", params.messages),
324
- ...params.system ? { "app.ai.system_instructions.content_chars": params.system.length } : {},
343
+ ...toGenAiMessagesTraceAttributes("gen_ai.input", params.messages),
344
+ ...params.system ? { "gen_ai.system_instructions.content_chars": params.system.length } : {},
325
345
  ...systemInstructionsAttribute ? { "gen_ai.system_instructions": systemInstructionsAttribute } : {},
326
346
  ...requestMessagesAttribute ? { "gen_ai.input.messages": requestMessagesAttribute } : {},
327
- "app.ai.auth_mode": authMode
347
+ "gen_ai.provider.auth_mode": authMode
328
348
  };
329
349
  return withSpan(
330
350
  `${GEN_AI_OPERATION_CHAT} ${params.modelId}`,
331
351
  "gen_ai.chat",
332
352
  logContextFromMetadata(params.modelId, params.metadata),
333
- async () => {
353
+ async (setSpanAttributes) => {
334
354
  let message;
335
355
  try {
336
356
  message = await completeSimple(
@@ -353,17 +373,12 @@ async function completeText(params) {
353
373
  }
354
374
  const outputText = extractText(message);
355
375
  const outputMessagesAttribute = serializeGenAiAttribute(
356
- messageAttributeMode === "metadata" ? [
357
- {
358
- role: "assistant",
359
- content: outputText ? [toGenAiTextMetadata(outputText)] : []
360
- }
361
- ] : [toCanonicalOutputMessage(message)]
376
+ messageAttributeMode === "content" ? [toCanonicalOutputMessage(message)] : void 0
362
377
  );
363
378
  const usageAttributes = extractGenAiUsageAttributes(message);
364
379
  const endAttributes = {
365
380
  ...baseAttributes,
366
- ...toGenAiMessagesTraceAttributes("app.ai.output", [
381
+ ...toGenAiMessagesTraceAttributes("gen_ai.output", [
367
382
  {
368
383
  role: "assistant",
369
384
  content: outputText ? [{ type: "text", text: outputText }] : []
@@ -371,7 +386,12 @@ async function completeText(params) {
371
386
  ]),
372
387
  ...outputMessagesAttribute ? { "gen_ai.output.messages": outputMessagesAttribute } : {},
373
388
  ...usageAttributes,
374
- ...message.stopReason ? { "gen_ai.response.finish_reasons": [message.stopReason] } : {}
389
+ ...message.stopReason ? {
390
+ "gen_ai.response.finish_reasons": [
391
+ normalizeGenAiFinishReason(message.stopReason)
392
+ ]
393
+ } : {},
394
+ ...message.model ? { "gen_ai.response.model": message.model } : {}
375
395
  };
376
396
  setSpanAttributes(endAttributes);
377
397
  if (message.stopReason === "error") {
@@ -416,15 +436,22 @@ async function completeObject(params) {
416
436
  `${GEN_AI_OPERATION_CHAT} ${params.modelId}`,
417
437
  "gen_ai.chat",
418
438
  logContextFromMetadata(params.modelId, params.metadata),
419
- async () => await generateObject({
420
- model: provider.chat(params.modelId),
421
- schema: params.schema,
422
- prompt: params.prompt,
423
- ...params.system !== void 0 ? { system: params.system } : {},
424
- ...params.temperature !== void 0 ? { temperature: params.temperature } : {},
425
- ...params.maxTokens !== void 0 ? { maxOutputTokens: params.maxTokens } : {},
426
- ...params.signal !== void 0 ? { abortSignal: params.signal } : {}
427
- }),
439
+ async (setSpanAttributes) => {
440
+ const result2 = await generateObject({
441
+ model: provider.chat(params.modelId),
442
+ schema: params.schema,
443
+ prompt: params.prompt,
444
+ ...params.system !== void 0 ? { system: params.system } : {},
445
+ ...params.temperature !== void 0 ? { temperature: params.temperature } : {},
446
+ ...params.maxTokens !== void 0 ? { maxOutputTokens: params.maxTokens } : {},
447
+ ...params.signal !== void 0 ? { abortSignal: params.signal } : {}
448
+ });
449
+ setSpanAttributes({
450
+ "gen_ai.response.finish_reasons": [result2.finishReason],
451
+ ...extractGenAiUsageAttributes(result2.usage)
452
+ });
453
+ return result2;
454
+ },
428
455
  {
429
456
  "gen_ai.provider.name": GEN_AI_PROVIDER_NAME,
430
457
  "gen_ai.operation.name": GEN_AI_OPERATION_CHAT,
@@ -432,19 +459,11 @@ async function completeObject(params) {
432
459
  "gen_ai.output.type": "json",
433
460
  "server.address": GEN_AI_SERVER_ADDRESS,
434
461
  "server.port": GEN_AI_SERVER_PORT,
435
- ...params.thinkingLevel ? { "gen_ai.request.reasoning.level": params.thinkingLevel } : {}
462
+ ...params.thinkingLevel ? { "gen_ai.request.reasoning.level": params.thinkingLevel } : {},
463
+ ...params.temperature !== void 0 ? { "gen_ai.request.temperature": params.temperature } : {},
464
+ ...params.maxTokens !== void 0 ? { "gen_ai.request.max_tokens": params.maxTokens } : {}
436
465
  }
437
466
  );
438
- setSpanAttributes({
439
- "gen_ai.provider.name": GEN_AI_PROVIDER_NAME,
440
- "gen_ai.operation.name": GEN_AI_OPERATION_CHAT,
441
- "gen_ai.request.model": params.modelId,
442
- "gen_ai.output.type": "json",
443
- "server.address": GEN_AI_SERVER_ADDRESS,
444
- "server.port": GEN_AI_SERVER_PORT,
445
- "gen_ai.response.finish_reasons": [result.finishReason],
446
- ...extractGenAiUsageAttributes(result.usage)
447
- });
448
467
  return { object: result.object };
449
468
  } catch (error) {
450
469
  const providerError = createProviderError(error);
@@ -477,38 +496,37 @@ async function embedTexts(params) {
477
496
  `${GEN_AI_OPERATION_EMBEDDINGS} ${params.modelId}`,
478
497
  "gen_ai.embeddings",
479
498
  logContextFromMetadata(params.modelId, params.metadata),
480
- async () => await embedMany({
481
- model: provider.embeddingModel(params.modelId),
482
- values: texts,
483
- ...params.signal !== void 0 ? { abortSignal: params.signal } : {}
484
- }),
499
+ async (setSpanAttributes) => {
500
+ const result2 = await embedMany({
501
+ model: provider.embeddingModel(params.modelId),
502
+ values: texts,
503
+ ...params.signal !== void 0 ? { abortSignal: params.signal } : {}
504
+ });
505
+ const dimensions = result2.embeddings[0]?.length;
506
+ if (result2.embeddings.length !== texts.length || !dimensions || !result2.embeddings.every(
507
+ (embedding) => embedding.length === dimensions
508
+ )) {
509
+ throw new Error("Embedding provider returned invalid vectors.");
510
+ }
511
+ setSpanAttributes({
512
+ "gen_ai.embeddings.dimension.count": dimensions,
513
+ ...extractGenAiUsageAttributes(result2.usage)
514
+ });
515
+ return { dimensions, result: result2 };
516
+ },
485
517
  {
486
518
  "gen_ai.provider.name": GEN_AI_PROVIDER_NAME,
487
519
  "gen_ai.operation.name": GEN_AI_OPERATION_EMBEDDINGS,
488
520
  "gen_ai.request.model": params.modelId,
489
- "gen_ai.output.type": "embedding",
490
521
  "server.address": GEN_AI_SERVER_ADDRESS,
491
522
  "server.port": GEN_AI_SERVER_PORT
492
523
  }
493
524
  );
494
- const dimensions = result.embeddings[0]?.length;
495
- if (result.embeddings.length !== texts.length || !dimensions || !result.embeddings.every((embedding) => embedding.length === dimensions)) {
496
- throw new Error("Embedding provider returned invalid vectors.");
497
- }
498
- setSpanAttributes({
499
- "gen_ai.provider.name": GEN_AI_PROVIDER_NAME,
500
- "gen_ai.operation.name": GEN_AI_OPERATION_EMBEDDINGS,
501
- "gen_ai.request.model": params.modelId,
502
- "gen_ai.output.type": "embedding",
503
- "server.address": GEN_AI_SERVER_ADDRESS,
504
- "server.port": GEN_AI_SERVER_PORT,
505
- ...extractGenAiUsageAttributes(result.usage)
506
- });
507
525
  return {
508
- dimensions,
526
+ dimensions: result.dimensions,
509
527
  model: params.modelId,
510
528
  provider: GEN_AI_PROVIDER_NAME,
511
- vectors: result.embeddings
529
+ vectors: result.result.embeddings
512
530
  };
513
531
  } catch (error) {
514
532
  const providerError = createProviderError(error);
@@ -1114,6 +1132,10 @@ export {
1114
1132
  stripRuntimeTurnContext,
1115
1133
  isProviderRetryError,
1116
1134
  nextProviderRetry,
1135
+ COMPACTION_SUMMARY_PREFIX,
1136
+ MODEL_HANDOFF_SUMMARY_PREFIX,
1137
+ isCompactionSummaryText,
1138
+ hasCompactedConversationContext,
1117
1139
  GEN_AI_PROVIDER_NAME,
1118
1140
  GEN_AI_SERVER_ADDRESS,
1119
1141
  GEN_AI_SERVER_PORT,
@@ -1,6 +1,6 @@
1
1
  // src/chat/tool-support/private-trace-result.ts
2
2
  import { randomUUID } from "crypto";
3
- var PRIVATE_TRACE_RESULT_ATTRIBUTE = "app.ai.tool.call.result.exposure";
3
+ var PRIVATE_TRACE_RESULT_ATTRIBUTE = "gen_ai.tool.call.result.exposure";
4
4
  var privateTraceResultToken = randomUUID();
5
5
  function privateTraceResultAttributes() {
6
6
  return { [PRIVATE_TRACE_RESULT_ATTRIBUTE]: privateTraceResultToken };
@@ -10,19 +10,20 @@ import {
10
10
  juniorConversations,
11
11
  legacyActorProvenance,
12
12
  piMessageSchema,
13
- readSessionLogEntries
14
- } from "./chunk-VHRM6GNH.js";
13
+ readSessionLogEntries,
14
+ sanitizePostgresJson
15
+ } from "./chunk-QZGVPPIJ.js";
15
16
  import {
16
17
  botConfig,
17
18
  escapeXml,
18
19
  getStateAdapter,
19
20
  resolveGatewayModel,
20
21
  unescapeXml
21
- } from "./chunk-A7X2FDUO.js";
22
+ } from "./chunk-SHBPSE7A.js";
22
23
  import {
23
24
  logWarn,
24
25
  setSpanAttributes
25
- } from "./chunk-I35CTGPO.js";
26
+ } from "./chunk-AEWZ7F65.js";
26
27
  import {
27
28
  parseSlackMessageTs
28
29
  } from "./chunk-7FBGKXPE.js";
@@ -464,7 +465,7 @@ async function hydrateConversationMessages(args) {
464
465
  args.conversation.messages = [];
465
466
  return;
466
467
  }
467
- const { ensureLegacyConversationImport: ensureLegacyConversationImport2 } = await import("./legacy-import-VCYLWT2V.js");
468
+ const { ensureLegacyConversationImport: ensureLegacyConversationImport2 } = await import("./legacy-import-R3BMM2GH.js");
468
469
  await ensureLegacyConversationImport2({ conversationId: args.conversationId });
469
470
  await hydrateConversationCompactions({
470
471
  conversation: args.conversation,
@@ -752,7 +753,7 @@ function insertRow(conversationId, step) {
752
753
  contextEpoch: step.contextEpoch,
753
754
  type,
754
755
  role: messageRole(step.entry),
755
- payload,
756
+ payload: sanitizePostgresJson(payload),
756
757
  createdAt: new Date(step.createdAtMs)
757
758
  };
758
759
  }
@@ -1,9 +1,9 @@
1
1
  import {
2
2
  pluginCatalogRuntime
3
- } from "./chunk-LMJPRYHP.js";
3
+ } from "./chunk-77LHNQK4.js";
4
4
  import {
5
5
  logWarn
6
- } from "./chunk-I35CTGPO.js";
6
+ } from "./chunk-AEWZ7F65.js";
7
7
  import {
8
8
  skillRoots
9
9
  } from "./chunk-3V7OFJZC.js";
@@ -3,14 +3,14 @@ import {
3
3
  isConversationScopedChannel,
4
4
  isDmChannel,
5
5
  normalizeSlackConversationId
6
- } from "./chunk-FP5N5OWZ.js";
6
+ } from "./chunk-IQ36I3DF.js";
7
7
  import {
8
8
  createPluginLogger,
9
9
  createPluginState
10
- } from "./chunk-PWC24W5F.js";
10
+ } from "./chunk-ZSHL44IQ.js";
11
11
  import {
12
12
  getDb
13
- } from "./chunk-VHRM6GNH.js";
13
+ } from "./chunk-QZGVPPIJ.js";
14
14
  import {
15
15
  SANDBOX_WORKSPACE_ROOT
16
16
  } from "./chunk-G3E7SCME.js";
@@ -18,13 +18,13 @@ import {
18
18
  botConfig,
19
19
  completeObject,
20
20
  embedTexts
21
- } from "./chunk-A7X2FDUO.js";
21
+ } from "./chunk-SHBPSE7A.js";
22
22
  import {
23
23
  isActorUserId,
24
24
  logInfo,
25
25
  logWarn,
26
26
  parseActorUserId
27
- } from "./chunk-I35CTGPO.js";
27
+ } from "./chunk-AEWZ7F65.js";
28
28
  import {
29
29
  parseSlackChannelReferenceId,
30
30
  parseSlackMessageTs,
@@ -108,14 +108,8 @@ var CREDENTIAL_SUBJECT_SIGNATURE_VERSION = "v1";
108
108
  function getCredentialSubjectSecret() {
109
109
  return process.env.JUNIOR_SECRET?.trim() || void 0;
110
110
  }
111
- function buildPayload(input) {
112
- return [
113
- CREDENTIAL_SUBJECT_HMAC_CONTEXT,
114
- input.allowedWhen,
115
- input.teamId,
116
- input.channelId,
117
- input.userId
118
- ].join("\0");
111
+ function buildPayload(parts) {
112
+ return [CREDENTIAL_SUBJECT_HMAC_CONTEXT, ...parts].join("\0");
119
113
  }
120
114
  function signPayload(secret, payload) {
121
115
  const digest = createHmac("sha256", secret).update(payload).digest("hex");
@@ -161,12 +155,7 @@ function bindSlackDirectCredentialSubject(input) {
161
155
  channelId,
162
156
  signature: signPayload(
163
157
  secret,
164
- buildPayload({
165
- allowedWhen: subject.allowedWhen,
166
- teamId,
167
- channelId,
168
- userId
169
- })
158
+ buildPayload([subject.allowedWhen, teamId, channelId, userId])
170
159
  )
171
160
  }
172
161
  };
@@ -184,12 +173,57 @@ function verifySlackDirectCredentialSubject(input) {
184
173
  }
185
174
  const expected = signPayload(
186
175
  secret,
187
- buildPayload({
188
- allowedWhen: subject.allowedWhen,
189
- teamId: binding.teamId,
190
- channelId: binding.channelId,
191
- userId: subject.userId
192
- })
176
+ buildPayload([
177
+ subject.allowedWhen,
178
+ binding.teamId,
179
+ binding.channelId,
180
+ subject.userId
181
+ ])
182
+ );
183
+ return timingSafeMatch(expected, binding.signature);
184
+ }
185
+ function bindScheduledTaskCredentialSubject(input) {
186
+ const secret = getCredentialSubjectSecret();
187
+ const plugin = input.plugin.trim();
188
+ const userId = parseActorUserId(input.subject.userId);
189
+ if (!secret || plugin !== "scheduler" || !userId || input.subject.allowedWhen !== "scheduled-task") {
190
+ return void 0;
191
+ }
192
+ const taskId = input.subject.taskId;
193
+ if (!taskId || taskId !== taskId.trim()) {
194
+ return void 0;
195
+ }
196
+ return {
197
+ type: "user",
198
+ userId,
199
+ allowedWhen: "scheduled-task",
200
+ taskId,
201
+ binding: {
202
+ type: "scheduled-task",
203
+ plugin,
204
+ taskId,
205
+ signature: signPayload(
206
+ secret,
207
+ buildPayload(["scheduled-task", plugin, taskId, userId])
208
+ )
209
+ }
210
+ };
211
+ }
212
+ function verifyScheduledTaskCredentialSubject(input) {
213
+ const secret = getCredentialSubjectSecret();
214
+ const { subject } = input;
215
+ const binding = subject.binding;
216
+ if (!secret || input.plugin !== "scheduler" || subject.type !== "user" || !isActorUserId(subject.userId) || subject.allowedWhen !== "scheduled-task" || !subject.taskId || binding.type !== "scheduled-task" || binding.plugin !== input.plugin || binding.taskId !== subject.taskId) {
217
+ return false;
218
+ }
219
+ const expected = signPayload(
220
+ secret,
221
+ buildPayload([
222
+ "scheduled-task",
223
+ binding.plugin,
224
+ binding.taskId,
225
+ subject.userId
226
+ ])
193
227
  );
194
228
  return timingSafeMatch(expected, binding.signature);
195
229
  }
@@ -1008,6 +1042,8 @@ export {
1008
1042
  getSlackToolContext,
1009
1043
  bindSlackDirectCredentialSubject,
1010
1044
  verifySlackDirectCredentialSubject,
1045
+ bindScheduledTaskCredentialSubject,
1046
+ verifyScheduledTaskCredentialSubject,
1011
1047
  resolveChannelCapabilities,
1012
1048
  PluginHookDeniedError,
1013
1049
  validatePlugins,