Skip to content

feat(workflow): implement comprehensive workflow engine for multi-mod… - #256

Merged
murdore merged 1 commit into
juspay:releasefrom
arx-optimus-17:feat-workflow-engine-implementation
Feb 9, 2026
Merged

murdore merged 1 commit into
juspay:releasefrom
arx-optimus-17:feat-workflow-engine-implementation

Conversation

@arx-optimus-17

@arx-optimus-17 arx-optimus-17 commented Nov 29, 2025 •

Copy link
Copy Markdown
Collaborator

…el orchestration

  • Add core workflow engine with ensemble executor, judge scorer, and response conditioner
  • Implement 9 predefined workflows (consensus, multi-judge, fallback, adaptive)
  • Add workflow registry for centralized workflow management
  • Integrate 5 workflow methods into NeuroLink SDK class
  • Add CLI workflow command with list, info, and execution support
  • Implement workflow validation and metrics tracking
  • Add comprehensive TypeScript types for all workflow components
  • Export all workflow functionality from lib/index.ts
  • Remove redundant .d.ts files (auto-generated during build)
  • Fix import paths after moving to src/lib/workflow/
  • Update memory bank documentation with implementation details

Pull Request

Description

Type of Change

  • 🐛 Bug fix (non-breaking change which fixes an issue)
  • ✨ New feature (non-breaking change which adds functionality)
  • 💥 Breaking change (fix or feature that would cause existing functionality to not work as expected)
  • 📚 Documentation update
  • 🧹 Code refactoring (no functional changes)
  • ⚡ Performance improvement
  • 🧪 Test coverage improvement
  • 🔧 Build/CI configuration change

Related Issues

  • Fixes #
  • Related to #

Changes Made

AI Provider Impact

  • OpenAI
  • Anthropic
  • Google AI/Vertex
  • AWS Bedrock
  • Azure OpenAI
  • Hugging Face
  • Ollama
  • Mistral
  • All providers
  • No provider-specific changes

Component Impact

  • CLI
  • SDK
  • MCP Integration
  • Streaming
  • Tool Calling
  • Configuration
  • Documentation
  • Tests

Testing

  • Unit tests added/updated
  • Integration tests added/updated
  • E2E tests added/updated
  • Manual testing performed
  • All existing tests pass

Test Environment

  • OS:
  • Node.js version:
  • Package manager:

Performance Impact

  • No performance impact
  • Performance improvement
  • Minor performance impact (acceptable)
  • Significant performance impact (needs discussion)

Breaking Changes

Screenshots/Demo

Checklist

  • My code follows the project's style guidelines
  • I have performed a self-review of my code
  • I have commented my code, particularly in hard-to-understand areas
  • I have made corresponding changes to the documentation
  • My changes generate no new warnings
  • I have added tests that prove my fix is effective or that my feature works
  • New and existing unit tests pass locally with my changes
  • Any dependent changes have been merged and published

Additional Notes

Summary by CodeRabbit

  • New Features

    • Full Workflow Engine: multi-model ensembles, judge-based scoring, response conditioning, streaming, and nine ready-made workflows (consensus, fallback, multi-judge, adaptive variants)
  • Public API

    • Workflow management: register, run (including streaming), get, list, and clear workflows; workflow-aware generate/stream paths
  • CLI

    • New workflow command to list, inspect, register, and run workflows with live progress and metrics
  • Documentation

    • HLD/LLD, implementation guide, integration requirements, examples, and usage docs
  • Tests

    • Unit/integration tests plus an executable integration example demonstrating workflows and registry operations

✏️ Tip: You can customize this high-level summary in your review settings.

Copilot AI review requested due to automatic review settings November 29, 2025 11:32
@coderabbitai

coderabbitai Bot commented Nov 29, 2025 •

Copy link
Copy Markdown

Important

Review skipped

Auto incremental reviews are disabled on this repository.

Please check the settings in the CodeRabbit UI or the .coderabbit.yaml file in this repository. To trigger a single review, invoke the @coderabbitai review command.

You can disable this status message by setting the reviews.review_status to false in the CodeRabbit configuration file.

  • 🔍 Trigger a full review

Walkthrough

Adds a complete Workflow Engine: public types, Zod-backed config, execution core (runner, ensemble executor, judge scorer, conditioner), in-memory registry, metrics/validation utilities, nine predefined workflows, CLI command, examples/tests, and NeuroLink/lib public exports for registering and running workflows.

Changes

Cohort / File(s) Summary
Public API & Barrel Exports
src/lib/workflow/index.ts, src/lib/index.ts, src/lib/workflow/types.ts, src/lib/types/*
Adds centralized workflow public API, new workflow types, constants, and re-exports; expands lib exports to include runWorkflow, registry APIs, workflows, validation, and metrics.
NeuroLink Integration
src/lib/neurolink.ts, src/lib/types/generateTypes.ts, src/lib/types/streamTypes.ts, WORKFLOW-INTEGRATION-COMPLETE.md
Adds NeuroLink methods (runWorkflow, registerWorkflow, getWorkflow, listWorkflows, clearWorkflows), workflow-aware generate/stream paths and type extensions for workflow payloads.
Execution Core
src/lib/workflow/core/workflowRunner.ts, src/lib/workflow/core/ensembleExecutor.ts, src/lib/workflow/core/judgeScorer.ts, src/lib/workflow/core/responseConditioner.ts
Implements runWorkflow (including streaming), layered/flat model execution, model timeouts/concurrency, single/multi-judge scoring, response conditioning/synthesis, metrics aggregation and error handling.
Registry & Persistence
src/lib/workflow/core/workflowRegistry.ts, src/lib/workflow/core/types/registryTypes.ts
In-memory workflow registry with register/unregister/get/list/update/import/export, metadata and stats tracking, and pagination/filtering.
Config, Schemas & Helpers
src/lib/workflow/config.ts, src/lib/workflow/utils/workflowValidation.ts
Zod schemas, defaults, cross-field refinements, mergeWithDefaults, validation helpers and validateForRegistration/Execution entry points.
Core Types (submodules)
src/lib/workflow/core/types/*, src/lib/workflow/utils/types/*
Adds fine-grained core type modules for ensemble, judge, layer, conditioner, registry, and metrics/validation types.
Metrics & Utilities
src/lib/workflow/utils/workflowMetrics.ts, src/lib/workflow/utils/*
In-memory metrics store, record/query APIs, model metrics, consensus/confidence calculations, compare/generate summary helpers.
Pre-built Workflows & Examples
src/lib/workflow/workflows/*, src/lib/workflow/LAYER-EXAMPLES.ts, src/lib/workflow/PROMPT-EXAMPLES.ts, examples/workflow-integration-example.ts
Adds nine predefined workflows (consensus, fallback, multi-judge, adaptive), layer/prompt examples, and an integration example demonstrating registry and run flows.
CLI Integration
src/cli/commands/workflow.ts, src/cli/index.ts
New workflow CLI command to register/list/info/run workflows with verbose/live output and spinner.
Tests & QA
src/lib/workflow/__tests__/workflow.test.ts, test/*
Vitest suite for predefined workflows, registry behaviors, and configuration validations; some TTS tests gated by API keys.
Docs, Guides & Site
WORKFLOW-ENGINE-COMPLETE.md, docs/WORKFLOW-ENGINE-HLD.md, docs/WORKFLOW-ENGINE-LLD.md, WORKFLOW-ENGINE-IMPLEMENTATION-GUIDE.md, WORKFLOW-INTEGRATION-REQUIREMENTS.md, memory-bank/*, mkdocs.yml
HLD/LLD, implementation guide, integration requirements, full engine documentation, docs navigation entries.
Build & Misc
package.json, scripts/build-validations.cjs
Adds build:cli:link script, adjusts build:cli, and skips console-statement checks for CLI command files.

Sequence Diagram(s)

sequenceDiagram
  participant Client as Client / CLI
  participant NL as NeuroLink
  participant WR as WorkflowRunner
  participant EE as EnsembleExecutor
  participant JS as JudgeScorer
  participant RC as ResponseConditioner
  participant Prov as AI Provider(s)

  Client->>NL: runWorkflow(config | id, options)
  NL->>WR: runWorkflow(config, options)
  activate WR
  WR->>WR: validate config
  rect `#e6f3ff`
    Note over WR,EE: Execute ensemble (layered or flat)
    WR->>EE: executeModels(prompt, config)
    activate EE
    EE->>Prov: call models (parallel / sequential)
    Prov-->>EE: responses (content, timing, usage)
    EE-->>WR: EnsembleExecutionResult
    deactivate EE
  end
  rect `#f0fff0`
    Note over WR,JS: Score ensemble (if judges configured)
    alt judges present
      WR->>JS: scoreEnsemble(responses, judges)
      activate JS
      JS->>Prov: judge evaluations
      Prov-->>JS: judge responses (scores, reasoning)
      JS-->>WR: JudgeScores / MultiJudgeScores
      deactivate JS
    else no judges
      WR-->>WR: produce neutral scores
    end
  end
  rect `#fff7e6`
    Note over WR,RC: Select best & condition
    WR->>WR: selectBestResponse(scores)
    WR->>RC: conditionResponse(best, allResponses, scores)
    activate RC
    alt synthesis configured
      RC->>Prov: synthesis call
      Prov-->>RC: synthesized content
    else
      RC-->>WR: original content + metadata
    end
    RC-->>WR: ConditionResult
    deactivate RC
  end
  WR->>WR: aggregate metrics & build WorkflowResult
  WR-->>NL: WorkflowResult
  deactivate WR
  NL-->>Client: WorkflowResult
Loading

Estimated code review effort

🎯 5 (Critical) | ⏱️ ~120 minutes

Possibly related PRs

Suggested labels

released

Suggested reviewers

  • murdore
  • charan-vadd

Poem

🐰 I hopped through types and layered code,

Ensembles raced and judges glowed,
Registry kept each workflow's key,
Conditioned answers sprung like tea,
A carrot-cheer for builds complete — hop, ship, and go! 🥕

Pre-merge checks and finishing touches

✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The PR title 'feat(workflow): implement comprehensive workflow engine for multi-model orchestration' clearly and specifically describes the primary change in this changeset—the implementation of a comprehensive workflow engine system.
Docstring Coverage ✅ Passed Docstring coverage is 98.92% which is sufficient. The required threshold is 80.00%.
✨ Finishing touches
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Post copyable unit tests in a comment

Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

This comment was marked as resolved.

coderabbitai[bot]

This comment was marked as resolved.

@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from ac14916 to 5e0431d Compare November 29, 2025 11:45
Copilot AI review requested due to automatic review settings November 29, 2025 12:14
@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from 5e0431d to c5b4720 Compare November 29, 2025 12:14

This comment was marked as resolved.

@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from c5b4720 to 84514b6 Compare November 29, 2025 12:40
Copilot AI review requested due to automatic review settings November 29, 2025 12:55
@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from 84514b6 to 6353547 Compare November 29, 2025 12:55

This comment was marked as resolved.

@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from 6353547 to 22b9685 Compare November 29, 2025 13:22
Copilot AI review requested due to automatic review settings November 30, 2025 10:00
@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from 22b9685 to f33724b Compare November 30, 2025 10:00

This comment was marked as resolved.

@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from f33724b to 1e96b8f Compare November 30, 2025 10:38
Copilot AI review requested due to automatic review settings November 30, 2025 10:49
@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from 1e96b8f to 1566b85 Compare November 30, 2025 10:49

This comment was marked as resolved.

@coderabbitai

coderabbitai Bot commented Dec 30, 2025

Copy link
Copy Markdown

@arx-optimus-17, I'll conduct a final comprehensive review of the workflow engine implementation.

🎯 Final Review Assessment

✅ Major Strengths

  1. Solid Architecture

    • Clean layered design: Executor → Judge → Conditioner
    • Well-separated concerns with modular components
    • Flexible configuration supporting multiple execution patterns
  2. Type Safety & Validation

    • Comprehensive TypeScript types across all components
    • Zod schemas for runtime validation
    • Strong validation utilities with detailed error messages
  3. Developer Experience

    • Rich public API with 5 workflow methods on NeuroLink class
    • 9 predefined workflows covering common patterns
    • CLI integration for workflow discovery and execution
    • Excellent documentation (HLD, LLD, implementation guides)
  4. Testing & Quality

    • Unit tests for workflows and registry
    • Integration examples
    • Validation coverage

🔍 Areas for Final Verification

1. Error Handling Robustness

  • Timeout Cascades: Verify timeout handling when modelTimeout + judgeTimeout + conditioningTimeout > totalTimeout
  • Partial Failures: Ensure minSuccessful logic is consistent across flat and layered execution
  • Judge Failures: Confirm graceful degradation when judges fail or disagree

2. Production Readiness

  • Response Conditioner: Currently a stub (testing phase) - ensure this is clearly documented in public API
  • Cost Tracking: Verify estimateWorkflowCost provides useful estimates or consider real-time cost tracking
  • Observability: Confirm metrics collection is comprehensive enough for production monitoring

3. API Consistency

  • Dual Configuration: models vs modelGroups could be confusing - ensure clear migration path
  • Prompt Resolution: Verify hierarchical prompt resolution (model → workflow → default) is consistently applied
  • Score Normalization: Confirm all judges use 0-100 scale consistently

4. Edge Cases

  • Empty Ensemble: What happens when all models fail before judge evaluation?
  • Judge Ties: How are multi-judge ties resolved (especially 2-judge scenarios)?
  • Cost Overruns: Verify behavior when executionCost exceeds costThreshold

5. Backward Compatibility

  • Existing generate() calls remain unaffected ✓
  • New workflow params are optional ✓
  • Consider deprecation timeline for any conflicting patterns

🎯 Specific Recommendations

  1. Documentation Clarity

    // Add prominent note in public API docs:
    /**
     * @note Response conditioning is in testing phase.
     * Set conditioning.enabled = false for production use until phase 2.
     */
  2. Registry Safety

    • Consider adding registry size limits to prevent memory issues
    • Add warning when registering duplicate workflow IDs
  3. Cost Controls

    • Implement actual cost tracking if estimates aren't sufficient
    • Add pre-flight cost estimation before execution
  4. Streaming Support

    • Current implementation appears to buffer workflow results
    • Consider progressive streaming for long-running workflows in future
  5. Monitoring Hooks

    • Add optional callbacks for workflow lifecycle events
    • Enable integration with external monitoring systems

📋 Pre-Merge Checklist

  • Verify all timeouts are honored (model, judge, conditioning, total)
  • Test edge case: all models fail → judge should handle gracefully
  • Test edge case: judges disagree equally → verify tie-breaking
  • Confirm cost threshold enforcement works correctly
  • Validate registry size limits or add warning
  • Ensure response conditioner stub behavior is documented
  • Verify metrics collection covers all workflow phases
  • Test backward compatibility with existing generate() usage
  • Confirm CLI commands work with all workflow types
  • Review examples/workflow-integration-example.ts for accuracy

🚀 Overall Assessment

This is a well-architected and comprehensive implementation of a multi-model workflow engine. The code quality is high, type safety is excellent, and the documentation is thorough.

Recommendation: ✅ Approve with minor enhancements

The implementation is production-ready for the testing/evaluation phase as documented. The main consideration is ensuring teams understand the response conditioner is currently a stub and planning the rollout timeline for phase 2 features.

🎯 Post-Merge Priorities

  1. Implement actual response conditioning logic
  2. Add comprehensive observability/monitoring
  3. Implement streaming support for workflows
  4. Add integration tests for edge cases
  5. Create migration guide for models → modelGroups

Let me trigger a final comprehensive review to catch any remaining implementation issues.

✅ Actions performed

Full review triggered.

@coderabbitai coderabbitai Bot left a comment

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 8

♻️ Duplicate comments (9)
docs/WORKFLOW-ENGINE-LLD.md (1)

880-885: Bug in code example: finalResult is undefined.

This issue was flagged in a previous review. The code example on line 883 references finalResult.metadata, but finalResult is never defined in the execute method example. This should be corrected.

src/lib/neurolink.ts (1)

1700-2055: Workflow integration: use typed errors and safer provider/model defaults.

There are a few consistency and robustness gaps in the workflow paths:

  • generateWithWorkflow and streamWithWorkflow throw plain Error for “workflow not found” / “either workflow or workflowConfig must be provided” instead of using the SDK’s typed errors via ErrorFactory (or dedicated workflow error helpers).
  • runWorkflow also throws a plain Error when a workflow ID is not found.
  • In generateWithWorkflow, provider/model fall back to workflowConfig.models[0]?.provider / .model when selectedResponse is absent. Workflows that rely solely on modelGroups or have an empty models array will yield undefined here, and workflow.selectedModel will become strings like "undefined-undefined", which is awkward for consumers and can violate type expectations.

Consider:

  • Introducing workflow-specific constructors in ErrorFactory (e.g., workflowNotFound(id), invalidWorkflowConfig(reason)) and using them in all these branches, instead of new Error(...).
  • Defaulting provider/model and selectedModel to safe string values such as "unknown" when neither selectedResponse nor a concrete models[0] entry exists, so GenerateResult.workflow.* fields are always well-formed.

Also applies to: 2057-2235, 6302-6472

src/lib/workflow/core/judgeScorer.ts (1)

597-614: calculateConsensusLevel still risks -Infinity when no bestResponse is set.

If all JudgeScores objects have bestResponse undefined/empty, modeCounts remains empty and Math.max(...Array.from(modeCounts.values())) returns -Infinity, yielding a consensus of -Infinity / judgeResults.length.

Add a guard before computing maxCount:

  • If modeCounts.size === 0, return 0 (or another neutral value) to indicate “no consensus” rather than propagating -Infinity.
Suggested patch
  const bestResponses = judgeResults.map((r) => r.bestResponse);
  const modeCounts = new Map<string, number>();

  bestResponses.forEach((response) => {
    if (response) {
      modeCounts.set(response, (modeCounts.get(response) || 0) + 1);
    }
  });

- const maxCount = Math.max(...Array.from(modeCounts.values()));
- return maxCount / judgeResults.length;
+ // If no judge produced a bestResponse, treat consensus as zero
+ if (modeCounts.size === 0) {
+   return 0;
+ }
+
+ const maxCount = Math.max(...Array.from(modeCounts.values()));
+ return maxCount / judgeResults.length;
src/lib/workflow/core/responseConditioner.ts (1)

141-215: Synthesis path should use typed errors and avoid hardcoded provider/model defaults.

Two concerns in synthesizeImprovedResponse:

  • The empty-result case throws a raw Error("Synthesis model returned empty response"). In src/lib/**, new errors should be created via ErrorFactory (or a workflow-specific typed error) for consistent error typing and observability.
  • synthesisProvider / synthesisModel default to "azure" / "gpt-4o" when config.synthesisModel is not provided. This couples conditioning to a specific provider/model and can be surprising, especially given the Azure provider already has its own defaults. You already have a metadata-only fallback when config.synthesisModel is absent; relying on that and requiring an explicit synthesisModel when synthesis is desired would keep behavior clearer.

Suggested direction:

  • Import ErrorFactory (or use WorkflowError) and throw a typed conditioning error when synthesis returns no content.
  • Drop the "azure" / "gpt-4o" fallbacks and either:
    • Require config.synthesisModel to be present for synthesis (otherwise use addMetadataOnly), or
    • Delegate to provider-level defaults by passing config.synthesisModel?.provider/.model through unchanged.

Optionally, in addModelAttribution, you may want to skip the “Evaluation Score: 0/100” footer when no judge scores are available instead of defaulting to 0.

src/lib/workflow/core/ensembleExecutor.ts (2)

52-64: Retry logic defined in config but not implemented.

ExecutionConfig defines retries, retryDelay, and retryableErrors, but executeModel doesn't implement retry behavior. Failed model executions are returned immediately without retry attempts.

This was flagged in a previous review and remains unaddressed.


346-352: Unused _executionConfig parameter in executeModelGroups.

The underscore prefix indicates intentional non-use, but this config contains important settings like minResponses and retry behavior that should be passed to layer execution.

This was flagged in a previous review.

src/lib/workflow/config.ts (3)

109-125: ConditioningConfigSchema missing synthesisModel field.

The ConditioningConfig interface in types.ts (lines 167-172) includes a synthesisModel field, but the Zod schema doesn't validate it. This could allow invalid configurations to pass validation.

This was flagged in a previous review.


384-404: createWorkflowConfig omits modelGroups and prompt defaults.

The function doesn't include modelGroups, defaultSystemPrompt, or defaultJudgePrompt from the partial input, so these fields will be silently dropped.

This was flagged in a previous review.


487-498: Cost estimation ignores modelGroups.

estimateWorkflowCost uses config.models.length but workflows may use modelGroups instead. The getAllModels helper already exists for this purpose.

This was flagged in a previous review.

🧹 Nitpick comments (14)
src/lib/utils/pdfProcessor.ts (2)

267-269: Use ErrorFactory for typed errors.

Per coding guidelines, errors should be created using ErrorFactory rather than plain Error objects.

🔎 Proposed fix using ErrorFactory

First, add the import at the top of the file:

+import { ErrorFactory } from "../errors/index.js";
 import type {
   FileProcessingResult,
   PDFProviderConfig,

Then update the error:

-    throw new Error(
-      `Invalid format: "${format}". Supported formats: "png", "jpeg".`,
-    );
+    throw ErrorFactory.createValidationError(
+      `Invalid format: "${format}". Supported formats: "png", "jpeg".`,
+    );

As per coding guidelines, use ErrorFactory for creating typed errors across the SDK.


254-380: Wrap async operations with withTimeout utility.

Per coding guidelines for src/lib/utils/*.ts, async operations should be wrapped with the withTimeout utility for timeout handling and graceful degradation. The function performs multiple external library calls (pdfjs-dist, canvas) that could hang or take excessive time, especially for large or complex PDFs.

Consider wrapping the main conversion logic with timeout protection:

import { withTimeout } from './timeout.js'; // adjust path as needed

static async convertPDFToImages(
  pdfBuffer: Buffer,
  options?: {
    maxPages?: number;
    scale?: number;
    format?: "png" | "jpeg";
    quality?: number;
    timeout?: number; // Add timeout option
  },
): Promise<Array<{ buffer: Buffer; pageNumber: number }>> {
  const timeout = options?.timeout || 30000; // Default 30s
  
  return withTimeout(
    async () => {
      // existing conversion logic
    },
    timeout,
    'PDF to image conversion'
  );
}

As per coding guidelines, wrap async operations with withTimeout utility for timeout handling and graceful degradation.

src/lib/workflow/workflows/fallbackWorkflow.ts (1)

50-56: Document the placeholder models pattern.

Both workflows include a placeholder models array alongside modelGroups. While the comment notes this is "required by schema," this pattern could confuse consumers who might not understand the precedence relationship.

Consider adding a JSDoc comment to the exported constants explaining the precedence:

/**
 * Fast-Fallback Workflow Configuration
 *
 * Uses layer-based execution with sequential groups:
 * ...
 * 
 * @remarks
 * The `models` array is a schema-required placeholder.
 * Execution uses `modelGroups`, which takes precedence.
 */
export const FAST_FALLBACK_WORKFLOW: WorkflowConfig = {
  // ...

Also applies to: 164-169

src/lib/workflow/PROMPT-EXAMPLES.ts (1)

12-37: Add explicit type annotations to example workflow configurations.

The example workflows are exported without type annotations, which reduces type safety and IDE support. Consider adding explicit WorkflowConfig typing to ensure the examples conform to the expected schema.

🔎 Proposed fix
+import type { WorkflowConfig } from "./types.js";
+
-const simpleWorkflow = {
+const simpleWorkflow: Partial<WorkflowConfig> = {
   id: "simple-ensemble",
   name: "Simple Ensemble with Workflow Defaults",
   type: "ensemble",

Apply similar typing to mixedWorkflow, advancedWorkflow, and multiJudgeWorkflow.

src/lib/workflow/workflows/consensusWorkflow.ts (1)

129-137: Consider adding validation for empty system prompts.

The createConsensus3WithPrompt function accepts any string, including empty strings. Consider adding basic validation or trimming.

🔎 Proposed fix
 export function createConsensus3WithPrompt(
   systemPrompt: string,
 ): WorkflowConfig {
+  const trimmedPrompt = systemPrompt.trim();
+  if (!trimmedPrompt) {
+    throw new Error("System prompt cannot be empty");
+  }
   return {
     ...CONSENSUS_3_WORKFLOW,
     id: `consensus-3-custom-${Date.now()}`,
-    defaultSystemPrompt: systemPrompt,
+    defaultSystemPrompt: trimmedPrompt,
   };
 }
src/lib/types/generateTypes.ts (1)

300-304: Consider aligning judgeScores.selectedModel with selectedModel field.

There's potential redundancy between judgeScores.selectedModel (line 303) and the top-level selectedModel (line 305). Consider documenting the distinction or consolidating.

src/lib/workflow/core/types/registryTypes.ts (1)

11-16: Consider consolidating WorkflowMetadata with RegistryEntry.

WorkflowMetadata (lines 49-53) has the same fields as the metadata portion of RegistryEntry (lines 11-16). Consider having RegistryEntry extend or use WorkflowMetadata to reduce duplication.

🔎 Proposed fix
+/**
+ * Workflow metadata
+ */
+export interface WorkflowMetadata {
+  registeredAt: string;
+  lastUsed?: string;
+  usageCount: number;
+}
+
 /**
  * Registry entry with metadata (internal)
  */
-export interface RegistryEntry {
+export interface RegistryEntry extends WorkflowMetadata {
   config: WorkflowConfig;
-  registeredAt: string;
-  lastUsed?: string;
-  usageCount: number;
 }
-
-/**
- * Workflow metadata
- */
-export interface WorkflowMetadata {
-  registeredAt: string;
-  lastUsed?: string;
-  usageCount: number;
-}

Also applies to: 49-53

src/lib/workflow/core/types/judgeTypes.ts (1)

31-35: Consider making error field more specific.

The error field is typed as WorkflowError, but scoring failures might not always produce a full WorkflowError. Consider using WorkflowError | Error | string or a simpler error representation.

🔎 Proposed fix
 export interface ScoreResult {
   scores: JudgeScores | MultiJudgeScores;
   judgeTime: number;
-  error?: WorkflowError;
+  error?: WorkflowError | Error;
 }
src/lib/workflow/utils/types/metricsTypes.ts (1)

36-41: Consider adding workflow IDs to WorkflowComparison.

The comparison result references workflow1 and workflow2 but doesn't include their IDs, making it harder to understand the comparison context without external tracking.

🔎 Proposed fix
 export interface WorkflowComparison {
+  workflow1Id: string;
+  workflow2Id: string;
   workflow1: SummaryStats;
   workflow2: SummaryStats;
   winner: "workflow1" | "workflow2" | "tie";
   reasoning: string;
 }
src/cli/commands/workflow.ts (2)

35-46: Consider the impact of clearing all workflows on every CLI invocation.

Calling neurolink.clearWorkflows() at the start of every workflow command will remove any custom workflows that may have been registered programmatically. While this ensures a clean slate for CLI operations, it could be unexpected behavior if the SDK instance is shared or if workflows were registered elsewhere in the application lifecycle.

Consider one of these approaches:

  • Document this behavior clearly in the CLI help text
  • Only clear and re-register if the registry is empty or stale
  • Use a separate registry instance for CLI operations

55-361: Method exceeds recommended line limit.

The createWorkflowCommand static method is 307 lines long, exceeding the 300-line threshold flagged by static analysis. While the code is well-organized with clear sections (list handler, info handler, run handler), extracting these handlers into separate private methods would improve maintainability and testability.

Suggested refactoring approach

Consider extracting the handler logic:

static createWorkflowCommand(): CommandModule<{}, WorkflowCommandArgs> {
  return {
    command: "workflow",
    describe: "Run multi-model workflows with judge-based evaluation",
    builder: (yargs) => {
      // ... builder configuration (keep as is)
    },
    handler: async (args) => {
      try {
        registerPredefinedWorkflows();
        
        if (args.list) {
          await this.handleList();
          return;
        }
        
        if (args.info && args.workflow) {
          await this.handleInfo(args.workflow);
          return;
        }
        
        if (args.prompt && args.workflow) {
          await this.handleRun(args);
          return;
        }
      } catch (error) {
        // ... error handling
      }
    },
  };
}

private static async handleList(): Promise<void> { /* ... */ }
private static async handleInfo(workflowId: string): Promise<void> { /* ... */ }
private static async handleRun(args: WorkflowCommandArgs): Promise<void> { /* ... */ }
src/lib/workflow/core/workflowRegistry.ts (2)

126-144: Side effect in getter: getWorkflow mutates registry state.

Calling getWorkflow increments usageCount and updates lastUsed, which may be unexpected for a "get" operation. Consider separating read-only retrieval from usage tracking, or renaming to getAndTrackWorkflow.

🔎 Proposed refactor
+/**
+ * Get workflow configuration by ID (read-only, no tracking)
+ */
+export function peekWorkflow(workflowId: string): WorkflowConfig | undefined {
+  return workflowRegistry.get(workflowId)?.config;
+}
+
 /**
- * Get workflow configuration by ID
+ * Get workflow configuration by ID and track usage
  */
 export function getWorkflow(workflowId: string): WorkflowConfig | undefined {

160-194: Pagination offset not applied when limit is undefined.

When limit is not provided, the offset parameter is silently ignored. Users might expect offset to work independently for skipping results.

🔎 Proposed fix
   // Apply pagination
-  if (limit !== undefined) {
-    workflows = workflows.slice(offset, offset + limit);
-  }
+  if (limit !== undefined || offset > 0) {
+    workflows = workflows.slice(offset, limit !== undefined ? offset + limit : undefined);
+  }
src/lib/workflow/types.ts (1)

364-391: MultiJudgeScores has potentially confusing duplicate field semantics.

Fields like scores and ranking are documented as "points to" averageScores and aggregatedRanking respectively (lines 384-385). This creates ambiguity about whether they're separate copies or actual references. Consider using getters or documenting the relationship more explicitly.

Verify that consumers understand scores is the same as averageScores and ensure no code expects them to differ.

📜 Review details

Configuration used: Organization UI

Review profile: CHILL

Plan: Pro

📥 Commits

Reviewing files that changed from the base of the PR and between 88261c4 and af99383.

📒 Files selected for processing (46)
  • WORKFLOW-ENGINE-COMPLETE.md
  • WORKFLOW-ENGINE-IMPLEMENTATION-GUIDE.md
  • WORKFLOW-INTEGRATION-COMPLETE.md
  • WORKFLOW-INTEGRATION-REQUIREMENTS.md
  • docs/WORKFLOW-ENGINE-HLD.md
  • docs/WORKFLOW-ENGINE-LLD.md
  • docs/index.md
  • examples/workflow-integration-example.ts
  • memory-bank/workflow-engine-implementation.md
  • mkdocs.yml
  • package.json
  • scripts/build-validations.cjs
  • src/cli/commands/workflow.ts
  • src/cli/index.ts
  • src/lib/index.ts
  • src/lib/neurolink.ts
  • src/lib/types/generateTypes.ts
  • src/lib/types/streamTypes.ts
  • src/lib/utils/pdfProcessor.ts
  • src/lib/workflow/LAYER-EXAMPLES.ts
  • src/lib/workflow/PROMPT-EXAMPLES.ts
  • src/lib/workflow/__tests__/workflow.test.ts
  • src/lib/workflow/config.ts
  • src/lib/workflow/core/ensembleExecutor.ts
  • src/lib/workflow/core/judgeScorer.ts
  • src/lib/workflow/core/responseConditioner.ts
  • src/lib/workflow/core/types/conditionerTypes.ts
  • src/lib/workflow/core/types/ensembleTypes.ts
  • src/lib/workflow/core/types/index.ts
  • src/lib/workflow/core/types/judgeTypes.ts
  • src/lib/workflow/core/types/layerTypes.ts
  • src/lib/workflow/core/types/registryTypes.ts
  • src/lib/workflow/core/workflowRegistry.ts
  • src/lib/workflow/core/workflowRunner.ts
  • src/lib/workflow/index.ts
  • src/lib/workflow/types.ts
  • src/lib/workflow/utils/types/index.ts
  • src/lib/workflow/utils/types/metricsTypes.ts
  • src/lib/workflow/utils/types/validationTypes.ts
  • src/lib/workflow/utils/workflowMetrics.ts
  • src/lib/workflow/utils/workflowValidation.ts
  • src/lib/workflow/workflows/adaptiveWorkflow.ts
  • src/lib/workflow/workflows/consensusWorkflow.ts
  • src/lib/workflow/workflows/fallbackWorkflow.ts
  • src/lib/workflow/workflows/multiJudgeWorkflow.ts
  • test/unit/tts-audio-output.test.ts
🧰 Additional context used
📓 Path-based instructions (6)
src/lib/types/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Organize TypeScript types by domain (providers, generation, streaming, MCP, etc.) to avoid circular dependencies

Files:

  • src/lib/types/generateTypes.ts
  • src/lib/types/streamTypes.ts
src/lib/**/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use ErrorFactory for creating typed errors across the SDK

Files:

  • src/lib/types/generateTypes.ts
  • src/lib/workflow/core/types/ensembleTypes.ts
  • src/lib/workflow/utils/types/index.ts
  • src/lib/workflow/core/types/layerTypes.ts
  • src/lib/workflow/utils/types/validationTypes.ts
  • src/lib/workflow/LAYER-EXAMPLES.ts
  • src/lib/workflow/core/workflowRunner.ts
  • src/lib/workflow/core/types/conditionerTypes.ts
  • src/lib/workflow/PROMPT-EXAMPLES.ts
  • src/lib/workflow/workflows/consensusWorkflow.ts
  • src/lib/workflow/utils/types/metricsTypes.ts
  • src/lib/workflow/core/types/registryTypes.ts
  • src/lib/workflow/utils/workflowMetrics.ts
  • src/lib/workflow/core/responseConditioner.ts
  • src/lib/workflow/workflows/adaptiveWorkflow.ts
  • src/lib/workflow/core/types/judgeTypes.ts
  • src/lib/workflow/core/judgeScorer.ts
  • src/lib/workflow/workflows/multiJudgeWorkflow.ts
  • src/lib/workflow/core/workflowRegistry.ts
  • src/lib/workflow/utils/workflowValidation.ts
  • src/lib/utils/pdfProcessor.ts
  • src/lib/workflow/__tests__/workflow.test.ts
  • src/lib/workflow/core/ensembleExecutor.ts
  • src/lib/workflow/workflows/fallbackWorkflow.ts
  • src/lib/neurolink.ts
  • src/lib/index.ts
  • src/lib/types/streamTypes.ts
  • src/lib/workflow/core/types/index.ts
  • src/lib/workflow/config.ts
  • src/lib/workflow/index.ts
  • src/lib/workflow/types.ts
**/*.{ts,tsx}

📄 CodeRabbit inference engine (CLAUDE.md)

Maintain strict TypeScript type checking across all SDK modules

Files:

  • src/lib/types/generateTypes.ts
  • examples/workflow-integration-example.ts
  • src/lib/workflow/core/types/ensembleTypes.ts
  • src/lib/workflow/utils/types/index.ts
  • src/lib/workflow/core/types/layerTypes.ts
  • test/unit/tts-audio-output.test.ts
  • src/lib/workflow/utils/types/validationTypes.ts
  • src/lib/workflow/LAYER-EXAMPLES.ts
  • src/lib/workflow/core/workflowRunner.ts
  • src/lib/workflow/core/types/conditionerTypes.ts
  • src/lib/workflow/PROMPT-EXAMPLES.ts
  • src/lib/workflow/workflows/consensusWorkflow.ts
  • src/lib/workflow/utils/types/metricsTypes.ts
  • src/lib/workflow/core/types/registryTypes.ts
  • src/cli/commands/workflow.ts
  • src/lib/workflow/utils/workflowMetrics.ts
  • src/lib/workflow/core/responseConditioner.ts
  • src/lib/workflow/workflows/adaptiveWorkflow.ts
  • src/lib/workflow/core/types/judgeTypes.ts
  • src/lib/workflow/core/judgeScorer.ts
  • src/lib/workflow/workflows/multiJudgeWorkflow.ts
  • src/lib/workflow/core/workflowRegistry.ts
  • src/lib/workflow/utils/workflowValidation.ts
  • src/lib/utils/pdfProcessor.ts
  • src/lib/workflow/__tests__/workflow.test.ts
  • src/lib/workflow/core/ensembleExecutor.ts
  • src/lib/workflow/workflows/fallbackWorkflow.ts
  • src/lib/neurolink.ts
  • src/lib/index.ts
  • src/lib/types/streamTypes.ts
  • src/lib/workflow/core/types/index.ts
  • src/cli/index.ts
  • src/lib/workflow/config.ts
  • src/lib/workflow/index.ts
  • src/lib/workflow/types.ts
src/cli/commands/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Use yargs command modules with CommandFactory pattern for all CLI commands

Files:

  • src/cli/commands/workflow.ts
src/lib/utils/*.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Wrap async operations with withTimeout utility for timeout handling and graceful degradation

Files:

  • src/lib/utils/pdfProcessor.ts
src/lib/utils/pdfProcessor.ts

📄 CodeRabbit inference engine (CLAUDE.md)

Process PDFs with PDFProcessor for native document support and structured content extraction

Files:

  • src/lib/utils/pdfProcessor.ts
🧠 Learnings (27)
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to src/lib/types/*.ts : Organize TypeScript types by domain (providers, generation, streaming, MCP, etc.) to avoid circular dependencies

Applied to files:

  • src/lib/workflow/core/types/ensembleTypes.ts
  • src/lib/workflow/utils/types/index.ts
  • src/lib/workflow/utils/types/validationTypes.ts
  • src/lib/workflow/utils/types/metricsTypes.ts
  • src/lib/workflow/core/types/registryTypes.ts
  • src/lib/neurolink.ts
  • src/lib/workflow/core/types/index.ts
  • src/lib/workflow/types.ts
📚 Learning: 2025-11-17T13:53:20.209Z
Learnt from: vigneshJuspay
Repo: juspay/neurolink PR: 237
File: memory-bank/tts-provider-implementation-plan.md:92-106
Timestamp: 2025-11-17T13:53:20.209Z
Learning: In PR 237's TTS modality implementation approach, TTS functionality uses GOOGLE_AI_API_KEY (not GOOGLE_TTS_API_KEY) when using the google-ai provider. TTS is implemented as an output modality that leverages the existing google-ai provider authentication.

Applied to files:

  • test/unit/tts-audio-output.test.ts
📚 Learning: 2025-11-11T14:02:21.868Z
Learnt from: vigneshJuspay
Repo: juspay/neurolink PR: 214
File: src/lib/index.ts:205-233
Timestamp: 2025-11-11T14:02:21.868Z
Learning: In the NeuroLink TTS SDK (src/lib/tts/), use GOOGLE_TTS_API_KEY environment variable specifically for Google Cloud Text-to-Speech access. GOOGLE_AI_API_KEY does not provide TTS access and should not be used for TTS functionality. The keys are intentionally kept separate for better access control and separation of concerns.

Applied to files:

  • test/unit/tts-audio-output.test.ts
📚 Learning: 2025-12-18T15:13:28.435Z
Learnt from: vigneshJuspay
Repo: juspay/neurolink PR: 693
File: src/lib/core/baseProvider.ts:490-517
Timestamp: 2025-12-18T15:13:28.435Z
Learning: In juspay/neurolink TTS integration (PR #693), when options.provider is "auto" and passed to TTSProcessor.synthesize, it will fail automatically during handler lookup since only concrete providers ("google-ai", "vertex") are registered as TTS handlers. No explicit validation against "auto" is needed—the implicit failure at handler registration lookup is by design.

Applied to files:

  • test/unit/tts-audio-output.test.ts
  • src/lib/workflow/core/responseConditioner.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Run `pnpm run check` to validate TypeScript types before committing changes

Applied to files:

  • scripts/build-validations.cjs
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to **/*.{ts,tsx} : Maintain strict TypeScript type checking across all SDK modules

Applied to files:

  • scripts/build-validations.cjs
  • src/lib/workflow/core/types/index.ts
📚 Learning: 2025-09-17T18:14:34.960Z
Learnt from: RajuSudhar
Repo: juspay/neurolink PR: 173
File: src/lib/types/index.ts:58-62
Timestamp: 2025-09-17T18:14:34.960Z
Learning: RajuSudhar explained that in the Neurolink codebase, there are multiple ProviderConfig types causing inconsistency. One existing ProviderConfig type better suited the "ProviderConfig" name, so they renamed the less-suitable one to AIModelProviderConfig to free up the name. Adding backward compatibility aliases would worsen naming inconsistency rather than help. The remaining duplicates will be systematically deduplicated in the 07-Types-Module.md TODO as part of their phased refactor approach.

Applied to files:

  • src/lib/workflow/LAYER-EXAMPLES.ts
  • docs/index.md
  • src/lib/workflow/core/responseConditioner.ts
📚 Learning: 2025-09-17T17:55:15.261Z
Learnt from: RajuSudhar
Repo: juspay/neurolink PR: 173
File: src/lib/index.ts:16-16
Timestamp: 2025-09-17T17:55:15.261Z
Learning: In src/lib/types/providers.ts, ProviderConfig was renamed to AIModelProviderConfig to deduplicate type names, as there was an existing ProviderConfig type that better suited the "ProviderConfig" name. This was an intentional breaking change for better type organization.

Applied to files:

  • src/lib/workflow/LAYER-EXAMPLES.ts
  • docs/index.md
  • src/lib/workflow/core/responseConditioner.ts
  • src/lib/neurolink.ts
  • src/lib/workflow/core/types/index.ts
  • src/lib/workflow/types.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Build with `pnpm run build` and test CLI with `pnpm run build:cli && pnpm run cli` before final validation

Applied to files:

  • package.json
  • src/cli/index.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Run relevant test suites with `pnpm test` to validate changes before building

Applied to files:

  • package.json
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to src/lib/types/index.ts : Add new AI providers to the `AIProviderName` enum in `src/lib/types/index.ts`

Applied to files:

  • src/lib/workflow/core/types/registryTypes.ts
  • src/lib/neurolink.ts
  • src/lib/workflow/core/types/index.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to src/cli/commands/*.ts : Use yargs command modules with `CommandFactory` pattern for all CLI commands

Applied to files:

  • src/cli/commands/workflow.ts
  • src/cli/index.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to src/cli/factories/commandFactory.ts : Update CLI provider choices in `src/cli/factories/commandFactory.ts` when adding new providers

Applied to files:

  • src/cli/commands/workflow.ts
  • src/cli/index.ts
📚 Learning: 2025-09-28T21:08:19.655Z
Learnt from: RajuSudhar
Repo: juspay/neurolink PR: 174
File: todos/refactor/03-providers-module.md:3-6
Timestamp: 2025-09-28T21:08:19.655Z
Learning: RajuSudhar mentioned that remaining interfaces in the SageMaker module (30+ interfaces across 5 files) will be resolved in a different PR, but no specific PR was found. The providers module refactor was marked COMPLETED prematurely while significant SageMaker interface conversion work remains pending.

Applied to files:

  • docs/index.md
📚 Learning: 2025-09-01T14:12:14.227Z
Learnt from: swaroopvarma1
Repo: juspay/neurolink PR: 141
File: docs/REAL-TIME-SPEECH-AGENTS.md:124-149
Timestamp: 2025-09-01T14:12:14.227Z
Learning: In the NeuroLink Speech-to-Speech agent system, the team prefers simple void-returning APIs (sendAudioFrame, sendText, flush) over Promise-based backpressure mechanisms, prioritizing ease of use and implementation simplicity for real-time speech processing.

Applied to files:

  • docs/index.md
📚 Learning: 2025-09-02T13:50:42.770Z
Learnt from: YasmeenOgo
Repo: juspay/neurolink PR: 145
File: src/lib/core/types.ts:0-0
Timestamp: 2025-09-02T13:50:42.770Z
Learning: The APIVersions enum in src/lib/core/types.ts now contains comprehensive API version constants for all major AI providers: Azure OpenAI (latest, stable, legacy), OpenAI (current, beta), Google AI (current, beta), and Anthropic (current). This centralization helps avoid API version drift across the codebase.

Applied to files:

  • docs/index.md
  • src/lib/neurolink.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to src/lib/mcp/toolRegistry.ts : Register all external tools and MCP servers with `MCPToolRegistry` for availability to AI models

Applied to files:

  • src/lib/workflow/core/workflowRegistry.ts
  • src/lib/neurolink.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to src/lib/utils/pdfProcessor.ts : Process PDFs with `PDFProcessor` for native document support and structured content extraction

Applied to files:

  • src/lib/utils/pdfProcessor.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to src/lib/**/*.ts : Use `ErrorFactory` for creating typed errors across the SDK

Applied to files:

  • src/lib/neurolink.ts
📚 Learning: 2025-09-01T22:58:39.149Z
Learnt from: sudharsan-juspay
Repo: juspay/neurolink PR: 140
File: src/lib/core/types.ts:198-203
Timestamp: 2025-09-01T22:58:39.149Z
Learning: In src/lib/core/types.ts, StreamOptions (imported from streamTypes.js) and StreamingOptions are intentionally different types with different use cases. StreamingOptions is for unified AI requests with multiple provider configurations, while StreamOptions is for individual streaming operations.

Applied to files:

  • src/lib/neurolink.ts
  • src/lib/types/streamTypes.ts
📚 Learning: 2025-12-29T06:57:39.349Z
Learnt from: CR
Repo: juspay/neurolink PR: 0
File: CLAUDE.md:0-0
Timestamp: 2025-12-29T06:57:39.349Z
Learning: Applies to src/lib/utils/transformationUtils.ts : Use `transformToolExecutions()` utility to convert tool results for provider API compatibility

Applied to files:

  • src/lib/neurolink.ts
📚 Learning: 2025-11-04T22:14:18.719Z
Learnt from: RajuSudhar
Repo: juspay/neurolink PR: 0
File: :0-0
Timestamp: 2025-11-04T22:14:18.719Z
Learning: In the juspay/neurolink repository, all new type definitions must be placed in src/lib/types/. New type definitions outside this directory should be flagged and blocked in code reviews.

Applied to files:

  • src/lib/neurolink.ts
  • src/lib/workflow/core/types/index.ts
📚 Learning: 2025-09-24T06:42:06.088Z
Learnt from: amreetkhuntia
Repo: juspay/neurolink PR: 185
File: src/lib/evaluation/contextBuilder.ts:79-85
Timestamp: 2025-09-24T06:42:06.088Z
Learning: In the NeuroLink codebase, using `(options.prompt || [])` pattern for handling potentially undefined prompt arrays is the preferred approach over extracting to a normalized variable when building conversation history in the ContextBuilder class.

Applied to files:

  • src/lib/neurolink.ts
📚 Learning: 2025-12-15T18:35:37.783Z
Learnt from: vigneshJuspay
Repo: juspay/neurolink PR: 0
File: :0-0
Timestamp: 2025-12-15T18:35:37.783Z
Learning: In juspay/neurolink TTS implementation (PR #691), the new StreamChunk discriminated union type introduced in TTS-019 will be integrated with StreamResult.stream during the actual TTS streaming implementation PR (TTS-020/TTS-021), not in the type-definition PR. This phased approach keeps type updates and implementation changes atomic.

Applied to files:

  • src/lib/types/streamTypes.ts
📚 Learning: 2025-09-01T06:15:59.759Z
Learnt from: amreetkhuntia
Repo: juspay/neurolink PR: 133
File: src/lib/core/types.ts:208-210
Timestamp: 2025-09-01T06:15:59.759Z
Learning: The middleware?: MiddlewareFactoryOptions field is already present in both TextGenerationOptions and StreamOptions interfaces in the neurolink codebase.

Applied to files:

  • src/lib/types/streamTypes.ts
📚 Learning: 2025-09-28T21:00:08.243Z
Learnt from: RajuSudhar
Repo: juspay/neurolink PR: 174
File: src/lib/mcp/contracts/mcpContract.ts:0-0
Timestamp: 2025-09-28T21:00:08.243Z
Learning: The src/lib/mcp/contracts/mcpContract.ts file was completely removed during the MCP types refactor in PR #174, with its types moved to centralized modules like src/lib/types/mcpTypes.ts and src/lib/types/index.ts.

Applied to files:

  • src/lib/workflow/core/types/index.ts
📚 Learning: 2025-11-05T20:31:04.103Z
Learnt from: RajuSudhar
Repo: juspay/neurolink PR: 227
File: src/lib/utils/redis.ts:15-15
Timestamp: 2025-11-05T20:31:04.103Z
Learning: In the juspay/neurolink repository, type centralization rules (requiring types in src/lib/types/) do not apply to private, non-exported utility types used within a single file. Simple readability helpers like `type RedisClient = ReturnType<typeof createClient>` should remain in their implementation file when they are not exported and only used locally. Only exported types shared across modules, business/domain types, and public API types require centralization.

Applied to files:

  • src/lib/workflow/core/types/index.ts
🧬 Code graph analysis (21)
examples/workflow-integration-example.ts (3)
src/lib/workflow/workflows/consensusWorkflow.ts (1)
  • CONSENSUS_3_WORKFLOW (44-108)
src/lib/workflow/workflows/multiJudgeWorkflow.ts (1)
  • MULTI_JUDGE_5_WORKFLOW (50-154)
src/lib/workflow/workflows/adaptiveWorkflow.ts (1)
  • QUALITY_MAX_WORKFLOW (44-170)
src/lib/workflow/core/types/ensembleTypes.ts (1)
src/lib/workflow/types.ts (4)
  • ModelConfig (97-118)
  • ExecutionConfig (193-219)
  • EnsembleResponse (305-331)
  • WorkflowError (507-523)
src/lib/workflow/core/types/layerTypes.ts (1)
src/lib/workflow/types.ts (2)
  • EnsembleResponse (305-331)
  • ModelGroup (40-60)
test/unit/tts-audio-output.test.ts (2)
src/lib/types/ttsTypes.ts (1)
  • TTSResult (75-97)
src/lib/utils/ttsProcessor.ts (2)
  • TTSError (30-51)
  • TTS_ERROR_CODES (18-25)
src/lib/workflow/utils/types/validationTypes.ts (2)
src/lib/workflow/utils/types/index.ts (1)
  • ValidationIssues (11-11)
src/lib/workflow/types.ts (2)
  • WorkflowValidationError (475-480)
  • WorkflowValidationWarning (485-490)
src/lib/workflow/LAYER-EXAMPLES.ts (1)
src/lib/workflow/types.ts (1)
  • WorkflowConfig (65-92)
src/lib/workflow/core/workflowRunner.ts (3)
src/lib/workflow/config.ts (3)
  • usesModelGroups (281-283)
  • PLACEHOLDER_PROVIDER (32-32)
  • PLACEHOLDER_MODEL (33-33)
src/lib/workflow/core/types/ensembleTypes.ts (1)
  • EnsembleExecutionResult (29-35)
src/lib/workflow/core/types/judgeTypes.ts (1)
  • ScoreResult (31-35)
src/lib/workflow/utils/types/metricsTypes.ts (1)
src/lib/workflow/utils/types/index.ts (3)
  • WorkflowExecutionMetrics (9-9)
  • SummaryStats (7-7)
  • WorkflowComparison (8-8)
src/lib/workflow/core/types/registryTypes.ts (1)
src/lib/workflow/types.ts (2)
  • WorkflowConfig (65-92)
  • WorkflowValidationResult (466-470)
src/lib/workflow/utils/workflowMetrics.ts (2)
src/lib/workflow/utils/types/metricsTypes.ts (3)
  • WorkflowExecutionMetrics (9-19)
  • SummaryStats (24-31)
  • WorkflowComparison (36-41)
src/lib/workflow/types.ts (2)
  • WorkflowResult (256-300)
  • EnsembleResponse (305-331)
src/lib/workflow/core/responseConditioner.ts (3)
src/lib/workflow/core/types/conditionerTypes.ts (2)
  • ConditionOptions (16-23)
  • ConditionResult (28-40)
src/lib/workflow/types.ts (4)
  • ConditioningConfig (157-188)
  • EnsembleResponse (305-331)
  • JudgeScores (337-359)
  • MultiJudgeScores (364-391)
src/lib/index.ts (3)
  • EnsembleResponse (309-309)
  • JudgeScores (310-310)
  • MultiJudgeScores (311-311)
src/lib/workflow/workflows/adaptiveWorkflow.ts (3)
src/lib/workflow/types.ts (1)
  • WorkflowConfig (65-92)
src/lib/workflow/config.ts (1)
  • WORKFLOW_CREATION_DATE (36-36)
src/lib/utils/logger.ts (1)
  • logger (358-401)
src/lib/workflow/core/types/judgeTypes.ts (1)
src/lib/workflow/types.ts (5)
  • JudgeConfig (124-151)
  • EnsembleResponse (305-331)
  • JudgeScores (337-359)
  • MultiJudgeScores (364-391)
  • WorkflowError (507-523)
src/lib/workflow/workflows/multiJudgeWorkflow.ts (4)
src/lib/index.ts (4)
  • MULTI_JUDGE_5_WORKFLOW (344-344)
  • WorkflowConfig (304-304)
  • MULTI_JUDGE_3_WORKFLOW (345-345)
  • createMultiJudgeWorkflow (346-346)
src/lib/workflow/index.ts (4)
  • MULTI_JUDGE_5_WORKFLOW (113-113)
  • WorkflowConfig (31-31)
  • MULTI_JUDGE_3_WORKFLOW (112-112)
  • createMultiJudgeWorkflow (111-111)
src/lib/workflow/types.ts (1)
  • WorkflowConfig (65-92)
src/lib/workflow/config.ts (1)
  • WORKFLOW_CREATION_DATE (36-36)
src/lib/workflow/core/workflowRegistry.ts (2)
src/lib/workflow/core/types/registryTypes.ts (6)
  • RegistryEntry (11-16)
  • RegisterOptions (21-24)
  • RegisterResult (29-34)
  • ListOptions (39-44)
  • WorkflowMetadata (49-53)
  • RegistryStats (58-67)
src/lib/workflow/types.ts (1)
  • WorkflowConfig (65-92)
src/lib/workflow/utils/workflowValidation.ts (3)
src/lib/workflow/types.ts (6)
  • WorkflowConfig (65-92)
  • WorkflowValidationResult (466-470)
  • WorkflowValidationError (475-480)
  • WorkflowValidationWarning (485-490)
  • ModelConfig (97-118)
  • JudgeConfig (124-151)
src/lib/workflow/config.ts (4)
  • hasJudge (461-463)
  • getAllJudges (470-478)
  • MIN_SCORE (25-25)
  • MAX_SCORE (26-26)
src/lib/workflow/utils/types/validationTypes.ts (1)
  • ValidationIssues (14-17)
src/lib/workflow/core/ensembleExecutor.ts (1)
src/lib/workflow/core/types/index.ts (2)
  • ExecuteEnsembleOptions (9-9)
  • EnsembleExecutionResult (8-8)
src/lib/types/streamTypes.ts (1)
src/lib/types/sdkTypes.ts (1)
  • AudioChunk (27-27)
src/cli/index.ts (2)
src/cli/parser.ts (1)
  • initializeCliParser (12-198)
src/cli/commands/workflow.ts (1)
  • WorkflowCommandFactory (51-362)
src/lib/workflow/config.ts (3)
src/lib/index.ts (6)
  • AIProviderName (38-38)
  • DEFAULT_SCORE_SCALE (369-369)
  • WorkflowConfig (304-304)
  • ModelConfig (306-306)
  • ModelGroup (308-308)
  • JudgeConfig (307-307)
src/lib/workflow/index.ts (13)
  • WorkflowConfigSchema (59-59)
  • ConditioningConfig (16-16)
  • DEFAULT_EXECUTION_CONFIG (54-54)
  • ExecutionConfig (19-19)
  • DEFAULT_SCORE_SCALE (165-165)
  • usesModelGroups (58-58)
  • WorkflowConfig (31-31)
  • getAllModels (56-56)
  • ModelConfig (24-24)
  • getModelGroups (57-57)
  • ModelGroup (25-25)
  • DEFAULT_JUDGE_CONFIG (55-55)
  • JudgeConfig (21-21)
src/lib/workflow/types.ts (6)
  • ConditioningConfig (157-188)
  • ExecutionConfig (193-219)
  • WorkflowConfig (65-92)
  • ModelConfig (97-118)
  • ModelGroup (40-60)
  • JudgeConfig (124-151)
src/lib/workflow/index.ts (1)
src/lib/index.ts (1)
  • WORKFLOW_ENGINE_VERSION (368-368)
🪛 GitHub Check: 🛡️ Code Quality & Security Gate
src/cli/commands/workflow.ts

[warning] 55-55:
Static method 'createWorkflowCommand' has too many lines (307). Maximum allowed is 300

🪛 GitHub Check: test (20)
src/cli/commands/workflow.ts

[warning] 55-55:
Static method 'createWorkflowCommand' has too many lines (307). Maximum allowed is 300

🪛 LanguageTool
docs/WORKFLOW-ENGINE-HLD.md

[style] ~4-~4: Some style guides suggest that commas should set off the year in a month-day-year date.
Context: ...Version**: 1.0 Date: November 28, 2025 Status: Design Phase Author...

(MISSING_COMMA_AFTER_YEAR)


[grammar] ~12-~12: Ensure spelling is correct
Context: ...les and judge-based scoring. It extends Neurolink's existing provider abstraction to suppor...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)


[grammar] ~408-~408: Ensure spelling is correct
Context: ...? Integration Points ### With Existing Neurolink Infrastructure #### 1. AIProviderFacto...

(QB_NEW_EN_ORTHOGRAPHY_ERROR_IDS_1)

docs/WORKFLOW-ENGINE-LLD.md

[style] ~4-~4: Some style guides suggest that commas should set off the year in a month-day-year date.
Context: ...Version**: 1.0 Date: November 28, 2025 Status: Design Phase Author...

(MISSING_COMMA_AFTER_YEAR)

Comment thread docs/index.md Outdated
- **LiteLLM Integration** – Access 100+ AI models from all major providers through unified interface. → [Setup Guide](LITELLM-INTEGRATION.md)
- **SageMaker Integration** – Deploy and use custom trained models on AWS infrastructure. → [Setup Guide](SAGEMAKER-INTEGRATION.md)
- **SageMaker Integration** – Deploy and use custom-trained models on AWS infrastructure. → [Setup Guide](SAGEMAKER-INTEGRATION.md)
- **OpenRouter Integration** – Access 300+ models from OpenAI, Anthropic, Google, Meta, and more through a single unified API. → [Setup Guide](getting-started/providers/openrouter.md)

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🌐 Web query:

OpenRouter API current number of models available 2025

💡 Result:

As of December 30, 2025, OpenRouter’s public documentation/catalog lists “400+” models available via its API. [1][2]

Sources:

  • OpenRouter documentation — Models overview (shows “Explore and browse 400+ models”). [1]
  • Independent review referencing OpenRouter’s public catalog (reports catalog size ~500+ in 2025). [2]

Update OpenRouter model count from outdated figure.

Line 33 claims "Access 300+ models" but OpenRouter's current documentation lists "400+" models available as of December 2025. Update both line 33 and line 70 to reflect the current count (400+) to avoid outdated marketing claims.

🤖 Prompt for AI Agents
In docs/index.md around lines 33 and 70, update the OpenRouter model count from
"300+ models" to "400+ models" to reflect the current December 2025 figure; edit
both lines so the text reads "Access 400+ models from OpenAI, Anthropic, Google,
Meta, and more through a single unified API. → [Setup
Guide](getting-started/providers/openrouter.md)" (or the equivalent phrase used
at line 70) ensuring the same updated count appears in both places for
consistency.

Comment thread docs/index.md Outdated
| **OpenAI Compatible** | Any OpenAI-compatible endpoint | Varies | ✅ Full | ✅ Production | [Setup Guide](getting-started/provider-setup.md#openai-compatible) |

**[📖 Provider Comparison Guide](reference/provider-comparison.md)** - Detailed feature matrix and selection criteria
**[🔬 Provider Feature Compatibility](reference/provider-feature-compatibility.md)** - Test-based compatibility reference for all 19 features across 11 providers

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

🧩 Analysis chain

🏁 Script executed:

# First, check if docs/index.md exists and read the relevant lines
if [ -f "docs/index.md" ]; then
  echo "=== docs/index.md (lines 55-85) ==="
  sed -n '55,85p' docs/index.md
else
  echo "docs/index.md not found"
fi

Repository: juspay/neurolink

Length of output: 3351


🏁 Script executed:

# Check if the provider-feature-compatibility.md file exists
if [ -f "docs/reference/provider-feature-compatibility.md" ]; then
  echo "=== docs/reference/provider-feature-compatibility.md (first 100 lines) ==="
  head -100 docs/reference/provider-feature-compatibility.md
else
  echo "docs/reference/provider-feature-compatibility.md not found"
fi

Repository: juspay/neurolink

Length of output: 4861


Correct provider count discrepancy in feature compatibility reference.

Line 78 references "11 providers" tested, but the main provider table lists 13 providers. The discrepancy is valid—only 11 of the 13 are actually included in the test matrix. However, the untested providers are OpenRouter and OpenAI Compatible, not LiteLLM (which is tested). Update the reference or clarify which providers are intentionally excluded from the compatibility testing.

🤖 Prompt for AI Agents
In docs/index.md around line 78, the provider count and exclusion list are
inconsistent: the text says "11 providers" but the main table has 13; update the
sentence to explicitly state which two providers are excluded from the
compatibility tests (OpenRouter and OpenAI Compatible) or reword to "13
providers (11 included in compatibility tests; OpenRouter and OpenAI Compatible
excluded)"; ensure the phrasing clearly identifies OpenRouter and OpenAI
Compatible as the intentionally untested providers.

Comment on lines +1773 to +1784
### Input Validation

````typescript
// Sanitize all user inputs before passing to models
function sanitizeInput(input: string): string {
// Remove potential prompt injection attempts
return input
.replace(/```[^`]*```/g, "") // Remove code blocks
.replace(/<script[^>]*>.*?<\/script>/gi, "") // Remove scripts
.trim();
}
````

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Input sanitization example is overly simplistic and may have issues.

The sanitizeInput function in the security section removes all code blocks, which could break legitimate technical content. Also, the regex for removing code blocks is incomplete (backticks can appear in other contexts). Consider documenting this as a placeholder that needs production-hardening.

🔎 Suggested improvement
 // Sanitize all user inputs before passing to models
+// NOTE: This is a simplified example. Production implementations should use
+// established sanitization libraries and consider the specific use case.
 function sanitizeInput(input: string): string {
-  // Remove potential prompt injection attempts
-  return input
-    .replace(/```[^`]*```/g, "") // Remove code blocks
-    .replace(/<script[^>]*>.*?<\/script>/gi, "") // Remove scripts
-    .trim();
+  // Consider using established sanitization libraries
+  // This example is for documentation purposes only
+  return input.trim();
 }
🤖 Prompt for AI Agents
In docs/WORKFLOW-ENGINE-LLD.md around lines 1773-1784, the provided
sanitizeInput implementation is overly simplistic and unsafe for production (it
bluntly strips code blocks with an incomplete regex and may break legitimate
content); mark this function as a documentation-only placeholder, revert removal
of code blocks, change the example to simply return input.trim() with a clear
comment stating "placeholder — use a vetted sanitization/escaping library in
production", and add a short note recommending specific libraries or frameworks
(e.g., DOMPurify/OWASP Java HTML Sanitizer or server-side validators) and to add
tests/validation rules tailored to expected input types.

Comment thread src/lib/neurolink.ts
Comment on lines +2003 to +2055
// Basic usage info
usage: workflowResult.usage
? {
input: workflowResult.usage.totalInputTokens,
output: workflowResult.usage.totalOutputTokens,
total: workflowResult.usage.totalTokens,
}
: undefined,

// Performance
responseTime: workflowResult.totalTime,

// Workflow-specific data
workflow: {
originalResponse:
workflowResult.originalContent || workflowResult.content, // Original unmodified best response
processedResponse: workflowResult.content, // After conditioning (with metadata)
ensembleResponses: workflowResult.ensembleResponses.map((r) => ({
provider: r.provider,
model: r.model,
content: r.content,
responseTime: r.responseTime,
status: r.status,
error: r.error,
})),
judgeScores: workflowResult.judgeScores
? {
scores: workflowResult.judgeScores.scores,
reasoning: workflowResult.reasoning,
selectedModel: `${workflowResult.selectedResponse?.provider}-${workflowResult.selectedResponse?.model}`,
}
: undefined,
selectedModel: `${workflowResult.selectedResponse?.provider}-${workflowResult.selectedResponse?.model}`,
metrics: {
totalTime: workflowResult.totalTime,
ensembleTime: workflowResult.ensembleTime,
judgeTime: workflowResult.judgeTime,
conditioningTime: workflowResult.conditioningTime,
},
workflowId: workflowResult.workflow,
workflowName: workflowResult.workflowName,
},
};

logger.debug("[NeuroLink] Workflow generation complete", {
workflowId: workflowResult.workflow,
selectedModel: generateResult.workflow?.selectedModel,
score: workflowResult.score,
totalTime: workflowResult.totalTime,
});

return generateResult;
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟠 Major

Streaming with workflows: audio-only inputs can crash and metadata may misrepresent the selected model.

Two issues in the streaming workflow path:

  1. streamWithWorkflow assumes options.input.text is a non-empty string (logging and passing it into runWorkflowWithStreaming), but validateStreamInput allows audio-only streams. Calling stream({ input: { audio: ... }, workflow: ... }) will pass validation and then hit a substring/string operation on undefined, causing a runtime error.
  2. streamWithWorkflow initializes StreamResult.provider/model from workflowConfig.models[0] and never updates them from finalResult.selectedResponse. For workflows that select a different model at judge time or only define modelGroups, this metadata will be inaccurate or undefined, while workflow.selectedModel already falls back to "unknown" when necessary.

Recommended adjustments:

  • In the workflow-branch of stream, enforce text-based input (e.g., throw a typed error via ErrorFactory if options.input.text is missing/empty when workflow/workflowConfig is set) to avoid audio-only misuse until workflows explicitly support audio.
  • After finalResult is available, update streamResult.provider and streamResult.model from result.selectedResponse (with "unknown" fallbacks) so top-level metadata matches the actually selected model.

Also applies to: 2057-2140, 3003-3015

🤖 Prompt for AI Agents
In src/lib/neurolink.ts around lines 2003-2055 (also apply same fix to 2057-2140
and 3003-3015): the streaming workflow path assumes options.input.text exists
and initializes StreamResult.provider/model from workflowConfig.models[0], which
breaks for audio-only inputs and when the judge selects a different model. Fix
by validating that when a workflow/workflowConfig is provided the input contains
non-empty text (throw a typed error via ErrorFactory if options.input.text is
missing/empty) to block audio-only usage until workflows support audio, and
after the finalResult (finalResult.selectedResponse) is available update
streamResult.provider and streamResult.model from finalResult.selectedResponse
(falling back to "unknown" if missing) so top-level metadata matches the actual
selected model.

Comment on lines +139 to +156
it("should register all predefined workflows", () => {
registerWorkflow(CONSENSUS_3_WORKFLOW);
registerWorkflow(CONSENSUS_3_FAST_WORKFLOW);
registerWorkflow(FAST_FALLBACK_WORKFLOW);
registerWorkflow(AGGRESSIVE_FALLBACK_WORKFLOW);
registerWorkflow(MULTI_JUDGE_5_WORKFLOW);
registerWorkflow(MULTI_JUDGE_3_WORKFLOW);
registerWorkflow(QUALITY_MAX_WORKFLOW);
registerWorkflow(SPEED_FIRST_WORKFLOW);
registerWorkflow(BALANCED_ADAPTIVE_WORKFLOW);

const list = listWorkflows();
// Some workflows may fail validation and not be registered
expect(list.length).toBeGreaterThan(0);
const ids = list.map((w) => w.id);
expect(ids).toContain("consensus-3");
expect(ids).toContain("multi-judge-5");
});

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Weak assertion reduces test reliability.

The vague expectation expect(list.length).toBeGreaterThan(0) combined with the comment "Some workflows may fail validation and not be registered" makes this test non-deterministic and masks potential registration failures.

🔎 Suggested improvement

Be explicit about expected registration outcomes:

-    const list = listWorkflows();
-    // Some workflows may fail validation and not be registered
-    expect(list.length).toBeGreaterThan(0);
+    const list = listWorkflows();
+    // All predefined workflows should register successfully
+    expect(list.length).toBe(9);
     const ids = list.map((w) => w.id);
     expect(ids).toContain("consensus-3");
     expect(ids).toContain("multi-judge-5");
+    // Add explicit checks for all 9 workflow IDs

If some workflows are expected to fail validation, document which ones and why, or fix the workflows to pass validation.

🤖 Prompt for AI Agents
In src/lib/workflow/__tests__/workflow.test.ts around lines 139 to 156, the test
uses a weak non-deterministic assertion expect(list.length).toBeGreaterThan(0)
which can mask registration failures; update the test to assert explicit,
deterministic outcomes by either (a) listing which workflows are expected to
successfully register and asserting list.length equals that exact number and
that each expected id is present, or (b) if some workflows are known to fail
validation, add comments documenting which ones and replace the loose length
check with assertions that only the known-valid workflow ids are present (and
assert the length equals the number of those known-valid ids) so the test
reliably fails when a workflow unexpectedly stops registering.

Comment on lines +348 to +378
export function importRegistry(
json: string,
options: RegisterOptions = {},
): RegisterResult[] {
try {
const workflows = JSON.parse(json) as WorkflowConfig[];
const results: RegisterResult[] = [];

workflows.forEach((config) => {
const result = registerWorkflow(config, options);
results.push(result);
});

logger.info(`[${functionTag}] Registry import completed`, {
total: workflows.length,
successful: results.filter((r) => r.success).length,
});

return results;
} catch (error) {
logger.error(`[${functionTag}] Registry import failed`, {
error: (error as Error).message,
});
return [
{
success: false,
workflowId: "import-error",
error: `Import failed: ${(error as Error).message}`,
},
];
}

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Unsafe JSON parsing in importRegistry may accept malformed data.

JSON.parse output is cast directly to WorkflowConfig[] without validation. Malformed JSON could pass through if validateBeforeRegister is disabled. Consider validating the array structure before iteration.

🔎 Proposed fix
 export function importRegistry(
   json: string,
   options: RegisterOptions = {},
 ): RegisterResult[] {
   try {
-    const workflows = JSON.parse(json) as WorkflowConfig[];
+    const parsed = JSON.parse(json);
+    if (!Array.isArray(parsed)) {
+      throw new Error("Expected an array of workflow configurations");
+    }
+    const workflows = parsed as WorkflowConfig[];
     const results: RegisterResult[] = [];
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
export function importRegistry(
json: string,
options: RegisterOptions = {},
): RegisterResult[] {
try {
const workflows = JSON.parse(json) as WorkflowConfig[];
const results: RegisterResult[] = [];
workflows.forEach((config) => {
const result = registerWorkflow(config, options);
results.push(result);
});
logger.info(`[${functionTag}] Registry import completed`, {
total: workflows.length,
successful: results.filter((r) => r.success).length,
});
return results;
} catch (error) {
logger.error(`[${functionTag}] Registry import failed`, {
error: (error as Error).message,
});
return [
{
success: false,
workflowId: "import-error",
error: `Import failed: ${(error as Error).message}`,
},
];
}
export function importRegistry(
json: string,
options: RegisterOptions = {},
): RegisterResult[] {
try {
const parsed = JSON.parse(json);
if (!Array.isArray(parsed)) {
throw ErrorFactory.createError("INVALID_REGISTRY_FORMAT", "Expected an array of workflow configurations");
}
const workflows = parsed as WorkflowConfig[];
const results: RegisterResult[] = [];
workflows.forEach((config) => {
const result = registerWorkflow(config, options);
results.push(result);
});
logger.info(`[${functionTag}] Registry import completed`, {
total: workflows.length,
successful: results.filter((r) => r.success).length,
});
return results;
} catch (error) {
logger.error(`[${functionTag}] Registry import failed`, {
error: (error as Error).message,
});
return [
{
success: false,
workflowId: "import-error",
error: `Import failed: ${(error as Error).message}`,
},
];
}
🤖 Prompt for AI Agents
In src/lib/workflow/core/workflowRegistry.ts around lines 348 to 378, the code
directly casts JSON.parse(json) to WorkflowConfig[] and iterates, which can
accept malformed data; change parsing to validate the parsed value is an array
and that each item is an object with required WorkflowConfig fields (e.g.,
id/name/steps or whatever the WorkflowConfig type requires) before calling
registerWorkflow; if validation fails, log a descriptive error and return a
failed RegisterResult instead of proceeding; implement a small validation helper
(or reuse existing schema/validator) to check types/required properties and skip
or reject invalid entries so malformed JSON or incorrect shapes do not get
registered.

Comment thread WORKFLOW-ENGINE-COMPLETE.md Outdated
Comment on lines +163 to +170
### Unit Tests (`src/workflow/__tests__/workflow.test.ts`)

- ✅ Predefined workflow loading (9 workflows)
- ✅ Workflow registry operations (CRUD)
- ✅ Configuration structure validation
- ✅ Score scale consistency
- ✅ Unique ID enforcement
- ✅ Models vs ModelGroups exclusivity

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

Test file path inconsistency.

The path src/workflow/__tests__/workflow.test.ts should be src/lib/workflow/__tests__/workflow.test.ts based on the actual file structure shown at line 237.

🔎 Proposed fix
-### Unit Tests (`src/workflow/__tests__/workflow.test.ts`)
+### Unit Tests (`src/lib/workflow/__tests__/workflow.test.ts`)
📝 Committable suggestion

‼️ IMPORTANT
Carefully review the code before committing. Ensure that it accurately replaces the highlighted code, contains no missing lines, and has no issues with indentation. Thoroughly test & benchmark the code to ensure it meets the requirements.

Suggested change
### Unit Tests (`src/workflow/__tests__/workflow.test.ts`)
- ✅ Predefined workflow loading (9 workflows)
- ✅ Workflow registry operations (CRUD)
- ✅ Configuration structure validation
- ✅ Score scale consistency
- ✅ Unique ID enforcement
- ✅ Models vs ModelGroups exclusivity
### Unit Tests (`src/lib/workflow/__tests__/workflow.test.ts`)
- ✅ Predefined workflow loading (9 workflows)
- ✅ Workflow registry operations (CRUD)
- ✅ Configuration structure validation
- ✅ Score scale consistency
- ✅ Unique ID enforcement
- ✅ Models vs ModelGroups exclusivity
🤖 Prompt for AI Agents
In WORKFLOW-ENGINE-COMPLETE.md around lines 163 to 170, the unit test file path
is incorrect — it lists src/workflow/__tests__/workflow.test.ts but the actual
file lives at src/lib/workflow/__tests__/workflow.test.ts; update the
documentation to use the correct path (replace src/workflow/... with
src/lib/workflow/...) so the README matches the repository structure everywhere
and verify other references to this test path in the document.

Comment thread WORKFLOW-ENGINE-COMPLETE.md Outdated
Comment on lines +206 to +245
src/workflow/
├── types.ts # Core type definitions
├── config.ts # Zod validation schemas
├── index.ts # Public API exports
├── LAYER-EXAMPLES.ts # Execution pattern examples
├── core/
│ ├── ensembleExecutor.ts # Model execution engine
│ ├── judgeScorer.ts # Judge evaluation
│ ├── responseConditioner.ts # Stub conditioner
│ ├── workflowRegistry.ts # Registry operations
│ ├── workflowRunner.ts # Main orchestrator
│ └── types/ # Core type definitions
│ ├── ensembleTypes.ts
│ ├── judgeTypes.ts
│ ├── conditionerTypes.ts
│ ├── registryTypes.ts
│ ├── layerTypes.ts
│ └── index.ts
├── utils/
│ ├── workflowValidation.ts # Validation logic
│ ├── workflowMetrics.ts # Metrics calculation
│ └── types/ # Utility type definitions
│ ├── validationTypes.ts
│ ├── metricsTypes.ts
│ └── index.ts
├── workflows/
│ ├── consensusWorkflow.ts # Consensus workflows (2)
│ ├── fallbackWorkflow.ts # Fallback workflows (2)
│ ├── multiJudgeWorkflow.ts # Multi-judge workflows (2)
│ └── adaptiveWorkflow.ts # Adaptive workflows (3)
└── __tests__/
└── workflow.test.ts # Unit tests (244 lines)

examples/
└── workflow-integration-example.ts # Integration example (130 lines)

lib/
├── index.ts # Main SDK exports (includes workflow)
└── neurolink.ts # NeuroLink class (with workflow methods)
```

Copy link
Copy Markdown

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

⚠️ Potential issue | 🟡 Minor

File structure paths missing lib/ prefix.

The file tree shows src/workflow/ but the actual implementation is under src/lib/workflow/. This could confuse developers navigating the codebase.

🔎 Proposed fix
-src/workflow/
+src/lib/workflow/
 ├── types.ts                    # Core type definitions
 ...
🤖 Prompt for AI Agents
In WORKFLOW-ENGINE-COMPLETE.md around lines 206 to 245, the displayed file tree
lists paths starting with src/workflow/ but the actual implementation lives
under src/lib/workflow/; update the tree entries to use the correct lib-prefixed
paths (e.g., src/lib/workflow/, src/lib/workflow/core/, src/lib/workflow/utils/,
src/lib/workflow/workflows/, src/lib/workflow/__tests__, and adjust any example
or lib references accordingly) so the documentation matches the repository
layout.

@murdore
murdore force-pushed the feat-workflow-engine-implementation branch from af99383 to 677dcd1 Compare December 30, 2025 20:05
├── lib/
│ ├── workflow/
│ │ ├── index.ts # Public API exports (60 lines)
│ │ ├── types.ts # Type definitions (250 lines)

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Types to be moved to the common types folder.

Comment thread docs/WORKFLOW-ENGINE-HLD.md Outdated
```
workflow/
├── index.ts # Public API exports
├── types.ts # Core workflow types

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Types to be moved to the common types folder.

Comment thread docs/WORKFLOW-ENGINE-HLD.md Outdated
```
┌────────────────────────────────────────────────────────────┐
│ 1. USER REQUEST │
│ neuro.generateWorkflow({ │

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

You cannot add any new functions. Only generate and stream can be added and extended with required inputs if there is any input requirement.

Comment thread docs/WORKFLOW-ENGINE-HLD.md Outdated
### WorkflowConfig

```typescript
interface WorkflowConfig {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No interfaces, only types can be created.

Comment thread docs/WORKFLOW-ENGINE-HLD.md Outdated
### ModelConfig

```typescript
interface ModelConfig {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

No interfaces, only types can be created.

Comment thread docs/WORKFLOW-ENGINE-HLD.md Outdated
});

// Execute custom workflow
const customResult = await neuro.generateWorkflow({

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

use generate and stream only as exposed commands

Comment thread docs/WORKFLOW-ENGINE-LLD.md Outdated
/**
* Complete workflow configuration
*/
export interface WorkflowConfig {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

only types to be created

console.log("Running 3 models in parallel with judge evaluation...\n");

try {
const result1 = await neurolink.runWorkflow(CONSENSUS_3_WORKFLOW, {

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

stream and generate to be exposed only

@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from 677dcd1 to 117e80a Compare January 2, 2026 11:42
### **CLI Commands** (`src/cli/commands/workflow.ts`)
```bash
# List all available workflows
neurolink workflow --list

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

there are required?

### **CLI Commands** (`src/cli/commands/workflow.ts`)
```bash
# List all available workflows
neurolink workflow --list

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

same for all workflow commands

@@ -0,0 +1,308 @@
# Workflow Engine - Implementation Complete ✅

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

do we need all of these documents? they should either be in correct location in doc or removed. or move to memory bank.

also need to add in readme q1 2026 items and an entry for this new feature we are adding

Comment thread src/lib/workflow/types.ts
@@ -0,0 +1,523 @@
/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move to types folder

@@ -0,0 +1,17 @@
/**

Copy link
Copy Markdown
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

move all to common types fodler

@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch 3 times, most recently from 2d1b39d to d950ed9 Compare January 11, 2026 19:01
@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch 6 times, most recently from 12af40f to d34e6fa Compare February 2, 2026 11:56
…el orchestration

- Add core workflow engine with ensemble executor, judge scorer, and response conditioner
- Implement 9 predefined workflows (consensus, multi-judge, fallback, adaptive)
- Add workflow registry for centralized workflow management
- Integrate 5 workflow methods into NeuroLink SDK class
- Add CLI workflow command with list, info, and execution support
- Implement workflow validation and metrics tracking
- Add comprehensive TypeScript types for all workflow components
- Export all workflow functionality from lib/index.ts
- Remove redundant .d.ts files (auto-generated during build)
- Fix import paths after moving to src/lib/workflow/
- Update memory bank documentation with implementation details
@arx-optimus-17
arx-optimus-17 force-pushed the feat-workflow-engine-implementation branch from d34e6fa to fbb41bb Compare February 8, 2026 20:53
@murdore
murdore merged commit 9257385 into juspay:release Feb 9, 2026
9 checks passed
@github-actions

github-actions Bot commented Feb 9, 2026

Copy link
Copy Markdown
Contributor

🎉 This PR is included in version 9.4.0 🎉

The release is available on:

Your semantic-release bot 📦🚀

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

Projects

None yet

Development

Successfully merging this pull request may close these issues.

3 participants