tools.go

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