@juspay/neurolink 1.0.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.
- package/README.md +815 -0
- package/dist/core/factory.d.ts +40 -0
- package/dist/core/factory.js +149 -0
- package/dist/core/types.d.ts +77 -0
- package/dist/core/types.js +55 -0
- package/dist/index.d.ts +54 -0
- package/dist/index.js +60 -0
- package/dist/providers/amazonBedrock.d.ts +11 -0
- package/dist/providers/amazonBedrock.js +229 -0
- package/dist/providers/googleVertexAI.d.ts +30 -0
- package/dist/providers/googleVertexAI.js +283 -0
- package/dist/providers/index.d.ts +24 -0
- package/dist/providers/index.js +19 -0
- package/dist/providers/openAI.d.ts +10 -0
- package/dist/providers/openAI.js +145 -0
- package/dist/utils/providerUtils.d.ts +20 -0
- package/dist/utils/providerUtils.js +63 -0
- package/package.json +82 -0
|
@@ -0,0 +1,30 @@
|
|
|
1
|
+
import type { ZodType, ZodTypeDef } from 'zod';
|
|
2
|
+
import { type StreamTextResult, type ToolSet, type Schema, type GenerateTextResult } from 'ai';
|
|
3
|
+
import type { AIProvider } from '../core/types.js';
|
|
4
|
+
export declare class GoogleVertexAI implements AIProvider {
|
|
5
|
+
private modelName;
|
|
6
|
+
/**
|
|
7
|
+
* Initializes a new instance of GoogleVertexAI
|
|
8
|
+
* @param modelName - Optional model name to override the default from config
|
|
9
|
+
*/
|
|
10
|
+
constructor(modelName?: string | null);
|
|
11
|
+
/**
|
|
12
|
+
* Gets the appropriate model instance (Google or Anthropic)
|
|
13
|
+
* @private
|
|
14
|
+
*/
|
|
15
|
+
private getModel;
|
|
16
|
+
/**
|
|
17
|
+
* Processes text using streaming approach with enhanced error handling callbacks
|
|
18
|
+
* @param prompt - The input text prompt to analyze
|
|
19
|
+
* @param analysisSchema - Optional Zod schema or Schema object for output validation
|
|
20
|
+
* @returns Promise resolving to StreamTextResult or null if operation fails
|
|
21
|
+
*/
|
|
22
|
+
streamText(prompt: string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<StreamTextResult<ToolSet, unknown> | null>;
|
|
23
|
+
/**
|
|
24
|
+
* Processes text using non-streaming approach with optional schema validation
|
|
25
|
+
* @param prompt - The input text prompt to analyze
|
|
26
|
+
* @param analysisSchema - Optional Zod schema or Schema object for output validation
|
|
27
|
+
* @returns Promise resolving to GenerateTextResult or null if operation fails
|
|
28
|
+
*/
|
|
29
|
+
generateText(prompt: string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<GenerateTextResult<ToolSet, unknown> | null>;
|
|
30
|
+
}
|
|
@@ -0,0 +1,283 @@
|
|
|
1
|
+
import { createVertex } from '@ai-sdk/google-vertex';
|
|
2
|
+
// Cache for anthropic module to avoid repeated imports
|
|
3
|
+
let _createVertexAnthropic = null;
|
|
4
|
+
let _anthropicImportAttempted = false;
|
|
5
|
+
// Function to dynamically import anthropic support
|
|
6
|
+
async function getCreateVertexAnthropic() {
|
|
7
|
+
if (_anthropicImportAttempted) {
|
|
8
|
+
return _createVertexAnthropic;
|
|
9
|
+
}
|
|
10
|
+
_anthropicImportAttempted = true;
|
|
11
|
+
try {
|
|
12
|
+
// Try to import the anthropic module - available in @ai-sdk/google-vertex ^2.2.0+
|
|
13
|
+
const anthropicModule = await import('@ai-sdk/google-vertex/anthropic');
|
|
14
|
+
_createVertexAnthropic = anthropicModule.createVertexAnthropic;
|
|
15
|
+
console.log('[GoogleVertexAI] Anthropic module successfully loaded');
|
|
16
|
+
return _createVertexAnthropic;
|
|
17
|
+
}
|
|
18
|
+
catch (error) {
|
|
19
|
+
// Anthropic module not available
|
|
20
|
+
console.warn('[GoogleVertexAI] Anthropic module not available. Install @ai-sdk/google-vertex ^2.2.0 for Anthropic model support.');
|
|
21
|
+
return null;
|
|
22
|
+
}
|
|
23
|
+
}
|
|
24
|
+
import { streamText, generateText, Output } from 'ai';
|
|
25
|
+
// Default system context
|
|
26
|
+
const DEFAULT_SYSTEM_CONTEXT = {
|
|
27
|
+
systemPrompt: 'You are a helpful AI assistant.'
|
|
28
|
+
};
|
|
29
|
+
// Configuration helpers
|
|
30
|
+
const getGCPVertexBreezeProjectId = () => {
|
|
31
|
+
const projectId = process.env.GOOGLE_VERTEX_PROJECT;
|
|
32
|
+
if (!projectId) {
|
|
33
|
+
throw new Error('GOOGLE_VERTEX_PROJECT environment variable is not set');
|
|
34
|
+
}
|
|
35
|
+
return projectId;
|
|
36
|
+
};
|
|
37
|
+
const getGCPVertexBreezeLocation = () => {
|
|
38
|
+
return process.env.GOOGLE_VERTEX_LOCATION || 'us-east5';
|
|
39
|
+
};
|
|
40
|
+
const getGoogleApplicationCredentials = () => {
|
|
41
|
+
return process.env.GOOGLE_APPLICATION_CREDENTIALS;
|
|
42
|
+
};
|
|
43
|
+
const getVertexModelId = () => {
|
|
44
|
+
return process.env.VERTEX_MODEL_ID || 'claude-sonnet-4@20250514';
|
|
45
|
+
};
|
|
46
|
+
const hasPrincipalAccountAuth = () => {
|
|
47
|
+
return !!getGoogleApplicationCredentials();
|
|
48
|
+
};
|
|
49
|
+
// Vertex AI setup with Principal Account Authentication support
|
|
50
|
+
const createVertexSettings = () => {
|
|
51
|
+
const functionTag = 'createVertexSettings';
|
|
52
|
+
const baseSettings = {
|
|
53
|
+
project: getGCPVertexBreezeProjectId(),
|
|
54
|
+
location: getGCPVertexBreezeLocation()
|
|
55
|
+
};
|
|
56
|
+
// Check for principal account authentication first (recommended for production)
|
|
57
|
+
if (hasPrincipalAccountAuth()) {
|
|
58
|
+
const credentialsPath = getGoogleApplicationCredentials();
|
|
59
|
+
console.log(`[${functionTag}] Principal account auth`, {
|
|
60
|
+
credentialsPath: credentialsPath ? '[PROVIDED]' : '[NOT_PROVIDED]',
|
|
61
|
+
authMethod: 'principal_account'
|
|
62
|
+
});
|
|
63
|
+
// For principal account auth, we don't need to provide explicit credentials
|
|
64
|
+
// The google-auth-library will use GOOGLE_APPLICATION_CREDENTIALS automatically
|
|
65
|
+
return baseSettings;
|
|
66
|
+
}
|
|
67
|
+
// Log warning if no valid authentication is available
|
|
68
|
+
console.warn(`[${functionTag}] No valid auth`, {
|
|
69
|
+
authMethod: 'none',
|
|
70
|
+
hasPrincipalAccount: hasPrincipalAccountAuth()
|
|
71
|
+
});
|
|
72
|
+
// Return base settings and let it fail if no auth is available
|
|
73
|
+
return baseSettings;
|
|
74
|
+
};
|
|
75
|
+
// Helper function to determine if a model is an Anthropic model
|
|
76
|
+
const isAnthropicModel = (modelName) => {
|
|
77
|
+
// Anthropic models in Vertex AI contain "claude" anywhere in the model name
|
|
78
|
+
return modelName.toLowerCase().includes('claude');
|
|
79
|
+
};
|
|
80
|
+
// Lazy initialization cache
|
|
81
|
+
let _vertex = null;
|
|
82
|
+
function getVertexInstance() {
|
|
83
|
+
if (!_vertex) {
|
|
84
|
+
_vertex = createVertex(createVertexSettings());
|
|
85
|
+
}
|
|
86
|
+
return _vertex;
|
|
87
|
+
}
|
|
88
|
+
// Google Vertex AI class with enhanced error handling and Anthropic model support
|
|
89
|
+
export class GoogleVertexAI {
|
|
90
|
+
modelName;
|
|
91
|
+
/**
|
|
92
|
+
* Initializes a new instance of GoogleVertexAI
|
|
93
|
+
* @param modelName - Optional model name to override the default from config
|
|
94
|
+
*/
|
|
95
|
+
constructor(modelName) {
|
|
96
|
+
const functionTag = 'GoogleVertexAI.constructor';
|
|
97
|
+
this.modelName = modelName || getVertexModelId();
|
|
98
|
+
try {
|
|
99
|
+
console.log(`[${functionTag}] Initialization started`, {
|
|
100
|
+
modelName: this.modelName,
|
|
101
|
+
isAnthropic: isAnthropicModel(this.modelName)
|
|
102
|
+
});
|
|
103
|
+
const hasPrincipal = hasPrincipalAccountAuth();
|
|
104
|
+
console.log(`[${functionTag}] Authentication validation`, {
|
|
105
|
+
hasPrincipalAccountAuth: hasPrincipal,
|
|
106
|
+
projectId: getGCPVertexBreezeProjectId() || 'MISSING',
|
|
107
|
+
location: getGCPVertexBreezeLocation() || 'MISSING'
|
|
108
|
+
});
|
|
109
|
+
if (hasPrincipal) {
|
|
110
|
+
console.log(`[${functionTag}] Auth method selected`, {
|
|
111
|
+
authMethod: 'principal_account',
|
|
112
|
+
hasGoogleApplicationCredentials: !!getGoogleApplicationCredentials()
|
|
113
|
+
});
|
|
114
|
+
}
|
|
115
|
+
else {
|
|
116
|
+
console.warn(`[${functionTag}] Auth method missing`, {
|
|
117
|
+
authMethod: 'none',
|
|
118
|
+
hasPrincipalAccountAuth: hasPrincipal
|
|
119
|
+
});
|
|
120
|
+
}
|
|
121
|
+
console.log(`[${functionTag}] Initialization completed`, {
|
|
122
|
+
modelName: this.modelName,
|
|
123
|
+
isAnthropic: isAnthropicModel(this.modelName),
|
|
124
|
+
authMethod: hasPrincipalAccountAuth() ? 'principal_account' : 'none',
|
|
125
|
+
success: true
|
|
126
|
+
});
|
|
127
|
+
}
|
|
128
|
+
catch (err) {
|
|
129
|
+
console.error(`[${functionTag}] Initialization failed`, {
|
|
130
|
+
message: 'Error in initializing Google Vertex AI',
|
|
131
|
+
modelName: this.modelName,
|
|
132
|
+
isAnthropic: isAnthropicModel(this.modelName),
|
|
133
|
+
error: err instanceof Error ? err.message : String(err),
|
|
134
|
+
stack: err instanceof Error ? err.stack : undefined
|
|
135
|
+
});
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
/**
|
|
139
|
+
* Gets the appropriate model instance (Google or Anthropic)
|
|
140
|
+
* @private
|
|
141
|
+
*/
|
|
142
|
+
async getModel() {
|
|
143
|
+
if (isAnthropicModel(this.modelName)) {
|
|
144
|
+
console.log('GoogleVertexAI.getModel - Anthropic model selected', {
|
|
145
|
+
modelName: this.modelName
|
|
146
|
+
});
|
|
147
|
+
const createVertexAnthropic = await getCreateVertexAnthropic();
|
|
148
|
+
if (!createVertexAnthropic) {
|
|
149
|
+
throw new Error(`Anthropic model "${this.modelName}" requested but @ai-sdk/google-vertex/anthropic is not available. ` +
|
|
150
|
+
'Please install @ai-sdk/google-vertex ^2.2.0 or use a Google model instead.');
|
|
151
|
+
}
|
|
152
|
+
const vertexAnthropic = createVertexAnthropic(createVertexSettings());
|
|
153
|
+
return vertexAnthropic(this.modelName);
|
|
154
|
+
}
|
|
155
|
+
const vertex = getVertexInstance();
|
|
156
|
+
return vertex(this.modelName);
|
|
157
|
+
}
|
|
158
|
+
/**
|
|
159
|
+
* Processes text using streaming approach with enhanced error handling callbacks
|
|
160
|
+
* @param prompt - The input text prompt to analyze
|
|
161
|
+
* @param analysisSchema - Optional Zod schema or Schema object for output validation
|
|
162
|
+
* @returns Promise resolving to StreamTextResult or null if operation fails
|
|
163
|
+
*/
|
|
164
|
+
async streamText(prompt, analysisSchema) {
|
|
165
|
+
const functionTag = 'GoogleVertexAI.streamText';
|
|
166
|
+
const provider = 'vertex';
|
|
167
|
+
let chunkCount = 0;
|
|
168
|
+
try {
|
|
169
|
+
console.log(`[${functionTag}] Stream request started`, {
|
|
170
|
+
provider,
|
|
171
|
+
modelName: this.modelName,
|
|
172
|
+
isAnthropic: isAnthropicModel(this.modelName),
|
|
173
|
+
promptLength: prompt.length,
|
|
174
|
+
hasSchema: !!analysisSchema
|
|
175
|
+
});
|
|
176
|
+
const model = await this.getModel();
|
|
177
|
+
const streamOptions = {
|
|
178
|
+
model: model,
|
|
179
|
+
prompt: prompt,
|
|
180
|
+
system: DEFAULT_SYSTEM_CONTEXT.systemPrompt,
|
|
181
|
+
onError: (event) => {
|
|
182
|
+
const error = event.error;
|
|
183
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
184
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
185
|
+
console.error(`[${functionTag}] Stream text error`, {
|
|
186
|
+
provider,
|
|
187
|
+
modelName: this.modelName,
|
|
188
|
+
error: errorMessage,
|
|
189
|
+
stack: errorStack,
|
|
190
|
+
promptLength: prompt.length,
|
|
191
|
+
chunkCount
|
|
192
|
+
});
|
|
193
|
+
},
|
|
194
|
+
onFinish: (event) => {
|
|
195
|
+
console.log(`[${functionTag}] Stream text finished`, {
|
|
196
|
+
provider,
|
|
197
|
+
modelName: this.modelName,
|
|
198
|
+
finishReason: event.finishReason,
|
|
199
|
+
usage: event.usage,
|
|
200
|
+
totalChunks: chunkCount,
|
|
201
|
+
promptLength: prompt.length,
|
|
202
|
+
responseLength: event.text?.length || 0
|
|
203
|
+
});
|
|
204
|
+
},
|
|
205
|
+
onChunk: (event) => {
|
|
206
|
+
chunkCount++;
|
|
207
|
+
console.debug(`[${functionTag}] Stream text chunk`, {
|
|
208
|
+
provider,
|
|
209
|
+
modelName: this.modelName,
|
|
210
|
+
chunkNumber: chunkCount,
|
|
211
|
+
chunkLength: event.chunk.text?.length || 0,
|
|
212
|
+
chunkType: event.chunk.type
|
|
213
|
+
});
|
|
214
|
+
}
|
|
215
|
+
};
|
|
216
|
+
if (analysisSchema) {
|
|
217
|
+
streamOptions.experimental_output = Output.object({ schema: analysisSchema });
|
|
218
|
+
}
|
|
219
|
+
const result = streamText(streamOptions);
|
|
220
|
+
return result;
|
|
221
|
+
}
|
|
222
|
+
catch (err) {
|
|
223
|
+
console.error(`[${functionTag}] Exception`, {
|
|
224
|
+
provider,
|
|
225
|
+
modelName: this.modelName,
|
|
226
|
+
message: 'Error in streaming text',
|
|
227
|
+
err: String(err),
|
|
228
|
+
promptLength: prompt.length
|
|
229
|
+
});
|
|
230
|
+
return null;
|
|
231
|
+
}
|
|
232
|
+
}
|
|
233
|
+
/**
|
|
234
|
+
* Processes text using non-streaming approach with optional schema validation
|
|
235
|
+
* @param prompt - The input text prompt to analyze
|
|
236
|
+
* @param analysisSchema - Optional Zod schema or Schema object for output validation
|
|
237
|
+
* @returns Promise resolving to GenerateTextResult or null if operation fails
|
|
238
|
+
*/
|
|
239
|
+
async generateText(prompt, analysisSchema) {
|
|
240
|
+
const functionTag = 'GoogleVertexAI.generateText';
|
|
241
|
+
const provider = 'vertex';
|
|
242
|
+
try {
|
|
243
|
+
console.log(`[${functionTag}] Generate request started`, {
|
|
244
|
+
provider,
|
|
245
|
+
modelName: this.modelName,
|
|
246
|
+
isAnthropic: isAnthropicModel(this.modelName),
|
|
247
|
+
promptLength: prompt.length
|
|
248
|
+
});
|
|
249
|
+
const model = await this.getModel();
|
|
250
|
+
const generateOptions = {
|
|
251
|
+
model: model,
|
|
252
|
+
prompt: prompt,
|
|
253
|
+
system: DEFAULT_SYSTEM_CONTEXT.systemPrompt
|
|
254
|
+
};
|
|
255
|
+
if (analysisSchema) {
|
|
256
|
+
generateOptions.experimental_output = Output.object({ schema: analysisSchema });
|
|
257
|
+
}
|
|
258
|
+
console.log(`[${functionTag}] Generate text started`, {
|
|
259
|
+
provider,
|
|
260
|
+
modelName: this.modelName,
|
|
261
|
+
isAnthropic: isAnthropicModel(this.modelName),
|
|
262
|
+
promptLength: prompt.length
|
|
263
|
+
});
|
|
264
|
+
const result = await generateText(generateOptions);
|
|
265
|
+
console.log(`[${functionTag}] Generate text completed`, {
|
|
266
|
+
provider,
|
|
267
|
+
modelName: this.modelName,
|
|
268
|
+
usage: result.usage,
|
|
269
|
+
finishReason: result.finishReason
|
|
270
|
+
});
|
|
271
|
+
return result;
|
|
272
|
+
}
|
|
273
|
+
catch (err) {
|
|
274
|
+
console.error(`[${functionTag}] Exception`, {
|
|
275
|
+
provider,
|
|
276
|
+
modelName: this.modelName,
|
|
277
|
+
message: 'Error in generating text',
|
|
278
|
+
err: String(err)
|
|
279
|
+
});
|
|
280
|
+
return null;
|
|
281
|
+
}
|
|
282
|
+
}
|
|
283
|
+
}
|
|
@@ -0,0 +1,24 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider exports for Vercel AI SDK integration
|
|
3
|
+
* This file centralizes all AI provider classes for easy import and usage
|
|
4
|
+
*/
|
|
5
|
+
export { GoogleVertexAI } from './googleVertexAI.js';
|
|
6
|
+
export { AmazonBedrock } from './amazonBedrock.js';
|
|
7
|
+
export { OpenAI } from './openAI.js';
|
|
8
|
+
export type { AIProvider } from '../core/types.js';
|
|
9
|
+
/**
|
|
10
|
+
* Provider registry for dynamic provider instantiation
|
|
11
|
+
*/
|
|
12
|
+
export declare const PROVIDERS: {
|
|
13
|
+
readonly vertex: "GoogleVertexAI";
|
|
14
|
+
readonly bedrock: "AmazonBedrock";
|
|
15
|
+
readonly openai: "OpenAI";
|
|
16
|
+
};
|
|
17
|
+
/**
|
|
18
|
+
* Type for valid provider names
|
|
19
|
+
*/
|
|
20
|
+
export type ProviderName = keyof typeof PROVIDERS;
|
|
21
|
+
/**
|
|
22
|
+
* List of all available provider names
|
|
23
|
+
*/
|
|
24
|
+
export declare const AVAILABLE_PROVIDERS: ProviderName[];
|
|
@@ -0,0 +1,19 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Provider exports for Vercel AI SDK integration
|
|
3
|
+
* This file centralizes all AI provider classes for easy import and usage
|
|
4
|
+
*/
|
|
5
|
+
export { GoogleVertexAI } from './googleVertexAI.js';
|
|
6
|
+
export { AmazonBedrock } from './amazonBedrock.js';
|
|
7
|
+
export { OpenAI } from './openAI.js';
|
|
8
|
+
/**
|
|
9
|
+
* Provider registry for dynamic provider instantiation
|
|
10
|
+
*/
|
|
11
|
+
export const PROVIDERS = {
|
|
12
|
+
vertex: 'GoogleVertexAI',
|
|
13
|
+
bedrock: 'AmazonBedrock',
|
|
14
|
+
openai: 'OpenAI'
|
|
15
|
+
};
|
|
16
|
+
/**
|
|
17
|
+
* List of all available provider names
|
|
18
|
+
*/
|
|
19
|
+
export const AVAILABLE_PROVIDERS = Object.keys(PROVIDERS);
|
|
@@ -0,0 +1,10 @@
|
|
|
1
|
+
import type { ZodType, ZodTypeDef } from 'zod';
|
|
2
|
+
import { type StreamTextResult, type ToolSet, type Schema, type GenerateTextResult } from 'ai';
|
|
3
|
+
import type { AIProvider } from '../core/types.js';
|
|
4
|
+
export declare class OpenAI implements AIProvider {
|
|
5
|
+
private modelName;
|
|
6
|
+
private model;
|
|
7
|
+
constructor(modelName?: string | null);
|
|
8
|
+
streamText(prompt: string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<StreamTextResult<ToolSet, unknown> | null>;
|
|
9
|
+
generateText(prompt: string, analysisSchema?: ZodType<unknown, ZodTypeDef, unknown> | Schema<unknown>): Promise<GenerateTextResult<ToolSet, unknown> | null>;
|
|
10
|
+
}
|
|
@@ -0,0 +1,145 @@
|
|
|
1
|
+
import { openai } from '@ai-sdk/openai';
|
|
2
|
+
import { streamText, generateText, Output } from 'ai';
|
|
3
|
+
// Default system context
|
|
4
|
+
const DEFAULT_SYSTEM_CONTEXT = {
|
|
5
|
+
systemPrompt: 'You are a helpful AI assistant.'
|
|
6
|
+
};
|
|
7
|
+
// Configuration helpers
|
|
8
|
+
const getOpenAIApiKey = () => {
|
|
9
|
+
const apiKey = process.env.OPENAI_API_KEY;
|
|
10
|
+
if (!apiKey) {
|
|
11
|
+
throw new Error('OPENAI_API_KEY environment variable is not set');
|
|
12
|
+
}
|
|
13
|
+
return apiKey;
|
|
14
|
+
};
|
|
15
|
+
const getOpenAIModel = () => {
|
|
16
|
+
return process.env.OPENAI_MODEL || 'gpt-4o';
|
|
17
|
+
};
|
|
18
|
+
// OpenAI class with enhanced error handling
|
|
19
|
+
export class OpenAI {
|
|
20
|
+
modelName;
|
|
21
|
+
model;
|
|
22
|
+
constructor(modelName) {
|
|
23
|
+
const functionTag = 'OpenAI.constructor';
|
|
24
|
+
this.modelName = modelName || getOpenAIModel();
|
|
25
|
+
try {
|
|
26
|
+
console.log(`[${functionTag}] Function called`, { modelName: this.modelName });
|
|
27
|
+
// Set OpenAI API key as environment variable
|
|
28
|
+
process.env.OPENAI_API_KEY = getOpenAIApiKey();
|
|
29
|
+
this.model = openai(this.modelName);
|
|
30
|
+
console.log(`[${functionTag}] Function result`, {
|
|
31
|
+
modelName: this.modelName,
|
|
32
|
+
success: true
|
|
33
|
+
});
|
|
34
|
+
}
|
|
35
|
+
catch (err) {
|
|
36
|
+
console.error(`[${functionTag}] Exception`, {
|
|
37
|
+
message: 'Error in initializing OpenAI',
|
|
38
|
+
modelName: this.modelName,
|
|
39
|
+
err: String(err)
|
|
40
|
+
});
|
|
41
|
+
throw err;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
44
|
+
async streamText(prompt, analysisSchema) {
|
|
45
|
+
const functionTag = 'OpenAI.streamText';
|
|
46
|
+
const provider = 'openai';
|
|
47
|
+
let chunkCount = 0;
|
|
48
|
+
try {
|
|
49
|
+
const streamOptions = {
|
|
50
|
+
model: this.model,
|
|
51
|
+
prompt: prompt,
|
|
52
|
+
system: DEFAULT_SYSTEM_CONTEXT.systemPrompt,
|
|
53
|
+
onError: (event) => {
|
|
54
|
+
const error = event.error;
|
|
55
|
+
const errorMessage = error instanceof Error ? error.message : String(error);
|
|
56
|
+
const errorStack = error instanceof Error ? error.stack : undefined;
|
|
57
|
+
console.error(`[${functionTag}] Stream text error`, {
|
|
58
|
+
provider,
|
|
59
|
+
modelName: this.modelName,
|
|
60
|
+
error: errorMessage,
|
|
61
|
+
stack: errorStack,
|
|
62
|
+
promptLength: prompt.length,
|
|
63
|
+
chunkCount
|
|
64
|
+
});
|
|
65
|
+
},
|
|
66
|
+
onFinish: (event) => {
|
|
67
|
+
console.log(`[${functionTag}] Stream text finished`, {
|
|
68
|
+
provider,
|
|
69
|
+
modelName: this.modelName,
|
|
70
|
+
finishReason: event.finishReason,
|
|
71
|
+
usage: event.usage,
|
|
72
|
+
totalChunks: chunkCount,
|
|
73
|
+
promptLength: prompt.length,
|
|
74
|
+
responseLength: event.text?.length || 0
|
|
75
|
+
});
|
|
76
|
+
},
|
|
77
|
+
onChunk: (event) => {
|
|
78
|
+
chunkCount++;
|
|
79
|
+
console.debug(`[${functionTag}] Stream text chunk`, {
|
|
80
|
+
provider,
|
|
81
|
+
modelName: this.modelName,
|
|
82
|
+
chunkNumber: chunkCount,
|
|
83
|
+
chunkLength: event.chunk.text?.length || 0,
|
|
84
|
+
chunkType: event.chunk.type
|
|
85
|
+
});
|
|
86
|
+
}
|
|
87
|
+
};
|
|
88
|
+
if (analysisSchema) {
|
|
89
|
+
streamOptions.experimental_output = Output.object({ schema: analysisSchema });
|
|
90
|
+
}
|
|
91
|
+
console.log(`[${functionTag}] Stream text started`, {
|
|
92
|
+
provider,
|
|
93
|
+
modelName: this.modelName,
|
|
94
|
+
promptLength: prompt.length
|
|
95
|
+
});
|
|
96
|
+
const result = streamText(streamOptions);
|
|
97
|
+
return result;
|
|
98
|
+
}
|
|
99
|
+
catch (err) {
|
|
100
|
+
console.error(`[${functionTag}] Exception`, {
|
|
101
|
+
provider,
|
|
102
|
+
modelName: this.modelName,
|
|
103
|
+
message: 'Error in streaming text',
|
|
104
|
+
err: String(err)
|
|
105
|
+
});
|
|
106
|
+
return null;
|
|
107
|
+
}
|
|
108
|
+
}
|
|
109
|
+
async generateText(prompt, analysisSchema) {
|
|
110
|
+
const functionTag = 'OpenAI.generateText';
|
|
111
|
+
const provider = 'openai';
|
|
112
|
+
try {
|
|
113
|
+
const generateOptions = {
|
|
114
|
+
model: this.model,
|
|
115
|
+
prompt: prompt,
|
|
116
|
+
system: DEFAULT_SYSTEM_CONTEXT.systemPrompt
|
|
117
|
+
};
|
|
118
|
+
if (analysisSchema) {
|
|
119
|
+
generateOptions.experimental_output = Output.object({ schema: analysisSchema });
|
|
120
|
+
}
|
|
121
|
+
console.log(`[${functionTag}] Generate text started`, {
|
|
122
|
+
provider,
|
|
123
|
+
modelName: this.modelName,
|
|
124
|
+
promptLength: prompt.length
|
|
125
|
+
});
|
|
126
|
+
const result = await generateText(generateOptions);
|
|
127
|
+
console.log(`[${functionTag}] Generate text completed`, {
|
|
128
|
+
provider,
|
|
129
|
+
modelName: this.modelName,
|
|
130
|
+
usage: result.usage,
|
|
131
|
+
finishReason: result.finishReason
|
|
132
|
+
});
|
|
133
|
+
return result;
|
|
134
|
+
}
|
|
135
|
+
catch (err) {
|
|
136
|
+
console.error(`[${functionTag}] Exception`, {
|
|
137
|
+
provider,
|
|
138
|
+
modelName: this.modelName,
|
|
139
|
+
message: 'Error in generating text',
|
|
140
|
+
err: String(err)
|
|
141
|
+
});
|
|
142
|
+
return null;
|
|
143
|
+
}
|
|
144
|
+
}
|
|
145
|
+
}
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for AI provider management
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get the best available provider based on preferences and availability
|
|
6
|
+
* @param requestedProvider - Optional preferred provider name
|
|
7
|
+
* @returns The best provider name to use
|
|
8
|
+
*/
|
|
9
|
+
export declare function getBestProvider(requestedProvider?: string): string;
|
|
10
|
+
/**
|
|
11
|
+
* Get available provider names
|
|
12
|
+
* @returns Array of available provider names
|
|
13
|
+
*/
|
|
14
|
+
export declare function getAvailableProviders(): string[];
|
|
15
|
+
/**
|
|
16
|
+
* Validate provider name
|
|
17
|
+
* @param provider - Provider name to validate
|
|
18
|
+
* @returns True if provider name is valid
|
|
19
|
+
*/
|
|
20
|
+
export declare function isValidProvider(provider: string): boolean;
|
|
@@ -0,0 +1,63 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* Utility functions for AI provider management
|
|
3
|
+
*/
|
|
4
|
+
/**
|
|
5
|
+
* Get the best available provider based on preferences and availability
|
|
6
|
+
* @param requestedProvider - Optional preferred provider name
|
|
7
|
+
* @returns The best provider name to use
|
|
8
|
+
*/
|
|
9
|
+
export function getBestProvider(requestedProvider) {
|
|
10
|
+
// If a specific provider is requested, return it
|
|
11
|
+
if (requestedProvider) {
|
|
12
|
+
return requestedProvider;
|
|
13
|
+
}
|
|
14
|
+
// Default fallback order based on environment variables
|
|
15
|
+
const providers = ['bedrock', 'vertex', 'openai'];
|
|
16
|
+
// Check which providers have their required environment variables
|
|
17
|
+
for (const provider of providers) {
|
|
18
|
+
if (isProviderConfigured(provider)) {
|
|
19
|
+
console.log(`[getBestProvider] Selected provider: ${provider}`);
|
|
20
|
+
return provider;
|
|
21
|
+
}
|
|
22
|
+
}
|
|
23
|
+
// Default to bedrock if nothing is configured
|
|
24
|
+
console.warn('[getBestProvider] No providers configured, defaulting to bedrock');
|
|
25
|
+
return 'bedrock';
|
|
26
|
+
}
|
|
27
|
+
/**
|
|
28
|
+
* Check if a provider has the minimum required configuration
|
|
29
|
+
* @param provider - Provider name to check
|
|
30
|
+
* @returns True if the provider appears to be configured
|
|
31
|
+
*/
|
|
32
|
+
function isProviderConfigured(provider) {
|
|
33
|
+
switch (provider.toLowerCase()) {
|
|
34
|
+
case 'bedrock':
|
|
35
|
+
case 'amazon':
|
|
36
|
+
case 'aws':
|
|
37
|
+
return !!(process.env.AWS_ACCESS_KEY_ID && process.env.AWS_SECRET_ACCESS_KEY);
|
|
38
|
+
case 'vertex':
|
|
39
|
+
case 'google':
|
|
40
|
+
case 'gemini':
|
|
41
|
+
return !!(process.env.GOOGLE_VERTEX_PROJECT || process.env.GOOGLE_APPLICATION_CREDENTIALS);
|
|
42
|
+
case 'openai':
|
|
43
|
+
case 'gpt':
|
|
44
|
+
return !!process.env.OPENAI_API_KEY;
|
|
45
|
+
default:
|
|
46
|
+
return false;
|
|
47
|
+
}
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* Get available provider names
|
|
51
|
+
* @returns Array of available provider names
|
|
52
|
+
*/
|
|
53
|
+
export function getAvailableProviders() {
|
|
54
|
+
return ['bedrock', 'vertex', 'openai'];
|
|
55
|
+
}
|
|
56
|
+
/**
|
|
57
|
+
* Validate provider name
|
|
58
|
+
* @param provider - Provider name to validate
|
|
59
|
+
* @returns True if provider name is valid
|
|
60
|
+
*/
|
|
61
|
+
export function isValidProvider(provider) {
|
|
62
|
+
return getAvailableProviders().includes(provider.toLowerCase());
|
|
63
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,82 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@juspay/neurolink",
|
|
3
|
+
"version": "1.0.0",
|
|
4
|
+
"description": "AI toolkit with multi-provider support for OpenAI, Amazon Bedrock, and Google Vertex AI",
|
|
5
|
+
"author": "Juspay Technologies",
|
|
6
|
+
"license": "MIT",
|
|
7
|
+
"scripts": {
|
|
8
|
+
"dev": "vite dev",
|
|
9
|
+
"build": "vite build && npm run prepack",
|
|
10
|
+
"preview": "vite preview",
|
|
11
|
+
"prepare": "svelte-kit sync || echo ''",
|
|
12
|
+
"prepack": "svelte-kit sync && svelte-package && publint",
|
|
13
|
+
"check": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json",
|
|
14
|
+
"check:watch": "svelte-kit sync && svelte-check --tsconfig ./tsconfig.json --watch",
|
|
15
|
+
"test": "vitest",
|
|
16
|
+
"test:run": "vitest run",
|
|
17
|
+
"lint": "prettier --check . && eslint .",
|
|
18
|
+
"format": "prettier --write ."
|
|
19
|
+
},
|
|
20
|
+
"files": [
|
|
21
|
+
"dist",
|
|
22
|
+
"!dist/**/*.test.*",
|
|
23
|
+
"!dist/**/*.spec.*"
|
|
24
|
+
],
|
|
25
|
+
"sideEffects": [
|
|
26
|
+
"**/*.css"
|
|
27
|
+
],
|
|
28
|
+
"svelte": "./dist/index.js",
|
|
29
|
+
"types": "./dist/index.d.ts",
|
|
30
|
+
"type": "module",
|
|
31
|
+
"main": "./dist/index.js",
|
|
32
|
+
"exports": {
|
|
33
|
+
".": {
|
|
34
|
+
"types": "./dist/index.d.ts",
|
|
35
|
+
"svelte": "./dist/index.js",
|
|
36
|
+
"import": "./dist/index.js",
|
|
37
|
+
"default": "./dist/index.js"
|
|
38
|
+
}
|
|
39
|
+
},
|
|
40
|
+
"peerDependencies": {
|
|
41
|
+
"ai": "^4.0.0",
|
|
42
|
+
"@ai-sdk/amazon-bedrock": "^1.0.0",
|
|
43
|
+
"@ai-sdk/openai": "^1.0.0",
|
|
44
|
+
"@ai-sdk/google-vertex": "^2.2.0",
|
|
45
|
+
"zod": "^3.22.0"
|
|
46
|
+
},
|
|
47
|
+
"devDependencies": {
|
|
48
|
+
"@sveltejs/adapter-auto": "^6.0.0",
|
|
49
|
+
"@sveltejs/kit": "^2.16.0",
|
|
50
|
+
"@sveltejs/package": "^2.0.0",
|
|
51
|
+
"@sveltejs/vite-plugin-svelte": "^5.0.0",
|
|
52
|
+
"@types/node": "^20.0.0",
|
|
53
|
+
"eslint": "^9.0.0",
|
|
54
|
+
"prettier": "^3.0.0",
|
|
55
|
+
"publint": "^0.3.2",
|
|
56
|
+
"svelte": "^5.0.0",
|
|
57
|
+
"svelte-check": "^4.0.0",
|
|
58
|
+
"tslib": "^2.4.1",
|
|
59
|
+
"typescript": "^5.0.0",
|
|
60
|
+
"vite": "^6.2.6",
|
|
61
|
+
"vitest": "^2.0.0"
|
|
62
|
+
},
|
|
63
|
+
"keywords": [
|
|
64
|
+
"ai",
|
|
65
|
+
"llm",
|
|
66
|
+
"openai",
|
|
67
|
+
"anthropic",
|
|
68
|
+
"google",
|
|
69
|
+
"bedrock",
|
|
70
|
+
"vertex",
|
|
71
|
+
"streaming",
|
|
72
|
+
"tools",
|
|
73
|
+
"neurolink",
|
|
74
|
+
"juspay",
|
|
75
|
+
"svelte"
|
|
76
|
+
],
|
|
77
|
+
"pnpm": {
|
|
78
|
+
"onlyBuiltDependencies": [
|
|
79
|
+
"esbuild"
|
|
80
|
+
]
|
|
81
|
+
}
|
|
82
|
+
}
|