UNPKG

@adonis-agora/agent

Version:

Governed, durable-backed AI agent (chat + tool-calling + governance) for AdonisJS — part of the Agora ecosystem.

79 lines • 3.6 kB
import { AGENT_TABLES, ensureAgentTables } from './lucid-schema.js'; function toNum(value) { if (typeof value === 'number') return value; if (typeof value === 'bigint') return Number(value); if (typeof value === 'string') return Number.parseFloat(value) || 0; return 0; } /** * A production {@link AgentPricingStore} backed by AdonisJS **Lucid** (Knex) over the * `agent_model_pricing` table — the write side the loop's cost fold prices token usage against. Like * {@link import('./lucid.js').LucidAgentStore} it touches only the structural {@link LucidDatabaseLike} * slice, so `@adonisjs/lucid` stays an optional peer (the factory casts the real `db` in). * * Atomic supersede (mirrors the reference Drizzle/MikroORM stores): `upsertModelPrice` retires the * model's prior `is_current` row and inserts a fresh current one, so exactly one live price exists * per model. `effective_from` is stored as epoch-ms (matching the rest of the schema) and read back * as an ISO string. Booleans are `INTEGER` 0/1 for cross-dialect portability. */ export class LucidPricingStore { db; autoCreateTables; constructor(db, options = {}) { this.db = db; this.autoCreateTables = options.autoCreateTables ?? true; } /** Provision the shared schema on first use (no-op when disabled), memoized across the stores. */ ready() { return this.autoCreateTables ? ensureAgentTables(this.db) : Promise.resolve(); } /** Provision the shared schema now (what the agent provider calls at app start). Idempotent. */ ensureSchema() { return this.ready(); } async upsertModelPrice(input) { await this.ready(); // Atomic supersede in a transaction: retire the model's current row, then insert the new one. await this.db.transaction(async (trx) => { await trx .from(AGENT_TABLES.modelPricing) .where('model_id', input.modelId) .where('is_current', 1) .update({ is_current: 0 }); await trx.table(AGENT_TABLES.modelPricing).insert({ id: crypto.randomUUID(), model_id: input.modelId, input_price_per_1m: input.inputPricePer1m, output_price_per_1m: input.outputPricePer1m, cache_write_price_per_1m: input.cacheWritePricePer1m ?? null, cache_read_price_per_1m: input.cacheReadPricePer1m ?? null, effective_from: Date.now(), is_current: 1, }); }); } async listCurrentPrices() { await this.ready(); const rows = await this.db.from(AGENT_TABLES.modelPricing).where('is_current', 1).select('*'); return rows.map((row) => { const cacheWrite = row.cache_write_price_per_1m; const cacheRead = row.cache_read_price_per_1m; return { modelId: String(row.model_id), inputPricePer1m: toNum(row.input_price_per_1m), outputPricePer1m: toNum(row.output_price_per_1m), effectiveFrom: new Date(toNum(row.effective_from)).toISOString(), ...(cacheWrite !== null && cacheWrite !== undefined ? { cacheWritePricePer1m: toNum(cacheWrite) } : {}), ...(cacheRead !== null && cacheRead !== undefined ? { cacheReadPricePer1m: toNum(cacheRead) } : {}), }; }); } } //# sourceMappingURL=lucid-pricing.js.map