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
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 }
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
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/SessionProviderinterfaces,GeminiProvider/OpenAIProviderimplementations, canonical turn normalization, and aProviderRegistry(src/daemon/providers/registry.ts) — but the registry is not wired into session creation:Sessionstill constructsClaudeProviderdirectly (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.onModelsalready tags reports withprovider.id, catalogs are cached/persisted per provider, andmodels.listtakes an optionalproviderparam.Proposed scope
ProviderRegistryinstead ofnew ClaudeProvider(...)inSession; the daemon registers available providers at boot (claude always; others gated on config/credentials)session.createaccepts an optionalprovider(wire-additive; default =DEFAULT_PROVIDER_IDfrom session-manager); persist the choice on the session row so resume reconstructs the right providerSessionInfoexposes the provider id (wire-additive) so frontends can label sessions and scope model pickers viamodels.list { provider }config.providers.*/modelvalidation already resolves againstsession.providerId(feat: persist the live model catalog so restarts serve current models #79); confirm alias resolution (resolveModelId'sclaude-*passthrough) gets a provider-appropriate equivalentNon-goals
Notes
SessionProvidervsAgentProvider: the registry currently storesAgentProvider; sessions needSessionProvider— either narrow the registry or register factories (a per-session provider instance is required today sinceClaudeProvideris stateful per session), which likely means the registry should hold(init) => SessionProviderfactories rather than instances