Skip to content

Support multiple models per OpenAI-compatible connection and independent model selection for bots and tasks #1370

Open

Description

@HappyDeedee

Description

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

  1. Configure an OpenAI-compatible provider with a base URL, an API key, and a model ID.
  2. Use an account whose API key has access to multiple models.
  3. Try to assign one model to Bot A and another model from the same provider to Bot B.
  4. 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

Release notes referenced: https://github.com/elie222/rakazo/releases/tag/v0.2.0

Activity

  1. HappyDeedee commented on Oct 15, 2026

    @HappyDeedee
    Author

    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.

  2. jfr956 commented on Oct 16, 2026

    @jfr956
    Contributor

    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.

  3. HappyDeedee commented on Oct 22, 2026

    @HappyDeedee
    Author

    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

    • 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.
    • The newer version also recovered from the tested stream interruption after a tool without executing that tool twice, which is an improvement and is not being reported as an unfixed duplicate of [SEV-1] BUG 4: Bots complete turns with no written output ('empty-notice' class) #1164 / fix: surface empty tool-turn failures instead of a silent notice (#1164) #1172.

    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:

    {"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 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.

    Relevant pinned sources: compatible provider, runtime, history compaction. No private prompts, reasoning transcripts, credentials or server addresses are included here.

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

      Milestone

      No milestone

      Relationships

      None yet

      Development

      No branches or pull requests

      Issue actions