fix: prioritize quoted functionCall keys in tool sieve

This commit is contained in:
CJACK.
2026-04-02 18:22:30 +08:00
parent 283aa304df
commit 02d64c192e
2 changed files with 17 additions and 9 deletions

View File

@@ -5,18 +5,18 @@ import "strings"
func findQuotedFunctionCallKeyStart(s string) int {
lower := strings.ToLower(s)
quotedIdx := findFunctionCallKeyStart(lower, `"functioncall"`)
baretIdx := findFunctionCallKeyStart(lower, "functioncall")
bareIdx := findFunctionCallKeyStart(lower, "functioncall")
switch {
case quotedIdx < 0:
return baretIdx
case baretIdx < 0:
// Prefer quoted JSON keys when present. Bare-key detection is a fallback
// for loose payloads like {functionCall:{...}}.
//
// This avoids anchoring on earlier prose such as:
// "... {note} functionCall: ... {\"functionCall\":{...}}"
// where choosing the earliest bare match can hide the real tool payload.
if quotedIdx >= 0 {
return quotedIdx
case quotedIdx < baretIdx:
return quotedIdx
default:
return baretIdx
}
return bareIdx
}
func findFunctionCallKeyStart(lower, key string) int {

View File

@@ -143,6 +143,14 @@ func TestFindToolSegmentStartDetectsLooseFunctionCallKey(t *testing.T) {
}
}
func TestFindToolSegmentStartPrefersQuotedFunctionCallOverEarlierBareProse(t *testing.T) {
input := `prefix {note} functionCall: docs hint {"functionCall":{"name":"search_web","args":{"query":"x"}}}`
want := strings.Index(input, `{"functionCall"`)
if got := findToolSegmentStart(input); got != want {
t.Fatalf("expected quoted functionCall JSON start %d, got %d", want, got)
}
}
func TestFindToolSegmentStartIgnoresLooseFunctionCallProse(t *testing.T) {
input := "Please explain why functionCall: is used in documentation examples."
if got := findToolSegmentStart(input); got != -1 {