Add docs/16 for session state machine, incomplete/resume, queue semantics, and agent-loop/harness/MCP gap review. Wire RunOutcome on max-rounds, run_id through audit, TrimMessages/Redact hooks, ConfirmBindHash on write confirm path; session file skeleton without HTTP yet. No push.
43 lines
1.3 KiB
Go
43 lines
1.3 KiB
Go
package ai
|
|
|
|
import (
|
|
"regexp"
|
|
"strings"
|
|
)
|
|
|
|
var (
|
|
reBearer = regexp.MustCompile(`(?i)(Bearer\s+)[A-Za-z0-9._\-]+`)
|
|
reSkKey = regexp.MustCompile(`(?i)\b(sk-[A-Za-z0-9]{8,})`)
|
|
rePassword = regexp.MustCompile(`(?i)(password|passwd|pwd)\s*[=:]\s*\S+`)
|
|
reDSN = regexp.MustCompile(`(?i)\b((?:mysql|postgres|postgresql|mongodb|redis)://[^:\s/]+):([^@\s]+)@`)
|
|
rePEM = regexp.MustCompile(`(?s)-----BEGIN [A-Z0-9 ]*PRIVATE KEY-----.*?-----END [A-Z0-9 ]*PRIVATE KEY-----`)
|
|
)
|
|
|
|
// RedactSensitive 脱敏:落盘 / 审计 summary / 展示共用。
|
|
func RedactSensitive(s string) string {
|
|
if s == "" {
|
|
return s
|
|
}
|
|
s = rePEM.ReplaceAllString(s, "[REDACTED_PRIVATE_KEY]")
|
|
s = reDSN.ReplaceAllString(s, "${1}:[REDACTED]@")
|
|
s = reBearer.ReplaceAllString(s, "${1}[REDACTED]")
|
|
s = reSkKey.ReplaceAllString(s, "sk-[REDACTED]")
|
|
s = rePassword.ReplaceAllString(s, "${1}=[REDACTED]")
|
|
return s
|
|
}
|
|
|
|
// RedactMessages 对消息 Content 做脱敏(不改 tool_call 结构)。
|
|
func RedactMessages(msgs []Message) []Message {
|
|
out := make([]Message, len(msgs))
|
|
copy(out, msgs)
|
|
for i := range out {
|
|
out[i].Content = RedactSensitive(out[i].Content)
|
|
}
|
|
return out
|
|
}
|
|
|
|
// NormalizeStatement 确认绑定前规范化 SQL/命令。
|
|
func NormalizeStatement(s string) string {
|
|
return strings.Join(strings.Fields(strings.TrimSpace(s)), " ")
|
|
}
|