mirror of
https://github.com/openclaw/openclaw.git
synced 2026-06-06 05:51:15 +08:00
fix: validate session tool numeric params
This commit is contained in:
@@ -247,7 +247,7 @@ describe("sessions tools", () => {
|
||||
});
|
||||
});
|
||||
|
||||
it("uses number (not integer) in tool schemas for Gemini compatibility", () => {
|
||||
it("uses integer schemas for session count and window parameters", () => {
|
||||
const tools = createOpenClawTools();
|
||||
const byName = (name: string) => {
|
||||
const tool = tools.find((candidate) => candidate.name === name);
|
||||
@@ -275,10 +275,10 @@ describe("sessions tools", () => {
|
||||
return value;
|
||||
};
|
||||
|
||||
expect(schemaProp("sessions_history", "limit").type).toBe("number");
|
||||
expect(schemaProp("sessions_list", "limit").type).toBe("number");
|
||||
expect(schemaProp("sessions_list", "activeMinutes").type).toBe("number");
|
||||
expect(schemaProp("sessions_list", "messageLimit").type).toBe("number");
|
||||
expect(schemaProp("sessions_history", "limit").type).toBe("integer");
|
||||
expect(schemaProp("sessions_list", "limit").type).toBe("integer");
|
||||
expect(schemaProp("sessions_list", "activeMinutes").type).toBe("integer");
|
||||
expect(schemaProp("sessions_list", "messageLimit").type).toBe("integer");
|
||||
expect(schemaProp("sessions_list", "label").type).toBe("string");
|
||||
expect(schemaProp("sessions_list", "agentId").type).toBe("string");
|
||||
expect(schemaProp("sessions_list", "search").type).toBe("string");
|
||||
|
||||
@@ -83,4 +83,12 @@ describe("sessions_history redaction", () => {
|
||||
expect(serialized).toContain("intern");
|
||||
expect((result.details as { contentRedacted?: unknown }).contentRedacted).toBe(true);
|
||||
});
|
||||
|
||||
it.each([0, 1.5])("rejects invalid limit value %s", async (limit) => {
|
||||
const tool = createHistoryToolWithMessage("hello");
|
||||
|
||||
await expect(tool.execute("call-1", { sessionKey: "main", limit })).rejects.toThrow(
|
||||
"limit must be a positive integer",
|
||||
);
|
||||
});
|
||||
});
|
||||
|
||||
@@ -12,7 +12,7 @@ import {
|
||||
SESSIONS_HISTORY_TOOL_DISPLAY_SUMMARY,
|
||||
} from "../tool-description-presets.js";
|
||||
import type { AnyAgentTool } from "./common.js";
|
||||
import { jsonResult, readStringParam } from "./common.js";
|
||||
import { jsonResult, readPositiveIntegerParam, readStringParam } from "./common.js";
|
||||
import {
|
||||
createSessionVisibilityGuard,
|
||||
createAgentToAgentPolicy,
|
||||
@@ -25,7 +25,7 @@ import {
|
||||
|
||||
const SessionsHistoryToolSchema = Type.Object({
|
||||
sessionKey: Type.String(),
|
||||
limit: Type.Optional(Type.Number({ minimum: 1 })),
|
||||
limit: Type.Optional(Type.Integer({ minimum: 1 })),
|
||||
includeTools: Type.Optional(Type.Boolean()),
|
||||
});
|
||||
|
||||
@@ -247,10 +247,7 @@ export function createSessionsHistoryTool(opts?: {
|
||||
});
|
||||
}
|
||||
|
||||
const limit =
|
||||
typeof params.limit === "number" && Number.isFinite(params.limit)
|
||||
? Math.max(1, Math.floor(params.limit))
|
||||
: undefined;
|
||||
const limit = readPositiveIntegerParam(params, "limit");
|
||||
const includeTools = Boolean(params.includeTools);
|
||||
const result = await gatewayCall<{ messages: Array<unknown> }>({
|
||||
method: "chat.history",
|
||||
|
||||
@@ -193,4 +193,16 @@ describe("sessions-list-tool", () => {
|
||||
expect(session?.elevatedLevel).toBe("on");
|
||||
expect(session?.responseUsage).toBe("full");
|
||||
});
|
||||
|
||||
it.each([
|
||||
[{ limit: 1.5 }, "limit must be a positive integer"],
|
||||
[{ activeMinutes: 0 }, "activeMinutes must be a positive integer"],
|
||||
[{ messageLimit: 1.5 }, "messageLimit must be a non-negative integer"],
|
||||
[{ messageLimit: -1 }, "messageLimit must be a non-negative integer"],
|
||||
])("rejects invalid numeric parameter %o", async (params, message) => {
|
||||
const tool = createSessionsListTool({ config: {} as never });
|
||||
|
||||
await expect(tool.execute("call-4", params)).rejects.toThrow(message);
|
||||
expect(mocks.gatewayCall).not.toHaveBeenCalled();
|
||||
});
|
||||
});
|
||||
|
||||
@@ -21,7 +21,13 @@ import {
|
||||
SESSIONS_LIST_TOOL_DISPLAY_SUMMARY,
|
||||
} from "../tool-description-presets.js";
|
||||
import type { AnyAgentTool } from "./common.js";
|
||||
import { jsonResult, readStringArrayParam, readStringParam } from "./common.js";
|
||||
import {
|
||||
jsonResult,
|
||||
readNonNegativeIntegerParam,
|
||||
readPositiveIntegerParam,
|
||||
readStringArrayParam,
|
||||
readStringParam,
|
||||
} from "./common.js";
|
||||
import {
|
||||
createAgentToAgentPolicy,
|
||||
createSessionVisibilityRowChecker,
|
||||
@@ -38,9 +44,9 @@ import {
|
||||
|
||||
const SessionsListToolSchema = Type.Object({
|
||||
kinds: Type.Optional(Type.Array(Type.String())),
|
||||
limit: Type.Optional(Type.Number({ minimum: 1 })),
|
||||
activeMinutes: Type.Optional(Type.Number({ minimum: 1 })),
|
||||
messageLimit: Type.Optional(Type.Number({ minimum: 0 })),
|
||||
limit: Type.Optional(Type.Integer({ minimum: 1 })),
|
||||
activeMinutes: Type.Optional(Type.Integer({ minimum: 1 })),
|
||||
messageLimit: Type.Optional(Type.Integer({ minimum: 0 })),
|
||||
label: Type.Optional(Type.String({ minLength: 1 })),
|
||||
agentId: Type.Optional(Type.String({ minLength: 1, maxLength: 64 })),
|
||||
search: Type.Optional(Type.String({ minLength: 1 })),
|
||||
@@ -97,18 +103,9 @@ export function createSessionsListTool(opts?: {
|
||||
);
|
||||
const allowedKinds = allowedKindsList.length ? new Set(allowedKindsList) : undefined;
|
||||
|
||||
const limit =
|
||||
typeof params.limit === "number" && Number.isFinite(params.limit)
|
||||
? Math.max(1, Math.floor(params.limit))
|
||||
: undefined;
|
||||
const activeMinutes =
|
||||
typeof params.activeMinutes === "number" && Number.isFinite(params.activeMinutes)
|
||||
? Math.max(1, Math.floor(params.activeMinutes))
|
||||
: undefined;
|
||||
const messageLimitRaw =
|
||||
typeof params.messageLimit === "number" && Number.isFinite(params.messageLimit)
|
||||
? Math.max(0, Math.floor(params.messageLimit))
|
||||
: 0;
|
||||
const limit = readPositiveIntegerParam(params, "limit");
|
||||
const activeMinutes = readPositiveIntegerParam(params, "activeMinutes");
|
||||
const messageLimitRaw = readNonNegativeIntegerParam(params, "messageLimit") ?? 0;
|
||||
const messageLimit = Math.min(messageLimitRaw, 20);
|
||||
const label = readStringParam(params, "label");
|
||||
const agentId = readStringParam(params, "agentId");
|
||||
|
||||
Reference in New Issue
Block a user