Copy hyperguild/ingestion/internal/llm into internal/adapters/llm and own it. Tapir owes that repo nothing at the dependency level — no module dep added. Router gives the local-Primary -> BYO-Fallback path needed for ai_routing.feature. Copied tests rewritten from testify to stdlib testing to keep go.mod dependency-free (repo has zero deps; acceptance tests are stdlib too). Co-Authored-By: Claude Opus 4.8 (1M context) <noreply@anthropic.com>
79 lines
2.1 KiB
Go
79 lines
2.1 KiB
Go
package llm
|
|
|
|
import (
|
|
"context"
|
|
"net/http"
|
|
"net/http/httptest"
|
|
"testing"
|
|
"time"
|
|
)
|
|
|
|
func TestRouter_PrimarySucceeds(t *testing.T) {
|
|
primary := mockServer(t, "from-primary")
|
|
defer primary.Close()
|
|
fallback := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
t.Error("fallback must not be called when primary succeeds")
|
|
}))
|
|
defer fallback.Close()
|
|
|
|
r := &Router{
|
|
Primary: New(primary.URL, "", "m", time.Second),
|
|
Fallback: New(fallback.URL, "", "m", time.Second),
|
|
}
|
|
out, err := r.Complete(context.Background(), "sys", "user")
|
|
if err != nil {
|
|
t.Fatalf("Complete: %v", err)
|
|
}
|
|
if out != "from-primary" {
|
|
t.Errorf("got %q, want %q", out, "from-primary")
|
|
}
|
|
}
|
|
|
|
func TestRouter_FallsBackOnPrimaryError(t *testing.T) {
|
|
primary := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, "unavailable", http.StatusServiceUnavailable)
|
|
}))
|
|
defer primary.Close()
|
|
fallback := mockServer(t, "from-fallback")
|
|
defer fallback.Close()
|
|
|
|
r := &Router{
|
|
Primary: New(primary.URL, "", "m", time.Second),
|
|
Fallback: New(fallback.URL, "", "m", time.Second),
|
|
}
|
|
out, err := r.Complete(context.Background(), "sys", "user")
|
|
if err != nil {
|
|
t.Fatalf("Complete: %v", err)
|
|
}
|
|
if out != "from-fallback" {
|
|
t.Errorf("got %q, want %q", out, "from-fallback")
|
|
}
|
|
}
|
|
|
|
func TestRouter_BothFail(t *testing.T) {
|
|
fail := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, "err", http.StatusBadGateway)
|
|
}))
|
|
defer fail.Close()
|
|
|
|
r := &Router{
|
|
Primary: New(fail.URL, "", "m", time.Second),
|
|
Fallback: New(fail.URL, "", "m", time.Second),
|
|
}
|
|
if _, err := r.Complete(context.Background(), "sys", "user"); err == nil {
|
|
t.Fatal("want error when both fail, got nil")
|
|
}
|
|
}
|
|
|
|
func TestRouter_NilFallback(t *testing.T) {
|
|
fail := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
|
|
http.Error(w, "err", http.StatusBadGateway)
|
|
}))
|
|
defer fail.Close()
|
|
|
|
r := &Router{Primary: New(fail.URL, "", "m", time.Second)}
|
|
if _, err := r.Complete(context.Background(), "sys", "user"); err == nil {
|
|
t.Fatal("want error with nil fallback, got nil")
|
|
}
|
|
}
|