refactor: move tool call parsing and formatting logic to a dedicated internal/toolcall package

This commit is contained in:
CJACK
2026-04-06 03:19:18 +08:00
parent 2857a171cc
commit 1530246e4f
39 changed files with 261 additions and 159 deletions

View File

@@ -1,6 +1,7 @@
package claude
import (
"ds2api/internal/toolcall"
"fmt"
"time"
@@ -8,9 +9,9 @@ import (
)
func BuildMessageResponse(messageID, model string, normalizedMessages []any, finalThinking, finalText string, toolNames []string) map[string]any {
detected := util.ParseToolCalls(finalText, toolNames)
detected := toolcall.ParseToolCalls(finalText, toolNames)
if len(detected) == 0 && finalText == "" && finalThinking != "" {
detected = util.ParseToolCalls(finalThinking, toolNames)
detected = toolcall.ParseToolCalls(finalThinking, toolNames)
}
content := make([]map[string]any, 0, 4)
if finalThinking != "" {

View File

@@ -1,14 +1,14 @@
package openai
import (
"ds2api/internal/toolcall"
"strings"
"time"
"ds2api/internal/util"
)
func BuildChatCompletion(completionID, model, finalPrompt, finalThinking, finalText string, toolNames []string) map[string]any {
detected := util.ParseStandaloneToolCallsDetailed(finalText, toolNames)
detected := toolcall.ParseStandaloneToolCallsDetailed(finalText, toolNames)
finishReason := "stop"
messageObj := map[string]any{"role": "assistant", "content": finalText}
if strings.TrimSpace(finalThinking) != "" {
@@ -16,7 +16,7 @@ func BuildChatCompletion(completionID, model, finalPrompt, finalThinking, finalT
}
if len(detected.Calls) > 0 {
finishReason = "tool_calls"
messageObj["tool_calls"] = util.FormatOpenAIToolCalls(detected.Calls)
messageObj["tool_calls"] = toolcall.FormatOpenAIToolCalls(detected.Calls)
messageObj["content"] = nil
}

View File

@@ -1,19 +1,19 @@
package openai
import (
"ds2api/internal/toolcall"
"encoding/json"
"strings"
"time"
"github.com/google/uuid"
"ds2api/internal/util"
)
func BuildResponseObject(responseID, model, finalPrompt, finalThinking, finalText string, toolNames []string) map[string]any {
// Strict mode: only standalone, structured tool-call payloads are treated
// as executable tool calls.
detected := util.ParseStandaloneToolCallsDetailed(finalText, toolNames)
detected := toolcall.ParseStandaloneToolCallsDetailed(finalText, toolNames)
exposedOutputText := finalText
output := make([]any, 0, 2)
if len(detected.Calls) > 0 {
@@ -71,7 +71,7 @@ func BuildResponseObjectFromItems(responseID, model, finalPrompt, finalThinking,
}
}
func toResponsesFunctionCallItems(toolCalls []util.ParsedToolCall) []any {
func toResponsesFunctionCallItems(toolCalls []toolcall.ParsedToolCall) []any {
if len(toolCalls) == 0 {
return nil
}