@juspay/neurolink 7.35.0 → 7.37.0

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
Files changed (63) hide show
  1. package/CHANGELOG.md +12 -0
  2. package/dist/adapters/providerImageAdapter.d.ts +56 -0
  3. package/dist/adapters/providerImageAdapter.js +257 -0
  4. package/dist/cli/commands/config.d.ts +20 -20
  5. package/dist/cli/factories/commandFactory.d.ts +1 -0
  6. package/dist/cli/factories/commandFactory.js +26 -3
  7. package/dist/config/taskClassificationConfig.d.ts +51 -0
  8. package/dist/config/taskClassificationConfig.js +148 -0
  9. package/dist/core/baseProvider.js +99 -45
  10. package/dist/core/types.d.ts +3 -0
  11. package/dist/lib/adapters/providerImageAdapter.d.ts +56 -0
  12. package/dist/lib/adapters/providerImageAdapter.js +257 -0
  13. package/dist/lib/config/taskClassificationConfig.d.ts +51 -0
  14. package/dist/lib/config/taskClassificationConfig.js +148 -0
  15. package/dist/lib/core/baseProvider.js +99 -45
  16. package/dist/lib/core/types.d.ts +3 -0
  17. package/dist/lib/neurolink.d.ts +20 -0
  18. package/dist/lib/neurolink.js +276 -8
  19. package/dist/lib/types/content.d.ts +78 -0
  20. package/dist/lib/types/content.js +5 -0
  21. package/dist/lib/types/conversation.d.ts +19 -0
  22. package/dist/lib/types/generateTypes.d.ts +4 -1
  23. package/dist/lib/types/index.d.ts +2 -0
  24. package/dist/lib/types/index.js +2 -0
  25. package/dist/lib/types/streamTypes.d.ts +6 -3
  26. package/dist/lib/types/taskClassificationTypes.d.ts +52 -0
  27. package/dist/lib/types/taskClassificationTypes.js +5 -0
  28. package/dist/lib/utils/imageProcessor.d.ts +84 -0
  29. package/dist/lib/utils/imageProcessor.js +362 -0
  30. package/dist/lib/utils/messageBuilder.d.ts +8 -1
  31. package/dist/lib/utils/messageBuilder.js +279 -0
  32. package/dist/lib/utils/modelRouter.d.ts +107 -0
  33. package/dist/lib/utils/modelRouter.js +292 -0
  34. package/dist/lib/utils/promptRedaction.d.ts +29 -0
  35. package/dist/lib/utils/promptRedaction.js +62 -0
  36. package/dist/lib/utils/taskClassificationUtils.d.ts +55 -0
  37. package/dist/lib/utils/taskClassificationUtils.js +149 -0
  38. package/dist/lib/utils/taskClassifier.d.ts +23 -0
  39. package/dist/lib/utils/taskClassifier.js +94 -0
  40. package/dist/neurolink.d.ts +20 -0
  41. package/dist/neurolink.js +276 -8
  42. package/dist/types/content.d.ts +78 -0
  43. package/dist/types/content.js +5 -0
  44. package/dist/types/conversation.d.ts +19 -0
  45. package/dist/types/generateTypes.d.ts +4 -1
  46. package/dist/types/index.d.ts +2 -0
  47. package/dist/types/index.js +2 -0
  48. package/dist/types/streamTypes.d.ts +6 -3
  49. package/dist/types/taskClassificationTypes.d.ts +52 -0
  50. package/dist/types/taskClassificationTypes.js +5 -0
  51. package/dist/utils/imageProcessor.d.ts +84 -0
  52. package/dist/utils/imageProcessor.js +362 -0
  53. package/dist/utils/messageBuilder.d.ts +8 -1
  54. package/dist/utils/messageBuilder.js +279 -0
  55. package/dist/utils/modelRouter.d.ts +107 -0
  56. package/dist/utils/modelRouter.js +292 -0
  57. package/dist/utils/promptRedaction.d.ts +29 -0
  58. package/dist/utils/promptRedaction.js +62 -0
  59. package/dist/utils/taskClassificationUtils.d.ts +55 -0
  60. package/dist/utils/taskClassificationUtils.js +149 -0
  61. package/dist/utils/taskClassifier.d.ts +23 -0
  62. package/dist/utils/taskClassifier.js +94 -0
  63. package/package.json +1 -1
@@ -0,0 +1,29 @@
1
+ /**
2
+ * Prompt redaction utilities for safe logging
3
+ * Provides consistent prompt masking across NeuroLink components
4
+ */
5
+ export interface PromptRedactionOptions {
6
+ /** Maximum length of redacted prompt */
7
+ maxLength?: number;
8
+ /** Whether to show word count */
9
+ showWordCount?: boolean;
10
+ /** Mask character to use for redaction */
11
+ maskChar?: string;
12
+ }
13
+ /**
14
+ * Redact a prompt for safe logging
15
+ * Truncates to maxLength and optionally shows word count
16
+ */
17
+ export declare function redactPrompt(prompt: string, options?: PromptRedactionOptions): string;
18
+ /**
19
+ * Create a short safe mask for highly sensitive contexts
20
+ */
21
+ export declare function createSafeMask(prompt: string, _maskLength?: number): string;
22
+ /**
23
+ * Redact for classification context (matches classifier behavior)
24
+ */
25
+ export declare function redactForClassification(prompt: string): string;
26
+ /**
27
+ * Redact for routing context (matches router behavior)
28
+ */
29
+ export declare function redactForRouting(prompt: string): string;
@@ -0,0 +1,62 @@
1
+ /**
2
+ * Prompt redaction utilities for safe logging
3
+ * Provides consistent prompt masking across NeuroLink components
4
+ */
5
+ /**
6
+ * Default redaction options
7
+ */
8
+ const DEFAULT_REDACTION_OPTIONS = {
9
+ maxLength: 100,
10
+ showWordCount: true,
11
+ maskChar: "*",
12
+ };
13
+ /**
14
+ * Redact a prompt for safe logging
15
+ * Truncates to maxLength and optionally shows word count
16
+ */
17
+ export function redactPrompt(prompt, options = {}) {
18
+ const opts = { ...DEFAULT_REDACTION_OPTIONS, ...options };
19
+ if (!prompt || typeof prompt !== 'string') {
20
+ return '[INVALID_PROMPT]';
21
+ }
22
+ const wordCount = prompt.trim().split(/\s+/).length;
23
+ let redacted = prompt.substring(0, opts.maxLength);
24
+ // Add ellipsis if truncated
25
+ if (prompt.length > opts.maxLength) {
26
+ redacted = redacted.substring(0, opts.maxLength - 3) + "...";
27
+ }
28
+ // Optionally append word count
29
+ if (opts.showWordCount) {
30
+ redacted += ` [${wordCount} words]`;
31
+ }
32
+ return redacted;
33
+ }
34
+ /**
35
+ * Create a short safe mask for highly sensitive contexts
36
+ */
37
+ export function createSafeMask(prompt, _maskLength = 20) {
38
+ if (!prompt || typeof prompt !== 'string') {
39
+ return '[INVALID_PROMPT]';
40
+ }
41
+ const wordCount = prompt.trim().split(/\s+/).length;
42
+ const charCount = prompt.length;
43
+ return `[REDACTED: ${charCount} chars, ${wordCount} words]`;
44
+ }
45
+ /**
46
+ * Redact for classification context (matches classifier behavior)
47
+ */
48
+ export function redactForClassification(prompt) {
49
+ return redactPrompt(prompt, {
50
+ maxLength: 100,
51
+ showWordCount: false,
52
+ });
53
+ }
54
+ /**
55
+ * Redact for routing context (matches router behavior)
56
+ */
57
+ export function redactForRouting(prompt) {
58
+ return redactPrompt(prompt, {
59
+ maxLength: 100,
60
+ showWordCount: true,
61
+ });
62
+ }
@@ -0,0 +1,55 @@
1
+ /**
2
+ * Task Classification Utility Functions
3
+ * Helper functions for analyzing prompts and calculating scores
4
+ */
5
+ import type { ClassificationScores } from "../types/taskClassificationTypes.js";
6
+ /**
7
+ * Analyze prompt length and apply scoring bonuses
8
+ */
9
+ export declare function analyzeLengthFactors(prompt: string, reasons: string[]): {
10
+ fastScore: number;
11
+ reasoningScore: number;
12
+ };
13
+ /**
14
+ * Check prompt against fast task patterns
15
+ */
16
+ export declare function checkFastPatterns(normalizedPrompt: string, reasons: string[]): number;
17
+ /**
18
+ * Check prompt against reasoning task patterns
19
+ */
20
+ export declare function checkReasoningPatterns(normalizedPrompt: string, reasons: string[]): number;
21
+ /**
22
+ * Analyze keyword matches in the prompt
23
+ */
24
+ export declare function analyzeKeywords(normalizedPrompt: string, reasons: string[]): {
25
+ fastScore: number;
26
+ reasoningScore: number;
27
+ };
28
+ /**
29
+ * Analyze question complexity
30
+ */
31
+ export declare function analyzeQuestionComplexity(prompt: string, reasons: string[]): number;
32
+ /**
33
+ * Analyze prompt structure and punctuation
34
+ */
35
+ export declare function analyzePromptStructure(prompt: string, reasons: string[]): number;
36
+ /**
37
+ * Analyze domain-specific indicators
38
+ */
39
+ export declare function analyzeDomainIndicators(normalizedPrompt: string, prompt: string, reasons: string[]): {
40
+ fastScore: number;
41
+ reasoningScore: number;
42
+ };
43
+ /**
44
+ * Calculate final confidence score
45
+ */
46
+ export declare function calculateConfidence(fastScore: number, reasoningScore: number): number;
47
+ /**
48
+ * Determine task type based on scores
49
+ */
50
+ export declare function determineTaskType(fastScore: number, reasoningScore: number): "fast" | "reasoning";
51
+ /**
52
+ * Comprehensive prompt analysis
53
+ * Runs all analysis functions and returns combined scores
54
+ */
55
+ export declare function analyzePrompt(prompt: string): ClassificationScores;
@@ -0,0 +1,149 @@
1
+ /**
2
+ * Task Classification Utility Functions
3
+ * Helper functions for analyzing prompts and calculating scores
4
+ */
5
+ import { FAST_PATTERNS, REASONING_PATTERNS, FAST_KEYWORDS, REASONING_KEYWORDS, SCORING_WEIGHTS, CLASSIFICATION_THRESHOLDS, DOMAIN_PATTERNS, } from "../config/taskClassificationConfig.js";
6
+ /**
7
+ * Analyze prompt length and apply scoring bonuses
8
+ */
9
+ export function analyzeLengthFactors(prompt, reasons) {
10
+ let fastScore = 0;
11
+ let reasoningScore = 0;
12
+ if (prompt.length < CLASSIFICATION_THRESHOLDS.SHORT_PROMPT_LENGTH) {
13
+ fastScore += SCORING_WEIGHTS.SHORT_PROMPT_BONUS;
14
+ reasons.push("short prompt");
15
+ }
16
+ else if (prompt.length > CLASSIFICATION_THRESHOLDS.LONG_PROMPT_LENGTH) {
17
+ reasoningScore += SCORING_WEIGHTS.LONG_PROMPT_BONUS;
18
+ reasons.push("detailed prompt");
19
+ }
20
+ return { fastScore, reasoningScore };
21
+ }
22
+ /**
23
+ * Check prompt against fast task patterns
24
+ */
25
+ export function checkFastPatterns(normalizedPrompt, reasons) {
26
+ for (const pattern of FAST_PATTERNS) {
27
+ if (pattern.test(normalizedPrompt)) {
28
+ reasons.push("fast pattern match");
29
+ return SCORING_WEIGHTS.PATTERN_MATCH_SCORE;
30
+ }
31
+ }
32
+ return 0;
33
+ }
34
+ /**
35
+ * Check prompt against reasoning task patterns
36
+ */
37
+ export function checkReasoningPatterns(normalizedPrompt, reasons) {
38
+ for (const pattern of REASONING_PATTERNS) {
39
+ if (pattern.test(normalizedPrompt)) {
40
+ reasons.push("reasoning pattern match");
41
+ return SCORING_WEIGHTS.PATTERN_MATCH_SCORE;
42
+ }
43
+ }
44
+ return 0;
45
+ }
46
+ /**
47
+ * Analyze keyword matches in the prompt
48
+ */
49
+ export function analyzeKeywords(normalizedPrompt, reasons) {
50
+ const fastKeywordMatches = FAST_KEYWORDS.filter((keyword) => normalizedPrompt.includes(keyword)).length;
51
+ const reasoningKeywordMatches = REASONING_KEYWORDS.filter((keyword) => normalizedPrompt.includes(keyword)).length;
52
+ const fastScore = fastKeywordMatches * SCORING_WEIGHTS.KEYWORD_MATCH_SCORE;
53
+ const reasoningScore = reasoningKeywordMatches * SCORING_WEIGHTS.KEYWORD_MATCH_SCORE;
54
+ if (fastKeywordMatches > 0) {
55
+ reasons.push(`${fastKeywordMatches} fast keywords`);
56
+ }
57
+ if (reasoningKeywordMatches > 0) {
58
+ reasons.push(`${reasoningKeywordMatches} reasoning keywords`);
59
+ }
60
+ return { fastScore, reasoningScore };
61
+ }
62
+ /**
63
+ * Analyze question complexity
64
+ */
65
+ export function analyzeQuestionComplexity(prompt, reasons) {
66
+ const questionMarks = (prompt.match(/\?/g) || []).length;
67
+ if (questionMarks > 1) {
68
+ reasons.push("multiple questions");
69
+ return SCORING_WEIGHTS.MULTIPLE_QUESTIONS_BONUS;
70
+ }
71
+ return 0;
72
+ }
73
+ /**
74
+ * Analyze prompt structure and punctuation
75
+ */
76
+ export function analyzePromptStructure(prompt, reasons) {
77
+ const sentences = prompt.split(/[.!?]+/).filter((s) => s.trim().length > 0);
78
+ if (sentences.length > 3) {
79
+ reasons.push("multi-sentence structure");
80
+ return SCORING_WEIGHTS.MULTI_SENTENCE_BONUS;
81
+ }
82
+ return 0;
83
+ }
84
+ /**
85
+ * Analyze domain-specific indicators
86
+ */
87
+ export function analyzeDomainIndicators(normalizedPrompt, prompt, reasons) {
88
+ let fastScore = 0;
89
+ let reasoningScore = 0;
90
+ // Check for technical domain
91
+ if (DOMAIN_PATTERNS.TECHNICAL.test(normalizedPrompt)) {
92
+ reasoningScore += SCORING_WEIGHTS.TECHNICAL_DOMAIN_BONUS;
93
+ reasons.push("technical domain");
94
+ }
95
+ // Check for simple definition requests
96
+ if (DOMAIN_PATTERNS.SIMPLE_DEFINITION.test(normalizedPrompt) &&
97
+ prompt.length < CLASSIFICATION_THRESHOLDS.SIMPLE_DEFINITION_LENGTH) {
98
+ fastScore += SCORING_WEIGHTS.SIMPLE_DEFINITION_BONUS;
99
+ reasons.push("simple definition request");
100
+ }
101
+ return { fastScore, reasoningScore };
102
+ }
103
+ /**
104
+ * Calculate final confidence score
105
+ */
106
+ export function calculateConfidence(fastScore, reasoningScore) {
107
+ const totalScore = fastScore + reasoningScore;
108
+ if (totalScore === 0) {
109
+ return CLASSIFICATION_THRESHOLDS.DEFAULT_CONFIDENCE;
110
+ }
111
+ const rawConfidence = Math.max(fastScore, reasoningScore) / totalScore;
112
+ return Math.max(CLASSIFICATION_THRESHOLDS.MIN_CONFIDENCE, Math.min(CLASSIFICATION_THRESHOLDS.MAX_CONFIDENCE, rawConfidence));
113
+ }
114
+ /**
115
+ * Determine task type based on scores
116
+ */
117
+ export function determineTaskType(fastScore, reasoningScore) {
118
+ return fastScore >= reasoningScore ? "fast" : "reasoning";
119
+ }
120
+ /**
121
+ * Comprehensive prompt analysis
122
+ * Runs all analysis functions and returns combined scores
123
+ */
124
+ export function analyzePrompt(prompt) {
125
+ const normalizedPrompt = prompt.toLowerCase().trim();
126
+ const reasons = [];
127
+ let fastScore = 0;
128
+ let reasoningScore = 0;
129
+ // 1. Length analysis
130
+ const lengthScores = analyzeLengthFactors(prompt, reasons);
131
+ fastScore += lengthScores.fastScore;
132
+ reasoningScore += lengthScores.reasoningScore;
133
+ // 2. Pattern matching
134
+ fastScore += checkFastPatterns(normalizedPrompt, reasons);
135
+ reasoningScore += checkReasoningPatterns(normalizedPrompt, reasons);
136
+ // 3. Keyword analysis
137
+ const keywordScores = analyzeKeywords(normalizedPrompt, reasons);
138
+ fastScore += keywordScores.fastScore;
139
+ reasoningScore += keywordScores.reasoningScore;
140
+ // 4. Question complexity
141
+ reasoningScore += analyzeQuestionComplexity(prompt, reasons);
142
+ // 5. Structure analysis
143
+ reasoningScore += analyzePromptStructure(prompt, reasons);
144
+ // 6. Domain analysis
145
+ const domainScores = analyzeDomainIndicators(normalizedPrompt, prompt, reasons);
146
+ fastScore += domainScores.fastScore;
147
+ reasoningScore += domainScores.reasoningScore;
148
+ return { fastScore, reasoningScore, reasons };
149
+ }
@@ -0,0 +1,23 @@
1
+ /**
2
+ * Binary Task Classifier for NeuroLink Orchestration
3
+ * Classifies tasks as either 'fast' (quick responses) or 'reasoning' (complex analysis)
4
+ */
5
+ import type { TaskType, TaskClassification, ClassificationStats, ClassificationValidation } from "../types/taskClassificationTypes.js";
6
+ /**
7
+ * Binary Task Classifier
8
+ * Determines if a task requires fast response or deeper reasoning
9
+ */
10
+ export declare class BinaryTaskClassifier {
11
+ /**
12
+ * Classify a prompt as either fast or reasoning task
13
+ */
14
+ static classify(prompt: string): TaskClassification;
15
+ /**
16
+ * Get classification statistics for multiple prompts
17
+ */
18
+ static getClassificationStats(prompts: string[]): ClassificationStats;
19
+ /**
20
+ * Validate classification accuracy (for testing/tuning)
21
+ */
22
+ static validateClassification(prompt: string, expectedType: TaskType): ClassificationValidation;
23
+ }
@@ -0,0 +1,94 @@
1
+ /**
2
+ * Binary Task Classifier for NeuroLink Orchestration
3
+ * Classifies tasks as either 'fast' (quick responses) or 'reasoning' (complex analysis)
4
+ */
5
+ import { logger } from "./logger.js";
6
+ import { CLASSIFICATION_THRESHOLDS } from "../config/taskClassificationConfig.js";
7
+ import { analyzePrompt, calculateConfidence, determineTaskType, } from "./taskClassificationUtils.js";
8
+ import { redactForClassification } from "./promptRedaction.js";
9
+ /**
10
+ * Binary Task Classifier
11
+ * Determines if a task requires fast response or deeper reasoning
12
+ */
13
+ export class BinaryTaskClassifier {
14
+ /**
15
+ * Classify a prompt as either fast or reasoning task
16
+ */
17
+ static classify(prompt) {
18
+ const startTime = Date.now();
19
+ // Analyze the prompt using utility functions
20
+ const scores = analyzePrompt(prompt);
21
+ const { fastScore, reasoningScore, reasons } = scores;
22
+ // Determine final classification
23
+ const totalScore = fastScore + reasoningScore;
24
+ let type;
25
+ let confidence;
26
+ if (totalScore === 0) {
27
+ // Default to fast for ambiguous cases
28
+ type = "fast";
29
+ confidence = CLASSIFICATION_THRESHOLDS.DEFAULT_CONFIDENCE;
30
+ reasons.push("default fallback");
31
+ }
32
+ else {
33
+ type = determineTaskType(fastScore, reasoningScore);
34
+ confidence = calculateConfidence(fastScore, reasoningScore);
35
+ }
36
+ const classification = {
37
+ type,
38
+ confidence,
39
+ reasoning: reasons.join(", "),
40
+ };
41
+ const classificationTime = Date.now() - startTime;
42
+ logger.debug("Task classified", {
43
+ prompt: redactForClassification(prompt),
44
+ classification: type,
45
+ confidence: confidence.toFixed(2),
46
+ fastScore,
47
+ reasoningScore,
48
+ reasons: reasons.join(", "),
49
+ classificationTime: `${classificationTime}ms`,
50
+ });
51
+ return classification;
52
+ }
53
+ /**
54
+ * Get classification statistics for multiple prompts
55
+ */
56
+ static getClassificationStats(prompts) {
57
+ // Guard against empty array to prevent divide-by-zero
58
+ if (prompts.length === 0) {
59
+ const stats = {
60
+ total: 0,
61
+ fast: 0,
62
+ reasoning: 0,
63
+ averageConfidence: 0,
64
+ };
65
+ logger.debug("Classification stats", stats);
66
+ return stats;
67
+ }
68
+ const classifications = prompts.map((prompt) => this.classify(prompt));
69
+ const stats = {
70
+ total: classifications.length,
71
+ fast: classifications.filter((c) => c.type === "fast").length,
72
+ reasoning: classifications.filter((c) => c.type === "reasoning").length,
73
+ averageConfidence: classifications.reduce((sum, c) => sum + c.confidence, 0) /
74
+ classifications.length,
75
+ };
76
+ logger.debug("Classification stats", stats);
77
+ return stats;
78
+ }
79
+ /**
80
+ * Validate classification accuracy (for testing/tuning)
81
+ */
82
+ static validateClassification(prompt, expectedType) {
83
+ const classification = this.classify(prompt);
84
+ const correct = classification.type === expectedType;
85
+ logger.debug("Classification validation", {
86
+ prompt: redactForClassification(prompt),
87
+ expected: expectedType,
88
+ actual: classification.type,
89
+ correct,
90
+ confidence: classification.confidence,
91
+ });
92
+ return { correct, classification };
93
+ }
94
+ }
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "7.35.0",
3
+ "version": "7.37.0",
4
4
  "description": "Universal AI Development Platform with working MCP integration, multi-provider support, and professional CLI. Built-in tools operational, 58+ external MCP servers discoverable. Connect to filesystem, GitHub, database operations, and more. Build, test, and deploy AI applications with 9 major providers: OpenAI, Anthropic, Google AI, AWS Bedrock, Azure, Hugging Face, Ollama, and Mistral AI.",
5
5
  "author": {
6
6
  "name": "Juspay Technologies",