85 lines
2.2 KiB
Go
85 lines
2.2 KiB
Go
package execute
|
|
|
|
import (
|
|
"encoding/json"
|
|
"strings"
|
|
)
|
|
|
|
// defaultColdTools are tools whose results are consumed immediately and don't
|
|
// need to persist verbatim in the message history.
|
|
var defaultColdTools = map[string]string{
|
|
"file_read": "cold",
|
|
"file_grep": "cold",
|
|
"file_glob": "cold",
|
|
"memory_recall": "cold",
|
|
"web_fetch": "cold",
|
|
"web_search": "cold",
|
|
"lsp_definition": "cold",
|
|
"lsp_references": "cold",
|
|
"lsp_hover": "cold",
|
|
"lsp_symbols": "cold",
|
|
"lsp_completion": "cold",
|
|
"lsp_diagnostics": "cold",
|
|
"reasoning_think": "cold",
|
|
}
|
|
|
|
// ResultTier implements tools.TierClassifier. Checks the built-in table first,
|
|
// then falls back to the script's "ollie:tier" annotation.
|
|
func (e *Server) ResultTier(name string) string {
|
|
if tier, ok := defaultColdTools[name]; ok {
|
|
return tier
|
|
}
|
|
code, err := ReadTool(name)
|
|
if err != nil {
|
|
return "hot"
|
|
}
|
|
return detectTier(code)
|
|
}
|
|
|
|
// ResultTierArgs classifies the tier using both the outer tool name and its
|
|
// arguments. For shell, it returns warm. For promoted tools, it
|
|
// delegates to ResultTier.
|
|
func (e *Server) ResultTierArgs(name string, args json.RawMessage) string {
|
|
switch name {
|
|
case "shell":
|
|
return "warm"
|
|
default:
|
|
return e.ResultTier(name)
|
|
}
|
|
}
|
|
|
|
// colderTier returns the colder of two tiers. cold < warm < hot.
|
|
func colderTier(a, b string) string {
|
|
order := map[string]int{"cold": 0, "warm": 1, "hot": 2}
|
|
if order[b] < order[a] {
|
|
return b
|
|
}
|
|
return a
|
|
}
|
|
|
|
// detectTier scans the first 10 lines of a tool script for an
|
|
// "ollie:tier" annotation. Matches "ollie:tier hot", "ollie:tier warm",
|
|
// or "ollie:tier cold" anywhere in the line.
|
|
func detectTier(code string) string {
|
|
lines := strings.SplitN(code, "\n", 11)
|
|
if len(lines) > 10 {
|
|
lines = lines[:10]
|
|
}
|
|
for _, line := range lines {
|
|
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 "hot"
|
|
}
|