@push.rocks/smartai 0.13.3 → 2.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.
Files changed (98) hide show
  1. package/dist_ts/00_commitinfo_data.js +3 -3
  2. package/dist_ts/index.d.ts +6 -11
  3. package/dist_ts/index.js +6 -12
  4. package/dist_ts/plugins.d.ts +10 -15
  5. package/dist_ts/plugins.js +13 -19
  6. package/dist_ts/smartai.classes.smartai.d.ts +7 -0
  7. package/dist_ts/smartai.classes.smartai.js +51 -0
  8. package/dist_ts/smartai.interfaces.d.ts +41 -0
  9. package/dist_ts/smartai.interfaces.js +2 -0
  10. package/dist_ts/smartai.middleware.anthropic.d.ts +7 -0
  11. package/dist_ts/smartai.middleware.anthropic.js +36 -0
  12. package/dist_ts/smartai.provider.ollama.d.ts +8 -0
  13. package/dist_ts/smartai.provider.ollama.js +378 -0
  14. package/dist_ts_audio/index.d.ts +9 -0
  15. package/dist_ts_audio/index.js +15 -0
  16. package/dist_ts_audio/plugins.d.ts +2 -0
  17. package/dist_ts_audio/plugins.js +3 -0
  18. package/dist_ts_document/index.d.ts +11 -0
  19. package/dist_ts_document/index.js +45 -0
  20. package/dist_ts_document/plugins.d.ts +3 -0
  21. package/dist_ts_document/plugins.js +4 -0
  22. package/dist_ts_image/index.d.ts +46 -0
  23. package/dist_ts_image/index.js +110 -0
  24. package/dist_ts_image/plugins.d.ts +3 -0
  25. package/dist_ts_image/plugins.js +4 -0
  26. package/dist_ts_research/index.d.ts +19 -0
  27. package/dist_ts_research/index.js +98 -0
  28. package/dist_ts_research/plugins.d.ts +2 -0
  29. package/dist_ts_research/plugins.js +3 -0
  30. package/dist_ts_vision/index.d.ts +8 -0
  31. package/dist_ts_vision/index.js +21 -0
  32. package/dist_ts_vision/plugins.d.ts +2 -0
  33. package/dist_ts_vision/plugins.js +3 -0
  34. package/package.json +50 -22
  35. package/readme.hints.md +34 -88
  36. package/readme.md +284 -547
  37. package/ts/00_commitinfo_data.ts +2 -2
  38. package/ts/index.ts +8 -11
  39. package/ts/plugins.ts +19 -35
  40. package/ts/smartai.classes.smartai.ts +51 -0
  41. package/ts/smartai.interfaces.ts +53 -0
  42. package/ts/smartai.middleware.anthropic.ts +38 -0
  43. package/ts/smartai.provider.ollama.ts +426 -0
  44. package/ts_audio/index.ts +24 -0
  45. package/ts_audio/plugins.ts +2 -0
  46. package/ts_document/index.ts +61 -0
  47. package/ts_document/plugins.ts +3 -0
  48. package/ts_image/index.ts +147 -0
  49. package/ts_image/plugins.ts +3 -0
  50. package/ts_research/index.ts +120 -0
  51. package/ts_research/plugins.ts +2 -0
  52. package/ts_vision/index.ts +29 -0
  53. package/ts_vision/plugins.ts +2 -0
  54. package/dist_ts/abstract.classes.multimodal.d.ts +0 -212
  55. package/dist_ts/abstract.classes.multimodal.js +0 -43
  56. package/dist_ts/classes.conversation.d.ts +0 -31
  57. package/dist_ts/classes.conversation.js +0 -150
  58. package/dist_ts/classes.smartai.d.ts +0 -59
  59. package/dist_ts/classes.smartai.js +0 -139
  60. package/dist_ts/classes.tts.d.ts +0 -6
  61. package/dist_ts/classes.tts.js +0 -10
  62. package/dist_ts/interfaces.d.ts +0 -1
  63. package/dist_ts/interfaces.js +0 -2
  64. package/dist_ts/paths.d.ts +0 -2
  65. package/dist_ts/paths.js +0 -4
  66. package/dist_ts/provider.anthropic.d.ts +0 -48
  67. package/dist_ts/provider.anthropic.js +0 -369
  68. package/dist_ts/provider.elevenlabs.d.ts +0 -43
  69. package/dist_ts/provider.elevenlabs.js +0 -64
  70. package/dist_ts/provider.exo.d.ts +0 -40
  71. package/dist_ts/provider.exo.js +0 -116
  72. package/dist_ts/provider.groq.d.ts +0 -39
  73. package/dist_ts/provider.groq.js +0 -178
  74. package/dist_ts/provider.mistral.d.ts +0 -61
  75. package/dist_ts/provider.mistral.js +0 -288
  76. package/dist_ts/provider.ollama.d.ts +0 -141
  77. package/dist_ts/provider.ollama.js +0 -529
  78. package/dist_ts/provider.openai.d.ts +0 -62
  79. package/dist_ts/provider.openai.js +0 -403
  80. package/dist_ts/provider.perplexity.d.ts +0 -37
  81. package/dist_ts/provider.perplexity.js +0 -215
  82. package/dist_ts/provider.xai.d.ts +0 -52
  83. package/dist_ts/provider.xai.js +0 -160
  84. package/ts/abstract.classes.multimodal.ts +0 -240
  85. package/ts/classes.conversation.ts +0 -176
  86. package/ts/classes.smartai.ts +0 -187
  87. package/ts/classes.tts.ts +0 -15
  88. package/ts/interfaces.ts +0 -0
  89. package/ts/paths.ts +0 -4
  90. package/ts/provider.anthropic.ts +0 -446
  91. package/ts/provider.elevenlabs.ts +0 -116
  92. package/ts/provider.exo.ts +0 -155
  93. package/ts/provider.groq.ts +0 -219
  94. package/ts/provider.mistral.ts +0 -352
  95. package/ts/provider.ollama.ts +0 -705
  96. package/ts/provider.openai.ts +0 -462
  97. package/ts/provider.perplexity.ts +0 -259
  98. package/ts/provider.xai.ts +0 -214
@@ -1,369 +0,0 @@
1
- import * as plugins from './plugins.js';
2
- import * as paths from './paths.js';
3
- import { MultiModalModel } from './abstract.classes.multimodal.js';
4
- export class AnthropicProvider extends MultiModalModel {
5
- constructor(optionsArg) {
6
- super();
7
- this.options = optionsArg; // Ensure the token is stored
8
- }
9
- async start() {
10
- await super.start();
11
- this.anthropicApiClient = new plugins.anthropic.default({
12
- apiKey: this.options.anthropicToken,
13
- });
14
- }
15
- async stop() {
16
- await super.stop();
17
- }
18
- /**
19
- * Returns the thinking configuration based on provider options.
20
- * Defaults to 'normal' mode (8000 tokens) if not specified.
21
- */
22
- getThinkingConfig() {
23
- const mode = this.options.extendedThinking ?? 'normal';
24
- const budgetMap = {
25
- quick: 2048,
26
- normal: 8000,
27
- deep: 16000,
28
- off: 0,
29
- };
30
- const budget = budgetMap[mode];
31
- return budget > 0 ? { type: 'enabled', budget_tokens: budget } : undefined;
32
- }
33
- async chatStream(input) {
34
- // Create a TextDecoder to handle incoming chunks
35
- const decoder = new TextDecoder();
36
- let buffer = '';
37
- let currentMessage = null;
38
- // Create a TransformStream to process the input
39
- const transform = new TransformStream({
40
- async transform(chunk, controller) {
41
- buffer += decoder.decode(chunk, { stream: true });
42
- // Try to parse complete JSON messages from the buffer
43
- while (true) {
44
- const newlineIndex = buffer.indexOf('\n');
45
- if (newlineIndex === -1)
46
- break;
47
- const line = buffer.slice(0, newlineIndex);
48
- buffer = buffer.slice(newlineIndex + 1);
49
- if (line.trim()) {
50
- try {
51
- const message = JSON.parse(line);
52
- currentMessage = {
53
- role: message.role || 'user',
54
- content: message.content || '',
55
- };
56
- }
57
- catch (e) {
58
- console.error('Failed to parse message:', e);
59
- }
60
- }
61
- }
62
- // If we have a complete message, send it to Anthropic
63
- if (currentMessage) {
64
- const thinkingConfig = this.getThinkingConfig();
65
- const stream = await this.anthropicApiClient.messages.create({
66
- model: 'claude-sonnet-4-5-20250929',
67
- messages: [{ role: currentMessage.role, content: currentMessage.content }],
68
- system: '',
69
- stream: true,
70
- max_tokens: 20000,
71
- ...(thinkingConfig && { thinking: thinkingConfig }),
72
- });
73
- // Process each chunk from Anthropic
74
- for await (const chunk of stream) {
75
- const content = chunk.delta?.text;
76
- if (content) {
77
- controller.enqueue(content);
78
- }
79
- }
80
- currentMessage = null;
81
- }
82
- },
83
- flush(controller) {
84
- if (buffer) {
85
- try {
86
- const message = JSON.parse(buffer);
87
- controller.enqueue(message.content || '');
88
- }
89
- catch (e) {
90
- console.error('Failed to parse remaining buffer:', e);
91
- }
92
- }
93
- }
94
- });
95
- // Connect the input to our transform stream
96
- return input.pipeThrough(transform);
97
- }
98
- // Implementing the synchronous chat interaction
99
- async chat(optionsArg) {
100
- // Convert message history to Anthropic format
101
- const messages = optionsArg.messageHistory.map(msg => ({
102
- role: msg.role === 'assistant' ? 'assistant' : 'user',
103
- content: msg.content
104
- }));
105
- const thinkingConfig = this.getThinkingConfig();
106
- const result = await this.anthropicApiClient.messages.create({
107
- model: 'claude-sonnet-4-5-20250929',
108
- system: optionsArg.systemMessage,
109
- messages: [
110
- ...messages,
111
- { role: 'user', content: optionsArg.userMessage }
112
- ],
113
- max_tokens: 20000,
114
- ...(thinkingConfig && { thinking: thinkingConfig }),
115
- });
116
- // Extract text content from the response
117
- let message = '';
118
- for (const block of result.content) {
119
- if ('text' in block) {
120
- message += block.text;
121
- }
122
- }
123
- return {
124
- role: 'assistant',
125
- message,
126
- };
127
- }
128
- async audio(optionsArg) {
129
- // Anthropic does not provide an audio API, so this method is not implemented.
130
- throw new Error('Audio generation is not yet supported by Anthropic.');
131
- }
132
- async vision(optionsArg) {
133
- const base64Image = optionsArg.image.toString('base64');
134
- const content = [
135
- {
136
- type: 'text',
137
- text: optionsArg.prompt
138
- },
139
- {
140
- type: 'image',
141
- source: {
142
- type: 'base64',
143
- media_type: 'image/jpeg',
144
- data: base64Image
145
- }
146
- }
147
- ];
148
- const thinkingConfig = this.getThinkingConfig();
149
- const result = await this.anthropicApiClient.messages.create({
150
- model: 'claude-sonnet-4-5-20250929',
151
- messages: [{
152
- role: 'user',
153
- content
154
- }],
155
- max_tokens: 10000,
156
- ...(thinkingConfig && { thinking: thinkingConfig }),
157
- });
158
- // Extract text content from the response
159
- let message = '';
160
- for (const block of result.content) {
161
- if ('text' in block) {
162
- message += block.text;
163
- }
164
- }
165
- return message;
166
- }
167
- async document(optionsArg) {
168
- // Ensure SmartPdf is initialized before processing documents
169
- await this.ensureSmartpdfReady();
170
- // Convert PDF documents to images using SmartPDF
171
- let documentImageBytesArray = [];
172
- for (const pdfDocument of optionsArg.pdfDocuments) {
173
- const documentImageArray = await this.smartpdfInstance.convertPDFToPngBytes(pdfDocument);
174
- documentImageBytesArray = documentImageBytesArray.concat(documentImageArray);
175
- }
176
- // Convert message history to Anthropic format
177
- const messages = optionsArg.messageHistory.map(msg => ({
178
- role: msg.role === 'assistant' ? 'assistant' : 'user',
179
- content: msg.content
180
- }));
181
- // Create content array with text and images
182
- const content = [
183
- {
184
- type: 'text',
185
- text: optionsArg.userMessage
186
- }
187
- ];
188
- // Add each document page as an image
189
- for (const imageBytes of documentImageBytesArray) {
190
- content.push({
191
- type: 'image',
192
- source: {
193
- type: 'base64',
194
- media_type: 'image/png',
195
- data: Buffer.from(imageBytes).toString('base64')
196
- }
197
- });
198
- }
199
- const thinkingConfig = this.getThinkingConfig();
200
- const result = await this.anthropicApiClient.messages.create({
201
- model: 'claude-sonnet-4-5-20250929',
202
- system: optionsArg.systemMessage,
203
- messages: [
204
- ...messages,
205
- { role: 'user', content }
206
- ],
207
- max_tokens: 20000,
208
- ...(thinkingConfig && { thinking: thinkingConfig }),
209
- });
210
- // Extract text content from the response
211
- let message = '';
212
- for (const block of result.content) {
213
- if ('text' in block) {
214
- message += block.text;
215
- }
216
- }
217
- return {
218
- message: {
219
- role: 'assistant',
220
- content: message
221
- }
222
- };
223
- }
224
- async research(optionsArg) {
225
- // Prepare the messages for the research request
226
- const systemMessage = `You are a research assistant with web search capabilities.
227
- Provide comprehensive, well-researched answers with citations and sources.
228
- When searching the web, be thorough and cite your sources accurately.`;
229
- try {
230
- // Build the tool configuration for web search
231
- const tools = [];
232
- if (this.options.enableWebSearch) {
233
- const webSearchTool = {
234
- type: 'web_search_20250305',
235
- name: 'web_search'
236
- };
237
- // Add optional parameters
238
- if (optionsArg.maxSources) {
239
- webSearchTool.max_uses = optionsArg.maxSources;
240
- }
241
- if (this.options.searchDomainAllowList?.length) {
242
- webSearchTool.allowed_domains = this.options.searchDomainAllowList;
243
- }
244
- else if (this.options.searchDomainBlockList?.length) {
245
- webSearchTool.blocked_domains = this.options.searchDomainBlockList;
246
- }
247
- tools.push(webSearchTool);
248
- }
249
- // Configure the request based on search depth
250
- const maxTokens = optionsArg.searchDepth === 'deep' ? 20000 :
251
- optionsArg.searchDepth === 'advanced' ? 20000 : 20000;
252
- // Add thinking configuration if enabled
253
- const thinkingConfig = this.getThinkingConfig();
254
- // Create the research request
255
- // Note: When thinking is enabled, temperature must be 1 (or omitted)
256
- const requestParams = {
257
- model: 'claude-sonnet-4-5-20250929',
258
- system: systemMessage,
259
- messages: [
260
- {
261
- role: 'user',
262
- content: optionsArg.query
263
- }
264
- ],
265
- max_tokens: maxTokens,
266
- // Only set temperature when thinking is NOT enabled
267
- ...(thinkingConfig ? {} : { temperature: 0.7 })
268
- };
269
- // Add tools if web search is enabled
270
- if (tools.length > 0) {
271
- requestParams.tools = tools;
272
- }
273
- // Add thinking configuration if enabled
274
- if (thinkingConfig) {
275
- requestParams.thinking = thinkingConfig;
276
- }
277
- // Execute the research request
278
- const result = await this.anthropicApiClient.messages.create(requestParams);
279
- // Extract the answer from content blocks
280
- let answer = '';
281
- const sources = [];
282
- const searchQueries = [];
283
- // Process content blocks
284
- for (const block of result.content) {
285
- if ('text' in block) {
286
- // Accumulate text content
287
- answer += block.text;
288
- // Extract citations if present
289
- if ('citations' in block && Array.isArray(block.citations)) {
290
- for (const citation of block.citations) {
291
- if (citation.type === 'web_search_result_location') {
292
- sources.push({
293
- title: citation.title || '',
294
- url: citation.url || '',
295
- snippet: citation.cited_text || ''
296
- });
297
- }
298
- }
299
- }
300
- }
301
- else if ('type' in block && block.type === 'server_tool_use') {
302
- // Extract search queries from server tool use
303
- if (block.name === 'web_search' && block.input && typeof block.input === 'object' && 'query' in block.input) {
304
- searchQueries.push(block.input.query);
305
- }
306
- }
307
- else if ('type' in block && block.type === 'web_search_tool_result') {
308
- // Extract sources from web search results
309
- if (Array.isArray(block.content)) {
310
- for (const result of block.content) {
311
- if (result.type === 'web_search_result') {
312
- // Only add if not already in sources (avoid duplicates from citations)
313
- if (!sources.some(s => s.url === result.url)) {
314
- sources.push({
315
- title: result.title || '',
316
- url: result.url || '',
317
- snippet: '' // Search results don't include snippets, only citations do
318
- });
319
- }
320
- }
321
- }
322
- }
323
- }
324
- }
325
- // Fallback: Parse markdown-style links if no citations found
326
- if (sources.length === 0) {
327
- const urlRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
328
- let match;
329
- while ((match = urlRegex.exec(answer)) !== null) {
330
- sources.push({
331
- title: match[1],
332
- url: match[2],
333
- snippet: ''
334
- });
335
- }
336
- }
337
- // Check if web search was used based on usage info
338
- const webSearchCount = result.usage?.server_tool_use?.web_search_requests || 0;
339
- return {
340
- answer,
341
- sources,
342
- searchQueries: searchQueries.length > 0 ? searchQueries : undefined,
343
- metadata: {
344
- model: 'claude-sonnet-4-5-20250929',
345
- searchDepth: optionsArg.searchDepth || 'basic',
346
- tokensUsed: result.usage?.output_tokens,
347
- webSearchesPerformed: webSearchCount
348
- }
349
- };
350
- }
351
- catch (error) {
352
- console.error('Anthropic research error:', error);
353
- throw new Error(`Failed to perform research: ${error.message}`);
354
- }
355
- }
356
- /**
357
- * Image generation is not supported by Anthropic
358
- */
359
- async imageGenerate(optionsArg) {
360
- throw new Error('Image generation is not supported by Anthropic. Claude can only analyze images, not generate them. Please use OpenAI provider for image generation.');
361
- }
362
- /**
363
- * Image editing is not supported by Anthropic
364
- */
365
- async imageEdit(optionsArg) {
366
- throw new Error('Image editing is not supported by Anthropic. Claude can only analyze images, not edit them. Please use OpenAI provider for image editing.');
367
- }
368
- }
369
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuYW50aHJvcGljLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvcHJvdmlkZXIuYW50aHJvcGljLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQXVCbkUsTUFBTSxPQUFPLGlCQUFrQixTQUFRLGVBQWU7SUFJcEQsWUFBWSxVQUFxQztRQUMvQyxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxPQUFPLEdBQUcsVUFBVSxDQUFBLENBQUMsNkJBQTZCO0lBQ3pELENBQUM7SUFFRCxLQUFLLENBQUMsS0FBSztRQUNULE1BQU0sS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO1FBQ3BCLElBQUksQ0FBQyxrQkFBa0IsR0FBRyxJQUFJLE9BQU8sQ0FBQyxTQUFTLENBQUMsT0FBTyxDQUFDO1lBQ3RELE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWM7U0FDcEMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVELEtBQUssQ0FBQyxJQUFJO1FBQ1IsTUFBTSxLQUFLLENBQUMsSUFBSSxFQUFFLENBQUM7SUFDckIsQ0FBQztJQUVEOzs7T0FHRztJQUNLLGlCQUFpQjtRQUN2QixNQUFNLElBQUksR0FBRyxJQUFJLENBQUMsT0FBTyxDQUFDLGdCQUFnQixJQUFJLFFBQVEsQ0FBQztRQUV2RCxNQUFNLFNBQVMsR0FBRztZQUNoQixLQUFLLEVBQUUsSUFBSTtZQUNYLE1BQU0sRUFBRSxJQUFJO1lBQ1osSUFBSSxFQUFFLEtBQUs7WUFDWCxHQUFHLEVBQUUsQ0FBQztTQUNQLENBQUM7UUFFRixNQUFNLE1BQU0sR0FBRyxTQUFTLENBQUMsSUFBSSxDQUFDLENBQUM7UUFFL0IsT0FBTyxNQUFNLEdBQUcsQ0FBQyxDQUFDLENBQUMs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
@@ -1,43 +0,0 @@
1
- import { MultiModalModel } from './abstract.classes.multimodal.js';
2
- import type { ChatOptions, ChatResponse, ResearchOptions, ResearchResponse, ImageGenerateOptions, ImageEditOptions, ImageResponse } from './abstract.classes.multimodal.js';
3
- export interface IElevenLabsProviderOptions {
4
- elevenlabsToken: string;
5
- defaultVoiceId?: string;
6
- defaultModelId?: string;
7
- }
8
- export interface IElevenLabsVoiceSettings {
9
- stability?: number;
10
- similarity_boost?: number;
11
- style?: number;
12
- use_speaker_boost?: boolean;
13
- }
14
- export declare class ElevenLabsProvider extends MultiModalModel {
15
- private options;
16
- private baseUrl;
17
- constructor(optionsArg: IElevenLabsProviderOptions);
18
- start(): Promise<void>;
19
- stop(): Promise<void>;
20
- chat(optionsArg: ChatOptions): Promise<ChatResponse>;
21
- chatStream(input: ReadableStream<Uint8Array>): Promise<ReadableStream<string>>;
22
- audio(optionsArg: {
23
- message: string;
24
- voiceId?: string;
25
- modelId?: string;
26
- voiceSettings?: IElevenLabsVoiceSettings;
27
- }): Promise<NodeJS.ReadableStream>;
28
- vision(optionsArg: {
29
- image: Buffer;
30
- prompt: string;
31
- }): Promise<string>;
32
- document(optionsArg: {
33
- systemMessage: string;
34
- userMessage: string;
35
- pdfDocuments: Uint8Array[];
36
- messageHistory: any[];
37
- }): Promise<{
38
- message: any;
39
- }>;
40
- research(optionsArg: ResearchOptions): Promise<ResearchResponse>;
41
- imageGenerate(optionsArg: ImageGenerateOptions): Promise<ImageResponse>;
42
- imageEdit(optionsArg: ImageEditOptions): Promise<ImageResponse>;
43
- }
@@ -1,64 +0,0 @@
1
- import * as plugins from './plugins.js';
2
- import { Readable } from 'stream';
3
- import { MultiModalModel } from './abstract.classes.multimodal.js';
4
- export class ElevenLabsProvider extends MultiModalModel {
5
- constructor(optionsArg) {
6
- super();
7
- this.baseUrl = 'https://api.elevenlabs.io/v1';
8
- this.options = optionsArg;
9
- }
10
- async start() {
11
- await super.start();
12
- }
13
- async stop() {
14
- await super.stop();
15
- }
16
- async chat(optionsArg) {
17
- throw new Error('ElevenLabs does not support chat functionality. This provider is specialized for text-to-speech only.');
18
- }
19
- async chatStream(input) {
20
- throw new Error('ElevenLabs does not support chat streaming functionality. This provider is specialized for text-to-speech only.');
21
- }
22
- async audio(optionsArg) {
23
- // Use Samara voice as default fallback
24
- const voiceId = optionsArg.voiceId || this.options.defaultVoiceId || '19STyYD15bswVz51nqLf';
25
- const modelId = optionsArg.modelId || this.options.defaultModelId || 'eleven_v3';
26
- const url = `${this.baseUrl}/text-to-speech/${voiceId}`;
27
- const requestBody = {
28
- text: optionsArg.message,
29
- model_id: modelId,
30
- };
31
- if (optionsArg.voiceSettings) {
32
- requestBody.voice_settings = optionsArg.voiceSettings;
33
- }
34
- const response = await plugins.smartrequest.SmartRequest.create()
35
- .url(url)
36
- .header('xi-api-key', this.options.elevenlabsToken)
37
- .json(requestBody)
38
- .autoDrain(false)
39
- .post();
40
- if (!response.ok) {
41
- const errorText = await response.text();
42
- throw new Error(`ElevenLabs API error: ${response.status} ${response.statusText} - ${errorText}`);
43
- }
44
- const webStream = response.stream();
45
- const nodeStream = Readable.fromWeb(webStream);
46
- return nodeStream;
47
- }
48
- async vision(optionsArg) {
49
- throw new Error('ElevenLabs does not support vision functionality. This provider is specialized for text-to-speech only.');
50
- }
51
- async document(optionsArg) {
52
- throw new Error('ElevenLabs does not support document processing. This provider is specialized for text-to-speech only.');
53
- }
54
- async research(optionsArg) {
55
- throw new Error('ElevenLabs does not support research capabilities. This provider is specialized for text-to-speech only.');
56
- }
57
- async imageGenerate(optionsArg) {
58
- throw new Error('ElevenLabs does not support image generation. This provider is specialized for text-to-speech only.');
59
- }
60
- async imageEdit(optionsArg) {
61
- throw new Error('ElevenLabs does not support image editing. This provider is specialized for text-to-speech only.');
62
- }
63
- }
64
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuZWxldmVubGFicy5qcyIsInNvdXJjZVJvb3QiOiIiLCJzb3VyY2VzIjpbIi4uL3RzL3Byb3ZpZGVyLmVsZXZlbmxhYnMudHMiXSwibmFtZXMiOltdLCJtYXBwaW5ncyI6IkFBQUEsT0FBTyxLQUFLLE9BQU8sTUFBTSxjQUFjLENBQUM7QUFDeEMsT0FBTyxFQUFFLFFBQVEsRUFBRSxNQUFNLFFBQVEsQ0FBQztBQUVsQyxPQUFPLEVBQUUsZUFBZSxFQUFFLE1BQU0sa0NBQWtDLENBQUM7QUF3Qm5FLE1BQU0sT0FBTyxrQkFBbUIsU0FBUSxlQUFlO0lBSXJELFlBQVksVUFBc0M7UUFDaEQsS0FBSyxFQUFFLENBQUM7UUFIRixZQUFPLEdBQVcsOEJBQThCLENBQUM7UUFJdkQsSUFBSSxDQUFDLE9BQU8sR0FBRyxVQUFVLENBQUM7SUFDNUIsQ0FBQztJQUVNLEtBQUssQ0FBQyxLQUFLO1FBQ2hCLE1BQU0sS0FBSyxDQUFDLEtBQUssRUFBRSxDQUFDO0lBQ3RCLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSTtRQUNmLE1BQU0sS0FBSyxDQUFDLElBQUksRUFBRSxDQUFDO0lBQ3JCLENBQUM7SUFFTSxLQUFLLENBQUMsSUFBSSxDQUFDLFVBQXVCO1FBQ3ZDLE1BQU0sSUFBSSxLQUFLLENBQUMsdUdBQXVHLENBQUMsQ0FBQztJQUMzSCxDQUFDO0lBRU0sS0FBSyxDQUFDLFVBQVUsQ0FBQyxLQUFpQztRQUN2RCxNQUFNLElBQUksS0FBSyxDQUFDLGlIQUFpSCxDQUFDLENBQUM7SUFDckksQ0FBQztJQUVNLEtBQUssQ0FBQyxLQUFLLENBQUMsVUFLbEI7UUFDQyx1Q0FBdUM7UUFDdkMsTUFBTSxPQUFPLEdBQUcsVUFBVSxDQUFDLE9BQU8sSUFBSSxJQUFJLENBQUMsT0FBTyxDQUFDLGNBQWMsSUFBSSxzQkFBc0IsQ0FBQztRQUU1RixNQUFNLE9BQU8sR0FBRyxVQUFVLENBQUMsT0FBTyxJQUFJLElBQUksQ0FBQyxPQUFPLENBQUMsY0FBYyxJQUFJLFdBQVcsQ0FBQztRQUVqRixNQUFNLEdBQUcsR0FBRyxHQUFHLElBQUksQ0FBQyxPQUFPLG1CQUFtQixPQUFPLEVBQUUsQ0FBQztRQUV4RCxNQUFNLFdBQVcsR0FBUTtZQUN2QixJQUFJLEVBQUUsVUFBVSxDQUFDLE9BQU87WUFDeEIsUUFBUSxFQUFFLE9BQU87U0FDbEIsQ0FBQztRQUVGLElBQUksVUFBVSxDQUFDLGFBQWEsRUFBRSxDQUFDO1lBQzdCLFdBQVcsQ0FBQyxjQUFjLEdBQUcsVUFBVSxDQUFDLGFBQWEsQ0FBQztRQUN4RCxDQUFDO1FBRUQsTUFBTSxRQUFRLEdBQUcsTUFBTSxPQUFPLENBQUMsWUFBWSxDQUFDLFlBQVksQ0FBQyxNQUFNLEVBQUU7YUFDOUQsR0FBRyxDQUFDLEdBQUcsQ0FBQzthQUNSLE1BQU0sQ0FBQyxZQUFZLEVBQUUsSUFBSSxDQUFDLE9BQU8sQ0FBQyxlQUFlLENBQUM7YUFDbEQsSUFBSSxDQUFDLFdBQVcsQ0FBQzthQUNqQixTQUFTLENBQUMsS0FBSyxDQUFDO2FBQ2hCLElBQUksRUFBRSxDQUFDO1FBRVYsSUFBSSxDQUFDLFFBQVEsQ0FBQyxFQUFFLEVBQUUsQ0FBQztZQUNqQixNQUFNLFNBQVMsR0FBRyxNQUFNLFFBQVEsQ0FBQyxJQUFJLEVBQUUsQ0FBQztZQUN4QyxNQUFNLElBQUksS0FBSyxDQUFDLHlCQUF5QixRQUFRLENBQUMsTUFBTSxJQUFJLFFBQVEsQ0FBQyxVQUFVLE1BQU0sU0FBUyxFQUFFLENBQUMsQ0FBQztRQUNwRyxDQUFDO1FBRUQsTUFBTSxTQUFTLEdBQUcsUUFBUSxDQUFDLE1BQU0sRUFBRSxDQUFDO1FBQ3BDLE1BQU0sVUFBVSxHQUFHLFFBQVEsQ0FBQyxPQUFPLENBQUMsU0FBZ0IsQ0FBQyxDQUFDO1FBQ3RELE9BQU8sVUFBVSxDQUFDO0lBQ3BCLENBQUM7SUFFTSxLQUFLLENBQUMsTUFBTSxDQUFDLFVBQTZDO1FBQy9ELE1BQU0sSUFBSSxLQUFLLENBQUMseUdBQXlHLENBQUMsQ0FBQztJQUM3SCxDQUFDO0lBRU0sS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUtyQjtRQUNDLE1BQU0sSUFBSSxLQUFLLENBQUMsd0dBQXdHLENBQUMsQ0FBQztJQUM1SCxDQUFDO0lBRU0sS0FBSyxDQUFDLFFBQVEsQ0FBQyxVQUEyQjtRQUMvQyxNQUFNLElBQUksS0FBSyxDQUFDLDBHQUEwRyxDQUFDLENBQUM7SUFDOUgsQ0FBQztJQUVNLEtBQUssQ0FBQyxhQUFhLENBQUMsVUFBZ0M7UUFDekQsTUFBTSxJQUFJLEtBQUssQ0FBQyxxR0FBcUcsQ0FBQyxDQUFDO0lBQ3pILENBQUM7SUFFTSxLQUFLLENBQUMsU0FBUyxDQUFDLFVBQTRCO1FBQ2pELE1BQU0sSUFBSSxLQUFLLENBQUMsa0dBQWtHLENBQUMsQ0FBQztJQUN0SCxDQUFDO0NBQ0YifQ==
@@ -1,40 +0,0 @@
1
- import * as plugins from './plugins.js';
2
- import { MultiModalModel } from './abstract.classes.multimodal.js';
3
- import type { ChatOptions, ChatResponse, ChatMessage, ResearchOptions, ResearchResponse, ImageGenerateOptions, ImageEditOptions, ImageResponse } from './abstract.classes.multimodal.js';
4
- export interface IExoProviderOptions {
5
- exoBaseUrl?: string;
6
- apiKey?: string;
7
- }
8
- export declare class ExoProvider extends MultiModalModel {
9
- private options;
10
- openAiApiClient: plugins.openai.default;
11
- constructor(optionsArg?: IExoProviderOptions);
12
- start(): Promise<void>;
13
- stop(): Promise<void>;
14
- chatStream(input: ReadableStream<Uint8Array>): Promise<ReadableStream<string>>;
15
- chat(options: ChatOptions): Promise<ChatResponse>;
16
- audio(optionsArg: {
17
- message: string;
18
- }): Promise<NodeJS.ReadableStream>;
19
- vision(optionsArg: {
20
- image: Buffer;
21
- prompt: string;
22
- }): Promise<string>;
23
- document(optionsArg: {
24
- systemMessage: string;
25
- userMessage: string;
26
- pdfDocuments: Uint8Array[];
27
- messageHistory: ChatMessage[];
28
- }): Promise<{
29
- message: any;
30
- }>;
31
- research(optionsArg: ResearchOptions): Promise<ResearchResponse>;
32
- /**
33
- * Image generation is not supported by Exo
34
- */
35
- imageGenerate(optionsArg: ImageGenerateOptions): Promise<ImageResponse>;
36
- /**
37
- * Image editing is not supported by Exo
38
- */
39
- imageEdit(optionsArg: ImageEditOptions): Promise<ImageResponse>;
40
- }
@@ -1,116 +0,0 @@
1
- import * as plugins from './plugins.js';
2
- import * as paths from './paths.js';
3
- import { MultiModalModel } from './abstract.classes.multimodal.js';
4
- export class ExoProvider extends MultiModalModel {
5
- constructor(optionsArg = {}) {
6
- super();
7
- this.options = {
8
- exoBaseUrl: 'http://localhost:8080/v1', // Default Exo API endpoint
9
- ...optionsArg
10
- };
11
- }
12
- async start() {
13
- this.openAiApiClient = new plugins.openai.default({
14
- apiKey: this.options.apiKey || 'not-needed', // Exo might not require an API key for local deployment
15
- baseURL: this.options.exoBaseUrl,
16
- });
17
- }
18
- async stop() { }
19
- async chatStream(input) {
20
- // Create a TextDecoder to handle incoming chunks
21
- const decoder = new TextDecoder();
22
- let buffer = '';
23
- let currentMessage = null;
24
- // Create a TransformStream to process the input
25
- const transform = new TransformStream({
26
- transform: async (chunk, controller) => {
27
- buffer += decoder.decode(chunk, { stream: true });
28
- // Try to parse complete JSON messages from the buffer
29
- while (true) {
30
- const newlineIndex = buffer.indexOf('\n');
31
- if (newlineIndex === -1)
32
- break;
33
- const line = buffer.slice(0, newlineIndex);
34
- buffer = buffer.slice(newlineIndex + 1);
35
- if (line.trim()) {
36
- try {
37
- const message = JSON.parse(line);
38
- currentMessage = message;
39
- // Process the message based on its type
40
- if (message.type === 'message') {
41
- const response = await this.chat({
42
- systemMessage: '',
43
- userMessage: message.content,
44
- messageHistory: [{ role: message.role, content: message.content }]
45
- });
46
- controller.enqueue(JSON.stringify(response) + '\n');
47
- }
48
- }
49
- catch (error) {
50
- console.error('Error processing message:', error);
51
- }
52
- }
53
- }
54
- },
55
- flush(controller) {
56
- if (buffer) {
57
- try {
58
- const message = JSON.parse(buffer);
59
- currentMessage = message;
60
- }
61
- catch (error) {
62
- console.error('Error processing remaining buffer:', error);
63
- }
64
- }
65
- }
66
- });
67
- return input.pipeThrough(transform);
68
- }
69
- async chat(options) {
70
- const messages = [
71
- { role: 'system', content: options.systemMessage },
72
- ...options.messageHistory,
73
- { role: 'user', content: options.userMessage }
74
- ];
75
- try {
76
- const response = await this.openAiApiClient.chat.completions.create({
77
- model: 'local-model', // Exo uses local models
78
- messages: messages,
79
- stream: false
80
- });
81
- return {
82
- role: 'assistant',
83
- message: response.choices[0]?.message?.content || ''
84
- };
85
- }
86
- catch (error) {
87
- console.error('Error in chat completion:', error);
88
- throw error;
89
- }
90
- }
91
- async audio(optionsArg) {
92
- throw new Error('Audio generation is not supported by Exo provider');
93
- }
94
- async vision(optionsArg) {
95
- throw new Error('Vision processing is not supported by Exo provider');
96
- }
97
- async document(optionsArg) {
98
- throw new Error('Document processing is not supported by Exo provider');
99
- }
100
- async research(optionsArg) {
101
- throw new Error('Research capabilities are not yet supported by Exo provider.');
102
- }
103
- /**
104
- * Image generation is not supported by Exo
105
- */
106
- async imageGenerate(optionsArg) {
107
- throw new Error('Image generation is not supported by Exo. Please use OpenAI provider for image generation.');
108
- }
109
- /**
110
- * Image editing is not supported by Exo
111
- */
112
- async imageEdit(optionsArg) {
113
- throw new Error('Image editing is not supported by Exo. Please use OpenAI provider for image editing.');
114
- }
115
- }
116
- //# sourceMappingURL=data:application/json;base64,eyJ2ZXJzaW9uIjozLCJmaWxlIjoicHJvdmlkZXIuZXhvLmpzIiwic291cmNlUm9vdCI6IiIsInNvdXJjZXMiOlsiLi4vdHMvcHJvdmlkZXIuZXhvLnRzIl0sIm5hbWVzIjpbXSwibWFwcGluZ3MiOiJBQUFBLE9BQU8sS0FBSyxPQUFPLE1BQU0sY0FBYyxDQUFDO0FBQ3hDLE9BQU8sS0FBSyxLQUFLLE1BQU0sWUFBWSxDQUFDO0FBQ3BDLE9BQU8sRUFBRSxlQUFlLEVBQUUsTUFBTSxrQ0FBa0MsQ0FBQztBQWtCbkUsTUFBTSxPQUFPLFdBQVksU0FBUSxlQUFlO0lBSTlDLFlBQVksYUFBa0MsRUFBRTtRQUM5QyxLQUFLLEVBQUUsQ0FBQztRQUNSLElBQUksQ0FBQyxPQUFPLEdBQUc7WUFDYixVQUFVLEVBQUUsMEJBQTBCLEVBQUcsMkJBQTJCO1lBQ3BFLEdBQUcsVUFBVTtTQUNkLENBQUM7SUFDSixDQUFDO0lBRU0sS0FBSyxDQUFDLEtBQUs7UUFDaEIsSUFBSSxDQUFDLGVBQWUsR0FBRyxJQUFJLE9BQU8sQ0FBQyxNQUFNLENBQUMsT0FBTyxDQUFDO1lBQ2hELE1BQU0sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLE1BQU0sSUFBSSxZQUFZLEVBQUcsd0RBQXdEO1lBQ3RHLE9BQU8sRUFBRSxJQUFJLENBQUMsT0FBTyxDQUFDLFVBQVU7U0FDakMsQ0FBQyxDQUFDO0lBQ0wsQ0FBQztJQUVNLEtBQUssQ0FBQyxJQUFJLEtBQUksQ0FBQztJQUVmLEtBQUssQ0FBQyxVQUFVLENBQUMsS0FBaUM7UUFDdkQsaURBQWlEO1FBQ2pELE1BQU0sT0FBTyxHQUFHLElBQUksV0FBVyxFQUFFLENBQUM7UUFDbEMsSUFBSSxNQUFNLEdBQUcsRUFBRSxDQUFDO1FBQ2hCLElBQUksY0FBYyxHQUE4QyxJQUFJLENBQUM7UUFFckUsZ0RBQWdEO1FBQ2hELE1BQU0sU0FBUyxHQUFHLElBQUksZUFBZSxDQUFxQjtZQUN4RCxTQUFTLEVBQUUsS0FBSyxFQUFFLEtBQUssRUFBRSxVQUFVLEVBQUUsRUFBRTtnQkFDckMsTUFBTSxJ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