@ai-me-chat/core 0.0.1

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/tools/generate-tools.ts","../src/tools/schema-extractor.ts","../src/tools/openapi-parser.ts","../src/executor.ts"],"sourcesContent":["import { z } from \"zod\";\nimport type { DiscoveredRoute, AIMeToolDefinition, ConfirmationConfig } from \"../types.js\";\nimport type { ExtractedSchema } from \"./schema-extractor.js\";\n\nconst DEFAULT_WRITE_METHODS = [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"];\n\n/**\n * Generate AI-Me tool definitions from discovered routes.\n * Each HTTP method on a route becomes a separate tool.\n */\nexport function generateToolDefinitions(\n routes: DiscoveredRoute[],\n confirmation?: ConfirmationConfig,\n): AIMeToolDefinition[] {\n const confirmMethods = confirmation?.methods ?? DEFAULT_WRITE_METHODS;\n const tools: AIMeToolDefinition[] = [];\n\n for (const route of routes) {\n for (const method of route.methods) {\n const toolName = buildToolName(method, route.path);\n const description = `${method} ${route.path}`;\n\n tools.push({\n name: toolName,\n description,\n parameters: buildParametersSchema(method, route.pathParams),\n requiresConfirmation: confirmMethods.includes(method),\n httpMethod: method,\n path: route.path,\n });\n }\n }\n\n return tools;\n}\n\n/**\n * Build a snake_case tool name from HTTP method and path.\n * e.g., GET /api/invoices → get_invoices\n * POST /api/projects/:id/tasks → post_projects_id_tasks\n */\nfunction buildToolName(method: string, routePath: string): string {\n const pathPart = routePath\n .replace(/^\\/api\\//, \"\") // Remove /api/ prefix\n .replace(/:/g, \"\") // Remove colon from params\n .replace(/\\*/g, \"\") // Remove catch-all asterisk\n .replace(/\\//g, \"_\") // Slashes to underscores\n .replace(/_+/g, \"_\") // Collapse multiple underscores\n .replace(/_$/, \"\"); // Remove trailing underscore\n\n return `${method.toLowerCase()}_${pathPart}`;\n}\n\n/**\n * Generate AI-Me tool definitions from discovered routes, enhanced with\n * extracted Zod schemas from the route source files.\n *\n * When a route file exports a matching schema (bodySchema for write methods,\n * querySchema for GET), it replaces the generic fallback schema with the\n * richer extracted version, giving the LLM better parameter descriptions.\n *\n * The `schemas` map is keyed by the route's `filePath` field.\n */\nexport function generateToolDefinitionsWithSchemas(\n routes: DiscoveredRoute[],\n schemas: Map<string, ExtractedSchema[]>,\n confirmation?: ConfirmationConfig,\n): AIMeToolDefinition[] {\n const confirmMethods = confirmation?.methods ?? DEFAULT_WRITE_METHODS;\n const tools: AIMeToolDefinition[] = [];\n\n for (const route of routes) {\n const fileSchemas = schemas.get(route.filePath) ?? [];\n\n for (const method of route.methods) {\n const toolName = buildToolName(method, route.path);\n const description = `${method} ${route.path}`;\n\n // Try to find a matching extracted schema for this method.\n const matchingSchema = pickBestSchema(fileSchemas, method);\n\n tools.push({\n name: toolName,\n description,\n parameters: matchingSchema\n ? buildParametersSchemaFromExtracted(method, route.pathParams, matchingSchema)\n : buildParametersSchema(method, route.pathParams),\n requiresConfirmation: confirmMethods.includes(method),\n httpMethod: method,\n path: route.path,\n });\n }\n }\n\n return tools;\n}\n\n/**\n * Choose the extracted schema that best matches the given HTTP method.\n * Prefers an exact method match (inferred from export name), then falls back\n * to any schema whose `exportName` contains a relevant keyword.\n */\nfunction pickBestSchema(\n fileSchemas: ExtractedSchema[],\n method: string,\n): ExtractedSchema | undefined {\n // Exact method match (e.g., bodySchema → POST).\n const exact = fileSchemas.find((s) => s.method === method);\n if (exact) return exact;\n\n // Keyword heuristics.\n if (method === \"GET\") {\n return fileSchemas.find((s) =>\n s.exportName.toLowerCase().includes(\"query\") ||\n s.exportName.toLowerCase().includes(\"search\"),\n );\n }\n\n if ([\"POST\", \"PUT\", \"PATCH\"].includes(method)) {\n return fileSchemas.find((s) =>\n s.exportName.toLowerCase().includes(\"body\") ||\n s.exportName.toLowerCase().includes(\"request\"),\n );\n }\n\n return undefined;\n}\n\n/**\n * Build a Zod schema that merges path params with an extracted JSON Schema\n * body or query definition.\n */\nfunction buildParametersSchemaFromExtracted(\n method: string,\n pathParams: string[],\n extracted: ExtractedSchema,\n): z.ZodType {\n const shape: Record<string, z.ZodType> = {};\n\n for (const param of pathParams) {\n shape[param] = z.string().describe(`Path parameter: ${param}`);\n }\n\n // Build a Zod object from the extracted JSON Schema properties.\n const props = extracted.jsonSchema[\"properties\"] as\n | Record<string, Record<string, unknown>>\n | undefined;\n\n const requiredFields = new Set<string>(\n Array.isArray(extracted.jsonSchema[\"required\"])\n ? (extracted.jsonSchema[\"required\"] as string[])\n : [],\n );\n\n if (props) {\n const innerShape: Record<string, z.ZodType> = {};\n for (const [key, propSchema] of Object.entries(props)) {\n const zodField = jsonSchemaScalarToZod(propSchema);\n innerShape[key] = requiredFields.has(key) ? zodField : zodField.optional();\n }\n\n if (method === \"GET\") {\n shape[\"query\"] = z.object(innerShape).optional().describe(\"Query parameters\");\n } else if ([\"POST\", \"PUT\", \"PATCH\"].includes(method)) {\n shape[\"body\"] = z.object(innerShape).optional().describe(\"Request body\");\n }\n } else {\n // No properties extracted — fall back to generic.\n if (method === \"GET\") {\n shape[\"query\"] = z\n .object({})\n .passthrough()\n .optional()\n .describe(\"Query string parameters\");\n } else if ([\"POST\", \"PUT\", \"PATCH\"].includes(method)) {\n shape[\"body\"] = z\n .object({})\n .passthrough()\n .optional()\n .describe(\"Request body (JSON object with any properties)\");\n }\n }\n\n return z.object(shape);\n}\n\n/**\n * Convert a simple JSON Schema scalar fragment to a Zod type.\n * This is intentionally minimal — it handles the output of the schema extractor\n * (string, number, boolean, array, anyOf-with-null for optionals).\n */\nfunction jsonSchemaScalarToZod(schema: Record<string, unknown>): z.ZodType {\n // anyOf: [type, null] → optional wrapper already handled by caller\n const anyOf = schema[\"anyOf\"];\n if (Array.isArray(anyOf)) {\n const nonNull = (anyOf as Record<string, unknown>[]).filter(\n (s) => s[\"type\"] !== \"null\",\n );\n if (nonNull.length === 1 && nonNull[0]) {\n return jsonSchemaScalarToZod(nonNull[0]);\n }\n return z.unknown();\n }\n\n if (Array.isArray(schema[\"enum\"])) {\n const values = schema[\"enum\"] as unknown[];\n if (values.every((v) => typeof v === \"string\") && values.length >= 2) {\n const [first, second, ...rest] = values as [string, string, ...string[]];\n return z.enum([first, second, ...rest]);\n }\n }\n\n switch (schema[\"type\"]) {\n case \"string\": return z.string();\n case \"number\":\n case \"integer\": return z.number();\n case \"boolean\": return z.boolean();\n case \"array\": {\n const items = schema[\"items\"] as Record<string, unknown> | undefined;\n return items ? z.array(jsonSchemaScalarToZod(items)) : z.array(z.unknown());\n }\n case \"object\": return z.record(z.string(), z.unknown());\n default: return z.unknown();\n }\n}\n\n/**\n * Build a Zod schema for tool parameters.\n * Path params become required string fields.\n * GET requests get an optional query params object.\n * POST/PUT/PATCH get an optional body object.\n */\nfunction buildParametersSchema(\n method: string,\n pathParams: string[],\n): z.ZodType {\n const shape: Record<string, z.ZodType> = {};\n\n for (const param of pathParams) {\n shape[param] = z.string().describe(`Path parameter: ${param}`);\n }\n\n if (method === \"GET\") {\n shape[\"query\"] = z\n .record(z.string(), z.string())\n .optional()\n .describe(\"Query string parameters\");\n } else if ([\"POST\", \"PUT\", \"PATCH\"].includes(method)) {\n shape[\"body\"] = z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Request body\");\n }\n\n return z.object(shape);\n}\n","/**\n * Static schema extractor for Next.js route files.\n *\n * Since we cannot safely dynamic-import arbitrary user route files and call Zod\n * at runtime (the files may import framework internals, use top-level await, etc.),\n * this module uses a regex/string-based approach to parse exported Zod schema\n * declarations and emit an equivalent JSON Schema representation.\n *\n * Supported export patterns:\n * export const bodySchema = z.object({...})\n * export const querySchema = z.object({...})\n * export const paramsSchema = z.object({...})\n *\n * Supported Zod primitives inside z.object({...}):\n * z.string(), z.number(), z.boolean(), z.enum([...])\n * Modifiers: .optional(), .array(), .nullable(), .default(...)\n *\n * For full fidelity use the OpenAPI parser instead.\n */\n\nexport interface ExtractedSchema {\n exportName: string;\n jsonSchema: Record<string, unknown>;\n method?: string;\n}\n\n// ---------------------------------------------------------------------------\n// Top-level entry point\n// ---------------------------------------------------------------------------\n\nexport function extractSchemasFromFile(\n _filePath: string,\n fileContent: string,\n): ExtractedSchema[] {\n const results: ExtractedSchema[] = [];\n\n const exportPattern =\n /export\\s+const\\s+(\\w+)\\s*=\\s*z\\.object\\s*\\(\\s*\\{([^]*?)\\}\\s*\\)/g;\n\n let match: RegExpExecArray | null;\n while ((match = exportPattern.exec(fileContent)) !== null) {\n const exportName = match[1];\n const objectBody = match[2];\n\n // exportName must be a non-empty identifier; objectBody may be \"\" for z.object({}).\n if (!exportName) continue;\n\n const jsonSchema = buildJsonSchema(objectBody);\n const method = inferMethod(exportName);\n\n results.push({ exportName, jsonSchema, method });\n }\n\n return results;\n}\n\n// ---------------------------------------------------------------------------\n// Internal helpers\n// ---------------------------------------------------------------------------\n\nfunction inferMethod(exportName: string): string | undefined {\n const lower = exportName.toLowerCase();\n if (lower.includes(\"body\") || lower.includes(\"request\")) return \"POST\";\n if (lower.includes(\"query\") || lower.includes(\"search\")) return \"GET\";\n return undefined;\n}\n\nfunction buildJsonSchema(objectBody: string): Record<string, unknown> {\n const properties: Record<string, unknown> = {};\n const required: string[] = [];\n\n const fields = splitFields(objectBody);\n\n for (const field of fields) {\n const fieldMatch = field.match(/^\\s*(\\w+)\\s*:\\s*(.+?)\\s*$/s);\n if (!fieldMatch) continue;\n\n const fieldName = fieldMatch[1];\n const typeExpr = fieldMatch[2];\n\n if (!fieldName || !typeExpr) continue;\n\n const { schema, isOptional } = parseZodType(typeExpr.trim());\n properties[fieldName] = schema;\n if (!isOptional) {\n required.push(fieldName);\n }\n }\n\n const jsonSchema: Record<string, unknown> = {\n type: \"object\",\n properties,\n };\n\n if (required.length > 0) {\n jsonSchema[\"required\"] = required;\n }\n\n return jsonSchema;\n}\n\nfunction splitFields(body: string): string[] {\n const fields: string[] = [];\n let depth = 0;\n let current = \"\";\n\n for (const char of body) {\n if (char === \"(\" || char === \"[\" || char === \"{\") {\n depth++;\n current += char;\n } else if (char === \")\" || char === \"]\" || char === \"}\") {\n depth--;\n current += char;\n } else if (char === \",\" && depth === 0) {\n const trimmed = current.trim();\n if (trimmed) fields.push(trimmed);\n current = \"\";\n } else {\n current += char;\n }\n }\n\n const trimmed = current.trim();\n if (trimmed) fields.push(trimmed);\n\n return fields;\n}\n\ninterface ParsedType {\n schema: Record<string, unknown>;\n isOptional: boolean;\n}\n\nfunction parseZodType(expr: string): ParsedType {\n const { base, modifiers } = tokeniseExpr(expr);\n\n let schema: Record<string, unknown> = resolveBaseType(base);\n let isOptional = false;\n\n for (const mod of modifiers) {\n if (mod.startsWith(\".optional\")) {\n isOptional = true;\n schema = { anyOf: [schema, { type: \"null\" }] };\n } else if (mod.startsWith(\".nullable\")) {\n schema = { anyOf: [schema, { type: \"null\" }] };\n } else if (mod.startsWith(\".array\")) {\n schema = { type: \"array\", items: schema };\n } else if (mod.startsWith(\".default\")) {\n isOptional = true;\n }\n }\n\n return { schema, isOptional };\n}\n\ninterface TokenisedExpr {\n base: string;\n modifiers: string[];\n}\n\nfunction tokeniseExpr(expr: string): TokenisedExpr {\n const modifiers: string[] = [];\n let rest = expr.trim();\n\n let depth = 0;\n let baseEnd = 0;\n let foundBase = false;\n\n for (let i = 0; i < rest.length; i++) {\n const ch = rest[i];\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0) {\n baseEnd = i + 1;\n foundBase = true;\n break;\n }\n }\n }\n\n if (!foundBase) {\n return { base: rest, modifiers: [] };\n }\n\n const base = rest.slice(0, baseEnd);\n rest = rest.slice(baseEnd);\n\n while (rest.startsWith(\".\")) {\n depth = 0;\n let modEnd = 0;\n let foundMod = false;\n\n for (let i = 1; i < rest.length; i++) {\n const ch = rest[i];\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0) {\n modEnd = i + 1;\n foundMod = true;\n break;\n }\n }\n }\n\n if (!foundMod) break;\n\n modifiers.push(rest.slice(0, modEnd));\n rest = rest.slice(modEnd);\n }\n\n return { base, modifiers };\n}\n\nfunction resolveBaseType(base: string): Record<string, unknown> {\n const trimmed = base.trim();\n\n if (trimmed.startsWith(\"z.string\")) return { type: \"string\" };\n if (trimmed.startsWith(\"z.number\")) return { type: \"number\" };\n if (trimmed.startsWith(\"z.boolean\")) return { type: \"boolean\" };\n if (trimmed.startsWith(\"z.null\")) return { type: \"null\" };\n if (trimmed.startsWith(\"z.unknown\") || trimmed.startsWith(\"z.any\"))\n return {};\n\n if (trimmed.startsWith(\"z.enum\")) {\n const enumValues = extractEnumValues(trimmed);\n return { type: \"string\", enum: enumValues };\n }\n\n if (trimmed.startsWith(\"z.array\")) {\n const inner = extractSingleArg(trimmed);\n if (inner) {\n const { schema: items } = parseZodType(inner);\n return { type: \"array\", items };\n }\n return { type: \"array\" };\n }\n\n if (trimmed.startsWith(\"z.object\")) {\n return { type: \"object\" };\n }\n\n if (trimmed.startsWith(\"z.record\")) return { type: \"object\" };\n\n if (trimmed.startsWith(\"z.literal\")) {\n const val = extractLiteralValue(trimmed);\n return val !== undefined ? { const: val } : {};\n }\n\n return {};\n}\n\nfunction extractEnumValues(expr: string): string[] {\n const inner = extractSingleArg(expr);\n if (!inner) return [];\n\n const values: string[] = [];\n const valuePattern = /[\"']([^\"']+)[\"']/g;\n let m: RegExpExecArray | null;\n while ((m = valuePattern.exec(inner)) !== null) {\n if (m[1]) values.push(m[1]);\n }\n return values;\n}\n\nfunction extractSingleArg(expr: string): string | null {\n const openParen = expr.indexOf(\"(\");\n if (openParen === -1) return null;\n\n let depth = 0;\n for (let i = openParen; i < expr.length; i++) {\n const ch = expr[i];\n if (ch === \"(\") depth++;\n else if (ch === \")\") {\n depth--;\n if (depth === 0) {\n return expr.slice(openParen + 1, i);\n }\n }\n }\n return null;\n}\n\nfunction extractLiteralValue(expr: string): string | number | boolean | undefined {\n const inner = extractSingleArg(expr)?.trim();\n if (!inner) return undefined;\n\n if ((inner.startsWith('\"') && inner.endsWith('\"')) ||\n (inner.startsWith(\"'\") && inner.endsWith(\"'\"))) {\n return inner.slice(1, -1);\n }\n if (inner === \"true\") return true;\n if (inner === \"false\") return false;\n const num = Number(inner);\n if (!Number.isNaN(num)) return num;\n return undefined;\n}\n","/**\n * OpenAPI 3.x spec parser.\n *\n * Converts OpenAPI path/operation entries into DiscoveredRoute objects and\n * AIMeToolDefinition objects with richer parameter schemas derived from the\n * JSON Schema definitions embedded in the spec.\n *\n * Supported features:\n * - path + query parameters (in: \"path\" | \"query\")\n * - requestBody with application/json content schema\n * - operationId → tool name (falls back to auto-generated name)\n * - summary / description → tool description\n * - $ref resolution for same-file component references (#/components/schemas/...)\n * - required flags on parameters and request body properties\n */\n\nimport { z } from \"zod\";\nimport type {\n DiscoveredRoute,\n AIMeToolDefinition,\n ConfirmationConfig,\n} from \"../types.js\";\n\n// ---------------------------------------------------------------------------\n// Public types\n// ---------------------------------------------------------------------------\n\nexport interface OpenAPISpec {\n openapi: string;\n info: { title: string; version: string };\n paths: Record<string, Record<string, OpenAPIOperation>>;\n components?: {\n schemas?: Record<string, Record<string, unknown>>;\n };\n}\n\nexport interface OpenAPIOperation {\n operationId?: string;\n summary?: string;\n description?: string;\n parameters?: OpenAPIParameter[];\n requestBody?: {\n required?: boolean;\n content: Record<string, { schema: Record<string, unknown> }>;\n };\n responses?: Record<string, unknown>;\n tags?: string[];\n}\n\nexport interface OpenAPIParameter {\n name: string;\n in: \"path\" | \"query\" | \"header\" | \"cookie\";\n required?: boolean;\n schema?: Record<string, unknown>;\n description?: string;\n}\n\n// ---------------------------------------------------------------------------\n// HTTP method set — these are the only keys we treat as operations in a path\n// item object. All other keys (summary, description, servers, parameters,\n// $ref) are ignored.\n// ---------------------------------------------------------------------------\n\nconst HTTP_METHODS = new Set([\n \"get\", \"post\", \"put\", \"patch\", \"delete\", \"head\", \"options\", \"trace\",\n]);\n\nconst DEFAULT_WRITE_METHODS = [\"POST\", \"PUT\", \"PATCH\", \"DELETE\"];\n\n// ---------------------------------------------------------------------------\n// parseOpenAPISpec\n// ---------------------------------------------------------------------------\n\n/**\n * Parse an OpenAPI 3.x spec and return a list of discovered routes.\n *\n * Each path + HTTP method combination becomes one DiscoveredRoute entry.\n * Path parameters are extracted from the OpenAPI `{param}` notation.\n */\nexport function parseOpenAPISpec(spec: OpenAPISpec): DiscoveredRoute[] {\n const routes: DiscoveredRoute[] = [];\n\n for (const [rawPath, pathItem] of Object.entries(spec.paths ?? {})) {\n // Collect all methods found on this path item.\n const methods: string[] = [];\n for (const key of Object.keys(pathItem)) {\n if (HTTP_METHODS.has(key.toLowerCase())) {\n methods.push(key.toUpperCase());\n }\n }\n\n if (methods.length === 0) continue;\n\n // Convert OpenAPI path notation (/items/{id}) → Express notation (/items/:id)\n const expressPath = openApiPathToExpress(rawPath);\n\n // Extract path parameter names from the OpenAPI-style path.\n const pathParams = extractPathParams(rawPath);\n\n routes.push({\n path: expressPath,\n methods,\n pathParams,\n // No real file path — use the spec path as a synthetic identifier.\n filePath: `openapi:${rawPath}`,\n });\n }\n\n return routes;\n}\n\n// ---------------------------------------------------------------------------\n// generateToolsFromOpenAPI\n// ---------------------------------------------------------------------------\n\n/**\n * Generate AIMeToolDefinition objects from an OpenAPI 3.x spec.\n *\n * This produces richer tool definitions than the filesystem-discovery path\n * because the OpenAPI spec provides parameter types, descriptions, and\n * required flags that allow us to build precise Zod schemas.\n */\nexport function generateToolsFromOpenAPI(\n spec: OpenAPISpec,\n confirmation?: ConfirmationConfig,\n): AIMeToolDefinition[] {\n const confirmMethods = confirmation?.methods ?? DEFAULT_WRITE_METHODS;\n const tools: AIMeToolDefinition[] = [];\n\n for (const [rawPath, pathItem] of Object.entries(spec.paths ?? {})) {\n for (const [methodKey, operation] of Object.entries(pathItem)) {\n if (!HTTP_METHODS.has(methodKey.toLowerCase())) continue;\n\n const method = methodKey.toUpperCase();\n const op = operation as OpenAPIOperation;\n\n const toolName = buildToolName(method, rawPath, op.operationId);\n const description = buildDescription(method, rawPath, op);\n const expressPath = openApiPathToExpress(rawPath);\n const parameters = buildZodSchema(method, rawPath, op, spec);\n\n tools.push({\n name: toolName,\n description,\n parameters,\n requiresConfirmation: confirmMethods.includes(method),\n httpMethod: method,\n path: expressPath,\n });\n }\n }\n\n return tools;\n}\n\n// ---------------------------------------------------------------------------\n// fetchOpenAPISpec\n// ---------------------------------------------------------------------------\n\n/**\n * Fetch an OpenAPI spec from a remote URL.\n * Returns the parsed JSON as an OpenAPISpec object.\n */\nexport async function fetchOpenAPISpec(url: string): Promise<OpenAPISpec> {\n const response = await fetch(url);\n if (!response.ok) {\n throw new Error(`Failed to fetch OpenAPI spec: ${response.status} ${response.statusText}`);\n }\n const spec = (await response.json()) as OpenAPISpec;\n return spec;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: naming helpers\n// ---------------------------------------------------------------------------\n\nfunction buildToolName(\n method: string,\n rawPath: string,\n operationId: string | undefined,\n): string {\n if (operationId) {\n // Normalise to snake_case: camelCase → snake_case, hyphens/spaces → underscores.\n return operationId\n .replace(/([a-z])([A-Z])/g, \"$1_$2\")\n .replace(/[-\\s]+/g, \"_\")\n .toLowerCase()\n .replace(/_+/g, \"_\")\n .replace(/^_|_$/g, \"\");\n }\n\n // Auto-generate from method + path (same logic as generate-tools.ts).\n const pathPart = rawPath\n .replace(/^\\//, \"\")\n .replace(/\\{([^}]+)\\}/g, \"$1\") // {id} → id\n .replace(/\\//g, \"_\")\n .replace(/_+/g, \"_\")\n .replace(/_$/, \"\");\n\n return `${method.toLowerCase()}_${pathPart}`;\n}\n\nfunction buildDescription(\n method: string,\n rawPath: string,\n op: OpenAPIOperation,\n): string {\n if (op.summary) return op.summary;\n if (op.description) return op.description;\n return `${method} ${rawPath}`;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: path helpers\n// ---------------------------------------------------------------------------\n\n/** Convert `/items/{id}` → `/items/:id` */\nfunction openApiPathToExpress(path: string): string {\n return path.replace(/\\{([^}]+)\\}/g, \":$1\");\n}\n\n/** Extract parameter names from `/items/{id}/sub/{subId}` → [\"id\", \"subId\"] */\nfunction extractPathParams(path: string): string[] {\n const params: string[] = [];\n const re = /\\{([^}]+)\\}/g;\n let m: RegExpExecArray | null;\n while ((m = re.exec(path)) !== null) {\n if (m[1]) params.push(m[1]);\n }\n return params;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: Zod schema builder\n// ---------------------------------------------------------------------------\n\n/**\n * Build a Zod object schema for a tool's parameters.\n *\n * The schema combines:\n * - path parameters (always string, required)\n * - query parameters (typed, optional/required per spec)\n * - requestBody fields (for POST/PUT/PATCH, typed, optional/required per spec)\n */\nfunction buildZodSchema(\n method: string,\n rawPath: string,\n op: OpenAPIOperation,\n spec: OpenAPISpec,\n): z.ZodObject<z.ZodRawShape> {\n // In Zod 4.x ZodRawShape has a readonly index signature, so we accumulate\n // into a plain mutable Record<string, z.ZodType> and cast at the z.object() call.\n const shape: Record<string, z.ZodType> = {};\n\n // Path params.\n for (const paramName of extractPathParams(rawPath)) {\n shape[paramName] = z\n .string()\n .describe(`Path parameter: ${paramName}`);\n }\n\n // Explicit parameters (path + query, skip header/cookie).\n for (const param of op.parameters ?? []) {\n if (param.in !== \"path\" && param.in !== \"query\") continue;\n if (param.in === \"path\") {\n // Already added above from path string; override only if spec provides\n // a richer description.\n if (param.description) {\n shape[param.name] = z.string().describe(param.description);\n }\n continue;\n }\n\n // query parameter\n const resolved = resolveSchema(param.schema ?? {}, spec);\n let zodField = jsonSchemaToZod(resolved);\n if (param.description) zodField = zodField.describe(param.description);\n shape[param.name] =\n param.required ? zodField : zodField.optional();\n }\n\n // Request body (POST / PUT / PATCH).\n if (\n [\"POST\", \"PUT\", \"PATCH\"].includes(method) &&\n op.requestBody\n ) {\n const jsonContent =\n op.requestBody.content[\"application/json\"] ??\n Object.values(op.requestBody.content)[0];\n\n if (jsonContent?.schema) {\n const resolved = resolveSchema(jsonContent.schema, spec);\n const bodySchema = jsonSchemaObjectToZod(resolved, spec);\n shape[\"body\"] = op.requestBody.required\n ? bodySchema\n : bodySchema.optional();\n } else {\n shape[\"body\"] = z\n .record(z.string(), z.unknown())\n .optional()\n .describe(\"Request body\");\n }\n }\n\n return z.object(shape as z.ZodRawShape);\n}\n\n// ---------------------------------------------------------------------------\n// Internal: $ref resolver\n// ---------------------------------------------------------------------------\n\n/**\n * Resolve a JSON Schema object that may contain a `$ref` pointing to\n * `#/components/schemas/<name>`. Only same-file references are supported.\n */\nfunction resolveSchema(\n schema: Record<string, unknown>,\n spec: OpenAPISpec,\n): Record<string, unknown> {\n const ref = schema[\"$ref\"];\n if (typeof ref !== \"string\") return schema;\n\n const prefix = \"#/components/schemas/\";\n if (!ref.startsWith(prefix)) return schema;\n\n const schemaName = ref.slice(prefix.length);\n const resolved = spec.components?.schemas?.[schemaName];\n return resolved ?? schema;\n}\n\n// ---------------------------------------------------------------------------\n// Internal: JSON Schema → Zod converters\n// ---------------------------------------------------------------------------\n\n/**\n * Convert a JSON Schema `type: \"object\"` definition to a Zod object schema.\n * Falls back to `z.record(z.string(), z.unknown())` for non-object schemas.\n */\nfunction jsonSchemaObjectToZod(\n schema: Record<string, unknown>,\n spec: OpenAPISpec,\n): z.ZodType {\n if (schema[\"type\"] !== \"object\") {\n return jsonSchemaToZod(schema);\n }\n\n const props = schema[\"properties\"] as Record<string, Record<string, unknown>> | undefined;\n if (!props) {\n return z.record(z.string(), z.unknown()).describe(\"Request body\");\n }\n\n const required = new Set<string>(\n Array.isArray(schema[\"required\"]) ? (schema[\"required\"] as string[]) : [],\n );\n\n const shape: Record<string, z.ZodType> = {};\n\n for (const [propName, propSchema] of Object.entries(props)) {\n const resolved = resolveSchema(propSchema, spec);\n const zodField = jsonSchemaToZod(resolved);\n shape[propName] = required.has(propName) ? zodField : zodField.optional();\n }\n\n return z.object(shape as z.ZodRawShape);\n}\n\n/**\n * Convert a JSON Schema fragment to a Zod type.\n * Handles: string, number, integer, boolean, array, object, anyOf/oneOf,\n * enum, and $ref (via pass-through — caller should resolve before calling).\n */\nfunction jsonSchemaToZod(schema: Record<string, unknown>): z.ZodType {\n const type = schema[\"type\"] as string | undefined;\n\n // anyOf / oneOf → z.union (with minimum 2 members; fall back to z.unknown)\n const anyOf = schema[\"anyOf\"] ?? schema[\"oneOf\"];\n if (Array.isArray(anyOf) && anyOf.length >= 2) {\n const members = (anyOf as Record<string, unknown>[]).map((s) =>\n jsonSchemaToZod(s),\n );\n // z.union requires a tuple of at least 2 ZodType — we build it dynamically.\n const [first, second, ...rest] = members as [z.ZodType, z.ZodType, ...z.ZodType[]];\n return z.union([first, second, ...rest]);\n }\n\n if (schema[\"enum\"] !== undefined) {\n const values = schema[\"enum\"] as unknown[];\n if (values.every((v) => typeof v === \"string\")) {\n const [first, second, ...rest] = values as [string, string, ...string[]];\n if (first !== undefined && second !== undefined) {\n return z.enum([first, second, ...rest]);\n }\n if (first !== undefined) return z.literal(first);\n }\n return z.unknown();\n }\n\n switch (type) {\n case \"string\":\n return z.string();\n case \"number\":\n case \"integer\":\n return z.number();\n case \"boolean\":\n return z.boolean();\n case \"null\":\n return z.null();\n case \"array\": {\n const items = schema[\"items\"] as Record<string, unknown> | undefined;\n return items ? z.array(jsonSchemaToZod(items)) : z.array(z.unknown());\n }\n case \"object\": {\n const props = schema[\"properties\"] as\n | Record<string, Record<string, unknown>>\n | undefined;\n if (!props) return z.record(z.string(), z.unknown());\n\n const required = new Set<string>(\n Array.isArray(schema[\"required\"])\n ? (schema[\"required\"] as string[])\n : [],\n );\n const innerShape: Record<string, z.ZodType> = {};\n for (const [k, v] of Object.entries(props)) {\n const field = jsonSchemaToZod(v);\n innerShape[k] = required.has(k) ? field : field.optional();\n }\n return z.object(innerShape as z.ZodRawShape);\n }\n default:\n return z.unknown();\n }\n}\n","import type { AIMeToolDefinition, ToolExecution } from \"./types.js\";\n\n/**\n * Execute a tool by calling its execute function or making an HTTP request\n * to the host app's API route.\n *\n * DEC-008: Uses shared service functions when available, falls back to HTTP.\n */\nexport async function executeTool(\n tool: AIMeToolDefinition,\n params: Record<string, unknown>,\n context: ExecutionContext,\n): Promise<ToolExecution> {\n const id = crypto.randomUUID();\n const startTime = new Date();\n\n try {\n let response: unknown;\n\n if (tool.execute) {\n // Custom tool with direct execute function (shared service pattern)\n response = await tool.execute(params);\n } else if (tool.httpMethod && tool.path) {\n // Auto-discovered route — call via HTTP with forwarded auth\n response = await executeHttpTool(tool, params, context);\n } else {\n throw new Error(`Tool \"${tool.name}\" has no execute function or HTTP path`);\n }\n\n return {\n id,\n toolName: tool.name,\n parameters: params,\n statusCode: 200,\n response,\n confirmed: !tool.requiresConfirmation,\n executedAt: startTime,\n };\n } catch (error) {\n return {\n id,\n toolName: tool.name,\n parameters: params,\n statusCode: 500,\n response: { error: error instanceof Error ? error.message : \"Unknown error\" },\n confirmed: false,\n executedAt: startTime,\n };\n }\n}\n\nexport interface ExecutionContext {\n /** Base URL for HTTP calls (e.g., \"http://localhost:3000\") */\n baseUrl: string;\n /** Headers to forward (cookies, authorization) */\n headers: Record<string, string>;\n}\n\nasync function executeHttpTool(\n tool: AIMeToolDefinition,\n params: Record<string, unknown>,\n context: ExecutionContext,\n): Promise<unknown> {\n const method = tool.httpMethod!;\n let url = `${context.baseUrl}${tool.path}`;\n\n // Replace path parameters\n for (const [key, value] of Object.entries(params)) {\n if (url.includes(`:${key}`)) {\n url = url.replace(`:${key}`, encodeURIComponent(String(value)));\n }\n }\n\n const fetchOptions: RequestInit = {\n method,\n headers: {\n \"Content-Type\": \"application/json\",\n ...context.headers,\n },\n };\n\n // Add query params for GET, body for write methods\n if (method === \"GET\" && params.query) {\n const queryParams = new URLSearchParams(\n params.query as Record<string, string>,\n );\n url += `?${queryParams.toString()}`;\n } else if ([\"POST\", \"PUT\", \"PATCH\"].includes(method) && params.body) {\n fetchOptions.body = JSON.stringify(params.body);\n }\n\n const response = await fetch(url, fetchOptions);\n\n if (!response.ok) {\n throw new Error(`HTTP ${response.status}: ${response.statusText}`);\n }\n\n const contentType = response.headers.get(\"content-type\") ?? \"\";\n if (contentType.includes(\"application/json\")) {\n return response.json();\n }\n return response.text();\n}\n"],"mappings":";AAAA,SAAS,SAAS;AAIlB,IAAM,wBAAwB,CAAC,QAAQ,OAAO,SAAS,QAAQ;AAMxD,SAAS,wBACd,QACA,cACsB;AACtB,QAAM,iBAAiB,cAAc,WAAW;AAChD,QAAM,QAA8B,CAAC;AAErC,aAAW,SAAS,QAAQ;AAC1B,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,WAAW,cAAc,QAAQ,MAAM,IAAI;AACjD,YAAM,cAAc,GAAG,MAAM,IAAI,MAAM,IAAI;AAE3C,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA,YAAY,sBAAsB,QAAQ,MAAM,UAAU;AAAA,QAC1D,sBAAsB,eAAe,SAAS,MAAM;AAAA,QACpD,YAAY;AAAA,QACZ,MAAM,MAAM;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAOA,SAAS,cAAc,QAAgB,WAA2B;AAChE,QAAM,WAAW,UACd,QAAQ,YAAY,EAAE,EACtB,QAAQ,MAAM,EAAE,EAChB,QAAQ,OAAO,EAAE,EACjB,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,MAAM,EAAE;AAEnB,SAAO,GAAG,OAAO,YAAY,CAAC,IAAI,QAAQ;AAC5C;AAYO,SAAS,mCACd,QACA,SACA,cACsB;AACtB,QAAM,iBAAiB,cAAc,WAAW;AAChD,QAAM,QAA8B,CAAC;AAErC,aAAW,SAAS,QAAQ;AAC1B,UAAM,cAAc,QAAQ,IAAI,MAAM,QAAQ,KAAK,CAAC;AAEpD,eAAW,UAAU,MAAM,SAAS;AAClC,YAAM,WAAW,cAAc,QAAQ,MAAM,IAAI;AACjD,YAAM,cAAc,GAAG,MAAM,IAAI,MAAM,IAAI;AAG3C,YAAM,iBAAiB,eAAe,aAAa,MAAM;AAEzD,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA,YAAY,iBACR,mCAAmC,QAAQ,MAAM,YAAY,cAAc,IAC3E,sBAAsB,QAAQ,MAAM,UAAU;AAAA,QAClD,sBAAsB,eAAe,SAAS,MAAM;AAAA,QACpD,YAAY;AAAA,QACZ,MAAM,MAAM;AAAA,MACd,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAOA,SAAS,eACP,aACA,QAC6B;AAE7B,QAAM,QAAQ,YAAY,KAAK,CAAC,MAAM,EAAE,WAAW,MAAM;AACzD,MAAI,MAAO,QAAO;AAGlB,MAAI,WAAW,OAAO;AACpB,WAAO,YAAY;AAAA,MAAK,CAAC,MACvB,EAAE,WAAW,YAAY,EAAE,SAAS,OAAO,KAC3C,EAAE,WAAW,YAAY,EAAE,SAAS,QAAQ;AAAA,IAC9C;AAAA,EACF;AAEA,MAAI,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,MAAM,GAAG;AAC7C,WAAO,YAAY;AAAA,MAAK,CAAC,MACvB,EAAE,WAAW,YAAY,EAAE,SAAS,MAAM,KAC1C,EAAE,WAAW,YAAY,EAAE,SAAS,SAAS;AAAA,IAC/C;AAAA,EACF;AAEA,SAAO;AACT;AAMA,SAAS,mCACP,QACA,YACA,WACW;AACX,QAAM,QAAmC,CAAC;AAE1C,aAAW,SAAS,YAAY;AAC9B,UAAM,KAAK,IAAI,EAAE,OAAO,EAAE,SAAS,mBAAmB,KAAK,EAAE;AAAA,EAC/D;AAGA,QAAM,QAAQ,UAAU,WAAW,YAAY;AAI/C,QAAM,iBAAiB,IAAI;AAAA,IACzB,MAAM,QAAQ,UAAU,WAAW,UAAU,CAAC,IACzC,UAAU,WAAW,UAAU,IAChC,CAAC;AAAA,EACP;AAEA,MAAI,OAAO;AACT,UAAM,aAAwC,CAAC;AAC/C,eAAW,CAAC,KAAK,UAAU,KAAK,OAAO,QAAQ,KAAK,GAAG;AACrD,YAAM,WAAW,sBAAsB,UAAU;AACjD,iBAAW,GAAG,IAAI,eAAe,IAAI,GAAG,IAAI,WAAW,SAAS,SAAS;AAAA,IAC3E;AAEA,QAAI,WAAW,OAAO;AACpB,YAAM,OAAO,IAAI,EAAE,OAAO,UAAU,EAAE,SAAS,EAAE,SAAS,kBAAkB;AAAA,IAC9E,WAAW,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,MAAM,GAAG;AACpD,YAAM,MAAM,IAAI,EAAE,OAAO,UAAU,EAAE,SAAS,EAAE,SAAS,cAAc;AAAA,IACzE;AAAA,EACF,OAAO;AAEL,QAAI,WAAW,OAAO;AACpB,YAAM,OAAO,IAAI,EACd,OAAO,CAAC,CAAC,EACT,YAAY,EACZ,SAAS,EACT,SAAS,yBAAyB;AAAA,IACvC,WAAW,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,MAAM,GAAG;AACpD,YAAM,MAAM,IAAI,EACb,OAAO,CAAC,CAAC,EACT,YAAY,EACZ,SAAS,EACT,SAAS,gDAAgD;AAAA,IAC9D;AAAA,EACF;AAEA,SAAO,EAAE,OAAO,KAAK;AACvB;AAOA,SAAS,sBAAsB,QAA4C;AAEzE,QAAM,QAAQ,OAAO,OAAO;AAC5B,MAAI,MAAM,QAAQ,KAAK,GAAG;AACxB,UAAM,UAAW,MAAoC;AAAA,MACnD,CAAC,MAAM,EAAE,MAAM,MAAM;AAAA,IACvB;AACA,QAAI,QAAQ,WAAW,KAAK,QAAQ,CAAC,GAAG;AACtC,aAAO,sBAAsB,QAAQ,CAAC,CAAC;AAAA,IACzC;AACA,WAAO,EAAE,QAAQ;AAAA,EACnB;AAEA,MAAI,MAAM,QAAQ,OAAO,MAAM,CAAC,GAAG;AACjC,UAAM,SAAS,OAAO,MAAM;AAC5B,QAAI,OAAO,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,KAAK,OAAO,UAAU,GAAG;AACpE,YAAM,CAAC,OAAO,QAAQ,GAAG,IAAI,IAAI;AACjC,aAAO,EAAE,KAAK,CAAC,OAAO,QAAQ,GAAG,IAAI,CAAC;AAAA,IACxC;AAAA,EACF;AAEA,UAAQ,OAAO,MAAM,GAAG;AAAA,IACtB,KAAK;AAAW,aAAO,EAAE,OAAO;AAAA,IAChC,KAAK;AAAA,IACL,KAAK;AAAW,aAAO,EAAE,OAAO;AAAA,IAChC,KAAK;AAAW,aAAO,EAAE,QAAQ;AAAA,IACjC,KAAK,SAAS;AACZ,YAAM,QAAQ,OAAO,OAAO;AAC5B,aAAO,QAAQ,EAAE,MAAM,sBAAsB,KAAK,CAAC,IAAI,EAAE,MAAM,EAAE,QAAQ,CAAC;AAAA,IAC5E;AAAA,IACA,KAAK;AAAW,aAAO,EAAE,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC;AAAA,IACvD;AAAgB,aAAO,EAAE,QAAQ;AAAA,EACnC;AACF;AAQA,SAAS,sBACP,QACA,YACW;AACX,QAAM,QAAmC,CAAC;AAE1C,aAAW,SAAS,YAAY;AAC9B,UAAM,KAAK,IAAI,EAAE,OAAO,EAAE,SAAS,mBAAmB,KAAK,EAAE;AAAA,EAC/D;AAEA,MAAI,WAAW,OAAO;AACpB,UAAM,OAAO,IAAI,EACd,OAAO,EAAE,OAAO,GAAG,EAAE,OAAO,CAAC,EAC7B,SAAS,EACT,SAAS,yBAAyB;AAAA,EACvC,WAAW,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,MAAM,GAAG;AACpD,UAAM,MAAM,IAAI,EACb,OAAO,EAAE,OAAO,GAAG,EAAE,QAAQ,CAAC,EAC9B,SAAS,EACT,SAAS,cAAc;AAAA,EAC5B;AAEA,SAAO,EAAE,OAAO,KAAK;AACvB;;;ACjOO,SAAS,uBACd,WACA,aACmB;AACnB,QAAM,UAA6B,CAAC;AAEpC,QAAM,gBACJ;AAEF,MAAI;AACJ,UAAQ,QAAQ,cAAc,KAAK,WAAW,OAAO,MAAM;AACzD,UAAM,aAAa,MAAM,CAAC;AAC1B,UAAM,aAAa,MAAM,CAAC;AAG1B,QAAI,CAAC,WAAY;AAEjB,UAAM,aAAa,gBAAgB,UAAU;AAC7C,UAAM,SAAS,YAAY,UAAU;AAErC,YAAQ,KAAK,EAAE,YAAY,YAAY,OAAO,CAAC;AAAA,EACjD;AAEA,SAAO;AACT;AAMA,SAAS,YAAY,YAAwC;AAC3D,QAAM,QAAQ,WAAW,YAAY;AACrC,MAAI,MAAM,SAAS,MAAM,KAAK,MAAM,SAAS,SAAS,EAAG,QAAO;AAChE,MAAI,MAAM,SAAS,OAAO,KAAK,MAAM,SAAS,QAAQ,EAAG,QAAO;AAChE,SAAO;AACT;AAEA,SAAS,gBAAgB,YAA6C;AACpE,QAAM,aAAsC,CAAC;AAC7C,QAAM,WAAqB,CAAC;AAE5B,QAAM,SAAS,YAAY,UAAU;AAErC,aAAW,SAAS,QAAQ;AAC1B,UAAM,aAAa,MAAM,MAAM,4BAA4B;AAC3D,QAAI,CAAC,WAAY;AAEjB,UAAM,YAAY,WAAW,CAAC;AAC9B,UAAM,WAAW,WAAW,CAAC;AAE7B,QAAI,CAAC,aAAa,CAAC,SAAU;AAE7B,UAAM,EAAE,QAAQ,WAAW,IAAI,aAAa,SAAS,KAAK,CAAC;AAC3D,eAAW,SAAS,IAAI;AACxB,QAAI,CAAC,YAAY;AACf,eAAS,KAAK,SAAS;AAAA,IACzB;AAAA,EACF;AAEA,QAAM,aAAsC;AAAA,IAC1C,MAAM;AAAA,IACN;AAAA,EACF;AAEA,MAAI,SAAS,SAAS,GAAG;AACvB,eAAW,UAAU,IAAI;AAAA,EAC3B;AAEA,SAAO;AACT;AAEA,SAAS,YAAY,MAAwB;AAC3C,QAAM,SAAmB,CAAC;AAC1B,MAAI,QAAQ;AACZ,MAAI,UAAU;AAEd,aAAW,QAAQ,MAAM;AACvB,QAAI,SAAS,OAAO,SAAS,OAAO,SAAS,KAAK;AAChD;AACA,iBAAW;AAAA,IACb,WAAW,SAAS,OAAO,SAAS,OAAO,SAAS,KAAK;AACvD;AACA,iBAAW;AAAA,IACb,WAAW,SAAS,OAAO,UAAU,GAAG;AACtC,YAAMA,WAAU,QAAQ,KAAK;AAC7B,UAAIA,SAAS,QAAO,KAAKA,QAAO;AAChC,gBAAU;AAAA,IACZ,OAAO;AACL,iBAAW;AAAA,IACb;AAAA,EACF;AAEA,QAAM,UAAU,QAAQ,KAAK;AAC7B,MAAI,QAAS,QAAO,KAAK,OAAO;AAEhC,SAAO;AACT;AAOA,SAAS,aAAa,MAA0B;AAC9C,QAAM,EAAE,MAAM,UAAU,IAAI,aAAa,IAAI;AAE7C,MAAI,SAAkC,gBAAgB,IAAI;AAC1D,MAAI,aAAa;AAEjB,aAAW,OAAO,WAAW;AAC3B,QAAI,IAAI,WAAW,WAAW,GAAG;AAC/B,mBAAa;AACb,eAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,EAAE;AAAA,IAC/C,WAAW,IAAI,WAAW,WAAW,GAAG;AACtC,eAAS,EAAE,OAAO,CAAC,QAAQ,EAAE,MAAM,OAAO,CAAC,EAAE;AAAA,IAC/C,WAAW,IAAI,WAAW,QAAQ,GAAG;AACnC,eAAS,EAAE,MAAM,SAAS,OAAO,OAAO;AAAA,IAC1C,WAAW,IAAI,WAAW,UAAU,GAAG;AACrC,mBAAa;AAAA,IACf;AAAA,EACF;AAEA,SAAO,EAAE,QAAQ,WAAW;AAC9B;AAOA,SAAS,aAAa,MAA6B;AACjD,QAAM,YAAsB,CAAC;AAC7B,MAAI,OAAO,KAAK,KAAK;AAErB,MAAI,QAAQ;AACZ,MAAI,UAAU;AACd,MAAI,YAAY;AAEhB,WAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,OAAO,IAAK;AAAA,aACP,OAAO,KAAK;AACnB;AACA,UAAI,UAAU,GAAG;AACf,kBAAU,IAAI;AACd,oBAAY;AACZ;AAAA,MACF;AAAA,IACF;AAAA,EACF;AAEA,MAAI,CAAC,WAAW;AACd,WAAO,EAAE,MAAM,MAAM,WAAW,CAAC,EAAE;AAAA,EACrC;AAEA,QAAM,OAAO,KAAK,MAAM,GAAG,OAAO;AAClC,SAAO,KAAK,MAAM,OAAO;AAEzB,SAAO,KAAK,WAAW,GAAG,GAAG;AAC3B,YAAQ;AACR,QAAI,SAAS;AACb,QAAI,WAAW;AAEf,aAAS,IAAI,GAAG,IAAI,KAAK,QAAQ,KAAK;AACpC,YAAM,KAAK,KAAK,CAAC;AACjB,UAAI,OAAO,IAAK;AAAA,eACP,OAAO,KAAK;AACnB;AACA,YAAI,UAAU,GAAG;AACf,mBAAS,IAAI;AACb,qBAAW;AACX;AAAA,QACF;AAAA,MACF;AAAA,IACF;AAEA,QAAI,CAAC,SAAU;AAEf,cAAU,KAAK,KAAK,MAAM,GAAG,MAAM,CAAC;AACpC,WAAO,KAAK,MAAM,MAAM;AAAA,EAC1B;AAEA,SAAO,EAAE,MAAM,UAAU;AAC3B;AAEA,SAAS,gBAAgB,MAAuC;AAC9D,QAAM,UAAU,KAAK,KAAK;AAE1B,MAAI,QAAQ,WAAW,UAAU,EAAG,QAAO,EAAE,MAAM,SAAS;AAC5D,MAAI,QAAQ,WAAW,UAAU,EAAG,QAAO,EAAE,MAAM,SAAS;AAC5D,MAAI,QAAQ,WAAW,WAAW,EAAG,QAAO,EAAE,MAAM,UAAU;AAC9D,MAAI,QAAQ,WAAW,QAAQ,EAAG,QAAO,EAAE,MAAM,OAAO;AACxD,MAAI,QAAQ,WAAW,WAAW,KAAK,QAAQ,WAAW,OAAO;AAC/D,WAAO,CAAC;AAEV,MAAI,QAAQ,WAAW,QAAQ,GAAG;AAChC,UAAM,aAAa,kBAAkB,OAAO;AAC5C,WAAO,EAAE,MAAM,UAAU,MAAM,WAAW;AAAA,EAC5C;AAEA,MAAI,QAAQ,WAAW,SAAS,GAAG;AACjC,UAAM,QAAQ,iBAAiB,OAAO;AACtC,QAAI,OAAO;AACT,YAAM,EAAE,QAAQ,MAAM,IAAI,aAAa,KAAK;AAC5C,aAAO,EAAE,MAAM,SAAS,MAAM;AAAA,IAChC;AACA,WAAO,EAAE,MAAM,QAAQ;AAAA,EACzB;AAEA,MAAI,QAAQ,WAAW,UAAU,GAAG;AAClC,WAAO,EAAE,MAAM,SAAS;AAAA,EAC1B;AAEA,MAAI,QAAQ,WAAW,UAAU,EAAG,QAAO,EAAE,MAAM,SAAS;AAE5D,MAAI,QAAQ,WAAW,WAAW,GAAG;AACnC,UAAM,MAAM,oBAAoB,OAAO;AACvC,WAAO,QAAQ,SAAY,EAAE,OAAO,IAAI,IAAI,CAAC;AAAA,EAC/C;AAEA,SAAO,CAAC;AACV;AAEA,SAAS,kBAAkB,MAAwB;AACjD,QAAM,QAAQ,iBAAiB,IAAI;AACnC,MAAI,CAAC,MAAO,QAAO,CAAC;AAEpB,QAAM,SAAmB,CAAC;AAC1B,QAAM,eAAe;AACrB,MAAI;AACJ,UAAQ,IAAI,aAAa,KAAK,KAAK,OAAO,MAAM;AAC9C,QAAI,EAAE,CAAC,EAAG,QAAO,KAAK,EAAE,CAAC,CAAC;AAAA,EAC5B;AACA,SAAO;AACT;AAEA,SAAS,iBAAiB,MAA6B;AACrD,QAAM,YAAY,KAAK,QAAQ,GAAG;AAClC,MAAI,cAAc,GAAI,QAAO;AAE7B,MAAI,QAAQ;AACZ,WAAS,IAAI,WAAW,IAAI,KAAK,QAAQ,KAAK;AAC5C,UAAM,KAAK,KAAK,CAAC;AACjB,QAAI,OAAO,IAAK;AAAA,aACP,OAAO,KAAK;AACnB;AACA,UAAI,UAAU,GAAG;AACf,eAAO,KAAK,MAAM,YAAY,GAAG,CAAC;AAAA,MACpC;AAAA,IACF;AAAA,EACF;AACA,SAAO;AACT;AAEA,SAAS,oBAAoB,MAAqD;AAChF,QAAM,QAAQ,iBAAiB,IAAI,GAAG,KAAK;AAC3C,MAAI,CAAC,MAAO,QAAO;AAEnB,MAAK,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,KAC3C,MAAM,WAAW,GAAG,KAAK,MAAM,SAAS,GAAG,GAAI;AAClD,WAAO,MAAM,MAAM,GAAG,EAAE;AAAA,EAC1B;AACA,MAAI,UAAU,OAAQ,QAAO;AAC7B,MAAI,UAAU,QAAS,QAAO;AAC9B,QAAM,MAAM,OAAO,KAAK;AACxB,MAAI,CAAC,OAAO,MAAM,GAAG,EAAG,QAAO;AAC/B,SAAO;AACT;;;ACzRA,SAAS,KAAAC,UAAS;AA+ClB,IAAM,eAAe,oBAAI,IAAI;AAAA,EAC3B;AAAA,EAAO;AAAA,EAAQ;AAAA,EAAO;AAAA,EAAS;AAAA,EAAU;AAAA,EAAQ;AAAA,EAAW;AAC9D,CAAC;AAED,IAAMC,yBAAwB,CAAC,QAAQ,OAAO,SAAS,QAAQ;AAYxD,SAAS,iBAAiB,MAAsC;AACrE,QAAM,SAA4B,CAAC;AAEnC,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,GAAG;AAElE,UAAM,UAAoB,CAAC;AAC3B,eAAW,OAAO,OAAO,KAAK,QAAQ,GAAG;AACvC,UAAI,aAAa,IAAI,IAAI,YAAY,CAAC,GAAG;AACvC,gBAAQ,KAAK,IAAI,YAAY,CAAC;AAAA,MAChC;AAAA,IACF;AAEA,QAAI,QAAQ,WAAW,EAAG;AAG1B,UAAM,cAAc,qBAAqB,OAAO;AAGhD,UAAM,aAAa,kBAAkB,OAAO;AAE5C,WAAO,KAAK;AAAA,MACV,MAAM;AAAA,MACN;AAAA,MACA;AAAA;AAAA,MAEA,UAAU,WAAW,OAAO;AAAA,IAC9B,CAAC;AAAA,EACH;AAEA,SAAO;AACT;AAaO,SAAS,yBACd,MACA,cACsB;AACtB,QAAM,iBAAiB,cAAc,WAAWA;AAChD,QAAM,QAA8B,CAAC;AAErC,aAAW,CAAC,SAAS,QAAQ,KAAK,OAAO,QAAQ,KAAK,SAAS,CAAC,CAAC,GAAG;AAClE,eAAW,CAAC,WAAW,SAAS,KAAK,OAAO,QAAQ,QAAQ,GAAG;AAC7D,UAAI,CAAC,aAAa,IAAI,UAAU,YAAY,CAAC,EAAG;AAEhD,YAAM,SAAS,UAAU,YAAY;AACrC,YAAM,KAAK;AAEX,YAAM,WAAWC,eAAc,QAAQ,SAAS,GAAG,WAAW;AAC9D,YAAM,cAAc,iBAAiB,QAAQ,SAAS,EAAE;AACxD,YAAM,cAAc,qBAAqB,OAAO;AAChD,YAAM,aAAa,eAAe,QAAQ,SAAS,IAAI,IAAI;AAE3D,YAAM,KAAK;AAAA,QACT,MAAM;AAAA,QACN;AAAA,QACA;AAAA,QACA,sBAAsB,eAAe,SAAS,MAAM;AAAA,QACpD,YAAY;AAAA,QACZ,MAAM;AAAA,MACR,CAAC;AAAA,IACH;AAAA,EACF;AAEA,SAAO;AACT;AAUA,eAAsB,iBAAiB,KAAmC;AACxE,QAAM,WAAW,MAAM,MAAM,GAAG;AAChC,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,iCAAiC,SAAS,MAAM,IAAI,SAAS,UAAU,EAAE;AAAA,EAC3F;AACA,QAAM,OAAQ,MAAM,SAAS,KAAK;AAClC,SAAO;AACT;AAMA,SAASA,eACP,QACA,SACA,aACQ;AACR,MAAI,aAAa;AAEf,WAAO,YACJ,QAAQ,mBAAmB,OAAO,EAClC,QAAQ,WAAW,GAAG,EACtB,YAAY,EACZ,QAAQ,OAAO,GAAG,EAClB,QAAQ,UAAU,EAAE;AAAA,EACzB;AAGA,QAAM,WAAW,QACd,QAAQ,OAAO,EAAE,EACjB,QAAQ,gBAAgB,IAAI,EAC5B,QAAQ,OAAO,GAAG,EAClB,QAAQ,OAAO,GAAG,EAClB,QAAQ,MAAM,EAAE;AAEnB,SAAO,GAAG,OAAO,YAAY,CAAC,IAAI,QAAQ;AAC5C;AAEA,SAAS,iBACP,QACA,SACA,IACQ;AACR,MAAI,GAAG,QAAS,QAAO,GAAG;AAC1B,MAAI,GAAG,YAAa,QAAO,GAAG;AAC9B,SAAO,GAAG,MAAM,IAAI,OAAO;AAC7B;AAOA,SAAS,qBAAqB,MAAsB;AAClD,SAAO,KAAK,QAAQ,gBAAgB,KAAK;AAC3C;AAGA,SAAS,kBAAkB,MAAwB;AACjD,QAAM,SAAmB,CAAC;AAC1B,QAAM,KAAK;AACX,MAAI;AACJ,UAAQ,IAAI,GAAG,KAAK,IAAI,OAAO,MAAM;AACnC,QAAI,EAAE,CAAC,EAAG,QAAO,KAAK,EAAE,CAAC,CAAC;AAAA,EAC5B;AACA,SAAO;AACT;AAcA,SAAS,eACP,QACA,SACA,IACA,MAC4B;AAG5B,QAAM,QAAmC,CAAC;AAG1C,aAAW,aAAa,kBAAkB,OAAO,GAAG;AAClD,UAAM,SAAS,IAAIF,GAChB,OAAO,EACP,SAAS,mBAAmB,SAAS,EAAE;AAAA,EAC5C;AAGA,aAAW,SAAS,GAAG,cAAc,CAAC,GAAG;AACvC,QAAI,MAAM,OAAO,UAAU,MAAM,OAAO,QAAS;AACjD,QAAI,MAAM,OAAO,QAAQ;AAGvB,UAAI,MAAM,aAAa;AACrB,cAAM,MAAM,IAAI,IAAIA,GAAE,OAAO,EAAE,SAAS,MAAM,WAAW;AAAA,MAC3D;AACA;AAAA,IACF;AAGA,UAAM,WAAW,cAAc,MAAM,UAAU,CAAC,GAAG,IAAI;AACvD,QAAI,WAAW,gBAAgB,QAAQ;AACvC,QAAI,MAAM,YAAa,YAAW,SAAS,SAAS,MAAM,WAAW;AACrE,UAAM,MAAM,IAAI,IACd,MAAM,WAAW,WAAW,SAAS,SAAS;AAAA,EAClD;AAGA,MACE,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,MAAM,KACxC,GAAG,aACH;AACA,UAAM,cACJ,GAAG,YAAY,QAAQ,kBAAkB,KACzC,OAAO,OAAO,GAAG,YAAY,OAAO,EAAE,CAAC;AAEzC,QAAI,aAAa,QAAQ;AACvB,YAAM,WAAW,cAAc,YAAY,QAAQ,IAAI;AACvD,YAAM,aAAa,sBAAsB,UAAU,IAAI;AACvD,YAAM,MAAM,IAAI,GAAG,YAAY,WAC3B,aACA,WAAW,SAAS;AAAA,IAC1B,OAAO;AACL,YAAM,MAAM,IAAIA,GACb,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAC9B,SAAS,EACT,SAAS,cAAc;AAAA,IAC5B;AAAA,EACF;AAEA,SAAOA,GAAE,OAAO,KAAsB;AACxC;AAUA,SAAS,cACP,QACA,MACyB;AACzB,QAAM,MAAM,OAAO,MAAM;AACzB,MAAI,OAAO,QAAQ,SAAU,QAAO;AAEpC,QAAM,SAAS;AACf,MAAI,CAAC,IAAI,WAAW,MAAM,EAAG,QAAO;AAEpC,QAAM,aAAa,IAAI,MAAM,OAAO,MAAM;AAC1C,QAAM,WAAW,KAAK,YAAY,UAAU,UAAU;AACtD,SAAO,YAAY;AACrB;AAUA,SAAS,sBACP,QACA,MACW;AACX,MAAI,OAAO,MAAM,MAAM,UAAU;AAC/B,WAAO,gBAAgB,MAAM;AAAA,EAC/B;AAEA,QAAM,QAAQ,OAAO,YAAY;AACjC,MAAI,CAAC,OAAO;AACV,WAAOA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC,EAAE,SAAS,cAAc;AAAA,EAClE;AAEA,QAAM,WAAW,IAAI;AAAA,IACnB,MAAM,QAAQ,OAAO,UAAU,CAAC,IAAK,OAAO,UAAU,IAAiB,CAAC;AAAA,EAC1E;AAEA,QAAM,QAAmC,CAAC;AAE1C,aAAW,CAAC,UAAU,UAAU,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1D,UAAM,WAAW,cAAc,YAAY,IAAI;AAC/C,UAAM,WAAW,gBAAgB,QAAQ;AACzC,UAAM,QAAQ,IAAI,SAAS,IAAI,QAAQ,IAAI,WAAW,SAAS,SAAS;AAAA,EAC1E;AAEA,SAAOA,GAAE,OAAO,KAAsB;AACxC;AAOA,SAAS,gBAAgB,QAA4C;AACnE,QAAM,OAAO,OAAO,MAAM;AAG1B,QAAM,QAAQ,OAAO,OAAO,KAAK,OAAO,OAAO;AAC/C,MAAI,MAAM,QAAQ,KAAK,KAAK,MAAM,UAAU,GAAG;AAC7C,UAAM,UAAW,MAAoC;AAAA,MAAI,CAAC,MACxD,gBAAgB,CAAC;AAAA,IACnB;AAEA,UAAM,CAAC,OAAO,QAAQ,GAAG,IAAI,IAAI;AACjC,WAAOA,GAAE,MAAM,CAAC,OAAO,QAAQ,GAAG,IAAI,CAAC;AAAA,EACzC;AAEA,MAAI,OAAO,MAAM,MAAM,QAAW;AAChC,UAAM,SAAS,OAAO,MAAM;AAC5B,QAAI,OAAO,MAAM,CAAC,MAAM,OAAO,MAAM,QAAQ,GAAG;AAC9C,YAAM,CAAC,OAAO,QAAQ,GAAG,IAAI,IAAI;AACjC,UAAI,UAAU,UAAa,WAAW,QAAW;AAC/C,eAAOA,GAAE,KAAK,CAAC,OAAO,QAAQ,GAAG,IAAI,CAAC;AAAA,MACxC;AACA,UAAI,UAAU,OAAW,QAAOA,GAAE,QAAQ,KAAK;AAAA,IACjD;AACA,WAAOA,GAAE,QAAQ;AAAA,EACnB;AAEA,UAAQ,MAAM;AAAA,IACZ,KAAK;AACH,aAAOA,GAAE,OAAO;AAAA,IAClB,KAAK;AAAA,IACL,KAAK;AACH,aAAOA,GAAE,OAAO;AAAA,IAClB,KAAK;AACH,aAAOA,GAAE,QAAQ;AAAA,IACnB,KAAK;AACH,aAAOA,GAAE,KAAK;AAAA,IAChB,KAAK,SAAS;AACZ,YAAM,QAAQ,OAAO,OAAO;AAC5B,aAAO,QAAQA,GAAE,MAAM,gBAAgB,KAAK,CAAC,IAAIA,GAAE,MAAMA,GAAE,QAAQ,CAAC;AAAA,IACtE;AAAA,IACA,KAAK,UAAU;AACb,YAAM,QAAQ,OAAO,YAAY;AAGjC,UAAI,CAAC,MAAO,QAAOA,GAAE,OAAOA,GAAE,OAAO,GAAGA,GAAE,QAAQ,CAAC;AAEnD,YAAM,WAAW,IAAI;AAAA,QACnB,MAAM,QAAQ,OAAO,UAAU,CAAC,IAC3B,OAAO,UAAU,IAClB,CAAC;AAAA,MACP;AACA,YAAM,aAAwC,CAAC;AAC/C,iBAAW,CAAC,GAAG,CAAC,KAAK,OAAO,QAAQ,KAAK,GAAG;AAC1C,cAAM,QAAQ,gBAAgB,CAAC;AAC/B,mBAAW,CAAC,IAAI,SAAS,IAAI,CAAC,IAAI,QAAQ,MAAM,SAAS;AAAA,MAC3D;AACA,aAAOA,GAAE,OAAO,UAA2B;AAAA,IAC7C;AAAA,IACA;AACE,aAAOA,GAAE,QAAQ;AAAA,EACrB;AACF;;;ACxaA,eAAsB,YACpB,MACA,QACA,SACwB;AACxB,QAAM,KAAK,OAAO,WAAW;AAC7B,QAAM,YAAY,oBAAI,KAAK;AAE3B,MAAI;AACF,QAAI;AAEJ,QAAI,KAAK,SAAS;AAEhB,iBAAW,MAAM,KAAK,QAAQ,MAAM;AAAA,IACtC,WAAW,KAAK,cAAc,KAAK,MAAM;AAEvC,iBAAW,MAAM,gBAAgB,MAAM,QAAQ,OAAO;AAAA,IACxD,OAAO;AACL,YAAM,IAAI,MAAM,SAAS,KAAK,IAAI,wCAAwC;AAAA,IAC5E;AAEA,WAAO;AAAA,MACL;AAAA,MACA,UAAU,KAAK;AAAA,MACf,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ;AAAA,MACA,WAAW,CAAC,KAAK;AAAA,MACjB,YAAY;AAAA,IACd;AAAA,EACF,SAAS,OAAO;AACd,WAAO;AAAA,MACL;AAAA,MACA,UAAU,KAAK;AAAA,MACf,YAAY;AAAA,MACZ,YAAY;AAAA,MACZ,UAAU,EAAE,OAAO,iBAAiB,QAAQ,MAAM,UAAU,gBAAgB;AAAA,MAC5E,WAAW;AAAA,MACX,YAAY;AAAA,IACd;AAAA,EACF;AACF;AASA,eAAe,gBACb,MACA,QACA,SACkB;AAClB,QAAM,SAAS,KAAK;AACpB,MAAI,MAAM,GAAG,QAAQ,OAAO,GAAG,KAAK,IAAI;AAGxC,aAAW,CAAC,KAAK,KAAK,KAAK,OAAO,QAAQ,MAAM,GAAG;AACjD,QAAI,IAAI,SAAS,IAAI,GAAG,EAAE,GAAG;AAC3B,YAAM,IAAI,QAAQ,IAAI,GAAG,IAAI,mBAAmB,OAAO,KAAK,CAAC,CAAC;AAAA,IAChE;AAAA,EACF;AAEA,QAAM,eAA4B;AAAA,IAChC;AAAA,IACA,SAAS;AAAA,MACP,gBAAgB;AAAA,MAChB,GAAG,QAAQ;AAAA,IACb;AAAA,EACF;AAGA,MAAI,WAAW,SAAS,OAAO,OAAO;AACpC,UAAM,cAAc,IAAI;AAAA,MACtB,OAAO;AAAA,IACT;AACA,WAAO,IAAI,YAAY,SAAS,CAAC;AAAA,EACnC,WAAW,CAAC,QAAQ,OAAO,OAAO,EAAE,SAAS,MAAM,KAAK,OAAO,MAAM;AACnE,iBAAa,OAAO,KAAK,UAAU,OAAO,IAAI;AAAA,EAChD;AAEA,QAAM,WAAW,MAAM,MAAM,KAAK,YAAY;AAE9C,MAAI,CAAC,SAAS,IAAI;AAChB,UAAM,IAAI,MAAM,QAAQ,SAAS,MAAM,KAAK,SAAS,UAAU,EAAE;AAAA,EACnE;AAEA,QAAM,cAAc,SAAS,QAAQ,IAAI,cAAc,KAAK;AAC5D,MAAI,YAAY,SAAS,kBAAkB,GAAG;AAC5C,WAAO,SAAS,KAAK;AAAA,EACvB;AACA,SAAO,SAAS,KAAK;AACvB;","names":["trimmed","z","DEFAULT_WRITE_METHODS","buildToolName"]}
package/package.json ADDED
@@ -0,0 +1,45 @@
1
+ {
2
+ "name": "@ai-me-chat/core",
3
+ "version": "0.0.1",
4
+ "description": "AI-Me core — framework-agnostic AI copilot engine",
5
+ "license": "MIT",
6
+ "repository": {
7
+ "type": "git",
8
+ "url": "https://github.com/aselims/ai-me-chat",
9
+ "directory": "packages/core"
10
+ },
11
+ "type": "module",
12
+ "main": "./dist/index.cjs",
13
+ "module": "./dist/index.js",
14
+ "types": "./dist/index.d.ts",
15
+ "exports": {
16
+ ".": {
17
+ "types": "./dist/index.d.ts",
18
+ "import": "./dist/index.js",
19
+ "require": "./dist/index.cjs"
20
+ }
21
+ },
22
+ "files": [
23
+ "dist"
24
+ ],
25
+ "sideEffects": false,
26
+ "peerDependencies": {
27
+ "ai": "^6.0.0",
28
+ "zod": "^4.0.0"
29
+ },
30
+ "devDependencies": {
31
+ "ai": "^6.0.116",
32
+ "zod": "^4.3.6",
33
+ "typescript": "^5.9.3",
34
+ "tsup": "^8.5.1",
35
+ "vitest": "^4.1.0"
36
+ },
37
+ "scripts": {
38
+ "build": "tsup",
39
+ "dev": "tsup --watch",
40
+ "test": "vitest run",
41
+ "typecheck": "tsc --noEmit",
42
+ "lint": "eslint src/",
43
+ "clean": "rm -rf dist"
44
+ }
45
+ }