feat: prepare GoodBuddy 0.8.0

This commit is contained in:
lofyer
2026-08-05 19:40:40 +08:00
parent 38ac2206f2
commit 39a457ded8
96 changed files with 14221 additions and 1027 deletions
+85 -1
View File
@@ -35,16 +35,100 @@ function redactValue(
export function redactSensitiveText(value: string): string {
return value
.replace(
/\bAuthorization\b(\s*[:=]\s*)Bearer\s+\S+/giu,
/\bAuthorization\b(\s*[:=]\s*)(?:"[^"\r\n]*"|'[^'\r\n]*'|[^\r\n,;}]+)/giu,
'Authorization$1[REDACTED]'
)
.replace(/\bBearer\s+\S+/giu, 'Bearer [REDACTED]')
.replace(
/(["']?)(api[-_ ]?key|token|secret|password|authorization)\1(\s*[:=]\s*)"[^"\r\n]*"/giu,
'$1$2$1$3"[REDACTED]"'
)
.replace(
/(["']?)(api[-_ ]?key|token|secret|password|authorization)\1(\s*[:=]\s*)'[^'\r\n]*'/giu,
"$1$2$1$3'[REDACTED]'"
)
.replace(
/\b(api[-_ ]?key|token|secret|password|authorization)\b(\s*[:=]\s*|\s+)(["']?)[^\s"',}]+/giu,
'$1$2[REDACTED]'
)
}
export function safeToolErrorDetail(
value: unknown,
maximum = 2_000
): string | undefined {
if (!Number.isSafeInteger(maximum) || maximum < 1) {
return undefined
}
const parts: string[] = []
let remaining = maximum
const seen = new WeakSet<object>()
const collect = (candidate: unknown, depth = 0): void => {
if (remaining <= 0 || depth > 4 || candidate === undefined) {
return
}
if (typeof candidate === 'string') {
const boundedCandidate = candidate.slice(
0,
Math.min(candidate.length, remaining * 4)
)
const text = redactSensitiveText(
[...boundedCandidate]
.filter((character) => {
const code = character.charCodeAt(0)
return (
code === 9 ||
code === 10 ||
code === 13 ||
(code > 31 && code !== 127)
)
})
.join('')
).trim()
if (!text) {
return
}
const separator = parts.length > 0 ? '\n' : ''
const available = Math.max(0, remaining - separator.length)
if (available === 0) {
return
}
const bounded = text.slice(0, available)
parts.push(`${separator}${bounded}`)
remaining -= separator.length + bounded.length
return
}
if (!candidate || typeof candidate !== 'object') {
return
}
if (seen.has(candidate)) {
return
}
seen.add(candidate)
if (Array.isArray(candidate)) {
for (const item of candidate.slice(0, 20)) {
collect(item, depth + 1)
}
return
}
const record = candidate as Record<string, unknown>
for (const key of [
'content',
'message',
'error',
'stderr',
'detail',
'data'
]) {
collect(record[key], depth + 1)
}
}
collect(value)
return parts.join('').trim() || undefined
}
export function safeToolArgumentSummary(
toolArguments: Record<string, unknown>,
preview?: unknown[],