fix: validate llm task numeric options · openclaw/openclaw@f77e09f
steipete
·
2026-05-29
·
via Recent Commits to openclaw:main
| Original file line number | Diff line number | Diff line change |
|---|
@@ -295,4 +295,46 @@ describe("llm-task tool (json-only)", () => {
|
295 | 295 | const call = await executeEmbeddedRun({ prompt: "x" }); |
296 | 296 | expect(call.disableTools).toBe(true); |
297 | 297 | }); |
| 298 | + |
| 299 | +it("drops malformed numeric run options before dispatch", async () => { |
| 300 | +mockEmbeddedRunJson({ ok: true }); |
| 301 | +const tool = createLlmTaskTool( |
| 302 | +fakeApi({ |
| 303 | +pluginConfig: { |
| 304 | +maxTokens: Number.POSITIVE_INFINITY, |
| 305 | +timeoutMs: 4096.5, |
| 306 | +}, |
| 307 | +}), |
| 308 | +); |
| 309 | + |
| 310 | +await tool.execute("id", { |
| 311 | +prompt: "x", |
| 312 | +temperature: Number.NaN, |
| 313 | +maxTokens: 0, |
| 314 | +timeoutMs: -1, |
| 315 | +}); |
| 316 | + |
| 317 | +const call = (runEmbeddedAgent as any).mock.calls[0]?.[0]; |
| 318 | +expect(call.timeoutMs).toBe(30_000); |
| 319 | +expect(call.streamParams).toEqual({ |
| 320 | +temperature: undefined, |
| 321 | +maxTokens: undefined, |
| 322 | +}); |
| 323 | +}); |
| 324 | + |
| 325 | +it("passes valid numeric run options before dispatch", async () => { |
| 326 | +mockEmbeddedRunJson({ ok: true }); |
| 327 | +const call = await executeEmbeddedRun({ |
| 328 | +prompt: "x", |
| 329 | +temperature: 0.2, |
| 330 | +maxTokens: 512, |
| 331 | +timeoutMs: 10_000, |
| 332 | +}); |
| 333 | + |
| 334 | +expect(call.timeoutMs).toBe(10_000); |
| 335 | +expect(call.streamParams).toEqual({ |
| 336 | +temperature: 0.2, |
| 337 | +maxTokens: 512, |
| 338 | +}); |
| 339 | +}); |
298 | 340 | }); |
| Original file line number | Diff line number | Diff line change |
|---|
@@ -4,7 +4,11 @@ import {
|
4 | 4 | type JsonSchemaObject, |
5 | 5 | validateJsonSchemaValue, |
6 | 6 | } from "openclaw/plugin-sdk/json-schema-runtime"; |
7 | | -import { normalizeOptionalString } from "openclaw/plugin-sdk/string-coerce-runtime"; |
| 7 | +import { |
| 8 | +asFiniteNumber, |
| 9 | +asPositiveSafeInteger, |
| 10 | +normalizeOptionalString, |
| 11 | +} from "openclaw/plugin-sdk/string-coerce-runtime"; |
8 | 12 | import { Type } from "typebox"; |
9 | 13 | import { resolvePreferredOpenClawTmpDir, withTempWorkspace } from "../api.js"; |
10 | 14 | import type { OpenClawPluginApi } from "../api.js"; |
@@ -220,22 +224,14 @@ export function createLlmTaskTool(api: OpenClawPluginApi) {
|
220 | 224 | } |
221 | 225 | |
222 | 226 | const timeoutMs = |
223 | | -(typeof params.timeoutMs === "number" && params.timeoutMs > 0 |
224 | | - ? params.timeoutMs |
225 | | - : undefined) || |
226 | | -(typeof pluginCfg.timeoutMs === "number" && pluginCfg.timeoutMs > 0 |
227 | | - ? pluginCfg.timeoutMs |
228 | | - : undefined) || |
| 227 | +asPositiveSafeInteger(params.timeoutMs) ?? |
| 228 | +asPositiveSafeInteger(pluginCfg.timeoutMs) ?? |
229 | 229 | 30_000; |
230 | 230 | |
231 | 231 | const streamParams = { |
232 | | -temperature: typeof params.temperature === "number" ? params.temperature : undefined, |
| 232 | +temperature: asFiniteNumber(params.temperature), |
233 | 233 | maxTokens: |
234 | | -typeof params.maxTokens === "number" |
235 | | - ? params.maxTokens |
236 | | - : typeof pluginCfg.maxTokens === "number" |
237 | | - ? pluginCfg.maxTokens |
238 | | - : undefined, |
| 234 | +asPositiveSafeInteger(params.maxTokens) ?? asPositiveSafeInteger(pluginCfg.maxTokens), |
239 | 235 | }; |
240 | 236 | |
241 | 237 | const input = params.input; |
|
此内容由惯性聚合(RSS阅读器)自动聚合整理,仅供阅读参考。 原文来自 — 版权归原作者所有。