@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.
- package/README.md +1 -1
- package/dist/{adapter-BIbMSKlG.js → adapter-eRFA_naf.js} +1 -1
- package/dist/{admin-D4d0HXax.js → admin-tILpP51p.js} +1 -1
- package/dist/{agent-runner-CvRxb09K.js → agent-runner-BtYK7bht.js} +263 -198
- package/dist/api/schema.d.ts +216 -15
- package/dist/api/schema.js +5 -5
- package/dist/api.js +109 -42
- package/dist/{app-Buc5gIWz.d.ts → app-Csbi9dW7.d.ts} +0 -4
- package/dist/app.d.ts +1 -1
- package/dist/app.js +79 -390
- package/dist/{assistant-reply-BcJj_ORj.js → assistant-reply-UyzAfZQo.js} +1 -1
- package/dist/{automation-CWX0qL8U.js → automation-BKpY9LPa.js} +31 -10
- package/dist/{briefs-BFfIE5N6.js → briefs-DgfWMU7e.js} +5 -5
- package/dist/{catalog-runtime-R53MWcMi.js → catalog-runtime-DAJjAbSx.js} +1 -1
- package/dist/cli/chat.js +15 -15
- package/dist/cli/check.js +3 -3
- package/dist/cli/init.js +4 -18
- package/dist/cli/main.js +4 -4
- package/dist/cli/plugins.js +4 -4
- package/dist/cli/snapshot-create.js +4 -4
- package/dist/cli/upgrade.js +3 -3
- package/dist/{client-DpOwh_zX.js → client-B0YZfxNy.js} +3 -8
- package/dist/{config-BxPrFVJP.js → config-C0UwYqDK.js} +100 -3
- package/dist/{connections-BnTM1nRf.js → connections-Bwu3VORi.js} +11 -10
- package/dist/{conversation-B0baEwoA.js → conversation-DF4rUcjb.js} +6 -2
- package/dist/{conversation-privacy-ueJ6i-t9.js → conversation-privacy-CY7JVjxn.js} +1 -1
- package/dist/{credential-sync-DeDkof_D.js → credential-sync-VGAMUTGp.js} +20 -20
- package/dist/{agent-hooks-D_PbluRX.js → credentialed-enF5Bf3y.js} +3316 -179
- package/dist/{executor-D3WIS4vl.js → executor-TnWbvL09.js} +10 -300
- package/dist/{history-AY8rs-FR.js → history-C84mlAwO.js} +2 -1
- package/dist/{images-5VNK_yYC.js → images-BKQqSi5W.js} +3 -3
- package/dist/instrumentation.js +41 -25
- package/dist/{job-queue-BYHonCAH.js → job-queue-DBpHmKnd.js} +53 -14
- package/dist/{logging-DNQqsQ57.js → logging-Ce0mXZ8J.js} +19 -32
- package/dist/{message-CDTJISxL.js → message-VZ3DFpGb.js} +4 -4
- package/dist/nitro.d.ts +17 -2
- package/dist/nitro.js +26 -27
- package/dist/{oauth-callback-server-Bk4rbLOs.js → oauth-callback-server-CpqWLjVY.js} +2 -2
- package/dist/{prompt-CxatQVaj.js → prompt-BcCGlmg2.js} +2 -2
- package/dist/{registry-CfdUEk4N.js → registry-1BEIPdbT.js} +1 -1
- package/dist/{resolve-BXShI336.js → resolve-BSHHkEGE.js} +7 -106
- package/dist/{result-R35jcahx.js → result-CwOpzqdh.js} +8 -8
- package/dist/{runner-IC4Drh3Y.js → runner-CEaX04kz.js} +11 -11
- package/dist/{sandbox-egress-signals-C4RIfjb8.js → sandbox-egress-signals-BwtGHwqa.js} +1 -1
- package/dist/{schema-QidbykYl.js → schema-RsaBHxRH.js} +45 -4
- package/dist/{sentry-BBUlHih9.js → sentry-MDkYAVPV.js} +3 -6
- package/dist/{service-account-DJSRo2cL.js → service-account-6wC76eBZ.js} +5 -5
- package/dist/{service-account-DifohWyX.js → service-account-Dg4lIbHm.js} +3 -3
- package/dist/{session-stop-B9RRGC-P.js → session-stop-tZOw9AJD.js} +120 -80
- package/dist/{skills-DVJmS_ZP.js → skills-DzyGN7wd.js} +2 -2
- package/dist/{spawn-DkVYGfSY.js → spawn-6rokq7l_.js} +2 -2
- package/dist/{store-BvolNnx4.js → store-DcKkzrdt.js} +3 -3
- package/dist/{store-C_mHwAnR.js → store-FALy-JQb.js} +6 -6
- package/dist/{task-queue-BcEyPhtX.js → task-queue-Bg4RS2Gy.js} +14 -19
- package/dist/{task-runner-CiQj5M_9.js → task-runner-8N5LIkSg.js} +47 -29
- package/dist/{tasks-OgXmReUv.js → tasks-DDT-J3Rf.js} +17 -2078
- package/dist/{thread-state-XFvpWXE9.js → thread-state-cprEaxgl.js} +5 -5
- package/dist/{turn-failure-response-BjBAtnVt.js → turn-failure-response-C8sMdsdX.js} +8 -8
- package/dist/{turn-lifecycle-nvKL2rul.js → turn-lifecycle-DaBVoz7h.js} +2 -2
- package/dist/{turn-session-routing-DEMxHySb.js → turn-session-routing-a9CHX-w6.js} +1 -1
- package/dist/{validation-XOFldwvE.js → validation-C2lllinq.js} +1 -1
- package/dist/{version-C9f5hdHD.js → version-oaLfxxnf.js} +1 -1
- package/dist/version.js +1 -1
- package/dist/{viewer-BuPwzOC9.js → viewer-BpE6Z3qf.js} +22 -6
- package/dist/{web-input-4t7TYLsY.js → web-input-B-bMjD1V.js} +147 -48
- package/dist/{work-C_aF6JN5.js → work-VX1SHWha.js} +52 -51
- package/dist/{worker-DR633sA-.js → worker-hook-y_Y.js} +5 -5
- package/package.json +10 -9
- package/dist/profile-ieODOp4u.js +0 -582
|
@@ -1,6 +1,5 @@
|
|
|
1
|
-
import
|
|
2
|
-
import {
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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
|
-
|
|
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 =
|
|
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
|
|
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
|
|
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. */
|
|
@@ -1,7 +1,7 @@
|
|
|
1
1
|
import { t as __exportAll } from "./rolldown-runtime-nwUcYXjP.js";
|
|
2
|
-
import {
|
|
3
|
-
import { S as readLiveAttachment, w as storeAttachment } from "./agent-runner-
|
|
4
|
-
import { H as detectImageMediaType } from "./conversation-
|
|
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,
|
package/dist/instrumentation.js
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
|
-
import { F as getDeploymentTelemetryAttributes, P as getDeploymentServiceVersion } from "./logging-
|
|
2
|
-
import {
|
|
3
|
-
import { n as getCurrentConversationPrivacy } from "./conversation-privacy-
|
|
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
|
-
|
|
145
|
-
|
|
146
|
-
|
|
147
|
-
|
|
148
|
-
streamGenAiSpans: true,
|
|
167
|
+
dataCollection: {
|
|
168
|
+
httpBodies: ["incomingRequest"],
|
|
169
|
+
databaseQueryData: false
|
|
170
|
+
},
|
|
149
171
|
beforeSend: scrubPrivateSentryEvent,
|
|
150
|
-
beforeSendLog: scrubPrivateSentryLog,
|
|
151
|
-
beforeSendSpan:
|
|
152
|
-
|
|
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-
|
|
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
|
|
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
|
-
|
|
48
|
-
function
|
|
49
|
-
|
|
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 ??
|
|
197
|
+
const client = options.client ?? getQueueProvider();
|
|
168
198
|
return { async send(message, sendOptions) {
|
|
169
|
-
const
|
|
170
|
-
|
|
171
|
-
|
|
172
|
-
|
|
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
|
|
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,
|
|
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 };
|