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