Merge pull request #2666 from afjcjsbx/fix/mcp-nil-arguments
fix(mcp): send empty object instead of null for tool
This commit is contained in:
commit
788f76f422
2 changed files with 51 additions and 1 deletions
|
|
@ -868,7 +868,7 @@ func cloneLLMResponse(resp *providers.LLMResponse) *providers.LLMResponse {
|
||||||
|
|
||||||
func cloneStringAnyMap(src map[string]any) map[string]any {
|
func cloneStringAnyMap(src map[string]any) map[string]any {
|
||||||
if len(src) == 0 {
|
if len(src) == 0 {
|
||||||
return nil
|
return map[string]any{}
|
||||||
}
|
}
|
||||||
|
|
||||||
cloned := make(map[string]any, len(src))
|
cloned := make(map[string]any, len(src))
|
||||||
|
|
|
||||||
|
|
@ -1431,6 +1431,56 @@ func TestAgentLoop_HookRespond_SteeringSkipsRemaining(t *testing.T) {
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestCloneStringAnyMap_EmptyMapReturnsNonNil(t *testing.T) {
|
||||||
|
tests := []struct {
|
||||||
|
name string
|
||||||
|
input map[string]any
|
||||||
|
wantNil bool
|
||||||
|
wantLen int
|
||||||
|
}{
|
||||||
|
{
|
||||||
|
name: "nil input returns empty map",
|
||||||
|
input: nil,
|
||||||
|
wantNil: false,
|
||||||
|
wantLen: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "empty map returns empty map",
|
||||||
|
input: map[string]any{},
|
||||||
|
wantNil: false,
|
||||||
|
wantLen: 0,
|
||||||
|
},
|
||||||
|
{
|
||||||
|
name: "populated map is cloned",
|
||||||
|
input: map[string]any{"key": "value"},
|
||||||
|
wantNil: false,
|
||||||
|
wantLen: 1,
|
||||||
|
},
|
||||||
|
}
|
||||||
|
|
||||||
|
for _, tt := range tests {
|
||||||
|
t.Run(tt.name, func(t *testing.T) {
|
||||||
|
result := cloneStringAnyMap(tt.input)
|
||||||
|
if result == nil {
|
||||||
|
t.Fatal("cloneStringAnyMap returned nil — MCP tool calls " +
|
||||||
|
"with no arguments would send null instead of {}")
|
||||||
|
}
|
||||||
|
if len(result) != tt.wantLen {
|
||||||
|
t.Fatalf("expected len %d, got %d", tt.wantLen, len(result))
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
|
t.Run("clone does not share underlying map", func(t *testing.T) {
|
||||||
|
src := map[string]any{"a": 1}
|
||||||
|
cloned := cloneStringAnyMap(src)
|
||||||
|
cloned["b"] = 2
|
||||||
|
if _, ok := src["b"]; ok {
|
||||||
|
t.Fatal("modifying clone should not affect source")
|
||||||
|
}
|
||||||
|
})
|
||||||
|
}
|
||||||
|
|
||||||
func filterEvents(events []Event, kind EventKind) []Event {
|
func filterEvents(events []Event, kind EventKind) []Event {
|
||||||
var result []Event
|
var result []Event
|
||||||
for _, evt := range events {
|
for _, evt := range events {
|
||||||
|
|
|
||||||
Loading…
Add table
Reference in a new issue