fix: validate llm task numeric options

This commit is contained in:
Peter Steinberger
2026-05-28 18:07:37 -04:00
parent 4287cd2e6e
commit f77e09f78e
2 changed files with 51 additions and 13 deletions

View File

@@ -295,4 +295,46 @@ describe("llm-task tool (json-only)", () => {
const call = await executeEmbeddedRun({ prompt: "x" });
expect(call.disableTools).toBe(true);
});
it("drops malformed numeric run options before dispatch", async () => {
mockEmbeddedRunJson({ ok: true });
const tool = createLlmTaskTool(
fakeApi({
pluginConfig: {
maxTokens: Number.POSITIVE_INFINITY,
timeoutMs: 4096.5,
},
}),
);
await tool.execute("id", {
prompt: "x",
temperature: Number.NaN,
maxTokens: 0,
timeoutMs: -1,
});
const call = (runEmbeddedAgent as any).mock.calls[0]?.[0];
expect(call.timeoutMs).toBe(30_000);
expect(call.streamParams).toEqual({
temperature: undefined,
maxTokens: undefined,
});
});
it("passes valid numeric run options before dispatch", async () => {
mockEmbeddedRunJson({ ok: true });
const call = await executeEmbeddedRun({
prompt: "x",
temperature: 0.2,
maxTokens: 512,
timeoutMs: 10_000,
});
expect(call.timeoutMs).toBe(10_000);
expect(call.streamParams).toEqual({
temperature: 0.2,
maxTokens: 512,
});
});
});

View File

@@ -4,7 +4,11 @@ import {
type JsonSchemaObject,
validateJsonSchemaValue,
} from "openclaw/plugin-sdk/json-schema-runtime";
import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime";
import {
asFiniteNumber,
asPositiveSafeInteger,
normalizeOptionalString,
} from "openclaw/plugin-sdk/string-coerce-runtime";
import { Type } from "typebox";
import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "../api.js";
import type { OpenClawPluginApi } from "../api.js";
@@ -220,22 +224,14 @@ export function createLlmTaskTool(api: OpenClawPluginApi) {
}
const timeoutMs =
(typeof params.timeoutMs === "number" && params.timeoutMs > 0
? params.timeoutMs
: undefined) ||
(typeof pluginCfg.timeoutMs === "number" && pluginCfg.timeoutMs > 0
? pluginCfg.timeoutMs
: undefined) ||
asPositiveSafeInteger(params.timeoutMs) ??
asPositiveSafeInteger(pluginCfg.timeoutMs) ??
30_000;
const streamParams = {
temperature: typeof params.temperature === "number" ? params.temperature : undefined,
temperature: asFiniteNumber(params.temperature),
maxTokens:
typeof params.maxTokens === "number"
? params.maxTokens
: typeof pluginCfg.maxTokens === "number"
? pluginCfg.maxTokens
: undefined,
asPositiveSafeInteger(params.maxTokens) ?? asPositiveSafeInteger(pluginCfg.maxTokens),
};
const input = params.input;