后端: 1.收口阶段 6 agent 结构迁移,将 newAgent 内核与 agentsvc 编排层迁入 services/agent - 切换 Agent 启动装配与 HTTP handler 直连 agent sv,移除旧 service agent bridge - 补齐 Agent 对 memory、task、task-class、schedule 的 RPC 适配与契约字段 - 扩展 schedule、task、task-class RPC/contract 支撑 Agent 查询、写入与 provider 切流 - 更新迁移文档、README 与相关注释,明确 agent 当前切流点和剩余 memory 迁移面
107 lines
3.7 KiB
Go
107 lines
3.7 KiB
Go
package agentprompt
|
|
|
|
import (
|
|
"fmt"
|
|
"strings"
|
|
)
|
|
|
|
// summarizeExecuteAnalyzeHealthObservationV2 把 analyze_health 结果压成更短的单行摘要。
|
|
//
|
|
// 职责边界:
|
|
// 1. 只保留 execute 下一步真正需要消费的裁决字段,不重复展开整份 metrics。
|
|
// 2. 若存在候选,会优先展示“候选数量 + 前两个候选工具”,帮助模型迅速进入选择题。
|
|
// 3. 这里只做摘要,不负责改变决策含义;真实判定仍以 analyze_health 原始 JSON 为准。
|
|
func summarizeExecuteAnalyzeHealthObservationV2(payload map[string]any) string {
|
|
decision, _ := payload["decision"].(map[string]any)
|
|
metrics, _ := payload["metrics"].(map[string]any)
|
|
rhythmMetrics, _ := metrics["rhythm"].(map[string]any)
|
|
tightnessMetrics, _ := metrics["tightness"].(map[string]any)
|
|
candidates, _ := decision["candidates"].([]any)
|
|
|
|
parts := make([]string, 0, 7)
|
|
if text := compactHealthAny(decision["should_continue_optimize"]); text != "" {
|
|
parts = append(parts, "continue="+text)
|
|
}
|
|
if text := strings.TrimSpace(asExecuteString(decision["recommended_operation"])); text != "" {
|
|
parts = append(parts, "recommended="+text)
|
|
}
|
|
if text := strings.TrimSpace(asExecuteString(tightnessMetrics["tightness_level"])); text != "" {
|
|
parts = append(parts, "tightness="+text)
|
|
}
|
|
if text := buildBlockBalanceSummary(rhythmMetrics); text != "" {
|
|
parts = append(parts, text)
|
|
}
|
|
if text := compactHealthAny(decision["is_forced_imperfection"]); text != "" {
|
|
parts = append(parts, "forced="+text)
|
|
}
|
|
if len(candidates) > 0 {
|
|
parts = append(parts, fmt.Sprintf("candidates=%d", len(candidates)))
|
|
if preview := compactHealthCandidatePreview(candidates); preview != "" {
|
|
parts = append(parts, "options="+preview)
|
|
}
|
|
}
|
|
if text := strings.TrimSpace(asExecuteString(decision["primary_problem"])); text != "" {
|
|
parts = append(parts, "problem="+compactExecuteText(text, 36))
|
|
}
|
|
if len(parts) == 0 {
|
|
return "返回了健康裁决结果。"
|
|
}
|
|
return strings.Join(parts, " | ")
|
|
}
|
|
|
|
// buildBlockBalanceSummary 把 block_balance 连同正负来源一起压成单段摘要。
|
|
//
|
|
// 职责边界:
|
|
// 1. 这里只做 execute 摘要层的可读性补充,避免 LLM 只看到 balance=0 却看不到来源。
|
|
// 2. 不改变 analyze_health 原始 JSON 结构;原始结构仍由 metrics.rhythm 提供完整字段。
|
|
// 3. 若三个字段都缺失,则直接留空,避免构造误导性的默认值。
|
|
func buildBlockBalanceSummary(rhythmMetrics map[string]any) string {
|
|
if len(rhythmMetrics) == 0 {
|
|
return ""
|
|
}
|
|
|
|
blockBalance := compactHealthAny(rhythmMetrics["block_balance"])
|
|
fragmentedCount := compactHealthAny(rhythmMetrics["fragmented_count"])
|
|
compressedCount := compactHealthAny(rhythmMetrics["compressed_run_count"])
|
|
if blockBalance == "" && fragmentedCount == "" && compressedCount == "" {
|
|
return ""
|
|
}
|
|
|
|
return fmt.Sprintf(
|
|
"block_balance=%s(fragmented=%s,compressed=%s)",
|
|
fallbackExecuteText(blockBalance, "?"),
|
|
fallbackExecuteText(fragmentedCount, "?"),
|
|
fallbackExecuteText(compressedCount, "?"),
|
|
)
|
|
}
|
|
|
|
func compactHealthCandidatePreview(candidates []any) string {
|
|
if len(candidates) == 0 {
|
|
return ""
|
|
}
|
|
preview := make([]string, 0, 2)
|
|
for _, raw := range candidates {
|
|
item, _ := raw.(map[string]any)
|
|
if len(item) == 0 {
|
|
continue
|
|
}
|
|
id := strings.TrimSpace(asExecuteString(item["candidate_id"]))
|
|
tool := strings.TrimSpace(asExecuteString(item["tool"]))
|
|
if id == "" && tool == "" {
|
|
continue
|
|
}
|
|
switch {
|
|
case id != "" && tool != "":
|
|
preview = append(preview, id+":"+tool)
|
|
case id != "":
|
|
preview = append(preview, id)
|
|
default:
|
|
preview = append(preview, tool)
|
|
}
|
|
if len(preview) >= 2 {
|
|
break
|
|
}
|
|
}
|
|
return strings.Join(preview, ",")
|
|
}
|