Files
tutti/services/tuttid/service/agent/external_import_payload.go
agent-radar 2ed3415fb7
Publish Claude Code Binaries / Stage and publish binaries (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-arm64 (push) Canceled after 0s
Publish Tutti App Runtime / Build darwin-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build linux-amd64 (push) Canceled after 0s
Publish Tutti App Runtime / Build windows-amd64 (push) Canceled after 0s
Sync Tutti Agent Skills / sync (push) Canceled after 0s
Windows Agent Adapters / Test Windows agent adapters (push) Canceled after 0s
Windows Daemon Adapters / Test Windows daemon adapters (push) Canceled after 0s
Publish Tutti App Runtime / Publish runtime catalog (push) Canceled after 0s
源码快照 @ 2026-09-01 (source-only, 剔除非源码素材)
2026-09-01 20:17:27 +08:00

138 lines
2.9 KiB
Go

package agent
import (
"encoding/json"
"fmt"
"strings"
"time"
)
func externalToolText(name string) string {
name = strings.TrimSpace(name)
if name == "" {
return ""
}
return "[Tool: " + name + "]"
}
func externalContentText(value any) string {
switch typed := value.(type) {
case string:
return strings.TrimSpace(typed)
case []any:
parts := make([]string, 0, len(typed))
for _, item := range typed {
if text := externalContentText(item); text != "" {
parts = append(parts, text)
}
}
return strings.TrimSpace(strings.Join(parts, "\n"))
case map[string]any:
blockType := stringField(typed, "type")
switch blockType {
case "text", "input_text", "output_text":
return strings.TrimSpace(stringField(typed, "text"))
case "tool_use", "function_call":
return externalToolText(firstNonEmptyString(stringField(typed, "name"), stringField(typed, "id")))
case "tool_result":
return firstNonEmptyString(externalContentText(typed["content"]), stringField(typed, "text"))
default:
return firstNonEmptyString(
stringField(typed, "text"),
externalContentText(typed["content"]),
externalContentText(typed["message"]),
)
}
default:
return ""
}
}
func isPureExternalToolResult(value any) bool {
items, ok := value.([]any)
if !ok || len(items) == 0 {
return false
}
for _, item := range items {
block, ok := item.(map[string]any)
if !ok || stringField(block, "type") != "tool_result" {
return false
}
}
return true
}
func unixMSFromAny(value any) int64 {
switch typed := value.(type) {
case string:
typed = strings.TrimSpace(typed)
if typed == "" {
return 0
}
if parsed, err := time.Parse(time.RFC3339Nano, typed); err == nil {
return parsed.UnixMilli()
}
case float64:
if typed > 1_000_000_000_000 {
return int64(typed)
}
return int64(typed * 1000)
case int64:
if typed > 1_000_000_000_000 {
return typed
}
return typed * 1000
case json.Number:
if parsed, err := parsedJSONNumberUnixMS(typed); err == nil {
return parsed
}
}
return 0
}
func parsedJSONNumberUnixMS(number json.Number) (int64, error) {
if value, err := number.Int64(); err == nil {
if value > 1_000_000_000_000 {
return value, nil
}
return value * 1000, nil
}
value, err := number.Float64()
if err != nil {
return 0, err
}
if value > 1_000_000_000_000 {
return int64(value), nil
}
return int64(value * 1000), nil
}
func stringField(values map[string]any, key string) string {
if values == nil {
return ""
}
value, ok := values[key]
if !ok {
return ""
}
switch typed := value.(type) {
case string:
return strings.TrimSpace(typed)
case fmt.Stringer:
return strings.TrimSpace(typed.String())
default:
return ""
}
}
func mapField(values map[string]any, key string) map[string]any {
if values == nil {
return nil
}
value, ok := values[key].(map[string]any)
if !ok {
return nil
}
return value
}