@kairos-sdk/core 0.3.2 → 0.4.0

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.
@@ -6,10 +6,11 @@ import {
6
6
  N8nFieldStripper,
7
7
  N8nValidator,
8
8
  NodeRegistry,
9
+ PatternAnalyzer,
9
10
  PromptBuilder,
10
11
  TelemetryReader,
11
12
  nullLogger
12
- } from "./chunk-RYGYNOR6.js";
13
+ } from "./chunk-NJ6QZBIC.js";
13
14
 
14
15
  // src/mcp-server.ts
15
16
  import { McpServer } from "@modelcontextprotocol/sdk/server/mcp.js";
@@ -380,6 +381,27 @@ server.tool(
380
381
  };
381
382
  }
382
383
  );
384
+ server.tool(
385
+ "kairos_patterns",
386
+ "Analyze telemetry data and return failure patterns, build stats, and credential breakdowns. Useful for understanding what goes wrong most often and how to prevent it.",
387
+ {
388
+ days: z.number().default(30).describe("Number of days of telemetry to analyze"),
389
+ limit: z.number().optional().describe("Maximum number of failure patterns to return")
390
+ },
391
+ async ({ days, limit }) => {
392
+ const analyzer = PatternAnalyzer.fromEnv();
393
+ const analysis = await analyzer.analyzeAndSave(days);
394
+ if (limit !== void 0 && limit > 0) {
395
+ analysis.topFailureRules = analysis.topFailureRules.slice(0, limit);
396
+ }
397
+ return {
398
+ content: [{
399
+ type: "text",
400
+ text: JSON.stringify(analysis, null, 2)
401
+ }]
402
+ };
403
+ }
404
+ );
383
405
  server.tool(
384
406
  "kairos_list",
385
407
  "List all workflows deployed on the connected n8n instance.",
@@ -1 +1 @@
1
- {"version":3,"sources":["../src/mcp-server.ts","../src/validation/node-syncer.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Kairos MCP Server — decomposed architecture.\n *\n * The host LLM (Claude, GPT, Gemini, whatever) generates the workflow.\n * Kairos provides the knowledge (system prompt, library, failure patterns)\n * and guardrails (validator, deployer). Zero Anthropic API key needed.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport { FileLibrary } from './library/file-library.js'\nimport { N8nValidator } from './validation/validator.js'\nimport { N8nFieldStripper } from './providers/n8n/stripper.js'\nimport { N8nApiClient } from './providers/n8n/api-client.js'\nimport { PromptBuilder } from './generation/prompt-builder.js'\nimport { TelemetryReader } from './telemetry/reader.js'\nimport { NodeSyncer, type SyncResult } from './validation/node-syncer.js'\nimport { nullLogger } from './utils/logger.js'\nimport type { N8nWorkflow } from './types/workflow.js'\nimport { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')) as { version: string }\n\nconst library = new FileLibrary()\nlet validator = new N8nValidator()\nconst nodeSyncer = new NodeSyncer()\nlet lastSync: SyncResult | null = null\nconst stripper = new N8nFieldStripper()\nconst promptBuilder = new PromptBuilder()\n\nfunction getTelemetryReader(): TelemetryReader | null {\n try {\n return new TelemetryReader()\n } catch {\n return null\n }\n}\n\nfunction isAllowed(action: 'deploy' | 'activate' | 'delete'): boolean {\n const key = `KAIROS_MCP_ALLOW_${action.toUpperCase()}`\n return process.env[key] === 'true'\n}\n\nfunction getApiClient(): N8nApiClient {\n const baseUrl = process.env['N8N_BASE_URL']\n const apiKey = process.env['N8N_API_KEY']\n if (!baseUrl || !apiKey) {\n throw new Error('N8N_BASE_URL and N8N_API_KEY environment variables are required for n8n operations')\n }\n return new N8nApiClient(baseUrl, apiKey, nullLogger)\n}\n\nasync function autoSync(): Promise<SyncResult | null> {\n if (lastSync) return lastSync\n const baseUrl = process.env['N8N_BASE_URL']\n const apiKey = process.env['N8N_API_KEY']\n if (!baseUrl || !apiKey) return null\n try {\n const client = new N8nApiClient(baseUrl, apiKey, nullLogger)\n const nodeTypes = await client.getNodeTypes()\n if (nodeTypes.length === 0) return null\n lastSync = nodeSyncer.sync(nodeTypes)\n validator = new N8nValidator(lastSync.registry)\n return lastSync\n } catch {\n return null\n }\n}\n\nconst server = new McpServer({\n name: 'kairos',\n version: pkg.version,\n})\n\n// ── Core generation tools (no API key needed) ──────────────────────────────\n\nserver.tool(\n 'kairos_prompt',\n 'Get the specialized n8n workflow generation context. Returns a system prompt with node catalog, connection rules, validation rules, plus library matches and failure patterns for the given description. Feed this to yourself as context, then generate the workflow JSON.',\n {\n description: z.string().describe('Plain-English description of the workflow to build'),\n name: z.string().optional().describe('Optional workflow name override'),\n },\n async ({ description, name }) => {\n const baseUrl = process.env['N8N_BASE_URL']\n const apiKey = process.env['N8N_API_KEY']\n if (!baseUrl || !apiKey) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'N8N_BASE_URL and N8N_API_KEY are required. Kairos needs to sync your n8n instance\\'s node types to generate accurate workflows.' }),\n }],\n isError: true,\n }\n }\n\n await library.initialize()\n const syncResult = await autoSync()\n const matches = await library.search(description)\n const telemetryReader = getTelemetryReader()\n const failureRates = await telemetryReader?.getFailureRates() ?? []\n\n const request = { description, ...(name ? { name } : {}) }\n const built = promptBuilder.build(request, matches, failureRates, syncResult?.catalogText)\n\n const systemText = built.system.map(block => block.text).join('\\n\\n---\\n\\n')\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n mode: built.mode,\n matchCount: matches.length,\n topMatchScore: matches[0]?.score ?? null,\n nodeCatalog: syncResult ? 'synced' : 'static',\n nodeCount: syncResult?.nodeCount ?? null,\n ...(syncResult ? {} : { syncWarning: 'Could not sync node types from your n8n instance. Using static fallback catalog — generated workflows may not match your exact n8n setup.' }),\n systemPrompt: systemText,\n userMessage: built.userMessage,\n outputFormat: {\n description: 'Generate a JSON object with this exact structure. The workflow field contains the n8n workflow. credentialsNeeded lists services requiring credentials.',\n schema: {\n workflow: {\n name: 'string — descriptive workflow name',\n nodes: 'array — n8n node objects with id (UUID v4), type, typeVersion, name, position, parameters',\n connections: 'object — keyed by source node NAME, maps to target nodes',\n settings: 'object — include executionOrder: \"v1\"',\n },\n credentialsNeeded: [{\n service: 'string — e.g. \"Slack\"',\n credentialType: 'string — e.g. \"slackOAuth2Api\"',\n description: 'string — what the user needs to set up',\n }],\n },\n },\n }, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_validate',\n 'Validate n8n workflow JSON against 23 structural rules. Returns pass/fail with specific issues. If validation fails, fix the issues and call this again. Errors block deployment; warnings are advisory.',\n {\n workflow: z.string().describe('The workflow JSON string to validate'),\n },\n async ({ workflow: workflowStr }) => {\n let parsed: N8nWorkflow\n try {\n parsed = JSON.parse(workflowStr) as N8nWorkflow\n } catch (e) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n valid: false,\n error: `Invalid JSON: ${e instanceof Error ? e.message : String(e)}`,\n }, null, 2),\n }],\n }\n }\n\n const result = validator.validate(parsed)\n const errors = result.issues.filter(i => i.severity === 'error')\n const warnings = result.issues.filter(i => i.severity === 'warn')\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n valid: result.valid,\n errorCount: errors.length,\n warningCount: warnings.length,\n errors: errors.map(i => ({\n rule: i.rule,\n message: i.message,\n nodeId: i.nodeId ?? null,\n })),\n warnings: warnings.map(i => ({\n rule: i.rule,\n message: i.message,\n nodeId: i.nodeId ?? null,\n })),\n deployable: errors.length === 0,\n }, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_deploy',\n 'Deploy a validated workflow to n8n. Pass the workflow JSON that passed kairos_validate. Strips server-assigned fields automatically. Requires N8N_BASE_URL and N8N_API_KEY.',\n {\n workflow: z.string().describe('The validated workflow JSON string to deploy'),\n activate: z.boolean().default(false).describe('Activate the workflow immediately after deployment'),\n },\n async ({ workflow: workflowStr, activate }) => {\n if (!isAllowed('deploy')) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'Deploy is disabled. Set KAIROS_MCP_ALLOW_DEPLOY=true to enable.' }),\n }],\n isError: true,\n }\n }\n\n let parsed: N8nWorkflow\n try {\n parsed = JSON.parse(workflowStr) as N8nWorkflow\n } catch (e) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: `Invalid JSON: ${e instanceof Error ? e.message : String(e)}` }),\n }],\n }\n }\n\n const validation = validator.validate(parsed)\n const errors = validation.issues.filter(i => i.severity === 'error')\n if (errors.length > 0) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n error: 'Workflow has validation errors — fix them before deploying',\n errors: errors.map(i => ({ rule: i.rule, message: i.message })),\n }, null, 2),\n }],\n }\n }\n\n const client = getApiClient()\n const stripped = stripper.stripForCreate(parsed)\n const response = await client.createWorkflow(stripped)\n\n if (activate) {\n if (!isAllowed('activate')) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n workflowId: response.id,\n name: response.name,\n activated: false,\n warning: 'Workflow deployed but activation is disabled. Set KAIROS_MCP_ALLOW_ACTIVATE=true to enable.',\n url: `${process.env['N8N_BASE_URL']}/workflow/${response.id}`,\n }, null, 2),\n }],\n }\n }\n await client.activateWorkflow(response.id)\n }\n\n // Save to library for future retrieval\n await library.initialize()\n await library.save(parsed, {\n description: parsed.name,\n generationMode: 'scratch',\n generationAttempts: 1,\n })\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n workflowId: response.id,\n name: response.name,\n activated: activate,\n url: `${process.env['N8N_BASE_URL']}/workflow/${response.id}`,\n }, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_search',\n 'Search the local workflow library for similar past builds. Returns matching workflows with scores, useful for finding examples and reusing patterns.',\n {\n query: z.string().describe('Search query — a workflow description or keywords'),\n limit: z.number().default(5).describe('Maximum number of results'),\n },\n async ({ query, limit }) => {\n await library.initialize()\n const matches = await library.search(query)\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(\n matches.slice(0, limit).map(m => ({\n score: Number(m.score.toFixed(3)),\n mode: m.mode,\n description: m.workflow.description,\n nodeCount: m.workflow.workflow.nodes.length,\n nodes: m.workflow.workflow.nodes.map(n => n.name),\n failurePatterns: m.workflow.failurePatterns ?? [],\n })),\n null,\n 2,\n ),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_sync',\n 'Sync the node catalog from your live n8n instance. Fetches all installed node types and versions so Kairos knows exactly what your n8n supports. Automatically called by kairos_prompt when n8n credentials are set, but you can call this manually to force a refresh.',\n {},\n async () => {\n const baseUrl = process.env['N8N_BASE_URL']\n const apiKey = process.env['N8N_API_KEY']\n if (!baseUrl || !apiKey) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'N8N_BASE_URL and N8N_API_KEY are required for sync.' }),\n }],\n isError: true,\n }\n }\n\n lastSync = null\n const result = await autoSync()\n if (!result) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'Failed to fetch node types from n8n. Check your credentials and that your instance is running.' }),\n }],\n isError: true,\n }\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n synced: true,\n nodeCount: result.nodeCount,\n newNodes: result.newNodes,\n message: `Synced ${result.nodeCount} node types from your n8n instance (${result.newNodes} not in default catalog).`,\n }, null, 2),\n }],\n }\n },\n)\n\n// ── n8n management tools (need N8N_BASE_URL + N8N_API_KEY) ─────────────────\n\nserver.tool(\n 'kairos_list',\n 'List all workflows deployed on the connected n8n instance.',\n {},\n async () => {\n const client = getApiClient()\n const workflows = await client.listWorkflows()\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(workflows, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_get',\n 'Get the full JSON definition of a specific workflow by ID.',\n {\n workflow_id: z.string().describe('The n8n workflow ID'),\n },\n async ({ workflow_id }) => {\n const client = getApiClient()\n const workflow = await client.getWorkflow(workflow_id)\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(workflow, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_activate',\n 'Activate a deployed workflow so it starts running on triggers.',\n {\n workflow_id: z.string().describe('The n8n workflow ID to activate'),\n },\n async ({ workflow_id }) => {\n if (!isAllowed('activate')) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'Activate is disabled. Set KAIROS_MCP_ALLOW_ACTIVATE=true to enable.' }),\n }],\n isError: true,\n }\n }\n\n const client = getApiClient()\n await client.activateWorkflow(workflow_id)\n\n return {\n content: [{\n type: 'text' as const,\n text: `Activated workflow ${workflow_id}`,\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_deactivate',\n 'Deactivate a running workflow.',\n {\n workflow_id: z.string().describe('The n8n workflow ID to deactivate'),\n },\n async ({ workflow_id }) => {\n const client = getApiClient()\n await client.deactivateWorkflow(workflow_id)\n\n return {\n content: [{\n type: 'text' as const,\n text: `Deactivated workflow ${workflow_id}`,\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_delete',\n 'Delete a workflow from n8n. This is irreversible.',\n {\n workflow_id: z.string().describe('The n8n workflow ID to delete'),\n },\n async ({ workflow_id }) => {\n if (!isAllowed('delete')) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'Delete is disabled. Set KAIROS_MCP_ALLOW_DELETE=true to enable.' }),\n }],\n isError: true,\n }\n }\n\n const client = getApiClient()\n await client.deleteWorkflow(workflow_id)\n\n return {\n content: [{\n type: 'text' as const,\n text: `Deleted workflow ${workflow_id}`,\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_executions',\n 'List recent executions for a workflow, showing status and timing.',\n {\n workflow_id: z.string().optional().describe('Filter to a specific workflow ID (omit for all)'),\n limit: z.number().default(20).describe('Maximum number of executions to return'),\n },\n async ({ workflow_id, limit }) => {\n const client = getApiClient()\n const executions = await client.getExecutions(workflow_id, { limit })\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(executions, null, 2),\n }],\n }\n },\n)\n\nasync function main() {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\nmain().catch((err: unknown) => {\n console.error('Kairos MCP server failed to start:', err)\n process.exit(1)\n})\n","import type { N8nNodeTypeInfo } from '../providers/n8n/types.js'\nimport type { NodeDefinition } from './registry.js'\nimport { NodeRegistry, DEFAULT_REGISTRY } from './registry.js'\n\nconst TRIGGER_PATTERNS = [/trigger/i, /Trigger$/]\n\nexport interface SyncResult {\n registry: NodeRegistry\n catalogText: string\n nodeCount: number\n newNodes: number\n}\n\nexport class NodeSyncer {\n private readonly baseRegistry: Map<string, NodeDefinition>\n\n constructor() {\n this.baseRegistry = new Map(DEFAULT_REGISTRY.map(d => [d.type, d]))\n }\n\n sync(liveNodes: N8nNodeTypeInfo[]): SyncResult {\n const merged = new Map(this.baseRegistry)\n let newNodes = 0\n\n for (const node of liveNodes) {\n const versions = Array.isArray(node.version) ? node.version : [node.version]\n const isTrigger = TRIGGER_PATTERNS.some(p => p.test(node.name))\n const credentialType = node.credentials?.[0]?.name\n\n const existing = merged.get(node.name)\n if (existing) {\n const allVersions = new Set([...existing.safeTypeVersions, ...versions])\n merged.set(node.name, {\n ...existing,\n safeTypeVersions: [...allVersions].sort((a, b) => a - b),\n })\n } else {\n newNodes++\n merged.set(node.name, {\n type: node.name,\n safeTypeVersions: versions.sort((a, b) => a - b),\n requiredParams: [],\n ...(credentialType ? { credentialType } : {}),\n ...(isTrigger ? { isTrigger: true } : {}),\n })\n }\n }\n\n const definitions = [...merged.values()]\n const registry = new NodeRegistry(definitions)\n const catalogText = this.buildCatalog(definitions)\n\n return { registry, catalogText, nodeCount: definitions.length, newNodes }\n }\n\n private buildCatalog(definitions: NodeDefinition[]): string {\n const triggers = definitions.filter(d => d.isTrigger)\n const regular = definitions.filter(d => !d.isTrigger)\n\n const formatEntry = (d: NodeDefinition): string => {\n const versions = d.safeTypeVersions.join(', ')\n const cred = d.credentialType ? ` — cred: ${d.credentialType}` : ''\n return `${d.type} typeVersion: ${versions}${cred}`\n }\n\n const triggerLines = triggers.map(formatEntry).join('\\n')\n const regularLines = regular.map(formatEntry).join('\\n')\n\n return `## NODE CATALOG — synced from your n8n instance (${definitions.length} node types)\n\n### Triggers:\n${triggerLines}\n\n### Regular nodes:\n${regularLines}`\n }\n}\n"],"mappings":"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","names":[]}
1
+ {"version":3,"sources":["../src/mcp-server.ts","../src/validation/node-syncer.ts"],"sourcesContent":["#!/usr/bin/env node\n\n/**\n * Kairos MCP Server — decomposed architecture.\n *\n * The host LLM (Claude, GPT, Gemini, whatever) generates the workflow.\n * Kairos provides the knowledge (system prompt, library, failure patterns)\n * and guardrails (validator, deployer). Zero Anthropic API key needed.\n */\n\nimport { McpServer } from '@modelcontextprotocol/sdk/server/mcp.js'\nimport { StdioServerTransport } from '@modelcontextprotocol/sdk/server/stdio.js'\nimport { z } from 'zod'\nimport { FileLibrary } from './library/file-library.js'\nimport { N8nValidator } from './validation/validator.js'\nimport { N8nFieldStripper } from './providers/n8n/stripper.js'\nimport { N8nApiClient } from './providers/n8n/api-client.js'\nimport { PromptBuilder } from './generation/prompt-builder.js'\nimport { TelemetryReader } from './telemetry/reader.js'\nimport { PatternAnalyzer } from './telemetry/pattern-analyzer.js'\nimport { NodeSyncer, type SyncResult } from './validation/node-syncer.js'\nimport { nullLogger } from './utils/logger.js'\nimport type { N8nWorkflow } from './types/workflow.js'\nimport { readFileSync } from 'node:fs'\nimport { dirname, join } from 'node:path'\nimport { fileURLToPath } from 'node:url'\n\nconst __dirname = dirname(fileURLToPath(import.meta.url))\nconst pkg = JSON.parse(readFileSync(join(__dirname, '..', 'package.json'), 'utf-8')) as { version: string }\n\nconst library = new FileLibrary()\nlet validator = new N8nValidator()\nconst nodeSyncer = new NodeSyncer()\nlet lastSync: SyncResult | null = null\nconst stripper = new N8nFieldStripper()\nconst promptBuilder = new PromptBuilder()\n\nfunction getTelemetryReader(): TelemetryReader | null {\n try {\n return new TelemetryReader()\n } catch {\n return null\n }\n}\n\nfunction isAllowed(action: 'deploy' | 'activate' | 'delete'): boolean {\n const key = `KAIROS_MCP_ALLOW_${action.toUpperCase()}`\n return process.env[key] === 'true'\n}\n\nfunction getApiClient(): N8nApiClient {\n const baseUrl = process.env['N8N_BASE_URL']\n const apiKey = process.env['N8N_API_KEY']\n if (!baseUrl || !apiKey) {\n throw new Error('N8N_BASE_URL and N8N_API_KEY environment variables are required for n8n operations')\n }\n return new N8nApiClient(baseUrl, apiKey, nullLogger)\n}\n\nasync function autoSync(): Promise<SyncResult | null> {\n if (lastSync) return lastSync\n const baseUrl = process.env['N8N_BASE_URL']\n const apiKey = process.env['N8N_API_KEY']\n if (!baseUrl || !apiKey) return null\n try {\n const client = new N8nApiClient(baseUrl, apiKey, nullLogger)\n const nodeTypes = await client.getNodeTypes()\n if (nodeTypes.length === 0) return null\n lastSync = nodeSyncer.sync(nodeTypes)\n validator = new N8nValidator(lastSync.registry)\n return lastSync\n } catch {\n return null\n }\n}\n\nconst server = new McpServer({\n name: 'kairos',\n version: pkg.version,\n})\n\n// ── Core generation tools (no API key needed) ──────────────────────────────\n\nserver.tool(\n 'kairos_prompt',\n 'Get the specialized n8n workflow generation context. Returns a system prompt with node catalog, connection rules, validation rules, plus library matches and failure patterns for the given description. Feed this to yourself as context, then generate the workflow JSON.',\n {\n description: z.string().describe('Plain-English description of the workflow to build'),\n name: z.string().optional().describe('Optional workflow name override'),\n },\n async ({ description, name }) => {\n const baseUrl = process.env['N8N_BASE_URL']\n const apiKey = process.env['N8N_API_KEY']\n if (!baseUrl || !apiKey) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'N8N_BASE_URL and N8N_API_KEY are required. Kairos needs to sync your n8n instance\\'s node types to generate accurate workflows.' }),\n }],\n isError: true,\n }\n }\n\n await library.initialize()\n const syncResult = await autoSync()\n const matches = await library.search(description)\n const telemetryReader = getTelemetryReader()\n const failureRates = await telemetryReader?.getFailureRates() ?? []\n\n const request = { description, ...(name ? { name } : {}) }\n const built = promptBuilder.build(request, matches, failureRates, syncResult?.catalogText)\n\n const systemText = built.system.map(block => block.text).join('\\n\\n---\\n\\n')\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n mode: built.mode,\n matchCount: matches.length,\n topMatchScore: matches[0]?.score ?? null,\n nodeCatalog: syncResult ? 'synced' : 'static',\n nodeCount: syncResult?.nodeCount ?? null,\n ...(syncResult ? {} : { syncWarning: 'Could not sync node types from your n8n instance. Using static fallback catalog — generated workflows may not match your exact n8n setup.' }),\n systemPrompt: systemText,\n userMessage: built.userMessage,\n outputFormat: {\n description: 'Generate a JSON object with this exact structure. The workflow field contains the n8n workflow. credentialsNeeded lists services requiring credentials.',\n schema: {\n workflow: {\n name: 'string — descriptive workflow name',\n nodes: 'array — n8n node objects with id (UUID v4), type, typeVersion, name, position, parameters',\n connections: 'object — keyed by source node NAME, maps to target nodes',\n settings: 'object — include executionOrder: \"v1\"',\n },\n credentialsNeeded: [{\n service: 'string — e.g. \"Slack\"',\n credentialType: 'string — e.g. \"slackOAuth2Api\"',\n description: 'string — what the user needs to set up',\n }],\n },\n },\n }, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_validate',\n 'Validate n8n workflow JSON against 23 structural rules. Returns pass/fail with specific issues. If validation fails, fix the issues and call this again. Errors block deployment; warnings are advisory.',\n {\n workflow: z.string().describe('The workflow JSON string to validate'),\n },\n async ({ workflow: workflowStr }) => {\n let parsed: N8nWorkflow\n try {\n parsed = JSON.parse(workflowStr) as N8nWorkflow\n } catch (e) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n valid: false,\n error: `Invalid JSON: ${e instanceof Error ? e.message : String(e)}`,\n }, null, 2),\n }],\n }\n }\n\n const result = validator.validate(parsed)\n const errors = result.issues.filter(i => i.severity === 'error')\n const warnings = result.issues.filter(i => i.severity === 'warn')\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n valid: result.valid,\n errorCount: errors.length,\n warningCount: warnings.length,\n errors: errors.map(i => ({\n rule: i.rule,\n message: i.message,\n nodeId: i.nodeId ?? null,\n })),\n warnings: warnings.map(i => ({\n rule: i.rule,\n message: i.message,\n nodeId: i.nodeId ?? null,\n })),\n deployable: errors.length === 0,\n }, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_deploy',\n 'Deploy a validated workflow to n8n. Pass the workflow JSON that passed kairos_validate. Strips server-assigned fields automatically. Requires N8N_BASE_URL and N8N_API_KEY.',\n {\n workflow: z.string().describe('The validated workflow JSON string to deploy'),\n activate: z.boolean().default(false).describe('Activate the workflow immediately after deployment'),\n },\n async ({ workflow: workflowStr, activate }) => {\n if (!isAllowed('deploy')) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'Deploy is disabled. Set KAIROS_MCP_ALLOW_DEPLOY=true to enable.' }),\n }],\n isError: true,\n }\n }\n\n let parsed: N8nWorkflow\n try {\n parsed = JSON.parse(workflowStr) as N8nWorkflow\n } catch (e) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: `Invalid JSON: ${e instanceof Error ? e.message : String(e)}` }),\n }],\n }\n }\n\n const validation = validator.validate(parsed)\n const errors = validation.issues.filter(i => i.severity === 'error')\n if (errors.length > 0) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n error: 'Workflow has validation errors — fix them before deploying',\n errors: errors.map(i => ({ rule: i.rule, message: i.message })),\n }, null, 2),\n }],\n }\n }\n\n const client = getApiClient()\n const stripped = stripper.stripForCreate(parsed)\n const response = await client.createWorkflow(stripped)\n\n if (activate) {\n if (!isAllowed('activate')) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n workflowId: response.id,\n name: response.name,\n activated: false,\n warning: 'Workflow deployed but activation is disabled. Set KAIROS_MCP_ALLOW_ACTIVATE=true to enable.',\n url: `${process.env['N8N_BASE_URL']}/workflow/${response.id}`,\n }, null, 2),\n }],\n }\n }\n await client.activateWorkflow(response.id)\n }\n\n // Save to library for future retrieval\n await library.initialize()\n await library.save(parsed, {\n description: parsed.name,\n generationMode: 'scratch',\n generationAttempts: 1,\n })\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n workflowId: response.id,\n name: response.name,\n activated: activate,\n url: `${process.env['N8N_BASE_URL']}/workflow/${response.id}`,\n }, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_search',\n 'Search the local workflow library for similar past builds. Returns matching workflows with scores, useful for finding examples and reusing patterns.',\n {\n query: z.string().describe('Search query — a workflow description or keywords'),\n limit: z.number().default(5).describe('Maximum number of results'),\n },\n async ({ query, limit }) => {\n await library.initialize()\n const matches = await library.search(query)\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(\n matches.slice(0, limit).map(m => ({\n score: Number(m.score.toFixed(3)),\n mode: m.mode,\n description: m.workflow.description,\n nodeCount: m.workflow.workflow.nodes.length,\n nodes: m.workflow.workflow.nodes.map(n => n.name),\n failurePatterns: m.workflow.failurePatterns ?? [],\n })),\n null,\n 2,\n ),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_sync',\n 'Sync the node catalog from your live n8n instance. Fetches all installed node types and versions so Kairos knows exactly what your n8n supports. Automatically called by kairos_prompt when n8n credentials are set, but you can call this manually to force a refresh.',\n {},\n async () => {\n const baseUrl = process.env['N8N_BASE_URL']\n const apiKey = process.env['N8N_API_KEY']\n if (!baseUrl || !apiKey) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'N8N_BASE_URL and N8N_API_KEY are required for sync.' }),\n }],\n isError: true,\n }\n }\n\n lastSync = null\n const result = await autoSync()\n if (!result) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'Failed to fetch node types from n8n. Check your credentials and that your instance is running.' }),\n }],\n isError: true,\n }\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({\n synced: true,\n nodeCount: result.nodeCount,\n newNodes: result.newNodes,\n message: `Synced ${result.nodeCount} node types from your n8n instance (${result.newNodes} not in default catalog).`,\n }, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_patterns',\n 'Analyze telemetry data and return failure patterns, build stats, and credential breakdowns. Useful for understanding what goes wrong most often and how to prevent it.',\n {\n days: z.number().default(30).describe('Number of days of telemetry to analyze'),\n limit: z.number().optional().describe('Maximum number of failure patterns to return'),\n },\n async ({ days, limit }) => {\n const analyzer = PatternAnalyzer.fromEnv()\n const analysis = await analyzer.analyzeAndSave(days)\n\n if (limit !== undefined && limit > 0) {\n analysis.topFailureRules = analysis.topFailureRules.slice(0, limit)\n }\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(analysis, null, 2),\n }],\n }\n },\n)\n\n// ── n8n management tools (need N8N_BASE_URL + N8N_API_KEY) ─────────────────\n\nserver.tool(\n 'kairos_list',\n 'List all workflows deployed on the connected n8n instance.',\n {},\n async () => {\n const client = getApiClient()\n const workflows = await client.listWorkflows()\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(workflows, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_get',\n 'Get the full JSON definition of a specific workflow by ID.',\n {\n workflow_id: z.string().describe('The n8n workflow ID'),\n },\n async ({ workflow_id }) => {\n const client = getApiClient()\n const workflow = await client.getWorkflow(workflow_id)\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(workflow, null, 2),\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_activate',\n 'Activate a deployed workflow so it starts running on triggers.',\n {\n workflow_id: z.string().describe('The n8n workflow ID to activate'),\n },\n async ({ workflow_id }) => {\n if (!isAllowed('activate')) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'Activate is disabled. Set KAIROS_MCP_ALLOW_ACTIVATE=true to enable.' }),\n }],\n isError: true,\n }\n }\n\n const client = getApiClient()\n await client.activateWorkflow(workflow_id)\n\n return {\n content: [{\n type: 'text' as const,\n text: `Activated workflow ${workflow_id}`,\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_deactivate',\n 'Deactivate a running workflow.',\n {\n workflow_id: z.string().describe('The n8n workflow ID to deactivate'),\n },\n async ({ workflow_id }) => {\n const client = getApiClient()\n await client.deactivateWorkflow(workflow_id)\n\n return {\n content: [{\n type: 'text' as const,\n text: `Deactivated workflow ${workflow_id}`,\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_delete',\n 'Delete a workflow from n8n. This is irreversible.',\n {\n workflow_id: z.string().describe('The n8n workflow ID to delete'),\n },\n async ({ workflow_id }) => {\n if (!isAllowed('delete')) {\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify({ error: 'Delete is disabled. Set KAIROS_MCP_ALLOW_DELETE=true to enable.' }),\n }],\n isError: true,\n }\n }\n\n const client = getApiClient()\n await client.deleteWorkflow(workflow_id)\n\n return {\n content: [{\n type: 'text' as const,\n text: `Deleted workflow ${workflow_id}`,\n }],\n }\n },\n)\n\nserver.tool(\n 'kairos_executions',\n 'List recent executions for a workflow, showing status and timing.',\n {\n workflow_id: z.string().optional().describe('Filter to a specific workflow ID (omit for all)'),\n limit: z.number().default(20).describe('Maximum number of executions to return'),\n },\n async ({ workflow_id, limit }) => {\n const client = getApiClient()\n const executions = await client.getExecutions(workflow_id, { limit })\n\n return {\n content: [{\n type: 'text' as const,\n text: JSON.stringify(executions, null, 2),\n }],\n }\n },\n)\n\nasync function main() {\n const transport = new StdioServerTransport()\n await server.connect(transport)\n}\n\nmain().catch((err: unknown) => {\n console.error('Kairos MCP server failed to start:', err)\n process.exit(1)\n})\n","import type { N8nNodeTypeInfo } from '../providers/n8n/types.js'\nimport type { NodeDefinition } from './registry.js'\nimport { NodeRegistry, DEFAULT_REGISTRY } from './registry.js'\n\nconst TRIGGER_PATTERNS = [/trigger/i, /Trigger$/]\n\nexport interface SyncResult {\n registry: NodeRegistry\n catalogText: string\n nodeCount: number\n newNodes: number\n}\n\nexport class NodeSyncer {\n private readonly baseRegistry: Map<string, NodeDefinition>\n\n constructor() {\n this.baseRegistry = new Map(DEFAULT_REGISTRY.map(d => [d.type, d]))\n }\n\n sync(liveNodes: N8nNodeTypeInfo[]): SyncResult {\n const merged = new Map(this.baseRegistry)\n let newNodes = 0\n\n for (const node of liveNodes) {\n const versions = Array.isArray(node.version) ? node.version : [node.version]\n const isTrigger = TRIGGER_PATTERNS.some(p => p.test(node.name))\n const credentialType = node.credentials?.[0]?.name\n\n const existing = merged.get(node.name)\n if (existing) {\n const allVersions = new Set([...existing.safeTypeVersions, ...versions])\n merged.set(node.name, {\n ...existing,\n safeTypeVersions: [...allVersions].sort((a, b) => a - b),\n })\n } else {\n newNodes++\n merged.set(node.name, {\n type: node.name,\n safeTypeVersions: versions.sort((a, b) => a - b),\n requiredParams: [],\n ...(credentialType ? { credentialType } : {}),\n ...(isTrigger ? { isTrigger: true } : {}),\n })\n }\n }\n\n const definitions = [...merged.values()]\n const registry = new NodeRegistry(definitions)\n const catalogText = this.buildCatalog(definitions)\n\n return { registry, catalogText, nodeCount: definitions.length, newNodes }\n }\n\n private buildCatalog(definitions: NodeDefinition[]): string {\n const triggers = definitions.filter(d => d.isTrigger)\n const regular = definitions.filter(d => !d.isTrigger)\n\n const formatEntry = (d: NodeDefinition): string => {\n const versions = d.safeTypeVersions.join(', ')\n const cred = d.credentialType ? ` — cred: ${d.credentialType}` : ''\n return `${d.type} typeVersion: ${versions}${cred}`\n }\n\n const triggerLines = triggers.map(formatEntry).join('\\n')\n const regularLines = regular.map(formatEntry).join('\\n')\n\n return `## NODE CATALOG — synced from your n8n instance (${definitions.length} node types)\n\n### Triggers:\n${triggerLines}\n\n### Regular nodes:\n${regularLines}`\n }\n}\n"],"mappings":"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","names":[]}
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@kairos-sdk/core",
3
- "version": "0.3.2",
3
+ "version": "0.4.0",
4
4
  "description": "LLM-powered n8n workflow generation — use as an SDK or MCP server",
5
5
  "type": "module",
6
6
  "main": "./dist/index.cjs",
@@ -1 +0,0 @@
1
- {"version":3,"sources":["../src/library/null-library.ts","../src/errors/guard-error.ts","../src/providers/n8n/provider.ts","../src/errors/generation-error.ts","../src/errors/response-parse-error.ts","../src/errors/validation-error.ts","../src/telemetry/collector.ts","../src/telemetry/types.ts","../src/client.ts","../src/generation/designer.ts","../src/templates/safety.ts","../src/templates/syncer.ts"],"sourcesContent":["import type { IWorkflowLibrary, WorkflowMatch, StoredWorkflow, WorkflowMetadataInput, LibraryFilters, SearchOptions, OutcomeData } from './types.js'\nimport type { N8nWorkflow } from '../types/workflow.js'\nimport { generateUUID } from '../utils/uuid.js'\n\nexport class NullLibrary implements IWorkflowLibrary {\n async initialize(): Promise<void> {}\n\n async search(_description: string, _options?: SearchOptions): Promise<WorkflowMatch[]> {\n return []\n }\n\n async save(_workflow: N8nWorkflow, _metadata: WorkflowMetadataInput): Promise<string> {\n return generateUUID()\n }\n\n async recordDeployment(_id: string): Promise<void> {}\n\n async recordOutcome(_id: string, _outcome: OutcomeData): Promise<void> {}\n\n async get(_id: string): Promise<StoredWorkflow | null> {\n return null\n }\n\n async list(_filters?: LibraryFilters): Promise<StoredWorkflow[]> {\n return []\n }\n}\n","import { KairosError } from './base.js'\n\nexport class GuardError extends KairosError {\n constructor(message: string) {\n super(message)\n this.name = 'GuardError'\n }\n}\n","import type { N8nWorkflow, Tag } from '../../types/workflow.js'\nimport type { DeployResult, WorkflowListItem, ExecutionSummary, ExecutionDetail } from '../../types/result.js'\nimport type { DeleteOptions, ExecutionFilter } from '../../types/options.js'\nimport type { IProvider } from '../types.js'\nimport { GuardError } from '../../errors/guard-error.js'\nimport { N8nApiClient } from './api-client.js'\nimport { N8nFieldStripper } from './stripper.js'\n\nexport class N8nProvider implements IProvider {\n readonly platform = 'n8n'\n\n constructor(\n private readonly client: N8nApiClient,\n private readonly stripper: N8nFieldStripper,\n ) {}\n\n async deploy(workflow: N8nWorkflow): Promise<DeployResult> {\n const stripped = this.stripper.stripForCreate(workflow)\n const response = await this.client.createWorkflow(stripped)\n return { workflowId: response.id, name: response.name }\n }\n\n async update(id: string, workflow: N8nWorkflow): Promise<DeployResult> {\n const stripped = this.stripper.stripForUpdate(workflow)\n const response = await this.client.updateWorkflow(id, stripped)\n return { workflowId: response.id, name: response.name }\n }\n\n async get(id: string): Promise<N8nWorkflow> {\n const response = await this.client.getWorkflow(id)\n return {\n name: response.name,\n nodes: response.nodes,\n connections: response.connections,\n ...(response.settings !== undefined ? { settings: response.settings } : {}),\n ...(response.tags !== undefined ? { tags: response.tags } : {}),\n }\n }\n\n async list(): Promise<WorkflowListItem[]> {\n return this.client.listWorkflows()\n }\n\n async activate(id: string): Promise<void> {\n await this.client.activateWorkflow(id)\n }\n\n async deactivate(id: string): Promise<void> {\n await this.client.deactivateWorkflow(id)\n }\n\n async delete(id: string, options: DeleteOptions): Promise<void> {\n if (options.confirm !== true) {\n throw new GuardError('delete() requires { confirm: true } to prevent accidental deletion')\n }\n await this.client.deleteWorkflow(id)\n }\n\n async executions(workflowId?: string, filter?: ExecutionFilter): Promise<ExecutionSummary[]> {\n return this.client.getExecutions(workflowId, filter)\n }\n\n async execution(id: string): Promise<ExecutionDetail> {\n return this.client.getExecution(id)\n }\n\n async listTags(): Promise<Tag[]> {\n return this.client.listTags()\n }\n\n async createTag(name: string): Promise<Tag> {\n return this.client.createTag(name)\n }\n\n async tag(workflowId: string, tagIds: string[]): Promise<void> {\n await this.client.tagWorkflow(workflowId, tagIds)\n }\n\n async untag(workflowId: string, tagIds: string[]): Promise<void> {\n await this.client.untagWorkflow(workflowId, tagIds)\n }\n}\n","import { KairosError } from './base.js'\n\nexport class GenerationError extends KairosError {\n constructor(message: string, cause?: unknown) {\n super(message, cause)\n this.name = 'GenerationError'\n }\n}\n","import { KairosError } from './base.js'\n\nexport class ResponseParseError extends KairosError {\n constructor(message: string, cause?: unknown) {\n super(message, cause)\n this.name = 'ResponseParseError'\n }\n}\n","import { KairosError } from './base.js'\nimport type { ValidationIssue } from '../validation/types.js'\n\nexport type { ValidationIssue }\n\nexport class ValidationError extends KairosError {\n constructor(\n message: string,\n public readonly issues: ValidationIssue[],\n ) {\n super(message)\n this.name = 'ValidationError'\n }\n}\n","import { appendFile, mkdir } from 'node:fs/promises'\nimport { join } from 'node:path'\nimport { homedir } from 'node:os'\nimport { generateUUID } from '../utils/uuid.js'\nimport type { TelemetryEvent } from './types.js'\nimport { TELEMETRY_SCHEMA_VERSION } from './types.js'\n\nexport class TelemetryCollector {\n private readonly dir: string\n readonly sessionId: string\n private dirReady: Promise<void> | null = null\n\n constructor(dir?: string) {\n this.dir = dir ?? join(homedir(), '.kairos', 'telemetry')\n this.sessionId = generateUUID()\n }\n\n async emit(eventType: TelemetryEvent['eventType'], data: Record<string, unknown>): Promise<void> {\n const event: TelemetryEvent = {\n schemaVersion: TELEMETRY_SCHEMA_VERSION,\n timestamp: new Date().toISOString(),\n sessionId: this.sessionId,\n eventType,\n data,\n }\n\n if (!this.dirReady) {\n this.dirReady = mkdir(this.dir, { recursive: true }).then(() => {})\n }\n await this.dirReady\n const filename = new Date().toISOString().slice(0, 10) + '.jsonl'\n const filepath = join(this.dir, filename)\n await appendFile(filepath, JSON.stringify(event) + '\\n', 'utf-8')\n }\n}\n","import type { ValidationIssue } from '../errors/validation-error.js'\n\nexport interface TelemetryEvent {\n schemaVersion: number\n timestamp: string\n sessionId: string\n eventType: 'build_start' | 'generation_attempt' | 'build_complete'\n data: Record<string, unknown>\n}\n\nexport const TELEMETRY_SCHEMA_VERSION = 2\n\nexport interface AttemptMetadata {\n attempt: number\n temperature: number\n durationMs: number\n tokensInput: number\n tokensOutput: number\n validationPassed: boolean\n issues: ValidationIssue[]\n}\n","import Anthropic from '@anthropic-ai/sdk'\nimport type { N8nWorkflow, Tag } from './types/workflow.js'\nimport type { BuildResult, WorkflowListItem, ExecutionSummary, ExecutionDetail } from './types/result.js'\nimport type { ClientOptions, BuildOptions, DeleteOptions, ExecutionFilter } from './types/options.js'\nimport type { IWorkflowLibrary, WorkflowMatch, WorkflowMetadataInput } from './library/types.js'\nimport { NullLibrary } from './library/null-library.js'\nimport { N8nApiClient } from './providers/n8n/api-client.js'\nimport { N8nFieldStripper } from './providers/n8n/stripper.js'\nimport { N8nProvider } from './providers/n8n/provider.js'\nimport { N8nValidator } from './validation/validator.js'\nimport { WorkflowDesigner } from './generation/designer.js'\nimport type { DesignResult } from './generation/types.js'\nimport { TelemetryCollector } from './telemetry/collector.js'\nimport { TelemetryReader } from './telemetry/reader.js'\nimport { nullLogger } from './utils/logger.js'\nimport type { ILogger } from './utils/logger.js'\nimport { scoreToMode } from './utils/thresholds.js'\nimport { GuardError } from './errors/guard-error.js'\n\nconst DEFAULT_MODEL = 'claude-sonnet-4-6'\n\nexport class Kairos {\n private readonly provider: N8nProvider | null\n private readonly designer: WorkflowDesigner\n private readonly validator: N8nValidator\n private readonly library: IWorkflowLibrary\n private readonly logger: ILogger\n private readonly telemetry: TelemetryCollector | null\n private readonly telemetryReader: TelemetryReader | null\n private readonly model: string\n private saveQueue: Promise<string | null> = Promise.resolve(null)\n\n constructor(options: ClientOptions) {\n const logger = options.logger ?? nullLogger\n this.model = options.model ?? DEFAULT_MODEL\n\n if (options.n8nBaseUrl && options.n8nApiKey) {\n try {\n new URL(options.n8nBaseUrl)\n } catch {\n throw new GuardError(`Invalid n8nBaseUrl: \"${options.n8nBaseUrl}\" — must be a valid URL`)\n }\n const apiClient = new N8nApiClient(options.n8nBaseUrl, options.n8nApiKey, logger)\n const stripper = new N8nFieldStripper()\n this.provider = new N8nProvider(apiClient, stripper)\n } else {\n this.provider = null\n }\n\n const anthropic = new Anthropic({ apiKey: options.anthropicApiKey })\n this.designer = new WorkflowDesigner(anthropic, this.model, logger)\n this.validator = new N8nValidator()\n this.library = options.library ?? new NullLibrary()\n this.logger = logger\n\n if (options.telemetry === true) {\n this.telemetry = new TelemetryCollector()\n this.telemetryReader = new TelemetryReader()\n } else if (typeof options.telemetry === 'string') {\n this.telemetry = new TelemetryCollector(options.telemetry)\n this.telemetryReader = new TelemetryReader(options.telemetry)\n } else {\n this.telemetry = null\n this.telemetryReader = null\n }\n }\n\n private requireProvider(): N8nProvider {\n if (!this.provider) {\n throw new GuardError('n8nBaseUrl and n8nApiKey are required for this operation — set them in the Kairos constructor, or use { dryRun: true } for generation-only mode')\n }\n return this.provider\n }\n\n private validateDescription(description: string): void {\n if (!description || description.trim().length === 0) {\n throw new GuardError('Description is required and must be non-empty')\n }\n }\n\n async build(description: string, options?: BuildOptions): Promise<BuildResult> {\n this.validateDescription(description)\n this.logger.info('Kairos.build', { description, dryRun: options?.dryRun })\n const buildStart = Date.now()\n\n await this.telemetry?.emit('build_start', {\n description,\n model: this.model,\n dryRun: options?.dryRun ?? false,\n })\n\n await this.library.initialize()\n const matches = await this.library.search(description)\n\n if (matches.length > 0) {\n const top = matches[0]!\n this.logger.info(`Library: ${matches.length} match(es), top=\"${top.workflow.description.slice(0, 50)}\" score=${top.score.toFixed(2)} mode=${top.mode}`)\n } else {\n this.logger.info('Library: no matches (scratch mode)')\n }\n\n const globalFailureRates = await this.telemetryReader?.getFailureRates() ?? []\n\n if (globalFailureRates.length > 0) {\n const highFreq = globalFailureRates.filter((r) => r.rate >= 0.15)\n if (highFreq.length > 0) {\n this.logger.info(`Telemetry: ${highFreq.length} high-frequency failure rule(s) will be warned about`)\n }\n }\n\n const designResult = await this.designer.design(\n { description, ...(options?.name ? { name: options.name } : {}) },\n matches,\n globalFailureRates,\n )\n\n await this.emitAttemptTelemetry(description, designResult)\n\n const workflow = options?.name\n ? { ...designResult.workflow, name: options.name }\n : designResult.workflow\n\n this.saveToLibrary(workflow, description, designResult, matches)\n\n if (options?.dryRun) {\n const totalTokensInput = designResult.attemptMetadata.reduce((s, m) => s + m.tokensInput, 0)\n const totalTokensOutput = designResult.attemptMetadata.reduce((s, m) => s + m.tokensOutput, 0)\n\n await this.telemetry?.emit('build_complete', {\n description,\n success: true,\n totalAttempts: designResult.attempts,\n totalDurationMs: Date.now() - buildStart,\n totalTokensInput,\n totalTokensOutput,\n workflowName: workflow.name,\n workflowId: null,\n dryRun: true,\n credentialsNeeded: designResult.credentialsNeeded.length,\n })\n\n return {\n workflowId: null,\n name: workflow.name,\n workflow,\n credentialsNeeded: designResult.credentialsNeeded,\n activationRequired: true,\n generationAttempts: designResult.attempts,\n dryRun: true,\n }\n }\n\n const provider = this.requireProvider()\n const deployed = await provider.deploy(workflow)\n this.recordDeploy()\n\n if (options?.activate) {\n await provider.activate(deployed.workflowId)\n }\n\n const totalTokensInput = designResult.attemptMetadata.reduce((s, m) => s + m.tokensInput, 0)\n const totalTokensOutput = designResult.attemptMetadata.reduce((s, m) => s + m.tokensOutput, 0)\n\n await this.telemetry?.emit('build_complete', {\n description,\n success: true,\n totalAttempts: designResult.attempts,\n totalDurationMs: Date.now() - buildStart,\n totalTokensInput,\n totalTokensOutput,\n workflowName: deployed.name,\n workflowId: deployed.workflowId,\n dryRun: false,\n credentialsNeeded: designResult.credentialsNeeded.length,\n })\n\n return {\n workflowId: deployed.workflowId,\n name: deployed.name,\n workflow,\n credentialsNeeded: designResult.credentialsNeeded,\n activationRequired: !options?.activate,\n generationAttempts: designResult.attempts,\n dryRun: false,\n }\n }\n\n async replace(id: string, description: string): Promise<BuildResult> {\n this.validateDescription(description)\n this.logger.info('Kairos.update', { id, description })\n const buildStart = Date.now()\n\n await this.telemetry?.emit('build_start', {\n description,\n model: this.model,\n dryRun: false,\n })\n\n await this.library.initialize()\n const matches = await this.library.search(description)\n const globalFailureRates = await this.telemetryReader?.getFailureRates() ?? []\n\n const designResult = await this.designer.design({ description }, matches, globalFailureRates)\n\n await this.emitAttemptTelemetry(description, designResult)\n\n const provider = this.requireProvider()\n const deployed = await provider.update(id, designResult.workflow)\n\n this.saveToLibrary(designResult.workflow, description, designResult, matches)\n this.recordDeploy()\n\n const totalTokensInput = designResult.attemptMetadata.reduce((s, m) => s + m.tokensInput, 0)\n const totalTokensOutput = designResult.attemptMetadata.reduce((s, m) => s + m.tokensOutput, 0)\n\n await this.telemetry?.emit('build_complete', {\n description,\n success: true,\n totalAttempts: designResult.attempts,\n totalDurationMs: Date.now() - buildStart,\n totalTokensInput,\n totalTokensOutput,\n workflowName: deployed.name,\n workflowId: deployed.workflowId,\n dryRun: false,\n credentialsNeeded: designResult.credentialsNeeded.length,\n })\n\n return {\n workflowId: deployed.workflowId,\n name: deployed.name,\n workflow: designResult.workflow,\n credentialsNeeded: designResult.credentialsNeeded,\n activationRequired: true,\n generationAttempts: designResult.attempts,\n dryRun: false,\n }\n }\n\n async drain(): Promise<void> {\n await this.saveQueue.catch(() => {})\n }\n\n private async emitAttemptTelemetry(description: string, designResult: DesignResult): Promise<void> {\n for (const meta of designResult.attemptMetadata) {\n await this.telemetry?.emit('generation_attempt', {\n description,\n attempt: meta.attempt,\n temperature: meta.temperature,\n durationMs: meta.durationMs,\n tokensInput: meta.tokensInput,\n tokensOutput: meta.tokensOutput,\n validationPassed: meta.validationPassed,\n issueCount: meta.issues.length,\n issues: meta.issues.map((i) => ({ rule: i.rule, message: i.message })),\n })\n }\n }\n\n private recordDeploy(): void {\n this.saveQueue = this.saveQueue\n .then(async (savedId) => {\n if (savedId) {\n await this.library.recordDeployment(savedId)\n }\n return savedId\n })\n .catch((err: unknown) => {\n this.logger.warn('Failed to record deployment (non-fatal)', { err: String(err) })\n return null\n })\n }\n\n private saveToLibrary(\n workflow: N8nWorkflow,\n description: string,\n designResult: DesignResult,\n matches: WorkflowMatch[],\n ): void {\n const failedAttempts = designResult.attemptMetadata.filter((m) => !m.validationPassed)\n const failurePatterns = failedAttempts.flatMap((m) =>\n m.issues.map((i) => ({ rule: i.rule, message: i.message })),\n )\n const topMatch = matches[0]\n const generationMode = topMatch ? scoreToMode(topMatch.score) : 'scratch' as const\n\n const autoTags = Array.from(new Set(\n workflow.nodes.flatMap((n) => {\n const bare = n.type.split('.').pop() ?? ''\n const tags = [bare]\n if (n.type.includes('Trigger') || n.type.includes('trigger')) tags.push(`trigger:${bare}`)\n if (n.type.includes('langchain')) tags.push('ai')\n return tags\n }),\n ))\n\n const metadata: WorkflowMetadataInput = {\n description,\n generationMode,\n generationAttempts: designResult.attempts,\n }\n if (autoTags.length > 0) metadata.tags = autoTags\n if (failurePatterns.length > 0) metadata.failurePatterns = failurePatterns\n if (matches.length > 0) metadata.sourceWorkflowIds = matches.map((m) => m.workflow.id)\n if (topMatch) metadata.topMatchScore = topMatch.score\n if (designResult.credentialsNeeded.length > 0) metadata.credentialsNeeded = designResult.credentialsNeeded\n\n const firstTryPass = designResult.attemptMetadata.length > 0\n && designResult.attemptMetadata[0]!.validationPassed\n const failedRules = Array.from(new Set(\n designResult.attemptMetadata\n .filter((m) => !m.validationPassed)\n .flatMap((m) => m.issues.map((i) => i.rule)),\n ))\n\n this.saveQueue = this.saveQueue\n .then(async () => {\n const savedId = await this.library.save(workflow, metadata)\n\n for (const match of matches) {\n if (match.mode === 'direct' || match.mode === 'reference') {\n await this.library.recordOutcome(match.workflow.id, {\n attempts: designResult.attempts,\n firstTryPass,\n failedRules,\n mode: match.mode,\n })\n }\n }\n\n return savedId\n })\n .catch((err: unknown) => {\n this.logger.warn('Failed to save workflow to library (non-fatal)', { err: String(err) })\n return null\n })\n }\n\n async get(id: string): Promise<N8nWorkflow> {\n return this.requireProvider().get(id)\n }\n\n async list(): Promise<WorkflowListItem[]> {\n return this.requireProvider().list()\n }\n\n async activate(id: string): Promise<void> {\n await this.requireProvider().activate(id)\n }\n\n async deactivate(id: string): Promise<void> {\n await this.requireProvider().deactivate(id)\n }\n\n async delete(id: string, options: DeleteOptions): Promise<void> {\n await this.requireProvider().delete(id, options)\n }\n\n async executions(workflowId?: string, filter?: ExecutionFilter): Promise<ExecutionSummary[]> {\n return this.requireProvider().executions(workflowId, filter)\n }\n\n async execution(id: string): Promise<ExecutionDetail> {\n return this.requireProvider().execution(id)\n }\n\n async listTags(): Promise<Tag[]> {\n return this.requireProvider().listTags()\n }\n\n async createTag(name: string): Promise<Tag> {\n return this.requireProvider().createTag(name)\n }\n\n async tag(workflowId: string, tagIds: string[]): Promise<void> {\n await this.requireProvider().tag(workflowId, tagIds)\n }\n\n async untag(workflowId: string, tagIds: string[]): Promise<void> {\n await this.requireProvider().untag(workflowId, tagIds)\n }\n}\n","import Anthropic from '@anthropic-ai/sdk'\nimport type { WorkflowMatch } from '../library/types.js'\nimport type { N8nWorkflow } from '../types/workflow.js'\nimport type { CredentialRequirement } from '../types/result.js'\nimport type { ILogger } from '../utils/logger.js'\nimport { GenerationError } from '../errors/generation-error.js'\nimport { ResponseParseError } from '../errors/response-parse-error.js'\nimport { ValidationError } from '../errors/validation-error.js'\nimport type { ValidationIssue } from '../errors/validation-error.js'\nimport { N8nValidator } from '../validation/validator.js'\nimport { PromptBuilder } from './prompt-builder.js'\nimport type { AttemptMetadata } from '../telemetry/types.js'\nimport type { RuleFailureRate } from '../telemetry/reader.js'\nimport type { DesignRequest, DesignResult, SystemPromptBlock } from './types.js'\n\nconst MAX_ATTEMPTS = 3\nconst BASE_TEMPERATURE = 0.2\nconst FINAL_TEMPERATURE = 0.1\n\nconst GENERATE_WORKFLOW_TOOL: Anthropic.Tool = {\n name: 'generate_workflow',\n description: 'Generate a valid n8n workflow JSON object',\n input_schema: {\n type: 'object',\n properties: {\n workflow: {\n type: 'object',\n description: 'The complete n8n workflow object',\n properties: {\n name: { type: 'string' },\n nodes: { type: 'array' },\n connections: { type: 'object' },\n settings: { type: 'object' },\n },\n required: ['name', 'nodes', 'connections'],\n },\n credentialsNeeded: {\n type: 'array',\n description: 'List of credentials the user must configure before activating',\n items: {\n type: 'object',\n properties: {\n service: { type: 'string' },\n credentialType: { type: 'string' },\n description: { type: 'string' },\n },\n required: ['service', 'credentialType', 'description'],\n },\n },\n error: {\n type: 'string',\n description: 'Set this if the request cannot be fulfilled — explain why',\n },\n },\n required: [],\n },\n}\n\ninterface ToolUseResult {\n workflow: N8nWorkflow\n credentialsNeeded: CredentialRequirement[]\n error?: string\n}\n\nexport class WorkflowDesigner {\n private readonly validator: N8nValidator\n private readonly promptBuilder: PromptBuilder\n\n constructor(\n private readonly anthropic: Anthropic,\n private readonly model: string,\n private readonly logger: ILogger,\n ) {\n this.validator = new N8nValidator()\n this.promptBuilder = new PromptBuilder()\n }\n\n async design(request: DesignRequest, matches: WorkflowMatch[], globalFailureRates: RuleFailureRate[] = []): Promise<DesignResult> {\n const attemptMetadata: AttemptMetadata[] = []\n let lastErrors: ValidationIssue[] = []\n let attempts = 0\n const built = this.promptBuilder.build(request, matches, globalFailureRates)\n\n for (let attempt = 1; attempt <= MAX_ATTEMPTS; attempt++) {\n attempts = attempt\n const temperature = attempt === MAX_ATTEMPTS ? FINAL_TEMPERATURE : BASE_TEMPERATURE\n\n let userMessage: string\n if (attempt === 1) {\n userMessage = built.userMessage\n this.logger.debug('WorkflowDesigner: attempt 1', { description: request.description })\n } else {\n const issueLines = lastErrors.map(\n (i) => `- [Rule ${i.rule}] ${i.message}${i.nodeId ? ` (node: ${i.nodeId})` : ''}`,\n )\n userMessage = this.promptBuilder.buildCorrectionMessage(request, matches, issueLines, attempt - 1)\n this.logger.debug(`WorkflowDesigner: correction attempt ${attempt}`, { issueCount: lastErrors.length })\n }\n\n const start = Date.now()\n const message = await this.callClaude(built.system, userMessage, temperature)\n const durationMs = Date.now() - start\n const parsed = this.extractToolUse(message)\n\n if (parsed.error) {\n throw new GenerationError(`Claude declined to generate workflow: ${parsed.error}`)\n }\n\n const validation = this.validator.validate(parsed.workflow)\n const errors = validation.issues.filter((i) => i.severity === 'error')\n\n attemptMetadata.push({\n attempt,\n temperature,\n durationMs,\n tokensInput: message.usage.input_tokens,\n tokensOutput: message.usage.output_tokens,\n validationPassed: validation.valid,\n issues: validation.issues,\n })\n\n if (validation.valid) {\n return { workflow: parsed.workflow, credentialsNeeded: parsed.credentialsNeeded, attempts, attemptMetadata }\n }\n\n lastErrors = errors\n this.logger.warn(`WorkflowDesigner: validation failed on attempt ${attempt}`, {\n errorCount: errors.length,\n })\n }\n\n const finalIssues = attemptMetadata.at(-1)?.issues ?? lastErrors\n throw new ValidationError(\n `Workflow failed validation after ${MAX_ATTEMPTS} attempts`,\n finalIssues,\n )\n }\n\n private async callClaude(\n system: SystemPromptBlock[],\n userMessage: string,\n temperature: number,\n ): Promise<Anthropic.Message> {\n const controller = new AbortController()\n const timer = setTimeout(() => controller.abort(), 120_000)\n try {\n return await this.anthropic.messages.create(\n {\n model: this.model,\n max_tokens: 8192,\n temperature,\n system: system.map((b) => ({ type: b.type, text: b.text, ...(b.cache_control ? { cache_control: b.cache_control } : {}) })),\n messages: [{ role: 'user', content: userMessage }],\n tools: [GENERATE_WORKFLOW_TOOL],\n tool_choice: { type: 'tool', name: 'generate_workflow' },\n },\n { signal: controller.signal },\n )\n } catch (err) {\n const detail = err instanceof Error ? err.message : String(err)\n throw new GenerationError(`Anthropic API call failed: ${detail}`, err)\n } finally {\n clearTimeout(timer)\n }\n }\n\n private extractToolUse(message: Anthropic.Message): ToolUseResult {\n const toolUseBlock = message.content.find(\n (block): block is Anthropic.ToolUseBlock => block.type === 'tool_use',\n )\n if (!toolUseBlock) {\n throw new ResponseParseError(\n 'Claude response contained no tool_use block — forced tool_choice failed unexpectedly',\n )\n }\n\n const input = toolUseBlock.input as Record<string, unknown>\n\n if (typeof input['error'] === 'string') {\n return {\n workflow: { name: '', nodes: [], connections: {} },\n credentialsNeeded: [],\n error: input['error'],\n }\n }\n\n if (!input['workflow'] || typeof input['workflow'] !== 'object') {\n throw new ResponseParseError('generate_workflow tool call missing workflow field')\n }\n\n const workflow = input['workflow'] as N8nWorkflow\n const credentialsNeeded = (input['credentialsNeeded'] as CredentialRequirement[] | undefined) ?? []\n\n return { workflow, credentialsNeeded }\n }\n}\n","import type { TrustLevel } from '../library/types.js'\nimport type { N8nWorkflow } from '../types/workflow.js'\n\ninterface SafetyResult {\n trustLevel: TrustLevel\n reasons: string[]\n}\n\nconst BLOCKED_NODE_TYPES = new Set([\n 'n8n-nodes-base.code',\n 'n8n-nodes-base.executeCommand',\n 'n8n-nodes-base.ssh',\n])\n\nconst REVIEW_NODE_TYPES = new Set([\n 'n8n-nodes-base.httpRequest',\n])\n\nconst SECRET_PATTERNS = [\n /sk-[a-zA-Z0-9]{20,}/,\n /ghp_[a-zA-Z0-9]{36}/,\n /xoxb-[0-9]+-[0-9]+-[a-zA-Z0-9]+/,\n /AIza[a-zA-Z0-9_-]{35}/,\n /AKIA[A-Z0-9]{16}/,\n]\n\nexport function assessTemplateSafety(workflow: N8nWorkflow): SafetyResult {\n const reasons: string[] = []\n let worst: TrustLevel = 'safe'\n\n const escalate = (level: TrustLevel, reason: string) => {\n reasons.push(reason)\n if (level === 'blocked') worst = 'blocked'\n else if (level === 'review' && worst === 'safe') worst = 'review'\n }\n\n for (const node of workflow.nodes) {\n if (BLOCKED_NODE_TYPES.has(node.type)) {\n escalate('blocked', `Contains ${node.type} node \"${node.name}\"`)\n }\n\n if (REVIEW_NODE_TYPES.has(node.type)) {\n escalate('review', `Contains ${node.type} node \"${node.name}\"`)\n }\n\n const paramStr = JSON.stringify(node.parameters)\n for (const pattern of SECRET_PATTERNS) {\n if (pattern.test(paramStr)) {\n escalate('blocked', `Node \"${node.name}\" parameters contain a hardcoded secret`)\n break\n }\n }\n }\n\n return { trustLevel: worst, reasons }\n}\n","import type { IWorkflowLibrary, WorkflowMetadataInput } from '../library/types.js'\nimport type { N8nWorkflow, N8nNode } from '../types/workflow.js'\nimport type { ILogger } from '../utils/logger.js'\nimport type { TemplateSearchResponse, TemplateDetailResponse, SyncProgress } from './types.js'\nimport { N8nValidator } from '../validation/validator.js'\nimport { assessTemplateSafety } from './safety.js'\n\nconst N8N_TEMPLATE_API = 'https://api.n8n.io/api/templates'\nconst PAGE_SIZE = 50\nconst DELAY_BETWEEN_FETCHES_MS = 200\n\nconst DEFAULT_SETTINGS: N8nWorkflow['settings'] = {\n executionOrder: 'v1',\n saveManualExecutions: true,\n timezone: 'UTC',\n}\n\nexport interface SyncOptions {\n maxTemplates?: number\n onProgress?: (progress: SyncProgress) => void\n}\n\nexport class TemplateSyncer {\n private readonly validator: N8nValidator\n private readonly logger: ILogger\n\n constructor(\n private readonly library: IWorkflowLibrary,\n logger: ILogger,\n ) {\n this.validator = new N8nValidator()\n this.logger = logger\n }\n\n async sync(options?: SyncOptions): Promise<SyncProgress> {\n const maxTemplates = options?.maxTemplates ?? 500\n\n await this.library.initialize()\n\n const existing = await this.library.list()\n const existingSourceIds = new Set(\n existing\n .filter((w) => w.sourceKind === 'n8n-template' && w.sourceId)\n .map((w) => w.sourceId!),\n )\n\n const progress: SyncProgress = {\n total: 0,\n processed: 0,\n saved: 0,\n skippedPaid: 0,\n skippedDuplicate: 0,\n blocked: 0,\n reviewed: 0,\n }\n\n const templateIds = await this.fetchTemplateIds(maxTemplates, progress)\n\n for (const id of templateIds) {\n if (existingSourceIds.has(String(id))) {\n progress.skippedDuplicate++\n progress.processed++\n options?.onProgress?.(progress)\n continue\n }\n\n try {\n await this.processTemplate(id, progress)\n } catch (err) {\n this.logger.warn(`Failed to process template ${id}`, { err: String(err) })\n }\n\n progress.processed++\n options?.onProgress?.(progress)\n\n await new Promise((resolve) => setTimeout(resolve, DELAY_BETWEEN_FETCHES_MS))\n }\n\n return progress\n }\n\n private async fetchTemplateIds(max: number, progress: SyncProgress): Promise<number[]> {\n const ids: number[] = []\n let page = 1\n\n while (ids.length < max) {\n const url = `${N8N_TEMPLATE_API}/search?page=${page}&rows=${PAGE_SIZE}`\n const response = await fetch(url)\n if (!response.ok) break\n\n const data = (await response.json()) as TemplateSearchResponse\n progress.total = Math.min(data.totalWorkflows, max)\n\n for (const template of data.workflows) {\n if (ids.length >= max) break\n if (template.price && template.price > 0) {\n progress.skippedPaid++\n continue\n }\n ids.push(template.id)\n }\n\n if (data.workflows.length < PAGE_SIZE) break\n page++\n\n await new Promise((resolve) => setTimeout(resolve, DELAY_BETWEEN_FETCHES_MS))\n }\n\n return ids\n }\n\n private async processTemplate(id: number, progress: SyncProgress): Promise<void> {\n const url = `${N8N_TEMPLATE_API}/workflows/${id}`\n const response = await fetch(url)\n if (!response.ok) return\n\n const data = (await response.json()) as TemplateDetailResponse\n const templateMeta = data.workflow\n const rawWorkflow = templateMeta.workflow\n\n if (!rawWorkflow?.nodes?.length) return\n\n const workflow: N8nWorkflow = {\n name: templateMeta.name,\n nodes: rawWorkflow.nodes.filter((n) => n.type && n.name) as N8nNode[],\n connections: rawWorkflow.connections as N8nWorkflow['connections'],\n settings: rawWorkflow.settings\n ? { executionOrder: 'v1' as const, ...rawWorkflow.settings }\n : { ...DEFAULT_SETTINGS },\n }\n\n const validation = this.validator.validate(workflow)\n const validationErrors = validation.issues.filter((i) => i.severity === 'error')\n\n if (validationErrors.length > 0) {\n progress.blocked++\n this.logger.debug(`Template ${id} blocked: ${validationErrors.length} validation errors`)\n return\n }\n\n const safety = assessTemplateSafety(workflow)\n\n if (safety.trustLevel === 'blocked') {\n progress.blocked++\n this.logger.debug(`Template ${id} blocked: ${safety.reasons.join(', ')}`)\n return\n }\n\n if (safety.trustLevel === 'review') {\n progress.reviewed++\n }\n\n const description = this.cleanDescription(templateMeta.description)\n\n const autoTags = Array.from(new Set(\n workflow.nodes.flatMap((n) => {\n const bare = n.type.split('.').pop() ?? ''\n const tags = [bare]\n if (n.type.includes('Trigger') || n.type.includes('trigger')) tags.push(`trigger:${bare}`)\n if (n.type.includes('langchain')) tags.push('ai')\n return tags\n }),\n ))\n\n const metadata: WorkflowMetadataInput = {\n description,\n tags: autoTags,\n sourceKind: 'n8n-template',\n sourceId: String(id),\n sourceUrl: `https://n8n.io/workflows/${id}`,\n trustLevel: safety.trustLevel,\n }\n\n await this.library.save(workflow, metadata)\n progress.saved++\n this.logger.debug(`Template ${id} saved: \"${templateMeta.name}\" (${safety.trustLevel})`)\n }\n\n private cleanDescription(raw: string): string {\n return raw\n .replace(/#{1,6}\\s*/g, '')\n .replace(/\\*{1,2}([^*]+)\\*{1,2}/g, '$1')\n .replace(/\\[([^\\]]+)\\]\\([^)]+\\)/g, '$1')\n .replace(/\\n{3,}/g, '\\n\\n')\n .trim()\n .slice(0, 500)\n }\n}\n"],"mappings":"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","names":["totalTokensInput","totalTokensOutput"]}