@dudousxd/nestjs-agent-store-drizzle 0.30.0 → 0.31.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/index.js CHANGED
@@ -381,6 +381,94 @@ var agentActionProposal = sqliteTable("agent_action_proposal", {
381
381
  uniqueIndex("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
382
382
  index("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
383
383
  ]);
384
+ var agentPoppyConversation = sqliteTable("agent_poppy_conversation", {
385
+ id: text("id").primaryKey(),
386
+ clientId: text("client_id").notNull(),
387
+ userId: text("user_id").notNull(),
388
+ accountRef: text("account_ref"),
389
+ agentName: text("agent_name").notNull(),
390
+ threadId: text("thread_id"),
391
+ parentId: text("parent_id"),
392
+ openDirectId: text("open_direct_id"),
393
+ status: text("status").notNull(),
394
+ responder: text("responder").notNull(),
395
+ context: text("context"),
396
+ activeRunId: text("active_run_id"),
397
+ turnSeq: integer("turn_seq").notNull(),
398
+ grantInfo: text("grant_info"),
399
+ readerHolder: text("reader_holder"),
400
+ readerUntil: integer("reader_until"),
401
+ prunedSeq: integer("pruned_seq").notNull(),
402
+ createdAt: integer("created_at").notNull(),
403
+ updatedAt: integer("updated_at").notNull()
404
+ });
405
+ var agentPoppyEvent = sqliteTable("agent_poppy_event", {
406
+ conversationId: text("conversation_id").notNull(),
407
+ seq: integer("seq").notNull(),
408
+ id: text("id").notNull(),
409
+ type: text("type").notNull(),
410
+ event: text("event").notNull(),
411
+ eventKey: text("event_key"),
412
+ createdAt: integer("created_at").notNull()
413
+ }, (table) => [
414
+ primaryKey({
415
+ columns: [
416
+ table.conversationId,
417
+ table.seq
418
+ ]
419
+ }),
420
+ uniqueIndex("agent_poppy_event_key_idx").on(table.conversationId, table.eventKey),
421
+ index("agent_poppy_event_id_idx").on(table.conversationId, table.id)
422
+ ]);
423
+ var agentPoppyMessage = sqliteTable("agent_poppy_message", {
424
+ owner: text("owner").notNull(),
425
+ messageId: text("message_id").notNull(),
426
+ fingerprint: text("fingerprint").notNull(),
427
+ conversationId: text("conversation_id").notNull(),
428
+ response: text("response").notNull(),
429
+ createdAt: integer("created_at").notNull()
430
+ }, (table) => [
431
+ primaryKey({
432
+ columns: [
433
+ table.owner,
434
+ table.messageId
435
+ ]
436
+ })
437
+ ]);
438
+ var agentPoppyConnection = sqliteTable("agent_poppy_connection", {
439
+ owner: text("owner").notNull(),
440
+ issuer: text("issuer").notNull(),
441
+ domain: text("domain").notNull(),
442
+ organization: text("organization").notNull(),
443
+ scope: text("scope").notNull(),
444
+ status: text("status").notNull(),
445
+ state: text("state").notNull(),
446
+ createdAt: integer("created_at").notNull(),
447
+ updatedAt: integer("updated_at").notNull()
448
+ }, (table) => [
449
+ primaryKey({
450
+ columns: [
451
+ table.owner,
452
+ table.issuer
453
+ ]
454
+ })
455
+ ]);
456
+ var agentPoppyConnect = sqliteTable("agent_poppy_connect", {
457
+ id: text("id").primaryKey(),
458
+ owner: text("owner").notNull(),
459
+ domain: text("domain").notNull(),
460
+ issuer: text("issuer").notNull(),
461
+ organization: text("organization").notNull(),
462
+ scope: text("scope").notNull(),
463
+ actor: text("actor"),
464
+ threadId: text("thread_id"),
465
+ runId: text("run_id"),
466
+ toolCallId: text("tool_call_id"),
467
+ flow: text("flow"),
468
+ status: text("status").notNull(),
469
+ expiresAt: integer("expires_at").notNull(),
470
+ createdAt: integer("created_at").notNull()
471
+ });
384
472
  var agentSchema = {
385
473
  agentActionProposal,
386
474
  agentThread,
@@ -395,7 +483,12 @@ var agentSchema = {
395
483
  ragIngestionLog,
396
484
  agentConfirmToken,
397
485
  agentChannelState,
398
- agentStreamFrame
486
+ agentStreamFrame,
487
+ agentPoppyConversation,
488
+ agentPoppyEvent,
489
+ agentPoppyMessage,
490
+ agentPoppyConnection,
491
+ agentPoppyConnect
399
492
  };
400
493
 
401
494
  // src/ensure-schema.ts
@@ -717,6 +810,124 @@ var agentActionProposal2 = mysqlTable("agent_action_proposal", {
717
810
  uniqueIndex2("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
718
811
  index2("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
719
812
  ]);
813
+ var agentPoppyConversation2 = mysqlTable("agent_poppy_conversation", {
814
+ id: key("id").primaryKey(),
815
+ clientId: varchar("client_id", {
816
+ length: 2048
817
+ }).notNull(),
818
+ userId: key("user_id").notNull(),
819
+ accountRef: key("account_ref"),
820
+ agentName: key("agent_name").notNull(),
821
+ threadId: key("thread_id"),
822
+ parentId: key("parent_id"),
823
+ openDirectId: key("open_direct_id"),
824
+ status: key("status").notNull(),
825
+ responder: key("responder").notNull(),
826
+ context: longtext("context"),
827
+ activeRunId: key("active_run_id"),
828
+ turnSeq: bigint("turn_seq", {
829
+ mode: "number"
830
+ }).notNull(),
831
+ grantInfo: longtext("grant_info"),
832
+ readerHolder: key("reader_holder"),
833
+ readerUntil: bigint("reader_until", {
834
+ mode: "number"
835
+ }),
836
+ prunedSeq: bigint("pruned_seq", {
837
+ mode: "number"
838
+ }).notNull(),
839
+ createdAt: bigint("created_at", {
840
+ mode: "number"
841
+ }).notNull(),
842
+ updatedAt: bigint("updated_at", {
843
+ mode: "number"
844
+ }).notNull()
845
+ });
846
+ var agentPoppyEvent2 = mysqlTable("agent_poppy_event", {
847
+ conversationId: key("conversation_id").notNull(),
848
+ seq: bigint("seq", {
849
+ mode: "number"
850
+ }).notNull(),
851
+ id: key("id").notNull(),
852
+ type: key("type").notNull(),
853
+ event: longtext("event").notNull(),
854
+ eventKey: key("event_key"),
855
+ createdAt: bigint("created_at", {
856
+ mode: "number"
857
+ }).notNull()
858
+ }, (table) => [
859
+ primaryKey2({
860
+ columns: [
861
+ table.conversationId,
862
+ table.seq
863
+ ]
864
+ }),
865
+ uniqueIndex2("agent_poppy_event_key_idx").on(table.conversationId, table.eventKey),
866
+ index2("agent_poppy_event_id_idx").on(table.conversationId, table.id)
867
+ ]);
868
+ var agentPoppyMessage2 = mysqlTable("agent_poppy_message", {
869
+ owner: key("owner").notNull(),
870
+ messageId: key("message_id").notNull(),
871
+ fingerprint: key("fingerprint").notNull(),
872
+ conversationId: key("conversation_id").notNull(),
873
+ response: longtext("response").notNull(),
874
+ createdAt: bigint("created_at", {
875
+ mode: "number"
876
+ }).notNull()
877
+ }, (table) => [
878
+ primaryKey2({
879
+ columns: [
880
+ table.owner,
881
+ table.messageId
882
+ ]
883
+ })
884
+ ]);
885
+ var agentPoppyConnection2 = mysqlTable("agent_poppy_connection", {
886
+ owner: key("owner").notNull(),
887
+ issuer: varchar("issuer", {
888
+ length: 512
889
+ }).notNull(),
890
+ domain: key("domain").notNull(),
891
+ organization: key("organization").notNull(),
892
+ scope: longtext("scope").notNull(),
893
+ status: key("status").notNull(),
894
+ state: longtext("state").notNull(),
895
+ createdAt: bigint("created_at", {
896
+ mode: "number"
897
+ }).notNull(),
898
+ updatedAt: bigint("updated_at", {
899
+ mode: "number"
900
+ }).notNull()
901
+ }, (table) => [
902
+ primaryKey2({
903
+ columns: [
904
+ table.owner,
905
+ table.issuer
906
+ ]
907
+ })
908
+ ]);
909
+ var agentPoppyConnect2 = mysqlTable("agent_poppy_connect", {
910
+ id: key("id").primaryKey(),
911
+ owner: key("owner").notNull(),
912
+ domain: key("domain").notNull(),
913
+ issuer: varchar("issuer", {
914
+ length: 512
915
+ }).notNull(),
916
+ organization: key("organization").notNull(),
917
+ scope: longtext("scope").notNull(),
918
+ actor: longtext("actor"),
919
+ threadId: key("thread_id"),
920
+ runId: key("run_id"),
921
+ toolCallId: key("tool_call_id"),
922
+ flow: longtext("flow"),
923
+ status: key("status").notNull(),
924
+ expiresAt: bigint("expires_at", {
925
+ mode: "number"
926
+ }).notNull(),
927
+ createdAt: bigint("created_at", {
928
+ mode: "number"
929
+ }).notNull()
930
+ });
720
931
  var mysqlAgentSchema = {
721
932
  agentActionProposal: agentActionProposal2,
722
933
  agentThread: agentThread2,
@@ -731,7 +942,12 @@ var mysqlAgentSchema = {
731
942
  ragIngestionLog: ragIngestionLog2,
732
943
  agentConfirmToken: agentConfirmToken2,
733
944
  agentChannelState: agentChannelState2,
734
- agentStreamFrame: agentStreamFrame2
945
+ agentStreamFrame: agentStreamFrame2,
946
+ agentPoppyConversation: agentPoppyConversation2,
947
+ agentPoppyEvent: agentPoppyEvent2,
948
+ agentPoppyMessage: agentPoppyMessage2,
949
+ agentPoppyConnection: agentPoppyConnection2,
950
+ agentPoppyConnect: agentPoppyConnect2
735
951
  };
736
952
 
737
953
  // src/schema-pg.ts
@@ -1038,6 +1254,118 @@ var agentActionProposal3 = pgTable("agent_action_proposal", {
1038
1254
  uniqueIndex3("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
1039
1255
  index3("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
1040
1256
  ]);
1257
+ var agentPoppyConversation3 = pgTable("agent_poppy_conversation", {
1258
+ id: text2("id").primaryKey(),
1259
+ clientId: text2("client_id").notNull(),
1260
+ userId: text2("user_id").notNull(),
1261
+ accountRef: text2("account_ref"),
1262
+ agentName: text2("agent_name").notNull(),
1263
+ threadId: text2("thread_id"),
1264
+ parentId: text2("parent_id"),
1265
+ openDirectId: text2("open_direct_id"),
1266
+ status: text2("status").notNull(),
1267
+ responder: text2("responder").notNull(),
1268
+ context: text2("context"),
1269
+ activeRunId: text2("active_run_id"),
1270
+ turnSeq: bigint2("turn_seq", {
1271
+ mode: "number"
1272
+ }).notNull(),
1273
+ grantInfo: text2("grant_info"),
1274
+ readerHolder: text2("reader_holder"),
1275
+ readerUntil: bigint2("reader_until", {
1276
+ mode: "number"
1277
+ }),
1278
+ prunedSeq: bigint2("pruned_seq", {
1279
+ mode: "number"
1280
+ }).notNull(),
1281
+ createdAt: bigint2("created_at", {
1282
+ mode: "number"
1283
+ }).notNull(),
1284
+ updatedAt: bigint2("updated_at", {
1285
+ mode: "number"
1286
+ }).notNull()
1287
+ });
1288
+ var agentPoppyEvent3 = pgTable("agent_poppy_event", {
1289
+ conversationId: text2("conversation_id").notNull(),
1290
+ seq: bigint2("seq", {
1291
+ mode: "number"
1292
+ }).notNull(),
1293
+ id: text2("id").notNull(),
1294
+ type: text2("type").notNull(),
1295
+ event: text2("event").notNull(),
1296
+ eventKey: text2("event_key"),
1297
+ createdAt: bigint2("created_at", {
1298
+ mode: "number"
1299
+ }).notNull()
1300
+ }, (table) => [
1301
+ primaryKey3({
1302
+ columns: [
1303
+ table.conversationId,
1304
+ table.seq
1305
+ ]
1306
+ }),
1307
+ uniqueIndex3("agent_poppy_event_key_idx").on(table.conversationId, table.eventKey),
1308
+ index3("agent_poppy_event_id_idx").on(table.conversationId, table.id)
1309
+ ]);
1310
+ var agentPoppyMessage3 = pgTable("agent_poppy_message", {
1311
+ owner: text2("owner").notNull(),
1312
+ messageId: text2("message_id").notNull(),
1313
+ fingerprint: text2("fingerprint").notNull(),
1314
+ conversationId: text2("conversation_id").notNull(),
1315
+ response: text2("response").notNull(),
1316
+ createdAt: bigint2("created_at", {
1317
+ mode: "number"
1318
+ }).notNull()
1319
+ }, (table) => [
1320
+ primaryKey3({
1321
+ columns: [
1322
+ table.owner,
1323
+ table.messageId
1324
+ ]
1325
+ })
1326
+ ]);
1327
+ var agentPoppyConnection3 = pgTable("agent_poppy_connection", {
1328
+ owner: text2("owner").notNull(),
1329
+ issuer: text2("issuer").notNull(),
1330
+ domain: text2("domain").notNull(),
1331
+ organization: text2("organization").notNull(),
1332
+ scope: text2("scope").notNull(),
1333
+ status: text2("status").notNull(),
1334
+ state: text2("state").notNull(),
1335
+ createdAt: bigint2("created_at", {
1336
+ mode: "number"
1337
+ }).notNull(),
1338
+ updatedAt: bigint2("updated_at", {
1339
+ mode: "number"
1340
+ }).notNull()
1341
+ }, (table) => [
1342
+ primaryKey3({
1343
+ columns: [
1344
+ table.owner,
1345
+ table.issuer
1346
+ ]
1347
+ })
1348
+ ]);
1349
+ var agentPoppyConnect3 = pgTable("agent_poppy_connect", {
1350
+ id: text2("id").primaryKey(),
1351
+ owner: text2("owner").notNull(),
1352
+ domain: text2("domain").notNull(),
1353
+ issuer: text2("issuer").notNull(),
1354
+ organization: text2("organization").notNull(),
1355
+ scope: text2("scope").notNull(),
1356
+ actor: text2("actor"),
1357
+ threadId: text2("thread_id"),
1358
+ runId: text2("run_id"),
1359
+ toolCallId: text2("tool_call_id"),
1360
+ flow: text2("flow"),
1361
+ status: text2("status").notNull(),
1362
+ expiresAt: bigint2("expires_at", {
1363
+ mode: "number"
1364
+ }).notNull(),
1365
+ createdAt: bigint2("created_at", {
1366
+ mode: "number"
1367
+ }).notNull()
1368
+ });
1041
1369
  var pgAgentSchema = {
1042
1370
  agentActionProposal: agentActionProposal3,
1043
1371
  agentThread: agentThread3,
@@ -1052,7 +1380,12 @@ var pgAgentSchema = {
1052
1380
  ragIngestionLog: ragIngestionLog3,
1053
1381
  agentConfirmToken: agentConfirmToken3,
1054
1382
  agentChannelState: agentChannelState3,
1055
- agentStreamFrame: agentStreamFrame3
1383
+ agentStreamFrame: agentStreamFrame3,
1384
+ agentPoppyConversation: agentPoppyConversation3,
1385
+ agentPoppyEvent: agentPoppyEvent3,
1386
+ agentPoppyMessage: agentPoppyMessage3,
1387
+ agentPoppyConnection: agentPoppyConnection3,
1388
+ agentPoppyConnect: agentPoppyConnect3
1056
1389
  };
1057
1390
 
1058
1391
  // src/dialect.ts
@@ -3883,14 +4216,392 @@ var DrizzleChannelStore = class {
3883
4216
  }
3884
4217
  };
3885
4218
 
4219
+ // src/drizzle-poppy-store.ts
4220
+ import { newEventId } from "@dudousxd/nestjs-agent-core";
4221
+ import { and as and8, desc as desc3, eq as eq9, gt as gt4, isNull as isNull4, lt as lt3, lte as lte5, or as or3 } from "drizzle-orm";
4222
+ var MAX_APPEND_ATTEMPTS = 50;
4223
+ var sleep = /* @__PURE__ */ __name((ms) => new Promise((resolve) => setTimeout(resolve, ms)), "sleep");
4224
+ var nullable = /* @__PURE__ */ __name((value) => value == null ? null : String(value), "nullable");
4225
+ function toInt(value) {
4226
+ if (typeof value === "number") return value;
4227
+ if (typeof value === "bigint") return Number(value);
4228
+ if (typeof value === "string") return Number.parseInt(value, 10) || 0;
4229
+ return 0;
4230
+ }
4231
+ __name(toInt, "toInt");
4232
+ var PATCH_COLUMNS = {
4233
+ accountRef: "accountRef",
4234
+ threadId: "threadId",
4235
+ openDirectId: "openDirectId",
4236
+ status: "status",
4237
+ responder: "responder",
4238
+ context: "context",
4239
+ activeRunId: "activeRunId",
4240
+ turnSeq: "turnSeq",
4241
+ grant: "grantInfo",
4242
+ prunedSeq: "prunedSeq"
4243
+ };
4244
+ var DrizzlePoppyStore = class {
4245
+ static {
4246
+ __name(this, "DrizzlePoppyStore");
4247
+ }
4248
+ db;
4249
+ dialect;
4250
+ t;
4251
+ constructor(db) {
4252
+ this.dialect = agentDialectOf(db);
4253
+ this.t = agentTablesFor(this.dialect);
4254
+ this.db = asBuilder(db);
4255
+ }
4256
+ async createConversation(record) {
4257
+ await this.db.insert(this.t.agentPoppyConversation).values({
4258
+ id: record.id,
4259
+ clientId: record.clientId,
4260
+ userId: record.userId,
4261
+ accountRef: record.accountRef,
4262
+ agentName: record.agentName,
4263
+ threadId: record.threadId,
4264
+ parentId: record.parentId,
4265
+ openDirectId: record.openDirectId,
4266
+ status: record.status,
4267
+ responder: record.responder,
4268
+ context: JSON.stringify(record.context),
4269
+ activeRunId: record.activeRunId,
4270
+ turnSeq: record.turnSeq,
4271
+ grantInfo: record.grant === null ? null : JSON.stringify(record.grant),
4272
+ readerHolder: null,
4273
+ readerUntil: null,
4274
+ prunedSeq: record.prunedSeq,
4275
+ createdAt: record.createdAt,
4276
+ updatedAt: record.updatedAt
4277
+ });
4278
+ }
4279
+ async getConversation(id) {
4280
+ const table = this.t.agentPoppyConversation;
4281
+ const [row] = await this.db.select().from(table).where(eq9(table.id, id)).limit(1);
4282
+ if (!row) return null;
4283
+ return {
4284
+ id: row.id,
4285
+ clientId: row.clientId,
4286
+ userId: row.userId,
4287
+ accountRef: nullable(row.accountRef),
4288
+ agentName: row.agentName,
4289
+ threadId: nullable(row.threadId),
4290
+ parentId: nullable(row.parentId),
4291
+ openDirectId: nullable(row.openDirectId),
4292
+ status: row.status,
4293
+ responder: row.responder,
4294
+ context: row.context == null ? {} : JSON.parse(row.context),
4295
+ activeRunId: nullable(row.activeRunId),
4296
+ turnSeq: toInt(row.turnSeq),
4297
+ grant: row.grantInfo == null ? null : JSON.parse(row.grantInfo),
4298
+ prunedSeq: toInt(row.prunedSeq),
4299
+ createdAt: toInt(row.createdAt),
4300
+ updatedAt: toInt(row.updatedAt)
4301
+ };
4302
+ }
4303
+ async updateConversation(id, patch) {
4304
+ const table = this.t.agentPoppyConversation;
4305
+ const set = {
4306
+ updatedAt: Date.now()
4307
+ };
4308
+ for (const [key2, column] of Object.entries(PATCH_COLUMNS)) {
4309
+ const value = patch[key2];
4310
+ if (value === void 0) continue;
4311
+ set[column] = key2 === "context" || key2 === "grant" && value !== null ? JSON.stringify(value) : value;
4312
+ }
4313
+ await this.db.update(table).set(set).where(eq9(table.id, id));
4314
+ }
4315
+ async appendEvent(conversationId, body, options = {}) {
4316
+ const table = this.t.agentPoppyEvent;
4317
+ for (let attempt = 1; ; attempt++) {
4318
+ if (options.key !== void 0) {
4319
+ const [existing] = await this.db.select({
4320
+ seq: table.seq,
4321
+ event: table.event
4322
+ }).from(table).where(and8(eq9(table.conversationId, conversationId), eq9(table.eventKey, options.key))).limit(1);
4323
+ if (existing) {
4324
+ return {
4325
+ event: {
4326
+ seq: toInt(existing.seq),
4327
+ event: JSON.parse(existing.event)
4328
+ },
4329
+ created: false
4330
+ };
4331
+ }
4332
+ }
4333
+ const seq = await this.lastSeq(conversationId) + 1;
4334
+ const now = Date.now();
4335
+ const stored = {
4336
+ seq,
4337
+ event: {
4338
+ id: newEventId(seq),
4339
+ created_at: new Date(now).toISOString(),
4340
+ ...body
4341
+ }
4342
+ };
4343
+ let inserted = false;
4344
+ try {
4345
+ inserted = await this.insertIgnore(table, {
4346
+ conversationId,
4347
+ seq,
4348
+ id: stored.event.id,
4349
+ type: body.type,
4350
+ event: JSON.stringify(stored.event),
4351
+ eventKey: options.key ?? null,
4352
+ createdAt: now
4353
+ });
4354
+ } catch (error) {
4355
+ if (!isUniqueViolation(error)) throw error;
4356
+ }
4357
+ if (inserted) return {
4358
+ event: stored,
4359
+ created: true
4360
+ };
4361
+ if (attempt >= MAX_APPEND_ATTEMPTS) {
4362
+ throw new Error(`poppy: could not append to ${conversationId} after ${attempt} attempts`);
4363
+ }
4364
+ await sleep(Math.random() * Math.min(attempt, 10) * 2);
4365
+ }
4366
+ }
4367
+ /** The last position taken: the last event's, or — every event pruned — the pruned floor. */
4368
+ async lastSeq(conversationId) {
4369
+ const table = this.t.agentPoppyEvent;
4370
+ const [last] = await this.db.select({
4371
+ seq: table.seq
4372
+ }).from(table).where(eq9(table.conversationId, conversationId)).orderBy(desc3(table.seq)).limit(1);
4373
+ if (last) return toInt(last.seq);
4374
+ const conversations = this.t.agentPoppyConversation;
4375
+ const [conversation] = await this.db.select({
4376
+ prunedSeq: conversations.prunedSeq
4377
+ }).from(conversations).where(eq9(conversations.id, conversationId)).limit(1);
4378
+ return toInt(conversation?.prunedSeq);
4379
+ }
4380
+ async listEvents(conversationId, afterSeq, limit) {
4381
+ const table = this.t.agentPoppyEvent;
4382
+ const rows = await this.db.select({
4383
+ seq: table.seq,
4384
+ event: table.event
4385
+ }).from(table).where(and8(eq9(table.conversationId, conversationId), gt4(table.seq, afterSeq))).orderBy(table.seq).limit(limit);
4386
+ return rows.map((row) => ({
4387
+ seq: toInt(row.seq),
4388
+ event: JSON.parse(row.event)
4389
+ }));
4390
+ }
4391
+ async findEventSeq(conversationId, eventId) {
4392
+ const table = this.t.agentPoppyEvent;
4393
+ const [row] = await this.db.select({
4394
+ seq: table.seq
4395
+ }).from(table).where(and8(eq9(table.conversationId, conversationId), eq9(table.id, eventId))).limit(1);
4396
+ return row ? toInt(row.seq) : null;
4397
+ }
4398
+ async pruneEvents(conversationId, before) {
4399
+ const table = this.t.agentPoppyEvent;
4400
+ const [last] = await this.db.select({
4401
+ seq: table.seq
4402
+ }).from(table).where(eq9(table.conversationId, conversationId)).orderBy(desc3(table.seq)).limit(1);
4403
+ if (!last) return;
4404
+ const [dropped] = await this.db.select({
4405
+ seq: table.seq
4406
+ }).from(table).where(and8(eq9(table.conversationId, conversationId), lt3(table.createdAt, before), lt3(table.seq, toInt(last.seq)))).orderBy(desc3(table.seq)).limit(1);
4407
+ if (!dropped) return;
4408
+ const upTo = toInt(dropped.seq);
4409
+ const conversations = this.t.agentPoppyConversation;
4410
+ await this.db.update(conversations).set({
4411
+ prunedSeq: upTo
4412
+ }).where(and8(eq9(conversations.id, conversationId), lt3(conversations.prunedSeq, upTo)));
4413
+ await this.db.delete(table).where(and8(eq9(table.conversationId, conversationId), lte5(table.seq, upTo)));
4414
+ }
4415
+ async claimMessage(owner, messageId, receipt) {
4416
+ const table = this.t.agentPoppyMessage;
4417
+ for (let attempt = 1; ; attempt++) {
4418
+ const inserted = await this.insertIgnore(table, {
4419
+ owner,
4420
+ messageId,
4421
+ fingerprint: receipt.fingerprint,
4422
+ conversationId: receipt.conversationId,
4423
+ response: JSON.stringify(receipt.response),
4424
+ createdAt: Date.now()
4425
+ });
4426
+ if (inserted) return {
4427
+ status: "claimed"
4428
+ };
4429
+ const [row] = await this.db.select().from(table).where(and8(eq9(table.owner, owner), eq9(table.messageId, messageId))).limit(1);
4430
+ if (row) {
4431
+ return {
4432
+ status: "existing",
4433
+ fingerprint: row.fingerprint,
4434
+ conversationId: row.conversationId,
4435
+ response: JSON.parse(row.response)
4436
+ };
4437
+ }
4438
+ if (attempt >= 5) throw new Error(`poppy: could not claim message ${messageId}`);
4439
+ }
4440
+ }
4441
+ async releaseMessage(owner, messageId) {
4442
+ const table = this.t.agentPoppyMessage;
4443
+ await this.db.delete(table).where(and8(eq9(table.owner, owner), eq9(table.messageId, messageId)));
4444
+ }
4445
+ async leaseReader(conversationId, holder, ttlMs) {
4446
+ const table = this.t.agentPoppyConversation;
4447
+ const now = Date.now();
4448
+ const taken = await affectedRows(this.dialect, this.db.update(table).set({
4449
+ readerHolder: holder,
4450
+ readerUntil: now + ttlMs
4451
+ }).where(and8(eq9(table.id, conversationId), or3(isNull4(table.readerHolder), eq9(table.readerHolder, holder), lte5(table.readerUntil, now)))), table.id);
4452
+ if (taken === 1) return true;
4453
+ if (this.dialect !== "mysql") return false;
4454
+ const [row] = await this.db.select({
4455
+ holder: table.readerHolder
4456
+ }).from(table).where(eq9(table.id, conversationId)).limit(1);
4457
+ return row?.holder === holder;
4458
+ }
4459
+ async releaseReader(conversationId, holder) {
4460
+ const table = this.t.agentPoppyConversation;
4461
+ await this.db.update(table).set({
4462
+ readerHolder: null,
4463
+ readerUntil: null
4464
+ }).where(and8(eq9(table.id, conversationId), eq9(table.readerHolder, holder)));
4465
+ }
4466
+ /** Insert `row`, skipping it on any duplicate key. `true` when it went in. */
4467
+ async insertIgnore(table, row) {
4468
+ if (this.dialect === "mysql") {
4469
+ const insert = this.db.insert(table);
4470
+ return mysqlAffectedRows(await insert.ignore().values(row)) === 1;
4471
+ }
4472
+ const statement = this.db.insert(table).values(row).onConflictDoNothing();
4473
+ return await affectedRows(this.dialect, statement, table.createdAt) === 1;
4474
+ }
4475
+ };
4476
+
4477
+ // src/drizzle-poppy-connection-store.ts
4478
+ import { and as and9, asc as asc5, eq as eq10 } from "drizzle-orm";
4479
+ var nullable2 = /* @__PURE__ */ __name((value) => value == null ? null : String(value), "nullable");
4480
+ var toInt2 = /* @__PURE__ */ __name((value) => typeof value === "number" ? value : Number(value ?? 0), "toInt");
4481
+ var DrizzlePoppyConnectionStore = class {
4482
+ static {
4483
+ __name(this, "DrizzlePoppyConnectionStore");
4484
+ }
4485
+ db;
4486
+ dialect;
4487
+ t;
4488
+ constructor(db) {
4489
+ this.dialect = agentDialectOf(db);
4490
+ this.t = agentTablesFor(this.dialect);
4491
+ this.db = asBuilder(db);
4492
+ }
4493
+ async listConnections(owner) {
4494
+ const table = this.t.agentPoppyConnection;
4495
+ const rows = await this.db.select().from(table).where(eq10(table.owner, owner)).orderBy(asc5(table.domain), asc5(table.issuer));
4496
+ return rows.map(toConnection);
4497
+ }
4498
+ async getConnection(owner, issuer) {
4499
+ const table = this.t.agentPoppyConnection;
4500
+ const [row] = await this.db.select().from(table).where(and9(eq10(table.owner, owner), eq10(table.issuer, issuer))).limit(1);
4501
+ return row ? toConnection(row) : null;
4502
+ }
4503
+ async saveConnection(record) {
4504
+ const table = this.t.agentPoppyConnection;
4505
+ const columns = {
4506
+ domain: record.domain,
4507
+ organization: record.organization,
4508
+ scope: record.scope,
4509
+ status: record.status,
4510
+ state: record.state,
4511
+ updatedAt: record.updatedAt
4512
+ };
4513
+ await upsert(this.dialect, this.db.insert(table).values({
4514
+ owner: record.owner,
4515
+ issuer: record.issuer,
4516
+ createdAt: record.createdAt,
4517
+ ...columns
4518
+ }), [
4519
+ table.owner,
4520
+ table.issuer
4521
+ ], columns);
4522
+ }
4523
+ async deleteConnection(owner, issuer) {
4524
+ const table = this.t.agentPoppyConnection;
4525
+ await this.db.delete(table).where(and9(eq10(table.owner, owner), eq10(table.issuer, issuer)));
4526
+ }
4527
+ async createPending(record) {
4528
+ const table = this.t.agentPoppyConnect;
4529
+ const row = {
4530
+ id: record.id,
4531
+ owner: record.owner,
4532
+ domain: record.domain,
4533
+ issuer: record.issuer,
4534
+ organization: record.organization,
4535
+ scope: record.scope,
4536
+ actor: record.actor === null ? null : JSON.stringify(record.actor),
4537
+ threadId: record.threadId,
4538
+ runId: record.runId,
4539
+ toolCallId: record.toolCallId,
4540
+ flow: record.flow,
4541
+ status: record.status,
4542
+ expiresAt: record.expiresAt,
4543
+ createdAt: record.createdAt
4544
+ };
4545
+ if (this.dialect === "mysql") {
4546
+ const insert = this.db.insert(table);
4547
+ await insert.ignore().values(row);
4548
+ return;
4549
+ }
4550
+ await this.db.insert(table).values(row).onConflictDoNothing();
4551
+ }
4552
+ async getPending(id) {
4553
+ const table = this.t.agentPoppyConnect;
4554
+ const [row] = await this.db.select().from(table).where(eq10(table.id, id)).limit(1);
4555
+ if (!row) return null;
4556
+ return {
4557
+ id: row.id,
4558
+ owner: row.owner,
4559
+ domain: row.domain,
4560
+ issuer: row.issuer,
4561
+ organization: row.organization,
4562
+ scope: row.scope ?? "",
4563
+ actor: row.actor == null ? null : JSON.parse(row.actor),
4564
+ threadId: nullable2(row.threadId),
4565
+ runId: nullable2(row.runId),
4566
+ toolCallId: nullable2(row.toolCallId),
4567
+ flow: nullable2(row.flow),
4568
+ status: row.status,
4569
+ expiresAt: toInt2(row.expiresAt),
4570
+ createdAt: toInt2(row.createdAt)
4571
+ };
4572
+ }
4573
+ async updatePending(id, patch) {
4574
+ const set = {};
4575
+ if (patch.flow !== void 0) set.flow = patch.flow;
4576
+ if (patch.status !== void 0) set.status = patch.status;
4577
+ if (Object.keys(set).length === 0) return;
4578
+ const table = this.t.agentPoppyConnect;
4579
+ await this.db.update(table).set(set).where(eq10(table.id, id));
4580
+ }
4581
+ };
4582
+ function toConnection(row) {
4583
+ return {
4584
+ owner: row.owner,
4585
+ issuer: row.issuer,
4586
+ domain: row.domain,
4587
+ organization: row.organization,
4588
+ scope: row.scope ?? "",
4589
+ status: row.status,
4590
+ state: row.state,
4591
+ createdAt: toInt2(row.createdAt),
4592
+ updatedAt: toInt2(row.updatedAt)
4593
+ };
4594
+ }
4595
+ __name(toConnection, "toConnection");
4596
+
3886
4597
  // src/drizzle-rag-ingestion-log.ts
3887
4598
  import { subscribe, unsubscribe } from "diagnostics_channel";
3888
4599
  import { Injectable, Logger } from "@nestjs/common";
3889
- import { and as and8, asc as asc5, count as count2, desc as desc3, eq as eq9, gt as gt4, lt as lt3, or as or3 } from "drizzle-orm";
3890
- function _ts_decorate(decorators, target, key2, desc4) {
3891
- var c = arguments.length, r = c < 3 ? target : desc4 === null ? desc4 = Object.getOwnPropertyDescriptor(target, key2) : desc4, d;
4600
+ import { and as and10, asc as asc6, count as count2, desc as desc4, eq as eq11, gt as gt5, lt as lt4, or as or4 } from "drizzle-orm";
4601
+ function _ts_decorate(decorators, target, key2, desc5) {
4602
+ var c = arguments.length, r = c < 3 ? target : desc5 === null ? desc5 = Object.getOwnPropertyDescriptor(target, key2) : desc5, d;
3892
4603
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
3893
- r = Reflect.decorate(decorators, target, key2, desc4);
4604
+ r = Reflect.decorate(decorators, target, key2, desc5);
3894
4605
  } else {
3895
4606
  for (var i = decorators.length - 1; i >= 0; i--) {
3896
4607
  if (d = decorators[i]) {
@@ -3934,8 +4645,8 @@ function num(value) {
3934
4645
  }
3935
4646
  __name(num, "num");
3936
4647
  var RAG_INGESTION_LOG_PAGE_ORDER = [
3937
- desc3(ragIngestionLog.updatedAt),
3938
- asc5(ragIngestionLog.documentId)
4648
+ desc4(ragIngestionLog.updatedAt),
4649
+ asc6(ragIngestionLog.documentId)
3939
4650
  ];
3940
4651
  var DEFAULT_PAGE_SIZE = 200;
3941
4652
  var DEFAULT_BATCH_SIZE = 200;
@@ -4085,17 +4796,17 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
4085
4796
  }
4086
4797
  /** The latest recorded outcome for one document, or null if it was never attempted. */
4087
4798
  async get(documentId) {
4088
- const [row] = await this.db.select().from(this.t.ragIngestionLog).where(eq9(this.t.ragIngestionLog.documentId, documentId));
4799
+ const [row] = await this.db.select().from(this.t.ragIngestionLog).where(eq11(this.t.ragIngestionLog.documentId, documentId));
4089
4800
  return row ?? null;
4090
4801
  }
4091
4802
  /** Forget one document's record. Returns whether a row was actually removed. */
4092
4803
  async remove(documentId) {
4093
- const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq9(this.t.ragIngestionLog.documentId, documentId)), this.t.ragIngestionLog.documentId);
4804
+ const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq11(this.t.ragIngestionLog.documentId, documentId)), this.t.ragIngestionLog.documentId);
4094
4805
  return removed > 0;
4095
4806
  }
4096
4807
  /** Forget every record for a collection — for when the collection itself is deleted. */
4097
4808
  async removeByCollection(collection) {
4098
- const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq9(this.t.ragIngestionLog.collection, collection)), this.t.ragIngestionLog.documentId);
4809
+ const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq11(this.t.ragIngestionLog.collection, collection)), this.t.ragIngestionLog.documentId);
4099
4810
  return removed;
4100
4811
  }
4101
4812
  /**
@@ -4125,7 +4836,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
4125
4836
  }
4126
4837
  }
4127
4838
  where(query) {
4128
- return and8(query.collection !== void 0 ? eq9(this.t.ragIngestionLog.collection, query.collection) : void 0, query.status !== void 0 ? eq9(this.t.ragIngestionLog.status, query.status) : void 0);
4839
+ return and10(query.collection !== void 0 ? eq11(this.t.ragIngestionLog.collection, query.collection) : void 0, query.status !== void 0 ? eq11(this.t.ragIngestionLog.status, query.status) : void 0);
4129
4840
  }
4130
4841
  /**
4131
4842
  * The coordinates filter AND'd with "strictly after `cursor` in
@@ -4140,7 +4851,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
4140
4851
  if (cursor === void 0) {
4141
4852
  return base;
4142
4853
  }
4143
- return and8(base, or3(lt3(this.t.ragIngestionLog.updatedAt, cursor.updatedAt), and8(eq9(this.t.ragIngestionLog.updatedAt, cursor.updatedAt), gt4(this.t.ragIngestionLog.documentId, cursor.documentId))));
4854
+ return and10(base, or4(lt4(this.t.ragIngestionLog.updatedAt, cursor.updatedAt), and10(eq11(this.t.ragIngestionLog.updatedAt, cursor.updatedAt), gt5(this.t.ragIngestionLog.documentId, cursor.documentId))));
4144
4855
  }
4145
4856
  /**
4146
4857
  * Upsert one outcome. Keyed by document id so the row always reflects the *current* state — a
@@ -4213,12 +4924,12 @@ DrizzleRagIngestionLog = _ts_decorate([
4213
4924
  ], DrizzleRagIngestionLog);
4214
4925
 
4215
4926
  // src/drizzle-agent-store.module.ts
4216
- import { AGENT_CHANNEL_STORE, AGENT_CONFIRM_TOKEN_STORE, AGENT_GOVERNANCE_QUERIES, AGENT_PRICING_STORE, AGENT_STORE } from "@dudousxd/nestjs-agent-core";
4927
+ import { AGENT_CHANNEL_STORE, AGENT_CONFIRM_TOKEN_STORE, AGENT_GOVERNANCE_QUERIES, AGENT_POPPY_CONNECTION_STORE, AGENT_POPPY_STORE, AGENT_PRICING_STORE, AGENT_STORE } from "@dudousxd/nestjs-agent-core";
4217
4928
  import { Module } from "@nestjs/common";
4218
- function _ts_decorate2(decorators, target, key2, desc4) {
4219
- var c = arguments.length, r = c < 3 ? target : desc4 === null ? desc4 = Object.getOwnPropertyDescriptor(target, key2) : desc4, d;
4929
+ function _ts_decorate2(decorators, target, key2, desc5) {
4930
+ var c = arguments.length, r = c < 3 ? target : desc5 === null ? desc5 = Object.getOwnPropertyDescriptor(target, key2) : desc5, d;
4220
4931
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
4221
- r = Reflect.decorate(decorators, target, key2, desc4);
4932
+ r = Reflect.decorate(decorators, target, key2, desc5);
4222
4933
  } else {
4223
4934
  for (var i = decorators.length - 1; i >= 0; i--) {
4224
4935
  if (d = decorators[i]) {
@@ -4301,6 +5012,23 @@ var DrizzleAgentStoreModule = class _DrizzleAgentStoreModule {
4301
5012
  {
4302
5013
  provide: AGENT_CHANNEL_STORE,
4303
5014
  useExisting: DrizzleChannelStore
5015
+ },
5016
+ // Personal Agent Protocol (Poppy) conversations and connections, shared by every replica.
5017
+ {
5018
+ provide: DrizzlePoppyStore,
5019
+ useFactory: /* @__PURE__ */ __name(() => new DrizzlePoppyStore(options.db), "useFactory")
5020
+ },
5021
+ {
5022
+ provide: AGENT_POPPY_STORE,
5023
+ useExisting: DrizzlePoppyStore
5024
+ },
5025
+ {
5026
+ provide: DrizzlePoppyConnectionStore,
5027
+ useFactory: /* @__PURE__ */ __name(() => new DrizzlePoppyConnectionStore(options.db), "useFactory")
5028
+ },
5029
+ {
5030
+ provide: AGENT_POPPY_CONNECTION_STORE,
5031
+ useExisting: DrizzlePoppyConnectionStore
4304
5032
  }
4305
5033
  ],
4306
5034
  exports: [
@@ -4317,7 +5045,11 @@ var DrizzleAgentStoreModule = class _DrizzleAgentStoreModule {
4317
5045
  DrizzleConfirmTokenStore,
4318
5046
  AGENT_CONFIRM_TOKEN_STORE,
4319
5047
  DrizzleChannelStore,
4320
- AGENT_CHANNEL_STORE
5048
+ AGENT_CHANNEL_STORE,
5049
+ DrizzlePoppyStore,
5050
+ AGENT_POPPY_STORE,
5051
+ DrizzlePoppyConnectionStore,
5052
+ AGENT_POPPY_CONNECTION_STORE
4321
5053
  ]
4322
5054
  };
4323
5055
  }
@@ -4333,6 +5065,8 @@ export {
4333
5065
  DrizzleConfirmTokenStore,
4334
5066
  DrizzleGovernanceQueries,
4335
5067
  DrizzleMemoryProvider,
5068
+ DrizzlePoppyConnectionStore,
5069
+ DrizzlePoppyStore,
4336
5070
  DrizzlePricingStore,
4337
5071
  DrizzleRagIngestionLog,
4338
5072
  DrizzleStreamFrameTable,
@@ -4346,6 +5080,11 @@ export {
4346
5080
  agentMemory,
4347
5081
  agentMessage,
4348
5082
  agentModelPricing,
5083
+ agentPoppyConnect,
5084
+ agentPoppyConnection,
5085
+ agentPoppyConversation,
5086
+ agentPoppyEvent,
5087
+ agentPoppyMessage,
4349
5088
  agentQueuedMessage,
4350
5089
  agentRun,
4351
5090
  agentSchema,