Initial commit on Forgejo
Some checks failed
CI and releases / Test and vet (push) Failing after 1s
CI and releases / Build release binaries (push) Has been skipped
CI and releases / Publish GitHub release (push) Has been skipped

Fresh repository history for elektrine/tarakan-client hosted at
https://git.elektrine.com/elektrine/tarakan-client.
This commit is contained in:
Maxfield Luke 2026-07-29 04:56:36 -04:00
commit 58b29a7f84
70 changed files with 12994 additions and 0 deletions

221
internal/agent/http_test.go Normal file
View file

@ -0,0 +1,221 @@
package agent
import (
"context"
"encoding/json"
"io"
"net/http"
"net/http/httptest"
"os"
"path/filepath"
"strings"
"testing"
)
func envFrom(pairs map[string]string) getenv {
return func(key string) string { return pairs[key] }
}
func TestDetectHTTPProvidersFromEnv(t *testing.T) {
// Neither configured, and no ollama binary: nothing detected.
original := lookPath
lookPath = func(string) (string, error) { return "", os.ErrNotExist }
defer func() { lookPath = original }()
if got := detectHTTPProviders(envFrom(nil)); len(got) != 0 {
t.Fatalf("expected no HTTP providers, got %#v", got)
}
providers := detectHTTPProviders(envFrom(map[string]string{
"OLLAMA_MODEL": "qwen2.5-coder",
"OLLAMA_HOST": "http://127.0.0.1:11434",
"OPENROUTER_API_KEY": "sk-or-test",
"OPENROUTER_MODEL": "anthropic/claude-3.5-sonnet",
"MOONSHOT_API_KEY": "sk-ms-test",
"MOONSHOT_MODEL": "kimi-k2.5",
}))
if len(providers) != 3 {
t.Fatalf("expected ollama + openrouter + kimi-http, got %#v", providers)
}
ollama := providers[0]
if ollama.Name != "ollama" || ollama.Kind != KindHTTP {
t.Fatalf("unexpected ollama provider: %#v", ollama)
}
if ollama.BaseURL != "http://127.0.0.1:11434/v1" {
t.Fatalf("ollama base URL = %q", ollama.BaseURL)
}
if ollama.Model != "qwen2.5-coder" || ollama.APIKeyEnv != "" {
t.Fatalf("ollama config = %#v", ollama)
}
openrouter := providers[1]
if openrouter.Name != "openrouter" || openrouter.APIKeyEnv != "OPENROUTER_API_KEY" {
t.Fatalf("unexpected openrouter provider: %#v", openrouter)
}
if openrouter.BaseURL != openRouterBaseURL || openrouter.Model != "anthropic/claude-3.5-sonnet" {
t.Fatalf("openrouter config = %#v", openrouter)
}
kimiHTTP := providers[2]
if kimiHTTP.Name != "kimi-http" || kimiHTTP.APIKeyEnv != "MOONSHOT_API_KEY" {
t.Fatalf("unexpected kimi-http provider: %#v", kimiHTTP)
}
if kimiHTTP.BaseURL != moonshotBaseURL || kimiHTTP.Model != "kimi-k2.5" {
t.Fatalf("kimi-http config = %#v", kimiHTTP)
}
}
func TestDetectOllamaDefaultsWhenBinaryPresent(t *testing.T) {
original := lookPath
lookPath = func(string) (string, error) { return "/usr/bin/ollama", nil }
defer func() { lookPath = original }()
providers := detectHTTPProviders(envFrom(nil))
if len(providers) != 1 || providers[0].Name != "ollama" {
t.Fatalf("expected default ollama, got %#v", providers)
}
if providers[0].BaseURL != defaultOllamaHost+"/v1" || providers[0].Model != defaultOllamaModel {
t.Fatalf("ollama defaults = %#v", providers[0])
}
}
func TestRunHTTPOllamaNoAuth(t *testing.T) {
var captured chatRequest
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if r.URL.Path != "/v1/chat/completions" {
t.Errorf("unexpected path %q", r.URL.Path)
}
if auth := r.Header.Get("Authorization"); auth != "" {
t.Errorf("ollama must not send auth, got %q", auth)
}
body, _ := io.ReadAll(r.Body)
_ = json.Unmarshal(body, &captured)
w.Header().Set("Content-Type", "application/json")
io.WriteString(w, `{"choices":[{"message":{"role":"assistant","content":" Found a SQL injection. "}}]}`)
}))
defer server.Close()
dir := writeRepo(t, map[string]string{"main.go": "package main // exec(userInput)"})
provider := Provider{Name: "ollama", Kind: KindHTTP, Description: "Ollama", BaseURL: server.URL + "/v1", Model: "llama3.1"}
out, err := runHTTP(context.Background(), provider, Request{Prompt: "review auth", Directory: dir})
if err != nil {
t.Fatal(err)
}
if out != "Found a SQL injection." {
t.Fatalf("output = %q", out)
}
if captured.Model != "llama3.1" || len(captured.Messages) != 2 {
t.Fatalf("request = %#v", captured)
}
if captured.Messages[0].Role != "system" || !strings.Contains(captured.Messages[0].Content, "read-only") {
t.Fatalf("system message = %#v", captured.Messages[0])
}
if !strings.Contains(captured.Messages[1].Content, "main.go") ||
!strings.Contains(captured.Messages[1].Content, "review auth") {
t.Fatalf("user message missing repo context or prompt: %q", captured.Messages[1].Content)
}
}
func TestRunHTTPOpenRouterRequiresKey(t *testing.T) {
dir := writeRepo(t, map[string]string{"a.py": "print(1)"})
provider := Provider{Name: "openrouter", Kind: KindHTTP, Description: "OpenRouter", BaseURL: "https://openrouter.ai/api/v1", Model: "x", APIKeyEnv: "OPENROUTER_API_KEY"}
os.Unsetenv("OPENROUTER_API_KEY")
if _, err := runHTTP(context.Background(), provider, Request{Prompt: "p", Directory: dir}); err == nil {
t.Fatal("expected error when API key is unset")
}
}
func TestRunHTTPOpenRouterSendsBearer(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
if got := r.Header.Get("Authorization"); got != "Bearer sk-or-secret" {
t.Errorf("authorization = %q", got)
}
io.WriteString(w, `{"choices":[{"message":{"content":"ok"}}]}`)
}))
defer server.Close()
dir := writeRepo(t, map[string]string{"a.py": "print(1)"})
t.Setenv("OPENROUTER_API_KEY", "sk-or-secret")
provider := Provider{Name: "openrouter", Kind: KindHTTP, Description: "OpenRouter", BaseURL: server.URL, Model: "x", APIKeyEnv: "OPENROUTER_API_KEY"}
if _, err := runHTTP(context.Background(), provider, Request{Prompt: "p", Directory: dir}); err != nil {
t.Fatal(err)
}
}
func TestRunHTTPSurfacesAPIError(t *testing.T) {
server := httptest.NewServer(http.HandlerFunc(func(w http.ResponseWriter, r *http.Request) {
w.WriteHeader(http.StatusBadRequest)
io.WriteString(w, `{"error":{"message":"model not found"}}`)
}))
defer server.Close()
dir := writeRepo(t, map[string]string{"a.py": "print(1)"})
provider := Provider{Name: "ollama", Kind: KindHTTP, Description: "Ollama", BaseURL: server.URL, Model: "missing"}
_, err := runHTTP(context.Background(), provider, Request{Prompt: "p", Directory: dir})
if err == nil || !strings.Contains(err.Error(), "model not found") {
t.Fatalf("expected API error surfaced, got %v", err)
}
}
func TestGatherRepositoryContextBoundsAndFilters(t *testing.T) {
dir := writeRepo(t, map[string]string{
"keep.go": "package main",
"nested/util.js": "export const x = 1",
"node_modules/dep/i.js": "should be skipped",
"bin.dat": "text\x00binary",
filepath.Join("big.txt"): strings.Repeat("A", maxFileBytes+1),
})
bundle, err := gatherRepositoryContext(dir)
if err != nil {
t.Fatal(err)
}
for _, want := range []string{"=== keep.go ===", "=== nested/util.js ==="} {
if !strings.Contains(bundle, want) {
t.Errorf("bundle missing %q", want)
}
}
for _, unwanted := range []string{"node_modules", "bin.dat", "big.txt"} {
if strings.Contains(bundle, unwanted) {
t.Errorf("bundle should have skipped %q", unwanted)
}
}
}
func TestModelIdentifierAndWithModel(t *testing.T) {
cli := Provider{Name: "claude", Kind: KindCLI}
if cli.ModelIdentifier() != "claude" {
t.Fatalf("cli identifier = %q", cli.ModelIdentifier())
}
if got := cli.WithModel("x"); got.Model != "" {
t.Fatalf("WithModel must not touch CLI providers: %#v", got)
}
http := Provider{Name: "ollama", Kind: KindHTTP, Model: "llama3.1"}
if http.ModelIdentifier() != "llama3.1" {
t.Fatalf("http identifier = %q", http.ModelIdentifier())
}
if got := http.WithModel("qwen"); got.Model != "qwen" {
t.Fatalf("WithModel = %#v", got)
}
}
func writeRepo(t *testing.T, files map[string]string) string {
t.Helper()
root := t.TempDir()
for name, content := range files {
full := filepath.Join(root, name)
if err := os.MkdirAll(filepath.Dir(full), 0o755); err != nil {
t.Fatal(err)
}
if err := os.WriteFile(full, []byte(content), 0o644); err != nil {
t.Fatal(err)
}
}
return root
}