This commit is contained in:
lpf
2026-02-19 21:11:27 +08:00
parent 764b2d3b79
commit b3d7774d9c
3 changed files with 63 additions and 1 deletions

View File

@@ -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)
} }

View File

@@ -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{})

View 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")
}
}