fix: simplify session tool schemas for Gemini compatibility (#599) (thanks @mcinteerj)

This commit is contained in:
Peter Steinberger
2026-01-09 20:17:46 +01:00
parent 423eef4624
commit 0edacd0469
3 changed files with 42 additions and 2 deletions

View File

@@ -23,6 +23,43 @@ vi.mock("../config/config.js", async (importOriginal) => {
import { createClawdbotTools } from "./clawdbot-tools.js";
describe("sessions tools", () => {
it("uses number (not integer) in tool schemas for Gemini compatibility", () => {
const tools = createClawdbotTools();
const byName = (name: string) => {
const tool = tools.find((candidate) => candidate.name === name);
expect(tool).toBeDefined();
if (!tool) throw new Error(`missing ${name} tool`);
return tool;
};
const schemaProp = (toolName: string, prop: string) => {
const tool = byName(toolName);
const schema = tool.parameters as {
anyOf?: unknown;
oneOf?: unknown;
properties?: Record<string, unknown>;
};
expect(schema.anyOf).toBeUndefined();
expect(schema.oneOf).toBeUndefined();
const properties = schema.properties ?? {};
const value = properties[prop] as { type?: unknown } | undefined;
expect(value).toBeDefined();
if (!value) throw new Error(`missing ${toolName} schema prop: ${prop}`);
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_send", "timeoutSeconds").type).toBe("number");
expect(schemaProp("sessions_spawn", "runTimeoutSeconds").type).toBe(
"number",
);
expect(schemaProp("sessions_spawn", "timeoutSeconds").type).toBe("number");
});
it("sessions_list filters kinds and includes messages", async () => {
callGatewayMock.mockReset();
callGatewayMock.mockImplementation(async (opts: unknown) => {

View File

@@ -32,8 +32,10 @@ import {
const SessionsSendToolSchema = Type.Object({
sessionKey: Type.Optional(Type.String()),
label: Type.Optional(Type.String()),
agentId: Type.Optional(Type.String()),
label: Type.Optional(
Type.String({ minLength: 1, maxLength: SESSION_LABEL_MAX_LENGTH }),
),
agentId: Type.Optional(Type.String({ minLength: 1, maxLength: 64 })),
message: Type.String(),
timeoutSeconds: Type.Optional(Type.Number({ minimum: 0 })),
});