-
Notifications
You must be signed in to change notification settings - Fork 2.4k
Expand file tree
/
Copy pathflow_test.go
More file actions
131 lines (111 loc) · 3.04 KB
/
Copy pathflow_test.go
File metadata and controls
131 lines (111 loc) · 3.04 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
package flow
import (
"context"
"testing"
"go-micro.dev/v6/ai"
"go-micro.dev/v6/registry"
)
func TestNew(t *testing.T) {
f := New("test-flow",
Trigger("events.test"),
Prompt("Handle this: {{.Data}}"),
Provider("anthropic"),
APIKey("test-key"),
HistoryLimit(10),
)
if f.Name() != "test-flow" {
t.Errorf("name = %q, want test-flow", f.Name())
}
if f.opts.TriggerTopic != "events.test" {
t.Errorf("trigger = %q", f.opts.TriggerTopic)
}
if f.opts.Provider != "anthropic" {
t.Errorf("provider = %q", f.opts.Provider)
}
if f.opts.HistoryLimit != 10 {
t.Errorf("history limit = %d", f.opts.HistoryLimit)
}
if f.tmpl == nil {
t.Fatal("template not parsed")
}
}
func TestPromptTemplate(t *testing.T) {
f := New("tmpl-test",
Prompt("User created: {{.Data}}. Send welcome email."),
)
// Test that the template renders
if f.tmpl == nil {
t.Fatal("template not parsed")
}
}
func TestResultsEmpty(t *testing.T) {
f := New("empty")
results := f.Results()
if len(results) != 0 {
t.Errorf("expected 0 results, got %d", len(results))
}
}
func TestOnResultCallback(t *testing.T) {
var called bool
f := New("callback",
OnResult(func(r Result) {
called = true
if r.FlowName != "callback" {
t.Errorf("flow name = %q", r.FlowName)
}
}),
)
f.record(Result{FlowName: "callback"})
if !called {
t.Error("OnResult not called")
}
if len(f.Results()) != 1 {
t.Errorf("results = %d, want 1", len(f.Results()))
}
}
func TestDefaultOptions(t *testing.T) {
f := New("defaults")
if f.opts.Provider != "openai" {
t.Errorf("default provider = %q, want openai", f.opts.Provider)
}
if f.opts.HistoryLimit != 20 {
t.Errorf("default history limit = %d, want 20", f.opts.HistoryLimit)
}
if f.opts.SystemPrompt == "" {
t.Error("default system prompt is empty")
}
}
func TestSingleStepFlowRunInfoIdentifiesFlow(t *testing.T) {
model := &runInfoModel{}
f := New("single-observed")
f.model = model
f.toolSet = ai.NewTools(registry.NewMemoryRegistry())
if err := f.Execute(context.Background(), "observe me"); err != nil {
t.Fatalf("Execute: %v", err)
}
if model.got.RunID == "" {
t.Fatal("RunInfo.RunID is empty")
}
if model.got.Flow != "single-observed" {
t.Fatalf("RunInfo.Flow = %q, want single-observed", model.got.Flow)
}
if model.got.Agent != "" {
t.Fatalf("RunInfo.Agent = %q, want empty for flow-owned LLM run", model.got.Agent)
}
if model.got.Step != "" {
t.Fatalf("RunInfo.Step = %q, want empty for single-step flow", model.got.Step)
}
}
type runInfoModel struct {
got ai.RunInfo
}
func (m *runInfoModel) Init(...ai.Option) error { return nil }
func (m *runInfoModel) Options() ai.Options { return ai.Options{} }
func (m *runInfoModel) Generate(ctx context.Context, _ *ai.Request, _ ...ai.GenerateOption) (*ai.Response, error) {
m.got, _ = ai.RunInfoFrom(ctx)
return &ai.Response{Reply: "ok"}, nil
}
func (m *runInfoModel) Stream(context.Context, *ai.Request, ...ai.GenerateOption) (ai.Stream, error) {
return nil, ai.ErrStreamingUnsupported
}
func (m *runInfoModel) String() string { return "run-info-model" }