package majordomo import ( "io" "net/http" "strings" ) // Shared fixtures for the built-ins that are "the openai client pointed // somewhere else" (kimi, qwen, ...). They live here rather than in any one // provider's test file so a new OpenAI-compat built-in has nothing to // copy — the same reason openaiCompatScheme exists on the production side. // chatCompletionOK is a minimal valid Chat Completions body, so Generate // returns a non-empty response (an empty one would trigger failover, not a // clean pass). const chatCompletionOK = `{"id":"c1","object":"chat.completion","choices":[` + `{"index":0,"message":{"role":"assistant","content":"ok"},"finish_reason":"stop"}]}` // captureRT records the last request (and the bytes of its body) and returns a // canned response without touching the network, so these tests stay hermetic // while still exercising the real openai client the built-ins reuse: base URL, // auth header, and the JSON actually put on the wire. type captureRT struct { req *http.Request reqBody []byte body string } func (c *captureRT) RoundTrip(r *http.Request) (*http.Response, error) { c.req = r // Drain and close the request body: a RoundTripper owns it, and those // bytes are what wire-shape assertions read. c.reqBody = nil if r.Body != nil { c.reqBody, _ = io.ReadAll(r.Body) _ = r.Body.Close() } return &http.Response{ StatusCode: http.StatusOK, Body: io.NopCloser(strings.NewReader(c.body)), Header: make(http.Header), Request: r, }, nil } // singleKeyEnv builds a WithEnvLookup function that knows exactly one variable // and returns "" for everything else. The empty default has teeth: a built-in // that reached for any other variable name gets nothing, so the request 401s // and the test fails rather than quietly authenticating off the wrong key. func singleKeyEnv(key, value string) func(string) string { return func(k string) string { if k == key { return value } return "" } }