@axiom-lattice/local-stores 3.1.21 → 3.1.22

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.js CHANGED
@@ -44,6 +44,7 @@ __export(index_exports, {
44
44
  LocalEvalStore: () => LocalEvalStore,
45
45
  LocalMcpServerConfigStore: () => LocalMcpServerConfigStore,
46
46
  LocalMetricsServerConfigStore: () => LocalMetricsServerConfigStore,
47
+ LocalModelProviderStore: () => LocalModelProviderStore,
47
48
  LocalOpenAuditStore: () => LocalOpenAuditStore,
48
49
  LocalProjectBotMembershipStore: () => LocalProjectBotMembershipStore,
49
50
  LocalProjectMembershipStore: () => LocalProjectMembershipStore,
@@ -2500,8 +2501,328 @@ function encryptEnvInConfig(config) {
2500
2501
  return { config: configCopy, isEnvEncrypted };
2501
2502
  }
2502
2503
 
2503
- // src/stores/LocalWorkflowTrackingStore.ts
2504
+ // src/stores/LocalModelProviderStore.ts
2505
+ var import_core3 = require("@axiom-lattice/core");
2504
2506
  var DDL12 = `
2507
+ CREATE TABLE IF NOT EXISTS lt_model_providers (
2508
+ id TEXT NOT NULL,
2509
+ tenant_id TEXT NOT NULL,
2510
+ name TEXT NOT NULL,
2511
+ display_name TEXT,
2512
+ protocol TEXT NOT NULL,
2513
+ api_style TEXT NOT NULL DEFAULT 'chat-completions',
2514
+ llm_provider TEXT NOT NULL,
2515
+ base_url TEXT NOT NULL,
2516
+ api_key_enc TEXT,
2517
+ api_key_hint TEXT,
2518
+ enabled INTEGER NOT NULL DEFAULT 1,
2519
+ status TEXT NOT NULL DEFAULT 'unknown',
2520
+ last_error TEXT,
2521
+ last_discovered_at TEXT,
2522
+ created_by TEXT,
2523
+ created_at TEXT NOT NULL,
2524
+ updated_at TEXT NOT NULL,
2525
+ PRIMARY KEY (tenant_id, id)
2526
+ );
2527
+ CREATE UNIQUE INDEX IF NOT EXISTS idx_lt_model_providers_name
2528
+ ON lt_model_providers(tenant_id, name);
2529
+
2530
+ CREATE TABLE IF NOT EXISTS lt_model_provider_models (
2531
+ id TEXT NOT NULL,
2532
+ tenant_id TEXT NOT NULL,
2533
+ provider_id TEXT NOT NULL,
2534
+ model_id TEXT NOT NULL,
2535
+ display_name TEXT,
2536
+ owned_by TEXT,
2537
+ upstream_created TEXT,
2538
+ enabled INTEGER NOT NULL DEFAULT 1,
2539
+ stale INTEGER NOT NULL DEFAULT 0,
2540
+ raw TEXT,
2541
+ discovered_at TEXT NOT NULL,
2542
+ PRIMARY KEY (tenant_id, provider_id, model_id)
2543
+ );
2544
+ CREATE INDEX IF NOT EXISTS idx_lt_model_provider_models_tenant
2545
+ ON lt_model_provider_models(tenant_id, model_id);
2546
+ `;
2547
+ var LocalModelProviderStore = class {
2548
+ constructor(db) {
2549
+ this.db = db;
2550
+ ensureTable(db, DDL12);
2551
+ this.ensureColumn(
2552
+ "lt_model_providers",
2553
+ "api_style",
2554
+ "api_style TEXT NOT NULL DEFAULT 'chat-completions'"
2555
+ );
2556
+ this.ensureColumn(
2557
+ "lt_model_provider_models",
2558
+ "stale",
2559
+ "stale INTEGER NOT NULL DEFAULT 0"
2560
+ );
2561
+ }
2562
+ /** Add a column if it does not exist (SQLite version compatible). */
2563
+ ensureColumn(table, column, ddl2) {
2564
+ const cols = this.db.prepare(`PRAGMA table_info(${table})`).all();
2565
+ if (!cols.some((c) => c.name === column)) {
2566
+ this.db.exec(`ALTER TABLE ${table} ADD COLUMN ${ddl2}`);
2567
+ }
2568
+ }
2569
+ async listProviders(tenantId) {
2570
+ const rows2 = this.db.prepare(
2571
+ `SELECT * FROM lt_model_providers WHERE tenant_id = ? ORDER BY created_at DESC`
2572
+ ).all(tenantId);
2573
+ return rows2.map((row) => mapRowToEntry4(row));
2574
+ }
2575
+ async getProviderById(tenantId, id) {
2576
+ const row = this.db.prepare(
2577
+ `SELECT * FROM lt_model_providers WHERE tenant_id = ? AND id = ?`
2578
+ ).get(tenantId, id);
2579
+ return row ? mapRowToEntry4(row) : null;
2580
+ }
2581
+ async getProviderByName(tenantId, name) {
2582
+ const row = this.db.prepare(
2583
+ `SELECT * FROM lt_model_providers WHERE tenant_id = ? AND name = ?`
2584
+ ).get(tenantId, name);
2585
+ return row ? mapRowToEntry4(row) : null;
2586
+ }
2587
+ async createProvider(tenantId, id, data) {
2588
+ const now = nowISO();
2589
+ this.db.prepare(
2590
+ `INSERT INTO lt_model_providers (
2591
+ id, tenant_id, name, display_name, protocol, api_style, llm_provider, base_url,
2592
+ api_key_enc, api_key_hint, enabled, status, created_at, updated_at
2593
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?, 'unknown', ?, ?)
2594
+ ON CONFLICT (tenant_id, id) DO UPDATE SET
2595
+ name = excluded.name,
2596
+ display_name = excluded.display_name,
2597
+ protocol = excluded.protocol,
2598
+ api_style = excluded.api_style,
2599
+ llm_provider = excluded.llm_provider,
2600
+ base_url = excluded.base_url,
2601
+ api_key_enc = excluded.api_key_enc,
2602
+ api_key_hint = excluded.api_key_hint,
2603
+ enabled = excluded.enabled,
2604
+ updated_at = excluded.updated_at`
2605
+ ).run(
2606
+ id,
2607
+ tenantId,
2608
+ data.name,
2609
+ data.displayName || null,
2610
+ data.protocol,
2611
+ data.apiStyle ?? "chat-completions",
2612
+ // Phase 1 pins the LLM provider (ADR-138 decision 7b)
2613
+ "openai",
2614
+ data.baseURL,
2615
+ data.apiKey ? (0, import_core3.encrypt)(data.apiKey) : null,
2616
+ data.apiKey ? data.apiKey.slice(-4) : null,
2617
+ data.enabled === false ? 0 : 1,
2618
+ now,
2619
+ now
2620
+ );
2621
+ const created = await this.getProviderById(tenantId, id);
2622
+ if (!created) {
2623
+ throw new Error("Failed to create model provider");
2624
+ }
2625
+ return created;
2626
+ }
2627
+ async updateProvider(tenantId, id, updates) {
2628
+ const existing = await this.getProviderById(tenantId, id);
2629
+ if (!existing) {
2630
+ return null;
2631
+ }
2632
+ const fields = [];
2633
+ const values = [];
2634
+ const set = (column, value) => {
2635
+ fields.push(`${column} = ?`);
2636
+ values.push(value);
2637
+ };
2638
+ if (updates.name !== void 0) set("name", updates.name);
2639
+ if (updates.displayName !== void 0) {
2640
+ set("display_name", updates.displayName || null);
2641
+ }
2642
+ if (updates.protocol !== void 0) set("protocol", updates.protocol);
2643
+ if (updates.apiStyle !== void 0) set("api_style", updates.apiStyle);
2644
+ if (updates.baseURL !== void 0) set("base_url", updates.baseURL);
2645
+ if (updates.enabled !== void 0) set("enabled", updates.enabled ? 1 : 0);
2646
+ if (updates.clearApiKey === true) {
2647
+ set("api_key_enc", null);
2648
+ set("api_key_hint", null);
2649
+ } else if (updates.apiKey) {
2650
+ set("api_key_enc", (0, import_core3.encrypt)(updates.apiKey));
2651
+ set("api_key_hint", updates.apiKey.slice(-4));
2652
+ }
2653
+ if (fields.length === 0) {
2654
+ return existing;
2655
+ }
2656
+ fields.push("updated_at = ?");
2657
+ values.push(nowISO(), tenantId, id);
2658
+ this.db.prepare(
2659
+ `UPDATE lt_model_providers SET ${fields.join(", ")}
2660
+ WHERE tenant_id = ? AND id = ?`
2661
+ ).run(...values);
2662
+ return this.getProviderById(tenantId, id);
2663
+ }
2664
+ async deleteProvider(tenantId, id) {
2665
+ await this.deleteModelsByProvider(tenantId, id);
2666
+ const result = this.db.prepare(`DELETE FROM lt_model_providers WHERE tenant_id = ? AND id = ?`).run(tenantId, id);
2667
+ return result.changes > 0;
2668
+ }
2669
+ async markProviderStatus(tenantId, id, status, lastError, discoveredAt) {
2670
+ this.db.prepare(
2671
+ `UPDATE lt_model_providers
2672
+ SET status = ?,
2673
+ last_error = ?,
2674
+ last_discovered_at = COALESCE(?, last_discovered_at),
2675
+ updated_at = ?
2676
+ WHERE tenant_id = ? AND id = ?`
2677
+ ).run(
2678
+ status,
2679
+ status === "ok" ? null : lastError || null,
2680
+ discoveredAt ? discoveredAt.toISOString() : null,
2681
+ nowISO(),
2682
+ tenantId,
2683
+ id
2684
+ );
2685
+ }
2686
+ async listModels(tenantId, providerId) {
2687
+ const rows2 = providerId ? this.db.prepare(
2688
+ `SELECT * FROM lt_model_provider_models
2689
+ WHERE tenant_id = ? AND provider_id = ? ORDER BY model_id ASC`
2690
+ ).all(tenantId, providerId) : this.db.prepare(
2691
+ `SELECT * FROM lt_model_provider_models
2692
+ WHERE tenant_id = ? ORDER BY model_id ASC`
2693
+ ).all(tenantId);
2694
+ return rows2.map((row) => mapRowToModel(row));
2695
+ }
2696
+ async getModel(tenantId, providerId, modelId) {
2697
+ const row = this.db.prepare(
2698
+ `SELECT * FROM lt_model_provider_models
2699
+ WHERE tenant_id = ? AND provider_id = ? AND model_id = ?`
2700
+ ).get(tenantId, providerId, modelId);
2701
+ return row ? mapRowToModel(row) : null;
2702
+ }
2703
+ /**
2704
+ * Replace a provider's model snapshot.
2705
+ *
2706
+ * Models the upstream no longer offers are deleted; survivors are upserted
2707
+ * without touching `enabled`, so the tenant's enable/disable choice survives.
2708
+ */
2709
+ async replaceProviderModels(tenantId, providerId, models) {
2710
+ const now = nowISO();
2711
+ const deduped = /* @__PURE__ */ new Map();
2712
+ for (const model of models) {
2713
+ deduped.set(model.id, model);
2714
+ }
2715
+ const rows2 = [...deduped.values()];
2716
+ if (rows2.length === 0) {
2717
+ await this.deleteModelsByProvider(tenantId, providerId);
2718
+ return [];
2719
+ }
2720
+ const current = new Map(
2721
+ (await this.listModels(tenantId, providerId)).map((model) => [
2722
+ model.modelId,
2723
+ model.enabled
2724
+ ])
2725
+ );
2726
+ const placeholders = rows2.map(() => "?").join(", ");
2727
+ this.db.prepare(
2728
+ `DELETE FROM lt_model_provider_models
2729
+ WHERE tenant_id = ? AND provider_id = ? AND model_id NOT IN (${placeholders})`
2730
+ ).run(tenantId, providerId, ...rows2.map((model) => model.id));
2731
+ for (const model of rows2) {
2732
+ this.db.prepare(
2733
+ `INSERT INTO lt_model_provider_models (
2734
+ id, tenant_id, provider_id, model_id, display_name, owned_by,
2735
+ upstream_created, raw, enabled, stale, discovered_at
2736
+ ) VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?, ?, ?)
2737
+ ON CONFLICT (tenant_id, provider_id, model_id) DO UPDATE SET
2738
+ display_name = excluded.display_name,
2739
+ owned_by = excluded.owned_by,
2740
+ upstream_created = excluded.upstream_created,
2741
+ raw = excluded.raw,
2742
+ enabled = excluded.enabled,
2743
+ stale = excluded.stale,
2744
+ discovered_at = excluded.discovered_at`
2745
+ ).run(
2746
+ `${providerId}:${model.id}`,
2747
+ tenantId,
2748
+ providerId,
2749
+ model.id,
2750
+ model.displayName || null,
2751
+ model.ownedBy || null,
2752
+ model.createdAt || null,
2753
+ model.raw === void 0 ? null : JSON.stringify(model.raw),
2754
+ model.enabled ?? current.get(model.id) ?? true ? 1 : 0,
2755
+ model.stale ? 1 : 0,
2756
+ now
2757
+ );
2758
+ }
2759
+ return rows2.map((model) => model.id);
2760
+ }
2761
+ async setModelEnabled(tenantId, providerId, modelId, enabled) {
2762
+ const result = this.db.prepare(
2763
+ `UPDATE lt_model_provider_models SET enabled = ?
2764
+ WHERE tenant_id = ? AND provider_id = ? AND model_id = ?`
2765
+ ).run(enabled ? 1 : 0, tenantId, providerId, modelId);
2766
+ if (result.changes === 0) {
2767
+ return null;
2768
+ }
2769
+ return this.getModel(tenantId, providerId, modelId);
2770
+ }
2771
+ async deleteModelsByProvider(tenantId, providerId) {
2772
+ const result = this.db.prepare(
2773
+ `DELETE FROM lt_model_provider_models
2774
+ WHERE tenant_id = ? AND provider_id = ?`
2775
+ ).run(tenantId, providerId);
2776
+ return result.changes;
2777
+ }
2778
+ };
2779
+ function mapRowToEntry4(row) {
2780
+ let apiKey;
2781
+ if (row.api_key_enc) {
2782
+ try {
2783
+ apiKey = (0, import_core3.decrypt)(row.api_key_enc);
2784
+ } catch (error) {
2785
+ console.error("Failed to decrypt model provider API key:", error);
2786
+ throw new Error("Failed to decrypt model provider API key");
2787
+ }
2788
+ }
2789
+ return {
2790
+ id: row.id,
2791
+ tenantId: row.tenant_id,
2792
+ name: row.name,
2793
+ displayName: row.display_name || void 0,
2794
+ protocol: row.protocol,
2795
+ apiStyle: row.api_style,
2796
+ llmProvider: row.llm_provider,
2797
+ baseURL: row.base_url,
2798
+ apiKey,
2799
+ apiKeyHint: row.api_key_hint || void 0,
2800
+ enabled: row.enabled === 1,
2801
+ status: row.status,
2802
+ lastError: row.last_error || void 0,
2803
+ lastDiscoveredAt: row.last_discovered_at ? parseISO(row.last_discovered_at) : void 0,
2804
+ createdBy: row.created_by || void 0,
2805
+ createdAt: parseISO(row.created_at),
2806
+ updatedAt: parseISO(row.updated_at)
2807
+ };
2808
+ }
2809
+ function mapRowToModel(row) {
2810
+ return {
2811
+ id: row.id,
2812
+ tenantId: row.tenant_id,
2813
+ providerId: row.provider_id,
2814
+ modelId: row.model_id,
2815
+ displayName: row.display_name || void 0,
2816
+ ownedBy: row.owned_by || void 0,
2817
+ upstreamCreatedAt: row.upstream_created ? parseISO(row.upstream_created) : void 0,
2818
+ enabled: row.enabled === 1,
2819
+ stale: row.stale === 1,
2820
+ discoveredAt: parseISO(row.discovered_at)
2821
+ };
2822
+ }
2823
+
2824
+ // src/stores/LocalWorkflowTrackingStore.ts
2825
+ var DDL13 = `
2505
2826
  CREATE TABLE IF NOT EXISTS lt_workflow_runs (
2506
2827
  id TEXT PRIMARY KEY,
2507
2828
  tenant_id TEXT NOT NULL,
@@ -2550,7 +2871,7 @@ ALTER TABLE lt_workflow_steps ADD COLUMN IF NOT EXISTS thread_id TEXT;
2550
2871
  var LocalWorkflowTrackingStore = class {
2551
2872
  constructor(db) {
2552
2873
  this.db = db;
2553
- ensureTable(db, DDL12);
2874
+ ensureTable(db, DDL13);
2554
2875
  }
2555
2876
  async createWorkflowRun(request) {
2556
2877
  const now = nowISO();
@@ -2841,7 +3162,7 @@ function mapRowToStep(row) {
2841
3162
 
2842
3163
  // src/stores/LocalEvalStore.ts
2843
3164
  var import_crypto = require("crypto");
2844
- var DDL13 = `
3165
+ var DDL14 = `
2845
3166
  CREATE TABLE IF NOT EXISTS lt_eval_projects (
2846
3167
  id TEXT NOT NULL,
2847
3168
  tenant_id TEXT NOT NULL,
@@ -2951,7 +3272,7 @@ function parseOptionalJson(val) {
2951
3272
  var LocalEvalStore = class {
2952
3273
  constructor(db) {
2953
3274
  this.db = db;
2954
- ensureTable(db, DDL13);
3275
+ ensureTable(db, DDL14);
2955
3276
  this.ensureColumn("lt_eval_runs", "interrupted_cases", "interrupted_cases INTEGER NOT NULL DEFAULT 0");
2956
3277
  this.ensureColumn("lt_eval_run_results", "interrupted", "interrupted INTEGER NOT NULL DEFAULT 0");
2957
3278
  this.ensureColumn("lt_eval_cases", "interrupt_policy", "interrupt_policy TEXT");
@@ -3580,7 +3901,7 @@ function mapConflict(row) {
3580
3901
  }
3581
3902
 
3582
3903
  // src/stores/LocalChannelBindingStore.ts
3583
- var DDL14 = `
3904
+ var DDL15 = `
3584
3905
  CREATE TABLE IF NOT EXISTS lt_channel_bindings (
3585
3906
  id TEXT PRIMARY KEY,
3586
3907
  channel TEXT NOT NULL,
@@ -3602,7 +3923,7 @@ CREATE TABLE IF NOT EXISTS lt_channel_bindings (
3602
3923
  var LocalChannelBindingStore = class {
3603
3924
  constructor(db) {
3604
3925
  this.db = db;
3605
- ensureTable(db, DDL14);
3926
+ ensureTable(db, DDL15);
3606
3927
  ensureChannelBindingSubjectIndex(db);
3607
3928
  }
3608
3929
  async findById(tenantId, id) {
@@ -3782,7 +4103,7 @@ function mapRowToBinding(row) {
3782
4103
  }
3783
4104
 
3784
4105
  // src/stores/LocalChannelInstallationStore.ts
3785
- var DDL15 = `
4106
+ var DDL16 = `
3786
4107
  CREATE TABLE IF NOT EXISTS lt_channel_installations (
3787
4108
  id TEXT PRIMARY KEY,
3788
4109
  tenant_id TEXT NOT NULL,
@@ -3800,7 +4121,7 @@ CREATE INDEX IF NOT EXISTS idx_lt_ci_tenant ON lt_channel_installations(tenant_i
3800
4121
  var LocalChannelInstallationStore = class {
3801
4122
  constructor(db) {
3802
4123
  this.db = db;
3803
- ensureTable(db, DDL15);
4124
+ ensureTable(db, DDL16);
3804
4125
  }
3805
4126
  async getInstallationById(installationId) {
3806
4127
  const row = this.db.prepare(
@@ -3924,9 +4245,9 @@ function mapRow6(row) {
3924
4245
  }
3925
4246
 
3926
4247
  // src/stores/LocalA2AApiKeyStore.ts
3927
- var import_core3 = require("@axiom-lattice/core");
4248
+ var import_core4 = require("@axiom-lattice/core");
3928
4249
  var import_crypto3 = require("crypto");
3929
- var DDL16 = `
4250
+ var DDL17 = `
3930
4251
  CREATE TABLE IF NOT EXISTS lt_a2a_api_keys (
3931
4252
  id TEXT PRIMARY KEY,
3932
4253
  key_value TEXT NOT NULL,
@@ -3964,7 +4285,7 @@ function parseAssistantIds(raw) {
3964
4285
  var LocalA2AApiKeyStore = class {
3965
4286
  constructor(db) {
3966
4287
  this.db = db;
3967
- ensureTable(db, DDL16);
4288
+ ensureTable(db, DDL17);
3968
4289
  this.ensureColumn("lt_a2a_api_keys", "assistant_ids", "assistant_ids TEXT");
3969
4290
  this.ensureColumn("lt_a2a_api_keys", "grants", "grants TEXT");
3970
4291
  this.repairManagementIds();
@@ -3995,7 +4316,7 @@ var LocalA2AApiKeyStore = class {
3995
4316
  ).all();
3996
4317
  for (const row of rows2) {
3997
4318
  try {
3998
- if ((0, import_core3.decrypt)(row.key_value) === key) return mapRowToRecord(row);
4319
+ if ((0, import_core4.decrypt)(row.key_value) === key) return mapRowToRecord(row);
3999
4320
  } catch {
4000
4321
  }
4001
4322
  }
@@ -4029,7 +4350,7 @@ var LocalA2AApiKeyStore = class {
4029
4350
  this.db.prepare(
4030
4351
  `INSERT INTO lt_a2a_api_keys (id, key_value, tenant_id, project_id, assistant_ids, grants, label, created_at, updated_at)
4031
4352
  VALUES (?, ?, ?, ?, ?, ?, ?, ?, ?)`
4032
- ).run(id, (0, import_core3.encrypt)(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.grants ? JSON.stringify(input.grants) : null, input.label || null, now, now);
4353
+ ).run(id, (0, import_core4.encrypt)(key), input.tenantId, input.projectId, input.assistantIds ? JSON.stringify(input.assistantIds) : null, input.grants ? JSON.stringify(input.grants) : null, input.label || null, now, now);
4033
4354
  const record2 = {
4034
4355
  id,
4035
4356
  key,
@@ -4098,7 +4419,7 @@ var LocalA2AApiKeyStore = class {
4098
4419
  const now = nowISO();
4099
4420
  this.db.prepare(
4100
4421
  `UPDATE lt_a2a_api_keys SET key_value = ?, updated_at = ? WHERE id = ?`
4101
- ).run((0, import_core3.encrypt)(key), now, id);
4422
+ ).run((0, import_core4.encrypt)(key), now, id);
4102
4423
  const row = this.db.prepare(`SELECT * FROM lt_a2a_api_keys WHERE id = ?`).get(id);
4103
4424
  if (!row) throw new Error(`A2A API key not found: ${id}`);
4104
4425
  const record2 = mapRowToRecord(row);
@@ -4115,7 +4436,7 @@ var LocalA2AApiKeyStore = class {
4115
4436
  const map2 = /* @__PURE__ */ new Map();
4116
4437
  for (const row of rows2) {
4117
4438
  try {
4118
- const key = (0, import_core3.decrypt)(row.key_value);
4439
+ const key = (0, import_core4.decrypt)(row.key_value);
4119
4440
  map2.set(key, {
4120
4441
  key,
4121
4442
  tenantId: row.tenant_id,
@@ -4131,7 +4452,7 @@ var LocalA2AApiKeyStore = class {
4131
4452
  function mapRowToRecord(row) {
4132
4453
  let key = "";
4133
4454
  try {
4134
- key = (0, import_core3.decrypt)(row.key_value);
4455
+ key = (0, import_core4.decrypt)(row.key_value);
4135
4456
  } catch {
4136
4457
  key = row.key_value;
4137
4458
  }
@@ -4151,7 +4472,7 @@ function mapRowToRecord(row) {
4151
4472
 
4152
4473
  // src/stores/LocalOpenAuditStore.ts
4153
4474
  var import_crypto4 = require("crypto");
4154
- var DDL17 = `
4475
+ var DDL18 = `
4155
4476
  CREATE TABLE IF NOT EXISTS lt_open_audit (
4156
4477
  id TEXT PRIMARY KEY,
4157
4478
  tenant_id TEXT NOT NULL,
@@ -4170,7 +4491,7 @@ CREATE TABLE IF NOT EXISTS lt_open_audit (
4170
4491
  var LocalOpenAuditStore = class {
4171
4492
  constructor(db) {
4172
4493
  this.db = db;
4173
- ensureTable(db, DDL17);
4494
+ ensureTable(db, DDL18);
4174
4495
  }
4175
4496
  async query(params) {
4176
4497
  const clauses = ["tenant_id = ?"];
@@ -4242,7 +4563,7 @@ var LocalOpenAuditStore = class {
4242
4563
  // src/stores/LocalThreadMessageQueueStore.ts
4243
4564
  var import_protocols4 = require("@axiom-lattice/protocols");
4244
4565
  var import_crypto5 = require("crypto");
4245
- var DDL18 = `
4566
+ var DDL19 = `
4246
4567
  CREATE TABLE IF NOT EXISTS lt_thread_message_queue (
4247
4568
  id TEXT PRIMARY KEY,
4248
4569
  thread_id TEXT NOT NULL,
@@ -4268,7 +4589,7 @@ var LocalThreadMessageQueueStore = class {
4268
4589
  constructor(db) {
4269
4590
  this.capacityTail = Promise.resolve();
4270
4591
  this.db = db;
4271
- ensureTable(db, DDL18);
4592
+ ensureTable(db, DDL19);
4272
4593
  const columns6 = db.prepare("PRAGMA table_info(lt_thread_message_queue)").all();
4273
4594
  const names = new Set(columns6.map(({ name }) => name));
4274
4595
  if (!names.has("trusted_run_context")) {
@@ -4481,7 +4802,7 @@ function rowToMessage(row) {
4481
4802
  }
4482
4803
 
4483
4804
  // src/stores/LocalSkillStore.ts
4484
- var DDL19 = `
4805
+ var DDL20 = `
4485
4806
  CREATE TABLE IF NOT EXISTS lt_skills (
4486
4807
  id TEXT NOT NULL,
4487
4808
  tenant_id TEXT NOT NULL,
@@ -4500,7 +4821,7 @@ CREATE TABLE IF NOT EXISTS lt_skills (
4500
4821
  var LocalSkillStore = class {
4501
4822
  constructor(db) {
4502
4823
  this.db = db;
4503
- ensureTable(db, DDL19);
4824
+ ensureTable(db, DDL20);
4504
4825
  }
4505
4826
  async getAllSkills(tenantId, _context) {
4506
4827
  const rows2 = this.db.prepare(
@@ -4650,7 +4971,7 @@ function mapRowToSkill(row) {
4650
4971
  }
4651
4972
 
4652
4973
  // src/stores/LocalScheduleStorage.ts
4653
- var DDL20 = `
4974
+ var DDL21 = `
4654
4975
  CREATE TABLE IF NOT EXISTS lt_scheduled_tasks (
4655
4976
  task_id TEXT PRIMARY KEY,
4656
4977
  task_type TEXT NOT NULL,
@@ -4683,7 +5004,7 @@ CREATE INDEX IF NOT EXISTS idx_lt_st_tenant ON lt_scheduled_tasks(tenant_id);
4683
5004
  var LocalScheduleStorage = class {
4684
5005
  constructor(db) {
4685
5006
  this.db = db;
4686
- ensureTable(db, DDL20);
5007
+ ensureTable(db, DDL21);
4687
5008
  }
4688
5009
  async save(task) {
4689
5010
  this.db.prepare(
@@ -4994,7 +5315,7 @@ var NEXT_UPDATED_AT_SQL = `updated_at = CASE
4994
5315
  THEN strftime('%Y-%m-%dT%H:%M:%fZ', updated_at, '+0.001 seconds')
4995
5316
  ELSE ?
4996
5317
  END`;
4997
- var DDL21 = `
5318
+ var DDL22 = `
4998
5319
  CREATE TABLE IF NOT EXISTS lt_tasks (
4999
5320
  id TEXT NOT NULL,
5000
5321
  tenant_id TEXT NOT NULL,
@@ -5067,7 +5388,7 @@ function assertPage(limit, offset = 0) {
5067
5388
  var LocalTaskStore = class {
5068
5389
  constructor(db) {
5069
5390
  this.db = db;
5070
- ensureTable(db, DDL21);
5391
+ ensureTable(db, DDL22);
5071
5392
  this.ensureColumn("lt_tasks", "require_review", "require_review INTEGER DEFAULT 0");
5072
5393
  this.ensureColumn("lt_tasks", "dependencies", "dependencies TEXT");
5073
5394
  this.ensureColumn("lt_tasks", "result", "result TEXT");
@@ -5747,7 +6068,7 @@ var PROJECT_LIFECYCLE_ACTIONS = /* @__PURE__ */ new Set([
5747
6068
  "cancelled",
5748
6069
  "reassigned"
5749
6070
  ]);
5750
- var DDL22 = `
6071
+ var DDL23 = `
5751
6072
  CREATE TABLE IF NOT EXISTS lt_task_work_items (
5752
6073
  id TEXT NOT NULL,
5753
6074
  tenant_id TEXT NOT NULL,
@@ -5821,7 +6142,7 @@ function assertLifecyclePage(query) {
5821
6142
  var LocalTaskWorkItemStore = class {
5822
6143
  constructor(db) {
5823
6144
  this.db = db;
5824
- ensureTable(db, DDL22);
6145
+ ensureTable(db, DDL23);
5825
6146
  this.ensureColumn("lt_task_work_items", "workspace_id", "workspace_id TEXT");
5826
6147
  this.ensureColumn("lt_task_work_items", "project_id", "project_id TEXT");
5827
6148
  this.ensureColumn("lt_task_work_items", "event_key", "event_key TEXT");
@@ -6018,7 +6339,7 @@ var LocalTaskWorkItemStore = class {
6018
6339
 
6019
6340
  // src/stores/LocalCapabilityBundleStore.ts
6020
6341
  var import_crypto7 = require("crypto");
6021
- 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);`;
6342
+ 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);`;
6022
6343
  var duplicateMessage = "Capability bundle key already exists for tenant";
6023
6344
  function map(row) {
6024
6345
  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() };
@@ -6039,7 +6360,7 @@ var LocalCapabilityBundleStore = class {
6039
6360
  */
6040
6361
  constructor(db) {
6041
6362
  this.db = db;
6042
- ensureTable(db, DDL23);
6363
+ ensureTable(db, DDL24);
6043
6364
  }
6044
6365
  async listByTenant(tenantId) {
6045
6366
  return this.db.prepare("SELECT * FROM lt_capability_bundles WHERE tenant_id = ? ORDER BY created_at").all(tenantId).map(map);
@@ -6129,6 +6450,7 @@ async function createLocalStoreConfig(options = {}) {
6129
6450
  connection: new LocalConnectionStore(db),
6130
6451
  metrics: new LocalMetricsServerConfigStore(db),
6131
6452
  mcp: new LocalMcpServerConfigStore(db),
6453
+ modelProvider: new LocalModelProviderStore(db),
6132
6454
  workflowTracking: new LocalWorkflowTrackingStore(db),
6133
6455
  eval: new LocalEvalStore(db),
6134
6456
  channelBinding: new LocalChannelBindingStore(db),
@@ -6197,6 +6519,7 @@ var InMemoryConversationStore = class {
6197
6519
  LocalEvalStore,
6198
6520
  LocalMcpServerConfigStore,
6199
6521
  LocalMetricsServerConfigStore,
6522
+ LocalModelProviderStore,
6200
6523
  LocalOpenAuditStore,
6201
6524
  LocalProjectBotMembershipStore,
6202
6525
  LocalProjectMembershipStore,