@dudousxd/nestjs-agent-store-drizzle 0.24.0 → 0.26.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 +128 -22
- package/dist/index.cjs +889 -171
- package/dist/index.cjs.map +1 -1
- package/dist/index.d.cts +2047 -490
- package/dist/index.d.ts +2047 -490
- package/dist/index.js +832 -116
- package/dist/index.js.map +1 -1
- package/package.json +7 -6
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"
|
|
@@ -84,6 +85,7 @@ var agentMessage = sqliteTable("agent_message", {
|
|
|
84
85
|
index("agent_message_thread_created_idx").on(table.threadId, table.createdAt)
|
|
85
86
|
]);
|
|
86
87
|
var agentToolCall = sqliteTable("agent_tool_call", {
|
|
88
|
+
proposalId: text("proposal_id"),
|
|
87
89
|
id: text("id").primaryKey(),
|
|
88
90
|
messageId: text("message_id").notNull().references(() => agentMessage.id, {
|
|
89
91
|
onDelete: "cascade"
|
|
@@ -108,6 +110,10 @@ var agentToolCall = sqliteTable("agent_tool_call", {
|
|
|
108
110
|
}),
|
|
109
111
|
/** The run (turn) this call belongs to, for a trace deep-link; null for a pre-rollout row. */
|
|
110
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(),
|
|
111
117
|
/** Who had to approve it (`requester` or a role); null for a call no policy put to anyone. */
|
|
112
118
|
approver: text("approver"),
|
|
113
119
|
/** When the approval request lapses; null → never. */
|
|
@@ -124,6 +130,9 @@ var agentToolCall = sqliteTable("agent_tool_call", {
|
|
|
124
130
|
index("agent_tool_call_message_idx").on(table.messageId)
|
|
125
131
|
]);
|
|
126
132
|
var agentQueuedMessage = sqliteTable("agent_queued_message", {
|
|
133
|
+
uiCapabilities: text("ui_capabilities", {
|
|
134
|
+
mode: "json"
|
|
135
|
+
}).$type(),
|
|
127
136
|
id: text("id").primaryKey(),
|
|
128
137
|
threadId: text("thread_id").notNull().references(() => agentThread.id, {
|
|
129
138
|
onDelete: "cascade"
|
|
@@ -301,7 +310,35 @@ var agentStreamFrame = sqliteTable("agent_stream_frame", {
|
|
|
301
310
|
]
|
|
302
311
|
})
|
|
303
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
|
+
]);
|
|
304
340
|
var agentSchema = {
|
|
341
|
+
agentActionProposal,
|
|
305
342
|
agentThread,
|
|
306
343
|
agentMessage,
|
|
307
344
|
agentQueuedMessage,
|
|
@@ -327,7 +364,8 @@ import { MySqlDatabase } from "drizzle-orm/mysql-core";
|
|
|
327
364
|
import { PgDatabase } from "drizzle-orm/pg-core";
|
|
328
365
|
|
|
329
366
|
// src/schema-mysql.ts
|
|
330
|
-
import {
|
|
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";
|
|
331
369
|
var ts = /* @__PURE__ */ __name((name) => datetime(name, {
|
|
332
370
|
mode: "date",
|
|
333
371
|
fsp: 3
|
|
@@ -359,6 +397,7 @@ var agentMessage2 = mysqlTable("agent_message", {
|
|
|
359
397
|
onDelete: "cascade"
|
|
360
398
|
}),
|
|
361
399
|
role: key("role").$type().notNull(),
|
|
400
|
+
actionProposalOutcome: longtext("action_proposal_outcome"),
|
|
362
401
|
content: longtext("content").notNull(),
|
|
363
402
|
toolCalls: json("tool_calls").$type(),
|
|
364
403
|
toolResults: json("tool_results").$type(),
|
|
@@ -379,6 +418,7 @@ var agentMessage2 = mysqlTable("agent_message", {
|
|
|
379
418
|
index2("agent_message_thread_created_idx").on(table.threadId, table.createdAt)
|
|
380
419
|
]);
|
|
381
420
|
var agentToolCall2 = mysqlTable("agent_tool_call", {
|
|
421
|
+
proposalId: key("proposal_id"),
|
|
382
422
|
id: key("id").primaryKey(),
|
|
383
423
|
messageId: key("message_id").notNull().references(() => agentMessage2.id, {
|
|
384
424
|
onDelete: "cascade"
|
|
@@ -394,6 +434,7 @@ var agentToolCall2 = mysqlTable("agent_tool_call", {
|
|
|
394
434
|
createdAt: ts("created_at").notNull(),
|
|
395
435
|
executedAt: ts("executed_at"),
|
|
396
436
|
runId: key("run_id"),
|
|
437
|
+
confirmation: json("confirmation").$type(),
|
|
397
438
|
approver: key("approver"),
|
|
398
439
|
expiresAt: ts("expires_at"),
|
|
399
440
|
remember: boolean("remember"),
|
|
@@ -402,6 +443,7 @@ var agentToolCall2 = mysqlTable("agent_tool_call", {
|
|
|
402
443
|
index2("agent_tool_call_message_idx").on(table.messageId)
|
|
403
444
|
]);
|
|
404
445
|
var agentQueuedMessage2 = mysqlTable("agent_queued_message", {
|
|
446
|
+
uiCapabilities: json("ui_capabilities").$type(),
|
|
405
447
|
id: key("id").primaryKey(),
|
|
406
448
|
threadId: key("thread_id").notNull().references(() => agentThread2.id, {
|
|
407
449
|
onDelete: "cascade"
|
|
@@ -531,7 +573,52 @@ var agentStreamFrame2 = mysqlTable("agent_stream_frame", {
|
|
|
531
573
|
]
|
|
532
574
|
})
|
|
533
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
|
+
]);
|
|
534
620
|
var mysqlAgentSchema = {
|
|
621
|
+
agentActionProposal: agentActionProposal2,
|
|
535
622
|
agentThread: agentThread2,
|
|
536
623
|
agentMessage: agentMessage2,
|
|
537
624
|
agentQueuedMessage: agentQueuedMessage2,
|
|
@@ -546,7 +633,8 @@ var mysqlAgentSchema = {
|
|
|
546
633
|
};
|
|
547
634
|
|
|
548
635
|
// src/schema-pg.ts
|
|
549
|
-
import {
|
|
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";
|
|
550
638
|
var ts2 = /* @__PURE__ */ __name((name) => timestamp(name, {
|
|
551
639
|
withTimezone: true,
|
|
552
640
|
precision: 3,
|
|
@@ -576,6 +664,7 @@ var agentMessage3 = pgTable("agent_message", {
|
|
|
576
664
|
onDelete: "cascade"
|
|
577
665
|
}),
|
|
578
666
|
role: text2("role").$type().notNull(),
|
|
667
|
+
actionProposalOutcome: text2("action_proposal_outcome"),
|
|
579
668
|
content: text2("content").notNull(),
|
|
580
669
|
toolCalls: jsonb("tool_calls").$type(),
|
|
581
670
|
toolResults: jsonb("tool_results").$type(),
|
|
@@ -596,6 +685,7 @@ var agentMessage3 = pgTable("agent_message", {
|
|
|
596
685
|
index3("agent_message_thread_created_idx").on(table.threadId, table.createdAt)
|
|
597
686
|
]);
|
|
598
687
|
var agentToolCall3 = pgTable("agent_tool_call", {
|
|
688
|
+
proposalId: text2("proposal_id"),
|
|
599
689
|
id: text2("id").primaryKey(),
|
|
600
690
|
messageId: text2("message_id").notNull().references(() => agentMessage3.id, {
|
|
601
691
|
onDelete: "cascade"
|
|
@@ -611,6 +701,7 @@ var agentToolCall3 = pgTable("agent_tool_call", {
|
|
|
611
701
|
createdAt: ts2("created_at").notNull(),
|
|
612
702
|
executedAt: ts2("executed_at"),
|
|
613
703
|
runId: text2("run_id"),
|
|
704
|
+
confirmation: jsonb("confirmation").$type(),
|
|
614
705
|
approver: text2("approver"),
|
|
615
706
|
expiresAt: ts2("expires_at"),
|
|
616
707
|
remember: boolean2("remember"),
|
|
@@ -619,6 +710,7 @@ var agentToolCall3 = pgTable("agent_tool_call", {
|
|
|
619
710
|
index3("agent_tool_call_message_idx").on(table.messageId)
|
|
620
711
|
]);
|
|
621
712
|
var agentQueuedMessage3 = pgTable("agent_queued_message", {
|
|
713
|
+
uiCapabilities: jsonb("ui_capabilities").$type(),
|
|
622
714
|
id: text2("id").primaryKey(),
|
|
623
715
|
threadId: text2("thread_id").notNull().references(() => agentThread3.id, {
|
|
624
716
|
onDelete: "cascade"
|
|
@@ -748,7 +840,50 @@ var agentStreamFrame3 = pgTable("agent_stream_frame", {
|
|
|
748
840
|
]
|
|
749
841
|
})
|
|
750
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
|
+
]);
|
|
751
885
|
var pgAgentSchema = {
|
|
886
|
+
agentActionProposal: agentActionProposal3,
|
|
752
887
|
agentThread: agentThread3,
|
|
753
888
|
agentMessage: agentMessage3,
|
|
754
889
|
agentQueuedMessage: agentQueuedMessage3,
|
|
@@ -1000,8 +1135,516 @@ async function heal(db, dialect) {
|
|
|
1000
1135
|
__name(heal, "heal");
|
|
1001
1136
|
|
|
1002
1137
|
// src/drizzle-agent-store.ts
|
|
1003
|
-
import { toolCallApprovalFromRow } from "@dudousxd/nestjs-agent-core";
|
|
1004
|
-
import { and, asc, desc, eq, gte, inArray, isNotNull, isNull, lte, max, min, or, sql as
|
|
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
|
+
"PostgresJsDatabase",
|
|
1153
|
+
"PostgresJsTransaction",
|
|
1154
|
+
"MySql2Database",
|
|
1155
|
+
"MySql2Transaction",
|
|
1156
|
+
"LibSQLDatabase",
|
|
1157
|
+
"LibSQLTransaction"
|
|
1158
|
+
].includes(kind)) return "async";
|
|
1159
|
+
return "unsupported";
|
|
1160
|
+
}
|
|
1161
|
+
__name(actionProposalTransactionMode, "actionProposalTransactionMode");
|
|
1162
|
+
|
|
1163
|
+
// src/drizzle-action-proposal-store.ts
|
|
1164
|
+
var DrizzleActionProposalStore = class {
|
|
1165
|
+
static {
|
|
1166
|
+
__name(this, "DrizzleActionProposalStore");
|
|
1167
|
+
}
|
|
1168
|
+
db;
|
|
1169
|
+
rawDb;
|
|
1170
|
+
actionProposalAdmissionSupported;
|
|
1171
|
+
synchronousSqlite;
|
|
1172
|
+
dialect;
|
|
1173
|
+
table;
|
|
1174
|
+
clock;
|
|
1175
|
+
constructor(db, options = {}) {
|
|
1176
|
+
this.rawDb = db;
|
|
1177
|
+
const kind = db.constructor[entityKind];
|
|
1178
|
+
const transactionMode = actionProposalTransactionMode(kind);
|
|
1179
|
+
this.synchronousSqlite = transactionMode === "sync";
|
|
1180
|
+
this.actionProposalAdmissionSupported = transactionMode !== "unsupported";
|
|
1181
|
+
this.dialect = agentDialectOf(db);
|
|
1182
|
+
this.table = agentTablesFor(this.dialect).agentActionProposal;
|
|
1183
|
+
this.db = asBuilder(db);
|
|
1184
|
+
this.clock = options.clock ?? Date.now;
|
|
1185
|
+
}
|
|
1186
|
+
async createActionProposal(input) {
|
|
1187
|
+
const proposal = initialActionProposal(input, this.clock());
|
|
1188
|
+
const row = {
|
|
1189
|
+
id: physicalId(input.id),
|
|
1190
|
+
scopeKey: scopeKey(input),
|
|
1191
|
+
decision: proposal.decision,
|
|
1192
|
+
logicalSort: logicalSort(input.id),
|
|
1193
|
+
createFingerprint: canonicalActionProposalJson3(input),
|
|
1194
|
+
proposal,
|
|
1195
|
+
...discoveryMetadata(proposal),
|
|
1196
|
+
version: 0,
|
|
1197
|
+
createdAt: proposal.createdAt
|
|
1198
|
+
};
|
|
1199
|
+
const table = this.table;
|
|
1200
|
+
const insert = this.db.insert(table);
|
|
1201
|
+
const inserted = this.dialect === "mysql" ? mysqlAffectedRows(await insert.ignore().values(row)) : await affectedRows(this.dialect, insert.values(row).onConflictDoNothing(), table.id);
|
|
1202
|
+
const stored = await this.read(input, input.id);
|
|
1203
|
+
if (!stored) return {
|
|
1204
|
+
status: "conflict"
|
|
1205
|
+
};
|
|
1206
|
+
if (inserted === 1) return {
|
|
1207
|
+
status: "created",
|
|
1208
|
+
proposal: stored.proposal
|
|
1209
|
+
};
|
|
1210
|
+
return {
|
|
1211
|
+
status: stored.createFingerprint === row.createFingerprint ? "unchanged" : "conflict",
|
|
1212
|
+
proposal: stored.proposal
|
|
1213
|
+
};
|
|
1214
|
+
}
|
|
1215
|
+
createReplacingActionProposal(input) {
|
|
1216
|
+
if (!input.replacementKey) return this.createActionProposal(input);
|
|
1217
|
+
const proposal = initialActionProposal(input, this.clock());
|
|
1218
|
+
return this.transactionSteps((db) => this.replacementSteps(db, input, proposal));
|
|
1219
|
+
}
|
|
1220
|
+
async supersedeActionProposal(scope, id, command) {
|
|
1221
|
+
const replacement = await this.getActionProposal(scope, command.replacementProposalId);
|
|
1222
|
+
if (!replacement) return {
|
|
1223
|
+
status: "not_found"
|
|
1224
|
+
};
|
|
1225
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalSupersession(row, replacement, command, now));
|
|
1226
|
+
}
|
|
1227
|
+
*replacementSteps(db, input, proposal) {
|
|
1228
|
+
const table = this.table;
|
|
1229
|
+
const thread = agentTablesFor(this.dialect).agentThread;
|
|
1230
|
+
if (this.dialect === "sqlite") yield {
|
|
1231
|
+
kind: "write",
|
|
1232
|
+
query: db.update(thread).set({
|
|
1233
|
+
updatedAt: sql2`${thread.updatedAt}`
|
|
1234
|
+
}).where(eq(thread.id, input.threadId))
|
|
1235
|
+
};
|
|
1236
|
+
const threads = yield {
|
|
1237
|
+
kind: "read",
|
|
1238
|
+
query: lockQuery(db.select().from(thread).where(eq(thread.id, input.threadId)).limit(1), this.dialect)
|
|
1239
|
+
};
|
|
1240
|
+
const owner = threads[0];
|
|
1241
|
+
if (!owner || owner.id !== input.threadId || owner.deletedAt || owner.actorRef !== input.actorRef || owner.tenantRef !== input.tenantRef) return {
|
|
1242
|
+
status: "conflict"
|
|
1243
|
+
};
|
|
1244
|
+
const existingRows = yield {
|
|
1245
|
+
kind: "read",
|
|
1246
|
+
query: db.select().from(table).where(eq(table.id, physicalId(input.id))).limit(1)
|
|
1247
|
+
};
|
|
1248
|
+
const existing = existingRows[0];
|
|
1249
|
+
if (existing) {
|
|
1250
|
+
if (existing.proposal.id !== input.id || !actionProposalScopeMatches(existing.proposal, input)) return {
|
|
1251
|
+
status: "conflict"
|
|
1252
|
+
};
|
|
1253
|
+
return {
|
|
1254
|
+
status: existing.createFingerprint === canonicalActionProposalJson3(input) ? "unchanged" : "conflict",
|
|
1255
|
+
proposal: existing.proposal
|
|
1256
|
+
};
|
|
1257
|
+
}
|
|
1258
|
+
const groupKey = replacementGroupKey(input);
|
|
1259
|
+
if (groupKey === null) throw new Error("Missing explicit replacement identity");
|
|
1260
|
+
const pending = yield {
|
|
1261
|
+
kind: "read",
|
|
1262
|
+
query: lockQuery(db.select().from(table).where(and(eq(table.scopeKey, scopeKey(input)), eq(table.replacementGroupKey, groupKey), eq(table.decision, "pending"))), this.dialect)
|
|
1263
|
+
};
|
|
1264
|
+
const row = {
|
|
1265
|
+
id: physicalId(input.id),
|
|
1266
|
+
scopeKey: scopeKey(input),
|
|
1267
|
+
decision: proposal.decision,
|
|
1268
|
+
logicalSort: logicalSort(input.id),
|
|
1269
|
+
createFingerprint: canonicalActionProposalJson3(input),
|
|
1270
|
+
proposal,
|
|
1271
|
+
...discoveryMetadata(proposal),
|
|
1272
|
+
version: 0,
|
|
1273
|
+
createdAt: proposal.createdAt
|
|
1274
|
+
};
|
|
1275
|
+
const insert = db.insert(table);
|
|
1276
|
+
const inserted = yield {
|
|
1277
|
+
kind: "read",
|
|
1278
|
+
query: this.dialect === "mysql" ? insert.ignore().values(row) : insert.values(row).onConflictDoNothing().returning({
|
|
1279
|
+
id: table.id
|
|
1280
|
+
})
|
|
1281
|
+
};
|
|
1282
|
+
const count3 = this.dialect === "mysql" ? mysqlAffectedRows(inserted) : inserted.length;
|
|
1283
|
+
if (count3 !== 1) return {
|
|
1284
|
+
status: "conflict"
|
|
1285
|
+
};
|
|
1286
|
+
for (const old of pending) {
|
|
1287
|
+
const result = transitionActionProposalSupersession(old.proposal, proposal, {
|
|
1288
|
+
replacementProposalId: proposal.id,
|
|
1289
|
+
actorRef: proposal.actorRef,
|
|
1290
|
+
via: "replacement"
|
|
1291
|
+
}, this.clock());
|
|
1292
|
+
if (!result.proposal || canonicalActionProposalJson3(result.proposal) === canonicalActionProposalJson3(old.proposal)) continue;
|
|
1293
|
+
const next = result.proposal;
|
|
1294
|
+
const update = db.update(table).set({
|
|
1295
|
+
proposal: next,
|
|
1296
|
+
decision: next.decision,
|
|
1297
|
+
...discoveryMetadata(next),
|
|
1298
|
+
version: old.version + 1
|
|
1299
|
+
}).where(and(eq(table.id, old.id), eq(table.version, old.version)));
|
|
1300
|
+
const updated = yield {
|
|
1301
|
+
kind: "read",
|
|
1302
|
+
query: this.dialect === "mysql" ? update : update.returning({
|
|
1303
|
+
id: table.id
|
|
1304
|
+
})
|
|
1305
|
+
};
|
|
1306
|
+
if ((this.dialect === "mysql" ? mysqlAffectedRows(updated) : updated.length) !== 1) throw new Error("Replacement lost its locked proposal fence");
|
|
1307
|
+
}
|
|
1308
|
+
return {
|
|
1309
|
+
status: "created",
|
|
1310
|
+
proposal
|
|
1311
|
+
};
|
|
1312
|
+
}
|
|
1313
|
+
async getActionProposal(scope, id) {
|
|
1314
|
+
return (await this.read(scope, id))?.proposal ?? null;
|
|
1315
|
+
}
|
|
1316
|
+
async listActionProposals(scope, query = {}) {
|
|
1317
|
+
const limit = validateActionProposalListQuery(query);
|
|
1318
|
+
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);
|
|
1319
|
+
return rows.map((row) => row.proposal).filter((proposal) => actionProposalScopeMatches(proposal, scope));
|
|
1320
|
+
}
|
|
1321
|
+
decideActionProposal(scope, id, command) {
|
|
1322
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalDecision(row, command, now));
|
|
1323
|
+
}
|
|
1324
|
+
claimActionProposal(scope, id, command) {
|
|
1325
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalClaim(row, command, now, randomUUID()));
|
|
1326
|
+
}
|
|
1327
|
+
extendActionProposalLease(scope, id, command) {
|
|
1328
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalLease(row, command, now));
|
|
1329
|
+
}
|
|
1330
|
+
settleActionProposal(scope, id, command) {
|
|
1331
|
+
return this.mutate(scope, id, (row, now) => transitionActionProposalSettlement(row, command, now));
|
|
1332
|
+
}
|
|
1333
|
+
async claimNextActionProposal(command) {
|
|
1334
|
+
const now = this.clock();
|
|
1335
|
+
validateActionProposalWorkerClaim(command, now);
|
|
1336
|
+
const table = this.table;
|
|
1337
|
+
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);
|
|
1338
|
+
for (const candidate of candidates) {
|
|
1339
|
+
const result = await this.claimActionProposal(candidate.proposal, candidate.proposal.id, command);
|
|
1340
|
+
if (result.status === "applied" && result.proposal) return result.proposal;
|
|
1341
|
+
}
|
|
1342
|
+
return null;
|
|
1343
|
+
}
|
|
1344
|
+
async expireActionProposals(command) {
|
|
1345
|
+
const now = this.clock();
|
|
1346
|
+
validateActionProposalExpiryBatch(command, now);
|
|
1347
|
+
const table = this.table;
|
|
1348
|
+
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);
|
|
1349
|
+
let expired = 0;
|
|
1350
|
+
for (const candidate of candidates) {
|
|
1351
|
+
const result = await this.decideActionProposal(candidate.proposal, candidate.proposal.id, {
|
|
1352
|
+
decision: "expired",
|
|
1353
|
+
actorRef: "system",
|
|
1354
|
+
via: "expiry"
|
|
1355
|
+
});
|
|
1356
|
+
if (result.status === "applied") expired++;
|
|
1357
|
+
}
|
|
1358
|
+
return expired;
|
|
1359
|
+
}
|
|
1360
|
+
async backfillActionProposalDiscoveryIndex(command) {
|
|
1361
|
+
validateActionProposalDiscoveryIndexBatch(command);
|
|
1362
|
+
const table = this.table;
|
|
1363
|
+
const candidates = await this.db.select().from(table).where(eq(table.discoveryIndexVersion, 0)).orderBy(asc(table.createdAt), asc(table.logicalSort)).limit(command.limit);
|
|
1364
|
+
let changed = 0;
|
|
1365
|
+
for (const row of candidates) {
|
|
1366
|
+
changed += await affectedRows(this.dialect, this.db.update(table).set({
|
|
1367
|
+
...discoveryMetadata(row.proposal),
|
|
1368
|
+
version: row.version + 1
|
|
1369
|
+
}).where(and(eq(table.id, row.id), eq(table.scopeKey, row.scopeKey), eq(table.version, row.version), eq(table.discoveryIndexVersion, 0))), table.id);
|
|
1370
|
+
}
|
|
1371
|
+
return changed;
|
|
1372
|
+
}
|
|
1373
|
+
async rememberedActionProposalApprovals(scope) {
|
|
1374
|
+
const table = this.table;
|
|
1375
|
+
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"))));
|
|
1376
|
+
return [
|
|
1377
|
+
...new Set(rows.filter((row) => actionProposalScopeMatches(row.proposal, scope) && row.proposal.decisionAudit?.remember === true).map((row) => row.proposal.toolName))
|
|
1378
|
+
];
|
|
1379
|
+
}
|
|
1380
|
+
async getThreadActionProposalScope(threadId) {
|
|
1381
|
+
const thread = agentTablesFor(this.dialect).agentThread;
|
|
1382
|
+
const [row] = await this.db.select().from(thread).where(and(eq(thread.id, threadId), isNull(thread.deletedAt))).limit(1);
|
|
1383
|
+
return row?.id === threadId ? {
|
|
1384
|
+
actorRef: row.actorRef,
|
|
1385
|
+
tenantRef: row.tenantRef,
|
|
1386
|
+
threadId: row.id
|
|
1387
|
+
} : null;
|
|
1388
|
+
}
|
|
1389
|
+
async claimNextActionProposalOutcome(command) {
|
|
1390
|
+
const now = this.clock();
|
|
1391
|
+
validateActionProposalWorkerClaim(command, now);
|
|
1392
|
+
const table = this.table;
|
|
1393
|
+
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);
|
|
1394
|
+
for (const row of candidates) {
|
|
1395
|
+
const result = await this.mutate(row.proposal, row.proposal.id, (proposal, time) => {
|
|
1396
|
+
const claimed2 = claimActionProposalOutcome(proposal, command, time, randomUUID());
|
|
1397
|
+
return claimed2 ? {
|
|
1398
|
+
status: "applied",
|
|
1399
|
+
proposal: claimed2
|
|
1400
|
+
} : {
|
|
1401
|
+
status: "conflict",
|
|
1402
|
+
proposal
|
|
1403
|
+
};
|
|
1404
|
+
});
|
|
1405
|
+
const claimed = result.proposal;
|
|
1406
|
+
if (result.status === "applied" && claimed?.outcome && claimed.outcomeDelivery?.lease) {
|
|
1407
|
+
return {
|
|
1408
|
+
outcome: claimed.outcome,
|
|
1409
|
+
lease: {
|
|
1410
|
+
outcomeId: claimed.outcome.id,
|
|
1411
|
+
token: claimed.outcomeDelivery.lease.token,
|
|
1412
|
+
generation: claimed.outcomeDelivery.generation
|
|
1413
|
+
}
|
|
1414
|
+
};
|
|
1415
|
+
}
|
|
1416
|
+
}
|
|
1417
|
+
return null;
|
|
1418
|
+
}
|
|
1419
|
+
async admitActionProposalOutcome(command) {
|
|
1420
|
+
return this.transactionSteps((db) => this.admissionSteps(db, command));
|
|
1421
|
+
}
|
|
1422
|
+
async transactionSteps(factory) {
|
|
1423
|
+
if (!this.actionProposalAdmissionSupported) throw new Error("Independent actions require a certified transactional Drizzle driver (better-sqlite3, node-postgres, mysql2 or libsql)");
|
|
1424
|
+
if (this.synchronousSqlite) {
|
|
1425
|
+
const database2 = this.rawDb;
|
|
1426
|
+
return database2.transaction((tx) => runSync(factory(asBuilder(tx))), {
|
|
1427
|
+
behavior: "immediate"
|
|
1428
|
+
});
|
|
1429
|
+
}
|
|
1430
|
+
const database = this.rawDb;
|
|
1431
|
+
return database.transaction(async (tx) => runAsync(factory(asBuilder(tx))));
|
|
1432
|
+
}
|
|
1433
|
+
*admissionSteps(db, command) {
|
|
1434
|
+
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");
|
|
1435
|
+
const table = this.table;
|
|
1436
|
+
const tables = agentTablesFor(this.dialect);
|
|
1437
|
+
if (this.dialect === "sqlite") yield {
|
|
1438
|
+
kind: "write",
|
|
1439
|
+
query: db.update(table).set({
|
|
1440
|
+
version: sql2`${table.version}`
|
|
1441
|
+
}).where(eq(table.outcomeIdKey, physicalId(command.outcomeId)))
|
|
1442
|
+
};
|
|
1443
|
+
const query = db.select().from(table).where(eq(table.outcomeIdKey, physicalId(command.outcomeId))).limit(1);
|
|
1444
|
+
const rows = yield {
|
|
1445
|
+
kind: "read",
|
|
1446
|
+
query: lockQuery(query, this.dialect)
|
|
1447
|
+
};
|
|
1448
|
+
const row = rows[0];
|
|
1449
|
+
if (!row || row.proposal.outcome?.id !== command.outcomeId) return {
|
|
1450
|
+
status: "not_found"
|
|
1451
|
+
};
|
|
1452
|
+
const proposal = row.proposal;
|
|
1453
|
+
const outcome = proposal.outcome;
|
|
1454
|
+
const delivery = proposal.outcomeDelivery;
|
|
1455
|
+
if (!outcome || !delivery) return {
|
|
1456
|
+
status: "not_found"
|
|
1457
|
+
};
|
|
1458
|
+
if (proposal.outcomeDelivery?.status === "admitted") return {
|
|
1459
|
+
status: "unchanged",
|
|
1460
|
+
...proposal.outcomeDelivery.messageId !== void 0 ? {
|
|
1461
|
+
messageId: proposal.outcomeDelivery.messageId
|
|
1462
|
+
} : {}
|
|
1463
|
+
};
|
|
1464
|
+
if (proposal.outcomeDelivery?.status === "discarded") return {
|
|
1465
|
+
status: "discarded"
|
|
1466
|
+
};
|
|
1467
|
+
if (!actionProposalOutcomeFenceValid(proposal, command, this.clock())) return {
|
|
1468
|
+
status: "conflict"
|
|
1469
|
+
};
|
|
1470
|
+
const threadQuery = db.select().from(tables.agentThread).where(eq(tables.agentThread.id, proposal.threadId)).limit(1);
|
|
1471
|
+
const threads = yield {
|
|
1472
|
+
kind: "read",
|
|
1473
|
+
query: lockQuery(threadQuery, this.dialect)
|
|
1474
|
+
};
|
|
1475
|
+
const thread = threads[0];
|
|
1476
|
+
const now = this.clock();
|
|
1477
|
+
if (!actionProposalOutcomeFenceValid(proposal, command, now)) return {
|
|
1478
|
+
status: "conflict"
|
|
1479
|
+
};
|
|
1480
|
+
if (!thread || thread.id !== proposal.threadId || thread.deletedAt || thread.actorRef !== proposal.actorRef || thread.tenantRef !== proposal.tenantRef) {
|
|
1481
|
+
const discarded = {
|
|
1482
|
+
...proposal,
|
|
1483
|
+
outcomeDelivery: {
|
|
1484
|
+
...delivery,
|
|
1485
|
+
status: "discarded",
|
|
1486
|
+
lease: null
|
|
1487
|
+
},
|
|
1488
|
+
updatedAt: now
|
|
1489
|
+
};
|
|
1490
|
+
yield {
|
|
1491
|
+
kind: "write",
|
|
1492
|
+
query: db.update(table).set({
|
|
1493
|
+
proposal: discarded,
|
|
1494
|
+
...discoveryMetadata(discarded),
|
|
1495
|
+
version: row.version + 1
|
|
1496
|
+
}).where(and(eq(table.id, row.id), eq(table.version, row.version)))
|
|
1497
|
+
};
|
|
1498
|
+
return {
|
|
1499
|
+
status: "discarded"
|
|
1500
|
+
};
|
|
1501
|
+
}
|
|
1502
|
+
if (thread.activeStreamId !== null) return {
|
|
1503
|
+
status: "busy"
|
|
1504
|
+
};
|
|
1505
|
+
const seqRows = yield {
|
|
1506
|
+
kind: "read",
|
|
1507
|
+
query: db.select({
|
|
1508
|
+
last: max(tables.agentMessage.seq)
|
|
1509
|
+
}).from(tables.agentMessage).where(eq(tables.agentMessage.threadId, thread.id))
|
|
1510
|
+
};
|
|
1511
|
+
const messageId = physicalId(command.outcomeId);
|
|
1512
|
+
yield {
|
|
1513
|
+
kind: "write",
|
|
1514
|
+
query: db.insert(tables.agentMessage).values({
|
|
1515
|
+
id: messageId,
|
|
1516
|
+
threadId: thread.id,
|
|
1517
|
+
role: "assistant",
|
|
1518
|
+
content: actionProposalOutcomeText(outcome),
|
|
1519
|
+
actionProposalOutcome: canonicalActionProposalJson3(outcome),
|
|
1520
|
+
ui: null,
|
|
1521
|
+
seq: Number(seqRows[0]?.last ?? 0) + 1,
|
|
1522
|
+
createdAt: new Date(now)
|
|
1523
|
+
})
|
|
1524
|
+
};
|
|
1525
|
+
yield {
|
|
1526
|
+
kind: "write",
|
|
1527
|
+
query: db.update(tables.agentThread).set({
|
|
1528
|
+
updatedAt: new Date(now)
|
|
1529
|
+
}).where(eq(tables.agentThread.id, thread.id))
|
|
1530
|
+
};
|
|
1531
|
+
const admitted = {
|
|
1532
|
+
...proposal,
|
|
1533
|
+
outcomeDelivery: {
|
|
1534
|
+
...delivery,
|
|
1535
|
+
status: "admitted",
|
|
1536
|
+
lease: null,
|
|
1537
|
+
messageId
|
|
1538
|
+
},
|
|
1539
|
+
updatedAt: now
|
|
1540
|
+
};
|
|
1541
|
+
const update = db.update(table).set({
|
|
1542
|
+
proposal: admitted,
|
|
1543
|
+
...discoveryMetadata(admitted),
|
|
1544
|
+
version: row.version + 1
|
|
1545
|
+
}).where(and(eq(table.id, row.id), eq(table.version, row.version)));
|
|
1546
|
+
const changed = yield {
|
|
1547
|
+
kind: "read",
|
|
1548
|
+
query: this.dialect === "mysql" ? update : update.returning({
|
|
1549
|
+
id: table.id
|
|
1550
|
+
})
|
|
1551
|
+
};
|
|
1552
|
+
const count3 = this.dialect === "mysql" ? mysqlAffectedRows(changed) : changed.length;
|
|
1553
|
+
if (count3 !== 1) throw new Error("Outcome admission lost its locked proposal fence");
|
|
1554
|
+
return {
|
|
1555
|
+
status: "applied",
|
|
1556
|
+
messageId
|
|
1557
|
+
};
|
|
1558
|
+
}
|
|
1559
|
+
async read(scope, id) {
|
|
1560
|
+
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);
|
|
1561
|
+
return row && row.proposal.id === id && actionProposalScopeMatches(row.proposal, scope) ? row : void 0;
|
|
1562
|
+
}
|
|
1563
|
+
async mutate(scope, id, transition) {
|
|
1564
|
+
for (let attempt = 0; attempt < 32; attempt++) {
|
|
1565
|
+
const row2 = await this.read(scope, id);
|
|
1566
|
+
if (!row2) return {
|
|
1567
|
+
status: "not_found"
|
|
1568
|
+
};
|
|
1569
|
+
const result = transition(row2.proposal, this.clock());
|
|
1570
|
+
if (!result.proposal || canonicalActionProposalJson3(result.proposal) === canonicalActionProposalJson3(row2.proposal)) return result;
|
|
1571
|
+
const changed = await affectedRows(this.dialect, this.db.update(this.table).set({
|
|
1572
|
+
proposal: result.proposal,
|
|
1573
|
+
decision: result.proposal.decision,
|
|
1574
|
+
...discoveryMetadata(result.proposal),
|
|
1575
|
+
version: row2.version + 1
|
|
1576
|
+
}).where(and(eq(this.table.id, physicalId(id)), eq(this.table.scopeKey, scopeKey(scope)), eq(this.table.version, row2.version))), this.table.id);
|
|
1577
|
+
if (changed === 1) return result;
|
|
1578
|
+
}
|
|
1579
|
+
const row = await this.read(scope, id);
|
|
1580
|
+
return row ? {
|
|
1581
|
+
status: "conflict",
|
|
1582
|
+
proposal: row.proposal
|
|
1583
|
+
} : {
|
|
1584
|
+
status: "not_found"
|
|
1585
|
+
};
|
|
1586
|
+
}
|
|
1587
|
+
};
|
|
1588
|
+
function scopeKey(scope) {
|
|
1589
|
+
return createHash("sha256").update(canonicalActionProposalJson3([
|
|
1590
|
+
scope.tenantRef,
|
|
1591
|
+
scope.actorRef,
|
|
1592
|
+
scope.threadId
|
|
1593
|
+
])).digest("hex");
|
|
1594
|
+
}
|
|
1595
|
+
__name(scopeKey, "scopeKey");
|
|
1596
|
+
function physicalId(id) {
|
|
1597
|
+
return createHash("sha256").update(canonicalActionProposalJson3(id)).digest("hex");
|
|
1598
|
+
}
|
|
1599
|
+
__name(physicalId, "physicalId");
|
|
1600
|
+
function logicalSort(id) {
|
|
1601
|
+
let sort = "";
|
|
1602
|
+
for (let index4 = 0; index4 < id.length; index4++) sort += id.charCodeAt(index4).toString(16).padStart(4, "0");
|
|
1603
|
+
return sort;
|
|
1604
|
+
}
|
|
1605
|
+
__name(logicalSort, "logicalSort");
|
|
1606
|
+
function discoveryMetadata(proposal) {
|
|
1607
|
+
return {
|
|
1608
|
+
replacementGroupKey: replacementGroupKey(proposal),
|
|
1609
|
+
deliveryStatus: proposal.outcomeDelivery?.status ?? null,
|
|
1610
|
+
deliveryLeaseExpiresAt: proposal.outcomeDelivery?.lease?.expiresAt ?? null,
|
|
1611
|
+
outcomeIdKey: proposal.outcome ? physicalId(proposal.outcome.id) : null,
|
|
1612
|
+
executionStatus: proposal.execution?.status ?? null,
|
|
1613
|
+
leaseExpiresAt: proposal.execution?.lease?.expiresAt ?? null,
|
|
1614
|
+
proposalExpiresAt: proposal.expiresAt,
|
|
1615
|
+
discoveryIndexVersion: 1
|
|
1616
|
+
};
|
|
1617
|
+
}
|
|
1618
|
+
__name(discoveryMetadata, "discoveryMetadata");
|
|
1619
|
+
function lockQuery(query, dialect) {
|
|
1620
|
+
return dialect === "sqlite" ? query : query.for("update");
|
|
1621
|
+
}
|
|
1622
|
+
__name(lockQuery, "lockQuery");
|
|
1623
|
+
function runSync(steps) {
|
|
1624
|
+
let next = steps.next();
|
|
1625
|
+
while (!next.done) {
|
|
1626
|
+
const { kind, query } = next.value;
|
|
1627
|
+
const statement = query;
|
|
1628
|
+
next = steps.next(kind === "read" ? statement.all() : statement.run());
|
|
1629
|
+
}
|
|
1630
|
+
return next.value;
|
|
1631
|
+
}
|
|
1632
|
+
__name(runSync, "runSync");
|
|
1633
|
+
async function runAsync(steps) {
|
|
1634
|
+
let next = steps.next();
|
|
1635
|
+
while (!next.done) next = steps.next(await next.value.query);
|
|
1636
|
+
return next.value;
|
|
1637
|
+
}
|
|
1638
|
+
__name(runAsync, "runAsync");
|
|
1639
|
+
function replacementGroupKey(proposal) {
|
|
1640
|
+
return proposal.replacementKey ? physicalId(canonicalActionProposalJson3([
|
|
1641
|
+
proposal.toolName,
|
|
1642
|
+
proposal.replacementKey
|
|
1643
|
+
])) : null;
|
|
1644
|
+
}
|
|
1645
|
+
__name(replacementGroupKey, "replacementGroupKey");
|
|
1646
|
+
|
|
1647
|
+
// src/drizzle-agent-store.ts
|
|
1005
1648
|
function turnMessageColumns(message) {
|
|
1006
1649
|
return {
|
|
1007
1650
|
id: message.id,
|
|
@@ -1022,11 +1665,61 @@ var DrizzleAgentStore = class {
|
|
|
1022
1665
|
db;
|
|
1023
1666
|
dialect;
|
|
1024
1667
|
t;
|
|
1025
|
-
|
|
1668
|
+
proposals;
|
|
1669
|
+
constructor(db, options = {}) {
|
|
1670
|
+
this.proposals = new DrizzleActionProposalStore(db, options);
|
|
1026
1671
|
this.dialect = agentDialectOf(db);
|
|
1027
1672
|
this.t = agentTablesFor(this.dialect);
|
|
1028
1673
|
this.db = asBuilder(db);
|
|
1029
1674
|
}
|
|
1675
|
+
createActionProposal(...args) {
|
|
1676
|
+
return this.proposals.createActionProposal(...args);
|
|
1677
|
+
}
|
|
1678
|
+
getActionProposal(...args) {
|
|
1679
|
+
return this.proposals.getActionProposal(...args);
|
|
1680
|
+
}
|
|
1681
|
+
listActionProposals(...args) {
|
|
1682
|
+
return this.proposals.listActionProposals(...args);
|
|
1683
|
+
}
|
|
1684
|
+
decideActionProposal(...args) {
|
|
1685
|
+
return this.proposals.decideActionProposal(...args);
|
|
1686
|
+
}
|
|
1687
|
+
claimActionProposal(...args) {
|
|
1688
|
+
return this.proposals.claimActionProposal(...args);
|
|
1689
|
+
}
|
|
1690
|
+
extendActionProposalLease(...args) {
|
|
1691
|
+
return this.proposals.extendActionProposalLease(...args);
|
|
1692
|
+
}
|
|
1693
|
+
claimNextActionProposal(...args) {
|
|
1694
|
+
return this.proposals.claimNextActionProposal(...args);
|
|
1695
|
+
}
|
|
1696
|
+
expireActionProposals(...args) {
|
|
1697
|
+
return this.proposals.expireActionProposals(...args);
|
|
1698
|
+
}
|
|
1699
|
+
backfillActionProposalDiscoveryIndex(command) {
|
|
1700
|
+
return this.proposals.backfillActionProposalDiscoveryIndex(command);
|
|
1701
|
+
}
|
|
1702
|
+
settleActionProposal(...args) {
|
|
1703
|
+
return this.proposals.settleActionProposal(...args);
|
|
1704
|
+
}
|
|
1705
|
+
createReplacingActionProposal(...args) {
|
|
1706
|
+
return this.proposals.createReplacingActionProposal(...args);
|
|
1707
|
+
}
|
|
1708
|
+
supersedeActionProposal(...args) {
|
|
1709
|
+
return this.proposals.supersedeActionProposal(...args);
|
|
1710
|
+
}
|
|
1711
|
+
get actionProposalAdmissionSupported() {
|
|
1712
|
+
return this.proposals.actionProposalAdmissionSupported;
|
|
1713
|
+
}
|
|
1714
|
+
getThreadActionProposalScope(threadId) {
|
|
1715
|
+
return this.proposals.getThreadActionProposalScope(threadId);
|
|
1716
|
+
}
|
|
1717
|
+
claimNextActionProposalOutcome(...args) {
|
|
1718
|
+
return this.proposals.claimNextActionProposalOutcome(...args);
|
|
1719
|
+
}
|
|
1720
|
+
admitActionProposalOutcome(...args) {
|
|
1721
|
+
return this.proposals.admitActionProposalOutcome(...args);
|
|
1722
|
+
}
|
|
1030
1723
|
async createThread(input) {
|
|
1031
1724
|
const now = /* @__PURE__ */ new Date();
|
|
1032
1725
|
const thread = {
|
|
@@ -1048,11 +1741,11 @@ var DrizzleAgentStore = class {
|
|
|
1048
1741
|
return this.toSummary(thread);
|
|
1049
1742
|
}
|
|
1050
1743
|
async getThread(threadId) {
|
|
1051
|
-
const [thread] = await this.db.select().from(this.t.agentThread).where(
|
|
1744
|
+
const [thread] = await this.db.select().from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1052
1745
|
if (thread === void 0) {
|
|
1053
1746
|
return null;
|
|
1054
1747
|
}
|
|
1055
|
-
const messages = await this.db.select().from(this.t.agentMessage).where(
|
|
1748
|
+
const messages = await this.db.select().from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId)).orderBy(...this.messageOrder());
|
|
1056
1749
|
const last = messages[messages.length - 1];
|
|
1057
1750
|
const approvals = await this.approvalsFor(messages.map((message) => message.id));
|
|
1058
1751
|
return {
|
|
@@ -1087,14 +1780,14 @@ var DrizzleAgentStore = class {
|
|
|
1087
1780
|
const [thread] = await this.db.select({
|
|
1088
1781
|
title: this.t.agentThread.title,
|
|
1089
1782
|
defaultAgent: this.t.agentThread.defaultAgent
|
|
1090
|
-
}).from(this.t.agentThread).where(
|
|
1783
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, query.threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1091
1784
|
if (thread === void 0) {
|
|
1092
1785
|
return null;
|
|
1093
1786
|
}
|
|
1094
1787
|
const messages = await this.loadTurnWindow(query.threadId, query.messageLimit);
|
|
1095
1788
|
const [answered] = await this.db.select({
|
|
1096
1789
|
id: this.t.agentMessage.id
|
|
1097
|
-
}).from(this.t.agentMessage).where(
|
|
1790
|
+
}).from(this.t.agentMessage).where(and2(eq2(this.t.agentMessage.threadId, query.threadId), eq2(this.t.agentMessage.role, "assistant"))).limit(1);
|
|
1098
1791
|
return {
|
|
1099
1792
|
title: thread.title,
|
|
1100
1793
|
defaultAgent: thread.defaultAgent,
|
|
@@ -1110,15 +1803,15 @@ var DrizzleAgentStore = class {
|
|
|
1110
1803
|
if (limit !== void 0 && limit <= 0) {
|
|
1111
1804
|
return [];
|
|
1112
1805
|
}
|
|
1113
|
-
const window = this.db.select(turnMessageColumns(this.t.agentMessage)).from(this.t.agentMessage).where(
|
|
1806
|
+
const window = this.db.select(turnMessageColumns(this.t.agentMessage)).from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId)).orderBy(...this.messageOrderNewestFirst());
|
|
1114
1807
|
const rows = limit === void 0 ? await window : await window.limit(limit);
|
|
1115
1808
|
return rows.reverse().map((row) => this.toStoredMessage(row));
|
|
1116
1809
|
}
|
|
1117
1810
|
async listThreads(actorRef, limit = 50) {
|
|
1118
|
-
const threads = await this.db.select().from(this.t.agentThread).where(
|
|
1811
|
+
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);
|
|
1119
1812
|
const summaries = [];
|
|
1120
1813
|
for (const thread of threads) {
|
|
1121
|
-
const [last] = await this.db.select().from(this.t.agentMessage).where(
|
|
1814
|
+
const [last] = await this.db.select().from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, thread.id)).orderBy(...this.messageOrderNewestFirst()).limit(1);
|
|
1122
1815
|
summaries.push(this.toSummary(thread, last?.content));
|
|
1123
1816
|
}
|
|
1124
1817
|
return summaries;
|
|
@@ -1126,14 +1819,14 @@ var DrizzleAgentStore = class {
|
|
|
1126
1819
|
async softDeleteThread(threadId) {
|
|
1127
1820
|
await this.db.update(this.t.agentThread).set({
|
|
1128
1821
|
deletedAt: /* @__PURE__ */ new Date()
|
|
1129
|
-
}).where(
|
|
1822
|
+
}).where(eq2(this.t.agentThread.id, threadId));
|
|
1130
1823
|
}
|
|
1131
1824
|
async forkThread(threadId, fromMessageId) {
|
|
1132
|
-
const [source] = await this.db.select().from(this.t.agentThread).where(
|
|
1825
|
+
const [source] = await this.db.select().from(this.t.agentThread).where(eq2(this.t.agentThread.id, threadId));
|
|
1133
1826
|
if (source === void 0) {
|
|
1134
1827
|
throw new Error(`thread ${threadId} not found`);
|
|
1135
1828
|
}
|
|
1136
|
-
const messages = await this.db.select().from(this.t.agentMessage).where(
|
|
1829
|
+
const messages = await this.db.select().from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId)).orderBy(...this.messageOrder());
|
|
1137
1830
|
const cutoff = messages.findIndex((message) => message.id === fromMessageId);
|
|
1138
1831
|
const kept = cutoff >= 0 ? messages.slice(0, cutoff + 1) : messages;
|
|
1139
1832
|
const now = /* @__PURE__ */ new Date();
|
|
@@ -1176,6 +1869,7 @@ var DrizzleAgentStore = class {
|
|
|
1176
1869
|
reasoning: message.reasoning,
|
|
1177
1870
|
reasoningMs: message.reasoningMs,
|
|
1178
1871
|
ui: message.ui,
|
|
1872
|
+
actionProposalOutcome: message.actionProposalOutcome,
|
|
1179
1873
|
createdAt: message.createdAt
|
|
1180
1874
|
})));
|
|
1181
1875
|
}
|
|
@@ -1184,20 +1878,20 @@ var DrizzleAgentStore = class {
|
|
|
1184
1878
|
async ownerOfThread(threadId) {
|
|
1185
1879
|
const [thread] = await this.db.select({
|
|
1186
1880
|
actorRef: this.t.agentThread.actorRef
|
|
1187
|
-
}).from(this.t.agentThread).where(
|
|
1881
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1188
1882
|
return thread?.actorRef ?? null;
|
|
1189
1883
|
}
|
|
1190
1884
|
async ownerOfToolCall(toolCallId) {
|
|
1191
1885
|
const [row] = await this.db.select({
|
|
1192
1886
|
actorRef: this.t.agentThread.actorRef
|
|
1193
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
1887
|
+
}).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));
|
|
1194
1888
|
return row?.actorRef ?? null;
|
|
1195
1889
|
}
|
|
1196
1890
|
async runForToolCall(toolCallId) {
|
|
1197
1891
|
const [row] = await this.db.select({
|
|
1198
1892
|
runId: this.t.agentToolCall.runId,
|
|
1199
1893
|
activeStreamId: this.t.agentThread.activeStreamId
|
|
1200
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
1894
|
+
}).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));
|
|
1201
1895
|
return row?.runId ?? row?.activeStreamId ?? null;
|
|
1202
1896
|
}
|
|
1203
1897
|
/**
|
|
@@ -1215,12 +1909,13 @@ var DrizzleAgentStore = class {
|
|
|
1215
1909
|
messageId: this.t.agentToolCall.messageId,
|
|
1216
1910
|
status: this.t.agentToolCall.status,
|
|
1217
1911
|
approver: this.t.agentToolCall.approver,
|
|
1912
|
+
confirmation: this.t.agentToolCall.confirmation,
|
|
1218
1913
|
expiresAt: this.t.agentToolCall.expiresAt,
|
|
1219
1914
|
remember: this.t.agentToolCall.remember,
|
|
1220
1915
|
executedByRef: this.t.agentToolCall.executedByRef,
|
|
1221
1916
|
decidedVia: this.t.agentToolCall.decidedVia,
|
|
1222
1917
|
error: this.t.agentToolCall.error
|
|
1223
|
-
}).from(this.t.agentToolCall).where(
|
|
1918
|
+
}).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));
|
|
1224
1919
|
for (const row of rows) {
|
|
1225
1920
|
const approval = toolCallApprovalFromRow({
|
|
1226
1921
|
...row,
|
|
@@ -1239,13 +1934,20 @@ var DrizzleAgentStore = class {
|
|
|
1239
1934
|
async rememberedApprovals(threadId) {
|
|
1240
1935
|
const rows = await this.db.selectDistinct({
|
|
1241
1936
|
toolName: this.t.agentToolCall.toolName
|
|
1242
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
1243
|
-
|
|
1937
|
+
}).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)));
|
|
1938
|
+
const scope = await this.getThreadActionProposalScope(threadId);
|
|
1939
|
+
const proposalNames = scope ? await this.proposals.rememberedActionProposalApprovals(scope) : [];
|
|
1940
|
+
return [
|
|
1941
|
+
.../* @__PURE__ */ new Set([
|
|
1942
|
+
...rows.map((row) => row.toolName),
|
|
1943
|
+
...proposalNames
|
|
1944
|
+
])
|
|
1945
|
+
];
|
|
1244
1946
|
}
|
|
1245
1947
|
async toolCallInput(toolCallId) {
|
|
1246
1948
|
const [row] = await this.db.select({
|
|
1247
1949
|
input: this.t.agentToolCall.input
|
|
1248
|
-
}).from(this.t.agentToolCall).where(
|
|
1950
|
+
}).from(this.t.agentToolCall).where(eq2(this.t.agentToolCall.id, toolCallId));
|
|
1249
1951
|
return row?.input ?? null;
|
|
1250
1952
|
}
|
|
1251
1953
|
async toolCallApproval(toolCallId) {
|
|
@@ -1253,7 +1955,7 @@ var DrizzleAgentStore = class {
|
|
|
1253
1955
|
status: this.t.agentToolCall.status,
|
|
1254
1956
|
approver: this.t.agentToolCall.approver,
|
|
1255
1957
|
expiresAt: this.t.agentToolCall.expiresAt
|
|
1256
|
-
}).from(this.t.agentToolCall).where(
|
|
1958
|
+
}).from(this.t.agentToolCall).where(eq2(this.t.agentToolCall.id, toolCallId));
|
|
1257
1959
|
if (row === void 0) {
|
|
1258
1960
|
return null;
|
|
1259
1961
|
}
|
|
@@ -1266,26 +1968,26 @@ var DrizzleAgentStore = class {
|
|
|
1266
1968
|
async ownerOfActiveStream(runId) {
|
|
1267
1969
|
const [thread] = await this.db.select({
|
|
1268
1970
|
actorRef: this.t.agentThread.actorRef
|
|
1269
|
-
}).from(this.t.agentThread).where(
|
|
1971
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.activeStreamId, runId), isNull2(this.t.agentThread.deletedAt)));
|
|
1270
1972
|
return thread?.actorRef ?? null;
|
|
1271
1973
|
}
|
|
1272
1974
|
async setTitle(threadId, title) {
|
|
1273
1975
|
await this.db.update(this.t.agentThread).set({
|
|
1274
1976
|
title,
|
|
1275
1977
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1276
|
-
}).where(
|
|
1978
|
+
}).where(eq2(this.t.agentThread.id, threadId));
|
|
1277
1979
|
}
|
|
1278
1980
|
async promoteThread(threadId) {
|
|
1279
1981
|
await this.db.update(this.t.agentThread).set({
|
|
1280
1982
|
transient: false,
|
|
1281
1983
|
updatedAt: /* @__PURE__ */ new Date()
|
|
1282
|
-
}).where(
|
|
1984
|
+
}).where(and2(eq2(this.t.agentThread.id, threadId), eq2(this.t.agentThread.transient, true)));
|
|
1283
1985
|
}
|
|
1284
1986
|
/** Who holds the thread's stream right now, deleted or not. */
|
|
1285
1987
|
async activeHolder(threadId) {
|
|
1286
1988
|
const [thread] = await this.db.select({
|
|
1287
1989
|
activeStreamId: this.t.agentThread.activeStreamId
|
|
1288
|
-
}).from(this.t.agentThread).where(
|
|
1990
|
+
}).from(this.t.agentThread).where(eq2(this.t.agentThread.id, threadId));
|
|
1289
1991
|
return thread?.activeStreamId ?? null;
|
|
1290
1992
|
}
|
|
1291
1993
|
/**
|
|
@@ -1297,16 +1999,16 @@ var DrizzleAgentStore = class {
|
|
|
1297
1999
|
messageOrder() {
|
|
1298
2000
|
const message = this.t.agentMessage;
|
|
1299
2001
|
return [
|
|
1300
|
-
|
|
1301
|
-
|
|
1302
|
-
|
|
2002
|
+
asc2(sql3`coalesce(${message.seq}, 0)`),
|
|
2003
|
+
asc2(message.createdAt),
|
|
2004
|
+
asc2(message.id)
|
|
1303
2005
|
];
|
|
1304
2006
|
}
|
|
1305
2007
|
/** {@link messageOrder}, newest first. */
|
|
1306
2008
|
messageOrderNewestFirst() {
|
|
1307
2009
|
const message = this.t.agentMessage;
|
|
1308
2010
|
return [
|
|
1309
|
-
desc(
|
|
2011
|
+
desc(sql3`coalesce(${message.seq}, 0)`),
|
|
1310
2012
|
desc(message.createdAt),
|
|
1311
2013
|
desc(message.id)
|
|
1312
2014
|
];
|
|
@@ -1317,15 +2019,15 @@ var DrizzleAgentStore = class {
|
|
|
1317
2019
|
*/
|
|
1318
2020
|
async nextMessageSeq(threadId) {
|
|
1319
2021
|
const [row] = await this.db.select({
|
|
1320
|
-
last:
|
|
1321
|
-
}).from(this.t.agentMessage).where(
|
|
2022
|
+
last: max2(this.t.agentMessage.seq)
|
|
2023
|
+
}).from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId));
|
|
1322
2024
|
return Number(row?.last ?? 0) + 1;
|
|
1323
2025
|
}
|
|
1324
2026
|
/** The run streaming the thread, or `null` — a projection of the one column. */
|
|
1325
2027
|
async activeRunForThread(threadId) {
|
|
1326
2028
|
const [thread] = await this.db.select({
|
|
1327
2029
|
activeStreamId: this.t.agentThread.activeStreamId
|
|
1328
|
-
}).from(this.t.agentThread).where(
|
|
2030
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1329
2031
|
return thread?.activeStreamId ?? null;
|
|
1330
2032
|
}
|
|
1331
2033
|
/**
|
|
@@ -1334,15 +2036,15 @@ var DrizzleAgentStore = class {
|
|
|
1334
2036
|
*/
|
|
1335
2037
|
async claimActiveStream(threadId, runId, options = {}) {
|
|
1336
2038
|
const holders = [
|
|
1337
|
-
|
|
1338
|
-
|
|
2039
|
+
isNull2(this.t.agentThread.activeStreamId),
|
|
2040
|
+
eq2(this.t.agentThread.activeStreamId, runId),
|
|
1339
2041
|
...options.replacing !== void 0 ? [
|
|
1340
|
-
|
|
2042
|
+
eq2(this.t.agentThread.activeStreamId, options.replacing)
|
|
1341
2043
|
] : []
|
|
1342
2044
|
];
|
|
1343
2045
|
const claimed = await affectedRows(this.dialect, this.db.update(this.t.agentThread).set({
|
|
1344
2046
|
activeStreamId: runId
|
|
1345
|
-
}).where(
|
|
2047
|
+
}).where(and2(eq2(this.t.agentThread.id, threadId), or2(...holders))), this.t.agentThread.id);
|
|
1346
2048
|
if (claimed > 0) {
|
|
1347
2049
|
return true;
|
|
1348
2050
|
}
|
|
@@ -1351,21 +2053,22 @@ var DrizzleAgentStore = class {
|
|
|
1351
2053
|
async releaseActiveStream(threadId, runId) {
|
|
1352
2054
|
const released = await affectedRows(this.dialect, this.db.update(this.t.agentThread).set({
|
|
1353
2055
|
activeStreamId: null
|
|
1354
|
-
}).where(
|
|
2056
|
+
}).where(and2(eq2(this.t.agentThread.id, threadId), eq2(this.t.agentThread.activeStreamId, runId))), this.t.agentThread.id);
|
|
1355
2057
|
return released > 0;
|
|
1356
2058
|
}
|
|
1357
2059
|
async enqueueMessage(input) {
|
|
1358
2060
|
const now = /* @__PURE__ */ new Date();
|
|
1359
2061
|
const [edge] = await this.db.select({
|
|
1360
2062
|
first: min(this.t.agentQueuedMessage.position),
|
|
1361
|
-
last:
|
|
1362
|
-
}).from(this.t.agentQueuedMessage).where(
|
|
2063
|
+
last: max2(this.t.agentQueuedMessage.position)
|
|
2064
|
+
}).from(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.threadId, input.threadId));
|
|
1363
2065
|
const position = input.at === "head" ? (edge?.first ?? 1) - 1 : (edge?.last ?? -1) + 1;
|
|
1364
2066
|
const row = {
|
|
1365
2067
|
id: crypto.randomUUID(),
|
|
1366
2068
|
threadId: input.threadId,
|
|
1367
2069
|
actor: input.actor,
|
|
1368
2070
|
content: input.content,
|
|
2071
|
+
uiCapabilities: input.uiCapabilities ?? null,
|
|
1369
2072
|
attachments: input.attachments !== void 0 && input.attachments.length > 0 ? input.attachments : null,
|
|
1370
2073
|
agentName: input.agentName ?? null,
|
|
1371
2074
|
persona: input.persona ?? null,
|
|
@@ -1380,11 +2083,11 @@ var DrizzleAgentStore = class {
|
|
|
1380
2083
|
return toQueuedMessage(row);
|
|
1381
2084
|
}
|
|
1382
2085
|
async listQueue(threadId) {
|
|
1383
|
-
const rows = await this.db.select().from(this.t.agentQueuedMessage).where(
|
|
2086
|
+
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));
|
|
1384
2087
|
return rows.map(toQueuedMessage);
|
|
1385
2088
|
}
|
|
1386
2089
|
async getQueuedMessage(id) {
|
|
1387
|
-
const [row] = await this.db.select().from(this.t.agentQueuedMessage).where(
|
|
2090
|
+
const [row] = await this.db.select().from(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.id, id));
|
|
1388
2091
|
return row === void 0 ? null : toQueuedMessage(row);
|
|
1389
2092
|
}
|
|
1390
2093
|
async updateQueuedMessage(id, patch) {
|
|
@@ -1400,7 +2103,7 @@ var DrizzleAgentStore = class {
|
|
|
1400
2103
|
if (patch.interrupt !== void 0) {
|
|
1401
2104
|
updates.interrupt = patch.interrupt;
|
|
1402
2105
|
}
|
|
1403
|
-
await this.db.update(this.t.agentQueuedMessage).set(updates).where(
|
|
2106
|
+
await this.db.update(this.t.agentQueuedMessage).set(updates).where(eq2(this.t.agentQueuedMessage.id, id));
|
|
1404
2107
|
return this.getQueuedMessage(id);
|
|
1405
2108
|
}
|
|
1406
2109
|
/** Rewrites the thread's positions as 0..n-1 in the new order — a queue is a handful of rows. */
|
|
@@ -1415,32 +2118,32 @@ var DrizzleAgentStore = class {
|
|
|
1415
2118
|
for (const [position, message] of order.entries()) {
|
|
1416
2119
|
await this.db.update(this.t.agentQueuedMessage).set({
|
|
1417
2120
|
position
|
|
1418
|
-
}).where(
|
|
2121
|
+
}).where(eq2(this.t.agentQueuedMessage.id, message.id));
|
|
1419
2122
|
}
|
|
1420
2123
|
return true;
|
|
1421
2124
|
}
|
|
1422
2125
|
async removeQueuedMessage(id) {
|
|
1423
|
-
const removed = await affectedRows(this.dialect, this.db.delete(this.t.agentQueuedMessage).where(
|
|
2126
|
+
const removed = await affectedRows(this.dialect, this.db.delete(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.id, id)), this.t.agentQueuedMessage.id);
|
|
1424
2127
|
return removed > 0;
|
|
1425
2128
|
}
|
|
1426
2129
|
async clearQueue(threadId) {
|
|
1427
|
-
return affectedRows(this.dialect, this.db.delete(this.t.agentQueuedMessage).where(
|
|
2130
|
+
return affectedRows(this.dialect, this.db.delete(this.t.agentQueuedMessage).where(eq2(this.t.agentQueuedMessage.threadId, threadId)), this.t.agentQueuedMessage.id);
|
|
1428
2131
|
}
|
|
1429
2132
|
async queuePause(threadId) {
|
|
1430
2133
|
const [thread] = await this.db.select({
|
|
1431
2134
|
queuePause: this.t.agentThread.queuePause
|
|
1432
|
-
}).from(this.t.agentThread).where(
|
|
2135
|
+
}).from(this.t.agentThread).where(eq2(this.t.agentThread.id, threadId));
|
|
1433
2136
|
return thread?.queuePause ?? null;
|
|
1434
2137
|
}
|
|
1435
2138
|
async setQueuePause(threadId, pause) {
|
|
1436
2139
|
await this.db.update(this.t.agentThread).set({
|
|
1437
2140
|
queuePause: pause
|
|
1438
|
-
}).where(
|
|
2141
|
+
}).where(eq2(this.t.agentThread.id, threadId));
|
|
1439
2142
|
}
|
|
1440
2143
|
async setActiveStream(threadId, runId) {
|
|
1441
2144
|
await this.db.update(this.t.agentThread).set({
|
|
1442
2145
|
activeStreamId: runId
|
|
1443
|
-
}).where(
|
|
2146
|
+
}).where(eq2(this.t.agentThread.id, threadId));
|
|
1444
2147
|
}
|
|
1445
2148
|
/**
|
|
1446
2149
|
* Patch a thread's `title` and/or `defaultAgent`. Each field is only touched when PRESENT in
|
|
@@ -1466,7 +2169,7 @@ var DrizzleAgentStore = class {
|
|
|
1466
2169
|
return;
|
|
1467
2170
|
}
|
|
1468
2171
|
updates.updatedAt = /* @__PURE__ */ new Date();
|
|
1469
|
-
await this.db.update(this.t.agentThread).set(updates).where(
|
|
2172
|
+
await this.db.update(this.t.agentThread).set(updates).where(eq2(this.t.agentThread.id, threadId));
|
|
1470
2173
|
}
|
|
1471
2174
|
/**
|
|
1472
2175
|
* The thread's default agent, projected — the caller wants one nullable scalar to decide which
|
|
@@ -1477,20 +2180,20 @@ var DrizzleAgentStore = class {
|
|
|
1477
2180
|
async modelForThread(threadId) {
|
|
1478
2181
|
const [thread] = await this.db.select({
|
|
1479
2182
|
model: this.t.agentThread.model
|
|
1480
|
-
}).from(this.t.agentThread).where(
|
|
2183
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1481
2184
|
return thread?.model ?? null;
|
|
1482
2185
|
}
|
|
1483
2186
|
/** The thread's pinned persona, projected like {@link defaultAgentForThread}. */
|
|
1484
2187
|
async personaForThread(threadId) {
|
|
1485
2188
|
const [thread] = await this.db.select({
|
|
1486
2189
|
persona: this.t.agentThread.persona
|
|
1487
|
-
}).from(agentThread).where(
|
|
2190
|
+
}).from(agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1488
2191
|
return thread?.persona ?? null;
|
|
1489
2192
|
}
|
|
1490
2193
|
async defaultAgentForThread(threadId) {
|
|
1491
2194
|
const [thread] = await this.db.select({
|
|
1492
2195
|
defaultAgent: this.t.agentThread.defaultAgent
|
|
1493
|
-
}).from(this.t.agentThread).where(
|
|
2196
|
+
}).from(this.t.agentThread).where(and2(eq2(this.t.agentThread.id, threadId), isNull2(this.t.agentThread.deletedAt)));
|
|
1494
2197
|
return thread?.defaultAgent ?? null;
|
|
1495
2198
|
}
|
|
1496
2199
|
/**
|
|
@@ -1532,16 +2235,16 @@ var DrizzleAgentStore = class {
|
|
|
1532
2235
|
if (end.errorMessage !== void 0) {
|
|
1533
2236
|
updates.errorMessage = end.errorMessage;
|
|
1534
2237
|
}
|
|
1535
|
-
await this.db.update(this.t.agentRun).set(updates).where(
|
|
2238
|
+
await this.db.update(this.t.agentRun).set(updates).where(eq2(this.t.agentRun.id, end.runId));
|
|
1536
2239
|
}
|
|
1537
2240
|
/** Bump the run's llm-step retry counter. Atomic `retries = retries + 1`, no read-modify-write. */
|
|
1538
2241
|
async bumpRunRetries(runId) {
|
|
1539
2242
|
await this.db.update(this.t.agentRun).set({
|
|
1540
|
-
retries:
|
|
1541
|
-
}).where(
|
|
2243
|
+
retries: sql3`${this.t.agentRun.retries} + 1`
|
|
2244
|
+
}).where(eq2(this.t.agentRun.id, runId));
|
|
1542
2245
|
}
|
|
1543
2246
|
async appendMessage(input) {
|
|
1544
|
-
const [thread] = await this.db.select().from(this.t.agentThread).where(
|
|
2247
|
+
const [thread] = await this.db.select().from(this.t.agentThread).where(eq2(this.t.agentThread.id, input.threadId));
|
|
1545
2248
|
if (thread === void 0) {
|
|
1546
2249
|
throw new Error(`thread ${input.threadId} not found`);
|
|
1547
2250
|
}
|
|
@@ -1551,6 +2254,7 @@ var DrizzleAgentStore = class {
|
|
|
1551
2254
|
threadId: input.threadId,
|
|
1552
2255
|
role: input.role,
|
|
1553
2256
|
content: input.content,
|
|
2257
|
+
actionProposalOutcome: input.actionProposalOutcome ? canonicalActionProposalJson4(input.actionProposalOutcome) : null,
|
|
1554
2258
|
toolCalls: input.toolCalls ?? null,
|
|
1555
2259
|
toolResults: input.toolResults ?? null,
|
|
1556
2260
|
attachments: input.attachments ?? null,
|
|
@@ -1569,32 +2273,32 @@ var DrizzleAgentStore = class {
|
|
|
1569
2273
|
await this.db.insert(this.t.agentMessage).values(message);
|
|
1570
2274
|
await this.db.update(this.t.agentThread).set({
|
|
1571
2275
|
updatedAt: now
|
|
1572
|
-
}).where(
|
|
2276
|
+
}).where(eq2(this.t.agentThread.id, input.threadId));
|
|
1573
2277
|
return this.toStoredMessage(message);
|
|
1574
2278
|
}
|
|
1575
2279
|
async setMessageToolResults(messageId, results) {
|
|
1576
2280
|
await this.db.update(this.t.agentMessage).set({
|
|
1577
2281
|
toolResults: results
|
|
1578
|
-
}).where(
|
|
2282
|
+
}).where(eq2(this.t.agentMessage.id, messageId));
|
|
1579
2283
|
}
|
|
1580
2284
|
async setMessageUi(messageId, ui) {
|
|
1581
2285
|
await this.db.update(this.t.agentMessage).set({
|
|
1582
2286
|
ui: ui.length > 0 ? ui : null
|
|
1583
|
-
}).where(
|
|
2287
|
+
}).where(eq2(this.t.agentMessage.id, messageId));
|
|
1584
2288
|
}
|
|
1585
2289
|
async threadOfMessage(messageId) {
|
|
1586
2290
|
const [row] = await this.db.select({
|
|
1587
2291
|
threadId: this.t.agentMessage.threadId
|
|
1588
|
-
}).from(this.t.agentMessage).where(
|
|
2292
|
+
}).from(this.t.agentMessage).where(eq2(this.t.agentMessage.id, messageId)).limit(1);
|
|
1589
2293
|
return row?.threadId ?? null;
|
|
1590
2294
|
}
|
|
1591
2295
|
async setMessageFeedback(messageId, feedback) {
|
|
1592
2296
|
await this.db.update(this.t.agentMessage).set({
|
|
1593
2297
|
feedback
|
|
1594
|
-
}).where(
|
|
2298
|
+
}).where(eq2(this.t.agentMessage.id, messageId));
|
|
1595
2299
|
}
|
|
1596
2300
|
async truncateFrom(threadId, messageId) {
|
|
1597
|
-
const messages = await this.db.select().from(this.t.agentMessage).where(
|
|
2301
|
+
const messages = await this.db.select().from(this.t.agentMessage).where(eq2(this.t.agentMessage.threadId, threadId)).orderBy(...this.messageOrder());
|
|
1598
2302
|
const cutoff = messages.findIndex((message) => message.id === messageId);
|
|
1599
2303
|
if (cutoff < 0) {
|
|
1600
2304
|
return;
|
|
@@ -1606,6 +2310,7 @@ var DrizzleAgentStore = class {
|
|
|
1606
2310
|
async recordToolCall(input) {
|
|
1607
2311
|
await this.db.insert(this.t.agentToolCall).values({
|
|
1608
2312
|
id: input.toolCallId,
|
|
2313
|
+
proposalId: input.proposalId ?? null,
|
|
1609
2314
|
messageId: input.messageId,
|
|
1610
2315
|
toolName: input.toolName,
|
|
1611
2316
|
toolType: input.toolType,
|
|
@@ -1619,6 +2324,7 @@ var DrizzleAgentStore = class {
|
|
|
1619
2324
|
executedAt: null,
|
|
1620
2325
|
runId: input.runId ?? null,
|
|
1621
2326
|
approver: input.approver ?? null,
|
|
2327
|
+
confirmation: input.confirmation ?? null,
|
|
1622
2328
|
expiresAt: input.expiresAt !== void 0 ? new Date(input.expiresAt) : null,
|
|
1623
2329
|
remember: null,
|
|
1624
2330
|
decidedVia: null
|
|
@@ -1649,7 +2355,7 @@ var DrizzleAgentStore = class {
|
|
|
1649
2355
|
if (input.status === "executed" || input.status === "auto_executed") {
|
|
1650
2356
|
updates.executedAt = /* @__PURE__ */ new Date();
|
|
1651
2357
|
}
|
|
1652
|
-
await this.db.update(this.t.agentToolCall).set(updates).where(
|
|
2358
|
+
await this.db.update(this.t.agentToolCall).set(updates).where(eq2(this.t.agentToolCall.id, input.toolCallId));
|
|
1653
2359
|
}
|
|
1654
2360
|
async toolCallOutcomes(toolCallIds) {
|
|
1655
2361
|
if (toolCallIds.length === 0) {
|
|
@@ -1675,7 +2381,7 @@ var DrizzleAgentStore = class {
|
|
|
1675
2381
|
}));
|
|
1676
2382
|
}
|
|
1677
2383
|
async failUnsettledToolCalls(runId, error) {
|
|
1678
|
-
const pending =
|
|
2384
|
+
const pending = and2(eq2(this.t.agentToolCall.runId, runId), eq2(this.t.agentToolCall.status, "pending_approval"));
|
|
1679
2385
|
const rows = await this.db.select({
|
|
1680
2386
|
id: this.t.agentToolCall.id
|
|
1681
2387
|
}).from(this.t.agentToolCall).where(pending);
|
|
@@ -1708,10 +2414,10 @@ var DrizzleAgentStore = class {
|
|
|
1708
2414
|
}
|
|
1709
2415
|
const rows = await this.db.select({
|
|
1710
2416
|
attachments: this.t.agentMessage.attachments
|
|
1711
|
-
}).from(this.t.agentMessage).innerJoin(this.t.agentThread,
|
|
2417
|
+
}).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)));
|
|
1712
2418
|
const queued = await this.db.select({
|
|
1713
2419
|
attachments: this.t.agentQueuedMessage.attachments
|
|
1714
|
-
}).from(this.t.agentQueuedMessage).innerJoin(this.t.agentThread,
|
|
2420
|
+
}).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)));
|
|
1715
2421
|
const wanted = new Set(mediaIds);
|
|
1716
2422
|
const found = /* @__PURE__ */ new Set();
|
|
1717
2423
|
for (const row of [
|
|
@@ -1750,7 +2456,7 @@ var DrizzleAgentStore = class {
|
|
|
1750
2456
|
async usageBetween(actorRef, fromDay, toDay) {
|
|
1751
2457
|
const start = /* @__PURE__ */ new Date(`${fromDay}T00:00:00.000Z`);
|
|
1752
2458
|
const end = /* @__PURE__ */ new Date(`${toDay}T23:59:59.999Z`);
|
|
1753
|
-
const rows = await this.db.select().from(this.t.agentTokenUsage).where(
|
|
2459
|
+
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)));
|
|
1754
2460
|
const usedTokens = rows.reduce((sum2, row) => sum2 + row.inputTokens + row.outputTokens, 0);
|
|
1755
2461
|
const costUsd = rows.reduce((sum2, row) => sum2 + (row.costUsd ?? 0), 0);
|
|
1756
2462
|
return {
|
|
@@ -1776,7 +2482,12 @@ var DrizzleAgentStore = class {
|
|
|
1776
2482
|
};
|
|
1777
2483
|
}
|
|
1778
2484
|
toStoredMessage(message) {
|
|
2485
|
+
const outcome = message.actionProposalOutcome ? JSON.parse(message.actionProposalOutcome) : void 0;
|
|
1779
2486
|
return {
|
|
2487
|
+
...outcome ? {
|
|
2488
|
+
actionProposalOutcome: outcome,
|
|
2489
|
+
ui: outcome.ui
|
|
2490
|
+
} : {},
|
|
1780
2491
|
id: message.id,
|
|
1781
2492
|
role: message.role,
|
|
1782
2493
|
content: message.content,
|
|
@@ -1822,6 +2533,9 @@ var DrizzleAgentStore = class {
|
|
|
1822
2533
|
};
|
|
1823
2534
|
function toQueuedMessage(row) {
|
|
1824
2535
|
return {
|
|
2536
|
+
...row.uiCapabilities !== null ? {
|
|
2537
|
+
uiCapabilities: row.uiCapabilities
|
|
2538
|
+
} : {},
|
|
1825
2539
|
id: row.id,
|
|
1826
2540
|
threadId: row.threadId,
|
|
1827
2541
|
actor: row.actor,
|
|
@@ -1852,7 +2566,7 @@ __name(toQueuedMessage, "toQueuedMessage");
|
|
|
1852
2566
|
|
|
1853
2567
|
// src/drizzle-governance-queries.ts
|
|
1854
2568
|
import { bucketByActor, bucketByModel, bucketByThread, bucketUsageTrend, dayBoundsUtc, rollupThreadUsage, truncateDetailContent } from "@dudousxd/nestjs-agent-core";
|
|
1855
|
-
import { and as
|
|
2569
|
+
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";
|
|
1856
2570
|
var UNCLASSIFIED_ERROR_CODE = "unknown";
|
|
1857
2571
|
var DEFAULT_AGENT_BUCKET = "(default)";
|
|
1858
2572
|
var TOOL_CALL_STATUSES = [
|
|
@@ -1990,7 +2704,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
1990
2704
|
}
|
|
1991
2705
|
async usageInRange(range) {
|
|
1992
2706
|
const { start, end } = dayBoundsUtc(range);
|
|
1993
|
-
const rows = await this.db.select().from(this.t.agentTokenUsage).where(
|
|
2707
|
+
const rows = await this.db.select().from(this.t.agentTokenUsage).where(and3(gte2(this.t.agentTokenUsage.createdAt, start), lte3(this.t.agentTokenUsage.createdAt, end)));
|
|
1994
2708
|
return rows.map(toUsageInput);
|
|
1995
2709
|
}
|
|
1996
2710
|
async spendByModel(range) {
|
|
@@ -2015,7 +2729,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2015
2729
|
if (threadIds.length === 0) {
|
|
2016
2730
|
return [];
|
|
2017
2731
|
}
|
|
2018
|
-
const threads = await this.db.select().from(this.t.agentThread).where(
|
|
2732
|
+
const threads = await this.db.select().from(this.t.agentThread).where(and3(inArray2(this.t.agentThread.id, threadIds), isNull3(this.t.agentThread.deletedAt)));
|
|
2019
2733
|
const threadsById = new Map(threads.map((thread) => [
|
|
2020
2734
|
thread.id,
|
|
2021
2735
|
{
|
|
@@ -2041,7 +2755,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2041
2755
|
threadId: this.t.agentMessage.threadId,
|
|
2042
2756
|
createdAt: this.t.agentToolCall.createdAt,
|
|
2043
2757
|
runId: this.t.agentToolCall.runId
|
|
2044
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
2758
|
+
}).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);
|
|
2045
2759
|
return rows.map((row) => ({
|
|
2046
2760
|
toolCallId: row.toolCallId,
|
|
2047
2761
|
toolName: row.toolName,
|
|
@@ -2107,12 +2821,12 @@ var DrizzleGovernanceQueries = class {
|
|
|
2107
2821
|
});
|
|
2108
2822
|
}
|
|
2109
2823
|
async recentThreads(limit) {
|
|
2110
|
-
const threads = await this.db.select().from(this.t.agentThread).where(
|
|
2824
|
+
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);
|
|
2111
2825
|
return this.toThreadActivityRows(threads);
|
|
2112
2826
|
}
|
|
2113
2827
|
async runsInRange(range) {
|
|
2114
2828
|
const { start, end } = dayBoundsUtc(range);
|
|
2115
|
-
return this.db.select().from(this.t.agentRun).where(
|
|
2829
|
+
return this.db.select().from(this.t.agentRun).where(and3(gte2(this.t.agentRun.startedAt, start), lte3(this.t.agentRun.startedAt, end)));
|
|
2116
2830
|
}
|
|
2117
2831
|
async runMetrics(range) {
|
|
2118
2832
|
const runs = await this.runsInRange(range);
|
|
@@ -2169,7 +2883,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2169
2883
|
}
|
|
2170
2884
|
async runErrors(range) {
|
|
2171
2885
|
const { start, end } = dayBoundsUtc(range);
|
|
2172
|
-
const runs = await this.db.select().from(this.t.agentRun).where(
|
|
2886
|
+
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")));
|
|
2173
2887
|
const byError = /* @__PURE__ */ new Map();
|
|
2174
2888
|
for (const run of runs) {
|
|
2175
2889
|
const errorCode = run.errorCode ?? UNCLASSIFIED_ERROR_CODE;
|
|
@@ -2228,7 +2942,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2228
2942
|
agentName: this.t.agentMessage.agentName,
|
|
2229
2943
|
requestedAt: this.t.agentToolCall.createdAt,
|
|
2230
2944
|
runId: this.t.agentToolCall.runId
|
|
2231
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
2945
|
+
}).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);
|
|
2232
2946
|
return rows.map((row) => ({
|
|
2233
2947
|
toolCallId: row.toolCallId,
|
|
2234
2948
|
toolName: row.toolName,
|
|
@@ -2250,7 +2964,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2250
2964
|
*/
|
|
2251
2965
|
async toolStats(range) {
|
|
2252
2966
|
const { start, end } = dayBoundsUtc(range);
|
|
2253
|
-
const calls = await this.db.select().from(this.t.agentToolCall).where(
|
|
2967
|
+
const calls = await this.db.select().from(this.t.agentToolCall).where(and3(gte2(this.t.agentToolCall.createdAt, start), lte3(this.t.agentToolCall.createdAt, end)));
|
|
2254
2968
|
const byTool = /* @__PURE__ */ new Map();
|
|
2255
2969
|
for (const call of calls) {
|
|
2256
2970
|
const key2 = `${call.toolName} ${call.toolType}`;
|
|
@@ -2300,10 +3014,10 @@ var DrizzleGovernanceQueries = class {
|
|
|
2300
3014
|
if (filters?.toolType !== void 0 && !isToolKind(filters.toolType)) {
|
|
2301
3015
|
return emptyPage(query);
|
|
2302
3016
|
}
|
|
2303
|
-
const whereClause =
|
|
3017
|
+
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);
|
|
2304
3018
|
const [totalRow] = await this.db.select({
|
|
2305
3019
|
value: count()
|
|
2306
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
3020
|
+
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage, eq3(this.t.agentToolCall.messageId, this.t.agentMessage.id)).where(whereClause);
|
|
2307
3021
|
const rows = await this.db.select({
|
|
2308
3022
|
toolCallId: this.t.agentToolCall.id,
|
|
2309
3023
|
toolName: this.t.agentToolCall.toolName,
|
|
@@ -2312,7 +3026,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2312
3026
|
threadId: this.t.agentMessage.threadId,
|
|
2313
3027
|
createdAt: this.t.agentToolCall.createdAt,
|
|
2314
3028
|
runId: this.t.agentToolCall.runId
|
|
2315
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
3029
|
+
}).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);
|
|
2316
3030
|
return {
|
|
2317
3031
|
rows: rows.map((row) => ({
|
|
2318
3032
|
toolCallId: row.toolCallId,
|
|
@@ -2336,7 +3050,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2336
3050
|
*/
|
|
2337
3051
|
async threadsPage(query) {
|
|
2338
3052
|
const filters = query.where;
|
|
2339
|
-
const whereClause =
|
|
3053
|
+
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);
|
|
2340
3054
|
const [totalRow] = await this.db.select({
|
|
2341
3055
|
value: count()
|
|
2342
3056
|
}).from(this.t.agentThread).where(whereClause);
|
|
@@ -2358,7 +3072,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2358
3072
|
if (filters?.status !== void 0 && !isRunStatus(filters.status)) {
|
|
2359
3073
|
return emptyPage(query);
|
|
2360
3074
|
}
|
|
2361
|
-
const whereClause =
|
|
3075
|
+
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);
|
|
2362
3076
|
const [totalRow] = await this.db.select({
|
|
2363
3077
|
value: count()
|
|
2364
3078
|
}).from(this.t.agentRun).where(whereClause);
|
|
@@ -2382,10 +3096,10 @@ var DrizzleGovernanceQueries = class {
|
|
|
2382
3096
|
*/
|
|
2383
3097
|
async approvalsPage(query) {
|
|
2384
3098
|
const filters = query.where;
|
|
2385
|
-
const whereClause =
|
|
3099
|
+
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);
|
|
2386
3100
|
const [totalRow] = await this.db.select({
|
|
2387
3101
|
value: count()
|
|
2388
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
3102
|
+
}).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);
|
|
2389
3103
|
const rows = await this.db.select({
|
|
2390
3104
|
toolCallId: this.t.agentToolCall.id,
|
|
2391
3105
|
toolName: this.t.agentToolCall.toolName,
|
|
@@ -2396,7 +3110,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2396
3110
|
agentName: this.t.agentMessage.agentName,
|
|
2397
3111
|
requestedAt: this.t.agentToolCall.createdAt,
|
|
2398
3112
|
runId: this.t.agentToolCall.runId
|
|
2399
|
-
}).from(this.t.agentToolCall).innerJoin(this.t.agentMessage,
|
|
3113
|
+
}).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);
|
|
2400
3114
|
return {
|
|
2401
3115
|
rows: rows.map((row) => ({
|
|
2402
3116
|
toolCallId: row.toolCallId,
|
|
@@ -2423,11 +3137,11 @@ var DrizzleGovernanceQueries = class {
|
|
|
2423
3137
|
const [row] = await this.db.select({
|
|
2424
3138
|
run: this.t.agentRun,
|
|
2425
3139
|
thread: this.t.agentThread
|
|
2426
|
-
}).from(this.t.agentRun).innerJoin(this.t.agentThread,
|
|
3140
|
+
}).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);
|
|
2427
3141
|
if (row === void 0) {
|
|
2428
3142
|
return null;
|
|
2429
3143
|
}
|
|
2430
|
-
const toolCalls = await this.db.select().from(this.t.agentToolCall).where(
|
|
3144
|
+
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));
|
|
2431
3145
|
return {
|
|
2432
3146
|
run: toRecentRunRow(row.run),
|
|
2433
3147
|
thread: {
|
|
@@ -2446,27 +3160,27 @@ var DrizzleGovernanceQueries = class {
|
|
|
2446
3160
|
* message. Soft-deleted threads are returned with `deleted: true`; an audit still needs them.
|
|
2447
3161
|
*/
|
|
2448
3162
|
async threadDetail(query) {
|
|
2449
|
-
const [thread] = await this.db.select().from(this.t.agentThread).where(
|
|
3163
|
+
const [thread] = await this.db.select().from(this.t.agentThread).where(eq3(this.t.agentThread.id, query.threadId)).limit(1);
|
|
2450
3164
|
if (thread === void 0) {
|
|
2451
3165
|
return null;
|
|
2452
3166
|
}
|
|
2453
3167
|
const pricing = await this.loadPricing();
|
|
2454
|
-
const usageRows = await this.db.select().from(this.t.agentTokenUsage).where(
|
|
3168
|
+
const usageRows = await this.db.select().from(this.t.agentTokenUsage).where(eq3(this.t.agentTokenUsage.threadId, thread.id));
|
|
2455
3169
|
const usage = rollupThreadUsage(usageRows.map(toUsageInput), pricing);
|
|
2456
3170
|
const [messageCountRow] = await this.db.select({
|
|
2457
3171
|
value: count()
|
|
2458
|
-
}).from(this.t.agentMessage).where(
|
|
2459
|
-
const messages = await this.db.select().from(this.t.agentMessage).where(
|
|
3172
|
+
}).from(this.t.agentMessage).where(eq3(this.t.agentMessage.threadId, thread.id));
|
|
3173
|
+
const messages = await this.db.select().from(this.t.agentMessage).where(eq3(this.t.agentMessage.threadId, thread.id)).orderBy(
|
|
2460
3174
|
// Append order (see DrizzleAgentStore's message order), newest first.
|
|
2461
|
-
desc2(
|
|
3175
|
+
desc2(sql4`coalesce(${this.t.agentMessage.seq}, 0)`),
|
|
2462
3176
|
desc2(this.t.agentMessage.createdAt),
|
|
2463
3177
|
desc2(this.t.agentMessage.id)
|
|
2464
3178
|
).limit(query.messageLimit);
|
|
2465
3179
|
const toolCallCounts = await this.toolCallCountsByMessage(messages.map((message) => message.id));
|
|
2466
3180
|
const [runTotalRow] = await this.db.select({
|
|
2467
3181
|
value: count()
|
|
2468
|
-
}).from(this.t.agentRun).where(
|
|
2469
|
-
const runs = await this.db.select().from(this.t.agentRun).where(
|
|
3182
|
+
}).from(this.t.agentRun).where(eq3(this.t.agentRun.threadId, thread.id));
|
|
3183
|
+
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);
|
|
2470
3184
|
return {
|
|
2471
3185
|
thread: {
|
|
2472
3186
|
threadId: thread.id,
|
|
@@ -2513,7 +3227,7 @@ var DrizzleGovernanceQueries = class {
|
|
|
2513
3227
|
|
|
2514
3228
|
// src/drizzle-memory-provider.ts
|
|
2515
3229
|
import { actorScope } from "@dudousxd/nestjs-agent-core";
|
|
2516
|
-
import { and as
|
|
3230
|
+
import { and as and4, eq as eq4, inArray as inArray3 } from "drizzle-orm";
|
|
2517
3231
|
function toRecord(row) {
|
|
2518
3232
|
return {
|
|
2519
3233
|
id: row.id,
|
|
@@ -2577,7 +3291,7 @@ var DrizzleMemoryProvider = class {
|
|
|
2577
3291
|
* answer cannot be used to find out which memories exist about other people.
|
|
2578
3292
|
*/
|
|
2579
3293
|
async forget({ id, ctx }) {
|
|
2580
|
-
const deleted = await affectedRows(this.dialect, this.db.delete(this.t.agentMemory).where(
|
|
3294
|
+
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);
|
|
2581
3295
|
return deleted > 0;
|
|
2582
3296
|
}
|
|
2583
3297
|
/**
|
|
@@ -2626,7 +3340,7 @@ var DrizzleMemoryProvider = class {
|
|
|
2626
3340
|
memory.scope,
|
|
2627
3341
|
memory.key
|
|
2628
3342
|
], set);
|
|
2629
|
-
[row] = await this.db.select().from(memory).where(
|
|
3343
|
+
[row] = await this.db.select().from(memory).where(and4(eq4(memory.scope, scope), eq4(memory.key, key2)));
|
|
2630
3344
|
} else {
|
|
2631
3345
|
[row] = await insert.onConflictDoUpdate({
|
|
2632
3346
|
target: [
|
|
@@ -2653,7 +3367,7 @@ var DrizzleMemoryProvider = class {
|
|
|
2653
3367
|
const updated = await affectedRows(this.dialect, this.db.update(this.t.agentMemory).set({
|
|
2654
3368
|
pinned,
|
|
2655
3369
|
updatedAt: /* @__PURE__ */ new Date()
|
|
2656
|
-
}).where(
|
|
3370
|
+
}).where(eq4(this.t.agentMemory.id, id)), this.t.agentMemory.id);
|
|
2657
3371
|
return updated > 0;
|
|
2658
3372
|
}
|
|
2659
3373
|
};
|
|
@@ -2666,7 +3380,7 @@ function assertAuthorMayWriteScope({ scope, origin, ctx }) {
|
|
|
2666
3380
|
__name(assertAuthorMayWriteScope, "assertAuthorMayWriteScope");
|
|
2667
3381
|
|
|
2668
3382
|
// src/drizzle-pricing-store.ts
|
|
2669
|
-
import { and as
|
|
3383
|
+
import { and as and5, eq as eq5 } from "drizzle-orm";
|
|
2670
3384
|
var DrizzlePricingStore = class {
|
|
2671
3385
|
static {
|
|
2672
3386
|
__name(this, "DrizzlePricingStore");
|
|
@@ -2682,7 +3396,7 @@ var DrizzlePricingStore = class {
|
|
|
2682
3396
|
async upsertModelPrice(input) {
|
|
2683
3397
|
await this.db.update(this.t.agentModelPricing).set({
|
|
2684
3398
|
isCurrent: false
|
|
2685
|
-
}).where(
|
|
3399
|
+
}).where(and5(eq5(this.t.agentModelPricing.modelId, input.modelId), eq5(this.t.agentModelPricing.isCurrent, true)));
|
|
2686
3400
|
await this.db.insert(this.t.agentModelPricing).values({
|
|
2687
3401
|
id: crypto.randomUUID(),
|
|
2688
3402
|
modelId: input.modelId,
|
|
@@ -2695,7 +3409,7 @@ var DrizzlePricingStore = class {
|
|
|
2695
3409
|
});
|
|
2696
3410
|
}
|
|
2697
3411
|
async listCurrentPrices() {
|
|
2698
|
-
const rows = await this.db.select().from(this.t.agentModelPricing).where(
|
|
3412
|
+
const rows = await this.db.select().from(this.t.agentModelPricing).where(eq5(this.t.agentModelPricing.isCurrent, true));
|
|
2699
3413
|
return rows.map((row) => ({
|
|
2700
3414
|
modelId: row.modelId,
|
|
2701
3415
|
inputPricePer1m: row.inputPricePer1m,
|
|
@@ -2713,7 +3427,7 @@ var DrizzlePricingStore = class {
|
|
|
2713
3427
|
|
|
2714
3428
|
// src/drizzle-token-stream-sink.ts
|
|
2715
3429
|
import { SqlTokenStreamSink } from "@dudousxd/nestjs-agent-core";
|
|
2716
|
-
import { and as
|
|
3430
|
+
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";
|
|
2717
3431
|
var DrizzleStreamFrameTable = class {
|
|
2718
3432
|
static {
|
|
2719
3433
|
__name(this, "DrizzleStreamFrameTable");
|
|
@@ -2727,7 +3441,7 @@ var DrizzleStreamFrameTable = class {
|
|
|
2727
3441
|
this.db = asBuilder(db);
|
|
2728
3442
|
}
|
|
2729
3443
|
async append(runId, row) {
|
|
2730
|
-
await runSql(this.db, this.dialect,
|
|
3444
|
+
await runSql(this.db, this.dialect, sql5`INSERT INTO agent_stream_frame (run_id, seq, frame, error, created_at)
|
|
2731
3445
|
SELECT ${runId}, COALESCE(MAX(seq), 0) + 1, ${row.frame}, ${row.error}, ${row.createdAt}
|
|
2732
3446
|
FROM agent_stream_frame WHERE run_id = ${runId}`);
|
|
2733
3447
|
}
|
|
@@ -2736,12 +3450,12 @@ var DrizzleStreamFrameTable = class {
|
|
|
2736
3450
|
seq: this.t.agentStreamFrame.seq,
|
|
2737
3451
|
frame: this.t.agentStreamFrame.frame,
|
|
2738
3452
|
error: this.t.agentStreamFrame.error
|
|
2739
|
-
}).from(this.t.agentStreamFrame).where(
|
|
3453
|
+
}).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);
|
|
2740
3454
|
}
|
|
2741
3455
|
async has(runId) {
|
|
2742
3456
|
const rows = await this.db.select({
|
|
2743
3457
|
seq: this.t.agentStreamFrame.seq
|
|
2744
|
-
}).from(this.t.agentStreamFrame).where(
|
|
3458
|
+
}).from(this.t.agentStreamFrame).where(eq6(this.t.agentStreamFrame.runId, runId)).limit(1);
|
|
2745
3459
|
return rows.length > 0;
|
|
2746
3460
|
}
|
|
2747
3461
|
async remove(runIds) {
|
|
@@ -2753,7 +3467,7 @@ var DrizzleStreamFrameTable = class {
|
|
|
2753
3467
|
async lapsedRuns(cutoff) {
|
|
2754
3468
|
const rows = await this.db.select({
|
|
2755
3469
|
runId: this.t.agentStreamFrame.runId
|
|
2756
|
-
}).from(this.t.agentStreamFrame).groupBy(this.t.agentStreamFrame.runId).having(lt(
|
|
3470
|
+
}).from(this.t.agentStreamFrame).groupBy(this.t.agentStreamFrame.runId).having(lt(max3(this.t.agentStreamFrame.createdAt), cutoff));
|
|
2757
3471
|
return rows.map((row) => row.runId);
|
|
2758
3472
|
}
|
|
2759
3473
|
isUniqueViolation(error) {
|
|
@@ -2770,7 +3484,7 @@ var DrizzleTokenStreamSink = class extends SqlTokenStreamSink {
|
|
|
2770
3484
|
};
|
|
2771
3485
|
|
|
2772
3486
|
// src/drizzle-confirm-token-store.ts
|
|
2773
|
-
import { eq as
|
|
3487
|
+
import { eq as eq7, lt as lt2 } from "drizzle-orm";
|
|
2774
3488
|
var DrizzleConfirmTokenStore = class {
|
|
2775
3489
|
static {
|
|
2776
3490
|
__name(this, "DrizzleConfirmTokenStore");
|
|
@@ -2800,7 +3514,7 @@ var DrizzleConfirmTokenStore = class {
|
|
|
2800
3514
|
return inserted === 1;
|
|
2801
3515
|
}
|
|
2802
3516
|
async release(hash) {
|
|
2803
|
-
await this.db.delete(this.t.agentConfirmToken).where(
|
|
3517
|
+
await this.db.delete(this.t.agentConfirmToken).where(eq7(this.t.agentConfirmToken.hash, hash));
|
|
2804
3518
|
}
|
|
2805
3519
|
async purgeExpired(now = Date.now()) {
|
|
2806
3520
|
const table = this.t.agentConfirmToken;
|
|
@@ -2811,7 +3525,7 @@ var DrizzleConfirmTokenStore = class {
|
|
|
2811
3525
|
// src/drizzle-rag-ingestion-log.ts
|
|
2812
3526
|
import { subscribe, unsubscribe } from "diagnostics_channel";
|
|
2813
3527
|
import { Injectable, Logger } from "@nestjs/common";
|
|
2814
|
-
import { and as
|
|
3528
|
+
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";
|
|
2815
3529
|
function _ts_decorate(decorators, target, key2, desc4) {
|
|
2816
3530
|
var c = arguments.length, r = c < 3 ? target : desc4 === null ? desc4 = Object.getOwnPropertyDescriptor(target, key2) : desc4, d;
|
|
2817
3531
|
if (typeof Reflect === "object" && typeof Reflect.decorate === "function") {
|
|
@@ -2860,7 +3574,7 @@ function num(value) {
|
|
|
2860
3574
|
__name(num, "num");
|
|
2861
3575
|
var RAG_INGESTION_LOG_PAGE_ORDER = [
|
|
2862
3576
|
desc3(ragIngestionLog.updatedAt),
|
|
2863
|
-
|
|
3577
|
+
asc5(ragIngestionLog.documentId)
|
|
2864
3578
|
];
|
|
2865
3579
|
var DEFAULT_PAGE_SIZE = 200;
|
|
2866
3580
|
var DEFAULT_BATCH_SIZE = 200;
|
|
@@ -3010,17 +3724,17 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
3010
3724
|
}
|
|
3011
3725
|
/** The latest recorded outcome for one document, or null if it was never attempted. */
|
|
3012
3726
|
async get(documentId) {
|
|
3013
|
-
const [row] = await this.db.select().from(this.t.ragIngestionLog).where(
|
|
3727
|
+
const [row] = await this.db.select().from(this.t.ragIngestionLog).where(eq8(this.t.ragIngestionLog.documentId, documentId));
|
|
3014
3728
|
return row ?? null;
|
|
3015
3729
|
}
|
|
3016
3730
|
/** Forget one document's record. Returns whether a row was actually removed. */
|
|
3017
3731
|
async remove(documentId) {
|
|
3018
|
-
const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(
|
|
3732
|
+
const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq8(this.t.ragIngestionLog.documentId, documentId)), this.t.ragIngestionLog.documentId);
|
|
3019
3733
|
return removed > 0;
|
|
3020
3734
|
}
|
|
3021
3735
|
/** Forget every record for a collection — for when the collection itself is deleted. */
|
|
3022
3736
|
async removeByCollection(collection) {
|
|
3023
|
-
const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(
|
|
3737
|
+
const removed = await affectedRows(this.dialect, this.db.delete(this.t.ragIngestionLog).where(eq8(this.t.ragIngestionLog.collection, collection)), this.t.ragIngestionLog.documentId);
|
|
3024
3738
|
return removed;
|
|
3025
3739
|
}
|
|
3026
3740
|
/**
|
|
@@ -3050,7 +3764,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
3050
3764
|
}
|
|
3051
3765
|
}
|
|
3052
3766
|
where(query) {
|
|
3053
|
-
return
|
|
3767
|
+
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);
|
|
3054
3768
|
}
|
|
3055
3769
|
/**
|
|
3056
3770
|
* The coordinates filter AND'd with "strictly after `cursor` in
|
|
@@ -3065,7 +3779,7 @@ var DrizzleRagIngestionLog = class _DrizzleRagIngestionLog {
|
|
|
3065
3779
|
if (cursor === void 0) {
|
|
3066
3780
|
return base;
|
|
3067
3781
|
}
|
|
3068
|
-
return
|
|
3782
|
+
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))));
|
|
3069
3783
|
}
|
|
3070
3784
|
/**
|
|
3071
3785
|
* Upsert one outcome. Keyed by document id so the row always reflects the *current* state — a
|
|
@@ -3240,6 +3954,7 @@ DrizzleAgentStoreModule = _ts_decorate2([
|
|
|
3240
3954
|
Module({})
|
|
3241
3955
|
], DrizzleAgentStoreModule);
|
|
3242
3956
|
export {
|
|
3957
|
+
DrizzleActionProposalStore,
|
|
3243
3958
|
DrizzleAgentStore,
|
|
3244
3959
|
DrizzleAgentStoreModule,
|
|
3245
3960
|
DrizzleConfirmTokenStore,
|
|
@@ -3250,6 +3965,7 @@ export {
|
|
|
3250
3965
|
DrizzleStreamFrameTable,
|
|
3251
3966
|
DrizzleTokenStreamSink,
|
|
3252
3967
|
RAG_INGESTION_LOG_PAGE_ORDER,
|
|
3968
|
+
agentActionProposal,
|
|
3253
3969
|
agentConfirmToken,
|
|
3254
3970
|
agentDialectOf,
|
|
3255
3971
|
agentMemory,
|