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}