tools.go

 1package tools
 2
 3import (
 4	"context"
 5	"os"
 6	"strconv"
 7	"strings"
 8	"testing"
 9)
10
11type (
12	sessionIDContextKey string
13	messageIDContextKey string
14	supportsImagesKey   string
15	modelNameKey        string
16)
17
18const (
19	// SessionIDContextKey is the key for the session ID in the context.
20	SessionIDContextKey sessionIDContextKey = "session_id"
21	// MessageIDContextKey is the key for the message ID in the context.
22	MessageIDContextKey messageIDContextKey = "message_id"
23	// SupportsImagesContextKey is the key for the model's image support capability.
24	SupportsImagesContextKey supportsImagesKey = "supports_images"
25	// ModelNameContextKey is the key for the model name in the context.
26	ModelNameContextKey modelNameKey = "model_name"
27)
28
29// getContextValue is a generic helper that retrieves a typed value from context.
30// If the value is not found or has the wrong type, it returns the default value.
31func getContextValue[T any](ctx context.Context, key any, defaultValue T) T {
32	value := ctx.Value(key)
33	if value == nil {
34		return defaultValue
35	}
36	if typedValue, ok := value.(T); ok {
37		return typedValue
38	}
39	return defaultValue
40}
41
42// GetSessionFromContext retrieves the session ID from the context.
43func GetSessionFromContext(ctx context.Context) string {
44	return getContextValue(ctx, SessionIDContextKey, "")
45}
46
47// GetMessageFromContext retrieves the message ID from the context.
48func GetMessageFromContext(ctx context.Context) string {
49	return getContextValue(ctx, MessageIDContextKey, "")
50}
51
52// GetSupportsImagesFromContext retrieves whether the model supports images from the context.
53func GetSupportsImagesFromContext(ctx context.Context) bool {
54	return getContextValue(ctx, SupportsImagesContextKey, false)
55}
56
57// GetModelNameFromContext retrieves the model name from the context.
58func GetModelNameFromContext(ctx context.Context) string {
59	return getContextValue(ctx, ModelNameContextKey, "")
60}
61
62// FirstLineDescription returns just the first non-empty line from the embedded
63// markdown description when CRUSH_SHORT_TOOL_DESCRIPTIONS is set, significantly
64// reducing token usage. Otherwise returns the full description.
65func FirstLineDescription(content []byte) string {
66	if !testing.Testing() {
67		if v, _ := strconv.ParseBool(os.Getenv("CRUSH_SHORT_TOOL_DESCRIPTIONS")); !v {
68			return strings.TrimSpace(string(content))
69		}
70	}
71	for line := range strings.SplitSeq(string(content), "\n") {
72		line = strings.TrimSpace(line)
73		if line != "" {
74			return line
75		}
76	}
77	return ""
78}