From 5e2a6bdb9ccdef32d122ffd092f34dcd18f3d504 Mon Sep 17 00:00:00 2001 From: czlonkowski <56956555+czlonkowski@users.noreply.github.com> Date: Tue, 7 Oct 2025 08:26:24 +0200 Subject: [PATCH] fix: resolve remaining AI validation integration test failures MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Simplified Calculator and Think tool validators (no toolDescription required - built-in descriptions) - Fixed trigger counting to exclude respondToWebhook from trigger detection - Fixed streaming error filters to use correct error code access pattern (details.code || code) This resolves 9 remaining integration test failures from Phase 2 AI validation implementation. 🤖 Generated with [Claude Code](https://claude.com/claude-code) Co-Authored-By: Claude --- src/services/ai-tool-validators.ts | 40 ++----------------- src/services/workflow-validator.ts | 5 ++- .../ai-validation/ai-agent-validation.test.ts | 9 +++-- .../chat-trigger-validation.test.ts | 9 +++-- .../ai-validation/e2e-validation.test.ts | 9 +++-- 5 files changed, 22 insertions(+), 50 deletions(-) diff --git a/src/services/ai-tool-validators.ts b/src/services/ai-tool-validators.ts index 27c543b..b3e0437 100644 --- a/src/services/ai-tool-validators.ts +++ b/src/services/ai-tool-validators.ts @@ -409,48 +409,16 @@ export function validateMCPClientTool(node: WorkflowNode): ValidationIssue[] { export function validateCalculatorTool(node: WorkflowNode): ValidationIssue[] { const issues: ValidationIssue[] = []; - // Check toolDescription (REQUIRED) - if (!node.parameters.toolDescription) { - issues.push({ - severity: 'error', - nodeId: node.id, - nodeName: node.name, - message: `Calculator Tool "${node.name}" has no toolDescription. Add one to help the LLM know when to use this tool.`, - code: 'MISSING_TOOL_DESCRIPTION' - }); - } else if (node.parameters.toolDescription.trim().length < MIN_DESCRIPTION_LENGTH_SHORT) { - issues.push({ - severity: 'info', - nodeId: node.id, - nodeName: node.name, - message: `Calculator Tool "${node.name}" has a very short toolDescription (minimum ${MIN_DESCRIPTION_LENGTH_SHORT} characters). Consider being more specific about when to use it.` - }); - } - + // Calculator Tool has a built-in description and is self-explanatory + // toolDescription is optional - no validation needed return issues; } export function validateThinkTool(node: WorkflowNode): ValidationIssue[] { const issues: ValidationIssue[] = []; - // Check toolDescription (REQUIRED) - if (!node.parameters.toolDescription) { - issues.push({ - severity: 'error', - nodeId: node.id, - nodeName: node.name, - message: `Think Tool "${node.name}" has no toolDescription. Add one to help the LLM know when to use thinking.`, - code: 'MISSING_TOOL_DESCRIPTION' - }); - } else if (node.parameters.toolDescription.trim().length < MIN_DESCRIPTION_LENGTH_MEDIUM) { - issues.push({ - severity: 'info', - nodeId: node.id, - nodeName: node.name, - message: `Think Tool "${node.name}" has a very short toolDescription (minimum ${MIN_DESCRIPTION_LENGTH_MEDIUM} characters). Explain when the agent should use thinking vs. action.` - }); - } - + // Think Tool has a built-in description and is self-explanatory + // toolDescription is optional - no validation needed return issues; } diff --git a/src/services/workflow-validator.ts b/src/services/workflow-validator.ts index 033605d..5dfdaef 100644 --- a/src/services/workflow-validator.ts +++ b/src/services/workflow-validator.ts @@ -327,8 +327,9 @@ export class WorkflowValidator { // Count trigger nodes - normalize type names first const triggerNodes = workflow.nodes.filter(n => { const normalizedType = NodeTypeNormalizer.normalizeToFullForm(n.type); - return normalizedType.toLowerCase().includes('trigger') || - normalizedType.toLowerCase().includes('webhook') || + const lowerType = normalizedType.toLowerCase(); + return lowerType.includes('trigger') || + (lowerType.includes('webhook') && !lowerType.includes('respond')) || normalizedType === 'nodes-base.start' || normalizedType === 'nodes-base.manualTrigger' || normalizedType === 'nodes-base.formTrigger'; diff --git a/tests/integration/ai-validation/ai-agent-validation.test.ts b/tests/integration/ai-validation/ai-agent-validation.test.ts index be2cd9c..67b3f3c 100644 --- a/tests/integration/ai-validation/ai-agent-validation.test.ts +++ b/tests/integration/ai-validation/ai-agent-validation.test.ts @@ -245,10 +245,11 @@ describe('Integration: AI Agent Validation', () => { expect(data.valid).toBe(false); expect(data.errors).toBeDefined(); - const streamingErrors = data.errors!.filter(e => - e.code === 'STREAMING_WITH_MAIN_OUTPUT' || - e.code === 'STREAMING_AGENT_HAS_OUTPUT' - ); + const streamingErrors = data.errors!.filter(e => { + const code = e.details?.code || e.code; + return code === 'STREAMING_WITH_MAIN_OUTPUT' || + code === 'STREAMING_AGENT_HAS_OUTPUT'; + }); expect(streamingErrors.length).toBeGreaterThan(0); }); diff --git a/tests/integration/ai-validation/chat-trigger-validation.test.ts b/tests/integration/ai-validation/chat-trigger-validation.test.ts index 3be8938..065f8af 100644 --- a/tests/integration/ai-validation/chat-trigger-validation.test.ts +++ b/tests/integration/ai-validation/chat-trigger-validation.test.ts @@ -308,10 +308,11 @@ describe('Integration: Chat Trigger Validation', () => { expect(data.errors).toBeDefined(); // Should detect streaming agent has output - const streamingErrors = data.errors!.filter(e => - e.code === 'STREAMING_AGENT_HAS_OUTPUT' || - e.message.toLowerCase().includes('streaming') - ); + const streamingErrors = data.errors!.filter(e => { + const code = e.details?.code || e.code; + return code === 'STREAMING_AGENT_HAS_OUTPUT' || + e.message.toLowerCase().includes('streaming'); + }); expect(streamingErrors.length).toBeGreaterThan(0); }); }); diff --git a/tests/integration/ai-validation/e2e-validation.test.ts b/tests/integration/ai-validation/e2e-validation.test.ts index 582d64c..ff52610 100644 --- a/tests/integration/ai-validation/e2e-validation.test.ts +++ b/tests/integration/ai-validation/e2e-validation.test.ts @@ -219,10 +219,11 @@ describe('Integration: End-to-End AI Workflow Validation', () => { expect(errorCodes).toContain('MISSING_CODE'); // Code Tool // Should also have streaming error - const streamingErrors = validationData.errors!.filter(e => - e.code === 'STREAMING_WITH_MAIN_OUTPUT' || - e.code === 'STREAMING_AGENT_HAS_OUTPUT' - ); + const streamingErrors = validationData.errors!.filter(e => { + const code = e.details?.code || e.code; + return code === 'STREAMING_WITH_MAIN_OUTPUT' || + code === 'STREAMING_AGENT_HAS_OUTPUT'; + }); expect(streamingErrors.length).toBeGreaterThan(0); // Verify error messages are actionable