This page documents the LLM Service and Provider Adapter architecture in the @prompt-optimizer/core package. It covers the adapter pattern implementation that abstracts interactions with different LLM providers (OpenAI, Gemini, Anthropic, DeepSeek, etc.), the registry system that manages adapters, and the LLMService class that orchestrates all text generation requests.
For information about model configuration management, see Model Configuration Management. For prompt optimization workflows that use the LLM service, see Prompt Optimization Service.
Sources: packages/core/src/services/llm/service.ts1-418 packages/core/src/services/llm/types.ts1-200 packages/core/src/services/llm/adapters/registry.ts1-250
The LLM service follows a three-tier architecture that separates business logic from provider-specific implementations using the adapter pattern.
Sources: packages/core/src/services/llm/service.ts19-30 packages/core/src/services/llm/adapters/registry.ts15-45
The adapter pattern abstracts provider-specific API implementations behind a uniform interface (ITextProviderAdapter), enabling the system to support any OpenAI-compatible or custom API without modifying core business logic.
Key Benefits:
Sources: packages/core/src/services/llm/types.ts85-167 packages/core/src/services/model/types.ts14-33
| Method | Purpose | Return Type |
|---|---|---|
getProvider() | Returns provider metadata (ID, name, baseURL, CORS restrictions, etc.) | TextProvider |
getModels() | Returns static model list known at compile time | TextModel[] |
buildDefaultModel() | Creates fallback model metadata when dynamic fetch fails | TextModel |
sendMessage() | Non-streaming text generation | Promise<LLMResponse> |
sendMessageStream() | Streaming text generation with callbacks | Promise<void> |
sendMessageStreamWithTools() | Streaming with tool/function calling support | Promise<void> |
fetchModels() | Dynamically fetches available models from provider API | Promise<TextModel[]> |
Sources: packages/core/src/services/llm/types.ts85-167
The TextAdapterRegistry class manages adapter instances using the singleton pattern per provider. It provides lazy initialization, caching, and graceful fallback mechanisms.
Sources: packages/core/src/services/llm/adapters/registry.ts15-150
Key Behaviors:
ModelConfigError for unknown providersSources: packages/core/src/services/llm/types.ts169-176 packages/core/src/services/llm/adapters/registry.ts22-95
| Provider ID | Adapter Class | API Base URL | Dynamic Models | CORS Restricted |
|---|---|---|---|---|
openai | OpenAIAdapter | https://api.openai.com/v1 | Yes | No |
gemini | GeminiAdapter | https://generativelanguage.googleapis.com/v1beta | Yes | No |
anthropic | AnthropicAdapter | https://api.anthropic.com/v1 | No | No |
deepseek | DeepSeekAdapter | https://api.deepseek.com/v1 | No | No |
siliconflow | SiliconFlowAdapter | https://api.siliconflow.cn/v1 | Yes | Yes |
zhipu | ZhipuAdapter | https://open.bigmodel.cn/api/paas/v4 | No | Yes |
dashscope | DashScopeAdapter | https://dashscope.aliyuncs.com/compatible-mode/v1 | No | Yes |
openrouter | OpenRouterAdapter | https://openrouter.ai/api/v1 | Yes | No |
modelscope | ModelScopeAdapter | https://api-inference.modelscope.cn/v1 | Yes | Yes |
custom | Uses OpenAIAdapter | User-configured | No | Varies |
Sources: packages/core/src/services/llm/adapters/registry.ts47-90 packages/core/src/services/model/defaults.ts10-29
The LLMService class orchestrates all LLM interactions by:
Sources: packages/core/src/services/llm/service.ts122-153 packages/core/src/services/llm/service.ts281-299
Returns structured response with content, reasoningContent (for o1-style models), and metadata.
Streams tokens via callbacks: onToken, onComplete, onError. Supports reasoning content streaming for models with chain-of-thought capabilities.
Enables function calling for models that support tools (OpenAI, Gemini).
Validates API configuration by sending a simple test message. Allows disabled models to be tested (option { allowDisabled: true }).
Retrieves available models for a provider, merging static and dynamic models. Returns options in format { value: modelId, label: modelName } for UI dropdowns.
Sources: packages/core/src/services/llm/service.ts80-279
The system supports three levels of parameter configuration:
TextModel.defaultParameterValuesTextModelConfig.paramOverridesSources: packages/core/src/services/llm/service.ts281-299 packages/core/src/services/model/parameter-utils.ts1-200
Key Points:
customParamOverrides is deprecated but still read for backward compatibilityparamOverrides is the unified field that contains all parameter overridesmergeOverrides() utility handles schema validation and type checkingSources: packages/core/src/services/llm/service.ts281-299 packages/core/src/services/model/parameter-utils.ts50-120
The OpenAIAdapter serves as the base implementation for most providers due to widespread OpenAI API compatibility.
Key Features:
openai npm package SDK/v1/models endpointStatic Models (as of implementation):
gpt-4o, gpt-4o-mini (128K context, tools, reasoning)o1-preview, o1-mini (reasoning models, 128K context)Sources: packages/core/src/services/llm/adapters/openai-adapter.ts1-300
Uses Google's @google/generative-ai SDK.
Key Features:
tools parameterStatic Models:
gemini-2.0-flash-exp (1M context, tools)gemini-1.5-pro, gemini-1.5-flash (2M/1M context, multimodal)Sources: packages/core/src/services/llm/adapters/gemini-adapter.ts1-400
Uses @anthropic-ai/sdk for Claude models.
Key Features:
stream: truesystem parameterStatic Models:
claude-3-7-sonnet (200K context, tools)claude-3-5-haiku, claude-3-opus (200K context)Sources: packages/core/src/services/llm/adapters/anthropic-adapter.ts1-350
Extends OpenAIAdapter for ModelScope API (阿里云魔搭社区).
Key Features:
https://api-inference.modelscope.cn/v1Static Models:
Qwen/Qwen3-Coder-480B-A35B-Instruct (131K context)Sources: packages/core/src/services/llm/adapters/modelscope-adapter.ts1-85 README.md33-36
The system supports unlimited custom providers via two mechanisms:
VITE_CUSTOM_API_KEY, VITE_CUSTOM_API_BASE_URL, VITE_CUSTOM_API_MODELVITE_CUSTOM_API_*_<suffix> (e.g., VITE_CUSTOM_API_KEY_ollama, VITE_CUSTOM_API_BASE_URL_ollama, VITE_CUSTOM_API_MODEL_ollama)Custom providers reuse OpenAIAdapter since most local/custom APIs follow OpenAI compatibility.
Sources: packages/core/src/services/model/defaults.ts70-94 packages/core/src/utils/environment.ts256-394 env.local.example42-66
Sources: packages/core/src/services/llm/service.ts33-76
| Error Class | Code Prefix | Usage |
|---|---|---|
RequestConfigError | LLM-* | Invalid configuration: missing API key, disabled model, malformed messages |
APIError | LLM-* | External API failures: network errors, rate limits, invalid responses |
ModelConfigError | MODEL-* | Model configuration issues: unknown provider, validation failures |
Error Code Examples:
LLM-001: Model provider cannot be emptyLLM-002: Messages array cannot be emptyLLM-003: Model is not enabledLLM-004: Connection test failedSources: packages/core/src/services/llm/errors.ts1-100 packages/core/src/constants/error-codes.ts20-40
Sources: packages/core/src/services/llm/service.ts80-279 packages/core/tests/unit/llm/service.test.ts1-400
In Electron desktop applications, the LLMService is replaced by ElectronLLMProxy to bypass renderer process restrictions and CORS limitations.
Key Points:
LLMService due to lack of Node.js APIscreateLLMService() factory detects Electron environment and returns proxySources: packages/core/src/services/llm/service.ts386-398 packages/core/src/services/llm/electron-proxy.ts1-150 packages/core/src/utils/environment.ts132-167
The codebase uses a VCR (Video Cassette Recorder) pattern to record and replay real API interactions for integration tests without consuming API credits.
Sources: packages/core/tests/unit/llm/service.test.ts1-500 packages/core/tests/unit/llm/modelscope-adapter.test.ts1-202
| Class/Interface | File Path | Primary Responsibility |
|---|---|---|
ILLMService | packages/core/src/services/llm/types.ts42-84 | Service interface defining all LLM operations |
LLMService | packages/core/src/services/llm/service.ts22-379 | Main service implementation orchestrating requests |
ITextProviderAdapter | packages/core/src/services/llm/types.ts85-167 | Adapter interface for provider-specific implementations |
TextAdapterRegistry | packages/core/src/services/llm/adapters/registry.ts15-150 | Singleton registry managing adapter instances |
OpenAIAdapter | packages/core/src/services/llm/adapters/openai-adapter.ts1-300 | OpenAI and compatible APIs adapter |
GeminiAdapter | packages/core/src/services/llm/adapters/gemini-adapter.ts1-400 | Google Gemini native SDK adapter |
AnthropicAdapter | packages/core/src/services/llm/adapters/anthropic-adapter.ts1-350 | Anthropic Claude native SDK adapter |
ModelScopeAdapter | packages/core/src/services/llm/adapters/modelscope-adapter.ts1-85 | ModelScope API adapter (OpenAI-compatible) |
ElectronLLMProxy | packages/core/src/services/llm/electron-proxy.ts1-150 | IPC proxy for Electron renderer process |
Sources: packages/core/src/index.ts38-57
Refresh this wiki