tool format hardening

This commit is contained in:
Luxferre
2026-08-09 15:19:36 +03:00
parent 88dd9dfef5
commit accd1fc75c
4 changed files with 92 additions and 21 deletions
+33
View File
@@ -157,7 +157,24 @@ type streamDelta struct {
} `json:"choices"`
}
func sanitizeMessages(msgs []Message) {
for i := range msgs {
if msgs[i].Role == "assistant" && len(msgs[i].ToolCalls) > 0 {
for j := range msgs[i].ToolCalls {
tc := &msgs[i].ToolCalls[j]
astr := tc.Function.Arguments
var a map[string]any
if err := json.Unmarshal([]byte(astr), &a); err != nil || a == nil {
fixed, _ := json.Marshal(map[string]string{"invalid_raw": astr})
tc.Function.Arguments = string(fixed)
}
}
}
}
}
func llm(cfg *Cfg, msgs []Message, tools []map[string]any) (Message, error) {
sanitizeMessages(msgs)
p := map[string]any{"model": cfg.Model, "temperature": cfg.Temperature, "messages": msgs, "stream": cfg.Stream}
if tools != nil { p["tools"] = tools }
body, _ := json.Marshal(p)
@@ -176,14 +193,21 @@ func llm(cfg *Cfg, msgs []Message, tools []map[string]any) (Message, error) {
req.Header.Set("User-Agent", "Mozilla/5.0 (compatible; Bantam/1.0)")
if cfg.APIKey != "" && cfg.APIKey != "-" { req.Header.Set("Authorization", "Bearer "+cfg.APIKey) }
resp, err = client.Do(req)
var is4xxClientErr bool
if err == nil && resp.StatusCode >= 400 {
b, _ := io.ReadAll(io.LimitReader(resp.Body, 4096))
resp.Body.Close()
err = fmt.Errorf("HTTP %d: %s", resp.StatusCode, strings.TrimSpace(string(b)))
if resp.StatusCode < 500 && resp.StatusCode != 408 && resp.StatusCode != 429 {
is4xxClientErr = true
}
resp = nil
}
if err == nil { break }
if COL { fmt.Print("\r\033[K") }
if is4xxClientErr {
return Message{}, err
}
if i < len(fib) {
fmt.Println(c(fmt.Sprintf("[network error: %v, retrying in %ds...]", err, fib[i]), 31))
time.Sleep(time.Duration(fib[i]) * time.Second)
@@ -301,6 +325,15 @@ func AL(cfg *Cfg, msgs []Message, sp string, depth int) ([]Message, error) {
for i := 0; i < cfg.MaxALIterations && !done; i++ {
m, err := llm(cfg, msgs, TOOLS)
if err != nil { return msgs, err }
for j := range m.ToolCalls {
tc := &m.ToolCalls[j]
astr := tc.Function.Arguments
var a map[string]any
if err := json.Unmarshal([]byte(astr), &a); err != nil || a == nil {
fixed, _ := json.Marshal(map[string]string{"invalid_raw": astr})
tc.Function.Arguments = string(fixed)
}
}
msgs = append(msgs, m)
if !cfg.Stream {
if m.ReasoningContent != "" {