/**
* Zod validation schemas for tool inputs and outputs
*/
import { z } from 'zod';
/** Search parameters schema */
export const searchParamsSchema = z.object({
query: z.string().describe('Search query text'),
tags: z.string().optional().describe('Filter tags (comma-separated)'),
numericFilters: z.string().optional().describe('Numeric filters (e.g., points>=100)'),
page: z.number().int().min(0).optional().default(0).describe('Page number (0-indexed)'),
hitsPerPage: z.number().int().min(1).max(100).optional().default(20).describe('Results per page'),
restrictSearchableAttributes: z.string().optional().describe('Restrict search to specific attributes'),
});
/** Story schema */
export const storySchema = z.object({
id: z.number(),
title: z.string(),
url: z.string().nullable(),
author: z.string(),
points: z.number(),
story_text: z.string().nullable(),
comment_text: z.null(),
created_at: z.string(),
created_at_i: z.number(),
num_comments: z.number(),
objectID: z.string(),
_tags: z.array(z.string()),
_highlightResult: z.record(z.unknown()).optional(),
});
/** Comment schema */
export const commentSchema = z.object({
id: z.number(),
author: z.string(),
text: z.string(),
comment_text: z.string(),
story_text: z.null(),
points: z.number().nullable(),
parent_id: z.number(),
story_id: z.number(),
created_at: z.string(),
created_at_i: z.number(),
objectID: z.string(),
_tags: z.array(z.string()),
children: z.array(z.any()).optional(),
});
/** User schema */
export const userSchema = z.object({
username: z.string(),
about: z.string().nullable(),
karma: z.number(),
created_at: z.string().optional(),
created_at_i: z.number().optional(),
});
/** Search result schema */
export function searchResultSchema<T extends z.ZodType>(itemSchema: T) {
return z.object({
hits: z.array(itemSchema),
nbHits: z.number(),
nbPages: z.number(),
page: z.number(),
hitsPerPage: z.number(),
processingTimeMS: z.number(),
query: z.string(),
params: z.string(),
});
}
/** Item response schema (nested) */
export const itemResponseSchema = z.object({
id: z.number(),
created_at: z.string(),
created_at_i: z.number().optional(),
author: z.string(),
title: z.string().optional(),
url: z.string().optional(),
text: z.string().optional(),
points: z.number(),
parent_id: z.number().nullable(),
children: z.array(z.any()).optional(),
type: z.string().optional(),
});