model_router_test.go RawHistoryFolder
1package provider
2
3import (
4 "context"
5 "testing"
6)
7
8type routeCaptureClient struct {
9 name string
10 models []string
11}
12
13func (c *routeCaptureClient) Name() string { return c.name }
14func (c *routeCaptureClient) Stream(_ context.Context, req Request) (<-chan Event, error) {
15 c.models = append(c.models, req.Model)
16 out := make(chan Event)
17 close(out)
18 return out, nil
19}
20
21func TestModelRouterDispatchesByModelAPI(t *testing.T) {
22 completions := &routeCaptureClient{name: "xai"}
23 responses := &routeCaptureClient{name: "xai"}
24 router := NewModelRouter("xai", completions, map[string]Client{
25 APIResponses: responses,
26 })
27
28 for _, model := range []string{"grok-4.5", "grok-build-0.1"} {
29 stream, err := router.Stream(context.Background(), Request{Model: model})
30 if err != nil {
31 t.Fatal(err)
32 }
33 for range stream {
34 }
35 }
36
37 if len(responses.models) != 1 || responses.models[0] != "grok-4.5" {
38 t.Fatalf("Responses models = %v", responses.models)
39 }
40 if len(completions.models) != 1 || completions.models[0] != "grok-build-0.1" {
41 t.Fatalf("Completions models = %v", completions.models)
42 }
43}
44
45func TestModelRouterRejectsMissingAPIClient(t *testing.T) {
46 router := NewModelRouter("xai", &routeCaptureClient{name: "xai"}, nil)
47 if _, err := router.Stream(context.Background(), Request{Model: "grok-4.5"}); err == nil {
48 t.Fatal("expected missing API client error")
49 }
50}
51
52func TestOpenCodeGoRoutesLunaToResponses(t *testing.T) {
53 router := NewOpenCodeGo("token", "https://example.com/go/v1").(*modelRouter)
54 if got := router.fallback.(*openaiClient).baseURL; got != "https://example.com/go/v1" {
55 t.Fatalf("Completions base URL = %q", got)
56 }
57 responses := router.byAPI[APIResponses].(*renamedClient).inner.(*codexClient)
58 if got := responses.baseURL; got != "https://example.com/go/v1/responses" {
59 t.Fatalf("Responses base URL = %q", got)
60 }
61
62 completionsCapture := &routeCaptureClient{name: "opencode-go"}
63 responsesCapture := &routeCaptureClient{name: "opencode-go"}
64 router.fallback = completionsCapture
65 router.byAPI[APIResponses] = responsesCapture
66 for _, model := range []string{"gpt-5.6-luna", "kimi-k3"} {
67 stream, err := router.Stream(context.Background(), Request{Model: model})
68 if err != nil {
69 t.Fatal(err)
70 }
71 for range stream {
72 }
73 }
74
75 if len(responsesCapture.models) != 1 || responsesCapture.models[0] != "gpt-5.6-luna" {
76 t.Fatalf("Responses models = %v", responsesCapture.models)
77 }
78 if len(completionsCapture.models) != 1 || completionsCapture.models[0] != "kimi-k3" {
79 t.Fatalf("Completions models = %v", completionsCapture.models)
80 }
81}