1package loop_test
2
3import (
4 "context"
5 "encoding/json"
6 "fmt"
7 "time"
8
9 "shelley.exe.dev/llm"
10 "shelley.exe.dev/loop"
11)
12
13func ExampleLoop() {
14 // Create a simple tool
15 testTool := &llm.Tool{
16 Name: "greet",
17 Description: "Greets the user with a friendly message",
18 InputSchema: llm.MustSchema(`{"type": "object", "properties": {"name": {"type": "string"}}}`),
19 Run: func(ctx context.Context, input json.RawMessage) llm.ToolOut {
20 var req struct {
21 Name string `json:"name"`
22 }
23 if err := json.Unmarshal(input, &req); err != nil {
24 return llm.ErrorToolOut(err)
25 }
26 return llm.ToolOut{
27 LLMContent: llm.TextContent(fmt.Sprintf("Hello, %s! Nice to meet you.", req.Name)),
28 }
29 },
30 }
31
32 // Message recording function (in real usage, this would save to database)
33 recordMessage := func(ctx context.Context, message llm.Message, usage llm.Usage) error {
34 roleStr := "user"
35 if message.Role == llm.MessageRoleAssistant {
36 roleStr = "assistant"
37 }
38 fmt.Printf("Recorded %s message with %d content items\n", roleStr, len(message.Content))
39 return nil
40 }
41
42 // Create a loop with initial history
43 initialHistory := []llm.Message{
44 {
45 Role: llm.MessageRoleUser,
46 Content: []llm.Content{
47 {Type: llm.ContentTypeText, Text: "Hello, I'm Alice"},
48 },
49 },
50 }
51
52 // Set up a predictable service for this example
53 service := loop.NewPredictableService()
54 myLoop := loop.NewLoop(loop.Config{
55 LLM: service,
56 History: initialHistory,
57 Tools: []*llm.Tool{testTool},
58 RecordMessage: recordMessage,
59 })
60
61 // Queue a user message that triggers a simple response
62 myLoop.QueueUserMessage(llm.Message{
63 Role: llm.MessageRoleUser,
64 Content: []llm.Content{{Type: llm.ContentTypeText, Text: "hello"}},
65 })
66
67 // Run the loop for a short time
68 ctx, cancel := context.WithTimeout(context.Background(), 100*time.Millisecond)
69 defer cancel()
70
71 myLoop.Go(ctx)
72
73 // Check usage
74 usage := myLoop.GetUsage()
75 fmt.Printf("Total usage: %s\n", usage.String())
76
77 // Output:
78 // Recorded assistant message with 1 content items
79 // Total usage: in: 31, out: 3
80}