diff --git a/v2/ollama/ollama.go b/v2/ollama/ollama.go index 586e6a0..9c04130 100644 --- a/v2/ollama/ollama.go +++ b/v2/ollama/ollama.go @@ -1,36 +1,22 @@ -// Package ollama implements the go-llm v2 provider interface for Ollama -// (https://ollama.com), a local model runner that exposes an OpenAI Chat -// Completions-compatible endpoint. No API key is required; capability depends -// on whichever model the user has pulled locally, so Rules are intentionally -// empty — we trust the local user. +// Package ollama implements the go-llm v2 provider interface for Ollama, +// targeting Ollama's native /api/chat endpoint. Supports both local Ollama +// instances (no API key) and Ollama Cloud (https://ollama.com, requires an +// API key sent as a Bearer token). package ollama -import ( - "gitea.stevedudenhoeffer.com/steve/go-llm/v2/openaicompat" -) - -// DefaultBaseURL points at a local Ollama instance with default port. Kept -// for the openaicompat-based shim; callers should migrate to -// DefaultLocalBaseURL (no /v1 suffix) which targets the native /api/chat -// endpoint. -const DefaultBaseURL = "http://localhost:11434/v1" - -// shimNew is the legacy openaicompat-based constructor, retained until the -// native provider's Complete/Stream are fully implemented (Task 4 replaces -// the public New() with a native-backed constructor). -func shimNew(apiKey, baseURL string) *openaicompat.Provider { - if baseURL == "" { - baseURL = DefaultBaseURL - } - return openaicompat.New(apiKey, baseURL, openaicompat.Rules{}) -} - -// New creates a new Ollama provider. An empty baseURL uses DefaultBaseURL. -// Ollama ignores the API key; callers may pass "". +// New creates a new Ollama provider over the native /api/chat API. An empty +// apiKey means local-mode (no Authorization header is sent). A non-empty +// apiKey is sent as `Authorization: Bearer ` for Ollama Cloud. // -// Note: this constructor currently still routes through the openaicompat -// shim. Subsequent commits replace the body with a native /api/chat -// implementation backed by the Provider type in native.go. -func New(apiKey, baseURL string) *openaicompat.Provider { - return shimNew(apiKey, baseURL) +// An empty baseURL defaults to DefaultLocalBaseURL when apiKey is empty, or +// DefaultCloudBaseURL when apiKey is set. +func New(apiKey, baseURL string) *Provider { + if baseURL == "" { + if apiKey == "" { + baseURL = DefaultLocalBaseURL + } else { + baseURL = DefaultCloudBaseURL + } + } + return newNative(apiKey, baseURL) } diff --git a/v2/ollama/ollama_test.go b/v2/ollama/ollama_test.go index 5c1e216..cb2c267 100644 --- a/v2/ollama/ollama_test.go +++ b/v2/ollama/ollama_test.go @@ -1,13 +1,35 @@ -package ollama_test +package ollama -import ( - "testing" +import "testing" - "gitea.stevedudenhoeffer.com/steve/go-llm/v2/ollama" -) +func TestNew(t *testing.T) { + t.Run("local mode picks default local URL", func(t *testing.T) { + p := New("", "") + if p == nil { + t.Fatal("New returned nil") + } + if p.baseURL != DefaultLocalBaseURL { + t.Errorf("baseURL: want %q, got %q", DefaultLocalBaseURL, p.baseURL) + } + if p.apiKey != "" { + t.Errorf("apiKey: want empty, got %q", p.apiKey) + } + }) -func TestNew_NoKeyNeeded(t *testing.T) { - if p := ollama.New("", ""); p == nil { - t.Fatal("New returned nil") - } + t.Run("cloud mode (apiKey set) picks cloud URL", func(t *testing.T) { + p := New("test-key", "") + if p.baseURL != DefaultCloudBaseURL { + t.Errorf("baseURL: want %q, got %q", DefaultCloudBaseURL, p.baseURL) + } + if p.apiKey != "test-key" { + t.Errorf("apiKey: want %q, got %q", "test-key", p.apiKey) + } + }) + + t.Run("explicit baseURL is preserved", func(t *testing.T) { + p := New("k", "http://example.test:9999") + if p.baseURL != "http://example.test:9999" { + t.Errorf("baseURL not preserved, got %q", p.baseURL) + } + }) } diff --git a/v2/registry.go b/v2/registry.go index 58ea1f5..4ba4db3 100644 --- a/v2/registry.go +++ b/v2/registry.go @@ -129,7 +129,7 @@ var providerRegistry = []ProviderInfo{ Name: "ollama", DisplayName: "Ollama (local)", EnvKey: "", // no key needed - DefaultURL: ollama.DefaultBaseURL, + DefaultURL: ollama.DefaultLocalBaseURL, Models: []string{ "llama3.2", "llama3.1", "qwen2.5", "mistral", "gemma2", "phi4", },