@dudousxd/nestjs-agent-store-drizzle 0.23.0 → 0.25.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/README.md +145 -9
- package/dist/index.cjs +1847 -636
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +8086 -1744
- package/dist/index.d.ts +8086 -1744
- package/dist/index.js +1800 -595
- package/dist/index.js.map +1 -1
- package/package.json +7 -4
package/dist/index.js
CHANGED
|
@@ -40,6 +40,7 @@ var agentMessage = sqliteTable("agent_message", {
|
|
|
40
40
|
onDelete: "cascade"
|
|
41
41
|
}),
|
|
42
42
|
role: text("role").$type().notNull(),
|
|
43
|
+
actionProposalOutcome: text("action_proposal_outcome"),
|
|
43
44
|
content: text("content").notNull(),
|
|
44
45
|
toolCalls: text("tool_calls", {
|
|
45
46
|
mode: "json"
|
|
@@ -71,6 +72,12 @@ var agentMessage = sqliteTable("agent_message", {
|
|
|
71
72
|
feedback: text("feedback", {
|
|
72
73
|
mode: "json"
|
|
73
74
|
}).$type(),
|
|
75
|
+
/**
|
|
76
|
+
* The message's place in its thread, 1-based, assigned on append — what orders a transcript.
|
|
77
|
+
* `created_at` cannot: two messages of one turn routinely share a timestamp, and the uuid that
|
|
78
|
+
* broke the tie is random. `null` on a row from before the column; those sort first.
|
|
79
|
+
*/
|
|
80
|
+
seq: integer("seq"),
|
|
74
81
|
createdAt: integer("created_at", {
|
|
75
82
|
mode: "timestamp_ms"
|
|
76
83
|
}).notNull()
|
|
@@ -78,6 +85,7 @@ var agentMessage = sqliteTable("agent_message", {
|
|
|
78
85
|
index("agent_message_thread_created_idx").on(table.threadId, table.createdAt)
|
|
79
86
|
]);
|
|
80
87
|
var agentToolCall = sqliteTable("agent_tool_call", {
|
|
88
|
+
proposalId: text("proposal_id"),
|
|
81
89
|
id: text("id").primaryKey(),
|
|
82
90
|
messageId: text("message_id").notNull().references(() => agentMessage.id, {
|
|
83
91
|
onDelete: "cascade"
|
|
@@ -102,6 +110,10 @@ var agentToolCall = sqliteTable("agent_tool_call", {
|
|
|
102
110
|
}),
|
|
103
111
|
/** The run (turn) this call belongs to, for a trace deep-link; null for a pre-rollout row. */
|
|
104
112
|
runId: text("run_id"),
|
|
113
|
+
/** Resolved per-call wording; null falls back to presentation templates. */
|
|
114
|
+
confirmation: text("confirmation", {
|
|
115
|
+
mode: "json"
|
|
116
|
+
}).$type(),
|
|
105
117
|
/** Who had to approve it (`requester` or a role); null for a call no policy put to anyone. */
|
|
106
118
|
approver: text("approver"),
|
|
107
119
|
/** When the approval request lapses; null → never. */
|
|
@@ -118,6 +130,9 @@ var agentToolCall = sqliteTable("agent_tool_call", {
|
|
|
118
130
|
index("agent_tool_call_message_idx").on(table.messageId)
|
|
119
131
|
]);
|
|
120
132
|
var agentQueuedMessage = sqliteTable("agent_queued_message", {
|
|
133
|
+
uiCapabilities: text("ui_capabilities", {
|
|
134
|
+
mode: "json"
|
|
135
|
+
}).$type(),
|
|
121
136
|
id: text("id").primaryKey(),
|
|
122
137
|
threadId: text("thread_id").notNull().references(() => agentThread.id, {
|
|
123
138
|
onDelete: "cascade"
|
|
@@ -295,7 +310,35 @@ var agentStreamFrame = sqliteTable("agent_stream_frame", {
|
|
|
295
310
|
]
|
|
296
311
|
})
|
|
297
312
|
]);
|
|
313
|
+
var agentActionProposal = sqliteTable("agent_action_proposal", {
|
|
314
|
+
id: text("id").primaryKey(),
|
|
315
|
+
scopeKey: text("scope_key").notNull(),
|
|
316
|
+
decision: text("decision").$type().notNull(),
|
|
317
|
+
logicalSort: text("logical_sort").notNull(),
|
|
318
|
+
createFingerprint: text("create_fingerprint").notNull(),
|
|
319
|
+
proposal: text("proposal", {
|
|
320
|
+
mode: "json"
|
|
321
|
+
}).$type().notNull(),
|
|
322
|
+
version: integer("version").notNull().default(0),
|
|
323
|
+
executionStatus: text("execution_status").$type(),
|
|
324
|
+
leaseExpiresAt: integer("lease_expires_at"),
|
|
325
|
+
deliveryStatus: text("delivery_status"),
|
|
326
|
+
deliveryLeaseExpiresAt: integer("delivery_lease_expires_at"),
|
|
327
|
+
replacementGroupKey: text("replacement_group_key"),
|
|
328
|
+
outcomeIdKey: text("outcome_id_key"),
|
|
329
|
+
proposalExpiresAt: integer("proposal_expires_at"),
|
|
330
|
+
discoveryIndexVersion: integer("discovery_index_version").notNull().default(0),
|
|
331
|
+
createdAt: integer("created_at").notNull()
|
|
332
|
+
}, (table) => [
|
|
333
|
+
index("agent_action_proposal_execution_idx").on(table.discoveryIndexVersion, table.executionStatus, table.leaseExpiresAt, table.createdAt),
|
|
334
|
+
index("agent_action_proposal_expiry_idx").on(table.discoveryIndexVersion, table.decision, table.proposalExpiresAt, table.createdAt),
|
|
335
|
+
index("agent_action_proposal_replacement_idx").on(table.scopeKey, table.replacementGroupKey, table.decision),
|
|
336
|
+
index("agent_action_proposal_delivery_idx").on(table.deliveryStatus, table.deliveryLeaseExpiresAt, table.createdAt),
|
|
337
|
+
uniqueIndex("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
|
|
338
|
+
index("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
|
|
339
|
+
]);
|
|
298
340
|
var agentSchema = {
|
|
341
|
+
agentActionProposal,
|
|
299
342
|
agentThread,
|
|
300
343
|
agentMessage,
|
|
301
344
|
agentQueuedMessage,
|
|
@@ -305,303 +348,1375 @@ var agentSchema = {
|
|
|
305
348
|
agentRun,
|
|
306
349
|
agentMemory,
|
|
307
350
|
ragIngestionLog,
|
|
308
|
-
agentConfirmToken
|
|
351
|
+
agentConfirmToken,
|
|
352
|
+
agentStreamFrame
|
|
309
353
|
};
|
|
310
354
|
|
|
311
355
|
// src/ensure-schema.ts
|
|
312
|
-
import { sql } from "drizzle-orm";
|
|
313
|
-
|
|
314
|
-
|
|
315
|
-
|
|
316
|
-
|
|
317
|
-
|
|
318
|
-
|
|
319
|
-
|
|
320
|
-
|
|
321
|
-
|
|
322
|
-
|
|
323
|
-
|
|
324
|
-
|
|
325
|
-
|
|
326
|
-
|
|
327
|
-
|
|
328
|
-
|
|
329
|
-
|
|
330
|
-
|
|
331
|
-
|
|
332
|
-
|
|
333
|
-
|
|
334
|
-
|
|
335
|
-
|
|
336
|
-
|
|
337
|
-
|
|
338
|
-
|
|
339
|
-
|
|
340
|
-
|
|
341
|
-
|
|
342
|
-
|
|
343
|
-
|
|
344
|
-
|
|
345
|
-
|
|
346
|
-
|
|
347
|
-
|
|
348
|
-
|
|
349
|
-
|
|
350
|
-
|
|
351
|
-
|
|
352
|
-
|
|
353
|
-
|
|
354
|
-
|
|
355
|
-
|
|
356
|
-
|
|
357
|
-
|
|
358
|
-
|
|
359
|
-
|
|
360
|
-
|
|
361
|
-
|
|
362
|
-
|
|
363
|
-
|
|
364
|
-
|
|
365
|
-
|
|
366
|
-
)
|
|
367
|
-
|
|
368
|
-
|
|
369
|
-
|
|
370
|
-
|
|
371
|
-
|
|
372
|
-
|
|
373
|
-
|
|
374
|
-
|
|
375
|
-
|
|
376
|
-
|
|
377
|
-
|
|
378
|
-
|
|
379
|
-
|
|
380
|
-
|
|
381
|
-
|
|
382
|
-
|
|
383
|
-
|
|
384
|
-
|
|
385
|
-
|
|
386
|
-
|
|
387
|
-
)
|
|
388
|
-
|
|
389
|
-
|
|
390
|
-
|
|
391
|
-
|
|
392
|
-
|
|
393
|
-
|
|
394
|
-
|
|
395
|
-
|
|
396
|
-
|
|
397
|
-
|
|
398
|
-
|
|
399
|
-
|
|
400
|
-
|
|
401
|
-
|
|
402
|
-
|
|
403
|
-
)
|
|
404
|
-
|
|
405
|
-
|
|
406
|
-
|
|
407
|
-
|
|
408
|
-
|
|
409
|
-
|
|
410
|
-
|
|
411
|
-
|
|
412
|
-
|
|
413
|
-
|
|
414
|
-
|
|
415
|
-
)
|
|
416
|
-
|
|
417
|
-
|
|
418
|
-
|
|
419
|
-
|
|
420
|
-
|
|
421
|
-
|
|
422
|
-
|
|
423
|
-
|
|
424
|
-
|
|
425
|
-
|
|
426
|
-
|
|
427
|
-
|
|
428
|
-
|
|
429
|
-
|
|
430
|
-
)
|
|
431
|
-
|
|
432
|
-
|
|
433
|
-
|
|
434
|
-
|
|
435
|
-
|
|
436
|
-
|
|
437
|
-
|
|
438
|
-
|
|
439
|
-
|
|
440
|
-
|
|
441
|
-
|
|
442
|
-
|
|
443
|
-
|
|
444
|
-
|
|
445
|
-
|
|
446
|
-
|
|
447
|
-
)
|
|
448
|
-
|
|
449
|
-
|
|
450
|
-
|
|
451
|
-
|
|
452
|
-
|
|
453
|
-
|
|
454
|
-
|
|
455
|
-
|
|
456
|
-
|
|
457
|
-
|
|
458
|
-
|
|
459
|
-
|
|
460
|
-
|
|
461
|
-
|
|
462
|
-
|
|
463
|
-
|
|
464
|
-
)
|
|
465
|
-
|
|
466
|
-
|
|
467
|
-
|
|
468
|
-
|
|
469
|
-
|
|
470
|
-
|
|
471
|
-
|
|
472
|
-
|
|
473
|
-
|
|
474
|
-
)
|
|
475
|
-
|
|
476
|
-
|
|
477
|
-
|
|
478
|
-
|
|
479
|
-
|
|
480
|
-
|
|
481
|
-
|
|
482
|
-
|
|
483
|
-
|
|
484
|
-
|
|
485
|
-
|
|
486
|
-
|
|
487
|
-
|
|
488
|
-
|
|
489
|
-
|
|
490
|
-
|
|
491
|
-
|
|
492
|
-
|
|
493
|
-
|
|
494
|
-
|
|
495
|
-
|
|
496
|
-
|
|
497
|
-
|
|
498
|
-
|
|
499
|
-
|
|
500
|
-
|
|
501
|
-
|
|
502
|
-
|
|
503
|
-
|
|
504
|
-
|
|
505
|
-
|
|
506
|
-
|
|
507
|
-
|
|
508
|
-
|
|
509
|
-
|
|
510
|
-
|
|
511
|
-
|
|
512
|
-
|
|
513
|
-
|
|
514
|
-
|
|
515
|
-
|
|
516
|
-
|
|
517
|
-
|
|
518
|
-
|
|
519
|
-
|
|
520
|
-
|
|
521
|
-
{
|
|
522
|
-
|
|
523
|
-
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
|
|
530
|
-
}
|
|
531
|
-
|
|
532
|
-
|
|
533
|
-
|
|
534
|
-
|
|
535
|
-
|
|
536
|
-
|
|
537
|
-
|
|
538
|
-
|
|
539
|
-
|
|
540
|
-
|
|
541
|
-
{
|
|
542
|
-
|
|
543
|
-
|
|
544
|
-
|
|
545
|
-
|
|
546
|
-
{
|
|
547
|
-
|
|
548
|
-
|
|
549
|
-
|
|
550
|
-
|
|
551
|
-
|
|
552
|
-
|
|
553
|
-
|
|
554
|
-
|
|
555
|
-
|
|
556
|
-
|
|
557
|
-
|
|
558
|
-
|
|
559
|
-
|
|
560
|
-
|
|
561
|
-
|
|
562
|
-
|
|
563
|
-
|
|
564
|
-
|
|
565
|
-
|
|
566
|
-
|
|
567
|
-
|
|
568
|
-
|
|
569
|
-
|
|
356
|
+
import { getTableName, sql } from "drizzle-orm";
|
|
357
|
+
import { getTableConfig as mysqlTableConfig } from "drizzle-orm/mysql-core";
|
|
358
|
+
import { getTableConfig as pgTableConfig } from "drizzle-orm/pg-core";
|
|
359
|
+
import { getTableConfig as sqliteTableConfig } from "drizzle-orm/sqlite-core";
|
|
360
|
+
|
|
361
|
+
// src/dialect.ts
|
|
362
|
+
import { is } from "drizzle-orm";
|
|
363
|
+
import { MySqlDatabase } from "drizzle-orm/mysql-core";
|
|
364
|
+
import { PgDatabase } from "drizzle-orm/pg-core";
|
|
365
|
+
|
|
366
|
+
// src/schema-mysql.ts
|
|
367
|
+
import { canonicalActionProposalJson } from "@dudousxd/nestjs-agent-core";
|
|
368
|
+
import { bigint, boolean, customType, datetime, double, index as index2, int, json, longtext, mysqlTable, primaryKey as primaryKey2, uniqueIndex as uniqueIndex2, varchar } from "drizzle-orm/mysql-core";
|
|
369
|
+
var ts = /* @__PURE__ */ __name((name) => datetime(name, {
|
|
370
|
+
mode: "date",
|
|
371
|
+
fsp: 3
|
|
372
|
+
}), "ts");
|
|
373
|
+
var key = /* @__PURE__ */ __name((name) => varchar(name, {
|
|
374
|
+
length: 255
|
|
375
|
+
}), "key");
|
|
376
|
+
var agentThread2 = mysqlTable("agent_thread", {
|
|
377
|
+
id: key("id").primaryKey(),
|
|
378
|
+
actorRef: key("actor_ref").notNull(),
|
|
379
|
+
tenantRef: key("tenant_ref"),
|
|
380
|
+
title: key("title").notNull(),
|
|
381
|
+
transient: boolean("transient").notNull().default(false),
|
|
382
|
+
activeStreamId: key("active_stream_id"),
|
|
383
|
+
defaultAgent: key("default_agent"),
|
|
384
|
+
model: key("model"),
|
|
385
|
+
/** The persona a send on this thread runs under when it names none; `null` → the agent's default. */
|
|
386
|
+
persona: key("persona"),
|
|
387
|
+
queuePause: json("queue_pause").$type(),
|
|
388
|
+
createdAt: ts("created_at").notNull(),
|
|
389
|
+
updatedAt: ts("updated_at").notNull(),
|
|
390
|
+
deletedAt: ts("deleted_at")
|
|
391
|
+
}, (table) => [
|
|
392
|
+
index2("agent_thread_actor_updated_idx").on(table.actorRef, table.updatedAt)
|
|
393
|
+
]);
|
|
394
|
+
var agentMessage2 = mysqlTable("agent_message", {
|
|
395
|
+
id: key("id").primaryKey(),
|
|
396
|
+
threadId: key("thread_id").notNull().references(() => agentThread2.id, {
|
|
397
|
+
onDelete: "cascade"
|
|
398
|
+
}),
|
|
399
|
+
role: key("role").$type().notNull(),
|
|
400
|
+
actionProposalOutcome: longtext("action_proposal_outcome"),
|
|
401
|
+
content: longtext("content").notNull(),
|
|
402
|
+
toolCalls: json("tool_calls").$type(),
|
|
403
|
+
toolResults: json("tool_results").$type(),
|
|
404
|
+
attachments: json("attachments").$type(),
|
|
405
|
+
followUps: json("follow_ups").$type(),
|
|
406
|
+
usage: json("usage").$type(),
|
|
407
|
+
agentName: key("agent_name"),
|
|
408
|
+
/** The persona the turn that wrote this message ran under; `null` → none. */
|
|
409
|
+
persona: key("persona"),
|
|
410
|
+
runId: key("run_id"),
|
|
411
|
+
reasoning: longtext("reasoning"),
|
|
412
|
+
reasoningMs: int("reasoning_ms"),
|
|
413
|
+
ui: json("ui").$type(),
|
|
414
|
+
feedback: json("feedback").$type(),
|
|
415
|
+
seq: int("seq"),
|
|
416
|
+
createdAt: ts("created_at").notNull()
|
|
417
|
+
}, (table) => [
|
|
418
|
+
index2("agent_message_thread_created_idx").on(table.threadId, table.createdAt)
|
|
419
|
+
]);
|
|
420
|
+
var agentToolCall2 = mysqlTable("agent_tool_call", {
|
|
421
|
+
proposalId: key("proposal_id"),
|
|
422
|
+
id: key("id").primaryKey(),
|
|
423
|
+
messageId: key("message_id").notNull().references(() => agentMessage2.id, {
|
|
424
|
+
onDelete: "cascade"
|
|
425
|
+
}),
|
|
426
|
+
toolName: key("tool_name").notNull(),
|
|
427
|
+
toolType: key("tool_type").$type().notNull(),
|
|
428
|
+
input: json("input"),
|
|
429
|
+
output: json("output"),
|
|
430
|
+
status: key("status").$type().notNull(),
|
|
431
|
+
executedByRef: key("executed_by_ref"),
|
|
432
|
+
executionMs: int("execution_ms"),
|
|
433
|
+
error: longtext("error"),
|
|
434
|
+
createdAt: ts("created_at").notNull(),
|
|
435
|
+
executedAt: ts("executed_at"),
|
|
436
|
+
runId: key("run_id"),
|
|
437
|
+
confirmation: json("confirmation").$type(),
|
|
438
|
+
approver: key("approver"),
|
|
439
|
+
expiresAt: ts("expires_at"),
|
|
440
|
+
remember: boolean("remember"),
|
|
441
|
+
decidedVia: key("decided_via")
|
|
442
|
+
}, (table) => [
|
|
443
|
+
index2("agent_tool_call_message_idx").on(table.messageId)
|
|
444
|
+
]);
|
|
445
|
+
var agentQueuedMessage2 = mysqlTable("agent_queued_message", {
|
|
446
|
+
uiCapabilities: json("ui_capabilities").$type(),
|
|
447
|
+
id: key("id").primaryKey(),
|
|
448
|
+
threadId: key("thread_id").notNull().references(() => agentThread2.id, {
|
|
449
|
+
onDelete: "cascade"
|
|
450
|
+
}),
|
|
451
|
+
actor: json("actor").$type().notNull(),
|
|
452
|
+
content: longtext("content").notNull(),
|
|
453
|
+
attachments: json("attachments").$type(),
|
|
454
|
+
agentName: key("agent_name"),
|
|
455
|
+
/** The persona the send resolved — what the message starts under. */
|
|
456
|
+
persona: key("persona"),
|
|
457
|
+
model: key("model"),
|
|
458
|
+
pageContext: json("page_context").$type(),
|
|
459
|
+
interrupt: boolean("interrupt").notNull().default(false),
|
|
460
|
+
position: int("position").notNull(),
|
|
461
|
+
createdAt: ts("created_at").notNull(),
|
|
462
|
+
updatedAt: ts("updated_at").notNull()
|
|
463
|
+
}, (table) => [
|
|
464
|
+
index2("agent_queued_message_thread_position_idx").on(table.threadId, table.position)
|
|
465
|
+
]);
|
|
466
|
+
var agentTokenUsage2 = mysqlTable("agent_token_usage", {
|
|
467
|
+
id: key("id").primaryKey(),
|
|
468
|
+
threadId: key("thread_id").notNull().references(() => agentThread2.id, {
|
|
469
|
+
onDelete: "cascade"
|
|
470
|
+
}),
|
|
471
|
+
actorRef: key("actor_ref").notNull(),
|
|
472
|
+
messageId: key("message_id"),
|
|
473
|
+
modelId: key("model_id").notNull(),
|
|
474
|
+
purpose: key("purpose").$type().notNull(),
|
|
475
|
+
inputTokens: int("input_tokens").notNull(),
|
|
476
|
+
outputTokens: int("output_tokens").notNull(),
|
|
477
|
+
cacheWriteTokens: int("cache_write_tokens"),
|
|
478
|
+
cacheReadTokens: int("cache_read_tokens"),
|
|
479
|
+
costUsd: double("cost_usd"),
|
|
480
|
+
createdAt: ts("created_at").notNull()
|
|
481
|
+
}, (table) => [
|
|
482
|
+
index2("agent_token_usage_actor_created_idx").on(table.actorRef, table.createdAt)
|
|
483
|
+
]);
|
|
484
|
+
var agentModelPricing2 = mysqlTable("agent_model_pricing", {
|
|
485
|
+
id: key("id").primaryKey(),
|
|
486
|
+
modelId: key("model_id").notNull(),
|
|
487
|
+
inputPricePer1m: double("input_price_per_1m").notNull(),
|
|
488
|
+
outputPricePer1m: double("output_price_per_1m").notNull(),
|
|
489
|
+
cacheWritePricePer1m: double("cache_write_price_per_1m"),
|
|
490
|
+
cacheReadPricePer1m: double("cache_read_price_per_1m"),
|
|
491
|
+
effectiveFrom: ts("effective_from").notNull(),
|
|
492
|
+
isCurrent: boolean("is_current").notNull()
|
|
493
|
+
});
|
|
494
|
+
var agentRun2 = mysqlTable("agent_run", {
|
|
495
|
+
id: key("id").primaryKey(),
|
|
496
|
+
threadId: key("thread_id").notNull().references(() => agentThread2.id, {
|
|
497
|
+
onDelete: "cascade"
|
|
498
|
+
}),
|
|
499
|
+
actorRef: key("actor_ref").notNull(),
|
|
500
|
+
agentName: key("agent_name"),
|
|
501
|
+
status: key("status").$type().notNull(),
|
|
502
|
+
durationMs: int("duration_ms"),
|
|
503
|
+
errorCode: key("error_code"),
|
|
504
|
+
errorMessage: longtext("error_message"),
|
|
505
|
+
retries: int("retries").notNull().default(0),
|
|
506
|
+
startedAt: ts("started_at").notNull(),
|
|
507
|
+
settledAt: ts("settled_at"),
|
|
508
|
+
promptHash: key("prompt_hash"),
|
|
509
|
+
parentRunId: key("parent_run_id")
|
|
510
|
+
}, (table) => [
|
|
511
|
+
index2("agent_run_started_idx").on(table.startedAt)
|
|
512
|
+
]);
|
|
513
|
+
var agentMemory2 = mysqlTable("agent_memory", {
|
|
514
|
+
id: key("id").primaryKey(),
|
|
515
|
+
scope: key("scope").notNull(),
|
|
516
|
+
key: key("key").notNull(),
|
|
517
|
+
text: longtext("text").notNull(),
|
|
518
|
+
originAuthor: key("origin_author").$type().notNull(),
|
|
519
|
+
originThreadId: key("origin_thread_id"),
|
|
520
|
+
originRunId: key("origin_run_id"),
|
|
521
|
+
originActorRef: key("origin_actor_ref"),
|
|
522
|
+
pinned: boolean("pinned").notNull().default(false),
|
|
523
|
+
createdAt: ts("created_at").notNull(),
|
|
524
|
+
updatedAt: ts("updated_at").notNull()
|
|
525
|
+
}, (table) => [
|
|
526
|
+
uniqueIndex2("agent_memory_scope_key_uq").on(table.scope, table.key)
|
|
527
|
+
]);
|
|
528
|
+
var ragIngestionLog2 = mysqlTable("rag_ingestion_log", {
|
|
529
|
+
documentId: key("document_id").primaryKey(),
|
|
530
|
+
status: key("status").$type().notNull(),
|
|
531
|
+
collection: key("collection"),
|
|
532
|
+
ownerType: key("owner_type"),
|
|
533
|
+
ownerId: key("owner_id"),
|
|
534
|
+
source: longtext("source"),
|
|
535
|
+
mimeType: key("mime_type"),
|
|
536
|
+
size: bigint("size", {
|
|
537
|
+
mode: "number"
|
|
538
|
+
}),
|
|
539
|
+
chunks: int("chunks"),
|
|
540
|
+
reason: key("reason"),
|
|
541
|
+
error: longtext("error"),
|
|
542
|
+
createdAt: ts("created_at").notNull(),
|
|
543
|
+
updatedAt: ts("updated_at").notNull()
|
|
544
|
+
}, (table) => [
|
|
545
|
+
index2("rag_ingestion_log_collection_idx").on(table.collection, table.updatedAt)
|
|
546
|
+
]);
|
|
547
|
+
var agentConfirmToken2 = mysqlTable("agent_confirm_token", {
|
|
548
|
+
hash: key("hash").primaryKey(),
|
|
549
|
+
actorRef: key("actor_ref").notNull(),
|
|
550
|
+
tool: key("tool").notNull(),
|
|
551
|
+
expiresAt: bigint("expires_at", {
|
|
552
|
+
mode: "number"
|
|
553
|
+
}).notNull(),
|
|
554
|
+
createdAt: bigint("created_at", {
|
|
555
|
+
mode: "number"
|
|
556
|
+
}).notNull()
|
|
557
|
+
}, (table) => [
|
|
558
|
+
index2("agent_confirm_token_expires_idx").on(table.expiresAt)
|
|
559
|
+
]);
|
|
560
|
+
var agentStreamFrame2 = mysqlTable("agent_stream_frame", {
|
|
561
|
+
runId: key("run_id").notNull(),
|
|
562
|
+
seq: int("seq").notNull(),
|
|
563
|
+
frame: longtext("frame"),
|
|
564
|
+
error: longtext("error"),
|
|
565
|
+
createdAt: bigint("created_at", {
|
|
566
|
+
mode: "number"
|
|
567
|
+
}).notNull()
|
|
568
|
+
}, (table) => [
|
|
569
|
+
primaryKey2({
|
|
570
|
+
columns: [
|
|
571
|
+
table.runId,
|
|
572
|
+
table.seq
|
|
573
|
+
]
|
|
574
|
+
})
|
|
575
|
+
]);
|
|
576
|
+
var proposalJson = customType({
|
|
577
|
+
dataType: /* @__PURE__ */ __name(() => "longtext", "dataType"),
|
|
578
|
+
toDriver: /* @__PURE__ */ __name((value) => canonicalActionProposalJson(value), "toDriver"),
|
|
579
|
+
fromDriver: /* @__PURE__ */ __name((value) => JSON.parse(value), "fromDriver")
|
|
580
|
+
});
|
|
581
|
+
var agentActionProposal2 = mysqlTable("agent_action_proposal", {
|
|
582
|
+
id: key("id").primaryKey(),
|
|
583
|
+
scopeKey: key("scope_key").notNull(),
|
|
584
|
+
decision: key("decision").$type().notNull(),
|
|
585
|
+
logicalSort: varchar("logical_sort", {
|
|
586
|
+
length: 1020
|
|
587
|
+
}).notNull(),
|
|
588
|
+
createFingerprint: longtext("create_fingerprint").notNull(),
|
|
589
|
+
proposal: proposalJson("proposal").notNull(),
|
|
590
|
+
version: bigint("version", {
|
|
591
|
+
mode: "number"
|
|
592
|
+
}).notNull().default(0),
|
|
593
|
+
executionStatus: key("execution_status").$type(),
|
|
594
|
+
leaseExpiresAt: bigint("lease_expires_at", {
|
|
595
|
+
mode: "number"
|
|
596
|
+
}),
|
|
597
|
+
deliveryStatus: key("delivery_status"),
|
|
598
|
+
deliveryLeaseExpiresAt: bigint("delivery_lease_expires_at", {
|
|
599
|
+
mode: "number"
|
|
600
|
+
}),
|
|
601
|
+
replacementGroupKey: key("replacement_group_key"),
|
|
602
|
+
outcomeIdKey: key("outcome_id_key"),
|
|
603
|
+
proposalExpiresAt: bigint("proposal_expires_at", {
|
|
604
|
+
mode: "number"
|
|
605
|
+
}),
|
|
606
|
+
discoveryIndexVersion: bigint("discovery_index_version", {
|
|
607
|
+
mode: "number"
|
|
608
|
+
}).notNull().default(0),
|
|
609
|
+
createdAt: bigint("created_at", {
|
|
610
|
+
mode: "number"
|
|
611
|
+
}).notNull()
|
|
612
|
+
}, (table) => [
|
|
613
|
+
index2("agent_action_proposal_execution_idx").on(table.discoveryIndexVersion, table.executionStatus, table.leaseExpiresAt, table.createdAt),
|
|
614
|
+
index2("agent_action_proposal_expiry_idx").on(table.discoveryIndexVersion, table.decision, table.proposalExpiresAt, table.createdAt),
|
|
615
|
+
index2("agent_action_proposal_replacement_idx").on(table.scopeKey, table.replacementGroupKey, table.decision),
|
|
616
|
+
index2("agent_action_proposal_delivery_idx").on(table.deliveryStatus, table.deliveryLeaseExpiresAt, table.createdAt),
|
|
617
|
+
uniqueIndex2("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
|
|
618
|
+
index2("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
|
|
619
|
+
]);
|
|
620
|
+
var mysqlAgentSchema = {
|
|
621
|
+
agentActionProposal: agentActionProposal2,
|
|
622
|
+
agentThread: agentThread2,
|
|
623
|
+
agentMessage: agentMessage2,
|
|
624
|
+
agentQueuedMessage: agentQueuedMessage2,
|
|
625
|
+
agentToolCall: agentToolCall2,
|
|
626
|
+
agentTokenUsage: agentTokenUsage2,
|
|
627
|
+
agentModelPricing: agentModelPricing2,
|
|
628
|
+
agentRun: agentRun2,
|
|
629
|
+
agentMemory: agentMemory2,
|
|
630
|
+
ragIngestionLog: ragIngestionLog2,
|
|
631
|
+
agentConfirmToken: agentConfirmToken2,
|
|
632
|
+
agentStreamFrame: agentStreamFrame2
|
|
633
|
+
};
|
|
634
|
+
|
|
635
|
+
// src/schema-pg.ts
|
|
636
|
+
import { canonicalActionProposalJson as canonicalActionProposalJson2 } from "@dudousxd/nestjs-agent-core";
|
|
637
|
+
import { bigint as bigint2, boolean as boolean2, customType as customType2, doublePrecision, index as index3, integer as integer2, jsonb, pgTable, primaryKey as primaryKey3, text as text2, timestamp, uniqueIndex as uniqueIndex3 } from "drizzle-orm/pg-core";
|
|
638
|
+
var ts2 = /* @__PURE__ */ __name((name) => timestamp(name, {
|
|
639
|
+
withTimezone: true,
|
|
640
|
+
precision: 3,
|
|
641
|
+
mode: "date"
|
|
642
|
+
}), "ts");
|
|
643
|
+
var agentThread3 = pgTable("agent_thread", {
|
|
644
|
+
id: text2("id").primaryKey(),
|
|
645
|
+
actorRef: text2("actor_ref").notNull(),
|
|
646
|
+
tenantRef: text2("tenant_ref"),
|
|
647
|
+
title: text2("title").notNull(),
|
|
648
|
+
transient: boolean2("transient").notNull().default(false),
|
|
649
|
+
activeStreamId: text2("active_stream_id"),
|
|
650
|
+
defaultAgent: text2("default_agent"),
|
|
651
|
+
model: text2("model"),
|
|
652
|
+
/** The persona a send on this thread runs under when it names none; `null` → the agent's default. */
|
|
653
|
+
persona: text2("persona"),
|
|
654
|
+
queuePause: jsonb("queue_pause").$type(),
|
|
655
|
+
createdAt: ts2("created_at").notNull(),
|
|
656
|
+
updatedAt: ts2("updated_at").notNull(),
|
|
657
|
+
deletedAt: ts2("deleted_at")
|
|
658
|
+
}, (table) => [
|
|
659
|
+
index3("agent_thread_actor_updated_idx").on(table.actorRef, table.updatedAt)
|
|
660
|
+
]);
|
|
661
|
+
var agentMessage3 = pgTable("agent_message", {
|
|
662
|
+
id: text2("id").primaryKey(),
|
|
663
|
+
threadId: text2("thread_id").notNull().references(() => agentThread3.id, {
|
|
664
|
+
onDelete: "cascade"
|
|
665
|
+
}),
|
|
666
|
+
role: text2("role").$type().notNull(),
|
|
667
|
+
actionProposalOutcome: text2("action_proposal_outcome"),
|
|
668
|
+
content: text2("content").notNull(),
|
|
669
|
+
toolCalls: jsonb("tool_calls").$type(),
|
|
670
|
+
toolResults: jsonb("tool_results").$type(),
|
|
671
|
+
attachments: jsonb("attachments").$type(),
|
|
672
|
+
followUps: jsonb("follow_ups").$type(),
|
|
673
|
+
usage: jsonb("usage").$type(),
|
|
674
|
+
agentName: text2("agent_name"),
|
|
675
|
+
/** The persona the turn that wrote this message ran under; `null` → none. */
|
|
676
|
+
persona: text2("persona"),
|
|
677
|
+
runId: text2("run_id"),
|
|
678
|
+
reasoning: text2("reasoning"),
|
|
679
|
+
reasoningMs: integer2("reasoning_ms"),
|
|
680
|
+
ui: jsonb("ui").$type(),
|
|
681
|
+
feedback: jsonb("feedback").$type(),
|
|
682
|
+
seq: integer2("seq"),
|
|
683
|
+
createdAt: ts2("created_at").notNull()
|
|
684
|
+
}, (table) => [
|
|
685
|
+
index3("agent_message_thread_created_idx").on(table.threadId, table.createdAt)
|
|
686
|
+
]);
|
|
687
|
+
var agentToolCall3 = pgTable("agent_tool_call", {
|
|
688
|
+
proposalId: text2("proposal_id"),
|
|
689
|
+
id: text2("id").primaryKey(),
|
|
690
|
+
messageId: text2("message_id").notNull().references(() => agentMessage3.id, {
|
|
691
|
+
onDelete: "cascade"
|
|
692
|
+
}),
|
|
693
|
+
toolName: text2("tool_name").notNull(),
|
|
694
|
+
toolType: text2("tool_type").$type().notNull(),
|
|
695
|
+
input: jsonb("input"),
|
|
696
|
+
output: jsonb("output"),
|
|
697
|
+
status: text2("status").$type().notNull(),
|
|
698
|
+
executedByRef: text2("executed_by_ref"),
|
|
699
|
+
executionMs: integer2("execution_ms"),
|
|
700
|
+
error: text2("error"),
|
|
701
|
+
createdAt: ts2("created_at").notNull(),
|
|
702
|
+
executedAt: ts2("executed_at"),
|
|
703
|
+
runId: text2("run_id"),
|
|
704
|
+
confirmation: jsonb("confirmation").$type(),
|
|
705
|
+
approver: text2("approver"),
|
|
706
|
+
expiresAt: ts2("expires_at"),
|
|
707
|
+
remember: boolean2("remember"),
|
|
708
|
+
decidedVia: text2("decided_via")
|
|
709
|
+
}, (table) => [
|
|
710
|
+
index3("agent_tool_call_message_idx").on(table.messageId)
|
|
711
|
+
]);
|
|
712
|
+
var agentQueuedMessage3 = pgTable("agent_queued_message", {
|
|
713
|
+
uiCapabilities: jsonb("ui_capabilities").$type(),
|
|
714
|
+
id: text2("id").primaryKey(),
|
|
715
|
+
threadId: text2("thread_id").notNull().references(() => agentThread3.id, {
|
|
716
|
+
onDelete: "cascade"
|
|
717
|
+
}),
|
|
718
|
+
actor: jsonb("actor").$type().notNull(),
|
|
719
|
+
content: text2("content").notNull(),
|
|
720
|
+
attachments: jsonb("attachments").$type(),
|
|
721
|
+
agentName: text2("agent_name"),
|
|
722
|
+
/** The persona the send resolved — what the message starts under. */
|
|
723
|
+
persona: text2("persona"),
|
|
724
|
+
model: text2("model"),
|
|
725
|
+
pageContext: jsonb("page_context").$type(),
|
|
726
|
+
interrupt: boolean2("interrupt").notNull().default(false),
|
|
727
|
+
position: integer2("position").notNull(),
|
|
728
|
+
createdAt: ts2("created_at").notNull(),
|
|
729
|
+
updatedAt: ts2("updated_at").notNull()
|
|
730
|
+
}, (table) => [
|
|
731
|
+
index3("agent_queued_message_thread_position_idx").on(table.threadId, table.position)
|
|
732
|
+
]);
|
|
733
|
+
var agentTokenUsage3 = pgTable("agent_token_usage", {
|
|
734
|
+
id: text2("id").primaryKey(),
|
|
735
|
+
threadId: text2("thread_id").notNull().references(() => agentThread3.id, {
|
|
736
|
+
onDelete: "cascade"
|
|
737
|
+
}),
|
|
738
|
+
actorRef: text2("actor_ref").notNull(),
|
|
739
|
+
messageId: text2("message_id"),
|
|
740
|
+
modelId: text2("model_id").notNull(),
|
|
741
|
+
purpose: text2("purpose").$type().notNull(),
|
|
742
|
+
inputTokens: integer2("input_tokens").notNull(),
|
|
743
|
+
outputTokens: integer2("output_tokens").notNull(),
|
|
744
|
+
cacheWriteTokens: integer2("cache_write_tokens"),
|
|
745
|
+
cacheReadTokens: integer2("cache_read_tokens"),
|
|
746
|
+
costUsd: doublePrecision("cost_usd"),
|
|
747
|
+
createdAt: ts2("created_at").notNull()
|
|
748
|
+
}, (table) => [
|
|
749
|
+
index3("agent_token_usage_actor_created_idx").on(table.actorRef, table.createdAt)
|
|
750
|
+
]);
|
|
751
|
+
var agentModelPricing3 = pgTable("agent_model_pricing", {
|
|
752
|
+
id: text2("id").primaryKey(),
|
|
753
|
+
modelId: text2("model_id").notNull(),
|
|
754
|
+
inputPricePer1m: doublePrecision("input_price_per_1m").notNull(),
|
|
755
|
+
outputPricePer1m: doublePrecision("output_price_per_1m").notNull(),
|
|
756
|
+
cacheWritePricePer1m: doublePrecision("cache_write_price_per_1m"),
|
|
757
|
+
cacheReadPricePer1m: doublePrecision("cache_read_price_per_1m"),
|
|
758
|
+
effectiveFrom: ts2("effective_from").notNull(),
|
|
759
|
+
isCurrent: boolean2("is_current").notNull()
|
|
760
|
+
});
|
|
761
|
+
var agentRun3 = pgTable("agent_run", {
|
|
762
|
+
id: text2("id").primaryKey(),
|
|
763
|
+
threadId: text2("thread_id").notNull().references(() => agentThread3.id, {
|
|
764
|
+
onDelete: "cascade"
|
|
765
|
+
}),
|
|
766
|
+
actorRef: text2("actor_ref").notNull(),
|
|
767
|
+
agentName: text2("agent_name"),
|
|
768
|
+
status: text2("status").$type().notNull(),
|
|
769
|
+
durationMs: integer2("duration_ms"),
|
|
770
|
+
errorCode: text2("error_code"),
|
|
771
|
+
errorMessage: text2("error_message"),
|
|
772
|
+
retries: integer2("retries").notNull().default(0),
|
|
773
|
+
startedAt: ts2("started_at").notNull(),
|
|
774
|
+
settledAt: ts2("settled_at"),
|
|
775
|
+
promptHash: text2("prompt_hash"),
|
|
776
|
+
parentRunId: text2("parent_run_id")
|
|
777
|
+
}, (table) => [
|
|
778
|
+
index3("agent_run_started_idx").on(table.startedAt)
|
|
779
|
+
]);
|
|
780
|
+
var agentMemory3 = pgTable("agent_memory", {
|
|
781
|
+
id: text2("id").primaryKey(),
|
|
782
|
+
scope: text2("scope").notNull(),
|
|
783
|
+
key: text2("key").notNull(),
|
|
784
|
+
text: text2("text").notNull(),
|
|
785
|
+
originAuthor: text2("origin_author").$type().notNull(),
|
|
786
|
+
originThreadId: text2("origin_thread_id"),
|
|
787
|
+
originRunId: text2("origin_run_id"),
|
|
788
|
+
originActorRef: text2("origin_actor_ref"),
|
|
789
|
+
pinned: boolean2("pinned").notNull().default(false),
|
|
790
|
+
createdAt: ts2("created_at").notNull(),
|
|
791
|
+
updatedAt: ts2("updated_at").notNull()
|
|
792
|
+
}, (table) => [
|
|
793
|
+
uniqueIndex3("agent_memory_scope_key_uq").on(table.scope, table.key)
|
|
794
|
+
]);
|
|
795
|
+
var ragIngestionLog3 = pgTable("rag_ingestion_log", {
|
|
796
|
+
documentId: text2("document_id").primaryKey(),
|
|
797
|
+
status: text2("status").$type().notNull(),
|
|
798
|
+
collection: text2("collection"),
|
|
799
|
+
ownerType: text2("owner_type"),
|
|
800
|
+
ownerId: text2("owner_id"),
|
|
801
|
+
source: text2("source"),
|
|
802
|
+
mimeType: text2("mime_type"),
|
|
803
|
+
size: bigint2("size", {
|
|
804
|
+
mode: "number"
|
|
805
|
+
}),
|
|
806
|
+
chunks: integer2("chunks"),
|
|
807
|
+
reason: text2("reason"),
|
|
808
|
+
error: text2("error"),
|
|
809
|
+
createdAt: ts2("created_at").notNull(),
|
|
810
|
+
updatedAt: ts2("updated_at").notNull()
|
|
811
|
+
}, (table) => [
|
|
812
|
+
index3("rag_ingestion_log_collection_idx").on(table.collection, table.updatedAt)
|
|
813
|
+
]);
|
|
814
|
+
var agentConfirmToken3 = pgTable("agent_confirm_token", {
|
|
815
|
+
hash: text2("hash").primaryKey(),
|
|
816
|
+
actorRef: text2("actor_ref").notNull(),
|
|
817
|
+
tool: text2("tool").notNull(),
|
|
818
|
+
expiresAt: bigint2("expires_at", {
|
|
819
|
+
mode: "number"
|
|
820
|
+
}).notNull(),
|
|
821
|
+
createdAt: bigint2("created_at", {
|
|
822
|
+
mode: "number"
|
|
823
|
+
}).notNull()
|
|
824
|
+
}, (table) => [
|
|
825
|
+
index3("agent_confirm_token_expires_idx").on(table.expiresAt)
|
|
826
|
+
]);
|
|
827
|
+
var agentStreamFrame3 = pgTable("agent_stream_frame", {
|
|
828
|
+
runId: text2("run_id").notNull(),
|
|
829
|
+
seq: integer2("seq").notNull(),
|
|
830
|
+
frame: text2("frame"),
|
|
831
|
+
error: text2("error"),
|
|
832
|
+
createdAt: bigint2("created_at", {
|
|
833
|
+
mode: "number"
|
|
834
|
+
}).notNull()
|
|
835
|
+
}, (table) => [
|
|
836
|
+
primaryKey3({
|
|
837
|
+
columns: [
|
|
838
|
+
table.runId,
|
|
839
|
+
table.seq
|
|
840
|
+
]
|
|
841
|
+
})
|
|
842
|
+
]);
|
|
843
|
+
var proposalJson2 = customType2({
|
|
844
|
+
dataType: /* @__PURE__ */ __name(() => "text", "dataType"),
|
|
845
|
+
toDriver: /* @__PURE__ */ __name((value) => canonicalActionProposalJson2(value), "toDriver"),
|
|
846
|
+
fromDriver: /* @__PURE__ */ __name((value) => JSON.parse(value), "fromDriver")
|
|
847
|
+
});
|
|
848
|
+
var agentActionProposal3 = pgTable("agent_action_proposal", {
|
|
849
|
+
id: text2("id").primaryKey(),
|
|
850
|
+
scopeKey: text2("scope_key").notNull(),
|
|
851
|
+
decision: text2("decision").$type().notNull(),
|
|
852
|
+
logicalSort: text2("logical_sort").notNull(),
|
|
853
|
+
createFingerprint: text2("create_fingerprint").notNull(),
|
|
854
|
+
proposal: proposalJson2("proposal").notNull(),
|
|
855
|
+
version: bigint2("version", {
|
|
856
|
+
mode: "number"
|
|
857
|
+
}).notNull().default(0),
|
|
858
|
+
executionStatus: text2("execution_status").$type(),
|
|
859
|
+
leaseExpiresAt: bigint2("lease_expires_at", {
|
|
860
|
+
mode: "number"
|
|
861
|
+
}),
|
|
862
|
+
deliveryStatus: text2("delivery_status"),
|
|
863
|
+
deliveryLeaseExpiresAt: bigint2("delivery_lease_expires_at", {
|
|
864
|
+
mode: "number"
|
|
865
|
+
}),
|
|
866
|
+
replacementGroupKey: text2("replacement_group_key"),
|
|
867
|
+
outcomeIdKey: text2("outcome_id_key"),
|
|
868
|
+
proposalExpiresAt: bigint2("proposal_expires_at", {
|
|
869
|
+
mode: "number"
|
|
870
|
+
}),
|
|
871
|
+
discoveryIndexVersion: bigint2("discovery_index_version", {
|
|
872
|
+
mode: "number"
|
|
873
|
+
}).notNull().default(0),
|
|
874
|
+
createdAt: bigint2("created_at", {
|
|
875
|
+
mode: "number"
|
|
876
|
+
}).notNull()
|
|
877
|
+
}, (table) => [
|
|
878
|
+
index3("agent_action_proposal_execution_idx").on(table.discoveryIndexVersion, table.executionStatus, table.leaseExpiresAt, table.createdAt),
|
|
879
|
+
index3("agent_action_proposal_expiry_idx").on(table.discoveryIndexVersion, table.decision, table.proposalExpiresAt, table.createdAt),
|
|
880
|
+
index3("agent_action_proposal_replacement_idx").on(table.scopeKey, table.replacementGroupKey, table.decision),
|
|
881
|
+
index3("agent_action_proposal_delivery_idx").on(table.deliveryStatus, table.deliveryLeaseExpiresAt, table.createdAt),
|
|
882
|
+
uniqueIndex3("agent_action_proposal_outcome_idx").on(table.outcomeIdKey),
|
|
883
|
+
index3("agent_action_proposal_scope_idx").on(table.scopeKey, table.createdAt, table.id)
|
|
884
|
+
]);
|
|
885
|
+
var pgAgentSchema = {
|
|
886
|
+
agentActionProposal: agentActionProposal3,
|
|
887
|
+
agentThread: agentThread3,
|
|
888
|
+
agentMessage: agentMessage3,
|
|
889
|
+
agentQueuedMessage: agentQueuedMessage3,
|
|
890
|
+
agentToolCall: agentToolCall3,
|
|
891
|
+
agentTokenUsage: agentTokenUsage3,
|
|
892
|
+
agentModelPricing: agentModelPricing3,
|
|
893
|
+
agentRun: agentRun3,
|
|
894
|
+
agentMemory: agentMemory3,
|
|
895
|
+
ragIngestionLog: ragIngestionLog3,
|
|
896
|
+
agentConfirmToken: agentConfirmToken3,
|
|
897
|
+
agentStreamFrame: agentStreamFrame3
|
|
898
|
+
};
|
|
899
|
+
|
|
900
|
+
// src/dialect.ts
|
|
901
|
+
function agentDialectOf(db) {
|
|
902
|
+
if (is(db, PgDatabase)) return "postgres";
|
|
903
|
+
if (is(db, MySqlDatabase)) return "mysql";
|
|
904
|
+
return "sqlite";
|
|
905
|
+
}
|
|
906
|
+
__name(agentDialectOf, "agentDialectOf");
|
|
907
|
+
function agentTablesFor(dialect) {
|
|
908
|
+
if (dialect === "postgres") return pgAgentSchema;
|
|
909
|
+
if (dialect === "mysql") return mysqlAgentSchema;
|
|
910
|
+
return agentSchema;
|
|
911
|
+
}
|
|
912
|
+
__name(agentTablesFor, "agentTablesFor");
|
|
913
|
+
function asBuilder(db) {
|
|
914
|
+
return db;
|
|
915
|
+
}
|
|
916
|
+
__name(asBuilder, "asBuilder");
|
|
917
|
+
async function affectedRows(dialect, statement, column) {
|
|
918
|
+
if (dialect !== "mysql") {
|
|
919
|
+
return (await statement.returning({
|
|
920
|
+
affected: column
|
|
921
|
+
})).length;
|
|
922
|
+
}
|
|
923
|
+
return mysqlAffectedRows(await statement);
|
|
924
|
+
}
|
|
925
|
+
__name(affectedRows, "affectedRows");
|
|
926
|
+
function mysqlAffectedRows(result) {
|
|
927
|
+
const header = Array.isArray(result) ? result[0] : result;
|
|
928
|
+
const counts = header;
|
|
929
|
+
const count3 = counts?.affectedRows ?? counts?.rowsAffected;
|
|
930
|
+
return typeof count3 === "number" ? count3 : 0;
|
|
931
|
+
}
|
|
932
|
+
__name(mysqlAffectedRows, "mysqlAffectedRows");
|
|
933
|
+
async function runSql(db, dialect, statement) {
|
|
934
|
+
if (dialect === "sqlite") {
|
|
935
|
+
await db.run(statement);
|
|
936
|
+
return;
|
|
570
937
|
}
|
|
571
|
-
|
|
572
|
-
|
|
573
|
-
|
|
574
|
-
await db.run(sql.raw(statement));
|
|
938
|
+
if (dialect === "postgres") {
|
|
939
|
+
await db.execute(statement);
|
|
940
|
+
return;
|
|
575
941
|
}
|
|
576
|
-
|
|
577
|
-
|
|
578
|
-
|
|
579
|
-
|
|
942
|
+
await db.execute(statement);
|
|
943
|
+
}
|
|
944
|
+
__name(runSql, "runSql");
|
|
945
|
+
async function querySql(db, dialect, statement) {
|
|
946
|
+
if (dialect === "sqlite") {
|
|
947
|
+
return db.all(statement);
|
|
948
|
+
}
|
|
949
|
+
const result = dialect === "postgres" ? await db.execute(statement) : await db.execute(statement);
|
|
950
|
+
if (dialect === "mysql") {
|
|
951
|
+
return Array.isArray(result) ? result[0] : [];
|
|
952
|
+
}
|
|
953
|
+
return Array.isArray(result) ? result : result.rows ?? [];
|
|
954
|
+
}
|
|
955
|
+
__name(querySql, "querySql");
|
|
956
|
+
function isUniqueViolation(error) {
|
|
957
|
+
for (let current = error; current !== null && typeof current === "object"; ) {
|
|
958
|
+
const { code, errno } = current;
|
|
959
|
+
if (code === "23505" || code === "ER_DUP_ENTRY" || errno === 1062 || code === "ER_LOCK_DEADLOCK" || errno === 1213 || typeof code === "string" && code.startsWith("SQLITE_CONSTRAINT")) {
|
|
960
|
+
return true;
|
|
580
961
|
}
|
|
962
|
+
current = current.cause;
|
|
581
963
|
}
|
|
964
|
+
return false;
|
|
965
|
+
}
|
|
966
|
+
__name(isUniqueViolation, "isUniqueViolation");
|
|
967
|
+
function upsert(dialect, insert, target, set) {
|
|
968
|
+
if (dialect === "mysql") {
|
|
969
|
+
return insert.onDuplicateKeyUpdate({
|
|
970
|
+
set
|
|
971
|
+
});
|
|
972
|
+
}
|
|
973
|
+
return insert.onConflictDoUpdate({
|
|
974
|
+
target,
|
|
975
|
+
set
|
|
976
|
+
});
|
|
977
|
+
}
|
|
978
|
+
__name(upsert, "upsert");
|
|
979
|
+
|
|
980
|
+
// src/ensure-schema.ts
|
|
981
|
+
async function ensureAgentSchema(db) {
|
|
982
|
+
const dialect = agentDialectOf(db);
|
|
983
|
+
if (dialect === "postgres") {
|
|
984
|
+
await db.transaction(async (tx) => {
|
|
985
|
+
await tx.execute(sql.raw(`select pg_advisory_xact_lock(hashtext('${LOCK_NAME}'))`));
|
|
986
|
+
await heal(tx, dialect);
|
|
987
|
+
});
|
|
988
|
+
return;
|
|
989
|
+
}
|
|
990
|
+
if (dialect === "mysql") {
|
|
991
|
+
await db.transaction(async (tx) => {
|
|
992
|
+
await tx.execute(sql.raw(`select get_lock('${LOCK_NAME}', 30)`));
|
|
993
|
+
try {
|
|
994
|
+
await heal(tx, dialect);
|
|
995
|
+
} finally {
|
|
996
|
+
await tx.execute(sql.raw(`select release_lock('${LOCK_NAME}')`));
|
|
997
|
+
}
|
|
998
|
+
});
|
|
999
|
+
return;
|
|
1000
|
+
}
|
|
1001
|
+
await heal(db, dialect);
|
|
582
1002
|
}
|
|
583
1003
|
__name(ensureAgentSchema, "ensureAgentSchema");
|
|
1004
|
+
var LOCK_NAME = "nestjs_agent_schema";
|
|
1005
|
+
var MYSQL_TABLE_OPTIONS = "ENGINE=InnoDB DEFAULT CHARSET=utf8mb4 COLLATE=utf8mb4_bin";
|
|
1006
|
+
function tableSpec(dialect, table) {
|
|
1007
|
+
const config = dialect === "postgres" ? pgTableConfig(table) : dialect === "mysql" ? mysqlTableConfig(table) : sqliteTableConfig(table);
|
|
1008
|
+
const columns = config.columns;
|
|
1009
|
+
const compositeKey = config.primaryKeys[0]?.columns.map((column) => column.name);
|
|
1010
|
+
return {
|
|
1011
|
+
name: config.name,
|
|
1012
|
+
columns,
|
|
1013
|
+
primaryKey: compositeKey ?? columns.filter((column) => column.primary).map((c) => c.name),
|
|
1014
|
+
foreignKeys: config.foreignKeys.map((foreignKey) => {
|
|
1015
|
+
const reference = foreignKey.reference();
|
|
1016
|
+
return {
|
|
1017
|
+
columns: reference.columns.map((column) => column.name),
|
|
1018
|
+
table: getTableName(reference.foreignTable),
|
|
1019
|
+
foreignColumns: reference.foreignColumns.map((column) => column.name),
|
|
1020
|
+
...foreignKey.onDelete !== void 0 ? {
|
|
1021
|
+
onDelete: foreignKey.onDelete
|
|
1022
|
+
} : {}
|
|
1023
|
+
};
|
|
1024
|
+
}),
|
|
1025
|
+
indexes: config.indexes.map((index4) => ({
|
|
1026
|
+
name: String(index4.config.name),
|
|
1027
|
+
unique: index4.config.unique === true,
|
|
1028
|
+
columns: index4.config.columns.map((column) => String(column.name))
|
|
1029
|
+
}))
|
|
1030
|
+
};
|
|
1031
|
+
}
|
|
1032
|
+
__name(tableSpec, "tableSpec");
|
|
1033
|
+
function quote(dialect, identifier) {
|
|
1034
|
+
return dialect === "mysql" ? `\`${identifier}\`` : `"${identifier}"`;
|
|
1035
|
+
}
|
|
1036
|
+
__name(quote, "quote");
|
|
1037
|
+
function literal(dialect, value) {
|
|
1038
|
+
if (typeof value === "boolean") {
|
|
1039
|
+
return dialect === "sqlite" ? value ? "1" : "0" : value ? "true" : "false";
|
|
1040
|
+
}
|
|
1041
|
+
if (typeof value === "number") return String(value);
|
|
1042
|
+
return `'${String(value).replaceAll("'", "''")}'`;
|
|
1043
|
+
}
|
|
1044
|
+
__name(literal, "literal");
|
|
1045
|
+
function columnDefinition(dialect, column) {
|
|
1046
|
+
const parts = [
|
|
1047
|
+
quote(dialect, column.name),
|
|
1048
|
+
column.getSQLType()
|
|
1049
|
+
];
|
|
1050
|
+
if (column.notNull) parts.push("NOT NULL");
|
|
1051
|
+
if (column.hasDefault && column.default !== void 0) {
|
|
1052
|
+
parts.push(`DEFAULT ${literal(dialect, column.default)}`);
|
|
1053
|
+
}
|
|
1054
|
+
return parts.join(" ");
|
|
1055
|
+
}
|
|
1056
|
+
__name(columnDefinition, "columnDefinition");
|
|
1057
|
+
function createTableSql(dialect, spec) {
|
|
1058
|
+
const q = /* @__PURE__ */ __name((identifier) => quote(dialect, identifier), "q");
|
|
1059
|
+
const lines = spec.columns.map((column) => columnDefinition(dialect, column));
|
|
1060
|
+
lines.push(`PRIMARY KEY (${spec.primaryKey.map(q).join(", ")})`);
|
|
1061
|
+
for (const foreignKey of spec.foreignKeys) {
|
|
1062
|
+
lines.push(`FOREIGN KEY (${foreignKey.columns.map(q).join(", ")}) REFERENCES ${q(foreignKey.table)} (${foreignKey.foreignColumns.map(q).join(", ")})${foreignKey.onDelete !== void 0 ? ` ON DELETE ${foreignKey.onDelete.toUpperCase()}` : ""}`);
|
|
1063
|
+
}
|
|
1064
|
+
const options = dialect === "mysql" ? ` ${MYSQL_TABLE_OPTIONS}` : "";
|
|
1065
|
+
return `CREATE TABLE IF NOT EXISTS ${q(spec.name)} (
|
|
1066
|
+
${lines.join(",\n ")}
|
|
1067
|
+
)${options}`;
|
|
1068
|
+
}
|
|
1069
|
+
__name(createTableSql, "createTableSql");
|
|
1070
|
+
function agentSchemaDdl(dialect) {
|
|
1071
|
+
const statements = [];
|
|
1072
|
+
for (const spec of specs(dialect)) {
|
|
1073
|
+
statements.push(createTableSql(dialect, spec));
|
|
1074
|
+
for (const index4 of spec.indexes) {
|
|
1075
|
+
statements.push(createIndexSql(dialect, spec.name, index4));
|
|
1076
|
+
}
|
|
1077
|
+
}
|
|
1078
|
+
return statements;
|
|
1079
|
+
}
|
|
1080
|
+
__name(agentSchemaDdl, "agentSchemaDdl");
|
|
1081
|
+
function createIndexSql(dialect, table, index4) {
|
|
1082
|
+
const q = /* @__PURE__ */ __name((identifier) => quote(dialect, identifier), "q");
|
|
1083
|
+
const guard = dialect === "mysql" ? "" : "IF NOT EXISTS ";
|
|
1084
|
+
return `CREATE ${index4.unique ? "UNIQUE " : ""}INDEX ${guard}${q(index4.name)} ON ${q(table)} (${index4.columns.map(q).join(", ")})`;
|
|
1085
|
+
}
|
|
1086
|
+
__name(createIndexSql, "createIndexSql");
|
|
1087
|
+
function specs(dialect) {
|
|
1088
|
+
const all = Object.values(agentTablesFor(dialect)).map((table) => tableSpec(dialect, table));
|
|
1089
|
+
const ordered = [];
|
|
1090
|
+
const placed = /* @__PURE__ */ new Set();
|
|
1091
|
+
while (ordered.length < all.length) {
|
|
1092
|
+
const ready = all.filter((spec) => !placed.has(spec.name) && spec.foreignKeys.every((key2) => key2.table === spec.name || placed.has(key2.table)));
|
|
1093
|
+
if (ready.length === 0) throw new Error("agent schema: circular foreign keys");
|
|
1094
|
+
for (const spec of ready) {
|
|
1095
|
+
ordered.push(spec);
|
|
1096
|
+
placed.add(spec.name);
|
|
1097
|
+
}
|
|
1098
|
+
}
|
|
1099
|
+
return ordered;
|
|
1100
|
+
}
|
|
1101
|
+
__name(specs, "specs");
|
|
1102
|
+
async function existingColumns(db, dialect, table) {
|
|
1103
|
+
const rows = dialect === "sqlite" ? await querySql(db, dialect, sql.raw(`PRAGMA table_info("${table}")`)) : await querySql(db, dialect, sql`select column_name as name from information_schema.columns where table_schema = ${sql.raw(dialect === "mysql" ? "database()" : "current_schema()")} and table_name = ${table}`);
|
|
1104
|
+
return new Set(rows.map((row) => String(row.name)));
|
|
1105
|
+
}
|
|
1106
|
+
__name(existingColumns, "existingColumns");
|
|
1107
|
+
async function indexExists(db, dialect, table, index4) {
|
|
1108
|
+
let query;
|
|
1109
|
+
if (dialect === "sqlite") {
|
|
1110
|
+
query = sql`select name from sqlite_master where type = 'index' and name = ${index4}`;
|
|
1111
|
+
} else if (dialect === "postgres") {
|
|
1112
|
+
query = sql`select indexname as name from pg_indexes where schemaname = current_schema() and indexname = ${index4}`;
|
|
1113
|
+
} else {
|
|
1114
|
+
query = sql`select index_name as name from information_schema.statistics where table_schema = database() and table_name = ${table} and index_name = ${index4}`;
|
|
1115
|
+
}
|
|
1116
|
+
return (await querySql(db, dialect, query)).length > 0;
|
|
1117
|
+
}
|
|
1118
|
+
__name(indexExists, "indexExists");
|
|
1119
|
+
async function heal(db, dialect) {
|
|
1120
|
+
for (const spec of specs(dialect)) {
|
|
1121
|
+
await runSql(db, dialect, sql.raw(createTableSql(dialect, spec)));
|
|
1122
|
+
const present = await existingColumns(db, dialect, spec.name);
|
|
1123
|
+
for (const column of spec.columns) {
|
|
1124
|
+
if (!present.has(column.name)) {
|
|
1125
|
+
await runSql(db, dialect, sql.raw(`ALTER TABLE ${quote(dialect, spec.name)} ADD COLUMN ${columnDefinition(dialect, column)}`));
|
|
1126
|
+
}
|
|
1127
|
+
}
|
|
1128
|
+
for (const index4 of spec.indexes) {
|
|
1129
|
+
if (!await indexExists(db, dialect, spec.name, index4.name)) {
|
|
1130
|
+
await runSql(db, dialect, sql.raw(createIndexSql(dialect, spec.name, index4)));
|
|
1131
|
+
}
|
|
1132
|
+
}
|
|
1133
|
+
}
|
|
1134
|
+
}
|
|
1135
|
+
__name(heal, "heal");
|
|
584
1136
|
|
|
585
1137
|
// src/drizzle-agent-store.ts
|
|
586
|
-
import { toolCallApprovalFromRow } from "@dudousxd/nestjs-agent-core";
|
|
587
|
-
import { and, asc, desc, eq, gte, inArray, isNotNull, isNull, lte, max, min, or, sql as
|
|
588
|
-
|
|
589
|
-
|
|
590
|
-
|
|
591
|
-
|
|
592
|
-
|
|
593
|
-
|
|
594
|
-
|
|
595
|
-
|
|
596
|
-
|
|
1138
|
+
import { canonicalActionProposalJson as canonicalActionProposalJson4, toolCallApprovalFromRow } from "@dudousxd/nestjs-agent-core";
|
|
1139
|
+
import { and as and2, asc as asc2, desc, eq as eq2, gte, inArray, isNotNull, isNull as isNull2, lte as lte2, max as max2, min, or as or2, sql as sql3 } from "drizzle-orm";
|
|
1140
|
+
|
|
1141
|
+
// src/drizzle-action-proposal-store.ts
|
|
1142
|
+
import { createHash, randomUUID } from "crypto";
|
|
1143
|
+
import { actionProposalOutcomeFenceValid, actionProposalOutcomeText, actionProposalScopeMatches, canonicalActionProposalJson as canonicalActionProposalJson3, claimActionProposalOutcome, initialActionProposal, transitionActionProposalClaim, transitionActionProposalDecision, transitionActionProposalLease, transitionActionProposalSettlement, transitionActionProposalSupersession, validateActionProposalDiscoveryIndexBatch, validateActionProposalExpiryBatch, validateActionProposalListQuery, validateActionProposalWorkerClaim } from "@dudousxd/nestjs-agent-core";
|
|
1144
|
+
import { and, asc, entityKind, eq, gt, isNull, lte, max, or, sql as sql2 } from "drizzle-orm";
|
|
1145
|
+
|
|
1146
|
+
// src/action-proposal-transaction-mode.ts
|
|
1147
|
+
function actionProposalTransactionMode(kind) {
|
|
1148
|
+
if (kind === "BetterSQLite3Database" || kind === "BetterSQLiteTransaction") return "sync";
|
|
1149
|
+
if (kind !== void 0 && [
|
|
1150
|
+
"NodePgDatabase",
|
|
1151
|
+
"NodePgTransaction",
|
|
1152
|
+
"MySql2Database",
|
|
1153
|
+
"MySql2Transaction",
|
|
1154
|
+
"LibSQLDatabase",
|
|
1155
|
+
"LibSQLTransaction"
|
|
1156
|
+
].includes(kind)) return "async";
|
|
1157
|
+
return "unsupported";
|
|
1158
|
+
}
|
|
1159
|
+
__name(actionProposalTransactionMode, "actionProposalTransactionMode");
|
|
1160
|
+
|
|
1161
|
+
// src/drizzle-action-proposal-store.ts
|
|
1162
|
+
var DrizzleActionProposalStore = class {
|
|
1163
|
+
static {
|
|
1164
|
+
__name(this, "DrizzleActionProposalStore");
|
|
1165
|
+
}
|
|
1166
|
+
db;
|
|
1167
|
+
rawDb;
|
|
1168
|
+
actionProposalAdmissionSupported;
|
|
1169
|
+
synchronousSqlite;
|
|
1170
|
+
dialect;
|
|
1171
|
+
table;
|
|
1172
|
+
clock;
|
|
1173
|
+
constructor(db, options = {}) {
|
|
1174
|
+
this.rawDb = db;
|
|
1175
|
+
const kind = db.constructor[entityKind];
|
|
1176
|
+
const transactionMode = actionProposalTransactionMode(kind);
|
|
1177
|
+
this.synchronousSqlite = transactionMode === "sync";
|
|
1178
|
+
this.actionProposalAdmissionSupported = transactionMode !== "unsupported";
|
|
1179
|
+
this.dialect = agentDialectOf(db);
|
|
1180
|
+
this.table = agentTablesFor(this.dialect).agentActionProposal;
|
|
1181
|
+
this.db = asBuilder(db);
|
|
1182
|
+
this.clock = options.clock ?? Date.now;
|
|
1183
|
+
}
|
|
1184
|
+
async createActionProposal(input) {
|
|
1185
|
+
const proposal = initialActionProposal(input, this.clock());
|
|
1186
|
+
const row = {
|
|
1187
|
+
id: physicalId(input.id),
|
|
1188
|
+
scopeKey: scopeKey(input),
|
|
1189
|
+
decision: proposal.decision,
|
|
1190
|
+
logicalSort: logicalSort(input.id),
|
|
1191
|
+
createFingerprint: canonicalActionProposalJson3(input),
|
|
1192
|
+
proposal,
|
|
1193
|
+
...discoveryMetadata(proposal),
|
|
1194
|
+
version: 0,
|
|
1195
|
+
createdAt: proposal.createdAt
|
|
1196
|
+
};
|
|
1197
|
+
const table = this.table;
|
|
1198
|
+
const insert = this.db.insert(table);
|
|
1199
|
+
const inserted = this.dialect === "mysql" ? mysqlAffectedRows(await insert.ignore().values(row)) : await affectedRows(this.dialect, insert.values(row).onConflictDoNothing(), table.id);
|
|
1200
|
+
const stored = await this.read(input, input.id);
|
|
1201
|
+
if (!stored) return {
|
|
1202
|
+
status: "conflict"
|
|
1203
|
+
};
|
|
1204
|
+
if (inserted === 1) return {
|
|
1205
|
+
status: "created",
|
|
1206
|
+
proposal: stored.proposal
|
|
1207
|
+
};
|
|
1208
|
+
return {
|
|
1209
|
+
status: stored.createFingerprint === row.createFingerprint ? "unchanged" : "conflict",
|
|
1210
|
+
proposal: stored.proposal
|
|
1211
|
+
};
|
|
1212
|
+
}
|
|
1213
|
+
createReplacingActionProposal(input) {
|
|
1214
|
+
if (!input.replacementKey) return this.createActionProposal(input);
|
|
1215
|
+
const proposal = initialActionProposal(input, this.clock());
|
|
1216
|
+
return this.transactionSteps((db) => this.replacementSteps(db, input, proposal));
|
|
1217
|
+
}
|
|
1218
|
+
async supersedeActionProposal(scope, id, command) {
|
|
1219
|
+
const replacement = await this.getActionProposal(scope, command.replacementProposalId);
|
|
1220
|
+
if (!replacement) return {
|
|
1221
|
+
status: "not_found"
|
|
1222
|
+
};
|
|
1223
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalSupersession(row, replacement, command, now));
|
|
1224
|
+
}
|
|
1225
|
+
*replacementSteps(db, input, proposal) {
|
|
1226
|
+
const table = this.table;
|
|
1227
|
+
const thread = agentTablesFor(this.dialect).agentThread;
|
|
1228
|
+
if (this.dialect === "sqlite") yield {
|
|
1229
|
+
kind: "write",
|
|
1230
|
+
query: db.update(thread).set({
|
|
1231
|
+
updatedAt: sql2`${thread.updatedAt}`
|
|
1232
|
+
}).where(eq(thread.id, input.threadId))
|
|
1233
|
+
};
|
|
1234
|
+
const threads = yield {
|
|
1235
|
+
kind: "read",
|
|
1236
|
+
query: lockQuery(db.select().from(thread).where(eq(thread.id, input.threadId)).limit(1), this.dialect)
|
|
1237
|
+
};
|
|
1238
|
+
const owner = threads[0];
|
|
1239
|
+
if (!owner || owner.id !== input.threadId || owner.deletedAt || owner.actorRef !== input.actorRef || owner.tenantRef !== input.tenantRef) return {
|
|
1240
|
+
status: "conflict"
|
|
1241
|
+
};
|
|
1242
|
+
const existingRows = yield {
|
|
1243
|
+
kind: "read",
|
|
1244
|
+
query: db.select().from(table).where(eq(table.id, physicalId(input.id))).limit(1)
|
|
1245
|
+
};
|
|
1246
|
+
const existing = existingRows[0];
|
|
1247
|
+
if (existing) {
|
|
1248
|
+
if (existing.proposal.id !== input.id || !actionProposalScopeMatches(existing.proposal, input)) return {
|
|
1249
|
+
status: "conflict"
|
|
1250
|
+
};
|
|
1251
|
+
return {
|
|
1252
|
+
status: existing.createFingerprint === canonicalActionProposalJson3(input) ? "unchanged" : "conflict",
|
|
1253
|
+
proposal: existing.proposal
|
|
1254
|
+
};
|
|
1255
|
+
}
|
|
1256
|
+
const groupKey = replacementGroupKey(input);
|
|
1257
|
+
if (groupKey === null) throw new Error("Missing explicit replacement identity");
|
|
1258
|
+
const pending = yield {
|
|
1259
|
+
kind: "read",
|
|
1260
|
+
query: lockQuery(db.select().from(table).where(and(eq(table.scopeKey, scopeKey(input)), eq(table.replacementGroupKey, groupKey), eq(table.decision, "pending"))), this.dialect)
|
|
1261
|
+
};
|
|
1262
|
+
const row = {
|
|
1263
|
+
id: physicalId(input.id),
|
|
1264
|
+
scopeKey: scopeKey(input),
|
|
1265
|
+
decision: proposal.decision,
|
|
1266
|
+
logicalSort: logicalSort(input.id),
|
|
1267
|
+
createFingerprint: canonicalActionProposalJson3(input),
|
|
1268
|
+
proposal,
|
|
1269
|
+
...discoveryMetadata(proposal),
|
|
1270
|
+
version: 0,
|
|
1271
|
+
createdAt: proposal.createdAt
|
|
1272
|
+
};
|
|
1273
|
+
const insert = db.insert(table);
|
|
1274
|
+
const inserted = yield {
|
|
1275
|
+
kind: "read",
|
|
1276
|
+
query: this.dialect === "mysql" ? insert.ignore().values(row) : insert.values(row).onConflictDoNothing().returning({
|
|
1277
|
+
id: table.id
|
|
1278
|
+
})
|
|
1279
|
+
};
|
|
1280
|
+
const count3 = this.dialect === "mysql" ? mysqlAffectedRows(inserted) : inserted.length;
|
|
1281
|
+
if (count3 !== 1) return {
|
|
1282
|
+
status: "conflict"
|
|
1283
|
+
};
|
|
1284
|
+
for (const old of pending) {
|
|
1285
|
+
const result = transitionActionProposalSupersession(old.proposal, proposal, {
|
|
1286
|
+
replacementProposalId: proposal.id,
|
|
1287
|
+
actorRef: proposal.actorRef,
|
|
1288
|
+
via: "replacement"
|
|
1289
|
+
}, this.clock());
|
|
1290
|
+
if (!result.proposal || canonicalActionProposalJson3(result.proposal) === canonicalActionProposalJson3(old.proposal)) continue;
|
|
1291
|
+
const next = result.proposal;
|
|
1292
|
+
const update = db.update(table).set({
|
|
1293
|
+
proposal: next,
|
|
1294
|
+
decision: next.decision,
|
|
1295
|
+
...discoveryMetadata(next),
|
|
1296
|
+
version: old.version + 1
|
|
1297
|
+
}).where(and(eq(table.id, old.id), eq(table.version, old.version)));
|
|
1298
|
+
const updated = yield {
|
|
1299
|
+
kind: "read",
|
|
1300
|
+
query: this.dialect === "mysql" ? update : update.returning({
|
|
1301
|
+
id: table.id
|
|
1302
|
+
})
|
|
1303
|
+
};
|
|
1304
|
+
if ((this.dialect === "mysql" ? mysqlAffectedRows(updated) : updated.length) !== 1) throw new Error("Replacement lost its locked proposal fence");
|
|
1305
|
+
}
|
|
1306
|
+
return {
|
|
1307
|
+
status: "created",
|
|
1308
|
+
proposal
|
|
1309
|
+
};
|
|
1310
|
+
}
|
|
1311
|
+
async getActionProposal(scope, id) {
|
|
1312
|
+
return (await this.read(scope, id))?.proposal ?? null;
|
|
1313
|
+
}
|
|
1314
|
+
async listActionProposals(scope, query = {}) {
|
|
1315
|
+
const limit = validateActionProposalListQuery(query);
|
|
1316
|
+
const rows = await this.db.select().from(this.table).where(and(eq(this.table.scopeKey, scopeKey(scope)), query.after === void 0 ? void 0 : or(gt(this.table.createdAt, query.after.createdAt), and(eq(this.table.createdAt, query.after.createdAt), gt(this.table.logicalSort, logicalSort(query.after.id)))), query.decision === void 0 ? void 0 : eq(this.table.decision, query.decision))).orderBy(asc(this.table.createdAt), asc(this.table.logicalSort)).limit(limit);
|
|
1317
|
+
return rows.map((row) => row.proposal).filter((proposal) => actionProposalScopeMatches(proposal, scope));
|
|
1318
|
+
}
|
|
1319
|
+
decideActionProposal(scope, id, command) {
|
|
1320
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalDecision(row, command, now));
|
|
1321
|
+
}
|
|
1322
|
+
claimActionProposal(scope, id, command) {
|
|
1323
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalClaim(row, command, now, randomUUID()));
|
|
1324
|
+
}
|
|
1325
|
+
extendActionProposalLease(scope, id, command) {
|
|
1326
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalLease(row, command, now));
|
|
1327
|
+
}
|
|
1328
|
+
settleActionProposal(scope, id, command) {
|
|
1329
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalSettlement(row, command, now));
|
|
1330
|
+
}
|
|
1331
|
+
async claimNextActionProposal(command) {
|
|
1332
|
+
const now = this.clock();
|
|
1333
|
+
validateActionProposalWorkerClaim(command, now);
|
|
1334
|
+
const table = this.table;
|
|
1335
|
+
const candidates = await this.db.select().from(table).where(and(eq(table.discoveryIndexVersion, 1), eq(table.decision, "approved"), or(eq(table.executionStatus, "queued"), and(eq(table.executionStatus, "executing"), lte(table.leaseExpiresAt, now))))).orderBy(asc(table.createdAt), asc(table.logicalSort)).limit(32);
|
|
1336
|
+
for (const candidate of candidates) {
|
|
1337
|
+
const result = await this.claimActionProposal(candidate.proposal, candidate.proposal.id, command);
|
|
1338
|
+
if (result.status === "applied" && result.proposal) return result.proposal;
|
|
1339
|
+
}
|
|
1340
|
+
return null;
|
|
1341
|
+
}
|
|
1342
|
+
async expireActionProposals(command) {
|
|
1343
|
+
const now = this.clock();
|
|
1344
|
+
validateActionProposalExpiryBatch(command, now);
|
|
1345
|
+
const table = this.table;
|
|
1346
|
+
const candidates = await this.db.select().from(table).where(and(eq(table.discoveryIndexVersion, 1), eq(table.decision, "pending"), lte(table.proposalExpiresAt, now))).orderBy(asc(table.createdAt), asc(table.logicalSort)).limit(command.limit);
|
|
1347
|
+
let expired = 0;
|
|
1348
|
+
for (const candidate of candidates) {
|
|
1349
|
+
const result = await this.decideActionProposal(candidate.proposal, candidate.proposal.id, {
|
|
1350
|
+
decision: "expired",
|
|
1351
|
+
actorRef: "system",
|
|
1352
|
+
via: "expiry"
|
|
1353
|
+
});
|
|
1354
|
+
if (result.status === "applied") expired++;
|
|
1355
|
+
}
|
|
1356
|
+
return expired;
|
|
1357
|
+
}
|
|
1358
|
+
async backfillActionProposalDiscoveryIndex(command) {
|
|
1359
|
+
validateActionProposalDiscoveryIndexBatch(command);
|
|
1360
|
+
const table = this.table;
|
|
1361
|
+
const candidates = await this.db.select().from(table).where(eq(table.discoveryIndexVersion, 0)).orderBy(asc(table.createdAt), asc(table.logicalSort)).limit(command.limit);
|
|
1362
|
+
let changed = 0;
|
|
1363
|
+
for (const row of candidates) {
|
|
1364
|
+
changed += await affectedRows(this.dialect, this.db.update(table).set({
|
|
1365
|
+
...discoveryMetadata(row.proposal),
|
|
1366
|
+
version: row.version + 1
|
|
1367
|
+
}).where(and(eq(table.id, row.id), eq(table.scopeKey, row.scopeKey), eq(table.version, row.version), eq(table.discoveryIndexVersion, 0))), table.id);
|
|
1368
|
+
}
|
|
1369
|
+
return changed;
|
|
1370
|
+
}
|
|
1371
|
+
async rememberedActionProposalApprovals(scope) {
|
|
1372
|
+
const table = this.table;
|
|
1373
|
+
const rows = await this.db.select().from(table).where(and(eq(table.scopeKey, scopeKey(scope)), eq(table.decision, "approved"), or(eq(table.executionStatus, "succeeded"), eq(table.executionStatus, "failed"))));
|
|
1374
|
+
return [
|
|
1375
|
+
...new Set(rows.filter((row) => actionProposalScopeMatches(row.proposal, scope) && row.proposal.decisionAudit?.remember === true).map((row) => row.proposal.toolName))
|
|
1376
|
+
];
|
|
1377
|
+
}
|
|
1378
|
+
async getThreadActionProposalScope(threadId) {
|
|
1379
|
+
const thread = agentTablesFor(this.dialect).agentThread;
|
|
1380
|
+
const [row] = await this.db.select().from(thread).where(and(eq(thread.id, threadId), isNull(thread.deletedAt))).limit(1);
|
|
1381
|
+
return row?.id === threadId ? {
|
|
1382
|
+
actorRef: row.actorRef,
|
|
1383
|
+
tenantRef: row.tenantRef,
|
|
1384
|
+
threadId: row.id
|
|
1385
|
+
} : null;
|
|
1386
|
+
}
|
|
1387
|
+
async claimNextActionProposalOutcome(command) {
|
|
1388
|
+
const now = this.clock();
|
|
1389
|
+
validateActionProposalWorkerClaim(command, now);
|
|
1390
|
+
const table = this.table;
|
|
1391
|
+
const candidates = await this.db.select().from(table).where(and(eq(table.deliveryStatus, "pending"), or(isNull(table.deliveryLeaseExpiresAt), lte(table.deliveryLeaseExpiresAt, now)))).orderBy(asc(table.createdAt), asc(table.logicalSort)).limit(32);
|
|
1392
|
+
for (const row of candidates) {
|
|
1393
|
+
const result = await this.mutate(row.proposal, row.proposal.id, (proposal, time) => {
|
|
1394
|
+
const claimed2 = claimActionProposalOutcome(proposal, command, time, randomUUID());
|
|
1395
|
+
return claimed2 ? {
|
|
1396
|
+
status: "applied",
|
|
1397
|
+
proposal: claimed2
|
|
1398
|
+
} : {
|
|
1399
|
+
status: "conflict",
|
|
1400
|
+
proposal
|
|
1401
|
+
};
|
|
1402
|
+
});
|
|
1403
|
+
const claimed = result.proposal;
|
|
1404
|
+
if (result.status === "applied" && claimed?.outcome && claimed.outcomeDelivery?.lease) {
|
|
1405
|
+
return {
|
|
1406
|
+
outcome: claimed.outcome,
|
|
1407
|
+
lease: {
|
|
1408
|
+
outcomeId: claimed.outcome.id,
|
|
1409
|
+
token: claimed.outcomeDelivery.lease.token,
|
|
1410
|
+
generation: claimed.outcomeDelivery.generation
|
|
1411
|
+
}
|
|
1412
|
+
};
|
|
1413
|
+
}
|
|
1414
|
+
}
|
|
1415
|
+
return null;
|
|
1416
|
+
}
|
|
1417
|
+
async admitActionProposalOutcome(command) {
|
|
1418
|
+
return this.transactionSteps((db) => this.admissionSteps(db, command));
|
|
1419
|
+
}
|
|
1420
|
+
async transactionSteps(factory) {
|
|
1421
|
+
if (!this.actionProposalAdmissionSupported) throw new Error("Independent actions require a certified transactional Drizzle driver (better-sqlite3, node-postgres, mysql2 or libsql)");
|
|
1422
|
+
if (this.synchronousSqlite) {
|
|
1423
|
+
const database2 = this.rawDb;
|
|
1424
|
+
return database2.transaction((tx) => runSync(factory(asBuilder(tx))), {
|
|
1425
|
+
behavior: "immediate"
|
|
1426
|
+
});
|
|
1427
|
+
}
|
|
1428
|
+
const database = this.rawDb;
|
|
1429
|
+
return database.transaction(async (tx) => runAsync(factory(asBuilder(tx))));
|
|
1430
|
+
}
|
|
1431
|
+
*admissionSteps(db, command) {
|
|
1432
|
+
if (typeof command.outcomeId !== "string" || !command.outcomeId || typeof command.token !== "string" || !command.token || !Number.isSafeInteger(command.generation) || command.generation < 1) throw new TypeError("Invalid outcome fence");
|
|
1433
|
+
const table = this.table;
|
|
1434
|
+
const tables = agentTablesFor(this.dialect);
|
|
1435
|
+
if (this.dialect === "sqlite") yield {
|
|
1436
|
+
kind: "write",
|
|
1437
|
+
query: db.update(table).set({
|
|
1438
|
+
version: sql2`${table.version}`
|
|
1439
|
+
}).where(eq(table.outcomeIdKey, physicalId(command.outcomeId)))
|
|
1440
|
+
};
|
|
1441
|
+
const query = db.select().from(table).where(eq(table.outcomeIdKey, physicalId(command.outcomeId))).limit(1);
|
|
1442
|
+
const rows = yield {
|
|
1443
|
+
kind: "read",
|
|
1444
|
+
query: lockQuery(query, this.dialect)
|
|
1445
|
+
};
|
|
1446
|
+
const row = rows[0];
|
|
1447
|
+
if (!row || row.proposal.outcome?.id !== command.outcomeId) return {
|
|
1448
|
+
status: "not_found"
|
|
1449
|
+
};
|
|
1450
|
+
const proposal = row.proposal;
|
|
1451
|
+
const outcome = proposal.outcome;
|
|
1452
|
+
const delivery = proposal.outcomeDelivery;
|
|
1453
|
+
if (!outcome || !delivery) return {
|
|
1454
|
+
status: "not_found"
|
|
1455
|
+
};
|
|
1456
|
+
if (proposal.outcomeDelivery?.status === "admitted") return {
|
|
1457
|
+
status: "unchanged",
|
|
1458
|
+
...proposal.outcomeDelivery.messageId !== void 0 ? {
|
|
1459
|
+
messageId: proposal.outcomeDelivery.messageId
|
|
1460
|
+
} : {}
|
|
1461
|
+
};
|
|
1462
|
+
if (proposal.outcomeDelivery?.status === "discarded") return {
|
|
1463
|
+
status: "discarded"
|
|
1464
|
+
};
|
|
1465
|
+
if (!actionProposalOutcomeFenceValid(proposal, command, this.clock())) return {
|
|
1466
|
+
status: "conflict"
|
|
1467
|
+
};
|
|
1468
|
+
const threadQuery = db.select().from(tables.agentThread).where(eq(tables.agentThread.id, proposal.threadId)).limit(1);
|
|
1469
|
+
const threads = yield {
|
|
1470
|
+
kind: "read",
|
|
1471
|
+
query: lockQuery(threadQuery, this.dialect)
|
|
1472
|
+
};
|
|
1473
|
+
const thread = threads[0];
|
|
1474
|
+
const now = this.clock();
|
|
1475
|
+
if (!actionProposalOutcomeFenceValid(proposal, command, now)) return {
|
|
1476
|
+
status: "conflict"
|
|
1477
|
+
};
|
|
1478
|
+
if (!thread || thread.id !== proposal.threadId || thread.deletedAt || thread.actorRef !== proposal.actorRef || thread.tenantRef !== proposal.tenantRef) {
|
|
1479
|
+
const discarded = {
|
|
1480
|
+
...proposal,
|
|
1481
|
+
outcomeDelivery: {
|
|
1482
|
+
...delivery,
|
|
1483
|
+
status: "discarded",
|
|
1484
|
+
lease: null
|
|
1485
|
+
},
|
|
1486
|
+
updatedAt: now
|
|
1487
|
+
};
|
|
1488
|
+
yield {
|
|
1489
|
+
kind: "write",
|
|
1490
|
+
query: db.update(table).set({
|
|
1491
|
+
proposal: discarded,
|
|
1492
|
+
...discoveryMetadata(discarded),
|
|
1493
|
+
version: row.version + 1
|
|
1494
|
+
}).where(and(eq(table.id, row.id), eq(table.version, row.version)))
|
|
1495
|
+
};
|
|
1496
|
+
return {
|
|
1497
|
+
status: "discarded"
|
|
1498
|
+
};
|
|
1499
|
+
}
|
|
1500
|
+
if (thread.activeStreamId !== null) return {
|
|
1501
|
+
status: "busy"
|
|
1502
|
+
};
|
|
1503
|
+
const seqRows = yield {
|
|
1504
|
+
kind: "read",
|
|
1505
|
+
query: db.select({
|
|
1506
|
+
last: max(tables.agentMessage.seq)
|
|
1507
|
+
}).from(tables.agentMessage).where(eq(tables.agentMessage.threadId, thread.id))
|
|
1508
|
+
};
|
|
1509
|
+
const messageId = physicalId(command.outcomeId);
|
|
1510
|
+
yield {
|
|
1511
|
+
kind: "write",
|
|
1512
|
+
query: db.insert(tables.agentMessage).values({
|
|
1513
|
+
id: messageId,
|
|
1514
|
+
threadId: thread.id,
|
|
1515
|
+
role: "assistant",
|
|
1516
|
+
content: actionProposalOutcomeText(outcome),
|
|
1517
|
+
actionProposalOutcome: canonicalActionProposalJson3(outcome),
|
|
1518
|
+
ui: null,
|
|
1519
|
+
seq: Number(seqRows[0]?.last ?? 0) + 1,
|
|
1520
|
+
createdAt: new Date(now)
|
|
1521
|
+
})
|
|
1522
|
+
};
|
|
1523
|
+
yield {
|
|
1524
|
+
kind: "write",
|
|
1525
|
+
query: db.update(tables.agentThread).set({
|
|
1526
|
+
updatedAt: new Date(now)
|
|
1527
|
+
}).where(eq(tables.agentThread.id, thread.id))
|
|
1528
|
+
};
|
|
1529
|
+
const admitted = {
|
|
1530
|
+
...proposal,
|
|
1531
|
+
outcomeDelivery: {
|
|
1532
|
+
...delivery,
|
|
1533
|
+
status: "admitted",
|
|
1534
|
+
lease: null,
|
|
1535
|
+
messageId
|
|
1536
|
+
},
|
|
1537
|
+
updatedAt: now
|
|
1538
|
+
};
|
|
1539
|
+
const update = db.update(table).set({
|
|
1540
|
+
proposal: admitted,
|
|
1541
|
+
...discoveryMetadata(admitted),
|
|
1542
|
+
version: row.version + 1
|
|
1543
|
+
}).where(and(eq(table.id, row.id), eq(table.version, row.version)));
|
|
1544
|
+
const changed = yield {
|
|
1545
|
+
kind: "read",
|
|
1546
|
+
query: this.dialect === "mysql" ? update : update.returning({
|
|
1547
|
+
id: table.id
|
|
1548
|
+
})
|
|
1549
|
+
};
|
|
1550
|
+
const count3 = this.dialect === "mysql" ? mysqlAffectedRows(changed) : changed.length;
|
|
1551
|
+
if (count3 !== 1) throw new Error("Outcome admission lost its locked proposal fence");
|
|
1552
|
+
return {
|
|
1553
|
+
status: "applied",
|
|
1554
|
+
messageId
|
|
1555
|
+
};
|
|
1556
|
+
}
|
|
1557
|
+
async read(scope, id) {
|
|
1558
|
+
const [row] = await this.db.select().from(this.table).where(and(eq(this.table.id, physicalId(id)), eq(this.table.scopeKey, scopeKey(scope)))).limit(1);
|
|
1559
|
+
return row && row.proposal.id === id && actionProposalScopeMatches(row.proposal, scope) ? row : void 0;
|
|
1560
|
+
}
|
|
1561
|
+
async mutate(scope, id, transition) {
|
|
1562
|
+
for (let attempt = 0; attempt < 32; attempt++) {
|
|
1563
|
+
const row2 = await this.read(scope, id);
|
|
1564
|
+
if (!row2) return {
|
|
1565
|
+
status: "not_found"
|
|
1566
|
+
};
|
|
1567
|
+
const result = transition(row2.proposal, this.clock());
|
|
1568
|
+
if (!result.proposal || canonicalActionProposalJson3(result.proposal) === canonicalActionProposalJson3(row2.proposal)) return result;
|
|
1569
|
+
const changed = await affectedRows(this.dialect, this.db.update(this.table).set({
|
|
1570
|
+
proposal: result.proposal,
|
|
1571
|
+
decision: result.proposal.decision,
|
|
1572
|
+
...discoveryMetadata(result.proposal),
|
|
1573
|
+
version: row2.version + 1
|
|
1574
|
+
}).where(and(eq(this.table.id, physicalId(id)), eq(this.table.scopeKey, scopeKey(scope)), eq(this.table.version, row2.version))), this.table.id);
|
|
1575
|
+
if (changed === 1) return result;
|
|
1576
|
+
}
|
|
1577
|
+
const row = await this.read(scope, id);
|
|
1578
|
+
return row ? {
|
|
1579
|
+
status: "conflict",
|
|
1580
|
+
proposal: row.proposal
|
|
1581
|
+
} : {
|
|
1582
|
+
status: "not_found"
|
|
1583
|
+
};
|
|
1584
|
+
}
|
|
597
1585
|
};
|
|
1586
|
+
function scopeKey(scope) {
|
|
1587
|
+
return createHash("sha256").update(canonicalActionProposalJson3([
|
|
1588
|
+
scope.tenantRef,
|
|
1589
|
+
scope.actorRef,
|
|
1590
|
+
scope.threadId
|
|
1591
|
+
])).digest("hex");
|
|
1592
|
+
}
|
|
1593
|
+
__name(scopeKey, "scopeKey");
|
|
1594
|
+
function physicalId(id) {
|
|
1595
|
+
return createHash("sha256").update(canonicalActionProposalJson3(id)).digest("hex");
|
|
1596
|
+
}
|
|
1597
|
+
__name(physicalId, "physicalId");
|
|
1598
|
+
function logicalSort(id) {
|
|
1599
|
+
let sort = "";
|
|
1600
|
+
for (let index4 = 0; index4 < id.length; index4++) sort += id.charCodeAt(index4).toString(16).padStart(4, "0");
|
|
1601
|
+
return sort;
|
|
1602
|
+
}
|
|
1603
|
+
__name(logicalSort, "logicalSort");
|
|
1604
|
+
function discoveryMetadata(proposal) {
|
|
1605
|
+
return {
|
|
1606
|
+
replacementGroupKey: replacementGroupKey(proposal),
|
|
1607
|
+
deliveryStatus: proposal.outcomeDelivery?.status ?? null,
|
|
1608
|
+
deliveryLeaseExpiresAt: proposal.outcomeDelivery?.lease?.expiresAt ?? null,
|
|
1609
|
+
outcomeIdKey: proposal.outcome ? physicalId(proposal.outcome.id) : null,
|
|
1610
|
+
executionStatus: proposal.execution?.status ?? null,
|
|
1611
|
+
leaseExpiresAt: proposal.execution?.lease?.expiresAt ?? null,
|
|
1612
|
+
proposalExpiresAt: proposal.expiresAt,
|
|
1613
|
+
discoveryIndexVersion: 1
|
|
1614
|
+
};
|
|
1615
|
+
}
|
|
1616
|
+
__name(discoveryMetadata, "discoveryMetadata");
|
|
1617
|
+
function lockQuery(query, dialect) {
|
|
1618
|
+
return dialect === "sqlite" ? query : query.for("update");
|
|
1619
|
+
}
|
|
1620
|
+
__name(lockQuery, "lockQuery");
|
|
1621
|
+
function runSync(steps) {
|
|
1622
|
+
let next = steps.next();
|
|
1623
|
+
while (!next.done) {
|
|
1624
|
+
const { kind, query } = next.value;
|
|
1625
|
+
const statement = query;
|
|
1626
|
+
next = steps.next(kind === "read" ? statement.all() : statement.run());
|
|
1627
|
+
}
|
|
1628
|
+
return next.value;
|
|
1629
|
+
}
|
|
1630
|
+
__name(runSync, "runSync");
|
|
1631
|
+
async function runAsync(steps) {
|
|
1632
|
+
let next = steps.next();
|
|
1633
|
+
while (!next.done) next = steps.next(await next.value.query);
|
|
1634
|
+
return next.value;
|
|
1635
|
+
}
|
|
1636
|
+
__name(runAsync, "runAsync");
|
|
1637
|
+
function replacementGroupKey(proposal) {
|
|
1638
|
+
return proposal.replacementKey ? physicalId(canonicalActionProposalJson3([
|
|
1639
|
+
proposal.toolName,
|
|
1640
|
+
proposal.replacementKey
|
|
1641
|
+
])) : null;
|
|
1642
|
+
}
|
|
1643
|
+
__name(replacementGroupKey, "replacementGroupKey");
|
|
1644
|
+
|
|
1645
|
+
// src/drizzle-agent-store.ts
|
|
1646
|
+
function turnMessageColumns(message) {
|
|
1647
|
+
return {
|
|
1648
|
+
id: message.id,
|
|
1649
|
+
role: message.role,
|
|
1650
|
+
content: message.content,
|
|
1651
|
+
agentName: message.agentName,
|
|
1652
|
+
toolCalls: message.toolCalls,
|
|
1653
|
+
toolResults: message.toolResults,
|
|
1654
|
+
attachments: message.attachments,
|
|
1655
|
+
createdAt: message.createdAt
|
|
1656
|
+
};
|
|
1657
|
+
}
|
|
1658
|
+
__name(turnMessageColumns, "turnMessageColumns");
|
|
598
1659
|
var DrizzleAgentStore = class {
|
|
599
1660
|
static {
|
|
600
1661
|
__name(this, "DrizzleAgentStore");
|
|
601
1662
|
}
|
|
602
1663
|
db;
|
|
603
|
-
|
|
604
|
-
|
|
1664
|
+
dialect;
|
|
1665
|
+
t;
|
|
1666
|
+
proposals;
|
|
1667
|
+
constructor(db, options = {}) {
|
|
1668
|
+
this.proposals = new DrizzleActionProposalStore(db, options);
|
|
1669
|
+
this.dialect = agentDialectOf(db);
|
|
1670
|
+
this.t = agentTablesFor(this.dialect);
|
|
1671
|
+
this.db = asBuilder(db);
|
|
1672
|
+
}
|
|
1673
|
+
createActionProposal(...args) {
|
|
1674
|
+
return this.proposals.createActionProposal(...args);
|
|
1675
|
+
}
|
|
1676
|
+
getActionProposal(...args) {
|
|
1677
|
+
return this.proposals.getActionProposal(...args);
|
|
1678
|
+
}
|
|
1679
|
+
listActionProposals(...args) {
|
|
1680
|
+
return this.proposals.listActionProposals(...args);
|
|
1681
|
+
}
|
|
1682
|
+
decideActionProposal(...args) {
|
|
1683
|
+
return this.proposals.decideActionProposal(...args);
|
|
1684
|
+
}
|
|
1685
|
+
claimActionProposal(...args) {
|
|
1686
|
+
return this.proposals.claimActionProposal(...args);
|
|
1687
|
+
}
|
|
1688
|
+
extendActionProposalLease(...args) {
|
|
1689
|
+
return this.proposals.extendActionProposalLease(...args);
|
|
1690
|
+
}
|
|
1691
|
+
claimNextActionProposal(...args) {
|
|
1692
|
+
return this.proposals.claimNextActionProposal(...args);
|
|
1693
|
+
}
|
|
1694
|
+
expireActionProposals(...args) {
|
|
1695
|
+
return this.proposals.expireActionProposals(...args);
|
|
1696
|
+
}
|
|
1697
|
+
backfillActionProposalDiscoveryIndex(command) {
|
|
1698
|
+
return this.proposals.backfillActionProposalDiscoveryIndex(command);
|
|
1699
|
+
}
|
|
1700
|
+
settleActionProposal(...args) {
|
|
1701
|
+
return this.proposals.settleActionProposal(...args);
|
|
1702
|
+
}
|
|
1703
|
+
createReplacingActionProposal(...args) {
|
|
1704
|
+
return this.proposals.createReplacingActionProposal(...args);
|
|
1705
|
+
}
|
|
1706
|
+
supersedeActionProposal(...args) {
|
|
1707
|
+
return this.proposals.supersedeActionProposal(...args);
|
|
1708
|
+
}
|
|
1709
|
+
get actionProposalAdmissionSupported() {
|
|
1710
|
+
return this.proposals.actionProposalAdmissionSupported;
|
|
1711
|
+
}
|
|
1712
|
+
getThreadActionProposalScope(threadId) {
|
|
1713
|
+
return this.proposals.getThreadActionProposalScope(threadId);
|
|
1714
|
+
}
|
|
1715
|
+
claimNextActionProposalOutcome(...args) {
|
|
1716
|
+
return this.proposals.claimNextActionProposalOutcome(...args);
|
|
1717
|
+
}
|
|
1718
|
+
admitActionProposalOutcome(...args) {
|
|
1719
|
+
return this.proposals.admitActionProposalOutcome(...args);
|
|
605
1720
|
}
|
|
606
1721
|
async createThread(input) {
|
|
607
1722
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -620,15 +1735,15 @@ var DrizzleAgentStore = class {
|
|
|
620
1735
|
updatedAt: now,
|
|
621
1736
|
deletedAt: null
|
|
622
1737
|
};
|
|
623
|
-
await this.db.insert(agentThread).values(thread);
|
|
1738
|
+
await this.db.insert(this.t.agentThread).values(thread);
|
|
624
1739
|
return this.toSummary(thread);
|
|
625
1740
|
}
|
|
626
1741
|
async getThread(threadId) {
|
|
627
|
-
const [thread] = await this.db.select().from(agentThread).where(
|
|
1742
|
+
const [thread] = await this.db.select().from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
628
1743
|
if (thread === void 0) {
|
|
629
1744
|
return null;
|
|
630
1745
|
}
|
|
631
|
-
const messages = await this.db.select().from(agentMessage).where(
|
|
1746
|
+
const messages = await this.db.select().from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId)).orderBy(...this.messageOrder());
|
|
632
1747
|
const last = messages[messages.length - 1];
|
|
633
1748
|
const approvals = await this.approvalsFor(messages.map((message) => message.id));
|
|
634
1749
|
return {
|
|
@@ -661,16 +1776,16 @@ var DrizzleAgentStore = class {
|
|
|
661
1776
|
*/
|
|
662
1777
|
async loadThreadForTurn(query) {
|
|
663
1778
|
const [thread] = await this.db.select({
|
|
664
|
-
title: agentThread.title,
|
|
665
|
-
defaultAgent: agentThread.defaultAgent
|
|
666
|
-
}).from(agentThread).where(
|
|
1779
|
+
title: this.t.agentThread.title,
|
|
1780
|
+
defaultAgent: this.t.agentThread.defaultAgent
|
|
1781
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, query.threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
667
1782
|
if (thread === void 0) {
|
|
668
1783
|
return null;
|
|
669
1784
|
}
|
|
670
1785
|
const messages = await this.loadTurnWindow(query.threadId, query.messageLimit);
|
|
671
1786
|
const [answered] = await this.db.select({
|
|
672
|
-
id: agentMessage.id
|
|
673
|
-
}).from(agentMessage).where(
|
|
1787
|
+
id: this.t.agentMessage.id
|
|
1788
|
+
}).from(this.t.agentMessage).where(and2(eq2(this.t.agentMessage.threadId, query.threadId), eq2(this.t.agentMessage.role, "assistant"))).limit(1);
|
|
674
1789
|
return {
|
|
675
1790
|
title: thread.title,
|
|
676
1791
|
defaultAgent: thread.defaultAgent,
|
|
@@ -686,30 +1801,30 @@ var DrizzleAgentStore = class {
|
|
|
686
1801
|
if (limit !== void 0 && limit <= 0) {
|
|
687
1802
|
return [];
|
|
688
1803
|
}
|
|
689
|
-
const window = this.db.select(
|
|
1804
|
+
const window = this.db.select(turnMessageColumns(this.t.agentMessage)).from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId)).orderBy(...this.messageOrderNewestFirst());
|
|
690
1805
|
const rows = limit === void 0 ? await window : await window.limit(limit);
|
|
691
1806
|
return rows.reverse().map((row) => this.toStoredMessage(row));
|
|
692
1807
|
}
|
|
693
1808
|
async listThreads(actorRef, limit = 50) {
|
|
694
|
-
const threads = await this.db.select().from(agentThread).where(
|
|
1809
|
+
const threads = await this.db.select().from(this.t.agentThread).where(and2(eq2(this.t.agentThread.actorRef, actorRef), eq2(this.t.agentThread.transient, false), isNull2(this.t.agentThread.deletedAt))).orderBy(desc(this.t.agentThread.updatedAt)).limit(limit);
|
|
695
1810
|
const summaries = [];
|
|
696
1811
|
for (const thread of threads) {
|
|
697
|
-
const [last] = await this.db.select().from(agentMessage).where(
|
|
1812
|
+
const [last] = await this.db.select().from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, thread.id)).orderBy(...this.messageOrderNewestFirst()).limit(1);
|
|
698
1813
|
summaries.push(this.toSummary(thread, last?.content));
|
|
699
1814
|
}
|
|
700
1815
|
return summaries;
|
|
701
1816
|
}
|
|
702
1817
|
async softDeleteThread(threadId) {
|
|
703
|
-
await this.db.update(agentThread).set({
|
|
1818
|
+
await this.db.update(this.t.agentThread).set({
|
|
704
1819
|
deletedAt: /* @__PURE__ */ new Date()
|
|
705
|
-
}).where(
|
|
1820
|
+
}).where(eq2(this.t.agentThread.id, threadId));
|
|
706
1821
|
}
|
|
707
1822
|
async forkThread(threadId, fromMessageId) {
|
|
708
|
-
const [source] = await this.db.select().from(agentThread).where(
|
|
1823
|
+
const [source] = await this.db.select().from(this.t.agentThread).where(eq2(this.t.agentThread.id, threadId));
|
|
709
1824
|
if (source === void 0) {
|
|
710
1825
|
throw new Error(`thread ${threadId} not found`);
|
|
711
1826
|
}
|
|
712
|
-
const messages = await this.db.select().from(agentMessage).where(
|
|
1827
|
+
const messages = await this.db.select().from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId)).orderBy(...this.messageOrder());
|
|
713
1828
|
const cutoff = messages.findIndex((message) => message.id === fromMessageId);
|
|
714
1829
|
const kept = cutoff >= 0 ? messages.slice(0, cutoff + 1) : messages;
|
|
715
1830
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -729,10 +1844,12 @@ var DrizzleAgentStore = class {
|
|
|
729
1844
|
updatedAt: now,
|
|
730
1845
|
deletedAt: null
|
|
731
1846
|
};
|
|
732
|
-
await this.db.insert(agentThread).values(fork);
|
|
1847
|
+
await this.db.insert(this.t.agentThread).values(fork);
|
|
733
1848
|
if (kept.length > 0) {
|
|
734
|
-
await this.db.insert(agentMessage).values(kept.map((message) => ({
|
|
1849
|
+
await this.db.insert(this.t.agentMessage).values(kept.map((message, index4) => ({
|
|
735
1850
|
id: crypto.randomUUID(),
|
|
1851
|
+
// Numbered afresh in the order just read, so the copy reads back in the original's order.
|
|
1852
|
+
seq: index4 + 1,
|
|
736
1853
|
threadId: fork.id,
|
|
737
1854
|
role: message.role,
|
|
738
1855
|
content: message.content,
|
|
@@ -750,6 +1867,7 @@ var DrizzleAgentStore = class {
|
|
|
750
1867
|
reasoning: message.reasoning,
|
|
751
1868
|
reasoningMs: message.reasoningMs,
|
|
752
1869
|
ui: message.ui,
|
|
1870
|
+
actionProposalOutcome: message.actionProposalOutcome,
|
|
753
1871
|
createdAt: message.createdAt
|
|
754
1872
|
})));
|
|
755
1873
|
}
|
|
@@ -757,21 +1875,21 @@ var DrizzleAgentStore = class {
|
|
|
757
1875
|
}
|
|
758
1876
|
async ownerOfThread(threadId) {
|
|
759
1877
|
const [thread] = await this.db.select({
|
|
760
|
-
actorRef: agentThread.actorRef
|
|
761
|
-
}).from(agentThread).where(
|
|
1878
|
+
actorRef: this.t.agentThread.actorRef
|
|
1879
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
762
1880
|
return thread?.actorRef ?? null;
|
|
763
1881
|
}
|
|
764
1882
|
async ownerOfToolCall(toolCallId) {
|
|
765
1883
|
const [row] = await this.db.select({
|
|
766
|
-
actorRef: agentThread.actorRef
|
|
767
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
1884
|
+
actorRef: this.t.agentThread.actorRef
|
|
1885
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq2(this.t.agentToolCall.messageId, this.t.agentMessage.id)).innerJoin(this.t.agentThread, eq2(this.t.agentMessage.threadId, this.t.agentThread.id)).where(eq2(this.t.agentToolCall.id, toolCallId));
|
|
768
1886
|
return row?.actorRef ?? null;
|
|
769
1887
|
}
|
|
770
1888
|
async runForToolCall(toolCallId) {
|
|
771
1889
|
const [row] = await this.db.select({
|
|
772
|
-
runId: agentToolCall.runId,
|
|
773
|
-
activeStreamId: agentThread.activeStreamId
|
|
774
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
1890
|
+
runId: this.t.agentToolCall.runId,
|
|
1891
|
+
activeStreamId: this.t.agentThread.activeStreamId
|
|
1892
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq2(this.t.agentToolCall.messageId, this.t.agentMessage.id)).innerJoin(this.t.agentThread, eq2(this.t.agentMessage.threadId, this.t.agentThread.id)).where(eq2(this.t.agentToolCall.id, toolCallId));
|
|
775
1893
|
return row?.runId ?? row?.activeStreamId ?? null;
|
|
776
1894
|
}
|
|
777
1895
|
/**
|
|
@@ -785,16 +1903,17 @@ var DrizzleAgentStore = class {
|
|
|
785
1903
|
return byMessage;
|
|
786
1904
|
}
|
|
787
1905
|
const rows = await this.db.select({
|
|
788
|
-
id: agentToolCall.id,
|
|
789
|
-
messageId: agentToolCall.messageId,
|
|
790
|
-
status: agentToolCall.status,
|
|
791
|
-
approver: agentToolCall.approver,
|
|
792
|
-
|
|
793
|
-
|
|
794
|
-
|
|
795
|
-
|
|
796
|
-
|
|
797
|
-
|
|
1906
|
+
id: this.t.agentToolCall.id,
|
|
1907
|
+
messageId: this.t.agentToolCall.messageId,
|
|
1908
|
+
status: this.t.agentToolCall.status,
|
|
1909
|
+
approver: this.t.agentToolCall.approver,
|
|
1910
|
+
confirmation: this.t.agentToolCall.confirmation,
|
|
1911
|
+
expiresAt: this.t.agentToolCall.expiresAt,
|
|
1912
|
+
remember: this.t.agentToolCall.remember,
|
|
1913
|
+
executedByRef: this.t.agentToolCall.executedByRef,
|
|
1914
|
+
decidedVia: this.t.agentToolCall.decidedVia,
|
|
1915
|
+
error: this.t.agentToolCall.error
|
|
1916
|
+
}).from(this.t.agentToolCall).where(and2(inArray(this.t.agentToolCall.messageId, messageIds), isNotNull(this.t.agentToolCall.approver))).orderBy(asc2(this.t.agentToolCall.createdAt), asc2(this.t.agentToolCall.id));
|
|
798
1917
|
for (const row of rows) {
|
|
799
1918
|
const approval = toolCallApprovalFromRow({
|
|
800
1919
|
...row,
|
|
@@ -812,22 +1931,29 @@ var DrizzleAgentStore = class {
|
|
|
812
1931
|
/** Tools whose approval someone asked to remember in this thread. */
|
|
813
1932
|
async rememberedApprovals(threadId) {
|
|
814
1933
|
const rows = await this.db.selectDistinct({
|
|
815
|
-
toolName: agentToolCall.toolName
|
|
816
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
817
|
-
|
|
1934
|
+
toolName: this.t.agentToolCall.toolName
|
|
1935
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq2(this.t.agentToolCall.messageId, this.t.agentMessage.id)).where(and2(eq2(this.t.agentMessage.threadId, threadId), eq2(this.t.agentToolCall.remember, true)));
|
|
1936
|
+
const scope = await this.getThreadActionProposalScope(threadId);
|
|
1937
|
+
const proposalNames = scope ? await this.proposals.rememberedActionProposalApprovals(scope) : [];
|
|
1938
|
+
return [
|
|
1939
|
+
.../* @__PURE__ */ new Set([
|
|
1940
|
+
...rows.map((row) => row.toolName),
|
|
1941
|
+
...proposalNames
|
|
1942
|
+
])
|
|
1943
|
+
];
|
|
818
1944
|
}
|
|
819
1945
|
async toolCallInput(toolCallId) {
|
|
820
1946
|
const [row] = await this.db.select({
|
|
821
|
-
input: agentToolCall.input
|
|
822
|
-
}).from(agentToolCall).where(
|
|
1947
|
+
input: this.t.agentToolCall.input
|
|
1948
|
+
}).from(this.t.agentToolCall).where(eq2(this.t.agentToolCall.id, toolCallId));
|
|
823
1949
|
return row?.input ?? null;
|
|
824
1950
|
}
|
|
825
1951
|
async toolCallApproval(toolCallId) {
|
|
826
1952
|
const [row] = await this.db.select({
|
|
827
|
-
status: agentToolCall.status,
|
|
828
|
-
approver: agentToolCall.approver,
|
|
829
|
-
expiresAt: agentToolCall.expiresAt
|
|
830
|
-
}).from(agentToolCall).where(
|
|
1953
|
+
status: this.t.agentToolCall.status,
|
|
1954
|
+
approver: this.t.agentToolCall.approver,
|
|
1955
|
+
expiresAt: this.t.agentToolCall.expiresAt
|
|
1956
|
+
}).from(this.t.agentToolCall).where(eq2(this.t.agentToolCall.id, toolCallId));
|
|
831
1957
|
if (row === void 0) {
|
|
832
1958
|
return null;
|
|
833
1959
|
}
|
|
@@ -839,27 +1965,67 @@ var DrizzleAgentStore = class {
|
|
|
839
1965
|
}
|
|
840
1966
|
async ownerOfActiveStream(runId) {
|
|
841
1967
|
const [thread] = await this.db.select({
|
|
842
|
-
actorRef: agentThread.actorRef
|
|
843
|
-
}).from(agentThread).where(
|
|
1968
|
+
actorRef: this.t.agentThread.actorRef
|
|
1969
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.activeStreamId, runId), isNull2(this.t.agentThread.deletedAt)));
|
|
844
1970
|
return thread?.actorRef ?? null;
|
|
845
1971
|
}
|
|
846
1972
|
async setTitle(threadId, title) {
|
|
847
|
-
await this.db.update(agentThread).set({
|
|
1973
|
+
await this.db.update(this.t.agentThread).set({
|
|
848
1974
|
title,
|
|
849
1975
|
updatedAt: /* @__PURE__ */ new Date()
|
|
850
|
-
}).where(
|
|
1976
|
+
}).where(eq2(this.t.agentThread.id, threadId));
|
|
851
1977
|
}
|
|
852
1978
|
async promoteThread(threadId) {
|
|
853
|
-
await this.db.update(agentThread).set({
|
|
1979
|
+
await this.db.update(this.t.agentThread).set({
|
|
854
1980
|
transient: false,
|
|
855
1981
|
updatedAt: /* @__PURE__ */ new Date()
|
|
856
|
-
}).where(
|
|
1982
|
+
}).where(and2(eq2(this.t.agentThread.id, threadId), eq2(this.t.agentThread.transient, true)));
|
|
1983
|
+
}
|
|
1984
|
+
/** Who holds the thread's stream right now, deleted or not. */
|
|
1985
|
+
async activeHolder(threadId) {
|
|
1986
|
+
const [thread] = await this.db.select({
|
|
1987
|
+
activeStreamId: this.t.agentThread.activeStreamId
|
|
1988
|
+
}).from(this.t.agentThread).where(eq2(this.t.agentThread.id, threadId));
|
|
1989
|
+
return thread?.activeStreamId ?? null;
|
|
1990
|
+
}
|
|
1991
|
+
/**
|
|
1992
|
+
* A thread's messages in the order they were appended: by `seq`, which append assigns. A row from
|
|
1993
|
+
* before `seq` existed has none and counts as 0 — first, since every such row is older than every
|
|
1994
|
+
* numbered one — and those order among themselves by `created_at`, then `id`, as they always did.
|
|
1995
|
+
* `coalesce` rather than `nulls first`, which MySQL cannot spell and Postgres defaults the other way.
|
|
1996
|
+
*/
|
|
1997
|
+
messageOrder() {
|
|
1998
|
+
const message = this.t.agentMessage;
|
|
1999
|
+
return [
|
|
2000
|
+
asc2(sql3`coalesce(${message.seq}, 0)`),
|
|
2001
|
+
asc2(message.createdAt),
|
|
2002
|
+
asc2(message.id)
|
|
2003
|
+
];
|
|
2004
|
+
}
|
|
2005
|
+
/** {@link messageOrder}, newest first. */
|
|
2006
|
+
messageOrderNewestFirst() {
|
|
2007
|
+
const message = this.t.agentMessage;
|
|
2008
|
+
return [
|
|
2009
|
+
desc(sql3`coalesce(${message.seq}, 0)`),
|
|
2010
|
+
desc(message.createdAt),
|
|
2011
|
+
desc(message.id)
|
|
2012
|
+
];
|
|
2013
|
+
}
|
|
2014
|
+
/**
|
|
2015
|
+
* The next `seq` in a thread: one past its highest. Two appends racing on ONE thread can draw the
|
|
2016
|
+
* same number — the turn loop never does that, and the tie then falls back to `created_at`, `id`.
|
|
2017
|
+
*/
|
|
2018
|
+
async nextMessageSeq(threadId) {
|
|
2019
|
+
const [row] = await this.db.select({
|
|
2020
|
+
last: max2(this.t.agentMessage.seq)
|
|
2021
|
+
}).from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId));
|
|
2022
|
+
return Number(row?.last ?? 0) + 1;
|
|
857
2023
|
}
|
|
858
2024
|
/** The run streaming the thread, or `null` — a projection of the one column. */
|
|
859
2025
|
async activeRunForThread(threadId) {
|
|
860
2026
|
const [thread] = await this.db.select({
|
|
861
|
-
activeStreamId: agentThread.activeStreamId
|
|
862
|
-
}).from(agentThread).where(
|
|
2027
|
+
activeStreamId: this.t.agentThread.activeStreamId
|
|
2028
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
863
2029
|
return thread?.activeStreamId ?? null;
|
|
864
2030
|
}
|
|
865
2031
|
/**
|
|
@@ -868,39 +2034,39 @@ var DrizzleAgentStore = class {
|
|
|
868
2034
|
*/
|
|
869
2035
|
async claimActiveStream(threadId, runId, options = {}) {
|
|
870
2036
|
const holders = [
|
|
871
|
-
|
|
872
|
-
|
|
2037
|
+
isNull2(this.t.agentThread.activeStreamId),
|
|
2038
|
+
eq2(this.t.agentThread.activeStreamId, runId),
|
|
873
2039
|
...options.replacing !== void 0 ? [
|
|
874
|
-
|
|
2040
|
+
eq2(this.t.agentThread.activeStreamId, options.replacing)
|
|
875
2041
|
] : []
|
|
876
2042
|
];
|
|
877
|
-
const claimed = await this.db.update(agentThread).set({
|
|
2043
|
+
const claimed = await affectedRows(this.dialect, this.db.update(this.t.agentThread).set({
|
|
878
2044
|
activeStreamId: runId
|
|
879
|
-
}).where(
|
|
880
|
-
|
|
881
|
-
|
|
882
|
-
|
|
2045
|
+
}).where(and2(eq2(this.t.agentThread.id, threadId), or2(...holders))), this.t.agentThread.id);
|
|
2046
|
+
if (claimed > 0) {
|
|
2047
|
+
return true;
|
|
2048
|
+
}
|
|
2049
|
+
return await this.activeHolder(threadId) === runId;
|
|
883
2050
|
}
|
|
884
2051
|
async releaseActiveStream(threadId, runId) {
|
|
885
|
-
const released = await this.db.update(agentThread).set({
|
|
2052
|
+
const released = await affectedRows(this.dialect, this.db.update(this.t.agentThread).set({
|
|
886
2053
|
activeStreamId: null
|
|
887
|
-
}).where(
|
|
888
|
-
|
|
889
|
-
});
|
|
890
|
-
return released.length > 0;
|
|
2054
|
+
}).where(and2(eq2(this.t.agentThread.id, threadId), eq2(this.t.agentThread.activeStreamId, runId))), this.t.agentThread.id);
|
|
2055
|
+
return released > 0;
|
|
891
2056
|
}
|
|
892
2057
|
async enqueueMessage(input) {
|
|
893
2058
|
const now = /* @__PURE__ */ new Date();
|
|
894
2059
|
const [edge] = await this.db.select({
|
|
895
|
-
first: min(agentQueuedMessage.position),
|
|
896
|
-
last:
|
|
897
|
-
}).from(agentQueuedMessage).where(
|
|
2060
|
+
first: min(this.t.agentQueuedMessage.position),
|
|
2061
|
+
last: max2(this.t.agentQueuedMessage.position)
|
|
2062
|
+
}).from(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.threadId, input.threadId));
|
|
898
2063
|
const position = input.at === "head" ? (edge?.first ?? 1) - 1 : (edge?.last ?? -1) + 1;
|
|
899
2064
|
const row = {
|
|
900
2065
|
id: crypto.randomUUID(),
|
|
901
2066
|
threadId: input.threadId,
|
|
902
2067
|
actor: input.actor,
|
|
903
2068
|
content: input.content,
|
|
2069
|
+
uiCapabilities: input.uiCapabilities ?? null,
|
|
904
2070
|
attachments: input.attachments !== void 0 && input.attachments.length > 0 ? input.attachments : null,
|
|
905
2071
|
agentName: input.agentName ?? null,
|
|
906
2072
|
persona: input.persona ?? null,
|
|
@@ -911,15 +2077,15 @@ var DrizzleAgentStore = class {
|
|
|
911
2077
|
createdAt: now,
|
|
912
2078
|
updatedAt: now
|
|
913
2079
|
};
|
|
914
|
-
await this.db.insert(agentQueuedMessage).values(row);
|
|
2080
|
+
await this.db.insert(this.t.agentQueuedMessage).values(row);
|
|
915
2081
|
return toQueuedMessage(row);
|
|
916
2082
|
}
|
|
917
2083
|
async listQueue(threadId) {
|
|
918
|
-
const rows = await this.db.select().from(agentQueuedMessage).where(
|
|
2084
|
+
const rows = await this.db.select().from(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.threadId, threadId)).orderBy(asc2(this.t.agentQueuedMessage.position), asc2(this.t.agentQueuedMessage.createdAt));
|
|
919
2085
|
return rows.map(toQueuedMessage);
|
|
920
2086
|
}
|
|
921
2087
|
async getQueuedMessage(id) {
|
|
922
|
-
const [row] = await this.db.select().from(agentQueuedMessage).where(
|
|
2088
|
+
const [row] = await this.db.select().from(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.id, id));
|
|
923
2089
|
return row === void 0 ? null : toQueuedMessage(row);
|
|
924
2090
|
}
|
|
925
2091
|
async updateQueuedMessage(id, patch) {
|
|
@@ -935,52 +2101,47 @@ var DrizzleAgentStore = class {
|
|
|
935
2101
|
if (patch.interrupt !== void 0) {
|
|
936
2102
|
updates.interrupt = patch.interrupt;
|
|
937
2103
|
}
|
|
938
|
-
await this.db.update(agentQueuedMessage).set(updates).where(
|
|
2104
|
+
await this.db.update(this.t.agentQueuedMessage).set(updates).where(eq2(this.t.agentQueuedMessage.id, id));
|
|
939
2105
|
return this.getQueuedMessage(id);
|
|
940
2106
|
}
|
|
941
2107
|
/** Rewrites the thread's positions as 0..n-1 in the new order — a queue is a handful of rows. */
|
|
942
|
-
async moveQueuedMessage(id,
|
|
2108
|
+
async moveQueuedMessage(id, index4) {
|
|
943
2109
|
const moving = await this.getQueuedMessage(id);
|
|
944
2110
|
if (moving === null) {
|
|
945
2111
|
return false;
|
|
946
2112
|
}
|
|
947
2113
|
const order = (await this.listQueue(moving.threadId)).filter((message) => message.id !== id);
|
|
948
|
-
const target = Math.max(0, Math.min(order.length, Math.trunc(
|
|
2114
|
+
const target = Math.max(0, Math.min(order.length, Math.trunc(index4)));
|
|
949
2115
|
order.splice(target, 0, moving);
|
|
950
2116
|
for (const [position, message] of order.entries()) {
|
|
951
|
-
await this.db.update(agentQueuedMessage).set({
|
|
2117
|
+
await this.db.update(this.t.agentQueuedMessage).set({
|
|
952
2118
|
position
|
|
953
|
-
}).where(
|
|
2119
|
+
}).where(eq2(this.t.agentQueuedMessage.id, message.id));
|
|
954
2120
|
}
|
|
955
2121
|
return true;
|
|
956
2122
|
}
|
|
957
2123
|
async removeQueuedMessage(id) {
|
|
958
|
-
const removed = await this.db.delete(agentQueuedMessage).where(
|
|
959
|
-
|
|
960
|
-
});
|
|
961
|
-
return removed.length > 0;
|
|
2124
|
+
const removed = await affectedRows(this.dialect, this.db.delete(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.id, id)), this.t.agentQueuedMessage.id);
|
|
2125
|
+
return removed > 0;
|
|
962
2126
|
}
|
|
963
2127
|
async clearQueue(threadId) {
|
|
964
|
-
|
|
965
|
-
id: agentQueuedMessage.id
|
|
966
|
-
});
|
|
967
|
-
return removed.length;
|
|
2128
|
+
return affectedRows(this.dialect, this.db.delete(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.threadId, threadId)), this.t.agentQueuedMessage.id);
|
|
968
2129
|
}
|
|
969
2130
|
async queuePause(threadId) {
|
|
970
2131
|
const [thread] = await this.db.select({
|
|
971
|
-
queuePause: agentThread.queuePause
|
|
972
|
-
}).from(agentThread).where(
|
|
2132
|
+
queuePause: this.t.agentThread.queuePause
|
|
2133
|
+
}).from(this.t.agentThread).where(eq2(this.t.agentThread.id, threadId));
|
|
973
2134
|
return thread?.queuePause ?? null;
|
|
974
2135
|
}
|
|
975
2136
|
async setQueuePause(threadId, pause) {
|
|
976
|
-
await this.db.update(agentThread).set({
|
|
2137
|
+
await this.db.update(this.t.agentThread).set({
|
|
977
2138
|
queuePause: pause
|
|
978
|
-
}).where(
|
|
2139
|
+
}).where(eq2(this.t.agentThread.id, threadId));
|
|
979
2140
|
}
|
|
980
2141
|
async setActiveStream(threadId, runId) {
|
|
981
|
-
await this.db.update(agentThread).set({
|
|
2142
|
+
await this.db.update(this.t.agentThread).set({
|
|
982
2143
|
activeStreamId: runId
|
|
983
|
-
}).where(
|
|
2144
|
+
}).where(eq2(this.t.agentThread.id, threadId));
|
|
984
2145
|
}
|
|
985
2146
|
/**
|
|
986
2147
|
* Patch a thread's `title` and/or `defaultAgent`. Each field is only touched when PRESENT in
|
|
@@ -1006,7 +2167,7 @@ var DrizzleAgentStore = class {
|
|
|
1006
2167
|
return;
|
|
1007
2168
|
}
|
|
1008
2169
|
updates.updatedAt = /* @__PURE__ */ new Date();
|
|
1009
|
-
await this.db.update(agentThread).set(updates).where(
|
|
2170
|
+
await this.db.update(this.t.agentThread).set(updates).where(eq2(this.t.agentThread.id, threadId));
|
|
1010
2171
|
}
|
|
1011
2172
|
/**
|
|
1012
2173
|
* The thread's default agent, projected — the caller wants one nullable scalar to decide which
|
|
@@ -1016,21 +2177,21 @@ var DrizzleAgentStore = class {
|
|
|
1016
2177
|
/** The thread's pinned model, projected like {@link defaultAgentForThread}. */
|
|
1017
2178
|
async modelForThread(threadId) {
|
|
1018
2179
|
const [thread] = await this.db.select({
|
|
1019
|
-
model: agentThread.model
|
|
1020
|
-
}).from(agentThread).where(
|
|
2180
|
+
model: this.t.agentThread.model
|
|
2181
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1021
2182
|
return thread?.model ?? null;
|
|
1022
2183
|
}
|
|
1023
2184
|
/** The thread's pinned persona, projected like {@link defaultAgentForThread}. */
|
|
1024
2185
|
async personaForThread(threadId) {
|
|
1025
2186
|
const [thread] = await this.db.select({
|
|
1026
|
-
persona: agentThread.persona
|
|
1027
|
-
}).from(agentThread).where(
|
|
2187
|
+
persona: this.t.agentThread.persona
|
|
2188
|
+
}).from(agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1028
2189
|
return thread?.persona ?? null;
|
|
1029
2190
|
}
|
|
1030
2191
|
async defaultAgentForThread(threadId) {
|
|
1031
2192
|
const [thread] = await this.db.select({
|
|
1032
|
-
defaultAgent: agentThread.defaultAgent
|
|
1033
|
-
}).from(agentThread).where(
|
|
2193
|
+
defaultAgent: this.t.agentThread.defaultAgent
|
|
2194
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1034
2195
|
return thread?.defaultAgent ?? null;
|
|
1035
2196
|
}
|
|
1036
2197
|
/**
|
|
@@ -1055,7 +2216,7 @@ var DrizzleAgentStore = class {
|
|
|
1055
2216
|
promptHash: run.promptHash ?? null,
|
|
1056
2217
|
parentRunId: run.parentRunId ?? null
|
|
1057
2218
|
};
|
|
1058
|
-
await this.db.insert(agentRun).values(runRow);
|
|
2219
|
+
await this.db.insert(this.t.agentRun).values(runRow);
|
|
1059
2220
|
}
|
|
1060
2221
|
/** Settle a run's outcome. A no-op when the run is unknown (mirrors `setTitle`/`updateThread`). */
|
|
1061
2222
|
async recordRunEnd(end) {
|
|
@@ -1072,16 +2233,16 @@ var DrizzleAgentStore = class {
|
|
|
1072
2233
|
if (end.errorMessage !== void 0) {
|
|
1073
2234
|
updates.errorMessage = end.errorMessage;
|
|
1074
2235
|
}
|
|
1075
|
-
await this.db.update(agentRun).set(updates).where(
|
|
2236
|
+
await this.db.update(this.t.agentRun).set(updates).where(eq2(this.t.agentRun.id, end.runId));
|
|
1076
2237
|
}
|
|
1077
2238
|
/** Bump the run's llm-step retry counter. Atomic `retries = retries + 1`, no read-modify-write. */
|
|
1078
2239
|
async bumpRunRetries(runId) {
|
|
1079
|
-
await this.db.update(agentRun).set({
|
|
1080
|
-
retries:
|
|
1081
|
-
}).where(
|
|
2240
|
+
await this.db.update(this.t.agentRun).set({
|
|
2241
|
+
retries: sql3`${this.t.agentRun.retries} + 1`
|
|
2242
|
+
}).where(eq2(this.t.agentRun.id, runId));
|
|
1082
2243
|
}
|
|
1083
2244
|
async appendMessage(input) {
|
|
1084
|
-
const [thread] = await this.db.select().from(agentThread).where(
|
|
2245
|
+
const [thread] = await this.db.select().from(this.t.agentThread).where(eq2(this.t.agentThread.id, input.threadId));
|
|
1085
2246
|
if (thread === void 0) {
|
|
1086
2247
|
throw new Error(`thread ${input.threadId} not found`);
|
|
1087
2248
|
}
|
|
@@ -1091,6 +2252,7 @@ var DrizzleAgentStore = class {
|
|
|
1091
2252
|
threadId: input.threadId,
|
|
1092
2253
|
role: input.role,
|
|
1093
2254
|
content: input.content,
|
|
2255
|
+
actionProposalOutcome: input.actionProposalOutcome ? canonicalActionProposalJson4(input.actionProposalOutcome) : null,
|
|
1094
2256
|
toolCalls: input.toolCalls ?? null,
|
|
1095
2257
|
toolResults: input.toolResults ?? null,
|
|
1096
2258
|
attachments: input.attachments ?? null,
|
|
@@ -1103,48 +2265,50 @@ var DrizzleAgentStore = class {
|
|
|
1103
2265
|
reasoningMs: input.reasoningMs ?? null,
|
|
1104
2266
|
ui: input.ui ?? null,
|
|
1105
2267
|
feedback: null,
|
|
2268
|
+
seq: await this.nextMessageSeq(input.threadId),
|
|
1106
2269
|
createdAt: now
|
|
1107
2270
|
};
|
|
1108
|
-
await this.db.insert(agentMessage).values(message);
|
|
1109
|
-
await this.db.update(agentThread).set({
|
|
2271
|
+
await this.db.insert(this.t.agentMessage).values(message);
|
|
2272
|
+
await this.db.update(this.t.agentThread).set({
|
|
1110
2273
|
updatedAt: now
|
|
1111
|
-
}).where(
|
|
2274
|
+
}).where(eq2(this.t.agentThread.id, input.threadId));
|
|
1112
2275
|
return this.toStoredMessage(message);
|
|
1113
2276
|
}
|
|
1114
2277
|
async setMessageToolResults(messageId, results) {
|
|
1115
|
-
await this.db.update(agentMessage).set({
|
|
2278
|
+
await this.db.update(this.t.agentMessage).set({
|
|
1116
2279
|
toolResults: results
|
|
1117
|
-
}).where(
|
|
2280
|
+
}).where(eq2(this.t.agentMessage.id, messageId));
|
|
1118
2281
|
}
|
|
1119
2282
|
async setMessageUi(messageId, ui) {
|
|
1120
|
-
await this.db.update(agentMessage).set({
|
|
2283
|
+
await this.db.update(this.t.agentMessage).set({
|
|
1121
2284
|
ui: ui.length > 0 ? ui : null
|
|
1122
|
-
}).where(
|
|
2285
|
+
}).where(eq2(this.t.agentMessage.id, messageId));
|
|
1123
2286
|
}
|
|
1124
2287
|
async threadOfMessage(messageId) {
|
|
1125
2288
|
const [row] = await this.db.select({
|
|
1126
|
-
threadId: agentMessage.threadId
|
|
1127
|
-
}).from(agentMessage).where(
|
|
2289
|
+
threadId: this.t.agentMessage.threadId
|
|
2290
|
+
}).from(this.t.agentMessage).where(eq2(this.t.agentMessage.id, messageId)).limit(1);
|
|
1128
2291
|
return row?.threadId ?? null;
|
|
1129
2292
|
}
|
|
1130
2293
|
async setMessageFeedback(messageId, feedback) {
|
|
1131
|
-
await this.db.update(agentMessage).set({
|
|
2294
|
+
await this.db.update(this.t.agentMessage).set({
|
|
1132
2295
|
feedback
|
|
1133
|
-
}).where(
|
|
2296
|
+
}).where(eq2(this.t.agentMessage.id, messageId));
|
|
1134
2297
|
}
|
|
1135
2298
|
async truncateFrom(threadId, messageId) {
|
|
1136
|
-
const messages = await this.db.select().from(agentMessage).where(
|
|
2299
|
+
const messages = await this.db.select().from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId)).orderBy(...this.messageOrder());
|
|
1137
2300
|
const cutoff = messages.findIndex((message) => message.id === messageId);
|
|
1138
2301
|
if (cutoff < 0) {
|
|
1139
2302
|
return;
|
|
1140
2303
|
}
|
|
1141
2304
|
const doomedIds = messages.slice(cutoff).map((message) => message.id);
|
|
1142
|
-
await this.db.delete(agentToolCall).where(inArray(agentToolCall.messageId, doomedIds));
|
|
1143
|
-
await this.db.delete(agentMessage).where(inArray(agentMessage.id, doomedIds));
|
|
2305
|
+
await this.db.delete(this.t.agentToolCall).where(inArray(this.t.agentToolCall.messageId, doomedIds));
|
|
2306
|
+
await this.db.delete(this.t.agentMessage).where(inArray(this.t.agentMessage.id, doomedIds));
|
|
1144
2307
|
}
|
|
1145
2308
|
async recordToolCall(input) {
|
|
1146
|
-
await this.db.insert(agentToolCall).values({
|
|
2309
|
+
await this.db.insert(this.t.agentToolCall).values({
|
|
1147
2310
|
id: input.toolCallId,
|
|
2311
|
+
proposalId: input.proposalId ?? null,
|
|
1148
2312
|
messageId: input.messageId,
|
|
1149
2313
|
toolName: input.toolName,
|
|
1150
2314
|
toolType: input.toolType,
|
|
@@ -1158,6 +2322,7 @@ var DrizzleAgentStore = class {
|
|
|
1158
2322
|
executedAt: null,
|
|
1159
2323
|
runId: input.runId ?? null,
|
|
1160
2324
|
approver: input.approver ?? null,
|
|
2325
|
+
confirmation: input.confirmation ?? null,
|
|
1161
2326
|
expiresAt: input.expiresAt !== void 0 ? new Date(input.expiresAt) : null,
|
|
1162
2327
|
remember: null,
|
|
1163
2328
|
decidedVia: null
|
|
@@ -1188,18 +2353,18 @@ var DrizzleAgentStore = class {
|
|
|
1188
2353
|
if (input.status === "executed" || input.status === "auto_executed") {
|
|
1189
2354
|
updates.executedAt = /* @__PURE__ */ new Date();
|
|
1190
2355
|
}
|
|
1191
|
-
await this.db.update(agentToolCall).set(updates).where(
|
|
2356
|
+
await this.db.update(this.t.agentToolCall).set(updates).where(eq2(this.t.agentToolCall.id, input.toolCallId));
|
|
1192
2357
|
}
|
|
1193
2358
|
async toolCallOutcomes(toolCallIds) {
|
|
1194
2359
|
if (toolCallIds.length === 0) {
|
|
1195
2360
|
return [];
|
|
1196
2361
|
}
|
|
1197
2362
|
const rows = await this.db.select({
|
|
1198
|
-
id: agentToolCall.id,
|
|
1199
|
-
status: agentToolCall.status,
|
|
1200
|
-
output: agentToolCall.output,
|
|
1201
|
-
error: agentToolCall.error
|
|
1202
|
-
}).from(agentToolCall).where(inArray(agentToolCall.id, [
|
|
2363
|
+
id: this.t.agentToolCall.id,
|
|
2364
|
+
status: this.t.agentToolCall.status,
|
|
2365
|
+
output: this.t.agentToolCall.output,
|
|
2366
|
+
error: this.t.agentToolCall.error
|
|
2367
|
+
}).from(this.t.agentToolCall).where(inArray(this.t.agentToolCall.id, [
|
|
1203
2368
|
...toolCallIds
|
|
1204
2369
|
]));
|
|
1205
2370
|
return rows.map((row) => ({
|
|
@@ -1214,14 +2379,14 @@ var DrizzleAgentStore = class {
|
|
|
1214
2379
|
}));
|
|
1215
2380
|
}
|
|
1216
2381
|
async failUnsettledToolCalls(runId, error) {
|
|
1217
|
-
const pending =
|
|
2382
|
+
const pending = and2(eq2(this.t.agentToolCall.runId, runId), eq2(this.t.agentToolCall.status, "pending_approval"));
|
|
1218
2383
|
const rows = await this.db.select({
|
|
1219
|
-
id: agentToolCall.id
|
|
1220
|
-
}).from(agentToolCall).where(pending);
|
|
2384
|
+
id: this.t.agentToolCall.id
|
|
2385
|
+
}).from(this.t.agentToolCall).where(pending);
|
|
1221
2386
|
if (rows.length === 0) {
|
|
1222
2387
|
return 0;
|
|
1223
2388
|
}
|
|
1224
|
-
await this.db.update(agentToolCall).set({
|
|
2389
|
+
await this.db.update(this.t.agentToolCall).set({
|
|
1225
2390
|
status: "failed",
|
|
1226
2391
|
error
|
|
1227
2392
|
}).where(pending);
|
|
@@ -1246,11 +2411,11 @@ var DrizzleAgentStore = class {
|
|
|
1246
2411
|
return [];
|
|
1247
2412
|
}
|
|
1248
2413
|
const rows = await this.db.select({
|
|
1249
|
-
attachments: agentMessage.attachments
|
|
1250
|
-
}).from(agentMessage).innerJoin(agentThread,
|
|
2414
|
+
attachments: this.t.agentMessage.attachments
|
|
2415
|
+
}).from(this.t.agentMessage).innerJoin(this.t.agentThread, eq2(this.t.agentMessage.threadId, this.t.agentThread.id)).where(and2(eq2(this.t.agentThread.actorRef, actorRef), isNotNull(this.t.agentMessage.attachments)));
|
|
1251
2416
|
const queued = await this.db.select({
|
|
1252
|
-
attachments: agentQueuedMessage.attachments
|
|
1253
|
-
}).from(agentQueuedMessage).innerJoin(agentThread,
|
|
2417
|
+
attachments: this.t.agentQueuedMessage.attachments
|
|
2418
|
+
}).from(this.t.agentQueuedMessage).innerJoin(this.t.agentThread, eq2(this.t.agentQueuedMessage.threadId, this.t.agentThread.id)).where(and2(eq2(this.t.agentThread.actorRef, actorRef), isNotNull(this.t.agentQueuedMessage.attachments)));
|
|
1254
2419
|
const wanted = new Set(mediaIds);
|
|
1255
2420
|
const found = /* @__PURE__ */ new Set();
|
|
1256
2421
|
for (const row of [
|
|
@@ -1268,7 +2433,7 @@ var DrizzleAgentStore = class {
|
|
|
1268
2433
|
].filter((mediaId) => found.has(mediaId));
|
|
1269
2434
|
}
|
|
1270
2435
|
async recordUsage(input) {
|
|
1271
|
-
await this.db.insert(agentTokenUsage).values({
|
|
2436
|
+
await this.db.insert(this.t.agentTokenUsage).values({
|
|
1272
2437
|
id: crypto.randomUUID(),
|
|
1273
2438
|
threadId: input.threadId,
|
|
1274
2439
|
actorRef: input.actorRef,
|
|
@@ -1289,7 +2454,7 @@ var DrizzleAgentStore = class {
|
|
|
1289
2454
|
async usageBetween(actorRef, fromDay, toDay) {
|
|
1290
2455
|
const start = /* @__PURE__ */ new Date(`${fromDay}T00:00:00.000Z`);
|
|
1291
2456
|
const end = /* @__PURE__ */ new Date(`${toDay}T23:59:59.999Z`);
|
|
1292
|
-
const rows = await this.db.select().from(agentTokenUsage).where(
|
|
2457
|
+
const rows = await this.db.select().from(this.t.agentTokenUsage).where(and2(eq2(this.t.agentTokenUsage.actorRef, actorRef), gte(this.t.agentTokenUsage.createdAt, start), lte2(this.t.agentTokenUsage.createdAt, end)));
|
|
1293
2458
|
const usedTokens = rows.reduce((sum2, row) => sum2 + row.inputTokens + row.outputTokens, 0);
|
|
1294
2459
|
const costUsd = rows.reduce((sum2, row) => sum2 + (row.costUsd ?? 0), 0);
|
|
1295
2460
|
return {
|
|
@@ -1315,7 +2480,12 @@ var DrizzleAgentStore = class {
|
|
|
1315
2480
|
};
|
|
1316
2481
|
}
|
|
1317
2482
|
toStoredMessage(message) {
|
|
2483
|
+
const outcome = message.actionProposalOutcome ? JSON.parse(message.actionProposalOutcome) : void 0;
|
|
1318
2484
|
return {
|
|
2485
|
+
...outcome ? {
|
|
2486
|
+
actionProposalOutcome: outcome,
|
|
2487
|
+
ui: outcome.ui
|
|
2488
|
+
} : {},
|
|
1319
2489
|
id: message.id,
|
|
1320
2490
|
role: message.role,
|
|
1321
2491
|
content: message.content,
|
|
@@ -1361,6 +2531,9 @@ var DrizzleAgentStore = class {
|
|
|
1361
2531
|
};
|
|
1362
2532
|
function toQueuedMessage(row) {
|
|
1363
2533
|
return {
|
|
2534
|
+
...row.uiCapabilities !== null ? {
|
|
2535
|
+
uiCapabilities: row.uiCapabilities
|
|
2536
|
+
} : {},
|
|
1364
2537
|
id: row.id,
|
|
1365
2538
|
threadId: row.threadId,
|
|
1366
2539
|
actor: row.actor,
|
|
@@ -1391,7 +2564,7 @@ __name(toQueuedMessage, "toQueuedMessage");
|
|
|
1391
2564
|
|
|
1392
2565
|
// src/drizzle-governance-queries.ts
|
|
1393
2566
|
import { bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, dayBoundsUtc, rollupThreadUsage, truncateDetailContent } from "@dudousxd/nestjs-agent-core";
|
|
1394
|
-
import { and as
|
|
2567
|
+
import { and as and3, asc as asc3, count, desc as desc2, eq as eq3, gte as gte2, inArray as inArray2, isNull as isNull3, like, lte as lte3, sql as sql4, sum } from "drizzle-orm";
|
|
1395
2568
|
var UNCLASSIFIED_ERROR_CODE = "unknown";
|
|
1396
2569
|
var DEFAULT_AGENT_BUCKET = "(default)";
|
|
1397
2570
|
var TOOL_CALL_STATUSES = [
|
|
@@ -1504,11 +2677,15 @@ var DrizzleGovernanceQueries = class {
|
|
|
1504
2677
|
static {
|
|
1505
2678
|
__name(this, "DrizzleGovernanceQueries");
|
|
1506
2679
|
}
|
|
1507
|
-
db;
|
|
1508
2680
|
pricingStore;
|
|
2681
|
+
db;
|
|
2682
|
+
dialect;
|
|
2683
|
+
t;
|
|
1509
2684
|
constructor(db, pricingStore) {
|
|
1510
|
-
this.db = db;
|
|
1511
2685
|
this.pricingStore = pricingStore;
|
|
2686
|
+
this.dialect = agentDialectOf(db);
|
|
2687
|
+
this.t = agentTablesFor(this.dialect);
|
|
2688
|
+
this.db = asBuilder(db);
|
|
1512
2689
|
}
|
|
1513
2690
|
async loadPricing() {
|
|
1514
2691
|
const prices = await this.pricingStore.listCurrentPrices();
|
|
@@ -1525,7 +2702,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
1525
2702
|
}
|
|
1526
2703
|
async usageInRange(range) {
|
|
1527
2704
|
const { start, end } = dayBoundsUtc(range);
|
|
1528
|
-
const rows = await this.db.select().from(agentTokenUsage).where(
|
|
2705
|
+
const rows = await this.db.select().from(this.t.agentTokenUsage).where(and3(gte2(this.t.agentTokenUsage.createdAt, start), lte3(this.t.agentTokenUsage.createdAt, end)));
|
|
1529
2706
|
return rows.map(toUsageInput);
|
|
1530
2707
|
}
|
|
1531
2708
|
async spendByModel(range) {
|
|
@@ -1550,7 +2727,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
1550
2727
|
if (threadIds.length === 0) {
|
|
1551
2728
|
return [];
|
|
1552
2729
|
}
|
|
1553
|
-
const threads = await this.db.select().from(agentThread).where(
|
|
2730
|
+
const threads = await this.db.select().from(this.t.agentThread).where(and3(inArray2(this.t.agentThread.id, threadIds), isNull3(this.t.agentThread.deletedAt)));
|
|
1554
2731
|
const threadsById = new Map(threads.map((thread) => [
|
|
1555
2732
|
thread.id,
|
|
1556
2733
|
{
|
|
@@ -1569,14 +2746,14 @@ var DrizzleGovernanceQueries = class {
|
|
|
1569
2746
|
}
|
|
1570
2747
|
async recentToolCalls(limit) {
|
|
1571
2748
|
const rows = await this.db.select({
|
|
1572
|
-
toolCallId: agentToolCall.id,
|
|
1573
|
-
toolName: agentToolCall.toolName,
|
|
1574
|
-
toolType: agentToolCall.toolType,
|
|
1575
|
-
status: agentToolCall.status,
|
|
1576
|
-
threadId: agentMessage.threadId,
|
|
1577
|
-
createdAt: agentToolCall.createdAt,
|
|
1578
|
-
runId: agentToolCall.runId
|
|
1579
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
2749
|
+
toolCallId: this.t.agentToolCall.id,
|
|
2750
|
+
toolName: this.t.agentToolCall.toolName,
|
|
2751
|
+
toolType: this.t.agentToolCall.toolType,
|
|
2752
|
+
status: this.t.agentToolCall.status,
|
|
2753
|
+
threadId: this.t.agentMessage.threadId,
|
|
2754
|
+
createdAt: this.t.agentToolCall.createdAt,
|
|
2755
|
+
runId: this.t.agentToolCall.runId
|
|
2756
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq3(this.t.agentToolCall.messageId, this.t.agentMessage.id)).orderBy(desc2(this.t.agentToolCall.createdAt), desc2(this.t.agentToolCall.id)).limit(limit);
|
|
1580
2757
|
return rows.map((row) => ({
|
|
1581
2758
|
toolCallId: row.toolCallId,
|
|
1582
2759
|
toolName: row.toolName,
|
|
@@ -1604,9 +2781,9 @@ var DrizzleGovernanceQueries = class {
|
|
|
1604
2781
|
return rollups;
|
|
1605
2782
|
}
|
|
1606
2783
|
const messageCounts = await this.db.select({
|
|
1607
|
-
threadId: agentMessage.threadId,
|
|
2784
|
+
threadId: this.t.agentMessage.threadId,
|
|
1608
2785
|
value: count()
|
|
1609
|
-
}).from(agentMessage).where(inArray2(agentMessage.threadId, threadIds)).groupBy(agentMessage.threadId);
|
|
2786
|
+
}).from(this.t.agentMessage).where(inArray2(this.t.agentMessage.threadId, threadIds)).groupBy(this.t.agentMessage.threadId);
|
|
1610
2787
|
for (const row of messageCounts) {
|
|
1611
2788
|
const bucket = rollups.get(row.threadId);
|
|
1612
2789
|
if (bucket !== void 0) {
|
|
@@ -1614,10 +2791,10 @@ var DrizzleGovernanceQueries = class {
|
|
|
1614
2791
|
}
|
|
1615
2792
|
}
|
|
1616
2793
|
const usageTotals = await this.db.select({
|
|
1617
|
-
threadId: agentTokenUsage.threadId,
|
|
1618
|
-
inputTokens: sum(agentTokenUsage.inputTokens),
|
|
1619
|
-
outputTokens: sum(agentTokenUsage.outputTokens)
|
|
1620
|
-
}).from(agentTokenUsage).where(inArray2(agentTokenUsage.threadId, threadIds)).groupBy(agentTokenUsage.threadId);
|
|
2794
|
+
threadId: this.t.agentTokenUsage.threadId,
|
|
2795
|
+
inputTokens: sum(this.t.agentTokenUsage.inputTokens),
|
|
2796
|
+
outputTokens: sum(this.t.agentTokenUsage.outputTokens)
|
|
2797
|
+
}).from(this.t.agentTokenUsage).where(inArray2(this.t.agentTokenUsage.threadId, threadIds)).groupBy(this.t.agentTokenUsage.threadId);
|
|
1621
2798
|
for (const row of usageTotals) {
|
|
1622
2799
|
const bucket = rollups.get(row.threadId);
|
|
1623
2800
|
if (bucket !== void 0) {
|
|
@@ -1642,12 +2819,12 @@ var DrizzleGovernanceQueries = class {
|
|
|
1642
2819
|
});
|
|
1643
2820
|
}
|
|
1644
2821
|
async recentThreads(limit) {
|
|
1645
|
-
const threads = await this.db.select().from(agentThread).where(
|
|
2822
|
+
const threads = await this.db.select().from(this.t.agentThread).where(isNull3(this.t.agentThread.deletedAt)).orderBy(desc2(this.t.agentThread.updatedAt), desc2(this.t.agentThread.id)).limit(limit);
|
|
1646
2823
|
return this.toThreadActivityRows(threads);
|
|
1647
2824
|
}
|
|
1648
2825
|
async runsInRange(range) {
|
|
1649
2826
|
const { start, end } = dayBoundsUtc(range);
|
|
1650
|
-
return this.db.select().from(agentRun).where(
|
|
2827
|
+
return this.db.select().from(this.t.agentRun).where(and3(gte2(this.t.agentRun.startedAt, start), lte3(this.t.agentRun.startedAt, end)));
|
|
1651
2828
|
}
|
|
1652
2829
|
async runMetrics(range) {
|
|
1653
2830
|
const runs = await this.runsInRange(range);
|
|
@@ -1704,7 +2881,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
1704
2881
|
}
|
|
1705
2882
|
async runErrors(range) {
|
|
1706
2883
|
const { start, end } = dayBoundsUtc(range);
|
|
1707
|
-
const runs = await this.db.select().from(agentRun).where(
|
|
2884
|
+
const runs = await this.db.select().from(this.t.agentRun).where(and3(gte2(this.t.agentRun.startedAt, start), lte3(this.t.agentRun.startedAt, end), eq3(this.t.agentRun.status, "failed")));
|
|
1708
2885
|
const byError = /* @__PURE__ */ new Map();
|
|
1709
2886
|
for (const run of runs) {
|
|
1710
2887
|
const errorCode = run.errorCode ?? UNCLASSIFIED_ERROR_CODE;
|
|
@@ -1744,7 +2921,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
1744
2921
|
return result;
|
|
1745
2922
|
}
|
|
1746
2923
|
async recentRuns(limit) {
|
|
1747
|
-
const runs = await this.db.select().from(agentRun).orderBy(desc2(agentRun.startedAt), desc2(agentRun.id)).limit(limit);
|
|
2924
|
+
const runs = await this.db.select().from(this.t.agentRun).orderBy(desc2(this.t.agentRun.startedAt), desc2(this.t.agentRun.id)).limit(limit);
|
|
1748
2925
|
return runs.map(toRecentRunRow);
|
|
1749
2926
|
}
|
|
1750
2927
|
/**
|
|
@@ -1754,16 +2931,16 @@ var DrizzleGovernanceQueries = class {
|
|
|
1754
2931
|
*/
|
|
1755
2932
|
async pendingApprovals(limit) {
|
|
1756
2933
|
const rows = await this.db.select({
|
|
1757
|
-
toolCallId: agentToolCall.id,
|
|
1758
|
-
toolName: agentToolCall.toolName,
|
|
1759
|
-
input: agentToolCall.input,
|
|
1760
|
-
threadId: agentThread.id,
|
|
1761
|
-
threadTitle: agentThread.title,
|
|
1762
|
-
actorRef: agentThread.actorRef,
|
|
1763
|
-
agentName: agentMessage.agentName,
|
|
1764
|
-
requestedAt: agentToolCall.createdAt,
|
|
1765
|
-
runId: agentToolCall.runId
|
|
1766
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
2934
|
+
toolCallId: this.t.agentToolCall.id,
|
|
2935
|
+
toolName: this.t.agentToolCall.toolName,
|
|
2936
|
+
input: this.t.agentToolCall.input,
|
|
2937
|
+
threadId: this.t.agentThread.id,
|
|
2938
|
+
threadTitle: this.t.agentThread.title,
|
|
2939
|
+
actorRef: this.t.agentThread.actorRef,
|
|
2940
|
+
agentName: this.t.agentMessage.agentName,
|
|
2941
|
+
requestedAt: this.t.agentToolCall.createdAt,
|
|
2942
|
+
runId: this.t.agentToolCall.runId
|
|
2943
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq3(this.t.agentToolCall.messageId, this.t.agentMessage.id)).innerJoin(this.t.agentThread, eq3(this.t.agentMessage.threadId, this.t.agentThread.id)).where(eq3(this.t.agentToolCall.status, "pending_approval")).orderBy(this.t.agentToolCall.createdAt, this.t.agentToolCall.id).limit(limit);
|
|
1767
2944
|
return rows.map((row) => ({
|
|
1768
2945
|
toolCallId: row.toolCallId,
|
|
1769
2946
|
toolName: row.toolName,
|
|
@@ -1785,11 +2962,11 @@ var DrizzleGovernanceQueries = class {
|
|
|
1785
2962
|
*/
|
|
1786
2963
|
async toolStats(range) {
|
|
1787
2964
|
const { start, end } = dayBoundsUtc(range);
|
|
1788
|
-
const calls = await this.db.select().from(agentToolCall).where(
|
|
2965
|
+
const calls = await this.db.select().from(this.t.agentToolCall).where(and3(gte2(this.t.agentToolCall.createdAt, start), lte3(this.t.agentToolCall.createdAt, end)));
|
|
1789
2966
|
const byTool = /* @__PURE__ */ new Map();
|
|
1790
2967
|
for (const call of calls) {
|
|
1791
|
-
const
|
|
1792
|
-
const bucket = byTool.get(
|
|
2968
|
+
const key2 = `${call.toolName} ${call.toolType}`;
|
|
2969
|
+
const bucket = byTool.get(key2) ?? {
|
|
1793
2970
|
toolName: call.toolName,
|
|
1794
2971
|
toolType: call.toolType,
|
|
1795
2972
|
calls: 0,
|
|
@@ -1803,7 +2980,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
1803
2980
|
if (call.executionMs != null) {
|
|
1804
2981
|
bucket.executionMs.push(call.executionMs);
|
|
1805
2982
|
}
|
|
1806
|
-
byTool.set(
|
|
2983
|
+
byTool.set(key2, bucket);
|
|
1807
2984
|
}
|
|
1808
2985
|
const result = [];
|
|
1809
2986
|
for (const bucket of byTool.values()) {
|
|
@@ -1835,19 +3012,19 @@ var DrizzleGovernanceQueries = class {
|
|
|
1835
3012
|
if (filters?.toolType !== void 0 && !isToolKind(filters.toolType)) {
|
|
1836
3013
|
return emptyPage(query);
|
|
1837
3014
|
}
|
|
1838
|
-
const whereClause =
|
|
3015
|
+
const whereClause = and3(filters?.toolName !== void 0 ? eq3(this.t.agentToolCall.toolName, filters.toolName) : void 0, filters?.toolType !== void 0 && isToolKind(filters.toolType) ? eq3(this.t.agentToolCall.toolType, filters.toolType) : void 0, filters?.status !== void 0 && isToolCallStatus(filters.status) ? eq3(this.t.agentToolCall.status, filters.status) : void 0, filters?.threadId !== void 0 ? eq3(this.t.agentMessage.threadId, filters.threadId) : void 0, filters?.fromDay !== void 0 ? gte2(this.t.agentToolCall.createdAt, dayStartUtc(filters.fromDay)) : void 0, filters?.toDay !== void 0 ? lte3(this.t.agentToolCall.createdAt, dayEndUtc(filters.toDay)) : void 0);
|
|
1839
3016
|
const [totalRow] = await this.db.select({
|
|
1840
3017
|
value: count()
|
|
1841
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
3018
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq3(this.t.agentToolCall.messageId, this.t.agentMessage.id)).where(whereClause);
|
|
1842
3019
|
const rows = await this.db.select({
|
|
1843
|
-
toolCallId: agentToolCall.id,
|
|
1844
|
-
toolName: agentToolCall.toolName,
|
|
1845
|
-
toolType: agentToolCall.toolType,
|
|
1846
|
-
status: agentToolCall.status,
|
|
1847
|
-
threadId: agentMessage.threadId,
|
|
1848
|
-
createdAt: agentToolCall.createdAt,
|
|
1849
|
-
runId: agentToolCall.runId
|
|
1850
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
3020
|
+
toolCallId: this.t.agentToolCall.id,
|
|
3021
|
+
toolName: this.t.agentToolCall.toolName,
|
|
3022
|
+
toolType: this.t.agentToolCall.toolType,
|
|
3023
|
+
status: this.t.agentToolCall.status,
|
|
3024
|
+
threadId: this.t.agentMessage.threadId,
|
|
3025
|
+
createdAt: this.t.agentToolCall.createdAt,
|
|
3026
|
+
runId: this.t.agentToolCall.runId
|
|
3027
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq3(this.t.agentToolCall.messageId, this.t.agentMessage.id)).where(whereClause).orderBy(desc2(this.t.agentToolCall.createdAt), desc2(this.t.agentToolCall.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
1851
3028
|
return {
|
|
1852
3029
|
rows: rows.map((row) => ({
|
|
1853
3030
|
toolCallId: row.toolCallId,
|
|
@@ -1871,11 +3048,11 @@ var DrizzleGovernanceQueries = class {
|
|
|
1871
3048
|
*/
|
|
1872
3049
|
async threadsPage(query) {
|
|
1873
3050
|
const filters = query.where;
|
|
1874
|
-
const whereClause =
|
|
3051
|
+
const whereClause = and3(isNull3(this.t.agentThread.deletedAt), filters?.actorRef !== void 0 ? eq3(this.t.agentThread.actorRef, filters.actorRef) : void 0, filters?.title !== void 0 ? like(sql4`lower(${this.t.agentThread.title})`, `%${filters.title.toLowerCase()}%`) : void 0, filters?.fromDay !== void 0 ? gte2(this.t.agentThread.updatedAt, dayStartUtc(filters.fromDay)) : void 0, filters?.toDay !== void 0 ? lte3(this.t.agentThread.updatedAt, dayEndUtc(filters.toDay)) : void 0);
|
|
1875
3052
|
const [totalRow] = await this.db.select({
|
|
1876
3053
|
value: count()
|
|
1877
|
-
}).from(agentThread).where(whereClause);
|
|
1878
|
-
const threads = await this.db.select().from(agentThread).where(whereClause).orderBy(desc2(agentThread.updatedAt), desc2(agentThread.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
3054
|
+
}).from(this.t.agentThread).where(whereClause);
|
|
3055
|
+
const threads = await this.db.select().from(this.t.agentThread).where(whereClause).orderBy(desc2(this.t.agentThread.updatedAt), desc2(this.t.agentThread.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
1879
3056
|
const rows = await this.toThreadActivityRows(threads);
|
|
1880
3057
|
return {
|
|
1881
3058
|
rows,
|
|
@@ -1893,11 +3070,11 @@ var DrizzleGovernanceQueries = class {
|
|
|
1893
3070
|
if (filters?.status !== void 0 && !isRunStatus(filters.status)) {
|
|
1894
3071
|
return emptyPage(query);
|
|
1895
3072
|
}
|
|
1896
|
-
const whereClause =
|
|
3073
|
+
const whereClause = and3(filters?.agentName !== void 0 ? eq3(this.t.agentRun.agentName, filters.agentName) : void 0, filters?.status !== void 0 && isRunStatus(filters.status) ? eq3(this.t.agentRun.status, filters.status) : void 0, filters?.errorCode !== void 0 ? eq3(this.t.agentRun.errorCode, filters.errorCode) : void 0, filters?.threadId !== void 0 ? eq3(this.t.agentRun.threadId, filters.threadId) : void 0, filters?.fromDay !== void 0 ? gte2(this.t.agentRun.startedAt, dayStartUtc(filters.fromDay)) : void 0, filters?.toDay !== void 0 ? lte3(this.t.agentRun.startedAt, dayEndUtc(filters.toDay)) : void 0);
|
|
1897
3074
|
const [totalRow] = await this.db.select({
|
|
1898
3075
|
value: count()
|
|
1899
|
-
}).from(agentRun).where(whereClause);
|
|
1900
|
-
const runs = await this.db.select().from(agentRun).where(whereClause).orderBy(desc2(agentRun.startedAt), desc2(agentRun.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
3076
|
+
}).from(this.t.agentRun).where(whereClause);
|
|
3077
|
+
const runs = await this.db.select().from(this.t.agentRun).where(whereClause).orderBy(desc2(this.t.agentRun.startedAt), desc2(this.t.agentRun.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
1901
3078
|
return {
|
|
1902
3079
|
rows: runs.map(toRecentRunRow),
|
|
1903
3080
|
total: totalRow?.value ?? 0,
|
|
@@ -1917,21 +3094,21 @@ var DrizzleGovernanceQueries = class {
|
|
|
1917
3094
|
*/
|
|
1918
3095
|
async approvalsPage(query) {
|
|
1919
3096
|
const filters = query.where;
|
|
1920
|
-
const whereClause =
|
|
3097
|
+
const whereClause = and3(eq3(this.t.agentToolCall.status, "pending_approval"), filters?.toolName !== void 0 ? eq3(this.t.agentToolCall.toolName, filters.toolName) : void 0, filters?.threadId !== void 0 ? eq3(this.t.agentThread.id, filters.threadId) : void 0, filters?.actorRef !== void 0 ? eq3(this.t.agentThread.actorRef, filters.actorRef) : void 0, filters?.agentName !== void 0 ? eq3(this.t.agentMessage.agentName, filters.agentName) : void 0, filters?.fromDay !== void 0 ? gte2(this.t.agentToolCall.createdAt, dayStartUtc(filters.fromDay)) : void 0, filters?.toDay !== void 0 ? lte3(this.t.agentToolCall.createdAt, dayEndUtc(filters.toDay)) : void 0);
|
|
1921
3098
|
const [totalRow] = await this.db.select({
|
|
1922
3099
|
value: count()
|
|
1923
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
3100
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq3(this.t.agentToolCall.messageId, this.t.agentMessage.id)).innerJoin(this.t.agentThread, eq3(this.t.agentMessage.threadId, this.t.agentThread.id)).where(whereClause);
|
|
1924
3101
|
const rows = await this.db.select({
|
|
1925
|
-
toolCallId: agentToolCall.id,
|
|
1926
|
-
toolName: agentToolCall.toolName,
|
|
1927
|
-
input: agentToolCall.input,
|
|
1928
|
-
threadId: agentThread.id,
|
|
1929
|
-
threadTitle: agentThread.title,
|
|
1930
|
-
actorRef: agentThread.actorRef,
|
|
1931
|
-
agentName: agentMessage.agentName,
|
|
1932
|
-
requestedAt: agentToolCall.createdAt,
|
|
1933
|
-
runId: agentToolCall.runId
|
|
1934
|
-
}).from(agentToolCall).innerJoin(agentMessage,
|
|
3102
|
+
toolCallId: this.t.agentToolCall.id,
|
|
3103
|
+
toolName: this.t.agentToolCall.toolName,
|
|
3104
|
+
input: this.t.agentToolCall.input,
|
|
3105
|
+
threadId: this.t.agentThread.id,
|
|
3106
|
+
threadTitle: this.t.agentThread.title,
|
|
3107
|
+
actorRef: this.t.agentThread.actorRef,
|
|
3108
|
+
agentName: this.t.agentMessage.agentName,
|
|
3109
|
+
requestedAt: this.t.agentToolCall.createdAt,
|
|
3110
|
+
runId: this.t.agentToolCall.runId
|
|
3111
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq3(this.t.agentToolCall.messageId, this.t.agentMessage.id)).innerJoin(this.t.agentThread, eq3(this.t.agentMessage.threadId, this.t.agentThread.id)).where(whereClause).orderBy(asc3(this.t.agentToolCall.createdAt), asc3(this.t.agentToolCall.id)).limit(query.pageSize).offset((query.page - 1) * query.pageSize);
|
|
1935
3112
|
return {
|
|
1936
3113
|
rows: rows.map((row) => ({
|
|
1937
3114
|
toolCallId: row.toolCallId,
|
|
@@ -1956,13 +3133,13 @@ var DrizzleGovernanceQueries = class {
|
|
|
1956
3133
|
*/
|
|
1957
3134
|
async runDetail(runId) {
|
|
1958
3135
|
const [row] = await this.db.select({
|
|
1959
|
-
run: agentRun,
|
|
1960
|
-
thread: agentThread
|
|
1961
|
-
}).from(agentRun).innerJoin(agentThread,
|
|
3136
|
+
run: this.t.agentRun,
|
|
3137
|
+
thread: this.t.agentThread
|
|
3138
|
+
}).from(this.t.agentRun).innerJoin(this.t.agentThread, eq3(this.t.agentRun.threadId, this.t.agentThread.id)).where(eq3(this.t.agentRun.id, runId)).limit(1);
|
|
1962
3139
|
if (row === void 0) {
|
|
1963
3140
|
return null;
|
|
1964
3141
|
}
|
|
1965
|
-
const toolCalls = await this.db.select().from(agentToolCall).where(
|
|
3142
|
+
const toolCalls = await this.db.select().from(this.t.agentToolCall).where(eq3(this.t.agentToolCall.runId, runId)).orderBy(asc3(this.t.agentToolCall.createdAt), asc3(this.t.agentToolCall.id));
|
|
1966
3143
|
return {
|
|
1967
3144
|
run: toRecentRunRow(row.run),
|
|
1968
3145
|
thread: {
|
|
@@ -1981,22 +3158,27 @@ var DrizzleGovernanceQueries = class {
|
|
|
1981
3158
|
* message. Soft-deleted threads are returned with `deleted: true`; an audit still needs them.
|
|
1982
3159
|
*/
|
|
1983
3160
|
async threadDetail(query) {
|
|
1984
|
-
const [thread] = await this.db.select().from(agentThread).where(
|
|
3161
|
+
const [thread] = await this.db.select().from(this.t.agentThread).where(eq3(this.t.agentThread.id, query.threadId)).limit(1);
|
|
1985
3162
|
if (thread === void 0) {
|
|
1986
3163
|
return null;
|
|
1987
3164
|
}
|
|
1988
3165
|
const pricing = await this.loadPricing();
|
|
1989
|
-
const usageRows = await this.db.select().from(agentTokenUsage).where(
|
|
3166
|
+
const usageRows = await this.db.select().from(this.t.agentTokenUsage).where(eq3(this.t.agentTokenUsage.threadId, thread.id));
|
|
1990
3167
|
const usage = rollupThreadUsage(usageRows.map(toUsageInput), pricing);
|
|
1991
3168
|
const [messageCountRow] = await this.db.select({
|
|
1992
3169
|
value: count()
|
|
1993
|
-
}).from(agentMessage).where(
|
|
1994
|
-
const messages = await this.db.select().from(agentMessage).where(
|
|
3170
|
+
}).from(this.t.agentMessage).where(eq3(this.t.agentMessage.threadId, thread.id));
|
|
3171
|
+
const messages = await this.db.select().from(this.t.agentMessage).where(eq3(this.t.agentMessage.threadId, thread.id)).orderBy(
|
|
3172
|
+
// Append order (see DrizzleAgentStore's message order), newest first.
|
|
3173
|
+
desc2(sql4`coalesce(${this.t.agentMessage.seq}, 0)`),
|
|
3174
|
+
desc2(this.t.agentMessage.createdAt),
|
|
3175
|
+
desc2(this.t.agentMessage.id)
|
|
3176
|
+
).limit(query.messageLimit);
|
|
1995
3177
|
const toolCallCounts = await this.toolCallCountsByMessage(messages.map((message) => message.id));
|
|
1996
3178
|
const [runTotalRow] = await this.db.select({
|
|
1997
3179
|
value: count()
|
|
1998
|
-
}).from(agentRun).where(
|
|
1999
|
-
const runs = await this.db.select().from(agentRun).where(
|
|
3180
|
+
}).from(this.t.agentRun).where(eq3(this.t.agentRun.threadId, thread.id));
|
|
3181
|
+
const runs = await this.db.select().from(this.t.agentRun).where(eq3(this.t.agentRun.threadId, thread.id)).orderBy(desc2(this.t.agentRun.startedAt), desc2(this.t.agentRun.id)).limit(query.runLimit);
|
|
2000
3182
|
return {
|
|
2001
3183
|
thread: {
|
|
2002
3184
|
threadId: thread.id,
|
|
@@ -2031,9 +3213,9 @@ var DrizzleGovernanceQueries = class {
|
|
|
2031
3213
|
return counts;
|
|
2032
3214
|
}
|
|
2033
3215
|
const rows = await this.db.select({
|
|
2034
|
-
messageId: agentToolCall.messageId,
|
|
3216
|
+
messageId: this.t.agentToolCall.messageId,
|
|
2035
3217
|
value: count()
|
|
2036
|
-
}).from(agentToolCall).where(inArray2(agentToolCall.messageId, messageIds)).groupBy(agentToolCall.messageId);
|
|
3218
|
+
}).from(this.t.agentToolCall).where(inArray2(this.t.agentToolCall.messageId, messageIds)).groupBy(this.t.agentToolCall.messageId);
|
|
2037
3219
|
for (const row of rows) {
|
|
2038
3220
|
counts.set(row.messageId, row.value);
|
|
2039
3221
|
}
|
|
@@ -2043,7 +3225,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2043
3225
|
|
|
2044
3226
|
// src/drizzle-memory-provider.ts
|
|
2045
3227
|
import { actorScope } from "@dudousxd/nestjs-agent-core";
|
|
2046
|
-
import { and as
|
|
3228
|
+
import { and as and4, eq as eq4, inArray as inArray3 } from "drizzle-orm";
|
|
2047
3229
|
function toRecord(row) {
|
|
2048
3230
|
return {
|
|
2049
3231
|
id: row.id,
|
|
@@ -2072,8 +3254,12 @@ var DrizzleMemoryProvider = class {
|
|
|
2072
3254
|
__name(this, "DrizzleMemoryProvider");
|
|
2073
3255
|
}
|
|
2074
3256
|
db;
|
|
3257
|
+
dialect;
|
|
3258
|
+
t;
|
|
2075
3259
|
constructor(db) {
|
|
2076
|
-
this.
|
|
3260
|
+
this.dialect = agentDialectOf(db);
|
|
3261
|
+
this.t = agentTablesFor(this.dialect);
|
|
3262
|
+
this.db = asBuilder(db);
|
|
2077
3263
|
}
|
|
2078
3264
|
/**
|
|
2079
3265
|
* Every memory visible at `scopes` — asked on EVERY turn, so it is one indexed `scope in (…)`
|
|
@@ -2087,7 +3273,7 @@ var DrizzleMemoryProvider = class {
|
|
|
2087
3273
|
if (scopes.length === 0) {
|
|
2088
3274
|
return [];
|
|
2089
3275
|
}
|
|
2090
|
-
const rows = await this.db.select().from(agentMemory).where(inArray3(agentMemory.scope, [
|
|
3276
|
+
const rows = await this.db.select().from(this.t.agentMemory).where(inArray3(this.t.agentMemory.scope, [
|
|
2091
3277
|
...scopes
|
|
2092
3278
|
]));
|
|
2093
3279
|
return rows.map(toRecord);
|
|
@@ -2103,10 +3289,8 @@ var DrizzleMemoryProvider = class {
|
|
|
2103
3289
|
* answer cannot be used to find out which memories exist about other people.
|
|
2104
3290
|
*/
|
|
2105
3291
|
async forget({ id, ctx }) {
|
|
2106
|
-
const deleted = await this.db.delete(agentMemory).where(
|
|
2107
|
-
|
|
2108
|
-
});
|
|
2109
|
-
return deleted.length > 0;
|
|
3292
|
+
const deleted = await affectedRows(this.dialect, this.db.delete(this.t.agentMemory).where(and4(eq4(this.t.agentMemory.id, id), eq4(this.t.agentMemory.scope, actorScope(ctx.actor)))), this.t.agentMemory.id);
|
|
3293
|
+
return deleted > 0;
|
|
2110
3294
|
}
|
|
2111
3295
|
/**
|
|
2112
3296
|
* Upsert on (`scope`, `key`) — one statement, against the unique index, rather than a read
|
|
@@ -2119,7 +3303,7 @@ var DrizzleMemoryProvider = class {
|
|
|
2119
3303
|
* rewriting `createdAt` would lose when the belief was first formed; reassigning `id` would
|
|
2120
3304
|
* invalidate the delete handle a person was already shown.
|
|
2121
3305
|
*/
|
|
2122
|
-
async write({ key, text:
|
|
3306
|
+
async write({ key: key2, text: text3, scope, origin, ctx }) {
|
|
2123
3307
|
assertAuthorMayWriteScope({
|
|
2124
3308
|
scope,
|
|
2125
3309
|
origin,
|
|
@@ -2132,28 +3316,40 @@ var DrizzleMemoryProvider = class {
|
|
|
2132
3316
|
originRunId: origin.runId ?? null,
|
|
2133
3317
|
originActorRef: origin.actorRef ?? null
|
|
2134
3318
|
};
|
|
2135
|
-
const
|
|
3319
|
+
const memory = this.t.agentMemory;
|
|
3320
|
+
const set = {
|
|
3321
|
+
text: text3,
|
|
3322
|
+
...columns,
|
|
3323
|
+
updatedAt: now
|
|
3324
|
+
};
|
|
3325
|
+
const insert = this.db.insert(memory).values({
|
|
2136
3326
|
id: crypto.randomUUID(),
|
|
2137
3327
|
scope,
|
|
2138
|
-
key,
|
|
2139
|
-
text:
|
|
3328
|
+
key: key2,
|
|
3329
|
+
text: text3,
|
|
2140
3330
|
...columns,
|
|
2141
3331
|
pinned: false,
|
|
2142
3332
|
createdAt: now,
|
|
2143
3333
|
updatedAt: now
|
|
2144
|
-
})
|
|
2145
|
-
|
|
2146
|
-
|
|
2147
|
-
|
|
2148
|
-
|
|
2149
|
-
|
|
2150
|
-
|
|
2151
|
-
|
|
2152
|
-
|
|
2153
|
-
|
|
2154
|
-
|
|
3334
|
+
});
|
|
3335
|
+
let row;
|
|
3336
|
+
if (this.dialect === "mysql") {
|
|
3337
|
+
await upsert(this.dialect, insert, [
|
|
3338
|
+
memory.scope,
|
|
3339
|
+
memory.key
|
|
3340
|
+
], set);
|
|
3341
|
+
[row] = await this.db.select().from(memory).where(and4(eq4(memory.scope, scope), eq4(memory.key, key2)));
|
|
3342
|
+
} else {
|
|
3343
|
+
[row] = await insert.onConflictDoUpdate({
|
|
3344
|
+
target: [
|
|
3345
|
+
memory.scope,
|
|
3346
|
+
memory.key
|
|
3347
|
+
],
|
|
3348
|
+
set
|
|
3349
|
+
}).returning();
|
|
3350
|
+
}
|
|
2155
3351
|
if (row === void 0) {
|
|
2156
|
-
throw new Error(`DrizzleMemoryProvider: the upsert of "${
|
|
3352
|
+
throw new Error(`DrizzleMemoryProvider: the upsert of "${key2}" at "${scope}" returned no row; the driver does not support RETURNING on conflict.`);
|
|
2157
3353
|
}
|
|
2158
3354
|
return toRecord(row);
|
|
2159
3355
|
}
|
|
@@ -2166,13 +3362,11 @@ var DrizzleMemoryProvider = class {
|
|
|
2166
3362
|
* `false` where there is no such id.
|
|
2167
3363
|
*/
|
|
2168
3364
|
async pin({ id, pinned }) {
|
|
2169
|
-
const updated = await this.db.update(agentMemory).set({
|
|
3365
|
+
const updated = await affectedRows(this.dialect, this.db.update(this.t.agentMemory).set({
|
|
2170
3366
|
pinned,
|
|
2171
3367
|
updatedAt: /* @__PURE__ */ new Date()
|
|
2172
|
-
}).where(
|
|
2173
|
-
|
|
2174
|
-
});
|
|
2175
|
-
return updated.length > 0;
|
|
3368
|
+
}).where(eq4(this.t.agentMemory.id, id)), this.t.agentMemory.id);
|
|
3369
|
+
return updated > 0;
|
|
2176
3370
|
}
|
|
2177
3371
|
};
|
|
2178
3372
|
function assertAuthorMayWriteScope({ scope, origin, ctx }) {
|
|
@@ -2184,20 +3378,24 @@ function assertAuthorMayWriteScope({ scope, origin, ctx }) {
|
|
|
2184
3378
|
__name(assertAuthorMayWriteScope, "assertAuthorMayWriteScope");
|
|
2185
3379
|
|
|
2186
3380
|
// src/drizzle-pricing-store.ts
|
|
2187
|
-
import { and as
|
|
3381
|
+
import { and as and5, eq as eq5 } from "drizzle-orm";
|
|
2188
3382
|
var DrizzlePricingStore = class {
|
|
2189
3383
|
static {
|
|
2190
3384
|
__name(this, "DrizzlePricingStore");
|
|
2191
3385
|
}
|
|
2192
3386
|
db;
|
|
3387
|
+
dialect;
|
|
3388
|
+
t;
|
|
2193
3389
|
constructor(db) {
|
|
2194
|
-
this.
|
|
3390
|
+
this.dialect = agentDialectOf(db);
|
|
3391
|
+
this.t = agentTablesFor(this.dialect);
|
|
3392
|
+
this.db = asBuilder(db);
|
|
2195
3393
|
}
|
|
2196
3394
|
async upsertModelPrice(input) {
|
|
2197
|
-
await this.db.update(agentModelPricing).set({
|
|
3395
|
+
await this.db.update(this.t.agentModelPricing).set({
|
|
2198
3396
|
isCurrent: false
|
|
2199
|
-
}).where(
|
|
2200
|
-
await this.db.insert(agentModelPricing).values({
|
|
3397
|
+
}).where(and5(eq5(this.t.agentModelPricing.modelId, input.modelId), eq5(this.t.agentModelPricing.isCurrent, true)));
|
|
3398
|
+
await this.db.insert(this.t.agentModelPricing).values({
|
|
2201
3399
|
id: crypto.randomUUID(),
|
|
2202
3400
|
modelId: input.modelId,
|
|
2203
3401
|
inputPricePer1m: input.inputPricePer1m,
|
|
@@ -2209,7 +3407,7 @@ var DrizzlePricingStore = class {
|
|
|
2209
3407
|
});
|
|
2210
3408
|
}
|
|
2211
3409
|
async listCurrentPrices() {
|
|
2212
|
-
const rows = await this.db.select().from(agentModelPricing).where(
|
|
3410
|
+
const rows = await this.db.select().from(this.t.agentModelPricing).where(eq5(this.t.agentModelPricing.isCurrent, true));
|
|
2213
3411
|
return rows.map((row) => ({
|
|
2214
3412
|
modelId: row.modelId,
|
|
2215
3413
|
inputPricePer1m: row.inputPricePer1m,
|
|
@@ -2227,52 +3425,47 @@ var DrizzlePricingStore = class {
|
|
|
2227
3425
|
|
|
2228
3426
|
// src/drizzle-token-stream-sink.ts
|
|
2229
3427
|
import { SqlTokenStreamSink } from "@dudousxd/nestjs-agent-core";
|
|
2230
|
-
import { and as
|
|
2231
|
-
function isUniqueViolation(error) {
|
|
2232
|
-
for (let current = error; current !== null && typeof current === "object"; ) {
|
|
2233
|
-
const code = current.code;
|
|
2234
|
-
if (typeof code === "string" && code.startsWith("SQLITE_CONSTRAINT")) return true;
|
|
2235
|
-
current = current.cause;
|
|
2236
|
-
}
|
|
2237
|
-
return false;
|
|
2238
|
-
}
|
|
2239
|
-
__name(isUniqueViolation, "isUniqueViolation");
|
|
3428
|
+
import { and as and6, asc as asc4, eq as eq6, gt as gt2, inArray as inArray4, lt, max as max3, sql as sql5 } from "drizzle-orm";
|
|
2240
3429
|
var DrizzleStreamFrameTable = class {
|
|
2241
3430
|
static {
|
|
2242
3431
|
__name(this, "DrizzleStreamFrameTable");
|
|
2243
3432
|
}
|
|
2244
3433
|
db;
|
|
3434
|
+
dialect;
|
|
3435
|
+
t;
|
|
2245
3436
|
constructor(db) {
|
|
2246
|
-
this.
|
|
3437
|
+
this.dialect = agentDialectOf(db);
|
|
3438
|
+
this.t = agentTablesFor(this.dialect);
|
|
3439
|
+
this.db = asBuilder(db);
|
|
2247
3440
|
}
|
|
2248
3441
|
async append(runId, row) {
|
|
2249
|
-
await this.db.
|
|
3442
|
+
await runSql(this.db, this.dialect, sql5`INSERT INTO agent_stream_frame (run_id, seq, frame, error, created_at)
|
|
2250
3443
|
SELECT ${runId}, COALESCE(MAX(seq), 0) + 1, ${row.frame}, ${row.error}, ${row.createdAt}
|
|
2251
3444
|
FROM agent_stream_frame WHERE run_id = ${runId}`);
|
|
2252
3445
|
}
|
|
2253
3446
|
async read(runId, after, limit) {
|
|
2254
3447
|
return this.db.select({
|
|
2255
|
-
seq: agentStreamFrame.seq,
|
|
2256
|
-
frame: agentStreamFrame.frame,
|
|
2257
|
-
error: agentStreamFrame.error
|
|
2258
|
-
}).from(agentStreamFrame).where(
|
|
3448
|
+
seq: this.t.agentStreamFrame.seq,
|
|
3449
|
+
frame: this.t.agentStreamFrame.frame,
|
|
3450
|
+
error: this.t.agentStreamFrame.error
|
|
3451
|
+
}).from(this.t.agentStreamFrame).where(and6(eq6(this.t.agentStreamFrame.runId, runId), gt2(this.t.agentStreamFrame.seq, after))).orderBy(asc4(this.t.agentStreamFrame.seq)).limit(limit);
|
|
2259
3452
|
}
|
|
2260
3453
|
async has(runId) {
|
|
2261
3454
|
const rows = await this.db.select({
|
|
2262
|
-
seq: agentStreamFrame.seq
|
|
2263
|
-
}).from(agentStreamFrame).where(
|
|
3455
|
+
seq: this.t.agentStreamFrame.seq
|
|
3456
|
+
}).from(this.t.agentStreamFrame).where(eq6(this.t.agentStreamFrame.runId, runId)).limit(1);
|
|
2264
3457
|
return rows.length > 0;
|
|
2265
3458
|
}
|
|
2266
3459
|
async remove(runIds) {
|
|
2267
3460
|
if (runIds.length === 0) return;
|
|
2268
|
-
await this.db.delete(agentStreamFrame).where(inArray4(agentStreamFrame.runId, [
|
|
3461
|
+
await this.db.delete(this.t.agentStreamFrame).where(inArray4(this.t.agentStreamFrame.runId, [
|
|
2269
3462
|
...runIds
|
|
2270
3463
|
]));
|
|
2271
3464
|
}
|
|
2272
3465
|
async lapsedRuns(cutoff) {
|
|
2273
3466
|
const rows = await this.db.select({
|
|
2274
|
-
runId: agentStreamFrame.runId
|
|
2275
|
-
}).from(agentStreamFrame).groupBy(agentStreamFrame.runId).having(lt(
|
|
3467
|
+
runId: this.t.agentStreamFrame.runId
|
|
3468
|
+
}).from(this.t.agentStreamFrame).groupBy(this.t.agentStreamFrame.runId).having(lt(max3(this.t.agentStreamFrame.createdAt), cutoff));
|
|
2276
3469
|
return rows.map((row) => row.runId);
|
|
2277
3470
|
}
|
|
2278
3471
|
isUniqueViolation(error) {
|
|
@@ -2289,54 +3482,60 @@ var DrizzleTokenStreamSink = class extends SqlTokenStreamSink {
|
|
|
2289
3482
|
};
|
|
2290
3483
|
|
|
2291
3484
|
// src/drizzle-confirm-token-store.ts
|
|
2292
|
-
import { eq as
|
|
3485
|
+
import { eq as eq7, lt as lt2 } from "drizzle-orm";
|
|
2293
3486
|
var DrizzleConfirmTokenStore = class {
|
|
2294
3487
|
static {
|
|
2295
3488
|
__name(this, "DrizzleConfirmTokenStore");
|
|
2296
3489
|
}
|
|
2297
3490
|
db;
|
|
3491
|
+
dialect;
|
|
3492
|
+
t;
|
|
2298
3493
|
constructor(db) {
|
|
2299
|
-
this.
|
|
3494
|
+
this.dialect = agentDialectOf(db);
|
|
3495
|
+
this.t = agentTablesFor(this.dialect);
|
|
3496
|
+
this.db = asBuilder(db);
|
|
2300
3497
|
}
|
|
2301
3498
|
async claim(input) {
|
|
2302
|
-
const
|
|
3499
|
+
const row = {
|
|
2303
3500
|
hash: input.hash,
|
|
2304
3501
|
actorRef: input.actorRef,
|
|
2305
3502
|
tool: input.tool,
|
|
2306
3503
|
expiresAt: input.expiresAt,
|
|
2307
3504
|
createdAt: Date.now()
|
|
2308
|
-
}
|
|
2309
|
-
|
|
2310
|
-
|
|
2311
|
-
|
|
3505
|
+
};
|
|
3506
|
+
const table = this.t.agentConfirmToken;
|
|
3507
|
+
if (this.dialect === "mysql") {
|
|
3508
|
+
const insert = this.db.insert(table);
|
|
3509
|
+
return mysqlAffectedRows(await insert.ignore().values(row)) === 1;
|
|
3510
|
+
}
|
|
3511
|
+
const inserted = await affectedRows(this.dialect, this.db.insert(table).values(row).onConflictDoNothing(), table.hash);
|
|
3512
|
+
return inserted === 1;
|
|
2312
3513
|
}
|
|
2313
3514
|
async release(hash) {
|
|
2314
|
-
await this.db.delete(agentConfirmToken).where(
|
|
3515
|
+
await this.db.delete(this.t.agentConfirmToken).where(eq7(this.t.agentConfirmToken.hash, hash));
|
|
2315
3516
|
}
|
|
2316
3517
|
async purgeExpired(now = Date.now()) {
|
|
2317
|
-
const
|
|
2318
|
-
|
|
2319
|
-
});
|
|
2320
|
-
return purged.length;
|
|
3518
|
+
const table = this.t.agentConfirmToken;
|
|
3519
|
+
return affectedRows(this.dialect, this.db.delete(table).where(lt2(table.expiresAt, now)), table.hash);
|
|
2321
3520
|
}
|
|
2322
3521
|
};
|
|
2323
3522
|
|
|
2324
3523
|
// src/drizzle-rag-ingestion-log.ts
|
|
2325
3524
|
import { subscribe, unsubscribe } from "diagnostics_channel";
|
|
2326
3525
|
import { Injectable, Logger } from "@nestjs/common";
|
|
2327
|
-
import { and as
|
|
2328
|
-
function _ts_decorate(decorators, target,
|
|
2329
|
-
var c = arguments.length, r = c < 3 ? target : desc4 === null ? desc4 = Object.getOwnPropertyDescriptor(target,
|
|
3526
|
+
import { and as and7, asc as asc5, count as count2, desc as desc3, eq as eq8, gt as gt3, lt as lt3, or as or3 } from "drizzle-orm";
|
|
3527
|
+
function _ts_decorate(decorators, target, key2, desc4) {
|
|
3528
|
+
var c = arguments.length, r = c < 3 ? target : desc4 === null ? desc4 = Object.getOwnPropertyDescriptor(target, key2) : desc4, d;
|
|
2330
3529
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2331
|
-
r = Reflect.decorate(decorators, target,
|
|
3530
|
+
r = Reflect.decorate(decorators, target, key2, desc4);
|
|
2332
3531
|
} else {
|
|
2333
3532
|
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2334
3533
|
if (d = decorators[i]) {
|
|
2335
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target,
|
|
3534
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key2, r) : d(target, key2)) || r;
|
|
2336
3535
|
}
|
|
2337
3536
|
}
|
|
2338
3537
|
}
|
|
2339
|
-
return c > 3 && r && Object.defineProperty(target,
|
|
3538
|
+
return c > 3 && r && Object.defineProperty(target, key2, r), r;
|
|
2340
3539
|
}
|
|
2341
3540
|
__name(_ts_decorate, "_ts_decorate");
|
|
2342
3541
|
function _ts_metadata(metadataKey, metadataValue) {
|
|
@@ -2373,7 +3572,7 @@ function num(value) {
|
|
|
2373
3572
|
__name(num, "num");
|
|
2374
3573
|
var RAG_INGESTION_LOG_PAGE_ORDER = [
|
|
2375
3574
|
desc3(ragIngestionLog.updatedAt),
|
|
2376
|
-
|
|
3575
|
+
asc5(ragIngestionLog.documentId)
|
|
2377
3576
|
];
|
|
2378
3577
|
var DEFAULT_PAGE_SIZE = 200;
|
|
2379
3578
|
var DEFAULT_BATCH_SIZE = 200;
|
|
@@ -2382,20 +3581,27 @@ function batches(batchSize) {
|
|
|
2382
3581
|
return Number.isFinite(requested) && requested >= 1 ? requested : DEFAULT_BATCH_SIZE;
|
|
2383
3582
|
}
|
|
2384
3583
|
__name(batches, "batches");
|
|
2385
|
-
|
|
2386
|
-
|
|
2387
|
-
|
|
2388
|
-
|
|
3584
|
+
function cursorColumns(log) {
|
|
3585
|
+
return {
|
|
3586
|
+
documentId: log.documentId,
|
|
3587
|
+
updatedAt: log.updatedAt
|
|
3588
|
+
};
|
|
3589
|
+
}
|
|
3590
|
+
__name(cursorColumns, "cursorColumns");
|
|
2389
3591
|
var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
2390
3592
|
static {
|
|
2391
3593
|
__name(this, "DrizzleRagIngestionLog");
|
|
2392
3594
|
}
|
|
2393
|
-
db;
|
|
2394
3595
|
logger = new Logger(_DrizzleRagIngestionLog.name);
|
|
2395
3596
|
teardowns = [];
|
|
2396
3597
|
inFlight = /* @__PURE__ */ new Set();
|
|
3598
|
+
db;
|
|
3599
|
+
dialect;
|
|
3600
|
+
t;
|
|
2397
3601
|
constructor(db) {
|
|
2398
|
-
this.
|
|
3602
|
+
this.dialect = agentDialectOf(db);
|
|
3603
|
+
this.t = agentTablesFor(this.dialect);
|
|
3604
|
+
this.db = asBuilder(db);
|
|
2399
3605
|
}
|
|
2400
3606
|
onModuleInit() {
|
|
2401
3607
|
for (const channel of CHANNELS) {
|
|
@@ -2424,7 +3630,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
2424
3630
|
}
|
|
2425
3631
|
/** The latest recorded outcome per document, newest first. */
|
|
2426
3632
|
async list(query = {}) {
|
|
2427
|
-
const rows = this.db.select().from(ragIngestionLog).where(this.where(query)).orderBy(...RAG_INGESTION_LOG_PAGE_ORDER).limit(query.limit ?? DEFAULT_PAGE_SIZE);
|
|
3633
|
+
const rows = this.db.select().from(this.t.ragIngestionLog).where(this.where(query)).orderBy(...RAG_INGESTION_LOG_PAGE_ORDER).limit(query.limit ?? DEFAULT_PAGE_SIZE);
|
|
2428
3634
|
return query.offset === void 0 ? rows : rows.offset(query.offset);
|
|
2429
3635
|
}
|
|
2430
3636
|
/**
|
|
@@ -2438,7 +3644,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
2438
3644
|
async listPage(query = {}) {
|
|
2439
3645
|
const [totalRow] = await this.db.select({
|
|
2440
3646
|
value: count2()
|
|
2441
|
-
}).from(ragIngestionLog).where(this.where(query));
|
|
3647
|
+
}).from(this.t.ragIngestionLog).where(this.where(query));
|
|
2442
3648
|
return {
|
|
2443
3649
|
rows: await this.list(query),
|
|
2444
3650
|
total: totalRow?.value ?? 0
|
|
@@ -2491,7 +3697,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
2491
3697
|
* sweep is run. A sweep that stops early stops by `break`ing out of the `for await`.
|
|
2492
3698
|
*/
|
|
2493
3699
|
iterate(where = {}, options = {}) {
|
|
2494
|
-
return this.sweep(where, batches(options.batchSize), options.after, (filter, limit) => this.db.select().from(ragIngestionLog).where(filter).orderBy(...RAG_INGESTION_LOG_PAGE_ORDER).limit(limit));
|
|
3700
|
+
return this.sweep(where, batches(options.batchSize), options.after, (filter, limit) => this.db.select().from(this.t.ragIngestionLog).where(filter).orderBy(...RAG_INGESTION_LOG_PAGE_ORDER).limit(limit));
|
|
2495
3701
|
}
|
|
2496
3702
|
/**
|
|
2497
3703
|
* Just the document ids of the matching rows, in {@link RAG_INGESTION_LOG_PAGE_ORDER}.
|
|
@@ -2508,7 +3714,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
2508
3714
|
*/
|
|
2509
3715
|
async listDocumentIds(where = {}, options = {}) {
|
|
2510
3716
|
const ids = [];
|
|
2511
|
-
const rows = this.sweep(where, batches(options.batchSize), void 0, (filter, limit) => this.db.select(
|
|
3717
|
+
const rows = this.sweep(where, batches(options.batchSize), void 0, (filter, limit) => this.db.select(cursorColumns(this.t.ragIngestionLog)).from(this.t.ragIngestionLog).where(filter).orderBy(...RAG_INGESTION_LOG_PAGE_ORDER).limit(limit));
|
|
2512
3718
|
for await (const row of rows) {
|
|
2513
3719
|
ids.push(row.documentId);
|
|
2514
3720
|
}
|
|
@@ -2516,22 +3722,18 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
2516
3722
|
}
|
|
2517
3723
|
/** The latest recorded outcome for one document, or null if it was never attempted. */
|
|
2518
3724
|
async get(documentId) {
|
|
2519
|
-
const [row] = await this.db.select().from(ragIngestionLog).where(
|
|
3725
|
+
const [row] = await this.db.select().from(this.t.ragIngestionLog).where(eq8(this.t.ragIngestionLog.documentId, documentId));
|
|
2520
3726
|
return row ?? null;
|
|
2521
3727
|
}
|
|
2522
3728
|
/** Forget one document's record. Returns whether a row was actually removed. */
|
|
2523
3729
|
async remove(documentId) {
|
|
2524
|
-
const removed = await this.db.delete(ragIngestionLog).where(
|
|
2525
|
-
|
|
2526
|
-
});
|
|
2527
|
-
return removed.length > 0;
|
|
3730
|
+
const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq8(this.t.ragIngestionLog.documentId, documentId)), this.t.ragIngestionLog.documentId);
|
|
3731
|
+
return removed > 0;
|
|
2528
3732
|
}
|
|
2529
3733
|
/** Forget every record for a collection — for when the collection itself is deleted. */
|
|
2530
3734
|
async removeByCollection(collection) {
|
|
2531
|
-
const removed = await this.db.delete(ragIngestionLog).where(
|
|
2532
|
-
|
|
2533
|
-
});
|
|
2534
|
-
return removed.length;
|
|
3735
|
+
const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq8(this.t.ragIngestionLog.collection, collection)), this.t.ragIngestionLog.documentId);
|
|
3736
|
+
return removed;
|
|
2535
3737
|
}
|
|
2536
3738
|
/**
|
|
2537
3739
|
* The keyset sweep both {@link iterate} and {@link listDocumentIds} are made of. `page` decides
|
|
@@ -2560,7 +3762,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
2560
3762
|
}
|
|
2561
3763
|
}
|
|
2562
3764
|
where(query) {
|
|
2563
|
-
return
|
|
3765
|
+
return and7(query.collection !== void 0 ? eq8(this.t.ragIngestionLog.collection, query.collection) : void 0, query.status !== void 0 ? eq8(this.t.ragIngestionLog.status, query.status) : void 0);
|
|
2564
3766
|
}
|
|
2565
3767
|
/**
|
|
2566
3768
|
* The coordinates filter AND'd with "strictly after `cursor` in
|
|
@@ -2575,7 +3777,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
2575
3777
|
if (cursor === void 0) {
|
|
2576
3778
|
return base;
|
|
2577
3779
|
}
|
|
2578
|
-
return
|
|
3780
|
+
return and7(base, or3(lt3(this.t.ragIngestionLog.updatedAt, cursor.updatedAt), and7(eq8(this.t.ragIngestionLog.updatedAt, cursor.updatedAt), gt3(this.t.ragIngestionLog.documentId, cursor.documentId))));
|
|
2579
3781
|
}
|
|
2580
3782
|
/**
|
|
2581
3783
|
* Upsert one outcome. Keyed by document id so the row always reflects the *current* state — a
|
|
@@ -2623,14 +3825,11 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
2623
3825
|
size
|
|
2624
3826
|
} : {}
|
|
2625
3827
|
};
|
|
2626
|
-
await this.db.insert(ragIngestionLog).values({
|
|
3828
|
+
await upsert(this.dialect, this.db.insert(this.t.ragIngestionLog).values({
|
|
2627
3829
|
documentId,
|
|
2628
3830
|
createdAt: now,
|
|
2629
3831
|
...outcome
|
|
2630
|
-
}).
|
|
2631
|
-
target: ragIngestionLog.documentId,
|
|
2632
|
-
set: outcome
|
|
2633
|
-
});
|
|
3832
|
+
}), this.t.ragIngestionLog.documentId, outcome);
|
|
2634
3833
|
} catch (error) {
|
|
2635
3834
|
this.logger.warn(`Could not record RAG ingestion outcome for ${documentId}: ${error instanceof Error ? error.message : String(error)}`);
|
|
2636
3835
|
}
|
|
@@ -2653,18 +3852,18 @@ DrizzleRagIngestionLog = _ts_decorate([
|
|
|
2653
3852
|
// src/drizzle-agent-store.module.ts
|
|
2654
3853
|
import { AGENT_CONFIRM_TOKEN_STORE, AGENT_GOVERNANCE_QUERIES, AGENT_PRICING_STORE, AGENT_STORE } from "@dudousxd/nestjs-agent-core";
|
|
2655
3854
|
import { Module } from "@nestjs/common";
|
|
2656
|
-
function _ts_decorate2(decorators, target,
|
|
2657
|
-
var c = arguments.length, r = c < 3 ? target : desc4 === null ? desc4 = Object.getOwnPropertyDescriptor(target,
|
|
3855
|
+
function _ts_decorate2(decorators, target, key2, desc4) {
|
|
3856
|
+
var c = arguments.length, r = c < 3 ? target : desc4 === null ? desc4 = Object.getOwnPropertyDescriptor(target, key2) : desc4, d;
|
|
2658
3857
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
2659
|
-
r = Reflect.decorate(decorators, target,
|
|
3858
|
+
r = Reflect.decorate(decorators, target, key2, desc4);
|
|
2660
3859
|
} else {
|
|
2661
3860
|
for (var i = decorators.length - 1; i >= 0; i--) {
|
|
2662
3861
|
if (d = decorators[i]) {
|
|
2663
|
-
r = (c < 3 ? d(r) : c > 3 ? d(target,
|
|
3862
|
+
r = (c < 3 ? d(r) : c > 3 ? d(target, key2, r) : d(target, key2)) || r;
|
|
2664
3863
|
}
|
|
2665
3864
|
}
|
|
2666
3865
|
}
|
|
2667
|
-
return c > 3 && r && Object.defineProperty(target,
|
|
3866
|
+
return c > 3 && r && Object.defineProperty(target, key2, r), r;
|
|
2668
3867
|
}
|
|
2669
3868
|
__name(_ts_decorate2, "_ts_decorate");
|
|
2670
3869
|
var DrizzleAgentStoreModule = class _DrizzleAgentStoreModule {
|
|
@@ -2753,6 +3952,7 @@ DrizzleAgentStoreModule = _ts_decorate2([
|
|
|
2753
3952
|
Module({})
|
|
2754
3953
|
], DrizzleAgentStoreModule);
|
|
2755
3954
|
export {
|
|
3955
|
+
DrizzleActionProposalStore,
|
|
2756
3956
|
DrizzleAgentStore,
|
|
2757
3957
|
DrizzleAgentStoreModule,
|
|
2758
3958
|
DrizzleConfirmTokenStore,
|
|
@@ -2763,18 +3963,23 @@ export {
|
|
|
2763
3963
|
DrizzleStreamFrameTable,
|
|
2764
3964
|
DrizzleTokenStreamSink,
|
|
2765
3965
|
RAG_INGESTION_LOG_PAGE_ORDER,
|
|
3966
|
+
agentActionProposal,
|
|
2766
3967
|
agentConfirmToken,
|
|
3968
|
+
agentDialectOf,
|
|
2767
3969
|
agentMemory,
|
|
2768
3970
|
agentMessage,
|
|
2769
3971
|
agentModelPricing,
|
|
2770
3972
|
agentQueuedMessage,
|
|
2771
3973
|
agentRun,
|
|
2772
3974
|
agentSchema,
|
|
3975
|
+
agentSchemaDdl,
|
|
2773
3976
|
agentStreamFrame,
|
|
2774
3977
|
agentThread,
|
|
2775
3978
|
agentTokenUsage,
|
|
2776
3979
|
agentToolCall,
|
|
2777
3980
|
ensureAgentSchema,
|
|
3981
|
+
mysqlAgentSchema,
|
|
3982
|
+
pgAgentSchema,
|
|
2778
3983
|
ragIngestionLog
|
|
2779
3984
|
};
|
|
2780
3985
|
//# sourceMappingURL=index.js.map
|