You signed in with another tab or window. Reload to refresh your session.You signed out in another tab or window. Reload to refresh your session.You switched accounts on another tab or window. Reload to refresh your session.Dismiss alert
{{ message }}
Repository navigation
Support multiple models per OpenAI-compatible connection and independent model selection for bots and tasks #1370
I use a third-party OpenAI-compatible provider. The same API key gives access to multiple models, but in my current setup I can only configure one model for the connection. All bots then use that model, and I cannot assign different models from the same connection to different bots.
I would also like to choose models independently for scheduled routines and individual tasks.
Steps to reproduce
Configure an OpenAI-compatible provider with a base URL, an API key, and a model ID.
Use an account whose API key has access to multiple models.
Try to assign one model to Bot A and another model from the same provider to Bot B.
Try to select a different model for a scheduled routine or an individual task.
Actual behavior
In my setup, only one model from this connection is available for assignment. I cannot achieve independent selection across bots, routines, and tasks.
Expected behavior
Configure the provider credentials once and register multiple model IDs under the same connection.
Let each bot select its own model from that connection.
Let a scheduled routine or individual task override the bot's default model.
For example, Bot A could use Model A, Bot B could use Model B, and a scheduled routine could use Model C, all with the same base URL and API key. This would help match model capability and cost to each use case.
The v0.2.0 release notes mention that routines can run on their own model. Is that also supported for multiple models under one third-party OpenAI-compatible connection? If so, could you clarify the configuration steps?
Environment
Rakazo version / commit: Unknown
Deployment type: Unknown
Operating system: Unknown
Provider name and example model IDs: Not specified
Additional findings: this also prevents choosing a different model from the same OpenAI-compatible connection as a backup.
Verified behavior
With the existing API key, the endpoint's /v1/models returns HTTP 200 and seven model IDs, including deepseek-v4.1-flash, deepseek-v4-flash, glm-5.3, and kimi-k3. This confirms discovery; it is not a generation test of every listed model.
The connection currently stores deepseek-v4.1-flash. Calling the deployed validateConnectedModelChoice for the separately listed deepseek-v4-flash returns Unknown model for that provider.
The backup picker exposes the saved compatible model, but not the other models served by the same endpoint/key. Changing the main model does not register an additional independently selectable model.
Deployment details missing from the original report: self-hosted Docker on Ubuntu; API, Web, and Worker image revision 9e9848b577cfb9c52abc1546111a93328ea74095. The deployment has local runtime patches for knowledge-curation tasks, so this is not a clean upstream reproduction. The source findings below were separately checked against upstream commit d165de43b48db500c771f5cb5628abeecfa9c92e on October 15.
Relevant upstream code
persistModelCredential updates the existing user/provider credential, and selectSpaceModelPreference saves one selected model for that credential. Discovering models does not persist them as separately selectable entries.
validateConnectedModelChoice requires a saved preference matching a custom compatible model ID; another ID returned by the endpoint is rejected unless already saved.
connectedBackupOptions excludes OpenAI-compatible catalog entries, then adds only the single compatible credential/model found with credentials.find(...).
Requested behavior across model selectors
Please support one connection with shared credentials and multiple registered model IDs, using the same model list for the space default, individual bots, routine/task overrides, and ordered backup models. Each registered model should retain its own capability/parameter settings, such as context/output limits, image support, and reasoning settings.
For example: Bot A uses deepseek-v4.1-flash, Bot B uses glm-5.3, a routine overrides its bot with kimi-k3, and a backup selects a different registered model, all using the same endpoint/key. Existing connections and selections should remain usable after migration; changing one selection should not remove other registered models or their settings.
If an existing supported configuration can achieve this, please point me to the steps. Otherwise, these findings suggest the limitation spans registration, validation, and the selectors, rather than only the settings dropdown.
I'd like to work on this. I hit the same limit: one OpenAI-compatible endpoint serves several models, but a connection can only register one, so bots, routines and backups all share it.
Proposed shape, before I open a PR:
The connection stores the model ids the user enables, chosen from the existing /v1/models probe. One of them stays the connection default. Connections saved before this change keep working as a one-item list.
Every selector (space default, bot, routine, helper, backup) accepts any enabled id from that connection, through the same shared validation that rejects other ids today.
Each bot keeps its own thinking level. Reasoning stays a connection capability, so any enabled model on a reasoning connection can use thinking.
Disabling a model that something still uses is refused, with the users listed, instead of leaving a broken pin.
Per-model limits (context and output size, images) stay connection-wide in this change, except the existing per-model vision list. I'd propose per-model limits as a follow-up so this stays reviewable.
Does that fit how you want model connections to work? I'll keep the UI change minimal and cover web and mobile.
Thanks @jfr956 for #1424. The enabled-model list across bots, routines, helpers and backups addresses the main selection limitation reported here. I have reviewed its inclusion in v0.3.1, but have not yet upgraded my deployment or verified it against my live provider.
I am adding these observations here because they affect the same custom OpenAI-compatible connection. They are separate from model registration/selection, so #1424 should not be taken as fixing them. If you prefer a separate compatibility issue for tracking, please let me know.
The connection advertises the DeepSeek-named model IDs in my earlier comment. This is a third-party compatible endpoint, not a direct official DeepSeek endpoint. I cannot yet attribute the original malformed output to the model, relay or SDK.
Observed behavior
Some bot replies contain inline <thought> / <brainstorm> tags, internal-looking summary envelopes, or malformed/unclosed reasoning markers in public content.
Other replies expose DSML / invoke / parameter text as ordinary prose. That text is not a structured tool call and must not be treated as evidence that a tool ran. A text-only intended action can therefore leave the requested work undone.
In an isolated partial-output fixture, finish_reason: "length" with some public text was returned as done without a truncation warning. The empty-output length case correctly raised an output-limit error.
Separate history-compaction checks retained historical reasoning blocks in the compaction prompt and inherited reasoning-enabled model settings. Could you clarify the intended reasoning/history policy for compaction?
What was actually verified
On October 19, an isolated HTTP/SSE fixture server drove the unmodified official PiAgentRuntime from both 9e9848b577cfb9c52abc1546111a93328ea74095 (pi-ai 0.87.1) and cf849a5ab96d0da58d33d059fc24b24c7e937c43 (pi-ai 1.3.0). No local compatibility patches were loaded. This was controlled replay, not a fresh direct-DeepSeek call or a complete persisted executor/mobile test.
All 19 privately retained real-incident content fixtures still exposed the anomalous text in both versions: six inline-thought, nine envelope and four protocol-text cases. In those fixture tests, a separate, genuine structured test tool call still executed once; the anomaly is not that all structured tools fail.
Normal reasoning_content separation, structured tool_calls, and reasoning replay after a tool passed in both versions. I am not reporting that standard DeepSeek fields are entirely unsupported.
On October 22, I additionally compared the tested newer commit with v0.3.1 (926710a09b30a6c1f83029da88dfe06656b031f2). The custom compatible provider, tool-call guard, thinking-signature and user-progress modules are unchanged; the SDK remains 1.3.0. The runtime change makes remember sequential, and the compaction change reuses the same escaping helper. I did not identify a fix for the observations above in those paths. This last check is source comparison only, not a claim that I reran the v0.3.1 image, live endpoint or iOS acceptance tests.
Minimal synthetic reproduction direction
Use a local streaming OpenAI-compatible fixture endpoint with harmless test markers in delta.content, for example:
Send these as successive SSE data: events, followed by [DONE], through the normal runtime. Inspect the user-visible text and independently count actual host tool callbacks. A second fixture can return protocol-looking text in content without any tool_calls; that text must never be executed as a command. A companion control should include a valid structured call and confirm it still runs once.
Could Rakazo provide an explicit compatibility policy for malformed assistant reasoning/protocol envelopes, and mark an incomplete or unusable result clearly rather than presenting it as ordinary successful output? Any recovery should request valid structured calls through the normal permission path, preserve legitimate quoted tags/source documents, and avoid repeating already executed tool effects.
Activity
HappyDeedee commentedon Oct 15, 2026
Additional findings: this also prevents choosing a different model from the same OpenAI-compatible connection as a backup.
Verified behavior
/v1/modelsreturns HTTP 200 and seven model IDs, includingdeepseek-v4.1-flash,deepseek-v4-flash,glm-5.3, andkimi-k3. This confirms discovery; it is not a generation test of every listed model.deepseek-v4.1-flash. Calling the deployedvalidateConnectedModelChoicefor the separately listeddeepseek-v4-flashreturnsUnknown model for that provider.Deployment details missing from the original report: self-hosted Docker on Ubuntu; API, Web, and Worker image revision
9e9848b577cfb9c52abc1546111a93328ea74095. The deployment has local runtime patches for knowledge-curation tasks, so this is not a clean upstream reproduction. The source findings below were separately checked against upstream commitd165de43b48db500c771f5cb5628abeecfa9c92eon October 15.Relevant upstream code
persistModelCredentialupdates the existing user/provider credential, andselectSpaceModelPreferencesaves one selected model for that credential. Discovering models does not persist them as separately selectable entries.validateConnectedModelChoicerequires a saved preference matching a custom compatible model ID; another ID returned by the endpoint is rejected unless already saved.connectedBackupOptionsexcludes OpenAI-compatible catalog entries, then adds only the single compatible credential/model found withcredentials.find(...).Requested behavior across model selectors
Please support one connection with shared credentials and multiple registered model IDs, using the same model list for the space default, individual bots, routine/task overrides, and ordered backup models. Each registered model should retain its own capability/parameter settings, such as context/output limits, image support, and reasoning settings.
For example: Bot A uses
deepseek-v4.1-flash, Bot B usesglm-5.3, a routine overrides its bot withkimi-k3, and a backup selects a different registered model, all using the same endpoint/key. Existing connections and selections should remain usable after migration; changing one selection should not remove other registered models or their settings.If an existing supported configuration can achieve this, please point me to the steps. Otherwise, these findings suggest the limitation spans registration, validation, and the selectors, rather than only the settings dropdown.
jfr956 commentedon Oct 16, 2026
I'd like to work on this. I hit the same limit: one OpenAI-compatible endpoint serves several models, but a connection can only register one, so bots, routines and backups all share it.
Proposed shape, before I open a PR:
/v1/modelsprobe. One of them stays the connection default. Connections saved before this change keep working as a one-item list.Does that fit how you want model connections to work? I'll keep the UI change minimal and cover web and mobile.
fix(models): keep model switches visible and compare normalized serve…
feat(models): let one OpenAI-compatible connection serve several mode…
HappyDeedee commentedon Oct 22, 2026
Thanks @jfr956 for #1424. The enabled-model list across bots, routines, helpers and backups addresses the main selection limitation reported here. I have reviewed its inclusion in v0.3.1, but have not yet upgraded my deployment or verified it against my live provider.
Additional DeepSeek-compatible runtime observations
I am adding these observations here because they affect the same custom OpenAI-compatible connection. They are separate from model registration/selection, so #1424 should not be taken as fixing them. If you prefer a separate compatibility issue for tracking, please let me know.
The connection advertises the DeepSeek-named model IDs in my earlier comment. This is a third-party compatible endpoint, not a direct official DeepSeek endpoint. I cannot yet attribute the original malformed output to the model, relay or SDK.
Observed behavior
<thought>/<brainstorm>tags, internal-looking summary envelopes, or malformed/unclosed reasoning markers in publiccontent.invoke/parametertext as ordinary prose. That text is not a structured tool call and must not be treated as evidence that a tool ran. A text-only intended action can therefore leave the requested work undone.finish_reason: "length"with some public text was returned as done without a truncation warning. The empty-output length case correctly raised an output-limit error.What was actually verified
On October 19, an isolated HTTP/SSE fixture server drove the unmodified official
PiAgentRuntimefrom both9e9848b577cfb9c52abc1546111a93328ea74095(pi-ai 0.87.1) andcf849a5ab96d0da58d33d059fc24b24c7e937c43(pi-ai 1.3.0). No local compatibility patches were loaded. This was controlled replay, not a fresh direct-DeepSeek call or a complete persisted executor/mobile test.reasoning_contentseparation, structuredtool_calls, and reasoning replay after a tool passed in both versions. I am not reporting that standard DeepSeek fields are entirely unsupported.On October 22, I additionally compared the tested newer commit with v0.3.1 (
926710a09b30a6c1f83029da88dfe06656b031f2). The custom compatible provider, tool-call guard, thinking-signature and user-progress modules are unchanged; the SDK remains 1.3.0. The runtime change makesremembersequential, and the compaction change reuses the same escaping helper. I did not identify a fix for the observations above in those paths. This last check is source comparison only, not a claim that I reran the v0.3.1 image, live endpoint or iOS acceptance tests.Minimal synthetic reproduction direction
Use a local streaming OpenAI-compatible fixture endpoint with harmless test markers in
delta.content, for example:{"choices":[{"index":0,"delta":{"content":"<thought>TEST_ONLY</thought>Public answer"},"finish_reason":null}]} {"choices":[{"index":0,"delta":{},"finish_reason":"stop"}]}Send these as successive SSE
data:events, followed by[DONE], through the normal runtime. Inspect the user-visible text and independently count actual host tool callbacks. A second fixture can return protocol-looking text incontentwithout anytool_calls; that text must never be executed as a command. A companion control should include a valid structured call and confirm it still runs once.Could Rakazo provide an explicit compatibility policy for malformed assistant reasoning/protocol envelopes, and mark an incomplete or unusable result clearly rather than presenting it as ordinary successful output? Any recovery should request valid structured calls through the normal permission path, preserve legitimate quoted tags/source documents, and avoid repeating already executed tool effects.
Relevant pinned sources: compatible provider, runtime, history compaction. No private prompts, reasoning transcripts, credentials or server addresses are included here.