@dudousxd/nestjs-agent-store-drizzle 0.30.0 → 0.32.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
@@ -249,6 +249,12 @@ var agentRun = sqliteTable("agent_run", {
249
249
  agentName: text("agent_name"),
250
250
  status: text("status").$type().notNull(),
251
251
  durationMs: integer("duration_ms"),
252
+ /** Turn start to the first `text` frame; null for a run that streamed none or did not complete. */
253
+ ttftMs: integer("ttft_ms"),
254
+ /** The run's known spend (the sum of its model calls with a known cost); null when none had one. */
255
+ costUsd: real("cost_usd"),
256
+ /** The model the run's last model call resolved to. */
257
+ modelId: text("model_id"),
252
258
  errorCode: text("error_code"),
253
259
  errorMessage: text("error_message"),
254
260
  retries: integer("retries").notNull().default(0),
@@ -381,6 +387,94 @@ var agentActionProposal = sqliteTable("agent_action_proposal", {
381
387
  uniqueIndex("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
382
388
  index("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
383
389
  ]);
390
+ var agentPoppyConversation = sqliteTable("agent_poppy_conversation", {
391
+ id: text("id").primaryKey(),
392
+ clientId: text("client_id").notNull(),
393
+ userId: text("user_id").notNull(),
394
+ accountRef: text("account_ref"),
395
+ agentName: text("agent_name").notNull(),
396
+ threadId: text("thread_id"),
397
+ parentId: text("parent_id"),
398
+ openDirectId: text("open_direct_id"),
399
+ status: text("status").notNull(),
400
+ responder: text("responder").notNull(),
401
+ context: text("context"),
402
+ activeRunId: text("active_run_id"),
403
+ turnSeq: integer("turn_seq").notNull(),
404
+ grantInfo: text("grant_info"),
405
+ readerHolder: text("reader_holder"),
406
+ readerUntil: integer("reader_until"),
407
+ prunedSeq: integer("pruned_seq").notNull(),
408
+ createdAt: integer("created_at").notNull(),
409
+ updatedAt: integer("updated_at").notNull()
410
+ });
411
+ var agentPoppyEvent = sqliteTable("agent_poppy_event", {
412
+ conversationId: text("conversation_id").notNull(),
413
+ seq: integer("seq").notNull(),
414
+ id: text("id").notNull(),
415
+ type: text("type").notNull(),
416
+ event: text("event").notNull(),
417
+ eventKey: text("event_key"),
418
+ createdAt: integer("created_at").notNull()
419
+ }, (table) => [
420
+ primaryKey({
421
+ columns: [
422
+ table.conversationId,
423
+ table.seq
424
+ ]
425
+ }),
426
+ uniqueIndex("agent_poppy_event_key_idx").on(table.conversationId, table.eventKey),
427
+ index("agent_poppy_event_id_idx").on(table.conversationId, table.id)
428
+ ]);
429
+ var agentPoppyMessage = sqliteTable("agent_poppy_message", {
430
+ owner: text("owner").notNull(),
431
+ messageId: text("message_id").notNull(),
432
+ fingerprint: text("fingerprint").notNull(),
433
+ conversationId: text("conversation_id").notNull(),
434
+ response: text("response").notNull(),
435
+ createdAt: integer("created_at").notNull()
436
+ }, (table) => [
437
+ primaryKey({
438
+ columns: [
439
+ table.owner,
440
+ table.messageId
441
+ ]
442
+ })
443
+ ]);
444
+ var agentPoppyConnection = sqliteTable("agent_poppy_connection", {
445
+ owner: text("owner").notNull(),
446
+ issuer: text("issuer").notNull(),
447
+ domain: text("domain").notNull(),
448
+ organization: text("organization").notNull(),
449
+ scope: text("scope").notNull(),
450
+ status: text("status").notNull(),
451
+ state: text("state").notNull(),
452
+ createdAt: integer("created_at").notNull(),
453
+ updatedAt: integer("updated_at").notNull()
454
+ }, (table) => [
455
+ primaryKey({
456
+ columns: [
457
+ table.owner,
458
+ table.issuer
459
+ ]
460
+ })
461
+ ]);
462
+ var agentPoppyConnect = sqliteTable("agent_poppy_connect", {
463
+ id: text("id").primaryKey(),
464
+ owner: text("owner").notNull(),
465
+ domain: text("domain").notNull(),
466
+ issuer: text("issuer").notNull(),
467
+ organization: text("organization").notNull(),
468
+ scope: text("scope").notNull(),
469
+ actor: text("actor"),
470
+ threadId: text("thread_id"),
471
+ runId: text("run_id"),
472
+ toolCallId: text("tool_call_id"),
473
+ flow: text("flow"),
474
+ status: text("status").notNull(),
475
+ expiresAt: integer("expires_at").notNull(),
476
+ createdAt: integer("created_at").notNull()
477
+ });
384
478
  var agentSchema = {
385
479
  agentActionProposal,
386
480
  agentThread,
@@ -395,7 +489,12 @@ var agentSchema = {
395
489
  ragIngestionLog,
396
490
  agentConfirmToken,
397
491
  agentChannelState,
398
- agentStreamFrame
492
+ agentStreamFrame,
493
+ agentPoppyConversation,
494
+ agentPoppyEvent,
495
+ agentPoppyMessage,
496
+ agentPoppyConnection,
497
+ agentPoppyConnect
399
498
  };
400
499
 
401
500
  // src/ensure-schema.ts
@@ -588,6 +687,12 @@ var agentRun2 = mysqlTable("agent_run", {
588
687
  agentName: key("agent_name"),
589
688
  status: key("status").$type().notNull(),
590
689
  durationMs: int("duration_ms"),
690
+ /** Turn start to the first `text` frame; null for a run that streamed none or did not complete. */
691
+ ttftMs: int("ttft_ms"),
692
+ /** The run's known spend (the sum of its model calls with a known cost); null when none had one. */
693
+ costUsd: double("cost_usd"),
694
+ /** The model the run's last model call resolved to. */
695
+ modelId: key("model_id"),
591
696
  errorCode: key("error_code"),
592
697
  errorMessage: longtext("error_message"),
593
698
  retries: int("retries").notNull().default(0),
@@ -717,6 +822,124 @@ var agentActionProposal2 = mysqlTable("agent_action_proposal", {
717
822
  uniqueIndex2("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
718
823
  index2("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
719
824
  ]);
825
+ var agentPoppyConversation2 = mysqlTable("agent_poppy_conversation", {
826
+ id: key("id").primaryKey(),
827
+ clientId: varchar("client_id", {
828
+ length: 2048
829
+ }).notNull(),
830
+ userId: key("user_id").notNull(),
831
+ accountRef: key("account_ref"),
832
+ agentName: key("agent_name").notNull(),
833
+ threadId: key("thread_id"),
834
+ parentId: key("parent_id"),
835
+ openDirectId: key("open_direct_id"),
836
+ status: key("status").notNull(),
837
+ responder: key("responder").notNull(),
838
+ context: longtext("context"),
839
+ activeRunId: key("active_run_id"),
840
+ turnSeq: bigint("turn_seq", {
841
+ mode: "number"
842
+ }).notNull(),
843
+ grantInfo: longtext("grant_info"),
844
+ readerHolder: key("reader_holder"),
845
+ readerUntil: bigint("reader_until", {
846
+ mode: "number"
847
+ }),
848
+ prunedSeq: bigint("pruned_seq", {
849
+ mode: "number"
850
+ }).notNull(),
851
+ createdAt: bigint("created_at", {
852
+ mode: "number"
853
+ }).notNull(),
854
+ updatedAt: bigint("updated_at", {
855
+ mode: "number"
856
+ }).notNull()
857
+ });
858
+ var agentPoppyEvent2 = mysqlTable("agent_poppy_event", {
859
+ conversationId: key("conversation_id").notNull(),
860
+ seq: bigint("seq", {
861
+ mode: "number"
862
+ }).notNull(),
863
+ id: key("id").notNull(),
864
+ type: key("type").notNull(),
865
+ event: longtext("event").notNull(),
866
+ eventKey: key("event_key"),
867
+ createdAt: bigint("created_at", {
868
+ mode: "number"
869
+ }).notNull()
870
+ }, (table) => [
871
+ primaryKey2({
872
+ columns: [
873
+ table.conversationId,
874
+ table.seq
875
+ ]
876
+ }),
877
+ uniqueIndex2("agent_poppy_event_key_idx").on(table.conversationId, table.eventKey),
878
+ index2("agent_poppy_event_id_idx").on(table.conversationId, table.id)
879
+ ]);
880
+ var agentPoppyMessage2 = mysqlTable("agent_poppy_message", {
881
+ owner: key("owner").notNull(),
882
+ messageId: key("message_id").notNull(),
883
+ fingerprint: key("fingerprint").notNull(),
884
+ conversationId: key("conversation_id").notNull(),
885
+ response: longtext("response").notNull(),
886
+ createdAt: bigint("created_at", {
887
+ mode: "number"
888
+ }).notNull()
889
+ }, (table) => [
890
+ primaryKey2({
891
+ columns: [
892
+ table.owner,
893
+ table.messageId
894
+ ]
895
+ })
896
+ ]);
897
+ var agentPoppyConnection2 = mysqlTable("agent_poppy_connection", {
898
+ owner: key("owner").notNull(),
899
+ issuer: varchar("issuer", {
900
+ length: 512
901
+ }).notNull(),
902
+ domain: key("domain").notNull(),
903
+ organization: key("organization").notNull(),
904
+ scope: longtext("scope").notNull(),
905
+ status: key("status").notNull(),
906
+ state: longtext("state").notNull(),
907
+ createdAt: bigint("created_at", {
908
+ mode: "number"
909
+ }).notNull(),
910
+ updatedAt: bigint("updated_at", {
911
+ mode: "number"
912
+ }).notNull()
913
+ }, (table) => [
914
+ primaryKey2({
915
+ columns: [
916
+ table.owner,
917
+ table.issuer
918
+ ]
919
+ })
920
+ ]);
921
+ var agentPoppyConnect2 = mysqlTable("agent_poppy_connect", {
922
+ id: key("id").primaryKey(),
923
+ owner: key("owner").notNull(),
924
+ domain: key("domain").notNull(),
925
+ issuer: varchar("issuer", {
926
+ length: 512
927
+ }).notNull(),
928
+ organization: key("organization").notNull(),
929
+ scope: longtext("scope").notNull(),
930
+ actor: longtext("actor"),
931
+ threadId: key("thread_id"),
932
+ runId: key("run_id"),
933
+ toolCallId: key("tool_call_id"),
934
+ flow: longtext("flow"),
935
+ status: key("status").notNull(),
936
+ expiresAt: bigint("expires_at", {
937
+ mode: "number"
938
+ }).notNull(),
939
+ createdAt: bigint("created_at", {
940
+ mode: "number"
941
+ }).notNull()
942
+ });
720
943
  var mysqlAgentSchema = {
721
944
  agentActionProposal: agentActionProposal2,
722
945
  agentThread: agentThread2,
@@ -731,7 +954,12 @@ var mysqlAgentSchema = {
731
954
  ragIngestionLog: ragIngestionLog2,
732
955
  agentConfirmToken: agentConfirmToken2,
733
956
  agentChannelState: agentChannelState2,
734
- agentStreamFrame: agentStreamFrame2
957
+ agentStreamFrame: agentStreamFrame2,
958
+ agentPoppyConversation: agentPoppyConversation2,
959
+ agentPoppyEvent: agentPoppyEvent2,
960
+ agentPoppyMessage: agentPoppyMessage2,
961
+ agentPoppyConnection: agentPoppyConnection2,
962
+ agentPoppyConnect: agentPoppyConnect2
735
963
  };
736
964
 
737
965
  // src/schema-pg.ts
@@ -911,6 +1139,12 @@ var agentRun3 = pgTable("agent_run", {
911
1139
  agentName: text2("agent_name"),
912
1140
  status: text2("status").$type().notNull(),
913
1141
  durationMs: integer2("duration_ms"),
1142
+ /** Turn start to the first `text` frame; null for a run that streamed none or did not complete. */
1143
+ ttftMs: integer2("ttft_ms"),
1144
+ /** The run's known spend (the sum of its model calls with a known cost); null when none had one. */
1145
+ costUsd: doublePrecision("cost_usd"),
1146
+ /** The model the run's last model call resolved to. */
1147
+ modelId: text2("model_id"),
914
1148
  errorCode: text2("error_code"),
915
1149
  errorMessage: text2("error_message"),
916
1150
  retries: integer2("retries").notNull().default(0),
@@ -1038,6 +1272,118 @@ var agentActionProposal3 = pgTable("agent_action_proposal", {
1038
1272
  uniqueIndex3("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
1039
1273
  index3("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
1040
1274
  ]);
1275
+ var agentPoppyConversation3 = pgTable("agent_poppy_conversation", {
1276
+ id: text2("id").primaryKey(),
1277
+ clientId: text2("client_id").notNull(),
1278
+ userId: text2("user_id").notNull(),
1279
+ accountRef: text2("account_ref"),
1280
+ agentName: text2("agent_name").notNull(),
1281
+ threadId: text2("thread_id"),
1282
+ parentId: text2("parent_id"),
1283
+ openDirectId: text2("open_direct_id"),
1284
+ status: text2("status").notNull(),
1285
+ responder: text2("responder").notNull(),
1286
+ context: text2("context"),
1287
+ activeRunId: text2("active_run_id"),
1288
+ turnSeq: bigint2("turn_seq", {
1289
+ mode: "number"
1290
+ }).notNull(),
1291
+ grantInfo: text2("grant_info"),
1292
+ readerHolder: text2("reader_holder"),
1293
+ readerUntil: bigint2("reader_until", {
1294
+ mode: "number"
1295
+ }),
1296
+ prunedSeq: bigint2("pruned_seq", {
1297
+ mode: "number"
1298
+ }).notNull(),
1299
+ createdAt: bigint2("created_at", {
1300
+ mode: "number"
1301
+ }).notNull(),
1302
+ updatedAt: bigint2("updated_at", {
1303
+ mode: "number"
1304
+ }).notNull()
1305
+ });
1306
+ var agentPoppyEvent3 = pgTable("agent_poppy_event", {
1307
+ conversationId: text2("conversation_id").notNull(),
1308
+ seq: bigint2("seq", {
1309
+ mode: "number"
1310
+ }).notNull(),
1311
+ id: text2("id").notNull(),
1312
+ type: text2("type").notNull(),
1313
+ event: text2("event").notNull(),
1314
+ eventKey: text2("event_key"),
1315
+ createdAt: bigint2("created_at", {
1316
+ mode: "number"
1317
+ }).notNull()
1318
+ }, (table) => [
1319
+ primaryKey3({
1320
+ columns: [
1321
+ table.conversationId,
1322
+ table.seq
1323
+ ]
1324
+ }),
1325
+ uniqueIndex3("agent_poppy_event_key_idx").on(table.conversationId, table.eventKey),
1326
+ index3("agent_poppy_event_id_idx").on(table.conversationId, table.id)
1327
+ ]);
1328
+ var agentPoppyMessage3 = pgTable("agent_poppy_message", {
1329
+ owner: text2("owner").notNull(),
1330
+ messageId: text2("message_id").notNull(),
1331
+ fingerprint: text2("fingerprint").notNull(),
1332
+ conversationId: text2("conversation_id").notNull(),
1333
+ response: text2("response").notNull(),
1334
+ createdAt: bigint2("created_at", {
1335
+ mode: "number"
1336
+ }).notNull()
1337
+ }, (table) => [
1338
+ primaryKey3({
1339
+ columns: [
1340
+ table.owner,
1341
+ table.messageId
1342
+ ]
1343
+ })
1344
+ ]);
1345
+ var agentPoppyConnection3 = pgTable("agent_poppy_connection", {
1346
+ owner: text2("owner").notNull(),
1347
+ issuer: text2("issuer").notNull(),
1348
+ domain: text2("domain").notNull(),
1349
+ organization: text2("organization").notNull(),
1350
+ scope: text2("scope").notNull(),
1351
+ status: text2("status").notNull(),
1352
+ state: text2("state").notNull(),
1353
+ createdAt: bigint2("created_at", {
1354
+ mode: "number"
1355
+ }).notNull(),
1356
+ updatedAt: bigint2("updated_at", {
1357
+ mode: "number"
1358
+ }).notNull()
1359
+ }, (table) => [
1360
+ primaryKey3({
1361
+ columns: [
1362
+ table.owner,
1363
+ table.issuer
1364
+ ]
1365
+ })
1366
+ ]);
1367
+ var agentPoppyConnect3 = pgTable("agent_poppy_connect", {
1368
+ id: text2("id").primaryKey(),
1369
+ owner: text2("owner").notNull(),
1370
+ domain: text2("domain").notNull(),
1371
+ issuer: text2("issuer").notNull(),
1372
+ organization: text2("organization").notNull(),
1373
+ scope: text2("scope").notNull(),
1374
+ actor: text2("actor"),
1375
+ threadId: text2("thread_id"),
1376
+ runId: text2("run_id"),
1377
+ toolCallId: text2("tool_call_id"),
1378
+ flow: text2("flow"),
1379
+ status: text2("status").notNull(),
1380
+ expiresAt: bigint2("expires_at", {
1381
+ mode: "number"
1382
+ }).notNull(),
1383
+ createdAt: bigint2("created_at", {
1384
+ mode: "number"
1385
+ }).notNull()
1386
+ });
1041
1387
  var pgAgentSchema = {
1042
1388
  agentActionProposal: agentActionProposal3,
1043
1389
  agentThread: agentThread3,
@@ -1052,7 +1398,12 @@ var pgAgentSchema = {
1052
1398
  ragIngestionLog: ragIngestionLog3,
1053
1399
  agentConfirmToken: agentConfirmToken3,
1054
1400
  agentChannelState: agentChannelState3,
1055
- agentStreamFrame: agentStreamFrame3
1401
+ agentStreamFrame: agentStreamFrame3,
1402
+ agentPoppyConversation: agentPoppyConversation3,
1403
+ agentPoppyEvent: agentPoppyEvent3,
1404
+ agentPoppyMessage: agentPoppyMessage3,
1405
+ agentPoppyConnection: agentPoppyConnection3,
1406
+ agentPoppyConnect: agentPoppyConnect3
1056
1407
  };
1057
1408
 
1058
1409
  // src/dialect.ts
@@ -2409,6 +2760,9 @@ var DrizzleAgentStore = class {
2409
2760
  agentName: run.agentName ?? null,
2410
2761
  status: "running",
2411
2762
  durationMs: null,
2763
+ ttftMs: null,
2764
+ costUsd: null,
2765
+ modelId: null,
2412
2766
  errorCode: null,
2413
2767
  errorMessage: null,
2414
2768
  retries: 0,
@@ -2428,6 +2782,15 @@ var DrizzleAgentStore = class {
2428
2782
  if (end.durationMs !== void 0) {
2429
2783
  updates.durationMs = end.durationMs;
2430
2784
  }
2785
+ if (end.ttftMs !== void 0) {
2786
+ updates.ttftMs = end.ttftMs;
2787
+ }
2788
+ if (end.costUsd !== void 0) {
2789
+ updates.costUsd = end.costUsd;
2790
+ }
2791
+ if (end.modelId !== void 0) {
2792
+ updates.modelId = end.modelId;
2793
+ }
2431
2794
  if (end.errorCode !== void 0) {
2432
2795
  updates.errorCode = end.errorCode;
2433
2796
  }
@@ -2913,6 +3276,11 @@ function toRecentRunRow(run) {
2913
3276
  agentName: run.agentName ?? null,
2914
3277
  status: run.status,
2915
3278
  durationMs: run.durationMs ?? null,
3279
+ ttftMs: run.ttftMs ?? null,
3280
+ // MySQL's DOUBLE and Postgres' double precision come back as numbers; a driver that hands a
3281
+ // decimal back as a string is normalized here so the SPI row is always a number.
3282
+ costUsd: run.costUsd == null ? null : Number(run.costUsd),
3283
+ modelId: run.modelId ?? null,
2916
3284
  errorCode: run.errorCode ?? null,
2917
3285
  errorMessage: run.errorMessage ?? null,
2918
3286
  retries: run.retries,
@@ -3116,6 +3484,7 @@ var DrizzleGovernanceQueries = class {
3116
3484
  let failed = 0;
3117
3485
  let retries = 0;
3118
3486
  const settledDurationsMs = [];
3487
+ const ttftsMs = [];
3119
3488
  for (const run of runs) {
3120
3489
  if (run.status === "completed") {
3121
3490
  completed += 1;
@@ -3126,8 +3495,12 @@ var DrizzleGovernanceQueries = class {
3126
3495
  if ((run.status === "completed" || run.status === "failed") && run.durationMs != null) {
3127
3496
  settledDurationsMs.push(run.durationMs);
3128
3497
  }
3498
+ if (run.status === "completed" && run.parentRunId == null && run.ttftMs != null) {
3499
+ ttftsMs.push(run.ttftMs);
3500
+ }
3129
3501
  }
3130
3502
  settledDurationsMs.sort((left, right) => left - right);
3503
+ ttftsMs.sort((left, right) => left - right);
3131
3504
  return {
3132
3505
  runs: runs.length,
3133
3506
  completed,
@@ -3135,7 +3508,9 @@ var DrizzleGovernanceQueries = class {
3135
3508
  successRate: runs.length === 0 ? 0 : completed / runs.length,
3136
3509
  retries,
3137
3510
  durationP50Ms: percentileMs(settledDurationsMs, 0.5),
3138
- durationP95Ms: percentileMs(settledDurationsMs, 0.95)
3511
+ durationP95Ms: percentileMs(settledDurationsMs, 0.95),
3512
+ ttftP50Ms: percentileMs(ttftsMs, 0.5),
3513
+ ttftP95Ms: percentileMs(ttftsMs, 0.95)
3139
3514
  };
3140
3515
  }
3141
3516
  async runsByAgent(range) {
@@ -3883,14 +4258,392 @@ var DrizzleChannelStore = class {
3883
4258
  }
3884
4259
  };
3885
4260
 
4261
+ // src/drizzle-poppy-store.ts
4262
+ import { newEventId } from "@dudousxd/nestjs-agent-core";
4263
+ 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";
4264
+ var MAX_APPEND_ATTEMPTS = 50;
4265
+ var sleep = /* @__PURE__ */ __name((ms) => new Promise((resolve) => setTimeout(resolve, ms)), "sleep");
4266
+ var nullable = /* @__PURE__ */ __name((value) => value == null ? null : String(value), "nullable");
4267
+ function toInt(value) {
4268
+ if (typeof value === "number") return value;
4269
+ if (typeof value === "bigint") return Number(value);
4270
+ if (typeof value === "string") return Number.parseInt(value, 10) || 0;
4271
+ return 0;
4272
+ }
4273
+ __name(toInt, "toInt");
4274
+ var PATCH_COLUMNS = {
4275
+ accountRef: "accountRef",
4276
+ threadId: "threadId",
4277
+ openDirectId: "openDirectId",
4278
+ status: "status",
4279
+ responder: "responder",
4280
+ context: "context",
4281
+ activeRunId: "activeRunId",
4282
+ turnSeq: "turnSeq",
4283
+ grant: "grantInfo",
4284
+ prunedSeq: "prunedSeq"
4285
+ };
4286
+ var DrizzlePoppyStore = class {
4287
+ static {
4288
+ __name(this, "DrizzlePoppyStore");
4289
+ }
4290
+ db;
4291
+ dialect;
4292
+ t;
4293
+ constructor(db) {
4294
+ this.dialect = agentDialectOf(db);
4295
+ this.t = agentTablesFor(this.dialect);
4296
+ this.db = asBuilder(db);
4297
+ }
4298
+ async createConversation(record) {
4299
+ await this.db.insert(this.t.agentPoppyConversation).values({
4300
+ id: record.id,
4301
+ clientId: record.clientId,
4302
+ userId: record.userId,
4303
+ accountRef: record.accountRef,
4304
+ agentName: record.agentName,
4305
+ threadId: record.threadId,
4306
+ parentId: record.parentId,
4307
+ openDirectId: record.openDirectId,
4308
+ status: record.status,
4309
+ responder: record.responder,
4310
+ context: JSON.stringify(record.context),
4311
+ activeRunId: record.activeRunId,
4312
+ turnSeq: record.turnSeq,
4313
+ grantInfo: record.grant === null ? null : JSON.stringify(record.grant),
4314
+ readerHolder: null,
4315
+ readerUntil: null,
4316
+ prunedSeq: record.prunedSeq,
4317
+ createdAt: record.createdAt,
4318
+ updatedAt: record.updatedAt
4319
+ });
4320
+ }
4321
+ async getConversation(id) {
4322
+ const table = this.t.agentPoppyConversation;
4323
+ const [row] = await this.db.select().from(table).where(eq9(table.id, id)).limit(1);
4324
+ if (!row) return null;
4325
+ return {
4326
+ id: row.id,
4327
+ clientId: row.clientId,
4328
+ userId: row.userId,
4329
+ accountRef: nullable(row.accountRef),
4330
+ agentName: row.agentName,
4331
+ threadId: nullable(row.threadId),
4332
+ parentId: nullable(row.parentId),
4333
+ openDirectId: nullable(row.openDirectId),
4334
+ status: row.status,
4335
+ responder: row.responder,
4336
+ context: row.context == null ? {} : JSON.parse(row.context),
4337
+ activeRunId: nullable(row.activeRunId),
4338
+ turnSeq: toInt(row.turnSeq),
4339
+ grant: row.grantInfo == null ? null : JSON.parse(row.grantInfo),
4340
+ prunedSeq: toInt(row.prunedSeq),
4341
+ createdAt: toInt(row.createdAt),
4342
+ updatedAt: toInt(row.updatedAt)
4343
+ };
4344
+ }
4345
+ async updateConversation(id, patch) {
4346
+ const table = this.t.agentPoppyConversation;
4347
+ const set = {
4348
+ updatedAt: Date.now()
4349
+ };
4350
+ for (const [key2, column] of Object.entries(PATCH_COLUMNS)) {
4351
+ const value = patch[key2];
4352
+ if (value === void 0) continue;
4353
+ set[column] = key2 === "context" || key2 === "grant" && value !== null ? JSON.stringify(value) : value;
4354
+ }
4355
+ await this.db.update(table).set(set).where(eq9(table.id, id));
4356
+ }
4357
+ async appendEvent(conversationId, body, options = {}) {
4358
+ const table = this.t.agentPoppyEvent;
4359
+ for (let attempt = 1; ; attempt++) {
4360
+ if (options.key !== void 0) {
4361
+ const [existing] = await this.db.select({
4362
+ seq: table.seq,
4363
+ event: table.event
4364
+ }).from(table).where(and8(eq9(table.conversationId, conversationId), eq9(table.eventKey, options.key))).limit(1);
4365
+ if (existing) {
4366
+ return {
4367
+ event: {
4368
+ seq: toInt(existing.seq),
4369
+ event: JSON.parse(existing.event)
4370
+ },
4371
+ created: false
4372
+ };
4373
+ }
4374
+ }
4375
+ const seq = await this.lastSeq(conversationId) + 1;
4376
+ const now = Date.now();
4377
+ const stored = {
4378
+ seq,
4379
+ event: {
4380
+ id: newEventId(seq),
4381
+ created_at: new Date(now).toISOString(),
4382
+ ...body
4383
+ }
4384
+ };
4385
+ let inserted = false;
4386
+ try {
4387
+ inserted = await this.insertIgnore(table, {
4388
+ conversationId,
4389
+ seq,
4390
+ id: stored.event.id,
4391
+ type: body.type,
4392
+ event: JSON.stringify(stored.event),
4393
+ eventKey: options.key ?? null,
4394
+ createdAt: now
4395
+ });
4396
+ } catch (error) {
4397
+ if (!isUniqueViolation(error)) throw error;
4398
+ }
4399
+ if (inserted) return {
4400
+ event: stored,
4401
+ created: true
4402
+ };
4403
+ if (attempt >= MAX_APPEND_ATTEMPTS) {
4404
+ throw new Error(`poppy: could not append to ${conversationId} after ${attempt} attempts`);
4405
+ }
4406
+ await sleep(Math.random() * Math.min(attempt, 10) * 2);
4407
+ }
4408
+ }
4409
+ /** The last position taken: the last event's, or — every event pruned — the pruned floor. */
4410
+ async lastSeq(conversationId) {
4411
+ const table = this.t.agentPoppyEvent;
4412
+ const [last] = await this.db.select({
4413
+ seq: table.seq
4414
+ }).from(table).where(eq9(table.conversationId, conversationId)).orderBy(desc3(table.seq)).limit(1);
4415
+ if (last) return toInt(last.seq);
4416
+ const conversations = this.t.agentPoppyConversation;
4417
+ const [conversation] = await this.db.select({
4418
+ prunedSeq: conversations.prunedSeq
4419
+ }).from(conversations).where(eq9(conversations.id, conversationId)).limit(1);
4420
+ return toInt(conversation?.prunedSeq);
4421
+ }
4422
+ async listEvents(conversationId, afterSeq, limit) {
4423
+ const table = this.t.agentPoppyEvent;
4424
+ const rows = await this.db.select({
4425
+ seq: table.seq,
4426
+ event: table.event
4427
+ }).from(table).where(and8(eq9(table.conversationId, conversationId), gt4(table.seq, afterSeq))).orderBy(table.seq).limit(limit);
4428
+ return rows.map((row) => ({
4429
+ seq: toInt(row.seq),
4430
+ event: JSON.parse(row.event)
4431
+ }));
4432
+ }
4433
+ async findEventSeq(conversationId, eventId) {
4434
+ const table = this.t.agentPoppyEvent;
4435
+ const [row] = await this.db.select({
4436
+ seq: table.seq
4437
+ }).from(table).where(and8(eq9(table.conversationId, conversationId), eq9(table.id, eventId))).limit(1);
4438
+ return row ? toInt(row.seq) : null;
4439
+ }
4440
+ async pruneEvents(conversationId, before) {
4441
+ const table = this.t.agentPoppyEvent;
4442
+ const [last] = await this.db.select({
4443
+ seq: table.seq
4444
+ }).from(table).where(eq9(table.conversationId, conversationId)).orderBy(desc3(table.seq)).limit(1);
4445
+ if (!last) return;
4446
+ const [dropped] = await this.db.select({
4447
+ seq: table.seq
4448
+ }).from(table).where(and8(eq9(table.conversationId, conversationId), lt3(table.createdAt, before), lt3(table.seq, toInt(last.seq)))).orderBy(desc3(table.seq)).limit(1);
4449
+ if (!dropped) return;
4450
+ const upTo = toInt(dropped.seq);
4451
+ const conversations = this.t.agentPoppyConversation;
4452
+ await this.db.update(conversations).set({
4453
+ prunedSeq: upTo
4454
+ }).where(and8(eq9(conversations.id, conversationId), lt3(conversations.prunedSeq, upTo)));
4455
+ await this.db.delete(table).where(and8(eq9(table.conversationId, conversationId), lte5(table.seq, upTo)));
4456
+ }
4457
+ async claimMessage(owner, messageId, receipt) {
4458
+ const table = this.t.agentPoppyMessage;
4459
+ for (let attempt = 1; ; attempt++) {
4460
+ const inserted = await this.insertIgnore(table, {
4461
+ owner,
4462
+ messageId,
4463
+ fingerprint: receipt.fingerprint,
4464
+ conversationId: receipt.conversationId,
4465
+ response: JSON.stringify(receipt.response),
4466
+ createdAt: Date.now()
4467
+ });
4468
+ if (inserted) return {
4469
+ status: "claimed"
4470
+ };
4471
+ const [row] = await this.db.select().from(table).where(and8(eq9(table.owner, owner), eq9(table.messageId, messageId))).limit(1);
4472
+ if (row) {
4473
+ return {
4474
+ status: "existing",
4475
+ fingerprint: row.fingerprint,
4476
+ conversationId: row.conversationId,
4477
+ response: JSON.parse(row.response)
4478
+ };
4479
+ }
4480
+ if (attempt >= 5) throw new Error(`poppy: could not claim message ${messageId}`);
4481
+ }
4482
+ }
4483
+ async releaseMessage(owner, messageId) {
4484
+ const table = this.t.agentPoppyMessage;
4485
+ await this.db.delete(table).where(and8(eq9(table.owner, owner), eq9(table.messageId, messageId)));
4486
+ }
4487
+ async leaseReader(conversationId, holder, ttlMs) {
4488
+ const table = this.t.agentPoppyConversation;
4489
+ const now = Date.now();
4490
+ const taken = await affectedRows(this.dialect, this.db.update(table).set({
4491
+ readerHolder: holder,
4492
+ readerUntil: now + ttlMs
4493
+ }).where(and8(eq9(table.id, conversationId), or3(isNull4(table.readerHolder), eq9(table.readerHolder, holder), lte5(table.readerUntil, now)))), table.id);
4494
+ if (taken === 1) return true;
4495
+ if (this.dialect !== "mysql") return false;
4496
+ const [row] = await this.db.select({
4497
+ holder: table.readerHolder
4498
+ }).from(table).where(eq9(table.id, conversationId)).limit(1);
4499
+ return row?.holder === holder;
4500
+ }
4501
+ async releaseReader(conversationId, holder) {
4502
+ const table = this.t.agentPoppyConversation;
4503
+ await this.db.update(table).set({
4504
+ readerHolder: null,
4505
+ readerUntil: null
4506
+ }).where(and8(eq9(table.id, conversationId), eq9(table.readerHolder, holder)));
4507
+ }
4508
+ /** Insert `row`, skipping it on any duplicate key. `true` when it went in. */
4509
+ async insertIgnore(table, row) {
4510
+ if (this.dialect === "mysql") {
4511
+ const insert = this.db.insert(table);
4512
+ return mysqlAffectedRows(await insert.ignore().values(row)) === 1;
4513
+ }
4514
+ const statement = this.db.insert(table).values(row).onConflictDoNothing();
4515
+ return await affectedRows(this.dialect, statement, table.createdAt) === 1;
4516
+ }
4517
+ };
4518
+
4519
+ // src/drizzle-poppy-connection-store.ts
4520
+ import { and as and9, asc as asc5, eq as eq10 } from "drizzle-orm";
4521
+ var nullable2 = /* @__PURE__ */ __name((value) => value == null ? null : String(value), "nullable");
4522
+ var toInt2 = /* @__PURE__ */ __name((value) => typeof value === "number" ? value : Number(value ?? 0), "toInt");
4523
+ var DrizzlePoppyConnectionStore = class {
4524
+ static {
4525
+ __name(this, "DrizzlePoppyConnectionStore");
4526
+ }
4527
+ db;
4528
+ dialect;
4529
+ t;
4530
+ constructor(db) {
4531
+ this.dialect = agentDialectOf(db);
4532
+ this.t = agentTablesFor(this.dialect);
4533
+ this.db = asBuilder(db);
4534
+ }
4535
+ async listConnections(owner) {
4536
+ const table = this.t.agentPoppyConnection;
4537
+ const rows = await this.db.select().from(table).where(eq10(table.owner, owner)).orderBy(asc5(table.domain), asc5(table.issuer));
4538
+ return rows.map(toConnection);
4539
+ }
4540
+ async getConnection(owner, issuer) {
4541
+ const table = this.t.agentPoppyConnection;
4542
+ const [row] = await this.db.select().from(table).where(and9(eq10(table.owner, owner), eq10(table.issuer, issuer))).limit(1);
4543
+ return row ? toConnection(row) : null;
4544
+ }
4545
+ async saveConnection(record) {
4546
+ const table = this.t.agentPoppyConnection;
4547
+ const columns = {
4548
+ domain: record.domain,
4549
+ organization: record.organization,
4550
+ scope: record.scope,
4551
+ status: record.status,
4552
+ state: record.state,
4553
+ updatedAt: record.updatedAt
4554
+ };
4555
+ await upsert(this.dialect, this.db.insert(table).values({
4556
+ owner: record.owner,
4557
+ issuer: record.issuer,
4558
+ createdAt: record.createdAt,
4559
+ ...columns
4560
+ }), [
4561
+ table.owner,
4562
+ table.issuer
4563
+ ], columns);
4564
+ }
4565
+ async deleteConnection(owner, issuer) {
4566
+ const table = this.t.agentPoppyConnection;
4567
+ await this.db.delete(table).where(and9(eq10(table.owner, owner), eq10(table.issuer, issuer)));
4568
+ }
4569
+ async createPending(record) {
4570
+ const table = this.t.agentPoppyConnect;
4571
+ const row = {
4572
+ id: record.id,
4573
+ owner: record.owner,
4574
+ domain: record.domain,
4575
+ issuer: record.issuer,
4576
+ organization: record.organization,
4577
+ scope: record.scope,
4578
+ actor: record.actor === null ? null : JSON.stringify(record.actor),
4579
+ threadId: record.threadId,
4580
+ runId: record.runId,
4581
+ toolCallId: record.toolCallId,
4582
+ flow: record.flow,
4583
+ status: record.status,
4584
+ expiresAt: record.expiresAt,
4585
+ createdAt: record.createdAt
4586
+ };
4587
+ if (this.dialect === "mysql") {
4588
+ const insert = this.db.insert(table);
4589
+ await insert.ignore().values(row);
4590
+ return;
4591
+ }
4592
+ await this.db.insert(table).values(row).onConflictDoNothing();
4593
+ }
4594
+ async getPending(id) {
4595
+ const table = this.t.agentPoppyConnect;
4596
+ const [row] = await this.db.select().from(table).where(eq10(table.id, id)).limit(1);
4597
+ if (!row) return null;
4598
+ return {
4599
+ id: row.id,
4600
+ owner: row.owner,
4601
+ domain: row.domain,
4602
+ issuer: row.issuer,
4603
+ organization: row.organization,
4604
+ scope: row.scope ?? "",
4605
+ actor: row.actor == null ? null : JSON.parse(row.actor),
4606
+ threadId: nullable2(row.threadId),
4607
+ runId: nullable2(row.runId),
4608
+ toolCallId: nullable2(row.toolCallId),
4609
+ flow: nullable2(row.flow),
4610
+ status: row.status,
4611
+ expiresAt: toInt2(row.expiresAt),
4612
+ createdAt: toInt2(row.createdAt)
4613
+ };
4614
+ }
4615
+ async updatePending(id, patch) {
4616
+ const set = {};
4617
+ if (patch.flow !== void 0) set.flow = patch.flow;
4618
+ if (patch.status !== void 0) set.status = patch.status;
4619
+ if (Object.keys(set).length === 0) return;
4620
+ const table = this.t.agentPoppyConnect;
4621
+ await this.db.update(table).set(set).where(eq10(table.id, id));
4622
+ }
4623
+ };
4624
+ function toConnection(row) {
4625
+ return {
4626
+ owner: row.owner,
4627
+ issuer: row.issuer,
4628
+ domain: row.domain,
4629
+ organization: row.organization,
4630
+ scope: row.scope ?? "",
4631
+ status: row.status,
4632
+ state: row.state,
4633
+ createdAt: toInt2(row.createdAt),
4634
+ updatedAt: toInt2(row.updatedAt)
4635
+ };
4636
+ }
4637
+ __name(toConnection, "toConnection");
4638
+
3886
4639
  // src/drizzle-rag-ingestion-log.ts
3887
4640
  import { subscribe, unsubscribe } from "diagnostics_channel";
3888
4641
  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;
4642
+ 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";
4643
+ function _ts_decorate(decorators, target, key2, desc5) {
4644
+ var c = arguments.length, r = c < 3 ? target : desc5 === null ? desc5 = Object.getOwnPropertyDescriptor(target, key2) : desc5, d;
3892
4645
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
3893
- r = Reflect.decorate(decorators, target, key2, desc4);
4646
+ r = Reflect.decorate(decorators, target, key2, desc5);
3894
4647
  } else {
3895
4648
  for (var i = decorators.length - 1; i >= 0; i--) {
3896
4649
  if (d = decorators[i]) {
@@ -3934,8 +4687,8 @@ function num(value) {
3934
4687
  }
3935
4688
  __name(num, "num");
3936
4689
  var RAG_INGESTION_LOG_PAGE_ORDER = [
3937
- desc3(ragIngestionLog.updatedAt),
3938
- asc5(ragIngestionLog.documentId)
4690
+ desc4(ragIngestionLog.updatedAt),
4691
+ asc6(ragIngestionLog.documentId)
3939
4692
  ];
3940
4693
  var DEFAULT_PAGE_SIZE = 200;
3941
4694
  var DEFAULT_BATCH_SIZE = 200;
@@ -4085,17 +4838,17 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
4085
4838
  }
4086
4839
  /** The latest recorded outcome for one document, or null if it was never attempted. */
4087
4840
  async get(documentId) {
4088
- const [row] = await this.db.select().from(this.t.ragIngestionLog).where(eq9(this.t.ragIngestionLog.documentId, documentId));
4841
+ const [row] = await this.db.select().from(this.t.ragIngestionLog).where(eq11(this.t.ragIngestionLog.documentId, documentId));
4089
4842
  return row ?? null;
4090
4843
  }
4091
4844
  /** Forget one document's record. Returns whether a row was actually removed. */
4092
4845
  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);
4846
+ const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq11(this.t.ragIngestionLog.documentId, documentId)), this.t.ragIngestionLog.documentId);
4094
4847
  return removed > 0;
4095
4848
  }
4096
4849
  /** Forget every record for a collection — for when the collection itself is deleted. */
4097
4850
  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);
4851
+ const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq11(this.t.ragIngestionLog.collection, collection)), this.t.ragIngestionLog.documentId);
4099
4852
  return removed;
4100
4853
  }
4101
4854
  /**
@@ -4125,7 +4878,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
4125
4878
  }
4126
4879
  }
4127
4880
  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);
4881
+ 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
4882
  }
4130
4883
  /**
4131
4884
  * The coordinates filter AND'd with "strictly after `cursor` in
@@ -4140,7 +4893,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
4140
4893
  if (cursor === void 0) {
4141
4894
  return base;
4142
4895
  }
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))));
4896
+ 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
4897
  }
4145
4898
  /**
4146
4899
  * Upsert one outcome. Keyed by document id so the row always reflects the *current* state — a
@@ -4213,12 +4966,12 @@ DrizzleRagIngestionLog = _ts_decorate([
4213
4966
  ], DrizzleRagIngestionLog);
4214
4967
 
4215
4968
  // 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";
4969
+ 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
4970
  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;
4971
+ function _ts_decorate2(decorators, target, key2, desc5) {
4972
+ var c = arguments.length, r = c < 3 ? target : desc5 === null ? desc5 = Object.getOwnPropertyDescriptor(target, key2) : desc5, d;
4220
4973
  if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
4221
- r = Reflect.decorate(decorators, target, key2, desc4);
4974
+ r = Reflect.decorate(decorators, target, key2, desc5);
4222
4975
  } else {
4223
4976
  for (var i = decorators.length - 1; i >= 0; i--) {
4224
4977
  if (d = decorators[i]) {
@@ -4301,6 +5054,23 @@ var DrizzleAgentStoreModule = class _DrizzleAgentStoreModule {
4301
5054
  {
4302
5055
  provide: AGENT_CHANNEL_STORE,
4303
5056
  useExisting: DrizzleChannelStore
5057
+ },
5058
+ // Personal Agent Protocol (Poppy) conversations and connections, shared by every replica.
5059
+ {
5060
+ provide: DrizzlePoppyStore,
5061
+ useFactory: /* @__PURE__ */ __name(() => new DrizzlePoppyStore(options.db), "useFactory")
5062
+ },
5063
+ {
5064
+ provide: AGENT_POPPY_STORE,
5065
+ useExisting: DrizzlePoppyStore
5066
+ },
5067
+ {
5068
+ provide: DrizzlePoppyConnectionStore,
5069
+ useFactory: /* @__PURE__ */ __name(() => new DrizzlePoppyConnectionStore(options.db), "useFactory")
5070
+ },
5071
+ {
5072
+ provide: AGENT_POPPY_CONNECTION_STORE,
5073
+ useExisting: DrizzlePoppyConnectionStore
4304
5074
  }
4305
5075
  ],
4306
5076
  exports: [
@@ -4317,7 +5087,11 @@ var DrizzleAgentStoreModule = class _DrizzleAgentStoreModule {
4317
5087
  DrizzleConfirmTokenStore,
4318
5088
  AGENT_CONFIRM_TOKEN_STORE,
4319
5089
  DrizzleChannelStore,
4320
- AGENT_CHANNEL_STORE
5090
+ AGENT_CHANNEL_STORE,
5091
+ DrizzlePoppyStore,
5092
+ AGENT_POPPY_STORE,
5093
+ DrizzlePoppyConnectionStore,
5094
+ AGENT_POPPY_CONNECTION_STORE
4321
5095
  ]
4322
5096
  };
4323
5097
  }
@@ -4333,6 +5107,8 @@ export {
4333
5107
  DrizzleConfirmTokenStore,
4334
5108
  DrizzleGovernanceQueries,
4335
5109
  DrizzleMemoryProvider,
5110
+ DrizzlePoppyConnectionStore,
5111
+ DrizzlePoppyStore,
4336
5112
  DrizzlePricingStore,
4337
5113
  DrizzleRagIngestionLog,
4338
5114
  DrizzleStreamFrameTable,
@@ -4346,6 +5122,11 @@ export {
4346
5122
  agentMemory,
4347
5123
  agentMessage,
4348
5124
  agentModelPricing,
5125
+ agentPoppyConnect,
5126
+ agentPoppyConnection,
5127
+ agentPoppyConversation,
5128
+ agentPoppyEvent,
5129
+ agentPoppyMessage,
4349
5130
  agentQueuedMessage,
4350
5131
  agentRun,
4351
5132
  agentSchema,