feat(ai): wire Config.ai.extraModels for user-defined OpenAI-compat providers#176
Open
ImIvanGil wants to merge 1 commit into
Open
feat(ai): wire Config.ai.extraModels for user-defined OpenAI-compat providers#176ImIvanGil wants to merge 1 commit into
ImIvanGil wants to merge 1 commit into
Conversation
…roviders
`Config.ai.extraModels` was declared in the schema (config/defaults/ai.js
and config/Config.qml line 1180) but never consumed by Ai.qml. As a
result, users had no way to register custom OpenAI-compatible providers
— Moonshot/Kimi, OpenRouter, LMStudio remote, llama.cpp HTTP servers,
groqcloud variants, etc. — beyond the hardcoded provider list.
This wires the existing schema field: `fetchAvailableModels()` now
iterates `Config.ai.extraModels` and registers each entry as a regular
AiModel. The "custom" provider already routes to OpenAiApiStrategy via
`getStrategyForProvider`, so the request/parse path is already correct
for any OpenAI-compat endpoint.
Entry schema (in ~/.config/ambxst/config/ai.json):
"extraModels": [
{
"name": "Kimi K2 (0905)",
"model": "kimi-k2-0905-preview",
"endpoint": "https://api.moonshot.ai/v1",
"provider": "custom",
"description": "Moonshot K2 preview",
"requires_key": true,
"key_provider": "custom"
}
]
The API key is read from KeyStore under `key_provider` (default "custom"),
which the existing "Custom Provider API Key" Save button in AiPanel.qml
already populates correctly. So the end-to-end flow now works without
any UI changes.
A future PR could add UI to manage the extraModels array from the panel
directly. For now, users edit ai.json — same pattern as systemPrompt
and other config fields.
Tested with Moonshot (Kimi K2 family + moonshot-v1-{8k,32k,128k}). Each
custom model appears in the dropdown and gets requested correctly.
This was referenced May 13, 2026
This file contains hidden or bidirectional Unicode text that may be interpreted or compiled differently than what appears below. To review, open the file in an editor that reveals hidden Unicode characters.
Learn more about bidirectional Unicode characters
Sign up for free
to join this conversation on GitHub.
Already have an account?
Sign in to comment
Add this suggestion to a batch that can be applied as a single commit.This suggestion is invalid because no changes were made to the code.Suggestions cannot be applied while the pull request is closed.Suggestions cannot be applied while viewing a subset of changes.Only one suggestion per line can be applied in a batch.Add this suggestion to a batch that can be applied as a single commit.Applying suggestions on deleted lines is not supported.You must change the existing code in this line in order to create a valid suggestion.Outdated suggestions cannot be applied.This suggestion has been applied or marked resolved.Suggestions cannot be applied from pending reviews.Suggestions cannot be applied on multi-line comments.Suggestions cannot be applied while the pull request is queued to merge.Suggestion cannot be applied right now. Please check back later.
Context
Config.ai.extraModelsis declared in the schema:config/defaults/ai.js:4→"extraModels": []config/Config.qml:1180→property list<var> extraModels: []But it's never consumed anywhere in the codebase (verified with
grep -rn extraModels). As a result, users have no way to register custom OpenAI-compatible providers — Moonshot/Kimi, OpenRouter, LMStudio remote, llama.cpp HTTP servers, free-tier providers, etc. — beyond the hardcoded list (Gemini/OpenAI/Mistral/Groq/Anthropic/Ollama/MiniMax).The
AiPanel.qmlUI has a "Custom Provider" section with fields for API Key + Endpoint + cURL Template, but only the API Key Save button is wired — the Endpoint and cURL Template fields try to persist toConfig.ai.customEndpointandConfig.ai.customCurlTemplate, neither of which exist in the schema. So the full "Custom Provider" flow is broken upstream.What this PR does
Wires
Config.ai.extraModelsend-to-end so users can configure arbitrary OpenAI-compat providers without UI changes (UI changes can be a follow-up).fetchAvailableModels()now iterates the array and registers each entry as a regularAiModel.The
"custom"provider already routes toOpenAiApiStrategyviagetStrategyForProvider()(Ai.qml:117), so the request/parse path is already correct.Entry schema (
~/.config/ambxst/config/ai.json){ "extraModels": [ { "name": "Kimi K2 (0905)", "model": "kimi-k2-0905-preview", "endpoint": "https://api.moonshot.ai/v1", "provider": "custom", "description": "Moonshot K2 preview", "requires_key": true, "key_provider": "custom" }, { "name": "Local Llama 3", "model": "llama-3-70b", "endpoint": "http://localhost:8080/v1", "provider": "custom", "requires_key": false } ] }provider: "custom"→ usesOpenAiApiStrategy(default for unknown providers anyway).requires_key: true(default) → looks up API key from KeyStore underkey_provider(default"custom"). The existing "Custom Provider API Key" Save button inAiPanel.qmlpopulates that KeyStore entry — so the end-to-end flow works without UI changes.requires_key: false→ for local/no-auth endpoints (Ollama remote, llama.cpp without keys, etc.).Why this approach
ai.jsonfor the rest, same pattern assystemPrompt.AiPanel.qml's broken "Custom Provider" Endpoint/cURL fields could be reworked to manageextraModelsentries directly, but that's a UX call best made separately.Tested with
kimi-k2-0905-preview,kimi-k2.6,kimi-k2-thinking,moonshot-v1-{8k,32k,128k}— all appear in dropdown, requests fire correctly, responses parse viaOpenAiApiStrategy.sk-...via the existing "Custom Provider API Key" Save button + adding entries toai.jsonproduced working models with zero panel-level glitches.Diff stats
Related PRs
This is the third in a series of Ambxst fixes. Related:
A follow-up PR will add
reasoning_content+ dynamic-temperature support so thinking models (Kimi K2.5/K2.6, GPT-o1, Claude thinking variants) work via the same flow.