package toolsrv import ( "encoding/json" "strings" ) type ToolMeta struct { ReadOnly bool `json:"readOnly,omitempty"` RequiresApproval bool `json:"requiresApproval,omitempty"` NetworkAccess bool `json:"networkAccess,omitempty"` PathScope string `json:"pathScope,omitempty"` SandboxLevel string `json:"sandboxLevel,omitempty"` Examples []string `json:"examples,omitempty"` Tags []string `json:"tags,omitempty"` } func ExtractArgsSchema(script string) json.RawMessage { for _, line := range strings.Split(script, "\n") { trimmed := strings.TrimSpace(line) if strings.HasPrefix(trimmed, "# args_json:") { schema := strings.TrimSpace(strings.TrimPrefix(trimmed, "# args_json:")) if schema != "" { return json.RawMessage(schema) } } } return nil } func ExtractTier(script string) string { for _, line := range strings.Split(script, "\n") { idx := strings.Index(line, "ollie:tier") if idx < 0 { continue } rest := strings.TrimSpace(line[idx+len("ollie:tier"):]) switch { case rest == "cold" || strings.HasPrefix(rest, "cold "): return "cold" case rest == "warm" || strings.HasPrefix(rest, "warm "): return "warm" case rest == "hot" || strings.HasPrefix(rest, "hot "): return "hot" } } return "" } func ExtractMetadata(script string) ToolMeta { var meta ToolMeta for _, line := range strings.Split(script, "\n") { trimmed := strings.TrimSpace(line) if strings.Contains(trimmed, "ollie:parallel read") { meta.ReadOnly = true } } return meta } func ParseToolInfo(name, script string) ToolInfo { prompt := ExtractPrompt(script) desc := ExtractShortDescription(prompt) argsSchema := ExtractArgsSchema(script) if argsSchema == nil { argsSchema = json.RawMessage(`{"type":"object","properties":{}}`) } meta := ExtractMetadata(script) tier := ExtractTier(script) if tier == "" { tier = "hot" } return ToolInfo{ Name: name, Description: desc, InputSchema: argsSchema, Prompt: prompt, Tier: tier, ReadOnly: meta.ReadOnly, } }