@sentry/junior 0.105.0 → 0.107.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (133) hide show
  1. package/dist/{agent-hooks-EOFSY2PD.js → agent-hooks-ICPIJAFY.js} +9 -7
  2. package/dist/api/conversations/detail.d.ts +1 -1
  3. package/dist/api/conversations/events.d.ts +14 -0
  4. package/dist/api/conversations/schema.d.ts +196 -463
  5. package/dist/api/schema.d.ts +2 -7
  6. package/dist/api/schema.js +10 -8
  7. package/dist/api.js +377 -810
  8. package/dist/app.js +2284 -2288
  9. package/dist/{catalog-runtime-5CVM2DOF.js → catalog-runtime-FOFNPR3P.js} +3 -2
  10. package/dist/chat/agent/prompt.d.ts +1 -1
  11. package/dist/chat/agent/request.d.ts +28 -29
  12. package/dist/chat/agent/resume.d.ts +7 -7
  13. package/dist/chat/agent/session.d.ts +5 -6
  14. package/dist/chat/agent/tools.d.ts +3 -3
  15. package/dist/chat/agent-dispatch/runner.d.ts +2 -0
  16. package/dist/chat/config.d.ts +3 -2
  17. package/dist/chat/conversations/history.d.ts +582 -167
  18. package/dist/chat/conversations/message-projection.d.ts +6 -0
  19. package/dist/chat/conversations/message-summaries.d.ts +9 -0
  20. package/dist/chat/conversations/messages.d.ts +13 -27
  21. package/dist/chat/conversations/projection.d.ts +30 -53
  22. package/dist/chat/conversations/provenance.d.ts +42 -0
  23. package/dist/chat/conversations/search.d.ts +2 -2
  24. package/dist/chat/conversations/sql/conversation-row.d.ts +1 -1
  25. package/dist/chat/conversations/sql/event-lock.d.ts +3 -0
  26. package/dist/chat/conversations/sql/history.d.ts +3 -3
  27. package/dist/chat/conversations/sql/privacy.d.ts +27 -0
  28. package/dist/chat/conversations/sql/purge.d.ts +2 -10
  29. package/dist/chat/conversations/sql/store.d.ts +0 -5
  30. package/dist/chat/conversations/store.d.ts +8 -13
  31. package/dist/chat/conversations/turn-lifecycle.d.ts +41 -0
  32. package/dist/chat/db.d.ts +4 -10
  33. package/dist/chat/model-profile.d.ts +10 -0
  34. package/dist/chat/oauth-flow.d.ts +0 -5
  35. package/dist/chat/pi/conversation-events.d.ts +33 -0
  36. package/dist/chat/pi/sql-model-usage.d.ts +10 -0
  37. package/dist/chat/plugins/agent-hooks.d.ts +4 -2
  38. package/dist/chat/resource-events/ingest.d.ts +0 -13
  39. package/dist/chat/runtime/delivered-turn-state.d.ts +1 -1
  40. package/dist/chat/runtime/generated-artifacts.d.ts +1 -1
  41. package/dist/chat/runtime/reply-executor.d.ts +2 -0
  42. package/dist/chat/runtime/slack-resume.d.ts +23 -28
  43. package/dist/chat/runtime/slack-runtime.d.ts +2 -0
  44. package/dist/chat/runtime/turn.d.ts +14 -1
  45. package/dist/chat/services/context-compaction-marker.d.ts +0 -1
  46. package/dist/chat/services/context-compaction.d.ts +1 -0
  47. package/dist/chat/services/conversation-memory.d.ts +9 -0
  48. package/dist/chat/services/plugin-auth-orchestration.d.ts +1 -4
  49. package/dist/chat/services/subscribed-decision.d.ts +1 -1
  50. package/dist/chat/services/turn-failure-response.d.ts +10 -3
  51. package/dist/chat/services/turn-limit.d.ts +6 -0
  52. package/dist/chat/services/turn-result.d.ts +7 -12
  53. package/dist/chat/services/{turn-reasoning-level.d.ts → turn-router.d.ts} +12 -8
  54. package/dist/chat/services/turn-session-record.d.ts +15 -17
  55. package/dist/chat/slack/adapter.d.ts +2 -2
  56. package/dist/chat/slack/errors.d.ts +2 -0
  57. package/dist/chat/slack/outbound.d.ts +0 -1
  58. package/dist/chat/slack/reply.d.ts +2 -8
  59. package/dist/chat/slack/tools/channel-capabilities.d.ts +2 -2
  60. package/dist/chat/slack/tools/{send-message.d.ts → send-files.d.ts} +27 -19
  61. package/dist/chat/state/conversation.d.ts +4 -4
  62. package/dist/chat/state/turn-id.d.ts +2 -0
  63. package/dist/chat/state/turn-session-keys.d.ts +6 -0
  64. package/dist/chat/state/turn-session.d.ts +11 -9
  65. package/dist/chat/task-execution/state.d.ts +6 -1
  66. package/dist/chat/task-execution/store.d.ts +1 -1
  67. package/dist/chat/tool-support/pi-tool-adapter.d.ts +1 -1
  68. package/dist/chat/tool-support/tool-execution-report.d.ts +1 -0
  69. package/dist/chat/tools/handoff/tool.d.ts +2 -2
  70. package/dist/chat/tools/sandbox/file-uploads.d.ts +28 -6
  71. package/dist/chat/tools/types.d.ts +6 -9
  72. package/dist/chat/tools/web/image-generate.d.ts +4 -6
  73. package/dist/{chunk-QDKRE3LS.js → chunk-4YF7Z6IA.js} +390 -270
  74. package/dist/{chunk-4PDVOHXP.js → chunk-AUUOHQAT.js} +2 -2
  75. package/dist/chunk-B2Z2H66D.js +250 -0
  76. package/dist/{chunk-QVTVCJR4.js → chunk-CQ7KSO2B.js} +75 -45
  77. package/dist/{chunk-MJSJAHBW.js → chunk-DY7TRYB5.js} +1 -1
  78. package/dist/{chunk-NJJFU6CP.js → chunk-EDLNHZH3.js} +883 -898
  79. package/dist/{chunk-O7ILGCMJ.js → chunk-IGHMVDWI.js} +134 -18
  80. package/dist/chunk-MU6HHZEN.js +99 -0
  81. package/dist/{chunk-BCULHGZK.js → chunk-NVOTGWYX.js} +458 -684
  82. package/dist/{chunk-AEWZ7F65.js → chunk-O24R4DCK.js} +2 -179
  83. package/dist/{chunk-CCFROYAV.js → chunk-PUAMO4PI.js} +115 -125
  84. package/dist/{chunk-VDHMFCDY.js → chunk-RMVOAJRL.js} +30 -13
  85. package/dist/{chunk-7G4J3CR7.js → chunk-SPUAJVVH.js} +6 -4
  86. package/dist/{chunk-M3UAVLEN.js → chunk-SS67LUOK.js} +43 -290
  87. package/dist/{chunk-FXFQNHRU.js → chunk-VFUK3X5B.js} +4 -2
  88. package/dist/{chunk-CCTCIISK.js → chunk-VH6KWKG2.js} +2 -2
  89. package/dist/chunk-VIXFG2VC.js +182 -0
  90. package/dist/{chunk-RMZ65YAA.js → chunk-YFQ7CQDE.js} +687 -21
  91. package/dist/{chunk-77LHNQK4.js → chunk-YIPD3L6L.js} +4 -2
  92. package/dist/{chunk-U26ZWZCN.js → chunk-YNP2ATQX.js} +6 -4
  93. package/dist/{chunk-WR7H7VLJ.js → chunk-YT72TOEK.js} +2 -2
  94. package/dist/cli/chat.js +21 -20
  95. package/dist/cli/check.js +4 -3
  96. package/dist/cli/plugins.js +11 -9
  97. package/dist/cli/snapshot-warmup.js +7 -5
  98. package/dist/cli/upgrade.js +2046 -105
  99. package/dist/db/schema/{agent-steps.d.ts → conversation-events.d.ts} +37 -21
  100. package/dist/db/schema.d.ts +28 -159
  101. package/dist/{db-PDMC67T3.js → db-DIGO4TGW.js} +6 -8
  102. package/dist/{runner-6A7MQRUE.js → runner-ACR2HAIC.js} +209 -101
  103. package/dist/{skills-722AXRV5.js → skills-ITNHBARB.js} +4 -3
  104. package/dist/{validation-EUI2UFRM.js → validation-AGQ46ZGV.js} +4 -3
  105. package/migrations/0005_conversation_events.sql +122 -0
  106. package/migrations/README.md +23 -10
  107. package/migrations/meta/0005_snapshot.json +948 -0
  108. package/migrations/meta/_journal.json +7 -0
  109. package/package.json +6 -6
  110. package/dist/api/conversations/activity.d.ts +0 -40
  111. package/dist/api/conversations/detail-projection.d.ts +0 -11
  112. package/dist/api/conversations/detail.query.d.ts +0 -3
  113. package/dist/api/conversations/subagent.d.ts +0 -10
  114. package/dist/api/conversations/transcript.d.ts +0 -28
  115. package/dist/chat/conversations/legacy-advisor-session.d.ts +0 -7
  116. package/dist/chat/conversations/legacy-import.d.ts +0 -38
  117. package/dist/chat/conversations/sql/legacy-history-import.d.ts +0 -55
  118. package/dist/chat/conversations/sql/messages.d.ts +0 -4
  119. package/dist/chat/conversations/visible-compactions.d.ts +0 -11
  120. package/dist/chat/conversations/visible-messages.d.ts +0 -47
  121. package/dist/chat/services/reply-delivery-plan.d.ts +0 -5
  122. package/dist/chat/state/session-log.d.ts +0 -384
  123. package/dist/chunk-RYDF4GOX.js +0 -1072
  124. package/dist/chunk-XIMUQ4IU.js +0 -147
  125. package/dist/db/schema/conversation-messages.d.ts +0 -153
  126. package/dist/handlers/github-webhook/check-suite.d.ts +0 -3
  127. package/dist/handlers/github-webhook/issue-comment.d.ts +0 -3
  128. package/dist/handlers/github-webhook/pull-request-review-comment.d.ts +0 -3
  129. package/dist/handlers/github-webhook/pull-request-review.d.ts +0 -3
  130. package/dist/handlers/github-webhook/pull-request.d.ts +0 -3
  131. package/dist/handlers/github-webhook/resource.d.ts +0 -10
  132. package/dist/handlers/github-webhook.d.ts +0 -15
  133. package/dist/legacy-import-G333RHJZ.js +0 -18
@@ -1,21 +1,18 @@
1
1
  import {
2
2
  getChatConfig,
3
- getConnectedStateContext,
4
- getStateAdapter,
5
3
  modelProfileSchema
6
- } from "./chunk-M3UAVLEN.js";
4
+ } from "./chunk-SS67LUOK.js";
7
5
  import {
8
6
  juniorDestinations,
9
7
  timestamptz
10
- } from "./chunk-FXFQNHRU.js";
8
+ } from "./chunk-VFUK3X5B.js";
11
9
  import {
12
10
  parseDestination,
13
11
  sameDestination
14
12
  } from "./chunk-B7PUBQQM.js";
15
13
  import {
16
- normalizeIdentityEmail,
17
- storedSlackActorSchema
18
- } from "./chunk-AEWZ7F65.js";
14
+ normalizeIdentityEmail
15
+ } from "./chunk-O24R4DCK.js";
19
16
 
20
17
  // src/chat/conversations/sql/store.ts
21
18
  import { randomUUID as randomUUID2 } from "crypto";
@@ -25,15 +22,18 @@ import { and as and2, asc, desc, eq as eq2, isNull, sql as sql5 } from "drizzle-
25
22
  import { randomUUID } from "crypto";
26
23
  import { and, eq, sql as sql4 } from "drizzle-orm";
27
24
 
28
- // src/db/schema/agent-steps.ts
25
+ // src/db/schema/conversation-events.ts
29
26
  import {
27
+ foreignKey,
30
28
  index as index3,
31
29
  integer as integer2,
32
30
  jsonb as jsonb3,
33
31
  pgTable as pgTable4,
34
32
  primaryKey,
35
- text as text4
33
+ text as text4,
34
+ uniqueIndex as uniqueIndex3
36
35
  } from "drizzle-orm/pg-core";
36
+ import { sql as sql3 } from "drizzle-orm";
37
37
 
38
38
  // src/db/schema/conversations.ts
39
39
  import { sql as sql2 } from "drizzle-orm";
@@ -183,62 +183,50 @@ var juniorConversations = pgTable3(
183
183
  ]
184
184
  );
185
185
 
186
- // src/db/schema/agent-steps.ts
187
- var juniorAgentSteps = pgTable4(
188
- "junior_agent_steps",
186
+ // src/db/schema/conversation-events.ts
187
+ var juniorConversationEvents = pgTable4(
188
+ "junior_conversation_events",
189
189
  {
190
- conversationId: text4("conversation_id").notNull().references(() => juniorConversations.conversationId),
190
+ conversationId: text4("conversation_id").notNull(),
191
191
  seq: integer2("seq").notNull(),
192
- contextEpoch: integer2("context_epoch").notNull(),
192
+ historyVersion: integer2("history_version").notNull(),
193
+ schemaVersion: integer2("schema_version").default(1).notNull(),
194
+ idempotencyKey: text4("idempotency_key"),
193
195
  type: text4("type").notNull(),
194
- role: text4("role"),
195
196
  payload: jsonb3("payload").$type().notNull(),
196
197
  createdAt: timestamptz("created_at").notNull()
197
198
  },
198
199
  (table) => [
199
- primaryKey({ columns: [table.conversationId, table.seq] }),
200
- index3("junior_agent_steps_epoch_idx").on(
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(
201
210
  table.conversationId,
202
- table.contextEpoch,
211
+ table.historyVersion,
203
212
  table.seq
204
- )
205
- ]
206
- );
207
-
208
- // src/db/schema/conversation-messages.ts
209
- import { sql as sql3 } from "drizzle-orm";
210
- import { index as index4, jsonb as jsonb4, pgTable as pgTable5, primaryKey as primaryKey2, text as text5 } from "drizzle-orm/pg-core";
211
- var juniorConversationMessages = pgTable5(
212
- "junior_conversation_messages",
213
- {
214
- conversationId: text5("conversation_id").notNull().references(() => juniorConversations.conversationId),
215
- messageId: text5("message_id").notNull(),
216
- role: text5("role").$type().notNull(),
217
- authorIdentityId: text5("author_identity_id").references(
218
- () => juniorIdentities.id
219
213
  ),
220
- text: text5("text").notNull(),
221
- meta: jsonb4("meta").$type(),
222
- repliedAt: timestamptz("replied_at"),
223
- createdAt: timestamptz("created_at").notNull()
224
- },
225
- (table) => [
226
- primaryKey2({ columns: [table.conversationId, table.messageId] }),
227
- index4("junior_conversation_messages_activity_idx").on(
214
+ index3("junior_conversation_events_type_idx").on(
228
215
  table.conversationId,
229
- table.createdAt
216
+ table.type,
217
+ table.seq
230
218
  ),
231
- index4("junior_conversation_messages_search_idx").using(
232
- "gin",
233
- sql3`to_tsvector('english', ${table.text})`
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
234
223
  )
235
224
  ]
236
225
  );
237
226
 
238
227
  // src/db/schema.ts
239
228
  var juniorSqlSchema = {
240
- juniorAgentSteps,
241
- juniorConversationMessages,
229
+ juniorConversationEvents,
242
230
  juniorConversations,
243
231
  juniorDestinations,
244
232
  juniorIdentities,
@@ -536,6 +524,11 @@ function conversationFromRow(readRow) {
536
524
  lastActivityAtMs: requiredMsFromDate(row.lastActivityAt),
537
525
  updatedAtMs: requiredMsFromDate(row.updatedAt),
538
526
  execution,
527
+ ...row.parentConversationId ? {
528
+ lineage: {
529
+ parentConversationId: row.parentConversationId
530
+ }
531
+ } : {},
539
532
  ...destination ? { destination } : {},
540
533
  ...actor ? { actor } : {},
541
534
  ...msFromDate(row.archivedAt) !== void 0 ? { archivedAtMs: msFromDate(row.archivedAt) } : {},
@@ -715,31 +708,6 @@ var SqlStore = class {
715
708
  }
716
709
  });
717
710
  }
718
- async ensureChildConversation(args) {
719
- const at = dateFromMs2(args.nowMs ?? now());
720
- await this.executor.db().insert(juniorConversations).values({
721
- conversationId: args.parentConversationId,
722
- schemaVersion: 1,
723
- createdAt: at,
724
- lastActivityAt: at,
725
- updatedAt: at,
726
- executionStatus: "idle"
727
- }).onConflictDoNothing({ target: juniorConversations.conversationId });
728
- await this.executor.db().insert(juniorConversations).values({
729
- conversationId: args.conversationId,
730
- schemaVersion: 1,
731
- parentConversationId: args.parentConversationId,
732
- createdAt: at,
733
- lastActivityAt: at,
734
- updatedAt: at,
735
- executionStatus: "idle"
736
- }).onConflictDoUpdate({
737
- target: juniorConversations.conversationId,
738
- set: {
739
- parentConversationId: sql5`coalesce(${juniorConversations.parentConversationId}, excluded.parent_conversation_id)`
740
- }
741
- });
742
- }
743
711
  /** Copy one conversation record and retained metrics into SQL during backfill. */
744
712
  async backfillConversation(sourceConversation, metrics) {
745
713
  const { visibility: _visibility, ...conversation } = sourceConversation;
@@ -904,7 +872,8 @@ var SqlStore = class {
904
872
  executionStatus: conversation.execution.status,
905
873
  runId: conversation.execution.runId ?? null,
906
874
  lastCheckpointAt: conversation.execution.lastCheckpointAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastCheckpointAtMs),
907
- lastEnqueuedAt: conversation.execution.lastEnqueuedAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastEnqueuedAtMs)
875
+ lastEnqueuedAt: conversation.execution.lastEnqueuedAtMs === void 0 ? null : dateFromMs2(conversation.execution.lastEnqueuedAtMs),
876
+ parentConversationId: conversation.lineage?.parentConversationId ?? null
908
877
  }).onConflictDoUpdate({
909
878
  target: juniorConversations.conversationId,
910
879
  set: {
@@ -971,99 +940,115 @@ function createSqlStore(executor) {
971
940
  }
972
941
 
973
942
  // src/chat/conversations/sql/history.ts
974
- import { and as and3, asc as asc2, eq as eq3, isNotNull, sql as sql7 } from "drizzle-orm";
943
+ import {
944
+ and as and3,
945
+ asc as asc2,
946
+ desc as desc2,
947
+ eq as eq3,
948
+ gte,
949
+ inArray,
950
+ isNotNull,
951
+ lte,
952
+ sql as sql7
953
+ } from "drizzle-orm";
975
954
 
976
955
  // src/chat/conversations/history.ts
977
- import { z as z3 } from "zod";
978
-
979
- // src/chat/pi/messages.ts
980
- import { z } from "zod";
981
- var piMessageSchema = z.object({
982
- role: z.string()
983
- }).passthrough().transform((value) => value);
984
- var piContentMessageSchema = z.object({
985
- content: z.array(z.unknown()),
986
- role: z.string().min(1)
987
- }).passthrough().transform((value) => value);
988
-
989
- // src/chat/state/session-log.ts
990
- import { isDeepStrictEqual } from "util";
991
956
  import { z as z2 } from "zod";
957
+
958
+ // src/chat/conversations/provenance.ts
992
959
  import { actorSchema } from "@sentry/junior-plugin-api";
993
- var AGENT_SESSION_LOG_PREFIX = "junior:agent-session-log";
994
- var AGENT_SESSION_LOG_SCHEMA_VERSION = 2;
995
- var INITIAL_SESSION_ID = "session_0";
996
- var STATE_STORE_LOCK_TTL_MS = 5e3;
997
- var schemaVersionSchema = z2.union([z2.literal(1), z2.literal(2)]);
998
- var piMessageAuthoritySchema = z2.union([
999
- z2.literal("instruction"),
1000
- z2.literal("context")
960
+ import { z } from "zod";
961
+ var conversationMessageAuthoritySchema = z.union([
962
+ z.literal("instruction"),
963
+ z.literal("context")
1001
964
  ]);
1002
- var piMessageProvenanceSchema = z2.object({
1003
- authority: piMessageAuthoritySchema,
965
+ var conversationMessageProvenanceSchema = z.object({
966
+ authority: conversationMessageAuthoritySchema,
1004
967
  actor: actorSchema.optional()
1005
968
  }).strict();
1006
- var unattributedContextProvenance = {
1007
- authority: "context"
1008
- };
1009
- function instructionProvenance(actor) {
969
+ function instructionProvenanceFor(actor) {
1010
970
  return actor ? { authority: "instruction", actor } : { authority: "instruction" };
1011
971
  }
1012
- function isDefaultContextProvenance(provenance) {
1013
- return provenance.authority === "context" && !provenance.actor;
972
+ var contextProvenance = {
973
+ authority: "context"
974
+ };
975
+ function actorIdentityKey(actor) {
976
+ if (actor.platform === "system") {
977
+ return `system ${actor.name}`;
978
+ }
979
+ return actor.platform === "slack" ? `slack\0${actor.teamId}\0${actor.userId}` : `${actor.platform}\0${actor.userId}`;
1014
980
  }
1015
- function legacyActorProvenance(actor) {
1016
- if (actor.teamId && actor.slackUserId && actor.platform) {
1017
- return instructionProvenance({
1018
- platform: "slack",
1019
- teamId: actor.teamId,
1020
- userId: actor.slackUserId,
1021
- ...actor.slackUserName ? { userName: actor.slackUserName } : {},
1022
- ...actor.fullName ? { fullName: actor.fullName } : {},
1023
- ...actor.email ? { email: actor.email } : {}
1024
- });
981
+ function instructionActors(provenance) {
982
+ const seen = /* @__PURE__ */ new Set();
983
+ const actors = [];
984
+ for (const entry of provenance) {
985
+ if (entry.authority !== "instruction" || !entry.actor) {
986
+ continue;
987
+ }
988
+ const identity = actorIdentityKey(entry.actor);
989
+ if (seen.has(identity)) {
990
+ continue;
991
+ }
992
+ seen.add(identity);
993
+ actors.push(entry.actor);
1025
994
  }
1026
- return unattributedContextProvenance;
995
+ return actors;
1027
996
  }
1028
- var piMessageEntrySchema = z2.object({
1029
- schemaVersion: schemaVersionSchema,
1030
- type: z2.literal("pi_message"),
1031
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1032
- message: piMessageSchema,
1033
- provenance: piMessageProvenanceSchema.optional(),
1034
- // Legacy v1 latest-wins actor, decoded into provenance on read.
1035
- actor: storedSlackActorSchema.optional()
1036
- });
1037
- var projectionResetEntrySchema = z2.object({
1038
- schemaVersion: schemaVersionSchema,
1039
- type: z2.literal("projection_reset"),
1040
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1041
- messages: z2.array(piMessageSchema),
1042
- provenance: z2.array(piMessageProvenanceSchema).optional(),
1043
- // Legacy v1 latest-wins actor; v1 resets carry no per-message provenance.
1044
- actor: storedSlackActorSchema.optional()
997
+
998
+ // src/chat/conversations/history.ts
999
+ var handoffModelProfileSchema = modelProfileSchema.refine(
1000
+ (profile) => profile !== "standard",
1001
+ "handoff profile must not be standard"
1002
+ );
1003
+ var conversationAgentStepPayloadSchema = z2.object({ role: z2.string() }).passthrough().transform((value) => value);
1004
+ var conversationMessageDataSchema = z2.object({
1005
+ message: conversationAgentStepPayloadSchema,
1006
+ provenance: conversationMessageProvenanceSchema.optional()
1007
+ }).strict();
1008
+ var agentStepEventDataSchema = conversationMessageDataSchema.extend({
1009
+ type: z2.literal("agent_step")
1045
1010
  });
1046
- var actorRecordedEntrySchema = z2.object({
1047
- schemaVersion: schemaVersionSchema,
1048
- type: z2.literal("actor_recorded"),
1049
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1050
- actor: storedSlackActorSchema
1011
+ var replacementHistoryMessageSchema = conversationMessageDataSchema.extend({
1012
+ // Preserve the copied message's position when a turn resumes. Synthetic
1013
+ // summary and handoff messages have no source event.
1014
+ sourceEventSeq: z2.number().int().nonnegative().optional()
1051
1015
  });
1052
- var mcpProviderConnectedEntrySchema = z2.object({
1053
- schemaVersion: schemaVersionSchema,
1016
+ var replacementHistorySchema = z2.array(replacementHistoryMessageSchema);
1017
+ var historyReplacementEventDataSchema = z2.discriminatedUnion("type", [
1018
+ z2.object({
1019
+ type: z2.literal("handoff"),
1020
+ modelProfile: handoffModelProfileSchema,
1021
+ modelId: z2.string().min(1),
1022
+ triggeringToolCallId: z2.string().min(1).optional(),
1023
+ replacementHistory: replacementHistorySchema
1024
+ }).strict(),
1025
+ z2.object({
1026
+ type: z2.literal("compaction"),
1027
+ modelProfile: modelProfileSchema,
1028
+ modelId: z2.string().min(1),
1029
+ replacementHistory: replacementHistorySchema
1030
+ }).strict()
1031
+ ]);
1032
+ var legacyRollbackEventDataSchema = z2.object({
1033
+ type: z2.literal("rollback"),
1034
+ modelProfile: modelProfileSchema,
1035
+ modelId: z2.string().min(1),
1036
+ replacementHistory: replacementHistorySchema
1037
+ }).strict();
1038
+ var historyReplacementSchema = z2.object({
1039
+ data: historyReplacementEventDataSchema,
1040
+ createdAtMs: z2.number().finite()
1041
+ }).strict();
1042
+ var mcpProviderConnectedEventDataSchema = z2.object({
1054
1043
  type: z2.literal("mcp_provider_connected"),
1055
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1056
1044
  provider: z2.string().min(1)
1057
- });
1045
+ }).strict();
1058
1046
  var authorizationKindSchema = z2.union([
1059
1047
  z2.literal("plugin"),
1060
1048
  z2.literal("mcp")
1061
1049
  ]);
1062
- var authorizationRequestedEntrySchema = z2.object({
1063
- schemaVersion: schemaVersionSchema,
1050
+ var authorizationRequestedEventDataSchema = z2.object({
1064
1051
  type: z2.literal("authorization_requested"),
1065
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1066
- createdAtMs: z2.number().int().nonnegative(),
1067
1052
  kind: authorizationKindSchema,
1068
1053
  provider: z2.string().min(1),
1069
1054
  actorId: z2.string().min(1),
@@ -1072,366 +1057,184 @@ var authorizationRequestedEntrySchema = z2.object({
1072
1057
  z2.literal("private_link_sent"),
1073
1058
  z2.literal("private_link_reused")
1074
1059
  ])
1075
- });
1076
- var authorizationCompletedEntrySchema = z2.object({
1077
- schemaVersion: schemaVersionSchema,
1060
+ }).strict();
1061
+ var authorizationCompletedEventDataSchema = z2.object({
1078
1062
  type: z2.literal("authorization_completed"),
1079
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1080
- createdAtMs: z2.number().int().nonnegative(),
1081
1063
  kind: authorizationKindSchema,
1082
1064
  provider: z2.string().min(1),
1083
1065
  actorId: z2.string().min(1),
1084
1066
  authorizationId: z2.string().min(1)
1085
- });
1086
- var transcriptRefSchema = z2.object({
1087
- type: z2.literal("advisor_session"),
1088
- parentConversationId: z2.string().min(1),
1089
- key: z2.string().min(1)
1090
- });
1091
- var toolExecutionStartedEntrySchema = z2.object({
1092
- schemaVersion: schemaVersionSchema,
1067
+ }).strict();
1068
+ var toolExecutionStartedEventDataSchema = z2.object({
1093
1069
  type: z2.literal("tool_execution_started"),
1094
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1095
- createdAtMs: z2.number().int().nonnegative(),
1096
1070
  toolCallId: z2.string().min(1),
1097
- toolName: z2.string().min(1),
1098
- args: z2.unknown().optional()
1071
+ toolName: z2.string().min(1)
1072
+ }).strict();
1073
+ var conversationMessageRoleSchema = z2.union([
1074
+ z2.literal("user"),
1075
+ z2.literal("assistant"),
1076
+ z2.literal("system")
1077
+ ]);
1078
+ var messageEventDataSchema = z2.object({
1079
+ type: z2.literal("message"),
1080
+ messageId: z2.string().min(1),
1081
+ role: conversationMessageRoleSchema,
1082
+ text: z2.string(),
1083
+ authorIdentityId: z2.string().min(1).optional(),
1084
+ meta: z2.record(z2.string(), z2.unknown()).optional()
1085
+ }).strict();
1086
+ var messageUpdatedEventDataSchema = messageEventDataSchema.extend({
1087
+ type: z2.literal("message_updated")
1099
1088
  });
1100
- var subagentStartedEntrySchema = z2.object({
1101
- schemaVersion: schemaVersionSchema,
1089
+ var messageHandledEventDataSchema = z2.object({
1090
+ type: z2.literal("message_handled"),
1091
+ messageId: z2.string().min(1)
1092
+ }).strict();
1093
+ var messagesSummarizedEventDataSchema = z2.object({
1094
+ type: z2.literal("messages_summarized"),
1095
+ historyFromSeq: z2.number().int().nonnegative(),
1096
+ compactions: z2.array(
1097
+ z2.object({
1098
+ coveredMessageCount: z2.number().int().nonnegative(),
1099
+ createdAtMs: z2.number(),
1100
+ id: z2.string().min(1),
1101
+ summary: z2.string()
1102
+ }).strict()
1103
+ )
1104
+ }).strict();
1105
+ var conversationTurnSurfaceSchema = z2.enum([
1106
+ "slack",
1107
+ "api",
1108
+ "scheduler",
1109
+ "internal"
1110
+ ]);
1111
+ var conversationTurnFailureCodeSchema = z2.enum([
1112
+ "agent_run_failed",
1113
+ "delivery_failed",
1114
+ "model_execution_failed",
1115
+ "persistence_failed"
1116
+ ]);
1117
+ var turnStartedEventDataSchema = z2.object({
1118
+ type: z2.literal("turn_started"),
1119
+ turnId: z2.string().min(1),
1120
+ inputMessageIds: z2.array(z2.string().min(1)).min(1),
1121
+ surface: conversationTurnSurfaceSchema
1122
+ }).strict().refine(
1123
+ (data) => new Set(data.inputMessageIds).size === data.inputMessageIds.length,
1124
+ "turn input message ids must be unique"
1125
+ );
1126
+ var turnCompletedEventDataSchema = z2.object({
1127
+ type: z2.literal("turn_completed"),
1128
+ turnId: z2.string().min(1),
1129
+ outcome: z2.enum(["success", "no_reply"])
1130
+ }).strict();
1131
+ var turnFailedEventDataSchema = z2.object({
1132
+ type: z2.literal("turn_failed"),
1133
+ turnId: z2.string().min(1),
1134
+ failureCode: conversationTurnFailureCodeSchema,
1135
+ eventId: z2.string().regex(/^[a-f0-9]{32}$/i).optional()
1136
+ }).strict();
1137
+ var subagentStartedEventDataSchema = z2.object({
1102
1138
  type: z2.literal("subagent_started"),
1103
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1104
1139
  subagentInvocationId: z2.string().min(1),
1105
1140
  subagentKind: z2.string().min(1),
1106
- parentToolCallId: z2.string().min(1).optional(),
1107
- parentConversationId: z2.string().min(1),
1108
- parentSessionId: z2.string().min(1).optional(),
1109
- transcriptRef: transcriptRefSchema,
1110
- historyMode: z2.literal("shared"),
1111
1141
  modelId: z2.string().min(1).optional(),
1142
+ parentToolCallId: z2.string().min(1).optional(),
1112
1143
  reasoningLevel: z2.string().min(1).optional(),
1113
- createdAtMs: z2.number().int().nonnegative()
1114
- });
1115
- var subagentEndedEntrySchema = z2.object({
1116
- schemaVersion: schemaVersionSchema,
1144
+ childConversationId: z2.string().min(1)
1145
+ }).strict();
1146
+ var subagentEndedEventDataSchema = z2.object({
1117
1147
  type: z2.literal("subagent_ended"),
1118
- sessionId: z2.string().min(1).default(INITIAL_SESSION_ID),
1119
1148
  subagentInvocationId: z2.string().min(1),
1120
1149
  outcome: z2.union([
1121
1150
  z2.literal("success"),
1122
1151
  z2.literal("error"),
1123
1152
  z2.literal("aborted")
1124
1153
  ]),
1125
- errorCode: z2.string().min(1).optional(),
1126
- transcriptEndMessageIndex: z2.number().int().nonnegative().optional(),
1127
- transcriptStartMessageIndex: z2.number().int().nonnegative().optional(),
1128
- createdAtMs: z2.number().int().nonnegative()
1129
- });
1130
- var sessionLogEntrySchema = z2.discriminatedUnion("type", [
1131
- piMessageEntrySchema,
1132
- projectionResetEntrySchema,
1133
- actorRecordedEntrySchema,
1134
- mcpProviderConnectedEntrySchema,
1135
- authorizationRequestedEntrySchema,
1136
- authorizationCompletedEntrySchema,
1137
- toolExecutionStartedEntrySchema,
1138
- subagentStartedEntrySchema,
1139
- subagentEndedEntrySchema
1140
- ]);
1141
- function key(scope) {
1142
- const prefix = getChatConfig().state.keyPrefix;
1143
- return [
1144
- ...prefix ? [prefix] : [],
1145
- AGENT_SESSION_LOG_PREFIX,
1146
- scope.conversationId
1147
- ].join(":");
1148
- }
1149
- function rawKey(scope) {
1150
- return [AGENT_SESSION_LOG_PREFIX, scope.conversationId].join(":");
1151
- }
1152
- function storedRecord(value) {
1153
- return typeof value === "object" && value !== null && !Array.isArray(value) ? value : void 0;
1154
- }
1155
- function migrateStoredEntry(value) {
1156
- const record = storedRecord(value);
1157
- if (!record) {
1158
- return value;
1159
- }
1160
- const migrated = { ...record };
1161
- if ("requester" in migrated && !("actor" in migrated)) {
1162
- migrated.actor = migrated.requester;
1163
- }
1164
- delete migrated.requester;
1165
- if (migrated.type === "requester_recorded") {
1166
- migrated.type = "actor_recorded";
1167
- }
1168
- if ("requesterId" in migrated && !("actorId" in migrated)) {
1169
- migrated.actorId = migrated.requesterId;
1170
- }
1171
- delete migrated.requesterId;
1172
- return migrated;
1173
- }
1174
- function piEntry(message, sessionId, provenance) {
1175
- return {
1176
- schemaVersion: AGENT_SESSION_LOG_SCHEMA_VERSION,
1177
- type: "pi_message",
1178
- sessionId,
1179
- message,
1180
- // Ambient context is the decode default, so only attributed/instruction
1181
- // provenance needs to be persisted on the entry.
1182
- ...provenance && !isDefaultContextProvenance(provenance) ? { provenance } : {}
1183
- };
1184
- }
1185
- function decode(value) {
1186
- if (typeof value === "string") {
1187
- return decode(JSON.parse(value));
1188
- }
1189
- const parsed = sessionLogEntrySchema.safeParse(migrateStoredEntry(value));
1190
- if (parsed.success) {
1191
- return parsed.data;
1192
- }
1193
- return piEntry(piMessageSchema.parse(value), INITIAL_SESSION_ID);
1194
- }
1195
- function actorIdentityKey(actor) {
1196
- if (actor.platform === "system") {
1197
- return `system ${actor.name}`;
1198
- }
1199
- return actor.platform === "slack" ? `slack\0${actor.teamId}\0${actor.userId}` : `${actor.platform}\0${actor.userId}`;
1200
- }
1201
- function instructionActors(provenance) {
1202
- const seen = /* @__PURE__ */ new Set();
1203
- const actors = [];
1204
- for (const entry of provenance) {
1205
- if (entry.authority !== "instruction" || !entry.actor) {
1206
- continue;
1207
- }
1208
- const identity = actorIdentityKey(entry.actor);
1209
- if (seen.has(identity)) {
1210
- continue;
1211
- }
1212
- seen.add(identity);
1213
- actors.push(entry.actor);
1214
- }
1215
- return actors;
1216
- }
1217
- function redisStore(redisStateAdapter) {
1218
- const client = redisStateAdapter.getClient();
1219
- return {
1220
- async append({ entries, scope, ttlMs }) {
1221
- const listKey = key(scope);
1222
- if (entries.length > 0) {
1223
- await client.rPush(
1224
- listKey,
1225
- entries.map((entry) => JSON.stringify(entry))
1226
- );
1227
- }
1228
- await client.pExpire(listKey, Math.max(1, ttlMs));
1229
- },
1230
- async read(scope) {
1231
- const values = await client.lRange(key(scope), 0, -1);
1232
- return values.map(decode);
1233
- }
1234
- };
1235
- }
1236
- function stateStore() {
1237
- const stateAdapter = getStateAdapter();
1238
- return {
1239
- async append({ entries, scope, ttlMs }) {
1240
- const listKey = rawKey(scope);
1241
- const lock = await stateAdapter.acquireLock(
1242
- `${listKey}:commit`,
1243
- STATE_STORE_LOCK_TTL_MS
1244
- );
1245
- if (!lock) {
1246
- throw new Error("Could not acquire session log commit lock");
1247
- }
1248
- try {
1249
- const existingValue = await stateAdapter.get(listKey);
1250
- const existingEntries = Array.isArray(existingValue) ? existingValue.map(decode) : (await stateAdapter.getList(listKey)).map(decode);
1251
- await stateAdapter.set(
1252
- listKey,
1253
- [...existingEntries, ...entries],
1254
- Math.max(1, ttlMs)
1255
- );
1256
- } finally {
1257
- await stateAdapter.releaseLock(lock);
1258
- }
1259
- },
1260
- async read(scope) {
1261
- const listKey = rawKey(scope);
1262
- const value = await stateAdapter.get(listKey);
1263
- if (Array.isArray(value)) {
1264
- return value.map(decode);
1265
- }
1266
- const values = await stateAdapter.getList(listKey);
1267
- return values.map(decode);
1268
- }
1269
- };
1270
- }
1271
- async function defaultStore() {
1272
- const { redisStateAdapter, stateAdapter } = await getConnectedStateContext();
1273
- if (redisStateAdapter) {
1274
- return redisStore(redisStateAdapter);
1275
- }
1276
- await stateAdapter.connect();
1277
- return stateStore();
1278
- }
1279
- async function loadEntries(args) {
1280
- const store = args.store ?? await defaultStore();
1281
- return (await store.read(args)).map(decode);
1282
- }
1283
- async function readSessionLogEntries(args) {
1284
- return loadEntries(args);
1285
- }
1286
- function instructionProvenanceFor(actor) {
1287
- return instructionProvenance(actor);
1288
- }
1289
- var contextProvenance = unattributedContextProvenance;
1290
-
1291
- // src/chat/conversations/history.ts
1292
- var handoffModelProfileSchema = modelProfileSchema.refine(
1293
- (profile) => profile !== "standard",
1294
- "handoff profile must not be standard"
1295
- );
1296
- var piMessageStepEntrySchema = z3.object({
1297
- type: z3.literal("pi_message"),
1298
- schemaVersion: z3.number().int().optional(),
1299
- message: piMessageSchema,
1300
- provenance: piMessageProvenanceSchema.optional()
1301
- });
1302
- var contextEpochStartedEntrySchema = z3.union([
1303
- z3.object({
1304
- type: z3.literal("context_epoch_started"),
1305
- reason: z3.literal("initial"),
1306
- modelProfile: z3.literal("standard"),
1307
- modelId: z3.string().min(1)
1308
- }).strict(),
1309
- z3.object({
1310
- type: z3.literal("context_epoch_started"),
1311
- reason: z3.literal("handoff"),
1312
- modelProfile: handoffModelProfileSchema,
1313
- modelId: z3.string().min(1)
1314
- }).strict(),
1315
- z3.object({
1316
- type: z3.literal("context_epoch_started"),
1317
- reason: z3.union([z3.literal("compaction"), z3.literal("rollback")]),
1318
- // TODO(v0.97.0): Remove support for deployed compaction/rollback markers
1319
- // without model bindings after those rows pass the retention horizon.
1320
- modelProfile: z3.undefined().optional(),
1321
- modelId: z3.undefined().optional()
1322
- }).strict(),
1323
- z3.object({
1324
- type: z3.literal("context_epoch_started"),
1325
- reason: z3.union([z3.literal("compaction"), z3.literal("rollback")]),
1326
- modelProfile: modelProfileSchema,
1327
- modelId: z3.string().min(1)
1328
- }).strict()
1329
- ]);
1330
- var piMessageStepSchema = z3.object({
1331
- message: piMessageSchema,
1332
- createdAtMs: z3.number().finite(),
1333
- provenance: piMessageProvenanceSchema.optional()
1154
+ errorCode: z2.string().min(1).optional()
1334
1155
  }).strict();
1335
- var contextEpochStartSchema = z3.discriminatedUnion("reason", [
1336
- z3.object({
1337
- reason: z3.literal("initial"),
1338
- modelProfile: z3.literal("standard"),
1339
- modelId: z3.string().min(1),
1340
- messages: z3.array(piMessageStepSchema)
1341
- }).strict(),
1342
- z3.object({
1343
- reason: z3.literal("handoff"),
1344
- modelProfile: handoffModelProfileSchema,
1345
- modelId: z3.string().min(1),
1346
- messages: z3.array(piMessageStepSchema)
1347
- }).strict(),
1348
- z3.object({
1349
- reason: z3.union([z3.literal("compaction"), z3.literal("rollback")]),
1350
- modelProfile: modelProfileSchema,
1351
- modelId: z3.string().min(1),
1352
- messages: z3.array(piMessageStepSchema)
1353
- }).strict()
1156
+ var appendableConversationEventDataSchema = z2.union([
1157
+ messageEventDataSchema,
1158
+ messageUpdatedEventDataSchema,
1159
+ agentStepEventDataSchema,
1160
+ mcpProviderConnectedEventDataSchema,
1161
+ authorizationRequestedEventDataSchema,
1162
+ authorizationCompletedEventDataSchema,
1163
+ toolExecutionStartedEventDataSchema,
1164
+ messageHandledEventDataSchema,
1165
+ messagesSummarizedEventDataSchema,
1166
+ turnStartedEventDataSchema,
1167
+ turnCompletedEventDataSchema,
1168
+ turnFailedEventDataSchema,
1169
+ subagentStartedEventDataSchema,
1170
+ subagentEndedEventDataSchema
1354
1171
  ]);
1355
- var mcpProviderConnectedEntrySchema2 = z3.object({
1356
- type: z3.literal("mcp_provider_connected"),
1357
- provider: z3.string().min(1)
1358
- });
1359
- var authorizationKindSchema2 = z3.union([
1360
- z3.literal("plugin"),
1361
- z3.literal("mcp")
1172
+ var conversationEventDataSchema = z2.union([
1173
+ appendableConversationEventDataSchema,
1174
+ historyReplacementEventDataSchema,
1175
+ legacyRollbackEventDataSchema
1362
1176
  ]);
1363
- var authorizationRequestedEntrySchema2 = z3.object({
1364
- type: z3.literal("authorization_requested"),
1365
- kind: authorizationKindSchema2,
1366
- provider: z3.string().min(1),
1367
- actorId: z3.string().min(1),
1368
- authorizationId: z3.string().min(1),
1369
- delivery: z3.union([
1370
- z3.literal("private_link_sent"),
1371
- z3.literal("private_link_reused")
1372
- ])
1373
- });
1374
- var authorizationCompletedEntrySchema2 = z3.object({
1375
- type: z3.literal("authorization_completed"),
1376
- kind: authorizationKindSchema2,
1377
- provider: z3.string().min(1),
1378
- actorId: z3.string().min(1),
1379
- authorizationId: z3.string().min(1)
1380
- });
1381
- var toolExecutionStartedEntrySchema2 = z3.object({
1382
- type: z3.literal("tool_execution_started"),
1383
- toolCallId: z3.string().min(1),
1384
- toolName: z3.string().min(1),
1385
- args: z3.unknown().optional()
1386
- });
1387
- var visibleContextCompactedEntrySchema = z3.object({
1388
- type: z3.literal("visible_context_compacted"),
1389
- compactions: z3.array(
1390
- z3.object({
1391
- coveredMessageIds: z3.array(z3.string()),
1392
- createdAtMs: z3.number(),
1393
- id: z3.string().min(1),
1394
- summary: z3.string()
1395
- })
1396
- )
1397
- });
1398
- var subagentStartedEntrySchema2 = z3.object({
1399
- type: z3.literal("subagent_started"),
1400
- subagentInvocationId: z3.string().min(1),
1401
- subagentKind: z3.string().min(1),
1402
- modelId: z3.string().min(1).optional(),
1403
- parentToolCallId: z3.string().min(1).optional(),
1404
- reasoningLevel: z3.string().min(1).optional(),
1405
- childConversationId: z3.string().min(1),
1406
- historyMode: z3.union([z3.literal("isolated"), z3.literal("shared")])
1407
- }).strict();
1408
- var subagentEndedEntrySchema2 = z3.object({
1409
- type: z3.literal("subagent_ended"),
1410
- subagentInvocationId: z3.string().min(1),
1411
- outcome: z3.union([
1412
- z3.literal("success"),
1413
- z3.literal("error"),
1414
- z3.literal("aborted")
1415
- ]),
1416
- errorCode: z3.string().min(1).optional()
1417
- });
1418
- var appendableAgentStepEntrySchema = z3.union([
1419
- piMessageStepEntrySchema,
1420
- mcpProviderConnectedEntrySchema2,
1421
- authorizationRequestedEntrySchema2,
1422
- authorizationCompletedEntrySchema2,
1423
- toolExecutionStartedEntrySchema2,
1424
- visibleContextCompactedEntrySchema,
1425
- subagentStartedEntrySchema2,
1426
- subagentEndedEntrySchema2
1177
+ var knownConversationEventTypeSchema = z2.enum([
1178
+ "message",
1179
+ "message_updated",
1180
+ "agent_step",
1181
+ "mcp_provider_connected",
1182
+ "authorization_requested",
1183
+ "authorization_completed",
1184
+ "tool_execution_started",
1185
+ "message_handled",
1186
+ "messages_summarized",
1187
+ "turn_started",
1188
+ "turn_completed",
1189
+ "turn_failed",
1190
+ "subagent_started",
1191
+ "subagent_ended",
1192
+ "handoff",
1193
+ "compaction",
1194
+ "rollback"
1427
1195
  ]);
1428
- var agentStepEntrySchema = z3.union([
1429
- appendableAgentStepEntrySchema,
1430
- contextEpochStartedEntrySchema
1196
+ var unknownConversationEventDataSchema = z2.object({
1197
+ type: z2.literal("unknown"),
1198
+ originalType: z2.string().min(1),
1199
+ payload: z2.unknown()
1200
+ }).strict();
1201
+ var conversationEventEnvelopeSchema = z2.object({
1202
+ schemaVersion: z2.number().int().nonnegative(),
1203
+ seq: z2.number().int().nonnegative(),
1204
+ historyVersion: z2.number().int().nonnegative(),
1205
+ idempotencyKey: z2.string().min(1).optional(),
1206
+ createdAtMs: z2.number().finite()
1207
+ }).strict();
1208
+ var conversationEventSchema = z2.union([
1209
+ conversationEventEnvelopeSchema.extend({
1210
+ schemaVersion: z2.literal(1),
1211
+ data: conversationEventDataSchema
1212
+ }),
1213
+ conversationEventEnvelopeSchema.extend({
1214
+ data: unknownConversationEventDataSchema
1215
+ })
1431
1216
  ]);
1432
- var newAgentStepSchema = z3.object({
1433
- entry: appendableAgentStepEntrySchema,
1434
- createdAtMs: z3.number().finite()
1217
+ var storedConversationEventSchema = conversationEventEnvelopeSchema.extend({
1218
+ type: z2.string().min(1),
1219
+ payload: z2.unknown()
1220
+ });
1221
+ function decodeStoredConversationEvent(value) {
1222
+ const stored = storedConversationEventSchema.parse(value);
1223
+ const { type, payload, ...envelope } = stored;
1224
+ const knownType = knownConversationEventTypeSchema.safeParse(type).success;
1225
+ if (stored.schemaVersion === 1 && knownType) {
1226
+ const data = typeof payload === "object" && payload !== null && !Array.isArray(payload) ? { ...payload, type } : { type };
1227
+ return conversationEventSchema.parse({ ...envelope, data });
1228
+ }
1229
+ return conversationEventSchema.parse({
1230
+ ...envelope,
1231
+ data: { type: "unknown", originalType: type, payload }
1232
+ });
1233
+ }
1234
+ var newConversationEventSchema = z2.object({
1235
+ data: appendableConversationEventDataSchema,
1236
+ idempotencyKey: z2.string().min(1).optional(),
1237
+ createdAtMs: z2.number().finite()
1435
1238
  }).strict();
1436
1239
 
1437
1240
  // src/chat/conversations/sql/conversation-row.ts
@@ -1470,66 +1273,92 @@ function sanitizePostgresJson(value) {
1470
1273
  return value;
1471
1274
  }
1472
1275
  return Object.fromEntries(
1473
- Object.entries(value).map(([key2, item]) => [
1474
- key2,
1276
+ Object.entries(value).map(([key, item]) => [
1277
+ key,
1475
1278
  sanitizePostgresJson(item)
1476
1279
  ])
1477
1280
  );
1478
1281
  }
1479
1282
 
1480
- // src/chat/conversations/sql/history.ts
1481
- function messageRole(entry) {
1482
- if (entry.type !== "pi_message") {
1483
- return null;
1484
- }
1485
- const role = entry.message.role;
1486
- return typeof role === "string" ? role : null;
1283
+ // src/chat/conversations/sql/event-lock.ts
1284
+ async function withConversationEventLock(executor, conversationId, callback) {
1285
+ return executor.withLock(
1286
+ `junior_conversation:event:${conversationId}`,
1287
+ callback
1288
+ );
1487
1289
  }
1488
- function insertFromStep(conversationId, seq, contextEpoch, step) {
1489
- const { type, ...payload } = agentStepEntrySchema.parse(step.entry);
1290
+
1291
+ // src/chat/conversations/sql/history.ts
1292
+ var messageHistoryEventTypes = [
1293
+ "message",
1294
+ "message_updated",
1295
+ "message_handled"
1296
+ ];
1297
+ function insertFromEvent(conversationId, seq, historyVersion, event) {
1298
+ const { type, ...payload } = conversationEventDataSchema.parse(event.data);
1490
1299
  return {
1491
1300
  conversationId,
1492
1301
  seq,
1493
- contextEpoch,
1302
+ historyVersion,
1303
+ schemaVersion: 1,
1304
+ idempotencyKey: event.idempotencyKey ?? null,
1494
1305
  type,
1495
- role: messageRole(step.entry),
1496
1306
  payload: sanitizePostgresJson(payload),
1497
- createdAt: new Date(step.createdAtMs)
1307
+ createdAt: new Date(event.createdAtMs)
1498
1308
  };
1499
1309
  }
1500
- function stepFromRow(row) {
1501
- const entry = agentStepEntrySchema.parse({ type: row.type, ...row.payload });
1502
- return {
1310
+ function eventFromRow(row) {
1311
+ return decodeStoredConversationEvent({
1312
+ schemaVersion: row.schemaVersion,
1503
1313
  seq: row.seq,
1504
- contextEpoch: row.contextEpoch,
1314
+ historyVersion: row.historyVersion,
1315
+ ...row.idempotencyKey ? { idempotencyKey: row.idempotencyKey } : {},
1505
1316
  createdAtMs: row.createdAt.getTime(),
1506
- entry
1507
- };
1508
- }
1509
- function piMessageStep(step) {
1510
- return {
1511
- entry: {
1512
- type: "pi_message",
1513
- message: step.message,
1514
- ...step.provenance ? { provenance: step.provenance } : {}
1515
- },
1516
- createdAtMs: step.createdAtMs
1517
- };
1317
+ type: row.type,
1318
+ payload: row.payload
1319
+ });
1518
1320
  }
1519
- var SqlAgentStepStore = class {
1321
+ var SqlConversationEventStore = class {
1520
1322
  constructor(executor) {
1521
1323
  this.executor = executor;
1522
1324
  }
1523
1325
  executor;
1524
- async append(conversationId, steps) {
1525
- const parsed = steps.map((step) => newAgentStepSchema.parse(step));
1326
+ async append(conversationId, events) {
1327
+ const parsed = events.map(
1328
+ (event) => newConversationEventSchema.parse(event)
1329
+ );
1526
1330
  if (parsed.length === 0) {
1527
1331
  return;
1528
1332
  }
1529
- const newestCreatedAtMs = Math.max(
1530
- ...parsed.map((step) => step.createdAtMs)
1531
- );
1532
- await this.executor.transaction(async () => {
1333
+ await withConversationEventLock(this.executor, conversationId, async () => {
1334
+ const existingKeys = parsed.map((event) => event.idempotencyKey).filter((key) => key !== void 0);
1335
+ const persistedKeys = existingKeys.length === 0 ? /* @__PURE__ */ new Set() : new Set(
1336
+ (await this.executor.db().select({ key: juniorConversationEvents.idempotencyKey }).from(juniorConversationEvents).where(
1337
+ and3(
1338
+ eq3(
1339
+ juniorConversationEvents.conversationId,
1340
+ conversationId
1341
+ ),
1342
+ inArray(
1343
+ juniorConversationEvents.idempotencyKey,
1344
+ existingKeys
1345
+ )
1346
+ )
1347
+ )).flatMap((row) => row.key ? [row.key] : [])
1348
+ );
1349
+ const acceptedKeys = new Set(persistedKeys);
1350
+ const pending = parsed.filter((event) => {
1351
+ if (event.idempotencyKey === void 0) return true;
1352
+ if (acceptedKeys.has(event.idempotencyKey)) return false;
1353
+ acceptedKeys.add(event.idempotencyKey);
1354
+ return true;
1355
+ });
1356
+ if (pending.length === 0) {
1357
+ return;
1358
+ }
1359
+ const newestCreatedAtMs = Math.max(
1360
+ ...pending.map((event) => event.createdAtMs)
1361
+ );
1533
1362
  await ensureConversationRow(
1534
1363
  this.executor,
1535
1364
  conversationId,
@@ -1542,17 +1371,17 @@ var SqlAgentStepStore = class {
1542
1371
  )
1543
1372
  );
1544
1373
  const cursor = await this.readCursor(conversationId);
1545
- const contextEpoch = cursor.maxEpoch ?? 0;
1374
+ const historyVersion = cursor.maxHistoryVersion ?? 0;
1546
1375
  let seq = cursor.nextSeq;
1547
- const rows = parsed.map(
1548
- (step) => insertFromStep(conversationId, seq++, contextEpoch, step)
1376
+ const rows = pending.map(
1377
+ (event) => insertFromEvent(conversationId, seq++, historyVersion, event)
1549
1378
  );
1550
- await this.executor.db().insert(juniorAgentSteps).values(rows);
1379
+ await this.executor.db().insert(juniorConversationEvents).values(rows);
1551
1380
  });
1552
1381
  }
1553
- async startEpoch(conversationId, opts) {
1554
- const parsed = contextEpochStartSchema.parse(opts);
1555
- await this.executor.transaction(async () => {
1382
+ async replaceHistory(conversationId, replacement) {
1383
+ const parsed = historyReplacementSchema.parse(replacement);
1384
+ await withConversationEventLock(this.executor, conversationId, async () => {
1556
1385
  await ensureConversationRow(this.executor, conversationId, Date.now());
1557
1386
  await this.executor.db().update(juniorConversations).set({ archivedAt: null }).where(
1558
1387
  and3(
@@ -1561,140 +1390,89 @@ var SqlAgentStepStore = class {
1561
1390
  )
1562
1391
  );
1563
1392
  const cursor = await this.readCursor(conversationId);
1564
- const contextEpoch = parsed.reason === "initial" ? cursor.maxEpoch ?? 0 : (cursor.maxEpoch ?? -1) + 1;
1565
- let seq = cursor.nextSeq;
1566
- const { messages, ...binding } = parsed;
1567
- const marker = {
1568
- entry: { type: "context_epoch_started", ...binding },
1569
- createdAtMs: Date.now()
1570
- };
1571
- const rows = [marker, ...messages.map(piMessageStep)].map(
1572
- (step) => insertFromStep(conversationId, seq++, contextEpoch, step)
1393
+ const historyVersion = (cursor.maxHistoryVersion ?? 0) + 1;
1394
+ await this.executor.db().insert(juniorConversationEvents).values(
1395
+ insertFromEvent(
1396
+ conversationId,
1397
+ cursor.nextSeq,
1398
+ historyVersion,
1399
+ parsed
1400
+ )
1573
1401
  );
1574
- await this.executor.db().insert(juniorAgentSteps).values(rows);
1575
1402
  });
1576
1403
  }
1577
- async loadCurrentEpoch(conversationId) {
1404
+ async loadCurrentHistory(conversationId) {
1578
1405
  const cursor = await this.readCursor(conversationId);
1579
- if (cursor.maxEpoch === null) {
1406
+ if (cursor.maxHistoryVersion === null) {
1580
1407
  return [];
1581
1408
  }
1582
- const rows = await this.executor.db().select().from(juniorAgentSteps).where(
1409
+ const rows = await this.executor.db().select().from(juniorConversationEvents).where(
1410
+ and3(
1411
+ eq3(juniorConversationEvents.conversationId, conversationId),
1412
+ eq3(juniorConversationEvents.historyVersion, cursor.maxHistoryVersion)
1413
+ )
1414
+ ).orderBy(asc2(juniorConversationEvents.seq));
1415
+ return rows.map(eventFromRow);
1416
+ }
1417
+ async loadHistoryContaining(conversationId, seq, throughSeq) {
1418
+ const [boundary] = await this.executor.db().select({ historyVersion: juniorConversationEvents.historyVersion }).from(juniorConversationEvents).where(
1419
+ and3(
1420
+ eq3(juniorConversationEvents.conversationId, conversationId),
1421
+ eq3(juniorConversationEvents.seq, seq)
1422
+ )
1423
+ ).limit(1);
1424
+ if (!boundary) return void 0;
1425
+ const rows = await this.executor.db().select().from(juniorConversationEvents).where(
1426
+ and3(
1427
+ eq3(juniorConversationEvents.conversationId, conversationId),
1428
+ eq3(juniorConversationEvents.historyVersion, boundary.historyVersion),
1429
+ throughSeq === void 0 ? void 0 : lte(juniorConversationEvents.seq, throughSeq)
1430
+ )
1431
+ ).orderBy(asc2(juniorConversationEvents.seq));
1432
+ return rows.map(eventFromRow);
1433
+ }
1434
+ async loadMessageHistory(conversationId) {
1435
+ const [compactionRow] = await this.executor.db().select().from(juniorConversationEvents).where(
1436
+ and3(
1437
+ eq3(juniorConversationEvents.conversationId, conversationId),
1438
+ eq3(juniorConversationEvents.type, "messages_summarized")
1439
+ )
1440
+ ).orderBy(desc2(juniorConversationEvents.seq)).limit(1);
1441
+ const compaction = compactionRow ? eventFromRow(compactionRow) : void 0;
1442
+ const historyFromSeq = compaction?.data.type === "messages_summarized" ? compaction.data.historyFromSeq : 0;
1443
+ const rows = await this.executor.db().select().from(juniorConversationEvents).where(
1583
1444
  and3(
1584
- eq3(juniorAgentSteps.conversationId, conversationId),
1585
- eq3(juniorAgentSteps.contextEpoch, cursor.maxEpoch)
1445
+ eq3(juniorConversationEvents.conversationId, conversationId),
1446
+ inArray(juniorConversationEvents.type, messageHistoryEventTypes),
1447
+ gte(juniorConversationEvents.seq, historyFromSeq)
1586
1448
  )
1587
- ).orderBy(asc2(juniorAgentSteps.seq));
1588
- return rows.map(stepFromRow);
1449
+ ).orderBy(asc2(juniorConversationEvents.seq));
1450
+ return { events: rows.map(eventFromRow), compaction };
1589
1451
  }
1590
1452
  async loadHistory(conversationId) {
1591
- const rows = await this.executor.db().select().from(juniorAgentSteps).where(eq3(juniorAgentSteps.conversationId, conversationId)).orderBy(asc2(juniorAgentSteps.seq));
1592
- return rows.map(stepFromRow);
1453
+ const rows = await this.executor.db().select().from(juniorConversationEvents).where(eq3(juniorConversationEvents.conversationId, conversationId)).orderBy(asc2(juniorConversationEvents.seq));
1454
+ return rows.map(eventFromRow);
1593
1455
  }
1594
- /** Read the next `seq` and current highest epoch for one conversation. */
1456
+ /** Read the next sequence and active model-history version. */
1595
1457
  async readCursor(conversationId) {
1596
1458
  const rows = await this.executor.db().select({
1597
- maxSeq: sql7`max(${juniorAgentSteps.seq})`,
1598
- maxEpoch: sql7`max(${juniorAgentSteps.contextEpoch})`
1599
- }).from(juniorAgentSteps).where(eq3(juniorAgentSteps.conversationId, conversationId));
1459
+ maxSeq: sql7`max(${juniorConversationEvents.seq})`,
1460
+ maxHistoryVersion: sql7`max(${juniorConversationEvents.historyVersion})`
1461
+ }).from(juniorConversationEvents).where(eq3(juniorConversationEvents.conversationId, conversationId));
1600
1462
  const maxSeq = rows[0]?.maxSeq;
1601
- const maxEpoch = rows[0]?.maxEpoch;
1463
+ const maxHistoryVersion = rows[0]?.maxHistoryVersion;
1602
1464
  return {
1603
- maxEpoch: maxEpoch === null || maxEpoch === void 0 ? null : Number(maxEpoch),
1465
+ maxHistoryVersion: maxHistoryVersion === null || maxHistoryVersion === void 0 ? null : Number(maxHistoryVersion),
1604
1466
  nextSeq: maxSeq === null || maxSeq === void 0 ? 0 : Number(maxSeq) + 1
1605
1467
  };
1606
1468
  }
1607
1469
  };
1608
- function createSqlAgentStepStore(executor) {
1609
- return new SqlAgentStepStore(executor);
1610
- }
1611
-
1612
- // src/chat/conversations/sql/messages.ts
1613
- import { and as and4, asc as asc3, eq as eq4, isNotNull as isNotNull2, isNull as isNull2, sql as sql8 } from "drizzle-orm";
1614
- function messageFromRow(row) {
1615
- return {
1616
- conversationId: row.conversationId,
1617
- messageId: row.messageId,
1618
- role: row.role,
1619
- text: row.text,
1620
- createdAtMs: row.createdAt.getTime(),
1621
- ...row.authorIdentityId ? { authorIdentityId: row.authorIdentityId } : {},
1622
- ...row.meta ? { meta: row.meta } : {},
1623
- ...row.repliedAt ? { repliedAtMs: row.repliedAt.getTime() } : {}
1624
- };
1625
- }
1626
- var SqlConversationMessageStore = class {
1627
- constructor(executor) {
1628
- this.executor = executor;
1629
- }
1630
- executor;
1631
- async record(conversationId, messages) {
1632
- if (messages.length === 0) {
1633
- return;
1634
- }
1635
- const newestCreatedAtMs = Math.max(
1636
- ...messages.map((message) => message.createdAtMs)
1637
- );
1638
- await this.executor.transaction(async () => {
1639
- await ensureConversationRow(
1640
- this.executor,
1641
- conversationId,
1642
- newestCreatedAtMs
1643
- );
1644
- await this.executor.db().update(juniorConversations).set({ archivedAt: null }).where(
1645
- and4(
1646
- eq4(juniorConversations.conversationId, conversationId),
1647
- isNotNull2(juniorConversations.archivedAt)
1648
- )
1649
- );
1650
- await this.executor.db().insert(juniorConversationMessages).values(
1651
- messages.map((message) => ({
1652
- conversationId,
1653
- messageId: message.messageId,
1654
- role: message.role,
1655
- authorIdentityId: message.authorIdentityId ?? null,
1656
- text: message.text,
1657
- meta: message.meta ?? null,
1658
- repliedAt: null,
1659
- createdAt: new Date(message.createdAtMs)
1660
- }))
1661
- ).onConflictDoUpdate({
1662
- target: [
1663
- juniorConversationMessages.conversationId,
1664
- juniorConversationMessages.messageId
1665
- ],
1666
- set: {
1667
- meta: sql8`nullif(coalesce(${juniorConversationMessages.meta}, '{}'::jsonb) || coalesce(excluded.meta, '{}'::jsonb), '{}'::jsonb)`
1668
- }
1669
- });
1670
- });
1671
- }
1672
- async markReplied(conversationId, messageId, repliedAtMs) {
1673
- await this.executor.db().update(juniorConversationMessages).set({
1674
- repliedAt: sql8`coalesce(${juniorConversationMessages.repliedAt}, ${new Date(repliedAtMs)})`
1675
- }).where(
1676
- and4(
1677
- eq4(juniorConversationMessages.conversationId, conversationId),
1678
- eq4(juniorConversationMessages.messageId, messageId),
1679
- isNull2(juniorConversationMessages.repliedAt)
1680
- )
1681
- );
1682
- }
1683
- async list(conversationId, opts = {}) {
1684
- const query = this.executor.db().select().from(juniorConversationMessages).where(eq4(juniorConversationMessages.conversationId, conversationId)).orderBy(
1685
- asc3(juniorConversationMessages.createdAt),
1686
- asc3(juniorConversationMessages.messageId)
1687
- );
1688
- const rows = opts.limit === void 0 ? await query : await query.limit(Math.max(0, opts.limit));
1689
- return rows.map(messageFromRow);
1690
- }
1691
- };
1692
- function createSqlConversationMessageStore(executor) {
1693
- return new SqlConversationMessageStore(executor);
1470
+ function createSqlConversationEventStore(executor) {
1471
+ return new SqlConversationEventStore(executor);
1694
1472
  }
1695
1473
 
1696
1474
  // src/chat/conversations/sql/search.ts
1697
- import { and as and5, desc as desc2, eq as eq5, inArray, isNull as isNull3, ne, sql as sql9 } from "drizzle-orm";
1475
+ import { and as and4, desc as desc3, eq as eq4, isNull as isNull2, ne, sql as sql8 } from "drizzle-orm";
1698
1476
  var SqlConversationSearchStore = class {
1699
1477
  constructor(executor) {
1700
1478
  this.executor = executor;
@@ -1702,48 +1480,51 @@ var SqlConversationSearchStore = class {
1702
1480
  executor;
1703
1481
  async search(args) {
1704
1482
  const db = this.executor.db();
1705
- const tsquery = sql9`websearch_to_tsquery('english', ${args.query})`;
1706
- const rank = sql9`ts_rank_cd(to_tsvector('english', ${juniorConversationMessages.text}), ${tsquery})`;
1707
- const excerpt = sql9`ts_headline('english', ${juniorConversationMessages.text}, ${tsquery}, 'MaxFragments=2, MinWords=8, MaxWords=40, FragmentDelimiter=" … ", StartSel=**, StopSel=**')`;
1708
- const role = sql9`${juniorConversationMessages.role}`;
1483
+ const tsquery = sql8`websearch_to_tsquery('english', ${args.query})`;
1484
+ const text5 = sql8`${juniorConversationEvents.payload}->>'text'`;
1485
+ const rank = sql8`ts_rank_cd(to_tsvector('english', ${text5}), ${tsquery})`;
1486
+ const excerpt = sql8`ts_headline('english', ${text5}, ${tsquery}, 'MaxFragments=2, MinWords=8, MaxWords=40, FragmentDelimiter=" … ", StartSel=**, StopSel=**')`;
1487
+ const role = sql8`${juniorConversationEvents.payload}->>'role'`;
1488
+ const messageId = sql8`${juniorConversationEvents.payload}->>'messageId'`;
1709
1489
  const bestPerConversation = db.selectDistinctOn([juniorConversations.conversationId], {
1710
1490
  conversationId: juniorConversations.conversationId,
1711
1491
  excerpt: excerpt.as("excerpt"),
1712
1492
  lastActivityAt: juniorConversations.lastActivityAt,
1713
- messageCreatedAt: juniorConversationMessages.createdAt,
1714
- messageId: juniorConversationMessages.messageId,
1493
+ messageCreatedAt: juniorConversationEvents.createdAt,
1494
+ messageId: messageId.as("message_id"),
1715
1495
  providerDestinationId: juniorDestinations.providerDestinationId,
1716
1496
  rank: rank.as("rank"),
1717
1497
  role: role.as("role")
1718
- }).from(juniorConversationMessages).innerJoin(
1498
+ }).from(juniorConversationEvents).innerJoin(
1719
1499
  juniorConversations,
1720
- eq5(
1500
+ eq4(
1721
1501
  juniorConversations.conversationId,
1722
- juniorConversationMessages.conversationId
1502
+ juniorConversationEvents.conversationId
1723
1503
  )
1724
1504
  ).innerJoin(
1725
1505
  juniorDestinations,
1726
- eq5(juniorDestinations.id, juniorConversations.destinationId)
1506
+ eq4(juniorDestinations.id, juniorConversations.destinationId)
1727
1507
  ).where(
1728
- and5(
1729
- eq5(juniorConversations.source, "slack"),
1730
- isNull3(juniorConversations.parentConversationId),
1731
- isNull3(juniorConversations.transcriptPurgedAt),
1508
+ and4(
1509
+ eq4(juniorConversations.source, "slack"),
1510
+ isNull2(juniorConversations.parentConversationId),
1511
+ isNull2(juniorConversations.transcriptPurgedAt),
1732
1512
  ne(juniorConversations.conversationId, args.currentConversationId),
1733
- eq5(juniorDestinations.provider, args.scope.provider),
1734
- eq5(juniorDestinations.providerTenantId, args.scope.providerTenantId),
1735
- eq5(juniorDestinations.visibility, "public"),
1736
- inArray(juniorConversationMessages.role, ["user", "assistant"]),
1737
- sql9`to_tsvector('english', ${juniorConversationMessages.text}) @@ ${tsquery}`
1513
+ eq4(juniorDestinations.provider, args.scope.provider),
1514
+ eq4(juniorDestinations.providerTenantId, args.scope.providerTenantId),
1515
+ eq4(juniorDestinations.visibility, "public"),
1516
+ eq4(juniorConversationEvents.type, "message"),
1517
+ sql8`${role} in ('user', 'assistant')`,
1518
+ sql8`to_tsvector('english', ${text5}) @@ ${tsquery}`
1738
1519
  )
1739
1520
  ).orderBy(
1740
1521
  juniorConversations.conversationId,
1741
- desc2(rank),
1742
- desc2(juniorConversationMessages.createdAt)
1522
+ desc3(rank),
1523
+ desc3(juniorConversationEvents.createdAt)
1743
1524
  ).as("best_conversation_matches");
1744
1525
  const rows = await db.select().from(bestPerConversation).orderBy(
1745
- desc2(bestPerConversation.rank),
1746
- desc2(bestPerConversation.lastActivityAt)
1526
+ desc3(bestPerConversation.rank),
1527
+ desc3(bestPerConversation.lastActivityAt)
1747
1528
  ).limit(args.limit);
1748
1529
  return rows.map((row) => ({
1749
1530
  conversationId: row.conversationId,
@@ -2014,24 +1795,23 @@ function createDb(args) {
2014
1795
  });
2015
1796
  }
2016
1797
  function getSqlExecutor() {
2017
- const { sql: sql10 } = getChatConfig();
2018
- if (current?.databaseUrl !== sql10.databaseUrl || current.driver !== sql10.driver) {
1798
+ const { sql: sql9 } = getChatConfig();
1799
+ if (current?.databaseUrl !== sql9.databaseUrl || current.driver !== sql9.driver) {
2019
1800
  if (current) {
2020
1801
  const previous = current;
2021
1802
  current = void 0;
2022
1803
  void previous.db.close().catch(() => void 0);
2023
1804
  }
2024
1805
  const db = createDb({
2025
- databaseUrl: sql10.databaseUrl,
2026
- driver: sql10.driver
1806
+ databaseUrl: sql9.databaseUrl,
1807
+ driver: sql9.driver
2027
1808
  });
2028
1809
  current = {
2029
- databaseUrl: sql10.databaseUrl,
2030
- driver: sql10.driver,
1810
+ databaseUrl: sql9.databaseUrl,
1811
+ driver: sql9.driver,
2031
1812
  db,
2032
1813
  store: createSqlStore(db),
2033
- stepStore: createSqlAgentStepStore(db),
2034
- messageStore: createSqlConversationMessageStore(db),
1814
+ eventStore: createSqlConversationEventStore(db),
2035
1815
  searchStore: createSqlConversationSearchStore(db)
2036
1816
  };
2037
1817
  }
@@ -2044,13 +1824,9 @@ function getConversationStore() {
2044
1824
  getSqlExecutor();
2045
1825
  return current.store;
2046
1826
  }
2047
- function getAgentStepStore() {
1827
+ function getConversationEventStore() {
2048
1828
  getSqlExecutor();
2049
- return current.stepStore;
2050
- }
2051
- function getConversationMessageStore() {
2052
- getSqlExecutor();
2053
- return current.messageStore;
1829
+ return current.eventStore;
2054
1830
  }
2055
1831
  function getConversationSearchStore() {
2056
1832
  getSqlExecutor();
@@ -2066,25 +1842,23 @@ export {
2066
1842
  juniorUsers,
2067
1843
  juniorIdentities,
2068
1844
  juniorConversations,
2069
- juniorAgentSteps,
2070
- juniorConversationMessages,
1845
+ juniorConversationEvents,
2071
1846
  createSqlStore,
2072
- piMessageSchema,
2073
- legacyActorProvenance,
2074
- instructionActors,
2075
- readSessionLogEntries,
1847
+ conversationMessageProvenanceSchema,
2076
1848
  instructionProvenanceFor,
2077
1849
  contextProvenance,
2078
- agentStepEntrySchema,
1850
+ instructionActors,
1851
+ conversationEventDataSchema,
1852
+ decodeStoredConversationEvent,
1853
+ newConversationEventSchema,
2079
1854
  sanitizePostgresJson,
2080
- createSqlAgentStepStore,
2081
- createSqlConversationMessageStore,
1855
+ withConversationEventLock,
1856
+ createSqlConversationEventStore,
2082
1857
  createJuniorSqlExecutor,
2083
1858
  getSqlExecutor,
2084
1859
  getDb,
2085
1860
  getConversationStore,
2086
- getAgentStepStore,
2087
- getConversationMessageStore,
1861
+ getConversationEventStore,
2088
1862
  getConversationSearchStore,
2089
1863
  closeDb
2090
1864
  };