Summary
ProviderRegistry.fromConfig rejects openai-compatible providers that omit
defaultChatModel, even when the provider is embedding-only. This forces
users to keep a dummy/placeholder chat model on embedding providers, and any
attempt to "clean up" the redundant key makes every startup mode
(tui, run, serve) fail.
Environment
- atomic-agent 0.6.0 (Linux, x86-64, self-contained binary)
Steps to reproduce
- Define an embedding-only provider in
~/.atomic-agent/config.json:
{
"llm": {
"activeTextProvider": "openrouter",
"activeEmbeddingProvider": "local-embed",
"providers": [
{ "id": "openrouter", "kind": "openai-compatible", "baseUrl": "https://openrouter.ai/api/v1", "...": "..." },
{
"id": "local-embed",
"kind": "openai-compatible",
"apiKey": "not-needed",
"baseUrl": "http://127.0.0.1:11435",
"defaultEmbeddingModel": "nomic-embed-text-v2-moe-Q8_0.gguf",
"userModels": [
{ "id": "nomic-embed-text-v2-moe-Q8_0.gguf", "kind": "embedding", "dim": 768 }
]
}
]
}
}
- Run
atomic-agent tui (or run / serve).
Actual behavior
Immediate fatal error; the TUI never renders:
Error: openai-compatible provider "local-embed" requires baseUrl and defaultChatModel
at ProviderRegistry.fromConfig
at async createAgentRuntime
at async tuiCommand
Expected behavior
An embedding-only provider (all userModels[].kind === "embedding", and/or
selected only via llm.activeEmbeddingProvider + defaultEmbeddingModel)
should not require defaultChatModel.
Why this matters
- The config schema already distinguishes embeddings explicitly
(defaultEmbeddingModel, userModels[].kind: "embedding",
llm.activeEmbeddingProvider), so the chat-model requirement contradicts
the schema's own design.
- Users must keep a placeholder chat model that doesn't exist on the
embedding server (e.g. defaultChatModel: "z-ai/glm-5.3-flash" on a local
llama.cpp endpoint), which is confusing and looks like a misconfiguration.
- The validation only fires at runtime startup, not at config-write time, so
a "harmless cleanup" edit breaks the agent with no warning until the next
launch.
Suggested fixes (any of)
- Skip the
defaultChatModel requirement when all of a provider's
userModels are kind: "embedding" (or when defaultEmbeddingModel is
set and the provider is not the active text provider).
- Default
defaultChatModel to the first kind: "chat" user model (error
only if none exists AND the provider is used for chat).
- At minimum, validate the config at write time (
atomic-agent config set)
and improve the error message to explain embedding-only providers still
need the key.
Workaround
Keep any defaultChatModel value on embedding-only providers, e.g.:
"defaultChatModel": "placeholder"
Summary
ProviderRegistry.fromConfigrejectsopenai-compatibleproviders that omitdefaultChatModel, even when the provider is embedding-only. This forcesusers to keep a dummy/placeholder chat model on embedding providers, and any
attempt to "clean up" the redundant key makes every startup mode
(
tui,run,serve) fail.Environment
Steps to reproduce
~/.atomic-agent/config.json:{ "llm": { "activeTextProvider": "openrouter", "activeEmbeddingProvider": "local-embed", "providers": [ { "id": "openrouter", "kind": "openai-compatible", "baseUrl": "https://openrouter.ai/api/v1", "...": "..." }, { "id": "local-embed", "kind": "openai-compatible", "apiKey": "not-needed", "baseUrl": "http://127.0.0.1:11435", "defaultEmbeddingModel": "nomic-embed-text-v2-moe-Q8_0.gguf", "userModels": [ { "id": "nomic-embed-text-v2-moe-Q8_0.gguf", "kind": "embedding", "dim": 768 } ] } ] } }atomic-agent tui(orrun/serve).Actual behavior
Immediate fatal error; the TUI never renders:
Expected behavior
An embedding-only provider (all
userModels[].kind === "embedding", and/orselected only via
llm.activeEmbeddingProvider+defaultEmbeddingModel)should not require
defaultChatModel.Why this matters
(
defaultEmbeddingModel,userModels[].kind: "embedding",llm.activeEmbeddingProvider), so the chat-model requirement contradictsthe schema's own design.
embedding server (e.g.
defaultChatModel: "z-ai/glm-5.3-flash"on a localllama.cpp endpoint), which is confusing and looks like a misconfiguration.
a "harmless cleanup" edit breaks the agent with no warning until the next
launch.
Suggested fixes (any of)
defaultChatModelrequirement when all of a provider'suserModelsarekind: "embedding"(or whendefaultEmbeddingModelisset and the provider is not the active text provider).
defaultChatModelto the firstkind: "chat"user model (erroronly if none exists AND the provider is used for chat).
atomic-agent config set)and improve the error message to explain embedding-only providers still
need the key.
Workaround
Keep any
defaultChatModelvalue on embedding-only providers, e.g.: