Files
smartmate/backend/newAgent/node/execute/args.go
LoveLosita 0b0ed3c61a Version: 0.9.47.dev.260427
后端:
1. execute 节点继续拆职责——超大 execute.go 下沉为 node/execute 子包,按决策流、动作路由、上下文锚点、工具执行、状态快照、工具展示与参数解析拆分;顶层 execute.go 收敛为桥接导出,降低单文件编排/业务/模型/工具逻辑混写
2. 节点公共能力继续沉到 shared——抽出 LLM 纠错回灌、完整上下文调试日志、thinking 开关、统一上下文压缩、可见 assistant 文本持久化等 node_* 公共件,减少 execute 独占实现并为其他节点复用铺路
3. speak 文本整理能力独立收口——新增 speak_text 辅助文件,补齐正文归一化的独立承载,继续收缩 execute 主文件体积

前端:
4. NewAgent 时间线接入 business_card 业务卡片协议——schedule_agent.ts 新增 task_query / task_record 卡片载荷类型与 business_card kind;AssistantPanel 增加业务卡片事件存储、时间线恢复、块渲染分支与 BusinessCardRenderer 接入,同时保留 interrupt / status / tool / reasoning 多块并存
5. 新增任务查询卡片与任务记录卡片组件,并补充 DesignDemo 设计预览页与路由,前端可先行验证 business_card 的视觉与交互落点

文档:
6. 新增 newagent business card 前后端对接说明,明确 timeline kind、payload 结构、卡片分类、前后端发射/渲染约束
2026-04-27 17:35:55 +08:00

163 lines
2.9 KiB
Go

package newagentexecute
import (
"encoding/json"
"fmt"
"strconv"
"strings"
)
func intSliceToSet(values []int) map[int]struct{} {
result := make(map[int]struct{}, len(values))
for _, value := range values {
result[value] = struct{}{}
}
return result
}
func readIntAnyFromMap(args map[string]any, keys ...string) (int, bool) {
for _, key := range keys {
if args == nil {
continue
}
raw, exists := args[key]
if !exists {
continue
}
if value, ok := parseAnyToInt(raw); ok {
return value, true
}
}
return 0, false
}
func readIntSliceAnyFromMap(args map[string]any, keys ...string) []int {
for _, key := range keys {
if args == nil {
continue
}
raw, exists := args[key]
if !exists {
continue
}
values := parseAnyToIntSlice(raw)
if len(values) > 0 {
return values
}
}
return nil
}
func readStringAnyFromMap(args map[string]any, keys ...string) string {
for _, key := range keys {
if args == nil {
continue
}
raw, exists := args[key]
if !exists {
continue
}
if text, ok := raw.(string); ok {
return text
}
}
return ""
}
func parseAnyToInt(value any) (int, bool) {
switch v := value.(type) {
case int:
return v, true
case int8:
return int(v), true
case int16:
return int(v), true
case int32:
return int(v), true
case int64:
return int(v), true
case float32:
return int(v), true
case float64:
return int(v), true
case json.Number:
if iv, err := v.Int64(); err == nil {
return int(iv), true
}
if fv, err := v.Float64(); err == nil {
return int(fv), true
}
case string:
text := strings.TrimSpace(v)
if text == "" {
return 0, false
}
iv, err := strconv.Atoi(text)
if err == nil {
return iv, true
}
}
return 0, false
}
func parseAnyToIntSlice(value any) []int {
switch values := value.(type) {
case []int:
result := make([]int, 0, len(values))
for _, value := range values {
result = append(result, value)
}
return result
case []any:
result := make([]int, 0, len(values))
for _, item := range values {
iv, ok := parseAnyToInt(item)
if !ok {
continue
}
result = append(result, iv)
}
return result
default:
return nil
}
}
func parseAnyToStringSlice(value any) []string {
switch values := value.(type) {
case []string:
result := make([]string, 0, len(values))
for _, item := range values {
text := strings.TrimSpace(item)
if text == "" {
continue
}
result = append(result, text)
}
return result
case []any:
result := make([]string, 0, len(values))
for _, item := range values {
text := strings.TrimSpace(fmt.Sprintf("%v", item))
if text == "" || text == "<nil>" {
continue
}
result = append(result, text)
}
return result
default:
return nil
}
}
func truncateText(text string, maxLen int) string {
text = strings.TrimSpace(text)
if len(text) <= maxLen {
return text
}
if maxLen <= 3 {
return text[:maxLen]
}
return text[:maxLen-3] + "..."
}