@sentry/junior 0.203.0 → 0.205.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/dist/agent-D4nu8MQV.js +17521 -0
- package/dist/agent-hooks-DXHpTJ4m.js +4042 -0
- package/dist/agent-runner-C04colea.js +678 -0
- package/dist/api/schema.d.ts +2736 -2639
- package/dist/api/schema.js +4 -169
- package/dist/api.d.ts +23 -17
- package/dist/api.js +3881 -5326
- package/dist/app-Cb776lL8.d.ts +247 -0
- package/dist/app.d.ts +4 -520
- package/dist/app.js +9524 -11875
- package/dist/auth-pause-state-C2P3guS1.js +168 -0
- package/dist/catalog-runtime-CXw3asJD.js +7 -0
- package/dist/checkpoint-CrViJ8Ps.js +2450 -0
- package/dist/cli/chat.d.ts +20 -0
- package/dist/cli/chat.js +229 -336
- package/dist/cli/check.d.ts +8 -0
- package/dist/cli/check.js +513 -806
- package/dist/cli/env.d.ts +13 -0
- package/dist/cli/env.js +63 -12
- package/dist/cli/init.d.ts +3 -0
- package/dist/cli/init.js +90 -159
- package/dist/cli/main.d.ts +6 -0
- package/dist/cli/main.js +43 -64
- package/dist/cli/plugins.d.ts +13 -0
- package/dist/cli/plugins.js +148 -227
- package/dist/cli/run.d.ts +16 -0
- package/dist/cli/run.js +52 -8
- package/dist/cli/snapshot-create.d.ts +4 -0
- package/dist/cli/snapshot-create.js +71 -125
- package/dist/cli/upgrade.d.ts +15 -0
- package/dist/cli/upgrade.js +232 -335
- package/dist/config-BOtJQ7Pc.js +941 -0
- package/dist/context-B45_WqVX.js +298 -0
- package/dist/conversation-privacy-BZRA6Pes.js +182 -0
- package/dist/conversation-work-C6y3T5Hx.js +51 -0
- package/dist/credential-sync-Bep34IB_.js +2661 -0
- package/dist/db-BeyXKJOI.d.ts +5 -0
- package/dist/destinations-BeBiJeEM.js +29 -0
- package/dist/execution-stats-B6lgWxCK.js +373 -0
- package/dist/executor-BlUhFL7_.js +721 -0
- package/dist/experimental-CIXf7Uye.js +46 -0
- package/dist/history-ClE4toxe.d.ts +32 -0
- package/dist/history-CqTuSAdI.js +441 -0
- package/dist/instrumentation.d.ts +3 -3
- package/dist/instrumentation.js +130 -176
- package/dist/job-queue-DLMqIK74.js +63 -0
- package/dist/logging-BMJzdDlP.js +1210 -0
- package/dist/model-profile-CZmVoGdX.js +49 -0
- package/dist/nitro.d.ts +31 -36
- package/dist/nitro.js +275 -456
- package/dist/oauth-callback-server-WwG5_Zgm.js +130 -0
- package/dist/oauth-relay-CdCnu80W.js +62 -0
- package/dist/package-discovery-7a9YqLhE.js +455 -0
- package/dist/pending-auth-CUbXq06G.js +185 -0
- package/dist/plugin-module-BKGOXca2.js +81 -0
- package/dist/plugins-BI9A1vKA.d.ts +95 -0
- package/dist/plugins-egKWjgue.js +99 -0
- package/dist/private-trace-result-BLvBjy_e.js +16 -0
- package/dist/profile-T0tXE4zu.js +861 -0
- package/dist/registry-BA0__8ai.js +1419 -0
- package/dist/reporting-schema-DosTN__Q.js +105 -0
- package/dist/resolve-bvD1ORdv.js +546 -0
- package/dist/rolldown-runtime-B4FMCO8f.js +28 -0
- package/dist/runner-BXYxfIUL.js +392 -0
- package/dist/sandbox-egress-signals-ngEPjSEW.js +46 -0
- package/dist/schema-Rn8-XEaN.js +1140 -0
- package/dist/sentry-CD3SdJl-.js +26 -0
- package/dist/skills-DJOlYdBs.js +316 -0
- package/dist/spawn-h0R1bTEo.js +29 -0
- package/dist/stats-3YZn-Swi.js +2648 -0
- package/dist/store-C5qxF2ac.d.ts +208 -0
- package/dist/task-queue-CoXwd2eq.js +136 -0
- package/dist/task-runner-B2_mJZj0.js +639 -0
- package/dist/thread-state-CqZ1m-es.js +431 -0
- package/dist/turn-execution-fI6PZ0iI.js +47 -0
- package/dist/turn-lifecycle-CcnwrOcp.js +54 -0
- package/dist/usage-B5SfMb3H.js +296 -0
- package/dist/usage-schema-CKaDkH_j.js +20 -0
- package/dist/validation-DfWcvhuS.js +40 -0
- package/dist/vercel-queue-DIkVcfK4.js +167 -0
- package/dist/vercel.d.ts +6 -6
- package/dist/vercel.js +14 -6
- package/dist/version-CnXZ614E.d.ts +5 -0
- package/dist/version-oD-oPrbO.js +8 -0
- package/dist/version.d.ts +2 -4
- package/dist/version.js +2 -6
- package/dist/web-authorization-Crbzlmzo.js +76 -0
- package/dist/web-input-BOuq3oKK.js +494 -0
- package/dist/work-B91LQKHr.js +509 -0
- package/dist/worker-BcRRTe6k.js +625 -0
- package/package.json +9 -9
- package/dist/agent-hooks-GB2VPTNA.js +0 -51
- package/dist/catalog-runtime-UBLIWD3O.js +0 -14
- package/dist/chunk-2LYHWMR4.js +0 -46
- package/dist/chunk-352OWAZH.js +0 -320
- package/dist/chunk-3Y47VMHV.js +0 -6
- package/dist/chunk-3YJSKOWF.js +0 -164
- package/dist/chunk-4KSSKTQ5.js +0 -229
- package/dist/chunk-4UO6FK4G.js +0 -64
- package/dist/chunk-5AHX53NQ.js +0 -717
- package/dist/chunk-5J3E5FWA.js +0 -700
- package/dist/chunk-5PDAG6O3.js +0 -206
- package/dist/chunk-6Y5B5PEX.js +0 -80
- package/dist/chunk-7GWQ5S5R.js +0 -2086
- package/dist/chunk-7H2VZTWN.js +0 -103
- package/dist/chunk-7NL7T6VU.js +0 -406
- package/dist/chunk-A5L27LE4.js +0 -387
- package/dist/chunk-ADIAWL34.js +0 -81
- package/dist/chunk-ASTEMBKJ.js +0 -519
- package/dist/chunk-CEMMLV5L.js +0 -98
- package/dist/chunk-CM5HNV2W.js +0 -131
- package/dist/chunk-CRTRBBRI.js +0 -105
- package/dist/chunk-DA2KGZZI.js +0 -13
- package/dist/chunk-DIB4GX3G.js +0 -8
- package/dist/chunk-DKIJ2RP5.js +0 -68
- package/dist/chunk-DWPN6SCH.js +0 -172
- package/dist/chunk-EDKUFGPL.js +0 -64
- package/dist/chunk-ENY6SKIU.js +0 -1228
- package/dist/chunk-F4MGCZOX.js +0 -2943
- package/dist/chunk-FA6POGLH.js +0 -70
- package/dist/chunk-FSUR7GTG.js +0 -20475
- package/dist/chunk-GKEOHJL5.js +0 -1856
- package/dist/chunk-GMCB6W5Y.js +0 -333
- package/dist/chunk-IE2VPG7O.js +0 -1135
- package/dist/chunk-IZ5B5IHQ.js +0 -3656
- package/dist/chunk-JAL3CH4G.js +0 -27
- package/dist/chunk-KIIEUXD3.js +0 -1764
- package/dist/chunk-KXU4NIL7.js +0 -692
- package/dist/chunk-MTM5IFCY.js +0 -1190
- package/dist/chunk-N7TMSOZH.js +0 -235
- package/dist/chunk-NCEBK6PH.js +0 -36
- package/dist/chunk-NHJU2ZAL.js +0 -56
- package/dist/chunk-P6KTRNVC.js +0 -321
- package/dist/chunk-PDO5BLNM.js +0 -22
- package/dist/chunk-PDRNLLFT.js +0 -3295
- package/dist/chunk-PEQXYSSE.js +0 -45
- package/dist/chunk-PKEX2AQX.js +0 -198
- package/dist/chunk-PSJCGIGO.js +0 -1163
- package/dist/chunk-PZUSUL55.js +0 -506
- package/dist/chunk-R45M4TUS.js +0 -37
- package/dist/chunk-RC745GGZ.js +0 -122
- package/dist/chunk-SP3QKZXJ.js +0 -820
- package/dist/chunk-TXKUKMVO.js +0 -417
- package/dist/chunk-UE4GPWSD.js +0 -931
- package/dist/chunk-UIE3R5XU.js +0 -17
- package/dist/chunk-UXPG6ZIN.js +0 -84
- package/dist/chunk-VFUK3X5B.js +0 -50
- package/dist/chunk-VNMJWREK.js +0 -787
- package/dist/chunk-VZ7CSOX2.js +0 -706
- package/dist/chunk-WCNQJKFT.js +0 -10
- package/dist/chunk-WDZR3QQM.js +0 -135
- package/dist/chunk-WLYVJCHV.js +0 -1433
- package/dist/chunk-WS7NAFTM.js +0 -1520
- package/dist/chunk-X6GDDWQH.js +0 -60
- package/dist/chunk-XPDEYNQI.js +0 -102
- package/dist/chunk-XRW44VGM.js +0 -58
- package/dist/chunk-Y2CM7HXH.js +0 -111
- package/dist/chunk-Y7X25LFY.js +0 -15
- package/dist/conversation-work-VIOQ5ZF3.js +0 -54
- package/dist/db-NGDJV7YH.js +0 -26
- package/dist/discovery-DWVDM7UK.js +0 -44
- package/dist/experimental-P5FZM4CU.js +0 -12
- package/dist/oauth-callback-server-YFY7YEGK.js +0 -243
- package/dist/oauth-relay-5XPVRPYB.js +0 -8
- package/dist/plugins-YTYJMMJF.js +0 -14
- package/dist/runner-ORTNSB2Q.js +0 -522
- package/dist/sandbox-egress-signals-FIL7EGPR.js +0 -73
- package/dist/sentry-MB3NL3IR.js +0 -42
- package/dist/skills-H376WQOH.js +0 -27
- package/dist/spawn-T43WHLOS.js +0 -42
- package/dist/task-runner-LBZWF32V.js +0 -36
- package/dist/validation-REJLRKI6.js +0 -17
- package/dist/work-3KJ3RE76.js +0 -51
- package/dist/worker-QFEBU72E.js +0 -24
|
@@ -0,0 +1,721 @@
|
|
|
1
|
+
import "./config-BOtJQ7Pc.js";
|
|
2
|
+
import { n as juniorDestinations, r as timestamptz } from "./destinations-BeBiJeEM.js";
|
|
3
|
+
import { AsyncLocalStorage } from "node:async_hooks";
|
|
4
|
+
import { getTableColumns, sql } from "drizzle-orm";
|
|
5
|
+
import { bigint, boolean, check, date, foreignKey, index, integer, jsonb, pgTable, primaryKey, text, uniqueIndex, uuid } from "drizzle-orm/pg-core";
|
|
6
|
+
import { Pool } from "@neondatabase/serverless";
|
|
7
|
+
import { drizzle } from "drizzle-orm/neon-serverless";
|
|
8
|
+
import { migrate } from "drizzle-orm/neon-serverless/migrator";
|
|
9
|
+
import pg from "pg";
|
|
10
|
+
import { drizzle as drizzle$1 } from "drizzle-orm/node-postgres";
|
|
11
|
+
import { migrate as migrate$1 } from "drizzle-orm/node-postgres/migrator";
|
|
12
|
+
//#region src/db/schema/artifacts.ts
|
|
13
|
+
/** Durable metadata for conversation-owned public artifacts. */
|
|
14
|
+
const juniorArtifacts = pgTable("junior_artifacts", {
|
|
15
|
+
/** Public identity used in `/public/artifacts/<id>.<ext>`. */
|
|
16
|
+
id: text("id").primaryKey(),
|
|
17
|
+
conversationId: text("conversation_id").notNull(),
|
|
18
|
+
sha256: text("sha256").notNull(),
|
|
19
|
+
ext: text("ext").notNull(),
|
|
20
|
+
storageKey: text("storage_key").notNull(),
|
|
21
|
+
contentType: text("content_type").notNull(),
|
|
22
|
+
bytes: integer("bytes").notNull(),
|
|
23
|
+
public: boolean("public").notNull(),
|
|
24
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
25
|
+
/** Set when the artifact should stop being served publicly. */
|
|
26
|
+
deleteRequestedAt: timestamptz("delete_requested_at")
|
|
27
|
+
}, (table) => [
|
|
28
|
+
uniqueIndex("junior_artifacts_conversation_sha_uidx").on(table.conversationId, table.sha256),
|
|
29
|
+
index("junior_artifacts_gc_idx").on(table.deleteRequestedAt, table.createdAt),
|
|
30
|
+
index("junior_artifacts_conversation_idx").on(table.conversationId)
|
|
31
|
+
]);
|
|
32
|
+
//#endregion
|
|
33
|
+
//#region src/db/schema/users.ts
|
|
34
|
+
const juniorUsers = pgTable("junior_users", {
|
|
35
|
+
id: text("id").primaryKey(),
|
|
36
|
+
primaryEmail: text("primary_email").notNull(),
|
|
37
|
+
primaryEmailNormalized: text("primary_email_normalized").notNull(),
|
|
38
|
+
displayName: text("display_name"),
|
|
39
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
40
|
+
updatedAt: timestamptz("updated_at").notNull()
|
|
41
|
+
}, (table) => [uniqueIndex("junior_users_primary_email_normalized_uidx").on(table.primaryEmailNormalized)]);
|
|
42
|
+
//#endregion
|
|
43
|
+
//#region src/db/schema/identities.ts
|
|
44
|
+
const juniorIdentities = pgTable("junior_identities", {
|
|
45
|
+
id: text("id").primaryKey(),
|
|
46
|
+
kind: text("kind").$type().notNull(),
|
|
47
|
+
provider: text("provider").notNull(),
|
|
48
|
+
providerTenantId: text("provider_tenant_id").notNull().default(""),
|
|
49
|
+
providerSubjectId: text("provider_subject_id").notNull(),
|
|
50
|
+
displayName: text("display_name"),
|
|
51
|
+
handle: text("handle"),
|
|
52
|
+
email: text("email"),
|
|
53
|
+
avatarUrl: text("avatar_url"),
|
|
54
|
+
metadata: jsonb("metadata_json"),
|
|
55
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
56
|
+
updatedAt: timestamptz("updated_at").notNull(),
|
|
57
|
+
userId: text("user_id").references(() => juniorUsers.id),
|
|
58
|
+
emailNormalized: text("email_normalized"),
|
|
59
|
+
emailVerified: boolean("email_verified").notNull().default(false)
|
|
60
|
+
}, (table) => [
|
|
61
|
+
uniqueIndex("junior_identities_provider_subject_uidx").on(table.provider, table.providerTenantId, table.providerSubjectId),
|
|
62
|
+
index("junior_identities_user_idx").on(table.userId),
|
|
63
|
+
index("junior_identities_verified_email_idx").on(table.emailNormalized).where(sql`${table.emailVerified} = true AND ${table.emailNormalized} IS NOT NULL`),
|
|
64
|
+
index("junior_identities_kind_provider_idx").on(table.kind, table.provider)
|
|
65
|
+
]);
|
|
66
|
+
//#endregion
|
|
67
|
+
//#region src/db/schema/conversations.ts
|
|
68
|
+
const juniorConversations = pgTable("junior_conversations", {
|
|
69
|
+
conversationId: text("conversation_id").primaryKey(),
|
|
70
|
+
schemaVersion: integer("schema_version").notNull().default(1),
|
|
71
|
+
source: text("source").$type(),
|
|
72
|
+
/** Structured session Source locator; set-once on the conversation root. */
|
|
73
|
+
sessionSource: jsonb("source_json").$type(),
|
|
74
|
+
originType: text("origin_type"),
|
|
75
|
+
originId: text("origin_id"),
|
|
76
|
+
originRunId: text("origin_run_id"),
|
|
77
|
+
/** Complete Location associated with this Conversation. */
|
|
78
|
+
location: jsonb("location_json").$type(),
|
|
79
|
+
destinationId: text("destination_id").references(() => juniorDestinations.id),
|
|
80
|
+
destination: jsonb("destination_json").$type(),
|
|
81
|
+
actorIdentityId: text("actor_identity_id").references(() => juniorIdentities.id),
|
|
82
|
+
creatorIdentityId: text("creator_identity_id").references(() => juniorIdentities.id),
|
|
83
|
+
credentialSubjectIdentityId: text("credential_subject_identity_id").references(() => juniorIdentities.id),
|
|
84
|
+
actor: jsonb("actor_json").$type(),
|
|
85
|
+
channelName: text("channel_name"),
|
|
86
|
+
title: text("title"),
|
|
87
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
88
|
+
lastActivityAt: timestamptz("last_activity_at").notNull(),
|
|
89
|
+
updatedAt: timestamptz("updated_at").notNull(),
|
|
90
|
+
executionUpdatedAt: timestamptz("execution_updated_at"),
|
|
91
|
+
executionStatus: text("execution_status").$type().notNull(),
|
|
92
|
+
runId: text("run_id"),
|
|
93
|
+
lastCheckpointAt: timestamptz("last_checkpoint_at"),
|
|
94
|
+
lastEnqueuedAt: timestamptz("last_enqueued_at"),
|
|
95
|
+
parentConversationId: text("parent_conversation_id").references(() => juniorConversations.conversationId),
|
|
96
|
+
rootConversationId: text("root_conversation_id").references(() => juniorConversations.conversationId),
|
|
97
|
+
transcriptPurgedAt: timestamptz("transcript_purged_at"),
|
|
98
|
+
durationMs: integer("duration_ms").notNull().default(0),
|
|
99
|
+
usage: jsonb("usage_json").$type(),
|
|
100
|
+
executionDurationMs: integer("execution_duration_ms").notNull().default(0),
|
|
101
|
+
executionUsage: jsonb("execution_usage_json").$type(),
|
|
102
|
+
metricRunId: text("metric_run_id"),
|
|
103
|
+
legacyArchivedAt: timestamptz("archived_at")
|
|
104
|
+
}, (table) => [
|
|
105
|
+
index("junior_conversations_last_activity_idx").on(table.lastActivityAt.desc(), table.conversationId),
|
|
106
|
+
index("junior_conversations_active_idx").using("btree", sql`coalesce(${table.executionUpdatedAt}, ${table.updatedAt})`, table.conversationId).where(sql`${table.executionStatus} <> 'idle'`),
|
|
107
|
+
index("junior_conversations_destination_activity_idx").on(table.destinationId, table.lastActivityAt.desc()),
|
|
108
|
+
index("junior_conversations_actor_activity_idx").on(table.actorIdentityId, table.lastActivityAt.desc()),
|
|
109
|
+
index("junior_conversations_origin_idx").on(table.originType, table.originId, table.lastActivityAt.desc()),
|
|
110
|
+
index("junior_conversations_parent_idx").on(table.parentConversationId),
|
|
111
|
+
index("junior_conversations_root_idx").on(table.rootConversationId)
|
|
112
|
+
]);
|
|
113
|
+
/** Select runtime conversation fields without reading the legacy archive column. */
|
|
114
|
+
function conversationReadColumns() {
|
|
115
|
+
const { legacyArchivedAt, ...columns } = getTableColumns(juniorConversations);
|
|
116
|
+
return columns;
|
|
117
|
+
}
|
|
118
|
+
//#endregion
|
|
119
|
+
//#region src/db/schema/attachments.ts
|
|
120
|
+
/** Durable metadata for files owned by one conversation. */
|
|
121
|
+
const juniorAttachments = pgTable("junior_attachments", {
|
|
122
|
+
id: text("id").primaryKey(),
|
|
123
|
+
conversationId: text("conversation_id").notNull().references(() => juniorConversations.conversationId, { onDelete: "cascade" }),
|
|
124
|
+
/** Service that stores the file bytes. */
|
|
125
|
+
storageProvider: text("storage_provider").notNull(),
|
|
126
|
+
storageKey: text("storage_key").notNull(),
|
|
127
|
+
/** Provider that supplied the file. */
|
|
128
|
+
provider: text("provider"),
|
|
129
|
+
/** File id assigned by the source provider. */
|
|
130
|
+
providerId: text("provider_id"),
|
|
131
|
+
filename: text("filename").notNull(),
|
|
132
|
+
contentType: text("content_type").notNull(),
|
|
133
|
+
bytes: integer("bytes").notNull(),
|
|
134
|
+
sha256: text("sha256").notNull(),
|
|
135
|
+
visionSummary: text("vision_summary"),
|
|
136
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
137
|
+
/** Set when conversation purge marks the attachment unavailable. */
|
|
138
|
+
deleteRequestedAt: timestamptz("delete_requested_at")
|
|
139
|
+
}, (table) => [
|
|
140
|
+
index("junior_attachments_conversation_idx").on(table.conversationId),
|
|
141
|
+
index("junior_attachments_provider_idx").on(table.conversationId, table.provider, table.providerId),
|
|
142
|
+
index("junior_attachments_gc_idx").on(table.storageProvider, table.deleteRequestedAt, table.createdAt)
|
|
143
|
+
]);
|
|
144
|
+
//#endregion
|
|
145
|
+
//#region src/db/schema/code.ts
|
|
146
|
+
/** Repository known to Junior through an installed code plugin. */
|
|
147
|
+
const juniorCodeRepositories = pgTable("junior_code_repositories", {
|
|
148
|
+
id: uuid("id").primaryKey(),
|
|
149
|
+
name: text("name").notNull(),
|
|
150
|
+
provider: text("provider").notNull(),
|
|
151
|
+
providerId: text("provider_id").notNull(),
|
|
152
|
+
url: text("url"),
|
|
153
|
+
updatedAt: timestamptz("updated_at").notNull()
|
|
154
|
+
}, (table) => [uniqueIndex("junior_code_repositories_provider_id_idx").on(table.provider, table.providerId)]);
|
|
155
|
+
/** Latest known state for one code change created by Junior. */
|
|
156
|
+
const juniorCodeChanges = pgTable("junior_code_changes", {
|
|
157
|
+
id: uuid("id").primaryKey(),
|
|
158
|
+
closedAt: timestamptz("closed_at"),
|
|
159
|
+
conversationIds: text("conversation_ids").array().notNull().default(sql`ARRAY[]::text[]`),
|
|
160
|
+
mergedAt: timestamptz("merged_at"),
|
|
161
|
+
number: integer("number").notNull(),
|
|
162
|
+
openedAt: timestamptz("opened_at").notNull(),
|
|
163
|
+
provider: text("provider").notNull(),
|
|
164
|
+
providerId: text("provider_id").notNull(),
|
|
165
|
+
repositoryId: uuid("repository_id").notNull().references(() => juniorCodeRepositories.id, { onDelete: "cascade" }),
|
|
166
|
+
state: text("state").$type().notNull(),
|
|
167
|
+
title: text("title"),
|
|
168
|
+
updatedAt: timestamptz("updated_at").notNull(),
|
|
169
|
+
url: text("url")
|
|
170
|
+
}, (table) => [
|
|
171
|
+
uniqueIndex("junior_code_changes_provider_id_idx").on(table.provider, table.providerId),
|
|
172
|
+
index("junior_code_changes_opened_at_idx").on(table.openedAt),
|
|
173
|
+
index("junior_code_changes_merged_at_idx").on(table.mergedAt),
|
|
174
|
+
index("junior_code_changes_closed_at_idx").on(table.closedAt),
|
|
175
|
+
index("junior_code_changes_open_idx").on(table.id).where(sql`${table.state} = 'open'`)
|
|
176
|
+
]);
|
|
177
|
+
//#endregion
|
|
178
|
+
//#region src/db/schema/conversation-annotations.ts
|
|
179
|
+
const juniorConversationAnnotations = pgTable("junior_conversation_annotations", {
|
|
180
|
+
conversationId: text("conversation_id").notNull(),
|
|
181
|
+
plugin: text("plugin").notNull(),
|
|
182
|
+
kind: text("kind").notNull(),
|
|
183
|
+
key: text("key").notNull(),
|
|
184
|
+
annotation: jsonb("annotation_json").$type().notNull(),
|
|
185
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
186
|
+
updatedAt: timestamptz("updated_at").notNull()
|
|
187
|
+
}, (table) => [primaryKey({
|
|
188
|
+
name: "junior_conversation_annotations_pk",
|
|
189
|
+
columns: [
|
|
190
|
+
table.conversationId,
|
|
191
|
+
table.plugin,
|
|
192
|
+
table.kind,
|
|
193
|
+
table.key
|
|
194
|
+
]
|
|
195
|
+
}), foreignKey({
|
|
196
|
+
name: "junior_conversation_annotations_conversation_id_fk",
|
|
197
|
+
columns: [table.conversationId],
|
|
198
|
+
foreignColumns: [juniorConversations.conversationId]
|
|
199
|
+
}).onDelete("cascade")]);
|
|
200
|
+
//#endregion
|
|
201
|
+
//#region src/db/schema/api-tokens.ts
|
|
202
|
+
const juniorApiTokens = pgTable("junior_api_tokens", {
|
|
203
|
+
id: text("id").primaryKey(),
|
|
204
|
+
ownerEmailNormalized: text("owner_email_normalized").notNull(),
|
|
205
|
+
name: text("name").notNull(),
|
|
206
|
+
tokenHash: text("token_hash").notNull(),
|
|
207
|
+
tokenSuffix: text("token_suffix").notNull(),
|
|
208
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
209
|
+
expiresAt: timestamptz("expires_at").notNull(),
|
|
210
|
+
lastUsedAt: timestamptz("last_used_at"),
|
|
211
|
+
revokedAt: timestamptz("revoked_at")
|
|
212
|
+
}, (table) => [uniqueIndex("junior_api_tokens_token_hash_uidx").on(table.tokenHash), index("junior_api_tokens_owner_email_idx").on(table.ownerEmailNormalized)]);
|
|
213
|
+
//#endregion
|
|
214
|
+
//#region src/db/schema/conversation-events.ts
|
|
215
|
+
/**
|
|
216
|
+
* Append-only canonical conversation history. `history_version` partitions
|
|
217
|
+
* model-history replacements, while `(conversation_id, seq)` is the stable
|
|
218
|
+
* event identity and lease-fencing tripwire.
|
|
219
|
+
*
|
|
220
|
+
* `actor_identity_id` is the first-class author identity for human-authored
|
|
221
|
+
* events. Message payloads may still carry display author fields in `meta`.
|
|
222
|
+
*/
|
|
223
|
+
const juniorConversationEvents = pgTable("junior_conversation_events", {
|
|
224
|
+
conversationId: text("conversation_id").notNull(),
|
|
225
|
+
seq: integer("seq").notNull(),
|
|
226
|
+
historyVersion: integer("history_version").notNull(),
|
|
227
|
+
schemaVersion: integer("schema_version").default(1).notNull(),
|
|
228
|
+
idempotencyKey: text("idempotency_key"),
|
|
229
|
+
type: text("type").notNull(),
|
|
230
|
+
payload: jsonb("payload").$type().notNull(),
|
|
231
|
+
actorIdentityId: text("actor_identity_id").references(() => juniorIdentities.id),
|
|
232
|
+
createdAt: timestamptz("created_at").notNull()
|
|
233
|
+
}, (table) => [
|
|
234
|
+
primaryKey({
|
|
235
|
+
name: "junior_conversation_events_conversation_id_seq_pk",
|
|
236
|
+
columns: [table.conversationId, table.seq]
|
|
237
|
+
}),
|
|
238
|
+
foreignKey({
|
|
239
|
+
name: "junior_conversation_events_conversation_id_junior_conversations_conversation_id_fk",
|
|
240
|
+
columns: [table.conversationId],
|
|
241
|
+
foreignColumns: [juniorConversations.conversationId]
|
|
242
|
+
}),
|
|
243
|
+
index("junior_conversation_events_history_version_idx").on(table.conversationId, table.historyVersion, table.seq),
|
|
244
|
+
index("junior_conversation_events_type_idx").on(table.conversationId, table.type, table.seq),
|
|
245
|
+
index("junior_conversation_events_actor_identity_idx").on(table.actorIdentityId, table.conversationId, table.seq),
|
|
246
|
+
index("junior_conversation_events_message_search_idx").using("gin", sql`to_tsvector('english', ${table.payload}->>'text')`).where(sql`${table.type} = 'message'`),
|
|
247
|
+
uniqueIndex("junior_conversation_events_idempotency_idx").on(table.conversationId, table.idempotencyKey)
|
|
248
|
+
]);
|
|
249
|
+
//#endregion
|
|
250
|
+
//#region src/db/schema/conversation-bindings.ts
|
|
251
|
+
/** Provider conversation coordinates bound to Junior's opaque durable conversation id. */
|
|
252
|
+
const juniorConversationBindings = pgTable("junior_conversation_bindings", {
|
|
253
|
+
conversationId: text("conversation_id").notNull().references(() => juniorConversations.conversationId),
|
|
254
|
+
provider: text("provider").notNull(),
|
|
255
|
+
providerTenantId: text("provider_tenant_id").notNull().default(""),
|
|
256
|
+
providerDestinationId: text("provider_destination_id").notNull(),
|
|
257
|
+
providerConversationId: text("provider_conversation_id").notNull(),
|
|
258
|
+
createdAt: timestamptz("created_at").notNull()
|
|
259
|
+
}, (table) => [primaryKey({
|
|
260
|
+
name: "junior_conversation_bindings_provider_conversation_pk",
|
|
261
|
+
columns: [
|
|
262
|
+
table.provider,
|
|
263
|
+
table.providerTenantId,
|
|
264
|
+
table.providerDestinationId,
|
|
265
|
+
table.providerConversationId
|
|
266
|
+
]
|
|
267
|
+
}), index("junior_conversation_bindings_conversation_idx").on(table.conversationId)]);
|
|
268
|
+
//#endregion
|
|
269
|
+
//#region src/db/schema/conversation-participants.ts
|
|
270
|
+
/**
|
|
271
|
+
* Materialized personal-feed membership for one linked user on one root
|
|
272
|
+
* conversation. Rows come from the root actor and from durable human user
|
|
273
|
+
* message authors.
|
|
274
|
+
*/
|
|
275
|
+
const juniorConversationParticipants = pgTable("junior_conversation_participants", {
|
|
276
|
+
userId: text("user_id").notNull().references(() => juniorUsers.id),
|
|
277
|
+
rootConversationId: text("root_conversation_id").notNull().references(() => juniorConversations.conversationId),
|
|
278
|
+
lastMessageAt: timestamptz("last_message_at").notNull(),
|
|
279
|
+
archivedAt: timestamptz("archived_at")
|
|
280
|
+
}, (table) => [
|
|
281
|
+
primaryKey({
|
|
282
|
+
name: "junior_conversation_participants_user_root_pk",
|
|
283
|
+
columns: [table.userId, table.rootConversationId]
|
|
284
|
+
}),
|
|
285
|
+
index("junior_conversation_participants_user_activity_idx").on(table.userId, table.lastMessageAt.desc()),
|
|
286
|
+
index("junior_conversation_participants_root_idx").on(table.rootConversationId)
|
|
287
|
+
]);
|
|
288
|
+
//#endregion
|
|
289
|
+
//#region src/db/schema/agent-invocations.ts
|
|
290
|
+
const AGENT_INVOCATION_MAILBOX_STATUSES = ["pending", "appended"];
|
|
291
|
+
const juniorAgentBindings = pgTable("junior_agent_bindings", {
|
|
292
|
+
parentConversationId: text("parent_conversation_id").notNull().references(() => juniorConversations.conversationId),
|
|
293
|
+
name: text("name").notNull(),
|
|
294
|
+
childConversationId: text("child_conversation_id").notNull().references(() => juniorConversations.conversationId)
|
|
295
|
+
}, (table) => [primaryKey({ columns: [table.parentConversationId, table.name] }), uniqueIndex("junior_agent_bindings_child_idx").on(table.childConversationId)]);
|
|
296
|
+
const juniorAgentInvocations = pgTable("junior_agent_invocations", {
|
|
297
|
+
invocationId: text("invocation_id").primaryKey(),
|
|
298
|
+
parentConversationId: text("parent_conversation_id").notNull().references(() => juniorConversations.conversationId),
|
|
299
|
+
childConversationId: text("child_conversation_id").notNull().references(() => juniorConversations.conversationId),
|
|
300
|
+
agentName: text("agent_name"),
|
|
301
|
+
input: text("input").notNull(),
|
|
302
|
+
actor: jsonb("actor_json").$type().notNull(),
|
|
303
|
+
credentialContext: jsonb("credential_context_json").$type(),
|
|
304
|
+
source: jsonb("source_json").$type().notNull(),
|
|
305
|
+
destination: jsonb("destination_json").$type().notNull(),
|
|
306
|
+
destinationVisibility: text("destination_visibility").$type(),
|
|
307
|
+
reasoningLevel: text("reasoning_level").$type(),
|
|
308
|
+
status: text("status").$type().notNull(),
|
|
309
|
+
mailboxStatus: text("mailbox_status").$type().notNull(),
|
|
310
|
+
result: text("result"),
|
|
311
|
+
errorMessage: text("error_message"),
|
|
312
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
313
|
+
updatedAt: timestamptz("updated_at").notNull(),
|
|
314
|
+
terminalAt: timestamptz("terminal_at")
|
|
315
|
+
}, (table) => [index("junior_agent_invocations_child_idx").on(table.childConversationId), index("junior_agent_invocations_mailbox_idx").on(table.mailboxStatus, table.createdAt)]);
|
|
316
|
+
//#endregion
|
|
317
|
+
//#region src/db/schema/location-configurations.ts
|
|
318
|
+
/** Durable user configuration entries scoped to provider Locations. */
|
|
319
|
+
const juniorLocationConfigurations = pgTable("junior_location_configurations", {
|
|
320
|
+
locationId: text("location_id").notNull().references(() => juniorDestinations.id, { onDelete: "cascade" }),
|
|
321
|
+
key: text("key").notNull(),
|
|
322
|
+
value: text("value").notNull(),
|
|
323
|
+
updatedAt: timestamptz("updated_at").notNull(),
|
|
324
|
+
updatedBy: text("updated_by"),
|
|
325
|
+
source: text("source"),
|
|
326
|
+
expiresAt: text("expires_at")
|
|
327
|
+
}, (table) => [primaryKey({ columns: [table.locationId, table.key] })]);
|
|
328
|
+
//#endregion
|
|
329
|
+
//#region src/db/schema/event-tasks.ts
|
|
330
|
+
const juniorEventTasks = pgTable("junior_event_tasks", {
|
|
331
|
+
id: text("id").primaryKey(),
|
|
332
|
+
teamId: text("team_id").notNull(),
|
|
333
|
+
namespace: text("namespace").notNull(),
|
|
334
|
+
identifier: text("identifier").notNull(),
|
|
335
|
+
createdAtMs: bigint("created_at_ms", { mode: "number" }).notNull(),
|
|
336
|
+
/** Retained row status. Deleted tasks keep history but stop matching. */
|
|
337
|
+
status: text("status").$type().notNull().default("active"),
|
|
338
|
+
/** Short display title generated from the task instruction. */
|
|
339
|
+
title: text("title"),
|
|
340
|
+
task: jsonb("task_json").$type().notNull()
|
|
341
|
+
}, (table) => [index("junior_event_tasks_team_idx").on(table.teamId, table.createdAtMs, table.id).where(sql`${table.status} <> 'deleted'`), index("junior_event_tasks_match_idx").on(table.namespace, table.identifier, table.createdAtMs, table.id).where(sql`${table.status} <> 'deleted'`)]);
|
|
342
|
+
//#endregion
|
|
343
|
+
//#region src/db/schema/stats.ts
|
|
344
|
+
/**
|
|
345
|
+
* Daily named counters used by Junior and loaded plugins.
|
|
346
|
+
* TODO: store hour keys when dashboard 24h workspace usage needs hourly bars.
|
|
347
|
+
* `date` is a Postgres date column, so counters stay day-bucketed today.
|
|
348
|
+
*/
|
|
349
|
+
const juniorStats = pgTable("junior_stats", {
|
|
350
|
+
date: date("date", { mode: "string" }).notNull(),
|
|
351
|
+
namespace: text("namespace").notNull(),
|
|
352
|
+
metric: text("metric").notNull(),
|
|
353
|
+
name: text("name").notNull(),
|
|
354
|
+
count: integer("count").notNull().default(0)
|
|
355
|
+
}, (table) => [primaryKey({
|
|
356
|
+
name: "junior_stats_date_namespace_metric_name_pk",
|
|
357
|
+
columns: [
|
|
358
|
+
table.date,
|
|
359
|
+
table.namespace,
|
|
360
|
+
table.metric,
|
|
361
|
+
table.name
|
|
362
|
+
]
|
|
363
|
+
})]);
|
|
364
|
+
//#endregion
|
|
365
|
+
//#region src/db/schema/task-executions.ts
|
|
366
|
+
/** One terminal task execution linked to its durable conversation when present. */
|
|
367
|
+
const juniorTaskExecutions = pgTable("junior_task_executions", {
|
|
368
|
+
executionId: text("execution_id").notNull(),
|
|
369
|
+
kind: text("kind").notNull(),
|
|
370
|
+
namespace: text("namespace").notNull(),
|
|
371
|
+
taskId: text("task_id").notNull(),
|
|
372
|
+
conversationId: text("conversation_id"),
|
|
373
|
+
executedAtMs: bigint("executed_at_ms", { mode: "number" }).notNull(),
|
|
374
|
+
status: text("status").$type().notNull()
|
|
375
|
+
}, (table) => [
|
|
376
|
+
check("junior_task_executions_kind_check", sql`${table.kind} in ('scheduled', 'event')`),
|
|
377
|
+
check("junior_task_executions_status_check", sql`${table.status} in ('blocked', 'completed', 'failed')`),
|
|
378
|
+
primaryKey({
|
|
379
|
+
name: "junior_task_executions_kind_namespace_execution_id_pk",
|
|
380
|
+
columns: [
|
|
381
|
+
table.kind,
|
|
382
|
+
table.namespace,
|
|
383
|
+
table.executionId
|
|
384
|
+
]
|
|
385
|
+
}),
|
|
386
|
+
foreignKey({
|
|
387
|
+
name: "junior_task_executions_conversation_id_junior_conversations_conversation_id_fk",
|
|
388
|
+
columns: [table.conversationId],
|
|
389
|
+
foreignColumns: [juniorConversations.conversationId]
|
|
390
|
+
}),
|
|
391
|
+
index("junior_task_executions_task_time_idx").on(table.kind, table.namespace, table.taskId, table.executedAtMs),
|
|
392
|
+
index("junior_task_executions_time_kind_idx").on(table.executedAtMs, table.kind),
|
|
393
|
+
index("junior_task_executions_conversation_time_idx").on(table.conversationId, table.executedAtMs)
|
|
394
|
+
]);
|
|
395
|
+
//#endregion
|
|
396
|
+
//#region src/db/schema/scheduled-tasks.ts
|
|
397
|
+
const juniorSchedulerTasks = pgTable("junior_scheduler_tasks", {
|
|
398
|
+
id: text("id").primaryKey(),
|
|
399
|
+
teamId: text("team_id").notNull(),
|
|
400
|
+
creatorSlackUserId: text("creator_slack_user_id"),
|
|
401
|
+
creatorIdentityId: text("creator_identity_id"),
|
|
402
|
+
status: text("status").notNull(),
|
|
403
|
+
nextRunAtMs: bigint("next_run_at_ms", { mode: "number" }),
|
|
404
|
+
runNowAtMs: bigint("run_now_at_ms", { mode: "number" }),
|
|
405
|
+
createdAtMs: bigint("created_at_ms", { mode: "number" }).notNull(),
|
|
406
|
+
/** Short display title generated from the task instruction. */
|
|
407
|
+
title: text("title"),
|
|
408
|
+
record: jsonb("record").$type().notNull()
|
|
409
|
+
}, (table) => [
|
|
410
|
+
index("junior_scheduler_tasks_creator_idx").on(table.teamId, table.creatorSlackUserId, table.createdAtMs, table.id).where(sql`${table.status} <> 'deleted'`),
|
|
411
|
+
index("junior_scheduler_tasks_creator_identity_idx").on(table.creatorIdentityId, table.createdAtMs, table.id).where(sql`${table.status} <> 'deleted' AND ${table.creatorIdentityId} IS NOT NULL`),
|
|
412
|
+
index("junior_scheduler_tasks_team_status_idx").on(table.teamId, table.createdAtMs, table.id).where(sql`${table.status} <> 'deleted'`),
|
|
413
|
+
index("junior_scheduler_tasks_run_now_due_idx").on(table.runNowAtMs, table.createdAtMs, table.id).where(sql`${table.status} = 'active' AND ${table.runNowAtMs} IS NOT NULL`),
|
|
414
|
+
index("junior_scheduler_tasks_next_run_due_idx").on(table.nextRunAtMs, table.createdAtMs, table.id).where(sql`${table.status} = 'active' AND ${table.nextRunAtMs} IS NOT NULL`)
|
|
415
|
+
]);
|
|
416
|
+
const juniorSchedulerRuns = pgTable("junior_scheduler_runs", {
|
|
417
|
+
id: text("id").primaryKey(),
|
|
418
|
+
taskId: text("task_id").notNull(),
|
|
419
|
+
status: text("status").notNull(),
|
|
420
|
+
scheduledForMs: bigint("scheduled_for_ms", { mode: "number" }).notNull(),
|
|
421
|
+
record: jsonb("record").$type().notNull()
|
|
422
|
+
}, (table) => [index("junior_scheduler_runs_task_status_idx").on(table.taskId, table.status, table.scheduledForMs), index("junior_scheduler_runs_status_idx").on(table.status, table.scheduledForMs)]);
|
|
423
|
+
//#endregion
|
|
424
|
+
//#region src/db/schema/workspaces.ts
|
|
425
|
+
/** Named recipe used to prepare a reusable Sandbox. */
|
|
426
|
+
const juniorWorkspaces = pgTable("junior_workspaces", {
|
|
427
|
+
id: text("id").primaryKey(),
|
|
428
|
+
name: text("name").notNull(),
|
|
429
|
+
setupScript: text("setup_script").notNull().default(""),
|
|
430
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
431
|
+
updatedAt: timestamptz("updated_at").notNull()
|
|
432
|
+
}, (table) => [uniqueIndex("junior_workspaces_name_idx").on(table.name)]);
|
|
433
|
+
/** Repository included in one Workspace recipe. */
|
|
434
|
+
const juniorWorkspaceRepos = pgTable("junior_workspace_repos", {
|
|
435
|
+
workspaceId: text("workspace_id").notNull().references(() => juniorWorkspaces.id, { onDelete: "cascade" }),
|
|
436
|
+
provider: text("provider").notNull(),
|
|
437
|
+
repo: text("repo").notNull()
|
|
438
|
+
}, (table) => [primaryKey({ columns: [
|
|
439
|
+
table.workspaceId,
|
|
440
|
+
table.provider,
|
|
441
|
+
table.repo
|
|
442
|
+
] })]);
|
|
443
|
+
//#endregion
|
|
444
|
+
//#region src/db/schema/snapshots.ts
|
|
445
|
+
/**
|
|
446
|
+
* Sandbox snapshot build and ready artifact for one Workspace recipe.
|
|
447
|
+
* A ready row keeps its builder owner until the snapshot is discarded.
|
|
448
|
+
*/
|
|
449
|
+
const juniorSnapshots = pgTable("junior_snapshots", {
|
|
450
|
+
id: text("id").primaryKey(),
|
|
451
|
+
workspaceId: text("workspace_id").notNull().references(() => juniorWorkspaces.id, { onDelete: "cascade" }),
|
|
452
|
+
profileHash: text("profile_hash").notNull(),
|
|
453
|
+
status: text("status").$type().notNull(),
|
|
454
|
+
snapshotId: text("snapshot_id"),
|
|
455
|
+
buildDurationMs: integer("build_duration_ms"),
|
|
456
|
+
sizeBytes: bigint("size_bytes", { mode: "number" }),
|
|
457
|
+
generatedAt: timestamptz("generated_at"),
|
|
458
|
+
buildStartedAt: timestamptz("build_started_at"),
|
|
459
|
+
buildPhase: text("build_phase").$type(),
|
|
460
|
+
buildSandboxName: text("build_sandbox_name"),
|
|
461
|
+
buildCommandId: text("build_command_id"),
|
|
462
|
+
buildError: text("build_error"),
|
|
463
|
+
createdAt: timestamptz("created_at").notNull(),
|
|
464
|
+
updatedAt: timestamptz("updated_at").notNull()
|
|
465
|
+
}, (table) => [
|
|
466
|
+
check("junior_snapshots_status_check", sql`${table.status} in ('building', 'failed', 'ready')`),
|
|
467
|
+
check("junior_snapshots_build_phase_check", sql`${table.buildPhase} is null or ${table.buildPhase} in ('created', 'dependencies_installed', 'repositories_prepared')`),
|
|
468
|
+
check("junior_snapshots_ready_fields_check", sql`${table.status} <> 'ready' or (${table.snapshotId} is not null and ${table.buildDurationMs} is not null and ${table.generatedAt} is not null)`),
|
|
469
|
+
check("junior_snapshots_build_fields_check", sql`${table.status} = 'ready' or (${table.buildStartedAt} is not null and ${table.buildPhase} is not null)`),
|
|
470
|
+
check("junior_snapshots_build_duration_check", sql`${table.buildDurationMs} is null or ${table.buildDurationMs} >= 0`),
|
|
471
|
+
check("junior_snapshots_size_bytes_check", sql`${table.sizeBytes} is null or ${table.sizeBytes} >= 0`),
|
|
472
|
+
uniqueIndex("junior_snapshots_snapshot_id_uidx").on(table.snapshotId),
|
|
473
|
+
index("junior_snapshots_workspace_idx").on(table.workspaceId),
|
|
474
|
+
index("junior_snapshots_workspace_profile_status_idx").on(table.workspaceId, table.profileHash, table.status),
|
|
475
|
+
uniqueIndex("junior_snapshots_active_build_uidx").on(table.workspaceId, table.profileHash).where(sql`${table.status} = 'building'`),
|
|
476
|
+
index("junior_snapshots_workspace_status_idx").on(table.workspaceId, table.status)
|
|
477
|
+
]);
|
|
478
|
+
//#endregion
|
|
479
|
+
//#region src/db/schema.ts
|
|
480
|
+
const juniorSqlSchema = {
|
|
481
|
+
juniorArtifacts,
|
|
482
|
+
juniorAttachments,
|
|
483
|
+
juniorCodeChanges,
|
|
484
|
+
juniorCodeRepositories,
|
|
485
|
+
juniorConversationAnnotations,
|
|
486
|
+
juniorApiTokens,
|
|
487
|
+
juniorAgentBindings,
|
|
488
|
+
juniorAgentInvocations,
|
|
489
|
+
juniorConversationEvents,
|
|
490
|
+
juniorConversationBindings,
|
|
491
|
+
juniorConversationParticipants,
|
|
492
|
+
juniorConversations,
|
|
493
|
+
juniorLocationConfigurations,
|
|
494
|
+
juniorDestinations,
|
|
495
|
+
juniorEventTasks,
|
|
496
|
+
juniorIdentities,
|
|
497
|
+
juniorSnapshots,
|
|
498
|
+
juniorStats,
|
|
499
|
+
juniorTaskExecutions,
|
|
500
|
+
juniorSchedulerRuns,
|
|
501
|
+
juniorSchedulerTasks,
|
|
502
|
+
juniorUsers,
|
|
503
|
+
juniorWorkspaceRepos,
|
|
504
|
+
juniorWorkspaces
|
|
505
|
+
};
|
|
506
|
+
//#endregion
|
|
507
|
+
//#region src/db/neon.ts
|
|
508
|
+
var NeonExecutor = class {
|
|
509
|
+
pool;
|
|
510
|
+
transactionClient = new AsyncLocalStorage();
|
|
511
|
+
savepointId = 0;
|
|
512
|
+
constructor(pool) {
|
|
513
|
+
this.pool = pool;
|
|
514
|
+
}
|
|
515
|
+
db() {
|
|
516
|
+
return drizzle(this.queryClient(), { schema: juniorSqlSchema });
|
|
517
|
+
}
|
|
518
|
+
async execute(statement, params = []) {
|
|
519
|
+
await this.queryClient().query(statement, [...params]);
|
|
520
|
+
}
|
|
521
|
+
async query(statement, params = []) {
|
|
522
|
+
return (await this.queryClient().query(statement, [...params])).rows;
|
|
523
|
+
}
|
|
524
|
+
async migrate(config) {
|
|
525
|
+
await migrate(drizzle(this.queryClient(), { schema: juniorSqlSchema }), config);
|
|
526
|
+
}
|
|
527
|
+
async transaction(callback) {
|
|
528
|
+
const existingClient = this.transactionClient.getStore();
|
|
529
|
+
if (existingClient) {
|
|
530
|
+
const savepoint = `junior_savepoint_${++this.savepointId}`;
|
|
531
|
+
await existingClient.query(`SAVEPOINT ${savepoint}`);
|
|
532
|
+
try {
|
|
533
|
+
const result = await callback();
|
|
534
|
+
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
535
|
+
return result;
|
|
536
|
+
} catch (error) {
|
|
537
|
+
await existingClient.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
538
|
+
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
539
|
+
throw error;
|
|
540
|
+
}
|
|
541
|
+
}
|
|
542
|
+
const client = await this.pool.connect();
|
|
543
|
+
try {
|
|
544
|
+
await client.query("BEGIN");
|
|
545
|
+
const result = await this.transactionClient.run(client, callback);
|
|
546
|
+
await client.query("COMMIT");
|
|
547
|
+
return result;
|
|
548
|
+
} catch (error) {
|
|
549
|
+
await client.query("ROLLBACK");
|
|
550
|
+
throw error;
|
|
551
|
+
} finally {
|
|
552
|
+
client.release();
|
|
553
|
+
}
|
|
554
|
+
}
|
|
555
|
+
async withLock(lockName, callback) {
|
|
556
|
+
if (!lockName) throw new Error("SQL lock name is required");
|
|
557
|
+
const existingClient = this.transactionClient.getStore();
|
|
558
|
+
if (existingClient) {
|
|
559
|
+
await existingClient.query("SELECT pg_advisory_xact_lock(hashtext($1))", [lockName]);
|
|
560
|
+
return await callback();
|
|
561
|
+
}
|
|
562
|
+
const client = await this.pool.connect();
|
|
563
|
+
try {
|
|
564
|
+
await client.query("BEGIN");
|
|
565
|
+
return await this.transactionClient.run(client, async () => {
|
|
566
|
+
try {
|
|
567
|
+
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [lockName]);
|
|
568
|
+
const result = await callback();
|
|
569
|
+
await client.query("COMMIT");
|
|
570
|
+
return result;
|
|
571
|
+
} catch (error) {
|
|
572
|
+
await client.query("ROLLBACK");
|
|
573
|
+
throw error;
|
|
574
|
+
}
|
|
575
|
+
});
|
|
576
|
+
} finally {
|
|
577
|
+
client.release();
|
|
578
|
+
}
|
|
579
|
+
}
|
|
580
|
+
async withMigrationLock(migrationTable, callback) {
|
|
581
|
+
const client = await this.pool.connect();
|
|
582
|
+
const lockName = `junior:migrate:${migrationTable}`;
|
|
583
|
+
try {
|
|
584
|
+
await client.query("SELECT pg_advisory_lock(hashtext($1))", [lockName]);
|
|
585
|
+
return await callback();
|
|
586
|
+
} finally {
|
|
587
|
+
client.release(true);
|
|
588
|
+
}
|
|
589
|
+
}
|
|
590
|
+
async close() {
|
|
591
|
+
await this.pool.end();
|
|
592
|
+
}
|
|
593
|
+
queryClient() {
|
|
594
|
+
return this.transactionClient.getStore() ?? this.pool;
|
|
595
|
+
}
|
|
596
|
+
};
|
|
597
|
+
/** Create the shared Neon-backed Junior SQL executor. */
|
|
598
|
+
function createNeonJuniorSqlExecutor(args) {
|
|
599
|
+
return new NeonExecutor(new Pool({
|
|
600
|
+
connectionString: args.connectionString,
|
|
601
|
+
max: 3,
|
|
602
|
+
statement_timeout: args.statementTimeoutMs
|
|
603
|
+
}));
|
|
604
|
+
}
|
|
605
|
+
//#endregion
|
|
606
|
+
//#region src/db/postgres.ts
|
|
607
|
+
const { Pool: Pool$1 } = pg;
|
|
608
|
+
var PostgresExecutor = class {
|
|
609
|
+
pool;
|
|
610
|
+
transactionClient = new AsyncLocalStorage();
|
|
611
|
+
savepointId = 0;
|
|
612
|
+
constructor(pool) {
|
|
613
|
+
this.pool = pool;
|
|
614
|
+
}
|
|
615
|
+
db() {
|
|
616
|
+
return drizzle$1(this.queryClient(), { schema: juniorSqlSchema });
|
|
617
|
+
}
|
|
618
|
+
async execute(statement, params = []) {
|
|
619
|
+
await this.queryClient().query(statement, [...params]);
|
|
620
|
+
}
|
|
621
|
+
async query(statement, params = []) {
|
|
622
|
+
return (await this.queryClient().query(statement, [...params])).rows;
|
|
623
|
+
}
|
|
624
|
+
async migrate(config) {
|
|
625
|
+
await migrate$1(drizzle$1(this.queryClient(), { schema: juniorSqlSchema }), config);
|
|
626
|
+
}
|
|
627
|
+
async transaction(callback) {
|
|
628
|
+
const existingClient = this.transactionClient.getStore();
|
|
629
|
+
if (existingClient) {
|
|
630
|
+
const savepoint = `junior_savepoint_${++this.savepointId}`;
|
|
631
|
+
await existingClient.query(`SAVEPOINT ${savepoint}`);
|
|
632
|
+
try {
|
|
633
|
+
const result = await callback();
|
|
634
|
+
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
635
|
+
return result;
|
|
636
|
+
} catch (error) {
|
|
637
|
+
await existingClient.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
638
|
+
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
639
|
+
throw error;
|
|
640
|
+
}
|
|
641
|
+
}
|
|
642
|
+
const client = await this.pool.connect();
|
|
643
|
+
try {
|
|
644
|
+
await client.query("BEGIN");
|
|
645
|
+
const result = await this.transactionClient.run(client, callback);
|
|
646
|
+
await client.query("COMMIT");
|
|
647
|
+
return result;
|
|
648
|
+
} catch (error) {
|
|
649
|
+
await client.query("ROLLBACK");
|
|
650
|
+
throw error;
|
|
651
|
+
} finally {
|
|
652
|
+
client.release();
|
|
653
|
+
}
|
|
654
|
+
}
|
|
655
|
+
async withLock(lockName, callback) {
|
|
656
|
+
if (!lockName) throw new Error("SQL lock name is required");
|
|
657
|
+
const existingClient = this.transactionClient.getStore();
|
|
658
|
+
if (existingClient) {
|
|
659
|
+
await existingClient.query("SELECT pg_advisory_xact_lock(hashtext($1))", [lockName]);
|
|
660
|
+
return await callback();
|
|
661
|
+
}
|
|
662
|
+
const client = await this.pool.connect();
|
|
663
|
+
try {
|
|
664
|
+
await client.query("BEGIN");
|
|
665
|
+
return await this.transactionClient.run(client, async () => {
|
|
666
|
+
try {
|
|
667
|
+
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [lockName]);
|
|
668
|
+
const result = await callback();
|
|
669
|
+
await client.query("COMMIT");
|
|
670
|
+
return result;
|
|
671
|
+
} catch (error) {
|
|
672
|
+
await client.query("ROLLBACK");
|
|
673
|
+
throw error;
|
|
674
|
+
}
|
|
675
|
+
});
|
|
676
|
+
} finally {
|
|
677
|
+
client.release();
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
async withMigrationLock(migrationTable, callback) {
|
|
681
|
+
const client = await this.pool.connect();
|
|
682
|
+
const lockName = `junior:migrate:${migrationTable}`;
|
|
683
|
+
try {
|
|
684
|
+
await client.query("SELECT pg_advisory_lock(hashtext($1))", [lockName]);
|
|
685
|
+
return await callback();
|
|
686
|
+
} finally {
|
|
687
|
+
client.release(true);
|
|
688
|
+
}
|
|
689
|
+
}
|
|
690
|
+
async close() {
|
|
691
|
+
await this.pool.end();
|
|
692
|
+
}
|
|
693
|
+
queryClient() {
|
|
694
|
+
return this.transactionClient.getStore() ?? this.pool;
|
|
695
|
+
}
|
|
696
|
+
};
|
|
697
|
+
/** Create the shared Node Postgres-backed Junior SQL executor. */
|
|
698
|
+
function createPostgresJuniorSqlExecutor(args) {
|
|
699
|
+
return new PostgresExecutor(new Pool$1({
|
|
700
|
+
application_name: args.applicationName,
|
|
701
|
+
connectionString: args.connectionString,
|
|
702
|
+
max: 3,
|
|
703
|
+
statement_timeout: args.statementTimeoutMs
|
|
704
|
+
}));
|
|
705
|
+
}
|
|
706
|
+
//#endregion
|
|
707
|
+
//#region src/db/executor.ts
|
|
708
|
+
/** Create the SQL executor appropriate for the configured database URL. */
|
|
709
|
+
function createJuniorSqlExecutor(args) {
|
|
710
|
+
const statementTimeoutMs = args.statementTimeoutMs ?? 3e4;
|
|
711
|
+
if (args.driver === "postgres") return createPostgresJuniorSqlExecutor({
|
|
712
|
+
connectionString: args.connectionString,
|
|
713
|
+
statementTimeoutMs
|
|
714
|
+
});
|
|
715
|
+
return createNeonJuniorSqlExecutor({
|
|
716
|
+
connectionString: args.connectionString,
|
|
717
|
+
statementTimeoutMs
|
|
718
|
+
});
|
|
719
|
+
}
|
|
720
|
+
//#endregion
|
|
721
|
+
export { juniorConversations as C, juniorArtifacts as E, conversationReadColumns as S, juniorUsers as T, juniorApiTokens as _, juniorSchedulerRuns as a, juniorCodeRepositories as b, juniorStats as c, AGENT_INVOCATION_MAILBOX_STATUSES as d, juniorAgentBindings as f, juniorConversationEvents as g, juniorConversationBindings as h, juniorWorkspaces as i, juniorEventTasks as l, juniorConversationParticipants as m, juniorSnapshots as n, juniorSchedulerTasks as o, juniorAgentInvocations as p, juniorWorkspaceRepos as r, juniorTaskExecutions as s, createJuniorSqlExecutor as t, juniorLocationConfigurations as u, juniorConversationAnnotations as v, juniorIdentities as w, juniorAttachments as x, juniorCodeChanges as y };
|