feat(schema-extraction): auto-extract inputSchema via executor during sync

- Add inputSchema, schemaSource, schemaExtractedAt fields to Tool model
- Create schema extraction helper that calls executor's /load-and-describe
- Update sync routes to extract schema synchronously after tool upsert
- Reduce changes feed batch size from 100 to 30 for extraction time
- Update /api/tools/update-schema to store full JSON Schema
- Add /api/tools/extract-schema endpoint for manual re-extraction
- Update tool page UI with schema source badge and re-extract button
- Add deprecation comments to parameters, returns, aiAgent in types

Authors no longer need to define inputSchema in package.json - it's now
automatically extracted from the tool at sync time. Falls back to
author-provided parameters if extraction fails.
This commit is contained in:
Ajax Davis 2025-12-17 12:56:25 +10:00
parent 00441c30db
commit 06271e079f
8 changed files with 556 additions and 53 deletions

View file

@ -66,9 +66,14 @@ model Tool {
// Tool Metadata
description String @db.Text
parameters Json? @db.JsonB
returns Json? @db.JsonB
aiAgent Json? @map("ai_agent") @db.JsonB
parameters Json? @db.JsonB // Legacy/fallback - author-provided parameters array
returns Json? @db.JsonB // @deprecated - will be auto-extracted in future
aiAgent Json? @map("ai_agent") @db.JsonB // @deprecated - will be auto-extracted in future
// Schema Extraction Fields
inputSchema Json? @map("input_schema") @db.JsonB // Full JSON Schema from executor
schemaSource String? @map("schema_source") @db.VarChar(20) // 'extracted' | 'author' | null
schemaExtractedAt DateTime? @map("schema_extracted_at")
// Tool Metrics
qualityScore Decimal? @map("quality_score") @db.Decimal(3, 2) // 0.00 to 1.00

View file

@ -22,6 +22,10 @@ export type TpmjsCategory = (typeof TPMJS_CATEGORIES)[number];
/**
* Tool parameter schema
*
* @deprecated Parameters are now auto-extracted from the tool's inputSchema at runtime.
* You no longer need to manually specify parameters in your package.json.
* This schema is kept for backward compatibility as a fallback if auto-extraction fails.
*/
export const TpmjsParameterSchema = z.object({
name: z.string().min(1),
@ -35,6 +39,9 @@ export type TpmjsParameter = z.infer<typeof TpmjsParameterSchema>;
/**
* Return value schema
*
* @deprecated Return type information is now auto-extracted from the tool at runtime.
* You no longer need to manually specify returns in your package.json.
*/
export const TpmjsReturnsSchema = z.object({
type: z.string().min(1),
@ -57,6 +64,9 @@ export type TpmjsEnv = z.infer<typeof TpmjsEnvSchema>;
/**
* AI Agent guidance schema
*
* @deprecated AI agent guidance is now auto-extracted from the tool at runtime.
* You no longer need to manually specify aiAgent in your package.json.
*/
export const TpmjsAiAgentSchema = z.object({
useCase: z.string().min(10),
@ -68,12 +78,24 @@ export type TpmjsAiAgent = z.infer<typeof TpmjsAiAgentSchema>;
/**
* Individual tool definition within a multi-tool package
*
* Required fields:
* - exportName: The export name of the tool from the package
* - description: A description of what the tool does (20-500 chars)
*
* @deprecated fields (now auto-extracted, kept for backward compatibility):
* - parameters: Tool input parameters - auto-extracted from inputSchema
* - returns: Tool return type - auto-extracted from tool
* - aiAgent: AI agent guidance - auto-extracted from tool
*/
export const TpmjsToolDefinitionSchema = z.object({
exportName: z.string().min(1, 'Export name is required'),
description: z.string().min(20, 'Description must be at least 20 characters').max(500),
// @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(),
});