1package tools
2
3import (
4 "context"
5 "encoding/json"
6
7 "github.com/charmbracelet/crush/internal/proto"
8)
9
10type ToolInfo struct {
11 Name string
12 Description string
13 Parameters map[string]any
14 Required []string
15}
16
17type (
18 sessionIDContextKey string
19 messageIDContextKey string
20)
21
22const (
23 ToolResponseTypeText = proto.ToolResponseTypeText
24 ToolResponseTypeImage = proto.ToolResponseTypeImage
25
26 SessionIDContextKey sessionIDContextKey = "session_id"
27 MessageIDContextKey messageIDContextKey = "message_id"
28)
29
30type ToolResponse = proto.ToolResponse
31
32func NewTextResponse(content string) ToolResponse {
33 return ToolResponse{
34 Type: ToolResponseTypeText,
35 Content: content,
36 }
37}
38
39func WithResponseMetadata(response ToolResponse, metadata any) ToolResponse {
40 if metadata != nil {
41 metadataBytes, err := json.Marshal(metadata)
42 if err != nil {
43 return response
44 }
45 response.Metadata = string(metadataBytes)
46 }
47 return response
48}
49
50func NewTextErrorResponse(content string) ToolResponse {
51 return ToolResponse{
52 Type: ToolResponseTypeText,
53 Content: content,
54 IsError: true,
55 }
56}
57
58type ToolCall = proto.ToolCall
59
60type BaseTool interface {
61 Info() ToolInfo
62 Name() string
63 Run(ctx context.Context, params ToolCall) (ToolResponse, error)
64}
65
66func GetContextValues(ctx context.Context) (string, string) {
67 sessionID := ctx.Value(SessionIDContextKey)
68 messageID := ctx.Value(MessageIDContextKey)
69 if sessionID == nil {
70 return "", ""
71 }
72 if messageID == nil {
73 return sessionID.(string), ""
74 }
75 return sessionID.(string), messageID.(string)
76}