@steno-ai/mcp 0.1.3 → 0.1.4

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.
Files changed (3) hide show
  1. package/dist/cli.js +830 -921
  2. package/package.json +3 -5
  3. package/src/cli.ts +10 -46
package/dist/cli.js CHANGED
@@ -1,5 +1,5 @@
1
1
  #!/usr/bin/env node
2
- #\!/usr/bin/env node
2
+ #!/usr/bin/env node
3
3
  var __defProp = Object.defineProperty;
4
4
  var __getOwnPropNames = Object.getOwnPropertyNames;
5
5
  var __esm = (fn, res) => function __init() {
@@ -24753,887 +24753,6 @@ var init_manager = __esm({
24753
24753
  }
24754
24754
  });
24755
24755
 
24756
- // packages/supabase-adapter/src/storage.js
24757
- function camelToSnake(key) {
24758
- return key.replace(/([A-Z])/g, (match2) => `_${match2.toLowerCase()}`);
24759
- }
24760
- function snakeToCamel(key) {
24761
- return key.replace(/_([a-z])/g, (_2, char) => char.toUpperCase());
24762
- }
24763
- function toSnakeCase(obj) {
24764
- const result = {};
24765
- for (const [key, value] of Object.entries(obj)) {
24766
- result[camelToSnake(key)] = value;
24767
- }
24768
- return result;
24769
- }
24770
- function toCamelCase(obj) {
24771
- const result = {};
24772
- for (const [key, value] of Object.entries(obj)) {
24773
- result[snakeToCamel(key)] = value;
24774
- }
24775
- return result;
24776
- }
24777
- function throwSupabaseError(method, error) {
24778
- throw new Error(`SupabaseStorageAdapter.${method}() failed: ${error?.message ?? "unknown error"}`);
24779
- }
24780
- var SupabaseStorageAdapter;
24781
- var init_storage = __esm({
24782
- "packages/supabase-adapter/src/storage.js"() {
24783
- "use strict";
24784
- SupabaseStorageAdapter = class {
24785
- client;
24786
- constructor(client) {
24787
- this.client = client;
24788
- }
24789
- async ping() {
24790
- const { error } = await this.client.from("tenants").select("id").limit(1);
24791
- return !error;
24792
- }
24793
- // ---------------------------------------------------------------------------
24794
- // Tenants
24795
- // ---------------------------------------------------------------------------
24796
- async createTenant(tenant) {
24797
- const row = toSnakeCase(tenant);
24798
- const { data, error } = await this.client.from("tenants").insert(row).select().single();
24799
- if (error)
24800
- throwSupabaseError("createTenant", error);
24801
- return toCamelCase(data);
24802
- }
24803
- async getTenant(id) {
24804
- const { data, error } = await this.client.from("tenants").select("*").eq("id", id).maybeSingle();
24805
- if (error)
24806
- throwSupabaseError("getTenant", error);
24807
- if (!data)
24808
- return null;
24809
- return toCamelCase(data);
24810
- }
24811
- async getTenantBySlug(slug) {
24812
- const { data, error } = await this.client.from("tenants").select("*").eq("slug", slug).maybeSingle();
24813
- if (error)
24814
- throwSupabaseError("getTenantBySlug", error);
24815
- if (!data)
24816
- return null;
24817
- return toCamelCase(data);
24818
- }
24819
- async updateTenant(id, updates) {
24820
- const row = toSnakeCase(updates);
24821
- const { data, error } = await this.client.from("tenants").update(row).eq("id", id).select().single();
24822
- if (error)
24823
- throwSupabaseError("updateTenant", error);
24824
- return toCamelCase(data);
24825
- }
24826
- // ---------------------------------------------------------------------------
24827
- // API Keys
24828
- // ---------------------------------------------------------------------------
24829
- async createApiKey(apiKey) {
24830
- const row = toSnakeCase(apiKey);
24831
- const { data, error } = await this.client.from("api_keys").insert(row).select().single();
24832
- if (error)
24833
- throwSupabaseError("createApiKey", error);
24834
- return toCamelCase(data);
24835
- }
24836
- async getApiKeyByPrefix(prefix5) {
24837
- const { data, error } = await this.client.from("api_keys").select("*").eq("key_prefix", prefix5).eq("active", true).maybeSingle();
24838
- if (error)
24839
- throwSupabaseError("getApiKeyByPrefix", error);
24840
- if (!data)
24841
- return null;
24842
- return toCamelCase(data);
24843
- }
24844
- async getApiKeysForTenant(tenantId) {
24845
- const { data, error } = await this.client.from("api_keys").select("*").eq("tenant_id", tenantId);
24846
- if (error)
24847
- throwSupabaseError("getApiKeysForTenant", error);
24848
- return (data ?? []).map((row) => toCamelCase(row));
24849
- }
24850
- async revokeApiKey(tenantId, id) {
24851
- const { error } = await this.client.from("api_keys").update({ active: false }).eq("id", id).eq("tenant_id", tenantId);
24852
- if (error)
24853
- throwSupabaseError("revokeApiKey", error);
24854
- }
24855
- async updateApiKeyLastUsed(id) {
24856
- const { error } = await this.client.from("api_keys").update({ last_used_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", id);
24857
- if (error)
24858
- throwSupabaseError("updateApiKeyLastUsed", error);
24859
- }
24860
- // ---------------------------------------------------------------------------
24861
- // Extractions
24862
- // ---------------------------------------------------------------------------
24863
- async createExtraction(extraction) {
24864
- const row = toSnakeCase({
24865
- ...extraction,
24866
- status: "queued"
24867
- });
24868
- const { data, error } = await this.client.from("extractions").insert(row).select().single();
24869
- if (error)
24870
- throwSupabaseError("createExtraction", error);
24871
- return toCamelCase(data);
24872
- }
24873
- async getExtraction(tenantId, id) {
24874
- const { data, error } = await this.client.from("extractions").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
24875
- if (error)
24876
- throwSupabaseError("getExtraction", error);
24877
- if (!data)
24878
- return null;
24879
- return toCamelCase(data);
24880
- }
24881
- async updateExtraction(tenantId, id, updates) {
24882
- const row = toSnakeCase(updates);
24883
- const { data, error } = await this.client.from("extractions").update(row).eq("tenant_id", tenantId).eq("id", id).select().single();
24884
- if (error)
24885
- throwSupabaseError("updateExtraction", error);
24886
- return toCamelCase(data);
24887
- }
24888
- async getExtractionByHash(tenantId, inputHash) {
24889
- const { data, error } = await this.client.from("extractions").select("*").eq("tenant_id", tenantId).eq("input_hash", inputHash).maybeSingle();
24890
- if (error)
24891
- throwSupabaseError("getExtractionByHash", error);
24892
- if (!data)
24893
- return null;
24894
- return toCamelCase(data);
24895
- }
24896
- async getExtractionsByTenant(tenantId, options) {
24897
- const { limit, cursor } = options;
24898
- let query = this.client.from("extractions").select("*").eq("tenant_id", tenantId).order("created_at", { ascending: false }).limit(limit + 1);
24899
- if (cursor) {
24900
- query = query.lt("created_at", cursor);
24901
- }
24902
- const { data, error } = await query;
24903
- if (error)
24904
- throwSupabaseError("getExtractionsByTenant", error);
24905
- const rows = data ?? [];
24906
- const hasMore = rows.length > limit;
24907
- const page = hasMore ? rows.slice(0, limit) : rows;
24908
- const extractions = page.map((row) => toCamelCase(row));
24909
- const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["created_at"] : null;
24910
- return { data: extractions, cursor: nextCursor, hasMore };
24911
- }
24912
- // ---------------------------------------------------------------------------
24913
- // Facts
24914
- // ---------------------------------------------------------------------------
24915
- async createFact(fact) {
24916
- const { embedding, ...rest } = fact;
24917
- const row = toSnakeCase(rest);
24918
- if (!("version" in row)) {
24919
- row["version"] = 1;
24920
- }
24921
- if (!row["lineage_id"]) {
24922
- row["lineage_id"] = fact.id;
24923
- }
24924
- if (embedding !== void 0) {
24925
- row["embedding"] = `[${embedding.join(",")}]`;
24926
- }
24927
- const { data, error } = await this.client.from("facts").insert(row).select().single();
24928
- if (error)
24929
- throwSupabaseError("createFact", error);
24930
- return toCamelCase(data);
24931
- }
24932
- async getFact(tenantId, id) {
24933
- const { data, error } = await this.client.from("facts").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
24934
- if (error)
24935
- throwSupabaseError("getFact", error);
24936
- if (!data)
24937
- return null;
24938
- return toCamelCase(data);
24939
- }
24940
- async getFactsByIds(tenantId, ids) {
24941
- if (ids.length === 0)
24942
- return [];
24943
- const { data, error } = await this.client.from("facts").select("*").eq("tenant_id", tenantId).in("id", ids);
24944
- if (error)
24945
- throwSupabaseError("getFactsByIds", error);
24946
- return (data ?? []).map((row) => toCamelCase(row));
24947
- }
24948
- async getFactsByLineage(tenantId, lineageId) {
24949
- const { data, error } = await this.client.from("facts").select("*").eq("tenant_id", tenantId).eq("lineage_id", lineageId).order("version", { ascending: true });
24950
- if (error)
24951
- throwSupabaseError("getFactsByLineage", error);
24952
- return (data ?? []).map((row) => toCamelCase(row));
24953
- }
24954
- async invalidateFact(tenantId, id) {
24955
- const { error } = await this.client.from("facts").update({ valid_until: (/* @__PURE__ */ new Date()).toISOString() }).eq("tenant_id", tenantId).eq("id", id);
24956
- if (error)
24957
- throwSupabaseError("invalidateFact", error);
24958
- }
24959
- // ---------------------------------------------------------------------------
24960
- // Entities
24961
- // ---------------------------------------------------------------------------
24962
- async createEntity(entity2) {
24963
- const { embedding, ...rest } = entity2;
24964
- const row = toSnakeCase(rest);
24965
- if (embedding !== void 0) {
24966
- row["embedding"] = `[${embedding.join(",")}]`;
24967
- }
24968
- const { data, error } = await this.client.from("entities").insert(row).select().single();
24969
- if (error)
24970
- throwSupabaseError("createEntity", error);
24971
- return toCamelCase(data);
24972
- }
24973
- async getEntity(tenantId, id) {
24974
- const { data, error } = await this.client.from("entities").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
24975
- if (error)
24976
- throwSupabaseError("getEntity", error);
24977
- if (!data)
24978
- return null;
24979
- return toCamelCase(data);
24980
- }
24981
- async findEntityByCanonicalName(tenantId, canonicalName, entityType) {
24982
- const { data, error } = await this.client.from("entities").select("*").eq("tenant_id", tenantId).eq("canonical_name", canonicalName).eq("entity_type", entityType).maybeSingle();
24983
- if (error)
24984
- throwSupabaseError("findEntityByCanonicalName", error);
24985
- if (!data)
24986
- return null;
24987
- return toCamelCase(data);
24988
- }
24989
- async findEntitiesByEmbedding(tenantId, embedding, limit, minSimilarity = 0.3) {
24990
- const { data, error } = await this.client.rpc("match_entities", {
24991
- query_embedding: JSON.stringify(embedding),
24992
- match_tenant_id: tenantId,
24993
- match_count: limit,
24994
- min_similarity: minSimilarity
24995
- });
24996
- if (error)
24997
- throwSupabaseError("findEntitiesByEmbedding", error);
24998
- return (data ?? []).map((row) => ({
24999
- entity: toCamelCase(row),
25000
- similarity: row["similarity"]
25001
- }));
25002
- }
25003
- // ---------------------------------------------------------------------------
25004
- // Fact-Entity junction
25005
- // ---------------------------------------------------------------------------
25006
- async linkFactEntity(factId, entityId, role) {
25007
- const { error } = await this.client.from("fact_entities").insert({
25008
- fact_id: factId,
25009
- entity_id: entityId,
25010
- role
25011
- });
25012
- if (error)
25013
- throwSupabaseError("linkFactEntity", error);
25014
- }
25015
- // ---------------------------------------------------------------------------
25016
- // Edges
25017
- // ---------------------------------------------------------------------------
25018
- async createEdge(edge) {
25019
- const row = toSnakeCase(edge);
25020
- const { data, error } = await this.client.from("edges").insert(row).select().single();
25021
- if (error)
25022
- throwSupabaseError("createEdge", error);
25023
- return toCamelCase(data);
25024
- }
25025
- // ---------------------------------------------------------------------------
25026
- // Vector search
25027
- // ---------------------------------------------------------------------------
25028
- async vectorSearch(options) {
25029
- const { embedding, tenantId, scope, scopeId, limit, minSimilarity } = options;
25030
- const { data, error } = await this.client.rpc("match_facts", {
25031
- query_embedding: `[${embedding.join(",")}]`,
25032
- match_tenant_id: tenantId,
25033
- match_scope: scope,
25034
- match_scope_id: scopeId,
25035
- match_count: limit,
25036
- min_similarity: minSimilarity ?? 0,
25037
- match_as_of: options.asOf?.toISOString() ?? null
25038
- });
25039
- if (error)
25040
- throwSupabaseError("vectorSearch", error);
25041
- return (data ?? []).map((row) => ({
25042
- fact: toCamelCase(row),
25043
- similarity: row["similarity"]
25044
- }));
25045
- }
25046
- // ---------------------------------------------------------------------------
25047
- // Usage
25048
- // ---------------------------------------------------------------------------
25049
- async incrementUsage(tenantId, tokens, queries, extractions, costUsd) {
25050
- const { error } = await this.client.rpc("increment_usage", {
25051
- p_tenant_id: tenantId,
25052
- p_tokens: tokens,
25053
- p_queries: queries,
25054
- p_extractions: extractions,
25055
- p_cost_usd: costUsd
25056
- });
25057
- if (error)
25058
- throwSupabaseError("incrementUsage", error);
25059
- }
25060
- async getUsage(tenantId, periodStart) {
25061
- const { data, error } = await this.client.from("usage_records").select("*").eq("tenant_id", tenantId).eq("period_start", periodStart.toISOString()).maybeSingle();
25062
- if (error)
25063
- throwSupabaseError("getUsage", error);
25064
- if (!data)
25065
- return null;
25066
- return toCamelCase(data);
25067
- }
25068
- async getCurrentUsage(tenantId) {
25069
- const now = /* @__PURE__ */ new Date();
25070
- const periodStart = new Date(now.getFullYear(), now.getMonth(), 1);
25071
- return this.getUsage(tenantId, periodStart);
25072
- }
25073
- // ---------------------------------------------------------------------------
25074
- // Stubs — implemented in Plan 3 (Retrieval Engine)
25075
- // ---------------------------------------------------------------------------
25076
- async getFactsByScope(tenantId, scope, scopeId, options) {
25077
- const { limit, cursor } = options;
25078
- let query = this.client.from("facts").select("*").eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId).order("created_at", { ascending: false }).limit(limit + 1);
25079
- if (cursor) {
25080
- query = query.lt("created_at", cursor);
25081
- }
25082
- const { data, error } = await query;
25083
- if (error)
25084
- throwSupabaseError("getFactsByScope", error);
25085
- const rows = data ?? [];
25086
- const hasMore = rows.length > limit;
25087
- const page = hasMore ? rows.slice(0, limit) : rows;
25088
- const facts = page.map((row) => toCamelCase(row));
25089
- const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["created_at"] : null;
25090
- return { data: facts, cursor: nextCursor, hasMore };
25091
- }
25092
- async purgeFacts(tenantId, scope, scopeId) {
25093
- const { data: factRows, error: fetchError } = await this.client.from("facts").select("id").eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId);
25094
- if (fetchError)
25095
- throwSupabaseError("purgeFacts", fetchError);
25096
- const factIds = (factRows ?? []).map((row) => row["id"]);
25097
- if (factIds.length === 0)
25098
- return 0;
25099
- const { error: feError } = await this.client.from("fact_entities").delete().in("fact_id", factIds);
25100
- if (feError)
25101
- throwSupabaseError("purgeFacts", feError);
25102
- const { error: edgeError } = await this.client.from("edges").delete().in("fact_id", factIds);
25103
- if (edgeError)
25104
- throwSupabaseError("purgeFacts", edgeError);
25105
- const { error: deleteError } = await this.client.from("facts").delete().eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId);
25106
- if (deleteError)
25107
- throwSupabaseError("purgeFacts", deleteError);
25108
- const { error: extractionError } = await this.client.from("extractions").delete().eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId);
25109
- if (extractionError)
25110
- throwSupabaseError("purgeFacts", extractionError);
25111
- return factIds.length;
25112
- }
25113
- async updateDecayScores(tenantId, facts) {
25114
- for (const fact of facts) {
25115
- const updates = {
25116
- decay_score: fact.decayScore
25117
- };
25118
- if (fact.lastAccessed !== void 0) {
25119
- updates["last_accessed"] = fact.lastAccessed.toISOString();
25120
- }
25121
- if (fact.frequency !== void 0) {
25122
- updates["frequency"] = fact.frequency;
25123
- }
25124
- if (fact.importance !== void 0) {
25125
- updates["importance"] = fact.importance;
25126
- }
25127
- const { error } = await this.client.from("facts").update(updates).eq("tenant_id", tenantId).eq("id", fact.id);
25128
- if (error)
25129
- throwSupabaseError("updateDecayScores", error);
25130
- }
25131
- }
25132
- async keywordSearch(options) {
25133
- const { query, tenantId, scope, scopeId, limit, asOf } = options;
25134
- const { data, error } = await this.client.rpc("keyword_search_facts", {
25135
- search_query: query,
25136
- match_tenant_id: tenantId,
25137
- match_scope: scope,
25138
- match_scope_id: scopeId,
25139
- match_count: limit,
25140
- match_as_of: asOf?.toISOString() ?? null
25141
- });
25142
- if (error)
25143
- throwSupabaseError("keywordSearch", error);
25144
- return (data ?? []).map((row) => {
25145
- const rankScore = row["rank_score"];
25146
- const converted = toCamelCase(row);
25147
- return {
25148
- fact: converted,
25149
- rankScore
25150
- };
25151
- });
25152
- }
25153
- async compoundSearch(options) {
25154
- const { data, error } = await this.client.rpc("steno_search", {
25155
- query_embedding: `[${options.embedding.join(",")}]`,
25156
- search_query: options.query,
25157
- match_tenant_id: options.tenantId,
25158
- match_scope: options.scope,
25159
- match_scope_id: options.scopeId,
25160
- match_count: options.limit,
25161
- min_similarity: options.minSimilarity ?? 0
25162
- });
25163
- if (error)
25164
- throwSupabaseError("compoundSearch", error);
25165
- return (data ?? []).map((row) => ({
25166
- source: row["source"],
25167
- fact: toCamelCase(row),
25168
- relevanceScore: row["relevance_score"]
25169
- }));
25170
- }
25171
- async getEntitiesForTenant(tenantId, options) {
25172
- const { limit, cursor } = options;
25173
- let query = this.client.from("entities").select("*").eq("tenant_id", tenantId).order("created_at", { ascending: true }).limit(limit + 1);
25174
- if (cursor) {
25175
- query = query.gt("created_at", cursor);
25176
- }
25177
- const { data, error } = await query;
25178
- if (error)
25179
- throwSupabaseError("getEntitiesForTenant", error);
25180
- const rows = data ?? [];
25181
- const hasMore = rows.length > limit;
25182
- const page = hasMore ? rows.slice(0, limit) : rows;
25183
- const entities = page.map((row) => toCamelCase(row));
25184
- const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["created_at"] : null;
25185
- return { data: entities, cursor: nextCursor, hasMore };
25186
- }
25187
- async getEntitiesForFact(factId) {
25188
- const { data: junctionRows, error: junctionError } = await this.client.from("fact_entities").select("entity_id").eq("fact_id", factId);
25189
- if (junctionError)
25190
- throwSupabaseError("getEntitiesForFact", junctionError);
25191
- if (!junctionRows || junctionRows.length === 0)
25192
- return [];
25193
- const entityIds = junctionRows.map((row) => row["entity_id"]);
25194
- const { data, error } = await this.client.from("entities").select("*").in("id", entityIds);
25195
- if (error)
25196
- throwSupabaseError("getEntitiesForFact", error);
25197
- return (data ?? []).map((row) => toCamelCase(row));
25198
- }
25199
- async getFactsForEntity(tenantId, entityId, options) {
25200
- const { limit, cursor } = options;
25201
- let query = this.client.from("fact_entities").select("fact_id, facts!inner(*)").eq("entity_id", entityId).eq("facts.tenant_id", tenantId).order("created_at", { ascending: false, referencedTable: "facts" }).limit(limit + 1);
25202
- if (cursor) {
25203
- query = query.lt("facts.created_at", cursor);
25204
- }
25205
- const { data, error } = await query;
25206
- if (error)
25207
- throwSupabaseError("getFactsForEntity", error);
25208
- const rows = data ?? [];
25209
- const hasMore = rows.length > limit;
25210
- const page = hasMore ? rows.slice(0, limit) : rows;
25211
- const facts = page.map((row) => {
25212
- const factRow = row["facts"];
25213
- return toCamelCase(factRow);
25214
- });
25215
- const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["facts"]["created_at"] : null;
25216
- return { data: facts, cursor: nextCursor, hasMore };
25217
- }
25218
- async getFactsForEntities(tenantId, entityIds, perEntityLimit) {
25219
- if (entityIds.length === 0)
25220
- return [];
25221
- const { data, error } = await this.client.rpc("get_facts_for_entities", {
25222
- match_tenant_id: tenantId,
25223
- entity_ids: entityIds,
25224
- per_entity_limit: perEntityLimit
25225
- });
25226
- if (error)
25227
- throwSupabaseError("getFactsForEntities", error);
25228
- return (data ?? []).map((row) => {
25229
- const entityId = row["entity_id"];
25230
- const factRow = { ...row };
25231
- delete factRow["entity_id"];
25232
- factRow["id"] = factRow["fact_id"];
25233
- delete factRow["fact_id"];
25234
- return {
25235
- entityId,
25236
- fact: toCamelCase(factRow)
25237
- };
25238
- });
25239
- }
25240
- async getEdgesForEntity(tenantId, entityId) {
25241
- const { data, error } = await this.client.from("edges").select("*").eq("tenant_id", tenantId).or(`source_id.eq.${entityId},target_id.eq.${entityId}`);
25242
- if (error)
25243
- throwSupabaseError("getEdgesForEntity", error);
25244
- return (data ?? []).map((row) => toCamelCase(row));
25245
- }
25246
- async graphTraversal(options) {
25247
- const { data, error } = await this.client.rpc("graph_traverse", {
25248
- match_tenant_id: options.tenantId,
25249
- seed_entity_ids: options.entityIds,
25250
- max_depth: options.maxDepth,
25251
- max_entities: options.maxEntities,
25252
- match_as_of: options.asOf?.toISOString() ?? null
25253
- });
25254
- if (error)
25255
- throwSupabaseError("graphTraversal", error);
25256
- const rows = data ?? [];
25257
- const entityMap = /* @__PURE__ */ new Map();
25258
- const edgeMap = /* @__PURE__ */ new Map();
25259
- for (const row of rows) {
25260
- const entityId = row["entity_id"];
25261
- if (!entityMap.has(entityId)) {
25262
- entityMap.set(entityId, {
25263
- id: entityId,
25264
- tenantId: options.tenantId,
25265
- name: row["entity_name"],
25266
- entityType: row["entity_type"],
25267
- canonicalName: row["canonical_name"],
25268
- properties: row["properties"] ?? {},
25269
- embeddingModel: null,
25270
- embeddingDim: null,
25271
- mergeTargetId: null,
25272
- createdAt: /* @__PURE__ */ new Date(),
25273
- updatedAt: /* @__PURE__ */ new Date()
25274
- });
25275
- }
25276
- const edgeId = row["edge_id"];
25277
- if (edgeId && !edgeMap.has(edgeId)) {
25278
- edgeMap.set(edgeId, {
25279
- id: edgeId,
25280
- tenantId: options.tenantId,
25281
- sourceId: row["edge_source_id"],
25282
- targetId: row["edge_target_id"],
25283
- relation: row["edge_relation"],
25284
- edgeType: row["edge_type"],
25285
- weight: row["edge_weight"] ?? 1,
25286
- validFrom: row["edge_valid_from"] ? new Date(row["edge_valid_from"]) : /* @__PURE__ */ new Date(),
25287
- validUntil: row["edge_valid_until"] ? new Date(row["edge_valid_until"]) : null,
25288
- factId: null,
25289
- confidence: row["edge_confidence"] ?? 1,
25290
- metadata: {},
25291
- createdAt: /* @__PURE__ */ new Date()
25292
- });
25293
- }
25294
- }
25295
- return {
25296
- entities: Array.from(entityMap.values()),
25297
- edges: Array.from(edgeMap.values())
25298
- };
25299
- }
25300
- async createTrigger(trigger) {
25301
- const row = toSnakeCase(trigger);
25302
- const { data, error } = await this.client.from("triggers").insert(row).select().single();
25303
- if (error)
25304
- throwSupabaseError("createTrigger", error);
25305
- return toCamelCase(data);
25306
- }
25307
- async getTrigger(tenantId, id) {
25308
- const { data, error } = await this.client.from("triggers").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25309
- if (error)
25310
- throwSupabaseError("getTrigger", error);
25311
- if (!data)
25312
- return null;
25313
- return toCamelCase(data);
25314
- }
25315
- async getActiveTriggers(tenantId, scope, scopeId) {
25316
- const { data, error } = await this.client.from("triggers").select("*").eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId).eq("active", true).order("priority", { ascending: false });
25317
- if (error)
25318
- throwSupabaseError("getActiveTriggers", error);
25319
- return (data ?? []).map((row) => toCamelCase(row));
25320
- }
25321
- async updateTrigger(tenantId, id, updates) {
25322
- const row = toSnakeCase(updates);
25323
- const { data, error } = await this.client.from("triggers").update(row).eq("tenant_id", tenantId).eq("id", id).select().single();
25324
- if (error)
25325
- throwSupabaseError("updateTrigger", error);
25326
- return toCamelCase(data);
25327
- }
25328
- async deleteTrigger(tenantId, id) {
25329
- const { error } = await this.client.from("triggers").delete().eq("tenant_id", tenantId).eq("id", id);
25330
- if (error)
25331
- throwSupabaseError("deleteTrigger", error);
25332
- }
25333
- async incrementTriggerFired(tenantId, id) {
25334
- const { error } = await this.client.rpc("increment_trigger_fired", {
25335
- p_tenant_id: tenantId,
25336
- p_trigger_id: id
25337
- });
25338
- if (error)
25339
- throwSupabaseError("incrementTriggerFired", error);
25340
- }
25341
- async createMemoryAccess(access) {
25342
- const row = toSnakeCase(access);
25343
- const { data, error } = await this.client.from("memory_accesses").insert(row).select().single();
25344
- if (error)
25345
- throwSupabaseError("createMemoryAccess", error);
25346
- return toCamelCase(data);
25347
- }
25348
- async updateFeedback(tenantId, factId, feedback) {
25349
- const { data: accessRows, error: findError } = await this.client.from("memory_accesses").select("id").eq("tenant_id", tenantId).eq("fact_id", factId).order("accessed_at", { ascending: false }).limit(1);
25350
- if (findError)
25351
- throwSupabaseError("updateFeedback", findError);
25352
- if (!accessRows || accessRows.length === 0)
25353
- return;
25354
- const accessId = accessRows[0]["id"];
25355
- const { error } = await this.client.from("memory_accesses").update({
25356
- was_useful: feedback.wasUseful,
25357
- feedback_type: feedback.feedbackType,
25358
- feedback_detail: feedback.feedbackDetail ?? null,
25359
- was_corrected: feedback.wasCorrected ?? false
25360
- }).eq("id", accessId);
25361
- if (error)
25362
- throwSupabaseError("updateFeedback", error);
25363
- }
25364
- async createSession(session) {
25365
- const row = toSnakeCase(session);
25366
- const { data, error } = await this.client.from("sessions").insert(row).select().single();
25367
- if (error)
25368
- throwSupabaseError("createSession", error);
25369
- return toCamelCase(data);
25370
- }
25371
- async getSession(tenantId, id) {
25372
- const { data, error } = await this.client.from("sessions").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25373
- if (error)
25374
- throwSupabaseError("getSession", error);
25375
- if (!data)
25376
- return null;
25377
- return toCamelCase(data);
25378
- }
25379
- async endSession(tenantId, id, summary, topics) {
25380
- const updates = {
25381
- ended_at: (/* @__PURE__ */ new Date()).toISOString()
25382
- };
25383
- if (summary !== void 0)
25384
- updates["summary"] = summary;
25385
- if (topics !== void 0)
25386
- updates["topics"] = topics;
25387
- const { data, error } = await this.client.from("sessions").update(updates).eq("tenant_id", tenantId).eq("id", id).select().single();
25388
- if (error)
25389
- throwSupabaseError("endSession", error);
25390
- return toCamelCase(data);
25391
- }
25392
- async getSessionsByScope(tenantId, scope, scopeId, options) {
25393
- const { limit, cursor } = options;
25394
- let query = this.client.from("sessions").select("*").eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId).order("started_at", { ascending: false }).limit(limit + 1);
25395
- if (cursor) {
25396
- query = query.lt("started_at", cursor);
25397
- }
25398
- const { data, error } = await query;
25399
- if (error)
25400
- throwSupabaseError("getSessionsByScope", error);
25401
- const rows = data ?? [];
25402
- const hasMore = rows.length > limit;
25403
- const page = hasMore ? rows.slice(0, limit) : rows;
25404
- const sessions = page.map((row) => toCamelCase(row));
25405
- const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["started_at"] : null;
25406
- return { data: sessions, cursor: nextCursor, hasMore };
25407
- }
25408
- // ---------------------------------------------------------------------------
25409
- // Webhooks
25410
- // ---------------------------------------------------------------------------
25411
- async createWebhook(webhook) {
25412
- const { secret: _secret, ...rest } = webhook;
25413
- const row = toSnakeCase(rest);
25414
- const { data, error } = await this.client.from("webhooks").insert(row).select().single();
25415
- if (error)
25416
- throwSupabaseError("createWebhook", error);
25417
- return toCamelCase(data);
25418
- }
25419
- async getWebhook(tenantId, id) {
25420
- const { data, error } = await this.client.from("webhooks").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25421
- if (error)
25422
- throwSupabaseError("getWebhook", error);
25423
- if (!data)
25424
- return null;
25425
- return toCamelCase(data);
25426
- }
25427
- async getWebhooksForTenant(tenantId) {
25428
- const { data, error } = await this.client.from("webhooks").select("*").eq("tenant_id", tenantId);
25429
- if (error)
25430
- throwSupabaseError("getWebhooksForTenant", error);
25431
- return (data ?? []).map((row) => toCamelCase(row));
25432
- }
25433
- async getWebhooksByEvent(tenantId, event) {
25434
- const { data, error } = await this.client.from("webhooks").select("*").eq("tenant_id", tenantId).eq("active", true).contains("events", [event]);
25435
- if (error)
25436
- throwSupabaseError("getWebhooksByEvent", error);
25437
- return (data ?? []).map((row) => toCamelCase(row));
25438
- }
25439
- async deleteWebhook(tenantId, id) {
25440
- const { error } = await this.client.from("webhooks").delete().eq("tenant_id", tenantId).eq("id", id);
25441
- if (error)
25442
- throwSupabaseError("deleteWebhook", error);
25443
- }
25444
- };
25445
- }
25446
- });
25447
-
25448
- // packages/supabase-adapter/src/client.js
25449
- import { createClient } from "@supabase/supabase-js";
25450
- function createSupabaseClient(config) {
25451
- return createClient(config.url, config.serviceRoleKey, {
25452
- auth: { persistSession: false },
25453
- db: { schema: "public" }
25454
- });
25455
- }
25456
- var init_client = __esm({
25457
- "packages/supabase-adapter/src/client.js"() {
25458
- "use strict";
25459
- }
25460
- });
25461
-
25462
- // packages/supabase-adapter/src/index.js
25463
- var src_exports = {};
25464
- __export(src_exports, {
25465
- SupabaseStorageAdapter: () => SupabaseStorageAdapter,
25466
- createSupabaseClient: () => createSupabaseClient
25467
- });
25468
- var init_src3 = __esm({
25469
- "packages/supabase-adapter/src/index.js"() {
25470
- "use strict";
25471
- init_storage();
25472
- init_client();
25473
- }
25474
- });
25475
-
25476
- // packages/openai-adapter/src/llm.js
25477
- import OpenAI from "openai";
25478
- var OpenAILLMAdapter;
25479
- var init_llm = __esm({
25480
- "packages/openai-adapter/src/llm.js"() {
25481
- "use strict";
25482
- OpenAILLMAdapter = class {
25483
- client;
25484
- model;
25485
- constructor(config) {
25486
- this.client = config._client ?? new OpenAI({ apiKey: config.apiKey });
25487
- this.model = config.model ?? "gpt-4.1-nano";
25488
- }
25489
- async complete(messages, options) {
25490
- const response = await this.client.chat.completions.create({
25491
- model: this.model,
25492
- messages,
25493
- temperature: options?.temperature ?? 0,
25494
- max_tokens: options?.maxTokens,
25495
- ...options?.responseFormat === "json" ? { response_format: { type: "json_object" } } : {}
25496
- });
25497
- const choice = response.choices[0];
25498
- if (!choice?.message?.content) {
25499
- throw new Error("OpenAI returned empty response");
25500
- }
25501
- return {
25502
- content: choice.message.content,
25503
- tokensInput: response.usage?.prompt_tokens ?? 0,
25504
- tokensOutput: response.usage?.completion_tokens ?? 0,
25505
- model: response.model
25506
- };
25507
- }
25508
- };
25509
- }
25510
- });
25511
-
25512
- // packages/openai-adapter/src/embedding.js
25513
- import OpenAI2 from "openai";
25514
- var OpenAIEmbeddingAdapter;
25515
- var init_embedding = __esm({
25516
- "packages/openai-adapter/src/embedding.js"() {
25517
- "use strict";
25518
- OpenAIEmbeddingAdapter = class {
25519
- client;
25520
- model;
25521
- dimensions;
25522
- constructor(config) {
25523
- this.client = config._client ?? new OpenAI2({ apiKey: config.apiKey });
25524
- this.model = config.model ?? "text-embedding-3-small";
25525
- this.dimensions = config.dimensions ?? 1536;
25526
- }
25527
- async embed(text) {
25528
- const response = await this.client.embeddings.create({
25529
- model: this.model,
25530
- input: text,
25531
- dimensions: this.dimensions
25532
- });
25533
- const item = response.data[0];
25534
- if (!item)
25535
- throw new Error("OpenAI returned empty embedding response");
25536
- return item.embedding;
25537
- }
25538
- async embedBatch(texts) {
25539
- if (texts.length === 0)
25540
- return [];
25541
- const response = await this.client.embeddings.create({
25542
- model: this.model,
25543
- input: texts,
25544
- dimensions: this.dimensions
25545
- });
25546
- return response.data.map((d2) => d2.embedding);
25547
- }
25548
- };
25549
- }
25550
- });
25551
-
25552
- // packages/openai-adapter/src/index.js
25553
- var src_exports2 = {};
25554
- __export(src_exports2, {
25555
- OpenAIEmbeddingAdapter: () => OpenAIEmbeddingAdapter,
25556
- OpenAILLMAdapter: () => OpenAILLMAdapter
25557
- });
25558
- var init_src4 = __esm({
25559
- "packages/openai-adapter/src/index.js"() {
25560
- "use strict";
25561
- init_llm();
25562
- init_embedding();
25563
- }
25564
- });
25565
-
25566
- // packages/engine/src/adapters/perplexity-embedding.js
25567
- var perplexity_embedding_exports = {};
25568
- __export(perplexity_embedding_exports, {
25569
- PerplexityEmbeddingAdapter: () => PerplexityEmbeddingAdapter
25570
- });
25571
- function decodeAndNormalize(b64String) {
25572
- const binaryStr = atob(b64String);
25573
- const bytes = new Uint8Array(binaryStr.length);
25574
- for (let i3 = 0; i3 < binaryStr.length; i3++) {
25575
- bytes[i3] = binaryStr.charCodeAt(i3);
25576
- }
25577
- const int8 = new Int8Array(bytes.buffer);
25578
- const float32 = new Array(int8.length);
25579
- let norm = 0;
25580
- for (let i3 = 0; i3 < int8.length; i3++) {
25581
- float32[i3] = int8[i3];
25582
- norm += float32[i3] * float32[i3];
25583
- }
25584
- norm = Math.sqrt(norm);
25585
- if (norm > 0) {
25586
- for (let i3 = 0; i3 < float32.length; i3++) {
25587
- float32[i3] = float32[i3] / norm;
25588
- }
25589
- }
25590
- return float32;
25591
- }
25592
- var PerplexityEmbeddingAdapter;
25593
- var init_perplexity_embedding = __esm({
25594
- "packages/engine/src/adapters/perplexity-embedding.js"() {
25595
- "use strict";
25596
- PerplexityEmbeddingAdapter = class {
25597
- model;
25598
- dimensions;
25599
- apiKey;
25600
- baseUrl = "https://api.perplexity.ai/v1/embeddings";
25601
- constructor(config) {
25602
- this.apiKey = config.apiKey;
25603
- this.model = config.model ?? "pplx-embed-v1-4b";
25604
- this.dimensions = config.dimensions ?? 2e3;
25605
- }
25606
- async embed(text) {
25607
- const results = await this.embedBatch([text]);
25608
- return results[0];
25609
- }
25610
- async embedBatch(texts) {
25611
- if (texts.length === 0)
25612
- return [];
25613
- const response = await fetch(this.baseUrl, {
25614
- method: "POST",
25615
- headers: {
25616
- "Authorization": `Bearer ${this.apiKey}`,
25617
- "Content-Type": "application/json"
25618
- },
25619
- body: JSON.stringify({
25620
- input: texts,
25621
- model: this.model,
25622
- ...this.dimensions !== 2560 ? { dimensions: this.dimensions } : {}
25623
- })
25624
- });
25625
- if (!response.ok) {
25626
- const error = await response.text();
25627
- throw new Error(`Perplexity embedding failed (${response.status}): ${error}`);
25628
- }
25629
- const data = await response.json();
25630
- const sorted = data.data.sort((a2, b) => a2.index - b.index);
25631
- return sorted.map((d2) => decodeAndNormalize(d2.embedding));
25632
- }
25633
- };
25634
- }
25635
- });
25636
-
25637
24756
  // packages/mcp-server/src/cli.ts
25638
24757
  import { StdioServerTransport } from "@modelcontextprotocol/sdk/server/stdio.js";
25639
24758
 
@@ -25933,6 +25052,826 @@ ${text}`
25933
25052
  return server;
25934
25053
  }
25935
25054
 
25055
+ // packages/supabase-adapter/src/storage.js
25056
+ function camelToSnake(key) {
25057
+ return key.replace(/([A-Z])/g, (match2) => `_${match2.toLowerCase()}`);
25058
+ }
25059
+ function snakeToCamel(key) {
25060
+ return key.replace(/_([a-z])/g, (_2, char) => char.toUpperCase());
25061
+ }
25062
+ function toSnakeCase(obj) {
25063
+ const result = {};
25064
+ for (const [key, value] of Object.entries(obj)) {
25065
+ result[camelToSnake(key)] = value;
25066
+ }
25067
+ return result;
25068
+ }
25069
+ function toCamelCase(obj) {
25070
+ const result = {};
25071
+ for (const [key, value] of Object.entries(obj)) {
25072
+ result[snakeToCamel(key)] = value;
25073
+ }
25074
+ return result;
25075
+ }
25076
+ function throwSupabaseError(method, error) {
25077
+ throw new Error(`SupabaseStorageAdapter.${method}() failed: ${error?.message ?? "unknown error"}`);
25078
+ }
25079
+ var SupabaseStorageAdapter = class {
25080
+ client;
25081
+ constructor(client) {
25082
+ this.client = client;
25083
+ }
25084
+ async ping() {
25085
+ const { error } = await this.client.from("tenants").select("id").limit(1);
25086
+ return !error;
25087
+ }
25088
+ // ---------------------------------------------------------------------------
25089
+ // Tenants
25090
+ // ---------------------------------------------------------------------------
25091
+ async createTenant(tenant) {
25092
+ const row = toSnakeCase(tenant);
25093
+ const { data, error } = await this.client.from("tenants").insert(row).select().single();
25094
+ if (error)
25095
+ throwSupabaseError("createTenant", error);
25096
+ return toCamelCase(data);
25097
+ }
25098
+ async getTenant(id) {
25099
+ const { data, error } = await this.client.from("tenants").select("*").eq("id", id).maybeSingle();
25100
+ if (error)
25101
+ throwSupabaseError("getTenant", error);
25102
+ if (!data)
25103
+ return null;
25104
+ return toCamelCase(data);
25105
+ }
25106
+ async getTenantBySlug(slug) {
25107
+ const { data, error } = await this.client.from("tenants").select("*").eq("slug", slug).maybeSingle();
25108
+ if (error)
25109
+ throwSupabaseError("getTenantBySlug", error);
25110
+ if (!data)
25111
+ return null;
25112
+ return toCamelCase(data);
25113
+ }
25114
+ async updateTenant(id, updates) {
25115
+ const row = toSnakeCase(updates);
25116
+ const { data, error } = await this.client.from("tenants").update(row).eq("id", id).select().single();
25117
+ if (error)
25118
+ throwSupabaseError("updateTenant", error);
25119
+ return toCamelCase(data);
25120
+ }
25121
+ // ---------------------------------------------------------------------------
25122
+ // API Keys
25123
+ // ---------------------------------------------------------------------------
25124
+ async createApiKey(apiKey) {
25125
+ const row = toSnakeCase(apiKey);
25126
+ const { data, error } = await this.client.from("api_keys").insert(row).select().single();
25127
+ if (error)
25128
+ throwSupabaseError("createApiKey", error);
25129
+ return toCamelCase(data);
25130
+ }
25131
+ async getApiKeyByPrefix(prefix5) {
25132
+ const { data, error } = await this.client.from("api_keys").select("*").eq("key_prefix", prefix5).eq("active", true).maybeSingle();
25133
+ if (error)
25134
+ throwSupabaseError("getApiKeyByPrefix", error);
25135
+ if (!data)
25136
+ return null;
25137
+ return toCamelCase(data);
25138
+ }
25139
+ async getApiKeysForTenant(tenantId) {
25140
+ const { data, error } = await this.client.from("api_keys").select("*").eq("tenant_id", tenantId);
25141
+ if (error)
25142
+ throwSupabaseError("getApiKeysForTenant", error);
25143
+ return (data ?? []).map((row) => toCamelCase(row));
25144
+ }
25145
+ async revokeApiKey(tenantId, id) {
25146
+ const { error } = await this.client.from("api_keys").update({ active: false }).eq("id", id).eq("tenant_id", tenantId);
25147
+ if (error)
25148
+ throwSupabaseError("revokeApiKey", error);
25149
+ }
25150
+ async updateApiKeyLastUsed(id) {
25151
+ const { error } = await this.client.from("api_keys").update({ last_used_at: (/* @__PURE__ */ new Date()).toISOString() }).eq("id", id);
25152
+ if (error)
25153
+ throwSupabaseError("updateApiKeyLastUsed", error);
25154
+ }
25155
+ // ---------------------------------------------------------------------------
25156
+ // Extractions
25157
+ // ---------------------------------------------------------------------------
25158
+ async createExtraction(extraction) {
25159
+ const row = toSnakeCase({
25160
+ ...extraction,
25161
+ status: "queued"
25162
+ });
25163
+ const { data, error } = await this.client.from("extractions").insert(row).select().single();
25164
+ if (error)
25165
+ throwSupabaseError("createExtraction", error);
25166
+ return toCamelCase(data);
25167
+ }
25168
+ async getExtraction(tenantId, id) {
25169
+ const { data, error } = await this.client.from("extractions").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25170
+ if (error)
25171
+ throwSupabaseError("getExtraction", error);
25172
+ if (!data)
25173
+ return null;
25174
+ return toCamelCase(data);
25175
+ }
25176
+ async updateExtraction(tenantId, id, updates) {
25177
+ const row = toSnakeCase(updates);
25178
+ const { data, error } = await this.client.from("extractions").update(row).eq("tenant_id", tenantId).eq("id", id).select().single();
25179
+ if (error)
25180
+ throwSupabaseError("updateExtraction", error);
25181
+ return toCamelCase(data);
25182
+ }
25183
+ async getExtractionByHash(tenantId, inputHash) {
25184
+ const { data, error } = await this.client.from("extractions").select("*").eq("tenant_id", tenantId).eq("input_hash", inputHash).maybeSingle();
25185
+ if (error)
25186
+ throwSupabaseError("getExtractionByHash", error);
25187
+ if (!data)
25188
+ return null;
25189
+ return toCamelCase(data);
25190
+ }
25191
+ async getExtractionsByTenant(tenantId, options) {
25192
+ const { limit, cursor } = options;
25193
+ let query = this.client.from("extractions").select("*").eq("tenant_id", tenantId).order("created_at", { ascending: false }).limit(limit + 1);
25194
+ if (cursor) {
25195
+ query = query.lt("created_at", cursor);
25196
+ }
25197
+ const { data, error } = await query;
25198
+ if (error)
25199
+ throwSupabaseError("getExtractionsByTenant", error);
25200
+ const rows = data ?? [];
25201
+ const hasMore = rows.length > limit;
25202
+ const page = hasMore ? rows.slice(0, limit) : rows;
25203
+ const extractions = page.map((row) => toCamelCase(row));
25204
+ const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["created_at"] : null;
25205
+ return { data: extractions, cursor: nextCursor, hasMore };
25206
+ }
25207
+ // ---------------------------------------------------------------------------
25208
+ // Facts
25209
+ // ---------------------------------------------------------------------------
25210
+ async createFact(fact) {
25211
+ const { embedding, ...rest } = fact;
25212
+ const row = toSnakeCase(rest);
25213
+ if (!("version" in row)) {
25214
+ row["version"] = 1;
25215
+ }
25216
+ if (!row["lineage_id"]) {
25217
+ row["lineage_id"] = fact.id;
25218
+ }
25219
+ if (embedding !== void 0) {
25220
+ row["embedding"] = `[${embedding.join(",")}]`;
25221
+ }
25222
+ const { data, error } = await this.client.from("facts").insert(row).select().single();
25223
+ if (error)
25224
+ throwSupabaseError("createFact", error);
25225
+ return toCamelCase(data);
25226
+ }
25227
+ async getFact(tenantId, id) {
25228
+ const { data, error } = await this.client.from("facts").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25229
+ if (error)
25230
+ throwSupabaseError("getFact", error);
25231
+ if (!data)
25232
+ return null;
25233
+ return toCamelCase(data);
25234
+ }
25235
+ async getFactsByIds(tenantId, ids) {
25236
+ if (ids.length === 0)
25237
+ return [];
25238
+ const { data, error } = await this.client.from("facts").select("*").eq("tenant_id", tenantId).in("id", ids);
25239
+ if (error)
25240
+ throwSupabaseError("getFactsByIds", error);
25241
+ return (data ?? []).map((row) => toCamelCase(row));
25242
+ }
25243
+ async getFactsByLineage(tenantId, lineageId) {
25244
+ const { data, error } = await this.client.from("facts").select("*").eq("tenant_id", tenantId).eq("lineage_id", lineageId).order("version", { ascending: true });
25245
+ if (error)
25246
+ throwSupabaseError("getFactsByLineage", error);
25247
+ return (data ?? []).map((row) => toCamelCase(row));
25248
+ }
25249
+ async invalidateFact(tenantId, id) {
25250
+ const { error } = await this.client.from("facts").update({ valid_until: (/* @__PURE__ */ new Date()).toISOString() }).eq("tenant_id", tenantId).eq("id", id);
25251
+ if (error)
25252
+ throwSupabaseError("invalidateFact", error);
25253
+ }
25254
+ // ---------------------------------------------------------------------------
25255
+ // Entities
25256
+ // ---------------------------------------------------------------------------
25257
+ async createEntity(entity2) {
25258
+ const { embedding, ...rest } = entity2;
25259
+ const row = toSnakeCase(rest);
25260
+ if (embedding !== void 0) {
25261
+ row["embedding"] = `[${embedding.join(",")}]`;
25262
+ }
25263
+ const { data, error } = await this.client.from("entities").insert(row).select().single();
25264
+ if (error)
25265
+ throwSupabaseError("createEntity", error);
25266
+ return toCamelCase(data);
25267
+ }
25268
+ async getEntity(tenantId, id) {
25269
+ const { data, error } = await this.client.from("entities").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25270
+ if (error)
25271
+ throwSupabaseError("getEntity", error);
25272
+ if (!data)
25273
+ return null;
25274
+ return toCamelCase(data);
25275
+ }
25276
+ async findEntityByCanonicalName(tenantId, canonicalName, entityType) {
25277
+ const { data, error } = await this.client.from("entities").select("*").eq("tenant_id", tenantId).eq("canonical_name", canonicalName).eq("entity_type", entityType).maybeSingle();
25278
+ if (error)
25279
+ throwSupabaseError("findEntityByCanonicalName", error);
25280
+ if (!data)
25281
+ return null;
25282
+ return toCamelCase(data);
25283
+ }
25284
+ async findEntitiesByEmbedding(tenantId, embedding, limit, minSimilarity = 0.3) {
25285
+ const { data, error } = await this.client.rpc("match_entities", {
25286
+ query_embedding: JSON.stringify(embedding),
25287
+ match_tenant_id: tenantId,
25288
+ match_count: limit,
25289
+ min_similarity: minSimilarity
25290
+ });
25291
+ if (error)
25292
+ throwSupabaseError("findEntitiesByEmbedding", error);
25293
+ return (data ?? []).map((row) => ({
25294
+ entity: toCamelCase(row),
25295
+ similarity: row["similarity"]
25296
+ }));
25297
+ }
25298
+ // ---------------------------------------------------------------------------
25299
+ // Fact-Entity junction
25300
+ // ---------------------------------------------------------------------------
25301
+ async linkFactEntity(factId, entityId, role) {
25302
+ const { error } = await this.client.from("fact_entities").insert({
25303
+ fact_id: factId,
25304
+ entity_id: entityId,
25305
+ role
25306
+ });
25307
+ if (error)
25308
+ throwSupabaseError("linkFactEntity", error);
25309
+ }
25310
+ // ---------------------------------------------------------------------------
25311
+ // Edges
25312
+ // ---------------------------------------------------------------------------
25313
+ async createEdge(edge) {
25314
+ const row = toSnakeCase(edge);
25315
+ const { data, error } = await this.client.from("edges").insert(row).select().single();
25316
+ if (error)
25317
+ throwSupabaseError("createEdge", error);
25318
+ return toCamelCase(data);
25319
+ }
25320
+ // ---------------------------------------------------------------------------
25321
+ // Vector search
25322
+ // ---------------------------------------------------------------------------
25323
+ async vectorSearch(options) {
25324
+ const { embedding, tenantId, scope, scopeId, limit, minSimilarity } = options;
25325
+ const { data, error } = await this.client.rpc("match_facts", {
25326
+ query_embedding: `[${embedding.join(",")}]`,
25327
+ match_tenant_id: tenantId,
25328
+ match_scope: scope,
25329
+ match_scope_id: scopeId,
25330
+ match_count: limit,
25331
+ min_similarity: minSimilarity ?? 0,
25332
+ match_as_of: options.asOf?.toISOString() ?? null
25333
+ });
25334
+ if (error)
25335
+ throwSupabaseError("vectorSearch", error);
25336
+ return (data ?? []).map((row) => ({
25337
+ fact: toCamelCase(row),
25338
+ similarity: row["similarity"]
25339
+ }));
25340
+ }
25341
+ // ---------------------------------------------------------------------------
25342
+ // Usage
25343
+ // ---------------------------------------------------------------------------
25344
+ async incrementUsage(tenantId, tokens, queries, extractions, costUsd) {
25345
+ const { error } = await this.client.rpc("increment_usage", {
25346
+ p_tenant_id: tenantId,
25347
+ p_tokens: tokens,
25348
+ p_queries: queries,
25349
+ p_extractions: extractions,
25350
+ p_cost_usd: costUsd
25351
+ });
25352
+ if (error)
25353
+ throwSupabaseError("incrementUsage", error);
25354
+ }
25355
+ async getUsage(tenantId, periodStart) {
25356
+ const { data, error } = await this.client.from("usage_records").select("*").eq("tenant_id", tenantId).eq("period_start", periodStart.toISOString()).maybeSingle();
25357
+ if (error)
25358
+ throwSupabaseError("getUsage", error);
25359
+ if (!data)
25360
+ return null;
25361
+ return toCamelCase(data);
25362
+ }
25363
+ async getCurrentUsage(tenantId) {
25364
+ const now = /* @__PURE__ */ new Date();
25365
+ const periodStart = new Date(now.getFullYear(), now.getMonth(), 1);
25366
+ return this.getUsage(tenantId, periodStart);
25367
+ }
25368
+ // ---------------------------------------------------------------------------
25369
+ // Stubs — implemented in Plan 3 (Retrieval Engine)
25370
+ // ---------------------------------------------------------------------------
25371
+ async getFactsByScope(tenantId, scope, scopeId, options) {
25372
+ const { limit, cursor } = options;
25373
+ let query = this.client.from("facts").select("*").eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId).order("created_at", { ascending: false }).limit(limit + 1);
25374
+ if (cursor) {
25375
+ query = query.lt("created_at", cursor);
25376
+ }
25377
+ const { data, error } = await query;
25378
+ if (error)
25379
+ throwSupabaseError("getFactsByScope", error);
25380
+ const rows = data ?? [];
25381
+ const hasMore = rows.length > limit;
25382
+ const page = hasMore ? rows.slice(0, limit) : rows;
25383
+ const facts = page.map((row) => toCamelCase(row));
25384
+ const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["created_at"] : null;
25385
+ return { data: facts, cursor: nextCursor, hasMore };
25386
+ }
25387
+ async purgeFacts(tenantId, scope, scopeId) {
25388
+ const { data: factRows, error: fetchError } = await this.client.from("facts").select("id").eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId);
25389
+ if (fetchError)
25390
+ throwSupabaseError("purgeFacts", fetchError);
25391
+ const factIds = (factRows ?? []).map((row) => row["id"]);
25392
+ if (factIds.length === 0)
25393
+ return 0;
25394
+ const { error: feError } = await this.client.from("fact_entities").delete().in("fact_id", factIds);
25395
+ if (feError)
25396
+ throwSupabaseError("purgeFacts", feError);
25397
+ const { error: edgeError } = await this.client.from("edges").delete().in("fact_id", factIds);
25398
+ if (edgeError)
25399
+ throwSupabaseError("purgeFacts", edgeError);
25400
+ const { error: deleteError } = await this.client.from("facts").delete().eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId);
25401
+ if (deleteError)
25402
+ throwSupabaseError("purgeFacts", deleteError);
25403
+ const { error: extractionError } = await this.client.from("extractions").delete().eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId);
25404
+ if (extractionError)
25405
+ throwSupabaseError("purgeFacts", extractionError);
25406
+ return factIds.length;
25407
+ }
25408
+ async updateDecayScores(tenantId, facts) {
25409
+ for (const fact of facts) {
25410
+ const updates = {
25411
+ decay_score: fact.decayScore
25412
+ };
25413
+ if (fact.lastAccessed !== void 0) {
25414
+ updates["last_accessed"] = fact.lastAccessed.toISOString();
25415
+ }
25416
+ if (fact.frequency !== void 0) {
25417
+ updates["frequency"] = fact.frequency;
25418
+ }
25419
+ if (fact.importance !== void 0) {
25420
+ updates["importance"] = fact.importance;
25421
+ }
25422
+ const { error } = await this.client.from("facts").update(updates).eq("tenant_id", tenantId).eq("id", fact.id);
25423
+ if (error)
25424
+ throwSupabaseError("updateDecayScores", error);
25425
+ }
25426
+ }
25427
+ async keywordSearch(options) {
25428
+ const { query, tenantId, scope, scopeId, limit, asOf } = options;
25429
+ const { data, error } = await this.client.rpc("keyword_search_facts", {
25430
+ search_query: query,
25431
+ match_tenant_id: tenantId,
25432
+ match_scope: scope,
25433
+ match_scope_id: scopeId,
25434
+ match_count: limit,
25435
+ match_as_of: asOf?.toISOString() ?? null
25436
+ });
25437
+ if (error)
25438
+ throwSupabaseError("keywordSearch", error);
25439
+ return (data ?? []).map((row) => {
25440
+ const rankScore = row["rank_score"];
25441
+ const converted = toCamelCase(row);
25442
+ return {
25443
+ fact: converted,
25444
+ rankScore
25445
+ };
25446
+ });
25447
+ }
25448
+ async compoundSearch(options) {
25449
+ const { data, error } = await this.client.rpc("steno_search", {
25450
+ query_embedding: `[${options.embedding.join(",")}]`,
25451
+ search_query: options.query,
25452
+ match_tenant_id: options.tenantId,
25453
+ match_scope: options.scope,
25454
+ match_scope_id: options.scopeId,
25455
+ match_count: options.limit,
25456
+ min_similarity: options.minSimilarity ?? 0
25457
+ });
25458
+ if (error)
25459
+ throwSupabaseError("compoundSearch", error);
25460
+ return (data ?? []).map((row) => ({
25461
+ source: row["source"],
25462
+ fact: toCamelCase(row),
25463
+ relevanceScore: row["relevance_score"]
25464
+ }));
25465
+ }
25466
+ async getEntitiesForTenant(tenantId, options) {
25467
+ const { limit, cursor } = options;
25468
+ let query = this.client.from("entities").select("*").eq("tenant_id", tenantId).order("created_at", { ascending: true }).limit(limit + 1);
25469
+ if (cursor) {
25470
+ query = query.gt("created_at", cursor);
25471
+ }
25472
+ const { data, error } = await query;
25473
+ if (error)
25474
+ throwSupabaseError("getEntitiesForTenant", error);
25475
+ const rows = data ?? [];
25476
+ const hasMore = rows.length > limit;
25477
+ const page = hasMore ? rows.slice(0, limit) : rows;
25478
+ const entities = page.map((row) => toCamelCase(row));
25479
+ const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["created_at"] : null;
25480
+ return { data: entities, cursor: nextCursor, hasMore };
25481
+ }
25482
+ async getEntitiesForFact(factId) {
25483
+ const { data: junctionRows, error: junctionError } = await this.client.from("fact_entities").select("entity_id").eq("fact_id", factId);
25484
+ if (junctionError)
25485
+ throwSupabaseError("getEntitiesForFact", junctionError);
25486
+ if (!junctionRows || junctionRows.length === 0)
25487
+ return [];
25488
+ const entityIds = junctionRows.map((row) => row["entity_id"]);
25489
+ const { data, error } = await this.client.from("entities").select("*").in("id", entityIds);
25490
+ if (error)
25491
+ throwSupabaseError("getEntitiesForFact", error);
25492
+ return (data ?? []).map((row) => toCamelCase(row));
25493
+ }
25494
+ async getFactsForEntity(tenantId, entityId, options) {
25495
+ const { limit, cursor } = options;
25496
+ let query = this.client.from("fact_entities").select("fact_id, facts!inner(*)").eq("entity_id", entityId).eq("facts.tenant_id", tenantId).order("created_at", { ascending: false, referencedTable: "facts" }).limit(limit + 1);
25497
+ if (cursor) {
25498
+ query = query.lt("facts.created_at", cursor);
25499
+ }
25500
+ const { data, error } = await query;
25501
+ if (error)
25502
+ throwSupabaseError("getFactsForEntity", error);
25503
+ const rows = data ?? [];
25504
+ const hasMore = rows.length > limit;
25505
+ const page = hasMore ? rows.slice(0, limit) : rows;
25506
+ const facts = page.map((row) => {
25507
+ const factRow = row["facts"];
25508
+ return toCamelCase(factRow);
25509
+ });
25510
+ const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["facts"]["created_at"] : null;
25511
+ return { data: facts, cursor: nextCursor, hasMore };
25512
+ }
25513
+ async getFactsForEntities(tenantId, entityIds, perEntityLimit) {
25514
+ if (entityIds.length === 0)
25515
+ return [];
25516
+ const { data, error } = await this.client.rpc("get_facts_for_entities", {
25517
+ match_tenant_id: tenantId,
25518
+ entity_ids: entityIds,
25519
+ per_entity_limit: perEntityLimit
25520
+ });
25521
+ if (error)
25522
+ throwSupabaseError("getFactsForEntities", error);
25523
+ return (data ?? []).map((row) => {
25524
+ const entityId = row["entity_id"];
25525
+ const factRow = { ...row };
25526
+ delete factRow["entity_id"];
25527
+ factRow["id"] = factRow["fact_id"];
25528
+ delete factRow["fact_id"];
25529
+ return {
25530
+ entityId,
25531
+ fact: toCamelCase(factRow)
25532
+ };
25533
+ });
25534
+ }
25535
+ async getEdgesForEntity(tenantId, entityId) {
25536
+ const { data, error } = await this.client.from("edges").select("*").eq("tenant_id", tenantId).or(`source_id.eq.${entityId},target_id.eq.${entityId}`);
25537
+ if (error)
25538
+ throwSupabaseError("getEdgesForEntity", error);
25539
+ return (data ?? []).map((row) => toCamelCase(row));
25540
+ }
25541
+ async graphTraversal(options) {
25542
+ const { data, error } = await this.client.rpc("graph_traverse", {
25543
+ match_tenant_id: options.tenantId,
25544
+ seed_entity_ids: options.entityIds,
25545
+ max_depth: options.maxDepth,
25546
+ max_entities: options.maxEntities,
25547
+ match_as_of: options.asOf?.toISOString() ?? null
25548
+ });
25549
+ if (error)
25550
+ throwSupabaseError("graphTraversal", error);
25551
+ const rows = data ?? [];
25552
+ const entityMap = /* @__PURE__ */ new Map();
25553
+ const edgeMap = /* @__PURE__ */ new Map();
25554
+ for (const row of rows) {
25555
+ const entityId = row["entity_id"];
25556
+ if (!entityMap.has(entityId)) {
25557
+ entityMap.set(entityId, {
25558
+ id: entityId,
25559
+ tenantId: options.tenantId,
25560
+ name: row["entity_name"],
25561
+ entityType: row["entity_type"],
25562
+ canonicalName: row["canonical_name"],
25563
+ properties: row["properties"] ?? {},
25564
+ embeddingModel: null,
25565
+ embeddingDim: null,
25566
+ mergeTargetId: null,
25567
+ createdAt: /* @__PURE__ */ new Date(),
25568
+ updatedAt: /* @__PURE__ */ new Date()
25569
+ });
25570
+ }
25571
+ const edgeId = row["edge_id"];
25572
+ if (edgeId && !edgeMap.has(edgeId)) {
25573
+ edgeMap.set(edgeId, {
25574
+ id: edgeId,
25575
+ tenantId: options.tenantId,
25576
+ sourceId: row["edge_source_id"],
25577
+ targetId: row["edge_target_id"],
25578
+ relation: row["edge_relation"],
25579
+ edgeType: row["edge_type"],
25580
+ weight: row["edge_weight"] ?? 1,
25581
+ validFrom: row["edge_valid_from"] ? new Date(row["edge_valid_from"]) : /* @__PURE__ */ new Date(),
25582
+ validUntil: row["edge_valid_until"] ? new Date(row["edge_valid_until"]) : null,
25583
+ factId: null,
25584
+ confidence: row["edge_confidence"] ?? 1,
25585
+ metadata: {},
25586
+ createdAt: /* @__PURE__ */ new Date()
25587
+ });
25588
+ }
25589
+ }
25590
+ return {
25591
+ entities: Array.from(entityMap.values()),
25592
+ edges: Array.from(edgeMap.values())
25593
+ };
25594
+ }
25595
+ async createTrigger(trigger) {
25596
+ const row = toSnakeCase(trigger);
25597
+ const { data, error } = await this.client.from("triggers").insert(row).select().single();
25598
+ if (error)
25599
+ throwSupabaseError("createTrigger", error);
25600
+ return toCamelCase(data);
25601
+ }
25602
+ async getTrigger(tenantId, id) {
25603
+ const { data, error } = await this.client.from("triggers").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25604
+ if (error)
25605
+ throwSupabaseError("getTrigger", error);
25606
+ if (!data)
25607
+ return null;
25608
+ return toCamelCase(data);
25609
+ }
25610
+ async getActiveTriggers(tenantId, scope, scopeId) {
25611
+ const { data, error } = await this.client.from("triggers").select("*").eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId).eq("active", true).order("priority", { ascending: false });
25612
+ if (error)
25613
+ throwSupabaseError("getActiveTriggers", error);
25614
+ return (data ?? []).map((row) => toCamelCase(row));
25615
+ }
25616
+ async updateTrigger(tenantId, id, updates) {
25617
+ const row = toSnakeCase(updates);
25618
+ const { data, error } = await this.client.from("triggers").update(row).eq("tenant_id", tenantId).eq("id", id).select().single();
25619
+ if (error)
25620
+ throwSupabaseError("updateTrigger", error);
25621
+ return toCamelCase(data);
25622
+ }
25623
+ async deleteTrigger(tenantId, id) {
25624
+ const { error } = await this.client.from("triggers").delete().eq("tenant_id", tenantId).eq("id", id);
25625
+ if (error)
25626
+ throwSupabaseError("deleteTrigger", error);
25627
+ }
25628
+ async incrementTriggerFired(tenantId, id) {
25629
+ const { error } = await this.client.rpc("increment_trigger_fired", {
25630
+ p_tenant_id: tenantId,
25631
+ p_trigger_id: id
25632
+ });
25633
+ if (error)
25634
+ throwSupabaseError("incrementTriggerFired", error);
25635
+ }
25636
+ async createMemoryAccess(access) {
25637
+ const row = toSnakeCase(access);
25638
+ const { data, error } = await this.client.from("memory_accesses").insert(row).select().single();
25639
+ if (error)
25640
+ throwSupabaseError("createMemoryAccess", error);
25641
+ return toCamelCase(data);
25642
+ }
25643
+ async updateFeedback(tenantId, factId, feedback) {
25644
+ const { data: accessRows, error: findError } = await this.client.from("memory_accesses").select("id").eq("tenant_id", tenantId).eq("fact_id", factId).order("accessed_at", { ascending: false }).limit(1);
25645
+ if (findError)
25646
+ throwSupabaseError("updateFeedback", findError);
25647
+ if (!accessRows || accessRows.length === 0)
25648
+ return;
25649
+ const accessId = accessRows[0]["id"];
25650
+ const { error } = await this.client.from("memory_accesses").update({
25651
+ was_useful: feedback.wasUseful,
25652
+ feedback_type: feedback.feedbackType,
25653
+ feedback_detail: feedback.feedbackDetail ?? null,
25654
+ was_corrected: feedback.wasCorrected ?? false
25655
+ }).eq("id", accessId);
25656
+ if (error)
25657
+ throwSupabaseError("updateFeedback", error);
25658
+ }
25659
+ async createSession(session) {
25660
+ const row = toSnakeCase(session);
25661
+ const { data, error } = await this.client.from("sessions").insert(row).select().single();
25662
+ if (error)
25663
+ throwSupabaseError("createSession", error);
25664
+ return toCamelCase(data);
25665
+ }
25666
+ async getSession(tenantId, id) {
25667
+ const { data, error } = await this.client.from("sessions").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25668
+ if (error)
25669
+ throwSupabaseError("getSession", error);
25670
+ if (!data)
25671
+ return null;
25672
+ return toCamelCase(data);
25673
+ }
25674
+ async endSession(tenantId, id, summary, topics) {
25675
+ const updates = {
25676
+ ended_at: (/* @__PURE__ */ new Date()).toISOString()
25677
+ };
25678
+ if (summary !== void 0)
25679
+ updates["summary"] = summary;
25680
+ if (topics !== void 0)
25681
+ updates["topics"] = topics;
25682
+ const { data, error } = await this.client.from("sessions").update(updates).eq("tenant_id", tenantId).eq("id", id).select().single();
25683
+ if (error)
25684
+ throwSupabaseError("endSession", error);
25685
+ return toCamelCase(data);
25686
+ }
25687
+ async getSessionsByScope(tenantId, scope, scopeId, options) {
25688
+ const { limit, cursor } = options;
25689
+ let query = this.client.from("sessions").select("*").eq("tenant_id", tenantId).eq("scope", scope).eq("scope_id", scopeId).order("started_at", { ascending: false }).limit(limit + 1);
25690
+ if (cursor) {
25691
+ query = query.lt("started_at", cursor);
25692
+ }
25693
+ const { data, error } = await query;
25694
+ if (error)
25695
+ throwSupabaseError("getSessionsByScope", error);
25696
+ const rows = data ?? [];
25697
+ const hasMore = rows.length > limit;
25698
+ const page = hasMore ? rows.slice(0, limit) : rows;
25699
+ const sessions = page.map((row) => toCamelCase(row));
25700
+ const nextCursor = hasMore && page.length > 0 ? page[page.length - 1]["started_at"] : null;
25701
+ return { data: sessions, cursor: nextCursor, hasMore };
25702
+ }
25703
+ // ---------------------------------------------------------------------------
25704
+ // Webhooks
25705
+ // ---------------------------------------------------------------------------
25706
+ async createWebhook(webhook) {
25707
+ const { secret: _secret, ...rest } = webhook;
25708
+ const row = toSnakeCase(rest);
25709
+ const { data, error } = await this.client.from("webhooks").insert(row).select().single();
25710
+ if (error)
25711
+ throwSupabaseError("createWebhook", error);
25712
+ return toCamelCase(data);
25713
+ }
25714
+ async getWebhook(tenantId, id) {
25715
+ const { data, error } = await this.client.from("webhooks").select("*").eq("tenant_id", tenantId).eq("id", id).maybeSingle();
25716
+ if (error)
25717
+ throwSupabaseError("getWebhook", error);
25718
+ if (!data)
25719
+ return null;
25720
+ return toCamelCase(data);
25721
+ }
25722
+ async getWebhooksForTenant(tenantId) {
25723
+ const { data, error } = await this.client.from("webhooks").select("*").eq("tenant_id", tenantId);
25724
+ if (error)
25725
+ throwSupabaseError("getWebhooksForTenant", error);
25726
+ return (data ?? []).map((row) => toCamelCase(row));
25727
+ }
25728
+ async getWebhooksByEvent(tenantId, event) {
25729
+ const { data, error } = await this.client.from("webhooks").select("*").eq("tenant_id", tenantId).eq("active", true).contains("events", [event]);
25730
+ if (error)
25731
+ throwSupabaseError("getWebhooksByEvent", error);
25732
+ return (data ?? []).map((row) => toCamelCase(row));
25733
+ }
25734
+ async deleteWebhook(tenantId, id) {
25735
+ const { error } = await this.client.from("webhooks").delete().eq("tenant_id", tenantId).eq("id", id);
25736
+ if (error)
25737
+ throwSupabaseError("deleteWebhook", error);
25738
+ }
25739
+ };
25740
+
25741
+ // packages/supabase-adapter/src/client.js
25742
+ import { createClient } from "@supabase/supabase-js";
25743
+ function createSupabaseClient(config) {
25744
+ return createClient(config.url, config.serviceRoleKey, {
25745
+ auth: { persistSession: false },
25746
+ db: { schema: "public" }
25747
+ });
25748
+ }
25749
+
25750
+ // packages/openai-adapter/src/llm.js
25751
+ import OpenAI from "openai";
25752
+ var OpenAILLMAdapter = class {
25753
+ client;
25754
+ model;
25755
+ constructor(config) {
25756
+ this.client = config._client ?? new OpenAI({ apiKey: config.apiKey });
25757
+ this.model = config.model ?? "gpt-4.1-nano";
25758
+ }
25759
+ async complete(messages, options) {
25760
+ const response = await this.client.chat.completions.create({
25761
+ model: this.model,
25762
+ messages,
25763
+ temperature: options?.temperature ?? 0,
25764
+ max_tokens: options?.maxTokens,
25765
+ ...options?.responseFormat === "json" ? { response_format: { type: "json_object" } } : {}
25766
+ });
25767
+ const choice = response.choices[0];
25768
+ if (!choice?.message?.content) {
25769
+ throw new Error("OpenAI returned empty response");
25770
+ }
25771
+ return {
25772
+ content: choice.message.content,
25773
+ tokensInput: response.usage?.prompt_tokens ?? 0,
25774
+ tokensOutput: response.usage?.completion_tokens ?? 0,
25775
+ model: response.model
25776
+ };
25777
+ }
25778
+ };
25779
+
25780
+ // packages/openai-adapter/src/embedding.js
25781
+ import OpenAI2 from "openai";
25782
+ var OpenAIEmbeddingAdapter = class {
25783
+ client;
25784
+ model;
25785
+ dimensions;
25786
+ constructor(config) {
25787
+ this.client = config._client ?? new OpenAI2({ apiKey: config.apiKey });
25788
+ this.model = config.model ?? "text-embedding-3-small";
25789
+ this.dimensions = config.dimensions ?? 1536;
25790
+ }
25791
+ async embed(text) {
25792
+ const response = await this.client.embeddings.create({
25793
+ model: this.model,
25794
+ input: text,
25795
+ dimensions: this.dimensions
25796
+ });
25797
+ const item = response.data[0];
25798
+ if (!item)
25799
+ throw new Error("OpenAI returned empty embedding response");
25800
+ return item.embedding;
25801
+ }
25802
+ async embedBatch(texts) {
25803
+ if (texts.length === 0)
25804
+ return [];
25805
+ const response = await this.client.embeddings.create({
25806
+ model: this.model,
25807
+ input: texts,
25808
+ dimensions: this.dimensions
25809
+ });
25810
+ return response.data.map((d2) => d2.embedding);
25811
+ }
25812
+ };
25813
+
25814
+ // packages/engine/src/adapters/perplexity-embedding.js
25815
+ var PerplexityEmbeddingAdapter = class {
25816
+ model;
25817
+ dimensions;
25818
+ apiKey;
25819
+ baseUrl = "https://api.perplexity.ai/v1/embeddings";
25820
+ constructor(config) {
25821
+ this.apiKey = config.apiKey;
25822
+ this.model = config.model ?? "pplx-embed-v1-4b";
25823
+ this.dimensions = config.dimensions ?? 2e3;
25824
+ }
25825
+ async embed(text) {
25826
+ const results = await this.embedBatch([text]);
25827
+ return results[0];
25828
+ }
25829
+ async embedBatch(texts) {
25830
+ if (texts.length === 0)
25831
+ return [];
25832
+ const response = await fetch(this.baseUrl, {
25833
+ method: "POST",
25834
+ headers: {
25835
+ "Authorization": `Bearer ${this.apiKey}`,
25836
+ "Content-Type": "application/json"
25837
+ },
25838
+ body: JSON.stringify({
25839
+ input: texts,
25840
+ model: this.model,
25841
+ ...this.dimensions !== 2560 ? { dimensions: this.dimensions } : {}
25842
+ })
25843
+ });
25844
+ if (!response.ok) {
25845
+ const error = await response.text();
25846
+ throw new Error(`Perplexity embedding failed (${response.status}): ${error}`);
25847
+ }
25848
+ const data = await response.json();
25849
+ const sorted = data.data.sort((a2, b) => a2.index - b.index);
25850
+ return sorted.map((d2) => decodeAndNormalize(d2.embedding));
25851
+ }
25852
+ };
25853
+ function decodeAndNormalize(b64String) {
25854
+ const binaryStr = atob(b64String);
25855
+ const bytes = new Uint8Array(binaryStr.length);
25856
+ for (let i3 = 0; i3 < binaryStr.length; i3++) {
25857
+ bytes[i3] = binaryStr.charCodeAt(i3);
25858
+ }
25859
+ const int8 = new Int8Array(bytes.buffer);
25860
+ const float32 = new Array(int8.length);
25861
+ let norm = 0;
25862
+ for (let i3 = 0; i3 < int8.length; i3++) {
25863
+ float32[i3] = int8[i3];
25864
+ norm += float32[i3] * float32[i3];
25865
+ }
25866
+ norm = Math.sqrt(norm);
25867
+ if (norm > 0) {
25868
+ for (let i3 = 0; i3 < float32.length; i3++) {
25869
+ float32[i3] = float32[i3] / norm;
25870
+ }
25871
+ }
25872
+ return float32;
25873
+ }
25874
+
25936
25875
  // packages/mcp-server/src/cli.ts
25937
25876
  async function main() {
25938
25877
  const supabaseUrl = process.env.SUPABASE_URL;
@@ -25946,52 +25885,22 @@ async function main() {
25946
25885
  console.error("Error: OPENAI_API_KEY is required.\n");
25947
25886
  process.exit(1);
25948
25887
  }
25949
- let createSupabaseClient2, SupabaseStorageAdapter2, OpenAILLMAdapter2;
25950
- try {
25951
- const supa = await import("@steno-ai/supabase-adapter");
25952
- createSupabaseClient2 = supa.createSupabaseClient;
25953
- SupabaseStorageAdapter2 = supa.SupabaseStorageAdapter;
25954
- const oai = await import("@steno-ai/openai-adapter");
25955
- OpenAILLMAdapter2 = oai.OpenAILLMAdapter;
25956
- } catch {
25957
- const supa = await Promise.resolve().then(() => (init_src3(), src_exports));
25958
- createSupabaseClient2 = supa.createSupabaseClient;
25959
- SupabaseStorageAdapter2 = supa.SupabaseStorageAdapter;
25960
- const oai = await Promise.resolve().then(() => (init_src4(), src_exports2));
25961
- OpenAILLMAdapter2 = oai.OpenAILLMAdapter;
25962
- }
25963
- const supabase = createSupabaseClient2({ url: supabaseUrl, serviceRoleKey: supabaseKey });
25964
- const storage = new SupabaseStorageAdapter2(supabase);
25965
- const cheapLLM = new OpenAILLMAdapter2({ apiKey: openaiKey, model: "gpt-5.4-mini" });
25888
+ const supabase = createSupabaseClient({ url: supabaseUrl, serviceRoleKey: supabaseKey });
25889
+ const storage = new SupabaseStorageAdapter(supabase);
25890
+ const cheapLLM = new OpenAILLMAdapter({ apiKey: openaiKey, model: "gpt-5.4-mini" });
25966
25891
  let embedding;
25967
25892
  let embeddingModel;
25968
25893
  let embeddingDim;
25969
25894
  if (process.env.PERPLEXITY_API_KEY) {
25970
- try {
25971
- const { PerplexityEmbeddingAdapter: PerplexityEmbeddingAdapter2 } = await import("@steno-ai/engine");
25972
- embedding = new PerplexityEmbeddingAdapter2({
25973
- apiKey: process.env.PERPLEXITY_API_KEY,
25974
- model: "pplx-embed-v1-4b",
25975
- dimensions: 2e3
25976
- });
25977
- } catch {
25978
- const { PerplexityEmbeddingAdapter: PerplexityEmbeddingAdapter2 } = await Promise.resolve().then(() => (init_perplexity_embedding(), perplexity_embedding_exports));
25979
- embedding = new PerplexityEmbeddingAdapter2({
25980
- apiKey: process.env.PERPLEXITY_API_KEY,
25981
- model: "pplx-embed-v1-4b",
25982
- dimensions: 2e3
25983
- });
25984
- }
25895
+ embedding = new PerplexityEmbeddingAdapter({
25896
+ apiKey: process.env.PERPLEXITY_API_KEY,
25897
+ model: "pplx-embed-v1-4b",
25898
+ dimensions: 2e3
25899
+ });
25985
25900
  embeddingModel = "pplx-embed-v1-4b";
25986
25901
  embeddingDim = 2e3;
25987
25902
  } else {
25988
- try {
25989
- const { OpenAIEmbeddingAdapter: OpenAIEmbeddingAdapter2 } = await import("@steno-ai/openai-adapter");
25990
- embedding = new OpenAIEmbeddingAdapter2({ apiKey: openaiKey, model: "text-embedding-3-large", dimensions: 3072 });
25991
- } catch {
25992
- const { OpenAIEmbeddingAdapter: OpenAIEmbeddingAdapter2 } = await Promise.resolve().then(() => (init_src4(), src_exports2));
25993
- embedding = new OpenAIEmbeddingAdapter2({ apiKey: openaiKey, model: "text-embedding-3-large", dimensions: 3072 });
25994
- }
25903
+ embedding = new OpenAIEmbeddingAdapter({ apiKey: openaiKey, model: "text-embedding-3-large", dimensions: 3072 });
25995
25904
  embeddingModel = "text-embedding-3-large";
25996
25905
  embeddingDim = 3072;
25997
25906
  }