@juspay/neurolink 7.33.2 → 7.33.4
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/CHANGELOG.md +8 -0
- package/dist/cli/commands/config.d.ts +3 -4
- package/dist/cli/commands/config.js +2 -3
- package/dist/constants/index.d.ts +192 -0
- package/dist/constants/index.js +195 -0
- package/dist/constants/performance.d.ts +366 -0
- package/dist/constants/performance.js +389 -0
- package/dist/constants/retry.d.ts +224 -0
- package/dist/constants/retry.js +266 -0
- package/dist/constants/timeouts.d.ts +225 -0
- package/dist/constants/timeouts.js +182 -0
- package/dist/constants/tokens.d.ts +234 -0
- package/dist/constants/tokens.js +314 -0
- package/dist/core/baseProvider.js +26 -1
- package/dist/core/constants.d.ts +12 -3
- package/dist/core/constants.js +22 -6
- package/dist/core/factory.js +19 -0
- package/dist/core/types.d.ts +268 -0
- package/dist/core/types.js +153 -0
- package/dist/factories/providerRegistry.js +2 -0
- package/dist/lib/constants/index.d.ts +192 -0
- package/dist/lib/constants/index.js +195 -0
- package/dist/lib/constants/performance.d.ts +366 -0
- package/dist/lib/constants/performance.js +389 -0
- package/dist/lib/constants/retry.d.ts +224 -0
- package/dist/lib/constants/retry.js +266 -0
- package/dist/lib/constants/timeouts.d.ts +225 -0
- package/dist/lib/constants/timeouts.js +182 -0
- package/dist/lib/constants/tokens.d.ts +234 -0
- package/dist/lib/constants/tokens.js +314 -0
- package/dist/lib/core/baseProvider.js +26 -1
- package/dist/lib/core/constants.d.ts +12 -3
- package/dist/lib/core/constants.js +22 -6
- package/dist/lib/core/factory.js +19 -0
- package/dist/lib/core/types.d.ts +268 -0
- package/dist/lib/core/types.js +153 -0
- package/dist/lib/factories/providerRegistry.js +2 -0
- package/dist/lib/mcp/servers/aiProviders/aiWorkflowTools.js +2 -2
- package/dist/lib/models/modelRegistry.d.ts +1 -1
- package/dist/lib/models/modelRegistry.js +63 -37
- package/dist/lib/neurolink.js +35 -34
- package/dist/lib/providers/amazonBedrock.js +2 -2
- package/dist/lib/providers/anthropic.js +3 -12
- package/dist/lib/providers/anthropicBaseProvider.js +1 -2
- package/dist/lib/providers/azureOpenai.d.ts +1 -1
- package/dist/lib/providers/azureOpenai.js +51 -9
- package/dist/lib/providers/googleAiStudio.js +3 -3
- package/dist/lib/providers/googleVertex.js +2 -2
- package/dist/lib/providers/huggingFace.js +1 -2
- package/dist/lib/providers/litellm.js +1 -2
- package/dist/lib/providers/mistral.js +2 -2
- package/dist/lib/providers/ollama.js +7 -8
- package/dist/lib/providers/openAI.js +2 -2
- package/dist/lib/providers/openaiCompatible.js +5 -2
- package/dist/lib/providers/sagemaker/language-model.d.ts +5 -0
- package/dist/lib/providers/sagemaker/language-model.js +9 -1
- package/dist/lib/utils/providerConfig.d.ts +25 -0
- package/dist/lib/utils/providerConfig.js +24 -3
- package/dist/lib/utils/providerHealth.d.ts +1 -1
- package/dist/lib/utils/providerHealth.js +47 -36
- package/dist/lib/utils/providerSetupMessages.js +7 -6
- package/dist/lib/utils/providerUtils.js +16 -24
- package/dist/lib/utils/tokenLimits.d.ts +2 -2
- package/dist/lib/utils/tokenLimits.js +10 -3
- package/dist/mcp/servers/aiProviders/aiWorkflowTools.js +2 -2
- package/dist/models/modelRegistry.d.ts +1 -1
- package/dist/models/modelRegistry.js +63 -37
- package/dist/neurolink.js +35 -34
- package/dist/providers/amazonBedrock.js +2 -2
- package/dist/providers/anthropic.js +3 -12
- package/dist/providers/anthropicBaseProvider.js +1 -2
- package/dist/providers/azureOpenai.d.ts +1 -1
- package/dist/providers/azureOpenai.js +51 -9
- package/dist/providers/googleAiStudio.js +3 -3
- package/dist/providers/googleVertex.js +2 -2
- package/dist/providers/huggingFace.js +1 -2
- package/dist/providers/litellm.js +1 -2
- package/dist/providers/mistral.js +2 -2
- package/dist/providers/ollama.js +7 -8
- package/dist/providers/openAI.js +2 -2
- package/dist/providers/openaiCompatible.js +5 -2
- package/dist/providers/sagemaker/language-model.d.ts +5 -0
- package/dist/providers/sagemaker/language-model.js +9 -1
- package/dist/utils/providerConfig.d.ts +25 -0
- package/dist/utils/providerConfig.js +24 -3
- package/dist/utils/providerHealth.d.ts +1 -1
- package/dist/utils/providerHealth.js +47 -36
- package/dist/utils/providerSetupMessages.js +7 -6
- package/dist/utils/providerUtils.js +16 -24
- package/dist/utils/tokenLimits.d.ts +2 -2
- package/dist/utils/tokenLimits.js +10 -3
- package/package.json +1 -1
@@ -3,7 +3,6 @@ import { streamText } from "ai";
|
|
3
3
|
import { BaseProvider } from "../core/baseProvider.js";
|
4
4
|
import { logger } from "../utils/logger.js";
|
5
5
|
import { createTimeoutController, TimeoutError } from "../utils/timeout.js";
|
6
|
-
import { DEFAULT_MAX_TOKENS } from "../core/constants.js";
|
7
6
|
import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
|
8
7
|
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
9
8
|
// Constants
|
@@ -163,7 +162,7 @@ export class OpenAICompatibleProvider extends BaseProvider {
|
|
163
162
|
prompt: options.input.text,
|
164
163
|
system: options.systemPrompt,
|
165
164
|
temperature: options.temperature,
|
166
|
-
maxTokens: options.maxTokens
|
165
|
+
maxTokens: options.maxTokens, // No default limit - unlimited unless specified
|
167
166
|
tools: options.tools,
|
168
167
|
toolChoice: "auto",
|
169
168
|
abortSignal: timeoutController?.controller.signal,
|
@@ -207,12 +206,16 @@ export class OpenAICompatibleProvider extends BaseProvider {
|
|
207
206
|
const modelsUrl = new URL("/v1/models", this.config.baseURL).toString();
|
208
207
|
logger.debug(`Fetching available models from: ${modelsUrl}`);
|
209
208
|
const proxyFetch = createProxyFetch();
|
209
|
+
const controller = new AbortController();
|
210
|
+
const t = setTimeout(() => controller.abort(), 5000);
|
210
211
|
const response = await proxyFetch(modelsUrl, {
|
211
212
|
headers: {
|
212
213
|
Authorization: `Bearer ${this.config.apiKey}`,
|
213
214
|
"Content-Type": "application/json",
|
214
215
|
},
|
216
|
+
signal: controller.signal,
|
215
217
|
});
|
218
|
+
clearTimeout(t);
|
216
219
|
if (!response.ok) {
|
217
220
|
logger.warn(`Models endpoint returned ${response.status}: ${response.statusText}`);
|
218
221
|
return this.getFallbackModels();
|
@@ -9,6 +9,11 @@ import type { SageMakerConfig, SageMakerModelConfig } from "./types.js";
|
|
9
9
|
import type { ConnectivityResult } from "../../types/typeAliases.js";
|
10
10
|
/**
|
11
11
|
* SageMaker Language Model implementing LanguageModelV1 interface
|
12
|
+
*
|
13
|
+
* Token Limit Behavior:
|
14
|
+
* - When maxTokens is undefined, SageMaker uses the model's default token limits
|
15
|
+
* - When maxTokens is specified, it sets max_new_tokens parameter explicitly
|
16
|
+
* - This aligns with the unlimited-by-default token policy across all providers
|
12
17
|
*/
|
13
18
|
export declare class SageMakerLanguageModel implements LanguageModelV1 {
|
14
19
|
readonly specificationVersion = "v1";
|
@@ -75,6 +75,11 @@ const DEFAULT_MAX_CONCURRENCY = 10;
|
|
75
75
|
const DEFAULT_MIN_CONCURRENCY = 1;
|
76
76
|
/**
|
77
77
|
* SageMaker Language Model implementing LanguageModelV1 interface
|
78
|
+
*
|
79
|
+
* Token Limit Behavior:
|
80
|
+
* - When maxTokens is undefined, SageMaker uses the model's default token limits
|
81
|
+
* - When maxTokens is specified, it sets max_new_tokens parameter explicitly
|
82
|
+
* - This aligns with the unlimited-by-default token policy across all providers
|
78
83
|
*/
|
79
84
|
export class SageMakerLanguageModel {
|
80
85
|
specificationVersion = "v1";
|
@@ -345,7 +350,10 @@ export class SageMakerLanguageModel {
|
|
345
350
|
const request = {
|
346
351
|
inputs: promptText,
|
347
352
|
parameters: {
|
348
|
-
max_new_tokens
|
353
|
+
// Only include max_new_tokens if explicitly specified; let SageMaker use model defaults otherwise
|
354
|
+
...(options.maxTokens !== undefined
|
355
|
+
? { max_new_tokens: options.maxTokens }
|
356
|
+
: {}),
|
349
357
|
temperature: options.temperature || 0.7,
|
350
358
|
top_p: options.topP || 0.9,
|
351
359
|
stop: options.stopSequences || [],
|
@@ -15,6 +15,31 @@ export interface ProviderConfigOptions {
|
|
15
15
|
instructions: string[];
|
16
16
|
fallbackEnvVars?: string[];
|
17
17
|
}
|
18
|
+
/**
|
19
|
+
* API key format validation patterns (extracted from advanced validation system)
|
20
|
+
* Exported for use across the codebase to replace scattered regex patterns
|
21
|
+
*/
|
22
|
+
export declare const API_KEY_FORMATS: Record<string, RegExp>;
|
23
|
+
/**
|
24
|
+
* API key length constants to replace scattered magic numbers
|
25
|
+
*/
|
26
|
+
export declare const API_KEY_LENGTHS: {
|
27
|
+
readonly OPENAI_MIN: 48;
|
28
|
+
readonly ANTHROPIC_MIN: 95;
|
29
|
+
readonly HUGGINGFACE_EXACT: 37;
|
30
|
+
readonly AZURE_MIN: 32;
|
31
|
+
readonly MISTRAL_EXACT: 32;
|
32
|
+
readonly AWS_ACCESS_KEY: 20;
|
33
|
+
readonly GOOGLE_AI_EXACT: 39;
|
34
|
+
};
|
35
|
+
/**
|
36
|
+
* Project ID format validation (for Google Cloud)
|
37
|
+
*/
|
38
|
+
export declare const PROJECT_ID_FORMAT: {
|
39
|
+
readonly MIN_LENGTH: 6;
|
40
|
+
readonly MAX_LENGTH: 30;
|
41
|
+
readonly PATTERN: RegExp;
|
42
|
+
};
|
18
43
|
/**
|
19
44
|
* Enhanced validation result with format checking
|
20
45
|
*/
|
@@ -6,16 +6,37 @@
|
|
6
6
|
*/
|
7
7
|
/**
|
8
8
|
* API key format validation patterns (extracted from advanced validation system)
|
9
|
+
* Exported for use across the codebase to replace scattered regex patterns
|
9
10
|
*/
|
10
|
-
const API_KEY_FORMATS = {
|
11
|
+
export const API_KEY_FORMATS = {
|
11
12
|
openai: /^sk-[A-Za-z0-9]{48,}$/,
|
12
13
|
anthropic: /^sk-ant-[A-Za-z0-9\-_]{95,}$/,
|
13
14
|
"google-ai": /^AIza[A-Za-z0-9\-_]{35}$/,
|
14
15
|
huggingface: /^hf_[A-Za-z0-9]{37}$/,
|
15
16
|
mistral: /^[A-Za-z0-9]{32}$/,
|
16
|
-
azure: /^[A-Za-z0-9]{32
|
17
|
+
azure: /^[A-Za-z0-9]{32}$/,
|
17
18
|
aws: /^[A-Z0-9]{20}$/, // Access Key ID format
|
18
|
-
|
19
|
+
bedrock: /^[A-Z0-9]{20}$/, // AWS access key ID: 20 uppercase alphanumerics
|
20
|
+
};
|
21
|
+
/**
|
22
|
+
* API key length constants to replace scattered magic numbers
|
23
|
+
*/
|
24
|
+
export const API_KEY_LENGTHS = {
|
25
|
+
OPENAI_MIN: 48, // OpenAI API keys minimum length
|
26
|
+
ANTHROPIC_MIN: 95, // Anthropic API keys minimum length
|
27
|
+
HUGGINGFACE_EXACT: 37, // HuggingFace tokens exact length
|
28
|
+
AZURE_MIN: 32, // Azure OpenAI API keys minimum length
|
29
|
+
MISTRAL_EXACT: 32, // Mistral API keys exact length
|
30
|
+
AWS_ACCESS_KEY: 20, // AWS access key ID exact length
|
31
|
+
GOOGLE_AI_EXACT: 39, // Google AI Studio keys exact length (with AIza prefix)
|
32
|
+
};
|
33
|
+
/**
|
34
|
+
* Project ID format validation (for Google Cloud)
|
35
|
+
*/
|
36
|
+
export const PROJECT_ID_FORMAT = {
|
37
|
+
MIN_LENGTH: 6, // Minimum project ID length
|
38
|
+
MAX_LENGTH: 30, // Maximum project ID length
|
39
|
+
PATTERN: /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/, // Google Cloud project ID format
|
19
40
|
};
|
20
41
|
/**
|
21
42
|
* Validates API key format for a specific provider
|
@@ -2,7 +2,7 @@
|
|
2
2
|
* Provider Health Checking System
|
3
3
|
* Prevents 500 errors by validating provider availability and configuration
|
4
4
|
*/
|
5
|
-
import { AIProviderName } from "../types
|
5
|
+
import { AIProviderName } from "../core/types.js";
|
6
6
|
export interface ProviderHealthStatus {
|
7
7
|
provider: AIProviderName;
|
8
8
|
isHealthy: boolean;
|
@@ -3,7 +3,8 @@
|
|
3
3
|
* Prevents 500 errors by validating provider availability and configuration
|
4
4
|
*/
|
5
5
|
import { logger } from "./logger.js";
|
6
|
-
import { AIProviderName } from "../types
|
6
|
+
import { AIProviderName, OpenAIModels, GoogleAIModels, AnthropicModels, BedrockModels, } from "../core/types.js";
|
7
|
+
import { API_KEY_LENGTHS, PROJECT_ID_FORMAT } from "./providerConfig.js";
|
7
8
|
import { basename } from "path";
|
8
9
|
import { createProxyFetch } from "../proxy/proxyFetch.js";
|
9
10
|
export class ProviderHealthChecker {
|
@@ -402,17 +403,19 @@ export class ProviderHealthChecker {
|
|
402
403
|
static validateApiKeyFormat(providerName, apiKey) {
|
403
404
|
switch (providerName) {
|
404
405
|
case AIProviderName.ANTHROPIC:
|
405
|
-
return apiKey.startsWith("sk-ant-") &&
|
406
|
+
return (apiKey.startsWith("sk-ant-") &&
|
407
|
+
apiKey.length >= API_KEY_LENGTHS.ANTHROPIC_MIN);
|
406
408
|
case AIProviderName.OPENAI:
|
407
|
-
return apiKey.startsWith("sk-") &&
|
409
|
+
return (apiKey.startsWith("sk-") &&
|
410
|
+
apiKey.length >= API_KEY_LENGTHS.OPENAI_MIN);
|
408
411
|
case AIProviderName.GOOGLE_AI:
|
409
|
-
return apiKey.length
|
412
|
+
return apiKey.length >= API_KEY_LENGTHS.GOOGLE_AI_EXACT; // Basic length check
|
410
413
|
case AIProviderName.VERTEX:
|
411
414
|
return apiKey.endsWith(".json") || apiKey.includes("type"); // JSON key format
|
412
415
|
case AIProviderName.BEDROCK:
|
413
|
-
return apiKey.length >=
|
416
|
+
return apiKey.length >= API_KEY_LENGTHS.AWS_ACCESS_KEY; // AWS access key length
|
414
417
|
case AIProviderName.AZURE:
|
415
|
-
return apiKey.length >=
|
418
|
+
return apiKey.length >= API_KEY_LENGTHS.AZURE_MIN; // Azure OpenAI API key length
|
416
419
|
case AIProviderName.OLLAMA:
|
417
420
|
return true; // Ollama usually doesn't require specific format
|
418
421
|
default:
|
@@ -604,14 +607,14 @@ export class ProviderHealthChecker {
|
|
604
607
|
static checkBedrockModels(healthStatus) {
|
605
608
|
const bedrockModel = process.env.BEDROCK_MODEL || process.env.BEDROCK_MODEL_ID;
|
606
609
|
const supportedModels = [
|
607
|
-
|
608
|
-
|
609
|
-
|
610
|
+
BedrockModels.CLAUDE_3_SONNET,
|
611
|
+
BedrockModels.CLAUDE_3_HAIKU,
|
612
|
+
BedrockModels.CLAUDE_3_5_SONNET,
|
610
613
|
"anthropic.claude-v2:1",
|
611
614
|
"amazon.titan-text-express-v1",
|
612
615
|
];
|
613
616
|
if (!bedrockModel) {
|
614
|
-
healthStatus.recommendations.push(
|
617
|
+
healthStatus.recommendations.push(`Set BEDROCK_MODEL or BEDROCK_MODEL_ID for faster startup (e.g., ${BedrockModels.CLAUDE_3_SONNET})`);
|
615
618
|
}
|
616
619
|
else if (!supportedModels.includes(bedrockModel)) {
|
617
620
|
healthStatus.recommendations.push(`Consider using a popular Bedrock model: ${supportedModels.slice(0, 3).join(", ")}`);
|
@@ -636,9 +639,13 @@ export class ProviderHealthChecker {
|
|
636
639
|
healthStatus.configurationIssues.push("Invalid AZURE_OPENAI_ENDPOINT format");
|
637
640
|
healthStatus.recommendations.push("Set AZURE_OPENAI_ENDPOINT to a valid URL (e.g., https://your-resource.openai.azure.com/)");
|
638
641
|
}
|
639
|
-
|
640
|
-
|
641
|
-
|
642
|
+
// Check for deployment name using the SAME logic as the Azure provider
|
643
|
+
const deploymentName = process.env.AZURE_OPENAI_MODEL ||
|
644
|
+
process.env.AZURE_OPENAI_DEPLOYMENT ||
|
645
|
+
process.env.AZURE_OPENAI_DEPLOYMENT_ID;
|
646
|
+
if (!deploymentName) {
|
647
|
+
healthStatus.configurationIssues.push("No Azure deployment specified");
|
648
|
+
healthStatus.recommendations.push("Set one of: AZURE_OPENAI_MODEL, AZURE_OPENAI_DEPLOYMENT, or AZURE_OPENAI_DEPLOYMENT_ID");
|
642
649
|
}
|
643
650
|
}
|
644
651
|
/**
|
@@ -658,39 +665,44 @@ export class ProviderHealthChecker {
|
|
658
665
|
switch (providerName) {
|
659
666
|
case AIProviderName.ANTHROPIC:
|
660
667
|
return [
|
661
|
-
|
662
|
-
|
663
|
-
|
668
|
+
AnthropicModels.CLAUDE_3_5_SONNET,
|
669
|
+
AnthropicModels.CLAUDE_3_HAIKU,
|
670
|
+
AnthropicModels.CLAUDE_3_OPUS,
|
664
671
|
];
|
665
672
|
case AIProviderName.OPENAI:
|
666
|
-
return [
|
673
|
+
return [
|
674
|
+
OpenAIModels.GPT_4O,
|
675
|
+
OpenAIModels.GPT_4O_MINI,
|
676
|
+
OpenAIModels.GPT_3_5_TURBO,
|
677
|
+
];
|
667
678
|
case AIProviderName.GOOGLE_AI:
|
668
|
-
return [
|
679
|
+
return [
|
680
|
+
GoogleAIModels.GEMINI_1_5_PRO,
|
681
|
+
GoogleAIModels.GEMINI_1_5_FLASH,
|
682
|
+
GoogleAIModels.GEMINI_2_5_PRO,
|
683
|
+
];
|
669
684
|
case AIProviderName.VERTEX:
|
670
685
|
return [
|
671
686
|
// Google models (via vertex provider)
|
672
|
-
|
673
|
-
|
674
|
-
|
675
|
-
|
676
|
-
|
677
|
-
|
687
|
+
GoogleAIModels.GEMINI_2_5_PRO,
|
688
|
+
GoogleAIModels.GEMINI_2_5_FLASH,
|
689
|
+
GoogleAIModels.GEMINI_2_5_FLASH_LITE,
|
690
|
+
GoogleAIModels.GEMINI_2_0_FLASH_001,
|
691
|
+
GoogleAIModels.GEMINI_1_5_PRO,
|
692
|
+
GoogleAIModels.GEMINI_1_5_FLASH,
|
678
693
|
// Anthropic models (via vertexAnthropic provider)
|
679
694
|
"claude-sonnet-4@20250514",
|
680
695
|
"claude-opus-4@20250514",
|
681
|
-
|
682
|
-
|
683
|
-
|
684
|
-
|
685
|
-
|
696
|
+
AnthropicModels.CLAUDE_3_5_SONNET,
|
697
|
+
AnthropicModels.CLAUDE_3_5_HAIKU,
|
698
|
+
AnthropicModels.CLAUDE_3_SONNET,
|
699
|
+
AnthropicModels.CLAUDE_3_HAIKU,
|
700
|
+
AnthropicModels.CLAUDE_3_OPUS,
|
686
701
|
];
|
687
702
|
case AIProviderName.BEDROCK:
|
688
|
-
return [
|
689
|
-
"anthropic.claude-3-sonnet-20240229-v1:0",
|
690
|
-
"anthropic.claude-3-haiku-20240307-v1:0",
|
691
|
-
];
|
703
|
+
return [BedrockModels.CLAUDE_3_SONNET, BedrockModels.CLAUDE_3_HAIKU];
|
692
704
|
case AIProviderName.AZURE:
|
693
|
-
return [
|
705
|
+
return [OpenAIModels.GPT_4O, OpenAIModels.GPT_4O_MINI, "gpt-35-turbo"];
|
694
706
|
case AIProviderName.OLLAMA:
|
695
707
|
return ["llama3.2:latest", "llama3.1:latest", "mistral:latest"];
|
696
708
|
default:
|
@@ -951,8 +963,7 @@ export class ProviderHealthChecker {
|
|
951
963
|
if (projectId) {
|
952
964
|
result.projectId = projectId;
|
953
965
|
// Validate project ID format
|
954
|
-
|
955
|
-
if (projectIdPattern.test(projectId)) {
|
966
|
+
if (PROJECT_ID_FORMAT.PATTERN.test(projectId)) {
|
956
967
|
result.isValid = true;
|
957
968
|
}
|
958
969
|
else {
|
@@ -2,6 +2,7 @@
|
|
2
2
|
* Enhanced Provider Setup Messages
|
3
3
|
* Provides detailed setup instructions for AI providers
|
4
4
|
*/
|
5
|
+
import { OpenAIModels, GoogleAIModels, AnthropicModels, APIVersions, } from "../core/types.js";
|
5
6
|
/**
|
6
7
|
* Generate enhanced error message with setup instructions
|
7
8
|
*/
|
@@ -12,7 +13,7 @@ export function getProviderSetupMessage(provider, missingVars) {
|
|
12
13
|
envVars: [
|
13
14
|
'OPENAI_API_KEY="sk-proj-your-openai-api-key"',
|
14
15
|
"# Optional:",
|
15
|
-
|
16
|
+
`OPENAI_MODEL="${OpenAIModels.GPT_4O}"`,
|
16
17
|
'OPENAI_BASE_URL="https://api.openai.com"',
|
17
18
|
],
|
18
19
|
},
|
@@ -21,7 +22,7 @@ export function getProviderSetupMessage(provider, missingVars) {
|
|
21
22
|
envVars: [
|
22
23
|
'ANTHROPIC_API_KEY="sk-ant-api03-your-anthropic-key"',
|
23
24
|
"# Optional:",
|
24
|
-
|
25
|
+
`ANTHROPIC_MODEL="${AnthropicModels.CLAUDE_3_5_SONNET}"`,
|
25
26
|
],
|
26
27
|
},
|
27
28
|
"google-ai": {
|
@@ -29,7 +30,7 @@ export function getProviderSetupMessage(provider, missingVars) {
|
|
29
30
|
envVars: [
|
30
31
|
'GOOGLE_AI_API_KEY="AIza-your-google-ai-api-key"',
|
31
32
|
"# Optional:",
|
32
|
-
|
33
|
+
`GOOGLE_AI_MODEL="${GoogleAIModels.GEMINI_2_5_PRO}"`,
|
33
34
|
],
|
34
35
|
},
|
35
36
|
vertex: {
|
@@ -39,7 +40,7 @@ export function getProviderSetupMessage(provider, missingVars) {
|
|
39
40
|
'GOOGLE_VERTEX_PROJECT="your-gcp-project-id"',
|
40
41
|
'GOOGLE_VERTEX_LOCATION="us-central1"',
|
41
42
|
"# Optional:",
|
42
|
-
|
43
|
+
`VERTEX_MODEL="${GoogleAIModels.GEMINI_2_5_PRO}"`,
|
43
44
|
],
|
44
45
|
},
|
45
46
|
bedrock: {
|
@@ -61,8 +62,8 @@ export function getProviderSetupMessage(provider, missingVars) {
|
|
61
62
|
'AZURE_OPENAI_ENDPOINT="https://your-resource.openai.azure.com/"',
|
62
63
|
'AZURE_OPENAI_DEPLOYMENT_ID="your-deployment-name"',
|
63
64
|
"# Optional:",
|
64
|
-
|
65
|
-
|
65
|
+
`AZURE_MODEL="${OpenAIModels.GPT_4O}"`,
|
66
|
+
`AZURE_API_VERSION="${APIVersions.AZURE_STABLE}"`,
|
66
67
|
],
|
67
68
|
},
|
68
69
|
huggingface: {
|
@@ -5,6 +5,7 @@
|
|
5
5
|
import { AIProviderFactory } from "../core/factory.js";
|
6
6
|
import { logger } from "./logger.js";
|
7
7
|
import { ProviderHealthChecker } from "./providerHealth.js";
|
8
|
+
import { API_KEY_FORMATS, API_KEY_LENGTHS, PROJECT_ID_FORMAT, } from "./providerConfig.js";
|
8
9
|
/**
|
9
10
|
* Get the best available provider based on real-time availability checks
|
10
11
|
* Enhanced version consolidated from providerUtils-fixed.ts
|
@@ -123,15 +124,6 @@ async function isProviderAvailable(providerName) {
|
|
123
124
|
return false;
|
124
125
|
}
|
125
126
|
}
|
126
|
-
/**
|
127
|
-
* Google Cloud Project ID validation regex
|
128
|
-
* Format requirements:
|
129
|
-
* - Must start with a lowercase letter
|
130
|
-
* - Can contain lowercase letters, numbers, and hyphens
|
131
|
-
* - Must end with a lowercase letter or number
|
132
|
-
* - Total length must be 6-30 characters
|
133
|
-
*/
|
134
|
-
const GOOGLE_CLOUD_PROJECT_ID_REGEX = /^[a-z][a-z0-9-]{4,28}[a-z0-9]$/;
|
135
127
|
/**
|
136
128
|
* Validate environment variable values for a provider
|
137
129
|
* Addresses GitHub Copilot comment about adding environment variable validation
|
@@ -166,7 +158,7 @@ export function validateProviderEnvVars(provider) {
|
|
166
158
|
validateAnthropicCredentials(result);
|
167
159
|
break;
|
168
160
|
case "azure":
|
169
|
-
case "
|
161
|
+
case "azureopenai":
|
170
162
|
validateAzureCredentials(result);
|
171
163
|
break;
|
172
164
|
case "google-ai":
|
@@ -240,7 +232,7 @@ function validateVertexCredentials(result) {
|
|
240
232
|
if (!projectId) {
|
241
233
|
result.missingVars.push("GOOGLE_CLOUD_PROJECT_ID (or variant)");
|
242
234
|
}
|
243
|
-
else if (!
|
235
|
+
else if (!PROJECT_ID_FORMAT.PATTERN.test(projectId)) {
|
244
236
|
result.invalidVars.push("Project ID format invalid (must be 6-30 lowercase letters, digits, hyphens)");
|
245
237
|
}
|
246
238
|
if (!hasCredentials) {
|
@@ -259,8 +251,8 @@ function validateOpenAICredentials(result) {
|
|
259
251
|
if (!apiKey) {
|
260
252
|
result.missingVars.push("OPENAI_API_KEY");
|
261
253
|
}
|
262
|
-
else if (
|
263
|
-
result.invalidVars.push(
|
254
|
+
else if (!API_KEY_FORMATS.openai.test(apiKey)) {
|
255
|
+
result.invalidVars.push(`OPENAI_API_KEY (should start with 'sk-' followed by ${API_KEY_LENGTHS.OPENAI_MIN}+ characters)`);
|
264
256
|
}
|
265
257
|
}
|
266
258
|
/**
|
@@ -271,8 +263,8 @@ function validateAnthropicCredentials(result) {
|
|
271
263
|
if (!apiKey) {
|
272
264
|
result.missingVars.push("ANTHROPIC_API_KEY");
|
273
265
|
}
|
274
|
-
else if (
|
275
|
-
result.invalidVars.push(
|
266
|
+
else if (!API_KEY_FORMATS.anthropic.test(apiKey)) {
|
267
|
+
result.invalidVars.push(`ANTHROPIC_API_KEY (should start with 'sk-ant-' followed by ${API_KEY_LENGTHS.ANTHROPIC_MIN}+ characters)`);
|
276
268
|
}
|
277
269
|
}
|
278
270
|
/**
|
@@ -284,8 +276,8 @@ function validateAzureCredentials(result) {
|
|
284
276
|
if (!apiKey) {
|
285
277
|
result.missingVars.push("AZURE_OPENAI_API_KEY");
|
286
278
|
}
|
287
|
-
else if (
|
288
|
-
result.invalidVars.push(
|
279
|
+
else if (!API_KEY_FORMATS.azure.test(apiKey)) {
|
280
|
+
result.invalidVars.push(`AZURE_OPENAI_API_KEY (should be at least ${API_KEY_LENGTHS.AZURE_MIN} alphanumeric characters)`);
|
289
281
|
}
|
290
282
|
if (!endpoint) {
|
291
283
|
result.missingVars.push("AZURE_OPENAI_ENDPOINT");
|
@@ -302,8 +294,8 @@ function validateGoogleAICredentials(result) {
|
|
302
294
|
if (!apiKey) {
|
303
295
|
result.missingVars.push("GOOGLE_AI_API_KEY (or GOOGLE_GENERATIVE_AI_API_KEY)");
|
304
296
|
}
|
305
|
-
else if (
|
306
|
-
result.invalidVars.push(
|
297
|
+
else if (!API_KEY_FORMATS["google-ai"].test(apiKey)) {
|
298
|
+
result.invalidVars.push(`GOOGLE_AI_API_KEY (should be ${API_KEY_LENGTHS.GOOGLE_AI_EXACT} alphanumeric characters with dashes/underscores)`);
|
307
299
|
}
|
308
300
|
}
|
309
301
|
/**
|
@@ -314,8 +306,8 @@ function validateHuggingFaceCredentials(result) {
|
|
314
306
|
if (!apiKey) {
|
315
307
|
result.missingVars.push("HUGGINGFACE_API_KEY (or HF_TOKEN)");
|
316
308
|
}
|
317
|
-
else if (
|
318
|
-
result.invalidVars.push(
|
309
|
+
else if (!API_KEY_FORMATS.huggingface.test(apiKey)) {
|
310
|
+
result.invalidVars.push(`HUGGINGFACE_API_KEY (should start with 'hf_' followed by ${API_KEY_LENGTHS.HUGGINGFACE_EXACT} characters)`);
|
319
311
|
}
|
320
312
|
}
|
321
313
|
/**
|
@@ -326,8 +318,8 @@ function validateMistralCredentials(result) {
|
|
326
318
|
if (!apiKey) {
|
327
319
|
result.missingVars.push("MISTRAL_API_KEY");
|
328
320
|
}
|
329
|
-
else if (
|
330
|
-
result.invalidVars.push(
|
321
|
+
else if (!API_KEY_FORMATS.mistral.test(apiKey)) {
|
322
|
+
result.invalidVars.push(`MISTRAL_API_KEY (should be ${API_KEY_LENGTHS.MISTRAL_EXACT} alphanumeric characters)`);
|
331
323
|
}
|
332
324
|
}
|
333
325
|
/**
|
@@ -381,7 +373,7 @@ export function hasProviderEnvVars(provider) {
|
|
381
373
|
case "claude":
|
382
374
|
return !!process.env.ANTHROPIC_API_KEY;
|
383
375
|
case "azure":
|
384
|
-
case "
|
376
|
+
case "azureopenai":
|
385
377
|
return !!process.env.AZURE_OPENAI_API_KEY;
|
386
378
|
case "google-ai":
|
387
379
|
case "google-studio":
|
@@ -6,13 +6,13 @@ import { PROVIDER_MAX_TOKENS } from "../core/constants.js";
|
|
6
6
|
/**
|
7
7
|
* Get the safe maximum tokens for a provider and model
|
8
8
|
*/
|
9
|
-
export declare function getSafeMaxTokens(provider: keyof typeof PROVIDER_MAX_TOKENS | string, model?: string, requestedMaxTokens?: number): number;
|
9
|
+
export declare function getSafeMaxTokens(provider: keyof typeof PROVIDER_MAX_TOKENS | string, model?: string, requestedMaxTokens?: number): number | undefined;
|
10
10
|
/**
|
11
11
|
* Validate if maxTokens is safe for a provider/model combination
|
12
12
|
*/
|
13
13
|
export declare function validateMaxTokens(provider: keyof typeof PROVIDER_MAX_TOKENS | string, model?: string, maxTokens?: number): {
|
14
14
|
isValid: boolean;
|
15
|
-
recommendedMaxTokens
|
15
|
+
recommendedMaxTokens?: number;
|
16
16
|
warning?: string;
|
17
17
|
};
|
18
18
|
/**
|
@@ -2,7 +2,7 @@
|
|
2
2
|
* Provider-specific token limit utilities
|
3
3
|
* Provides safe maxTokens values based on provider and model capabilities
|
4
4
|
*/
|
5
|
-
import { PROVIDER_MAX_TOKENS
|
5
|
+
import { PROVIDER_MAX_TOKENS } from "../core/constants.js";
|
6
6
|
import { logger } from "./logger.js";
|
7
7
|
/**
|
8
8
|
* Get the safe maximum tokens for a provider and model
|
@@ -11,8 +11,8 @@ export function getSafeMaxTokens(provider, model, requestedMaxTokens) {
|
|
11
11
|
// Get provider-specific limits
|
12
12
|
const providerLimits = PROVIDER_MAX_TOKENS[provider];
|
13
13
|
if (!providerLimits) {
|
14
|
-
logger.warn(`Unknown provider ${provider},
|
15
|
-
return
|
14
|
+
logger.warn(`Unknown provider ${provider}, no token limits enforced`);
|
15
|
+
return requestedMaxTokens || undefined; // No default limit for unknown providers
|
16
16
|
}
|
17
17
|
// Get model-specific limit or provider default
|
18
18
|
let maxLimit;
|
@@ -54,6 +54,13 @@ export function validateMaxTokens(provider, model, maxTokens) {
|
|
54
54
|
recommendedMaxTokens: safeMaxTokens,
|
55
55
|
};
|
56
56
|
}
|
57
|
+
// If no limits are defined, validation always passes
|
58
|
+
if (safeMaxTokens === undefined) {
|
59
|
+
return {
|
60
|
+
isValid: true,
|
61
|
+
recommendedMaxTokens: maxTokens,
|
62
|
+
};
|
63
|
+
}
|
57
64
|
const isValid = maxTokens <= safeMaxTokens;
|
58
65
|
return {
|
59
66
|
isValid,
|
@@ -146,7 +146,7 @@ Return ONLY a valid JSON object with this exact structure:
|
|
146
146
|
Generate 3-5 comprehensive test cases covering the requested types.`;
|
147
147
|
const result = await provider.generate({
|
148
148
|
prompt: prompt,
|
149
|
-
maxTokens:
|
149
|
+
maxTokens: 10000, // High limit for complex analysis
|
150
150
|
temperature: 0.3, // Lower temperature for more consistent structured output
|
151
151
|
});
|
152
152
|
if (!result || !result.content) {
|
@@ -360,7 +360,7 @@ Return ONLY a valid JSON object with this exact structure:
|
|
360
360
|
Focus on creating accurate, useful documentation that explains the code's purpose, parameters, return values, and usage patterns.`;
|
361
361
|
const result = await provider.generate({
|
362
362
|
prompt: prompt,
|
363
|
-
maxTokens:
|
363
|
+
maxTokens: 10000, // High limit for complex analysis
|
364
364
|
temperature: 0.3, // Moderate temperature for creative but structured documentation
|
365
365
|
});
|
366
366
|
if (!result || !result.content) {
|
@@ -3,7 +3,7 @@
|
|
3
3
|
* Provides centralized model data for models command system
|
4
4
|
* Part of Phase 4.1 - Models Command System
|
5
5
|
*/
|
6
|
-
import { AIProviderName } from "../types
|
6
|
+
import { AIProviderName } from "../core/types.js";
|
7
7
|
import type { JsonValue } from "../types/common.js";
|
8
8
|
/**
|
9
9
|
* Model capabilities interface
|