@sentry/junior 0.108.0 → 0.110.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-NU5HK3PS.js → agent-hooks-ELT4ODFF.js} +12 -13
- package/dist/api/conversations/access.d.ts +9 -0
- package/dist/api/conversations/aggregate.d.ts +12 -1
- package/dist/api/conversations/archive.d.ts +3 -5
- package/dist/api/conversations/detail.d.ts +156 -7
- package/dist/api/conversations/events.d.ts +2 -2
- package/dist/api/conversations/list.d.ts +57 -6
- package/dist/api/conversations/projection.d.ts +6 -7
- package/dist/api/conversations/reporting.d.ts +10 -4
- package/dist/api/conversations/routes.d.ts +2 -1
- package/dist/api/conversations/shared.d.ts +1 -1
- package/dist/api/conversations/stats.d.ts +37 -6
- package/dist/api/conversations/stats.query.d.ts +1 -1
- package/dist/api/conversations/usage.d.ts +9 -0
- package/dist/api/http.d.ts +7 -0
- package/dist/api/locations/detail.d.ts +102 -6
- package/dist/api/locations/list.d.ts +43 -5
- package/dist/api/locations/query.d.ts +4 -2
- package/dist/api/locations/routes.d.ts +2 -1
- package/dist/api/people/list.d.ts +28 -6
- package/dist/api/people/list.query.d.ts +1 -1
- package/dist/api/people/profile.d.ts +96 -7
- package/dist/api/people/profile.query.d.ts +4 -2
- package/dist/api/people/routes.d.ts +2 -1
- package/dist/api/people/shared.d.ts +1219 -2
- package/dist/api/route.d.ts +18 -4
- package/dist/api/schema/common.d.ts +6 -0
- package/dist/api/{conversations/schema.d.ts → schema/conversation.d.ts} +88 -9
- package/dist/api/{locations/schema.d.ts → schema/location.d.ts} +5 -0
- package/dist/api/{people/schema.d.ts → schema/person.d.ts} +37 -45
- package/dist/api/schema.d.ts +8 -22
- package/dist/api/schema.js +10 -2
- package/dist/api.d.ts +5 -1
- package/dist/api.js +838 -369
- package/dist/app.d.ts +1 -0
- package/dist/app.js +1564 -486
- package/dist/catalog-runtime-4GI22PXK.js +16 -0
- package/dist/chat/agent/resume.d.ts +11 -12
- package/dist/chat/conversations/history.d.ts +3 -0
- package/dist/chat/conversations/sql/privacy.d.ts +3 -15
- 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/pi/messages.d.ts +2 -2
- package/dist/chat/pi/sql-model-usage.d.ts +4 -1
- package/dist/chat/runtime/slack-resume.d.ts +2 -2
- package/dist/chat/services/auth-pause.d.ts +4 -0
- package/dist/chat/services/context-compaction.d.ts +1 -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/queue-signing.d.ts +10 -8
- package/dist/chat/task-execution/queue.d.ts +9 -7
- package/dist/chat/task-execution/slack-work.d.ts +6 -6
- package/dist/{chunk-UD6THJ2I.js → chunk-2T7TIEXI.js} +197 -12
- package/dist/{chunk-CEA3A3UA.js → chunk-2ZTTXTSZ.js} +24 -1
- package/dist/{chunk-XKB7LGIW.js → chunk-3S7YYHBI.js} +3 -139
- package/dist/chunk-3TV7OEHL.js +10 -0
- package/dist/{chunk-A5CO2EHL.js → chunk-3UBQI73J.js} +11 -15
- package/dist/{chunk-7FBGKXPE.js → chunk-42WRQLJ6.js} +10 -33
- package/dist/{chunk-TE4QHJH4.js → chunk-4QU44P7Q.js} +135 -595
- package/dist/{chunk-RT5BUHR5.js → chunk-6Y5L4BOM.js} +3 -5
- package/dist/{chunk-VIXFG2VC.js → chunk-C4MZ3GP5.js} +1 -2
- package/dist/{chunk-3RGQLX2F.js → chunk-C5XAFTHY.js} +1011 -29
- package/dist/{chunk-PUAMO4PI.js → chunk-FPK7XY3F.js} +139 -99
- package/dist/{chunk-H3QYZL7K.js → chunk-GK47NBDE.js} +28 -3
- package/dist/{chunk-O24R4DCK.js → chunk-IYKPU7H6.js} +94 -56
- package/dist/chunk-JQFJO5WH.js +477 -0
- package/dist/{chunk-VH6KWKG2.js → chunk-L5XQPJ7T.js} +3 -3
- package/dist/{chunk-2XXEKR44.js → chunk-MIAKQNYX.js} +43 -31
- package/dist/{chunk-KPMPQ6AA.js → chunk-RHHRKSPI.js} +249 -223
- package/dist/{chunk-YT72TOEK.js → chunk-SBOBTS27.js} +2 -2
- package/dist/{chunk-B5I5LMSP.js → chunk-W6RJZG7F.js} +5 -7
- package/dist/chunk-W75ZPAGG.js +44 -0
- package/dist/{chunk-SS67LUOK.js → chunk-WNOVRQ67.js} +6 -7
- package/dist/{chunk-YIPD3L6L.js → chunk-Y3H2DN6F.js} +8 -10
- package/dist/{chunk-DY7TRYB5.js → chunk-Y5FK3CNG.js} +1 -1
- package/dist/chunk-ZKIOWEFL.js +125 -0
- package/dist/cli/chat.js +23 -24
- package/dist/cli/check.js +9 -7
- package/dist/cli/plugins.js +16 -17
- package/dist/cli/snapshot-warmup.js +11 -10
- package/dist/cli/upgrade.js +314 -3505
- package/dist/db/db.d.ts +1 -1
- package/dist/db/schema/conversations.d.ts +17 -0
- package/dist/db/schema.d.ts +17 -0
- package/dist/{db-AMRBAT5D.js → db-Y6W6CWWW.js} +8 -7
- package/dist/instrumentation.js +4 -3
- package/dist/nitro.js +4 -4
- package/dist/reporting-schema.d.ts +46 -0
- package/dist/{runner-TQH5GAJ4.js → runner-BBFV5GLR.js} +17 -21
- package/dist/{skills-ITNHBARB.js → skills-AR4AF32L.js} +8 -6
- package/dist/{validation-AGQ46ZGV.js → validation-FBIEPTC2.js} +8 -6
- 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/0007_thick_sugar_man.sql +23 -0
- package/migrations/README.md +12 -9
- package/migrations/meta/0006_snapshot.json +948 -0
- package/migrations/meta/0007_snapshot.json +1013 -0
- package/migrations/meta/_journal.json +14 -0
- package/package.json +9 -5
- package/dist/catalog-runtime-FOFNPR3P.js +0 -14
- package/dist/chunk-AHJR2IFF.js +0 -115
- package/dist/chunk-B7PUBQQM.js +0 -53
- package/dist/chunk-G3E7SCME.js +0 -28
- package/dist/chunk-J3B3FPP2.js +0 -1061
- package/dist/chunk-OB42YVAE.js +0 -16
- package/dist/chunk-TWINAEZQ.js +0 -1283
|
@@ -1,239 +1,73 @@
|
|
|
1
|
+
import {
|
|
2
|
+
createJuniorSqlExecutor,
|
|
3
|
+
juniorConversationEvents,
|
|
4
|
+
juniorConversations,
|
|
5
|
+
juniorIdentities,
|
|
6
|
+
juniorUsers
|
|
7
|
+
} from "./chunk-JQFJO5WH.js";
|
|
1
8
|
import {
|
|
2
9
|
getChatConfig,
|
|
3
10
|
modelProfileSchema
|
|
4
|
-
} from "./chunk-
|
|
11
|
+
} from "./chunk-WNOVRQ67.js";
|
|
5
12
|
import {
|
|
6
|
-
juniorDestinations
|
|
7
|
-
timestamptz
|
|
13
|
+
juniorDestinations
|
|
8
14
|
} from "./chunk-VFUK3X5B.js";
|
|
9
|
-
import {
|
|
10
|
-
parseDestination,
|
|
11
|
-
sameDestination
|
|
12
|
-
} from "./chunk-B7PUBQQM.js";
|
|
13
15
|
import {
|
|
14
16
|
normalizeIdentityEmail
|
|
15
|
-
} from "./chunk-
|
|
17
|
+
} from "./chunk-IYKPU7H6.js";
|
|
18
|
+
import {
|
|
19
|
+
parseSlackChannelReferenceId,
|
|
20
|
+
parseSlackTeamId
|
|
21
|
+
} from "./chunk-42WRQLJ6.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
|
|
20
|
-
|
|
21
|
-
// src/chat/identities/sql.ts
|
|
22
|
-
import { randomUUID } from "crypto";
|
|
23
|
-
import { and, eq, sql as sql4 } from "drizzle-orm";
|
|
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";
|
|
25
|
+
import { and as and2, asc, desc, eq as eq2, isNull, sql as sql2 } from "drizzle-orm";
|
|
37
26
|
|
|
38
|
-
// src/
|
|
39
|
-
import { sql as sql2 } from "drizzle-orm";
|
|
27
|
+
// src/chat/destination.ts
|
|
40
28
|
import {
|
|
41
|
-
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
45
|
-
|
|
46
|
-
|
|
47
|
-
|
|
48
|
-
|
|
49
|
-
|
|
50
|
-
|
|
51
|
-
|
|
52
|
-
|
|
53
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
63
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
}
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
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
|
-
};
|
|
29
|
+
destinationSchema
|
|
30
|
+
} from "@sentry/junior-plugin-api";
|
|
31
|
+
function createSlackDestination(input) {
|
|
32
|
+
const channelId = parseSlackChannelReferenceId(input.channelId);
|
|
33
|
+
const teamId = parseSlackTeamId(input.teamId);
|
|
34
|
+
if (!channelId || !teamId) {
|
|
35
|
+
return void 0;
|
|
36
|
+
}
|
|
37
|
+
return { platform: "slack", teamId, channelId };
|
|
38
|
+
}
|
|
39
|
+
function parseDestination(value) {
|
|
40
|
+
const parsed = destinationSchema.safeParse(value);
|
|
41
|
+
return parsed.success ? parsed.data : void 0;
|
|
42
|
+
}
|
|
43
|
+
function requireSlackDestination(destination, action) {
|
|
44
|
+
if (destination?.platform === "slack") {
|
|
45
|
+
return destination;
|
|
46
|
+
}
|
|
47
|
+
throw new Error(`${action} requires a Slack destination`);
|
|
48
|
+
}
|
|
49
|
+
function sameDestination(left, right) {
|
|
50
|
+
if (left.platform !== right.platform) {
|
|
51
|
+
return false;
|
|
52
|
+
}
|
|
53
|
+
if (left.platform === "local" && right.platform === "local") {
|
|
54
|
+
return left.conversationId === right.conversationId;
|
|
55
|
+
}
|
|
56
|
+
if (left.platform === "slack" && right.platform === "slack") {
|
|
57
|
+
return left.teamId === right.teamId && left.channelId === right.channelId;
|
|
58
|
+
}
|
|
59
|
+
return false;
|
|
60
|
+
}
|
|
61
|
+
function destinationKey(destination) {
|
|
62
|
+
if (destination.platform === "local") {
|
|
63
|
+
return destination.conversationId;
|
|
64
|
+
}
|
|
65
|
+
return `slack:${destination.teamId}:${destination.channelId}`;
|
|
66
|
+
}
|
|
235
67
|
|
|
236
68
|
// src/chat/identities/sql.ts
|
|
69
|
+
import { randomUUID } from "crypto";
|
|
70
|
+
import { and, eq, sql } from "drizzle-orm";
|
|
237
71
|
function dateFromMs(ms) {
|
|
238
72
|
return new Date(ms);
|
|
239
73
|
}
|
|
@@ -251,8 +85,8 @@ async function upsertUser(executor, args) {
|
|
|
251
85
|
}).onConflictDoUpdate({
|
|
252
86
|
target: juniorUsers.primaryEmailNormalized,
|
|
253
87
|
set: {
|
|
254
|
-
displayName:
|
|
255
|
-
updatedAt:
|
|
88
|
+
displayName: sql`coalesce(${juniorUsers.displayName}, excluded.display_name)`,
|
|
89
|
+
updatedAt: sql`excluded.updated_at`
|
|
256
90
|
}
|
|
257
91
|
}).returning({ id: juniorUsers.id });
|
|
258
92
|
const id = rows[0]?.id;
|
|
@@ -313,16 +147,16 @@ async function upsertIdentity(executor, identity, nowMs = Date.now()) {
|
|
|
313
147
|
juniorIdentities.providerSubjectId
|
|
314
148
|
],
|
|
315
149
|
set: {
|
|
316
|
-
kind:
|
|
317
|
-
userId:
|
|
318
|
-
displayName:
|
|
319
|
-
handle:
|
|
320
|
-
email:
|
|
321
|
-
emailNormalized:
|
|
322
|
-
emailVerified:
|
|
323
|
-
avatarUrl:
|
|
324
|
-
metadata:
|
|
325
|
-
updatedAt:
|
|
150
|
+
kind: sql`excluded.kind`,
|
|
151
|
+
userId: sql`coalesce(${juniorIdentities.userId}, excluded.user_id)`,
|
|
152
|
+
displayName: sql`coalesce(${juniorIdentities.displayName}, excluded.display_name)`,
|
|
153
|
+
handle: sql`coalesce(${juniorIdentities.handle}, excluded.handle)`,
|
|
154
|
+
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`,
|
|
155
|
+
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`,
|
|
156
|
+
emailVerified: sql`${juniorIdentities.emailVerified} OR excluded.email_verified`,
|
|
157
|
+
avatarUrl: sql`coalesce(${juniorIdentities.avatarUrl}, excluded.avatar_url)`,
|
|
158
|
+
metadata: sql`coalesce(${juniorIdentities.metadata}, excluded.metadata_json)`,
|
|
159
|
+
updatedAt: sql`excluded.updated_at`
|
|
326
160
|
}
|
|
327
161
|
}).returning({
|
|
328
162
|
id: juniorIdentities.id,
|
|
@@ -712,63 +546,6 @@ var SqlStore = class {
|
|
|
712
546
|
}
|
|
713
547
|
});
|
|
714
548
|
}
|
|
715
|
-
/** Copy one conversation record and retained metrics into SQL during backfill. */
|
|
716
|
-
async backfillConversation(sourceConversation, metrics) {
|
|
717
|
-
const { visibility: _visibility, ...conversation } = sourceConversation;
|
|
718
|
-
await this.withConversationMutation(
|
|
719
|
-
conversation.conversationId,
|
|
720
|
-
async () => {
|
|
721
|
-
const existing = await this.get({
|
|
722
|
-
conversationId: conversation.conversationId
|
|
723
|
-
});
|
|
724
|
-
const sourceExecutionAtMs = conversation.execution.updatedAtMs ?? conversation.updatedAtMs;
|
|
725
|
-
const existingExecutionAtMs = existing === void 0 ? void 0 : existing.execution.updatedAtMs ?? existing.updatedAtMs;
|
|
726
|
-
const refreshExecutionFromSource = existingExecutionAtMs === void 0 || sourceExecutionAtMs >= existingExecutionAtMs;
|
|
727
|
-
const mergedConversation = existing ? {
|
|
728
|
-
...conversation,
|
|
729
|
-
channelName: existing.channelName ?? conversation.channelName,
|
|
730
|
-
createdAtMs: Math.min(
|
|
731
|
-
existing.createdAtMs,
|
|
732
|
-
conversation.createdAtMs
|
|
733
|
-
),
|
|
734
|
-
destination: existing.destination ?? conversation.destination,
|
|
735
|
-
lastActivityAtMs: Math.max(
|
|
736
|
-
existing.lastActivityAtMs,
|
|
737
|
-
conversation.lastActivityAtMs
|
|
738
|
-
),
|
|
739
|
-
actor: existing.actor ?? conversation.actor,
|
|
740
|
-
source: existing.source ?? conversation.source,
|
|
741
|
-
title: existing.title ?? conversation.title,
|
|
742
|
-
updatedAtMs: Math.max(
|
|
743
|
-
existing.updatedAtMs,
|
|
744
|
-
conversation.updatedAtMs
|
|
745
|
-
),
|
|
746
|
-
execution: refreshExecutionFromSource ? conversation.execution : existing.execution
|
|
747
|
-
} : conversation;
|
|
748
|
-
await this.upsertConversation({ conversation: mergedConversation });
|
|
749
|
-
if (metrics) {
|
|
750
|
-
await this.executor.db().update(juniorConversations).set({
|
|
751
|
-
durationMs: metrics.durationMs,
|
|
752
|
-
usage: metrics.usage ?? null,
|
|
753
|
-
...refreshExecutionFromSource ? {
|
|
754
|
-
metricRunId: conversation.execution.runId ?? null,
|
|
755
|
-
executionDurationMs: metrics.executionDurationMs,
|
|
756
|
-
executionUsage: metrics.executionUsage ?? null
|
|
757
|
-
} : {}
|
|
758
|
-
}).where(
|
|
759
|
-
and2(
|
|
760
|
-
eq2(
|
|
761
|
-
juniorConversations.conversationId,
|
|
762
|
-
conversation.conversationId
|
|
763
|
-
),
|
|
764
|
-
eq2(juniorConversations.durationMs, 0),
|
|
765
|
-
isNull(juniorConversations.usage)
|
|
766
|
-
)
|
|
767
|
-
);
|
|
768
|
-
}
|
|
769
|
-
}
|
|
770
|
-
);
|
|
771
|
-
}
|
|
772
549
|
async listByActivity(args = {}) {
|
|
773
550
|
const rows = await this.executor.db().select({
|
|
774
551
|
conversation: juniorConversations,
|
|
@@ -838,9 +615,9 @@ var SqlStore = class {
|
|
|
838
615
|
/** Upsert the conversation row while preserving previously discovered nullable metadata fields. */
|
|
839
616
|
async upsertConversation(args) {
|
|
840
617
|
const { conversation } = args;
|
|
841
|
-
const incomingExecutionVersion =
|
|
842
|
-
const currentExecutionVersion =
|
|
843
|
-
const incomingExecutionIsFresh =
|
|
618
|
+
const incomingExecutionVersion = sql2`coalesce(excluded.execution_updated_at, excluded.updated_at)`;
|
|
619
|
+
const currentExecutionVersion = sql2`coalesce(${juniorConversations.executionUpdatedAt}, ${juniorConversations.updatedAt})`;
|
|
620
|
+
const incomingExecutionIsFresh = sql2`${incomingExecutionVersion} >= ${currentExecutionVersion}`;
|
|
844
621
|
const destinationId = await this.upsertDestination(
|
|
845
622
|
destinationUpsertFromDestination({
|
|
846
623
|
channelName: conversation.channelName,
|
|
@@ -856,7 +633,12 @@ var SqlStore = class {
|
|
|
856
633
|
actorIdentityObservation,
|
|
857
634
|
conversation.updatedAtMs
|
|
858
635
|
) : void 0;
|
|
859
|
-
|
|
636
|
+
const rootConversationId = conversation.lineage ? sql2`(
|
|
637
|
+
select parent.root_conversation_id
|
|
638
|
+
from junior_conversations parent
|
|
639
|
+
where parent.conversation_id = ${conversation.lineage.parentConversationId}
|
|
640
|
+
)` : conversation.conversationId;
|
|
641
|
+
const rows = await this.executor.db().insert(juniorConversations).values({
|
|
860
642
|
conversationId: conversation.conversationId,
|
|
861
643
|
schemaVersion: 1,
|
|
862
644
|
source: conversation.source ?? null,
|
|
@@ -879,36 +661,43 @@ var SqlStore = class {
|
|
|
879
661
|
runId: conversation.execution.runId ?? null,
|
|
880
662
|
lastCheckpointAt: conversation.execution.lastCheckpointAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastCheckpointAtMs),
|
|
881
663
|
lastEnqueuedAt: conversation.execution.lastEnqueuedAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastEnqueuedAtMs),
|
|
882
|
-
parentConversationId: conversation.lineage?.parentConversationId ?? null
|
|
664
|
+
parentConversationId: conversation.lineage?.parentConversationId ?? null,
|
|
665
|
+
rootConversationId
|
|
883
666
|
}).onConflictDoUpdate({
|
|
884
667
|
target: juniorConversations.conversationId,
|
|
885
668
|
set: {
|
|
886
|
-
source:
|
|
887
|
-
originType:
|
|
888
|
-
originId:
|
|
889
|
-
originRunId:
|
|
890
|
-
destinationId:
|
|
891
|
-
actorIdentityId:
|
|
892
|
-
creatorIdentityId:
|
|
893
|
-
credentialSubjectIdentityId:
|
|
894
|
-
channelName:
|
|
895
|
-
title:
|
|
896
|
-
createdAt:
|
|
897
|
-
lastActivityAt:
|
|
898
|
-
updatedAt:
|
|
899
|
-
executionUpdatedAt:
|
|
900
|
-
executionStatus:
|
|
901
|
-
runId:
|
|
902
|
-
lastCheckpointAt:
|
|
903
|
-
lastEnqueuedAt:
|
|
669
|
+
source: sql2`coalesce(excluded.source, ${juniorConversations.source})`,
|
|
670
|
+
originType: sql2`coalesce(excluded.origin_type, ${juniorConversations.originType})`,
|
|
671
|
+
originId: sql2`coalesce(excluded.origin_id, ${juniorConversations.originId})`,
|
|
672
|
+
originRunId: sql2`coalesce(excluded.origin_run_id, ${juniorConversations.originRunId})`,
|
|
673
|
+
destinationId: sql2`coalesce(excluded.destination_id, ${juniorConversations.destinationId})`,
|
|
674
|
+
actorIdentityId: sql2`coalesce(excluded.actor_identity_id, ${juniorConversations.actorIdentityId})`,
|
|
675
|
+
creatorIdentityId: sql2`coalesce(excluded.creator_identity_id, ${juniorConversations.creatorIdentityId})`,
|
|
676
|
+
credentialSubjectIdentityId: sql2`coalesce(excluded.credential_subject_identity_id, ${juniorConversations.credentialSubjectIdentityId})`,
|
|
677
|
+
channelName: sql2`coalesce(excluded.channel_name, ${juniorConversations.channelName})`,
|
|
678
|
+
title: sql2`coalesce(excluded.title, ${juniorConversations.title})`,
|
|
679
|
+
createdAt: sql2`least(${juniorConversations.createdAt}, excluded.created_at)`,
|
|
680
|
+
lastActivityAt: sql2`greatest(${juniorConversations.lastActivityAt}, excluded.last_activity_at)`,
|
|
681
|
+
updatedAt: sql2`greatest(${juniorConversations.updatedAt}, excluded.updated_at)`,
|
|
682
|
+
executionUpdatedAt: sql2`case when ${incomingExecutionIsFresh} then excluded.execution_updated_at else ${juniorConversations.executionUpdatedAt} end`,
|
|
683
|
+
executionStatus: sql2`case when ${incomingExecutionIsFresh} then excluded.execution_status else ${juniorConversations.executionStatus} end`,
|
|
684
|
+
runId: sql2`case when ${incomingExecutionIsFresh} then excluded.run_id else ${juniorConversations.runId} end`,
|
|
685
|
+
lastCheckpointAt: sql2`case when ${incomingExecutionIsFresh} then coalesce(excluded.last_checkpoint_at, ${juniorConversations.lastCheckpointAt}) else ${juniorConversations.lastCheckpointAt} end`,
|
|
686
|
+
lastEnqueuedAt: sql2`case when ${incomingExecutionIsFresh} then coalesce(excluded.last_enqueued_at, ${juniorConversations.lastEnqueuedAt}) else ${juniorConversations.lastEnqueuedAt} end`,
|
|
687
|
+
rootConversationId: sql2`coalesce(${juniorConversations.rootConversationId}, excluded.root_conversation_id)`
|
|
904
688
|
}
|
|
689
|
+
}).returning({
|
|
690
|
+
rootConversationId: juniorConversations.rootConversationId
|
|
905
691
|
});
|
|
692
|
+
if (!rows[0]?.rootConversationId) {
|
|
693
|
+
throw new Error("Conversation parent is missing its persisted root");
|
|
694
|
+
}
|
|
906
695
|
}
|
|
907
696
|
async upsertDestination(destination, nowMs) {
|
|
908
697
|
if (!destination) {
|
|
909
698
|
return void 0;
|
|
910
699
|
}
|
|
911
|
-
const visibilityUpdate = destination.refreshVisibility ?
|
|
700
|
+
const visibilityUpdate = destination.refreshVisibility ? sql2`excluded.visibility` : juniorDestinations.visibility;
|
|
912
701
|
const rows = await this.executor.db().insert(juniorDestinations).values({
|
|
913
702
|
id: randomUUID2(),
|
|
914
703
|
provider: destination.provider,
|
|
@@ -928,14 +717,14 @@ var SqlStore = class {
|
|
|
928
717
|
juniorDestinations.providerDestinationId
|
|
929
718
|
],
|
|
930
719
|
set: {
|
|
931
|
-
kind:
|
|
932
|
-
displayName:
|
|
720
|
+
kind: sql2`excluded.kind`,
|
|
721
|
+
displayName: sql2`coalesce(excluded.display_name, ${juniorDestinations.displayName})`,
|
|
933
722
|
// Signal-less writes insert as private but must not clobber an
|
|
934
723
|
// existing public/private value. Live source signals refresh this
|
|
935
724
|
// field so converted channels converge on the next message.
|
|
936
725
|
visibility: visibilityUpdate,
|
|
937
|
-
metadata:
|
|
938
|
-
updatedAt:
|
|
726
|
+
metadata: sql2`coalesce(excluded.metadata_json, ${juniorDestinations.metadata})`,
|
|
727
|
+
updatedAt: sql2`excluded.updated_at`
|
|
939
728
|
}
|
|
940
729
|
}).returning({ id: juniorDestinations.id });
|
|
941
730
|
return rows[0]?.id;
|
|
@@ -955,7 +744,7 @@ import {
|
|
|
955
744
|
inArray,
|
|
956
745
|
isNotNull,
|
|
957
746
|
lte,
|
|
958
|
-
sql as
|
|
747
|
+
sql as sql4
|
|
959
748
|
} from "drizzle-orm";
|
|
960
749
|
|
|
961
750
|
// src/chat/conversations/history.ts
|
|
@@ -1025,6 +814,7 @@ var historyReplacementEventDataSchema = z2.discriminatedUnion("type", [
|
|
|
1025
814
|
type: z2.literal("handoff"),
|
|
1026
815
|
modelProfile: handoffModelProfileSchema,
|
|
1027
816
|
modelId: z2.string().min(1),
|
|
817
|
+
reasoningLevel: z2.string().min(1).optional(),
|
|
1028
818
|
triggeringToolCallId: z2.string().min(1).optional(),
|
|
1029
819
|
replacementHistory: replacementHistorySchema
|
|
1030
820
|
}).strict(),
|
|
@@ -1244,7 +1034,7 @@ var newConversationEventSchema = z2.object({
|
|
|
1244
1034
|
}).strict();
|
|
1245
1035
|
|
|
1246
1036
|
// src/chat/conversations/sql/conversation-row.ts
|
|
1247
|
-
import { sql as
|
|
1037
|
+
import { sql as sql3 } from "drizzle-orm";
|
|
1248
1038
|
async function ensureConversationRow(executor, conversationId, atMs) {
|
|
1249
1039
|
const at = new Date(atMs);
|
|
1250
1040
|
await executor.db().insert(juniorConversations).values({
|
|
@@ -1256,8 +1046,8 @@ async function ensureConversationRow(executor, conversationId, atMs) {
|
|
|
1256
1046
|
}).onConflictDoUpdate({
|
|
1257
1047
|
target: juniorConversations.conversationId,
|
|
1258
1048
|
set: {
|
|
1259
|
-
lastActivityAt:
|
|
1260
|
-
updatedAt:
|
|
1049
|
+
lastActivityAt: sql3`greatest(${juniorConversations.lastActivityAt}, excluded.last_activity_at)`,
|
|
1050
|
+
updatedAt: sql3`greatest(${juniorConversations.updatedAt}, excluded.updated_at)`,
|
|
1261
1051
|
transcriptPurgedAt: null
|
|
1262
1052
|
}
|
|
1263
1053
|
});
|
|
@@ -1471,8 +1261,8 @@ var SqlConversationEventStore = class {
|
|
|
1471
1261
|
/** Read the next sequence and active model-history version. */
|
|
1472
1262
|
async readCursor(conversationId) {
|
|
1473
1263
|
const rows = await this.executor.db().select({
|
|
1474
|
-
maxSeq:
|
|
1475
|
-
maxHistoryVersion:
|
|
1264
|
+
maxSeq: sql4`max(${juniorConversationEvents.seq})`,
|
|
1265
|
+
maxHistoryVersion: sql4`max(${juniorConversationEvents.historyVersion})`
|
|
1476
1266
|
}).from(juniorConversationEvents).where(eq3(juniorConversationEvents.conversationId, conversationId));
|
|
1477
1267
|
const maxSeq = rows[0]?.maxSeq;
|
|
1478
1268
|
const maxHistoryVersion = rows[0]?.maxHistoryVersion;
|
|
@@ -1487,7 +1277,7 @@ function createSqlConversationEventStore(executor) {
|
|
|
1487
1277
|
}
|
|
1488
1278
|
|
|
1489
1279
|
// src/chat/conversations/sql/search.ts
|
|
1490
|
-
import { and as and4, desc as desc3, eq as eq4, isNull as isNull2, ne, sql as
|
|
1280
|
+
import { and as and4, desc as desc3, eq as eq4, isNull as isNull2, ne, sql as sql5 } from "drizzle-orm";
|
|
1491
1281
|
var SqlConversationSearchStore = class {
|
|
1492
1282
|
constructor(executor) {
|
|
1493
1283
|
this.executor = executor;
|
|
@@ -1495,12 +1285,12 @@ var SqlConversationSearchStore = class {
|
|
|
1495
1285
|
executor;
|
|
1496
1286
|
async search(args) {
|
|
1497
1287
|
const db = this.executor.db();
|
|
1498
|
-
const tsquery =
|
|
1499
|
-
const
|
|
1500
|
-
const rank =
|
|
1501
|
-
const excerpt =
|
|
1502
|
-
const role =
|
|
1503
|
-
const messageId =
|
|
1288
|
+
const tsquery = sql5`websearch_to_tsquery('english', ${args.query})`;
|
|
1289
|
+
const text = sql5`${juniorConversationEvents.payload}->>'text'`;
|
|
1290
|
+
const rank = sql5`ts_rank_cd(to_tsvector('english', ${text}), ${tsquery})`;
|
|
1291
|
+
const excerpt = sql5`ts_headline('english', ${text}, ${tsquery}, 'MaxFragments=2, MinWords=8, MaxWords=40, FragmentDelimiter=" … ", StartSel=**, StopSel=**')`;
|
|
1292
|
+
const role = sql5`${juniorConversationEvents.payload}->>'role'`;
|
|
1293
|
+
const messageId = sql5`${juniorConversationEvents.payload}->>'messageId'`;
|
|
1504
1294
|
const bestPerConversation = db.selectDistinctOn([juniorConversations.conversationId], {
|
|
1505
1295
|
conversationId: juniorConversations.conversationId,
|
|
1506
1296
|
excerpt: excerpt.as("excerpt"),
|
|
@@ -1529,8 +1319,8 @@ var SqlConversationSearchStore = class {
|
|
|
1529
1319
|
eq4(juniorDestinations.providerTenantId, args.scope.providerTenantId),
|
|
1530
1320
|
eq4(juniorDestinations.visibility, "public"),
|
|
1531
1321
|
eq4(juniorConversationEvents.type, "message"),
|
|
1532
|
-
|
|
1533
|
-
|
|
1322
|
+
sql5`${role} in ('user', 'assistant')`,
|
|
1323
|
+
sql5`to_tsvector('english', ${text}) @@ ${tsquery}`
|
|
1534
1324
|
)
|
|
1535
1325
|
).orderBy(
|
|
1536
1326
|
juniorConversations.conversationId,
|
|
@@ -1555,252 +1345,6 @@ function createSqlConversationSearchStore(executor) {
|
|
|
1555
1345
|
return new SqlConversationSearchStore(executor);
|
|
1556
1346
|
}
|
|
1557
1347
|
|
|
1558
|
-
// src/db/neon.ts
|
|
1559
|
-
import { AsyncLocalStorage } from "async_hooks";
|
|
1560
|
-
import {
|
|
1561
|
-
Pool
|
|
1562
|
-
} from "@neondatabase/serverless";
|
|
1563
|
-
import { drizzle } from "drizzle-orm/neon-serverless";
|
|
1564
|
-
import { migrate } from "drizzle-orm/neon-serverless/migrator";
|
|
1565
|
-
var NeonExecutor = class {
|
|
1566
|
-
constructor(pool) {
|
|
1567
|
-
this.pool = pool;
|
|
1568
|
-
}
|
|
1569
|
-
pool;
|
|
1570
|
-
transactionClient = new AsyncLocalStorage();
|
|
1571
|
-
savepointId = 0;
|
|
1572
|
-
db() {
|
|
1573
|
-
return drizzle(this.queryClient(), {
|
|
1574
|
-
schema: juniorSqlSchema
|
|
1575
|
-
});
|
|
1576
|
-
}
|
|
1577
|
-
async execute(statement, params = []) {
|
|
1578
|
-
await this.queryClient().query(statement, [...params]);
|
|
1579
|
-
}
|
|
1580
|
-
async query(statement, params = []) {
|
|
1581
|
-
const result = await this.queryClient().query(statement, [
|
|
1582
|
-
...params
|
|
1583
|
-
]);
|
|
1584
|
-
return result.rows;
|
|
1585
|
-
}
|
|
1586
|
-
async migrate(config) {
|
|
1587
|
-
await migrate(
|
|
1588
|
-
drizzle(this.queryClient(), { schema: juniorSqlSchema }),
|
|
1589
|
-
config
|
|
1590
|
-
);
|
|
1591
|
-
}
|
|
1592
|
-
async transaction(callback) {
|
|
1593
|
-
const existingClient = this.transactionClient.getStore();
|
|
1594
|
-
if (existingClient) {
|
|
1595
|
-
const savepoint = `junior_savepoint_${++this.savepointId}`;
|
|
1596
|
-
await existingClient.query(`SAVEPOINT ${savepoint}`);
|
|
1597
|
-
try {
|
|
1598
|
-
const result = await callback();
|
|
1599
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
1600
|
-
return result;
|
|
1601
|
-
} catch (error) {
|
|
1602
|
-
await existingClient.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
1603
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
1604
|
-
throw error;
|
|
1605
|
-
}
|
|
1606
|
-
}
|
|
1607
|
-
const client = await this.pool.connect();
|
|
1608
|
-
try {
|
|
1609
|
-
await client.query("BEGIN");
|
|
1610
|
-
const result = await this.transactionClient.run(client, callback);
|
|
1611
|
-
await client.query("COMMIT");
|
|
1612
|
-
return result;
|
|
1613
|
-
} catch (error) {
|
|
1614
|
-
await client.query("ROLLBACK");
|
|
1615
|
-
throw error;
|
|
1616
|
-
} finally {
|
|
1617
|
-
client.release();
|
|
1618
|
-
}
|
|
1619
|
-
}
|
|
1620
|
-
async withLock(lockName, callback) {
|
|
1621
|
-
if (!lockName) {
|
|
1622
|
-
throw new Error("SQL lock name is required");
|
|
1623
|
-
}
|
|
1624
|
-
const existingClient = this.transactionClient.getStore();
|
|
1625
|
-
if (existingClient) {
|
|
1626
|
-
await existingClient.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1627
|
-
lockName
|
|
1628
|
-
]);
|
|
1629
|
-
return await callback();
|
|
1630
|
-
}
|
|
1631
|
-
const client = await this.pool.connect();
|
|
1632
|
-
try {
|
|
1633
|
-
await client.query("BEGIN");
|
|
1634
|
-
return await this.transactionClient.run(client, async () => {
|
|
1635
|
-
try {
|
|
1636
|
-
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1637
|
-
lockName
|
|
1638
|
-
]);
|
|
1639
|
-
const result = await callback();
|
|
1640
|
-
await client.query("COMMIT");
|
|
1641
|
-
return result;
|
|
1642
|
-
} catch (error) {
|
|
1643
|
-
await client.query("ROLLBACK");
|
|
1644
|
-
throw error;
|
|
1645
|
-
}
|
|
1646
|
-
});
|
|
1647
|
-
} finally {
|
|
1648
|
-
client.release();
|
|
1649
|
-
}
|
|
1650
|
-
}
|
|
1651
|
-
async withMigrationLock(migrationTable, callback) {
|
|
1652
|
-
const client = await this.pool.connect();
|
|
1653
|
-
const lockName = `junior:migrate:${migrationTable}`;
|
|
1654
|
-
try {
|
|
1655
|
-
await client.query("SELECT pg_advisory_lock(hashtext($1))", [lockName]);
|
|
1656
|
-
return await callback();
|
|
1657
|
-
} finally {
|
|
1658
|
-
client.release(true);
|
|
1659
|
-
}
|
|
1660
|
-
}
|
|
1661
|
-
async close() {
|
|
1662
|
-
await this.pool.end();
|
|
1663
|
-
}
|
|
1664
|
-
queryClient() {
|
|
1665
|
-
return this.transactionClient.getStore() ?? this.pool;
|
|
1666
|
-
}
|
|
1667
|
-
};
|
|
1668
|
-
function createNeonJuniorSqlExecutor(args) {
|
|
1669
|
-
return new NeonExecutor(
|
|
1670
|
-
new Pool({
|
|
1671
|
-
connectionString: args.connectionString,
|
|
1672
|
-
max: 3
|
|
1673
|
-
})
|
|
1674
|
-
);
|
|
1675
|
-
}
|
|
1676
|
-
|
|
1677
|
-
// src/db/postgres.ts
|
|
1678
|
-
import { AsyncLocalStorage as AsyncLocalStorage2 } from "async_hooks";
|
|
1679
|
-
import pg from "pg";
|
|
1680
|
-
import { drizzle as drizzle2 } from "drizzle-orm/node-postgres";
|
|
1681
|
-
import { migrate as migrate2 } from "drizzle-orm/node-postgres/migrator";
|
|
1682
|
-
var { Pool: Pool2 } = pg;
|
|
1683
|
-
var PostgresExecutor = class {
|
|
1684
|
-
constructor(pool) {
|
|
1685
|
-
this.pool = pool;
|
|
1686
|
-
}
|
|
1687
|
-
pool;
|
|
1688
|
-
transactionClient = new AsyncLocalStorage2();
|
|
1689
|
-
savepointId = 0;
|
|
1690
|
-
db() {
|
|
1691
|
-
return drizzle2(this.queryClient(), {
|
|
1692
|
-
schema: juniorSqlSchema
|
|
1693
|
-
});
|
|
1694
|
-
}
|
|
1695
|
-
async execute(statement, params = []) {
|
|
1696
|
-
await this.queryClient().query(statement, [...params]);
|
|
1697
|
-
}
|
|
1698
|
-
async query(statement, params = []) {
|
|
1699
|
-
const result = await this.queryClient().query(statement, [
|
|
1700
|
-
...params
|
|
1701
|
-
]);
|
|
1702
|
-
return result.rows;
|
|
1703
|
-
}
|
|
1704
|
-
async migrate(config) {
|
|
1705
|
-
await migrate2(
|
|
1706
|
-
drizzle2(this.queryClient(), { schema: juniorSqlSchema }),
|
|
1707
|
-
config
|
|
1708
|
-
);
|
|
1709
|
-
}
|
|
1710
|
-
async transaction(callback) {
|
|
1711
|
-
const existingClient = this.transactionClient.getStore();
|
|
1712
|
-
if (existingClient) {
|
|
1713
|
-
const savepoint = `junior_savepoint_${++this.savepointId}`;
|
|
1714
|
-
await existingClient.query(`SAVEPOINT ${savepoint}`);
|
|
1715
|
-
try {
|
|
1716
|
-
const result = await callback();
|
|
1717
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
1718
|
-
return result;
|
|
1719
|
-
} catch (error) {
|
|
1720
|
-
await existingClient.query(`ROLLBACK TO SAVEPOINT ${savepoint}`);
|
|
1721
|
-
await existingClient.query(`RELEASE SAVEPOINT ${savepoint}`);
|
|
1722
|
-
throw error;
|
|
1723
|
-
}
|
|
1724
|
-
}
|
|
1725
|
-
const client = await this.pool.connect();
|
|
1726
|
-
try {
|
|
1727
|
-
await client.query("BEGIN");
|
|
1728
|
-
const result = await this.transactionClient.run(client, callback);
|
|
1729
|
-
await client.query("COMMIT");
|
|
1730
|
-
return result;
|
|
1731
|
-
} catch (error) {
|
|
1732
|
-
await client.query("ROLLBACK");
|
|
1733
|
-
throw error;
|
|
1734
|
-
} finally {
|
|
1735
|
-
client.release();
|
|
1736
|
-
}
|
|
1737
|
-
}
|
|
1738
|
-
async withLock(lockName, callback) {
|
|
1739
|
-
if (!lockName) {
|
|
1740
|
-
throw new Error("SQL lock name is required");
|
|
1741
|
-
}
|
|
1742
|
-
const existingClient = this.transactionClient.getStore();
|
|
1743
|
-
if (existingClient) {
|
|
1744
|
-
await existingClient.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1745
|
-
lockName
|
|
1746
|
-
]);
|
|
1747
|
-
return await callback();
|
|
1748
|
-
}
|
|
1749
|
-
const client = await this.pool.connect();
|
|
1750
|
-
try {
|
|
1751
|
-
await client.query("BEGIN");
|
|
1752
|
-
return await this.transactionClient.run(client, async () => {
|
|
1753
|
-
try {
|
|
1754
|
-
await client.query("SELECT pg_advisory_xact_lock(hashtext($1))", [
|
|
1755
|
-
lockName
|
|
1756
|
-
]);
|
|
1757
|
-
const result = await callback();
|
|
1758
|
-
await client.query("COMMIT");
|
|
1759
|
-
return result;
|
|
1760
|
-
} catch (error) {
|
|
1761
|
-
await client.query("ROLLBACK");
|
|
1762
|
-
throw error;
|
|
1763
|
-
}
|
|
1764
|
-
});
|
|
1765
|
-
} finally {
|
|
1766
|
-
client.release();
|
|
1767
|
-
}
|
|
1768
|
-
}
|
|
1769
|
-
async withMigrationLock(migrationTable, callback) {
|
|
1770
|
-
const client = await this.pool.connect();
|
|
1771
|
-
const lockName = `junior:migrate:${migrationTable}`;
|
|
1772
|
-
try {
|
|
1773
|
-
await client.query("SELECT pg_advisory_lock(hashtext($1))", [lockName]);
|
|
1774
|
-
return await callback();
|
|
1775
|
-
} finally {
|
|
1776
|
-
client.release(true);
|
|
1777
|
-
}
|
|
1778
|
-
}
|
|
1779
|
-
async close() {
|
|
1780
|
-
await this.pool.end();
|
|
1781
|
-
}
|
|
1782
|
-
queryClient() {
|
|
1783
|
-
return this.transactionClient.getStore() ?? this.pool;
|
|
1784
|
-
}
|
|
1785
|
-
};
|
|
1786
|
-
function createPostgresJuniorSqlExecutor(args) {
|
|
1787
|
-
return new PostgresExecutor(
|
|
1788
|
-
new Pool2({
|
|
1789
|
-
application_name: args.applicationName,
|
|
1790
|
-
connectionString: args.connectionString,
|
|
1791
|
-
max: 3
|
|
1792
|
-
})
|
|
1793
|
-
);
|
|
1794
|
-
}
|
|
1795
|
-
|
|
1796
|
-
// src/db/executor.ts
|
|
1797
|
-
function createJuniorSqlExecutor(args) {
|
|
1798
|
-
if (args.driver === "postgres") {
|
|
1799
|
-
return createPostgresJuniorSqlExecutor(args);
|
|
1800
|
-
}
|
|
1801
|
-
return createNeonJuniorSqlExecutor(args);
|
|
1802
|
-
}
|
|
1803
|
-
|
|
1804
1348
|
// src/chat/db.ts
|
|
1805
1349
|
var current;
|
|
1806
1350
|
function createDb(args) {
|
|
@@ -1810,20 +1354,20 @@ function createDb(args) {
|
|
|
1810
1354
|
});
|
|
1811
1355
|
}
|
|
1812
1356
|
function getSqlExecutor() {
|
|
1813
|
-
const { sql:
|
|
1814
|
-
if (current?.databaseUrl !==
|
|
1357
|
+
const { sql: sql6 } = getChatConfig();
|
|
1358
|
+
if (current?.databaseUrl !== sql6.databaseUrl || current.driver !== sql6.driver) {
|
|
1815
1359
|
if (current) {
|
|
1816
1360
|
const previous = current;
|
|
1817
1361
|
current = void 0;
|
|
1818
1362
|
void previous.db.close().catch(() => void 0);
|
|
1819
1363
|
}
|
|
1820
1364
|
const db = createDb({
|
|
1821
|
-
databaseUrl:
|
|
1822
|
-
driver:
|
|
1365
|
+
databaseUrl: sql6.databaseUrl,
|
|
1366
|
+
driver: sql6.driver
|
|
1823
1367
|
});
|
|
1824
1368
|
current = {
|
|
1825
|
-
databaseUrl:
|
|
1826
|
-
driver:
|
|
1369
|
+
databaseUrl: sql6.databaseUrl,
|
|
1370
|
+
driver: sql6.driver,
|
|
1827
1371
|
db,
|
|
1828
1372
|
store: createSqlStore(db),
|
|
1829
1373
|
eventStore: createSqlConversationEventStore(db),
|
|
@@ -1854,22 +1398,18 @@ async function closeDb() {
|
|
|
1854
1398
|
}
|
|
1855
1399
|
|
|
1856
1400
|
export {
|
|
1857
|
-
|
|
1858
|
-
|
|
1859
|
-
|
|
1860
|
-
|
|
1861
|
-
|
|
1862
|
-
conversationMessageProvenanceSchema,
|
|
1401
|
+
createSlackDestination,
|
|
1402
|
+
parseDestination,
|
|
1403
|
+
requireSlackDestination,
|
|
1404
|
+
sameDestination,
|
|
1405
|
+
destinationKey,
|
|
1863
1406
|
instructionProvenanceFor,
|
|
1864
1407
|
contextProvenance,
|
|
1865
1408
|
instructionActors,
|
|
1866
|
-
conversationEventDataSchema,
|
|
1867
1409
|
decodeStoredConversationEvent,
|
|
1868
|
-
newConversationEventSchema,
|
|
1869
1410
|
sanitizePostgresJson,
|
|
1870
1411
|
withConversationEventLock,
|
|
1871
1412
|
createSqlConversationEventStore,
|
|
1872
|
-
createJuniorSqlExecutor,
|
|
1873
1413
|
getSqlExecutor,
|
|
1874
1414
|
getDb,
|
|
1875
1415
|
getConversationStore,
|