dsh-model-groups 0.3.7 → 0.3.9

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.
@@ -3,8 +3,369 @@
3
3
  "packageName": "@deepseek-ai/dsh-llm-pi-ai",
4
4
  "target": "node_modules/@deepseek-ai/dsh-llm-pi-ai/lib/index.js",
5
5
  "baseSha256": "070c839e2c00e2d5f7c5d82307ca3d84dbb2323e46979daf265908751bbe8ae8",
6
- "resultSha256": "7c234a4d68794ee54112583c4d4bfaf7c9819b9227c3149f58fa7584883c7aff",
6
+ "resultSha256": "7c91a878438fd82f047e365a07235aa0aabd62fb749a1bc0292fef91e0f16809",
7
7
  "variants": [
8
+ {
9
+ "source": "multi-key revision before per-entry API overrides",
10
+ "baseSha256": "070c839e2c00e2d5f7c5d82307ca3d84dbb2323e46979daf265908751bbe8ae8",
11
+ "resultSha256": "bd5b251b3d1d8441ee7aa552b537d0331b3f8f78c0f9f26f3b5035e5a36fe5ed",
12
+ "replacements": [
13
+ {
14
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
15
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
16
+ },
17
+ {
18
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
19
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
20
+ },
21
+ {
22
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
23
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
24
+ },
25
+ {
26
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
27
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
28
+ },
29
+ {
30
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
31
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
32
+ },
33
+ {
34
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
35
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
36
+ },
37
+ {
38
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
39
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
40
+ },
41
+ {
42
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
43
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
44
+ },
45
+ {
46
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
47
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
48
+ },
49
+ {
50
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
51
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
52
+ },
53
+ {
54
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
55
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
56
+ },
57
+ {
58
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
59
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
60
+ },
61
+ {
62
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
63
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
64
+ },
65
+ {
66
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
67
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
68
+ },
69
+ {
70
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
71
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
72
+ },
73
+ {
74
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
75
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
76
+ },
77
+ {
78
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
79
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
80
+ },
81
+ {
82
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
83
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
84
+ },
85
+ {
86
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
87
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
88
+ },
89
+ {
90
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
91
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
92
+ },
93
+ {
94
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
95
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
96
+ },
97
+ {
98
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
99
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
100
+ },
101
+ {
102
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
103
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
104
+ },
105
+ {
106
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
107
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
108
+ },
109
+ {
110
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
111
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
112
+ },
113
+ {
114
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
115
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
116
+ },
117
+ {
118
+ "before": "function listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");",
119
+ "after": "/** Strip trailing slashes and one trailing `/v1`, the segment the Anthropic SDK adds itself. */\nfunction anthropicRoot(baseURL) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");\n\treturn base.endsWith(\"/v1\") ? base.slice(0, -3) : base;\n}\nfunction listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");"
120
+ },
121
+ {
122
+ "before": "\t\tconst baseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (baseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);",
123
+ "after": "\t\tconst configuredBaseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (configuredBaseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);\n\t\tconst baseUrl = api === \"anthropic-messages\" ? anthropicRoot(configuredBaseUrl) : configuredBaseUrl;"
124
+ },
125
+ {
126
+ "before": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${base.endsWith(\"/v1\") ? base.slice(0, -3) : base}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;",
127
+ "after": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${anthropicRoot(base)}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;"
128
+ },
129
+ {
130
+ "before": "* gateway documentation publishes both spellings of the same root. Only this\n* listing URL normalizes that segment; model requests receive the configured\n* `baseURL` unchanged.\n*/",
131
+ "after": "* gateway documentation publishes both spellings of the same root. Anthropic\n* listings and model requests both normalize it, because the Anthropic SDK\n* appends `/v1/messages` on its own while OpenAI protocols append\n* `/chat/completions`; without this, one root would work for chat and double\n* the segment for Anthropic.\n*/"
132
+ }
133
+ ]
134
+ },
135
+ {
136
+ "source": "multi-key revision before per-entry API overrides",
137
+ "baseSha256": "070c839e2c00e2d5f7c5d82307ca3d84dbb2323e46979daf265908751bbe8ae8",
138
+ "resultSha256": "56b60061cc2ca642d3572214a40dbd679390c7f5427e739a11b3230ac2169ded",
139
+ "replacements": [
140
+ {
141
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
142
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
143
+ },
144
+ {
145
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
146
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
147
+ },
148
+ {
149
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
150
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
151
+ },
152
+ {
153
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
154
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
155
+ },
156
+ {
157
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
158
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
159
+ },
160
+ {
161
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
162
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
163
+ },
164
+ {
165
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
166
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
167
+ },
168
+ {
169
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
170
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
171
+ },
172
+ {
173
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
174
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
175
+ },
176
+ {
177
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
178
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
179
+ },
180
+ {
181
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
182
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
183
+ },
184
+ {
185
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
186
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
187
+ },
188
+ {
189
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
190
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
191
+ },
192
+ {
193
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
194
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
195
+ },
196
+ {
197
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
198
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
199
+ },
200
+ {
201
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
202
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
203
+ },
204
+ {
205
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
206
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
207
+ },
208
+ {
209
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
210
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
211
+ },
212
+ {
213
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
214
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
215
+ },
216
+ {
217
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
218
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
219
+ },
220
+ {
221
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
222
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
223
+ },
224
+ {
225
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
226
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
227
+ },
228
+ {
229
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
230
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
231
+ },
232
+ {
233
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
234
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
235
+ },
236
+ {
237
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
238
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
239
+ },
240
+ {
241
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
242
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
243
+ },
244
+ {
245
+ "before": "function listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");",
246
+ "after": "/** Strip trailing slashes and one trailing `/v1`, the segment the Anthropic SDK adds itself. */\nfunction anthropicRoot(baseURL) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");\n\treturn base.endsWith(\"/v1\") ? base.slice(0, -3) : base;\n}\nfunction listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");"
247
+ },
248
+ {
249
+ "before": "\t\tconst baseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (baseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);",
250
+ "after": "\t\tconst configuredBaseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (configuredBaseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);\n\t\tconst baseUrl = api === \"anthropic-messages\" ? anthropicRoot(configuredBaseUrl) : configuredBaseUrl;"
251
+ },
252
+ {
253
+ "before": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${base.endsWith(\"/v1\") ? base.slice(0, -3) : base}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;",
254
+ "after": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${anthropicRoot(base)}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;"
255
+ }
256
+ ]
257
+ },
258
+ {
259
+ "source": "multi-key revision before per-entry API overrides",
260
+ "baseSha256": "070c839e2c00e2d5f7c5d82307ca3d84dbb2323e46979daf265908751bbe8ae8",
261
+ "resultSha256": "7c234a4d68794ee54112583c4d4bfaf7c9819b9227c3149f58fa7584883c7aff",
262
+ "replacements": [
263
+ {
264
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
265
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
266
+ },
267
+ {
268
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
269
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
270
+ },
271
+ {
272
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
273
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
274
+ },
275
+ {
276
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
277
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
278
+ },
279
+ {
280
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
281
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
282
+ },
283
+ {
284
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
285
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
286
+ },
287
+ {
288
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
289
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
290
+ },
291
+ {
292
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
293
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
294
+ },
295
+ {
296
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
297
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
298
+ },
299
+ {
300
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
301
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
302
+ },
303
+ {
304
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
305
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
306
+ },
307
+ {
308
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
309
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
310
+ },
311
+ {
312
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
313
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
314
+ },
315
+ {
316
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
317
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
318
+ },
319
+ {
320
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
321
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
322
+ },
323
+ {
324
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
325
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
326
+ },
327
+ {
328
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
329
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
330
+ },
331
+ {
332
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
333
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
334
+ },
335
+ {
336
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
337
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
338
+ },
339
+ {
340
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
341
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
342
+ },
343
+ {
344
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
345
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
346
+ },
347
+ {
348
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
349
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
350
+ },
351
+ {
352
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
353
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
354
+ },
355
+ {
356
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
357
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
358
+ },
359
+ {
360
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
361
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
362
+ },
363
+ {
364
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
365
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
366
+ }
367
+ ]
368
+ },
8
369
  {
9
370
  "source": "multi-key revision before per-entry API overrides",
10
371
  "baseSha256": "070c839e2c00e2d5f7c5d82307ca3d84dbb2323e46979daf265908751bbe8ae8",
@@ -100,7 +461,478 @@
100
461
  },
101
462
  {
102
463
  "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
103
- "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api ?? selectedStored?.api ?? \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
464
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api ?? selectedStored?.api ?? \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
465
+ },
466
+ {
467
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
468
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
469
+ },
470
+ {
471
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
472
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
473
+ },
474
+ {
475
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
476
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
477
+ }
478
+ ]
479
+ },
480
+ {
481
+ "source": "multi-key revision before per-entry API overrides",
482
+ "baseSha256": "070c839e2c00e2d5f7c5d82307ca3d84dbb2323e46979daf265908751bbe8ae8",
483
+ "resultSha256": "a2b3bcda38015026ed58074cef0d508bbd2d7cb1423c00331651fcbd1a9f6b55",
484
+ "replacements": [
485
+ {
486
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
487
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
488
+ },
489
+ {
490
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
491
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
492
+ },
493
+ {
494
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
495
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
496
+ },
497
+ {
498
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
499
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
500
+ },
501
+ {
502
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
503
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
504
+ },
505
+ {
506
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
507
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
508
+ },
509
+ {
510
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
511
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
512
+ },
513
+ {
514
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
515
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
516
+ },
517
+ {
518
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
519
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
520
+ },
521
+ {
522
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
523
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
524
+ },
525
+ {
526
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
527
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
528
+ },
529
+ {
530
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
531
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
532
+ },
533
+ {
534
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
535
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
536
+ },
537
+ {
538
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
539
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
540
+ },
541
+ {
542
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
543
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
544
+ },
545
+ {
546
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
547
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
548
+ },
549
+ {
550
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
551
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
552
+ },
553
+ {
554
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
555
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
556
+ },
557
+ {
558
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
559
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
560
+ }
561
+ ]
562
+ },
563
+ {
564
+ "source": "0.2.2-rc.1 with tool lookup optimization and credential cancellation",
565
+ "baseSha256": "0a99a2fc903a4285044b09114b3bd20ee1e612f39aa381e4a71b10d48ee9e9f7",
566
+ "resultSha256": "c87f965d9fcc5bbcd386e98ea3b292b05ec7a55d80df1266e18234031b80990e",
567
+ "replacements": [
568
+ {
569
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
570
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
571
+ },
572
+ {
573
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
574
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
575
+ },
576
+ {
577
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
578
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
579
+ },
580
+ {
581
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
582
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
583
+ },
584
+ {
585
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
586
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
587
+ },
588
+ {
589
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
590
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
591
+ },
592
+ {
593
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
594
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
595
+ },
596
+ {
597
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
598
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
599
+ },
600
+ {
601
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
602
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
603
+ },
604
+ {
605
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
606
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
607
+ },
608
+ {
609
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
610
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
611
+ },
612
+ {
613
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
614
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
615
+ },
616
+ {
617
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
618
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
619
+ },
620
+ {
621
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
622
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
623
+ },
624
+ {
625
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
626
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
627
+ },
628
+ {
629
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
630
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
631
+ },
632
+ {
633
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
634
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
635
+ },
636
+ {
637
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
638
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
639
+ },
640
+ {
641
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
642
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
643
+ }
644
+ ]
645
+ },
646
+ {
647
+ "source": "npm official 0.2.2-rc.1",
648
+ "baseSha256": "1a3ae58f9b4493e15459cc5000ec80f21b5d3f4a9dea6ffb6bc28e5b8817ae8a",
649
+ "resultSha256": "b9416207cc7c27aff40cb2b877c9176e53809eb2f6dc741828c2ed6f6bdf541b",
650
+ "replacements": [
651
+ {
652
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
653
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
654
+ },
655
+ {
656
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
657
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
658
+ },
659
+ {
660
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
661
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
662
+ },
663
+ {
664
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
665
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
666
+ },
667
+ {
668
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
669
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
670
+ },
671
+ {
672
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
673
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
674
+ },
675
+ {
676
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
677
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
678
+ },
679
+ {
680
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
681
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
682
+ },
683
+ {
684
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
685
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
686
+ },
687
+ {
688
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
689
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
690
+ },
691
+ {
692
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
693
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
694
+ },
695
+ {
696
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
697
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
698
+ },
699
+ {
700
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
701
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
702
+ },
703
+ {
704
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
705
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
706
+ },
707
+ {
708
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
709
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
710
+ },
711
+ {
712
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
713
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
714
+ },
715
+ {
716
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
717
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
718
+ },
719
+ {
720
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
721
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
722
+ },
723
+ {
724
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
725
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
726
+ }
727
+ ]
728
+ },
729
+ {
730
+ "source": "npm official 0.2.2-rc.1 with per-entry API overrides",
731
+ "baseSha256": "1a3ae58f9b4493e15459cc5000ec80f21b5d3f4a9dea6ffb6bc28e5b8817ae8a",
732
+ "resultSha256": "5ea8e84da726c04caa6bb321cf41617051ad9a80444834328007643b09b43a32",
733
+ "replacements": [
734
+ {
735
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
736
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
737
+ },
738
+ {
739
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
740
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
741
+ },
742
+ {
743
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
744
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
745
+ },
746
+ {
747
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
748
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
749
+ },
750
+ {
751
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
752
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
753
+ },
754
+ {
755
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
756
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
757
+ },
758
+ {
759
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
760
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
761
+ },
762
+ {
763
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
764
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
765
+ },
766
+ {
767
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
768
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
769
+ },
770
+ {
771
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
772
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
773
+ },
774
+ {
775
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
776
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
777
+ },
778
+ {
779
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
780
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
781
+ },
782
+ {
783
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
784
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
785
+ },
786
+ {
787
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
788
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
789
+ },
790
+ {
791
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
792
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
793
+ },
794
+ {
795
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
796
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
797
+ },
798
+ {
799
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
800
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
801
+ },
802
+ {
803
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
804
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
805
+ },
806
+ {
807
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
808
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
809
+ },
810
+ {
811
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
812
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
813
+ },
814
+ {
815
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
816
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
817
+ },
818
+ {
819
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
820
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
821
+ },
822
+ {
823
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
824
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api ?? selectedStored?.api ?? \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
825
+ },
826
+ {
827
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
828
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
829
+ },
830
+ {
831
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
832
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
833
+ },
834
+ {
835
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
836
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
837
+ }
838
+ ]
839
+ },
840
+ {
841
+ "source": "npm official 0.2.2-rc.1 with per-entry API overrides",
842
+ "baseSha256": "1a3ae58f9b4493e15459cc5000ec80f21b5d3f4a9dea6ffb6bc28e5b8817ae8a",
843
+ "resultSha256": "9ca2b07c19694a4521a29c82b7948fb6326d80ee7741200a1d7b0f3f06e1da19",
844
+ "replacements": [
845
+ {
846
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
847
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
848
+ },
849
+ {
850
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
851
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
852
+ },
853
+ {
854
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
855
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
856
+ },
857
+ {
858
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
859
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
860
+ },
861
+ {
862
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
863
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
864
+ },
865
+ {
866
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
867
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
868
+ },
869
+ {
870
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
871
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
872
+ },
873
+ {
874
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
875
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
876
+ },
877
+ {
878
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
879
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
880
+ },
881
+ {
882
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
883
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
884
+ },
885
+ {
886
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
887
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
888
+ },
889
+ {
890
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
891
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
892
+ },
893
+ {
894
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
895
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
896
+ },
897
+ {
898
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
899
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
900
+ },
901
+ {
902
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
903
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
904
+ },
905
+ {
906
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
907
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
908
+ },
909
+ {
910
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
911
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
912
+ },
913
+ {
914
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
915
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
916
+ },
917
+ {
918
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
919
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
920
+ },
921
+ {
922
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
923
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
924
+ },
925
+ {
926
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
927
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
928
+ },
929
+ {
930
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
931
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
932
+ },
933
+ {
934
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
935
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
104
936
  },
105
937
  {
106
938
  "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
@@ -117,9 +949,9 @@
117
949
  ]
118
950
  },
119
951
  {
120
- "source": "multi-key revision before per-entry API overrides",
121
- "baseSha256": "070c839e2c00e2d5f7c5d82307ca3d84dbb2323e46979daf265908751bbe8ae8",
122
- "resultSha256": "a2b3bcda38015026ed58074cef0d508bbd2d7cb1423c00331651fcbd1a9f6b55",
952
+ "source": "0.2.2-rc.1 with tool lookup optimization and credential cancellation with per-entry API overrides",
953
+ "baseSha256": "0a99a2fc903a4285044b09114b3bd20ee1e612f39aa381e4a71b10d48ee9e9f7",
954
+ "resultSha256": "e999e1a7f2352177c653ff0cea6485c3b1d1ea95b40ea613fc0549e2c8e49662",
123
955
  "replacements": [
124
956
  {
125
957
  "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
@@ -196,13 +1028,41 @@
196
1028
  {
197
1029
  "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
198
1030
  "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
1031
+ },
1032
+ {
1033
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
1034
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
1035
+ },
1036
+ {
1037
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
1038
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
1039
+ },
1040
+ {
1041
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
1042
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
1043
+ },
1044
+ {
1045
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
1046
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
1047
+ },
1048
+ {
1049
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
1050
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
1051
+ },
1052
+ {
1053
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
1054
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
1055
+ },
1056
+ {
1057
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
1058
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
199
1059
  }
200
1060
  ]
201
1061
  },
202
1062
  {
203
- "source": "0.2.2-rc.1 with tool lookup optimization and credential cancellation",
1063
+ "source": "0.2.2-rc.1 with tool lookup optimization and credential cancellation with per-entry API overrides",
204
1064
  "baseSha256": "0a99a2fc903a4285044b09114b3bd20ee1e612f39aa381e4a71b10d48ee9e9f7",
205
- "resultSha256": "c87f965d9fcc5bbcd386e98ea3b292b05ec7a55d80df1266e18234031b80990e",
1065
+ "resultSha256": "0a398e35a7e66f0cb547da9c421e33123b9959bd058c3d006baf3c587ff4c596",
206
1066
  "replacements": [
207
1067
  {
208
1068
  "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
@@ -279,13 +1139,176 @@
279
1139
  {
280
1140
  "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
281
1141
  "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
1142
+ },
1143
+ {
1144
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
1145
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
1146
+ },
1147
+ {
1148
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
1149
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
1150
+ },
1151
+ {
1152
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
1153
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
1154
+ },
1155
+ {
1156
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
1157
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
1158
+ },
1159
+ {
1160
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
1161
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
1162
+ },
1163
+ {
1164
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
1165
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
1166
+ },
1167
+ {
1168
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
1169
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
1170
+ },
1171
+ {
1172
+ "before": "function listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");",
1173
+ "after": "/** Strip trailing slashes and one trailing `/v1`, the segment the Anthropic SDK adds itself. */\nfunction anthropicRoot(baseURL) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");\n\treturn base.endsWith(\"/v1\") ? base.slice(0, -3) : base;\n}\nfunction listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");"
1174
+ },
1175
+ {
1176
+ "before": "\t\tconst baseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (baseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);",
1177
+ "after": "\t\tconst configuredBaseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (configuredBaseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);\n\t\tconst baseUrl = api === \"anthropic-messages\" ? anthropicRoot(configuredBaseUrl) : configuredBaseUrl;"
1178
+ },
1179
+ {
1180
+ "before": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${base.endsWith(\"/v1\") ? base.slice(0, -3) : base}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;",
1181
+ "after": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${anthropicRoot(base)}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;"
282
1182
  }
283
1183
  ]
284
1184
  },
285
1185
  {
286
- "source": "npm official 0.2.2-rc.1",
1186
+ "source": "npm official 0.2.2-rc.1 with per-entry API overrides",
287
1187
  "baseSha256": "1a3ae58f9b4493e15459cc5000ec80f21b5d3f4a9dea6ffb6bc28e5b8817ae8a",
288
- "resultSha256": "b9416207cc7c27aff40cb2b877c9176e53809eb2f6dc741828c2ed6f6bdf541b",
1188
+ "resultSha256": "432b9050dff97c9dae6744b6c6189e0c4a4363321afab6310aec4d5fcb418681",
1189
+ "replacements": [
1190
+ {
1191
+ "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
1192
+ "after": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\n// Model selection carries an opaque entry identity, never a credential or a wire alias.\nconst KEY_MODEL_PREFIX = \"@dsh-key/\";\nconst KEY_ENTRY_ID = /^[A-Za-z0-9][A-Za-z0-9_-]{0,79}$/;\nconst FORBIDDEN_KEY_ENTRY_IDS = new Set([\"__proto__\", \"prototype\", \"constructor\"]);\nconst AUTH_HEADER_NAMES = new Set([\"authorization\", \"proxy-authorization\", \"x-api-key\", \"api-key\", \"cf-aig-authorization\"]);\nfunction validKeyEntryId(id) {\n\treturn KEY_ENTRY_ID.test(id) && !FORBIDDEN_KEY_ENTRY_IDS.has(id);\n}\nfunction keyModelId(entryId, model) {\n\treturn `${KEY_MODEL_PREFIX}${encodeURIComponent(entryId)}/${encodeURIComponent(model)}`;\n}\nfunction keyModelRoute(model) {\n\tif (!model.startsWith(KEY_MODEL_PREFIX)) return void 0;\n\ttry {\n\t\tconst parts = model.slice(KEY_MODEL_PREFIX.length).split(\"/\");\n\t\tif (parts.length === 2) {\n\t\t\tconst entryId = decodeURIComponent(parts[0]);\n\t\t\tconst wireModel = decodeURIComponent(parts[1]);\n\t\t\tif (validKeyEntryId(entryId) && wireModel.length > 0 && !wireModel.startsWith(KEY_MODEL_PREFIX) && keyModelId(entryId, wireModel) === model) return { entryId, wireModel };\n\t\t}\n\t} catch {}\n\tthrow new LlmError(`invalid multi-key model selection \"${model}\"`, \"UNKNOWN_MODEL\");\n}\nconst keyEntryProfile = z.object({\n\tname: z.string().max(120).required(),\n\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});\nconst profile = z.object({\n\tmultiKey: z.boolean().default(false),\n\tkeyEntries: z.dict(keyEntryProfile).default({}),\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n"
1193
+ },
1194
+ {
1195
+ "before": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\") {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n",
1196
+ "after": "* @param providers - configured provider profiles keyed by route.\n* @param validation - writes require a complete catalog; stored reads retain catalog diagnostics.\n* @returns validated profiles in configuration order.\n*/\nfunction resolveProfiles(providers, validation = \"strict\", forKeyEntry = false) {\n\tif (Array.isArray(providers)) throw new Error(\"llm-pi-ai: providers is now a dict keyed by provider route, not an array of profiles\");\n\tconst entries = Object.entries(providers ?? {});\n\tconst resolved = /* @__PURE__ */ new Map();\n\tfor (const [provider, source] of entries) {\n"
1197
+ },
1198
+ {
1199
+ "before": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n",
1200
+ "after": "\t\tif (provider.length === 0) throw new Error(\"llm-pi-ai: provider names must be non-empty\");\n\t\tif (source.baseURL !== void 0 && source.baseURL.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty baseURL`);\n\t\tif (source.displayName !== void 0 && source.displayName.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" has an empty displayName`);\n\t\tassertValidHeaders(provider, source.headers);\n\t\tconst entrySources = source.keyEntries ?? {};\n\t\tif (typeof entrySources !== \"object\" || entrySources === null || Array.isArray(entrySources)) throw new Error(`llm-pi-ai: provider \"${provider}\" keyEntries must be a dictionary`);\n\t\tconst assertWireModels = (models, site) => {\n\t\t\tfor (const model of models ?? []) if (typeof model.id !== \"string\" || model.id.length === 0 || model.id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} must use non-empty upstream model ids outside the reserved ${KEY_MODEL_PREFIX} prefix`);\n\t\t};\n\t\tassertWireModels(source.models, \"models\");\n\t\tfor (const id of Object.keys(source.modelOverrides ?? {})) if (id.startsWith(KEY_MODEL_PREFIX)) throw new Error(`llm-pi-ai: provider \"${provider}\" modelOverrides uses reserved prefix ${KEY_MODEL_PREFIX}`);\n\t\tfor (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tif (!validKeyEntryId(id)) throw new Error(`llm-pi-ai: provider \"${provider}\" has an invalid key entry id \"${id}\"`);\n\t\t\tif (typeof entry !== \"object\" || entry === null || typeof entry.name !== \"string\" || entry.name.trim().length === 0 || entry.name.length > 120) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs a name of 1-120 characters`);\n\t\t\tif (typeof entry.apiKeyEnv !== \"string\" || entry.apiKeyEnv.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own apiKeyEnv`);\n\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" needs its own models list`);\n\t\t\tassertWireModels(entry.models, `key entry \"${id}\" models`);\n\t\t}\n\t\tconst assertEntryHeaders = (headers, site) => {\n\t\t\tfor (const name of Object.keys(headers ?? {})) if (AUTH_HEADER_NAMES.has(name.toLowerCase())) throw new Error(`llm-pi-ai: provider \"${provider}\" ${site} authentication header \"${name}\" would override the selected key; remove it before enabling multiKey`);\n\t\t};\n\t\tif (source.multiKey === true || forKeyEntry) {\n\t\t\tassertEntryHeaders(source.headers, \"shared\");\n\t\t\tfor (const model of source.models ?? []) assertEntryHeaders(model.headers, `model \"${model.id}\"`);\n\t\t\tfor (const [id, override] of Object.entries(source.modelOverrides ?? {})) assertEntryHeaders(override.headers, `model override \"${id}\"`);\n\t\t}\n\t\tconst streamIdleTimeoutMs = source.streamIdleTimeoutMs ?? 3e5;\n\t\tif (!Number.isFinite(streamIdleTimeoutMs) || streamIdleTimeoutMs <= 0 || streamIdleTimeoutMs > MAX_TIMER_DELAY_MS) throw new Error(`llm-pi-ai: provider \"${provider}\" streamIdleTimeoutMs must be a positive finite number no greater than ${MAX_TIMER_DELAY_MS}`);\n\t\tconst maxRequestImageBytes = source.maxRequestImageBytes ?? 20971520;\n\t\tif (!Number.isInteger(maxRequestImageBytes) || maxRequestImageBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" maxRequestImageBytes must be a positive integer`);\n"
1201
+ },
1202
+ {
1203
+ "before": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\ttry {\n\t\t\tcatalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n",
1204
+ "after": "\t\tif (!Number.isSafeInteger(requestImageMaxBytes) || requestImageMaxBytes <= 0) throw new Error(`llm-pi-ai: provider \"${provider}\" requestImageMaxBytes must be a positive safe integer`);\n\t\tconst defaultInput = [...source.defaultInput ?? DEFAULT_INPUT];\n\t\tif (defaultInput.length === 0) throw new Error(`llm-pi-ai: provider \"${provider}\" defaultInput must name at least one modality`);\n\t\tconst displayName = source.displayName ?? provider;\n\t\tconst keyEntries = new Map();\n\t\t// Disabled entries remain stored, but cannot constrain legacy single-key runtime behavior.\n\t\tif (source.multiKey === true) for (const [id, entry] of Object.entries(entrySources)) {\n\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,\n\t\t\t\tkeyEntries: {},\n\t\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\t\tmodels: entry.models,\n\t\t\t\tmodelOverrides: void 0\n\t\t\t} }, validation, true).get(provider);\n\t\t\t// Entry auth must not consult a catalog provider's ambient/OAuth credential or endpoint.\n\t\t\tkeyEntries.set(id, {\n\t\t\t\t...child,\n\t\t\t\tkeyEntryId: id,\n\t\t\t\tkeyEntryName: entry.name,\n\t\t\t\t...child.piProvider === void 0 ? {} : { piProvider: { ...child.piProvider, auth: { apiKey: harnessApiKeyAuth(entry.name) } } }\n\t\t\t});\n\t\t}\n\t\tlet catalog;\n\t\tlet piProvider;\n\t\tlet catalogError;\n\t\tconst entryOnly = forKeyEntry && source.models.length === 0 || source.multiKey === true && keyEntries.size > 0 && (source.models ?? []).length === 0 && catalogModels(provider).size === 0;\n\t\ttry {\n\t\t\tif (entryOnly) catalog = { models: [], configuredMaxTokens: new Map(), modelErrors: new Map() };\n\t\t\telse catalog = resolveRouteModels({\n\t\t\t\tprovider,\n\t\t\t\t...source.api === void 0 ? {} : { api: source.api },\n\t\t\t\t...source.baseURL === void 0 ? {} : { baseURL: source.baseURL },\n\t\t\t\t...source.models === void 0 ? {} : { models: source.models },\n"
1205
+ },
1206
+ {
1207
+ "before": "\t\t\t}, validation);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;",
1208
+ "after": "\t\t\t}, validation);\n\t\t\tif (source.multiKey === true || forKeyEntry) for (const model of catalog.models) assertEntryHeaders(model.headers, `resolved model \"${model.id}\"`);\n\t\t\tcatalogError = catalog.modelErrors.values().next().value;"
1209
+ },
1210
+ {
1211
+ "before": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },",
1212
+ "after": "\t\tconst { apiKeyEnv, retryPolicy, models: _models, displayName: _displayName, keyEntries: _keyEntries, ...rest } = source;\n\t\tresolved.set(provider, {\n\t\t\t...rest,\n\t\t\tprovider,\n\t\t\tdisplayName,\n\t\t\tkeyEntries,\n\t\t\t...apiKeyEnv === void 0 ? {} : { apiKeyEnv: credentialRef(apiKeyEnv) },"
1213
+ },
1214
+ {
1215
+ "before": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/**\n* pi-ai-backed multi-provider adapter.",
1216
+ "after": "\t} catch (error) {\n\t\tthrow new LlmError(`pi-ai request header preparation failed for provider \"${options.provider}\": ${requestHeaderDiagnostic(error)}`, \"REQUEST_HEADERS\", { cause: error });\n\t}\n}\n/** Decode only the selected replay owner at the pi boundary; never merge equal wire ids across keys. */\nfunction replayContextForRoute(context, provider, requestedModel, wireModel) {\n\tconst selectedEntry = requestedModel.startsWith(KEY_MODEL_PREFIX);\n\treturn {\n\t\t...context,\n\t\tmessages: context.messages.map((message) => {\n\t\t\tif (message.role !== \"assistant\") return message;\n\t\t\tif (message.provider === provider && message.model === requestedModel) return { ...message, model: wireModel.id };\n\t\t\tif (!message.model.startsWith(KEY_MODEL_PREFIX) && !(selectedEntry && message.provider === provider && message.model === wireModel.id)) return message;\n\t\t\treturn {\n\t\t\t\trole: \"assistant\",\n\t\t\t\tapi: \"dsh-foreign\",\n\t\t\t\tprovider: message.provider,\n\t\t\t\tmodel: \"dsh-foreign\",\n\t\t\t\tcontent: message.content.flatMap((block) => {\n\t\t\t\t\tif (block.type === \"thinking\") return [];\n\t\t\t\t\tif (block.type === \"text\") return [{ type: \"text\", text: block.text }];\n\t\t\t\t\tif (block.type === \"toolCall\") return [{ type: \"toolCall\", id: block.id, name: block.name, arguments: block.arguments }];\n\t\t\t\t\treturn [block];\n\t\t\t\t}),\n\t\t\t\tusage: message.usage,\n\t\t\t\tstopReason: message.stopReason,\n\t\t\t\ttimestamp: message.timestamp\n\t\t\t};\n\t\t})\n\t};\n}\n/**\n* pi-ai-backed multi-provider adapter."
1217
+ },
1218
+ {
1219
+ "before": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tfor (const profile of profiles.values()) if (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n",
1220
+ "after": "\tcurrent() {\n\t\tconst profiles = this.config.profiles();\n\t\tif (this.snapshot?.profiles === profiles) return this.snapshot;\n\t\tconst models = createModels(this.config.auth);\n\t\tconst entryModels = new Map();\n\t\tfor (const [provider, profile] of profiles) {\n\t\t\tif (profile.piProvider !== void 0) models.setProvider(profile.piProvider);\n\t\t\tconst entries = new Map();\n\t\t\tfor (const [id, entry] of profile.keyEntries) {\n\t\t\t\tconst collection = createModels(this.config.auth);\n\t\t\t\tif (entry.piProvider !== void 0) collection.setProvider(entry.piProvider);\n\t\t\t\tentries.set(id, collection);\n\t\t\t}\n\t\t\tentryModels.set(provider, entries);\n\t\t}\n\t\tthis.snapshot = {\n\t\t\tprofiles,\n\t\t\tmodels,\n\t\t\tentryModels\n\t\t};\n\t\treturn this.snapshot;\n\t}\n\t/** The profile for one route within one snapshot, or the not-owned failure. */\n"
1221
+ },
1222
+ {
1223
+ "before": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst failure = profile.modelErrors.get(model) ?? (profile.piProvider === void 0 ? profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = snapshot.models.getModel(provider, model);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n",
1224
+ "after": "\t\tconst profile = snapshot.profiles.get(provider);\n\t\tif (profile === void 0) throw new LlmError(`pi-ai adapter does not own provider \"${provider}\"`, \"NO_ADAPTER\");\n\t\treturn profile;\n\t}\n\t/** Bind the public selection to an exact profile, independent model collection, and upstream id. */\n\trouteOf(snapshot, provider, model) {\n\t\tconst root = this.profileOf(snapshot, provider);\n\t\tconst entry = keyModelRoute(model);\n\t\tif (entry === void 0) return { profile: root, models: snapshot.models, wireModel: model };\n\t\tif (root.multiKey !== true) throw new LlmError(`multi-key selection is disabled for provider \"${provider}\"`, \"UNKNOWN_MODEL\");\n\t\tconst profile = root.keyEntries.get(entry.entryId);\n\t\tconst models = snapshot.entryModels.get(provider)?.get(entry.entryId);\n\t\tif (profile === void 0 || models === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${entry.entryId}\"`, \"UNKNOWN_MODEL\");\n\t\treturn { profile, models, wireModel: entry.wireModel };\n\t}\n\t/** The configured descriptor for one exact route/model pair within one snapshot. */\n\tmodelOf(snapshot, provider, model) {\n\t\tconst route = this.routeOf(snapshot, provider, model);\n\t\tconst failure = route.profile.modelErrors.get(route.wireModel) ?? (route.profile.piProvider === void 0 ? route.profile.catalogError : void 0);\n\t\tif (failure !== void 0) throw new LlmError(failure, \"INVALID_CONFIG\");\n\t\tconst resolved = route.models.getModel(provider, route.wireModel);\n\t\tif (resolved === void 0) throw new LlmError(`pi-ai provider \"${provider}\" has no configured model \"${model}\"`, \"UNKNOWN_MODEL\");\n\t\treturn resolved;\n\t}\n\tproviderInfo(provider) {\n"
1225
+ },
1226
+ {
1227
+ "before": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\ttry {\n\t\t\t\tawait this.config.resolveApiKey(provider, profile);\n\t\t\t} catch (error) {\n\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return [];\n\t\t\t\tthrow error;\n\t\t\t}\n\t\t\treturn snapshot.models.getModels(provider).map((model) => ({\n\t\t\t\tprovider,\n\t\t\t\tid: model.id,\n\t\t\t\tname: model.name,\n\t\t\t\tinputModalities: [...model.input]\n\t\t\t}));\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n",
1228
+ "after": "\tlistModels(provider) {\n\t\treturn Promise.resolve().then(async () => {\n\t\t\tconst snapshot = this.current();\n\t\t\tconst profile = this.profileOf(snapshot, provider);\n\t\t\tconst listed = [];\n\t\t\tconst append = async (owner, models, entryId) => {\n\t\t\t\ttry {\n\t\t\t\t\tconst key = await this.config.resolveApiKey(provider, owner);\n\t\t\t\t\tif (entryId !== void 0 && (key === void 0 || key.length === 0)) return;\n\t\t\t\t} catch (error) {\n\t\t\t\t\tif (error instanceof LlmError && error.code === \"MISSING_CREDENTIAL\") return;\n\t\t\t\t\tthrow error;\n\t\t\t\t}\n\t\t\t\tfor (const model of models.getModels(provider)) listed.push({\n\t\t\t\t\tprovider,\n\t\t\t\t\tid: entryId === void 0 ? model.id : keyModelId(entryId, model.id),\n\t\t\t\t\tname: model.name,\n\t\t\t\t\tinputModalities: [...model.input]\n\t\t\t\t});\n\t\t\t};\n\t\t\t// Keep raw root models advertised so old sessions remain routable without changing keys.\n\t\t\tawait append(profile, snapshot.models);\n\t\t\tif (profile.multiKey === true) for (const [id, entry] of profile.keyEntries) await append(entry, snapshot.entryModels.get(provider).get(id), id);\n\t\t\treturn listed;\n\t\t});\n\t}\n\tresolveModel(provider, model, _signal) {\n\t\treturn Promise.resolve().then(() => {\n"
1229
+ },
1230
+ {
1231
+ "before": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst profile = this.profileOf(snapshot, provider);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(model);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n",
1232
+ "after": "\t\t\treturn this.modelInfo(snapshot, provider, model);\n\t\t});\n\t}\n\tmodelInfo(snapshot, provider, model) {\n\t\tconst { profile, wireModel } = this.routeOf(snapshot, provider, model);\n\t\tconst resolvedModel = this.modelOf(snapshot, provider, model);\n\t\tconst defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning);\n\t\tconst configuredMaxTokens = profile.configuredMaxTokens.get(wireModel);\n\t\treturn {\n\t\t\tprovider,\n\t\t\tid: model,\n\t\t\tname: resolvedModel.name,\n"
1233
+ },
1234
+ {
1235
+ "before": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => this.streamWithSnapshot(options, snapshot)\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot(options, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n",
1236
+ "after": "\tprepareCall(provider, model, _signal) {\n\t\tconst snapshot = this.current();\n\t\treturn Promise.resolve({\n\t\t\tmodel: this.modelInfo(snapshot, provider, model),\n\t\t\tstream: (options) => {\n\t\t\t\tif (options.provider !== provider || options.model !== model) throw new LlmError(\"prepared multi-key model selection changed before adapter dispatch\", \"INVALID_CONFIG\");\n\t\t\t\t// Async generators are lazy; pin the owner before returning one to caller-owned code.\n\t\t\t\treturn this.streamWithSnapshot({ ...options, provider, model }, snapshot);\n\t\t\t}\n\t\t});\n\t}\n\tstream(options) {\n\t\treturn this.streamWithSnapshot({ ...options }, this.current());\n\t}\n\tasync *streamWithSnapshot(options, snapshot) {\n\t\tconst env_1 = {\n\t\t\tstack: [],\n"
1237
+ },
1238
+ {
1239
+ "before": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst profile = this.profileOf(snapshot, options.provider);\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n",
1240
+ "after": "\t\t\thasError: false\n\t\t};\n\t\ttry {\n\t\t\tif (options.stop !== void 0) throw new LlmError(\"llm-pi-ai does not support GenerateOptions.stop\", \"UNSUPPORTED_OPTION\");\n\t\t\tconst route = this.routeOf(snapshot, options.provider, options.model);\n\t\t\tconst profile = route.profile;\n\t\t\tconst model = this.modelOf(snapshot, options.provider, options.model);\n\t\t\tconst updates = conversationUpdates(model);\n\t\t\tconst tools = options.tools ?? [];\n\t\t\tconst request = model.api === \"anthropic-messages\" && updates.toolUpdate === \"in-history\" && tools.every((tool) => tool.deferLoading === true) && options.messages.some((message) => message.role === \"developer\" && message.content.some((block) => block.type === \"tool-addition\" || block.type === \"tool-removal\")) ? {\n"
1241
+ },
1242
+ {
1243
+ "before": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n",
1244
+ "after": "\t\t\t\ttools: [ANTHROPIC_TOOL_UPDATE_PLACEHOLDER, ...tools]\n\t\t\t} : options;\n\t\t\tconst reasoning = resolveReasoningLevel(model, options.reasoningEffort ?? profile.reasoning);\n\t\t\tconst apiKey = await this.config.resolveApiKey(options.provider, profile);\n\t\t\tif (profile.keyEntryId !== void 0 && (apiKey === void 0 || apiKey.length === 0)) throw new LlmError(`provider \"${options.provider}\" key entry \"${profile.keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\tconst consumer = new AbortController();\n\t\t\tconst upstream = options.signal === void 0 ? consumer.signal : AbortSignal.any([options.signal, consumer.signal]);\n\t\t\tconst streamIdleTimeoutMs = profile.streamIdleTimeoutMs;\n\t\t\tconst watchdog = __addDisposableResource(env_1, idleWatchdog(upstream, streamIdleTimeoutMs, \"LLM_STREAM_IDLE_TIMEOUT\"), false);\n"
1245
+ },
1246
+ {
1247
+ "before": "\t\t\t\tconst iterator = toStreamChunks(snapshot.models.streamSimple(model, context, {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, model.id)[Symbol.asyncIterator]();",
1248
+ "after": "\t\t\t\tconst iterator = toStreamChunks(route.models.streamSimple(model, replayContextForRoute(context, options.provider, options.model, model), {\n\t\t\t\t\t...profileOptions(profile, reasoning, apiKey),\n\t\t\t\t\t...options.temperature === void 0 ? {} : { temperature: options.temperature },\n\t\t\t\t\t...options.maxTokens === void 0 ? {} : { maxTokens: options.maxTokens },\n\t\t\t\t\t...options.sessionId === void 0 ? {} : { sessionId: String(options.sessionId) },\n\t\t\t\t\tsignal: watchdog.signal,\n\t\t\t\t\theaders: requestHeaders(profile.headers, options, model.baseUrl, this.config.prepareHeaders)\n\t\t\t\t}), model.contextWindow, options.signal, options.model)[Symbol.asyncIterator]();"
1249
+ },
1250
+ {
1251
+ "before": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n",
1252
+ "after": "* @throws LlmError when the protocol has no readable listing, the endpoint\n* refuses or fails the request, or the reply is not a model listing.\n*/\nasync function discoverModels(request, storedProfile) {\n\t// Validate host-owned entry identity even on the installed-catalog shortcut.\n\tconst selectedStored = request.keyEntryId === void 0 ? void 0 : storedProfile?.();\n\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {\n\t\tconst installed = catalogModels(request.provider);\n\t\tif (installed.size > 0) return [...installed.values()].map((model) => ({\n\t\t\tid: model.id,\n"
1253
+ },
1254
+ {
1255
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n",
1256
+ "after": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);\n\tconst stored = selectedStored ?? storedProfile?.();\n\tconst supplied = request.apiKey ?? await stored?.resolveApiKey();\n\tconst apiKey = supplied === void 0 ? void 0 : usableProbeKey(supplied);\n\tlet response;\n\ttry {\n"
1257
+ },
1258
+ {
1259
+ "before": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n",
1260
+ "after": "function registrationFacts(profiles) {\n\treturn [...profiles.entries()].map(([provider, profile]) => ({\n\t\tprovider,\n\t\tdisplayName: profile.displayName,\n\t\tretryPolicy: profile.retryPolicy,\n\t\tmultiKey: profile.multiKey === true,\n\t\tapiKeyEnv: profile.apiKeyEnv,\n\t\tmodels: profile.piProvider?.getModels(),\n\t\tmodelErrors: [...profile.modelErrors],\n\t\tkeyEntries: [...profile.keyEntries].map(([id, entry]) => ({\n\t\t\tid,\n\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),\n\t\t\tmodelErrors: [...entry.modelErrors]\n\t\t})).sort((left, right) => left.id.localeCompare(right.id))\n\t})).sort((left, right) => left.provider.localeCompare(right.provider));\n}\n/**\n* The configurable-provider directory: every installed catalog route, plus\n"
1261
+ },
1262
+ {
1263
+ "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
1264
+ "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
1265
+ },
1266
+ {
1267
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
1268
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
1269
+ },
1270
+ {
1271
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
1272
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
1273
+ },
1274
+ {
1275
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
1276
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
1277
+ },
1278
+ {
1279
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
1280
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
1281
+ },
1282
+ {
1283
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
1284
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
1285
+ },
1286
+ {
1287
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
1288
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
1289
+ },
1290
+ {
1291
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
1292
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
1293
+ },
1294
+ {
1295
+ "before": "function listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");",
1296
+ "after": "/** Strip trailing slashes and one trailing `/v1`, the segment the Anthropic SDK adds itself. */\nfunction anthropicRoot(baseURL) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");\n\treturn base.endsWith(\"/v1\") ? base.slice(0, -3) : base;\n}\nfunction listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");"
1297
+ },
1298
+ {
1299
+ "before": "\t\tconst baseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (baseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);",
1300
+ "after": "\t\tconst configuredBaseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (configuredBaseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);\n\t\tconst baseUrl = api === \"anthropic-messages\" ? anthropicRoot(configuredBaseUrl) : configuredBaseUrl;"
1301
+ },
1302
+ {
1303
+ "before": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${base.endsWith(\"/v1\") ? base.slice(0, -3) : base}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;",
1304
+ "after": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${anthropicRoot(base)}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;"
1305
+ }
1306
+ ]
1307
+ },
1308
+ {
1309
+ "source": "0.2.2-rc.1 with tool lookup optimization and credential cancellation with per-entry API overrides",
1310
+ "baseSha256": "0a99a2fc903a4285044b09114b3bd20ee1e612f39aa381e4a71b10d48ee9e9f7",
1311
+ "resultSha256": "c7d20ebe93753ae6f30d614121bac533fe5a8fa9372ea1c5fdc8bf2f7eba1d1d",
289
1312
  "replacements": [
290
1313
  {
291
1314
  "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
@@ -362,13 +1385,57 @@
362
1385
  {
363
1386
  "before": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider) => {\n\t\tif (provider === void 0) return void 0;\n\t\tconst profile = profiles().get(provider);\n\t\tif (profile === void 0) return void 0;\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: () => resolveApiKey(provider, profile)\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n",
364
1387
  "after": "\t\tdirectoryFacts = entries;\n\t};\n\tensureDirectory();\n\t/** Host-owned request inputs for discovery of one configured route. */\n\tconst storedDiscoveryProfile = (provider, keyEntryId) => {\n\t\tif (provider === void 0) {\n\t\t\tif (keyEntryId !== void 0) throw new LlmError(\"multi-key discovery needs a provider id\", \"INVALID_CONFIG\");\n\t\t\treturn void 0;\n\t\t}\n\t\tconst root = profiles().get(provider);\n\t\tif (keyEntryId === void 0) return root === void 0 ? void 0 : { headers: root.headers, resolveApiKey: () => resolveApiKey(provider, root) };\n\t\tif (!validKeyEntryId(keyEntryId) || root?.multiKey !== true) throw new LlmError(`multi-key discovery is not enabled for provider \"${provider}\"`, \"INVALID_CONFIG\");\n\t\tconst profile = root.keyEntries.get(keyEntryId);\n\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,\n\t\t\tresolveApiKey: async () => {\n\t\t\t\tconst key = await resolveApiKey(provider, profile);\n\t\t\t\tif (key === void 0 || key.length === 0) throw new LlmError(`provider \"${provider}\" key entry \"${keyEntryId}\" has no credential`, \"MISSING_CREDENTIAL\");\n\t\t\t\treturn key;\n\t\t\t}\n\t\t};\n\t};\n\tctx.llm.registerModelDiscovery(settingsNs, (request, signal) => discoverModels({\n\t\t...request,\n\t\t...signal === void 0 ? {} : { signal }\n\t}, () => storedDiscoveryProfile(request.provider, request.keyEntryId)));\n\tlet registration;\n\tlet registeredFacts;\n\tconst ensureRegistrationFacts = () => {\n\t\tconst facts = registrationFacts(profiles());\n"
1388
+ },
1389
+ {
1390
+ "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
1391
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
1392
+ },
1393
+ {
1394
+ "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
1395
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
1396
+ },
1397
+ {
1398
+ "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
1399
+ "after": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\t...entry.api === void 0 ? {} : { api: entry.api },\n\t\t\t\tmultiKey: false,"
1400
+ },
1401
+ {
1402
+ "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
1403
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
1404
+ },
1405
+ {
1406
+ "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
1407
+ "after": "\tconst baseURL = request.baseURL ?? selectedStored?.baseURL;\n\tif (baseURL === void 0 || baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(baseURL, api);"
1408
+ },
1409
+ {
1410
+ "before": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tmodels: entry.piProvider?.getModels(),",
1411
+ "after": "\t\t\tname: entry.keyEntryName,\n\t\t\tapiKeyEnv: entry.apiKeyEnv,\n\t\t\tapi: entry.api,\n\t\t\tmodels: entry.piProvider?.getModels(),"
1412
+ },
1413
+ {
1414
+ "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
1415
+ "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
1416
+ },
1417
+ {
1418
+ "before": "function listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");",
1419
+ "after": "/** Strip trailing slashes and one trailing `/v1`, the segment the Anthropic SDK adds itself. */\nfunction anthropicRoot(baseURL) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");\n\treturn base.endsWith(\"/v1\") ? base.slice(0, -3) : base;\n}\nfunction listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");"
1420
+ },
1421
+ {
1422
+ "before": "\t\tconst baseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (baseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);",
1423
+ "after": "\t\tconst configuredBaseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (configuredBaseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);\n\t\tconst baseUrl = api === \"anthropic-messages\" ? anthropicRoot(configuredBaseUrl) : configuredBaseUrl;"
1424
+ },
1425
+ {
1426
+ "before": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${base.endsWith(\"/v1\") ? base.slice(0, -3) : base}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;",
1427
+ "after": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${anthropicRoot(base)}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;"
1428
+ },
1429
+ {
1430
+ "before": "* gateway documentation publishes both spellings of the same root. Only this\n* listing URL normalizes that segment; model requests receive the configured\n* `baseURL` unchanged.\n*/",
1431
+ "after": "* gateway documentation publishes both spellings of the same root. Anthropic\n* listings and model requests both normalize it, because the Anthropic SDK\n* appends `/v1/messages` on its own while OpenAI protocols append\n* `/chat/completions`; without this, one root would work for chat and double\n* the segment for Anthropic.\n*/"
365
1432
  }
366
1433
  ]
367
1434
  },
368
1435
  {
369
1436
  "source": "npm official 0.2.2-rc.1 with per-entry API overrides",
370
1437
  "baseSha256": "1a3ae58f9b4493e15459cc5000ec80f21b5d3f4a9dea6ffb6bc28e5b8817ae8a",
371
- "resultSha256": "5ea8e84da726c04caa6bb321cf41617051ad9a80444834328007643b09b43a32",
1438
+ "resultSha256": "2e00ea0c1b447153e341a1ca675ed6a829094c7caf62c6524e6809bd6540be71",
372
1439
  "replacements": [
373
1440
  {
374
1441
  "before": "\t...modelFields\n});\n/** A {@link modelProfile} whose id lives in the `modelOverrides` dict key. */\nconst modelOverride = z.object(modelFields);\nconst profile = z.object({\n\tapiKeyEnv: z.string().role(\"credential-ref\"),\n\tdisplayName: z.string(),\n\tapi: z.union(supportedProtocols()),\n\tbaseURL: z.string(),\n",
@@ -460,7 +1527,7 @@
460
1527
  },
461
1528
  {
462
1529
  "before": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tif (request.provider !== void 0) {",
463
- "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api ?? selectedStored?.api ?? \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
1530
+ "after": "\tif (request.keyEntryId !== void 0 && selectedStored === void 0) throw new LlmError(\"multi-key model discovery requires an existing provider key entry\", \"INVALID_CONFIG\");\n\tconst api = request.api !== void 0 ? request.api : selectedStored?.api !== void 0 ? selectedStored.api : \"openai-completions\";\n\tif (!supportedProtocols().includes(api)) throw new LlmError(`pi-ai model discovery api must be a supported protocol`, \"INVALID_CONFIG\");\n\t// A selected entry must probe its effective protocol, not a catalog for another API.\n\tconst entryProtocol = request.keyEntryId !== void 0 && (request.api !== void 0 || selectedStored.api !== void 0);\n\tif (!entryProtocol && request.provider !== void 0) {"
464
1531
  },
465
1532
  {
466
1533
  "before": "\tif (request.baseURL === void 0 || request.baseURL.length === 0) throw new LlmError(`pi-ai ships no catalog for provider \"${request.provider ?? \"\"}\", so its models can only come from its endpoint; set a baseURL, or enter this provider's models by hand`, \"DISCOVERY_FAILED\");\n\tconst api = request.api ?? \"openai-completions\";\n\tif (!LISTABLE_PROTOCOLS.has(api)) throw new LlmError(`pi-ai protocol \"${api}\" has no model listing this build can read; enter this provider's models by hand`, \"DISCOVERY_UNSUPPORTED\");\n\tconst url = listingUrl(request.baseURL, api);",
@@ -473,19 +1540,35 @@
473
1540
  {
474
1541
  "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
475
1542
  "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
1543
+ },
1544
+ {
1545
+ "before": "function listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");",
1546
+ "after": "/** Strip trailing slashes and one trailing `/v1`, the segment the Anthropic SDK adds itself. */\nfunction anthropicRoot(baseURL) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");\n\treturn base.endsWith(\"/v1\") ? base.slice(0, -3) : base;\n}\nfunction listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");"
1547
+ },
1548
+ {
1549
+ "before": "\t\tconst baseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (baseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);",
1550
+ "after": "\t\tconst configuredBaseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (configuredBaseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);\n\t\tconst baseUrl = api === \"anthropic-messages\" ? anthropicRoot(configuredBaseUrl) : configuredBaseUrl;"
1551
+ },
1552
+ {
1553
+ "before": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${base.endsWith(\"/v1\") ? base.slice(0, -3) : base}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;",
1554
+ "after": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${anthropicRoot(base)}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;"
1555
+ },
1556
+ {
1557
+ "before": "* gateway documentation publishes both spellings of the same root. Only this\n* listing URL normalizes that segment; model requests receive the configured\n* `baseURL` unchanged.\n*/",
1558
+ "after": "* gateway documentation publishes both spellings of the same root. Anthropic\n* listings and model requests both normalize it, because the Anthropic SDK\n* appends `/v1/messages` on its own while OpenAI protocols append\n* `/chat/completions`; without this, one root would work for chat and double\n* the segment for Anthropic.\n*/"
476
1559
  }
477
1560
  ]
478
1561
  },
479
1562
  {
480
1563
  "source": "npm official 0.2.2-rc.1 with per-entry API overrides",
481
1564
  "baseSha256": "1a3ae58f9b4493e15459cc5000ec80f21b5d3f4a9dea6ffb6bc28e5b8817ae8a",
482
- "resultSha256": "9ca2b07c19694a4521a29c82b7948fb6326d80ee7741200a1d7b0f3f06e1da19",
1565
+ "resultSha256": "97baad73bbaa8e71c7a4b0a76cab946d0aee8d94a81bafc1cdbfa9100feec3b6",
483
1566
  "current": true
484
1567
  },
485
1568
  {
486
1569
  "source": "0.2.2-rc.1 with tool lookup optimization and credential cancellation with per-entry API overrides",
487
1570
  "baseSha256": "0a99a2fc903a4285044b09114b3bd20ee1e612f39aa381e4a71b10d48ee9e9f7",
488
- "resultSha256": "e999e1a7f2352177c653ff0cea6485c3b1d1ea95b40ea613fc0549e2c8e49662",
1571
+ "resultSha256": "70dd30c46c5504422738a158acf789bb6fe43cff9b134d5ddf5e5c3da3236340",
489
1572
  "current": true
490
1573
  }
491
1574
  ],
@@ -568,11 +1651,11 @@
568
1651
  },
569
1652
  {
570
1653
  "before": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tmodels: z.array(modelProfile).required()\n});",
571
- "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tmodels: z.array(modelProfile).required()\n});"
1654
+ "after": "\tapiKeyEnv: z.string().role(\"credential-ref\").required(),\n\tapi: z.union(supportedProtocols()),\n\tsortOrder: z.number().step(1).min(0).max(Number.MAX_SAFE_INTEGER),\n\tmodels: z.array(modelProfile).required()\n});"
572
1655
  },
573
1656
  {
574
1657
  "before": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (!Array.isArray(entry.models))",
575
- "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (!Array.isArray(entry.models))"
1658
+ "after": "\t\t\tcredentialRef(entry.apiKeyEnv);\n\t\t\tif (entry.api !== void 0 && !supportedProtocols().includes(entry.api)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" api must be a supported protocol`);\n\t\t\tif (entry.sortOrder !== void 0 && (!Number.isSafeInteger(entry.sortOrder) || entry.sortOrder < 0)) throw new Error(`llm-pi-ai: provider \"${provider}\" key entry \"${id}\" sortOrder must be a nonnegative safe integer`);\n\t\t\tif (!Array.isArray(entry.models))"
576
1659
  },
577
1660
  {
578
1661
  "before": "\t\t\tconst child = resolveProfiles({ [provider]: {\n\t\t\t\t...source,\n\t\t\t\tmultiKey: false,",
@@ -593,6 +1676,22 @@
593
1676
  {
594
1677
  "before": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\theaders: profile.headers,",
595
1678
  "after": "\t\tif (profile === void 0) throw new LlmError(`provider \"${provider}\" has no key entry \"${keyEntryId}\"`, \"INVALID_CONFIG\");\n\t\treturn {\n\t\t\tapi: profile.api,\n\t\t\tbaseURL: profile.baseURL ?? catalogProvider(provider)?.baseUrl,\n\t\t\theaders: profile.headers,"
1679
+ },
1680
+ {
1681
+ "before": "function listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");",
1682
+ "after": "/** Strip trailing slashes and one trailing `/v1`, the segment the Anthropic SDK adds itself. */\nfunction anthropicRoot(baseURL) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");\n\treturn base.endsWith(\"/v1\") ? base.slice(0, -3) : base;\n}\nfunction listingUrl(baseURL, api) {\n\tconst base = baseURL.replace(/\\/+$/, \"\");"
1683
+ },
1684
+ {
1685
+ "before": "\t\tconst baseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (baseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);",
1686
+ "after": "\t\tconst configuredBaseUrl = request.baseURL ?? base?.baseUrl ?? providerBaseUrl;\n\t\tif (configuredBaseUrl === void 0) invalid(provider, `model \"${entry.id}\" needs a baseURL; the installed catalog does not describe this route`);\n\t\tconst baseUrl = api === \"anthropic-messages\" ? anthropicRoot(configuredBaseUrl) : configuredBaseUrl;"
1687
+ },
1688
+ {
1689
+ "before": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${base.endsWith(\"/v1\") ? base.slice(0, -3) : base}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;",
1690
+ "after": "\tif (api !== \"anthropic-messages\") return `${base}/models`;\n\treturn `${anthropicRoot(base)}/v1/models?limit=${String(ANTHROPIC_MODEL_LIMIT)}`;"
1691
+ },
1692
+ {
1693
+ "before": "* gateway documentation publishes both spellings of the same root. Only this\n* listing URL normalizes that segment; model requests receive the configured\n* `baseURL` unchanged.\n*/",
1694
+ "after": "* gateway documentation publishes both spellings of the same root. Anthropic\n* listings and model requests both normalize it, because the Anthropic SDK\n* appends `/v1/messages` on its own while OpenAI protocols append\n* `/chat/completions`; without this, one root would work for chat and double\n* the segment for Anthropic.\n*/"
596
1695
  }
597
1696
  ],
598
1697
  "current": true,