package majordomo import ( "context" "fmt" "gitea.stevedudenhoeffer.com/steve/majordomo/llm" ) // Built-in provider names. Real client implementations land per-phase // (see progress.md); until a provider's phase ships, its registration is a // stub that resolves (so specs parse and env DSNs load) but errors on use. const ( ProviderOpenAI = "openai" ProviderAnthropic = "anthropic" ProviderGoogle = "google" ProviderOllama = "ollama" ProviderOllamaCloud = "ollama-cloud" ProviderForeman = "foreman" ) // registerBuiltins installs the built-in providers and env-DSN scheme // factories into a fresh registry. func registerBuiltins(r *Registry) { stub := func(kind string) SchemeFactory { return func(name string, dsn DSN) (llm.Provider, error) { return &stubProvider{name: name, kind: kind, baseURL: dsn.BaseURL(), token: dsn.Token}, nil } } for _, kind := range []string{ ProviderOpenAI, ProviderAnthropic, ProviderGoogle, ProviderOllama, ProviderOllamaCloud, ProviderForeman, } { r.providers[kind] = &stubProvider{name: kind, kind: kind} r.schemes[kind] = stub(kind) } // "gemini" is an alternate scheme for the Google provider. r.schemes["gemini"] = stub(ProviderGoogle) } // stubProvider stands in for a provider implementation that lands in a // later phase. It resolves and carries its connection details (so Parse, // chains, and env loading are fully functional) but errors on use. type stubProvider struct { name string kind string baseURL string token string } func (s *stubProvider) Name() string { return s.name } func (s *stubProvider) Model(id string, opts ...llm.ModelOption) (llm.Model, error) { cfg := llm.ApplyModelOptions(opts) return &stubModel{provider: s, id: id, cfg: cfg}, nil } type stubModel struct { provider *stubProvider id string cfg llm.ModelConfig } func (m *stubModel) err() error { return fmt.Errorf("majordomo: provider %q (%s) is not implemented yet", m.provider.name, m.provider.kind) } func (m *stubModel) Generate(context.Context, llm.Request, ...llm.Option) (*llm.Response, error) { return nil, m.err() } func (m *stubModel) Stream(context.Context, llm.Request, ...llm.Option) (llm.Stream, error) { return nil, m.err() } func (m *stubModel) Capabilities() llm.Capabilities { if m.cfg.Capabilities != nil { return *m.cfg.Capabilities } return llm.Capabilities{} }