feat: v2.3.0 流式输出 + 日志系统 + 会议室架构全面升级
- 流式输出: SSE 逐 token 接收, \\n\n\ 段落缓冲后 mdprint 彩色渲染 - 日志系统: charmbracelet/log v2 双写(stderr + log.yml), yunshu log 命令 - 会议室架构: dialog(main) + weather/profile/note(sub) 多 Agent 编排 - 泛型工具注册: NewTool[T] 反射推导 JSON Schema, 类型安全 - 安全加固: safeMemoryPath 三段校验(EvalSymlinks+Rel), maxToolCalls=2 - 性能优化: sync.Once 延迟加载, note 一步完成, obs/summary 合并 - Prompt 适配: 流式输出原则(先调工具不说话), 单 Agent 查询跳过 obs+summary - 文档: AGENTS.md + architecture.md + changelog.md 全部同步至 v2.3.0
This commit is contained in:
57
catalog.go
57
catalog.go
@@ -51,6 +51,7 @@ type CatalogSkill struct {
|
||||
|
||||
type CatalogAgent struct {
|
||||
Name string `yaml:"name"`
|
||||
Type string `yaml:"type"`
|
||||
Path string `yaml:"path"`
|
||||
Description string `yaml:"description"`
|
||||
Tools []string `yaml:"tools"`
|
||||
@@ -84,22 +85,37 @@ func buildToolList() []CatalogTool {
|
||||
Source: "src/tool.go",
|
||||
}
|
||||
|
||||
// 从 JSON Schema 提取参数
|
||||
// 从 Schema (map[string]any) 提取参数
|
||||
ct.Parameters = make(map[string]ParameterField)
|
||||
for name, prop := range t.Parameters.Properties {
|
||||
required := false
|
||||
for _, r := range t.Parameters.Required {
|
||||
if r == name {
|
||||
required = true
|
||||
break
|
||||
if t.Parameters == nil {
|
||||
list = append(list, ct)
|
||||
continue
|
||||
}
|
||||
|
||||
props, _ := t.Parameters["properties"].(map[string]any)
|
||||
required := make(map[string]bool)
|
||||
if reqList, ok := t.Parameters["required"].([]any); ok {
|
||||
for _, r := range reqList {
|
||||
if s, ok := r.(string); ok {
|
||||
required[s] = true
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
for name, propRaw := range props {
|
||||
prop, ok := propRaw.(map[string]any)
|
||||
if !ok {
|
||||
continue
|
||||
}
|
||||
typ, _ := prop["type"].(string)
|
||||
desc, _ := prop["description"].(string)
|
||||
ct.Parameters[name] = ParameterField{
|
||||
Type: prop.Type,
|
||||
Required: required,
|
||||
Description: prop.Description,
|
||||
Type: typ,
|
||||
Required: required[name],
|
||||
Description: desc,
|
||||
}
|
||||
}
|
||||
|
||||
list = append(list, ct)
|
||||
}
|
||||
return list
|
||||
@@ -181,8 +197,14 @@ func scanAgents() []CatalogAgent {
|
||||
continue
|
||||
}
|
||||
|
||||
agentType := "main"
|
||||
if t, ok := fm["type"]; ok {
|
||||
agentType = fmt.Sprintf("%v", t)
|
||||
}
|
||||
|
||||
cat := CatalogAgent{
|
||||
Name: fmt.Sprintf("%v", fm["name"]),
|
||||
Type: agentType,
|
||||
Path: fmt.Sprintf("agents/%s", e.Name()),
|
||||
Status: "active",
|
||||
}
|
||||
@@ -244,6 +266,21 @@ func GenerateToolsYAML() {
|
||||
// 注入目录到 system prompt
|
||||
// ============================================================
|
||||
|
||||
// BuildSubAgentPrompt 生成可用子 Agent 列表,动态注入到主 Agent 的 system prompt
|
||||
func BuildSubAgentPrompt(subs []*AgentDef) string {
|
||||
if len(subs) == 0 {
|
||||
return ""
|
||||
}
|
||||
var b strings.Builder
|
||||
b.WriteString("\n\n## 可用子 Agent\n")
|
||||
b.WriteString("\n以下子 Agent 可通过 task 工具调度:\n")
|
||||
for _, s := range subs {
|
||||
b.WriteString(fmt.Sprintf("- **%s**: %s\n", s.Name, s.Description))
|
||||
}
|
||||
b.WriteString("\n用 `task(\"agent_name\", {args})` 调度。不自己回答领域问题。\n")
|
||||
return b.String()
|
||||
}
|
||||
|
||||
// BuildInjectPrompt 生成能力边界目录,追加到 system prompt 末尾
|
||||
func BuildInjectPrompt(toolNames []string) string {
|
||||
var b strings.Builder
|
||||
|
||||
Reference in New Issue
Block a user