@sentry/junior 0.107.1 → 0.109.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-hooks-ICPIJAFY.js → agent-hooks-FHHVLNPA.js} +12 -12
- package/dist/api/conversations/events.d.ts +1 -1
- package/dist/api/conversations/list.d.ts +1 -0
- package/dist/api/conversations/schema.d.ts +57 -6
- package/dist/api/schema.js +1 -1
- package/dist/api.js +116 -27
- package/dist/app.d.ts +1 -0
- package/dist/app.js +1741 -458
- package/dist/{catalog-runtime-FOFNPR3P.js → catalog-runtime-DMGJSLV2.js} +6 -4
- package/dist/chat/conversations/history.d.ts +16 -5
- package/dist/chat/conversations/message-projection.d.ts +3 -5
- package/dist/chat/conversations/sql/store.d.ts +0 -7
- package/dist/chat/log-context.d.ts +40 -0
- package/dist/chat/logging.d.ts +3 -26
- package/dist/chat/resource-events/store.d.ts +6 -0
- package/dist/chat/runtime/slack-resume.d.ts +2 -2
- package/dist/chat/runtime/slack-runtime.d.ts +3 -0
- package/dist/chat/services/turn-session-record.d.ts +0 -2
- package/dist/chat/slack/reply.d.ts +7 -19
- package/dist/chat/state/conversation.d.ts +1 -0
- package/dist/chat/task-execution/slack-work.d.ts +237 -10
- package/dist/chat/tool-support/turn-deadline-result.d.ts +3 -0
- package/dist/chunk-3SXUV423.js +10 -0
- package/dist/{chunk-YFQ7CQDE.js → chunk-72OMGPDS.js} +1017 -39
- package/dist/{chunk-2XXEKR44.js → chunk-7Q6WCISF.js} +1 -1
- package/dist/{chunk-NVOTGWYX.js → chunk-FENLIFJD.js} +97 -601
- package/dist/{chunk-IGHMVDWI.js → chunk-FWJRXN4F.js} +3 -3
- package/dist/{chunk-PUAMO4PI.js → chunk-HHVY4SMP.js} +41 -7
- package/dist/{chunk-SPUAJVVH.js → chunk-HO5NT6OE.js} +5 -7
- package/dist/{chunk-O24R4DCK.js → chunk-ISMWX44P.js} +93 -55
- package/dist/{chunk-7FBGKXPE.js → chunk-IVVGFRQQ.js} +5 -0
- package/dist/{chunk-EDLNHZH3.js → chunk-IXKSQGIO.js} +226 -191
- package/dist/{chunk-SS67LUOK.js → chunk-JNAVF45E.js} +6 -7
- package/dist/{chunk-DY7TRYB5.js → chunk-MGUMR35T.js} +1 -1
- package/dist/{chunk-CQ7KSO2B.js → chunk-MXW4GL53.js} +11 -15
- package/dist/{chunk-RT5BUHR5.js → chunk-O3JMSZLI.js} +1 -1
- package/dist/chunk-OCD3OZRK.js +125 -0
- package/dist/{chunk-B2Z2H66D.js → chunk-OUHNWH46.js} +60 -5
- package/dist/{chunk-VIXFG2VC.js → chunk-PLB7MRCQ.js} +1 -2
- package/dist/{chunk-RMVOAJRL.js → chunk-QY636HZU.js} +114 -12
- package/dist/{chunk-VH6KWKG2.js → chunk-RGX4V75M.js} +3 -3
- package/dist/{chunk-B7PUBQQM.js → chunk-SYAQIR5Z.js} +1 -1
- package/dist/chunk-TMBRFULF.js +471 -0
- package/dist/{chunk-YIPD3L6L.js → chunk-TT6GMXNA.js} +8 -10
- package/dist/{chunk-YT72TOEK.js → chunk-WHMOBKT7.js} +2 -2
- package/dist/cli/chat.js +23 -23
- package/dist/cli/check.js +8 -6
- package/dist/cli/plugins.js +16 -16
- package/dist/cli/snapshot-warmup.js +10 -9
- package/dist/cli/upgrade.js +314 -3505
- package/dist/db/db.d.ts +1 -1
- package/dist/{db-DIGO4TGW.js → db-V3NU72O2.js} +8 -6
- package/dist/instrumentation.js +3 -2
- package/dist/nitro.js +5 -4
- package/dist/{runner-ACR2HAIC.js → runner-JYBCQBLK.js} +17 -20
- package/dist/{skills-ITNHBARB.js → skills-U6MDAST7.js} +7 -5
- package/dist/{validation-AGQ46ZGV.js → validation-72N3JVRU.js} +7 -5
- package/dist/version.d.ts +2 -0
- package/dist/version.js +7 -0
- package/migrations/0006_drop_legacy_conversation_messages.sql +1 -0
- package/migrations/README.md +12 -9
- package/migrations/meta/0006_snapshot.json +948 -0
- package/migrations/meta/_journal.json +7 -0
- package/package.json +11 -7
- package/dist/chunk-4YF7Z6IA.js +0 -1061
- package/dist/chunk-AUUOHQAT.js +0 -115
- package/dist/chunk-G3E7SCME.js +0 -28
- package/dist/chunk-YNP2ATQX.js +0 -1282
|
@@ -1,239 +1,32 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createJuniorSqlExecutor,
|
|
3
|
+
juniorConversationEvents,
|
|
4
|
+
juniorConversations,
|
|
5
|
+
juniorIdentities,
|
|
6
|
+
juniorUsers
|
|
7
|
+
} from "./chunk-TMBRFULF.js";
|
|
1
8
|
import {
|
|
2
9
|
getChatConfig,
|
|
3
10
|
modelProfileSchema
|
|
4
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-JNAVF45E.js";
|
|
5
12
|
import {
|
|
6
|
-
juniorDestinations
|
|
7
|
-
timestamptz
|
|
13
|
+
juniorDestinations
|
|
8
14
|
} from "./chunk-VFUK3X5B.js";
|
|
9
15
|
import {
|
|
10
16
|
parseDestination,
|
|
11
17
|
sameDestination
|
|
12
|
-
} from "./chunk-
|
|
18
|
+
} from "./chunk-SYAQIR5Z.js";
|
|
13
19
|
import {
|
|
14
20
|
normalizeIdentityEmail
|
|
15
|
-
} from "./chunk-
|
|
21
|
+
} from "./chunk-ISMWX44P.js";
|
|
16
22
|
|
|
17
23
|
// src/chat/conversations/sql/store.ts
|
|
18
24
|
import { randomUUID as randomUUID2 } from "crypto";
|
|
19
|
-
import { and as and2, asc, desc, eq as eq2, isNull, sql as
|
|
25
|
+
import { and as and2, asc, desc, eq as eq2, isNull, sql as sql2 } from "drizzle-orm";
|
|
20
26
|
|
|
21
27
|
// src/chat/identities/sql.ts
|
|
22
28
|
import { randomUUID } from "crypto";
|
|
23
|
-
import { and, eq, sql
|
|
24
|
-
|
|
25
|
-
// src/db/schema/conversation-events.ts
|
|
26
|
-
import {
|
|
27
|
-
foreignKey,
|
|
28
|
-
index as index3,
|
|
29
|
-
integer as integer2,
|
|
30
|
-
jsonb as jsonb3,
|
|
31
|
-
pgTable as pgTable4,
|
|
32
|
-
primaryKey,
|
|
33
|
-
text as text4,
|
|
34
|
-
uniqueIndex as uniqueIndex3
|
|
35
|
-
} from "drizzle-orm/pg-core";
|
|
36
|
-
import { sql as sql3 } from "drizzle-orm";
|
|
37
|
-
|
|
38
|
-
// src/db/schema/conversations.ts
|
|
39
|
-
import { sql as sql2 } from "drizzle-orm";
|
|
40
|
-
import {
|
|
41
|
-
index as index2,
|
|
42
|
-
integer,
|
|
43
|
-
jsonb as jsonb2,
|
|
44
|
-
pgTable as pgTable3,
|
|
45
|
-
text as text3
|
|
46
|
-
} from "drizzle-orm/pg-core";
|
|
47
|
-
|
|
48
|
-
// src/db/schema/identities.ts
|
|
49
|
-
import { sql } from "drizzle-orm";
|
|
50
|
-
import {
|
|
51
|
-
boolean,
|
|
52
|
-
index,
|
|
53
|
-
jsonb,
|
|
54
|
-
pgTable as pgTable2,
|
|
55
|
-
text as text2,
|
|
56
|
-
uniqueIndex as uniqueIndex2
|
|
57
|
-
} from "drizzle-orm/pg-core";
|
|
58
|
-
|
|
59
|
-
// src/db/schema/users.ts
|
|
60
|
-
import { text, pgTable, uniqueIndex } from "drizzle-orm/pg-core";
|
|
61
|
-
var juniorUsers = pgTable(
|
|
62
|
-
"junior_users",
|
|
63
|
-
{
|
|
64
|
-
id: text("id").primaryKey(),
|
|
65
|
-
primaryEmail: text("primary_email").notNull(),
|
|
66
|
-
primaryEmailNormalized: text("primary_email_normalized").notNull(),
|
|
67
|
-
displayName: text("display_name"),
|
|
68
|
-
createdAt: timestamptz("created_at").notNull(),
|
|
69
|
-
updatedAt: timestamptz("updated_at").notNull()
|
|
70
|
-
},
|
|
71
|
-
(table) => [
|
|
72
|
-
uniqueIndex("junior_users_primary_email_normalized_uidx").on(
|
|
73
|
-
table.primaryEmailNormalized
|
|
74
|
-
)
|
|
75
|
-
]
|
|
76
|
-
);
|
|
77
|
-
|
|
78
|
-
// src/db/schema/identities.ts
|
|
79
|
-
var juniorIdentities = pgTable2(
|
|
80
|
-
"junior_identities",
|
|
81
|
-
{
|
|
82
|
-
id: text2("id").primaryKey(),
|
|
83
|
-
kind: text2("kind").$type().notNull(),
|
|
84
|
-
provider: text2("provider").notNull(),
|
|
85
|
-
providerTenantId: text2("provider_tenant_id").notNull().default(""),
|
|
86
|
-
providerSubjectId: text2("provider_subject_id").notNull(),
|
|
87
|
-
displayName: text2("display_name"),
|
|
88
|
-
handle: text2("handle"),
|
|
89
|
-
email: text2("email"),
|
|
90
|
-
avatarUrl: text2("avatar_url"),
|
|
91
|
-
metadata: jsonb("metadata_json"),
|
|
92
|
-
createdAt: timestamptz("created_at").notNull(),
|
|
93
|
-
updatedAt: timestamptz("updated_at").notNull(),
|
|
94
|
-
userId: text2("user_id").references(() => juniorUsers.id),
|
|
95
|
-
emailNormalized: text2("email_normalized"),
|
|
96
|
-
emailVerified: boolean("email_verified").notNull().default(false)
|
|
97
|
-
},
|
|
98
|
-
(table) => [
|
|
99
|
-
uniqueIndex2("junior_identities_provider_subject_uidx").on(
|
|
100
|
-
table.provider,
|
|
101
|
-
table.providerTenantId,
|
|
102
|
-
table.providerSubjectId
|
|
103
|
-
),
|
|
104
|
-
index("junior_identities_user_idx").on(table.userId),
|
|
105
|
-
index("junior_identities_verified_email_idx").on(table.emailNormalized).where(
|
|
106
|
-
sql`${table.emailVerified} = true AND ${table.emailNormalized} IS NOT NULL`
|
|
107
|
-
),
|
|
108
|
-
index("junior_identities_kind_provider_idx").on(table.kind, table.provider)
|
|
109
|
-
]
|
|
110
|
-
);
|
|
111
|
-
|
|
112
|
-
// src/db/schema/conversations.ts
|
|
113
|
-
var juniorConversations = pgTable3(
|
|
114
|
-
"junior_conversations",
|
|
115
|
-
{
|
|
116
|
-
conversationId: text3("conversation_id").primaryKey(),
|
|
117
|
-
schemaVersion: integer("schema_version").notNull().default(1),
|
|
118
|
-
source: text3("source").$type(),
|
|
119
|
-
originType: text3("origin_type"),
|
|
120
|
-
originId: text3("origin_id"),
|
|
121
|
-
originRunId: text3("origin_run_id"),
|
|
122
|
-
destinationId: text3("destination_id").references(
|
|
123
|
-
() => juniorDestinations.id
|
|
124
|
-
),
|
|
125
|
-
destination: jsonb2("destination_json").$type(),
|
|
126
|
-
actorIdentityId: text3("actor_identity_id").references(
|
|
127
|
-
() => juniorIdentities.id
|
|
128
|
-
),
|
|
129
|
-
creatorIdentityId: text3("creator_identity_id").references(
|
|
130
|
-
() => juniorIdentities.id
|
|
131
|
-
),
|
|
132
|
-
credentialSubjectIdentityId: text3(
|
|
133
|
-
"credential_subject_identity_id"
|
|
134
|
-
).references(() => juniorIdentities.id),
|
|
135
|
-
actor: jsonb2("actor_json").$type(),
|
|
136
|
-
channelName: text3("channel_name"),
|
|
137
|
-
title: text3("title"),
|
|
138
|
-
createdAt: timestamptz("created_at").notNull(),
|
|
139
|
-
lastActivityAt: timestamptz("last_activity_at").notNull(),
|
|
140
|
-
updatedAt: timestamptz("updated_at").notNull(),
|
|
141
|
-
executionUpdatedAt: timestamptz("execution_updated_at"),
|
|
142
|
-
executionStatus: text3("execution_status").$type().notNull(),
|
|
143
|
-
runId: text3("run_id"),
|
|
144
|
-
lastCheckpointAt: timestamptz("last_checkpoint_at"),
|
|
145
|
-
lastEnqueuedAt: timestamptz("last_enqueued_at"),
|
|
146
|
-
// Subagent runs are child conversations; top-level listings filter
|
|
147
|
-
// parent_conversation_id IS NULL. Historical advisor children use this too.
|
|
148
|
-
parentConversationId: text3("parent_conversation_id").references(
|
|
149
|
-
() => juniorConversations.conversationId
|
|
150
|
-
),
|
|
151
|
-
transcriptPurgedAt: timestamptz("transcript_purged_at"),
|
|
152
|
-
durationMs: integer("duration_ms").notNull().default(0),
|
|
153
|
-
usage: jsonb2("usage_json").$type(),
|
|
154
|
-
executionDurationMs: integer("execution_duration_ms").notNull().default(0),
|
|
155
|
-
executionUsage: jsonb2("execution_usage_json").$type(),
|
|
156
|
-
metricRunId: text3("metric_run_id"),
|
|
157
|
-
archivedAt: timestamptz("archived_at")
|
|
158
|
-
},
|
|
159
|
-
(table) => [
|
|
160
|
-
index2("junior_conversations_last_activity_idx").on(
|
|
161
|
-
table.lastActivityAt.desc(),
|
|
162
|
-
table.conversationId
|
|
163
|
-
),
|
|
164
|
-
index2("junior_conversations_active_idx").using(
|
|
165
|
-
"btree",
|
|
166
|
-
sql2`coalesce(${table.executionUpdatedAt}, ${table.updatedAt})`,
|
|
167
|
-
table.conversationId
|
|
168
|
-
).where(sql2`${table.executionStatus} <> 'idle'`),
|
|
169
|
-
index2("junior_conversations_destination_activity_idx").on(
|
|
170
|
-
table.destinationId,
|
|
171
|
-
table.lastActivityAt.desc()
|
|
172
|
-
),
|
|
173
|
-
index2("junior_conversations_actor_activity_idx").on(
|
|
174
|
-
table.actorIdentityId,
|
|
175
|
-
table.lastActivityAt.desc()
|
|
176
|
-
),
|
|
177
|
-
index2("junior_conversations_origin_idx").on(
|
|
178
|
-
table.originType,
|
|
179
|
-
table.originId,
|
|
180
|
-
table.lastActivityAt.desc()
|
|
181
|
-
),
|
|
182
|
-
index2("junior_conversations_parent_idx").on(table.parentConversationId)
|
|
183
|
-
]
|
|
184
|
-
);
|
|
185
|
-
|
|
186
|
-
// src/db/schema/conversation-events.ts
|
|
187
|
-
var juniorConversationEvents = pgTable4(
|
|
188
|
-
"junior_conversation_events",
|
|
189
|
-
{
|
|
190
|
-
conversationId: text4("conversation_id").notNull(),
|
|
191
|
-
seq: integer2("seq").notNull(),
|
|
192
|
-
historyVersion: integer2("history_version").notNull(),
|
|
193
|
-
schemaVersion: integer2("schema_version").default(1).notNull(),
|
|
194
|
-
idempotencyKey: text4("idempotency_key"),
|
|
195
|
-
type: text4("type").notNull(),
|
|
196
|
-
payload: jsonb3("payload").$type().notNull(),
|
|
197
|
-
createdAt: timestamptz("created_at").notNull()
|
|
198
|
-
},
|
|
199
|
-
(table) => [
|
|
200
|
-
primaryKey({
|
|
201
|
-
name: "junior_conversation_events_conversation_id_seq_pk",
|
|
202
|
-
columns: [table.conversationId, table.seq]
|
|
203
|
-
}),
|
|
204
|
-
foreignKey({
|
|
205
|
-
name: "junior_conversation_events_conversation_id_junior_conversations_conversation_id_fk",
|
|
206
|
-
columns: [table.conversationId],
|
|
207
|
-
foreignColumns: [juniorConversations.conversationId]
|
|
208
|
-
}),
|
|
209
|
-
index3("junior_conversation_events_history_version_idx").on(
|
|
210
|
-
table.conversationId,
|
|
211
|
-
table.historyVersion,
|
|
212
|
-
table.seq
|
|
213
|
-
),
|
|
214
|
-
index3("junior_conversation_events_type_idx").on(
|
|
215
|
-
table.conversationId,
|
|
216
|
-
table.type,
|
|
217
|
-
table.seq
|
|
218
|
-
),
|
|
219
|
-
index3("junior_conversation_events_message_search_idx").using("gin", sql3`to_tsvector('english', ${table.payload}->>'text')`).where(sql3`${table.type} = 'message'`),
|
|
220
|
-
uniqueIndex3("junior_conversation_events_idempotency_idx").on(
|
|
221
|
-
table.conversationId,
|
|
222
|
-
table.idempotencyKey
|
|
223
|
-
)
|
|
224
|
-
]
|
|
225
|
-
);
|
|
226
|
-
|
|
227
|
-
// src/db/schema.ts
|
|
228
|
-
var juniorSqlSchema = {
|
|
229
|
-
juniorConversationEvents,
|
|
230
|
-
juniorConversations,
|
|
231
|
-
juniorDestinations,
|
|
232
|
-
juniorIdentities,
|
|
233
|
-
juniorUsers
|
|
234
|
-
};
|
|
235
|
-
|
|
236
|
-
// src/chat/identities/sql.ts
|
|
29
|
+
import { and, eq, sql } from "drizzle-orm";
|
|
237
30
|
function dateFromMs(ms) {
|
|
238
31
|
return new Date(ms);
|
|
239
32
|
}
|
|
@@ -251,8 +44,8 @@ async function upsertUser(executor, args) {
|
|
|
251
44
|
}).onConflictDoUpdate({
|
|
252
45
|
target: juniorUsers.primaryEmailNormalized,
|
|
253
46
|
set: {
|
|
254
|
-
displayName:
|
|
255
|
-
updatedAt:
|
|
47
|
+
displayName: sql`coalesce(${juniorUsers.displayName}, excluded.display_name)`,
|
|
48
|
+
updatedAt: sql`excluded.updated_at`
|
|
256
49
|
}
|
|
257
50
|
}).returning({ id: juniorUsers.id });
|
|
258
51
|
const id = rows[0]?.id;
|
|
@@ -313,16 +106,16 @@ async function upsertIdentity(executor, identity, nowMs = Date.now()) {
|
|
|
313
106
|
juniorIdentities.providerSubjectId
|
|
314
107
|
],
|
|
315
108
|
set: {
|
|
316
|
-
kind:
|
|
317
|
-
userId:
|
|
318
|
-
displayName:
|
|
319
|
-
handle:
|
|
320
|
-
email:
|
|
321
|
-
emailNormalized:
|
|
322
|
-
emailVerified:
|
|
323
|
-
avatarUrl:
|
|
324
|
-
metadata:
|
|
325
|
-
updatedAt:
|
|
109
|
+
kind: sql`excluded.kind`,
|
|
110
|
+
userId: sql`coalesce(${juniorIdentities.userId}, excluded.user_id)`,
|
|
111
|
+
displayName: sql`coalesce(${juniorIdentities.displayName}, excluded.display_name)`,
|
|
112
|
+
handle: sql`coalesce(${juniorIdentities.handle}, excluded.handle)`,
|
|
113
|
+
email: sql`case when ${juniorIdentities.emailVerified} then coalesce(${juniorIdentities.email}, excluded.email) when excluded.email_verified then excluded.email else coalesce(${juniorIdentities.email}, excluded.email) end`,
|
|
114
|
+
emailNormalized: sql`case when ${juniorIdentities.emailVerified} then coalesce(${juniorIdentities.emailNormalized}, excluded.email_normalized) when excluded.email_verified then excluded.email_normalized else coalesce(${juniorIdentities.emailNormalized}, excluded.email_normalized) end`,
|
|
115
|
+
emailVerified: sql`${juniorIdentities.emailVerified} OR excluded.email_verified`,
|
|
116
|
+
avatarUrl: sql`coalesce(${juniorIdentities.avatarUrl}, excluded.avatar_url)`,
|
|
117
|
+
metadata: sql`coalesce(${juniorIdentities.metadata}, excluded.metadata_json)`,
|
|
118
|
+
updatedAt: sql`excluded.updated_at`
|
|
326
119
|
}
|
|
327
120
|
}).returning({
|
|
328
121
|
id: juniorIdentities.id,
|
|
@@ -462,16 +255,17 @@ function privacyFromRow(row) {
|
|
|
462
255
|
}
|
|
463
256
|
return row.destination.visibility === "public" ? "public" : "private";
|
|
464
257
|
}
|
|
465
|
-
function actorFromIdentityRow(identity) {
|
|
258
|
+
function actorFromIdentityRow(identity, userDisplayName) {
|
|
466
259
|
if (!identity) {
|
|
467
260
|
return void 0;
|
|
468
261
|
}
|
|
469
262
|
if (identity.provider !== "slack") {
|
|
470
263
|
return void 0;
|
|
471
264
|
}
|
|
265
|
+
const fullName = userDisplayName?.trim() ? userDisplayName : identity.displayName;
|
|
472
266
|
return {
|
|
473
267
|
...identity.emailNormalized ? { email: identity.emailNormalized } : identity.email ? { email: identity.email } : {},
|
|
474
|
-
...
|
|
268
|
+
...fullName ? { fullName } : {},
|
|
475
269
|
platform: "slack",
|
|
476
270
|
slackUserId: identity.providerSubjectId,
|
|
477
271
|
...identity.handle ? { slackUserName: identity.handle } : {},
|
|
@@ -502,7 +296,10 @@ function conversationFromRow(readRow) {
|
|
|
502
296
|
throw new Error("Conversation legacy actor is not migrated");
|
|
503
297
|
}
|
|
504
298
|
const destination = destinationFromRow(readRow.destination);
|
|
505
|
-
const actor = actorFromIdentityRow(
|
|
299
|
+
const actor = actorFromIdentityRow(
|
|
300
|
+
readRow.actorIdentity,
|
|
301
|
+
readRow.actorUserDisplayName
|
|
302
|
+
);
|
|
506
303
|
if (readRow.destination !== null && !destination) {
|
|
507
304
|
throw new Error("Conversation record destination is invalid");
|
|
508
305
|
}
|
|
@@ -708,75 +505,19 @@ var SqlStore = class {
|
|
|
708
505
|
}
|
|
709
506
|
});
|
|
710
507
|
}
|
|
711
|
-
/** Copy one conversation record and retained metrics into SQL during backfill. */
|
|
712
|
-
async backfillConversation(sourceConversation, metrics) {
|
|
713
|
-
const { visibility: _visibility, ...conversation } = sourceConversation;
|
|
714
|
-
await this.withConversationMutation(
|
|
715
|
-
conversation.conversationId,
|
|
716
|
-
async () => {
|
|
717
|
-
const existing = await this.get({
|
|
718
|
-
conversationId: conversation.conversationId
|
|
719
|
-
});
|
|
720
|
-
const sourceExecutionAtMs = conversation.execution.updatedAtMs ?? conversation.updatedAtMs;
|
|
721
|
-
const existingExecutionAtMs = existing === void 0 ? void 0 : existing.execution.updatedAtMs ?? existing.updatedAtMs;
|
|
722
|
-
const refreshExecutionFromSource = existingExecutionAtMs === void 0 || sourceExecutionAtMs >= existingExecutionAtMs;
|
|
723
|
-
const mergedConversation = existing ? {
|
|
724
|
-
...conversation,
|
|
725
|
-
channelName: existing.channelName ?? conversation.channelName,
|
|
726
|
-
createdAtMs: Math.min(
|
|
727
|
-
existing.createdAtMs,
|
|
728
|
-
conversation.createdAtMs
|
|
729
|
-
),
|
|
730
|
-
destination: existing.destination ?? conversation.destination,
|
|
731
|
-
lastActivityAtMs: Math.max(
|
|
732
|
-
existing.lastActivityAtMs,
|
|
733
|
-
conversation.lastActivityAtMs
|
|
734
|
-
),
|
|
735
|
-
actor: existing.actor ?? conversation.actor,
|
|
736
|
-
source: existing.source ?? conversation.source,
|
|
737
|
-
title: existing.title ?? conversation.title,
|
|
738
|
-
updatedAtMs: Math.max(
|
|
739
|
-
existing.updatedAtMs,
|
|
740
|
-
conversation.updatedAtMs
|
|
741
|
-
),
|
|
742
|
-
execution: refreshExecutionFromSource ? conversation.execution : existing.execution
|
|
743
|
-
} : conversation;
|
|
744
|
-
await this.upsertConversation({ conversation: mergedConversation });
|
|
745
|
-
if (metrics) {
|
|
746
|
-
await this.executor.db().update(juniorConversations).set({
|
|
747
|
-
durationMs: metrics.durationMs,
|
|
748
|
-
usage: metrics.usage ?? null,
|
|
749
|
-
...refreshExecutionFromSource ? {
|
|
750
|
-
metricRunId: conversation.execution.runId ?? null,
|
|
751
|
-
executionDurationMs: metrics.executionDurationMs,
|
|
752
|
-
executionUsage: metrics.executionUsage ?? null
|
|
753
|
-
} : {}
|
|
754
|
-
}).where(
|
|
755
|
-
and2(
|
|
756
|
-
eq2(
|
|
757
|
-
juniorConversations.conversationId,
|
|
758
|
-
conversation.conversationId
|
|
759
|
-
),
|
|
760
|
-
eq2(juniorConversations.durationMs, 0),
|
|
761
|
-
isNull(juniorConversations.usage)
|
|
762
|
-
)
|
|
763
|
-
);
|
|
764
|
-
}
|
|
765
|
-
}
|
|
766
|
-
);
|
|
767
|
-
}
|
|
768
508
|
async listByActivity(args = {}) {
|
|
769
509
|
const rows = await this.executor.db().select({
|
|
770
510
|
conversation: juniorConversations,
|
|
771
511
|
destination: juniorDestinations,
|
|
772
|
-
actorIdentity: juniorIdentities
|
|
512
|
+
actorIdentity: juniorIdentities,
|
|
513
|
+
actorUserDisplayName: juniorUsers.displayName
|
|
773
514
|
}).from(juniorConversations).leftJoin(
|
|
774
515
|
juniorDestinations,
|
|
775
516
|
eq2(juniorDestinations.id, juniorConversations.destinationId)
|
|
776
517
|
).leftJoin(
|
|
777
518
|
juniorIdentities,
|
|
778
519
|
eq2(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
779
|
-
).where(isNull(juniorConversations.parentConversationId)).orderBy(
|
|
520
|
+
).leftJoin(juniorUsers, eq2(juniorUsers.id, juniorIdentities.userId)).where(isNull(juniorConversations.parentConversationId)).orderBy(
|
|
780
521
|
desc(juniorConversations.lastActivityAt),
|
|
781
522
|
asc(juniorConversations.conversationId)
|
|
782
523
|
).limit(Math.max(0, args.limit ?? 1e4)).offset(Math.max(0, args.offset ?? 0));
|
|
@@ -819,22 +560,23 @@ var SqlStore = class {
|
|
|
819
560
|
const rows = await this.executor.db().select({
|
|
820
561
|
conversation: juniorConversations,
|
|
821
562
|
destination: juniorDestinations,
|
|
822
|
-
actorIdentity: juniorIdentities
|
|
563
|
+
actorIdentity: juniorIdentities,
|
|
564
|
+
actorUserDisplayName: juniorUsers.displayName
|
|
823
565
|
}).from(juniorConversations).leftJoin(
|
|
824
566
|
juniorDestinations,
|
|
825
567
|
eq2(juniorDestinations.id, juniorConversations.destinationId)
|
|
826
568
|
).leftJoin(
|
|
827
569
|
juniorIdentities,
|
|
828
570
|
eq2(juniorIdentities.id, juniorConversations.actorIdentityId)
|
|
829
|
-
).where(eq2(juniorConversations.conversationId, conversationId));
|
|
571
|
+
).leftJoin(juniorUsers, eq2(juniorUsers.id, juniorIdentities.userId)).where(eq2(juniorConversations.conversationId, conversationId));
|
|
830
572
|
return rows[0];
|
|
831
573
|
}
|
|
832
574
|
/** Upsert the conversation row while preserving previously discovered nullable metadata fields. */
|
|
833
575
|
async upsertConversation(args) {
|
|
834
576
|
const { conversation } = args;
|
|
835
|
-
const incomingExecutionVersion =
|
|
836
|
-
const currentExecutionVersion =
|
|
837
|
-
const incomingExecutionIsFresh =
|
|
577
|
+
const incomingExecutionVersion = sql2`coalesce(excluded.execution_updated_at, excluded.updated_at)`;
|
|
578
|
+
const currentExecutionVersion = sql2`coalesce(${juniorConversations.executionUpdatedAt}, ${juniorConversations.updatedAt})`;
|
|
579
|
+
const incomingExecutionIsFresh = sql2`${incomingExecutionVersion} >= ${currentExecutionVersion}`;
|
|
838
580
|
const destinationId = await this.upsertDestination(
|
|
839
581
|
destinationUpsertFromDestination({
|
|
840
582
|
channelName: conversation.channelName,
|
|
@@ -877,24 +619,24 @@ var SqlStore = class {
|
|
|
877
619
|
}).onConflictDoUpdate({
|
|
878
620
|
target: juniorConversations.conversationId,
|
|
879
621
|
set: {
|
|
880
|
-
source:
|
|
881
|
-
originType:
|
|
882
|
-
originId:
|
|
883
|
-
originRunId:
|
|
884
|
-
destinationId:
|
|
885
|
-
actorIdentityId:
|
|
886
|
-
creatorIdentityId:
|
|
887
|
-
credentialSubjectIdentityId:
|
|
888
|
-
channelName:
|
|
889
|
-
title:
|
|
890
|
-
createdAt:
|
|
891
|
-
lastActivityAt:
|
|
892
|
-
updatedAt:
|
|
893
|
-
executionUpdatedAt:
|
|
894
|
-
executionStatus:
|
|
895
|
-
runId:
|
|
896
|
-
lastCheckpointAt:
|
|
897
|
-
lastEnqueuedAt:
|
|
622
|
+
source: sql2`coalesce(excluded.source, ${juniorConversations.source})`,
|
|
623
|
+
originType: sql2`coalesce(excluded.origin_type, ${juniorConversations.originType})`,
|
|
624
|
+
originId: sql2`coalesce(excluded.origin_id, ${juniorConversations.originId})`,
|
|
625
|
+
originRunId: sql2`coalesce(excluded.origin_run_id, ${juniorConversations.originRunId})`,
|
|
626
|
+
destinationId: sql2`coalesce(excluded.destination_id, ${juniorConversations.destinationId})`,
|
|
627
|
+
actorIdentityId: sql2`coalesce(excluded.actor_identity_id, ${juniorConversations.actorIdentityId})`,
|
|
628
|
+
creatorIdentityId: sql2`coalesce(excluded.creator_identity_id, ${juniorConversations.creatorIdentityId})`,
|
|
629
|
+
credentialSubjectIdentityId: sql2`coalesce(excluded.credential_subject_identity_id, ${juniorConversations.credentialSubjectIdentityId})`,
|
|
630
|
+
channelName: sql2`coalesce(excluded.channel_name, ${juniorConversations.channelName})`,
|
|
631
|
+
title: sql2`coalesce(excluded.title, ${juniorConversations.title})`,
|
|
632
|
+
createdAt: sql2`least(${juniorConversations.createdAt}, excluded.created_at)`,
|
|
633
|
+
lastActivityAt: sql2`greatest(${juniorConversations.lastActivityAt}, excluded.last_activity_at)`,
|
|
634
|
+
updatedAt: sql2`greatest(${juniorConversations.updatedAt}, excluded.updated_at)`,
|
|
635
|
+
executionUpdatedAt: sql2`case when ${incomingExecutionIsFresh} then excluded.execution_updated_at else ${juniorConversations.executionUpdatedAt} end`,
|
|
636
|
+
executionStatus: sql2`case when ${incomingExecutionIsFresh} then excluded.execution_status else ${juniorConversations.executionStatus} end`,
|
|
637
|
+
runId: sql2`case when ${incomingExecutionIsFresh} then excluded.run_id else ${juniorConversations.runId} end`,
|
|
638
|
+
lastCheckpointAt: sql2`case when ${incomingExecutionIsFresh} then coalesce(excluded.last_checkpoint_at, ${juniorConversations.lastCheckpointAt}) else ${juniorConversations.lastCheckpointAt} end`,
|
|
639
|
+
lastEnqueuedAt: sql2`case when ${incomingExecutionIsFresh} then coalesce(excluded.last_enqueued_at, ${juniorConversations.lastEnqueuedAt}) else ${juniorConversations.lastEnqueuedAt} end`
|
|
898
640
|
}
|
|
899
641
|
});
|
|
900
642
|
}
|
|
@@ -902,7 +644,7 @@ var SqlStore = class {
|
|
|
902
644
|
if (!destination) {
|
|
903
645
|
return void 0;
|
|
904
646
|
}
|
|
905
|
-
const visibilityUpdate = destination.refreshVisibility ?
|
|
647
|
+
const visibilityUpdate = destination.refreshVisibility ? sql2`excluded.visibility` : juniorDestinations.visibility;
|
|
906
648
|
const rows = await this.executor.db().insert(juniorDestinations).values({
|
|
907
649
|
id: randomUUID2(),
|
|
908
650
|
provider: destination.provider,
|
|
@@ -922,14 +664,14 @@ var SqlStore = class {
|
|
|
922
664
|
juniorDestinations.providerDestinationId
|
|
923
665
|
],
|
|
924
666
|
set: {
|
|
925
|
-
kind:
|
|
926
|
-
displayName:
|
|
667
|
+
kind: sql2`excluded.kind`,
|
|
668
|
+
displayName: sql2`coalesce(excluded.display_name, ${juniorDestinations.displayName})`,
|
|
927
669
|
// Signal-less writes insert as private but must not clobber an
|
|
928
670
|
// existing public/private value. Live source signals refresh this
|
|
929
671
|
// field so converted channels converge on the next message.
|
|
930
672
|
visibility: visibilityUpdate,
|
|
931
|
-
metadata:
|
|
932
|
-
updatedAt:
|
|
673
|
+
metadata: sql2`coalesce(excluded.metadata_json, ${juniorDestinations.metadata})`,
|
|
674
|
+
updatedAt: sql2`excluded.updated_at`
|
|
933
675
|
}
|
|
934
676
|
}).returning({ id: juniorDestinations.id });
|
|
935
677
|
return rows[0]?.id;
|
|
@@ -949,7 +691,7 @@ import {
|
|
|
949
691
|
inArray,
|
|
950
692
|
isNotNull,
|
|
951
693
|
lte,
|
|
952
|
-
sql as
|
|
694
|
+
sql as sql4
|
|
953
695
|
} from "drizzle-orm";
|
|
954
696
|
|
|
955
697
|
// src/chat/conversations/history.ts
|
|
@@ -1238,7 +980,7 @@ var newConversationEventSchema = z2.object({
|
|
|
1238
980
|
}).strict();
|
|
1239
981
|
|
|
1240
982
|
// src/chat/conversations/sql/conversation-row.ts
|
|
1241
|
-
import { sql as
|
|
983
|
+
import { sql as sql3 } from "drizzle-orm";
|
|
1242
984
|
async function ensureConversationRow(executor, conversationId, atMs) {
|
|
1243
985
|
const at = new Date(atMs);
|
|
1244
986
|
await executor.db().insert(juniorConversations).values({
|
|
@@ -1250,8 +992,8 @@ async function ensureConversationRow(executor, conversationId, atMs) {
|
|
|
1250
992
|
}).onConflictDoUpdate({
|
|
1251
993
|
target: juniorConversations.conversationId,
|
|
1252
994
|
set: {
|
|
1253
|
-
lastActivityAt:
|
|
1254
|
-
updatedAt:
|
|
995
|
+
lastActivityAt: sql3`greatest(${juniorConversations.lastActivityAt}, excluded.last_activity_at)`,
|
|
996
|
+
updatedAt: sql3`greatest(${juniorConversations.updatedAt}, excluded.updated_at)`,
|
|
1255
997
|
transcriptPurgedAt: null
|
|
1256
998
|
}
|
|
1257
999
|
});
|
|
@@ -1318,6 +1060,15 @@ function eventFromRow(row) {
|
|
|
1318
1060
|
payload: row.payload
|
|
1319
1061
|
});
|
|
1320
1062
|
}
|
|
1063
|
+
function messagesSummarizedEventFromRow(row) {
|
|
1064
|
+
const event = eventFromRow(row);
|
|
1065
|
+
if (event.schemaVersion !== 1 || event.data.type !== "messages_summarized") {
|
|
1066
|
+
throw new Error(
|
|
1067
|
+
"Message compaction row did not decode as messages_summarized"
|
|
1068
|
+
);
|
|
1069
|
+
}
|
|
1070
|
+
return { ...event, schemaVersion: 1, data: event.data };
|
|
1071
|
+
}
|
|
1321
1072
|
var SqlConversationEventStore = class {
|
|
1322
1073
|
constructor(executor) {
|
|
1323
1074
|
this.executor = executor;
|
|
@@ -1438,8 +1189,8 @@ var SqlConversationEventStore = class {
|
|
|
1438
1189
|
eq3(juniorConversationEvents.type, "messages_summarized")
|
|
1439
1190
|
)
|
|
1440
1191
|
).orderBy(desc2(juniorConversationEvents.seq)).limit(1);
|
|
1441
|
-
const compaction = compactionRow ?
|
|
1442
|
-
const historyFromSeq = compaction?.data.
|
|
1192
|
+
const compaction = compactionRow ? messagesSummarizedEventFromRow(compactionRow) : void 0;
|
|
1193
|
+
const historyFromSeq = compaction?.data.historyFromSeq ?? 0;
|
|
1443
1194
|
const rows = await this.executor.db().select().from(juniorConversationEvents).where(
|
|
1444
1195
|
and3(
|
|
1445
1196
|
eq3(juniorConversationEvents.conversationId, conversationId),
|
|
@@ -1447,7 +1198,7 @@ var SqlConversationEventStore = class {
|
|
|
1447
1198
|
gte(juniorConversationEvents.seq, historyFromSeq)
|
|
1448
1199
|
)
|
|
1449
1200
|
).orderBy(asc2(juniorConversationEvents.seq));
|
|
1450
|
-
return { events: rows.map(eventFromRow), compaction };
|
|
1201
|
+
return { events: rows.map(eventFromRow), compaction, historyFromSeq };
|
|
1451
1202
|
}
|
|
1452
1203
|
async loadHistory(conversationId) {
|
|
1453
1204
|
const rows = await this.executor.db().select().from(juniorConversationEvents).where(eq3(juniorConversationEvents.conversationId, conversationId)).orderBy(asc2(juniorConversationEvents.seq));
|
|
@@ -1456,8 +1207,8 @@ var SqlConversationEventStore = class {
|
|
|
1456
1207
|
/** Read the next sequence and active model-history version. */
|
|
1457
1208
|
async readCursor(conversationId) {
|
|
1458
1209
|
const rows = await this.executor.db().select({
|
|
1459
|
-
maxSeq:
|
|
1460
|
-
maxHistoryVersion:
|
|
1210
|
+
maxSeq: sql4`max(${juniorConversationEvents.seq})`,
|
|
1211
|
+
maxHistoryVersion: sql4`max(${juniorConversationEvents.historyVersion})`
|
|
1461
1212
|
}).from(juniorConversationEvents).where(eq3(juniorConversationEvents.conversationId, conversationId));
|
|
1462
1213
|
const maxSeq = rows[0]?.maxSeq;
|
|
1463
1214
|
const maxHistoryVersion = rows[0]?.maxHistoryVersion;
|
|
@@ -1472,7 +1223,7 @@ function createSqlConversationEventStore(executor) {
|
|
|
1472
1223
|
}
|
|
1473
1224
|
|
|
1474
1225
|
// src/chat/conversations/sql/search.ts
|
|
1475
|
-
import { and as and4, desc as desc3, eq as eq4, isNull as isNull2, ne, sql as
|
|
1226
|
+
import { and as and4, desc as desc3, eq as eq4, isNull as isNull2, ne, sql as sql5 } from "drizzle-orm";
|
|
1476
1227
|
var SqlConversationSearchStore = class {
|
|
1477
1228
|
constructor(executor) {
|
|
1478
1229
|
this.executor = executor;
|
|
@@ -1480,12 +1231,12 @@ var SqlConversationSearchStore = class {
|
|
|
1480
1231
|
executor;
|
|
1481
1232
|
async search(args) {
|
|
1482
1233
|
const db = this.executor.db();
|
|
1483
|
-
const tsquery =
|
|
1484
|
-
const
|
|
1485
|
-
const rank =
|
|
1486
|
-
const excerpt =
|
|
1487
|
-
const role =
|
|
1488
|
-
const messageId =
|
|
1234
|
+
const tsquery = sql5`websearch_to_tsquery('english', ${args.query})`;
|
|
1235
|
+
const text = sql5`${juniorConversationEvents.payload}->>'text'`;
|
|
1236
|
+
const rank = sql5`ts_rank_cd(to_tsvector('english', ${text}), ${tsquery})`;
|
|
1237
|
+
const excerpt = sql5`ts_headline('english', ${text}, ${tsquery}, 'MaxFragments=2, MinWords=8, MaxWords=40, FragmentDelimiter=" … ", StartSel=**, StopSel=**')`;
|
|
1238
|
+
const role = sql5`${juniorConversationEvents.payload}->>'role'`;
|
|
1239
|
+
const messageId = sql5`${juniorConversationEvents.payload}->>'messageId'`;
|
|
1489
1240
|
const bestPerConversation = db.selectDistinctOn([juniorConversations.conversationId], {
|
|
1490
1241
|
conversationId: juniorConversations.conversationId,
|
|
1491
1242
|
excerpt: excerpt.as("excerpt"),
|
|
@@ -1514,8 +1265,8 @@ var SqlConversationSearchStore = class {
|
|
|
1514
1265
|
eq4(juniorDestinations.providerTenantId, args.scope.providerTenantId),
|
|
1515
1266
|
eq4(juniorDestinations.visibility, "public"),
|
|
1516
1267
|
eq4(juniorConversationEvents.type, "message"),
|
|
1517
|
-
|
|
1518
|
-
|
|
1268
|
+
sql5`${role} in ('user', 'assistant')`,
|
|
1269
|
+
sql5`to_tsvector('english', ${text}) @@ ${tsquery}`
|
|
1519
1270
|
)
|
|
1520
1271
|
).orderBy(
|
|
1521
1272
|
juniorConversations.conversationId,
|
|
@@ -1540,252 +1291,6 @@ function createSqlConversationSearchStore(executor) {
|
|
|
1540
1291
|
return new SqlConversationSearchStore(executor);
|
|
1541
1292
|
}
|
|
1542
1293
|
|
|
1543
|
-
// src/db/neon.ts
|
|
1544
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
1545
|
-
import {
|
|
1546
|
-
Pool
|
|
1547
|
-
} from "@neondatabase/serverless";
|
|
1548
|
-
import { drizzle } from "drizzle-orm/neon-serverless";
|
|
1549
|
-
import { migrate } from "drizzle-orm/neon-serverless/migrator";
|
|
1550
|
-
var NeonExecutor = class {
|
|
1551
|
-
constructor(pool) {
|
|
1552
|
-
this.pool = pool;
|
|
1553
|
-
}
|
|
1554
|
-
pool;
|
|
1555
|
-
transactionClient = new AsyncLocalStorage();
|
|
1556
|
-
savepointId = 0;
|
|
1557
|
-
db() {
|
|
1558
|
-
return drizzle(this.queryClient(), {
|
|
1559
|
-
schema: juniorSqlSchema
|
|
1560
|
-
});
|
|
1561
|
-
}
|
|
1562
|
-
async execute(statement, params = []) {
|
|
1563
|
-
await this.queryClient().query(statement, [...params]);
|
|
1564
|
-
}
|
|
1565
|
-
async query(statement, params = []) {
|
|
1566
|
-
const result = await this.queryClient().query(statement, [
|
|
1567
|
-
...params
|
|
1568
|
-
]);
|
|
1569
|
-
return result.rows;
|
|
1570
|
-
}
|
|
1571
|
-
async migrate(config) {
|
|
1572
|
-
await migrate(
|
|
1573
|
-
drizzle(this.queryClient(), { schema: juniorSqlSchema }),
|
|
1574
|
-
config
|
|
1575
|
-
);
|
|
1576
|
-
}
|
|
1577
|
-
async transaction(callback) {
|
|
1578
|
-
const existingClient = this.transactionClient.getStore();
|
|
1579
|
-
if (existingClient) {
|
|
1580
|
-
const savepoint = `junior_savepoint_${++this.savepointId}`;
|
|
1581
|
-
await existingClient.query(`SAVEPOINT ${savepoint}`);
|
|
1582
|
-
try {
|
|
1583
|
-
const result = await callback();
|
|
1584
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
1585
|
-
return result;
|
|
1586
|
-
} catch (error) {
|
|
1587
|
-
await existingClient.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
1588
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
1589
|
-
throw error;
|
|
1590
|
-
}
|
|
1591
|
-
}
|
|
1592
|
-
const client = await this.pool.connect();
|
|
1593
|
-
try {
|
|
1594
|
-
await client.query("BEGIN");
|
|
1595
|
-
const result = await this.transactionClient.run(client, callback);
|
|
1596
|
-
await client.query("COMMIT");
|
|
1597
|
-
return result;
|
|
1598
|
-
} catch (error) {
|
|
1599
|
-
await client.query("ROLLBACK");
|
|
1600
|
-
throw error;
|
|
1601
|
-
} finally {
|
|
1602
|
-
client.release();
|
|
1603
|
-
}
|
|
1604
|
-
}
|
|
1605
|
-
async withLock(lockName, callback) {
|
|
1606
|
-
if (!lockName) {
|
|
1607
|
-
throw new Error("SQL lock name is required");
|
|
1608
|
-
}
|
|
1609
|
-
const existingClient = this.transactionClient.getStore();
|
|
1610
|
-
if (existingClient) {
|
|
1611
|
-
await existingClient.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1612
|
-
lockName
|
|
1613
|
-
]);
|
|
1614
|
-
return await callback();
|
|
1615
|
-
}
|
|
1616
|
-
const client = await this.pool.connect();
|
|
1617
|
-
try {
|
|
1618
|
-
await client.query("BEGIN");
|
|
1619
|
-
return await this.transactionClient.run(client, async () => {
|
|
1620
|
-
try {
|
|
1621
|
-
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1622
|
-
lockName
|
|
1623
|
-
]);
|
|
1624
|
-
const result = await callback();
|
|
1625
|
-
await client.query("COMMIT");
|
|
1626
|
-
return result;
|
|
1627
|
-
} catch (error) {
|
|
1628
|
-
await client.query("ROLLBACK");
|
|
1629
|
-
throw error;
|
|
1630
|
-
}
|
|
1631
|
-
});
|
|
1632
|
-
} finally {
|
|
1633
|
-
client.release();
|
|
1634
|
-
}
|
|
1635
|
-
}
|
|
1636
|
-
async withMigrationLock(migrationTable, callback) {
|
|
1637
|
-
const client = await this.pool.connect();
|
|
1638
|
-
const lockName = `junior:migrate:${migrationTable}`;
|
|
1639
|
-
try {
|
|
1640
|
-
await client.query("SELECT pg_advisory_lock(hashtext($1))", [lockName]);
|
|
1641
|
-
return await callback();
|
|
1642
|
-
} finally {
|
|
1643
|
-
client.release(true);
|
|
1644
|
-
}
|
|
1645
|
-
}
|
|
1646
|
-
async close() {
|
|
1647
|
-
await this.pool.end();
|
|
1648
|
-
}
|
|
1649
|
-
queryClient() {
|
|
1650
|
-
return this.transactionClient.getStore() ?? this.pool;
|
|
1651
|
-
}
|
|
1652
|
-
};
|
|
1653
|
-
function createNeonJuniorSqlExecutor(args) {
|
|
1654
|
-
return new NeonExecutor(
|
|
1655
|
-
new Pool({
|
|
1656
|
-
connectionString: args.connectionString,
|
|
1657
|
-
max: 3
|
|
1658
|
-
})
|
|
1659
|
-
);
|
|
1660
|
-
}
|
|
1661
|
-
|
|
1662
|
-
// src/db/postgres.ts
|
|
1663
|
-
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
1664
|
-
import pg from "pg";
|
|
1665
|
-
import { drizzle as drizzle2 } from "drizzle-orm/node-postgres";
|
|
1666
|
-
import { migrate as migrate2 } from "drizzle-orm/node-postgres/migrator";
|
|
1667
|
-
var { Pool: Pool2 } = pg;
|
|
1668
|
-
var PostgresExecutor = class {
|
|
1669
|
-
constructor(pool) {
|
|
1670
|
-
this.pool = pool;
|
|
1671
|
-
}
|
|
1672
|
-
pool;
|
|
1673
|
-
transactionClient = new AsyncLocalStorage2();
|
|
1674
|
-
savepointId = 0;
|
|
1675
|
-
db() {
|
|
1676
|
-
return drizzle2(this.queryClient(), {
|
|
1677
|
-
schema: juniorSqlSchema
|
|
1678
|
-
});
|
|
1679
|
-
}
|
|
1680
|
-
async execute(statement, params = []) {
|
|
1681
|
-
await this.queryClient().query(statement, [...params]);
|
|
1682
|
-
}
|
|
1683
|
-
async query(statement, params = []) {
|
|
1684
|
-
const result = await this.queryClient().query(statement, [
|
|
1685
|
-
...params
|
|
1686
|
-
]);
|
|
1687
|
-
return result.rows;
|
|
1688
|
-
}
|
|
1689
|
-
async migrate(config) {
|
|
1690
|
-
await migrate2(
|
|
1691
|
-
drizzle2(this.queryClient(), { schema: juniorSqlSchema }),
|
|
1692
|
-
config
|
|
1693
|
-
);
|
|
1694
|
-
}
|
|
1695
|
-
async transaction(callback) {
|
|
1696
|
-
const existingClient = this.transactionClient.getStore();
|
|
1697
|
-
if (existingClient) {
|
|
1698
|
-
const savepoint = `junior_savepoint_${++this.savepointId}`;
|
|
1699
|
-
await existingClient.query(`SAVEPOINT ${savepoint}`);
|
|
1700
|
-
try {
|
|
1701
|
-
const result = await callback();
|
|
1702
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
1703
|
-
return result;
|
|
1704
|
-
} catch (error) {
|
|
1705
|
-
await existingClient.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
1706
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
1707
|
-
throw error;
|
|
1708
|
-
}
|
|
1709
|
-
}
|
|
1710
|
-
const client = await this.pool.connect();
|
|
1711
|
-
try {
|
|
1712
|
-
await client.query("BEGIN");
|
|
1713
|
-
const result = await this.transactionClient.run(client, callback);
|
|
1714
|
-
await client.query("COMMIT");
|
|
1715
|
-
return result;
|
|
1716
|
-
} catch (error) {
|
|
1717
|
-
await client.query("ROLLBACK");
|
|
1718
|
-
throw error;
|
|
1719
|
-
} finally {
|
|
1720
|
-
client.release();
|
|
1721
|
-
}
|
|
1722
|
-
}
|
|
1723
|
-
async withLock(lockName, callback) {
|
|
1724
|
-
if (!lockName) {
|
|
1725
|
-
throw new Error("SQL lock name is required");
|
|
1726
|
-
}
|
|
1727
|
-
const existingClient = this.transactionClient.getStore();
|
|
1728
|
-
if (existingClient) {
|
|
1729
|
-
await existingClient.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1730
|
-
lockName
|
|
1731
|
-
]);
|
|
1732
|
-
return await callback();
|
|
1733
|
-
}
|
|
1734
|
-
const client = await this.pool.connect();
|
|
1735
|
-
try {
|
|
1736
|
-
await client.query("BEGIN");
|
|
1737
|
-
return await this.transactionClient.run(client, async () => {
|
|
1738
|
-
try {
|
|
1739
|
-
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1740
|
-
lockName
|
|
1741
|
-
]);
|
|
1742
|
-
const result = await callback();
|
|
1743
|
-
await client.query("COMMIT");
|
|
1744
|
-
return result;
|
|
1745
|
-
} catch (error) {
|
|
1746
|
-
await client.query("ROLLBACK");
|
|
1747
|
-
throw error;
|
|
1748
|
-
}
|
|
1749
|
-
});
|
|
1750
|
-
} finally {
|
|
1751
|
-
client.release();
|
|
1752
|
-
}
|
|
1753
|
-
}
|
|
1754
|
-
async withMigrationLock(migrationTable, callback) {
|
|
1755
|
-
const client = await this.pool.connect();
|
|
1756
|
-
const lockName = `junior:migrate:${migrationTable}`;
|
|
1757
|
-
try {
|
|
1758
|
-
await client.query("SELECT pg_advisory_lock(hashtext($1))", [lockName]);
|
|
1759
|
-
return await callback();
|
|
1760
|
-
} finally {
|
|
1761
|
-
client.release(true);
|
|
1762
|
-
}
|
|
1763
|
-
}
|
|
1764
|
-
async close() {
|
|
1765
|
-
await this.pool.end();
|
|
1766
|
-
}
|
|
1767
|
-
queryClient() {
|
|
1768
|
-
return this.transactionClient.getStore() ?? this.pool;
|
|
1769
|
-
}
|
|
1770
|
-
};
|
|
1771
|
-
function createPostgresJuniorSqlExecutor(args) {
|
|
1772
|
-
return new PostgresExecutor(
|
|
1773
|
-
new Pool2({
|
|
1774
|
-
application_name: args.applicationName,
|
|
1775
|
-
connectionString: args.connectionString,
|
|
1776
|
-
max: 3
|
|
1777
|
-
})
|
|
1778
|
-
);
|
|
1779
|
-
}
|
|
1780
|
-
|
|
1781
|
-
// src/db/executor.ts
|
|
1782
|
-
function createJuniorSqlExecutor(args) {
|
|
1783
|
-
if (args.driver === "postgres") {
|
|
1784
|
-
return createPostgresJuniorSqlExecutor(args);
|
|
1785
|
-
}
|
|
1786
|
-
return createNeonJuniorSqlExecutor(args);
|
|
1787
|
-
}
|
|
1788
|
-
|
|
1789
1294
|
// src/chat/db.ts
|
|
1790
1295
|
var current;
|
|
1791
1296
|
function createDb(args) {
|
|
@@ -1795,20 +1300,20 @@ function createDb(args) {
|
|
|
1795
1300
|
});
|
|
1796
1301
|
}
|
|
1797
1302
|
function getSqlExecutor() {
|
|
1798
|
-
const { sql:
|
|
1799
|
-
if (current?.databaseUrl !==
|
|
1303
|
+
const { sql: sql6 } = getChatConfig();
|
|
1304
|
+
if (current?.databaseUrl !== sql6.databaseUrl || current.driver !== sql6.driver) {
|
|
1800
1305
|
if (current) {
|
|
1801
1306
|
const previous = current;
|
|
1802
1307
|
current = void 0;
|
|
1803
1308
|
void previous.db.close().catch(() => void 0);
|
|
1804
1309
|
}
|
|
1805
1310
|
const db = createDb({
|
|
1806
|
-
databaseUrl:
|
|
1807
|
-
driver:
|
|
1311
|
+
databaseUrl: sql6.databaseUrl,
|
|
1312
|
+
driver: sql6.driver
|
|
1808
1313
|
});
|
|
1809
1314
|
current = {
|
|
1810
|
-
databaseUrl:
|
|
1811
|
-
driver:
|
|
1315
|
+
databaseUrl: sql6.databaseUrl,
|
|
1316
|
+
driver: sql6.driver,
|
|
1812
1317
|
db,
|
|
1813
1318
|
store: createSqlStore(db),
|
|
1814
1319
|
eventStore: createSqlConversationEventStore(db),
|
|
@@ -1839,22 +1344,13 @@ async function closeDb() {
|
|
|
1839
1344
|
}
|
|
1840
1345
|
|
|
1841
1346
|
export {
|
|
1842
|
-
juniorUsers,
|
|
1843
|
-
juniorIdentities,
|
|
1844
|
-
juniorConversations,
|
|
1845
|
-
juniorConversationEvents,
|
|
1846
|
-
createSqlStore,
|
|
1847
|
-
conversationMessageProvenanceSchema,
|
|
1848
1347
|
instructionProvenanceFor,
|
|
1849
1348
|
contextProvenance,
|
|
1850
1349
|
instructionActors,
|
|
1851
|
-
conversationEventDataSchema,
|
|
1852
1350
|
decodeStoredConversationEvent,
|
|
1853
|
-
newConversationEventSchema,
|
|
1854
1351
|
sanitizePostgresJson,
|
|
1855
1352
|
withConversationEventLock,
|
|
1856
1353
|
createSqlConversationEventStore,
|
|
1857
|
-
createJuniorSqlExecutor,
|
|
1858
1354
|
getSqlExecutor,
|
|
1859
1355
|
getDb,
|
|
1860
1356
|
getConversationStore,
|