@dudousxd/nestjs-agent-store-drizzle 0.1.0 → 0.3.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/index.cjs CHANGED
@@ -42,7 +42,6 @@ var agentThread = (0, import_sqlite_core.sqliteTable)("agent_thread", {
42
42
  actorRef: (0, import_sqlite_core.text)("actor_ref").notNull(),
43
43
  tenantRef: (0, import_sqlite_core.text)("tenant_ref"),
44
44
  title: (0, import_sqlite_core.text)("title").notNull(),
45
- persona: (0, import_sqlite_core.text)("persona").notNull().default("default"),
46
45
  transient: (0, import_sqlite_core.integer)("transient", {
47
46
  mode: "boolean"
48
47
  }).notNull().default(false),
@@ -78,7 +77,7 @@ var agentMessage = (0, import_sqlite_core.sqliteTable)("agent_message", {
78
77
  usage: (0, import_sqlite_core.text)("usage", {
79
78
  mode: "json"
80
79
  }).$type(),
81
- persona: (0, import_sqlite_core.text)("persona"),
80
+ agentName: (0, import_sqlite_core.text)("agent_name"),
82
81
  createdAt: (0, import_sqlite_core.integer)("created_at", {
83
82
  mode: "timestamp_ms"
84
83
  }).notNull()
@@ -164,7 +163,6 @@ var statements = [
164
163
  actor_ref TEXT NOT NULL,
165
164
  tenant_ref TEXT,
166
165
  title TEXT NOT NULL,
167
- persona TEXT NOT NULL DEFAULT 'default',
168
166
  transient INTEGER NOT NULL DEFAULT 0,
169
167
  active_stream_id TEXT,
170
168
  created_at INTEGER NOT NULL,
@@ -182,7 +180,7 @@ var statements = [
182
180
  tool_results TEXT,
183
181
  follow_ups TEXT,
184
182
  usage TEXT,
185
- persona TEXT,
183
+ agent_name TEXT,
186
184
  created_at INTEGER NOT NULL
187
185
  )`,
188
186
  `CREATE INDEX IF NOT EXISTS agent_message_thread_created_idx
@@ -252,7 +250,6 @@ var DrizzleAgentStore = class {
252
250
  actorRef: input.actor.id,
253
251
  tenantRef: input.actor.tenantRef ?? null,
254
252
  title: input.title ?? "New chat",
255
- persona: input.persona,
256
253
  transient: input.transient ?? false,
257
254
  activeStreamId: null,
258
255
  createdAt: now,
@@ -305,7 +302,6 @@ var DrizzleAgentStore = class {
305
302
  actorRef: source.actorRef,
306
303
  tenantRef: source.tenantRef,
307
304
  title: source.title,
308
- persona: source.persona,
309
305
  transient: false,
310
306
  activeStreamId: null,
311
307
  createdAt: now,
@@ -323,7 +319,7 @@ var DrizzleAgentStore = class {
323
319
  toolResults: message.toolResults,
324
320
  followUps: message.followUps,
325
321
  usage: message.usage,
326
- persona: message.persona,
322
+ agentName: message.agentName,
327
323
  createdAt: message.createdAt
328
324
  })));
329
325
  }
@@ -359,6 +355,12 @@ var DrizzleAgentStore = class {
359
355
  updatedAt: /* @__PURE__ */ new Date()
360
356
  }).where((0, import_drizzle_orm2.eq)(agentThread.id, threadId));
361
357
  }
358
+ async promoteThread(threadId) {
359
+ await this.db.update(agentThread).set({
360
+ transient: false,
361
+ updatedAt: /* @__PURE__ */ new Date()
362
+ }).where((0, import_drizzle_orm2.and)((0, import_drizzle_orm2.eq)(agentThread.id, threadId), (0, import_drizzle_orm2.eq)(agentThread.transient, true)));
363
+ }
362
364
  async setActiveStream(threadId, runId) {
363
365
  await this.db.update(agentThread).set({
364
366
  activeStreamId: runId
@@ -379,7 +381,7 @@ var DrizzleAgentStore = class {
379
381
  toolResults: input.toolResults ?? null,
380
382
  followUps: input.followUps ?? null,
381
383
  usage: input.usage ?? null,
382
- persona: input.persona ?? null,
384
+ agentName: input.agentName ?? null,
383
385
  createdAt: now
384
386
  };
385
387
  await this.db.insert(agentMessage).values(message);
@@ -456,15 +458,16 @@ var DrizzleAgentStore = class {
456
458
  const end = /* @__PURE__ */ new Date(`${day}T23:59:59.999Z`);
457
459
  const rows = await this.db.select().from(agentTokenUsage).where((0, import_drizzle_orm2.and)((0, import_drizzle_orm2.eq)(agentTokenUsage.actorRef, actorRef), (0, import_drizzle_orm2.gte)(agentTokenUsage.createdAt, start), (0, import_drizzle_orm2.lte)(agentTokenUsage.createdAt, end)));
458
460
  const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);
461
+ const costUsd = rows.reduce((sum, row) => sum + (row.costUsd ?? 0), 0);
459
462
  return {
460
- usedTokens
463
+ usedTokens,
464
+ costUsd
461
465
  };
462
466
  }
463
467
  toSummary(thread, lastContent) {
464
468
  return {
465
469
  id: thread.id,
466
470
  title: thread.title,
467
- persona: thread.persona,
468
471
  transient: thread.transient,
469
472
  createdAt: thread.createdAt.toISOString(),
470
473
  updatedAt: thread.updatedAt.toISOString(),
@@ -490,6 +493,9 @@ var DrizzleAgentStore = class {
490
493
  } : {},
491
494
  ...message.usage != null ? {
492
495
  usage: message.usage
496
+ } : {},
497
+ ...message.agentName != null ? {
498
+ agentName: message.agentName
493
499
  } : {}
494
500
  };
495
501
  }
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/ensure-schema.ts","../src/drizzle-agent-store.ts","../src/drizzle-governance-queries.ts","../src/drizzle-pricing-store.ts","../src/drizzle-agent-store.module.ts"],"sourcesContent":["export * from './schema.js';\nexport * from './ensure-schema.js';\nexport * from './drizzle-agent-store.js';\nexport * from './drizzle-governance-queries.js';\nexport * from './drizzle-pricing-store.js';\nexport * from './drizzle-agent-store.module.js';\n","import type {\n MessageRole,\n MessageUsage,\n ToolCallRequest,\n ToolCallStatus,\n ToolKind,\n ToolResult,\n UsagePurpose,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n type BaseSQLiteDatabase,\n index,\n integer,\n real,\n sqliteTable,\n text,\n} from 'drizzle-orm/sqlite-core';\n\n/**\n * Drizzle schema mirroring the MikroORM agent entities (same logical columns/relations):\n * threads, messages, tool calls, token usage and model pricing. Targets the SQLite core so the\n * db-test runs on an in-memory better-sqlite3; timestamps are stored as integer epoch-ms columns\n * (`{ mode: 'timestamp_ms' }`) which Drizzle round-trips to/from JS `Date`, and the model-facing\n * message extras (tool calls/results, follow-ups, usage) live in JSON `text` columns.\n */\n\n/**\n * A conversation thread. `deletedAt` drives soft delete: a deleted thread is hidden from\n * {@link import('./drizzle-agent-store.js').DrizzleAgentStore.getThread}/`listThreads` but its\n * row survives.\n */\nexport const agentThread = sqliteTable(\n 'agent_thread',\n {\n id: text('id').primaryKey(),\n actorRef: text('actor_ref').notNull(),\n tenantRef: text('tenant_ref'),\n title: text('title').notNull(),\n persona: text('persona').notNull().default('default'),\n transient: integer('transient', { mode: 'boolean' }).notNull().default(false),\n activeStreamId: text('active_stream_id'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n updatedAt: integer('updated_at', { mode: 'timestamp_ms' }).notNull(),\n deletedAt: integer('deleted_at', { mode: 'timestamp_ms' }),\n },\n (table) => [index('agent_thread_actor_updated_idx').on(table.actorRef, table.updatedAt)],\n);\n\n/**\n * One stored message in a thread. The model-facing extras (`toolCalls`/`toolResults`/\n * `followUps`/`usage`) are folded into nullable JSON columns so a single row round-trips to a\n * {@link import('@dudousxd/nestjs-agent-core').StoredMessage}. `threadId` cascades on delete.\n */\nexport const agentMessage = sqliteTable(\n 'agent_message',\n {\n id: text('id').primaryKey(),\n threadId: text('thread_id')\n .notNull()\n .references(() => agentThread.id, { onDelete: 'cascade' }),\n role: text('role').$type<MessageRole>().notNull(),\n content: text('content').notNull(),\n toolCalls: text('tool_calls', { mode: 'json' }).$type<ToolCallRequest[]>(),\n toolResults: text('tool_results', { mode: 'json' }).$type<ToolResult[]>(),\n followUps: text('follow_ups', { mode: 'json' }).$type<string[]>(),\n usage: text('usage', { mode: 'json' }).$type<MessageUsage>(),\n persona: text('persona'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n },\n (table) => [index('agent_message_thread_created_idx').on(table.threadId, table.createdAt)],\n);\n\n/** A tool call requested during an assistant turn. The pk is the model-supplied `toolCallId`. */\nexport const agentToolCall = sqliteTable('agent_tool_call', {\n id: text('id').primaryKey(),\n messageId: text('message_id')\n .notNull()\n .references(() => agentMessage.id, { onDelete: 'cascade' }),\n toolName: text('tool_name').notNull(),\n toolType: text('tool_type').$type<ToolKind>().notNull(),\n input: text('input', { mode: 'json' }),\n output: text('output', { mode: 'json' }),\n status: text('status').$type<ToolCallStatus>().notNull(),\n executedByRef: text('executed_by_ref'),\n executionMs: integer('execution_ms'),\n error: text('error'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n executedAt: integer('executed_at', { mode: 'timestamp_ms' }),\n});\n\n/** A token-usage ledger row, summed per actor per day by `quotaToday`. */\nexport const agentTokenUsage = sqliteTable(\n 'agent_token_usage',\n {\n id: text('id').primaryKey(),\n threadId: text('thread_id')\n .notNull()\n .references(() => agentThread.id, { onDelete: 'cascade' }),\n actorRef: text('actor_ref').notNull(),\n messageId: text('message_id'),\n modelId: text('model_id').notNull(),\n purpose: text('purpose').$type<UsagePurpose>().notNull(),\n inputTokens: integer('input_tokens').notNull(),\n outputTokens: integer('output_tokens').notNull(),\n /** Subset of `inputTokens` written to the prompt cache this turn; null when not reported. */\n cacheWriteTokens: integer('cache_write_tokens'),\n /** Subset of `inputTokens` served from the prompt cache this turn; null when not reported. */\n cacheReadTokens: integer('cache_read_tokens'),\n /** Provider-reported actual USD cost for the turn; null when only tokens were reported. */\n costUsd: real('cost_usd'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n },\n (table) => [index('agent_token_usage_actor_created_idx').on(table.actorRef, table.createdAt)],\n);\n\n/** Per-model token pricing, versioned by `effectiveFrom`; `isCurrent` flags the live row. */\nexport const agentModelPricing = sqliteTable('agent_model_pricing', {\n id: text('id').primaryKey(),\n modelId: text('model_id').notNull(),\n inputPricePer1m: real('input_price_per_1m').notNull(),\n outputPricePer1m: real('output_price_per_1m').notNull(),\n /** Per-1M price for cache-write input tokens; null → price them at the input rate. */\n cacheWritePricePer1m: real('cache_write_price_per_1m'),\n /** Per-1M price for cache-read input tokens; null → price them at the input rate. */\n cacheReadPricePer1m: real('cache_read_price_per_1m'),\n effectiveFrom: integer('effective_from', { mode: 'timestamp_ms' }).notNull(),\n isCurrent: integer('is_current', { mode: 'boolean' }).notNull(),\n});\n\n/** The five agent tables as one schema object, ready for `drizzle(client, { schema })`. */\nexport const agentSchema = {\n agentThread,\n agentMessage,\n agentToolCall,\n agentTokenUsage,\n agentModelPricing,\n};\n\n/**\n * The dialect-portable Drizzle SQLite database handle the store operates on. Accepts any SQLite\n * driver (better-sqlite3, libsql, D1, …) in either sync or async result mode; the host app owns\n * the connection and passes the `drizzle(...)` instance in.\n */\nexport type AgentDrizzleDb = BaseSQLiteDatabase<'sync' | 'async', unknown>;\n\n/** A persisted thread row as Drizzle selects it. */\nexport type AgentThreadRow = typeof agentThread.$inferSelect;\n/** A persisted message row as Drizzle selects it. */\nexport type AgentMessageRow = typeof agentMessage.$inferSelect;\n","import { sql } from 'drizzle-orm';\nimport type { AgentDrizzleDb } from './schema.js';\n\n/**\n * Idempotent `CREATE TABLE IF NOT EXISTS` DDL for the five agent tables, mirroring\n * {@link import('./schema.js').agentSchema}. SQLite dialect (the db-test driver); kept here rather\n * than relying on drizzle-kit so the package can stand up its schema with no migration files. Safe\n * to run on boot against a shared database — it never drops or alters existing columns.\n */\nconst statements: string[] = [\n `CREATE TABLE IF NOT EXISTS agent_thread (\n id TEXT PRIMARY KEY NOT NULL,\n actor_ref TEXT NOT NULL,\n tenant_ref TEXT,\n title TEXT NOT NULL,\n persona TEXT NOT NULL DEFAULT 'default',\n transient INTEGER NOT NULL DEFAULT 0,\n active_stream_id TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n deleted_at INTEGER\n )`,\n `CREATE INDEX IF NOT EXISTS agent_thread_actor_updated_idx\n ON agent_thread (actor_ref, updated_at)`,\n `CREATE TABLE IF NOT EXISTS agent_message (\n id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL REFERENCES agent_thread(id) ON DELETE CASCADE,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n tool_calls TEXT,\n tool_results TEXT,\n follow_ups TEXT,\n usage TEXT,\n persona TEXT,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS agent_message_thread_created_idx\n ON agent_message (thread_id, created_at)`,\n `CREATE TABLE IF NOT EXISTS agent_tool_call (\n id TEXT PRIMARY KEY NOT NULL,\n message_id TEXT NOT NULL REFERENCES agent_message(id) ON DELETE CASCADE,\n tool_name TEXT NOT NULL,\n tool_type TEXT NOT NULL,\n input TEXT,\n output TEXT,\n status TEXT NOT NULL,\n executed_by_ref TEXT,\n execution_ms INTEGER,\n error TEXT,\n created_at INTEGER NOT NULL,\n executed_at INTEGER\n )`,\n `CREATE TABLE IF NOT EXISTS agent_token_usage (\n id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL REFERENCES agent_thread(id) ON DELETE CASCADE,\n actor_ref TEXT NOT NULL,\n message_id TEXT,\n model_id TEXT NOT NULL,\n purpose TEXT NOT NULL,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n cache_write_tokens INTEGER,\n cache_read_tokens INTEGER,\n cost_usd REAL,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS agent_token_usage_actor_created_idx\n ON agent_token_usage (actor_ref, created_at)`,\n `CREATE TABLE IF NOT EXISTS agent_model_pricing (\n id TEXT PRIMARY KEY NOT NULL,\n model_id TEXT NOT NULL,\n input_price_per_1m REAL NOT NULL,\n output_price_per_1m REAL NOT NULL,\n cache_write_price_per_1m REAL,\n cache_read_price_per_1m REAL,\n effective_from INTEGER NOT NULL,\n is_current INTEGER NOT NULL\n )`,\n];\n\n/** Runs the `CREATE TABLE IF NOT EXISTS` DDL above against the supplied Drizzle SQLite db. */\nexport async function ensureAgentSchema(db: AgentDrizzleDb): Promise<void> {\n for (const statement of statements) {\n await db.run(sql.raw(statement));\n }\n}\n","import type {\n AgentStore,\n AppendMessageInput,\n CreateThreadInput,\n RecordToolCallInput,\n RecordUsageInput,\n StoredMessage,\n ThreadDetail,\n ThreadSummary,\n UpdateToolCallInput,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, asc, desc, eq, gte, inArray, isNull, lte } from 'drizzle-orm';\nimport {\n type AgentDrizzleDb,\n type AgentMessageRow,\n type AgentThreadRow,\n agentMessage,\n agentThread,\n agentTokenUsage,\n agentToolCall,\n} from './schema.js';\n\n/**\n * {@link AgentStore} backed by Drizzle ORM — a second adapter alongside the MikroORM one, proving\n * the store SPI is ORM-portable. A POJO receiving a Drizzle SQLite database handle (the host app\n * owns the connection). Behaviour mirrors {@link import('@dudousxd/nestjs-agent-store-mikro-orm')}\n * exactly (fork/truncate/quota/active-stream/soft-delete semantics) so the two are interchangeable.\n */\nexport class DrizzleAgentStore implements AgentStore {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n async createThread(input: CreateThreadInput): Promise<ThreadSummary> {\n const now = new Date();\n const thread: AgentThreadRow = {\n id: crypto.randomUUID(),\n actorRef: input.actor.id,\n tenantRef: input.actor.tenantRef ?? null,\n title: input.title ?? 'New chat',\n persona: input.persona,\n transient: input.transient ?? false,\n activeStreamId: null,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n };\n await this.db.insert(agentThread).values(thread);\n return this.toSummary(thread);\n }\n\n async getThread(threadId: string): Promise<ThreadDetail | null> {\n const [thread] = await this.db\n .select()\n .from(agentThread)\n .where(and(eq(agentThread.id, threadId), isNull(agentThread.deletedAt)));\n if (thread === undefined) {\n return null;\n }\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const last = messages[messages.length - 1];\n return {\n ...this.toSummary(thread, last?.content),\n messages: messages.map((message) => this.toStoredMessage(message)),\n ...(thread.activeStreamId != null ? { activeStreamId: thread.activeStreamId } : {}),\n };\n }\n\n async listThreads(actorRef: string, limit = 50): Promise<ThreadSummary[]> {\n const threads = await this.db\n .select()\n .from(agentThread)\n .where(\n and(\n eq(agentThread.actorRef, actorRef),\n eq(agentThread.transient, false),\n isNull(agentThread.deletedAt),\n ),\n )\n .orderBy(desc(agentThread.updatedAt))\n .limit(limit);\n const summaries: ThreadSummary[] = [];\n for (const thread of threads) {\n const [last] = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, thread.id))\n .orderBy(desc(agentMessage.createdAt), desc(agentMessage.id))\n .limit(1);\n summaries.push(this.toSummary(thread, last?.content));\n }\n return summaries;\n }\n\n async softDeleteThread(threadId: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ deletedAt: new Date() })\n .where(eq(agentThread.id, threadId));\n }\n\n async forkThread(threadId: string, fromMessageId: string): Promise<ThreadSummary> {\n const [source] = await this.db.select().from(agentThread).where(eq(agentThread.id, threadId));\n if (source === undefined) {\n throw new Error(`thread ${threadId} not found`);\n }\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const cutoff = messages.findIndex((message) => message.id === fromMessageId);\n const kept = cutoff >= 0 ? messages.slice(0, cutoff + 1) : messages;\n const now = new Date();\n const fork: AgentThreadRow = {\n id: crypto.randomUUID(),\n actorRef: source.actorRef,\n tenantRef: source.tenantRef,\n title: source.title,\n persona: source.persona,\n transient: false,\n activeStreamId: null,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n };\n await this.db.insert(agentThread).values(fork);\n if (kept.length > 0) {\n await this.db.insert(agentMessage).values(\n kept.map((message) => ({\n id: crypto.randomUUID(),\n threadId: fork.id,\n role: message.role,\n content: message.content,\n toolCalls: message.toolCalls,\n toolResults: message.toolResults,\n followUps: message.followUps,\n usage: message.usage,\n persona: message.persona,\n createdAt: message.createdAt,\n })),\n );\n }\n return this.toSummary(fork);\n }\n\n async ownerOfThread(threadId: string): Promise<string | null> {\n const [thread] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentThread)\n .where(and(eq(agentThread.id, threadId), isNull(agentThread.deletedAt)));\n return thread?.actorRef ?? null;\n }\n\n async ownerOfToolCall(toolCallId: string): Promise<string | null> {\n const [row] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .innerJoin(agentThread, eq(agentMessage.threadId, agentThread.id))\n .where(eq(agentToolCall.id, toolCallId));\n return row?.actorRef ?? null;\n }\n\n async runForToolCall(toolCallId: string): Promise<string | null> {\n const [row] = await this.db\n .select({ activeStreamId: agentThread.activeStreamId })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .innerJoin(agentThread, eq(agentMessage.threadId, agentThread.id))\n .where(eq(agentToolCall.id, toolCallId));\n return row?.activeStreamId ?? null;\n }\n\n async ownerOfActiveStream(runId: string): Promise<string | null> {\n const [thread] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentThread)\n .where(and(eq(agentThread.activeStreamId, runId), isNull(agentThread.deletedAt)));\n return thread?.actorRef ?? null;\n }\n\n async setTitle(threadId: string, title: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ title, updatedAt: new Date() })\n .where(eq(agentThread.id, threadId));\n }\n\n async setActiveStream(threadId: string, runId: string | null): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ activeStreamId: runId })\n .where(eq(agentThread.id, threadId));\n }\n\n async appendMessage(input: AppendMessageInput): Promise<StoredMessage> {\n const [thread] = await this.db\n .select()\n .from(agentThread)\n .where(eq(agentThread.id, input.threadId));\n if (thread === undefined) {\n throw new Error(`thread ${input.threadId} not found`);\n }\n const now = new Date();\n const message: AgentMessageRow = {\n id: crypto.randomUUID(),\n threadId: input.threadId,\n role: input.role,\n content: input.content,\n toolCalls: input.toolCalls ?? null,\n toolResults: input.toolResults ?? null,\n followUps: input.followUps ?? null,\n usage: input.usage ?? null,\n persona: input.persona ?? null,\n createdAt: now,\n };\n await this.db.insert(agentMessage).values(message);\n await this.db\n .update(agentThread)\n .set({ updatedAt: now })\n .where(eq(agentThread.id, input.threadId));\n return this.toStoredMessage(message);\n }\n\n async truncateFrom(threadId: string, messageId: string): Promise<void> {\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const cutoff = messages.findIndex((message) => message.id === messageId);\n if (cutoff < 0) {\n return;\n }\n const doomedIds = messages.slice(cutoff).map((message) => message.id);\n await this.db.delete(agentToolCall).where(inArray(agentToolCall.messageId, doomedIds));\n await this.db.delete(agentMessage).where(inArray(agentMessage.id, doomedIds));\n }\n\n async recordToolCall(input: RecordToolCallInput): Promise<void> {\n await this.db.insert(agentToolCall).values({\n id: input.toolCallId,\n messageId: input.messageId,\n toolName: input.toolName,\n toolType: input.toolType,\n input: input.input,\n output: null,\n status: input.status,\n executedByRef: null,\n executionMs: null,\n error: null,\n createdAt: new Date(),\n executedAt: null,\n });\n }\n\n async updateToolCall(input: UpdateToolCallInput): Promise<void> {\n const updates: Partial<typeof agentToolCall.$inferInsert> = { status: input.status };\n if (input.output !== undefined) {\n updates.output = input.output;\n }\n if (input.error !== undefined) {\n updates.error = input.error;\n }\n if (input.executionMs !== undefined) {\n updates.executionMs = input.executionMs;\n }\n if (input.executedByRef !== undefined) {\n updates.executedByRef = input.executedByRef;\n }\n if (input.status === 'executed' || input.status === 'auto_executed') {\n updates.executedAt = new Date();\n }\n await this.db.update(agentToolCall).set(updates).where(eq(agentToolCall.id, input.toolCallId));\n }\n\n async recordUsage(input: RecordUsageInput): Promise<void> {\n await this.db.insert(agentTokenUsage).values({\n id: crypto.randomUUID(),\n threadId: input.threadId,\n actorRef: input.actorRef,\n messageId: input.messageId ?? null,\n modelId: input.modelId,\n purpose: input.purpose,\n inputTokens: input.usage.inputTokens,\n outputTokens: input.usage.outputTokens,\n cacheWriteTokens: input.usage.cacheWriteTokens ?? null,\n cacheReadTokens: input.usage.cacheReadTokens ?? null,\n costUsd: input.costUsd ?? null,\n createdAt: new Date(),\n });\n }\n\n async quotaToday(actorRef: string, day: string): Promise<{ usedTokens: number }> {\n const start = new Date(`${day}T00:00:00.000Z`);\n const end = new Date(`${day}T23:59:59.999Z`);\n const rows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(\n and(\n eq(agentTokenUsage.actorRef, actorRef),\n gte(agentTokenUsage.createdAt, start),\n lte(agentTokenUsage.createdAt, end),\n ),\n );\n const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);\n return { usedTokens };\n }\n\n private toSummary(thread: AgentThreadRow, lastContent?: string): ThreadSummary {\n return {\n id: thread.id,\n title: thread.title,\n persona: thread.persona,\n transient: thread.transient,\n createdAt: thread.createdAt.toISOString(),\n updatedAt: thread.updatedAt.toISOString(),\n ...(lastContent !== undefined ? { lastMessagePreview: lastContent.slice(0, 120) } : {}),\n };\n }\n\n private toStoredMessage(message: AgentMessageRow): StoredMessage {\n return {\n id: message.id,\n role: message.role,\n content: message.content,\n createdAt: message.createdAt.toISOString(),\n ...(message.toolCalls != null ? { toolCalls: message.toolCalls } : {}),\n ...(message.toolResults != null ? { toolResults: message.toolResults } : {}),\n ...(message.followUps != null ? { followUps: message.followUps } : {}),\n ...(message.usage != null ? { usage: message.usage } : {}),\n };\n }\n}\n","import type {\n ActorSpendRow,\n AgentGovernanceQueries,\n GovernanceRange,\n ModelSpendRow,\n ThreadActivityRow,\n ToolCallActivityRow,\n UsageTrendPoint,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, count, desc, eq, gte, isNull, lte } from 'drizzle-orm';\nimport {\n type AgentDrizzleDb,\n agentMessage,\n agentModelPricing,\n agentThread,\n agentTokenUsage,\n agentToolCall,\n} from './schema.js';\n\n/** The current per-1M token prices for one model; cache rates fall back to the input rate. */\ninterface ModelPrice {\n inputPricePer1m: number;\n outputPricePer1m: number;\n cacheWritePricePer1m?: number | null;\n cacheReadPricePer1m?: number | null;\n}\n\n/**\n * Token-ledger estimate for one usage row against the current pricing row: the uncached input at the\n * input rate, cache-write/cache-read tokens at their own rates (falling back to the input rate when\n * unpriced), plus output at the output rate. An unpriced model contributes 0 (tokens still count).\n * Cache token counts are subsets of `inputTokens`, so the uncached remainder is the difference.\n */\nfunction estimateFromTokens(\n pricing: Map<string, ModelPrice>,\n row: typeof agentTokenUsage.$inferSelect,\n): number {\n const price = pricing.get(row.modelId);\n if (price === undefined) {\n return 0;\n }\n const cacheWriteTokens = row.cacheWriteTokens ?? 0;\n const cacheReadTokens = row.cacheReadTokens ?? 0;\n const uncachedInputTokens = row.inputTokens - cacheWriteTokens - cacheReadTokens;\n return (\n (uncachedInputTokens / 1_000_000) * price.inputPricePer1m +\n (cacheWriteTokens / 1_000_000) * (price.cacheWritePricePer1m ?? price.inputPricePer1m) +\n (cacheReadTokens / 1_000_000) * (price.cacheReadPricePer1m ?? price.inputPricePer1m) +\n (row.outputTokens / 1_000_000) * price.outputPricePer1m\n );\n}\n\n/**\n * The cost of one usage row: the provider-reported `costUsd` when present (gateways report real\n * spend), otherwise the cache-aware token estimate against the current pricing row.\n */\nfunction rowCost(\n pricing: Map<string, ModelPrice>,\n row: typeof agentTokenUsage.$inferSelect,\n): number {\n return row.costUsd ?? estimateFromTokens(pricing, row);\n}\n\n/** Turns an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used by `quotaToday`. */\nfunction dayBounds(range: GovernanceRange): { start: Date; end: Date } {\n return {\n start: new Date(`${range.fromDay}T00:00:00.000Z`),\n end: new Date(`${range.toDay}T23:59:59.999Z`),\n };\n}\n\n/**\n * {@link AgentGovernanceQueries} backed by Drizzle ORM — the read/analytics half of the store SPI,\n * mirroring {@link import('@dudousxd/nestjs-agent-store-mikro-orm')} exactly. Cost is the token\n * ledger joined to the current pricing row per model (`agentModelPricing.isCurrent`); an unpriced\n * model contributes 0 cost. Aggregation is in-process (like `quotaToday`) so day-bucketing stays\n * dialect-portable.\n */\nexport class DrizzleGovernanceQueries implements AgentGovernanceQueries {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n private async loadPricing(): Promise<Map<string, ModelPrice>> {\n const rows = await this.db\n .select()\n .from(agentModelPricing)\n .where(eq(agentModelPricing.isCurrent, true));\n const pricing = new Map<string, ModelPrice>();\n for (const row of rows) {\n pricing.set(row.modelId, {\n inputPricePer1m: row.inputPricePer1m,\n outputPricePer1m: row.outputPricePer1m,\n cacheWritePricePer1m: row.cacheWritePricePer1m,\n cacheReadPricePer1m: row.cacheReadPricePer1m,\n });\n }\n return pricing;\n }\n\n private async usageInRange(\n range: GovernanceRange,\n ): Promise<(typeof agentTokenUsage.$inferSelect)[]> {\n const { start, end } = dayBounds(range);\n const rows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(and(gte(agentTokenUsage.createdAt, start), lte(agentTokenUsage.createdAt, end)));\n return rows;\n }\n\n async spendByModel(range: GovernanceRange): Promise<ModelSpendRow[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byModel = new Map<\n string,\n { requests: number; inputTokens: number; outputTokens: number; costUsd: number }\n >();\n for (const row of rows) {\n const bucket = byModel.get(row.modelId) ?? {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n costUsd: 0,\n };\n bucket.requests += 1;\n bucket.inputTokens += row.inputTokens;\n bucket.outputTokens += row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byModel.set(row.modelId, bucket);\n }\n const result: ModelSpendRow[] = [];\n for (const [modelId, bucket] of byModel) {\n result.push({\n modelId,\n requests: bucket.requests,\n inputTokens: bucket.inputTokens,\n outputTokens: bucket.outputTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId),\n );\n return result;\n }\n\n async spendByActor(range: GovernanceRange): Promise<ActorSpendRow[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byActor = new Map<string, { requests: number; totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byActor.get(row.actorRef) ?? { requests: 0, totalTokens: 0, costUsd: 0 };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byActor.set(row.actorRef, bucket);\n }\n const result: ActorSpendRow[] = [];\n for (const [actorRef, bucket] of byActor) {\n result.push({\n actorRef,\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef),\n );\n return result;\n }\n\n async usageTrend(range: GovernanceRange): Promise<UsageTrendPoint[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byDay = new Map<string, { totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const day = row.createdAt.toISOString().slice(0, 10);\n const bucket = byDay.get(day) ?? { totalTokens: 0, costUsd: 0 };\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byDay.set(day, bucket);\n }\n const result: UsageTrendPoint[] = [];\n for (const [day, bucket] of byDay) {\n result.push({ day, totalTokens: bucket.totalTokens, costUsd: bucket.costUsd });\n }\n result.sort((left, right) => left.day.localeCompare(right.day));\n return result;\n }\n\n async recentToolCalls(limit: number): Promise<ToolCallActivityRow[]> {\n const rows = await this.db\n .select({\n toolCallId: agentToolCall.id,\n toolName: agentToolCall.toolName,\n toolType: agentToolCall.toolType,\n status: agentToolCall.status,\n threadId: agentMessage.threadId,\n createdAt: agentToolCall.createdAt,\n })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .orderBy(desc(agentToolCall.createdAt), desc(agentToolCall.id))\n .limit(limit);\n return rows.map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n toolType: row.toolType,\n status: row.status,\n threadId: row.threadId,\n createdAt: row.createdAt.toISOString(),\n }));\n }\n\n async recentThreads(limit: number): Promise<ThreadActivityRow[]> {\n const threads = await this.db\n .select()\n .from(agentThread)\n .where(isNull(agentThread.deletedAt))\n .orderBy(desc(agentThread.updatedAt), desc(agentThread.id))\n .limit(limit);\n const result: ThreadActivityRow[] = [];\n for (const thread of threads) {\n const [messageCountRow] = await this.db\n .select({ value: count() })\n .from(agentMessage)\n .where(eq(agentMessage.threadId, thread.id));\n const usageRows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(eq(agentTokenUsage.threadId, thread.id));\n const totalTokens = usageRows.reduce(\n (sum, row) => sum + row.inputTokens + row.outputTokens,\n 0,\n );\n result.push({\n threadId: thread.id,\n title: thread.title,\n actorRef: thread.actorRef,\n messageCount: messageCountRow?.value ?? 0,\n totalTokens,\n lastActivityAt: thread.updatedAt.toISOString(),\n });\n }\n return result;\n }\n}\n","import type {\n AgentPricingStore,\n CurrentModelPrice,\n ModelPriceInput,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, eq } from 'drizzle-orm';\nimport { type AgentDrizzleDb, agentModelPricing } from './schema.js';\n\n/**\n * {@link AgentPricingStore} backed by Drizzle ORM — the write side of the pricing table\n * {@link import('./drizzle-governance-queries.js').DrizzleGovernanceQueries} joins against. A POJO\n * receiving a Drizzle SQLite database handle (the host app owns the connection), mirroring\n * {@link import('@dudousxd/nestjs-agent-store-mikro-orm')} exactly (atomic supersede semantics).\n */\nexport class DrizzlePricingStore implements AgentPricingStore {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n async upsertModelPrice(input: ModelPriceInput): Promise<void> {\n await this.db\n .update(agentModelPricing)\n .set({ isCurrent: false })\n .where(\n and(eq(agentModelPricing.modelId, input.modelId), eq(agentModelPricing.isCurrent, true)),\n );\n await this.db.insert(agentModelPricing).values({\n id: crypto.randomUUID(),\n modelId: input.modelId,\n inputPricePer1m: input.inputPricePer1m,\n outputPricePer1m: input.outputPricePer1m,\n cacheWritePricePer1m: input.cacheWritePricePer1m ?? null,\n cacheReadPricePer1m: input.cacheReadPricePer1m ?? null,\n effectiveFrom: new Date(),\n isCurrent: true,\n });\n }\n\n async listCurrentPrices(): Promise<CurrentModelPrice[]> {\n const rows = await this.db\n .select()\n .from(agentModelPricing)\n .where(eq(agentModelPricing.isCurrent, true));\n return rows.map((row) => ({\n modelId: row.modelId,\n inputPricePer1m: row.inputPricePer1m,\n outputPricePer1m: row.outputPricePer1m,\n effectiveFrom: row.effectiveFrom.toISOString(),\n ...(row.cacheWritePricePer1m != null\n ? { cacheWritePricePer1m: row.cacheWritePricePer1m }\n : {}),\n ...(row.cacheReadPricePer1m != null ? { cacheReadPricePer1m: row.cacheReadPricePer1m } : {}),\n }));\n }\n}\n","import {\n AGENT_GOVERNANCE_QUERIES,\n AGENT_PRICING_STORE,\n AGENT_STORE,\n} from '@dudousxd/nestjs-agent-core';\nimport { type DynamicModule, Module } from '@nestjs/common';\nimport { DrizzleAgentStore } from './drizzle-agent-store.js';\nimport { DrizzleGovernanceQueries } from './drizzle-governance-queries.js';\nimport { DrizzlePricingStore } from './drizzle-pricing-store.js';\nimport type { AgentDrizzleDb } from './schema.js';\n\n/** Options for {@link DrizzleAgentStoreModule.forRoot}. The app owns and supplies the db handle. */\nexport interface DrizzleAgentStoreModuleOptions {\n /** A Drizzle SQLite database instance (`drizzle(client, { schema: agentSchema })`). */\n db: AgentDrizzleDb;\n}\n\n/**\n * Binds {@link DrizzleAgentStore} to the {@link AGENT_STORE} token consumed by\n * `@dudousxd/nestjs-agent`, plus {@link DrizzleGovernanceQueries} to\n * {@link AGENT_GOVERNANCE_QUERIES} (the read-model the dashboard/telescope surfaces consume) and\n * {@link DrizzlePricingStore} to {@link AGENT_PRICING_STORE} (the write side of that pricing table).\n * The host app supplies an already-opened Drizzle db — this module never opens a connection itself.\n *\n * The returned module is global, so {@link AGENT_STORE}, {@link AGENT_GOVERNANCE_QUERIES} and\n * {@link AGENT_PRICING_STORE} are visible app-wide — `AgentModule` resolves the store without an\n * explicit `store` option, and the dashboard/telescope resolve {@link AGENT_GOVERNANCE_QUERIES}\n * without the host re-binding it.\n *\n * ```ts\n * @Module({ imports: [DrizzleAgentStoreModule.forRoot({ db })] })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class DrizzleAgentStoreModule {\n static forRoot(options: DrizzleAgentStoreModuleOptions): DynamicModule {\n return {\n module: DrizzleAgentStoreModule,\n global: true,\n providers: [\n { provide: DrizzleAgentStore, useFactory: () => new DrizzleAgentStore(options.db) },\n { provide: AGENT_STORE, useExisting: DrizzleAgentStore },\n {\n provide: DrizzleGovernanceQueries,\n useFactory: () => new DrizzleGovernanceQueries(options.db),\n },\n { provide: AGENT_GOVERNANCE_QUERIES, useExisting: DrizzleGovernanceQueries },\n {\n provide: DrizzlePricingStore,\n useFactory: () => new DrizzlePricingStore(options.db),\n },\n { provide: AGENT_PRICING_STORE, useExisting: DrizzlePricingStore },\n ],\n exports: [\n DrizzleAgentStore,\n AGENT_STORE,\n DrizzleGovernanceQueries,\n AGENT_GOVERNANCE_QUERIES,\n DrizzlePricingStore,\n AGENT_PRICING_STORE,\n ],\n };\n }\n}\n"],"mappings":"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","names":["agentThread","sqliteTable","id","text","primaryKey","actorRef","notNull","tenantRef","title","persona","default","transient","integer","mode","activeStreamId","createdAt","updatedAt","deletedAt","table","index","on","agentMessage","threadId","references","onDelete","role","$type","content","toolCalls","toolResults","followUps","usage","agentToolCall","messageId","toolName","toolType","input","output","status","executedByRef","executionMs","error","executedAt","agentTokenUsage","modelId","purpose","inputTokens","outputTokens","cacheWriteTokens","cacheReadTokens","costUsd","real","agentModelPricing","inputPricePer1m","outputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","effectiveFrom","isCurrent","agentSchema","statements","ensureAgentSchema","db","statement","run","sql","raw","import_drizzle_orm","DrizzleAgentStore","db","createThread","input","now","Date","thread","id","crypto","randomUUID","actorRef","actor","tenantRef","title","persona","transient","activeStreamId","createdAt","updatedAt","deletedAt","insert","agentThread","values","toSummary","getThread","threadId","select","from","where","and","eq","isNull","undefined","messages","agentMessage","orderBy","asc","last","length","content","map","message","toStoredMessage","listThreads","limit","threads","desc","summaries","push","softDeleteThread","update","set","forkThread","fromMessageId","source","Error","cutoff","findIndex","kept","slice","fork","role","toolCalls","toolResults","followUps","usage","ownerOfThread","ownerOfToolCall","toolCallId","row","agentToolCall","innerJoin","messageId","runForToolCall","ownerOfActiveStream","runId","setTitle","setActiveStream","appendMessage","truncateFrom","doomedIds","delete","inArray","recordToolCall","toolName","toolType","output","status","executedByRef","executionMs","error","executedAt","updateToolCall","updates","recordUsage","agentTokenUsage","modelId","purpose","inputTokens","outputTokens","cacheWriteTokens","cacheReadTokens","costUsd","quotaToday","day","start","end","rows","gte","lte","usedTokens","reduce","sum","lastContent","toISOString","lastMessagePreview","import_drizzle_orm","estimateFromTokens","pricing","row","price","get","modelId","undefined","cacheWriteTokens","cacheReadTokens","uncachedInputTokens","inputTokens","inputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","outputTokens","outputPricePer1m","rowCost","costUsd","dayBounds","range","start","Date","fromDay","end","toDay","DrizzleGovernanceQueries","db","loadPricing","rows","select","from","agentModelPricing","where","eq","isCurrent","Map","set","usageInRange","agentTokenUsage","and","gte","createdAt","lte","spendByModel","byModel","bucket","requests","result","push","sort","left","right","localeCompare","spendByActor","byActor","actorRef","totalTokens","usageTrend","byDay","day","toISOString","slice","recentToolCalls","limit","toolCallId","agentToolCall","id","toolName","toolType","status","threadId","agentMessage","innerJoin","messageId","orderBy","desc","map","recentThreads","threads","agentThread","isNull","deletedAt","updatedAt","thread","messageCountRow","value","count","usageRows","reduce","sum","title","messageCount","lastActivityAt","import_drizzle_orm","DrizzlePricingStore","db","upsertModelPrice","input","update","agentModelPricing","set","isCurrent","where","and","eq","modelId","insert","values","id","crypto","randomUUID","inputPricePer1m","outputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","effectiveFrom","Date","listCurrentPrices","rows","select","from","map","row","toISOString","DrizzleAgentStoreModule","forRoot","options","module","global","providers","provide","DrizzleAgentStore","useFactory","db","AGENT_STORE","useExisting","DrizzleGovernanceQueries","AGENT_GOVERNANCE_QUERIES","DrizzlePricingStore","AGENT_PRICING_STORE","exports"]}
1
+ {"version":3,"sources":["../src/index.ts","../src/schema.ts","../src/ensure-schema.ts","../src/drizzle-agent-store.ts","../src/drizzle-governance-queries.ts","../src/drizzle-pricing-store.ts","../src/drizzle-agent-store.module.ts"],"sourcesContent":["export * from './schema.js';\nexport * from './ensure-schema.js';\nexport * from './drizzle-agent-store.js';\nexport * from './drizzle-governance-queries.js';\nexport * from './drizzle-pricing-store.js';\nexport * from './drizzle-agent-store.module.js';\n","import type {\n MessageRole,\n MessageUsage,\n ToolCallRequest,\n ToolCallStatus,\n ToolKind,\n ToolResult,\n UsagePurpose,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n type BaseSQLiteDatabase,\n index,\n integer,\n real,\n sqliteTable,\n text,\n} from 'drizzle-orm/sqlite-core';\n\n/**\n * Drizzle schema mirroring the MikroORM agent entities (same logical columns/relations):\n * threads, messages, tool calls, token usage and model pricing. Targets the SQLite core so the\n * db-test runs on an in-memory better-sqlite3; timestamps are stored as integer epoch-ms columns\n * (`{ mode: 'timestamp_ms' }`) which Drizzle round-trips to/from JS `Date`, and the model-facing\n * message extras (tool calls/results, follow-ups, usage) live in JSON `text` columns.\n */\n\n/**\n * A conversation thread. `deletedAt` drives soft delete: a deleted thread is hidden from\n * {@link import('./drizzle-agent-store.js').DrizzleAgentStore.getThread}/`listThreads` but its\n * row survives.\n */\nexport const agentThread = sqliteTable(\n 'agent_thread',\n {\n id: text('id').primaryKey(),\n actorRef: text('actor_ref').notNull(),\n tenantRef: text('tenant_ref'),\n title: text('title').notNull(),\n transient: integer('transient', { mode: 'boolean' }).notNull().default(false),\n activeStreamId: text('active_stream_id'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n updatedAt: integer('updated_at', { mode: 'timestamp_ms' }).notNull(),\n deletedAt: integer('deleted_at', { mode: 'timestamp_ms' }),\n },\n (table) => [index('agent_thread_actor_updated_idx').on(table.actorRef, table.updatedAt)],\n);\n\n/**\n * One stored message in a thread. The model-facing extras (`toolCalls`/`toolResults`/\n * `followUps`/`usage`) are folded into nullable JSON columns so a single row round-trips to a\n * {@link import('@dudousxd/nestjs-agent-core').StoredMessage}. `threadId` cascades on delete.\n */\nexport const agentMessage = sqliteTable(\n 'agent_message',\n {\n id: text('id').primaryKey(),\n threadId: text('thread_id')\n .notNull()\n .references(() => agentThread.id, { onDelete: 'cascade' }),\n role: text('role').$type<MessageRole>().notNull(),\n content: text('content').notNull(),\n toolCalls: text('tool_calls', { mode: 'json' }).$type<ToolCallRequest[]>(),\n toolResults: text('tool_results', { mode: 'json' }).$type<ToolResult[]>(),\n followUps: text('follow_ups', { mode: 'json' }).$type<string[]>(),\n usage: text('usage', { mode: 'json' }).$type<MessageUsage>(),\n agentName: text('agent_name'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n },\n (table) => [index('agent_message_thread_created_idx').on(table.threadId, table.createdAt)],\n);\n\n/** A tool call requested during an assistant turn. The pk is the model-supplied `toolCallId`. */\nexport const agentToolCall = sqliteTable('agent_tool_call', {\n id: text('id').primaryKey(),\n messageId: text('message_id')\n .notNull()\n .references(() => agentMessage.id, { onDelete: 'cascade' }),\n toolName: text('tool_name').notNull(),\n toolType: text('tool_type').$type<ToolKind>().notNull(),\n input: text('input', { mode: 'json' }),\n output: text('output', { mode: 'json' }),\n status: text('status').$type<ToolCallStatus>().notNull(),\n executedByRef: text('executed_by_ref'),\n executionMs: integer('execution_ms'),\n error: text('error'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n executedAt: integer('executed_at', { mode: 'timestamp_ms' }),\n});\n\n/** A token-usage ledger row, summed per actor per day by `quotaToday`. */\nexport const agentTokenUsage = sqliteTable(\n 'agent_token_usage',\n {\n id: text('id').primaryKey(),\n threadId: text('thread_id')\n .notNull()\n .references(() => agentThread.id, { onDelete: 'cascade' }),\n actorRef: text('actor_ref').notNull(),\n messageId: text('message_id'),\n modelId: text('model_id').notNull(),\n purpose: text('purpose').$type<UsagePurpose>().notNull(),\n inputTokens: integer('input_tokens').notNull(),\n outputTokens: integer('output_tokens').notNull(),\n /** Subset of `inputTokens` written to the prompt cache this turn; null when not reported. */\n cacheWriteTokens: integer('cache_write_tokens'),\n /** Subset of `inputTokens` served from the prompt cache this turn; null when not reported. */\n cacheReadTokens: integer('cache_read_tokens'),\n /** Provider-reported actual USD cost for the turn; null when only tokens were reported. */\n costUsd: real('cost_usd'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n },\n (table) => [index('agent_token_usage_actor_created_idx').on(table.actorRef, table.createdAt)],\n);\n\n/** Per-model token pricing, versioned by `effectiveFrom`; `isCurrent` flags the live row. */\nexport const agentModelPricing = sqliteTable('agent_model_pricing', {\n id: text('id').primaryKey(),\n modelId: text('model_id').notNull(),\n inputPricePer1m: real('input_price_per_1m').notNull(),\n outputPricePer1m: real('output_price_per_1m').notNull(),\n /** Per-1M price for cache-write input tokens; null → price them at the input rate. */\n cacheWritePricePer1m: real('cache_write_price_per_1m'),\n /** Per-1M price for cache-read input tokens; null → price them at the input rate. */\n cacheReadPricePer1m: real('cache_read_price_per_1m'),\n effectiveFrom: integer('effective_from', { mode: 'timestamp_ms' }).notNull(),\n isCurrent: integer('is_current', { mode: 'boolean' }).notNull(),\n});\n\n/** The five agent tables as one schema object, ready for `drizzle(client, { schema })`. */\nexport const agentSchema = {\n agentThread,\n agentMessage,\n agentToolCall,\n agentTokenUsage,\n agentModelPricing,\n};\n\n/**\n * The dialect-portable Drizzle SQLite database handle the store operates on. Accepts any SQLite\n * driver (better-sqlite3, libsql, D1, …) in either sync or async result mode; the host app owns\n * the connection and passes the `drizzle(...)` instance in.\n */\nexport type AgentDrizzleDb = BaseSQLiteDatabase<'sync' | 'async', unknown>;\n\n/** A persisted thread row as Drizzle selects it. */\nexport type AgentThreadRow = typeof agentThread.$inferSelect;\n/** A persisted message row as Drizzle selects it. */\nexport type AgentMessageRow = typeof agentMessage.$inferSelect;\n","import { sql } from 'drizzle-orm';\nimport type { AgentDrizzleDb } from './schema.js';\n\n/**\n * Idempotent `CREATE TABLE IF NOT EXISTS` DDL for the five agent tables, mirroring\n * {@link import('./schema.js').agentSchema}. SQLite dialect (the db-test driver); kept here rather\n * than relying on drizzle-kit so the package can stand up its schema with no migration files. Safe\n * to run on boot against a shared database — it never drops or alters existing columns.\n */\nconst statements: string[] = [\n `CREATE TABLE IF NOT EXISTS agent_thread (\n id TEXT PRIMARY KEY NOT NULL,\n actor_ref TEXT NOT NULL,\n tenant_ref TEXT,\n title TEXT NOT NULL,\n transient INTEGER NOT NULL DEFAULT 0,\n active_stream_id TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n deleted_at INTEGER\n )`,\n `CREATE INDEX IF NOT EXISTS agent_thread_actor_updated_idx\n ON agent_thread (actor_ref, updated_at)`,\n `CREATE TABLE IF NOT EXISTS agent_message (\n id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL REFERENCES agent_thread(id) ON DELETE CASCADE,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n tool_calls TEXT,\n tool_results TEXT,\n follow_ups TEXT,\n usage TEXT,\n agent_name TEXT,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS agent_message_thread_created_idx\n ON agent_message (thread_id, created_at)`,\n `CREATE TABLE IF NOT EXISTS agent_tool_call (\n id TEXT PRIMARY KEY NOT NULL,\n message_id TEXT NOT NULL REFERENCES agent_message(id) ON DELETE CASCADE,\n tool_name TEXT NOT NULL,\n tool_type TEXT NOT NULL,\n input TEXT,\n output TEXT,\n status TEXT NOT NULL,\n executed_by_ref TEXT,\n execution_ms INTEGER,\n error TEXT,\n created_at INTEGER NOT NULL,\n executed_at INTEGER\n )`,\n `CREATE TABLE IF NOT EXISTS agent_token_usage (\n id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL REFERENCES agent_thread(id) ON DELETE CASCADE,\n actor_ref TEXT NOT NULL,\n message_id TEXT,\n model_id TEXT NOT NULL,\n purpose TEXT NOT NULL,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n cache_write_tokens INTEGER,\n cache_read_tokens INTEGER,\n cost_usd REAL,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS agent_token_usage_actor_created_idx\n ON agent_token_usage (actor_ref, created_at)`,\n `CREATE TABLE IF NOT EXISTS agent_model_pricing (\n id TEXT PRIMARY KEY NOT NULL,\n model_id TEXT NOT NULL,\n input_price_per_1m REAL NOT NULL,\n output_price_per_1m REAL NOT NULL,\n cache_write_price_per_1m REAL,\n cache_read_price_per_1m REAL,\n effective_from INTEGER NOT NULL,\n is_current INTEGER NOT NULL\n )`,\n];\n\n/** Runs the `CREATE TABLE IF NOT EXISTS` DDL above against the supplied Drizzle SQLite db. */\nexport async function ensureAgentSchema(db: AgentDrizzleDb): Promise<void> {\n for (const statement of statements) {\n await db.run(sql.raw(statement));\n }\n}\n","import type {\n AgentStore,\n AppendMessageInput,\n CreateThreadInput,\n RecordToolCallInput,\n RecordUsageInput,\n StoredMessage,\n ThreadDetail,\n ThreadSummary,\n UpdateToolCallInput,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, asc, desc, eq, gte, inArray, isNull, lte } from 'drizzle-orm';\nimport {\n type AgentDrizzleDb,\n type AgentMessageRow,\n type AgentThreadRow,\n agentMessage,\n agentThread,\n agentTokenUsage,\n agentToolCall,\n} from './schema.js';\n\n/**\n * {@link AgentStore} backed by Drizzle ORM — a second adapter alongside the MikroORM one, proving\n * the store SPI is ORM-portable. A POJO receiving a Drizzle SQLite database handle (the host app\n * owns the connection). Behaviour mirrors {@link import('@dudousxd/nestjs-agent-store-mikro-orm')}\n * exactly (fork/truncate/quota/active-stream/soft-delete semantics) so the two are interchangeable.\n */\nexport class DrizzleAgentStore implements AgentStore {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n async createThread(input: CreateThreadInput): Promise<ThreadSummary> {\n const now = new Date();\n const thread: AgentThreadRow = {\n id: crypto.randomUUID(),\n actorRef: input.actor.id,\n tenantRef: input.actor.tenantRef ?? null,\n title: input.title ?? 'New chat',\n transient: input.transient ?? false,\n activeStreamId: null,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n };\n await this.db.insert(agentThread).values(thread);\n return this.toSummary(thread);\n }\n\n async getThread(threadId: string): Promise<ThreadDetail | null> {\n const [thread] = await this.db\n .select()\n .from(agentThread)\n .where(and(eq(agentThread.id, threadId), isNull(agentThread.deletedAt)));\n if (thread === undefined) {\n return null;\n }\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const last = messages[messages.length - 1];\n return {\n ...this.toSummary(thread, last?.content),\n messages: messages.map((message) => this.toStoredMessage(message)),\n ...(thread.activeStreamId != null ? { activeStreamId: thread.activeStreamId } : {}),\n };\n }\n\n async listThreads(actorRef: string, limit = 50): Promise<ThreadSummary[]> {\n const threads = await this.db\n .select()\n .from(agentThread)\n .where(\n and(\n eq(agentThread.actorRef, actorRef),\n eq(agentThread.transient, false),\n isNull(agentThread.deletedAt),\n ),\n )\n .orderBy(desc(agentThread.updatedAt))\n .limit(limit);\n const summaries: ThreadSummary[] = [];\n for (const thread of threads) {\n const [last] = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, thread.id))\n .orderBy(desc(agentMessage.createdAt), desc(agentMessage.id))\n .limit(1);\n summaries.push(this.toSummary(thread, last?.content));\n }\n return summaries;\n }\n\n async softDeleteThread(threadId: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ deletedAt: new Date() })\n .where(eq(agentThread.id, threadId));\n }\n\n async forkThread(threadId: string, fromMessageId: string): Promise<ThreadSummary> {\n const [source] = await this.db.select().from(agentThread).where(eq(agentThread.id, threadId));\n if (source === undefined) {\n throw new Error(`thread ${threadId} not found`);\n }\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const cutoff = messages.findIndex((message) => message.id === fromMessageId);\n const kept = cutoff >= 0 ? messages.slice(0, cutoff + 1) : messages;\n const now = new Date();\n const fork: AgentThreadRow = {\n id: crypto.randomUUID(),\n actorRef: source.actorRef,\n tenantRef: source.tenantRef,\n title: source.title,\n transient: false,\n activeStreamId: null,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n };\n await this.db.insert(agentThread).values(fork);\n if (kept.length > 0) {\n await this.db.insert(agentMessage).values(\n kept.map((message) => ({\n id: crypto.randomUUID(),\n threadId: fork.id,\n role: message.role,\n content: message.content,\n toolCalls: message.toolCalls,\n toolResults: message.toolResults,\n followUps: message.followUps,\n usage: message.usage,\n agentName: message.agentName,\n createdAt: message.createdAt,\n })),\n );\n }\n return this.toSummary(fork);\n }\n\n async ownerOfThread(threadId: string): Promise<string | null> {\n const [thread] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentThread)\n .where(and(eq(agentThread.id, threadId), isNull(agentThread.deletedAt)));\n return thread?.actorRef ?? null;\n }\n\n async ownerOfToolCall(toolCallId: string): Promise<string | null> {\n const [row] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .innerJoin(agentThread, eq(agentMessage.threadId, agentThread.id))\n .where(eq(agentToolCall.id, toolCallId));\n return row?.actorRef ?? null;\n }\n\n async runForToolCall(toolCallId: string): Promise<string | null> {\n const [row] = await this.db\n .select({ activeStreamId: agentThread.activeStreamId })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .innerJoin(agentThread, eq(agentMessage.threadId, agentThread.id))\n .where(eq(agentToolCall.id, toolCallId));\n return row?.activeStreamId ?? null;\n }\n\n async ownerOfActiveStream(runId: string): Promise<string | null> {\n const [thread] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentThread)\n .where(and(eq(agentThread.activeStreamId, runId), isNull(agentThread.deletedAt)));\n return thread?.actorRef ?? null;\n }\n\n async setTitle(threadId: string, title: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ title, updatedAt: new Date() })\n .where(eq(agentThread.id, threadId));\n }\n\n async promoteThread(threadId: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ transient: false, updatedAt: new Date() })\n .where(and(eq(agentThread.id, threadId), eq(agentThread.transient, true)));\n }\n\n async setActiveStream(threadId: string, runId: string | null): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ activeStreamId: runId })\n .where(eq(agentThread.id, threadId));\n }\n\n async appendMessage(input: AppendMessageInput): Promise<StoredMessage> {\n const [thread] = await this.db\n .select()\n .from(agentThread)\n .where(eq(agentThread.id, input.threadId));\n if (thread === undefined) {\n throw new Error(`thread ${input.threadId} not found`);\n }\n const now = new Date();\n const message: AgentMessageRow = {\n id: crypto.randomUUID(),\n threadId: input.threadId,\n role: input.role,\n content: input.content,\n toolCalls: input.toolCalls ?? null,\n toolResults: input.toolResults ?? null,\n followUps: input.followUps ?? null,\n usage: input.usage ?? null,\n agentName: input.agentName ?? null,\n createdAt: now,\n };\n await this.db.insert(agentMessage).values(message);\n await this.db\n .update(agentThread)\n .set({ updatedAt: now })\n .where(eq(agentThread.id, input.threadId));\n return this.toStoredMessage(message);\n }\n\n async truncateFrom(threadId: string, messageId: string): Promise<void> {\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const cutoff = messages.findIndex((message) => message.id === messageId);\n if (cutoff < 0) {\n return;\n }\n const doomedIds = messages.slice(cutoff).map((message) => message.id);\n await this.db.delete(agentToolCall).where(inArray(agentToolCall.messageId, doomedIds));\n await this.db.delete(agentMessage).where(inArray(agentMessage.id, doomedIds));\n }\n\n async recordToolCall(input: RecordToolCallInput): Promise<void> {\n await this.db.insert(agentToolCall).values({\n id: input.toolCallId,\n messageId: input.messageId,\n toolName: input.toolName,\n toolType: input.toolType,\n input: input.input,\n output: null,\n status: input.status,\n executedByRef: null,\n executionMs: null,\n error: null,\n createdAt: new Date(),\n executedAt: null,\n });\n }\n\n async updateToolCall(input: UpdateToolCallInput): Promise<void> {\n const updates: Partial<typeof agentToolCall.$inferInsert> = { status: input.status };\n if (input.output !== undefined) {\n updates.output = input.output;\n }\n if (input.error !== undefined) {\n updates.error = input.error;\n }\n if (input.executionMs !== undefined) {\n updates.executionMs = input.executionMs;\n }\n if (input.executedByRef !== undefined) {\n updates.executedByRef = input.executedByRef;\n }\n if (input.status === 'executed' || input.status === 'auto_executed') {\n updates.executedAt = new Date();\n }\n await this.db.update(agentToolCall).set(updates).where(eq(agentToolCall.id, input.toolCallId));\n }\n\n async recordUsage(input: RecordUsageInput): Promise<void> {\n await this.db.insert(agentTokenUsage).values({\n id: crypto.randomUUID(),\n threadId: input.threadId,\n actorRef: input.actorRef,\n messageId: input.messageId ?? null,\n modelId: input.modelId,\n purpose: input.purpose,\n inputTokens: input.usage.inputTokens,\n outputTokens: input.usage.outputTokens,\n cacheWriteTokens: input.usage.cacheWriteTokens ?? null,\n cacheReadTokens: input.usage.cacheReadTokens ?? null,\n costUsd: input.costUsd ?? null,\n createdAt: new Date(),\n });\n }\n\n async quotaToday(\n actorRef: string,\n day: string,\n ): Promise<{ usedTokens: number; costUsd: number }> {\n const start = new Date(`${day}T00:00:00.000Z`);\n const end = new Date(`${day}T23:59:59.999Z`);\n const rows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(\n and(\n eq(agentTokenUsage.actorRef, actorRef),\n gte(agentTokenUsage.createdAt, start),\n lte(agentTokenUsage.createdAt, end),\n ),\n );\n const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);\n const costUsd = rows.reduce((sum, row) => sum + (row.costUsd ?? 0), 0);\n return { usedTokens, costUsd };\n }\n\n private toSummary(thread: AgentThreadRow, lastContent?: string): ThreadSummary {\n return {\n id: thread.id,\n title: thread.title,\n transient: thread.transient,\n createdAt: thread.createdAt.toISOString(),\n updatedAt: thread.updatedAt.toISOString(),\n ...(lastContent !== undefined ? { lastMessagePreview: lastContent.slice(0, 120) } : {}),\n };\n }\n\n private toStoredMessage(message: AgentMessageRow): StoredMessage {\n return {\n id: message.id,\n role: message.role,\n content: message.content,\n createdAt: message.createdAt.toISOString(),\n ...(message.toolCalls != null ? { toolCalls: message.toolCalls } : {}),\n ...(message.toolResults != null ? { toolResults: message.toolResults } : {}),\n ...(message.followUps != null ? { followUps: message.followUps } : {}),\n ...(message.usage != null ? { usage: message.usage } : {}),\n ...(message.agentName != null ? { agentName: message.agentName } : {}),\n };\n }\n}\n","import type {\n ActorSpendRow,\n AgentGovernanceQueries,\n GovernanceRange,\n ModelSpendRow,\n ThreadActivityRow,\n ToolCallActivityRow,\n UsageTrendPoint,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, count, desc, eq, gte, isNull, lte } from 'drizzle-orm';\nimport {\n type AgentDrizzleDb,\n agentMessage,\n agentModelPricing,\n agentThread,\n agentTokenUsage,\n agentToolCall,\n} from './schema.js';\n\n/** The current per-1M token prices for one model; cache rates fall back to the input rate. */\ninterface ModelPrice {\n inputPricePer1m: number;\n outputPricePer1m: number;\n cacheWritePricePer1m?: number | null;\n cacheReadPricePer1m?: number | null;\n}\n\n/**\n * Token-ledger estimate for one usage row against the current pricing row: the uncached input at the\n * input rate, cache-write/cache-read tokens at their own rates (falling back to the input rate when\n * unpriced), plus output at the output rate. An unpriced model contributes 0 (tokens still count).\n * Cache token counts are subsets of `inputTokens`, so the uncached remainder is the difference.\n */\nfunction estimateFromTokens(\n pricing: Map<string, ModelPrice>,\n row: typeof agentTokenUsage.$inferSelect,\n): number {\n const price = pricing.get(row.modelId);\n if (price === undefined) {\n return 0;\n }\n const cacheWriteTokens = row.cacheWriteTokens ?? 0;\n const cacheReadTokens = row.cacheReadTokens ?? 0;\n const uncachedInputTokens = row.inputTokens - cacheWriteTokens - cacheReadTokens;\n return (\n (uncachedInputTokens / 1_000_000) * price.inputPricePer1m +\n (cacheWriteTokens / 1_000_000) * (price.cacheWritePricePer1m ?? price.inputPricePer1m) +\n (cacheReadTokens / 1_000_000) * (price.cacheReadPricePer1m ?? price.inputPricePer1m) +\n (row.outputTokens / 1_000_000) * price.outputPricePer1m\n );\n}\n\n/**\n * The cost of one usage row: the provider-reported `costUsd` when present (gateways report real\n * spend), otherwise the cache-aware token estimate against the current pricing row.\n */\nfunction rowCost(\n pricing: Map<string, ModelPrice>,\n row: typeof agentTokenUsage.$inferSelect,\n): number {\n return row.costUsd ?? estimateFromTokens(pricing, row);\n}\n\n/** Turns an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used by `quotaToday`. */\nfunction dayBounds(range: GovernanceRange): { start: Date; end: Date } {\n return {\n start: new Date(`${range.fromDay}T00:00:00.000Z`),\n end: new Date(`${range.toDay}T23:59:59.999Z`),\n };\n}\n\n/**\n * {@link AgentGovernanceQueries} backed by Drizzle ORM — the read/analytics half of the store SPI,\n * mirroring {@link import('@dudousxd/nestjs-agent-store-mikro-orm')} exactly. Cost is the token\n * ledger joined to the current pricing row per model (`agentModelPricing.isCurrent`); an unpriced\n * model contributes 0 cost. Aggregation is in-process (like `quotaToday`) so day-bucketing stays\n * dialect-portable.\n */\nexport class DrizzleGovernanceQueries implements AgentGovernanceQueries {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n private async loadPricing(): Promise<Map<string, ModelPrice>> {\n const rows = await this.db\n .select()\n .from(agentModelPricing)\n .where(eq(agentModelPricing.isCurrent, true));\n const pricing = new Map<string, ModelPrice>();\n for (const row of rows) {\n pricing.set(row.modelId, {\n inputPricePer1m: row.inputPricePer1m,\n outputPricePer1m: row.outputPricePer1m,\n cacheWritePricePer1m: row.cacheWritePricePer1m,\n cacheReadPricePer1m: row.cacheReadPricePer1m,\n });\n }\n return pricing;\n }\n\n private async usageInRange(\n range: GovernanceRange,\n ): Promise<(typeof agentTokenUsage.$inferSelect)[]> {\n const { start, end } = dayBounds(range);\n const rows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(and(gte(agentTokenUsage.createdAt, start), lte(agentTokenUsage.createdAt, end)));\n return rows;\n }\n\n async spendByModel(range: GovernanceRange): Promise<ModelSpendRow[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byModel = new Map<\n string,\n { requests: number; inputTokens: number; outputTokens: number; costUsd: number }\n >();\n for (const row of rows) {\n const bucket = byModel.get(row.modelId) ?? {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n costUsd: 0,\n };\n bucket.requests += 1;\n bucket.inputTokens += row.inputTokens;\n bucket.outputTokens += row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byModel.set(row.modelId, bucket);\n }\n const result: ModelSpendRow[] = [];\n for (const [modelId, bucket] of byModel) {\n result.push({\n modelId,\n requests: bucket.requests,\n inputTokens: bucket.inputTokens,\n outputTokens: bucket.outputTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId),\n );\n return result;\n }\n\n async spendByActor(range: GovernanceRange): Promise<ActorSpendRow[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byActor = new Map<string, { requests: number; totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byActor.get(row.actorRef) ?? { requests: 0, totalTokens: 0, costUsd: 0 };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byActor.set(row.actorRef, bucket);\n }\n const result: ActorSpendRow[] = [];\n for (const [actorRef, bucket] of byActor) {\n result.push({\n actorRef,\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef),\n );\n return result;\n }\n\n async usageTrend(range: GovernanceRange): Promise<UsageTrendPoint[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byDay = new Map<string, { totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const day = row.createdAt.toISOString().slice(0, 10);\n const bucket = byDay.get(day) ?? { totalTokens: 0, costUsd: 0 };\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byDay.set(day, bucket);\n }\n const result: UsageTrendPoint[] = [];\n for (const [day, bucket] of byDay) {\n result.push({ day, totalTokens: bucket.totalTokens, costUsd: bucket.costUsd });\n }\n result.sort((left, right) => left.day.localeCompare(right.day));\n return result;\n }\n\n async recentToolCalls(limit: number): Promise<ToolCallActivityRow[]> {\n const rows = await this.db\n .select({\n toolCallId: agentToolCall.id,\n toolName: agentToolCall.toolName,\n toolType: agentToolCall.toolType,\n status: agentToolCall.status,\n threadId: agentMessage.threadId,\n createdAt: agentToolCall.createdAt,\n })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .orderBy(desc(agentToolCall.createdAt), desc(agentToolCall.id))\n .limit(limit);\n return rows.map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n toolType: row.toolType,\n status: row.status,\n threadId: row.threadId,\n createdAt: row.createdAt.toISOString(),\n }));\n }\n\n async recentThreads(limit: number): Promise<ThreadActivityRow[]> {\n const threads = await this.db\n .select()\n .from(agentThread)\n .where(isNull(agentThread.deletedAt))\n .orderBy(desc(agentThread.updatedAt), desc(agentThread.id))\n .limit(limit);\n const result: ThreadActivityRow[] = [];\n for (const thread of threads) {\n const [messageCountRow] = await this.db\n .select({ value: count() })\n .from(agentMessage)\n .where(eq(agentMessage.threadId, thread.id));\n const usageRows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(eq(agentTokenUsage.threadId, thread.id));\n const totalTokens = usageRows.reduce(\n (sum, row) => sum + row.inputTokens + row.outputTokens,\n 0,\n );\n result.push({\n threadId: thread.id,\n title: thread.title,\n actorRef: thread.actorRef,\n messageCount: messageCountRow?.value ?? 0,\n totalTokens,\n lastActivityAt: thread.updatedAt.toISOString(),\n });\n }\n return result;\n }\n}\n","import type {\n AgentPricingStore,\n CurrentModelPrice,\n ModelPriceInput,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, eq } from 'drizzle-orm';\nimport { type AgentDrizzleDb, agentModelPricing } from './schema.js';\n\n/**\n * {@link AgentPricingStore} backed by Drizzle ORM — the write side of the pricing table\n * {@link import('./drizzle-governance-queries.js').DrizzleGovernanceQueries} joins against. A POJO\n * receiving a Drizzle SQLite database handle (the host app owns the connection), mirroring\n * {@link import('@dudousxd/nestjs-agent-store-mikro-orm')} exactly (atomic supersede semantics).\n */\nexport class DrizzlePricingStore implements AgentPricingStore {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n async upsertModelPrice(input: ModelPriceInput): Promise<void> {\n await this.db\n .update(agentModelPricing)\n .set({ isCurrent: false })\n .where(\n and(eq(agentModelPricing.modelId, input.modelId), eq(agentModelPricing.isCurrent, true)),\n );\n await this.db.insert(agentModelPricing).values({\n id: crypto.randomUUID(),\n modelId: input.modelId,\n inputPricePer1m: input.inputPricePer1m,\n outputPricePer1m: input.outputPricePer1m,\n cacheWritePricePer1m: input.cacheWritePricePer1m ?? null,\n cacheReadPricePer1m: input.cacheReadPricePer1m ?? null,\n effectiveFrom: new Date(),\n isCurrent: true,\n });\n }\n\n async listCurrentPrices(): Promise<CurrentModelPrice[]> {\n const rows = await this.db\n .select()\n .from(agentModelPricing)\n .where(eq(agentModelPricing.isCurrent, true));\n return rows.map((row) => ({\n modelId: row.modelId,\n inputPricePer1m: row.inputPricePer1m,\n outputPricePer1m: row.outputPricePer1m,\n effectiveFrom: row.effectiveFrom.toISOString(),\n ...(row.cacheWritePricePer1m != null\n ? { cacheWritePricePer1m: row.cacheWritePricePer1m }\n : {}),\n ...(row.cacheReadPricePer1m != null ? { cacheReadPricePer1m: row.cacheReadPricePer1m } : {}),\n }));\n }\n}\n","import {\n AGENT_GOVERNANCE_QUERIES,\n AGENT_PRICING_STORE,\n AGENT_STORE,\n} from '@dudousxd/nestjs-agent-core';\nimport { type DynamicModule, Module } from '@nestjs/common';\nimport { DrizzleAgentStore } from './drizzle-agent-store.js';\nimport { DrizzleGovernanceQueries } from './drizzle-governance-queries.js';\nimport { DrizzlePricingStore } from './drizzle-pricing-store.js';\nimport type { AgentDrizzleDb } from './schema.js';\n\n/** Options for {@link DrizzleAgentStoreModule.forRoot}. The app owns and supplies the db handle. */\nexport interface DrizzleAgentStoreModuleOptions {\n /** A Drizzle SQLite database instance (`drizzle(client, { schema: agentSchema })`). */\n db: AgentDrizzleDb;\n}\n\n/**\n * Binds {@link DrizzleAgentStore} to the {@link AGENT_STORE} token consumed by\n * `@dudousxd/nestjs-agent`, plus {@link DrizzleGovernanceQueries} to\n * {@link AGENT_GOVERNANCE_QUERIES} (the read-model the dashboard/telescope surfaces consume) and\n * {@link DrizzlePricingStore} to {@link AGENT_PRICING_STORE} (the write side of that pricing table).\n * The host app supplies an already-opened Drizzle db — this module never opens a connection itself.\n *\n * The returned module is global, so {@link AGENT_STORE}, {@link AGENT_GOVERNANCE_QUERIES} and\n * {@link AGENT_PRICING_STORE} are visible app-wide — `AgentModule` resolves the store without an\n * explicit `store` option, and the dashboard/telescope resolve {@link AGENT_GOVERNANCE_QUERIES}\n * without the host re-binding it.\n *\n * ```ts\n * @Module({ imports: [DrizzleAgentStoreModule.forRoot({ db })] })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class DrizzleAgentStoreModule {\n static forRoot(options: DrizzleAgentStoreModuleOptions): DynamicModule {\n return {\n module: DrizzleAgentStoreModule,\n global: true,\n providers: [\n { provide: DrizzleAgentStore, useFactory: () => new DrizzleAgentStore(options.db) },\n { provide: AGENT_STORE, useExisting: DrizzleAgentStore },\n {\n provide: DrizzleGovernanceQueries,\n useFactory: () => new DrizzleGovernanceQueries(options.db),\n },\n { provide: AGENT_GOVERNANCE_QUERIES, useExisting: DrizzleGovernanceQueries },\n {\n provide: DrizzlePricingStore,\n useFactory: () => new DrizzlePricingStore(options.db),\n },\n { provide: AGENT_PRICING_STORE, useExisting: DrizzlePricingStore },\n ],\n exports: [\n DrizzleAgentStore,\n AGENT_STORE,\n DrizzleGovernanceQueries,\n AGENT_GOVERNANCE_QUERIES,\n DrizzlePricingStore,\n AGENT_PRICING_STORE,\n ],\n };\n }\n}\n"],"mappings":";;;;;;;;;;;;;;;;;;;;;AAAA;;;;;;;;;;;;;;;;;ACSA,yBAOO;AAeA,IAAMA,kBAAcC,gCACzB,gBACA;EACEC,QAAIC,yBAAK,IAAA,EAAMC,WAAU;EACzBC,cAAUF,yBAAK,WAAA,EAAaG,QAAO;EACnCC,eAAWJ,yBAAK,YAAA;EAChBK,WAAOL,yBAAK,OAAA,EAASG,QAAO;EAC5BG,eAAWC,4BAAQ,aAAa;IAAEC,MAAM;EAAU,CAAA,EAAGL,QAAO,EAAGM,QAAQ,KAAA;EACvEC,oBAAgBV,yBAAK,kBAAA;EACrBW,eAAWJ,4BAAQ,cAAc;IAAEC,MAAM;EAAe,CAAA,EAAGL,QAAO;EAClES,eAAWL,4BAAQ,cAAc;IAAEC,MAAM;EAAe,CAAA,EAAGL,QAAO;EAClEU,eAAWN,4BAAQ,cAAc;IAAEC,MAAM;EAAe,CAAA;AAC1D,GACA,CAACM,UAAU;MAACC,0BAAM,gCAAA,EAAkCC,GAAGF,MAAMZ,UAAUY,MAAMF,SAAS;CAAE;AAQnF,IAAMK,mBAAenB,gCAC1B,iBACA;EACEC,QAAIC,yBAAK,IAAA,EAAMC,WAAU;EACzBiB,cAAUlB,yBAAK,WAAA,EACZG,QAAO,EACPgB,WAAW,MAAMtB,YAAYE,IAAI;IAAEqB,UAAU;EAAU,CAAA;EAC1DC,UAAMrB,yBAAK,MAAA,EAAQsB,MAAK,EAAgBnB,QAAO;EAC/CoB,aAASvB,yBAAK,SAAA,EAAWG,QAAO;EAChCqB,eAAWxB,yBAAK,cAAc;IAAEQ,MAAM;EAAO,CAAA,EAAGc,MAAK;EACrDG,iBAAazB,yBAAK,gBAAgB;IAAEQ,MAAM;EAAO,CAAA,EAAGc,MAAK;EACzDI,eAAW1B,yBAAK,cAAc;IAAEQ,MAAM;EAAO,CAAA,EAAGc,MAAK;EACrDK,WAAO3B,yBAAK,SAAS;IAAEQ,MAAM;EAAO,CAAA,EAAGc,MAAK;EAC5CM,eAAW5B,yBAAK,YAAA;EAChBW,eAAWJ,4BAAQ,cAAc;IAAEC,MAAM;EAAe,CAAA,EAAGL,QAAO;AACpE,GACA,CAACW,UAAU;MAACC,0BAAM,kCAAA,EAAoCC,GAAGF,MAAMI,UAAUJ,MAAMH,SAAS;CAAE;AAIrF,IAAMkB,oBAAgB/B,gCAAY,mBAAmB;EAC1DC,QAAIC,yBAAK,IAAA,EAAMC,WAAU;EACzB6B,eAAW9B,yBAAK,YAAA,EACbG,QAAO,EACPgB,WAAW,MAAMF,aAAalB,IAAI;IAAEqB,UAAU;EAAU,CAAA;EAC3DW,cAAU/B,yBAAK,WAAA,EAAaG,QAAO;EACnC6B,cAAUhC,yBAAK,WAAA,EAAasB,MAAK,EAAanB,QAAO;EACrD8B,WAAOjC,yBAAK,SAAS;IAAEQ,MAAM;EAAO,CAAA;EACpC0B,YAAQlC,yBAAK,UAAU;IAAEQ,MAAM;EAAO,CAAA;EACtC2B,YAAQnC,yBAAK,QAAA,EAAUsB,MAAK,EAAmBnB,QAAO;EACtDiC,mBAAepC,yBAAK,iBAAA;EACpBqC,iBAAa9B,4BAAQ,cAAA;EACrB+B,WAAOtC,yBAAK,OAAA;EACZW,eAAWJ,4BAAQ,cAAc;IAAEC,MAAM;EAAe,CAAA,EAAGL,QAAO;EAClEoC,gBAAYhC,4BAAQ,eAAe;IAAEC,MAAM;EAAe,CAAA;AAC5D,CAAA;AAGO,IAAMgC,sBAAkB1C,gCAC7B,qBACA;EACEC,QAAIC,yBAAK,IAAA,EAAMC,WAAU;EACzBiB,cAAUlB,yBAAK,WAAA,EACZG,QAAO,EACPgB,WAAW,MAAMtB,YAAYE,IAAI;IAAEqB,UAAU;EAAU,CAAA;EAC1DlB,cAAUF,yBAAK,WAAA,EAAaG,QAAO;EACnC2B,eAAW9B,yBAAK,YAAA;EAChByC,aAASzC,yBAAK,UAAA,EAAYG,QAAO;EACjCuC,aAAS1C,yBAAK,SAAA,EAAWsB,MAAK,EAAiBnB,QAAO;EACtDwC,iBAAapC,4BAAQ,cAAA,EAAgBJ,QAAO;EAC5CyC,kBAAcrC,4BAAQ,eAAA,EAAiBJ,QAAO;;EAE9C0C,sBAAkBtC,4BAAQ,oBAAA;;EAE1BuC,qBAAiBvC,4BAAQ,mBAAA;;EAEzBwC,aAASC,yBAAK,UAAA;EACdrC,eAAWJ,4BAAQ,cAAc;IAAEC,MAAM;EAAe,CAAA,EAAGL,QAAO;AACpE,GACA,CAACW,UAAU;MAACC,0BAAM,qCAAA,EAAuCC,GAAGF,MAAMZ,UAAUY,MAAMH,SAAS;CAAE;AAIxF,IAAMsC,wBAAoBnD,gCAAY,uBAAuB;EAClEC,QAAIC,yBAAK,IAAA,EAAMC,WAAU;EACzBwC,aAASzC,yBAAK,UAAA,EAAYG,QAAO;EACjC+C,qBAAiBF,yBAAK,oBAAA,EAAsB7C,QAAO;EACnDgD,sBAAkBH,yBAAK,qBAAA,EAAuB7C,QAAO;;EAErDiD,0BAAsBJ,yBAAK,0BAAA;;EAE3BK,yBAAqBL,yBAAK,yBAAA;EAC1BM,mBAAe/C,4BAAQ,kBAAkB;IAAEC,MAAM;EAAe,CAAA,EAAGL,QAAO;EAC1EoD,eAAWhD,4BAAQ,cAAc;IAAEC,MAAM;EAAU,CAAA,EAAGL,QAAO;AAC/D,CAAA;AAGO,IAAMqD,cAAc;EACzB3D;EACAoB;EACAY;EACAW;EACAS;AACF;;;ACvIA,yBAAoB;AASpB,IAAMQ,aAAuB;EAC3B;;;;;;;;;;;EAWA;;EAEA;;;;;;;;;;;;EAYA;;EAEA;;;;;;;;;;;;;;EAcA;;;;;;;;;;;;;;EAcA;;EAEA;;;;;;;;;;;AAaF,eAAsBC,kBAAkBC,IAAkB;AACxD,aAAWC,aAAaH,YAAY;AAClC,UAAME,GAAGE,IAAIC,uBAAIC,IAAIH,SAAAA,CAAAA;EACvB;AACF;AAJsBF;;;ACrEtB,IAAAM,sBAA8D;AAiBvD,IAAMC,oBAAN,MAAMA;EAjBb,OAiBaA;;;;EACX,YAA6BC,IAAoB;SAApBA,KAAAA;EAAqB;EAElD,MAAMC,aAAaC,OAAkD;AACnE,UAAMC,MAAM,oBAAIC,KAAAA;AAChB,UAAMC,SAAyB;MAC7BC,IAAIC,OAAOC,WAAU;MACrBC,UAAUP,MAAMQ,MAAMJ;MACtBK,WAAWT,MAAMQ,MAAMC,aAAa;MACpCC,OAAOV,MAAMU,SAAS;MACtBC,WAAWX,MAAMW,aAAa;MAC9BC,gBAAgB;MAChBC,WAAWZ;MACXa,WAAWb;MACXc,WAAW;IACb;AACA,UAAM,KAAKjB,GAAGkB,OAAOC,WAAAA,EAAaC,OAAOf,MAAAA;AACzC,WAAO,KAAKgB,UAAUhB,MAAAA;EACxB;EAEA,MAAMiB,UAAUC,UAAgD;AAC9D,UAAM,CAAClB,MAAAA,IAAU,MAAM,KAAKL,GACzBwB,OAAM,EACNC,KAAKN,WAAAA,EACLO,UAAMC,6BAAIC,wBAAGT,YAAYb,IAAIiB,QAAAA,OAAWM,4BAAOV,YAAYF,SAAS,CAAA,CAAA;AACvE,QAAIZ,WAAWyB,QAAW;AACxB,aAAO;IACT;AACA,UAAMC,WAAW,MAAM,KAAK/B,GACzBwB,OAAM,EACNC,KAAKO,YAAAA,EACLN,UAAME,wBAAGI,aAAaT,UAAUA,QAAAA,CAAAA,EAChCU,YAAQC,yBAAIF,aAAajB,SAAS,OAAGmB,yBAAIF,aAAa1B,EAAE,CAAA;AAC3D,UAAM6B,OAAOJ,SAASA,SAASK,SAAS,CAAA;AACxC,WAAO;MACL,GAAG,KAAKf,UAAUhB,QAAQ8B,MAAME,OAAAA;MAChCN,UAAUA,SAASO,IAAI,CAACC,YAAY,KAAKC,gBAAgBD,OAAAA,CAAAA;MACzD,GAAIlC,OAAOS,kBAAkB,OAAO;QAAEA,gBAAgBT,OAAOS;MAAe,IAAI,CAAC;IACnF;EACF;EAEA,MAAM2B,YAAYhC,UAAkBiC,QAAQ,IAA8B;AACxE,UAAMC,UAAU,MAAM,KAAK3C,GACxBwB,OAAM,EACNC,KAAKN,WAAAA,EACLO,UACCC,6BACEC,wBAAGT,YAAYV,UAAUA,QAAAA,OACzBmB,wBAAGT,YAAYN,WAAW,KAAA,OAC1BgB,4BAAOV,YAAYF,SAAS,CAAA,CAAA,EAG/BgB,YAAQW,0BAAKzB,YAAYH,SAAS,CAAA,EAClC0B,MAAMA,KAAAA;AACT,UAAMG,YAA6B,CAAA;AACnC,eAAWxC,UAAUsC,SAAS;AAC5B,YAAM,CAACR,IAAAA,IAAQ,MAAM,KAAKnC,GACvBwB,OAAM,EACNC,KAAKO,YAAAA,EACLN,UAAME,wBAAGI,aAAaT,UAAUlB,OAAOC,EAAE,CAAA,EACzC2B,YAAQW,0BAAKZ,aAAajB,SAAS,OAAG6B,0BAAKZ,aAAa1B,EAAE,CAAA,EAC1DoC,MAAM,CAAA;AACTG,gBAAUC,KAAK,KAAKzB,UAAUhB,QAAQ8B,MAAME,OAAAA,CAAAA;IAC9C;AACA,WAAOQ;EACT;EAEA,MAAME,iBAAiBxB,UAAiC;AACtD,UAAM,KAAKvB,GACRgD,OAAO7B,WAAAA,EACP8B,IAAI;MAAEhC,WAAW,oBAAIb,KAAAA;IAAO,CAAA,EAC5BsB,UAAME,wBAAGT,YAAYb,IAAIiB,QAAAA,CAAAA;EAC9B;EAEA,MAAM2B,WAAW3B,UAAkB4B,eAA+C;AAChF,UAAM,CAACC,MAAAA,IAAU,MAAM,KAAKpD,GAAGwB,OAAM,EAAGC,KAAKN,WAAAA,EAAaO,UAAME,wBAAGT,YAAYb,IAAIiB,QAAAA,CAAAA;AACnF,QAAI6B,WAAWtB,QAAW;AACxB,YAAM,IAAIuB,MAAM,UAAU9B,QAAAA,YAAoB;IAChD;AACA,UAAMQ,WAAW,MAAM,KAAK/B,GACzBwB,OAAM,EACNC,KAAKO,YAAAA,EACLN,UAAME,wBAAGI,aAAaT,UAAUA,QAAAA,CAAAA,EAChCU,YAAQC,yBAAIF,aAAajB,SAAS,OAAGmB,yBAAIF,aAAa1B,EAAE,CAAA;AAC3D,UAAMgD,SAASvB,SAASwB,UAAU,CAAChB,YAAYA,QAAQjC,OAAO6C,aAAAA;AAC9D,UAAMK,OAAOF,UAAU,IAAIvB,SAAS0B,MAAM,GAAGH,SAAS,CAAA,IAAKvB;AAC3D,UAAM5B,MAAM,oBAAIC,KAAAA;AAChB,UAAMsD,OAAuB;MAC3BpD,IAAIC,OAAOC,WAAU;MACrBC,UAAU2C,OAAO3C;MACjBE,WAAWyC,OAAOzC;MAClBC,OAAOwC,OAAOxC;MACdC,WAAW;MACXC,gBAAgB;MAChBC,WAAWZ;MACXa,WAAWb;MACXc,WAAW;IACb;AACA,UAAM,KAAKjB,GAAGkB,OAAOC,WAAAA,EAAaC,OAAOsC,IAAAA;AACzC,QAAIF,KAAKpB,SAAS,GAAG;AACnB,YAAM,KAAKpC,GAAGkB,OAAOc,YAAAA,EAAcZ,OACjCoC,KAAKlB,IAAI,CAACC,aAAa;QACrBjC,IAAIC,OAAOC,WAAU;QACrBe,UAAUmC,KAAKpD;QACfqD,MAAMpB,QAAQoB;QACdtB,SAASE,QAAQF;QACjBuB,WAAWrB,QAAQqB;QACnBC,aAAatB,QAAQsB;QACrBC,WAAWvB,QAAQuB;QACnBC,OAAOxB,QAAQwB;QACfC,WAAWzB,QAAQyB;QACnBjD,WAAWwB,QAAQxB;MACrB,EAAA,CAAA;IAEJ;AACA,WAAO,KAAKM,UAAUqC,IAAAA;EACxB;EAEA,MAAMO,cAAc1C,UAA0C;AAC5D,UAAM,CAAClB,MAAAA,IAAU,MAAM,KAAKL,GACzBwB,OAAO;MAAEf,UAAUU,YAAYV;IAAS,CAAA,EACxCgB,KAAKN,WAAAA,EACLO,UAAMC,6BAAIC,wBAAGT,YAAYb,IAAIiB,QAAAA,OAAWM,4BAAOV,YAAYF,SAAS,CAAA,CAAA;AACvE,WAAOZ,QAAQI,YAAY;EAC7B;EAEA,MAAMyD,gBAAgBC,YAA4C;AAChE,UAAM,CAACC,GAAAA,IAAO,MAAM,KAAKpE,GACtBwB,OAAO;MAAEf,UAAUU,YAAYV;IAAS,CAAA,EACxCgB,KAAK4C,aAAAA,EACLC,UAAUtC,kBAAcJ,wBAAGyC,cAAcE,WAAWvC,aAAa1B,EAAE,CAAA,EACnEgE,UAAUnD,iBAAaS,wBAAGI,aAAaT,UAAUJ,YAAYb,EAAE,CAAA,EAC/DoB,UAAME,wBAAGyC,cAAc/D,IAAI6D,UAAAA,CAAAA;AAC9B,WAAOC,KAAK3D,YAAY;EAC1B;EAEA,MAAM+D,eAAeL,YAA4C;AAC/D,UAAM,CAACC,GAAAA,IAAO,MAAM,KAAKpE,GACtBwB,OAAO;MAAEV,gBAAgBK,YAAYL;IAAe,CAAA,EACpDW,KAAK4C,aAAAA,EACLC,UAAUtC,kBAAcJ,wBAAGyC,cAAcE,WAAWvC,aAAa1B,EAAE,CAAA,EACnEgE,UAAUnD,iBAAaS,wBAAGI,aAAaT,UAAUJ,YAAYb,EAAE,CAAA,EAC/DoB,UAAME,wBAAGyC,cAAc/D,IAAI6D,UAAAA,CAAAA;AAC9B,WAAOC,KAAKtD,kBAAkB;EAChC;EAEA,MAAM2D,oBAAoBC,OAAuC;AAC/D,UAAM,CAACrE,MAAAA,IAAU,MAAM,KAAKL,GACzBwB,OAAO;MAAEf,UAAUU,YAAYV;IAAS,CAAA,EACxCgB,KAAKN,WAAAA,EACLO,UAAMC,6BAAIC,wBAAGT,YAAYL,gBAAgB4D,KAAAA,OAAQ7C,4BAAOV,YAAYF,SAAS,CAAA,CAAA;AAChF,WAAOZ,QAAQI,YAAY;EAC7B;EAEA,MAAMkE,SAASpD,UAAkBX,OAA8B;AAC7D,UAAM,KAAKZ,GACRgD,OAAO7B,WAAAA,EACP8B,IAAI;MAAErC;MAAOI,WAAW,oBAAIZ,KAAAA;IAAO,CAAA,EACnCsB,UAAME,wBAAGT,YAAYb,IAAIiB,QAAAA,CAAAA;EAC9B;EAEA,MAAMqD,cAAcrD,UAAiC;AACnD,UAAM,KAAKvB,GACRgD,OAAO7B,WAAAA,EACP8B,IAAI;MAAEpC,WAAW;MAAOG,WAAW,oBAAIZ,KAAAA;IAAO,CAAA,EAC9CsB,UAAMC,6BAAIC,wBAAGT,YAAYb,IAAIiB,QAAAA,OAAWK,wBAAGT,YAAYN,WAAW,IAAA,CAAA,CAAA;EACvE;EAEA,MAAMgE,gBAAgBtD,UAAkBmD,OAAqC;AAC3E,UAAM,KAAK1E,GACRgD,OAAO7B,WAAAA,EACP8B,IAAI;MAAEnC,gBAAgB4D;IAAM,CAAA,EAC5BhD,UAAME,wBAAGT,YAAYb,IAAIiB,QAAAA,CAAAA;EAC9B;EAEA,MAAMuD,cAAc5E,OAAmD;AACrE,UAAM,CAACG,MAAAA,IAAU,MAAM,KAAKL,GACzBwB,OAAM,EACNC,KAAKN,WAAAA,EACLO,UAAME,wBAAGT,YAAYb,IAAIJ,MAAMqB,QAAQ,CAAA;AAC1C,QAAIlB,WAAWyB,QAAW;AACxB,YAAM,IAAIuB,MAAM,UAAUnD,MAAMqB,QAAQ,YAAY;IACtD;AACA,UAAMpB,MAAM,oBAAIC,KAAAA;AAChB,UAAMmC,UAA2B;MAC/BjC,IAAIC,OAAOC,WAAU;MACrBe,UAAUrB,MAAMqB;MAChBoC,MAAMzD,MAAMyD;MACZtB,SAASnC,MAAMmC;MACfuB,WAAW1D,MAAM0D,aAAa;MAC9BC,aAAa3D,MAAM2D,eAAe;MAClCC,WAAW5D,MAAM4D,aAAa;MAC9BC,OAAO7D,MAAM6D,SAAS;MACtBC,WAAW9D,MAAM8D,aAAa;MAC9BjD,WAAWZ;IACb;AACA,UAAM,KAAKH,GAAGkB,OAAOc,YAAAA,EAAcZ,OAAOmB,OAAAA;AAC1C,UAAM,KAAKvC,GACRgD,OAAO7B,WAAAA,EACP8B,IAAI;MAAEjC,WAAWb;IAAI,CAAA,EACrBuB,UAAME,wBAAGT,YAAYb,IAAIJ,MAAMqB,QAAQ,CAAA;AAC1C,WAAO,KAAKiB,gBAAgBD,OAAAA;EAC9B;EAEA,MAAMwC,aAAaxD,UAAkBgD,WAAkC;AACrE,UAAMxC,WAAW,MAAM,KAAK/B,GACzBwB,OAAM,EACNC,KAAKO,YAAAA,EACLN,UAAME,wBAAGI,aAAaT,UAAUA,QAAAA,CAAAA,EAChCU,YAAQC,yBAAIF,aAAajB,SAAS,OAAGmB,yBAAIF,aAAa1B,EAAE,CAAA;AAC3D,UAAMgD,SAASvB,SAASwB,UAAU,CAAChB,YAAYA,QAAQjC,OAAOiE,SAAAA;AAC9D,QAAIjB,SAAS,GAAG;AACd;IACF;AACA,UAAM0B,YAAYjD,SAAS0B,MAAMH,MAAAA,EAAQhB,IAAI,CAACC,YAAYA,QAAQjC,EAAE;AACpE,UAAM,KAAKN,GAAGiF,OAAOZ,aAAAA,EAAe3C,UAAMwD,6BAAQb,cAAcE,WAAWS,SAAAA,CAAAA;AAC3E,UAAM,KAAKhF,GAAGiF,OAAOjD,YAAAA,EAAcN,UAAMwD,6BAAQlD,aAAa1B,IAAI0E,SAAAA,CAAAA;EACpE;EAEA,MAAMG,eAAejF,OAA2C;AAC9D,UAAM,KAAKF,GAAGkB,OAAOmD,aAAAA,EAAejD,OAAO;MACzCd,IAAIJ,MAAMiE;MACVI,WAAWrE,MAAMqE;MACjBa,UAAUlF,MAAMkF;MAChBC,UAAUnF,MAAMmF;MAChBnF,OAAOA,MAAMA;MACboF,QAAQ;MACRC,QAAQrF,MAAMqF;MACdC,eAAe;MACfC,aAAa;MACbC,OAAO;MACP3E,WAAW,oBAAIX,KAAAA;MACfuF,YAAY;IACd,CAAA;EACF;EAEA,MAAMC,eAAe1F,OAA2C;AAC9D,UAAM2F,UAAsD;MAAEN,QAAQrF,MAAMqF;IAAO;AACnF,QAAIrF,MAAMoF,WAAWxD,QAAW;AAC9B+D,cAAQP,SAASpF,MAAMoF;IACzB;AACA,QAAIpF,MAAMwF,UAAU5D,QAAW;AAC7B+D,cAAQH,QAAQxF,MAAMwF;IACxB;AACA,QAAIxF,MAAMuF,gBAAgB3D,QAAW;AACnC+D,cAAQJ,cAAcvF,MAAMuF;IAC9B;AACA,QAAIvF,MAAMsF,kBAAkB1D,QAAW;AACrC+D,cAAQL,gBAAgBtF,MAAMsF;IAChC;AACA,QAAItF,MAAMqF,WAAW,cAAcrF,MAAMqF,WAAW,iBAAiB;AACnEM,cAAQF,aAAa,oBAAIvF,KAAAA;IAC3B;AACA,UAAM,KAAKJ,GAAGgD,OAAOqB,aAAAA,EAAepB,IAAI4C,OAAAA,EAASnE,UAAME,wBAAGyC,cAAc/D,IAAIJ,MAAMiE,UAAU,CAAA;EAC9F;EAEA,MAAM2B,YAAY5F,OAAwC;AACxD,UAAM,KAAKF,GAAGkB,OAAO6E,eAAAA,EAAiB3E,OAAO;MAC3Cd,IAAIC,OAAOC,WAAU;MACrBe,UAAUrB,MAAMqB;MAChBd,UAAUP,MAAMO;MAChB8D,WAAWrE,MAAMqE,aAAa;MAC9ByB,SAAS9F,MAAM8F;MACfC,SAAS/F,MAAM+F;MACfC,aAAahG,MAAM6D,MAAMmC;MACzBC,cAAcjG,MAAM6D,MAAMoC;MAC1BC,kBAAkBlG,MAAM6D,MAAMqC,oBAAoB;MAClDC,iBAAiBnG,MAAM6D,MAAMsC,mBAAmB;MAChDC,SAASpG,MAAMoG,WAAW;MAC1BvF,WAAW,oBAAIX,KAAAA;IACjB,CAAA;EACF;EAEA,MAAMmG,WACJ9F,UACA+F,KACkD;AAClD,UAAMC,QAAQ,oBAAIrG,KAAK,GAAGoG,GAAAA,gBAAmB;AAC7C,UAAME,MAAM,oBAAItG,KAAK,GAAGoG,GAAAA,gBAAmB;AAC3C,UAAMG,OAAO,MAAM,KAAK3G,GACrBwB,OAAM,EACNC,KAAKsE,eAAAA,EACLrE,UACCC,6BACEC,wBAAGmE,gBAAgBtF,UAAUA,QAAAA,OAC7BmG,yBAAIb,gBAAgBhF,WAAW0F,KAAAA,OAC/BI,yBAAId,gBAAgBhF,WAAW2F,GAAAA,CAAAA,CAAAA;AAGrC,UAAMI,aAAaH,KAAKI,OAAO,CAACC,KAAK5C,QAAQ4C,MAAM5C,IAAI8B,cAAc9B,IAAI+B,cAAc,CAAA;AACvF,UAAMG,UAAUK,KAAKI,OAAO,CAACC,KAAK5C,QAAQ4C,OAAO5C,IAAIkC,WAAW,IAAI,CAAA;AACpE,WAAO;MAAEQ;MAAYR;IAAQ;EAC/B;EAEQjF,UAAUhB,QAAwB4G,aAAqC;AAC7E,WAAO;MACL3G,IAAID,OAAOC;MACXM,OAAOP,OAAOO;MACdC,WAAWR,OAAOQ;MAClBE,WAAWV,OAAOU,UAAUmG,YAAW;MACvClG,WAAWX,OAAOW,UAAUkG,YAAW;MACvC,GAAID,gBAAgBnF,SAAY;QAAEqF,oBAAoBF,YAAYxD,MAAM,GAAG,GAAA;MAAK,IAAI,CAAC;IACvF;EACF;EAEQjB,gBAAgBD,SAAyC;AAC/D,WAAO;MACLjC,IAAIiC,QAAQjC;MACZqD,MAAMpB,QAAQoB;MACdtB,SAASE,QAAQF;MACjBtB,WAAWwB,QAAQxB,UAAUmG,YAAW;MACxC,GAAI3E,QAAQqB,aAAa,OAAO;QAAEA,WAAWrB,QAAQqB;MAAU,IAAI,CAAC;MACpE,GAAIrB,QAAQsB,eAAe,OAAO;QAAEA,aAAatB,QAAQsB;MAAY,IAAI,CAAC;MAC1E,GAAItB,QAAQuB,aAAa,OAAO;QAAEA,WAAWvB,QAAQuB;MAAU,IAAI,CAAC;MACpE,GAAIvB,QAAQwB,SAAS,OAAO;QAAEA,OAAOxB,QAAQwB;MAAM,IAAI,CAAC;MACxD,GAAIxB,QAAQyB,aAAa,OAAO;QAAEA,WAAWzB,QAAQyB;MAAU,IAAI,CAAC;IACtE;EACF;AACF;;;ACjVA,IAAAoD,sBAAuD;AAwBvD,SAASC,mBACPC,SACAC,KAAwC;AAExC,QAAMC,QAAQF,QAAQG,IAAIF,IAAIG,OAAO;AACrC,MAAIF,UAAUG,QAAW;AACvB,WAAO;EACT;AACA,QAAMC,mBAAmBL,IAAIK,oBAAoB;AACjD,QAAMC,kBAAkBN,IAAIM,mBAAmB;AAC/C,QAAMC,sBAAsBP,IAAIQ,cAAcH,mBAAmBC;AACjE,SACGC,sBAAsB,MAAaN,MAAMQ,kBACzCJ,mBAAmB,OAAcJ,MAAMS,wBAAwBT,MAAMQ,mBACrEH,kBAAkB,OAAcL,MAAMU,uBAAuBV,MAAMQ,mBACnET,IAAIY,eAAe,MAAaX,MAAMY;AAE3C;AAjBSf;AAuBT,SAASgB,QACPf,SACAC,KAAwC;AAExC,SAAOA,IAAIe,WAAWjB,mBAAmBC,SAASC,GAAAA;AACpD;AALSc;AAQT,SAASE,UAAUC,OAAsB;AACvC,SAAO;IACLC,OAAO,oBAAIC,KAAK,GAAGF,MAAMG,OAAO,gBAAgB;IAChDC,KAAK,oBAAIF,KAAK,GAAGF,MAAMK,KAAK,gBAAgB;EAC9C;AACF;AALSN;AAcF,IAAMO,2BAAN,MAAMA;EArEb,OAqEaA;;;;EACX,YAA6BC,IAAoB;SAApBA,KAAAA;EAAqB;EAElD,MAAcC,cAAgD;AAC5D,UAAMC,OAAO,MAAM,KAAKF,GACrBG,OAAM,EACNC,KAAKC,iBAAAA,EACLC,UAAMC,wBAAGF,kBAAkBG,WAAW,IAAA,CAAA;AACzC,UAAMjC,UAAU,oBAAIkC,IAAAA;AACpB,eAAWjC,OAAO0B,MAAM;AACtB3B,cAAQmC,IAAIlC,IAAIG,SAAS;QACvBM,iBAAiBT,IAAIS;QACrBI,kBAAkBb,IAAIa;QACtBH,sBAAsBV,IAAIU;QAC1BC,qBAAqBX,IAAIW;MAC3B,CAAA;IACF;AACA,WAAOZ;EACT;EAEA,MAAcoC,aACZlB,OACkD;AAClD,UAAM,EAAEC,OAAOG,IAAG,IAAKL,UAAUC,KAAAA;AACjC,UAAMS,OAAO,MAAM,KAAKF,GACrBG,OAAM,EACNC,KAAKQ,eAAAA,EACLN,UAAMO,6BAAIC,yBAAIF,gBAAgBG,WAAWrB,KAAAA,OAAQsB,yBAAIJ,gBAAgBG,WAAWlB,GAAAA,CAAAA,CAAAA;AACnF,WAAOK;EACT;EAEA,MAAMe,aAAaxB,OAAkD;AACnE,UAAMlB,UAAU,MAAM,KAAK0B,YAAW;AACtC,UAAMC,OAAO,MAAM,KAAKS,aAAalB,KAAAA;AACrC,UAAMyB,UAAU,oBAAIT,IAAAA;AAIpB,eAAWjC,OAAO0B,MAAM;AACtB,YAAMiB,SAASD,QAAQxC,IAAIF,IAAIG,OAAO,KAAK;QACzCyC,UAAU;QACVpC,aAAa;QACbI,cAAc;QACdG,SAAS;MACX;AACA4B,aAAOC,YAAY;AACnBD,aAAOnC,eAAeR,IAAIQ;AAC1BmC,aAAO/B,gBAAgBZ,IAAIY;AAC3B+B,aAAO5B,WAAWD,QAAQf,SAASC,GAAAA;AACnC0C,cAAQR,IAAIlC,IAAIG,SAASwC,MAAAA;IAC3B;AACA,UAAME,SAA0B,CAAA;AAChC,eAAW,CAAC1C,SAASwC,MAAAA,KAAWD,SAAS;AACvCG,aAAOC,KAAK;QACV3C;QACAyC,UAAUD,OAAOC;QACjBpC,aAAamC,OAAOnC;QACpBI,cAAc+B,OAAO/B;QACrBG,SAAS4B,OAAO5B;MAClB,CAAA;IACF;AACA8B,WAAOE,KACL,CAACC,MAAMC,UAAUA,MAAMlC,UAAUiC,KAAKjC,WAAWiC,KAAK7C,QAAQ+C,cAAcD,MAAM9C,OAAO,CAAA;AAE3F,WAAO0C;EACT;EAEA,MAAMM,aAAalC,OAAkD;AACnE,UAAMlB,UAAU,MAAM,KAAK0B,YAAW;AACtC,UAAMC,OAAO,MAAM,KAAKS,aAAalB,KAAAA;AACrC,UAAMmC,UAAU,oBAAInB,IAAAA;AACpB,eAAWjC,OAAO0B,MAAM;AACtB,YAAMiB,SAASS,QAAQlD,IAAIF,IAAIqD,QAAQ,KAAK;QAAET,UAAU;QAAGU,aAAa;QAAGvC,SAAS;MAAE;AACtF4B,aAAOC,YAAY;AACnBD,aAAOW,eAAetD,IAAIQ,cAAcR,IAAIY;AAC5C+B,aAAO5B,WAAWD,QAAQf,SAASC,GAAAA;AACnCoD,cAAQlB,IAAIlC,IAAIqD,UAAUV,MAAAA;IAC5B;AACA,UAAME,SAA0B,CAAA;AAChC,eAAW,CAACQ,UAAUV,MAAAA,KAAWS,SAAS;AACxCP,aAAOC,KAAK;QACVO;QACAT,UAAUD,OAAOC;QACjBU,aAAaX,OAAOW;QACpBvC,SAAS4B,OAAO5B;MAClB,CAAA;IACF;AACA8B,WAAOE,KACL,CAACC,MAAMC,UAAUA,MAAMlC,UAAUiC,KAAKjC,WAAWiC,KAAKK,SAASH,cAAcD,MAAMI,QAAQ,CAAA;AAE7F,WAAOR;EACT;EAEA,MAAMU,WAAWtC,OAAoD;AACnE,UAAMlB,UAAU,MAAM,KAAK0B,YAAW;AACtC,UAAMC,OAAO,MAAM,KAAKS,aAAalB,KAAAA;AACrC,UAAMuC,QAAQ,oBAAIvB,IAAAA;AAClB,eAAWjC,OAAO0B,MAAM;AACtB,YAAM+B,MAAMzD,IAAIuC,UAAUmB,YAAW,EAAGC,MAAM,GAAG,EAAA;AACjD,YAAMhB,SAASa,MAAMtD,IAAIuD,GAAAA,KAAQ;QAAEH,aAAa;QAAGvC,SAAS;MAAE;AAC9D4B,aAAOW,eAAetD,IAAIQ,cAAcR,IAAIY;AAC5C+B,aAAO5B,WAAWD,QAAQf,SAASC,GAAAA;AACnCwD,YAAMtB,IAAIuB,KAAKd,MAAAA;IACjB;AACA,UAAME,SAA4B,CAAA;AAClC,eAAW,CAACY,KAAKd,MAAAA,KAAWa,OAAO;AACjCX,aAAOC,KAAK;QAAEW;QAAKH,aAAaX,OAAOW;QAAavC,SAAS4B,OAAO5B;MAAQ,CAAA;IAC9E;AACA8B,WAAOE,KAAK,CAACC,MAAMC,UAAUD,KAAKS,IAAIP,cAAcD,MAAMQ,GAAG,CAAA;AAC7D,WAAOZ;EACT;EAEA,MAAMe,gBAAgBC,OAA+C;AACnE,UAAMnC,OAAO,MAAM,KAAKF,GACrBG,OAAO;MACNmC,YAAYC,cAAcC;MAC1BC,UAAUF,cAAcE;MACxBC,UAAUH,cAAcG;MACxBC,QAAQJ,cAAcI;MACtBC,UAAUC,aAAaD;MACvB7B,WAAWwB,cAAcxB;IAC3B,CAAA,EACCX,KAAKmC,aAAAA,EACLO,UAAUD,kBAActC,wBAAGgC,cAAcQ,WAAWF,aAAaL,EAAE,CAAA,EACnEQ,YAAQC,0BAAKV,cAAcxB,SAAS,OAAGkC,0BAAKV,cAAcC,EAAE,CAAA,EAC5DH,MAAMA,KAAAA;AACT,WAAOnC,KAAKgD,IAAI,CAAC1E,SAAS;MACxB8D,YAAY9D,IAAI8D;MAChBG,UAAUjE,IAAIiE;MACdC,UAAUlE,IAAIkE;MACdC,QAAQnE,IAAImE;MACZC,UAAUpE,IAAIoE;MACd7B,WAAWvC,IAAIuC,UAAUmB,YAAW;IACtC,EAAA;EACF;EAEA,MAAMiB,cAAcd,OAA6C;AAC/D,UAAMe,UAAU,MAAM,KAAKpD,GACxBG,OAAM,EACNC,KAAKiD,WAAAA,EACL/C,UAAMgD,4BAAOD,YAAYE,SAAS,CAAA,EAClCP,YAAQC,0BAAKI,YAAYG,SAAS,OAAGP,0BAAKI,YAAYb,EAAE,CAAA,EACxDH,MAAMA,KAAAA;AACT,UAAMhB,SAA8B,CAAA;AACpC,eAAWoC,UAAUL,SAAS;AAC5B,YAAM,CAACM,eAAAA,IAAmB,MAAM,KAAK1D,GAClCG,OAAO;QAAEwD,WAAOC,2BAAAA;MAAQ,CAAA,EACxBxD,KAAKyC,YAAAA,EACLvC,UAAMC,wBAAGsC,aAAaD,UAAUa,OAAOjB,EAAE,CAAA;AAC5C,YAAMqB,YAAY,MAAM,KAAK7D,GAC1BG,OAAM,EACNC,KAAKQ,eAAAA,EACLN,UAAMC,wBAAGK,gBAAgBgC,UAAUa,OAAOjB,EAAE,CAAA;AAC/C,YAAMV,cAAc+B,UAAUC,OAC5B,CAACC,KAAKvF,QAAQuF,MAAMvF,IAAIQ,cAAcR,IAAIY,cAC1C,CAAA;AAEFiC,aAAOC,KAAK;QACVsB,UAAUa,OAAOjB;QACjBwB,OAAOP,OAAOO;QACdnC,UAAU4B,OAAO5B;QACjBoC,cAAcP,iBAAiBC,SAAS;QACxC7B;QACAoC,gBAAgBT,OAAOD,UAAUtB,YAAW;MAC9C,CAAA;IACF;AACA,WAAOb;EACT;AACF;;;ACjPA,IAAA8C,sBAAwB;AASjB,IAAMC,sBAAN,MAAMA;EATb,OASaA;;;;EACX,YAA6BC,IAAoB;SAApBA,KAAAA;EAAqB;EAElD,MAAMC,iBAAiBC,OAAuC;AAC5D,UAAM,KAAKF,GACRG,OAAOC,iBAAAA,EACPC,IAAI;MAAEC,WAAW;IAAM,CAAA,EACvBC,UACCC,6BAAIC,wBAAGL,kBAAkBM,SAASR,MAAMQ,OAAO,OAAGD,wBAAGL,kBAAkBE,WAAW,IAAA,CAAA,CAAA;AAEtF,UAAM,KAAKN,GAAGW,OAAOP,iBAAAA,EAAmBQ,OAAO;MAC7CC,IAAIC,OAAOC,WAAU;MACrBL,SAASR,MAAMQ;MACfM,iBAAiBd,MAAMc;MACvBC,kBAAkBf,MAAMe;MACxBC,sBAAsBhB,MAAMgB,wBAAwB;MACpDC,qBAAqBjB,MAAMiB,uBAAuB;MAClDC,eAAe,oBAAIC,KAAAA;MACnBf,WAAW;IACb,CAAA;EACF;EAEA,MAAMgB,oBAAkD;AACtD,UAAMC,OAAO,MAAM,KAAKvB,GACrBwB,OAAM,EACNC,KAAKrB,iBAAAA,EACLG,UAAME,wBAAGL,kBAAkBE,WAAW,IAAA,CAAA;AACzC,WAAOiB,KAAKG,IAAI,CAACC,SAAS;MACxBjB,SAASiB,IAAIjB;MACbM,iBAAiBW,IAAIX;MACrBC,kBAAkBU,IAAIV;MACtBG,eAAeO,IAAIP,cAAcQ,YAAW;MAC5C,GAAID,IAAIT,wBAAwB,OAC5B;QAAEA,sBAAsBS,IAAIT;MAAqB,IACjD,CAAC;MACL,GAAIS,IAAIR,uBAAuB,OAAO;QAAEA,qBAAqBQ,IAAIR;MAAoB,IAAI,CAAC;IAC5F,EAAA;EACF;AACF;;;ACpDA,+BAIO;AACP,oBAA2C;;;;;;;;AA8BpC,IAAMU,0BAAN,MAAMA,yBAAAA;SAAAA;;;EACX,OAAOC,QAAQC,SAAwD;AACrE,WAAO;MACLC,QAAQH;MACRI,QAAQ;MACRC,WAAW;QACT;UAAEC,SAASC;UAAmBC,YAAY,6BAAM,IAAID,kBAAkBL,QAAQO,EAAE,GAAtC;QAAwC;QAClF;UAAEH,SAASI;UAAaC,aAAaJ;QAAkB;QACvD;UACED,SAASM;UACTJ,YAAY,6BAAM,IAAII,yBAAyBV,QAAQO,EAAE,GAA7C;QACd;QACA;UAAEH,SAASO;UAA0BF,aAAaC;QAAyB;QAC3E;UACEN,SAASQ;UACTN,YAAY,6BAAM,IAAIM,oBAAoBZ,QAAQO,EAAE,GAAxC;QACd;QACA;UAAEH,SAASS;UAAqBJ,aAAaG;QAAoB;;MAEnEE,SAAS;QACPT;QACAG;QACAE;QACAC;QACAC;QACAC;;IAEJ;EACF;AACF;;;;","names":["agentThread","sqliteTable","id","text","primaryKey","actorRef","notNull","tenantRef","title","transient","integer","mode","default","activeStreamId","createdAt","updatedAt","deletedAt","table","index","on","agentMessage","threadId","references","onDelete","role","$type","content","toolCalls","toolResults","followUps","usage","agentName","agentToolCall","messageId","toolName","toolType","input","output","status","executedByRef","executionMs","error","executedAt","agentTokenUsage","modelId","purpose","inputTokens","outputTokens","cacheWriteTokens","cacheReadTokens","costUsd","real","agentModelPricing","inputPricePer1m","outputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","effectiveFrom","isCurrent","agentSchema","statements","ensureAgentSchema","db","statement","run","sql","raw","import_drizzle_orm","DrizzleAgentStore","db","createThread","input","now","Date","thread","id","crypto","randomUUID","actorRef","actor","tenantRef","title","transient","activeStreamId","createdAt","updatedAt","deletedAt","insert","agentThread","values","toSummary","getThread","threadId","select","from","where","and","eq","isNull","undefined","messages","agentMessage","orderBy","asc","last","length","content","map","message","toStoredMessage","listThreads","limit","threads","desc","summaries","push","softDeleteThread","update","set","forkThread","fromMessageId","source","Error","cutoff","findIndex","kept","slice","fork","role","toolCalls","toolResults","followUps","usage","agentName","ownerOfThread","ownerOfToolCall","toolCallId","row","agentToolCall","innerJoin","messageId","runForToolCall","ownerOfActiveStream","runId","setTitle","promoteThread","setActiveStream","appendMessage","truncateFrom","doomedIds","delete","inArray","recordToolCall","toolName","toolType","output","status","executedByRef","executionMs","error","executedAt","updateToolCall","updates","recordUsage","agentTokenUsage","modelId","purpose","inputTokens","outputTokens","cacheWriteTokens","cacheReadTokens","costUsd","quotaToday","day","start","end","rows","gte","lte","usedTokens","reduce","sum","lastContent","toISOString","lastMessagePreview","import_drizzle_orm","estimateFromTokens","pricing","row","price","get","modelId","undefined","cacheWriteTokens","cacheReadTokens","uncachedInputTokens","inputTokens","inputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","outputTokens","outputPricePer1m","rowCost","costUsd","dayBounds","range","start","Date","fromDay","end","toDay","DrizzleGovernanceQueries","db","loadPricing","rows","select","from","agentModelPricing","where","eq","isCurrent","Map","set","usageInRange","agentTokenUsage","and","gte","createdAt","lte","spendByModel","byModel","bucket","requests","result","push","sort","left","right","localeCompare","spendByActor","byActor","actorRef","totalTokens","usageTrend","byDay","day","toISOString","slice","recentToolCalls","limit","toolCallId","agentToolCall","id","toolName","toolType","status","threadId","agentMessage","innerJoin","messageId","orderBy","desc","map","recentThreads","threads","agentThread","isNull","deletedAt","updatedAt","thread","messageCountRow","value","count","usageRows","reduce","sum","title","messageCount","lastActivityAt","import_drizzle_orm","DrizzlePricingStore","db","upsertModelPrice","input","update","agentModelPricing","set","isCurrent","where","and","eq","modelId","insert","values","id","crypto","randomUUID","inputPricePer1m","outputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","effectiveFrom","Date","listCurrentPrices","rows","select","from","map","row","toISOString","DrizzleAgentStoreModule","forRoot","options","module","global","providers","provide","DrizzleAgentStore","useFactory","db","AGENT_STORE","useExisting","DrizzleGovernanceQueries","AGENT_GOVERNANCE_QUERIES","DrizzlePricingStore","AGENT_PRICING_STORE","exports"]}
package/dist/index.d.cts CHANGED
@@ -95,25 +95,6 @@ declare const agentThread: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
95
95
  }, {}, {
96
96
  length: number | undefined;
97
97
  }>;
98
- persona: drizzle_orm_sqlite_core.SQLiteColumn<{
99
- name: "persona";
100
- tableName: "agent_thread";
101
- dataType: "string";
102
- columnType: "SQLiteText";
103
- data: string;
104
- driverParam: string;
105
- notNull: true;
106
- hasDefault: true;
107
- isPrimaryKey: false;
108
- isAutoincrement: false;
109
- hasRuntimeDefault: false;
110
- enumValues: [string, ...string[]];
111
- baseColumn: never;
112
- identity: undefined;
113
- generated: undefined;
114
- }, {}, {
115
- length: number | undefined;
116
- }>;
117
98
  transient: drizzle_orm_sqlite_core.SQLiteColumn<{
118
99
  name: "transient";
119
100
  tableName: "agent_thread";
@@ -366,8 +347,8 @@ declare const agentMessage: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
366
347
  }, {}, {
367
348
  $type: MessageUsage;
368
349
  }>;
369
- persona: drizzle_orm_sqlite_core.SQLiteColumn<{
370
- name: "persona";
350
+ agentName: drizzle_orm_sqlite_core.SQLiteColumn<{
351
+ name: "agent_name";
371
352
  tableName: "agent_message";
372
353
  dataType: "string";
373
354
  columnType: "SQLiteText";
@@ -1088,25 +1069,6 @@ declare const agentSchema: {
1088
1069
  }, {}, {
1089
1070
  length: number | undefined;
1090
1071
  }>;
1091
- persona: drizzle_orm_sqlite_core.SQLiteColumn<{
1092
- name: "persona";
1093
- tableName: "agent_thread";
1094
- dataType: "string";
1095
- columnType: "SQLiteText";
1096
- data: string;
1097
- driverParam: string;
1098
- notNull: true;
1099
- hasDefault: true;
1100
- isPrimaryKey: false;
1101
- isAutoincrement: false;
1102
- hasRuntimeDefault: false;
1103
- enumValues: [string, ...string[]];
1104
- baseColumn: never;
1105
- identity: undefined;
1106
- generated: undefined;
1107
- }, {}, {
1108
- length: number | undefined;
1109
- }>;
1110
1072
  transient: drizzle_orm_sqlite_core.SQLiteColumn<{
1111
1073
  name: "transient";
1112
1074
  tableName: "agent_thread";
@@ -1354,8 +1316,8 @@ declare const agentSchema: {
1354
1316
  }, {}, {
1355
1317
  $type: MessageUsage;
1356
1318
  }>;
1357
- persona: drizzle_orm_sqlite_core.SQLiteColumn<{
1358
- name: "persona";
1319
+ agentName: drizzle_orm_sqlite_core.SQLiteColumn<{
1320
+ name: "agent_name";
1359
1321
  tableName: "agent_message";
1360
1322
  dataType: "string";
1361
1323
  columnType: "SQLiteText";
@@ -2025,6 +1987,7 @@ declare class DrizzleAgentStore implements AgentStore {
2025
1987
  runForToolCall(toolCallId: string): Promise<string | null>;
2026
1988
  ownerOfActiveStream(runId: string): Promise<string | null>;
2027
1989
  setTitle(threadId: string, title: string): Promise<void>;
1990
+ promoteThread(threadId: string): Promise<void>;
2028
1991
  setActiveStream(threadId: string, runId: string | null): Promise<void>;
2029
1992
  appendMessage(input: AppendMessageInput): Promise<StoredMessage>;
2030
1993
  truncateFrom(threadId: string, messageId: string): Promise<void>;
@@ -2033,6 +1996,7 @@ declare class DrizzleAgentStore implements AgentStore {
2033
1996
  recordUsage(input: RecordUsageInput): Promise<void>;
2034
1997
  quotaToday(actorRef: string, day: string): Promise<{
2035
1998
  usedTokens: number;
1999
+ costUsd: number;
2036
2000
  }>;
2037
2001
  private toSummary;
2038
2002
  private toStoredMessage;
package/dist/index.d.ts CHANGED
@@ -95,25 +95,6 @@ declare const agentThread: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
95
95
  }, {}, {
96
96
  length: number | undefined;
97
97
  }>;
98
- persona: drizzle_orm_sqlite_core.SQLiteColumn<{
99
- name: "persona";
100
- tableName: "agent_thread";
101
- dataType: "string";
102
- columnType: "SQLiteText";
103
- data: string;
104
- driverParam: string;
105
- notNull: true;
106
- hasDefault: true;
107
- isPrimaryKey: false;
108
- isAutoincrement: false;
109
- hasRuntimeDefault: false;
110
- enumValues: [string, ...string[]];
111
- baseColumn: never;
112
- identity: undefined;
113
- generated: undefined;
114
- }, {}, {
115
- length: number | undefined;
116
- }>;
117
98
  transient: drizzle_orm_sqlite_core.SQLiteColumn<{
118
99
  name: "transient";
119
100
  tableName: "agent_thread";
@@ -366,8 +347,8 @@ declare const agentMessage: drizzle_orm_sqlite_core.SQLiteTableWithColumns<{
366
347
  }, {}, {
367
348
  $type: MessageUsage;
368
349
  }>;
369
- persona: drizzle_orm_sqlite_core.SQLiteColumn<{
370
- name: "persona";
350
+ agentName: drizzle_orm_sqlite_core.SQLiteColumn<{
351
+ name: "agent_name";
371
352
  tableName: "agent_message";
372
353
  dataType: "string";
373
354
  columnType: "SQLiteText";
@@ -1088,25 +1069,6 @@ declare const agentSchema: {
1088
1069
  }, {}, {
1089
1070
  length: number | undefined;
1090
1071
  }>;
1091
- persona: drizzle_orm_sqlite_core.SQLiteColumn<{
1092
- name: "persona";
1093
- tableName: "agent_thread";
1094
- dataType: "string";
1095
- columnType: "SQLiteText";
1096
- data: string;
1097
- driverParam: string;
1098
- notNull: true;
1099
- hasDefault: true;
1100
- isPrimaryKey: false;
1101
- isAutoincrement: false;
1102
- hasRuntimeDefault: false;
1103
- enumValues: [string, ...string[]];
1104
- baseColumn: never;
1105
- identity: undefined;
1106
- generated: undefined;
1107
- }, {}, {
1108
- length: number | undefined;
1109
- }>;
1110
1072
  transient: drizzle_orm_sqlite_core.SQLiteColumn<{
1111
1073
  name: "transient";
1112
1074
  tableName: "agent_thread";
@@ -1354,8 +1316,8 @@ declare const agentSchema: {
1354
1316
  }, {}, {
1355
1317
  $type: MessageUsage;
1356
1318
  }>;
1357
- persona: drizzle_orm_sqlite_core.SQLiteColumn<{
1358
- name: "persona";
1319
+ agentName: drizzle_orm_sqlite_core.SQLiteColumn<{
1320
+ name: "agent_name";
1359
1321
  tableName: "agent_message";
1360
1322
  dataType: "string";
1361
1323
  columnType: "SQLiteText";
@@ -2025,6 +1987,7 @@ declare class DrizzleAgentStore implements AgentStore {
2025
1987
  runForToolCall(toolCallId: string): Promise<string | null>;
2026
1988
  ownerOfActiveStream(runId: string): Promise<string | null>;
2027
1989
  setTitle(threadId: string, title: string): Promise<void>;
1990
+ promoteThread(threadId: string): Promise<void>;
2028
1991
  setActiveStream(threadId: string, runId: string | null): Promise<void>;
2029
1992
  appendMessage(input: AppendMessageInput): Promise<StoredMessage>;
2030
1993
  truncateFrom(threadId: string, messageId: string): Promise<void>;
@@ -2033,6 +1996,7 @@ declare class DrizzleAgentStore implements AgentStore {
2033
1996
  recordUsage(input: RecordUsageInput): Promise<void>;
2034
1997
  quotaToday(actorRef: string, day: string): Promise<{
2035
1998
  usedTokens: number;
1999
+ costUsd: number;
2036
2000
  }>;
2037
2001
  private toSummary;
2038
2002
  private toStoredMessage;
package/dist/index.js CHANGED
@@ -8,7 +8,6 @@ var agentThread = sqliteTable("agent_thread", {
8
8
  actorRef: text("actor_ref").notNull(),
9
9
  tenantRef: text("tenant_ref"),
10
10
  title: text("title").notNull(),
11
- persona: text("persona").notNull().default("default"),
12
11
  transient: integer("transient", {
13
12
  mode: "boolean"
14
13
  }).notNull().default(false),
@@ -44,7 +43,7 @@ var agentMessage = sqliteTable("agent_message", {
44
43
  usage: text("usage", {
45
44
  mode: "json"
46
45
  }).$type(),
47
- persona: text("persona"),
46
+ agentName: text("agent_name"),
48
47
  createdAt: integer("created_at", {
49
48
  mode: "timestamp_ms"
50
49
  }).notNull()
@@ -130,7 +129,6 @@ var statements = [
130
129
  actor_ref TEXT NOT NULL,
131
130
  tenant_ref TEXT,
132
131
  title TEXT NOT NULL,
133
- persona TEXT NOT NULL DEFAULT 'default',
134
132
  transient INTEGER NOT NULL DEFAULT 0,
135
133
  active_stream_id TEXT,
136
134
  created_at INTEGER NOT NULL,
@@ -148,7 +146,7 @@ var statements = [
148
146
  tool_results TEXT,
149
147
  follow_ups TEXT,
150
148
  usage TEXT,
151
- persona TEXT,
149
+ agent_name TEXT,
152
150
  created_at INTEGER NOT NULL
153
151
  )`,
154
152
  `CREATE INDEX IF NOT EXISTS agent_message_thread_created_idx
@@ -218,7 +216,6 @@ var DrizzleAgentStore = class {
218
216
  actorRef: input.actor.id,
219
217
  tenantRef: input.actor.tenantRef ?? null,
220
218
  title: input.title ?? "New chat",
221
- persona: input.persona,
222
219
  transient: input.transient ?? false,
223
220
  activeStreamId: null,
224
221
  createdAt: now,
@@ -271,7 +268,6 @@ var DrizzleAgentStore = class {
271
268
  actorRef: source.actorRef,
272
269
  tenantRef: source.tenantRef,
273
270
  title: source.title,
274
- persona: source.persona,
275
271
  transient: false,
276
272
  activeStreamId: null,
277
273
  createdAt: now,
@@ -289,7 +285,7 @@ var DrizzleAgentStore = class {
289
285
  toolResults: message.toolResults,
290
286
  followUps: message.followUps,
291
287
  usage: message.usage,
292
- persona: message.persona,
288
+ agentName: message.agentName,
293
289
  createdAt: message.createdAt
294
290
  })));
295
291
  }
@@ -325,6 +321,12 @@ var DrizzleAgentStore = class {
325
321
  updatedAt: /* @__PURE__ */ new Date()
326
322
  }).where(eq(agentThread.id, threadId));
327
323
  }
324
+ async promoteThread(threadId) {
325
+ await this.db.update(agentThread).set({
326
+ transient: false,
327
+ updatedAt: /* @__PURE__ */ new Date()
328
+ }).where(and(eq(agentThread.id, threadId), eq(agentThread.transient, true)));
329
+ }
328
330
  async setActiveStream(threadId, runId) {
329
331
  await this.db.update(agentThread).set({
330
332
  activeStreamId: runId
@@ -345,7 +347,7 @@ var DrizzleAgentStore = class {
345
347
  toolResults: input.toolResults ?? null,
346
348
  followUps: input.followUps ?? null,
347
349
  usage: input.usage ?? null,
348
- persona: input.persona ?? null,
350
+ agentName: input.agentName ?? null,
349
351
  createdAt: now
350
352
  };
351
353
  await this.db.insert(agentMessage).values(message);
@@ -422,15 +424,16 @@ var DrizzleAgentStore = class {
422
424
  const end = /* @__PURE__ */ new Date(`${day}T23:59:59.999Z`);
423
425
  const rows = await this.db.select().from(agentTokenUsage).where(and(eq(agentTokenUsage.actorRef, actorRef), gte(agentTokenUsage.createdAt, start), lte(agentTokenUsage.createdAt, end)));
424
426
  const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);
427
+ const costUsd = rows.reduce((sum, row) => sum + (row.costUsd ?? 0), 0);
425
428
  return {
426
- usedTokens
429
+ usedTokens,
430
+ costUsd
427
431
  };
428
432
  }
429
433
  toSummary(thread, lastContent) {
430
434
  return {
431
435
  id: thread.id,
432
436
  title: thread.title,
433
- persona: thread.persona,
434
437
  transient: thread.transient,
435
438
  createdAt: thread.createdAt.toISOString(),
436
439
  updatedAt: thread.updatedAt.toISOString(),
@@ -456,6 +459,9 @@ var DrizzleAgentStore = class {
456
459
  } : {},
457
460
  ...message.usage != null ? {
458
461
  usage: message.usage
462
+ } : {},
463
+ ...message.agentName != null ? {
464
+ agentName: message.agentName
459
465
  } : {}
460
466
  };
461
467
  }
package/dist/index.js.map CHANGED
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/schema.ts","../src/ensure-schema.ts","../src/drizzle-agent-store.ts","../src/drizzle-governance-queries.ts","../src/drizzle-pricing-store.ts","../src/drizzle-agent-store.module.ts"],"sourcesContent":["import type {\n MessageRole,\n MessageUsage,\n ToolCallRequest,\n ToolCallStatus,\n ToolKind,\n ToolResult,\n UsagePurpose,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n type BaseSQLiteDatabase,\n index,\n integer,\n real,\n sqliteTable,\n text,\n} from 'drizzle-orm/sqlite-core';\n\n/**\n * Drizzle schema mirroring the MikroORM agent entities (same logical columns/relations):\n * threads, messages, tool calls, token usage and model pricing. Targets the SQLite core so the\n * db-test runs on an in-memory better-sqlite3; timestamps are stored as integer epoch-ms columns\n * (`{ mode: 'timestamp_ms' }`) which Drizzle round-trips to/from JS `Date`, and the model-facing\n * message extras (tool calls/results, follow-ups, usage) live in JSON `text` columns.\n */\n\n/**\n * A conversation thread. `deletedAt` drives soft delete: a deleted thread is hidden from\n * {@link import('./drizzle-agent-store.js').DrizzleAgentStore.getThread}/`listThreads` but its\n * row survives.\n */\nexport const agentThread = sqliteTable(\n 'agent_thread',\n {\n id: text('id').primaryKey(),\n actorRef: text('actor_ref').notNull(),\n tenantRef: text('tenant_ref'),\n title: text('title').notNull(),\n persona: text('persona').notNull().default('default'),\n transient: integer('transient', { mode: 'boolean' }).notNull().default(false),\n activeStreamId: text('active_stream_id'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n updatedAt: integer('updated_at', { mode: 'timestamp_ms' }).notNull(),\n deletedAt: integer('deleted_at', { mode: 'timestamp_ms' }),\n },\n (table) => [index('agent_thread_actor_updated_idx').on(table.actorRef, table.updatedAt)],\n);\n\n/**\n * One stored message in a thread. The model-facing extras (`toolCalls`/`toolResults`/\n * `followUps`/`usage`) are folded into nullable JSON columns so a single row round-trips to a\n * {@link import('@dudousxd/nestjs-agent-core').StoredMessage}. `threadId` cascades on delete.\n */\nexport const agentMessage = sqliteTable(\n 'agent_message',\n {\n id: text('id').primaryKey(),\n threadId: text('thread_id')\n .notNull()\n .references(() => agentThread.id, { onDelete: 'cascade' }),\n role: text('role').$type<MessageRole>().notNull(),\n content: text('content').notNull(),\n toolCalls: text('tool_calls', { mode: 'json' }).$type<ToolCallRequest[]>(),\n toolResults: text('tool_results', { mode: 'json' }).$type<ToolResult[]>(),\n followUps: text('follow_ups', { mode: 'json' }).$type<string[]>(),\n usage: text('usage', { mode: 'json' }).$type<MessageUsage>(),\n persona: text('persona'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n },\n (table) => [index('agent_message_thread_created_idx').on(table.threadId, table.createdAt)],\n);\n\n/** A tool call requested during an assistant turn. The pk is the model-supplied `toolCallId`. */\nexport const agentToolCall = sqliteTable('agent_tool_call', {\n id: text('id').primaryKey(),\n messageId: text('message_id')\n .notNull()\n .references(() => agentMessage.id, { onDelete: 'cascade' }),\n toolName: text('tool_name').notNull(),\n toolType: text('tool_type').$type<ToolKind>().notNull(),\n input: text('input', { mode: 'json' }),\n output: text('output', { mode: 'json' }),\n status: text('status').$type<ToolCallStatus>().notNull(),\n executedByRef: text('executed_by_ref'),\n executionMs: integer('execution_ms'),\n error: text('error'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n executedAt: integer('executed_at', { mode: 'timestamp_ms' }),\n});\n\n/** A token-usage ledger row, summed per actor per day by `quotaToday`. */\nexport const agentTokenUsage = sqliteTable(\n 'agent_token_usage',\n {\n id: text('id').primaryKey(),\n threadId: text('thread_id')\n .notNull()\n .references(() => agentThread.id, { onDelete: 'cascade' }),\n actorRef: text('actor_ref').notNull(),\n messageId: text('message_id'),\n modelId: text('model_id').notNull(),\n purpose: text('purpose').$type<UsagePurpose>().notNull(),\n inputTokens: integer('input_tokens').notNull(),\n outputTokens: integer('output_tokens').notNull(),\n /** Subset of `inputTokens` written to the prompt cache this turn; null when not reported. */\n cacheWriteTokens: integer('cache_write_tokens'),\n /** Subset of `inputTokens` served from the prompt cache this turn; null when not reported. */\n cacheReadTokens: integer('cache_read_tokens'),\n /** Provider-reported actual USD cost for the turn; null when only tokens were reported. */\n costUsd: real('cost_usd'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n },\n (table) => [index('agent_token_usage_actor_created_idx').on(table.actorRef, table.createdAt)],\n);\n\n/** Per-model token pricing, versioned by `effectiveFrom`; `isCurrent` flags the live row. */\nexport const agentModelPricing = sqliteTable('agent_model_pricing', {\n id: text('id').primaryKey(),\n modelId: text('model_id').notNull(),\n inputPricePer1m: real('input_price_per_1m').notNull(),\n outputPricePer1m: real('output_price_per_1m').notNull(),\n /** Per-1M price for cache-write input tokens; null → price them at the input rate. */\n cacheWritePricePer1m: real('cache_write_price_per_1m'),\n /** Per-1M price for cache-read input tokens; null → price them at the input rate. */\n cacheReadPricePer1m: real('cache_read_price_per_1m'),\n effectiveFrom: integer('effective_from', { mode: 'timestamp_ms' }).notNull(),\n isCurrent: integer('is_current', { mode: 'boolean' }).notNull(),\n});\n\n/** The five agent tables as one schema object, ready for `drizzle(client, { schema })`. */\nexport const agentSchema = {\n agentThread,\n agentMessage,\n agentToolCall,\n agentTokenUsage,\n agentModelPricing,\n};\n\n/**\n * The dialect-portable Drizzle SQLite database handle the store operates on. Accepts any SQLite\n * driver (better-sqlite3, libsql, D1, …) in either sync or async result mode; the host app owns\n * the connection and passes the `drizzle(...)` instance in.\n */\nexport type AgentDrizzleDb = BaseSQLiteDatabase<'sync' | 'async', unknown>;\n\n/** A persisted thread row as Drizzle selects it. */\nexport type AgentThreadRow = typeof agentThread.$inferSelect;\n/** A persisted message row as Drizzle selects it. */\nexport type AgentMessageRow = typeof agentMessage.$inferSelect;\n","import { sql } from 'drizzle-orm';\nimport type { AgentDrizzleDb } from './schema.js';\n\n/**\n * Idempotent `CREATE TABLE IF NOT EXISTS` DDL for the five agent tables, mirroring\n * {@link import('./schema.js').agentSchema}. SQLite dialect (the db-test driver); kept here rather\n * than relying on drizzle-kit so the package can stand up its schema with no migration files. Safe\n * to run on boot against a shared database — it never drops or alters existing columns.\n */\nconst statements: string[] = [\n `CREATE TABLE IF NOT EXISTS agent_thread (\n id TEXT PRIMARY KEY NOT NULL,\n actor_ref TEXT NOT NULL,\n tenant_ref TEXT,\n title TEXT NOT NULL,\n persona TEXT NOT NULL DEFAULT 'default',\n transient INTEGER NOT NULL DEFAULT 0,\n active_stream_id TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n deleted_at INTEGER\n )`,\n `CREATE INDEX IF NOT EXISTS agent_thread_actor_updated_idx\n ON agent_thread (actor_ref, updated_at)`,\n `CREATE TABLE IF NOT EXISTS agent_message (\n id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL REFERENCES agent_thread(id) ON DELETE CASCADE,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n tool_calls TEXT,\n tool_results TEXT,\n follow_ups TEXT,\n usage TEXT,\n persona TEXT,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS agent_message_thread_created_idx\n ON agent_message (thread_id, created_at)`,\n `CREATE TABLE IF NOT EXISTS agent_tool_call (\n id TEXT PRIMARY KEY NOT NULL,\n message_id TEXT NOT NULL REFERENCES agent_message(id) ON DELETE CASCADE,\n tool_name TEXT NOT NULL,\n tool_type TEXT NOT NULL,\n input TEXT,\n output TEXT,\n status TEXT NOT NULL,\n executed_by_ref TEXT,\n execution_ms INTEGER,\n error TEXT,\n created_at INTEGER NOT NULL,\n executed_at INTEGER\n )`,\n `CREATE TABLE IF NOT EXISTS agent_token_usage (\n id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL REFERENCES agent_thread(id) ON DELETE CASCADE,\n actor_ref TEXT NOT NULL,\n message_id TEXT,\n model_id TEXT NOT NULL,\n purpose TEXT NOT NULL,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n cache_write_tokens INTEGER,\n cache_read_tokens INTEGER,\n cost_usd REAL,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS agent_token_usage_actor_created_idx\n ON agent_token_usage (actor_ref, created_at)`,\n `CREATE TABLE IF NOT EXISTS agent_model_pricing (\n id TEXT PRIMARY KEY NOT NULL,\n model_id TEXT NOT NULL,\n input_price_per_1m REAL NOT NULL,\n output_price_per_1m REAL NOT NULL,\n cache_write_price_per_1m REAL,\n cache_read_price_per_1m REAL,\n effective_from INTEGER NOT NULL,\n is_current INTEGER NOT NULL\n )`,\n];\n\n/** Runs the `CREATE TABLE IF NOT EXISTS` DDL above against the supplied Drizzle SQLite db. */\nexport async function ensureAgentSchema(db: AgentDrizzleDb): Promise<void> {\n for (const statement of statements) {\n await db.run(sql.raw(statement));\n }\n}\n","import type {\n AgentStore,\n AppendMessageInput,\n CreateThreadInput,\n RecordToolCallInput,\n RecordUsageInput,\n StoredMessage,\n ThreadDetail,\n ThreadSummary,\n UpdateToolCallInput,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, asc, desc, eq, gte, inArray, isNull, lte } from 'drizzle-orm';\nimport {\n type AgentDrizzleDb,\n type AgentMessageRow,\n type AgentThreadRow,\n agentMessage,\n agentThread,\n agentTokenUsage,\n agentToolCall,\n} from './schema.js';\n\n/**\n * {@link AgentStore} backed by Drizzle ORM — a second adapter alongside the MikroORM one, proving\n * the store SPI is ORM-portable. A POJO receiving a Drizzle SQLite database handle (the host app\n * owns the connection). Behaviour mirrors {@link import('@dudousxd/nestjs-agent-store-mikro-orm')}\n * exactly (fork/truncate/quota/active-stream/soft-delete semantics) so the two are interchangeable.\n */\nexport class DrizzleAgentStore implements AgentStore {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n async createThread(input: CreateThreadInput): Promise<ThreadSummary> {\n const now = new Date();\n const thread: AgentThreadRow = {\n id: crypto.randomUUID(),\n actorRef: input.actor.id,\n tenantRef: input.actor.tenantRef ?? null,\n title: input.title ?? 'New chat',\n persona: input.persona,\n transient: input.transient ?? false,\n activeStreamId: null,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n };\n await this.db.insert(agentThread).values(thread);\n return this.toSummary(thread);\n }\n\n async getThread(threadId: string): Promise<ThreadDetail | null> {\n const [thread] = await this.db\n .select()\n .from(agentThread)\n .where(and(eq(agentThread.id, threadId), isNull(agentThread.deletedAt)));\n if (thread === undefined) {\n return null;\n }\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const last = messages[messages.length - 1];\n return {\n ...this.toSummary(thread, last?.content),\n messages: messages.map((message) => this.toStoredMessage(message)),\n ...(thread.activeStreamId != null ? { activeStreamId: thread.activeStreamId } : {}),\n };\n }\n\n async listThreads(actorRef: string, limit = 50): Promise<ThreadSummary[]> {\n const threads = await this.db\n .select()\n .from(agentThread)\n .where(\n and(\n eq(agentThread.actorRef, actorRef),\n eq(agentThread.transient, false),\n isNull(agentThread.deletedAt),\n ),\n )\n .orderBy(desc(agentThread.updatedAt))\n .limit(limit);\n const summaries: ThreadSummary[] = [];\n for (const thread of threads) {\n const [last] = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, thread.id))\n .orderBy(desc(agentMessage.createdAt), desc(agentMessage.id))\n .limit(1);\n summaries.push(this.toSummary(thread, last?.content));\n }\n return summaries;\n }\n\n async softDeleteThread(threadId: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ deletedAt: new Date() })\n .where(eq(agentThread.id, threadId));\n }\n\n async forkThread(threadId: string, fromMessageId: string): Promise<ThreadSummary> {\n const [source] = await this.db.select().from(agentThread).where(eq(agentThread.id, threadId));\n if (source === undefined) {\n throw new Error(`thread ${threadId} not found`);\n }\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const cutoff = messages.findIndex((message) => message.id === fromMessageId);\n const kept = cutoff >= 0 ? messages.slice(0, cutoff + 1) : messages;\n const now = new Date();\n const fork: AgentThreadRow = {\n id: crypto.randomUUID(),\n actorRef: source.actorRef,\n tenantRef: source.tenantRef,\n title: source.title,\n persona: source.persona,\n transient: false,\n activeStreamId: null,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n };\n await this.db.insert(agentThread).values(fork);\n if (kept.length > 0) {\n await this.db.insert(agentMessage).values(\n kept.map((message) => ({\n id: crypto.randomUUID(),\n threadId: fork.id,\n role: message.role,\n content: message.content,\n toolCalls: message.toolCalls,\n toolResults: message.toolResults,\n followUps: message.followUps,\n usage: message.usage,\n persona: message.persona,\n createdAt: message.createdAt,\n })),\n );\n }\n return this.toSummary(fork);\n }\n\n async ownerOfThread(threadId: string): Promise<string | null> {\n const [thread] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentThread)\n .where(and(eq(agentThread.id, threadId), isNull(agentThread.deletedAt)));\n return thread?.actorRef ?? null;\n }\n\n async ownerOfToolCall(toolCallId: string): Promise<string | null> {\n const [row] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .innerJoin(agentThread, eq(agentMessage.threadId, agentThread.id))\n .where(eq(agentToolCall.id, toolCallId));\n return row?.actorRef ?? null;\n }\n\n async runForToolCall(toolCallId: string): Promise<string | null> {\n const [row] = await this.db\n .select({ activeStreamId: agentThread.activeStreamId })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .innerJoin(agentThread, eq(agentMessage.threadId, agentThread.id))\n .where(eq(agentToolCall.id, toolCallId));\n return row?.activeStreamId ?? null;\n }\n\n async ownerOfActiveStream(runId: string): Promise<string | null> {\n const [thread] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentThread)\n .where(and(eq(agentThread.activeStreamId, runId), isNull(agentThread.deletedAt)));\n return thread?.actorRef ?? null;\n }\n\n async setTitle(threadId: string, title: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ title, updatedAt: new Date() })\n .where(eq(agentThread.id, threadId));\n }\n\n async setActiveStream(threadId: string, runId: string | null): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ activeStreamId: runId })\n .where(eq(agentThread.id, threadId));\n }\n\n async appendMessage(input: AppendMessageInput): Promise<StoredMessage> {\n const [thread] = await this.db\n .select()\n .from(agentThread)\n .where(eq(agentThread.id, input.threadId));\n if (thread === undefined) {\n throw new Error(`thread ${input.threadId} not found`);\n }\n const now = new Date();\n const message: AgentMessageRow = {\n id: crypto.randomUUID(),\n threadId: input.threadId,\n role: input.role,\n content: input.content,\n toolCalls: input.toolCalls ?? null,\n toolResults: input.toolResults ?? null,\n followUps: input.followUps ?? null,\n usage: input.usage ?? null,\n persona: input.persona ?? null,\n createdAt: now,\n };\n await this.db.insert(agentMessage).values(message);\n await this.db\n .update(agentThread)\n .set({ updatedAt: now })\n .where(eq(agentThread.id, input.threadId));\n return this.toStoredMessage(message);\n }\n\n async truncateFrom(threadId: string, messageId: string): Promise<void> {\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const cutoff = messages.findIndex((message) => message.id === messageId);\n if (cutoff < 0) {\n return;\n }\n const doomedIds = messages.slice(cutoff).map((message) => message.id);\n await this.db.delete(agentToolCall).where(inArray(agentToolCall.messageId, doomedIds));\n await this.db.delete(agentMessage).where(inArray(agentMessage.id, doomedIds));\n }\n\n async recordToolCall(input: RecordToolCallInput): Promise<void> {\n await this.db.insert(agentToolCall).values({\n id: input.toolCallId,\n messageId: input.messageId,\n toolName: input.toolName,\n toolType: input.toolType,\n input: input.input,\n output: null,\n status: input.status,\n executedByRef: null,\n executionMs: null,\n error: null,\n createdAt: new Date(),\n executedAt: null,\n });\n }\n\n async updateToolCall(input: UpdateToolCallInput): Promise<void> {\n const updates: Partial<typeof agentToolCall.$inferInsert> = { status: input.status };\n if (input.output !== undefined) {\n updates.output = input.output;\n }\n if (input.error !== undefined) {\n updates.error = input.error;\n }\n if (input.executionMs !== undefined) {\n updates.executionMs = input.executionMs;\n }\n if (input.executedByRef !== undefined) {\n updates.executedByRef = input.executedByRef;\n }\n if (input.status === 'executed' || input.status === 'auto_executed') {\n updates.executedAt = new Date();\n }\n await this.db.update(agentToolCall).set(updates).where(eq(agentToolCall.id, input.toolCallId));\n }\n\n async recordUsage(input: RecordUsageInput): Promise<void> {\n await this.db.insert(agentTokenUsage).values({\n id: crypto.randomUUID(),\n threadId: input.threadId,\n actorRef: input.actorRef,\n messageId: input.messageId ?? null,\n modelId: input.modelId,\n purpose: input.purpose,\n inputTokens: input.usage.inputTokens,\n outputTokens: input.usage.outputTokens,\n cacheWriteTokens: input.usage.cacheWriteTokens ?? null,\n cacheReadTokens: input.usage.cacheReadTokens ?? null,\n costUsd: input.costUsd ?? null,\n createdAt: new Date(),\n });\n }\n\n async quotaToday(actorRef: string, day: string): Promise<{ usedTokens: number }> {\n const start = new Date(`${day}T00:00:00.000Z`);\n const end = new Date(`${day}T23:59:59.999Z`);\n const rows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(\n and(\n eq(agentTokenUsage.actorRef, actorRef),\n gte(agentTokenUsage.createdAt, start),\n lte(agentTokenUsage.createdAt, end),\n ),\n );\n const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);\n return { usedTokens };\n }\n\n private toSummary(thread: AgentThreadRow, lastContent?: string): ThreadSummary {\n return {\n id: thread.id,\n title: thread.title,\n persona: thread.persona,\n transient: thread.transient,\n createdAt: thread.createdAt.toISOString(),\n updatedAt: thread.updatedAt.toISOString(),\n ...(lastContent !== undefined ? { lastMessagePreview: lastContent.slice(0, 120) } : {}),\n };\n }\n\n private toStoredMessage(message: AgentMessageRow): StoredMessage {\n return {\n id: message.id,\n role: message.role,\n content: message.content,\n createdAt: message.createdAt.toISOString(),\n ...(message.toolCalls != null ? { toolCalls: message.toolCalls } : {}),\n ...(message.toolResults != null ? { toolResults: message.toolResults } : {}),\n ...(message.followUps != null ? { followUps: message.followUps } : {}),\n ...(message.usage != null ? { usage: message.usage } : {}),\n };\n }\n}\n","import type {\n ActorSpendRow,\n AgentGovernanceQueries,\n GovernanceRange,\n ModelSpendRow,\n ThreadActivityRow,\n ToolCallActivityRow,\n UsageTrendPoint,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, count, desc, eq, gte, isNull, lte } from 'drizzle-orm';\nimport {\n type AgentDrizzleDb,\n agentMessage,\n agentModelPricing,\n agentThread,\n agentTokenUsage,\n agentToolCall,\n} from './schema.js';\n\n/** The current per-1M token prices for one model; cache rates fall back to the input rate. */\ninterface ModelPrice {\n inputPricePer1m: number;\n outputPricePer1m: number;\n cacheWritePricePer1m?: number | null;\n cacheReadPricePer1m?: number | null;\n}\n\n/**\n * Token-ledger estimate for one usage row against the current pricing row: the uncached input at the\n * input rate, cache-write/cache-read tokens at their own rates (falling back to the input rate when\n * unpriced), plus output at the output rate. An unpriced model contributes 0 (tokens still count).\n * Cache token counts are subsets of `inputTokens`, so the uncached remainder is the difference.\n */\nfunction estimateFromTokens(\n pricing: Map<string, ModelPrice>,\n row: typeof agentTokenUsage.$inferSelect,\n): number {\n const price = pricing.get(row.modelId);\n if (price === undefined) {\n return 0;\n }\n const cacheWriteTokens = row.cacheWriteTokens ?? 0;\n const cacheReadTokens = row.cacheReadTokens ?? 0;\n const uncachedInputTokens = row.inputTokens - cacheWriteTokens - cacheReadTokens;\n return (\n (uncachedInputTokens / 1_000_000) * price.inputPricePer1m +\n (cacheWriteTokens / 1_000_000) * (price.cacheWritePricePer1m ?? price.inputPricePer1m) +\n (cacheReadTokens / 1_000_000) * (price.cacheReadPricePer1m ?? price.inputPricePer1m) +\n (row.outputTokens / 1_000_000) * price.outputPricePer1m\n );\n}\n\n/**\n * The cost of one usage row: the provider-reported `costUsd` when present (gateways report real\n * spend), otherwise the cache-aware token estimate against the current pricing row.\n */\nfunction rowCost(\n pricing: Map<string, ModelPrice>,\n row: typeof agentTokenUsage.$inferSelect,\n): number {\n return row.costUsd ?? estimateFromTokens(pricing, row);\n}\n\n/** Turns an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used by `quotaToday`. */\nfunction dayBounds(range: GovernanceRange): { start: Date; end: Date } {\n return {\n start: new Date(`${range.fromDay}T00:00:00.000Z`),\n end: new Date(`${range.toDay}T23:59:59.999Z`),\n };\n}\n\n/**\n * {@link AgentGovernanceQueries} backed by Drizzle ORM — the read/analytics half of the store SPI,\n * mirroring {@link import('@dudousxd/nestjs-agent-store-mikro-orm')} exactly. Cost is the token\n * ledger joined to the current pricing row per model (`agentModelPricing.isCurrent`); an unpriced\n * model contributes 0 cost. Aggregation is in-process (like `quotaToday`) so day-bucketing stays\n * dialect-portable.\n */\nexport class DrizzleGovernanceQueries implements AgentGovernanceQueries {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n private async loadPricing(): Promise<Map<string, ModelPrice>> {\n const rows = await this.db\n .select()\n .from(agentModelPricing)\n .where(eq(agentModelPricing.isCurrent, true));\n const pricing = new Map<string, ModelPrice>();\n for (const row of rows) {\n pricing.set(row.modelId, {\n inputPricePer1m: row.inputPricePer1m,\n outputPricePer1m: row.outputPricePer1m,\n cacheWritePricePer1m: row.cacheWritePricePer1m,\n cacheReadPricePer1m: row.cacheReadPricePer1m,\n });\n }\n return pricing;\n }\n\n private async usageInRange(\n range: GovernanceRange,\n ): Promise<(typeof agentTokenUsage.$inferSelect)[]> {\n const { start, end } = dayBounds(range);\n const rows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(and(gte(agentTokenUsage.createdAt, start), lte(agentTokenUsage.createdAt, end)));\n return rows;\n }\n\n async spendByModel(range: GovernanceRange): Promise<ModelSpendRow[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byModel = new Map<\n string,\n { requests: number; inputTokens: number; outputTokens: number; costUsd: number }\n >();\n for (const row of rows) {\n const bucket = byModel.get(row.modelId) ?? {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n costUsd: 0,\n };\n bucket.requests += 1;\n bucket.inputTokens += row.inputTokens;\n bucket.outputTokens += row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byModel.set(row.modelId, bucket);\n }\n const result: ModelSpendRow[] = [];\n for (const [modelId, bucket] of byModel) {\n result.push({\n modelId,\n requests: bucket.requests,\n inputTokens: bucket.inputTokens,\n outputTokens: bucket.outputTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId),\n );\n return result;\n }\n\n async spendByActor(range: GovernanceRange): Promise<ActorSpendRow[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byActor = new Map<string, { requests: number; totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byActor.get(row.actorRef) ?? { requests: 0, totalTokens: 0, costUsd: 0 };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byActor.set(row.actorRef, bucket);\n }\n const result: ActorSpendRow[] = [];\n for (const [actorRef, bucket] of byActor) {\n result.push({\n actorRef,\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef),\n );\n return result;\n }\n\n async usageTrend(range: GovernanceRange): Promise<UsageTrendPoint[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byDay = new Map<string, { totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const day = row.createdAt.toISOString().slice(0, 10);\n const bucket = byDay.get(day) ?? { totalTokens: 0, costUsd: 0 };\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byDay.set(day, bucket);\n }\n const result: UsageTrendPoint[] = [];\n for (const [day, bucket] of byDay) {\n result.push({ day, totalTokens: bucket.totalTokens, costUsd: bucket.costUsd });\n }\n result.sort((left, right) => left.day.localeCompare(right.day));\n return result;\n }\n\n async recentToolCalls(limit: number): Promise<ToolCallActivityRow[]> {\n const rows = await this.db\n .select({\n toolCallId: agentToolCall.id,\n toolName: agentToolCall.toolName,\n toolType: agentToolCall.toolType,\n status: agentToolCall.status,\n threadId: agentMessage.threadId,\n createdAt: agentToolCall.createdAt,\n })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .orderBy(desc(agentToolCall.createdAt), desc(agentToolCall.id))\n .limit(limit);\n return rows.map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n toolType: row.toolType,\n status: row.status,\n threadId: row.threadId,\n createdAt: row.createdAt.toISOString(),\n }));\n }\n\n async recentThreads(limit: number): Promise<ThreadActivityRow[]> {\n const threads = await this.db\n .select()\n .from(agentThread)\n .where(isNull(agentThread.deletedAt))\n .orderBy(desc(agentThread.updatedAt), desc(agentThread.id))\n .limit(limit);\n const result: ThreadActivityRow[] = [];\n for (const thread of threads) {\n const [messageCountRow] = await this.db\n .select({ value: count() })\n .from(agentMessage)\n .where(eq(agentMessage.threadId, thread.id));\n const usageRows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(eq(agentTokenUsage.threadId, thread.id));\n const totalTokens = usageRows.reduce(\n (sum, row) => sum + row.inputTokens + row.outputTokens,\n 0,\n );\n result.push({\n threadId: thread.id,\n title: thread.title,\n actorRef: thread.actorRef,\n messageCount: messageCountRow?.value ?? 0,\n totalTokens,\n lastActivityAt: thread.updatedAt.toISOString(),\n });\n }\n return result;\n }\n}\n","import type {\n AgentPricingStore,\n CurrentModelPrice,\n ModelPriceInput,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, eq } from 'drizzle-orm';\nimport { type AgentDrizzleDb, agentModelPricing } from './schema.js';\n\n/**\n * {@link AgentPricingStore} backed by Drizzle ORM — the write side of the pricing table\n * {@link import('./drizzle-governance-queries.js').DrizzleGovernanceQueries} joins against. A POJO\n * receiving a Drizzle SQLite database handle (the host app owns the connection), mirroring\n * {@link import('@dudousxd/nestjs-agent-store-mikro-orm')} exactly (atomic supersede semantics).\n */\nexport class DrizzlePricingStore implements AgentPricingStore {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n async upsertModelPrice(input: ModelPriceInput): Promise<void> {\n await this.db\n .update(agentModelPricing)\n .set({ isCurrent: false })\n .where(\n and(eq(agentModelPricing.modelId, input.modelId), eq(agentModelPricing.isCurrent, true)),\n );\n await this.db.insert(agentModelPricing).values({\n id: crypto.randomUUID(),\n modelId: input.modelId,\n inputPricePer1m: input.inputPricePer1m,\n outputPricePer1m: input.outputPricePer1m,\n cacheWritePricePer1m: input.cacheWritePricePer1m ?? null,\n cacheReadPricePer1m: input.cacheReadPricePer1m ?? null,\n effectiveFrom: new Date(),\n isCurrent: true,\n });\n }\n\n async listCurrentPrices(): Promise<CurrentModelPrice[]> {\n const rows = await this.db\n .select()\n .from(agentModelPricing)\n .where(eq(agentModelPricing.isCurrent, true));\n return rows.map((row) => ({\n modelId: row.modelId,\n inputPricePer1m: row.inputPricePer1m,\n outputPricePer1m: row.outputPricePer1m,\n effectiveFrom: row.effectiveFrom.toISOString(),\n ...(row.cacheWritePricePer1m != null\n ? { cacheWritePricePer1m: row.cacheWritePricePer1m }\n : {}),\n ...(row.cacheReadPricePer1m != null ? { cacheReadPricePer1m: row.cacheReadPricePer1m } : {}),\n }));\n }\n}\n","import {\n AGENT_GOVERNANCE_QUERIES,\n AGENT_PRICING_STORE,\n AGENT_STORE,\n} from '@dudousxd/nestjs-agent-core';\nimport { type DynamicModule, Module } from '@nestjs/common';\nimport { DrizzleAgentStore } from './drizzle-agent-store.js';\nimport { DrizzleGovernanceQueries } from './drizzle-governance-queries.js';\nimport { DrizzlePricingStore } from './drizzle-pricing-store.js';\nimport type { AgentDrizzleDb } from './schema.js';\n\n/** Options for {@link DrizzleAgentStoreModule.forRoot}. The app owns and supplies the db handle. */\nexport interface DrizzleAgentStoreModuleOptions {\n /** A Drizzle SQLite database instance (`drizzle(client, { schema: agentSchema })`). */\n db: AgentDrizzleDb;\n}\n\n/**\n * Binds {@link DrizzleAgentStore} to the {@link AGENT_STORE} token consumed by\n * `@dudousxd/nestjs-agent`, plus {@link DrizzleGovernanceQueries} to\n * {@link AGENT_GOVERNANCE_QUERIES} (the read-model the dashboard/telescope surfaces consume) and\n * {@link DrizzlePricingStore} to {@link AGENT_PRICING_STORE} (the write side of that pricing table).\n * The host app supplies an already-opened Drizzle db — this module never opens a connection itself.\n *\n * The returned module is global, so {@link AGENT_STORE}, {@link AGENT_GOVERNANCE_QUERIES} and\n * {@link AGENT_PRICING_STORE} are visible app-wide — `AgentModule` resolves the store without an\n * explicit `store` option, and the dashboard/telescope resolve {@link AGENT_GOVERNANCE_QUERIES}\n * without the host re-binding it.\n *\n * ```ts\n * @Module({ imports: [DrizzleAgentStoreModule.forRoot({ db })] })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class DrizzleAgentStoreModule {\n static forRoot(options: DrizzleAgentStoreModuleOptions): DynamicModule {\n return {\n module: DrizzleAgentStoreModule,\n global: true,\n providers: [\n { provide: DrizzleAgentStore, useFactory: () => new DrizzleAgentStore(options.db) },\n { provide: AGENT_STORE, useExisting: DrizzleAgentStore },\n {\n provide: DrizzleGovernanceQueries,\n useFactory: () => new DrizzleGovernanceQueries(options.db),\n },\n { provide: AGENT_GOVERNANCE_QUERIES, useExisting: DrizzleGovernanceQueries },\n {\n provide: DrizzlePricingStore,\n useFactory: () => new DrizzlePricingStore(options.db),\n },\n { provide: AGENT_PRICING_STORE, useExisting: DrizzlePricingStore },\n ],\n exports: [\n DrizzleAgentStore,\n AGENT_STORE,\n DrizzleGovernanceQueries,\n AGENT_GOVERNANCE_QUERIES,\n DrizzlePricingStore,\n AGENT_PRICING_STORE,\n ],\n };\n }\n}\n"],"mappings":"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","names":["index","integer","real","sqliteTable","text","agentThread","id","primaryKey","actorRef","notNull","tenantRef","title","persona","default","transient","mode","activeStreamId","createdAt","updatedAt","deletedAt","table","on","agentMessage","threadId","references","onDelete","role","$type","content","toolCalls","toolResults","followUps","usage","agentToolCall","messageId","toolName","toolType","input","output","status","executedByRef","executionMs","error","executedAt","agentTokenUsage","modelId","purpose","inputTokens","outputTokens","cacheWriteTokens","cacheReadTokens","costUsd","agentModelPricing","inputPricePer1m","outputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","effectiveFrom","isCurrent","agentSchema","sql","statements","ensureAgentSchema","db","statement","run","sql","raw","and","asc","desc","eq","gte","inArray","isNull","lte","DrizzleAgentStore","db","createThread","input","now","Date","thread","id","crypto","randomUUID","actorRef","actor","tenantRef","title","persona","transient","activeStreamId","createdAt","updatedAt","deletedAt","insert","agentThread","values","toSummary","getThread","threadId","select","from","where","and","eq","isNull","undefined","messages","agentMessage","orderBy","asc","last","length","content","map","message","toStoredMessage","listThreads","limit","threads","desc","summaries","push","softDeleteThread","update","set","forkThread","fromMessageId","source","Error","cutoff","findIndex","kept","slice","fork","role","toolCalls","toolResults","followUps","usage","ownerOfThread","ownerOfToolCall","toolCallId","row","agentToolCall","innerJoin","messageId","runForToolCall","ownerOfActiveStream","runId","setTitle","setActiveStream","appendMessage","truncateFrom","doomedIds","delete","inArray","recordToolCall","toolName","toolType","output","status","executedByRef","executionMs","error","executedAt","updateToolCall","updates","recordUsage","agentTokenUsage","modelId","purpose","inputTokens","outputTokens","cacheWriteTokens","cacheReadTokens","costUsd","quotaToday","day","start","end","rows","gte","lte","usedTokens","reduce","sum","lastContent","toISOString","lastMessagePreview","and","count","desc","eq","gte","isNull","lte","estimateFromTokens","pricing","row","price","get","modelId","undefined","cacheWriteTokens","cacheReadTokens","uncachedInputTokens","inputTokens","inputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","outputTokens","outputPricePer1m","rowCost","costUsd","dayBounds","range","start","Date","fromDay","end","toDay","DrizzleGovernanceQueries","db","loadPricing","rows","select","from","agentModelPricing","where","eq","isCurrent","Map","set","usageInRange","agentTokenUsage","and","gte","createdAt","lte","spendByModel","byModel","bucket","requests","result","push","sort","left","right","localeCompare","spendByActor","byActor","actorRef","totalTokens","usageTrend","byDay","day","toISOString","slice","recentToolCalls","limit","toolCallId","agentToolCall","id","toolName","toolType","status","threadId","agentMessage","innerJoin","messageId","orderBy","desc","map","recentThreads","threads","agentThread","isNull","deletedAt","updatedAt","thread","messageCountRow","value","count","usageRows","reduce","sum","title","messageCount","lastActivityAt","and","eq","DrizzlePricingStore","db","upsertModelPrice","input","update","agentModelPricing","set","isCurrent","where","and","eq","modelId","insert","values","id","crypto","randomUUID","inputPricePer1m","outputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","effectiveFrom","Date","listCurrentPrices","rows","select","from","map","row","toISOString","AGENT_GOVERNANCE_QUERIES","AGENT_PRICING_STORE","AGENT_STORE","Module","DrizzleAgentStoreModule","forRoot","options","module","global","providers","provide","DrizzleAgentStore","useFactory","db","AGENT_STORE","useExisting","DrizzleGovernanceQueries","AGENT_GOVERNANCE_QUERIES","DrizzlePricingStore","AGENT_PRICING_STORE","exports"]}
1
+ {"version":3,"sources":["../src/schema.ts","../src/ensure-schema.ts","../src/drizzle-agent-store.ts","../src/drizzle-governance-queries.ts","../src/drizzle-pricing-store.ts","../src/drizzle-agent-store.module.ts"],"sourcesContent":["import type {\n MessageRole,\n MessageUsage,\n ToolCallRequest,\n ToolCallStatus,\n ToolKind,\n ToolResult,\n UsagePurpose,\n} from '@dudousxd/nestjs-agent-core';\nimport {\n type BaseSQLiteDatabase,\n index,\n integer,\n real,\n sqliteTable,\n text,\n} from 'drizzle-orm/sqlite-core';\n\n/**\n * Drizzle schema mirroring the MikroORM agent entities (same logical columns/relations):\n * threads, messages, tool calls, token usage and model pricing. Targets the SQLite core so the\n * db-test runs on an in-memory better-sqlite3; timestamps are stored as integer epoch-ms columns\n * (`{ mode: 'timestamp_ms' }`) which Drizzle round-trips to/from JS `Date`, and the model-facing\n * message extras (tool calls/results, follow-ups, usage) live in JSON `text` columns.\n */\n\n/**\n * A conversation thread. `deletedAt` drives soft delete: a deleted thread is hidden from\n * {@link import('./drizzle-agent-store.js').DrizzleAgentStore.getThread}/`listThreads` but its\n * row survives.\n */\nexport const agentThread = sqliteTable(\n 'agent_thread',\n {\n id: text('id').primaryKey(),\n actorRef: text('actor_ref').notNull(),\n tenantRef: text('tenant_ref'),\n title: text('title').notNull(),\n transient: integer('transient', { mode: 'boolean' }).notNull().default(false),\n activeStreamId: text('active_stream_id'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n updatedAt: integer('updated_at', { mode: 'timestamp_ms' }).notNull(),\n deletedAt: integer('deleted_at', { mode: 'timestamp_ms' }),\n },\n (table) => [index('agent_thread_actor_updated_idx').on(table.actorRef, table.updatedAt)],\n);\n\n/**\n * One stored message in a thread. The model-facing extras (`toolCalls`/`toolResults`/\n * `followUps`/`usage`) are folded into nullable JSON columns so a single row round-trips to a\n * {@link import('@dudousxd/nestjs-agent-core').StoredMessage}. `threadId` cascades on delete.\n */\nexport const agentMessage = sqliteTable(\n 'agent_message',\n {\n id: text('id').primaryKey(),\n threadId: text('thread_id')\n .notNull()\n .references(() => agentThread.id, { onDelete: 'cascade' }),\n role: text('role').$type<MessageRole>().notNull(),\n content: text('content').notNull(),\n toolCalls: text('tool_calls', { mode: 'json' }).$type<ToolCallRequest[]>(),\n toolResults: text('tool_results', { mode: 'json' }).$type<ToolResult[]>(),\n followUps: text('follow_ups', { mode: 'json' }).$type<string[]>(),\n usage: text('usage', { mode: 'json' }).$type<MessageUsage>(),\n agentName: text('agent_name'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n },\n (table) => [index('agent_message_thread_created_idx').on(table.threadId, table.createdAt)],\n);\n\n/** A tool call requested during an assistant turn. The pk is the model-supplied `toolCallId`. */\nexport const agentToolCall = sqliteTable('agent_tool_call', {\n id: text('id').primaryKey(),\n messageId: text('message_id')\n .notNull()\n .references(() => agentMessage.id, { onDelete: 'cascade' }),\n toolName: text('tool_name').notNull(),\n toolType: text('tool_type').$type<ToolKind>().notNull(),\n input: text('input', { mode: 'json' }),\n output: text('output', { mode: 'json' }),\n status: text('status').$type<ToolCallStatus>().notNull(),\n executedByRef: text('executed_by_ref'),\n executionMs: integer('execution_ms'),\n error: text('error'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n executedAt: integer('executed_at', { mode: 'timestamp_ms' }),\n});\n\n/** A token-usage ledger row, summed per actor per day by `quotaToday`. */\nexport const agentTokenUsage = sqliteTable(\n 'agent_token_usage',\n {\n id: text('id').primaryKey(),\n threadId: text('thread_id')\n .notNull()\n .references(() => agentThread.id, { onDelete: 'cascade' }),\n actorRef: text('actor_ref').notNull(),\n messageId: text('message_id'),\n modelId: text('model_id').notNull(),\n purpose: text('purpose').$type<UsagePurpose>().notNull(),\n inputTokens: integer('input_tokens').notNull(),\n outputTokens: integer('output_tokens').notNull(),\n /** Subset of `inputTokens` written to the prompt cache this turn; null when not reported. */\n cacheWriteTokens: integer('cache_write_tokens'),\n /** Subset of `inputTokens` served from the prompt cache this turn; null when not reported. */\n cacheReadTokens: integer('cache_read_tokens'),\n /** Provider-reported actual USD cost for the turn; null when only tokens were reported. */\n costUsd: real('cost_usd'),\n createdAt: integer('created_at', { mode: 'timestamp_ms' }).notNull(),\n },\n (table) => [index('agent_token_usage_actor_created_idx').on(table.actorRef, table.createdAt)],\n);\n\n/** Per-model token pricing, versioned by `effectiveFrom`; `isCurrent` flags the live row. */\nexport const agentModelPricing = sqliteTable('agent_model_pricing', {\n id: text('id').primaryKey(),\n modelId: text('model_id').notNull(),\n inputPricePer1m: real('input_price_per_1m').notNull(),\n outputPricePer1m: real('output_price_per_1m').notNull(),\n /** Per-1M price for cache-write input tokens; null → price them at the input rate. */\n cacheWritePricePer1m: real('cache_write_price_per_1m'),\n /** Per-1M price for cache-read input tokens; null → price them at the input rate. */\n cacheReadPricePer1m: real('cache_read_price_per_1m'),\n effectiveFrom: integer('effective_from', { mode: 'timestamp_ms' }).notNull(),\n isCurrent: integer('is_current', { mode: 'boolean' }).notNull(),\n});\n\n/** The five agent tables as one schema object, ready for `drizzle(client, { schema })`. */\nexport const agentSchema = {\n agentThread,\n agentMessage,\n agentToolCall,\n agentTokenUsage,\n agentModelPricing,\n};\n\n/**\n * The dialect-portable Drizzle SQLite database handle the store operates on. Accepts any SQLite\n * driver (better-sqlite3, libsql, D1, …) in either sync or async result mode; the host app owns\n * the connection and passes the `drizzle(...)` instance in.\n */\nexport type AgentDrizzleDb = BaseSQLiteDatabase<'sync' | 'async', unknown>;\n\n/** A persisted thread row as Drizzle selects it. */\nexport type AgentThreadRow = typeof agentThread.$inferSelect;\n/** A persisted message row as Drizzle selects it. */\nexport type AgentMessageRow = typeof agentMessage.$inferSelect;\n","import { sql } from 'drizzle-orm';\nimport type { AgentDrizzleDb } from './schema.js';\n\n/**\n * Idempotent `CREATE TABLE IF NOT EXISTS` DDL for the five agent tables, mirroring\n * {@link import('./schema.js').agentSchema}. SQLite dialect (the db-test driver); kept here rather\n * than relying on drizzle-kit so the package can stand up its schema with no migration files. Safe\n * to run on boot against a shared database — it never drops or alters existing columns.\n */\nconst statements: string[] = [\n `CREATE TABLE IF NOT EXISTS agent_thread (\n id TEXT PRIMARY KEY NOT NULL,\n actor_ref TEXT NOT NULL,\n tenant_ref TEXT,\n title TEXT NOT NULL,\n transient INTEGER NOT NULL DEFAULT 0,\n active_stream_id TEXT,\n created_at INTEGER NOT NULL,\n updated_at INTEGER NOT NULL,\n deleted_at INTEGER\n )`,\n `CREATE INDEX IF NOT EXISTS agent_thread_actor_updated_idx\n ON agent_thread (actor_ref, updated_at)`,\n `CREATE TABLE IF NOT EXISTS agent_message (\n id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL REFERENCES agent_thread(id) ON DELETE CASCADE,\n role TEXT NOT NULL,\n content TEXT NOT NULL,\n tool_calls TEXT,\n tool_results TEXT,\n follow_ups TEXT,\n usage TEXT,\n agent_name TEXT,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS agent_message_thread_created_idx\n ON agent_message (thread_id, created_at)`,\n `CREATE TABLE IF NOT EXISTS agent_tool_call (\n id TEXT PRIMARY KEY NOT NULL,\n message_id TEXT NOT NULL REFERENCES agent_message(id) ON DELETE CASCADE,\n tool_name TEXT NOT NULL,\n tool_type TEXT NOT NULL,\n input TEXT,\n output TEXT,\n status TEXT NOT NULL,\n executed_by_ref TEXT,\n execution_ms INTEGER,\n error TEXT,\n created_at INTEGER NOT NULL,\n executed_at INTEGER\n )`,\n `CREATE TABLE IF NOT EXISTS agent_token_usage (\n id TEXT PRIMARY KEY NOT NULL,\n thread_id TEXT NOT NULL REFERENCES agent_thread(id) ON DELETE CASCADE,\n actor_ref TEXT NOT NULL,\n message_id TEXT,\n model_id TEXT NOT NULL,\n purpose TEXT NOT NULL,\n input_tokens INTEGER NOT NULL,\n output_tokens INTEGER NOT NULL,\n cache_write_tokens INTEGER,\n cache_read_tokens INTEGER,\n cost_usd REAL,\n created_at INTEGER NOT NULL\n )`,\n `CREATE INDEX IF NOT EXISTS agent_token_usage_actor_created_idx\n ON agent_token_usage (actor_ref, created_at)`,\n `CREATE TABLE IF NOT EXISTS agent_model_pricing (\n id TEXT PRIMARY KEY NOT NULL,\n model_id TEXT NOT NULL,\n input_price_per_1m REAL NOT NULL,\n output_price_per_1m REAL NOT NULL,\n cache_write_price_per_1m REAL,\n cache_read_price_per_1m REAL,\n effective_from INTEGER NOT NULL,\n is_current INTEGER NOT NULL\n )`,\n];\n\n/** Runs the `CREATE TABLE IF NOT EXISTS` DDL above against the supplied Drizzle SQLite db. */\nexport async function ensureAgentSchema(db: AgentDrizzleDb): Promise<void> {\n for (const statement of statements) {\n await db.run(sql.raw(statement));\n }\n}\n","import type {\n AgentStore,\n AppendMessageInput,\n CreateThreadInput,\n RecordToolCallInput,\n RecordUsageInput,\n StoredMessage,\n ThreadDetail,\n ThreadSummary,\n UpdateToolCallInput,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, asc, desc, eq, gte, inArray, isNull, lte } from 'drizzle-orm';\nimport {\n type AgentDrizzleDb,\n type AgentMessageRow,\n type AgentThreadRow,\n agentMessage,\n agentThread,\n agentTokenUsage,\n agentToolCall,\n} from './schema.js';\n\n/**\n * {@link AgentStore} backed by Drizzle ORM — a second adapter alongside the MikroORM one, proving\n * the store SPI is ORM-portable. A POJO receiving a Drizzle SQLite database handle (the host app\n * owns the connection). Behaviour mirrors {@link import('@dudousxd/nestjs-agent-store-mikro-orm')}\n * exactly (fork/truncate/quota/active-stream/soft-delete semantics) so the two are interchangeable.\n */\nexport class DrizzleAgentStore implements AgentStore {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n async createThread(input: CreateThreadInput): Promise<ThreadSummary> {\n const now = new Date();\n const thread: AgentThreadRow = {\n id: crypto.randomUUID(),\n actorRef: input.actor.id,\n tenantRef: input.actor.tenantRef ?? null,\n title: input.title ?? 'New chat',\n transient: input.transient ?? false,\n activeStreamId: null,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n };\n await this.db.insert(agentThread).values(thread);\n return this.toSummary(thread);\n }\n\n async getThread(threadId: string): Promise<ThreadDetail | null> {\n const [thread] = await this.db\n .select()\n .from(agentThread)\n .where(and(eq(agentThread.id, threadId), isNull(agentThread.deletedAt)));\n if (thread === undefined) {\n return null;\n }\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const last = messages[messages.length - 1];\n return {\n ...this.toSummary(thread, last?.content),\n messages: messages.map((message) => this.toStoredMessage(message)),\n ...(thread.activeStreamId != null ? { activeStreamId: thread.activeStreamId } : {}),\n };\n }\n\n async listThreads(actorRef: string, limit = 50): Promise<ThreadSummary[]> {\n const threads = await this.db\n .select()\n .from(agentThread)\n .where(\n and(\n eq(agentThread.actorRef, actorRef),\n eq(agentThread.transient, false),\n isNull(agentThread.deletedAt),\n ),\n )\n .orderBy(desc(agentThread.updatedAt))\n .limit(limit);\n const summaries: ThreadSummary[] = [];\n for (const thread of threads) {\n const [last] = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, thread.id))\n .orderBy(desc(agentMessage.createdAt), desc(agentMessage.id))\n .limit(1);\n summaries.push(this.toSummary(thread, last?.content));\n }\n return summaries;\n }\n\n async softDeleteThread(threadId: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ deletedAt: new Date() })\n .where(eq(agentThread.id, threadId));\n }\n\n async forkThread(threadId: string, fromMessageId: string): Promise<ThreadSummary> {\n const [source] = await this.db.select().from(agentThread).where(eq(agentThread.id, threadId));\n if (source === undefined) {\n throw new Error(`thread ${threadId} not found`);\n }\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const cutoff = messages.findIndex((message) => message.id === fromMessageId);\n const kept = cutoff >= 0 ? messages.slice(0, cutoff + 1) : messages;\n const now = new Date();\n const fork: AgentThreadRow = {\n id: crypto.randomUUID(),\n actorRef: source.actorRef,\n tenantRef: source.tenantRef,\n title: source.title,\n transient: false,\n activeStreamId: null,\n createdAt: now,\n updatedAt: now,\n deletedAt: null,\n };\n await this.db.insert(agentThread).values(fork);\n if (kept.length > 0) {\n await this.db.insert(agentMessage).values(\n kept.map((message) => ({\n id: crypto.randomUUID(),\n threadId: fork.id,\n role: message.role,\n content: message.content,\n toolCalls: message.toolCalls,\n toolResults: message.toolResults,\n followUps: message.followUps,\n usage: message.usage,\n agentName: message.agentName,\n createdAt: message.createdAt,\n })),\n );\n }\n return this.toSummary(fork);\n }\n\n async ownerOfThread(threadId: string): Promise<string | null> {\n const [thread] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentThread)\n .where(and(eq(agentThread.id, threadId), isNull(agentThread.deletedAt)));\n return thread?.actorRef ?? null;\n }\n\n async ownerOfToolCall(toolCallId: string): Promise<string | null> {\n const [row] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .innerJoin(agentThread, eq(agentMessage.threadId, agentThread.id))\n .where(eq(agentToolCall.id, toolCallId));\n return row?.actorRef ?? null;\n }\n\n async runForToolCall(toolCallId: string): Promise<string | null> {\n const [row] = await this.db\n .select({ activeStreamId: agentThread.activeStreamId })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .innerJoin(agentThread, eq(agentMessage.threadId, agentThread.id))\n .where(eq(agentToolCall.id, toolCallId));\n return row?.activeStreamId ?? null;\n }\n\n async ownerOfActiveStream(runId: string): Promise<string | null> {\n const [thread] = await this.db\n .select({ actorRef: agentThread.actorRef })\n .from(agentThread)\n .where(and(eq(agentThread.activeStreamId, runId), isNull(agentThread.deletedAt)));\n return thread?.actorRef ?? null;\n }\n\n async setTitle(threadId: string, title: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ title, updatedAt: new Date() })\n .where(eq(agentThread.id, threadId));\n }\n\n async promoteThread(threadId: string): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ transient: false, updatedAt: new Date() })\n .where(and(eq(agentThread.id, threadId), eq(agentThread.transient, true)));\n }\n\n async setActiveStream(threadId: string, runId: string | null): Promise<void> {\n await this.db\n .update(agentThread)\n .set({ activeStreamId: runId })\n .where(eq(agentThread.id, threadId));\n }\n\n async appendMessage(input: AppendMessageInput): Promise<StoredMessage> {\n const [thread] = await this.db\n .select()\n .from(agentThread)\n .where(eq(agentThread.id, input.threadId));\n if (thread === undefined) {\n throw new Error(`thread ${input.threadId} not found`);\n }\n const now = new Date();\n const message: AgentMessageRow = {\n id: crypto.randomUUID(),\n threadId: input.threadId,\n role: input.role,\n content: input.content,\n toolCalls: input.toolCalls ?? null,\n toolResults: input.toolResults ?? null,\n followUps: input.followUps ?? null,\n usage: input.usage ?? null,\n agentName: input.agentName ?? null,\n createdAt: now,\n };\n await this.db.insert(agentMessage).values(message);\n await this.db\n .update(agentThread)\n .set({ updatedAt: now })\n .where(eq(agentThread.id, input.threadId));\n return this.toStoredMessage(message);\n }\n\n async truncateFrom(threadId: string, messageId: string): Promise<void> {\n const messages = await this.db\n .select()\n .from(agentMessage)\n .where(eq(agentMessage.threadId, threadId))\n .orderBy(asc(agentMessage.createdAt), asc(agentMessage.id));\n const cutoff = messages.findIndex((message) => message.id === messageId);\n if (cutoff < 0) {\n return;\n }\n const doomedIds = messages.slice(cutoff).map((message) => message.id);\n await this.db.delete(agentToolCall).where(inArray(agentToolCall.messageId, doomedIds));\n await this.db.delete(agentMessage).where(inArray(agentMessage.id, doomedIds));\n }\n\n async recordToolCall(input: RecordToolCallInput): Promise<void> {\n await this.db.insert(agentToolCall).values({\n id: input.toolCallId,\n messageId: input.messageId,\n toolName: input.toolName,\n toolType: input.toolType,\n input: input.input,\n output: null,\n status: input.status,\n executedByRef: null,\n executionMs: null,\n error: null,\n createdAt: new Date(),\n executedAt: null,\n });\n }\n\n async updateToolCall(input: UpdateToolCallInput): Promise<void> {\n const updates: Partial<typeof agentToolCall.$inferInsert> = { status: input.status };\n if (input.output !== undefined) {\n updates.output = input.output;\n }\n if (input.error !== undefined) {\n updates.error = input.error;\n }\n if (input.executionMs !== undefined) {\n updates.executionMs = input.executionMs;\n }\n if (input.executedByRef !== undefined) {\n updates.executedByRef = input.executedByRef;\n }\n if (input.status === 'executed' || input.status === 'auto_executed') {\n updates.executedAt = new Date();\n }\n await this.db.update(agentToolCall).set(updates).where(eq(agentToolCall.id, input.toolCallId));\n }\n\n async recordUsage(input: RecordUsageInput): Promise<void> {\n await this.db.insert(agentTokenUsage).values({\n id: crypto.randomUUID(),\n threadId: input.threadId,\n actorRef: input.actorRef,\n messageId: input.messageId ?? null,\n modelId: input.modelId,\n purpose: input.purpose,\n inputTokens: input.usage.inputTokens,\n outputTokens: input.usage.outputTokens,\n cacheWriteTokens: input.usage.cacheWriteTokens ?? null,\n cacheReadTokens: input.usage.cacheReadTokens ?? null,\n costUsd: input.costUsd ?? null,\n createdAt: new Date(),\n });\n }\n\n async quotaToday(\n actorRef: string,\n day: string,\n ): Promise<{ usedTokens: number; costUsd: number }> {\n const start = new Date(`${day}T00:00:00.000Z`);\n const end = new Date(`${day}T23:59:59.999Z`);\n const rows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(\n and(\n eq(agentTokenUsage.actorRef, actorRef),\n gte(agentTokenUsage.createdAt, start),\n lte(agentTokenUsage.createdAt, end),\n ),\n );\n const usedTokens = rows.reduce((sum, row) => sum + row.inputTokens + row.outputTokens, 0);\n const costUsd = rows.reduce((sum, row) => sum + (row.costUsd ?? 0), 0);\n return { usedTokens, costUsd };\n }\n\n private toSummary(thread: AgentThreadRow, lastContent?: string): ThreadSummary {\n return {\n id: thread.id,\n title: thread.title,\n transient: thread.transient,\n createdAt: thread.createdAt.toISOString(),\n updatedAt: thread.updatedAt.toISOString(),\n ...(lastContent !== undefined ? { lastMessagePreview: lastContent.slice(0, 120) } : {}),\n };\n }\n\n private toStoredMessage(message: AgentMessageRow): StoredMessage {\n return {\n id: message.id,\n role: message.role,\n content: message.content,\n createdAt: message.createdAt.toISOString(),\n ...(message.toolCalls != null ? { toolCalls: message.toolCalls } : {}),\n ...(message.toolResults != null ? { toolResults: message.toolResults } : {}),\n ...(message.followUps != null ? { followUps: message.followUps } : {}),\n ...(message.usage != null ? { usage: message.usage } : {}),\n ...(message.agentName != null ? { agentName: message.agentName } : {}),\n };\n }\n}\n","import type {\n ActorSpendRow,\n AgentGovernanceQueries,\n GovernanceRange,\n ModelSpendRow,\n ThreadActivityRow,\n ToolCallActivityRow,\n UsageTrendPoint,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, count, desc, eq, gte, isNull, lte } from 'drizzle-orm';\nimport {\n type AgentDrizzleDb,\n agentMessage,\n agentModelPricing,\n agentThread,\n agentTokenUsage,\n agentToolCall,\n} from './schema.js';\n\n/** The current per-1M token prices for one model; cache rates fall back to the input rate. */\ninterface ModelPrice {\n inputPricePer1m: number;\n outputPricePer1m: number;\n cacheWritePricePer1m?: number | null;\n cacheReadPricePer1m?: number | null;\n}\n\n/**\n * Token-ledger estimate for one usage row against the current pricing row: the uncached input at the\n * input rate, cache-write/cache-read tokens at their own rates (falling back to the input rate when\n * unpriced), plus output at the output rate. An unpriced model contributes 0 (tokens still count).\n * Cache token counts are subsets of `inputTokens`, so the uncached remainder is the difference.\n */\nfunction estimateFromTokens(\n pricing: Map<string, ModelPrice>,\n row: typeof agentTokenUsage.$inferSelect,\n): number {\n const price = pricing.get(row.modelId);\n if (price === undefined) {\n return 0;\n }\n const cacheWriteTokens = row.cacheWriteTokens ?? 0;\n const cacheReadTokens = row.cacheReadTokens ?? 0;\n const uncachedInputTokens = row.inputTokens - cacheWriteTokens - cacheReadTokens;\n return (\n (uncachedInputTokens / 1_000_000) * price.inputPricePer1m +\n (cacheWriteTokens / 1_000_000) * (price.cacheWritePricePer1m ?? price.inputPricePer1m) +\n (cacheReadTokens / 1_000_000) * (price.cacheReadPricePer1m ?? price.inputPricePer1m) +\n (row.outputTokens / 1_000_000) * price.outputPricePer1m\n );\n}\n\n/**\n * The cost of one usage row: the provider-reported `costUsd` when present (gateways report real\n * spend), otherwise the cache-aware token estimate against the current pricing row.\n */\nfunction rowCost(\n pricing: Map<string, ModelPrice>,\n row: typeof agentTokenUsage.$inferSelect,\n): number {\n return row.costUsd ?? estimateFromTokens(pricing, row);\n}\n\n/** Turns an inclusive `YYYY-MM-DD` day range into the UTC datetime bounds used by `quotaToday`. */\nfunction dayBounds(range: GovernanceRange): { start: Date; end: Date } {\n return {\n start: new Date(`${range.fromDay}T00:00:00.000Z`),\n end: new Date(`${range.toDay}T23:59:59.999Z`),\n };\n}\n\n/**\n * {@link AgentGovernanceQueries} backed by Drizzle ORM — the read/analytics half of the store SPI,\n * mirroring {@link import('@dudousxd/nestjs-agent-store-mikro-orm')} exactly. Cost is the token\n * ledger joined to the current pricing row per model (`agentModelPricing.isCurrent`); an unpriced\n * model contributes 0 cost. Aggregation is in-process (like `quotaToday`) so day-bucketing stays\n * dialect-portable.\n */\nexport class DrizzleGovernanceQueries implements AgentGovernanceQueries {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n private async loadPricing(): Promise<Map<string, ModelPrice>> {\n const rows = await this.db\n .select()\n .from(agentModelPricing)\n .where(eq(agentModelPricing.isCurrent, true));\n const pricing = new Map<string, ModelPrice>();\n for (const row of rows) {\n pricing.set(row.modelId, {\n inputPricePer1m: row.inputPricePer1m,\n outputPricePer1m: row.outputPricePer1m,\n cacheWritePricePer1m: row.cacheWritePricePer1m,\n cacheReadPricePer1m: row.cacheReadPricePer1m,\n });\n }\n return pricing;\n }\n\n private async usageInRange(\n range: GovernanceRange,\n ): Promise<(typeof agentTokenUsage.$inferSelect)[]> {\n const { start, end } = dayBounds(range);\n const rows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(and(gte(agentTokenUsage.createdAt, start), lte(agentTokenUsage.createdAt, end)));\n return rows;\n }\n\n async spendByModel(range: GovernanceRange): Promise<ModelSpendRow[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byModel = new Map<\n string,\n { requests: number; inputTokens: number; outputTokens: number; costUsd: number }\n >();\n for (const row of rows) {\n const bucket = byModel.get(row.modelId) ?? {\n requests: 0,\n inputTokens: 0,\n outputTokens: 0,\n costUsd: 0,\n };\n bucket.requests += 1;\n bucket.inputTokens += row.inputTokens;\n bucket.outputTokens += row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byModel.set(row.modelId, bucket);\n }\n const result: ModelSpendRow[] = [];\n for (const [modelId, bucket] of byModel) {\n result.push({\n modelId,\n requests: bucket.requests,\n inputTokens: bucket.inputTokens,\n outputTokens: bucket.outputTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.modelId.localeCompare(right.modelId),\n );\n return result;\n }\n\n async spendByActor(range: GovernanceRange): Promise<ActorSpendRow[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byActor = new Map<string, { requests: number; totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const bucket = byActor.get(row.actorRef) ?? { requests: 0, totalTokens: 0, costUsd: 0 };\n bucket.requests += 1;\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byActor.set(row.actorRef, bucket);\n }\n const result: ActorSpendRow[] = [];\n for (const [actorRef, bucket] of byActor) {\n result.push({\n actorRef,\n requests: bucket.requests,\n totalTokens: bucket.totalTokens,\n costUsd: bucket.costUsd,\n });\n }\n result.sort(\n (left, right) => right.costUsd - left.costUsd || left.actorRef.localeCompare(right.actorRef),\n );\n return result;\n }\n\n async usageTrend(range: GovernanceRange): Promise<UsageTrendPoint[]> {\n const pricing = await this.loadPricing();\n const rows = await this.usageInRange(range);\n const byDay = new Map<string, { totalTokens: number; costUsd: number }>();\n for (const row of rows) {\n const day = row.createdAt.toISOString().slice(0, 10);\n const bucket = byDay.get(day) ?? { totalTokens: 0, costUsd: 0 };\n bucket.totalTokens += row.inputTokens + row.outputTokens;\n bucket.costUsd += rowCost(pricing, row);\n byDay.set(day, bucket);\n }\n const result: UsageTrendPoint[] = [];\n for (const [day, bucket] of byDay) {\n result.push({ day, totalTokens: bucket.totalTokens, costUsd: bucket.costUsd });\n }\n result.sort((left, right) => left.day.localeCompare(right.day));\n return result;\n }\n\n async recentToolCalls(limit: number): Promise<ToolCallActivityRow[]> {\n const rows = await this.db\n .select({\n toolCallId: agentToolCall.id,\n toolName: agentToolCall.toolName,\n toolType: agentToolCall.toolType,\n status: agentToolCall.status,\n threadId: agentMessage.threadId,\n createdAt: agentToolCall.createdAt,\n })\n .from(agentToolCall)\n .innerJoin(agentMessage, eq(agentToolCall.messageId, agentMessage.id))\n .orderBy(desc(agentToolCall.createdAt), desc(agentToolCall.id))\n .limit(limit);\n return rows.map((row) => ({\n toolCallId: row.toolCallId,\n toolName: row.toolName,\n toolType: row.toolType,\n status: row.status,\n threadId: row.threadId,\n createdAt: row.createdAt.toISOString(),\n }));\n }\n\n async recentThreads(limit: number): Promise<ThreadActivityRow[]> {\n const threads = await this.db\n .select()\n .from(agentThread)\n .where(isNull(agentThread.deletedAt))\n .orderBy(desc(agentThread.updatedAt), desc(agentThread.id))\n .limit(limit);\n const result: ThreadActivityRow[] = [];\n for (const thread of threads) {\n const [messageCountRow] = await this.db\n .select({ value: count() })\n .from(agentMessage)\n .where(eq(agentMessage.threadId, thread.id));\n const usageRows = await this.db\n .select()\n .from(agentTokenUsage)\n .where(eq(agentTokenUsage.threadId, thread.id));\n const totalTokens = usageRows.reduce(\n (sum, row) => sum + row.inputTokens + row.outputTokens,\n 0,\n );\n result.push({\n threadId: thread.id,\n title: thread.title,\n actorRef: thread.actorRef,\n messageCount: messageCountRow?.value ?? 0,\n totalTokens,\n lastActivityAt: thread.updatedAt.toISOString(),\n });\n }\n return result;\n }\n}\n","import type {\n AgentPricingStore,\n CurrentModelPrice,\n ModelPriceInput,\n} from '@dudousxd/nestjs-agent-core';\nimport { and, eq } from 'drizzle-orm';\nimport { type AgentDrizzleDb, agentModelPricing } from './schema.js';\n\n/**\n * {@link AgentPricingStore} backed by Drizzle ORM — the write side of the pricing table\n * {@link import('./drizzle-governance-queries.js').DrizzleGovernanceQueries} joins against. A POJO\n * receiving a Drizzle SQLite database handle (the host app owns the connection), mirroring\n * {@link import('@dudousxd/nestjs-agent-store-mikro-orm')} exactly (atomic supersede semantics).\n */\nexport class DrizzlePricingStore implements AgentPricingStore {\n constructor(private readonly db: AgentDrizzleDb) {}\n\n async upsertModelPrice(input: ModelPriceInput): Promise<void> {\n await this.db\n .update(agentModelPricing)\n .set({ isCurrent: false })\n .where(\n and(eq(agentModelPricing.modelId, input.modelId), eq(agentModelPricing.isCurrent, true)),\n );\n await this.db.insert(agentModelPricing).values({\n id: crypto.randomUUID(),\n modelId: input.modelId,\n inputPricePer1m: input.inputPricePer1m,\n outputPricePer1m: input.outputPricePer1m,\n cacheWritePricePer1m: input.cacheWritePricePer1m ?? null,\n cacheReadPricePer1m: input.cacheReadPricePer1m ?? null,\n effectiveFrom: new Date(),\n isCurrent: true,\n });\n }\n\n async listCurrentPrices(): Promise<CurrentModelPrice[]> {\n const rows = await this.db\n .select()\n .from(agentModelPricing)\n .where(eq(agentModelPricing.isCurrent, true));\n return rows.map((row) => ({\n modelId: row.modelId,\n inputPricePer1m: row.inputPricePer1m,\n outputPricePer1m: row.outputPricePer1m,\n effectiveFrom: row.effectiveFrom.toISOString(),\n ...(row.cacheWritePricePer1m != null\n ? { cacheWritePricePer1m: row.cacheWritePricePer1m }\n : {}),\n ...(row.cacheReadPricePer1m != null ? { cacheReadPricePer1m: row.cacheReadPricePer1m } : {}),\n }));\n }\n}\n","import {\n AGENT_GOVERNANCE_QUERIES,\n AGENT_PRICING_STORE,\n AGENT_STORE,\n} from '@dudousxd/nestjs-agent-core';\nimport { type DynamicModule, Module } from '@nestjs/common';\nimport { DrizzleAgentStore } from './drizzle-agent-store.js';\nimport { DrizzleGovernanceQueries } from './drizzle-governance-queries.js';\nimport { DrizzlePricingStore } from './drizzle-pricing-store.js';\nimport type { AgentDrizzleDb } from './schema.js';\n\n/** Options for {@link DrizzleAgentStoreModule.forRoot}. The app owns and supplies the db handle. */\nexport interface DrizzleAgentStoreModuleOptions {\n /** A Drizzle SQLite database instance (`drizzle(client, { schema: agentSchema })`). */\n db: AgentDrizzleDb;\n}\n\n/**\n * Binds {@link DrizzleAgentStore} to the {@link AGENT_STORE} token consumed by\n * `@dudousxd/nestjs-agent`, plus {@link DrizzleGovernanceQueries} to\n * {@link AGENT_GOVERNANCE_QUERIES} (the read-model the dashboard/telescope surfaces consume) and\n * {@link DrizzlePricingStore} to {@link AGENT_PRICING_STORE} (the write side of that pricing table).\n * The host app supplies an already-opened Drizzle db — this module never opens a connection itself.\n *\n * The returned module is global, so {@link AGENT_STORE}, {@link AGENT_GOVERNANCE_QUERIES} and\n * {@link AGENT_PRICING_STORE} are visible app-wide — `AgentModule` resolves the store without an\n * explicit `store` option, and the dashboard/telescope resolve {@link AGENT_GOVERNANCE_QUERIES}\n * without the host re-binding it.\n *\n * ```ts\n * @Module({ imports: [DrizzleAgentStoreModule.forRoot({ db })] })\n * export class AppModule {}\n * ```\n */\n@Module({})\nexport class DrizzleAgentStoreModule {\n static forRoot(options: DrizzleAgentStoreModuleOptions): DynamicModule {\n return {\n module: DrizzleAgentStoreModule,\n global: true,\n providers: [\n { provide: DrizzleAgentStore, useFactory: () => new DrizzleAgentStore(options.db) },\n { provide: AGENT_STORE, useExisting: DrizzleAgentStore },\n {\n provide: DrizzleGovernanceQueries,\n useFactory: () => new DrizzleGovernanceQueries(options.db),\n },\n { provide: AGENT_GOVERNANCE_QUERIES, useExisting: DrizzleGovernanceQueries },\n {\n provide: DrizzlePricingStore,\n useFactory: () => new DrizzlePricingStore(options.db),\n },\n { provide: AGENT_PRICING_STORE, useExisting: DrizzlePricingStore },\n ],\n exports: [\n DrizzleAgentStore,\n AGENT_STORE,\n DrizzleGovernanceQueries,\n AGENT_GOVERNANCE_QUERIES,\n DrizzlePricingStore,\n AGENT_PRICING_STORE,\n ],\n };\n }\n}\n"],"mappings":"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","names":["index","integer","real","sqliteTable","text","agentThread","id","primaryKey","actorRef","notNull","tenantRef","title","transient","mode","default","activeStreamId","createdAt","updatedAt","deletedAt","table","on","agentMessage","threadId","references","onDelete","role","$type","content","toolCalls","toolResults","followUps","usage","agentName","agentToolCall","messageId","toolName","toolType","input","output","status","executedByRef","executionMs","error","executedAt","agentTokenUsage","modelId","purpose","inputTokens","outputTokens","cacheWriteTokens","cacheReadTokens","costUsd","agentModelPricing","inputPricePer1m","outputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","effectiveFrom","isCurrent","agentSchema","sql","statements","ensureAgentSchema","db","statement","run","sql","raw","and","asc","desc","eq","gte","inArray","isNull","lte","DrizzleAgentStore","db","createThread","input","now","Date","thread","id","crypto","randomUUID","actorRef","actor","tenantRef","title","transient","activeStreamId","createdAt","updatedAt","deletedAt","insert","agentThread","values","toSummary","getThread","threadId","select","from","where","and","eq","isNull","undefined","messages","agentMessage","orderBy","asc","last","length","content","map","message","toStoredMessage","listThreads","limit","threads","desc","summaries","push","softDeleteThread","update","set","forkThread","fromMessageId","source","Error","cutoff","findIndex","kept","slice","fork","role","toolCalls","toolResults","followUps","usage","agentName","ownerOfThread","ownerOfToolCall","toolCallId","row","agentToolCall","innerJoin","messageId","runForToolCall","ownerOfActiveStream","runId","setTitle","promoteThread","setActiveStream","appendMessage","truncateFrom","doomedIds","delete","inArray","recordToolCall","toolName","toolType","output","status","executedByRef","executionMs","error","executedAt","updateToolCall","updates","recordUsage","agentTokenUsage","modelId","purpose","inputTokens","outputTokens","cacheWriteTokens","cacheReadTokens","costUsd","quotaToday","day","start","end","rows","gte","lte","usedTokens","reduce","sum","lastContent","toISOString","lastMessagePreview","and","count","desc","eq","gte","isNull","lte","estimateFromTokens","pricing","row","price","get","modelId","undefined","cacheWriteTokens","cacheReadTokens","uncachedInputTokens","inputTokens","inputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","outputTokens","outputPricePer1m","rowCost","costUsd","dayBounds","range","start","Date","fromDay","end","toDay","DrizzleGovernanceQueries","db","loadPricing","rows","select","from","agentModelPricing","where","eq","isCurrent","Map","set","usageInRange","agentTokenUsage","and","gte","createdAt","lte","spendByModel","byModel","bucket","requests","result","push","sort","left","right","localeCompare","spendByActor","byActor","actorRef","totalTokens","usageTrend","byDay","day","toISOString","slice","recentToolCalls","limit","toolCallId","agentToolCall","id","toolName","toolType","status","threadId","agentMessage","innerJoin","messageId","orderBy","desc","map","recentThreads","threads","agentThread","isNull","deletedAt","updatedAt","thread","messageCountRow","value","count","usageRows","reduce","sum","title","messageCount","lastActivityAt","and","eq","DrizzlePricingStore","db","upsertModelPrice","input","update","agentModelPricing","set","isCurrent","where","and","eq","modelId","insert","values","id","crypto","randomUUID","inputPricePer1m","outputPricePer1m","cacheWritePricePer1m","cacheReadPricePer1m","effectiveFrom","Date","listCurrentPrices","rows","select","from","map","row","toISOString","AGENT_GOVERNANCE_QUERIES","AGENT_PRICING_STORE","AGENT_STORE","Module","DrizzleAgentStoreModule","forRoot","options","module","global","providers","provide","DrizzleAgentStore","useFactory","db","AGENT_STORE","useExisting","DrizzleGovernanceQueries","AGENT_GOVERNANCE_QUERIES","DrizzlePricingStore","AGENT_PRICING_STORE","exports"]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@dudousxd/nestjs-agent-store-drizzle",
3
- "version": "0.1.0",
3
+ "version": "0.3.0",
4
4
  "description": "nestjs-agent Drizzle ORM agent store (threads, messages, tool calls, usage)",
5
5
  "license": "MIT",
6
6
  "author": "Davide Carvalho",
@@ -24,7 +24,7 @@
24
24
  "dist"
25
25
  ],
26
26
  "dependencies": {
27
- "@dudousxd/nestjs-agent-core": "0.1.0"
27
+ "@dudousxd/nestjs-agent-core": "0.3.0"
28
28
  },
29
29
  "peerDependencies": {
30
30
  "@nestjs/common": "^10.0.0 || ^11.0.0",
@@ -38,7 +38,7 @@
38
38
  "tsup": "8.3.5",
39
39
  "typescript": "5.9.3",
40
40
  "vitest": "2.1.9",
41
- "@dudousxd/nestjs-agent-core": "0.1.0"
41
+ "@dudousxd/nestjs-agent-core": "0.3.0"
42
42
  },
43
43
  "scripts": {
44
44
  "build": "tsup",