


























@@ -1,14 +1,14 @@
11import type { AgentMessage } from "@earendil-works/pi-agent-core";
22import type { SessionManager } from "@earendil-works/pi-coding-agent";
33import type { OpenClawConfig } from "../config/types.openclaw.js";
4-import { redactSensitiveText } from "../logging/redact.js";
54import { getGlobalHookRunner } from "../plugins/hook-runner-global.js";
65import {
76applyInputProvenanceToUserMessage,
87type InputProvenance,
98} from "../sessions/input-provenance.js";
109import { resolveLiveToolResultMaxChars } from "./pi-embedded-runner/tool-result-truncation.js";
1110import { installSessionToolResultGuard } from "./session-tool-result-guard.js";
11+import { redactTranscriptMessage } from "./transcript-redact.js";
12121313type GuardedSessionManager = SessionManager & {
1414/** Flush any synthetic tool results for pending tool calls. Idempotent. */
@@ -17,71 +17,6 @@ type GuardedSessionManager = SessionManager & {
1717clearPendingToolResults?: () => void;
1818};
191920-function redactTranscriptText(value: string, cfg?: OpenClawConfig): string {
21-if (cfg?.logging?.redactSensitive === "off") {
22-return value;
23-}
24-return redactSensitiveText(value, {
25-mode: cfg?.logging?.redactSensitive,
26-patterns: cfg?.logging?.redactPatterns,
27-});
28-}
29-30-function redactTranscriptContentBlock(block: unknown, cfg?: OpenClawConfig): unknown {
31-if (!block || typeof block !== "object" || Array.isArray(block)) {
32-return block;
33-}
34-const source = block as Record<string, unknown>;
35-let next: Record<string, unknown> | null = null;
36-const assign = (key: string, value: string) => {
37-const redacted = redactTranscriptText(value, cfg);
38-if (redacted === value) {
39-return;
40-}
41-next ??= { ...source };
42-next[key] = redacted;
43-};
44-45-if (typeof source.text === "string") {
46-assign("text", source.text);
47-}
48-if (typeof source.thinking === "string") {
49-assign("thinking", source.thinking);
50-}
51-if (typeof source.partialJson === "string") {
52-assign("partialJson", source.partialJson);
53-}
54-return next ?? block;
55-}
56-57-function redactTranscriptContent(content: unknown, cfg?: OpenClawConfig): unknown {
58-if (typeof content === "string") {
59-return redactTranscriptText(content, cfg);
60-}
61-if (!Array.isArray(content)) {
62-return content;
63-}
64-let changed = false;
65-const redacted = content.map((block) => {
66-const next = redactTranscriptContentBlock(block, cfg);
67-changed ||= next !== block;
68-return next;
69-});
70-return changed ? redacted : content;
71-}
72-73-function redactTranscriptMessage(message: AgentMessage, cfg?: OpenClawConfig): AgentMessage {
74-const source = message as unknown as Record<string, unknown>;
75-const redactedContent = redactTranscriptContent(source.content, cfg);
76-if (redactedContent === source.content) {
77-return message;
78-}
79-return {
80- ...source,
81-content: redactedContent,
82-} as unknown as AgentMessage;
83-}
84-8520/**
8621 * Apply the tool-result guard to a SessionManager exactly once and expose
8722 * a flush method on the instance for easy teardown handling.
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。