@llmops/core 0.1.5-beta.2 → 0.1.6-beta.1

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.d.mts CHANGED
@@ -1,4 +1,4 @@
1
- import { A as TableName, B as configVariantsSchema, C as EnvironmentSecretsTable, D as LLMRequestsTable, E as LLMRequest, F as VariantVersion, G as schemas, H as environmentSecretsSchema, I as VariantVersionsTable, J as variantsSchema, K as targetingRulesSchema, L as VariantsTable, M as TargetingRulesTable, N as Updateable, O as SCHEMA_METADATA, P as Variant, R as WorkspaceSettings, S as EnvironmentSecret, T as Insertable, U as environmentsSchema, V as configsSchema, W as llmRequestsSchema, Y as workspaceSettingsSchema, _ as ConfigVariant, a as createDatabaseFromConnection, b as Database, c as MigrationResult, d as runAutoMigrations, f as parsePartialTableData, g as Config, h as validateTableData, i as createDatabase, j as TargetingRule, k as Selectable, l as getMigrations, m as validatePartialTableData, n as DatabaseOptions, o as detectDatabaseType, p as parseTableData, q as variantVersionsSchema, r as DatabaseType, s as MigrationOptions, t as DatabaseConnection, u as matchType, v as ConfigVariantsTable, w as EnvironmentsTable, x as Environment, y as ConfigsTable, z as WorkspaceSettingsTable } from "./index-mUSLoeGU.mjs";
1
+ import { A as TableName, B as configVariantsSchema, C as EnvironmentSecretsTable, D as LLMRequestsTable, E as LLMRequest, F as VariantVersion, G as schemas, H as environmentSecretsSchema, I as VariantVersionsTable, J as variantsSchema, K as targetingRulesSchema, L as VariantsTable, M as TargetingRulesTable, N as Updateable, O as SCHEMA_METADATA, P as Variant, R as WorkspaceSettings, S as EnvironmentSecret, T as Insertable, U as environmentsSchema, V as configsSchema, W as llmRequestsSchema, Y as workspaceSettingsSchema, _ as ConfigVariant, a as createDatabaseFromConnection, b as Database, c as MigrationResult, d as runAutoMigrations, f as parsePartialTableData, g as Config, h as validateTableData, i as createDatabase, j as TargetingRule, k as Selectable, l as getMigrations, m as validatePartialTableData, n as DatabaseOptions, o as detectDatabaseType, p as parseTableData, q as variantVersionsSchema, r as DatabaseType, s as MigrationOptions, t as DatabaseConnection, u as matchType, v as ConfigVariantsTable, w as EnvironmentsTable, x as Environment, y as ConfigsTable, z as WorkspaceSettingsTable } from "./index-fgiyw393.mjs";
2
2
  import gateway from "@llmops/gateway";
3
3
  import { Kysely } from "kysely";
4
4
  import pino from "pino";
@@ -1519,6 +1519,7 @@ declare const insertLLMRequestSchema: z$1.ZodObject<{
1519
1519
  requestId: z$1.ZodString;
1520
1520
  configId: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
1521
1521
  variantId: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
1522
+ environmentId: z$1.ZodOptional<z$1.ZodNullable<z$1.ZodString>>;
1522
1523
  provider: z$1.ZodString;
1523
1524
  model: z$1.ZodString;
1524
1525
  promptTokens: z$1.ZodDefault<z$1.ZodNumber>;
@@ -1543,17 +1544,24 @@ declare const listRequestsSchema: z$1.ZodObject<{
1543
1544
  limit: z$1.ZodDefault<z$1.ZodNumber>;
1544
1545
  offset: z$1.ZodDefault<z$1.ZodNumber>;
1545
1546
  configId: z$1.ZodOptional<z$1.ZodString>;
1547
+ variantId: z$1.ZodOptional<z$1.ZodString>;
1548
+ environmentId: z$1.ZodOptional<z$1.ZodString>;
1546
1549
  provider: z$1.ZodOptional<z$1.ZodString>;
1547
1550
  model: z$1.ZodOptional<z$1.ZodString>;
1548
1551
  startDate: z$1.ZodOptional<z$1.ZodDate>;
1549
1552
  endDate: z$1.ZodOptional<z$1.ZodDate>;
1553
+ tags: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodArray<z$1.ZodString>>>;
1550
1554
  }, z$1.core.$strip>;
1551
1555
  /**
1552
- * Schema for date range queries
1556
+ * Schema for date range queries with optional filters
1553
1557
  */
1554
1558
  declare const dateRangeSchema: z$1.ZodObject<{
1555
1559
  startDate: z$1.ZodDate;
1556
1560
  endDate: z$1.ZodDate;
1561
+ configId: z$1.ZodOptional<z$1.ZodString>;
1562
+ variantId: z$1.ZodOptional<z$1.ZodString>;
1563
+ environmentId: z$1.ZodOptional<z$1.ZodString>;
1564
+ tags: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodArray<z$1.ZodString>>>;
1557
1565
  }, z$1.core.$strip>;
1558
1566
  /**
1559
1567
  * Schema for cost summary with grouping
@@ -1561,6 +1569,10 @@ declare const dateRangeSchema: z$1.ZodObject<{
1561
1569
  declare const costSummarySchema: z$1.ZodObject<{
1562
1570
  startDate: z$1.ZodDate;
1563
1571
  endDate: z$1.ZodDate;
1572
+ configId: z$1.ZodOptional<z$1.ZodString>;
1573
+ variantId: z$1.ZodOptional<z$1.ZodString>;
1574
+ environmentId: z$1.ZodOptional<z$1.ZodString>;
1575
+ tags: z$1.ZodOptional<z$1.ZodRecord<z$1.ZodString, z$1.ZodArray<z$1.ZodString>>>;
1564
1576
  groupBy: z$1.ZodOptional<z$1.ZodEnum<{
1565
1577
  provider: "provider";
1566
1578
  model: "model";
@@ -1585,6 +1597,7 @@ declare const createLLMRequestsDataLayer: (db: Kysely<Database>) => {
1585
1597
  variantId: string | null;
1586
1598
  id: string;
1587
1599
  provider: string;
1600
+ environmentId: string | null;
1588
1601
  requestId: string;
1589
1602
  model: string;
1590
1603
  promptTokens: number;
@@ -1613,6 +1626,7 @@ declare const createLLMRequestsDataLayer: (db: Kysely<Database>) => {
1613
1626
  variantId: string | null;
1614
1627
  id: string;
1615
1628
  provider: string;
1629
+ environmentId: string | null;
1616
1630
  requestId: string;
1617
1631
  model: string;
1618
1632
  promptTokens: number;
@@ -1643,6 +1657,7 @@ declare const createLLMRequestsDataLayer: (db: Kysely<Database>) => {
1643
1657
  variantId: string | null;
1644
1658
  id: string;
1645
1659
  provider: string;
1660
+ environmentId: string | null;
1646
1661
  requestId: string;
1647
1662
  model: string;
1648
1663
  promptTokens: number;
@@ -1662,7 +1677,7 @@ declare const createLLMRequestsDataLayer: (db: Kysely<Database>) => {
1662
1677
  updatedAt: Date;
1663
1678
  } | undefined>;
1664
1679
  /**
1665
- * Get total cost for a date range
1680
+ * Get total cost for a date range with optional filters
1666
1681
  */
1667
1682
  getTotalCost: (params: z$1.infer<typeof dateRangeSchema>) => Promise<{
1668
1683
  totalCost: number;
@@ -1723,7 +1738,7 @@ declare const createLLMRequestsDataLayer: (db: Kysely<Database>) => {
1723
1738
  date: string;
1724
1739
  }[]>;
1725
1740
  /**
1726
- * Get cost summary with flexible grouping
1741
+ * Get cost summary with flexible grouping and optional filters
1727
1742
  */
1728
1743
  getCostSummary: (params: z$1.infer<typeof costSummarySchema>) => Promise<{
1729
1744
  totalCost: number;
@@ -1731,7 +1746,7 @@ declare const createLLMRequestsDataLayer: (db: Kysely<Database>) => {
1731
1746
  groupKey: string;
1732
1747
  }[]>;
1733
1748
  /**
1734
- * Get request count and stats for a time range
1749
+ * Get request count and stats for a time range with optional filters
1735
1750
  */
1736
1751
  getRequestStats: (params: z$1.infer<typeof dateRangeSchema>) => Promise<{
1737
1752
  avgLatencyMs: number;
@@ -1742,6 +1757,14 @@ declare const createLLMRequestsDataLayer: (db: Kysely<Database>) => {
1742
1757
  maxLatencyMs: number;
1743
1758
  minLatencyMs: number;
1744
1759
  } | undefined>;
1760
+ /**
1761
+ * Get all distinct tag key-value pairs from llm_requests
1762
+ * Used for populating tag filter dropdowns in the UI
1763
+ */
1764
+ getDistinctTags: () => Promise<{
1765
+ key: string;
1766
+ value: string;
1767
+ }[]>;
1745
1768
  };
1746
1769
  //#endregion
1747
1770
  //#region src/datalayer/index.d.ts
@@ -2176,6 +2199,7 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2176
2199
  variantId: string | null;
2177
2200
  id: string;
2178
2201
  provider: string;
2202
+ environmentId: string | null;
2179
2203
  requestId: string;
2180
2204
  model: string;
2181
2205
  promptTokens: number;
@@ -2198,16 +2222,20 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2198
2222
  limit: zod0.ZodDefault<zod0.ZodNumber>;
2199
2223
  offset: zod0.ZodDefault<zod0.ZodNumber>;
2200
2224
  configId: zod0.ZodOptional<zod0.ZodString>;
2225
+ variantId: zod0.ZodOptional<zod0.ZodString>;
2226
+ environmentId: zod0.ZodOptional<zod0.ZodString>;
2201
2227
  provider: zod0.ZodOptional<zod0.ZodString>;
2202
2228
  model: zod0.ZodOptional<zod0.ZodString>;
2203
2229
  startDate: zod0.ZodOptional<zod0.ZodDate>;
2204
2230
  endDate: zod0.ZodOptional<zod0.ZodDate>;
2231
+ tags: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodArray<zod0.ZodString>>>;
2205
2232
  }, zod_v4_core0.$strip>>) => Promise<{
2206
2233
  data: {
2207
2234
  configId: string | null;
2208
2235
  variantId: string | null;
2209
2236
  id: string;
2210
2237
  provider: string;
2238
+ environmentId: string | null;
2211
2239
  requestId: string;
2212
2240
  model: string;
2213
2241
  promptTokens: number;
@@ -2235,6 +2263,7 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2235
2263
  variantId: string | null;
2236
2264
  id: string;
2237
2265
  provider: string;
2266
+ environmentId: string | null;
2238
2267
  requestId: string;
2239
2268
  model: string;
2240
2269
  promptTokens: number;
@@ -2256,6 +2285,10 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2256
2285
  getTotalCost: (params: zod0.infer<zod0.ZodObject<{
2257
2286
  startDate: zod0.ZodDate;
2258
2287
  endDate: zod0.ZodDate;
2288
+ configId: zod0.ZodOptional<zod0.ZodString>;
2289
+ variantId: zod0.ZodOptional<zod0.ZodString>;
2290
+ environmentId: zod0.ZodOptional<zod0.ZodString>;
2291
+ tags: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodArray<zod0.ZodString>>>;
2259
2292
  }, zod_v4_core0.$strip>>) => Promise<{
2260
2293
  totalCost: number;
2261
2294
  totalInputCost: number;
@@ -2268,6 +2301,10 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2268
2301
  getCostByModel: (params: zod0.infer<zod0.ZodObject<{
2269
2302
  startDate: zod0.ZodDate;
2270
2303
  endDate: zod0.ZodDate;
2304
+ configId: zod0.ZodOptional<zod0.ZodString>;
2305
+ variantId: zod0.ZodOptional<zod0.ZodString>;
2306
+ environmentId: zod0.ZodOptional<zod0.ZodString>;
2307
+ tags: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodArray<zod0.ZodString>>>;
2271
2308
  }, zod_v4_core0.$strip>>) => Promise<{
2272
2309
  provider: string;
2273
2310
  model: string;
@@ -2281,6 +2318,10 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2281
2318
  getCostByProvider: (params: zod0.infer<zod0.ZodObject<{
2282
2319
  startDate: zod0.ZodDate;
2283
2320
  endDate: zod0.ZodDate;
2321
+ configId: zod0.ZodOptional<zod0.ZodString>;
2322
+ variantId: zod0.ZodOptional<zod0.ZodString>;
2323
+ environmentId: zod0.ZodOptional<zod0.ZodString>;
2324
+ tags: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodArray<zod0.ZodString>>>;
2284
2325
  }, zod_v4_core0.$strip>>) => Promise<{
2285
2326
  provider: string;
2286
2327
  totalCost: number;
@@ -2293,6 +2334,10 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2293
2334
  getCostByConfig: (params: zod0.infer<zod0.ZodObject<{
2294
2335
  startDate: zod0.ZodDate;
2295
2336
  endDate: zod0.ZodDate;
2337
+ configId: zod0.ZodOptional<zod0.ZodString>;
2338
+ variantId: zod0.ZodOptional<zod0.ZodString>;
2339
+ environmentId: zod0.ZodOptional<zod0.ZodString>;
2340
+ tags: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodArray<zod0.ZodString>>>;
2296
2341
  }, zod_v4_core0.$strip>>) => Promise<{
2297
2342
  configId: string | null;
2298
2343
  totalCost: number;
@@ -2306,6 +2351,10 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2306
2351
  getDailyCosts: (params: zod0.infer<zod0.ZodObject<{
2307
2352
  startDate: zod0.ZodDate;
2308
2353
  endDate: zod0.ZodDate;
2354
+ configId: zod0.ZodOptional<zod0.ZodString>;
2355
+ variantId: zod0.ZodOptional<zod0.ZodString>;
2356
+ environmentId: zod0.ZodOptional<zod0.ZodString>;
2357
+ tags: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodArray<zod0.ZodString>>>;
2309
2358
  }, zod_v4_core0.$strip>>) => Promise<{
2310
2359
  totalCost: number;
2311
2360
  totalInputCost: number;
@@ -2317,6 +2366,10 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2317
2366
  getCostSummary: (params: zod0.infer<zod0.ZodObject<{
2318
2367
  startDate: zod0.ZodDate;
2319
2368
  endDate: zod0.ZodDate;
2369
+ configId: zod0.ZodOptional<zod0.ZodString>;
2370
+ variantId: zod0.ZodOptional<zod0.ZodString>;
2371
+ environmentId: zod0.ZodOptional<zod0.ZodString>;
2372
+ tags: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodArray<zod0.ZodString>>>;
2320
2373
  groupBy: zod0.ZodOptional<zod0.ZodEnum<{
2321
2374
  provider: "provider";
2322
2375
  model: "model";
@@ -2332,6 +2385,10 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2332
2385
  getRequestStats: (params: zod0.infer<zod0.ZodObject<{
2333
2386
  startDate: zod0.ZodDate;
2334
2387
  endDate: zod0.ZodDate;
2388
+ configId: zod0.ZodOptional<zod0.ZodString>;
2389
+ variantId: zod0.ZodOptional<zod0.ZodString>;
2390
+ environmentId: zod0.ZodOptional<zod0.ZodString>;
2391
+ tags: zod0.ZodOptional<zod0.ZodRecord<zod0.ZodString, zod0.ZodArray<zod0.ZodString>>>;
2335
2392
  }, zod_v4_core0.$strip>>) => Promise<{
2336
2393
  avgLatencyMs: number;
2337
2394
  totalRequests: number;
@@ -2341,6 +2398,10 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2341
2398
  maxLatencyMs: number;
2342
2399
  minLatencyMs: number;
2343
2400
  } | undefined>;
2401
+ getDistinctTags: () => Promise<{
2402
+ key: string;
2403
+ value: string;
2404
+ }[]>;
2344
2405
  createEnvironmentSecret: (params: zod0.infer<zod0.ZodObject<{
2345
2406
  environmentId: zod0.ZodUUID;
2346
2407
  keyName: zod0.ZodString;
@@ -2636,6 +2697,7 @@ declare const createDataLayer: (db: Kysely<Database>) => Promise<{
2636
2697
  }, zod_v4_core0.$strip>>) => Promise<{
2637
2698
  configId: string;
2638
2699
  variantId: string;
2700
+ environmentId: string;
2639
2701
  version: number;
2640
2702
  provider: string;
2641
2703
  modelName: string;
package/dist/index.mjs CHANGED
@@ -1,4 +1,4 @@
1
- import { A as object, C as zod_default, D as boolean, E as array, M as string, N as union, O as literal, P as unknown, S as workspaceSettingsSchema, T as any, _ as llmRequestsSchema, a as matchType, b as variantVersionsSchema, c as parsePartialTableData, d as validateTableData, f as SCHEMA_METADATA, g as environmentsSchema, h as environmentSecretsSchema, i as getMigrations, j as record, k as number, l as parseTableData, m as configsSchema, n as createDatabaseFromConnection, o as runAutoMigrations, p as configVariantsSchema, r as detectDatabaseType, s as logger, t as createDatabase, u as validatePartialTableData, v as schemas, w as _enum, x as variantsSchema, y as targetingRulesSchema } from "./db-DSzwrW4p.mjs";
1
+ import { A as object, C as zod_default, D as boolean, E as array, M as string, N as union, O as literal, P as unknown, S as workspaceSettingsSchema, T as any, _ as llmRequestsSchema, a as matchType, b as variantVersionsSchema, c as parsePartialTableData, d as validateTableData, f as SCHEMA_METADATA, g as environmentsSchema, h as environmentSecretsSchema, i as getMigrations, j as record, k as number, l as parseTableData, m as configsSchema, n as createDatabaseFromConnection, o as runAutoMigrations, p as configVariantsSchema, r as detectDatabaseType, s as logger, t as createDatabase, u as validatePartialTableData, v as schemas, w as _enum, x as variantsSchema, y as targetingRulesSchema } from "./db-D78x_Elf.mjs";
2
2
  import gateway from "@llmops/gateway";
3
3
  import { sql } from "kysely";
4
4
  import * as fs from "node:fs/promises";
@@ -1283,7 +1283,8 @@ const createConfigVariantDataLayer = (db) => {
1283
1283
  return {
1284
1284
  ...versionData,
1285
1285
  configId: resolvedConfigId,
1286
- variantId: configVariant.variantId
1286
+ variantId: configVariant.variantId,
1287
+ environmentId
1287
1288
  };
1288
1289
  }
1289
1290
  };
@@ -1453,6 +1454,7 @@ const insertLLMRequestSchema = zod_default.object({
1453
1454
  requestId: zod_default.string().uuid(),
1454
1455
  configId: zod_default.string().uuid().nullable().optional(),
1455
1456
  variantId: zod_default.string().uuid().nullable().optional(),
1457
+ environmentId: zod_default.string().uuid().nullable().optional(),
1456
1458
  provider: zod_default.string(),
1457
1459
  model: zod_default.string(),
1458
1460
  promptTokens: zod_default.number().int().default(0),
@@ -1476,17 +1478,24 @@ const listRequestsSchema = zod_default.object({
1476
1478
  limit: zod_default.number().int().positive().max(1e3).default(100),
1477
1479
  offset: zod_default.number().int().nonnegative().default(0),
1478
1480
  configId: zod_default.string().uuid().optional(),
1481
+ variantId: zod_default.string().uuid().optional(),
1482
+ environmentId: zod_default.string().uuid().optional(),
1479
1483
  provider: zod_default.string().optional(),
1480
1484
  model: zod_default.string().optional(),
1481
1485
  startDate: zod_default.date().optional(),
1482
- endDate: zod_default.date().optional()
1486
+ endDate: zod_default.date().optional(),
1487
+ tags: zod_default.record(zod_default.string(), zod_default.array(zod_default.string())).optional()
1483
1488
  });
1484
1489
  /**
1485
- * Schema for date range queries
1490
+ * Schema for date range queries with optional filters
1486
1491
  */
1487
1492
  const dateRangeSchema = zod_default.object({
1488
1493
  startDate: zod_default.date(),
1489
- endDate: zod_default.date()
1494
+ endDate: zod_default.date(),
1495
+ configId: zod_default.string().uuid().optional(),
1496
+ variantId: zod_default.string().uuid().optional(),
1497
+ environmentId: zod_default.string().uuid().optional(),
1498
+ tags: zod_default.record(zod_default.string(), zod_default.array(zod_default.string())).optional()
1490
1499
  });
1491
1500
  /**
1492
1501
  * Schema for cost summary with grouping
@@ -1494,6 +1503,10 @@ const dateRangeSchema = zod_default.object({
1494
1503
  const costSummarySchema = zod_default.object({
1495
1504
  startDate: zod_default.date(),
1496
1505
  endDate: zod_default.date(),
1506
+ configId: zod_default.string().uuid().optional(),
1507
+ variantId: zod_default.string().uuid().optional(),
1508
+ environmentId: zod_default.string().uuid().optional(),
1509
+ tags: zod_default.record(zod_default.string(), zod_default.array(zod_default.string())).optional(),
1497
1510
  groupBy: zod_default.enum([
1498
1511
  "day",
1499
1512
  "hour",
@@ -1523,6 +1536,7 @@ const createLLMRequestsDataLayer = (db) => {
1523
1536
  requestId: req.requestId,
1524
1537
  configId: req.configId ?? null,
1525
1538
  variantId: req.variantId ?? null,
1539
+ environmentId: req.environmentId ?? null,
1526
1540
  provider: req.provider,
1527
1541
  model: req.model,
1528
1542
  promptTokens: req.promptTokens,
@@ -1554,6 +1568,7 @@ const createLLMRequestsDataLayer = (db) => {
1554
1568
  requestId: req.requestId,
1555
1569
  configId: req.configId ?? null,
1556
1570
  variantId: req.variantId ?? null,
1571
+ environmentId: req.environmentId ?? null,
1557
1572
  provider: req.provider,
1558
1573
  model: req.model,
1559
1574
  promptTokens: req.promptTokens,
@@ -1576,14 +1591,43 @@ const createLLMRequestsDataLayer = (db) => {
1576
1591
  listRequests: async (params) => {
1577
1592
  const result = await listRequestsSchema.safeParseAsync(params || {});
1578
1593
  if (!result.success) throw new LLMOpsError(`Invalid parameters: ${result.error.message}`);
1579
- const { limit, offset, configId, provider, model, startDate, endDate } = result.data;
1594
+ const { limit, offset, configId, variantId, environmentId, provider, model, startDate, endDate, tags } = result.data;
1595
+ console.log("[listRequests] Parsed filters:", {
1596
+ configId,
1597
+ variantId,
1598
+ environmentId,
1599
+ provider,
1600
+ model
1601
+ });
1580
1602
  let baseQuery = db.selectFrom("llm_requests");
1581
- if (configId) baseQuery = baseQuery.where("configId", "=", configId);
1603
+ if (configId) {
1604
+ console.log("[listRequests] Adding configId filter:", configId);
1605
+ baseQuery = baseQuery.where("configId", "=", configId);
1606
+ }
1607
+ if (variantId) {
1608
+ console.log("[listRequests] Adding variantId filter:", variantId);
1609
+ baseQuery = baseQuery.where("variantId", "=", variantId);
1610
+ }
1611
+ if (environmentId) {
1612
+ console.log("[listRequests] Adding environmentId filter:", environmentId);
1613
+ baseQuery = baseQuery.where("environmentId", "=", environmentId);
1614
+ }
1582
1615
  if (provider) baseQuery = baseQuery.where("provider", "=", provider);
1583
1616
  if (model) baseQuery = baseQuery.where("model", "=", model);
1584
1617
  if (startDate) baseQuery = baseQuery.where(sql`${col("createdAt")} >= ${startDate.toISOString()}`);
1585
1618
  if (endDate) baseQuery = baseQuery.where(sql`${col("createdAt")} <= ${endDate.toISOString()}`);
1586
- const countResult = await baseQuery.select(sql`COUNT(*)`.as("total")).executeTakeFirst();
1619
+ if (tags && Object.keys(tags).length > 0) for (const [key, values] of Object.entries(tags)) {
1620
+ if (values.length === 0) continue;
1621
+ if (values.length === 1) baseQuery = baseQuery.where(sql`${col("tags")}->>${key} = ${values[0]}`);
1622
+ else {
1623
+ const valueList = sql.join(values.map((v) => sql`${v}`));
1624
+ baseQuery = baseQuery.where(sql`${col("tags")}->>${key} IN (${valueList})`);
1625
+ }
1626
+ }
1627
+ const countQuery = baseQuery.select(sql`COUNT(*)`.as("total"));
1628
+ console.log("[listRequests] Count SQL:", countQuery.compile().sql);
1629
+ console.log("[listRequests] Count params:", countQuery.compile().parameters);
1630
+ const countResult = await countQuery.executeTakeFirst();
1587
1631
  const total = Number(countResult?.total ?? 0);
1588
1632
  return {
1589
1633
  data: await baseQuery.selectAll().orderBy("createdAt", "desc").limit(limit).offset(offset).execute(),
@@ -1598,8 +1642,8 @@ const createLLMRequestsDataLayer = (db) => {
1598
1642
  getTotalCost: async (params) => {
1599
1643
  const result = await dateRangeSchema.safeParseAsync(params);
1600
1644
  if (!result.success) throw new LLMOpsError(`Invalid parameters: ${result.error.message}`);
1601
- const { startDate, endDate } = result.data;
1602
- return await db.selectFrom("llm_requests").select([
1645
+ const { startDate, endDate, configId, variantId, environmentId, tags } = result.data;
1646
+ let query = db.selectFrom("llm_requests").select([
1603
1647
  sql`COALESCE(SUM(${col("cost")}), 0)`.as("totalCost"),
1604
1648
  sql`COALESCE(SUM(${col("inputCost")}), 0)`.as("totalInputCost"),
1605
1649
  sql`COALESCE(SUM(${col("outputCost")}), 0)`.as("totalOutputCost"),
@@ -1607,7 +1651,19 @@ const createLLMRequestsDataLayer = (db) => {
1607
1651
  sql`COALESCE(SUM(${col("completionTokens")}), 0)`.as("totalCompletionTokens"),
1608
1652
  sql`COALESCE(SUM(${col("totalTokens")}), 0)`.as("totalTokens"),
1609
1653
  sql`COUNT(*)`.as("requestCount")
1610
- ]).where(sql`${col("createdAt")} >= ${startDate.toISOString()}`).where(sql`${col("createdAt")} <= ${endDate.toISOString()}`).executeTakeFirst();
1654
+ ]).where(sql`${col("createdAt")} >= ${startDate.toISOString()}`).where(sql`${col("createdAt")} <= ${endDate.toISOString()}`);
1655
+ if (configId) query = query.where("configId", "=", configId);
1656
+ if (variantId) query = query.where("variantId", "=", variantId);
1657
+ if (environmentId) query = query.where("environmentId", "=", environmentId);
1658
+ if (tags && Object.keys(tags).length > 0) for (const [key, values] of Object.entries(tags)) {
1659
+ if (values.length === 0) continue;
1660
+ if (values.length === 1) query = query.where(sql`${col("tags")}->>${key} = ${values[0]}`);
1661
+ else {
1662
+ const valueList = sql.join(values.map((v) => sql`${v}`));
1663
+ query = query.where(sql`${col("tags")}->>${key} IN (${valueList})`);
1664
+ }
1665
+ }
1666
+ return await query.executeTakeFirst();
1611
1667
  },
1612
1668
  getCostByModel: async (params) => {
1613
1669
  const result = await dateRangeSchema.safeParseAsync(params);
@@ -1673,18 +1729,31 @@ const createLLMRequestsDataLayer = (db) => {
1673
1729
  getCostSummary: async (params) => {
1674
1730
  const result = await costSummarySchema.safeParseAsync(params);
1675
1731
  if (!result.success) throw new LLMOpsError(`Invalid parameters: ${result.error.message}`);
1676
- const { startDate, endDate, groupBy } = result.data;
1677
- const baseQuery = db.selectFrom("llm_requests").where(sql`${col("createdAt")} >= ${startDate.toISOString()}`).where(sql`${col("createdAt")} <= ${endDate.toISOString()}`);
1732
+ const { startDate, endDate, groupBy, configId, variantId, environmentId, tags } = result.data;
1733
+ let baseQuery = db.selectFrom("llm_requests").where(sql`${col("createdAt")} >= ${startDate.toISOString()}`).where(sql`${col("createdAt")} <= ${endDate.toISOString()}`);
1734
+ if (configId) baseQuery = baseQuery.where("configId", "=", configId);
1735
+ if (variantId) baseQuery = baseQuery.where("variantId", "=", variantId);
1736
+ if (environmentId) baseQuery = baseQuery.where("environmentId", "=", environmentId);
1737
+ if (tags && Object.keys(tags).length > 0) for (const [key, values] of Object.entries(tags)) {
1738
+ if (values.length === 0) continue;
1739
+ if (values.length === 1) baseQuery = baseQuery.where(sql`${col("tags")}->>${key} = ${values[0]}`);
1740
+ else {
1741
+ const valueList = sql.join(values.map((v) => sql`${v}`));
1742
+ baseQuery = baseQuery.where(sql`${col("tags")}->>${key} IN (${valueList})`);
1743
+ }
1744
+ }
1678
1745
  switch (groupBy) {
1679
1746
  case "day": return baseQuery.select([
1680
1747
  sql`DATE(${col("createdAt")})`.as("groupKey"),
1681
1748
  sql`COALESCE(SUM(${col("cost")}), 0)`.as("totalCost"),
1682
- sql`COUNT(*)`.as("requestCount")
1749
+ sql`COUNT(*)`.as("requestCount"),
1750
+ sql`COALESCE(SUM(${col("totalTokens")}), 0)`.as("totalTokens")
1683
1751
  ]).groupBy(sql`DATE(${col("createdAt")})`).orderBy(sql`DATE(${col("createdAt")})`, "asc").execute();
1684
1752
  case "hour": return baseQuery.select([
1685
1753
  sql`DATE_TRUNC('hour', ${col("createdAt")})`.as("groupKey"),
1686
1754
  sql`COALESCE(SUM(${col("cost")}), 0)`.as("totalCost"),
1687
- sql`COUNT(*)`.as("requestCount")
1755
+ sql`COUNT(*)`.as("requestCount"),
1756
+ sql`COALESCE(SUM(${col("totalTokens")}), 0)`.as("totalTokens")
1688
1757
  ]).groupBy(sql`DATE_TRUNC('hour', ${col("createdAt")})`).orderBy(sql`DATE_TRUNC('hour', ${col("createdAt")})`, "asc").execute();
1689
1758
  case "model": return baseQuery.select([
1690
1759
  sql`${col("provider")} || '/' || ${col("model")}`.as("groupKey"),
@@ -1711,8 +1780,8 @@ const createLLMRequestsDataLayer = (db) => {
1711
1780
  getRequestStats: async (params) => {
1712
1781
  const result = await dateRangeSchema.safeParseAsync(params);
1713
1782
  if (!result.success) throw new LLMOpsError(`Invalid parameters: ${result.error.message}`);
1714
- const { startDate, endDate } = result.data;
1715
- return await db.selectFrom("llm_requests").select([
1783
+ const { startDate, endDate, configId, variantId, environmentId, tags } = result.data;
1784
+ let query = db.selectFrom("llm_requests").select([
1716
1785
  sql`COUNT(*)`.as("totalRequests"),
1717
1786
  sql`COUNT(CASE WHEN ${col("statusCode")} >= 200 AND ${col("statusCode")} < 300 THEN 1 END)`.as("successfulRequests"),
1718
1787
  sql`COUNT(CASE WHEN ${col("statusCode")} >= 400 THEN 1 END)`.as("failedRequests"),
@@ -1720,7 +1789,27 @@ const createLLMRequestsDataLayer = (db) => {
1720
1789
  sql`AVG(${col("latencyMs")})`.as("avgLatencyMs"),
1721
1790
  sql`MAX(${col("latencyMs")})`.as("maxLatencyMs"),
1722
1791
  sql`MIN(${col("latencyMs")})`.as("minLatencyMs")
1723
- ]).where(sql`${col("createdAt")} >= ${startDate.toISOString()}`).where(sql`${col("createdAt")} <= ${endDate.toISOString()}`).executeTakeFirst();
1792
+ ]).where(sql`${col("createdAt")} >= ${startDate.toISOString()}`).where(sql`${col("createdAt")} <= ${endDate.toISOString()}`);
1793
+ if (configId) query = query.where("configId", "=", configId);
1794
+ if (variantId) query = query.where("variantId", "=", variantId);
1795
+ if (environmentId) query = query.where("environmentId", "=", environmentId);
1796
+ if (tags && Object.keys(tags).length > 0) for (const [key, values] of Object.entries(tags)) {
1797
+ if (values.length === 0) continue;
1798
+ if (values.length === 1) query = query.where(sql`${col("tags")}->>${key} = ${values[0]}`);
1799
+ else {
1800
+ const valueList = sql.join(values.map((v) => sql`${v}`));
1801
+ query = query.where(sql`${col("tags")}->>${key} IN (${valueList})`);
1802
+ }
1803
+ }
1804
+ return await query.executeTakeFirst();
1805
+ },
1806
+ getDistinctTags: async () => {
1807
+ return (await sql`
1808
+ SELECT DISTINCT key, value
1809
+ FROM llm_requests, jsonb_each_text(tags) AS t(key, value)
1810
+ WHERE tags != '{}'::jsonb
1811
+ ORDER BY key, value
1812
+ `.execute(db)).rows;
1724
1813
  }
1725
1814
  };
1726
1815
  };
@@ -1,4 +1,4 @@
1
- const require_db = require('./db-eEfIe5dO.cjs');
1
+ const require_db = require('./db-C_u1BuaR.cjs');
2
2
  let kysely = require("kysely");
3
3
 
4
4
  //#region src/db/node-sqlite-dialect.ts
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@llmops/core",
3
- "version": "0.1.5-beta.2",
3
+ "version": "0.1.6-beta.1",
4
4
  "description": "Core LLMOps functionality and utilities",
5
5
  "type": "module",
6
6
  "license": "Apache-2.0",
@@ -51,7 +51,7 @@
51
51
  "hono": "^4.10.7",
52
52
  "kysely": "^0.28.8",
53
53
  "pino": "^10.1.0",
54
- "@llmops/gateway": "^0.1.5-beta.2"
54
+ "@llmops/gateway": "^0.1.6-beta.1"
55
55
  },
56
56
  "scripts": {
57
57
  "build": "tsdown",