feat(embeddings): add OpenRouter support (#6396)

* feat(knowledge): add OpenRouter embedding fallback

* fix(knowledge): preserve successful embedding batches

* feat(embeddings): add OpenRouter provider

* fix(knowledge): bill only platform embedding tokens

* test(embeddings): include OpenRouter provider

* feat(embeddings): load OpenRouter model catalog

* fix(embeddings): preserve legacy provider default

* fix(embeddings): batch OpenRouter requests

* fix(embeddings): reset stale OpenRouter model
This commit is contained in:
Theodore Li
2026-08-10 15:15:18 -04:00
committed by GitHub
parent bc8826af56
commit 56910c002e
42 changed files with 1999 additions and 247 deletions
+33
View File
@@ -15,6 +15,7 @@ import {
inspectCapability,
inspectOAuthClientCapability,
isTruthyEnvCapabilityValue,
KNOWLEDGE_EMBEDDINGS_CAPABILITY,
LLM_KEY_POOLS,
OAUTH_CLIENT_CAPABILITIES,
type OAuthClientCapabilityId,
@@ -43,6 +44,8 @@ interface FeatureStatusBase<TId extends SetupStatusFeatureId> {
}
type EmailProviderId = (typeof EMAIL_CAPABILITY.providers)[number]['id']
type KnowledgeEmbeddingsProviderId =
(typeof KNOWLEDGE_EMBEDDINGS_CAPABILITY.providers)[number]['id']
type StorageProviderId =
| (typeof STORAGE_CAPABILITY)['defaultProvider']['id']
| (typeof STORAGE_CAPABILITY.providers)[number]['id']
@@ -77,6 +80,13 @@ export interface KnowledgeCapabilityStatus extends FeatureStatusBase<'knowledge'
providerId: 'local' | 'mistral' | 'azure-mistral' | null
}
export interface KnowledgeEmbeddingsCapabilityStatus
extends FeatureStatusBase<'knowledge-embeddings'> {
strategy: 'fallback'
providerIds: readonly KnowledgeEmbeddingsProviderId[]
providers: readonly ProviderInspection<KnowledgeEmbeddingsProviderId>[]
}
export interface LlmKeyPoolStatus {
id: LlmKeyPoolId
state: 'configured' | 'missing'
@@ -99,6 +109,7 @@ interface FeatureStatusById {
jobs: JobsCapabilityStatus
cache: CacheCapabilityStatus
knowledge: KnowledgeCapabilityStatus
'knowledge-embeddings': KnowledgeEmbeddingsCapabilityStatus
llm: LlmCapabilityStatus
}
@@ -391,6 +402,26 @@ function inspectKnowledge(values: EnvCapabilityValues): KnowledgeCapabilityStatu
}
}
function inspectKnowledgeEmbeddings(
values: EnvCapabilityValues
): KnowledgeEmbeddingsCapabilityStatus {
const inspection = inspectCapability(KNOWLEDGE_EMBEDDINGS_CAPABILITY, values)
const brokenState = brokenProviderState(inspection.providers)
const state = inspection.configured ? 'configured' : (brokenState ?? 'missing')
const configurationError =
inspection.error ??
getCapabilityConfigurationError(KNOWLEDGE_EMBEDDINGS_CAPABILITY, inspection.providers)
return {
...featureMetadata('knowledge-embeddings'),
strategy: 'fallback',
state,
providerIds: inspection.providerIds,
providers: inspection.providers,
...(configurationError ? { issue: issue(brokenState ?? 'invalid', configurationError) } : {}),
}
}
function inspectLlm(values: EnvCapabilityValues): LlmCapabilityStatus {
const pools = {} as Record<LlmKeyPoolId, LlmKeyPoolStatus>
let configuredPoolCount = 0
@@ -463,6 +494,7 @@ const FEATURE_STATUS_BUILDERS = {
jobs: inspectJobs,
cache: inspectCache,
knowledge: inspectKnowledge,
'knowledge-embeddings': inspectKnowledgeEmbeddings,
llm: inspectLlm,
} satisfies Record<SetupStatusFeatureId, (values: EnvCapabilityValues) => unknown>
@@ -476,6 +508,7 @@ export function buildEnvCapabilityStatus(values: EnvCapabilityValues): EnvCapabi
jobs: FEATURE_STATUS_BUILDERS.jobs(values),
cache: FEATURE_STATUS_BUILDERS.cache(values),
knowledge: FEATURE_STATUS_BUILDERS.knowledge(values),
'knowledge-embeddings': FEATURE_STATUS_BUILDERS['knowledge-embeddings'](values),
llm: FEATURE_STATUS_BUILDERS.llm(values),
},
oauthClients: inspectOAuthClients(values),