fix: enforce subagent prompt files and refine webui

This commit is contained in:
lpf
2026-03-09 11:24:31 +08:00
parent ba3be33c91
commit acf8a22c0a
25 changed files with 257 additions and 211 deletions

View File

@@ -27,7 +27,6 @@ type SubagentTask struct {
NotifyMainPolicy string `json:"notify_main_policy,omitempty"`
SessionKey string `json:"session_key"`
MemoryNS string `json:"memory_ns"`
SystemPrompt string `json:"system_prompt,omitempty"`
SystemPromptFile string `json:"system_prompt_file,omitempty"`
ToolAllowlist []string `json:"tool_allowlist,omitempty"`
MaxRetries int `json:"max_retries,omitempty"`
@@ -168,7 +167,6 @@ func (sm *SubagentManager) spawnTask(ctx context.Context, opts SubagentSpawnOpti
agentID = "default"
}
memoryNS := agentID
systemPrompt := ""
systemPromptFile := ""
transport := "local"
nodeID := ""
@@ -207,7 +205,6 @@ func (sm *SubagentManager) spawnTask(ctx context.Context, opts SubagentSpawnOpti
nodeID = strings.TrimSpace(profile.NodeID)
parentAgentID = strings.TrimSpace(profile.ParentAgentID)
notifyMainPolicy = normalizeNotifyMainPolicy(profile.NotifyMainPolicy)
systemPrompt = strings.TrimSpace(profile.SystemPrompt)
systemPromptFile = strings.TrimSpace(profile.SystemPromptFile)
toolAllowlist = append([]string(nil), profile.ToolAllowlist...)
maxRetries = profile.MaxRetries
@@ -288,7 +285,6 @@ func (sm *SubagentManager) spawnTask(ctx context.Context, opts SubagentSpawnOpti
NotifyMainPolicy: notifyMainPolicy,
SessionKey: sessionKey,
MemoryNS: memoryNS,
SystemPrompt: systemPrompt,
SystemPromptFile: systemPromptFile,
ToolAllowlist: toolAllowlist,
MaxRetries: maxRetries,
@@ -671,9 +667,6 @@ func (sm *SubagentManager) resolveSystemPrompt(task *SubagentTask) string {
return systemPrompt + "\n\nSubagent policy (" + promptFile + "):\n" + promptText
}
}
if rolePrompt := strings.TrimSpace(task.SystemPrompt); rolePrompt != "" {
return systemPrompt + "\n\nRole-specific profile prompt:\n" + rolePrompt
}
return systemPrompt
}

View File

@@ -21,14 +21,12 @@ func DraftConfigSubagent(description, agentIDHint string) map[string]interface{}
displayName := inferDraftDisplayName(role, agentID)
toolAllowlist := inferDraftToolAllowlist(role)
keywords := inferDraftKeywords(role, lower)
systemPrompt := inferDraftSystemPrompt(role, desc)
return map[string]interface{}{
"agent_id": agentID,
"role": role,
"display_name": displayName,
"description": desc,
"notify_main_policy": "final_only",
"system_prompt": systemPrompt,
"system_prompt_file": "agents/" + agentID + "/AGENT.md",
"memory_namespace": agentID,
"tool_allowlist": toolAllowlist,
@@ -87,9 +85,6 @@ func UpsertConfigSubagent(configPath string, args map[string]interface{}) (map[s
if v := stringArgFromMap(args, "description"); v != "" {
subcfg.Description = v
}
if v := stringArgFromMap(args, "system_prompt"); v != "" {
subcfg.SystemPrompt = v
}
if v := stringArgFromMap(args, "system_prompt_file"); v != "" {
subcfg.SystemPromptFile = v
}

View File

@@ -45,7 +45,6 @@ func (t *SubagentConfigTool) Parameters() map[string]interface{} {
"parent_agent_id": map[string]interface{}{"type": "string"},
"role": map[string]interface{}{"type": "string"},
"display_name": map[string]interface{}{"type": "string"},
"system_prompt": map[string]interface{}{"type": "string"},
"system_prompt_file": map[string]interface{}{"type": "string"},
"memory_namespace": map[string]interface{}{"type": "string"},
"type": map[string]interface{}{"type": "string"},

View File

@@ -35,7 +35,6 @@ func TestSubagentConfigToolUpsert(t *testing.T) {
"notify_main_policy": "internal_only",
"display_name": "Review Agent",
"description": "负责回归与评审",
"system_prompt": "review changes",
"system_prompt_file": "agents/reviewer/AGENT.md",
"routing_keywords": []interface{}{"review", "regression"},
"tool_allowlist": []interface{}{"shell", "sessions"},

View File

@@ -24,7 +24,6 @@ type SubagentProfile struct {
ParentAgentID string `json:"parent_agent_id,omitempty"`
NotifyMainPolicy string `json:"notify_main_policy,omitempty"`
Role string `json:"role,omitempty"`
SystemPrompt string `json:"system_prompt,omitempty"`
SystemPromptFile string `json:"system_prompt_file,omitempty"`
ToolAllowlist []string `json:"tool_allowlist,omitempty"`
MemoryNamespace string `json:"memory_namespace,omitempty"`
@@ -191,7 +190,6 @@ func normalizeSubagentProfile(in SubagentProfile) SubagentProfile {
p.ParentAgentID = normalizeSubagentIdentifier(p.ParentAgentID)
p.NotifyMainPolicy = normalizeNotifyMainPolicy(p.NotifyMainPolicy)
p.Role = strings.TrimSpace(p.Role)
p.SystemPrompt = strings.TrimSpace(p.SystemPrompt)
p.SystemPromptFile = strings.TrimSpace(p.SystemPromptFile)
p.MemoryNamespace = normalizeSubagentIdentifier(p.MemoryNamespace)
if p.MemoryNamespace == "" {
@@ -409,7 +407,6 @@ func profileFromConfig(agentID string, subcfg config.SubagentConfig) SubagentPro
ParentAgentID: strings.TrimSpace(subcfg.ParentAgentID),
NotifyMainPolicy: strings.TrimSpace(subcfg.NotifyMainPolicy),
Role: strings.TrimSpace(subcfg.Role),
SystemPrompt: strings.TrimSpace(subcfg.SystemPrompt),
SystemPromptFile: strings.TrimSpace(subcfg.SystemPromptFile),
ToolAllowlist: append([]string(nil), subcfg.Tools.Allowlist...),
MemoryNamespace: strings.TrimSpace(subcfg.MemoryNamespace),
@@ -554,7 +551,6 @@ func (t *SubagentProfileTool) Parameters() map[string]interface{} {
"name": map[string]interface{}{"type": "string"},
"notify_main_policy": map[string]interface{}{"type": "string", "description": "final_only|internal_only|milestone|on_blocked|always"},
"role": map[string]interface{}{"type": "string"},
"system_prompt": map[string]interface{}{"type": "string"},
"system_prompt_file": map[string]interface{}{"type": "string"},
"memory_namespace": map[string]interface{}{"type": "string"},
"status": map[string]interface{}{"type": "string", "description": "active|disabled"},
@@ -625,7 +621,6 @@ func (t *SubagentProfileTool) Execute(ctx context.Context, args map[string]inter
Name: stringArg(args, "name"),
NotifyMainPolicy: stringArg(args, "notify_main_policy"),
Role: stringArg(args, "role"),
SystemPrompt: stringArg(args, "system_prompt"),
SystemPromptFile: stringArg(args, "system_prompt_file"),
MemoryNamespace: stringArg(args, "memory_namespace"),
Status: stringArg(args, "status"),
@@ -662,9 +657,6 @@ func (t *SubagentProfileTool) Execute(ctx context.Context, args map[string]inter
if _, ok := args["notify_main_policy"]; ok {
next.NotifyMainPolicy = stringArg(args, "notify_main_policy")
}
if _, ok := args["system_prompt"]; ok {
next.SystemPrompt = stringArg(args, "system_prompt")
}
if _, ok := args["system_prompt_file"]; ok {
next.SystemPromptFile = stringArg(args, "system_prompt_file")
}

View File

@@ -126,7 +126,6 @@ func TestSubagentProfileStoreReadsProfilesFromRuntimeConfig(t *testing.T) {
Enabled: true,
DisplayName: "Code Agent",
Role: "coding",
SystemPrompt: "write code",
SystemPromptFile: "agents/coder/AGENT.md",
MemoryNamespace: "code-ns",
Tools: config.SubagentToolsConfig{

View File

@@ -719,7 +719,6 @@ func TestSubagentUsesConfiguredSystemPromptFile(t *testing.T) {
if _, err := manager.ProfileStore().Upsert(SubagentProfile{
AgentID: "coder",
Status: "active",
SystemPrompt: "inline-fallback",
SystemPromptFile: "agents/coder/AGENT.md",
}); err != nil {
t.Fatalf("profile upsert failed: %v", err)