Files
picoclaw/pkg/utils/visible_tool_calls.go
T

107 lines
2.6 KiB
Go

package utils
import (
"bytes"
"encoding/json"
"strings"
"github.com/sipeed/picoclaw/pkg/providers"
)
type VisibleToolCall struct {
ID string `json:"id,omitempty"`
Type string `json:"type,omitempty"`
Function *VisibleToolCallFunction `json:"function,omitempty"`
ExtraContent *VisibleToolCallExtraContent `json:"extra_content,omitempty"`
}
type VisibleToolCallFunction struct {
Name string `json:"name,omitempty"`
Arguments string `json:"arguments,omitempty"`
}
type VisibleToolCallExtraContent struct {
ToolFeedbackExplanation string `json:"tool_feedback_explanation,omitempty"`
}
func BuildVisibleToolCalls(
toolCalls []providers.ToolCall,
maxArgsLen int,
) []VisibleToolCall {
if len(toolCalls) == 0 {
return nil
}
visible := make([]VisibleToolCall, 0, len(toolCalls))
for _, tc := range toolCalls {
name, _ := VisibleToolCallNameAndArguments(tc)
argsPreview := VisibleToolCallArgumentsPreview(tc, maxArgsLen)
explanation := ""
if tc.ExtraContent != nil {
explanation = strings.TrimSpace(tc.ExtraContent.ToolFeedbackExplanation)
}
if name == "" && explanation == "" && argsPreview == "" {
continue
}
visibleCall := VisibleToolCall{
ID: strings.TrimSpace(tc.ID),
Type: strings.TrimSpace(tc.Type),
}
if visibleCall.Type == "" {
visibleCall.Type = "function"
}
if name != "" || argsPreview != "" {
visibleCall.Function = &VisibleToolCallFunction{
Name: name,
Arguments: argsPreview,
}
}
if explanation != "" {
visibleCall.ExtraContent = &VisibleToolCallExtraContent{
ToolFeedbackExplanation: explanation,
}
}
visible = append(visible, visibleCall)
}
if len(visible) == 0 {
return nil
}
return visible
}
func VisibleToolCallNameAndArguments(tc providers.ToolCall) (string, string) {
name := strings.TrimSpace(tc.Name)
argsJSON := ""
if tc.Function != nil {
if name == "" {
name = strings.TrimSpace(tc.Function.Name)
}
argsJSON = strings.TrimSpace(tc.Function.Arguments)
}
if argsJSON == "" && len(tc.Arguments) > 0 {
if encodedArgs, err := json.Marshal(tc.Arguments); err == nil {
argsJSON = string(encodedArgs)
}
}
return name, strings.TrimSpace(argsJSON)
}
func VisibleToolCallArgumentsPreview(tc providers.ToolCall, maxLen int) string {
_, argsJSON := VisibleToolCallNameAndArguments(tc)
if argsJSON == "" {
return ""
}
var pretty bytes.Buffer
if err := json.Indent(&pretty, []byte(argsJSON), "", " "); err == nil {
argsJSON = pretty.String()
}
if maxLen > 0 {
return Truncate(argsJSON, maxLen)
}
return argsJSON
}