mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-04-13 18:07:36 +08:00
harden dialog execution policy with intent slots and commit-push receipt formatting
This commit is contained in:
@@ -129,6 +129,12 @@ Constraints:
|
||||
parts = append(parts, memoryContext)
|
||||
}
|
||||
|
||||
parts = append(parts, `# Execution & Reply Policy
|
||||
- Default behavior: execute first, then report.
|
||||
- Avoid empty/meta fallback replies.
|
||||
- For commit/push intents, treat as one transaction and return commit hash + push result.
|
||||
- Use concise receipt style: 已理解 -> 正在执行 -> 已完成.`)
|
||||
|
||||
// Join with "---" separator
|
||||
return strings.Join(parts, "\n\n---\n\n")
|
||||
}
|
||||
|
||||
@@ -14,6 +14,7 @@ import (
|
||||
"path/filepath"
|
||||
"regexp"
|
||||
"strings"
|
||||
"sync"
|
||||
|
||||
"clawgo/pkg/bus"
|
||||
"clawgo/pkg/config"
|
||||
@@ -49,6 +50,8 @@ type AgentLoop struct {
|
||||
systemRewriteTemplate string
|
||||
audit *triggerAudit
|
||||
running bool
|
||||
intentMu sync.RWMutex
|
||||
intentHints map[string]string
|
||||
}
|
||||
|
||||
// StartupCompactionReport provides startup memory/session maintenance stats.
|
||||
@@ -220,6 +223,7 @@ func NewAgentLoop(cfg *config.Config, msgBus *bus.MessageBus, provider providers
|
||||
systemRewriteTemplate: cfg.Agents.Defaults.Texts.SystemRewriteTemplate,
|
||||
audit: newTriggerAudit(workspace),
|
||||
running: false,
|
||||
intentHints: map[string]string{},
|
||||
}
|
||||
|
||||
// 注入递归运行逻辑,使 subagent 具备 full tool-calling 能力
|
||||
@@ -424,10 +428,13 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
preferredLang, lastLang := al.sessions.GetLanguagePreferences(msg.SessionKey)
|
||||
responseLang := DetectResponseLanguage(msg.Content, preferredLang, lastLang)
|
||||
|
||||
al.updateIntentHint(msg.SessionKey, msg.Content)
|
||||
effectiveUserContent := al.applyIntentHint(msg.SessionKey, msg.Content)
|
||||
|
||||
messages := al.contextBuilder.BuildMessages(
|
||||
history,
|
||||
summary,
|
||||
msg.Content,
|
||||
effectiveUserContent,
|
||||
nil,
|
||||
msg.Channel,
|
||||
msg.ChatID,
|
||||
@@ -563,7 +570,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
if finalContent == "" {
|
||||
fallback := strings.TrimSpace(al.noResponseFallback)
|
||||
if fallback == "" {
|
||||
fallback = "I've completed processing but have no response to give."
|
||||
fallback = "我已完成处理,但当前没有可直接返回的结果。请告诉我下一步要继续执行什么。"
|
||||
}
|
||||
finalContent = fallback
|
||||
}
|
||||
@@ -580,7 +587,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
if iteration == 1 {
|
||||
fallback := strings.TrimSpace(al.thinkOnlyFallback)
|
||||
if fallback == "" {
|
||||
fallback = "Thinking process completed."
|
||||
fallback = "已完成思考流程。"
|
||||
}
|
||||
userContent = fallback
|
||||
}
|
||||
@@ -591,6 +598,7 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
userContent = strings.TrimSpace(userContent + "\n\n" + src)
|
||||
}
|
||||
}
|
||||
userContent = enforceExecutionReceiptTemplate(effectiveUserContent, userContent)
|
||||
|
||||
al.sessions.AddMessage(msg.SessionKey, "user", msg.Content)
|
||||
|
||||
@@ -616,6 +624,60 @@ func (al *AgentLoop) processMessage(ctx context.Context, msg bus.InboundMessage)
|
||||
return userContent, nil
|
||||
}
|
||||
|
||||
func (al *AgentLoop) updateIntentHint(sessionKey, content string) {
|
||||
content = strings.TrimSpace(content)
|
||||
if sessionKey == "" || content == "" {
|
||||
return
|
||||
}
|
||||
lower := strings.ToLower(content)
|
||||
if !strings.Contains(lower, "提交") && !strings.Contains(lower, "推送") && !strings.Contains(lower, "commit") && !strings.Contains(lower, "push") {
|
||||
if strings.HasPrefix(content, "1.") || strings.HasPrefix(content, "2.") {
|
||||
al.intentMu.Lock()
|
||||
if prev := strings.TrimSpace(al.intentHints[sessionKey]); prev != "" {
|
||||
al.intentHints[sessionKey] = prev + " | " + content
|
||||
}
|
||||
al.intentMu.Unlock()
|
||||
}
|
||||
return
|
||||
}
|
||||
hint := "执行事务: commit+push 一次闭环,包含分支/范围确认。"
|
||||
if strings.Contains(lower, "所有分支") || strings.Contains(lower, "all branches") {
|
||||
hint += " 范围=所有分支。"
|
||||
}
|
||||
al.intentMu.Lock()
|
||||
al.intentHints[sessionKey] = hint + " 用户补充=" + content
|
||||
al.intentMu.Unlock()
|
||||
}
|
||||
|
||||
func (al *AgentLoop) applyIntentHint(sessionKey, content string) string {
|
||||
al.intentMu.RLock()
|
||||
hint := strings.TrimSpace(al.intentHints[sessionKey])
|
||||
al.intentMu.RUnlock()
|
||||
if hint == "" {
|
||||
return content
|
||||
}
|
||||
lower := strings.ToLower(strings.TrimSpace(content))
|
||||
if strings.Contains(lower, "提交") || strings.Contains(lower, "推送") || strings.HasPrefix(content, "1.") || strings.HasPrefix(content, "2.") {
|
||||
return "[Intent Slot]\n" + hint + "\n\n[User Message]\n" + content
|
||||
}
|
||||
return content
|
||||
}
|
||||
|
||||
func enforceExecutionReceiptTemplate(userInput, output string) string {
|
||||
l := strings.ToLower(userInput)
|
||||
if !(strings.Contains(l, "提交") || strings.Contains(l, "推送") || strings.Contains(l, "commit") || strings.Contains(l, "push")) {
|
||||
return output
|
||||
}
|
||||
clean := strings.TrimSpace(output)
|
||||
if clean == "" {
|
||||
return clean
|
||||
}
|
||||
if strings.Contains(clean, "已理解") && strings.Contains(clean, "已完成") {
|
||||
return clean
|
||||
}
|
||||
return "已理解:按你的要求执行提交/推送事务。\n正在执行:整理改动并完成 commit + push。\n已完成:\n" + clean
|
||||
}
|
||||
|
||||
func (al *AgentLoop) processSystemMessage(ctx context.Context, msg bus.InboundMessage) (string, error) {
|
||||
// Verify this is a system message
|
||||
if msg.Channel != "system" {
|
||||
|
||||
Reference in New Issue
Block a user