Skip to content

fix(cli): TUI onboarding cannot create custom relay connections (OpenAI Chat / OpenAI Responses / Anthropic) — Desktop can #3405

Closed

Description

@me2seeks

What happened

In the TUI setup wizard (/setup and first-run), the three custom relay providers never appear in the provider picker, so there is no way to create these connections from the TUI:

  • Custom relay (OpenAI Chat-compatible) — openai-compatible
  • Custom relay (OpenAI Responses) — openai-responses-compatible
  • Custom relay (Anthropic) — anthropic-compatible

The Desktop Settings → Models page lists all three and can create them (its add form collects the base URL for category === 'custom' providers). The TUI is the only surface where they are unreachable.

Root cause

Two gaps, one visible and one structural:

  1. The TUI catalog filter drops every provider without a built-in base URL. listApiKeyOnboardableProviders() maps the registry and then filters with .filter((provider) => !provider.requiresBaseUrl) (packages/cli/src/onboarding-catalog.ts:20), where requiresBaseUrl: !definition.baseUrl (:16). The three relay entries declare baseUrl: '' precisely because the user must supply their own endpoint (packages/core/src/provider-registry.ts:1724, :1743, :1762), so all three are filtered out of both TUI paths: the standalone fallback list (packages/cli/src/pi-tui-runner.ts:1765) and the runtime-host projection (packages/cli/src/runtime-host-onboarding.ts:81).

  2. The onboarding protocol has no field to carry a base URL anyway. The wizard only collects an API key and an enabled-model set; OnboardingVerifyInput/OnboardingSaveInput (packages/cli/src/pi-tui-contracts.ts:37-51) and the host-side ConnectionOnboardingVerifyInput/ConnectionOnboardingSaveInput (packages/runtime-host/src/protocol/connection-effects.ts:67-74) carry only { providerType, apiKey, enabledModelIds }. Host-side discovery builds transientConnection(input.providerType) with no endpoint override (packages/runtime-host/src/server/connection-effect-coordinator.ts:220-224), so even if the relays were listed, verify would run model discovery against an empty base URL and fail.

So this is not just "add three rows to the picker": the TUI wizard needs a base URL step for requiresBaseUrl providers, plumbed through the CLI contracts and the runtime-host onboarding operations.

Proposed boundary

  1. Stop filtering requiresBaseUrl out of listApiKeyOnboardableProviders(); keep the flag so the wizard knows which providers need an endpoint.
  2. Add a base URL step to OnboardingWizard between provider pick and API key for entries with requiresBaseUrl (validate non-empty URL; reuse Desktop's normalization rules for relay base URLs).
  3. Extend OnboardingVerifyInput/OnboardingSaveInput and the runtime-host connection.onboarding.verify/save inputs with an optional baseUrl; thread it into transientConnection and commitConnectionOnboarding so the saved connection persists it.
  4. Keep the existing single-provider-slug model: saving a relay updates the same derived slug connection Desktop manages, so both surfaces stay in sync.

How to reproduce

  1. Run the maka TUI (first run, or /setup in-session).
  2. Scroll the provider picker: OpenAI, Anthropic, aggregators, local servers are listed — no "Custom relay" entries.
  3. Open Desktop → Settings → Models → Add provider: all three custom relay types are present and can be created with a base URL + API key.

Environment

  • Maka commit: 57e08d834
  • Surface: CLI TUI (pi-tui-runner onboarding wizard), compared against Desktop settings
  • OS: Linux

Activity

  1. me2seeks commented on Aug 21, 2026

    @me2seeks
    ContributorAuthor

    Archaeology: this gap was originally an explicit phase-1 scope cut, not an oversight at the time the filter was written.

    Net effect stands as described: the deferral was intentional, but phase 2 never arrived and the rationale is no longer visible in the code, so the TUI/Desktop asymmetry now functions as a defect for users.

  2. UncertaintyDeterminesYou4ndMe commented on Aug 22, 2026

    @UncertaintyDeterminesYou4ndMe
    Contributor

    Claiming this — implementing the proposed boundary as specified: unfilter requiresBaseUrl providers from the TUI catalog, add a base-URL step to the wizard between provider pick and API key, thread an always-present baseUrl: string | null through connection.onboarding.verify/save (exact-record protocol style, mirroring apiKey), apply it to discovery and persist it via commitConnectionOnboarding with persistedBaseUrl() semantics. Blank input on an existing relay connection will reuse the persisted base URL, mirroring the blank-key-reuses-stored-secret pattern.

  3. added a commit that references this issue on Aug 23, 2026
    9b33fdd
  4. added 3 commits that reference this issue on Aug 23, 2026
    000644b
    aebae8d
    bd9cb93
  5. added a commit that references this issue on Aug 24, 2026
    74dcd56
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Metadata

Metadata

Labels

bugSomething isn't workinghelp wantedExtra attention is needed

Type

No type

Projects

No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions