diff --git a/README.md b/README.md index d15db3ee..03be9477 100644 --- a/README.md +++ b/README.md @@ -957,6 +957,7 @@ IMAP_PASSWORD=your-password-here | `zhipu` | LLM (Zhipu GLM) | [open.bigmodel.cn](https://open.bigmodel.cn) | | `mimo` | LLM (MiMo) | [platform.xiaomimimo.com](https://platform.xiaomimimo.com) | | `ollama` | LLM (local, Ollama) | — | +| `lm_studio` | LLM (local, LM Studio) | — | | `mistral` | LLM | [docs.mistral.ai](https://docs.mistral.ai/) | | `stepfun` | LLM (Step Fun/阶跃星辰) | [platform.stepfun.com](https://platform.stepfun.com) | | `ovms` | LLM (local, OpenVINO Model Server) | [docs.openvino.ai](https://docs.openvino.ai/2026/model-server/ovms_docs_llm_quickstart.html) | @@ -1044,7 +1045,7 @@ nanobot agent -c ~/.nanobot-telegram/config.json -w /tmp/nanobot-telegram-test -
Custom Provider (Any OpenAI-compatible API) -Connects directly to any OpenAI-compatible endpoint — LM Studio, llama.cpp, Together AI, Fireworks, Azure OpenAI, or any self-hosted server. Model name is passed as-is. +Connects directly to any OpenAI-compatible endpoint — llama.cpp, Together AI, Fireworks, Azure OpenAI, or any self-hosted server. Model name is passed as-is. ```json { @@ -1062,7 +1063,7 @@ Connects directly to any OpenAI-compatible endpoint — LM Studio, llama.cpp, To } ``` -> For local servers that don't require a key, set `apiKey` to any non-empty string (e.g. `"no-key"`). +> For local servers that don't require authentication, set `apiKey` to `null`. > > `custom` is the right choice for providers that expose an OpenAI-compatible **chat completions** API. It does **not** force third-party endpoints onto the OpenAI/Azure **Responses API**. > @@ -1121,6 +1122,40 @@ ollama run llama3.2
+
+LM Studio (local) + +[LM Studio](https://lmstudio.ai/) provides a local OpenAI-compatible server for running LLMs. Download models through the LM Studio UI, then start the local server. + +**1. Start LM Studio server:** +- Launch LM Studio +- Go to the "Local Server" tab +- Load a model (e.g., Llama, Mistral, Qwen) +- Click "Start Server" (default port: 1234) + +**2. Add to config** (partial — merge into `~/.nanobot/config.json`): +```json +{ + "providers": { + "lm_studio": { + "apiKey": null, + "apiBase": "http://localhost:1234/v1" + } + }, + "agents": { + "defaults": { + "provider": "lm_studio", + "model": "local-model" + } + } +} +``` + +> **Note:** Set `apiKey` to `null` for LM Studio since it runs locally and doesn't require authentication. The model name should match what's shown in the LM Studio UI. +> `provider: "auto"` also works when `providers.lm_studio.apiBase` is configured, but setting `"provider": "lm_studio"` is the clearest option. + +
+
OpenVINO Model Server (local / OpenAI-compatible) @@ -1208,12 +1243,12 @@ vllm serve meta-llama/Llama-3.1-8B-Instruct --port 8000 **2. Add to config** (partial — merge into `~/.nanobot/config.json`): -*Provider (key can be any non-empty string for local):* +*Provider (set API key to null for local servers):* ```json { "providers": { "vllm": { - "apiKey": "dummy", + "apiKey": null, "apiBase": "http://localhost:8000/v1" } } diff --git a/nanobot/config/schema.py b/nanobot/config/schema.py index 00b32acb..a0f1f60a 100644 --- a/nanobot/config/schema.py +++ b/nanobot/config/schema.py @@ -96,7 +96,7 @@ class AgentsConfig(Base): class ProviderConfig(Base): """LLM provider configuration.""" - api_key: str = "" + api_key: str | None = None api_base: str | None = None extra_headers: dict[str, str] | None = None # Custom headers (e.g. APP-Code for AiHubMix) @@ -115,6 +115,7 @@ class ProvidersConfig(Base): dashscope: ProviderConfig = Field(default_factory=ProviderConfig) vllm: ProviderConfig = Field(default_factory=ProviderConfig) ollama: ProviderConfig = Field(default_factory=ProviderConfig) # Ollama local models + lm_studio: ProviderConfig = Field(default_factory=ProviderConfig) # LM Studio local models ovms: ProviderConfig = Field(default_factory=ProviderConfig) # OpenVINO Model Server (OVMS) gemini: ProviderConfig = Field(default_factory=ProviderConfig) moonshot: ProviderConfig = Field(default_factory=ProviderConfig) diff --git a/nanobot/providers/registry.py b/nanobot/providers/registry.py index f4ea9fe2..be098731 100644 --- a/nanobot/providers/registry.py +++ b/nanobot/providers/registry.py @@ -337,6 +337,17 @@ PROVIDERS: tuple[ProviderSpec, ...] = ( detect_by_base_keyword="11434", default_api_base="http://localhost:11434/v1", ), + # LM Studio (local, OpenAI-compatible) + ProviderSpec( + name="lm_studio", + keywords=("lm-studio", "lmstudio", "lm_studio"), + env_key="LM_STUDIO_API_KEY", + display_name="LM Studio", + backend="openai_compat", + is_local=True, + detect_by_base_keyword="1234", + default_api_base="http://localhost:1234/v1", + ), # === OpenVINO Model Server (direct, local, OpenAI-compatible at /v3) === ProviderSpec( name="ovms",