Skip to content

Wire ProviderRegistry into session creation — sessions are hardcoded to ClaudeProvider #80

Description

@saucam

Context

codeoid is becoming a meta-harness over multiple code harnesses (Claude Code today; Gemini, OpenAI, Hermes, antigravity SDK planned). The multi-provider foundation (#38) shipped the pieces — AgentProvider/SessionProvider interfaces, GeminiProvider/OpenAIProvider implementations, canonical turn normalization, and a ProviderRegistry (src/daemon/providers/registry.ts) — but the registry is not wired into session creation: Session still constructs ClaudeProvider directly (src/daemon/session.ts:357, opts._testProvider ?? new ClaudeProvider({...})), so every real session is Claude-backed regardless of what's registered.

The per-provider model-catalog layer landed in #79 and is ready for this: Session.onModels already tags reports with provider.id, catalogs are cached/persisted per provider, and models.list takes an optional provider param.

Proposed scope

  • Construct/lookup providers through ProviderRegistry instead of new ClaudeProvider(...) in Session; the daemon registers available providers at boot (claude always; others gated on config/credentials)
  • session.create accepts an optional provider (wire-additive; default = DEFAULT_PROVIDER_ID from session-manager); persist the choice on the session row so resume reconstructs the right provider
  • SessionInfo exposes the provider id (wire-additive) so frontends can label sessions and scope model pickers via models.list { provider }
  • Per-provider config surface (API keys / endpoints) — likely config.providers.*
  • /model validation already resolves against session.providerId (feat: persist the live model catalog so restarts serve current models #79); confirm alias resolution (resolveModelId's claude-* passthrough) gets a provider-appropriate equivalent
  • Tests: registry-driven construction, resume with a non-default provider, unknown-provider rejection at create, mock-provider end-to-end via the registry path

Non-goals

  • Mid-session provider switching (turn-level provider routing is a separate design)
  • Shipping working Gemini/OpenAI auth flows — this issue is the plumbing; provider hardening can follow per provider

Notes

  • SessionProvider vs AgentProvider: the registry currently stores AgentProvider; sessions need SessionProvider — either narrow the registry or register factories (a per-session provider instance is required today since ClaudeProvider is stateful per session), which likely means the registry should hold (init) => SessionProvider factories rather than instances
  • Keep everything wire-additive; the Rust protocol crate tolerates unknown fields

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Type

    No type

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions