@sentry/junior 0.264.0 → 0.266.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 (69) hide show
  1. package/README.md +1 -1
  2. package/dist/{adapter-BIbMSKlG.js → adapter-eRFA_naf.js} +1 -1
  3. package/dist/{admin-D4d0HXax.js → admin-tILpP51p.js} +1 -1
  4. package/dist/{agent-runner-CvRxb09K.js → agent-runner-BtYK7bht.js} +263 -198
  5. package/dist/api/schema.d.ts +216 -15
  6. package/dist/api/schema.js +5 -5
  7. package/dist/api.js +109 -42
  8. package/dist/{app-Buc5gIWz.d.ts → app-Csbi9dW7.d.ts} +0 -4
  9. package/dist/app.d.ts +1 -1
  10. package/dist/app.js +79 -390
  11. package/dist/{assistant-reply-BcJj_ORj.js → assistant-reply-UyzAfZQo.js} +1 -1
  12. package/dist/{automation-CWX0qL8U.js → automation-BKpY9LPa.js} +31 -10
  13. package/dist/{briefs-BFfIE5N6.js → briefs-DgfWMU7e.js} +5 -5
  14. package/dist/{catalog-runtime-R53MWcMi.js → catalog-runtime-DAJjAbSx.js} +1 -1
  15. package/dist/cli/chat.js +15 -15
  16. package/dist/cli/check.js +3 -3
  17. package/dist/cli/init.js +4 -18
  18. package/dist/cli/main.js +4 -4
  19. package/dist/cli/plugins.js +4 -4
  20. package/dist/cli/snapshot-create.js +4 -4
  21. package/dist/cli/upgrade.js +3 -3
  22. package/dist/{client-DpOwh_zX.js → client-B0YZfxNy.js} +3 -8
  23. package/dist/{config-BxPrFVJP.js → config-C0UwYqDK.js} +100 -3
  24. package/dist/{connections-BnTM1nRf.js → connections-Bwu3VORi.js} +11 -10
  25. package/dist/{conversation-B0baEwoA.js → conversation-DF4rUcjb.js} +6 -2
  26. package/dist/{conversation-privacy-ueJ6i-t9.js → conversation-privacy-CY7JVjxn.js} +1 -1
  27. package/dist/{credential-sync-DeDkof_D.js → credential-sync-VGAMUTGp.js} +20 -20
  28. package/dist/{agent-hooks-D_PbluRX.js → credentialed-enF5Bf3y.js} +3316 -179
  29. package/dist/{executor-D3WIS4vl.js → executor-TnWbvL09.js} +10 -300
  30. package/dist/{history-AY8rs-FR.js → history-C84mlAwO.js} +2 -1
  31. package/dist/{images-5VNK_yYC.js → images-BKQqSi5W.js} +3 -3
  32. package/dist/instrumentation.js +41 -25
  33. package/dist/{job-queue-BYHonCAH.js → job-queue-DBpHmKnd.js} +53 -14
  34. package/dist/{logging-DNQqsQ57.js → logging-Ce0mXZ8J.js} +19 -32
  35. package/dist/{message-CDTJISxL.js → message-VZ3DFpGb.js} +4 -4
  36. package/dist/nitro.d.ts +17 -2
  37. package/dist/nitro.js +26 -27
  38. package/dist/{oauth-callback-server-Bk4rbLOs.js → oauth-callback-server-CpqWLjVY.js} +2 -2
  39. package/dist/{prompt-CxatQVaj.js → prompt-BcCGlmg2.js} +2 -2
  40. package/dist/{registry-CfdUEk4N.js → registry-1BEIPdbT.js} +1 -1
  41. package/dist/{resolve-BXShI336.js → resolve-BSHHkEGE.js} +7 -106
  42. package/dist/{result-R35jcahx.js → result-CwOpzqdh.js} +8 -8
  43. package/dist/{runner-IC4Drh3Y.js → runner-CEaX04kz.js} +11 -11
  44. package/dist/{sandbox-egress-signals-C4RIfjb8.js → sandbox-egress-signals-BwtGHwqa.js} +1 -1
  45. package/dist/{schema-QidbykYl.js → schema-RsaBHxRH.js} +45 -4
  46. package/dist/{sentry-BBUlHih9.js → sentry-MDkYAVPV.js} +3 -6
  47. package/dist/{service-account-DJSRo2cL.js → service-account-6wC76eBZ.js} +5 -5
  48. package/dist/{service-account-DifohWyX.js → service-account-Dg4lIbHm.js} +3 -3
  49. package/dist/{session-stop-B9RRGC-P.js → session-stop-tZOw9AJD.js} +120 -80
  50. package/dist/{skills-DVJmS_ZP.js → skills-DzyGN7wd.js} +2 -2
  51. package/dist/{spawn-DkVYGfSY.js → spawn-6rokq7l_.js} +2 -2
  52. package/dist/{store-BvolNnx4.js → store-DcKkzrdt.js} +3 -3
  53. package/dist/{store-C_mHwAnR.js → store-FALy-JQb.js} +6 -6
  54. package/dist/{task-queue-BcEyPhtX.js → task-queue-Bg4RS2Gy.js} +14 -19
  55. package/dist/{task-runner-CiQj5M_9.js → task-runner-8N5LIkSg.js} +47 -29
  56. package/dist/{tasks-OgXmReUv.js → tasks-DDT-J3Rf.js} +17 -2078
  57. package/dist/{thread-state-XFvpWXE9.js → thread-state-cprEaxgl.js} +5 -5
  58. package/dist/{turn-failure-response-BjBAtnVt.js → turn-failure-response-C8sMdsdX.js} +8 -8
  59. package/dist/{turn-lifecycle-nvKL2rul.js → turn-lifecycle-DaBVoz7h.js} +2 -2
  60. package/dist/{turn-session-routing-DEMxHySb.js → turn-session-routing-a9CHX-w6.js} +1 -1
  61. package/dist/{validation-XOFldwvE.js → validation-C2lllinq.js} +1 -1
  62. package/dist/{version-C9f5hdHD.js → version-oaLfxxnf.js} +1 -1
  63. package/dist/version.js +1 -1
  64. package/dist/{viewer-BuPwzOC9.js → viewer-BpE6Z3qf.js} +22 -6
  65. package/dist/{web-input-4t7TYLsY.js → web-input-B-bMjD1V.js} +147 -48
  66. package/dist/{work-C_aF6JN5.js → work-VX1SHWha.js} +52 -51
  67. package/dist/{worker-DR633sA-.js → worker-hook-y_Y.js} +5 -5
  68. package/package.json +10 -9
  69. package/dist/profile-ieODOp4u.js +0 -582
@@ -1,6 +1,5 @@
1
- import { f as logException } from "./logging-DNQqsQ57.js";
2
- import { g as startSpanManual } from "./sentry-BBUlHih9.js";
3
- import "./config-BxPrFVJP.js";
1
+ import "./config-C0UwYqDK.js";
2
+ import { f as logException } from "./logging-Ce0mXZ8J.js";
4
3
  import { a as juniorAgentInvocations, c as juniorIdentities, d as juniorDestinations, f as timestamptz, i as juniorAgentBindings, l as juniorUsers, s as juniorConversations } from "./agent-invocations-CxKldAeB.js";
5
4
  import { AsyncLocalStorage } from "node:async_hooks";
6
5
  import { sql } from "drizzle-orm";
@@ -8,7 +7,6 @@ import { bigint, boolean, check, date, doublePrecision, foreignKey, index, integ
8
7
  import { Pool } from "@neondatabase/serverless";
9
8
  import { drizzle } from "drizzle-orm/neon-serverless";
10
9
  import { migrate } from "drizzle-orm/neon-serverless/migrator";
11
- import { SpanKind } from "@opentelemetry/api";
12
10
  import pg from "pg";
13
11
  import { drizzle as drizzle$1 } from "drizzle-orm/node-postgres";
14
12
  import { migrate as migrate$1 } from "drizzle-orm/node-postgres/migrator";
@@ -463,288 +461,14 @@ const juniorSqlSchema = {
463
461
  juniorWorkspaceRepos,
464
462
  juniorWorkspaces
465
463
  };
466
- // src/db/tracing.ts
467
- const traced = Symbol("junior.db.traced");
468
- const MAX_QUERY_TEXT_LENGTH = 1e4;
469
- const MAX_QUERY_SUMMARY_LENGTH = 255;
470
- const SQL_OPERATIONS = /* @__PURE__ */ new Set([
471
- "ALTER",
472
- "ANALYZE",
473
- "BEGIN",
474
- "CALL",
475
- "COMMIT",
476
- "COPY",
477
- "CREATE",
478
- "DELETE",
479
- "DROP",
480
- "EXPLAIN",
481
- "GRANT",
482
- "INSERT",
483
- "MERGE",
484
- "RELEASE",
485
- "REVOKE",
486
- "ROLLBACK",
487
- "SAVEPOINT",
488
- "SELECT",
489
- "SET",
490
- "SHOW",
491
- "TRUNCATE",
492
- "UPDATE",
493
- "VACUUM"
494
- ]);
495
- const SQL_IDENTIFIER = String.raw`(?:(?:U&)?"(?:""|[^"])*"|[A-Za-z_][A-Za-z0-9_$]*)(?:\.(?:(?:U&)?"(?:""|[^"])*"|[A-Za-z_][A-Za-z0-9_$]*))*`;
496
- function targetPattern(prefix) {
497
- return new RegExp(`${prefix}(${SQL_IDENTIFIER})`, "i");
498
- }
499
- const SQL_TARGET = {
500
- ALTER: targetPattern(String.raw`\bALTER\s+TABLE\s+`),
501
- CALL: targetPattern(String.raw`\bCALL\s+`),
502
- CREATE: targetPattern(String.raw`\bCREATE\s+(?:OR\s+REPLACE\s+)?(?:TABLE|VIEW)\s+(?:IF\s+NOT\s+EXISTS\s+)?`),
503
- DELETE: targetPattern(String.raw`\bDELETE\s+FROM\s+`),
504
- DROP: targetPattern(String.raw`\bDROP\s+(?:TABLE|VIEW)\s+(?:IF\s+EXISTS\s+)?`),
505
- INSERT: targetPattern(String.raw`\bINSERT\s+INTO\s+`),
506
- MERGE: targetPattern(String.raw`\bMERGE\s+INTO\s+`),
507
- SELECT: targetPattern(String.raw`\bFROM\s+`),
508
- TRUNCATE: targetPattern(String.raw`\bTRUNCATE\s+(?:TABLE\s+)?`),
509
- UPDATE: targetPattern(String.raw`\bUPDATE\s+`)
510
- };
511
- function queryText(query) {
512
- if (typeof query === "string") return query;
513
- if (!query || typeof query !== "object" || !("text" in query)) return;
514
- return typeof query.text === "string" ? query.text : void 0;
515
- }
516
- function safeSqlText(text) {
517
- let safe = "";
518
- for (let index = 0; index < text.length;) {
519
- if (text.startsWith("--", index)) {
520
- const end = text.indexOf("\n", index + 2);
521
- safe += " ";
522
- index = end === -1 ? text.length : end;
523
- continue;
524
- }
525
- if (text.startsWith("/*", index)) {
526
- let depth = 1;
527
- index += 2;
528
- while (index < text.length && depth > 0) if (text.startsWith("/*", index)) {
529
- depth += 1;
530
- index += 2;
531
- } else if (text.startsWith("*/", index)) {
532
- depth -= 1;
533
- index += 2;
534
- } else index += 1;
535
- safe += " ";
536
- continue;
537
- }
538
- const dollarTag = /^\$(?:[A-Za-z_][A-Za-z0-9_]*)?\$/.exec(text.slice(index))?.[0];
539
- if (dollarTag) {
540
- const end = text.indexOf(dollarTag, index + dollarTag.length);
541
- index = end === -1 ? text.length : end + dollarTag.length;
542
- safe += "?";
543
- continue;
544
- }
545
- const identifierPrefix = /^(?:U&)?"/i.exec(text.slice(index))?.[0];
546
- if (identifierPrefix) {
547
- let end = index + identifierPrefix.length;
548
- while (end < text.length) {
549
- if (text[end] !== "\"") {
550
- end += 1;
551
- continue;
552
- }
553
- if (text[end + 1] === "\"") {
554
- end += 2;
555
- continue;
556
- }
557
- end += 1;
558
- break;
559
- }
560
- safe += text.slice(index, end);
561
- index = end;
562
- continue;
563
- }
564
- const stringPrefix = /^(?:E|U&|B|X)?'/i.exec(text.slice(index))?.[0];
565
- if (stringPrefix) {
566
- const supportsBackslashEscapes = /^E'/i.test(stringPrefix);
567
- let end = index + stringPrefix.length;
568
- while (end < text.length) {
569
- if (supportsBackslashEscapes && text[end] === "\\") {
570
- end += 2;
571
- continue;
572
- }
573
- if (text[end] !== "'") {
574
- end += 1;
575
- continue;
576
- }
577
- if (text[end + 1] === "'") {
578
- end += 2;
579
- continue;
580
- }
581
- end += 1;
582
- break;
583
- }
584
- safe += "?";
585
- index = end;
586
- continue;
587
- }
588
- const token = /^(?:TRUE|FALSE|NULL|0x[\da-f_]+|0b[01_]+|0o[0-7_]+|\d[\d_]*(?:\.[\d_]*)?(?:e[+-]?[\d_]+)?)(?![A-Za-z0-9_$])/i.exec(text.slice(index))?.[0];
589
- const previous = text[index - 1];
590
- if (token && (!previous || !/[A-Za-z0-9_$]/.test(previous))) {
591
- safe += "?";
592
- index += token.length;
593
- continue;
594
- }
595
- safe += text[index];
596
- index += 1;
597
- }
598
- return safe;
599
- }
600
- function normalizeQueryText(text) {
601
- return safeSqlText(text.slice(0, MAX_QUERY_TEXT_LENGTH)).replace(/\s+/g, " ").trim().slice(0, MAX_QUERY_TEXT_LENGTH);
602
- }
603
- function operationFromText(text) {
604
- const tokens = /(?:U&)?"(?:""|[^"])*"|[A-Za-z_][A-Za-z0-9_$]*|[()]/gi;
605
- let depth = 0;
606
- for (const match of text.matchAll(tokens)) {
607
- const token = match[0];
608
- if (token === "(") depth += 1;
609
- else if (token === ")") depth = Math.max(0, depth - 1);
610
- else if (depth === 0 && !token.includes("\"")) {
611
- if (SQL_OPERATIONS.has(token.toUpperCase())) return {
612
- index: match.index,
613
- name: token
614
- };
615
- }
616
- }
617
- }
618
- function targetFromOperation(operation, text) {
619
- if (operation.toUpperCase() !== "SELECT") return SQL_TARGET[operation.toUpperCase()]?.exec(text)?.[1];
620
- const tokens = /(?:U&)?"(?:""|[^"])*"|[A-Za-z_][A-Za-z0-9_$]*|[()]/gi;
621
- let depth = 0;
622
- for (const match of text.matchAll(tokens)) {
623
- const token = match[0];
624
- if (token === "(") depth += 1;
625
- else if (token === ")") depth = Math.max(0, depth - 1);
626
- else if (depth === 0 && token.toUpperCase() === "FROM") {
627
- const targetText = text.slice(match.index + token.length).trimStart();
628
- return new RegExp(`^(${SQL_IDENTIFIER})`, "i").exec(targetText)?.[1];
629
- }
630
- }
631
- }
632
- function querySummary(operation, target) {
633
- if (!operation) return void 0;
634
- const summary = target ? `${operation} ${target}` : operation;
635
- return summary.length <= MAX_QUERY_SUMMARY_LENGTH ? summary : operation;
636
- }
637
- function detailsFromQuery(args) {
638
- const rawText = queryText(args[0]);
639
- if (!rawText) return {};
640
- const text = normalizeQueryText(rawText);
641
- const operationMatch = operationFromText(text);
642
- const operation = operationMatch?.name;
643
- const operationText = operationMatch ? text.slice(operationMatch.index) : "";
644
- const target = operation ? targetFromOperation(operation, operationText) : void 0;
645
- const summary = querySummary(operation, target);
646
- const isCall = operation?.toUpperCase() === "CALL";
647
- return {
648
- collection: isCall ? void 0 : target,
649
- operation,
650
- storedProcedure: isCall ? target : void 0,
651
- summary,
652
- text: text || void 0
653
- };
654
- }
655
- function connectionAttributes(connectionString) {
656
- try {
657
- const url = new URL(connectionString);
658
- const namespace = decodeURIComponent(url.pathname.replace(/^\//, ""));
659
- const port = url.port ? Number(url.port) : void 0;
660
- return {
661
- ...namespace ? { "db.namespace": namespace } : void 0,
662
- ...url.hostname ? { "server.address": url.hostname } : void 0,
663
- ...port && port !== 5432 ? { "server.port": port } : void 0
664
- };
665
- } catch {
666
- return {};
667
- }
668
- }
669
- function responseStatusCode(error) {
670
- if (!error || typeof error !== "object" || !("code" in error)) return;
671
- return typeof error.code === "string" || typeof error.code === "number" ? String(error.code) : void 0;
672
- }
673
- function errorType(error) {
674
- return responseStatusCode(error) ?? (error instanceof Error ? error.name : typeof error);
675
- }
676
- function markFailed(span, error) {
677
- const statusCode = responseStatusCode(error);
678
- span.setAttribute("error.type", statusCode ?? errorType(error));
679
- if (statusCode && /^[0-9A-Z]{5}$/i.test(statusCode)) span.setAttribute("db.response.status_code", statusCode);
680
- span.setStatus({ code: 2 });
681
- }
682
- /** Add OpenTelemetry database client spans to an owned PostgreSQL query client. */
683
- function traceQueries(client, options) {
684
- if (client[traced]) return client;
685
- client[traced] = true;
686
- const query = client.query.bind(client);
687
- const connection = connectionAttributes(options.connectionString);
688
- client.query = ((...originalArgs) => {
689
- const details = detailsFromQuery(originalArgs);
690
- const args = [...originalArgs];
691
- const callbackIndex = typeof args.at(-1) === "function" ? args.length - 1 : void 0;
692
- return startSpanManual({
693
- name: details.summary ?? details.operation ?? "postgresql",
694
- op: "db.query",
695
- kind: SpanKind.CLIENT,
696
- onlyIfParent: true,
697
- attributes: {
698
- "db.system.name": "postgresql",
699
- ...connection,
700
- ...details.operation ? { "db.operation.name": details.operation } : void 0,
701
- ...details.summary ? { "db.query.summary": details.summary } : void 0,
702
- ...details.text ? { "db.query.text": details.text } : void 0,
703
- ...details.storedProcedure ? { "db.stored_procedure.name": details.storedProcedure } : void 0,
704
- ...details.collection ? { "db.collection.name": details.collection } : void 0,
705
- "app.db.driver": options.driver
706
- }
707
- }, (span, finish) => {
708
- if (callbackIndex !== void 0) {
709
- const callback = args[callbackIndex];
710
- args[callbackIndex] = ((error, ...callbackArgs) => {
711
- if (error) markFailed(span, error);
712
- finish();
713
- return callback(error, ...callbackArgs);
714
- });
715
- }
716
- try {
717
- const result = query(...args);
718
- if (callbackIndex !== void 0) return result;
719
- if (result && typeof result === "object" && "then" in result) return Promise.resolve(result).then((value) => {
720
- finish();
721
- return value;
722
- }, (error) => {
723
- markFailed(span, error);
724
- finish();
725
- throw error;
726
- });
727
- finish();
728
- return result;
729
- } catch (error) {
730
- markFailed(span, error);
731
- finish();
732
- throw error;
733
- }
734
- });
735
- });
736
- return client;
737
- }
738
464
  // src/db/neon.ts
739
465
  var NeonExecutor = class {
740
466
  transactionClient = new AsyncLocalStorage();
741
467
  savepointId = 0;
742
468
  isolatedQueryId = 0;
743
469
  pool;
744
- connectionString;
745
- constructor(pool, connectionString) {
470
+ constructor(pool) {
746
471
  this.pool = pool;
747
- this.connectionString = connectionString;
748
472
  }
749
473
  db() {
750
474
  return drizzle(this.queryClient(), { schema: juniorSqlSchema });
@@ -756,10 +480,7 @@ var NeonExecutor = class {
756
480
  return (await this.queryClient().query(statement, [...params])).rows;
757
481
  }
758
482
  async queryIsolated(statement, params = []) {
759
- const client = traceQueries(await this.pool.connect(), {
760
- connectionString: this.connectionString,
761
- driver: "neon"
762
- });
483
+ const client = await this.pool.connect();
763
484
  try {
764
485
  return (await client.query({
765
486
  name: `junior_isolated_${++this.isolatedQueryId}`,
@@ -840,10 +561,7 @@ var NeonExecutor = class {
840
561
  await this.pool.end();
841
562
  }
842
563
  queryClient() {
843
- return traceQueries(this.transactionClient.getStore() ?? this.pool, {
844
- connectionString: this.connectionString,
845
- driver: "neon"
846
- });
564
+ return this.transactionClient.getStore() ?? this.pool;
847
565
  }
848
566
  };
849
567
  /** Create the shared Neon-backed Junior SQL executor. */
@@ -856,7 +574,7 @@ function createNeonJuniorSqlExecutor(args) {
856
574
  pool.on("error", (error) => {
857
575
  logException(error, "db.pool.client.failed", { "app.db.driver": "neon" });
858
576
  });
859
- return new NeonExecutor(pool, args.connectionString);
577
+ return new NeonExecutor(pool);
860
578
  }
861
579
  // src/db/postgres.ts
862
580
  const { Pool: Pool$1 } = pg;
@@ -865,10 +583,8 @@ var PostgresExecutor = class {
865
583
  savepointId = 0;
866
584
  isolatedQueryId = 0;
867
585
  pool;
868
- connectionString;
869
- constructor(pool, connectionString) {
586
+ constructor(pool) {
870
587
  this.pool = pool;
871
- this.connectionString = connectionString;
872
588
  }
873
589
  db() {
874
590
  return drizzle$1(this.queryClient(), { schema: juniorSqlSchema });
@@ -880,10 +596,7 @@ var PostgresExecutor = class {
880
596
  return (await this.queryClient().query(statement, [...params])).rows;
881
597
  }
882
598
  async queryIsolated(statement, params = []) {
883
- const client = traceQueries(await this.pool.connect(), {
884
- connectionString: this.connectionString,
885
- driver: "postgres"
886
- });
599
+ const client = await this.pool.connect();
887
600
  try {
888
601
  return (await client.query({
889
602
  name: `junior_isolated_${++this.isolatedQueryId}`,
@@ -964,10 +677,7 @@ var PostgresExecutor = class {
964
677
  await this.pool.end();
965
678
  }
966
679
  queryClient() {
967
- return traceQueries(this.transactionClient.getStore() ?? this.pool, {
968
- connectionString: this.connectionString,
969
- driver: "postgres"
970
- });
680
+ return this.transactionClient.getStore() ?? this.pool;
971
681
  }
972
682
  };
973
683
  /** Create the shared Node Postgres-backed Junior SQL executor. */
@@ -981,7 +691,7 @@ function createPostgresJuniorSqlExecutor(args) {
981
691
  pool.on("error", (error) => {
982
692
  logException(error, "db.pool.client.failed", { "app.db.driver": "postgres" });
983
693
  });
984
- return new PostgresExecutor(pool, args.connectionString);
694
+ return new PostgresExecutor(pool);
985
695
  }
986
696
  // src/db/executor.ts
987
697
  /** Create the SQL executor appropriate for the configured database URL. */
@@ -366,7 +366,8 @@ const turnCompletedEventDataSchema = z.object({
366
366
  outcome: z.enum([
367
367
  "success",
368
368
  "no_reply",
369
- "cancelled"
369
+ "cancelled",
370
+ "blocked"
370
371
  ])
371
372
  }).strict();
372
373
  const turnFailedEventDataSchema = z.object({
@@ -1,7 +1,7 @@
1
1
  import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
2
- import { f as getSqlExecutor } from "./viewer-BuPwzOC9.js";
3
- import { S as readLiveAttachment, w as storeAttachment } from "./agent-runner-CvRxb09K.js";
4
- import { H as detectImageMediaType } from "./conversation-B0baEwoA.js";
2
+ import { p as getSqlExecutor } from "./viewer-BpE6Z3qf.js";
3
+ import { S as readLiveAttachment, w as storeAttachment } from "./agent-runner-BtYK7bht.js";
4
+ import { H as detectImageMediaType } from "./conversation-DF4rUcjb.js";
5
5
  // src/chat/attachments/images.ts
6
6
  var images_exports = /* @__PURE__ */ __exportAll({
7
7
  decodeInputImages: () => decodeInputImages,
@@ -1,6 +1,6 @@
1
- import { F as getDeploymentTelemetryAttributes, P as getDeploymentServiceVersion } from "./logging-DNQqsQ57.js";
2
- import { _ as vercelAIIntegration, a as getClient, b as withStreamedSpan, c as init, o as getGlobalScope } from "./sentry-BBUlHih9.js";
3
- import { n as getCurrentConversationPrivacy } from "./conversation-privacy-ueJ6i-t9.js";
1
+ import { F as getDeploymentTelemetryAttributes, P as getDeploymentServiceVersion } from "./logging-Ce0mXZ8J.js";
2
+ import { a as getClient, c as init, o as getGlobalScope } from "./sentry-MDkYAVPV.js";
3
+ import { n as getCurrentConversationPrivacy } from "./conversation-privacy-CY7JVjxn.js";
4
4
  import { t as consumePrivateTraceResultMarker } from "./private-trace-result-CE7_lEdq.js";
5
5
  // src/chat/sentry-payload-filter.ts
6
6
  const PAYLOAD_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
@@ -15,9 +15,11 @@ const PAYLOAD_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
15
15
  const URL_ATTRIBUTE_KEYS = /* @__PURE__ */ new Set([
16
16
  "http.target",
17
17
  "http.url",
18
+ "url",
18
19
  "url.full",
19
20
  "url.path"
20
21
  ]);
22
+ const SLACK_FILE_HOST = "files.slack.com";
21
23
  const OAUTH_CALLBACK_PATH = "/api/oauth/callback/";
22
24
  const LOCAL_CREDENTIAL_PATH = "/api/internal/local-oauth-credentials";
23
25
  const SECRET_HEADER_NAMES = /* @__PURE__ */ new Set(["x-junior-local-credential-signature", "x-junior-sandbox-egress-token"]);
@@ -29,14 +31,34 @@ function isSecretHeaderAttribute(key) {
29
31
  const normalized = key.toLowerCase().replace(/[^a-z0-9]/g, "");
30
32
  return normalized.endsWith("xjuniorlocalcredentialsignature") || normalized.endsWith("xjuniorsandboxegresstoken");
31
33
  }
34
+ function isSlackFileRequest(attributes) {
35
+ return attributes["server.address"] === SLACK_FILE_HOST || [...URL_ATTRIBUTE_KEYS].some((key) => {
36
+ const value = attributes[key];
37
+ return typeof value === "string" && value.includes(`//${SLACK_FILE_HOST}/`);
38
+ });
39
+ }
40
+ /** Keep only the host of private Slack file URLs, which name the workspace and file. */
41
+ function scrubSlackFileUrls(attributes) {
42
+ for (const key of URL_ATTRIBUTE_KEYS) {
43
+ const value = attributes[key];
44
+ if (typeof value !== "string") continue;
45
+ if (value.includes("://")) attributes[key] = `https://${SLACK_FILE_HOST}`;
46
+ else delete attributes[key];
47
+ }
48
+ }
32
49
  function scrubSensitiveUrlAttributes(attributes) {
33
50
  if (!attributes) return;
34
51
  delete attributes["url.query"];
52
+ delete attributes["url.fragment"];
35
53
  const hasLocalCredentialUrl = [...URL_ATTRIBUTE_KEYS].some((key) => {
36
54
  const value = attributes[key];
37
55
  return typeof value === "string" && value.includes(LOCAL_CREDENTIAL_PATH);
38
56
  });
39
57
  for (const key of Object.keys(attributes)) if (isSecretHeaderAttribute(key) || hasLocalCredentialUrl && key === "http.request.body.data") delete attributes[key];
58
+ if (isSlackFileRequest(attributes)) {
59
+ scrubSlackFileUrls(attributes);
60
+ return;
61
+ }
40
62
  for (const key of URL_ATTRIBUTE_KEYS) {
41
63
  const value = attributes[key];
42
64
  if (typeof value !== "string" || !value.includes(OAUTH_CALLBACK_PATH)) continue;
@@ -88,14 +110,6 @@ function scrubPrivateSentryEvent(event) {
88
110
  for (const breadcrumb of event.breadcrumbs ?? []) scrubContainer(breadcrumb);
89
111
  return event;
90
112
  }
91
- /** Remove private conversation payloads and boundary secrets from transactions. */
92
- function scrubPrivateSentryTransaction(event) {
93
- scrubContainer(event);
94
- scrubSensitiveRequest(event.request);
95
- scrubContainer(event.contexts?.trace);
96
- for (const span of event.spans ?? []) scrubContainer(span);
97
- return event;
98
- }
99
113
  /** Remove private conversation payloads and boundary secrets from streamed spans. */
100
114
  function scrubPrivateSentrySpan(span) {
101
115
  scrubContainer(span);
@@ -107,6 +121,15 @@ function scrubPrivateSentryLog(log) {
107
121
  return log;
108
122
  }
109
123
  // src/instrumentation.ts
124
+ const MANUAL_GEN_AI_INTEGRATIONS = /* @__PURE__ */ new Set([
125
+ "Anthropic_AI",
126
+ "Google_GenAI",
127
+ "Groq",
128
+ "Mistral",
129
+ "OpenAI",
130
+ "TogetherAI",
131
+ "VercelAI"
132
+ ]);
110
133
  function getSampleRate(value, fallback) {
111
134
  if (!value) return fallback;
112
135
  const parsed = Number(value);
@@ -141,21 +164,14 @@ function initSentry() {
141
164
  environment: process.env.SENTRY_ENVIRONMENT ?? process.env.VERCEL_ENV ?? process.env.NODE_ENV,
142
165
  release: serviceVersion,
143
166
  tracesSampleRate: getSampleRate(process.env.SENTRY_TRACES_SAMPLE_RATE, 1),
144
- traceLifecycle: "stream",
145
- sendDefaultPii: true,
146
- enableLogs,
147
- registerEsmLoaderHooks: false,
148
- streamGenAiSpans: true,
167
+ dataCollection: {
168
+ httpBodies: ["incomingRequest"],
169
+ databaseQueryData: false
170
+ },
149
171
  beforeSend: scrubPrivateSentryEvent,
150
- beforeSendLog: scrubPrivateSentryLog,
151
- beforeSendSpan: withStreamedSpan(scrubPrivateSentrySpan),
152
- beforeSendTransaction: scrubPrivateSentryTransaction,
153
- integrations(defaultIntegrations) {
154
- return [...defaultIntegrations, vercelAIIntegration({
155
- recordInputs: true,
156
- recordOutputs: true
157
- })];
158
- }
172
+ beforeSendLog: enableLogs ? scrubPrivateSentryLog : () => null,
173
+ beforeSendSpan: scrubPrivateSentrySpan,
174
+ integrations: (defaultIntegrations) => defaultIntegrations.filter((integration) => !MANUAL_GEN_AI_INTEGRATIONS.has(integration.name))
159
175
  });
160
176
  getGlobalScope().setAttributes(deploymentSpanAttributes);
161
177
  }
@@ -1,8 +1,9 @@
1
- import { i as getChatConfig } from "./config-BxPrFVJP.js";
1
+ import { i as getChatConfig } from "./config-C0UwYqDK.js";
2
+ import { T as withSpan } from "./logging-Ce0mXZ8J.js";
2
3
  import { AsyncLocalStorage } from "node:async_hooks";
3
4
  import { z } from "zod";
4
5
  import { createHash, createHmac, timingSafeEqual } from "node:crypto";
5
- import { QueueClient } from "@vercel/queue";
6
+ import { QueueClient, handleCallback, registerDevConsumer } from "@vercel/queue";
6
7
  /** Validate the v2 conversation work hint sent through Vercel Queue. */
7
8
  const conversationQueueMessageSchema = z.object({
8
9
  schemaVersion: z.literal(2),
@@ -39,14 +40,43 @@ function runWithTurnRequestDeadline(callback, startedAtMs = Date.now()) {
39
40
  if (requestDeadlineStorage.getStore()) return callback();
40
41
  return requestDeadlineStorage.run(createTurnRequestDeadline(startedAtMs), callback);
41
42
  }
42
- // src/chat/vercel-queue-client.ts
43
+ // src/chat/queue/vercel.ts
43
44
  function defaultQueueClientOptions() {
44
45
  if (process.env.VERCEL_DEPLOYMENT_ID?.trim()) return {};
45
46
  return { deploymentId: null };
46
47
  }
47
- /** Create a Vercel Queue client that also works in local and eval runtimes. */
48
- function createVercelQueueClient() {
49
- return new QueueClient(defaultQueueClientOptions());
48
+ let client;
49
+ function getVercelQueueClient() {
50
+ client ??= new QueueClient(defaultQueueClientOptions());
51
+ return client;
52
+ }
53
+ function visibility(consumer) {
54
+ return consumer.visibilityTimeoutSeconds === void 0 ? {} : { visibilityTimeoutSeconds: consumer.visibilityTimeoutSeconds };
55
+ }
56
+ /** Queue provider backed by Vercel Queues. */
57
+ const vercelQueueProvider = {
58
+ messagingSystem: "vercel_queue",
59
+ send: async (topic, payload, options) => {
60
+ const { messageId } = await getVercelQueueClient().send(topic, payload, options);
61
+ return messageId ? { messageId } : {};
62
+ },
63
+ createCallback: (consumer) => handleCallback(consumer.handler, {
64
+ retry: consumer.retry,
65
+ ...visibility(consumer)
66
+ }),
67
+ registerDevConsumer: (consumer) => registerDevConsumer({
68
+ client: getVercelQueueClient(),
69
+ consumerGroup: consumer.consumerGroup,
70
+ handler: consumer.handler,
71
+ retry: consumer.retry,
72
+ topic: consumer.topic,
73
+ ...visibility(consumer)
74
+ })
75
+ };
76
+ // src/chat/queue/provider.ts
77
+ /** Return the queue provider for this deployment. */
78
+ function getQueueProvider() {
79
+ return vercelQueueProvider;
50
80
  }
51
81
  // src/chat/queue/sign.ts
52
82
  /** Sign and check queue messages before public callbacks run them. */
@@ -164,14 +194,23 @@ function toDelaySeconds(options) {
164
194
  /** Create the Vercel Queue implementation for conversation wake-up nudges. */
165
195
  function createVercelConversationWorkQueue(options = {}) {
166
196
  const topic = resolveConversationWorkQueueTopic(options);
167
- const client = options.client ?? createVercelQueueClient();
197
+ const client = options.client ?? getQueueProvider();
168
198
  return { async send(message, sendOptions) {
169
- const result = await client.send(topic, signConversationQueueMessage(message), {
170
- idempotencyKey: sendOptions?.idempotencyKey,
171
- delaySeconds: toDelaySeconds(sendOptions),
172
- retentionSeconds: options.retentionSeconds ?? CONVERSATION_WORK_QUEUE_RETENTION_SECONDS
199
+ const payload = signConversationQueueMessage(message);
200
+ return await withSpan("conversation.work.publish", "queue.publish", { conversationId: message.conversationId }, async (setSpanAttributes) => {
201
+ const result = await client.send(topic, payload, {
202
+ idempotencyKey: sendOptions?.idempotencyKey,
203
+ delaySeconds: toDelaySeconds(sendOptions),
204
+ retentionSeconds: options.retentionSeconds ?? CONVERSATION_WORK_QUEUE_RETENTION_SECONDS
205
+ });
206
+ if (!result.messageId) return {};
207
+ setSpanAttributes({ "messaging.message.id": result.messageId });
208
+ return { messageId: result.messageId };
209
+ }, {
210
+ "messaging.destination.name": topic,
211
+ "messaging.message.body.size": Buffer.byteLength(JSON.stringify(payload)),
212
+ "messaging.system": getQueueProvider().messagingSystem
173
213
  });
174
- return result.messageId ? { messageId: result.messageId } : {};
175
214
  } };
176
215
  }
177
216
  /** Return the default production conversation work queue. */
@@ -207,7 +246,7 @@ function verifyWorkspaceSnapshotJobMessage(value, nowMs = Date.now()) {
207
246
  async function send(message, idempotencyKey) {
208
247
  const options = { retentionSeconds: QUEUE_SIGNATURE_MAX_AGE_MS / 1e3 };
209
248
  if (idempotencyKey) options.idempotencyKey = idempotencyKey;
210
- await createVercelQueueClient().send(WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC, signWorkspaceSnapshotJobMessage(message), options);
249
+ await getQueueProvider().send(WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC, signWorkspaceSnapshotJobMessage(message), options);
211
250
  }
212
251
  /** Send a job unless the same Workspace build already has one. */
213
252
  async function sendWorkspaceSnapshotJob(message) {
@@ -217,4 +256,4 @@ async function sendWorkspaceSnapshotJob(message) {
217
256
  async function sendNextWorkspaceSnapshotJob(message) {
218
257
  await send(message);
219
258
  }
220
- export { getVercelConversationWorkQueue as a, QUEUE_SIGNATURE_MAX_AGE_MS as c, createVercelQueueClient as d, getTurnRequestDeadline as f, isConversationQueueMessageRejectedError as g, conversationQueueMessageSchema as h, verifyWorkspaceSnapshotJobMessage as i, signQueueMessage as l, ConversationQueueMessageRejectedError as m, sendNextWorkspaceSnapshotJob as n, resolveConversationWorkQueueTopic as o, runWithTurnRequestDeadline as p, sendWorkspaceSnapshotJob as r, verifyConversationQueueMessage as s, WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC as t, verifyQueueMessage as u };
259
+ export { getVercelConversationWorkQueue as a, QUEUE_SIGNATURE_MAX_AGE_MS as c, getQueueProvider as d, getTurnRequestDeadline as f, isConversationQueueMessageRejectedError as g, conversationQueueMessageSchema as h, verifyWorkspaceSnapshotJobMessage as i, signQueueMessage as l, ConversationQueueMessageRejectedError as m, sendNextWorkspaceSnapshotJob as n, resolveConversationWorkQueueTopic as o, runWithTurnRequestDeadline as p, sendWorkspaceSnapshotJob as r, verifyConversationQueueMessage as s, WORKSPACE_SNAPSHOT_JOB_QUEUE_TOPIC as t, verifyQueueMessage as u };