Merge remote-tracking branch 'origin/master' into claude/unified-environment-credentials-c8841a
# Conflicts: # apps/web/tests/models-settings.e2e.ts # docs/config-catalog.md # packages/llm/llm-deepseek/README.i18n.yaml # packages/llm/llm-deepseek/README.md # packages/llm/llm-deepseek/README.zh.md # packages/llm/llm-deepseek/src/index.ts # packages/llm/llm-pi-ai/src/config.ts # packages/llm/llm-pi-ai/src/index.ts
This commit is contained in:
@@ -22,7 +22,7 @@
|
||||
* @module dsh-llm-pi-ai/discovery
|
||||
*/
|
||||
|
||||
import { LlmError } from '@deepseek-ai/dsh-llm'
|
||||
import { INVALID_CREDENTIAL_CODE, LlmError, normalizeApiKey } from '@deepseek-ai/dsh-llm'
|
||||
import type { LlmDiscoveredModel, LlmModelDiscoveryRequest } from '@deepseek-ai/dsh-llm'
|
||||
import { attributionHeaders } from '@deepseek-ai/dsh-llm'
|
||||
import { catalogModels } from './catalog.ts'
|
||||
@@ -161,6 +161,25 @@ function readListing(body: unknown): LlmDiscoveredModel[] {
|
||||
return models
|
||||
}
|
||||
|
||||
/**
|
||||
* Accept one probe key, or refuse it before the header is built. Without this
|
||||
* the `fetch` below would throw a ByteString `TypeError` that this function's
|
||||
* catch reports as `could not reach <url>` — blaming the network for a local,
|
||||
* deterministic fault.
|
||||
* @param raw - the key typed into the form or read from storage.
|
||||
* @returns the trimmed, usable key.
|
||||
*/
|
||||
function usableProbeKey(raw: string): string {
|
||||
const checked = normalizeApiKey(raw)
|
||||
if (checked.ok) return checked.value
|
||||
throw new LlmError(
|
||||
checked.reason === 'empty'
|
||||
? 'this provider\'s API key is blank; enter it on the Models page, or clear it to probe unauthenticated'
|
||||
: 'this provider\'s API key contains characters no HTTP header can carry; paste the raw key only',
|
||||
INVALID_CREDENTIAL_CODE,
|
||||
)
|
||||
}
|
||||
|
||||
/**
|
||||
* Interrogate one draft provider endpoint for the models it advertises.
|
||||
* @param request - the endpoint, protocol, and one-shot credential to use.
|
||||
@@ -216,7 +235,10 @@ export async function discoverModels(
|
||||
// stored one is only asked for here, past the catalog short-circuit and the
|
||||
// protocol check, so a route answered from the registry costs no credential
|
||||
// lookup — and no diagnostic about a credential it never needed.
|
||||
const apiKey = request.apiKey ?? await storedApiKey?.()
|
||||
// A probe carrying no key stays unauthenticated, which is how a route that
|
||||
// relies on the provider's own ambient discovery is meant to be asked.
|
||||
const supplied = request.apiKey ?? await storedApiKey?.()
|
||||
const apiKey = supplied === undefined ? undefined : usableProbeKey(supplied)
|
||||
let response: Response
|
||||
try {
|
||||
response = await fetch(url, {
|
||||
|
||||
@@ -44,7 +44,7 @@
|
||||
|
||||
import type { Context } from 'cordis'
|
||||
import { environmentOf } from '@deepseek-ai/dsh-environment'
|
||||
import { LlmError } from '@deepseek-ai/dsh-llm'
|
||||
import { assertUsableApiKey, LlmError } from '@deepseek-ai/dsh-llm'
|
||||
import type { AdapterRegistrationHandle, DirectoryRegistrationHandle, LlmConfigurableProvider } from '@deepseek-ai/dsh-llm'
|
||||
import { deepEqualJson, installSettingsSection, settingsNamespace } from '@deepseek-ai/dsh-settings'
|
||||
import { PiAiAdapter } from './adapter.ts'
|
||||
@@ -144,7 +144,7 @@ export function apply(ctx: Context, config: Config): void {
|
||||
? (await credentials.resolve(ref))?.value
|
||||
// Without the seam the environment is the whole credential plane.
|
||||
: environmentOf(ctx).getFrom(ref, ['process', 'project-env', 'user-env'])?.value
|
||||
if (hit !== undefined && hit.length > 0) return hit
|
||||
if (hit !== undefined && hit.length > 0) return assertUsableApiKey(hit, 'llm-pi-ai', ref)
|
||||
throw new LlmError(
|
||||
`llm-pi-ai: no credential for provider route "${provider}"; its profile resolves ${ref}, which is not`
|
||||
+ ` set — store ${ref} through the credentials service (the web Models page writes it) or export it,`
|
||||
|
||||
Reference in New Issue
Block a user