@kairos-sdk/core 0.5.0 → 0.5.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.
package/README.md CHANGED
@@ -1,6 +1,6 @@
1
1
  # @kairos-sdk/core
2
2
 
3
- [![CI](https://github.com/Kruttz/kairos-sdk/actions/workflows/ci.yml/badge.svg)](https://github.com/Kruttz/kairos-sdk/actions/workflows/ci.yml)
3
+ [![CI](https://github.com/Kruttz/Kairos/actions/workflows/ci.yml/badge.svg)](https://github.com/Kruttz/Kairos/actions/workflows/ci.yml)
4
4
  [![npm version](https://img.shields.io/npm/v/@kairos-sdk/core)](https://www.npmjs.com/package/@kairos-sdk/core)
5
5
  [![npm downloads](https://img.shields.io/npm/dw/@kairos-sdk/core)](https://www.npmjs.com/package/@kairos-sdk/core)
6
6
 
@@ -111,12 +111,14 @@ This means Kairos works with **any LLM** — Claude, GPT, Gemini, Llama, or anyt
111
111
  | `kairos_validate` | Validates workflow JSON against 34 structural rules — returns errors and warnings |
112
112
  | `kairos_search` | Searches the local workflow library for similar past builds |
113
113
  | `kairos_sync` | Manually refresh the node catalog from your n8n instance (auto-runs on first `kairos_prompt` call) |
114
+ | `kairos_patterns` | Returns pattern analysis — top failure rules, confidence scores, and improvement suggestions derived from build telemetry |
114
115
 
115
116
  #### Deployment tools
116
117
 
117
118
  | Tool | Description |
118
119
  |------|-------------|
119
120
  | `kairos_deploy` | Deploys validated workflow JSON to n8n (re-validates before deploying) |
121
+ | `kairos_replace` | Replaces an existing n8n workflow with a new version — validates before updating, preserves workflow ID |
120
122
  | `kairos_list` | List all deployed workflows |
121
123
  | `kairos_get` | Get full workflow JSON by ID |
122
124
  | `kairos_activate` | Activate a workflow |
@@ -124,6 +126,13 @@ This means Kairos works with **any LLM** — Claude, GPT, Gemini, Llama, or anyt
124
126
  | `kairos_delete` | Delete a workflow |
125
127
  | `kairos_executions` | List recent executions with status |
126
128
 
129
+ #### Library tools
130
+
131
+ | Tool | Description |
132
+ |------|-------------|
133
+ | `kairos_library` | Browse or search the local Kairos workflow library — returns metadata, node counts, deploy history, and n8n workflow IDs |
134
+ | `kairos_outcome` | Record build outcome against a library entry — feeds the pattern learning system with attempt counts, failed rules, and generation mode |
135
+
127
136
  ---
128
137
 
129
138
  ## Use as SDK
@@ -1,14 +1,14 @@
1
1
  import {
2
2
  PromptBuilder,
3
3
  inferWorkflowType
4
- } from "./chunk-EVOAYH2K.js";
4
+ } from "./chunk-V2IZBZGB.js";
5
5
  import {
6
6
  GenerationError,
7
7
  N8nProvider,
8
8
  NullLibrary,
9
9
  ResponseParseError,
10
10
  ValidationError
11
- } from "./chunk-5GAY7CSJ.js";
11
+ } from "./chunk-MYAGTDQ2.js";
12
12
  import {
13
13
  GuardError,
14
14
  N8nApiClient,
@@ -20,7 +20,7 @@ import {
20
20
  generateUUID,
21
21
  nullLogger,
22
22
  scoreToMode
23
- } from "./chunk-KIFT5LA7.js";
23
+ } from "./chunk-VPPWTMRJ.js";
24
24
 
25
25
  // src/client.ts
26
26
  import Anthropic from "@anthropic-ai/sdk";
@@ -195,7 +195,6 @@ var DEFAULT_MODEL = process.env["KAIROS_MODEL"] ?? "claude-sonnet-4-6";
195
195
  var Kairos = class {
196
196
  provider;
197
197
  designer;
198
- validator;
199
198
  library;
200
199
  logger;
201
200
  telemetry;
@@ -221,7 +220,6 @@ var Kairos = class {
221
220
  const anthropic = new Anthropic({ apiKey: options.anthropicApiKey });
222
221
  const patternsPath = typeof options.telemetry === "string" ? join(options.telemetry, "..", "patterns.json") : join(homedir(), ".kairos", "patterns.json");
223
222
  this.designer = new WorkflowDesigner(anthropic, this.model, logger, patternsPath);
224
- this.validator = new N8nValidator();
225
223
  this.library = options.library ?? new NullLibrary();
226
224
  this.logger = logger;
227
225
  if (options.telemetry === true) {
@@ -318,7 +316,6 @@ var Kairos = class {
318
316
  }
319
317
  await this.emitAttemptTelemetry(description, designResult, workflowType, runId);
320
318
  const workflow = options?.name ? { ...designResult.workflow, name: options.name } : designResult.workflow;
321
- this.saveToLibrary(workflow, description, designResult, matches);
322
319
  if (options?.dryRun) {
323
320
  const totalTokensInput2 = designResult.attemptMetadata.reduce((s, m) => s + m.tokensInput, 0);
324
321
  const totalTokensOutput2 = designResult.attemptMetadata.reduce((s, m) => s + m.tokensOutput, 0);
@@ -354,6 +351,7 @@ var Kairos = class {
354
351
  if (options?.activate) {
355
352
  await provider.activate(deployed.workflowId);
356
353
  }
354
+ this.saveToLibrary(workflow, description, designResult, matches, deployed.workflowId);
357
355
  let smokeTestResult;
358
356
  if (options?.smokeTest) {
359
357
  smokeTestResult = await provider.smokeTest(deployed.workflowId, workflow).catch((err) => {
@@ -599,4 +597,4 @@ var Kairos = class {
599
597
  export {
600
598
  Kairos
601
599
  };
602
- //# sourceMappingURL=chunk-HBGZTUUZ.js.map
600
+ //# sourceMappingURL=chunk-GVZKMS53.js.map
@@ -0,0 +1 @@
1
+ {"version":3,"sources":["../src/client.ts","../src/generation/designer.ts"],"sourcesContent":["import Anthropic from '@anthropic-ai/sdk'\nimport type { N8nWorkflow, Tag } from './types/workflow.js'\nimport type { BuildResult, WorkflowListItem, ExecutionSummary, ExecutionDetail, SmokeTestResult } 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 { 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 { PatternAnalyzer } from './telemetry/pattern-analyzer.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'\nimport { ValidationError } from './errors/validation-error.js'\nimport { inferWorkflowType } from './utils/workflow-type.js'\nimport { generateUUID } from './utils/uuid.js'\nimport { homedir } from 'node:os'\nimport { join } from 'node:path'\n\nconst DEFAULT_MODEL = process.env['KAIROS_MODEL'] ?? 'claude-sonnet-4-6'\n\nexport class Kairos {\n private readonly provider: N8nProvider | null\n private readonly designer: WorkflowDesigner\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 patternAnalyzer: PatternAnalyzer | 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 const patternsPath = typeof options.telemetry === 'string'\n ? join(options.telemetry, '..', 'patterns.json')\n : join(homedir(), '.kairos', 'patterns.json')\n this.designer = new WorkflowDesigner(anthropic, this.model, logger, patternsPath)\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 this.patternAnalyzer = new PatternAnalyzer()\n } else if (typeof options.telemetry === 'string') {\n this.telemetry = new TelemetryCollector(options.telemetry)\n this.telemetryReader = new TelemetryReader(options.telemetry)\n this.patternAnalyzer = new PatternAnalyzer(options.telemetry)\n } else {\n this.telemetry = null\n this.telemetryReader = null\n this.patternAnalyzer = 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 const runId = generateUUID()\n const workflowType = inferWorkflowType(description)\n\n await this.telemetry?.emit('build_start', {\n description,\n model: this.model,\n dryRun: options?.dryRun ?? false,\n }, runId)\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 let designResult: DesignResult\n try {\n designResult = await this.designer.design(\n { description, ...(options?.name ? { name: options.name } : {}) },\n matches,\n globalFailureRates,\n )\n } catch (err) {\n if (err instanceof ValidationError && err.attemptMetadata) {\n for (const meta of err.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, severity: i.severity, message: i.message, nodeId: i.nodeId ?? null, nodeType: i.nodeType ?? null })),\n workflowType,\n }, runId)\n }\n await this.telemetry?.emit('build_complete', {\n description,\n success: false,\n totalAttempts: err.attemptMetadata.length,\n totalDurationMs: Date.now() - buildStart,\n totalTokensInput: err.attemptMetadata.reduce((s, m) => s + m.tokensInput, 0),\n totalTokensOutput: err.attemptMetadata.reduce((s, m) => s + m.tokensOutput, 0),\n workflowName: null,\n workflowId: null,\n dryRun: options?.dryRun ?? false,\n credentialsNeeded: 0,\n warnedRules: err.warnedRules ?? [],\n workflowType,\n }, runId)\n this.updatePatterns()\n }\n throw err\n }\n\n await this.emitAttemptTelemetry(description, designResult, workflowType, runId)\n\n const workflow = options?.name\n ? { ...designResult.workflow, name: options.name }\n : designResult.workflow\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 warnedRules: designResult.warnedRules,\n workflowType,\n }, runId)\n\n this.updatePatterns()\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 // Log the workflow ID immediately — if any post-deploy step fails, this ID\n // lets the user manually locate and clean up the orphaned workflow in n8n.\n this.logger.info('Workflow deployed to n8n', { workflowId: deployed.workflowId, name: deployed.name })\n this.recordDeploy(deployed.workflowId)\n\n if (options?.activate) {\n await provider.activate(deployed.workflowId)\n }\n\n this.saveToLibrary(workflow, description, designResult, matches, deployed.workflowId)\n\n let smokeTestResult: SmokeTestResult | undefined\n if (options?.smokeTest) {\n smokeTestResult = await provider.smokeTest(deployed.workflowId, workflow).catch((err: unknown): SmokeTestResult => {\n this.logger.warn('Smoke test threw unexpectedly', { err: String(err) })\n return { status: 'error', triggerType: 'manual', error: String(err) }\n })\n this.logger.info('Smoke test complete', { status: smokeTestResult.status, triggerType: smokeTestResult.triggerType })\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 warnedRules: designResult.warnedRules,\n workflowType,\n }, runId)\n\n this.updatePatterns()\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 ...(smokeTestResult !== undefined ? { smokeTest: smokeTestResult } : {}),\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 const runId = generateUUID()\n const workflowType = inferWorkflowType(description)\n\n await this.telemetry?.emit('build_start', {\n description,\n model: this.model,\n dryRun: false,\n }, runId)\n\n await this.library.initialize()\n const matches = await this.library.search(description)\n const globalFailureRates = await this.telemetryReader?.getFailureRates() ?? []\n\n let designResult: DesignResult\n try {\n designResult = await this.designer.design({ description }, matches, globalFailureRates)\n } catch (err) {\n if (err instanceof ValidationError && err.attemptMetadata) {\n for (const meta of err.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, severity: i.severity, message: i.message, nodeId: i.nodeId ?? null, nodeType: i.nodeType ?? null })),\n workflowType,\n }, runId)\n }\n await this.telemetry?.emit('build_complete', {\n description,\n success: false,\n totalAttempts: err.attemptMetadata.length,\n totalDurationMs: Date.now() - buildStart,\n totalTokensInput: err.attemptMetadata.reduce((s, m) => s + m.tokensInput, 0),\n totalTokensOutput: err.attemptMetadata.reduce((s, m) => s + m.tokensOutput, 0),\n workflowName: null,\n workflowId: null,\n dryRun: false,\n credentialsNeeded: 0,\n warnedRules: err.warnedRules ?? [],\n workflowType,\n }, runId)\n this.updatePatterns()\n }\n throw err\n }\n\n await this.emitAttemptTelemetry(description, designResult, workflowType, runId)\n\n const provider = this.requireProvider()\n const deployed = await provider.update(id, designResult.workflow)\n this.logger.info('Workflow updated in n8n', { workflowId: deployed.workflowId, name: deployed.name })\n\n this.saveToLibrary(designResult.workflow, description, designResult, matches, deployed.workflowId)\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 warnedRules: designResult.warnedRules,\n workflowType,\n }, runId)\n\n this.updatePatterns()\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 updatePatterns(): void {\n if (!this.patternAnalyzer) return\n this.saveQueue = this.saveQueue\n .then(() => this.patternAnalyzer!.analyzeAndSave())\n .then(() => null)\n .catch((err: unknown) => {\n this.logger.warn('Pattern analysis failed (non-fatal)', { err: String(err) })\n return null\n })\n }\n\n private async emitAttemptTelemetry(description: string, designResult: DesignResult, workflowType: string | null, runId: string): 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, severity: i.severity, message: i.message, nodeId: i.nodeId ?? null, nodeType: i.nodeType ?? null })),\n workflowType,\n }, runId)\n }\n }\n\n private recordDeploy(n8nWorkflowId?: string): void {\n this.saveQueue = this.saveQueue\n .then(async (savedId) => {\n if (savedId) {\n await this.library.recordDeployment(savedId, n8nWorkflowId)\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 n8nWorkflowId?: string,\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 if (n8nWorkflowId) metadata.n8nWorkflowId = n8nWorkflowId\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 patternsPath?: string,\n ) {\n this.validator = new N8nValidator()\n this.promptBuilder = new PromptBuilder(patternsPath)\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 const failingRuleIds = lastErrors.map((i) => i.rule)\n userMessage = this.promptBuilder.buildCorrectionMessage(request, matches, issueLines, attempt - 1, failingRuleIds)\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, warnedRules: this.promptBuilder.getWarnedRules() }\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 attemptMetadata,\n this.promptBuilder.getWarnedRules(),\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 if (message.stop_reason === 'max_tokens') {\n throw new GenerationError(\n 'Claude response was truncated (max_tokens reached) — the workflow may be too large. Try a simpler description or break it into smaller workflows.',\n )\n }\n\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"],"mappings":"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","names":["totalTokensInput","totalTokensOutput"]}
@@ -4,7 +4,7 @@ import {
4
4
  N8nValidator,
5
5
  ProviderError,
6
6
  generateUUID
7
- } from "./chunk-KIFT5LA7.js";
7
+ } from "./chunk-VPPWTMRJ.js";
8
8
 
9
9
  // src/library/null-library.ts
10
10
  var NullLibrary = class {
@@ -408,4 +408,4 @@ export {
408
408
  ValidationError,
409
409
  TemplateSyncer
410
410
  };
411
- //# sourceMappingURL=chunk-5GAY7CSJ.js.map
411
+ //# sourceMappingURL=chunk-MYAGTDQ2.js.map
@@ -2,7 +2,7 @@ import {
2
2
  RULE_EXAMPLES,
3
3
  RULE_MITIGATIONS,
4
4
  scoreToMode
5
- } from "./chunk-KIFT5LA7.js";
5
+ } from "./chunk-VPPWTMRJ.js";
6
6
 
7
7
  // src/generation/prompt-builder.ts
8
8
  import { readFileSync } from "fs";
@@ -566,4 +566,4 @@ export {
566
566
  PromptBuilder,
567
567
  inferWorkflowType
568
568
  };
569
- //# sourceMappingURL=chunk-EVOAYH2K.js.map
569
+ //# sourceMappingURL=chunk-V2IZBZGB.js.map
@@ -1421,7 +1421,7 @@ var PatternAnalyzer = class _PatternAnalyzer {
1421
1421
  this._cachedEvents = events;
1422
1422
  const starts = events.filter((e) => e.eventType === "build_start");
1423
1423
  const attempts = events.filter((e) => e.eventType === "generation_attempt");
1424
- const passed = attempts.filter(
1424
+ const _passed = attempts.filter(
1425
1425
  (a) => a.data.validationPassed === true
1426
1426
  );
1427
1427
  const failed = attempts.filter(
@@ -2579,4 +2579,4 @@ export {
2579
2579
  buildSearchCorpus,
2580
2580
  FileLibrary
2581
2581
  };
2582
- //# sourceMappingURL=chunk-KIFT5LA7.js.map
2582
+ //# sourceMappingURL=chunk-VPPWTMRJ.js.map