@juspay/neurolink 9.68.7 → 9.68.8

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.
@@ -1,9 +1,8 @@
1
1
  import type { AIProviderName } from "../constants/enums.js";
2
- import { BaseProvider } from "../core/baseProvider.js";
3
- import type { NeurolinkCredentials, StreamOptions, StreamResult, ValidationSchema } from "../types/index.js";
4
- import type { LanguageModel } from "../types/index.js";
2
+ import type { NeurolinkCredentials } from "../types/index.js";
3
+ import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
5
4
  /**
6
- * Cloudflare Workers AI Provider
5
+ * Cloudflare Workers AI Provider — direct HTTP, no AI SDK.
7
6
  *
8
7
  * Edge-served open models (Llama / Mistral / Qwen / Gemma) at
9
8
  * `https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/v1`
@@ -11,25 +10,17 @@ import type { LanguageModel } from "../types/index.js";
11
10
  *
12
11
  * Required env: `CLOUDFLARE_API_KEY` + `CLOUDFLARE_ACCOUNT_ID`.
13
12
  *
13
+ * All request/stream/tool-loop orchestration lives in
14
+ * `OpenAIChatCompletionsProvider`; this class only declares configuration
15
+ * and provider-specific error mapping.
16
+ *
14
17
  * @see https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/
15
18
  */
16
- export declare class CloudflareProvider extends BaseProvider {
17
- private model;
18
- private apiKey;
19
- private baseURL;
19
+ export declare class CloudflareProvider extends OpenAIChatCompletionsProvider {
20
20
  constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["cloudflare"]);
21
- protected executeStream(options: StreamOptions, _analysisSchema?: ValidationSchema): Promise<StreamResult>;
22
- private executeStreamInner;
23
21
  protected getProviderName(): AIProviderName;
24
22
  protected getDefaultModel(): string;
25
- protected getAISDKModel(): LanguageModel;
23
+ protected getFallbackModelName(): string;
24
+ protected getFallbackModels(): string[];
26
25
  protected formatProviderError(error: unknown): Error;
27
- validateConfiguration(): Promise<boolean>;
28
- getConfiguration(): {
29
- provider: AIProviderName;
30
- model: string;
31
- defaultModel: string;
32
- baseURL: string;
33
- };
34
26
  }
35
- export default CloudflareProvider;
@@ -1,20 +1,9 @@
1
- import { createOpenAI } from "@ai-sdk/openai";
2
1
  import { CloudflareModels } from "../constants/enums.js";
3
- import { BaseProvider } from "../core/baseProvider.js";
4
- import { DEFAULT_MAX_STEPS } from "../core/constants.js";
5
- import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
6
- import { isNeuroLink } from "../neurolink.js";
7
- import { createLoggingFetch } from "../utils/loggingFetch.js";
8
- import { tracers, ATTR, withClientStreamSpan } from "../telemetry/index.js";
9
2
  import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
10
3
  import { logger } from "../utils/logger.js";
11
4
  import { createCloudflareConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
12
- import { composeAbortSignals, createTimeoutController, TimeoutError, } from "../utils/timeout.js";
13
- import { emitToolEndFromStepFinish } from "../utils/toolEndEmitter.js";
14
- import { resolveToolChoice } from "../utils/toolChoice.js";
15
- import { toAnalyticsStreamResult } from "./providerTypeUtils.js";
16
- import { stepCountIs } from "../utils/tool.js";
17
- import { streamText } from "../utils/generation.js";
5
+ import { TimeoutError } from "../utils/timeout.js";
6
+ import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
18
7
  /**
19
8
  * Cloudflare Workers AI exposes an OpenAI-compatible endpoint scoped per
20
9
  * account: `https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/v1`.
@@ -24,7 +13,7 @@ const buildCloudflareBaseURL = (accountId) => `https://api.cloudflare.com/client
24
13
  const getCloudflareApiKey = () => validateApiKey(createCloudflareConfig());
25
14
  const getDefaultCloudflareModel = () => getProviderModel("CLOUDFLARE_MODEL", CloudflareModels.LLAMA_3_3_70B_FAST);
26
15
  /**
27
- * Cloudflare Workers AI Provider
16
+ * Cloudflare Workers AI Provider — direct HTTP, no AI SDK.
28
17
  *
29
18
  * Edge-served open models (Llama / Mistral / Qwen / Gemma) at
30
19
  * `https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/v1`
@@ -32,111 +21,50 @@ const getDefaultCloudflareModel = () => getProviderModel("CLOUDFLARE_MODEL", Clo
32
21
  *
33
22
  * Required env: `CLOUDFLARE_API_KEY` + `CLOUDFLARE_ACCOUNT_ID`.
34
23
  *
24
+ * All request/stream/tool-loop orchestration lives in
25
+ * `OpenAIChatCompletionsProvider`; this class only declares configuration
26
+ * and provider-specific error mapping.
27
+ *
35
28
  * @see https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/
36
29
  */
37
- export class CloudflareProvider extends BaseProvider {
38
- model;
39
- apiKey;
40
- baseURL;
30
+ export class CloudflareProvider extends OpenAIChatCompletionsProvider {
41
31
  constructor(modelName, sdk, _region, credentials) {
42
- const validatedNeurolink = isNeuroLink(sdk) ? sdk : undefined;
43
- super(modelName, "cloudflare", validatedNeurolink);
44
32
  const overrideApiKey = credentials?.apiKey?.trim();
45
- this.apiKey =
46
- overrideApiKey && overrideApiKey.length > 0
47
- ? overrideApiKey
48
- : getCloudflareApiKey();
33
+ const apiKey = overrideApiKey && overrideApiKey.length > 0
34
+ ? overrideApiKey
35
+ : getCloudflareApiKey();
49
36
  const accountId = (credentials?.accountId ??
50
37
  process.env.CLOUDFLARE_ACCOUNT_ID ??
51
38
  "").trim();
52
39
  if (!accountId) {
53
40
  throw new Error("CLOUDFLARE_ACCOUNT_ID is required (or pass credentials.cloudflare.accountId). Get the account id from https://dash.cloudflare.com/");
54
41
  }
55
- this.baseURL = credentials?.baseURL ?? buildCloudflareBaseURL(accountId);
56
- const cloudflare = createOpenAI({
57
- apiKey: this.apiKey,
58
- baseURL: this.baseURL,
59
- fetch: createLoggingFetch("cloudflare"),
60
- });
61
- this.model = cloudflare.chat(this.modelName);
42
+ const baseURL = credentials?.baseURL ?? buildCloudflareBaseURL(accountId);
43
+ super("cloudflare", modelName, sdk, { baseURL, apiKey });
62
44
  logger.debug("Cloudflare Workers AI Provider initialized", {
63
45
  modelName: this.modelName,
64
46
  providerName: this.providerName,
65
- baseURL: this.baseURL,
47
+ baseURL: this.config.baseURL,
66
48
  });
67
49
  }
68
- async executeStream(options, _analysisSchema) {
69
- return withClientStreamSpan({
70
- name: "neurolink.provider.stream",
71
- tracer: tracers.provider,
72
- attributes: {
73
- [ATTR.GEN_AI_SYSTEM]: "cloudflare",
74
- [ATTR.GEN_AI_MODEL]: this.modelName,
75
- [ATTR.GEN_AI_OPERATION]: "stream",
76
- [ATTR.NL_STREAM_MODE]: true,
77
- },
78
- }, async () => this.executeStreamInner(options), (r) => r.stream, (r, wrapped) => ({ ...r, stream: wrapped }));
79
- }
80
- async executeStreamInner(options) {
81
- this.validateStreamOptions(options);
82
- const startTime = Date.now();
83
- const timeout = this.getTimeout(options);
84
- const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
85
- try {
86
- const shouldUseTools = !options.disableTools && this.supportsTools();
87
- const tools = shouldUseTools
88
- ? options.tools || (await this.getAllTools())
89
- : {};
90
- const messages = await this.buildMessagesForStream(options);
91
- const model = await this.getAISDKModelWithMiddleware(options);
92
- const result = await streamText({
93
- model,
94
- messages,
95
- temperature: options.temperature,
96
- maxOutputTokens: options.maxTokens,
97
- tools,
98
- stopWhen: stepCountIs(options.maxSteps || DEFAULT_MAX_STEPS),
99
- toolChoice: resolveToolChoice(options, tools, shouldUseTools),
100
- abortSignal: composeAbortSignals(options.abortSignal, timeoutController?.controller.signal),
101
- experimental_telemetry: this.telemetryHandler.getTelemetryConfig(options),
102
- experimental_repairToolCall: this.getToolCallRepairFn(options),
103
- onStepFinish: ({ toolCalls, toolResults }) => {
104
- emitToolEndFromStepFinish(this.neurolink?.getEventEmitter(), toolResults);
105
- this.handleToolExecutionStorage(toolCalls, toolResults, options, new Date()).catch((error) => {
106
- logger.warn("[CloudflareProvider] Failed to store tool executions", {
107
- provider: this.providerName,
108
- error: error instanceof Error ? error.message : String(error),
109
- });
110
- });
111
- },
112
- });
113
- timeoutController?.cleanup();
114
- const transformedStream = this.createTextStream(result);
115
- const analyticsPromise = streamAnalyticsCollector.createAnalytics(this.providerName, this.modelName, toAnalyticsStreamResult(result), Date.now() - startTime, {
116
- requestId: `cloudflare-stream-${Date.now()}`,
117
- streamingMode: true,
118
- });
119
- return {
120
- stream: transformedStream,
121
- provider: this.providerName,
122
- model: this.modelName,
123
- analytics: analyticsPromise,
124
- metadata: { startTime, streamId: `cloudflare-${Date.now()}` },
125
- };
126
- }
127
- catch (error) {
128
- timeoutController?.cleanup();
129
- throw this.handleProviderError(error);
130
- }
131
- }
132
50
  getProviderName() {
133
- return this.providerName;
51
+ return "cloudflare";
134
52
  }
135
53
  getDefaultModel() {
136
54
  return getDefaultCloudflareModel();
137
55
  }
138
- getAISDKModel() {
139
- return this.model;
56
+ getFallbackModelName() {
57
+ return CloudflareModels.LLAMA_3_1_8B_FAST;
58
+ }
59
+ getFallbackModels() {
60
+ return [
61
+ CloudflareModels.LLAMA_3_3_70B_FAST,
62
+ CloudflareModels.LLAMA_3_1_70B_INSTRUCT,
63
+ CloudflareModels.LLAMA_3_1_8B_FAST,
64
+ CloudflareModels.LLAMA_3_2_11B_VISION,
65
+ CloudflareModels.MISTRAL_7B_INSTRUCT_V0_2,
66
+ CloudflareModels.QWEN_1P5_14B_CHAT_AWQ,
67
+ ];
140
68
  }
141
69
  formatProviderError(error) {
142
70
  if (error instanceof TimeoutError) {
@@ -159,17 +87,5 @@ export class CloudflareProvider extends BaseProvider {
159
87
  }
160
88
  return new ProviderError(`Cloudflare Workers AI error: ${message}`, "cloudflare");
161
89
  }
162
- async validateConfiguration() {
163
- return typeof this.apiKey === "string" && this.apiKey.trim().length > 0;
164
- }
165
- getConfiguration() {
166
- return {
167
- provider: this.providerName,
168
- model: this.modelName,
169
- defaultModel: getDefaultCloudflareModel(),
170
- baseURL: this.baseURL,
171
- };
172
- }
173
90
  }
174
- export default CloudflareProvider;
175
91
  //# sourceMappingURL=cloudflare.js.map
@@ -1,9 +1,8 @@
1
1
  import type { AIProviderName } from "../constants/enums.js";
2
- import { BaseProvider } from "../core/baseProvider.js";
3
- import type { NeurolinkCredentials, StreamOptions, StreamResult, ValidationSchema } from "../types/index.js";
4
- import type { LanguageModel } from "../types/index.js";
2
+ import type { NeurolinkCredentials } from "../types/index.js";
3
+ import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
5
4
  /**
6
- * Cloudflare Workers AI Provider
5
+ * Cloudflare Workers AI Provider — direct HTTP, no AI SDK.
7
6
  *
8
7
  * Edge-served open models (Llama / Mistral / Qwen / Gemma) at
9
8
  * `https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/v1`
@@ -11,25 +10,17 @@ import type { LanguageModel } from "../types/index.js";
11
10
  *
12
11
  * Required env: `CLOUDFLARE_API_KEY` + `CLOUDFLARE_ACCOUNT_ID`.
13
12
  *
13
+ * All request/stream/tool-loop orchestration lives in
14
+ * `OpenAIChatCompletionsProvider`; this class only declares configuration
15
+ * and provider-specific error mapping.
16
+ *
14
17
  * @see https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/
15
18
  */
16
- export declare class CloudflareProvider extends BaseProvider {
17
- private model;
18
- private apiKey;
19
- private baseURL;
19
+ export declare class CloudflareProvider extends OpenAIChatCompletionsProvider {
20
20
  constructor(modelName?: string, sdk?: unknown, _region?: string, credentials?: NeurolinkCredentials["cloudflare"]);
21
- protected executeStream(options: StreamOptions, _analysisSchema?: ValidationSchema): Promise<StreamResult>;
22
- private executeStreamInner;
23
21
  protected getProviderName(): AIProviderName;
24
22
  protected getDefaultModel(): string;
25
- protected getAISDKModel(): LanguageModel;
23
+ protected getFallbackModelName(): string;
24
+ protected getFallbackModels(): string[];
26
25
  protected formatProviderError(error: unknown): Error;
27
- validateConfiguration(): Promise<boolean>;
28
- getConfiguration(): {
29
- provider: AIProviderName;
30
- model: string;
31
- defaultModel: string;
32
- baseURL: string;
33
- };
34
26
  }
35
- export default CloudflareProvider;
@@ -1,20 +1,9 @@
1
- import { createOpenAI } from "@ai-sdk/openai";
2
1
  import { CloudflareModels } from "../constants/enums.js";
3
- import { BaseProvider } from "../core/baseProvider.js";
4
- import { DEFAULT_MAX_STEPS } from "../core/constants.js";
5
- import { streamAnalyticsCollector } from "../core/streamAnalytics.js";
6
- import { isNeuroLink } from "../neurolink.js";
7
- import { createLoggingFetch } from "../utils/loggingFetch.js";
8
- import { tracers, ATTR, withClientStreamSpan } from "../telemetry/index.js";
9
2
  import { AuthenticationError, InvalidModelError, NetworkError, ProviderError, RateLimitError, } from "../types/index.js";
10
3
  import { logger } from "../utils/logger.js";
11
4
  import { createCloudflareConfig, getProviderModel, validateApiKey, } from "../utils/providerConfig.js";
12
- import { composeAbortSignals, createTimeoutController, TimeoutError, } from "../utils/timeout.js";
13
- import { emitToolEndFromStepFinish } from "../utils/toolEndEmitter.js";
14
- import { resolveToolChoice } from "../utils/toolChoice.js";
15
- import { toAnalyticsStreamResult } from "./providerTypeUtils.js";
16
- import { stepCountIs } from "../utils/tool.js";
17
- import { streamText } from "../utils/generation.js";
5
+ import { TimeoutError } from "../utils/timeout.js";
6
+ import { OpenAIChatCompletionsProvider } from "./openaiChatCompletionsBase.js";
18
7
  /**
19
8
  * Cloudflare Workers AI exposes an OpenAI-compatible endpoint scoped per
20
9
  * account: `https://api.cloudflare.com/client/v4/accounts/{ACCOUNT_ID}/ai/v1`.
@@ -24,7 +13,7 @@ const buildCloudflareBaseURL = (accountId) => `https://api.cloudflare.com/client
24
13
  const getCloudflareApiKey = () => validateApiKey(createCloudflareConfig());
25
14
  const getDefaultCloudflareModel = () => getProviderModel("CLOUDFLARE_MODEL", CloudflareModels.LLAMA_3_3_70B_FAST);
26
15
  /**
27
- * Cloudflare Workers AI Provider
16
+ * Cloudflare Workers AI Provider — direct HTTP, no AI SDK.
28
17
  *
29
18
  * Edge-served open models (Llama / Mistral / Qwen / Gemma) at
30
19
  * `https://api.cloudflare.com/client/v4/accounts/{accountId}/ai/v1`
@@ -32,111 +21,50 @@ const getDefaultCloudflareModel = () => getProviderModel("CLOUDFLARE_MODEL", Clo
32
21
  *
33
22
  * Required env: `CLOUDFLARE_API_KEY` + `CLOUDFLARE_ACCOUNT_ID`.
34
23
  *
24
+ * All request/stream/tool-loop orchestration lives in
25
+ * `OpenAIChatCompletionsProvider`; this class only declares configuration
26
+ * and provider-specific error mapping.
27
+ *
35
28
  * @see https://developers.cloudflare.com/workers-ai/configuration/open-ai-compatibility/
36
29
  */
37
- export class CloudflareProvider extends BaseProvider {
38
- model;
39
- apiKey;
40
- baseURL;
30
+ export class CloudflareProvider extends OpenAIChatCompletionsProvider {
41
31
  constructor(modelName, sdk, _region, credentials) {
42
- const validatedNeurolink = isNeuroLink(sdk) ? sdk : undefined;
43
- super(modelName, "cloudflare", validatedNeurolink);
44
32
  const overrideApiKey = credentials?.apiKey?.trim();
45
- this.apiKey =
46
- overrideApiKey && overrideApiKey.length > 0
47
- ? overrideApiKey
48
- : getCloudflareApiKey();
33
+ const apiKey = overrideApiKey && overrideApiKey.length > 0
34
+ ? overrideApiKey
35
+ : getCloudflareApiKey();
49
36
  const accountId = (credentials?.accountId ??
50
37
  process.env.CLOUDFLARE_ACCOUNT_ID ??
51
38
  "").trim();
52
39
  if (!accountId) {
53
40
  throw new Error("CLOUDFLARE_ACCOUNT_ID is required (or pass credentials.cloudflare.accountId). Get the account id from https://dash.cloudflare.com/");
54
41
  }
55
- this.baseURL = credentials?.baseURL ?? buildCloudflareBaseURL(accountId);
56
- const cloudflare = createOpenAI({
57
- apiKey: this.apiKey,
58
- baseURL: this.baseURL,
59
- fetch: createLoggingFetch("cloudflare"),
60
- });
61
- this.model = cloudflare.chat(this.modelName);
42
+ const baseURL = credentials?.baseURL ?? buildCloudflareBaseURL(accountId);
43
+ super("cloudflare", modelName, sdk, { baseURL, apiKey });
62
44
  logger.debug("Cloudflare Workers AI Provider initialized", {
63
45
  modelName: this.modelName,
64
46
  providerName: this.providerName,
65
- baseURL: this.baseURL,
47
+ baseURL: this.config.baseURL,
66
48
  });
67
49
  }
68
- async executeStream(options, _analysisSchema) {
69
- return withClientStreamSpan({
70
- name: "neurolink.provider.stream",
71
- tracer: tracers.provider,
72
- attributes: {
73
- [ATTR.GEN_AI_SYSTEM]: "cloudflare",
74
- [ATTR.GEN_AI_MODEL]: this.modelName,
75
- [ATTR.GEN_AI_OPERATION]: "stream",
76
- [ATTR.NL_STREAM_MODE]: true,
77
- },
78
- }, async () => this.executeStreamInner(options), (r) => r.stream, (r, wrapped) => ({ ...r, stream: wrapped }));
79
- }
80
- async executeStreamInner(options) {
81
- this.validateStreamOptions(options);
82
- const startTime = Date.now();
83
- const timeout = this.getTimeout(options);
84
- const timeoutController = createTimeoutController(timeout, this.providerName, "stream");
85
- try {
86
- const shouldUseTools = !options.disableTools && this.supportsTools();
87
- const tools = shouldUseTools
88
- ? options.tools || (await this.getAllTools())
89
- : {};
90
- const messages = await this.buildMessagesForStream(options);
91
- const model = await this.getAISDKModelWithMiddleware(options);
92
- const result = await streamText({
93
- model,
94
- messages,
95
- temperature: options.temperature,
96
- maxOutputTokens: options.maxTokens,
97
- tools,
98
- stopWhen: stepCountIs(options.maxSteps || DEFAULT_MAX_STEPS),
99
- toolChoice: resolveToolChoice(options, tools, shouldUseTools),
100
- abortSignal: composeAbortSignals(options.abortSignal, timeoutController?.controller.signal),
101
- experimental_telemetry: this.telemetryHandler.getTelemetryConfig(options),
102
- experimental_repairToolCall: this.getToolCallRepairFn(options),
103
- onStepFinish: ({ toolCalls, toolResults }) => {
104
- emitToolEndFromStepFinish(this.neurolink?.getEventEmitter(), toolResults);
105
- this.handleToolExecutionStorage(toolCalls, toolResults, options, new Date()).catch((error) => {
106
- logger.warn("[CloudflareProvider] Failed to store tool executions", {
107
- provider: this.providerName,
108
- error: error instanceof Error ? error.message : String(error),
109
- });
110
- });
111
- },
112
- });
113
- timeoutController?.cleanup();
114
- const transformedStream = this.createTextStream(result);
115
- const analyticsPromise = streamAnalyticsCollector.createAnalytics(this.providerName, this.modelName, toAnalyticsStreamResult(result), Date.now() - startTime, {
116
- requestId: `cloudflare-stream-${Date.now()}`,
117
- streamingMode: true,
118
- });
119
- return {
120
- stream: transformedStream,
121
- provider: this.providerName,
122
- model: this.modelName,
123
- analytics: analyticsPromise,
124
- metadata: { startTime, streamId: `cloudflare-${Date.now()}` },
125
- };
126
- }
127
- catch (error) {
128
- timeoutController?.cleanup();
129
- throw this.handleProviderError(error);
130
- }
131
- }
132
50
  getProviderName() {
133
- return this.providerName;
51
+ return "cloudflare";
134
52
  }
135
53
  getDefaultModel() {
136
54
  return getDefaultCloudflareModel();
137
55
  }
138
- getAISDKModel() {
139
- return this.model;
56
+ getFallbackModelName() {
57
+ return CloudflareModels.LLAMA_3_1_8B_FAST;
58
+ }
59
+ getFallbackModels() {
60
+ return [
61
+ CloudflareModels.LLAMA_3_3_70B_FAST,
62
+ CloudflareModels.LLAMA_3_1_70B_INSTRUCT,
63
+ CloudflareModels.LLAMA_3_1_8B_FAST,
64
+ CloudflareModels.LLAMA_3_2_11B_VISION,
65
+ CloudflareModels.MISTRAL_7B_INSTRUCT_V0_2,
66
+ CloudflareModels.QWEN_1P5_14B_CHAT_AWQ,
67
+ ];
140
68
  }
141
69
  formatProviderError(error) {
142
70
  if (error instanceof TimeoutError) {
@@ -159,16 +87,4 @@ export class CloudflareProvider extends BaseProvider {
159
87
  }
160
88
  return new ProviderError(`Cloudflare Workers AI error: ${message}`, "cloudflare");
161
89
  }
162
- async validateConfiguration() {
163
- return typeof this.apiKey === "string" && this.apiKey.trim().length > 0;
164
- }
165
- getConfiguration() {
166
- return {
167
- provider: this.providerName,
168
- model: this.modelName,
169
- defaultModel: getDefaultCloudflareModel(),
170
- baseURL: this.baseURL,
171
- };
172
- }
173
90
  }
174
- export default CloudflareProvider;
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "@juspay/neurolink",
3
- "version": "9.68.7",
3
+ "version": "9.68.8",
4
4
  "packageManager": "pnpm@10.15.1",
5
5
  "description": "Universal AI Development Platform with working MCP integration, multi-provider support, voice (TTS/STT/realtime), and professional CLI. 58+ external MCP servers discoverable, multimodal file processing, RAG pipelines. Build, test, and deploy AI applications with 21+ providers: OpenAI, Anthropic, Google AI Studio, Google Vertex, AWS Bedrock, Azure OpenAI, Mistral, LiteLLM, SageMaker, Hugging Face, Ollama, OpenAI-compatible, OpenRouter, DeepSeek, NVIDIA NIM, LM Studio, llama.cpp, plus voice (OpenAI TTS, ElevenLabs, Deepgram, Azure Speech).",
6
6
  "author": {