From 861e8c2b7e70289d68c18643d4db40f386439962 Mon Sep 17 00:00:00 2001 From: Ajax Davis Date: Wed, 17 Dec 2025 19:56:01 +1000 Subject: [PATCH] fix: add backwards compatibility for exportName in tpmjs schema The TpmjsToolDefinitionSchema now accepts both 'name' and 'exportName' fields, transforming exportName to name for backward compatibility with published packages that still use the old field name. Also fix type errors in sync routes for auto-discovered tools. --- apps/web/src/app/api/sync/changes/route.ts | 3 ++ apps/web/src/app/api/sync/keyword/route.ts | 3 ++ packages/types/src/tpmjs.ts | 48 ++++++++++++++++------ 3 files changed, 42 insertions(+), 12 deletions(-) diff --git a/apps/web/src/app/api/sync/changes/route.ts b/apps/web/src/app/api/sync/changes/route.ts index e786e84..9ebfd4c 100644 --- a/apps/web/src/app/api/sync/changes/route.ts +++ b/apps/web/src/app/api/sync/changes/route.ts @@ -152,6 +152,9 @@ export async function POST(request: NextRequest) { .map((t) => ({ name: t.name, description: t.description, + parameters: undefined, + returns: undefined, + aiAgent: undefined, })); toolDiscoverySource = 'auto'; console.log( diff --git a/apps/web/src/app/api/sync/keyword/route.ts b/apps/web/src/app/api/sync/keyword/route.ts index c9a853a..2c084f5 100644 --- a/apps/web/src/app/api/sync/keyword/route.ts +++ b/apps/web/src/app/api/sync/keyword/route.ts @@ -166,6 +166,9 @@ export async function POST(request: NextRequest) { .map((t) => ({ name: t.name, description: t.description, + parameters: undefined, + returns: undefined, + aiAgent: undefined, })); toolDiscoverySource = 'auto'; console.log( diff --git a/packages/types/src/tpmjs.ts b/packages/types/src/tpmjs.ts index 2b13db7..3c62ea9 100644 --- a/packages/types/src/tpmjs.ts +++ b/packages/types/src/tpmjs.ts @@ -89,19 +89,40 @@ export type TpmjsAiAgent = z.infer; * - parameters: Tool input parameters - auto-extracted from inputSchema * - returns: Tool return type - auto-extracted from tool * - aiAgent: AI agent guidance - auto-extracted from tool + * - exportName: Renamed to 'name' - kept for backward compatibility with published packages */ -export const TpmjsToolDefinitionSchema = z.object({ - // Required: The export name of the tool from the package - name: z.string().min(1), - // Optional - auto-extracted from tool if not provided - description: z.string().min(20, 'Description must be at least 20 characters').max(500).optional(), - // @deprecated - now auto-extracted from tool's inputSchema - parameters: z.array(TpmjsParameterSchema).optional(), - // @deprecated - now auto-extracted from tool - returns: TpmjsReturnsSchema.optional(), - // @deprecated - now auto-extracted from tool - aiAgent: TpmjsAiAgentSchema.optional(), -}); +export const TpmjsToolDefinitionSchema = z + .object({ + // Required: The export name of the tool from the package + // Accepts both 'name' and legacy 'exportName' field + name: z.string().min(1).optional(), + // @deprecated - renamed to 'name', kept for backward compatibility + exportName: z.string().min(1).optional(), + // Optional - auto-extracted from tool if not provided + description: z + .string() + .min(20, 'Description must be at least 20 characters') + .max(500) + .optional(), + // @deprecated - now auto-extracted from tool's inputSchema + parameters: z.array(TpmjsParameterSchema).optional(), + // @deprecated - now auto-extracted from tool + returns: TpmjsReturnsSchema.optional(), + // @deprecated - now auto-extracted from tool + aiAgent: TpmjsAiAgentSchema.optional(), + }) + .transform((data) => ({ + // Transform exportName to name for backward compatibility + name: data.name || data.exportName || '', + description: data.description, + parameters: data.parameters, + returns: data.returns, + aiAgent: data.aiAgent, + })) + .refine((data) => data.name.length > 0, { + message: 'Either name or exportName is required', + path: ['name'], + }); export type TpmjsToolDefinition = z.infer; @@ -268,6 +289,9 @@ export function validateTpmjsField(tpmjs: unknown): ValidationResult { const tool: TpmjsToolDefinition = { name: 'default', description: minimalResult.data.description, + parameters: undefined, + returns: undefined, + aiAgent: undefined, }; return {