mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-17 11:47:28 +08:00
enforce pending-call matching to block orphan and duplicate function call outputs
This commit is contained in:
@@ -106,9 +106,9 @@ func (p *HTTPProvider) callChatCompletions(ctx context.Context, messages []Messa
|
|||||||
|
|
||||||
func (p *HTTPProvider) callResponses(ctx context.Context, messages []Message, tools []ToolDefinition, model string, options map[string]interface{}) ([]byte, int, string, error) {
|
func (p *HTTPProvider) callResponses(ctx context.Context, messages []Message, tools []ToolDefinition, model string, options map[string]interface{}) ([]byte, int, string, error) {
|
||||||
input := make([]map[string]interface{}, 0, len(messages))
|
input := make([]map[string]interface{}, 0, len(messages))
|
||||||
seenCalls := map[string]struct{}{}
|
pendingCalls := map[string]struct{}{}
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
input = append(input, toResponsesInputItemsWithState(msg, seenCalls)...)
|
input = append(input, toResponsesInputItemsWithState(msg, pendingCalls)...)
|
||||||
}
|
}
|
||||||
requestBody := map[string]interface{}{
|
requestBody := map[string]interface{}{
|
||||||
"model": model,
|
"model": model,
|
||||||
@@ -211,7 +211,7 @@ func toResponsesInputItems(msg Message) []map[string]interface{} {
|
|||||||
return toResponsesInputItemsWithState(msg, nil)
|
return toResponsesInputItemsWithState(msg, nil)
|
||||||
}
|
}
|
||||||
|
|
||||||
func toResponsesInputItemsWithState(msg Message, seenCalls map[string]struct{}) []map[string]interface{} {
|
func toResponsesInputItemsWithState(msg Message, pendingCalls map[string]struct{}) []map[string]interface{} {
|
||||||
role := strings.ToLower(strings.TrimSpace(msg.Role))
|
role := strings.ToLower(strings.TrimSpace(msg.Role))
|
||||||
switch role {
|
switch role {
|
||||||
case "system", "developer", "user":
|
case "system", "developer", "user":
|
||||||
@@ -252,8 +252,8 @@ func toResponsesInputItemsWithState(msg Message, seenCalls map[string]struct{})
|
|||||||
argsRaw = string(argsJSON)
|
argsRaw = string(argsJSON)
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
if seenCalls != nil {
|
if pendingCalls != nil {
|
||||||
seenCalls[callID] = struct{}{}
|
pendingCalls[callID] = struct{}{}
|
||||||
}
|
}
|
||||||
items = append(items, map[string]interface{}{
|
items = append(items, map[string]interface{}{
|
||||||
"type": "function_call",
|
"type": "function_call",
|
||||||
@@ -271,11 +271,12 @@ func toResponsesInputItemsWithState(msg Message, seenCalls map[string]struct{})
|
|||||||
if callID == "" {
|
if callID == "" {
|
||||||
return []map[string]interface{}{responsesMessageItem("user", msg.Content, "input_text")}
|
return []map[string]interface{}{responsesMessageItem("user", msg.Content, "input_text")}
|
||||||
}
|
}
|
||||||
if seenCalls != nil {
|
if pendingCalls != nil {
|
||||||
if _, ok := seenCalls[callID]; !ok {
|
if _, ok := pendingCalls[callID]; !ok {
|
||||||
// Avoid invalid orphan tool outputs in /responses payload.
|
// Avoid invalid orphan/duplicate tool outputs in /responses payload.
|
||||||
return []map[string]interface{}{responsesMessageItem("user", msg.Content, "input_text")}
|
return []map[string]interface{}{responsesMessageItem("user", msg.Content, "input_text")}
|
||||||
}
|
}
|
||||||
|
delete(pendingCalls, callID)
|
||||||
}
|
}
|
||||||
return []map[string]interface{}{map[string]interface{}{
|
return []map[string]interface{}{map[string]interface{}{
|
||||||
"type": "function_call_output",
|
"type": "function_call_output",
|
||||||
@@ -696,9 +697,9 @@ func (p *HTTPProvider) BuildSummaryViaResponsesCompact(ctx context.Context, mode
|
|||||||
if strings.TrimSpace(existingSummary) != "" {
|
if strings.TrimSpace(existingSummary) != "" {
|
||||||
input = append(input, responsesMessageItem("system", "Existing summary:\n"+strings.TrimSpace(existingSummary), "input_text"))
|
input = append(input, responsesMessageItem("system", "Existing summary:\n"+strings.TrimSpace(existingSummary), "input_text"))
|
||||||
}
|
}
|
||||||
seenCalls := map[string]struct{}{}
|
pendingCalls := map[string]struct{}{}
|
||||||
for _, msg := range messages {
|
for _, msg := range messages {
|
||||||
input = append(input, toResponsesInputItemsWithState(msg, seenCalls)...)
|
input = append(input, toResponsesInputItemsWithState(msg, pendingCalls)...)
|
||||||
}
|
}
|
||||||
if len(input) == 0 {
|
if len(input) == 0 {
|
||||||
return strings.TrimSpace(existingSummary), nil
|
return strings.TrimSpace(existingSummary), nil
|
||||||
|
|||||||
Reference in New Issue
Block a user