Обзор модуля LLM Providers
Этот документ описывает общую архитектуру подсистемы LLM provider в Elftia. Подсистема отвечает за управление конфигурациями нескольких provider, пулами API-ключей, обнаружением моделей, маршрутизацией запросов и конвейером вызовов Completion.
Расположение файлов
| Модуль | Путь |
|---|---|
| CompletionService | packages/desktop/app/main/services/capabilities/llm/completion/CompletionService.ts |
| ApiKeyPoolService | packages/desktop/app/main/services/capabilities/llm/completion/ApiKeyPoolService.ts |
| LLMConfigService | packages/desktop/app/main/services/capabilities/llm/config-service/LLMConfigService.ts |
| ProviderManager | packages/desktop/app/main/services/capabilities/llm/config-service/ProviderManager.ts |
| ModelDiscoveryManager | packages/desktop/app/main/services/capabilities/llm/config-service/ModelDiscoveryManager.ts |
| ConfigIOManager | packages/desktop/app/main/services/capabilities/llm/config-service/ConfigIOManager.ts |
| AgentModelsManager | packages/desktop/app/main/services/capabilities/llm/config-service/AgentModelsManager.ts |
| ThinkingResolver | packages/desktop/app/main/services/capabilities/llm/completion/ThinkingResolver.ts |
| StreamHandler | packages/desktop/app/main/services/capabilities/llm/completion/StreamHandler.ts |
| DirectApiHandler | packages/desktop/app/main/services/capabilities/llm/completion/DirectApiHandler.ts |
| ToolHandler | packages/desktop/app/main/services/capabilities/llm/completion/ToolHandler.ts |
| TransformerHandler | packages/desktop/app/main/services/capabilities/llm/completion/TransformerHandler.ts |
| ProviderSearchInjector | packages/desktop/app/main/services/capabilities/llm/completion/ProviderSearchInjector.ts |
| NativeSearchInjector | packages/desktop/app/main/services/capabilities/llm/completion/NativeSearchInjector.ts |
| URL Builder | packages/desktop/app/main/services/capabilities/llm/completion/url-builder.ts |
| Header Builder | packages/desktop/app/main/services/capabilities/llm/completion/header-builder.ts |
| Message Converter | packages/desktop/app/main/services/capabilities/llm/completion/message-converter.ts |
| Provider Presets | packages/desktop/app/shared/provider-presets.ts |
| IPC Routers | packages/desktop/app/main/services/routers/llm/ |
Архитектурный контекст
graph TB
subgraph Frontend ["Frontend (Renderer)"]
UI[Provider Settings UI]
ChatUI[Chat Interface]
end
subgraph IPCLayer ["IPC Layer"]
PR[ProviderRouter]
AKR[ApiKeyRouter]
CR[CompletionRouter]
RCR[RouterConfigRouter]
TR[TransformerRouter]
MPR[ModelParametersRouter]
end
subgraph LLMConfigService ["LLMConfigService (Delegate Pattern)"]
PM[ProviderManager]
MDM[ModelDiscoveryManager]
CIOM[ConfigIOManager]
AMM[AgentModelsManager]
end
subgraph CompletionService ["CompletionService (Facade Pattern)"]
DAH[DirectApiHandler]
SH[StreamHandler]
TH[ToolHandler]
THR[TransformerHandler]
TR2[ThinkingResolver]
end
AKPS[ApiKeyPoolService]
subgraph ExternalAPIs ["External APIs"]
OpenAI[OpenAI API]
Anthropic[Anthropic API]
Gemini[Gemini API]
Azure[Azure OpenAI API]
Others[Other Providers...]
end
subgraph Storage ["Storage"]
SQLite[(SQLite)]
JSON[(llms-config.json)]
end
UI --> PR
UI --> AKR
ChatUI --> CR
PR --> PM
AKR --> AKPS
CR --> CompletionService
PM --> SQLite
PM --> JSON
MDM --> SQLite
MDM --> JSON
CompletionService --> AKPS
CompletionService --> LLMConfigService
DAH --> OpenAI
DAH --> Anthropic
DAH --> Gemini
DAH --> Azure
SH --> OpenAI
SH --> Anthropic
SH --> Gemini
SH --> Azure
Структуры данных
Основные типы
// API format enum
type ApiFormat = 'openai' | 'anthropic' | 'google' | 'azure-openai' | 'openai-response';
// LLM provider
interface LLMProvider {
id: string; // Unique identifier
name: string; // Display name
apiFormat?: ApiFormat; // API format (preferred field)
chatApiFormat?: ApiFormat; // Legacy API format field
apiType?: string; // Legacy type field
api_base_url?: string; // API base URL
api_key: string; // Single key (legacy)
models: string[]; // Model ID list
modelConfigs?: ModelConfig[]; // Per-model detailed config
modelGroups?: ModelGroup[]; // Model groups
modelsEndpoint?: string; // Model discovery endpoint
enabled: boolean; // Whether enabled
transformer?: TransformerConfig; // Transformer chain config
icon?: string; // Icon
website?: string; // Official website
docsUrl?: string; // Documentation link
defaultSettings?: CompletionSettings; // Default completion parameters
codingPlan?: CodingPlanConfig; // Coding Plan config
isSystem?: boolean; // System built-in provider
presetId?: string; // Preset template ID
createdAt: string;
updatedAt: string;
}
// Completion request options
interface CompletionOptions {
providerId: string; // Provider ID
model: string; // Model ID
messages: SimpleChatMessage[]; // Message list
maxTokens?: number; // Max token count
temperature?: number; // Temperature
stream?: boolean; // Whether streaming
thinkLevel?: ThinkLevel; // Thinking level
nativeSearchAugmentation?: NativeSearchAugmentation; // Native search augmentation
sessionId?: string; // Session ID (for API Key Pool affinity)
}
// API key pool entry
interface ApiKeyEntry {
id: string; // Unique ID
providerId: string; // Owning provider
label?: string; // Display label
apiKey: string; // Key value
enabled: boolean; // Whether enabled
weight: number; // Weight (1-100)
}
Обзор потока данных
Конвейер запроса Completion
sequenceDiagram
participant Frontend as Frontend
participant CS as CompletionService
participant LLC as LLMConfigService
participant AKP as ApiKeyPoolService
participant Handler as API Handler
participant API as Provider API
Frontend->>CS: complete() / completeStream()
CS->>LLC: resolveRoutedModel(providerId, model)
LLC-->>CS: actualProviderId + actualModel
CS->>LLC: getProvider(actualProviderId)
LLC-->>CS: provider config
CS->>CS: resolveApiKeyForRequest()
Note right of CS: Priority: codingPlan > pool > legacy
CS->>AKP: getKeyForSession(providerId, sessionId)
AKP-->>CS: resolved API key
CS->>CS: resolveApiFormat(provider)
CS->>Handler: callDirectHandler / callStreamHandler
Handler->>API: HTTP request
API-->>Handler: response / SSE stream
Handler-->>CS: CompletionResult
alt 429/529 error
CS->>AKP: reportError(providerId, sessionId, status)
AKP-->>CS: new key
CS->>Handler: retry with new key
end
CS->>AKP: reportSuccess(sessionId)
CS-->>Frontend: result
Границы модулей и зоны ответственности
| Модуль | Зоны ответственности | Не отвечает за |
|---|---|---|
| CompletionService | Оркестрация конвейера запросов, диспетчеризация форматов, повторные попытки, fallback для vision | Provider CRUD, хранение ключей |
| ApiKeyPoolService | Балансировка нагрузки между несколькими ключами, привязка к сессии, cooldown backoff | Сохранение ключей (делегировано DB) |
| LLMConfigService | Управление конфигурацией provider, обнаружение моделей, маршрутизация, цепочка Transformer | API-вызовы |
| ProviderManager | Provider CRUD, система шаблонов/пресетов, сохранение в SQLite | Обнаружение моделей, конфигурация маршрутизации |
| ModelDiscoveryManager | Обнаружение списка моделей, кэширование (SQLite + файл) | Provider CRUD |
| ConfigIOManager | Импорт/экспорт конфигурации, ввод-вывод JSON-файлов | Операции с базой данных |
| AgentModelsManager | Конфигурация маршрутизации, управление Transformer, глобальные параметры | Provider CRUD |
| ThinkingResolver | Разрешение max_tokens, расчет thinking budget | Отправка запросов |
| StreamHandler | Обработка SSE-потоков (OpenAI/Anthropic/Gemini) | Непотоковые запросы |
| DirectApiHandler | Непотоковые API-вызовы | Потоковые запросы |
| ToolHandler | Цикл вызовов инструментов Agent | Обычный Completion |
| TransformerHandler | Completion через цепочку Transformer | Прямые API-вызовы |
Таблица интеграции IPC
| IPC-канал | Направление | Router | Описание |
|---|---|---|---|
llmConfig:getProviders | Renderer -> Main | ProviderRouter | Получить всех provider |
llmConfig:getProvider | Renderer -> Main | ProviderRouter | Получить одного provider |
llmConfig:addProvider | Renderer -> Main | ProviderRouter | Добавить provider |
llmConfig:updateProvider | Renderer -> Main | ProviderRouter | Обновить provider |
llmConfig:deleteProvider | Renderer -> Main | ProviderRouter | Удалить provider |
llmConfig:toggleProvider | Renderer -> Main | ProviderRouter | Включить/отключить provider |
llmConfig:discoverModels | Renderer -> Main | ProviderRouter | Обнаружить список моделей |
llmConfig:getProviderPresets | Renderer -> Main | ProviderRouter | Получить шаблоны пресетов |
llmConfig:addFromPreset | Renderer -> Main | ProviderRouter | Добавить provider из пресета |
llmConfig:exportConfig | Renderer -> Main | ProviderRouter | Экспортировать конфигурацию |
llmConfig:importConfig | Renderer -> Main | ProviderRouter | Импортировать конфигурацию |
llmConfig:getApiKeys | Renderer -> Main | ApiKeyRouter | Получить список ключей |
llmConfig:addApiKey | Renderer -> Main | ApiKeyRouter | Добавить ключ |
llmConfig:updateApiKey | Renderer -> Main | ApiKeyRouter | Обновить ключ |
llmConfig:deleteApiKey | Renderer -> Main | ApiKeyRouter | Удалить ключ |
llmConfig:toggleApiKey | Renderer -> Main | ApiKeyRouter | Включить/отключить ключ |
Точки расширения
- Добавление нового API-формата: добавьте функцию построения URL в
url-builder.ts, добавьте функции-обработчики вDirectApiHandler.ts/StreamHandler.tsи зарегистрируйте их в switch вCompletionService - Добавление нового пресета provider: добавьте шаблон в массив
PROVIDER_PRESETSвprovider-presets.ts - Добавление новой поисковой конфигурации: добавьте запись в
PROVIDER_SEARCH_CONFIGSвprovider-presets.ts - Пользовательский Transformer: зарегистрируйте новую цепочку Transformer через
AgentModelsManager
Связанные файлы
| Файл | Назначение |
|---|---|
packages/desktop/app/shared/llm-config.ts | Общие определения типов конфигурации LLM |
packages/desktop/app/shared/completion-types.ts | Определения типов Completion |
packages/desktop/app/shared/thinking-config.ts | Конфигурация thinking и расчет budget |
packages/desktop/app/shared/provider-presets.ts | Шаблоны пресетов provider и поисковые конфигурации |
packages/desktop/app/main/services/routers/llm/schemas.ts | Zod schemas для валидации IPC-запросов |
packages/desktop/app/main/services/capabilities/llm/config-service/schemas.ts | Внутренние Zod schemas сервиса конфигурации |
packages/desktop/app/main/services/infra/utils/sse-parser.ts | Утилиты разбора SSE-потоков |
packages/desktop/app/main/workers/db/apiKeys.ts | Операции базы данных для API-ключей |
packages/desktop/app/main/workers/DbClient.ts | Клиент базы данных |
packages/desktop/app/preload/index.ts | Экспорт Preload API |