@byok-sdk/keys 0.3.10 → 0.4.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
package/dist/errors.d.ts CHANGED
@@ -27,8 +27,9 @@ export declare class ByokKeysError extends Error {
27
27
  * stored value as-is), `SECRET_ENVELOPE_INVALID` (it reported a malformed
28
28
  * envelope as an absent secret), and `SECRET_NAME_INVALID` /
29
29
  * `SECRET_VALUE_INVALID` (the runtime replacements for the closed
30
- * `KeychainSecretName` union). Everything else matches the source string for
31
- * string.
30
+ * `KeychainSecretName` union). `PROVIDER_STORE_SCHEMA_STALE` joins them: it
31
+ * guards a persisted `provider_profile` DDL that differs from the one this
32
+ * package generates. Everything else matches the source string for string.
32
33
  *
33
34
  * `SECRET_NAMESPACE_INVALID` is a separate case. The source does record it:
34
35
  * `normalizeSecretNamespace` (`index.ts:748-757`) throws the verbatim string
@@ -70,6 +71,7 @@ export declare const BYOK_KEYS_ERROR_CODES: {
70
71
  readonly PROVIDER_SECRET_MISSING: 'PROVIDER_SECRET_MISSING';
71
72
  readonly PROVIDER_SECRET_NOT_ALLOWED: 'PROVIDER_SECRET_NOT_ALLOWED';
72
73
  readonly PROVIDER_SECRET_ROLLBACK_FAILED: 'PROVIDER_SECRET_ROLLBACK_FAILED';
74
+ readonly PROVIDER_STORE_SCHEMA_STALE: 'PROVIDER_STORE_SCHEMA_STALE';
73
75
  readonly PROVIDER_STORE_UNAVAILABLE: 'PROVIDER_STORE_UNAVAILABLE';
74
76
  readonly PROVIDER_TRUTH_INVALID: 'PROVIDER_TRUTH_INVALID';
75
77
  readonly PROVIDER_URL_INVALID: 'PROVIDER_URL_INVALID';
package/dist/index.d.ts CHANGED
@@ -2,6 +2,8 @@ export { ByokKeysError, BYOK_KEYS_ERROR_CODES } from './errors';
2
2
  export type { ByokKeysErrorCode } from './errors';
3
3
  export { MODEL_PROVIDER_ADAPTERS, MODEL_PROVIDER_KINDS, PROVIDER_AUTH_MODES, PROVIDER_MODEL_CAPABILITIES, ModelProviderProfileSchema, ProviderModelCapabilitySchema, ProviderProfileRefSchema, parseModelProviderProfile, exactProviderProfileBinding, assertExactProviderProfileBinding, } from './provider-profile';
4
4
  export type { ModelProviderAdapter, ModelProviderKind, ModelProviderProfile, ModelProviderProfileInput, ExactProviderProfileBinding, ProviderAuthMode, ProviderModelCapability, ProviderProfileRef, } from './provider-profile';
5
+ export { MODEL_PROVIDER_VENDORS, MODEL_PROVIDER_VENDOR_IDS, modelProviderVendor, } from './provider-catalog';
6
+ export type { ModelProviderVendor, ModelProviderVendorId, } from './provider-catalog';
5
7
  export { providerHeaders, requiredProviderSecret } from './headers';
6
8
  export type { ProviderAuthProfile } from './headers';
7
9
  export { normalizeProviderUrl, isLoopbackHost, isLoopbackProviderUrl, isPrivateNetworkLiteral, } from './url';
package/dist/index.js CHANGED
@@ -47,6 +47,7 @@ var BYOK_KEYS_ERROR_CODES = {
47
47
  PROVIDER_SECRET_MISSING: "PROVIDER_SECRET_MISSING",
48
48
  PROVIDER_SECRET_NOT_ALLOWED: "PROVIDER_SECRET_NOT_ALLOWED",
49
49
  PROVIDER_SECRET_ROLLBACK_FAILED: "PROVIDER_SECRET_ROLLBACK_FAILED",
50
+ PROVIDER_STORE_SCHEMA_STALE: "PROVIDER_STORE_SCHEMA_STALE",
50
51
  PROVIDER_STORE_UNAVAILABLE: "PROVIDER_STORE_UNAVAILABLE",
51
52
  PROVIDER_TRUTH_INVALID: "PROVIDER_TRUTH_INVALID",
52
53
  PROVIDER_URL_INVALID: "PROVIDER_URL_INVALID",
@@ -56,6 +57,89 @@ var BYOK_KEYS_ERROR_CODES = {
56
57
  SECRET_VALUE_INVALID: "SECRET_VALUE_INVALID"
57
58
  };
58
59
 
60
+ // src/provider-catalog.ts
61
+ function openAiCompatible(display_name, base_url, api_key_env) {
62
+ return {
63
+ display_name,
64
+ base_url,
65
+ adapter: "openai_compatible",
66
+ auth_mode: "bearer",
67
+ api_key_env
68
+ };
69
+ }
70
+ function anthropicMessages(display_name, base_url, api_key_env) {
71
+ return {
72
+ display_name,
73
+ base_url,
74
+ adapter: "anthropic",
75
+ auth_mode: "x_api_key",
76
+ api_key_env
77
+ };
78
+ }
79
+ var MODEL_PROVIDER_VENDORS = {
80
+ "ant-ling": openAiCompatible("Ant Ling", "https://api.ant-ling.com/v1", "ANT_LING_API_KEY"),
81
+ baseten: openAiCompatible("Baseten", "https://inference.baseten.co/v1", "BASETEN_API_KEY"),
82
+ cerebras: openAiCompatible("Cerebras", "https://api.cerebras.ai/v1", "CEREBRAS_API_KEY"),
83
+ deepseek: openAiCompatible("DeepSeek", "https://api.deepseek.com", "DEEPSEEK_API_KEY"),
84
+ groq: openAiCompatible("Groq", "https://api.groq.com/openai/v1", "GROQ_API_KEY"),
85
+ huggingface: openAiCompatible("Hugging Face", "https://router.huggingface.co/v1", "HF_TOKEN"),
86
+ moonshotai: openAiCompatible("Moonshot AI", "https://api.moonshot.ai/v1", "MOONSHOT_API_KEY"),
87
+ "moonshotai-cn": openAiCompatible("Moonshot AI CN", "https://api.moonshot.cn/v1", "MOONSHOT_API_KEY"),
88
+ nvidia: openAiCompatible("NVIDIA", "https://integrate.api.nvidia.com/v1", "NVIDIA_API_KEY"),
89
+ openai: openAiCompatible("OpenAI", "https://api.openai.com/v1", "OPENAI_API_KEY"),
90
+ openrouter: openAiCompatible("OpenRouter", "https://openrouter.ai/api/v1", "OPENROUTER_API_KEY"),
91
+ "qwen-token-plan": openAiCompatible(
92
+ "Qwen Token Plan",
93
+ "https://token-plan.ap-southeast-1.maas.aliyuncs.com/compatible-mode/v1",
94
+ "QWEN_TOKEN_PLAN_API_KEY"
95
+ ),
96
+ "qwen-token-plan-cn": openAiCompatible(
97
+ "Qwen Token Plan CN",
98
+ "https://token-plan.cn-beijing.maas.aliyuncs.com/compatible-mode/v1",
99
+ "QWEN_TOKEN_PLAN_CN_API_KEY"
100
+ ),
101
+ together: openAiCompatible("Together", "https://api.together.ai/v1", "TOGETHER_API_KEY"),
102
+ xai: openAiCompatible("xAI", "https://api.x.ai/v1", "XAI_API_KEY"),
103
+ xiaomi: openAiCompatible("Xiaomi", "https://api.xiaomimimo.com/v1", "XIAOMI_API_KEY"),
104
+ "xiaomi-token-plan-ams": openAiCompatible(
105
+ "Xiaomi Token Plan AMS",
106
+ "https://token-plan-ams.xiaomimimo.com/v1",
107
+ "XIAOMI_TOKEN_PLAN_AMS_API_KEY"
108
+ ),
109
+ "xiaomi-token-plan-cn": openAiCompatible(
110
+ "Xiaomi Token Plan CN",
111
+ "https://token-plan-cn.xiaomimimo.com/v1",
112
+ "XIAOMI_TOKEN_PLAN_CN_API_KEY"
113
+ ),
114
+ "xiaomi-token-plan-sgp": openAiCompatible(
115
+ "Xiaomi Token Plan SGP",
116
+ "https://token-plan-sgp.xiaomimimo.com/v1",
117
+ "XIAOMI_TOKEN_PLAN_SGP_API_KEY"
118
+ ),
119
+ zai: openAiCompatible("Z.AI", "https://api.z.ai/api/coding/paas/v4", "ZAI_API_KEY"),
120
+ "zai-coding-cn": openAiCompatible(
121
+ "Z.AI Coding CN",
122
+ "https://open.bigmodel.cn/api/coding/paas/v4",
123
+ "ZAI_CODING_CN_API_KEY"
124
+ ),
125
+ anthropic: anthropicMessages("Anthropic", "https://api.anthropic.com/v1", "ANTHROPIC_API_KEY"),
126
+ fireworks: anthropicMessages("Fireworks", "https://api.fireworks.ai/inference/v1", "FIREWORKS_API_KEY"),
127
+ "kimi-coding": anthropicMessages("Kimi For Coding", "https://api.kimi.com/coding/v1", "KIMI_API_KEY"),
128
+ minimax: anthropicMessages("MiniMax", "https://api.minimax.io/anthropic/v1", "MINIMAX_API_KEY"),
129
+ "minimax-cn": anthropicMessages("MiniMax CN", "https://api.minimaxi.com/anthropic/v1", "MINIMAX_CN_API_KEY"),
130
+ "vercel-ai-gateway": anthropicMessages(
131
+ "Vercel AI Gateway",
132
+ "https://ai-gateway.vercel.sh/v1",
133
+ "AI_GATEWAY_API_KEY"
134
+ )
135
+ };
136
+ var MODEL_PROVIDER_VENDOR_IDS = Object.keys(
137
+ MODEL_PROVIDER_VENDORS
138
+ );
139
+ function modelProviderVendor(kind) {
140
+ return Object.hasOwn(MODEL_PROVIDER_VENDORS, kind) ? MODEL_PROVIDER_VENDORS[kind] : void 0;
141
+ }
142
+
59
143
  // src/url.ts
60
144
  function normalizeProviderUrl(value) {
61
145
  let url;
@@ -105,9 +189,7 @@ var ProviderProfileRefSchema = z.string().min(1).max(64).regex(
105
189
  "provider profile refs must be lowercase portable identifiers"
106
190
  );
107
191
  var MODEL_PROVIDER_KINDS = [
108
- "openai",
109
- "deepseek",
110
- "anthropic",
192
+ ...MODEL_PROVIDER_VENDOR_IDS,
111
193
  "custom"
112
194
  ];
113
195
  var PROVIDER_MODEL_CAPABILITIES = ["image-input"];
@@ -182,6 +264,14 @@ var ModelProviderProfileSchema = z.object({
182
264
  path: ["auth_mode"]
183
265
  });
184
266
  }
267
+ const vendor = modelProviderVendor(profile.provider_kind);
268
+ if (vendor !== void 0 && vendor.adapter !== profile.adapter) {
269
+ ctx.addIssue({
270
+ code: "custom",
271
+ message: `Provider kind ${profile.provider_kind} speaks the ${vendor.adapter} adapter`,
272
+ path: ["adapter"]
273
+ });
274
+ }
185
275
  if (Date.parse(profile.updated_at) < Date.parse(profile.created_at)) {
186
276
  ctx.addIssue({
187
277
  code: "custom",
@@ -1320,15 +1410,18 @@ function secureSqliteFilePermissions(databasePath) {
1320
1410
  }
1321
1411
 
1322
1412
  // src/sqlite-profile-store.ts
1413
+ function sqlList(values) {
1414
+ return values.map((value) => `'${value}'`).join(", ");
1415
+ }
1323
1416
  var SCHEMA = `
1324
1417
  CREATE TABLE IF NOT EXISTS provider_profile (
1325
1418
  profile_ref TEXT PRIMARY KEY,
1326
- provider_kind TEXT NOT NULL CHECK (provider_kind IN ('openai', 'deepseek', 'anthropic', 'custom')),
1419
+ provider_kind TEXT NOT NULL CHECK (provider_kind IN (${sqlList(MODEL_PROVIDER_KINDS)})),
1327
1420
  kind TEXT NOT NULL CHECK (kind = 'model'),
1328
- adapter TEXT NOT NULL CHECK (adapter IN ('openai_compatible', 'anthropic')),
1421
+ adapter TEXT NOT NULL CHECK (adapter IN (${sqlList(MODEL_PROVIDER_ADAPTERS)})),
1329
1422
  display_name TEXT NOT NULL,
1330
1423
  base_url TEXT NOT NULL,
1331
- auth_mode TEXT NOT NULL CHECK (auth_mode IN ('bearer', 'x_api_key', 'none')),
1424
+ auth_mode TEXT NOT NULL CHECK (auth_mode IN (${sqlList(PROVIDER_AUTH_MODES)})),
1332
1425
  model TEXT NOT NULL,
1333
1426
  capabilities TEXT NOT NULL,
1334
1427
  enabled INTEGER NOT NULL CHECK (enabled IN (0, 1)),
@@ -1336,6 +1429,21 @@ CREATE TABLE IF NOT EXISTS provider_profile (
1336
1429
  updated_at TEXT NOT NULL
1337
1430
  );
1338
1431
  `;
1432
+ function normalizeTableDdl(sql) {
1433
+ return sql.replace(/\bIF\s+NOT\s+EXISTS\b/giu, "").replace(/\s+/gu, " ").trim().replace(/;$/u, "").trim();
1434
+ }
1435
+ function assertProviderProfileSchemaIsCurrent(database, path2) {
1436
+ const row = database.prepare(
1437
+ "SELECT sql FROM sqlite_master WHERE type = 'table' AND name = 'provider_profile'"
1438
+ ).get();
1439
+ const stored = row?.sql;
1440
+ if (typeof stored !== "string") return;
1441
+ if (normalizeTableDdl(stored) === normalizeTableDdl(SCHEMA)) return;
1442
+ throw new ByokKeysError(
1443
+ "PROVIDER_STORE_SCHEMA_STALE",
1444
+ `Provider profile store at ${path2} was created by a different @byok-sdk/keys schema; recreate the store file to continue`
1445
+ );
1446
+ }
1339
1447
  var ENABLED_INDEX = `
1340
1448
  CREATE UNIQUE INDEX IF NOT EXISTS provider_profile_one_enabled
1341
1449
  ON provider_profile(kind)
@@ -1352,6 +1460,7 @@ var SqliteProviderProfileStore = class {
1352
1460
  try {
1353
1461
  this.#database.exec(SCHEMA);
1354
1462
  this.#database.exec(ENABLED_INDEX);
1463
+ assertProviderProfileSchemaIsCurrent(this.#database, options.path);
1355
1464
  secureSqliteFilePermissions(options.path);
1356
1465
  } catch (error) {
1357
1466
  closeSqliteDatabaseAfterInitializationFailure(
@@ -1360,6 +1469,16 @@ var SqliteProviderProfileStore = class {
1360
1469
  "SqliteProviderProfileStore initialization failed and its native handle could not be closed"
1361
1470
  );
1362
1471
  }
1472
+ } else {
1473
+ try {
1474
+ assertProviderProfileSchemaIsCurrent(this.#database, options.path);
1475
+ } catch (error) {
1476
+ closeSqliteDatabaseAfterInitializationFailure(
1477
+ this.#database,
1478
+ error,
1479
+ "SqliteProviderProfileStore read-only schema check failed and its native handle could not be closed"
1480
+ );
1481
+ }
1363
1482
  }
1364
1483
  }
1365
1484
  /**
@@ -1866,6 +1985,6 @@ function buildPiProviderProjection(profile) {
1866
1985
  };
1867
1986
  }
1868
1987
 
1869
- export { AnthropicMessagesClient, BYOK_KEYS_ERROR_CODES, ByokKeysError, DEFAULT_KEYCHAIN_SECRET_STORAGE_PREFIX, DEFAULT_SECRET_ENVELOPE_PREFIX, DEFAULT_SECRET_SERVICE_PREFIX, EnvelopeScopedSecretStore, InMemoryProviderProfileStore, InMemorySecretStore, MODEL_PROVIDER_ADAPTERS, MODEL_PROVIDER_KINDS, MacOsKeychainSecretStore, ModelProviderProfileSchema, OpenAiCompatibleChatClient, PI_PROJECTED_KEY_ENV, PROVIDER_AUTH_MODES, PROVIDER_MODEL_CAPABILITIES, PROVIDER_PROFILE_TRUTH_RECORD_KEY, PROVIDER_RESPONSE_MAX_BYTES, PROVIDER_TIMEOUT_MS, ProviderModelCapabilitySchema, ProviderProfileRefSchema, ProviderRegistry, SECRET_NAMESPACE_PATTERN, SECRET_NAME_PATTERN, SqliteProviderProfileStore, TruthStoreProviderProfileStore, WindowsCredentialManagerSecretStore, anthropicMessageText, assertExactProviderProfileBinding, assertLiveModelResponse, assertSecretName, assertSecretNamespace, assertSharedSecretValue, buildPiProviderProjection, chatCompletionText, classifyModelProviderHttpError, decodeStrictBase64Utf8, exactProviderProfileBinding, fetchWithProviderGuards, isLoopbackHost, isLoopbackProviderUrl, isPrivateNetworkLiteral, isSqliteAvailable, loadSqliteModule, modelApiUrl, modelMessageText, modelProviderSecretName, normalizeProviderUrl, objectValue, openSqliteDatabase, parseBoundedJsonResponse, parseModelProviderProfile, providerHeaders, readModelProviderResponse, requiredProviderSecret, runCommand, scopeSecretStore, secretScopeId, secureSqliteFilePermissions };
1988
+ export { AnthropicMessagesClient, BYOK_KEYS_ERROR_CODES, ByokKeysError, DEFAULT_KEYCHAIN_SECRET_STORAGE_PREFIX, DEFAULT_SECRET_ENVELOPE_PREFIX, DEFAULT_SECRET_SERVICE_PREFIX, EnvelopeScopedSecretStore, InMemoryProviderProfileStore, InMemorySecretStore, MODEL_PROVIDER_ADAPTERS, MODEL_PROVIDER_KINDS, MODEL_PROVIDER_VENDORS, MODEL_PROVIDER_VENDOR_IDS, MacOsKeychainSecretStore, ModelProviderProfileSchema, OpenAiCompatibleChatClient, PI_PROJECTED_KEY_ENV, PROVIDER_AUTH_MODES, PROVIDER_MODEL_CAPABILITIES, PROVIDER_PROFILE_TRUTH_RECORD_KEY, PROVIDER_RESPONSE_MAX_BYTES, PROVIDER_TIMEOUT_MS, ProviderModelCapabilitySchema, ProviderProfileRefSchema, ProviderRegistry, SECRET_NAMESPACE_PATTERN, SECRET_NAME_PATTERN, SqliteProviderProfileStore, TruthStoreProviderProfileStore, WindowsCredentialManagerSecretStore, anthropicMessageText, assertExactProviderProfileBinding, assertLiveModelResponse, assertSecretName, assertSecretNamespace, assertSharedSecretValue, buildPiProviderProjection, chatCompletionText, classifyModelProviderHttpError, decodeStrictBase64Utf8, exactProviderProfileBinding, fetchWithProviderGuards, isLoopbackHost, isLoopbackProviderUrl, isPrivateNetworkLiteral, isSqliteAvailable, loadSqliteModule, modelApiUrl, modelMessageText, modelProviderSecretName, modelProviderVendor, normalizeProviderUrl, objectValue, openSqliteDatabase, parseBoundedJsonResponse, parseModelProviderProfile, providerHeaders, readModelProviderResponse, requiredProviderSecret, runCommand, scopeSecretStore, secretScopeId, secureSqliteFilePermissions };
1870
1989
  //# sourceMappingURL=index.js.map
1871
1990
  //# sourceMappingURL=index.js.map