mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-18 09:37:28 +08:00
fix orphan tool messages in openai compat
This commit is contained in:
@@ -183,6 +183,7 @@ func (p *HTTPProvider) buildOpenAICompatChatRequest(messages []Message, tools []
|
|||||||
|
|
||||||
func openAICompatMessages(messages []Message) []map[string]interface{} {
|
func openAICompatMessages(messages []Message) []map[string]interface{} {
|
||||||
out := make([]map[string]interface{}, 0, len(messages))
|
out := make([]map[string]interface{}, 0, len(messages))
|
||||||
|
pendingCalls := map[string]struct{}{}
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
role := strings.ToLower(strings.TrimSpace(msg.Role))
|
role := strings.ToLower(strings.TrimSpace(msg.Role))
|
||||||
content := openAICompatMessageContent(msg)
|
content := openAICompatMessageContent(msg)
|
||||||
@@ -199,6 +200,9 @@ func openAICompatMessages(messages []Message) []map[string]interface{} {
|
|||||||
if len(msg.ToolCalls) > 0 {
|
if len(msg.ToolCalls) > 0 {
|
||||||
toolCalls := make([]map[string]interface{}, 0, len(msg.ToolCalls))
|
toolCalls := make([]map[string]interface{}, 0, len(msg.ToolCalls))
|
||||||
for _, tc := range msg.ToolCalls {
|
for _, tc := range msg.ToolCalls {
|
||||||
|
if strings.TrimSpace(tc.ID) != "" {
|
||||||
|
pendingCalls[strings.TrimSpace(tc.ID)] = struct{}{}
|
||||||
|
}
|
||||||
args := ""
|
args := ""
|
||||||
if tc.Function != nil {
|
if tc.Function != nil {
|
||||||
args = tc.Function.Arguments
|
args = tc.Function.Arguments
|
||||||
@@ -224,9 +228,17 @@ func openAICompatMessages(messages []Message) []map[string]interface{} {
|
|||||||
}
|
}
|
||||||
out = append(out, item)
|
out = append(out, item)
|
||||||
case "tool":
|
case "tool":
|
||||||
|
callID := strings.TrimSpace(msg.ToolCallID)
|
||||||
|
if callID == "" {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
if _, ok := pendingCalls[callID]; !ok {
|
||||||
|
continue
|
||||||
|
}
|
||||||
|
delete(pendingCalls, callID)
|
||||||
out = append(out, map[string]interface{}{
|
out = append(out, map[string]interface{}{
|
||||||
"role": "tool",
|
"role": "tool",
|
||||||
"tool_call_id": msg.ToolCallID,
|
"tool_call_id": callID,
|
||||||
"content": content,
|
"content": content,
|
||||||
})
|
})
|
||||||
default:
|
default:
|
||||||
|
|||||||
@@ -159,6 +159,37 @@ func TestOpenAICompatMessagesPreserveMultimodalContentParts(t *testing.T) {
|
|||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func TestOpenAICompatMessagesDropsOrphanToolOutputs(t *testing.T) {
|
||||||
|
msgs := openAICompatMessages([]Message{
|
||||||
|
{Role: "user", Content: "hi"},
|
||||||
|
{Role: "tool", ToolCallID: "call-orphan", Content: "orphan output"},
|
||||||
|
{
|
||||||
|
Role: "assistant",
|
||||||
|
ToolCalls: []ToolCall{{
|
||||||
|
ID: "call-1",
|
||||||
|
Name: "read_file",
|
||||||
|
Function: &FunctionCall{
|
||||||
|
Name: "read_file",
|
||||||
|
Arguments: `{"path":"README.md"}`,
|
||||||
|
},
|
||||||
|
}},
|
||||||
|
},
|
||||||
|
{Role: "tool", ToolCallID: "call-1", Content: "file content"},
|
||||||
|
})
|
||||||
|
if len(msgs) != 3 {
|
||||||
|
t.Fatalf("messages = %#v, want 3 items", msgs)
|
||||||
|
}
|
||||||
|
if got := msgs[1]["role"]; got != "assistant" {
|
||||||
|
t.Fatalf("second role = %#v, want assistant", got)
|
||||||
|
}
|
||||||
|
if got := msgs[2]["role"]; got != "tool" {
|
||||||
|
t.Fatalf("third role = %#v, want tool", got)
|
||||||
|
}
|
||||||
|
if got := msgs[2]["tool_call_id"]; got != "call-1" {
|
||||||
|
t.Fatalf("tool_call_id = %#v, want call-1", got)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
func TestBuildOpenAICompatChatRequestAppliesThinkingSuffix(t *testing.T) {
|
func TestBuildOpenAICompatChatRequestAppliesThinkingSuffix(t *testing.T) {
|
||||||
base := NewHTTPProvider("openai", "token", "https://example.com/v1", "gpt-5", false, "api_key", 5*time.Second, nil)
|
base := NewHTTPProvider("openai", "token", "https://example.com/v1", "gpt-5", false, "api_key", 5*time.Second, nil)
|
||||||
body := base.buildOpenAICompatChatRequest([]Message{{Role: "user", Content: "hi"}}, nil, "gpt-5(high)", nil)
|
body := base.buildOpenAICompatChatRequest([]Message{{Role: "user", Content: "hi"}}, nil, "gpt-5(high)", nil)
|
||||||
|
|||||||
Reference in New Issue
Block a user