From 56ea6b6e43b4147ee48e231d918f5b224d90211c Mon Sep 17 00:00:00 2001 From: Peter Steinberger Date: Thu, 1 Jan 2026 17:30:19 +0100 Subject: [PATCH] fix: align tool schemas and health snapshot --- package.json | 5 +++++ pnpm-lock.yaml | 5 ++++- src/agents/bash-tools.ts | 23 ++++++++++++++++++----- src/agents/clawdis-tools.ts | 5 +++-- src/agents/pi-tools.ts | 7 ++++--- src/commands/health.snapshot.test.ts | 1 + src/config/config.ts | 23 ++++++++++++----------- 7 files changed, 47 insertions(+), 22 deletions(-) diff --git a/package.json b/package.json index 30a30a37d..13a57461d 100644 --- a/package.json +++ b/package.json @@ -127,6 +127,11 @@ "vitest": "^4.0.16", "wireit": "^0.14.12" }, + "pnpm": { + "overrides": { + "@sinclair/typebox": "0.34.45" + } + }, "vitest": { "coverage": { "provider": "v8", diff --git a/pnpm-lock.yaml b/pnpm-lock.yaml index d524e4c4a..5894da5e1 100644 --- a/pnpm-lock.yaml +++ b/pnpm-lock.yaml @@ -4,6 +4,9 @@ settings: autoInstallPeers: true excludeLinksFromLockfile: false +overrides: + '@sinclair/typebox': 0.34.45 + patchedDependencies: '@mariozechner/pi-ai': hash: bf3e904ebaad236b8c3bb48c7d1150a1463735e783acaab6d15d6cd381b43832 @@ -29,7 +32,7 @@ importers: specifier: ^0.30.2 version: 0.30.2(ws@8.18.3)(zod@4.2.1) '@sinclair/typebox': - specifier: ^0.34.45 + specifier: 0.34.45 version: 0.34.45 '@whiskeysockets/baileys': specifier: 7.0.0-rc.9 diff --git a/src/agents/bash-tools.ts b/src/agents/bash-tools.ts index d0ac65f47..30e43a875 100644 --- a/src/agents/bash-tools.ts +++ b/src/agents/bash-tools.ts @@ -1,7 +1,6 @@ import { type ChildProcessWithoutNullStreams, spawn } from "node:child_process"; import { randomUUID } from "node:crypto"; import type { AgentTool, AgentToolResult } from "@mariozechner/pi-ai"; -import { StringEnum } from "@mariozechner/pi-ai"; import { Type } from "@sinclair/typebox"; import { @@ -31,6 +30,18 @@ const DEFAULT_MAX_OUTPUT = clampNumber( 150_000, ); +const stringEnum = ( + values: readonly string[], + options?: Parameters[1], +) => + Type.Union( + values.map((value) => Type.Literal(value)) as [ + ReturnType, + ...ReturnType[], + ], + options, + ); + export type BashToolDefaults = { backgroundMs?: number; timeoutSec?: number; @@ -60,7 +71,7 @@ const bashSchema = Type.Object({ }), ), stdinMode: Type.Optional( - StringEnum(["pipe", "pty"] as const, { + stringEnum(["pipe", "pty"] as const, { description: "Only pipe is supported", }), ), @@ -83,7 +94,8 @@ export type BashToolDetails = export function createBashTool( defaults?: BashToolDefaults, -): AgentTool { + // biome-ignore lint/suspicious/noExplicitAny: TypeBox schema type from pi-ai uses a different module instance. +): AgentTool { const defaultBackgroundMs = clampNumber( defaults?.backgroundMs ?? readEnvInt("PI_BASH_YIELD_MS"), 20_000, @@ -329,7 +341,7 @@ export function createBashTool( export const bashTool = createBashTool(); const processSchema = Type.Object({ - action: StringEnum( + action: stringEnum( ["list", "poll", "log", "write", "kill", "clear", "remove"] as const, { description: "Process action", @@ -346,7 +358,8 @@ const processSchema = Type.Object({ export function createProcessTool( defaults?: ProcessToolDefaults, -): AgentTool { + // biome-ignore lint/suspicious/noExplicitAny: TypeBox schema type from pi-ai uses a different module instance. +): AgentTool { if (defaults?.cleanupMs !== undefined) { setJobTtlMs(defaults.cleanupMs); } diff --git a/src/agents/clawdis-tools.ts b/src/agents/clawdis-tools.ts index 0a273008e..e77a66472 100644 --- a/src/agents/clawdis-tools.ts +++ b/src/agents/clawdis-tools.ts @@ -2,7 +2,7 @@ import crypto from "node:crypto"; import fs from "node:fs/promises"; import type { AgentTool, AgentToolResult } from "@mariozechner/pi-ai"; -import { type TSchema, Type } from "@sinclair/typebox"; +import { Type } from "@sinclair/typebox"; import { browserCloseTab, browserFocusTab, @@ -45,7 +45,8 @@ import { callGateway } from "../gateway/call.js"; import { detectMime } from "../media/mime.js"; import { sanitizeToolResultImages } from "./tool-images.js"; -type AnyAgentTool = AgentTool; +// biome-ignore lint/suspicious/noExplicitAny: TypeBox schema type from pi-ai uses a different module instance. +type AnyAgentTool = AgentTool; const DEFAULT_GATEWAY_URL = "ws://127.0.0.1:18789"; diff --git a/src/agents/pi-tools.ts b/src/agents/pi-tools.ts index ffd5bb339..b7c9c9cc4 100644 --- a/src/agents/pi-tools.ts +++ b/src/agents/pi-tools.ts @@ -1,6 +1,6 @@ import type { AgentTool, AgentToolResult } from "@mariozechner/pi-ai"; import { codingTools, readTool } from "@mariozechner/pi-coding-agent"; -import { type TSchema, Type } from "@sinclair/typebox"; +import { Type } from "@sinclair/typebox"; import { detectMime } from "../media/mime.js"; import { startWebLoginWithQr, waitForWebLogin } from "../web/login-qr.js"; @@ -103,7 +103,8 @@ async function normalizeReadImageResult( return { ...result, content: nextContent }; } -type AnyAgentTool = AgentTool; +// biome-ignore lint/suspicious/noExplicitAny: TypeBox schema type from pi-ai uses a different module instance. +type AnyAgentTool = AgentTool; function extractEnumValues(schema: unknown): unknown[] | undefined { if (!schema || typeof schema !== "object") return undefined; @@ -204,7 +205,7 @@ function normalizeToolParameters(tool: AnyAgentTool): AnyAgentTool { : {}), additionalProperties: "additionalProperties" in schema ? schema.additionalProperties : true, - } as unknown as TSchema, + }, }; } diff --git a/src/commands/health.snapshot.test.ts b/src/commands/health.snapshot.test.ts index cdeb5a505..4de1fa2a5 100644 --- a/src/commands/health.snapshot.test.ts +++ b/src/commands/health.snapshot.test.ts @@ -109,6 +109,7 @@ describe("getHealthSnapshot", () => { fs.writeFileSync(tokenFile, "t-file\n", "utf-8"); testConfig = { telegram: { tokenFile } }; testStore = {}; + vi.stubEnv("TELEGRAM_BOT_TOKEN", ""); const calls: string[] = []; vi.stubGlobal( diff --git a/src/config/config.ts b/src/config/config.ts index fe898c89d..c9cbf4b5b 100644 --- a/src/config/config.ts +++ b/src/config/config.ts @@ -431,7 +431,6 @@ export type ClawdisConfig = { canvasHost?: CanvasHostConfig; talk?: TalkConfig; gateway?: GatewayConfig; - skills?: SkillsConfig; }; /** @@ -903,16 +902,18 @@ const ClawdisSchema = z.object({ .optional(), }) .optional(), - entries: z.record( - z.string(), - z - .object({ - enabled: z.boolean().optional(), - apiKey: z.string().optional(), - env: z.record(z.string(), z.string()).optional(), - }) - .passthrough(), - ).optional(), + entries: z + .record( + z.string(), + z + .object({ + enabled: z.boolean().optional(), + apiKey: z.string().optional(), + env: z.record(z.string(), z.string()).optional(), + }) + .passthrough(), + ) + .optional(), }) .optional(), });