nub/internal/agent/ask_test.go
Tom a97013d876 initial commit
- v 0.1.0 siehe CHANGELOG.md
2026-07-25 11:08:01 +02:00

77 lines
2.3 KiB
Go

package agent
import (
"context"
"encoding/json"
"testing"
"nub/internal/llm"
"nub/internal/tool"
)
// askRecordingTool prüft, dass env.Ask beim Tool ankommt und tatsächlich
// l.AskUser ist, nicht irgendein Default.
type askRecordingTool struct{}
func (askRecordingTool) Name() string { return "echo" }
func (askRecordingTool) Description() string { return "echoes input" }
func (askRecordingTool) Schema() json.RawMessage { return json.RawMessage(`{"type":"object"}`) }
func (askRecordingTool) Run(ctx context.Context, input json.RawMessage, env tool.Env) (tool.Result, error) {
if env.Ask == nil {
return tool.Result{ForModel: "no ask hook", IsError: true}, nil
}
answer, err := env.Ask(ctx, "which format?", []string{"json", "yaml"})
if err != nil {
return tool.Result{ForModel: err.Error(), IsError: true}, nil
}
return tool.Result{ForModel: "got: " + answer}, nil
}
func TestRunTools_EnvAskIsWiredToLoopAskUser(t *testing.T) {
provider := &fakeProvider{batches: [][]llm.Event{
toolCallEvents("call_1", "echo", `{}`),
textEvents("done"),
}}
loop, reg := newTestLoop(provider)
reg.Register(askRecordingTool{})
var gotQuestion string
loop.AskUser = func(ctx context.Context, question string, options []string) (string, error) {
gotQuestion = question
return "json please", nil
}
events := runOneRound(t, loop)
out := findToolCallOutput(events)
if out == nil {
t.Fatal("expected a ToolCallOutput event")
}
if out.Result.IsError {
t.Fatalf("unexpected error: %s", out.Result.ForModel)
}
if out.Result.ForModel != "got: json please" {
t.Errorf("ForModel = %q", out.Result.ForModel)
}
if gotQuestion != "which format?" {
t.Errorf("question passed through = %q", gotQuestion)
}
}
func TestRunTools_EnvAskNilWithoutLoopAskUser(t *testing.T) {
provider := &fakeProvider{batches: [][]llm.Event{
toolCallEvents("call_1", "echo", `{}`),
textEvents("done"),
}}
loop, reg := newTestLoop(provider)
reg.Register(askRecordingTool{})
// loop.AskUser bleibt nil (Print-Modus-Fall).
events := runOneRound(t, loop)
out := findToolCallOutput(events)
if out == nil {
t.Fatal("expected a ToolCallOutput event")
}
if !out.Result.IsError || out.Result.ForModel != "no ask hook" {
t.Errorf("expected the tool to observe env.Ask == nil, got: %+v", out.Result)
}
}