Files
odidere/internal/llm/client_test.go
dwrz f6fb21d40c Replace go-openai with native client
Drop the github.com/sashabaranov/go-openai dependency in favor of an
internal HTTP client.

The LLM package is now split into:
- llm.go: type definitions (Message, ChatRequest, ChatResponse, etc.)
- client.go: client construction and configuration
- client_completions.go: Completions and CompletionsStream methods
- client_models.go: ListModels
- client_tools.go: tool call execution

CompletionsStream uses typed SSE events (delta, done, message) so the
frontend can render progressive streaming output.

Move tool.go and tool_test.go from internal/tool/ into internal/llm/
to co-locate the registry with the client that consumes it.

Update job.go and service.go to use the new llm.Message types and
Completions/CompletionsStream methods. Remove the Voice field from
chat request/response (voice is now tracked via message metadata).

Frontend: handle delta/done/message SSE events, render a streaming
placeholder that receives progressive text deltas, and finalize with
full message binding (reasoning, tool calls, actions).
2026-06-26 14:22:05 +00:00

133 lines
2.3 KiB
Go

package llm
import (
"testing"
)
func TestConfigValidate(t *testing.T) {
tests := []struct {
name string
cfg Config
wantErr bool
}{
{
name: "empty config",
cfg: Config{},
wantErr: true,
},
{
name: "missing URL",
cfg: Config{},
wantErr: true,
},
{
name: "invalid timeout",
cfg: Config{
URL: "http://localhost:8080",
Timeout: "not-a-duration",
},
wantErr: true,
},
{
name: "valid minimal config",
cfg: Config{
URL: "http://localhost:8080",
},
wantErr: false,
},
{
name: "valid config with timeout",
cfg: Config{
URL: "http://localhost:8080",
Timeout: "15m",
},
wantErr: false,
},
{
name: "valid config with complex timeout",
cfg: Config{
URL: "http://localhost:8080",
Timeout: "1h30m45s",
},
wantErr: false,
},
{
name: "valid full config",
cfg: Config{
Key: "sk-test-key",
SystemMessage: "You are a helpful assistant.",
Timeout: "30m",
URL: "http://localhost:8080",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
err := tt.cfg.Validate()
if (err != nil) != tt.wantErr {
t.Errorf(
"Validate() error = %v, wantErr %v",
err, tt.wantErr,
)
}
})
}
}
func TestNewClient(t *testing.T) {
tests := []struct {
name string
cfg Config
wantErr bool
}{
{
name: "invalid config",
cfg: Config{},
wantErr: true,
},
{
name: "valid config without timeout",
cfg: Config{
URL: "http://localhost:8080",
},
wantErr: false,
},
{
name: "valid config with timeout",
cfg: Config{
URL: "http://localhost:8080",
Timeout: "10m",
},
wantErr: false,
},
{
name: "valid config with all fields",
cfg: Config{
Key: "test-key",
SystemMessage: "Test message",
Timeout: "5m",
URL: "http://localhost:8080",
},
wantErr: false,
},
}
for _, tt := range tests {
t.Run(tt.name, func(t *testing.T) {
client, err := NewClient(tt.cfg, nil, nil)
if (err != nil) != tt.wantErr {
t.Errorf(
"NewClient() error = %v, wantErr %v",
err, tt.wantErr,
)
return
}
if !tt.wantErr && client == nil {
t.Error("NewClient() returned nil client")
}
})
}
}