Merge origin/master at f1402327fa

This commit is contained in:
Tianyi Cui
2026-08-07 23:57:23 +08:00
447 changed files with 20295 additions and 1680 deletions

View File

@@ -94,6 +94,29 @@ function profileOptions(
}
}
/**
* The profile default this exact model can actually take, for DESCRIBING it.
* A configured level the model does not support yields none rather than
* throwing: `resolveModel` builds the model catalog, and a catalog that fails
* takes its whole provider out of every picker — so one mis-set profile field
* would hide every model on the route, including the ones that support the
* level. The request path still refuses, which is where a bad configuration
* belongs: describing what a model can do must not fail because a deployment
* asked it for something it cannot.
* @param model - the resolved model descriptor.
* @param effort - the profile's configured level, if any.
* @returns the level when this model supports it, otherwise undefined.
*/
function describableReasoningLevel(
model: Model<Api>,
effort: ReasoningEffortIdType | ModelThinkingLevel | undefined,
): ModelThinkingLevel | undefined {
if (effort === undefined) return undefined
return getSupportedThinkingLevels(model).some(level => level === effort)
? effort as ModelThinkingLevel
: undefined
}
/** Validate an explicit Harness/profile effort without invoking pi-ai's clamp. */
function resolveReasoningLevel(
model: Model<Api>,
@@ -229,7 +252,7 @@ export class PiAiAdapter extends LlmAdapter {
const snapshot = this.current()
const profile = this.profileOf(snapshot, provider)
const resolvedModel = this.modelOf(snapshot, provider, model)
const defaultLevel = resolveReasoningLevel(resolvedModel, profile.reasoning)
const defaultLevel = describableReasoningLevel(resolvedModel, profile.reasoning)
// Only a cap the deployment configured is a request default; the
// catalog's `maxTokens` sizes the model and stops there.
const configuredMaxTokens = profile.configuredMaxTokens.get(model)

View File

@@ -93,11 +93,21 @@ function registrationFacts(profiles: ReadonlyMap<string, ResolvedPiAiProviderPro
function directoryEntries(
profiles: ReadonlyMap<string, ResolvedPiAiProviderProfile>,
): LlmConfigurableProvider[] {
const catalog = new Set(catalogProviderIds())
const entries = new Map<string, LlmConfigurableProvider>()
const declare = (provider: string, displayName: string): void => {
entries.set(provider, { provider, displayName, settingsNs: NS, settingsPath: ['providers', provider] })
entries.set(provider, {
provider,
displayName,
settingsNs: NS,
settingsPath: ['providers', provider],
// Membership of the installed catalog, not of the settings document:
// narrowing a shipped provider's models stores a profile too, and that
// route is still one pi-ai knows.
declared: !catalog.has(provider),
})
}
for (const provider of catalogProviderIds()) declare(provider, provider)
for (const provider of catalog) declare(provider, provider)
for (const [provider, profile] of profiles) declare(provider, profile.displayName)
return [...entries.values()]
}