@axiom-lattice/local-stores 3.1.21 → 3.1.23

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.mjs CHANGED
@@ -2420,8 +2420,328 @@ function encryptEnvInConfig(config) {
2420
2420
  return { config: configCopy, isEnvEncrypted };
2421
2421
  }
2422
2422
 
2423
- // src/stores/LocalWorkflowTrackingStore.ts
2423
+ // src/stores/LocalModelProviderStore.ts
2424
+ import { encrypt as encrypt3, decrypt as decrypt3 } from "@axiom-lattice/core";
2424
2425
  var DDL12 = `
2426
+ CREATE TABLE IF NOT EXISTS lt_model_providers (
2427
+ id TEXT NOT NULL,
2428
+ tenant_id TEXT NOT NULL,
2429
+ name TEXT NOT NULL,
2430
+ display_name TEXT,
2431
+ protocol TEXT NOT NULL,
2432
+ api_style TEXT NOT NULL DEFAULT 'chat-completions',
2433
+ llm_provider TEXT NOT NULL,
2434
+ base_url TEXT NOT NULL,
2435
+ api_key_enc TEXT,
2436
+ api_key_hint TEXT,
2437
+ enabled INTEGER NOT NULL DEFAULT 1,
2438
+ status TEXT NOT NULL DEFAULT 'unknown',
2439
+ last_error TEXT,
2440
+ last_discovered_at TEXT,
2441
+ created_by TEXT,
2442
+ created_at TEXT NOT NULL,
2443
+ updated_at TEXT NOT NULL,
2444
+ PRIMARY KEY (tenant_id, id)
2445
+ );
2446
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_lt_model_providers_name
2447
+ ON lt_model_providers(tenant_id, name);
2448
+
2449
+ CREATE TABLE IF NOT EXISTS lt_model_provider_models (
2450
+ id TEXT NOT NULL,
2451
+ tenant_id TEXT NOT NULL,
2452
+ provider_id TEXT NOT NULL,
2453
+ model_id TEXT NOT NULL,
2454
+ display_name TEXT,
2455
+ owned_by TEXT,
2456
+ upstream_created TEXT,
2457
+ enabled INTEGER NOT NULL DEFAULT 1,
2458
+ stale INTEGER NOT NULL DEFAULT 0,
2459
+ raw TEXT,
2460
+ discovered_at TEXT NOT NULL,
2461
+ PRIMARY KEY (tenant_id, provider_id, model_id)
2462
+ );
2463
+ CREATE INDEX IF NOT EXISTS idx_lt_model_provider_models_tenant
2464
+ ON lt_model_provider_models(tenant_id, model_id);
2465
+ `;
2466
+ var LocalModelProviderStore = class {
2467
+ constructor(db) {
2468
+ this.db = db;
2469
+ ensureTable(db, DDL12);
2470
+ this.ensureColumn(
2471
+ "lt_model_providers",
2472
+ "api_style",
2473
+ "api_style TEXT NOT NULL DEFAULT 'chat-completions'"
2474
+ );
2475
+ this.ensureColumn(
2476
+ "lt_model_provider_models",
2477
+ "stale",
2478
+ "stale INTEGER NOT NULL DEFAULT 0"
2479
+ );
2480
+ }
2481
+ /** Add a column if it does not exist (SQLite version compatible). */
2482
+ ensureColumn(table, column, ddl2) {
2483
+ const cols = this.db.prepare(`PRAGMA table_info(${table})`).all();
2484
+ if (!cols.some((c) => c.name === column)) {
2485
+ this.db.exec(`ALTER TABLE ${table} ADD COLUMN ${ddl2}`);
2486
+ }
2487
+ }
2488
+ async listProviders(tenantId) {
2489
+ const rows2 = this.db.prepare(
2490
+ `SELECT * FROM lt_model_providers WHERE tenant_id = ? ORDER BY created_at DESC`
2491
+ ).all(tenantId);
2492
+ return rows2.map((row) => mapRowToEntry4(row));
2493
+ }
2494
+ async getProviderById(tenantId, id) {
2495
+ const row = this.db.prepare(
2496
+ `SELECT * FROM lt_model_providers WHERE tenant_id = ? AND id = ?`
2497
+ ).get(tenantId, id);
2498
+ return row ? mapRowToEntry4(row) : null;
2499
+ }
2500
+ async getProviderByName(tenantId, name) {
2501
+ const row = this.db.prepare(
2502
+ `SELECT * FROM lt_model_providers WHERE tenant_id = ? AND name = ?`
2503
+ ).get(tenantId, name);
2504
+ return row ? mapRowToEntry4(row) : null;
2505
+ }
2506
+ async createProvider(tenantId, id, data) {
2507
+ const now = nowISO();
2508
+ this.db.prepare(
2509
+ `INSERT INTO lt_model_providers (
2510
+ id, tenant_id, name, display_name, protocol, api_style, llm_provider, base_url,
2511
+ api_key_enc, api_key_hint, enabled, status, created_at, updated_at
2512
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'unknown', ?, ?)
2513
+ ON CONFLICT (tenant_id, id) DO UPDATE SET
2514
+ name = excluded.name,
2515
+ display_name = excluded.display_name,
2516
+ protocol = excluded.protocol,
2517
+ api_style = excluded.api_style,
2518
+ llm_provider = excluded.llm_provider,
2519
+ base_url = excluded.base_url,
2520
+ api_key_enc = excluded.api_key_enc,
2521
+ api_key_hint = excluded.api_key_hint,
2522
+ enabled = excluded.enabled,
2523
+ updated_at = excluded.updated_at`
2524
+ ).run(
2525
+ id,
2526
+ tenantId,
2527
+ data.name,
2528
+ data.displayName || null,
2529
+ data.protocol,
2530
+ data.apiStyle ?? "chat-completions",
2531
+ // Phase 1 pins the LLM provider (ADR-138 decision 7b)
2532
+ "openai",
2533
+ data.baseURL,
2534
+ data.apiKey ? encrypt3(data.apiKey) : null,
2535
+ data.apiKey ? data.apiKey.slice(-4) : null,
2536
+ data.enabled === false ? 0 : 1,
2537
+ now,
2538
+ now
2539
+ );
2540
+ const created = await this.getProviderById(tenantId, id);
2541
+ if (!created) {
2542
+ throw new Error("Failed to create model provider");
2543
+ }
2544
+ return created;
2545
+ }
2546
+ async updateProvider(tenantId, id, updates) {
2547
+ const existing = await this.getProviderById(tenantId, id);
2548
+ if (!existing) {
2549
+ return null;
2550
+ }
2551
+ const fields = [];
2552
+ const values = [];
2553
+ const set = (column, value) => {
2554
+ fields.push(`${column} = ?`);
2555
+ values.push(value);
2556
+ };
2557
+ if (updates.name !== void 0) set("name", updates.name);
2558
+ if (updates.displayName !== void 0) {
2559
+ set("display_name", updates.displayName || null);
2560
+ }
2561
+ if (updates.protocol !== void 0) set("protocol", updates.protocol);
2562
+ if (updates.apiStyle !== void 0) set("api_style", updates.apiStyle);
2563
+ if (updates.baseURL !== void 0) set("base_url", updates.baseURL);
2564
+ if (updates.enabled !== void 0) set("enabled", updates.enabled ? 1 : 0);
2565
+ if (updates.clearApiKey === true) {
2566
+ set("api_key_enc", null);
2567
+ set("api_key_hint", null);
2568
+ } else if (updates.apiKey) {
2569
+ set("api_key_enc", encrypt3(updates.apiKey));
2570
+ set("api_key_hint", updates.apiKey.slice(-4));
2571
+ }
2572
+ if (fields.length === 0) {
2573
+ return existing;
2574
+ }
2575
+ fields.push("updated_at = ?");
2576
+ values.push(nowISO(), tenantId, id);
2577
+ this.db.prepare(
2578
+ `UPDATE lt_model_providers SET ${fields.join(", ")}
2579
+ WHERE tenant_id = ? AND id = ?`
2580
+ ).run(...values);
2581
+ return this.getProviderById(tenantId, id);
2582
+ }
2583
+ async deleteProvider(tenantId, id) {
2584
+ await this.deleteModelsByProvider(tenantId, id);
2585
+ const result = this.db.prepare(`DELETE FROM lt_model_providers WHERE tenant_id = ? AND id = ?`).run(tenantId, id);
2586
+ return result.changes > 0;
2587
+ }
2588
+ async markProviderStatus(tenantId, id, status, lastError, discoveredAt) {
2589
+ this.db.prepare(
2590
+ `UPDATE lt_model_providers
2591
+ SET status = ?,
2592
+ last_error = ?,
2593
+ last_discovered_at = COALESCE(?, last_discovered_at),
2594
+ updated_at = ?
2595
+ WHERE tenant_id = ? AND id = ?`
2596
+ ).run(
2597
+ status,
2598
+ status === "ok" ? null : lastError || null,
2599
+ discoveredAt ? discoveredAt.toISOString() : null,
2600
+ nowISO(),
2601
+ tenantId,
2602
+ id
2603
+ );
2604
+ }
2605
+ async listModels(tenantId, providerId) {
2606
+ const rows2 = providerId ? this.db.prepare(
2607
+ `SELECT * FROM lt_model_provider_models
2608
+ WHERE tenant_id = ? AND provider_id = ? ORDER BY model_id ASC`
2609
+ ).all(tenantId, providerId) : this.db.prepare(
2610
+ `SELECT * FROM lt_model_provider_models
2611
+ WHERE tenant_id = ? ORDER BY model_id ASC`
2612
+ ).all(tenantId);
2613
+ return rows2.map((row) => mapRowToModel(row));
2614
+ }
2615
+ async getModel(tenantId, providerId, modelId) {
2616
+ const row = this.db.prepare(
2617
+ `SELECT * FROM lt_model_provider_models
2618
+ WHERE tenant_id = ? AND provider_id = ? AND model_id = ?`
2619
+ ).get(tenantId, providerId, modelId);
2620
+ return row ? mapRowToModel(row) : null;
2621
+ }
2622
+ /**
2623
+ * Replace a provider's model snapshot.
2624
+ *
2625
+ * Models the upstream no longer offers are deleted; survivors are upserted
2626
+ * without touching `enabled`, so the tenant's enable/disable choice survives.
2627
+ */
2628
+ async replaceProviderModels(tenantId, providerId, models) {
2629
+ const now = nowISO();
2630
+ const deduped = /* @__PURE__ */ new Map();
2631
+ for (const model of models) {
2632
+ deduped.set(model.id, model);
2633
+ }
2634
+ const rows2 = [...deduped.values()];
2635
+ if (rows2.length === 0) {
2636
+ await this.deleteModelsByProvider(tenantId, providerId);
2637
+ return [];
2638
+ }
2639
+ const current = new Map(
2640
+ (await this.listModels(tenantId, providerId)).map((model) => [
2641
+ model.modelId,
2642
+ model.enabled
2643
+ ])
2644
+ );
2645
+ const placeholders = rows2.map(() => "?").join(", ");
2646
+ this.db.prepare(
2647
+ `DELETE FROM lt_model_provider_models
2648
+ WHERE tenant_id = ? AND provider_id = ? AND model_id NOT IN (${placeholders})`
2649
+ ).run(tenantId, providerId, ...rows2.map((model) => model.id));
2650
+ for (const model of rows2) {
2651
+ this.db.prepare(
2652
+ `INSERT INTO lt_model_provider_models (
2653
+ id, tenant_id, provider_id, model_id, display_name, owned_by,
2654
+ upstream_created, raw, enabled, stale, discovered_at
2655
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2656
+ ON CONFLICT (tenant_id, provider_id, model_id) DO UPDATE SET
2657
+ display_name = excluded.display_name,
2658
+ owned_by = excluded.owned_by,
2659
+ upstream_created = excluded.upstream_created,
2660
+ raw = excluded.raw,
2661
+ enabled = excluded.enabled,
2662
+ stale = excluded.stale,
2663
+ discovered_at = excluded.discovered_at`
2664
+ ).run(
2665
+ `${providerId}:${model.id}`,
2666
+ tenantId,
2667
+ providerId,
2668
+ model.id,
2669
+ model.displayName || null,
2670
+ model.ownedBy || null,
2671
+ model.createdAt || null,
2672
+ model.raw === void 0 ? null : JSON.stringify(model.raw),
2673
+ model.enabled ?? current.get(model.id) ?? true ? 1 : 0,
2674
+ model.stale ? 1 : 0,
2675
+ now
2676
+ );
2677
+ }
2678
+ return rows2.map((model) => model.id);
2679
+ }
2680
+ async setModelEnabled(tenantId, providerId, modelId, enabled) {
2681
+ const result = this.db.prepare(
2682
+ `UPDATE lt_model_provider_models SET enabled = ?
2683
+ WHERE tenant_id = ? AND provider_id = ? AND model_id = ?`
2684
+ ).run(enabled ? 1 : 0, tenantId, providerId, modelId);
2685
+ if (result.changes === 0) {
2686
+ return null;
2687
+ }
2688
+ return this.getModel(tenantId, providerId, modelId);
2689
+ }
2690
+ async deleteModelsByProvider(tenantId, providerId) {
2691
+ const result = this.db.prepare(
2692
+ `DELETE FROM lt_model_provider_models
2693
+ WHERE tenant_id = ? AND provider_id = ?`
2694
+ ).run(tenantId, providerId);
2695
+ return result.changes;
2696
+ }
2697
+ };
2698
+ function mapRowToEntry4(row) {
2699
+ let apiKey;
2700
+ if (row.api_key_enc) {
2701
+ try {
2702
+ apiKey = decrypt3(row.api_key_enc);
2703
+ } catch (error) {
2704
+ console.error("Failed to decrypt model provider API key:", error);
2705
+ throw new Error("Failed to decrypt model provider API key");
2706
+ }
2707
+ }
2708
+ return {
2709
+ id: row.id,
2710
+ tenantId: row.tenant_id,
2711
+ name: row.name,
2712
+ displayName: row.display_name || void 0,
2713
+ protocol: row.protocol,
2714
+ apiStyle: row.api_style,
2715
+ llmProvider: row.llm_provider,
2716
+ baseURL: row.base_url,
2717
+ apiKey,
2718
+ apiKeyHint: row.api_key_hint || void 0,
2719
+ enabled: row.enabled === 1,
2720
+ status: row.status,
2721
+ lastError: row.last_error || void 0,
2722
+ lastDiscoveredAt: row.last_discovered_at ? parseISO(row.last_discovered_at) : void 0,
2723
+ createdBy: row.created_by || void 0,
2724
+ createdAt: parseISO(row.created_at),
2725
+ updatedAt: parseISO(row.updated_at)
2726
+ };
2727
+ }
2728
+ function mapRowToModel(row) {
2729
+ return {
2730
+ id: row.id,
2731
+ tenantId: row.tenant_id,
2732
+ providerId: row.provider_id,
2733
+ modelId: row.model_id,
2734
+ displayName: row.display_name || void 0,
2735
+ ownedBy: row.owned_by || void 0,
2736
+ upstreamCreatedAt: row.upstream_created ? parseISO(row.upstream_created) : void 0,
2737
+ enabled: row.enabled === 1,
2738
+ stale: row.stale === 1,
2739
+ discoveredAt: parseISO(row.discovered_at)
2740
+ };
2741
+ }
2742
+
2743
+ // src/stores/LocalWorkflowTrackingStore.ts
2744
+ var DDL13 = `
2425
2745
  CREATE TABLE IF NOT EXISTS lt_workflow_runs (
2426
2746
  id TEXT PRIMARY KEY,
2427
2747
  tenant_id TEXT NOT NULL,
@@ -2470,7 +2790,7 @@ ALTER TABLE lt_workflow_steps ADD COLUMN IF NOT EXISTS thread_id TEXT;
2470
2790
  var LocalWorkflowTrackingStore = class {
2471
2791
  constructor(db) {
2472
2792
  this.db = db;
2473
- ensureTable(db, DDL12);
2793
+ ensureTable(db, DDL13);
2474
2794
  }
2475
2795
  async createWorkflowRun(request) {
2476
2796
  const now = nowISO();
@@ -2761,7 +3081,7 @@ function mapRowToStep(row) {
2761
3081
 
2762
3082
  // src/stores/LocalEvalStore.ts
2763
3083
  import { randomUUID } from "crypto";
2764
- var DDL13 = `
3084
+ var DDL14 = `
2765
3085
  CREATE TABLE IF NOT EXISTS lt_eval_projects (
2766
3086
  id TEXT NOT NULL,
2767
3087
  tenant_id TEXT NOT NULL,
@@ -2871,7 +3191,7 @@ function parseOptionalJson(val) {
2871
3191
  var LocalEvalStore = class {
2872
3192
  constructor(db) {
2873
3193
  this.db = db;
2874
- ensureTable(db, DDL13);
3194
+ ensureTable(db, DDL14);
2875
3195
  this.ensureColumn("lt_eval_runs", "interrupted_cases", "interrupted_cases INTEGER NOT NULL DEFAULT 0");
2876
3196
  this.ensureColumn("lt_eval_run_results", "interrupted", "interrupted INTEGER NOT NULL DEFAULT 0");
2877
3197
  this.ensureColumn("lt_eval_cases", "interrupt_policy", "interrupt_policy TEXT");
@@ -3504,7 +3824,7 @@ function mapConflict(row) {
3504
3824
  }
3505
3825
 
3506
3826
  // src/stores/LocalChannelBindingStore.ts
3507
- var DDL14 = `
3827
+ var DDL15 = `
3508
3828
  CREATE TABLE IF NOT EXISTS lt_channel_bindings (
3509
3829
  id TEXT PRIMARY KEY,
3510
3830
  channel TEXT NOT NULL,
@@ -3526,7 +3846,7 @@ CREATE TABLE IF NOT EXISTS lt_channel_bindings (
3526
3846
  var LocalChannelBindingStore = class {
3527
3847
  constructor(db) {
3528
3848
  this.db = db;
3529
- ensureTable(db, DDL14);
3849
+ ensureTable(db, DDL15);
3530
3850
  ensureChannelBindingSubjectIndex(db);
3531
3851
  }
3532
3852
  async findById(tenantId, id) {
@@ -3706,7 +4026,7 @@ function mapRowToBinding(row) {
3706
4026
  }
3707
4027
 
3708
4028
  // src/stores/LocalChannelInstallationStore.ts
3709
- var DDL15 = `
4029
+ var DDL16 = `
3710
4030
  CREATE TABLE IF NOT EXISTS lt_channel_installations (
3711
4031
  id TEXT PRIMARY KEY,
3712
4032
  tenant_id TEXT NOT NULL,
@@ -3724,7 +4044,7 @@ CREATE INDEX IF NOT EXISTS idx_lt_ci_tenant ON lt_channel_installations(tenant_i
3724
4044
  var LocalChannelInstallationStore = class {
3725
4045
  constructor(db) {
3726
4046
  this.db = db;
3727
- ensureTable(db, DDL15);
4047
+ ensureTable(db, DDL16);
3728
4048
  }
3729
4049
  async getInstallationById(installationId) {
3730
4050
  const row = this.db.prepare(
@@ -3848,9 +4168,9 @@ function mapRow6(row) {
3848
4168
  }
3849
4169
 
3850
4170
  // src/stores/LocalA2AApiKeyStore.ts
3851
- import { encrypt as encrypt3, decrypt as decrypt3 } from "@axiom-lattice/core";
4171
+ import { encrypt as encrypt4, decrypt as decrypt4 } from "@axiom-lattice/core";
3852
4172
  import { randomUUID as randomUUID3 } from "crypto";
3853
- var DDL16 = `
4173
+ var DDL17 = `
3854
4174
  CREATE TABLE IF NOT EXISTS lt_a2a_api_keys (
3855
4175
  id TEXT PRIMARY KEY,
3856
4176
  key_value TEXT NOT NULL,
@@ -3888,7 +4208,7 @@ function parseAssistantIds(raw) {
3888
4208
  var LocalA2AApiKeyStore = class {
3889
4209
  constructor(db) {
3890
4210
  this.db = db;
3891
- ensureTable(db, DDL16);
4211
+ ensureTable(db, DDL17);
3892
4212
  this.ensureColumn("lt_a2a_api_keys", "assistant_ids", "assistant_ids TEXT");
3893
4213
  this.ensureColumn("lt_a2a_api_keys", "grants", "grants TEXT");
3894
4214
  this.repairManagementIds();
@@ -3919,7 +4239,7 @@ var LocalA2AApiKeyStore = class {
3919
4239
  ).all();
3920
4240
  for (const row of rows2) {
3921
4241
  try {
3922
- if (decrypt3(row.key_value) === key) return mapRowToRecord(row);
4242
+ if (decrypt4(row.key_value) === key) return mapRowToRecord(row);
3923
4243
  } catch {
3924
4244
  }
3925
4245
  }
@@ -3953,7 +4273,7 @@ var LocalA2AApiKeyStore = class {
3953
4273
  this.db.prepare(
3954
4274
  `INSERT INTO lt_a2a_api_keys (id, key_value, tenant_id, project_id, assistant_ids, grants, label, created_at, updated_at)
3955
4275
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
3956
- ).run(id, encrypt3(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.grants ? JSON.stringify(input.grants) : null, input.label || null, now, now);
4276
+ ).run(id, encrypt4(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.grants ? JSON.stringify(input.grants) : null, input.label || null, now, now);
3957
4277
  const record2 = {
3958
4278
  id,
3959
4279
  key,
@@ -4022,7 +4342,7 @@ var LocalA2AApiKeyStore = class {
4022
4342
  const now = nowISO();
4023
4343
  this.db.prepare(
4024
4344
  `UPDATE lt_a2a_api_keys SET key_value = ?, updated_at = ? WHERE id = ?`
4025
- ).run(encrypt3(key), now, id);
4345
+ ).run(encrypt4(key), now, id);
4026
4346
  const row = this.db.prepare(`SELECT * FROM lt_a2a_api_keys WHERE id = ?`).get(id);
4027
4347
  if (!row) throw new Error(`A2A API key not found: ${id}`);
4028
4348
  const record2 = mapRowToRecord(row);
@@ -4039,7 +4359,7 @@ var LocalA2AApiKeyStore = class {
4039
4359
  const map2 = /* @__PURE__ */ new Map();
4040
4360
  for (const row of rows2) {
4041
4361
  try {
4042
- const key = decrypt3(row.key_value);
4362
+ const key = decrypt4(row.key_value);
4043
4363
  map2.set(key, {
4044
4364
  key,
4045
4365
  tenantId: row.tenant_id,
@@ -4055,7 +4375,7 @@ var LocalA2AApiKeyStore = class {
4055
4375
  function mapRowToRecord(row) {
4056
4376
  let key = "";
4057
4377
  try {
4058
- key = decrypt3(row.key_value);
4378
+ key = decrypt4(row.key_value);
4059
4379
  } catch {
4060
4380
  key = row.key_value;
4061
4381
  }
@@ -4075,7 +4395,7 @@ function mapRowToRecord(row) {
4075
4395
 
4076
4396
  // src/stores/LocalOpenAuditStore.ts
4077
4397
  import { randomUUID as randomUUID4 } from "crypto";
4078
- var DDL17 = `
4398
+ var DDL18 = `
4079
4399
  CREATE TABLE IF NOT EXISTS lt_open_audit (
4080
4400
  id TEXT PRIMARY KEY,
4081
4401
  tenant_id TEXT NOT NULL,
@@ -4094,7 +4414,7 @@ CREATE TABLE IF NOT EXISTS lt_open_audit (
4094
4414
  var LocalOpenAuditStore = class {
4095
4415
  constructor(db) {
4096
4416
  this.db = db;
4097
- ensureTable(db, DDL17);
4417
+ ensureTable(db, DDL18);
4098
4418
  }
4099
4419
  async query(params) {
4100
4420
  const clauses = ["tenant_id = ?"];
@@ -4169,7 +4489,7 @@ import {
4169
4489
  parseTrustedRunContext
4170
4490
  } from "@axiom-lattice/protocols";
4171
4491
  import { randomUUID as randomUUID5 } from "crypto";
4172
- var DDL18 = `
4492
+ var DDL19 = `
4173
4493
  CREATE TABLE IF NOT EXISTS lt_thread_message_queue (
4174
4494
  id TEXT PRIMARY KEY,
4175
4495
  thread_id TEXT NOT NULL,
@@ -4195,7 +4515,7 @@ var LocalThreadMessageQueueStore = class {
4195
4515
  constructor(db) {
4196
4516
  this.capacityTail = Promise.resolve();
4197
4517
  this.db = db;
4198
- ensureTable(db, DDL18);
4518
+ ensureTable(db, DDL19);
4199
4519
  const columns6 = db.prepare("PRAGMA table_info(lt_thread_message_queue)").all();
4200
4520
  const names = new Set(columns6.map(({ name }) => name));
4201
4521
  if (!names.has("trusted_run_context")) {
@@ -4408,7 +4728,7 @@ function rowToMessage(row) {
4408
4728
  }
4409
4729
 
4410
4730
  // src/stores/LocalSkillStore.ts
4411
- var DDL19 = `
4731
+ var DDL20 = `
4412
4732
  CREATE TABLE IF NOT EXISTS lt_skills (
4413
4733
  id TEXT NOT NULL,
4414
4734
  tenant_id TEXT NOT NULL,
@@ -4427,7 +4747,7 @@ CREATE TABLE IF NOT EXISTS lt_skills (
4427
4747
  var LocalSkillStore = class {
4428
4748
  constructor(db) {
4429
4749
  this.db = db;
4430
- ensureTable(db, DDL19);
4750
+ ensureTable(db, DDL20);
4431
4751
  }
4432
4752
  async getAllSkills(tenantId, _context) {
4433
4753
  const rows2 = this.db.prepare(
@@ -4577,7 +4897,7 @@ function mapRowToSkill(row) {
4577
4897
  }
4578
4898
 
4579
4899
  // src/stores/LocalScheduleStorage.ts
4580
- var DDL20 = `
4900
+ var DDL21 = `
4581
4901
  CREATE TABLE IF NOT EXISTS lt_scheduled_tasks (
4582
4902
  task_id TEXT PRIMARY KEY,
4583
4903
  task_type TEXT NOT NULL,
@@ -4610,7 +4930,7 @@ CREATE INDEX IF NOT EXISTS idx_lt_st_tenant ON lt_scheduled_tasks(tenant_id);
4610
4930
  var LocalScheduleStorage = class {
4611
4931
  constructor(db) {
4612
4932
  this.db = db;
4613
- ensureTable(db, DDL20);
4933
+ ensureTable(db, DDL21);
4614
4934
  }
4615
4935
  async save(task) {
4616
4936
  this.db.prepare(
@@ -4921,7 +5241,7 @@ var NEXT_UPDATED_AT_SQL = `updated_at = CASE
4921
5241
  THEN strftime('%Y-%m-%dT%H:%M:%fZ', updated_at, '+0.001 seconds')
4922
5242
  ELSE ?
4923
5243
  END`;
4924
- var DDL21 = `
5244
+ var DDL22 = `
4925
5245
  CREATE TABLE IF NOT EXISTS lt_tasks (
4926
5246
  id TEXT NOT NULL,
4927
5247
  tenant_id TEXT NOT NULL,
@@ -4994,7 +5314,7 @@ function assertPage(limit, offset = 0) {
4994
5314
  var LocalTaskStore = class {
4995
5315
  constructor(db) {
4996
5316
  this.db = db;
4997
- ensureTable(db, DDL21);
5317
+ ensureTable(db, DDL22);
4998
5318
  this.ensureColumn("lt_tasks", "require_review", "require_review INTEGER DEFAULT 0");
4999
5319
  this.ensureColumn("lt_tasks", "dependencies", "dependencies TEXT");
5000
5320
  this.ensureColumn("lt_tasks", "result", "result TEXT");
@@ -5674,7 +5994,7 @@ var PROJECT_LIFECYCLE_ACTIONS = /* @__PURE__ */ new Set([
5674
5994
  "cancelled",
5675
5995
  "reassigned"
5676
5996
  ]);
5677
- var DDL22 = `
5997
+ var DDL23 = `
5678
5998
  CREATE TABLE IF NOT EXISTS lt_task_work_items (
5679
5999
  id TEXT NOT NULL,
5680
6000
  tenant_id TEXT NOT NULL,
@@ -5748,7 +6068,7 @@ function assertLifecyclePage(query) {
5748
6068
  var LocalTaskWorkItemStore = class {
5749
6069
  constructor(db) {
5750
6070
  this.db = db;
5751
- ensureTable(db, DDL22);
6071
+ ensureTable(db, DDL23);
5752
6072
  this.ensureColumn("lt_task_work_items", "workspace_id", "workspace_id TEXT");
5753
6073
  this.ensureColumn("lt_task_work_items", "project_id", "project_id TEXT");
5754
6074
  this.ensureColumn("lt_task_work_items", "event_key", "event_key TEXT");
@@ -5945,7 +6265,7 @@ var LocalTaskWorkItemStore = class {
5945
6265
 
5946
6266
  // src/stores/LocalCapabilityBundleStore.ts
5947
6267
  import { randomUUID as randomUUID7 } from "crypto";
5948
- var DDL23 = `CREATE TABLE IF NOT EXISTS lt_capability_bundles (id TEXT NOT NULL, tenant_id TEXT NOT NULL, bundle_key TEXT NOT NULL, name TEXT NOT NULL, description TEXT, capabilities TEXT NOT NULL DEFAULT '[]', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, PRIMARY KEY (tenant_id, id), UNIQUE (tenant_id, bundle_key)); CREATE INDEX IF NOT EXISTS idx_lt_capability_bundles_tenant ON lt_capability_bundles(tenant_id);`;
6268
+ var DDL24 = `CREATE TABLE IF NOT EXISTS lt_capability_bundles (id TEXT NOT NULL, tenant_id TEXT NOT NULL, bundle_key TEXT NOT NULL, name TEXT NOT NULL, description TEXT, capabilities TEXT NOT NULL DEFAULT '[]', created_at TEXT NOT NULL, updated_at TEXT NOT NULL, PRIMARY KEY (tenant_id, id), UNIQUE (tenant_id, bundle_key)); CREATE INDEX IF NOT EXISTS idx_lt_capability_bundles_tenant ON lt_capability_bundles(tenant_id);`;
5949
6269
  var duplicateMessage = "Capability bundle key already exists for tenant";
5950
6270
  function map(row) {
5951
6271
  return { id: row.id, tenantId: row.tenant_id, key: row.bundle_key, name: row.name, description: row.description ?? void 0, capabilities: JSON.parse(row.capabilities), createdAt: parseISO(row.created_at).toISOString(), updatedAt: parseISO(row.updated_at).toISOString() };
@@ -5966,7 +6286,7 @@ var LocalCapabilityBundleStore = class {
5966
6286
  */
5967
6287
  constructor(db) {
5968
6288
  this.db = db;
5969
- ensureTable(db, DDL23);
6289
+ ensureTable(db, DDL24);
5970
6290
  }
5971
6291
  async listByTenant(tenantId) {
5972
6292
  return this.db.prepare("SELECT * FROM lt_capability_bundles WHERE tenant_id = ? ORDER BY created_at").all(tenantId).map(map);
@@ -6056,6 +6376,7 @@ async function createLocalStoreConfig(options = {}) {
6056
6376
  connection: new LocalConnectionStore(db),
6057
6377
  metrics: new LocalMetricsServerConfigStore(db),
6058
6378
  mcp: new LocalMcpServerConfigStore(db),
6379
+ modelProvider: new LocalModelProviderStore(db),
6059
6380
  workflowTracking: new LocalWorkflowTrackingStore(db),
6060
6381
  eval: new LocalEvalStore(db),
6061
6382
  channelBinding: new LocalChannelBindingStore(db),
@@ -6123,6 +6444,7 @@ export {
6123
6444
  LocalEvalStore,
6124
6445
  LocalMcpServerConfigStore,
6125
6446
  LocalMetricsServerConfigStore,
6447
+ LocalModelProviderStore,
6126
6448
  LocalOpenAuditStore,
6127
6449
  LocalProjectBotMembershipStore,
6128
6450
  LocalProjectMembershipStore,