mirror of
https://github.com/YspCoder/clawgo.git
synced 2026-05-08 03:57:30 +08:00
fix loop
This commit is contained in:
@@ -78,6 +78,8 @@ Your workspace is at: %s
|
|||||||
%s
|
%s
|
||||||
|
|
||||||
Always be helpful, accurate, and concise. When using tools, explain what you're doing.
|
Always be helpful, accurate, and concise. When using tools, explain what you're doing.
|
||||||
|
For operational tasks (for example configuring git remotes/credentials), prefer executing tools directly instead of only giving manual steps.
|
||||||
|
If user provides credentials/tokens for a requested operation, you may use them to execute the task, but never expose full secrets in visible output.
|
||||||
When remembering something, write to %s/memory/MEMORY.md`,
|
When remembering something, write to %s/memory/MEMORY.md`,
|
||||||
now, runtime, workspacePath, workspacePath, workspacePath, workspacePath, toolsSection, workspacePath)
|
now, runtime, workspacePath, workspacePath, workspacePath, workspacePath, toolsSection, workspacePath)
|
||||||
}
|
}
|
||||||
|
|||||||
@@ -3381,7 +3381,8 @@ func (al *AgentLoop) executeSingleToolCall(
|
|||||||
progress *stageReporter,
|
progress *stageReporter,
|
||||||
) toolCallExecResult {
|
) toolCallExecResult {
|
||||||
if !systemMode {
|
if !systemMode {
|
||||||
argsJSON, _ := json.Marshal(tc.Arguments)
|
safeArgs := sanitizeSensitiveToolArgs(tc.Arguments)
|
||||||
|
argsJSON, _ := json.Marshal(safeArgs)
|
||||||
argsPreview := truncate(string(argsJSON), 200)
|
argsPreview := truncate(string(argsJSON), 200)
|
||||||
logger.InfoCF("agent", fmt.Sprintf("Tool call: %s(%s)", tc.Name, argsPreview), map[string]interface{}{
|
logger.InfoCF("agent", fmt.Sprintf("Tool call: %s(%s)", tc.Name, argsPreview), map[string]interface{}{
|
||||||
"tool": tc.Name,
|
"tool": tc.Name,
|
||||||
@@ -4326,6 +4327,39 @@ func truncate(s string, maxLen int) string {
|
|||||||
return s[:maxLen-3] + "..."
|
return s[:maxLen-3] + "..."
|
||||||
}
|
}
|
||||||
|
|
||||||
|
func sanitizeSensitiveToolArgs(args map[string]interface{}) map[string]interface{} {
|
||||||
|
if len(args) == 0 {
|
||||||
|
return map[string]interface{}{}
|
||||||
|
}
|
||||||
|
raw, err := json.Marshal(args)
|
||||||
|
if err != nil {
|
||||||
|
return map[string]interface{}{"_masked": true}
|
||||||
|
}
|
||||||
|
redacted := redactSecretsInText(string(raw))
|
||||||
|
out := map[string]interface{}{}
|
||||||
|
if err := json.Unmarshal([]byte(redacted), &out); err != nil {
|
||||||
|
return map[string]interface{}{"_masked": true}
|
||||||
|
}
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
|
func redactSecretsInText(text string) string {
|
||||||
|
if strings.TrimSpace(text) == "" {
|
||||||
|
return text
|
||||||
|
}
|
||||||
|
out := text
|
||||||
|
authHeaderPattern := regexp.MustCompile(`(?i)(authorization\s*[:=]\s*["']?(?:bearer|token)\s+)([^\s"']+)`)
|
||||||
|
out = authHeaderPattern.ReplaceAllString(out, "${1}[REDACTED]")
|
||||||
|
|
||||||
|
keyValuePattern := regexp.MustCompile(`(?i)("?(?:token|api[_-]?key|password|passwd|secret|authorization|access[_-]?token|refresh[_-]?token)"?\s*:\s*")([^"]+)(")`)
|
||||||
|
out = keyValuePattern.ReplaceAllString(out, "${1}[REDACTED]${3}")
|
||||||
|
|
||||||
|
commonTokenPattern := regexp.MustCompile(`(?i)\b(ghp_[A-Za-z0-9_]+|glpat-[A-Za-z0-9_-]+)\b`)
|
||||||
|
out = commonTokenPattern.ReplaceAllString(out, "[REDACTED]")
|
||||||
|
|
||||||
|
return out
|
||||||
|
}
|
||||||
|
|
||||||
// GetStartupInfo returns information about loaded tools and skills for logging.
|
// GetStartupInfo returns information about loaded tools and skills for logging.
|
||||||
func (al *AgentLoop) GetStartupInfo() map[string]interface{} {
|
func (al *AgentLoop) GetStartupInfo() map[string]interface{} {
|
||||||
info := make(map[string]interface{})
|
info := make(map[string]interface{})
|
||||||
|
|||||||
26
pkg/agent/loop_secret_test.go
Normal file
26
pkg/agent/loop_secret_test.go
Normal file
@@ -0,0 +1,26 @@
|
|||||||
|
package agent
|
||||||
|
|
||||||
|
import "testing"
|
||||||
|
|
||||||
|
func TestRedactSecretsInText(t *testing.T) {
|
||||||
|
in := `{"token":"abc123","authorization":"Bearer sk-xyz","password":"p@ss","note":"ok"}`
|
||||||
|
out := redactSecretsInText(in)
|
||||||
|
|
||||||
|
if out == in {
|
||||||
|
t.Fatalf("expected redaction to change input")
|
||||||
|
}
|
||||||
|
if containsAnySubstring(out, "abc123", "sk-xyz", "p@ss") {
|
||||||
|
t.Fatalf("expected sensitive values to be redacted, got: %s", out)
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
func TestSanitizeSensitiveToolArgs(t *testing.T) {
|
||||||
|
args := map[string]interface{}{
|
||||||
|
"command": "git -c http.extraHeader='Authorization: token abc123' ls-remote https://example.com/repo.git",
|
||||||
|
"token": "abc123",
|
||||||
|
}
|
||||||
|
safe := sanitizeSensitiveToolArgs(args)
|
||||||
|
if safe["token"] == "abc123" {
|
||||||
|
t.Fatalf("expected token field to be redacted")
|
||||||
|
}
|
||||||
|
}
|
||||||
Reference in New Issue
Block a user