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
Maka's storage and execution model can already represent multiple Connection entities for one providerType, with credentials isolated by connectionId. Product support is incomplete and inconsistent:
Desktop can create suffixed API-key connections such as openai-2, but it orchestrates catalog creation, credential storage, and discovery as separate Runtime Host calls.
CLI/TUI onboarding projects one entry per provider and cannot explicitly create or manage another connection for that provider.
Desktop OAuth selects the first connection for a provider and presents one account card per provider, although OAuth tickets themselves are already bound to a specific connectionId.
Desktop and TUI model pickers both select connectionSlug + model, but do not apply the same duplicate-account disambiguation rules.
Session and AgentRun headers persist the connection slug, not the immutable connection ID. If connection A is deleted and connection B later reuses A's slug, an old Session can resolve to B's credentials instead of reporting that its original account was deleted.
This is related to #2677, but intentionally tracks a different product model. Each account remains a separate, user-visible Connection selected explicitly. Weighted routing, automatic balancing, and silent failover are not part of this issue.
Desired outcome
Support multiple API-key and OAuth accounts for the same provider consistently across CLI/TUI and Desktop, while keeping Runtime Host as the authority for onboarding identity, credential binding, Session targeting, and recovery.
Use these identity semantics:
providerType identifies the provider implementation, for example openai.
connectionId is the immutable identity of one configured account/connection entity.
slug is a unique, human-readable locator such as openai or openai-2; it may be reused after deletion and therefore must not be the sole historical identity.
Credentials remain isolated by connectionId.
Session persists connectionId + connectionSlug + model; AgentRun also records connectionId for execution attribution.
Execution resolves the Connection by connectionId and verifies that the stored slug still describes that entity. It must never fall back from a missing ID to a same-named replacement.
If the original Connection is deleted, the old Session clearly reports original account deleted. Only an explicit user selection may bind the Session to another Connection and restore execution.
S remains blocked and reports that its original account was deleted; it does not use B.
The user explicitly selects B, after which S stores B's ID, slug, and model and may run again.
Architecture boundary
Runtime Host should own:
distinguishing edit existing(connectionId) from create another provider account;
allocating and committing the final slug against the authoritative catalog snapshot;
atomic/recoverable catalog, credential, headers, and onboarding updates;
returning the final connectionId + slug;
OAuth login against an explicitly selected Connection;
validating and persisting Session entity bindings;
deletion diagnostics and explicit rebinding admission.
Storage remains the canonical persistence layer. Surfaces query choices, submit user intent, and present results; they do not allocate identity from a possibly stale local existingSlugs snapshot or silently choose credentials.
Implementation progress
Durable identity foundation — merged:feat(runtime): bind new sessions to connection identity #3864 is on main. New Host-created Sessions persist canonical Connection identity; derived Sessions and AgentRuns preserve it; execution resolves bound ID + slug and refuses same-slug replacement fallback.
API-key multi-account onboarding — refreshed and in review:feat(runtime-host): own multi-account API-key onboarding #3882 is rebuilt as an onboarding-only slice on current main. Runtime Host now owns explicit create(providerType) / existing(connectionId) targets, Storage-owned UUID + unique-slug allocation, recoverable v2 onboarding identity, and committed Connection results. CLI/TUI project every existing account plus add-account actions. The wire change uses compatibility epoch 68. This remains undelivered until feat(runtime-host): own multi-account API-key onboarding #3882 merges.
Offer explicit edit-existing and add-another-account actions.
Use Runtime Host onboarding rather than calculating existingSlugs in the surface.
Show enough account identity in setup and model selection to disambiguate duplicate names.
4. Desktop API-key convergence
Move the current multi-call create/credential/discovery orchestration onto the managed Runtime Host onboarding transaction.
Preserve existing IDs and slugs, including data such as openai-2; no catalog migration or renaming should be required.
5. Desktop OAuth multi-account support
Replace first-connection-by-provider selection with explicit Connection selection and multiple account cards.
Create additional OAuth Connections through the same Host-owned identity path.
Keep login/status/refresh/logout scoped to the selected connectionId.
Preserve the existing Connection-bound InteractiveOAuthLoginTicket checks.
Initially, the Host's single-active-interactive-login limitation may remain if it is surfaced as an explicit conflict and never silently supersedes another account's login. Per-Connection concurrent login lanes can be tracked separately if required.
6. Shared selection and deletion UX
Apply consistent duplicate-name and OAuth-safe labels across Desktop and TUI model pickers.
Keep the existing default Connection when another account is added unless the user explicitly changes the default.
On deletion, show the affected Session as blocked with “original account deleted” semantics and provide an explicit account/model picker to recover.
Never perform automatic account balancing, fallback, or slug-based rebinding.
Acceptance criteria
Two or more API-key Connections for the same provider can be created, edited, selected, and deleted from CLI/TUI and Desktop.
Two or more OAuth Connections for openai-codex and xai-oauth can be created and independently logged in, inspected, refreshed, logged out, selected, and deleted.
Each Connection has a unique immutable connectionId and catalog-unique slug; credentials are read and written only through that ID.
Concurrent create attempts cannot accidentally allocate the same slug or split catalog and credential ownership across surfaces.
Model choice remains explicit at Connection + model granularity and is visibly disambiguated on both Desktop and TUI.
A Session and every new AgentRun retain the selected Connection ID, slug, and model.
Deleting a selected Connection blocks existing Sessions with an “original account deleted” state.
Recreating the same slug never rebinds old Sessions.
Only an explicit Session configuration update can bind a blocked Session to a replacement Connection.
Adding another account does not silently change the default target.
Existing multi-Connection Desktop data remains valid without identity replacement or credential migration.
Protocol compatibility behavior is covered for the onboarding and Session contract changes.
Non-goals
Multiple credential profiles inside one Connection
Weighted load balancing or round-robin routing
Automatic quota failover
Silent selection of another account
Using an OAuth email address as a durable identity or mandatory slug
Current code anchors
Connection catalog and slug allocation: packages/storage/src/runtime-policy/connection-catalog-document.ts
Problem
Maka's storage and execution model can already represent multiple
Connectionentities for oneproviderType, with credentials isolated byconnectionId. Product support is incomplete and inconsistent:openai-2, but it orchestrates catalog creation, credential storage, and discovery as separate Runtime Host calls.connectionId.connectionSlug + model, but do not apply the same duplicate-account disambiguation rules.This is related to #2677, but intentionally tracks a different product model. Each account remains a separate, user-visible Connection selected explicitly. Weighted routing, automatic balancing, and silent failover are not part of this issue.
Desired outcome
Support multiple API-key and OAuth accounts for the same provider consistently across CLI/TUI and Desktop, while keeping Runtime Host as the authority for onboarding identity, credential binding, Session targeting, and recovery.
Use these identity semantics:
providerTypeidentifies the provider implementation, for exampleopenai.connectionIdis the immutable identity of one configured account/connection entity.slugis a unique, human-readable locator such asopenaioropenai-2; it may be reused after deletion and therefore must not be the sole historical identity.connectionId.connectionId + connectionSlug + model; AgentRun also recordsconnectionIdfor execution attribution.connectionIdand verifies that the stored slug still describes that entity. It must never fall back from a missing ID to a same-named replacement.Example:
{ connectionId: "A", connectionSlug: "openai-2", model: "gpt-5" }.openai-2.Architecture boundary
Runtime Host should own:
edit existing(connectionId)fromcreate another provider account;connectionId + slug;Storage remains the canonical persistence layer. Surfaces query choices, submit user intent, and present results; they do not allocate identity from a possibly stale local
existingSlugssnapshot or silently choose credentials.Implementation progress
main. New Host-created Sessions persist canonical Connection identity; derived Sessions and AgentRuns preserve it; execution resolves bound ID + slug and refuses same-slug replacement fallback.main. Runtime Host now owns explicitcreate(providerType)/existing(connectionId)targets, Storage-owned UUID + unique-slug allocation, recoverable v2 onboarding identity, and committed Connection results. CLI/TUI project every existing account plus add-account actions. The wire change uses compatibility epoch 68. This remains undelivered until feat(runtime-host): own multi-account API-key onboarding #3882 merges.Checkboxes below remain acceptance criteria for the tracking issue; an open PR is not marked delivered until it merges.
Workstreams
1. Runtime Host onboarding contract
connectionIdcreate semantics with an explicit target such asexisting(connectionId)/create(slug?, name?).provider,provider-2, ...) inside the authoritative Host/storage write path.connectionId + slug.2. Durable Session and AgentRun identity
connectionId + connectionSlug + modelon Session.connectionIdwith the existing connection/model information on AgentRun.3. CLI/TUI connection management
existingSlugsin the surface.4. Desktop API-key convergence
openai-2; no catalog migration or renaming should be required.5. Desktop OAuth multi-account support
connectionId.InteractiveOAuthLoginTicketchecks.6. Shared selection and deletion UX
Acceptance criteria
openai-codexandxai-oauthcan be created and independently logged in, inspected, refreshed, logged out, selected, and deleted.connectionIdand catalog-unique slug; credentials are read and written only through that ID.Non-goals
Current code anchors
packages/storage/src/runtime-policy/connection-catalog-document.tspackages/storage/src/runtime-policy/credential-vault-document.tspackages/storage/src/runtime-policy/coordinator.tspackages/runtime-host/src/server/connection-effect-coordinator.tspackages/cli/src/runtime-host-onboarding.tsapps/desktop/src/renderer/settings/provider-add-form.tsxapps/desktop/src/main/runtime-host-account-connection.tspackages/core/src/session.tspackages/core/src/agent-run.tspackages/core/src/chat-model-choice.tsandpackages/ui/src/chat-model-helpers.ts