2026-06-06 12:25:03 -05:00
# Development
2026-06-10 00:36:22 +08:00
This page collects contributor-facing notes for extending nanobot. User-facing setup and runtime options live in [`configuration.md` ](./configuration.md ).
2026-06-06 12:25:03 -05:00
## Adding an LLM Provider
2026-06-10 00:36:22 +08:00
nanobot uses the provider registry in `nanobot/providers/registry.py` as the source of truth for LLM provider metadata. Most OpenAI-compatible providers need only two changes.
2026-06-06 12:25:03 -05:00
1. Add a `ProviderSpec` entry to `PROVIDERS` :
```python
ProviderSpec (
name = "myprovider" ,
keywords = ( "myprovider" , "mymodel" ),
env_key = "MYPROVIDER_API_KEY" ,
display_name = "My Provider" ,
default_api_base = "https://api.myprovider.com/v1" ,
)
```
2. Add a field to `ProvidersConfig` in `nanobot/config/schema.py` :
```python
class ProvidersConfig ( BaseModel ):
...
myprovider : ProviderConfig = Field ( default_factory = ProviderConfig )
```
2026-06-10 00:36:22 +08:00
Environment variables, config matching, provider status, and WebUI credential display derive from those two entries.
2026-06-06 12:25:03 -05:00
Useful `ProviderSpec` options:
| Field | Description |
|---|---|
| `default_api_base` | Default OpenAI-compatible base URL. |
| `env_extras` | Additional environment variables derived from the provider config. |
| `model_overrides` | Per-model request parameter overrides. |
| `is_gateway` | Provider can route many model families, like OpenRouter. |
| `detect_by_key_prefix` | Match configured gateways by API-key prefix. |
| `detect_by_base_keyword` | Match configured gateways by API base URL. |
| `strip_model_prefix` | Strip `provider/` before sending the model to the upstream API. |
| `supports_max_completion_tokens` | Use `max_completion_tokens` instead of `max_tokens` . |
| `is_transcription_only` | Provider has credentials but cannot serve chat completions. |
## Adding a Transcription Provider
Transcription is intentionally split into two layers:
2026-06-10 00:36:22 +08:00
- `nanobot/audio/transcription_registry.py` owns provider names, aliases, default models, and adapter loading.
2026-06-06 12:25:03 -05:00
- `nanobot/providers/transcription.py` owns provider-specific HTTP behavior.
2026-06-11 13:51:25 +08:00
Credentials still live under `providers.<provider>` so chat channels and WebUI resolve API keys and API bases the same way.
2026-06-06 12:25:03 -05:00
1. Add provider credentials to `ProvidersConfig` .
```python
class ProvidersConfig ( BaseModel ):
...
my_stt : ProviderConfig = Field ( default_factory = ProviderConfig )
```
2. Add a `ProviderSpec` in `nanobot/providers/registry.py` .
2026-06-10 00:36:22 +08:00
For transcription-only providers, set `is_transcription_only=True` so they show up in credential/settings surfaces but stay out of chat model selection.
2026-06-06 12:25:03 -05:00
```python
ProviderSpec (
name = "my_stt" ,
keywords = ( "my_stt" ,),
env_key = "MY_STT_API_KEY" ,
display_name = "My STT" ,
default_api_base = "https://api.example.com/v1" ,
is_transcription_only = True ,
)
```
3. Add an adapter class in `nanobot/providers/transcription.py` .
2026-06-10 00:36:22 +08:00
Adapters receive resolved credentials and settings. They return an empty string for provider errors so channel voice messages fail quietly instead of crashing the agent loop.
2026-06-06 12:25:03 -05:00
```python
class MySTTTranscriptionProvider :
def __init__ (
self ,
api_key : str | None = None ,
api_base : str | None = None ,
language : str | None = None ,
model : str | None = None ,
):
self . api_key = api_key or os . environ . get ( "MY_STT_API_KEY" )
self . api_base = api_base or "https://api.example.com/v1"
self . language = language or None
self . model = model or "my-default-stt-model"
async def transcribe ( self , file_path : str | Path ) -> str :
...
```
4. Register the adapter in `nanobot/audio/transcription_registry.py` .
```python
TranscriptionProviderSpec (
name = "my_stt" ,
default_model = "my-default-stt-model" ,
adapter = "nanobot.providers.transcription:MySTTTranscriptionProvider" ,
aliases = ( "mystt" ,),
)
```
5. Add tests.
At minimum, cover:
- config resolution in `tests/providers/test_transcription.py`
- adapter request/response behavior and retry/error handling
- WebUI settings payload/update behavior in `tests/webui/test_settings_api.py`
- provider brand mapping if the provider appears in Settings
6. Update user-facing docs.
2026-06-10 00:36:22 +08:00
Add the provider to [`configuration.md` ](./configuration.md ) where users choose `transcription.provider` , but keep implementation details in this development guide.