@@ -5,6 +5,7 @@ import (
6 "encoding/json"
6 "encoding/json"
10 "path/filepath"
11 "path/filepath"
@@ -18,8 +19,25 @@ import (
19const CrushLogsToolName = "crush_logs"
20const CrushLogsToolName = "crush_logs"
21−//go:embed crush_logs.md
22+//go:embed crush_logs.md.tpl
23+var crushLogsDescriptionTmpl []byte
25+var crushLogsDescriptionTpl = template.Must(
26+ template.New("crushLogsDescription").
27+ Parse(string(crushLogsDescriptionTmpl)),
30+type crushLogsDescriptionData struct {
22−var crushLogsDescription string
35+func crushLogsDescription() string {
36+ return renderTemplate(crushLogsDescriptionTpl, crushLogsDescriptionData{
37+ DefaultLines: defaultLogLines,
38+ MaxLines: maxLogLines,
24// Max line size to prevent memory issues with very long log lines (1 MB).
42// Max line size to prevent memory issues with very long log lines (1 MB).
25const maxLogLineSize = 1024 * 1024
43const maxLogLineSize = 1024 * 1024
@@ -58,7 +76,7 @@ type CrushLogsParams struct {
58func NewCrushLogsTool(logFile string) fantasy.AgentTool {
76func NewCrushLogsTool(logFile string) fantasy.AgentTool {
59 return fantasy.NewAgentTool(
77 return fantasy.NewAgentTool(
60 CrushLogsToolName,
78 CrushLogsToolName,
61− crushLogsDescription,
79+ crushLogsDescription(),
62 func(ctx context.Context, params CrushLogsParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
80 func(ctx context.Context, params CrushLogsParams, call fantasy.ToolCall) (fantasy.ToolResponse, error) {
63 result := runCrushLogs(logFile, params)
81 result := runCrushLogs(logFile, params)
64 return fantasy.NewTextResponse(result), nil
82 return fantasy.NewTextResponse(result), nil