example_test.go

 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}