mirror of
https://github.com/openclaw/openclaw.git
synced 2026-08-12 21:53:00 -06:00
refactor(cron): share diagnostic summary normalization (#113595)
This commit is contained in:
@@ -113,7 +113,7 @@ function normalizeDiagnosticMessage(
|
||||
return { message: `${truncateUtf16Safe(redacted, MAX_ENTRY_CHARS - 1)}…`, truncated: true };
|
||||
}
|
||||
|
||||
function trimSummary(value: string | undefined): string | undefined {
|
||||
export function normalizeCronRunDiagnosticSummary(value: string | undefined): string | undefined {
|
||||
const normalized = normalizeOptionalString(value);
|
||||
if (!normalized) {
|
||||
return undefined;
|
||||
@@ -167,7 +167,7 @@ export function normalizeCronRunDiagnostics(
|
||||
entries.shift();
|
||||
}
|
||||
}
|
||||
const summary = trimSummary(
|
||||
const summary = normalizeCronRunDiagnosticSummary(
|
||||
typeof record.summary === "string" ? redactText(record.summary) : undefined,
|
||||
);
|
||||
if (entries.length === 0 && !summary) {
|
||||
|
||||
@@ -90,6 +90,21 @@ describe("cron run diagnostics", () => {
|
||||
expect(summarizeCronRunDiagnostics(undefined)).toBeUndefined();
|
||||
});
|
||||
|
||||
it("bounds fallback summaries at valid UTF-16 boundaries", () => {
|
||||
expect(
|
||||
summarizeCronRunDiagnostics({
|
||||
entries: [
|
||||
{
|
||||
ts: 1,
|
||||
source: "exec",
|
||||
severity: "error",
|
||||
message: `${"s".repeat(1_998)}😀tail`,
|
||||
},
|
||||
],
|
||||
}),
|
||||
).toBe(`${"s".repeat(1_998)}…`);
|
||||
});
|
||||
|
||||
it("creates diagnostics from errors and prefers the latest error summary", () => {
|
||||
const first = createCronRunDiagnosticsFromError("cron-preflight", "first failure", {
|
||||
nowMs: () => 100,
|
||||
|
||||
@@ -1,6 +1,5 @@
|
||||
/** Builds bounded, redacted diagnostics for cron run logs and UI surfaces. */
|
||||
import { normalizeOptionalString } from "@openclaw/normalization-core/string-coerce";
|
||||
import { truncateUtf16Safe } from "@openclaw/normalization-core/utf16-slice";
|
||||
import { isToolAllowedByPolicyName } from "../agents/tool-policy-match.js";
|
||||
import { normalizeToolName as normalizePolicyToolName } from "../agents/tool-policy.js";
|
||||
import { getReplyPayloadMetadata } from "../auto-reply/reply-payload.js";
|
||||
@@ -8,6 +7,7 @@ import { redactSensitiveText } from "../logging/redact.js";
|
||||
import {
|
||||
formatUnknownError,
|
||||
isRecord,
|
||||
normalizeCronRunDiagnosticSummary,
|
||||
normalizeCronRunDiagnostics as normalizeCronRunDiagnosticsValue,
|
||||
normalizeExitCode,
|
||||
normalizeToolName,
|
||||
@@ -20,7 +20,6 @@ import type {
|
||||
CronRunDiagnosticSource,
|
||||
} from "./types.js";
|
||||
|
||||
const MAX_SUMMARY_CHARS = 2_000;
|
||||
const EXEC_DIAGNOSTIC_TAIL_CHARS = 2_000;
|
||||
const WEB_SEARCH_TOOL_NAME = "web_search";
|
||||
|
||||
@@ -37,17 +36,6 @@ export function toolsAllowRequestsWebSearch(toolsAllow?: string[]): boolean {
|
||||
);
|
||||
}
|
||||
|
||||
function trimSummary(value: string | undefined): string | undefined {
|
||||
const normalized = normalizeOptionalString(value);
|
||||
if (!normalized) {
|
||||
return undefined;
|
||||
}
|
||||
if (normalized.length <= MAX_SUMMARY_CHARS) {
|
||||
return normalized;
|
||||
}
|
||||
return `${truncateUtf16Safe(normalized, MAX_SUMMARY_CHARS - 1)}…`;
|
||||
}
|
||||
|
||||
/** Returns the operator-facing summary for persisted cron diagnostics. */
|
||||
export function summarizeCronRunDiagnostics(
|
||||
diagnostics: CronRunDiagnostics | undefined,
|
||||
@@ -55,7 +43,7 @@ export function summarizeCronRunDiagnostics(
|
||||
if (!diagnostics) {
|
||||
return undefined;
|
||||
}
|
||||
return trimSummary(diagnostics.summary ?? diagnostics.entries[0]?.message);
|
||||
return normalizeCronRunDiagnosticSummary(diagnostics.summary ?? diagnostics.entries[0]?.message);
|
||||
}
|
||||
|
||||
/** Normalizes untrusted cron diagnostic payloads into bounded, redacted entries. */
|
||||
@@ -84,7 +72,9 @@ export function mergeCronRunDiagnostics(
|
||||
normalized.entries.findLast((entry) => entry.severity === "error") ??
|
||||
normalized.entries.findLast((entry) => entry.severity === "warn") ??
|
||||
normalized.entries.findLast((entry) => entry.severity === "info");
|
||||
const summary = trimSummary(normalized.summary ?? entryCandidate?.message);
|
||||
const summary = normalizeCronRunDiagnosticSummary(
|
||||
normalized.summary ?? entryCandidate?.message,
|
||||
);
|
||||
if (summary) {
|
||||
const severity =
|
||||
entryCandidate?.severity === "error" ? 2 : entryCandidate?.severity === "warn" ? 1 : 0;
|
||||
|
||||
Reference in New Issue
Block a user