fix: parse diffs numeric options

This commit is contained in:
Peter Steinberger
2026-05-28 21:22:05 -04:00
parent c0d525c8a0
commit fd8353012f
3 changed files with 45 additions and 44 deletions
+3 -3
View File
@@ -206,7 +206,7 @@ describe("diffs tool", () => {
before: "one\n",
after: "two\n",
mode: "file",
ttlSeconds: 1,
ttlSeconds: "1",
});
const filePath = requireString(readDetails(result).filePath, "filePath");
await fs.access(filePath);
@@ -263,8 +263,8 @@ describe("diffs tool", () => {
after: "two\n",
mode: "file",
imageQuality: "hq",
imageScale: 2.4,
imageMaxWidth: 1100,
imageScale: "2.4",
imageMaxWidth: "1100",
});
expect((result?.details as Record<string, unknown>).fileQuality).toBe("hq");
+41 -41
View File
@@ -1,6 +1,7 @@
import fs from "node:fs/promises";
import { stringEnum } from "openclaw/plugin-sdk/channel-actions";
import { optionalFiniteNumberSchema, stringEnum } from "openclaw/plugin-sdk/channel-actions";
import { formatErrorMessage } from "openclaw/plugin-sdk/error-runtime";
import { readFiniteNumberParam } from "openclaw/plugin-sdk/param-readers";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import { Type } from "typebox";
import type { Static } from "typebox";
@@ -82,20 +83,16 @@ const DiffsToolSchema = Type.Object(
fileFormat: Type.Optional(
stringEnum(DIFF_OUTPUT_FORMATS, { description: "Rendered file format: png or pdf." }),
),
fileScale: Type.Optional(
Type.Number({
description: "Optional rendered-file device scale factor override (1-4).",
minimum: 1,
maximum: 4,
}),
),
fileMaxWidth: Type.Optional(
Type.Number({
description: "Optional rendered-file max width in CSS pixels (640-2400).",
minimum: 640,
maximum: 2400,
}),
),
fileScale: optionalFiniteNumberSchema({
description: "Optional rendered-file device scale factor override (1-4).",
minimum: 1,
maximum: 4,
}),
fileMaxWidth: optionalFiniteNumberSchema({
description: "Optional rendered-file max width in CSS pixels (640-2400).",
minimum: 640,
maximum: 2400,
}),
/** @deprecated Use fileQuality. */
imageQuality: Type.Optional(
stringEnum(DIFF_IMAGE_QUALITY_PRESETS, {
@@ -111,33 +108,27 @@ const DiffsToolSchema = Type.Object(
}),
),
/** @deprecated Use fileScale. */
imageScale: Type.Optional(
Type.Number({
description: "Deprecated alias for fileScale.",
deprecated: true,
minimum: 1,
maximum: 4,
}),
),
imageScale: optionalFiniteNumberSchema({
description: "Deprecated alias for fileScale.",
deprecated: true,
minimum: 1,
maximum: 4,
}),
/** @deprecated Use fileMaxWidth. */
imageMaxWidth: Type.Optional(
Type.Number({
description: "Deprecated alias for fileMaxWidth.",
deprecated: true,
minimum: 640,
maximum: 2400,
}),
),
imageMaxWidth: optionalFiniteNumberSchema({
description: "Deprecated alias for fileMaxWidth.",
deprecated: true,
minimum: 640,
maximum: 2400,
}),
expandUnchanged: Type.Optional(
Type.Boolean({ description: "Expand unchanged sections instead of collapsing them." }),
),
ttlSeconds: Type.Optional(
Type.Number({
description: "Artifact lifetime in seconds. Default: 1800. Maximum: 21600.",
minimum: 1,
maximum: 21_600,
}),
),
ttlSeconds: optionalFiniteNumberSchema({
description: "Artifact lifetime in seconds. Default: 1800. Maximum: 21600.",
minimum: 1,
maximum: 21_600,
}),
baseUrl: Type.Optional(
Type.String({
description:
@@ -171,21 +162,30 @@ export function createDiffsTool(params: {
parameters: DiffsToolSchema,
execute: async (_toolCallId, rawParams) => {
const toolParams = rawParams as DiffsToolRawParams;
const rawRecord = rawParams as Record<string, unknown>;
const artifactContext = buildArtifactContext(params.context);
const input = normalizeDiffInput(toolParams);
const mode = normalizeMode(toolParams.mode, params.defaults.mode);
const theme = normalizeTheme(toolParams.theme, params.defaults.theme);
const layout = normalizeLayout(toolParams.layout, params.defaults.layout);
const expandUnchanged = toolParams.expandUnchanged === true;
const ttlMs = normalizeTtlMs(toolParams.ttlSeconds ?? params.defaults.ttlSeconds);
const ttlSeconds =
readFiniteNumberParam(rawRecord, "ttlSeconds") ?? params.defaults.ttlSeconds;
const fileScale =
readFiniteNumberParam(rawRecord, "fileScale") ??
readFiniteNumberParam(rawRecord, "imageScale");
const fileMaxWidth =
readFiniteNumberParam(rawRecord, "fileMaxWidth") ??
readFiniteNumberParam(rawRecord, "imageMaxWidth");
const ttlMs = normalizeTtlMs(ttlSeconds);
const image = resolveDiffImageRenderOptions({
defaults: params.defaults,
fileFormat: normalizeOutputFormat(
toolParams.fileFormat ?? toolParams.imageFormat ?? toolParams.format,
),
fileQuality: normalizeFileQuality(toolParams.fileQuality ?? toolParams.imageQuality),
fileScale: toolParams.fileScale ?? toolParams.imageScale,
fileMaxWidth: toolParams.fileMaxWidth ?? toolParams.imageMaxWidth,
fileScale,
fileMaxWidth,
});
const renderTarget = resolveRenderTarget(mode);
+1
View File
@@ -24,6 +24,7 @@ type IntegerSchemaOptions = {
type NumberSchemaOptions = {
description?: string;
deprecated?: boolean;
minimum?: number;
maximum?: number;
exclusiveMinimum?: number;