@push.rocks/smartai 0.5.11 → 0.7.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/dist_ts/00_commitinfo_data.js +2 -2
- package/dist_ts/abstract.classes.multimodal.d.ts +95 -0
- package/dist_ts/abstract.classes.multimodal.js +1 -1
- package/dist_ts/index.d.ts +6 -0
- package/dist_ts/index.js +7 -1
- package/dist_ts/provider.anthropic.d.ts +13 -1
- package/dist_ts/provider.anthropic.js +141 -5
- package/dist_ts/provider.exo.d.ts +10 -1
- package/dist_ts/provider.exo.js +16 -1
- package/dist_ts/provider.groq.d.ts +10 -1
- package/dist_ts/provider.groq.js +16 -1
- package/dist_ts/provider.ollama.d.ts +10 -1
- package/dist_ts/provider.ollama.js +16 -1
- package/dist_ts/provider.openai.d.ts +13 -0
- package/dist_ts/provider.openai.js +218 -1
- package/dist_ts/provider.perplexity.d.ts +10 -1
- package/dist_ts/provider.perplexity.js +72 -1
- package/dist_ts/provider.xai.d.ts +10 -0
- package/dist_ts/provider.xai.js +16 -1
- package/package.json +2 -1
- package/readme.md +56 -9
- package/ts/00_commitinfo_data.ts +1 -1
- package/ts/abstract.classes.multimodal.ts +103 -0
- package/ts/index.ts +6 -0
- package/ts/provider.anthropic.ts +168 -5
- package/ts/provider.exo.ts +28 -1
- package/ts/provider.groq.ts +28 -1
- package/ts/provider.ollama.ts +28 -1
- package/ts/provider.openai.ts +224 -1
- package/ts/provider.perplexity.ts +89 -1
- package/ts/provider.xai.ts +28 -1
package/ts/provider.openai.ts
CHANGED
|
@@ -9,13 +9,22 @@ export type TChatCompletionRequestMessage = {
|
|
|
9
9
|
};
|
|
10
10
|
|
|
11
11
|
import { MultiModalModel } from './abstract.classes.multimodal.js';
|
|
12
|
+
import type {
|
|
13
|
+
ResearchOptions,
|
|
14
|
+
ResearchResponse,
|
|
15
|
+
ImageGenerateOptions,
|
|
16
|
+
ImageEditOptions,
|
|
17
|
+
ImageResponse
|
|
18
|
+
} from './abstract.classes.multimodal.js';
|
|
12
19
|
|
|
13
20
|
export interface IOpenaiProviderOptions {
|
|
14
21
|
openaiToken: string;
|
|
15
22
|
chatModel?: string;
|
|
16
23
|
audioModel?: string;
|
|
17
24
|
visionModel?: string;
|
|
18
|
-
|
|
25
|
+
researchModel?: string;
|
|
26
|
+
imageModel?: string;
|
|
27
|
+
enableWebSearch?: boolean;
|
|
19
28
|
}
|
|
20
29
|
|
|
21
30
|
export class OpenAiProvider extends MultiModalModel {
|
|
@@ -229,4 +238,218 @@ export class OpenAiProvider extends MultiModalModel {
|
|
|
229
238
|
const result = await this.openAiApiClient.chat.completions.create(requestParams);
|
|
230
239
|
return result.choices[0].message.content || '';
|
|
231
240
|
}
|
|
241
|
+
|
|
242
|
+
public async research(optionsArg: ResearchOptions): Promise<ResearchResponse> {
|
|
243
|
+
// Determine which model to use - Deep Research API requires specific models
|
|
244
|
+
let model: string;
|
|
245
|
+
if (optionsArg.searchDepth === 'deep') {
|
|
246
|
+
model = this.options.researchModel || 'o4-mini-deep-research-2025-06-26';
|
|
247
|
+
} else {
|
|
248
|
+
// For basic/advanced, still use deep research models if web search is needed
|
|
249
|
+
if (optionsArg.includeWebSearch) {
|
|
250
|
+
model = this.options.researchModel || 'o4-mini-deep-research-2025-06-26';
|
|
251
|
+
} else {
|
|
252
|
+
model = this.options.chatModel || 'gpt-5-mini';
|
|
253
|
+
}
|
|
254
|
+
}
|
|
255
|
+
|
|
256
|
+
const systemMessage = 'You are a research assistant. Provide comprehensive answers with citations and sources when available.';
|
|
257
|
+
|
|
258
|
+
// Prepare request parameters using Deep Research API format
|
|
259
|
+
const requestParams: any = {
|
|
260
|
+
model,
|
|
261
|
+
instructions: systemMessage,
|
|
262
|
+
input: optionsArg.query
|
|
263
|
+
};
|
|
264
|
+
|
|
265
|
+
// Add web search tool if requested
|
|
266
|
+
if (optionsArg.includeWebSearch || optionsArg.searchDepth === 'deep') {
|
|
267
|
+
requestParams.tools = [
|
|
268
|
+
{
|
|
269
|
+
type: 'web_search_preview',
|
|
270
|
+
search_context_size: optionsArg.searchDepth === 'deep' ? 'high' :
|
|
271
|
+
optionsArg.searchDepth === 'advanced' ? 'medium' : 'low'
|
|
272
|
+
}
|
|
273
|
+
];
|
|
274
|
+
}
|
|
275
|
+
|
|
276
|
+
// Add background flag for deep research
|
|
277
|
+
if (optionsArg.background && optionsArg.searchDepth === 'deep') {
|
|
278
|
+
requestParams.background = true;
|
|
279
|
+
}
|
|
280
|
+
|
|
281
|
+
try {
|
|
282
|
+
// Execute the research request using Deep Research API
|
|
283
|
+
const result = await this.openAiApiClient.responses.create(requestParams);
|
|
284
|
+
|
|
285
|
+
// Extract the answer from output items
|
|
286
|
+
let answer = '';
|
|
287
|
+
const sources: Array<{ url: string; title: string; snippet: string }> = [];
|
|
288
|
+
const searchQueries: string[] = [];
|
|
289
|
+
|
|
290
|
+
// Process output items
|
|
291
|
+
for (const item of result.output || []) {
|
|
292
|
+
// Extract message content
|
|
293
|
+
if (item.type === 'message' && 'content' in item) {
|
|
294
|
+
const messageItem = item as any;
|
|
295
|
+
for (const contentItem of messageItem.content || []) {
|
|
296
|
+
if (contentItem.type === 'output_text' && 'text' in contentItem) {
|
|
297
|
+
answer += contentItem.text;
|
|
298
|
+
}
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
// Extract web search queries
|
|
303
|
+
if (item.type === 'web_search_call' && 'action' in item) {
|
|
304
|
+
const searchItem = item as any;
|
|
305
|
+
if (searchItem.action && searchItem.action.type === 'search' && 'query' in searchItem.action) {
|
|
306
|
+
searchQueries.push(searchItem.action.query);
|
|
307
|
+
}
|
|
308
|
+
}
|
|
309
|
+
}
|
|
310
|
+
|
|
311
|
+
// Parse sources from markdown links in the answer
|
|
312
|
+
const urlRegex = /\[([^\]]+)\]\(([^)]+)\)/g;
|
|
313
|
+
let match: RegExpExecArray | null;
|
|
314
|
+
|
|
315
|
+
while ((match = urlRegex.exec(answer)) !== null) {
|
|
316
|
+
sources.push({
|
|
317
|
+
title: match[1],
|
|
318
|
+
url: match[2],
|
|
319
|
+
snippet: ''
|
|
320
|
+
});
|
|
321
|
+
}
|
|
322
|
+
|
|
323
|
+
return {
|
|
324
|
+
answer,
|
|
325
|
+
sources,
|
|
326
|
+
searchQueries: searchQueries.length > 0 ? searchQueries : undefined,
|
|
327
|
+
metadata: {
|
|
328
|
+
model,
|
|
329
|
+
searchDepth: optionsArg.searchDepth || 'basic',
|
|
330
|
+
tokensUsed: result.usage?.total_tokens
|
|
331
|
+
}
|
|
332
|
+
};
|
|
333
|
+
} catch (error) {
|
|
334
|
+
console.error('Research API error:', error);
|
|
335
|
+
throw new Error(`Failed to perform research: ${error.message}`);
|
|
336
|
+
}
|
|
337
|
+
}
|
|
338
|
+
|
|
339
|
+
/**
|
|
340
|
+
* Image generation using OpenAI's gpt-image-1 or DALL-E models
|
|
341
|
+
*/
|
|
342
|
+
public async imageGenerate(optionsArg: ImageGenerateOptions): Promise<ImageResponse> {
|
|
343
|
+
const model = optionsArg.model || this.options.imageModel || 'gpt-image-1';
|
|
344
|
+
|
|
345
|
+
try {
|
|
346
|
+
const requestParams: any = {
|
|
347
|
+
model,
|
|
348
|
+
prompt: optionsArg.prompt,
|
|
349
|
+
n: optionsArg.n || 1,
|
|
350
|
+
};
|
|
351
|
+
|
|
352
|
+
// Add gpt-image-1 specific parameters
|
|
353
|
+
if (model === 'gpt-image-1') {
|
|
354
|
+
if (optionsArg.quality) requestParams.quality = optionsArg.quality;
|
|
355
|
+
if (optionsArg.size) requestParams.size = optionsArg.size;
|
|
356
|
+
if (optionsArg.background) requestParams.background = optionsArg.background;
|
|
357
|
+
if (optionsArg.outputFormat) requestParams.output_format = optionsArg.outputFormat;
|
|
358
|
+
if (optionsArg.outputCompression !== undefined) requestParams.output_compression = optionsArg.outputCompression;
|
|
359
|
+
if (optionsArg.moderation) requestParams.moderation = optionsArg.moderation;
|
|
360
|
+
if (optionsArg.stream !== undefined) requestParams.stream = optionsArg.stream;
|
|
361
|
+
if (optionsArg.partialImages !== undefined) requestParams.partial_images = optionsArg.partialImages;
|
|
362
|
+
} else if (model === 'dall-e-3') {
|
|
363
|
+
// DALL-E 3 specific parameters
|
|
364
|
+
if (optionsArg.quality) requestParams.quality = optionsArg.quality;
|
|
365
|
+
if (optionsArg.size) requestParams.size = optionsArg.size;
|
|
366
|
+
if (optionsArg.style) requestParams.style = optionsArg.style;
|
|
367
|
+
requestParams.response_format = 'b64_json'; // Always use base64 for consistency
|
|
368
|
+
} else if (model === 'dall-e-2') {
|
|
369
|
+
// DALL-E 2 specific parameters
|
|
370
|
+
if (optionsArg.size) requestParams.size = optionsArg.size;
|
|
371
|
+
requestParams.response_format = 'b64_json';
|
|
372
|
+
}
|
|
373
|
+
|
|
374
|
+
const result = await this.openAiApiClient.images.generate(requestParams);
|
|
375
|
+
|
|
376
|
+
const images = (result.data || []).map(img => ({
|
|
377
|
+
b64_json: img.b64_json,
|
|
378
|
+
url: img.url,
|
|
379
|
+
revisedPrompt: img.revised_prompt
|
|
380
|
+
}));
|
|
381
|
+
|
|
382
|
+
return {
|
|
383
|
+
images,
|
|
384
|
+
metadata: {
|
|
385
|
+
model,
|
|
386
|
+
quality: result.quality,
|
|
387
|
+
size: result.size,
|
|
388
|
+
outputFormat: result.output_format,
|
|
389
|
+
tokensUsed: result.usage?.total_tokens
|
|
390
|
+
}
|
|
391
|
+
};
|
|
392
|
+
} catch (error) {
|
|
393
|
+
console.error('Image generation error:', error);
|
|
394
|
+
throw new Error(`Failed to generate image: ${error.message}`);
|
|
395
|
+
}
|
|
396
|
+
}
|
|
397
|
+
|
|
398
|
+
/**
|
|
399
|
+
* Image editing using OpenAI's gpt-image-1 or DALL-E 2 models
|
|
400
|
+
*/
|
|
401
|
+
public async imageEdit(optionsArg: ImageEditOptions): Promise<ImageResponse> {
|
|
402
|
+
const model = optionsArg.model || this.options.imageModel || 'gpt-image-1';
|
|
403
|
+
|
|
404
|
+
try {
|
|
405
|
+
const requestParams: any = {
|
|
406
|
+
model,
|
|
407
|
+
image: optionsArg.image,
|
|
408
|
+
prompt: optionsArg.prompt,
|
|
409
|
+
n: optionsArg.n || 1,
|
|
410
|
+
};
|
|
411
|
+
|
|
412
|
+
// Add mask if provided
|
|
413
|
+
if (optionsArg.mask) {
|
|
414
|
+
requestParams.mask = optionsArg.mask;
|
|
415
|
+
}
|
|
416
|
+
|
|
417
|
+
// Add gpt-image-1 specific parameters
|
|
418
|
+
if (model === 'gpt-image-1') {
|
|
419
|
+
if (optionsArg.quality) requestParams.quality = optionsArg.quality;
|
|
420
|
+
if (optionsArg.size) requestParams.size = optionsArg.size;
|
|
421
|
+
if (optionsArg.background) requestParams.background = optionsArg.background;
|
|
422
|
+
if (optionsArg.outputFormat) requestParams.output_format = optionsArg.outputFormat;
|
|
423
|
+
if (optionsArg.outputCompression !== undefined) requestParams.output_compression = optionsArg.outputCompression;
|
|
424
|
+
if (optionsArg.stream !== undefined) requestParams.stream = optionsArg.stream;
|
|
425
|
+
if (optionsArg.partialImages !== undefined) requestParams.partial_images = optionsArg.partialImages;
|
|
426
|
+
} else if (model === 'dall-e-2') {
|
|
427
|
+
// DALL-E 2 specific parameters
|
|
428
|
+
if (optionsArg.size) requestParams.size = optionsArg.size;
|
|
429
|
+
requestParams.response_format = 'b64_json';
|
|
430
|
+
}
|
|
431
|
+
|
|
432
|
+
const result = await this.openAiApiClient.images.edit(requestParams);
|
|
433
|
+
|
|
434
|
+
const images = (result.data || []).map(img => ({
|
|
435
|
+
b64_json: img.b64_json,
|
|
436
|
+
url: img.url,
|
|
437
|
+
revisedPrompt: img.revised_prompt
|
|
438
|
+
}));
|
|
439
|
+
|
|
440
|
+
return {
|
|
441
|
+
images,
|
|
442
|
+
metadata: {
|
|
443
|
+
model,
|
|
444
|
+
quality: result.quality,
|
|
445
|
+
size: result.size,
|
|
446
|
+
outputFormat: result.output_format,
|
|
447
|
+
tokensUsed: result.usage?.total_tokens
|
|
448
|
+
}
|
|
449
|
+
};
|
|
450
|
+
} catch (error) {
|
|
451
|
+
console.error('Image edit error:', error);
|
|
452
|
+
throw new Error(`Failed to edit image: ${error.message}`);
|
|
453
|
+
}
|
|
454
|
+
}
|
|
232
455
|
}
|
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import * as paths from './paths.js';
|
|
3
3
|
import { MultiModalModel } from './abstract.classes.multimodal.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
ChatOptions,
|
|
6
|
+
ChatResponse,
|
|
7
|
+
ChatMessage,
|
|
8
|
+
ResearchOptions,
|
|
9
|
+
ResearchResponse,
|
|
10
|
+
ImageGenerateOptions,
|
|
11
|
+
ImageEditOptions,
|
|
12
|
+
ImageResponse
|
|
13
|
+
} from './abstract.classes.multimodal.js';
|
|
5
14
|
|
|
6
15
|
export interface IPerplexityProviderOptions {
|
|
7
16
|
perplexityToken: string;
|
|
@@ -168,4 +177,83 @@ export class PerplexityProvider extends MultiModalModel {
|
|
|
168
177
|
}): Promise<{ message: any }> {
|
|
169
178
|
throw new Error('Document processing is not supported by Perplexity.');
|
|
170
179
|
}
|
|
180
|
+
|
|
181
|
+
public async research(optionsArg: ResearchOptions): Promise<ResearchResponse> {
|
|
182
|
+
// Perplexity has Sonar models that are optimized for search
|
|
183
|
+
// sonar models: sonar, sonar-pro
|
|
184
|
+
const model = optionsArg.searchDepth === 'deep' ? 'sonar-pro' : 'sonar';
|
|
185
|
+
|
|
186
|
+
try {
|
|
187
|
+
const response = await fetch('https://api.perplexity.ai/chat/completions', {
|
|
188
|
+
method: 'POST',
|
|
189
|
+
headers: {
|
|
190
|
+
'Authorization': `Bearer ${this.options.perplexityToken}`,
|
|
191
|
+
'Content-Type': 'application/json',
|
|
192
|
+
},
|
|
193
|
+
body: JSON.stringify({
|
|
194
|
+
model,
|
|
195
|
+
messages: [
|
|
196
|
+
{
|
|
197
|
+
role: 'system',
|
|
198
|
+
content: 'You are a helpful research assistant. Provide accurate information with sources.'
|
|
199
|
+
},
|
|
200
|
+
{
|
|
201
|
+
role: 'user',
|
|
202
|
+
content: optionsArg.query
|
|
203
|
+
}
|
|
204
|
+
],
|
|
205
|
+
temperature: 0.7,
|
|
206
|
+
max_tokens: 4000
|
|
207
|
+
}),
|
|
208
|
+
});
|
|
209
|
+
|
|
210
|
+
if (!response.ok) {
|
|
211
|
+
throw new Error(`Perplexity API error: ${response.statusText}`);
|
|
212
|
+
}
|
|
213
|
+
|
|
214
|
+
const result = await response.json();
|
|
215
|
+
const answer = result.choices[0].message.content;
|
|
216
|
+
|
|
217
|
+
// Parse citations from the response
|
|
218
|
+
const sources: Array<{ url: string; title: string; snippet: string }> = [];
|
|
219
|
+
|
|
220
|
+
// Perplexity includes citations in the format [1], [2], etc. with sources listed
|
|
221
|
+
// This is a simplified parser - could be enhanced based on actual Perplexity response format
|
|
222
|
+
if (result.citations) {
|
|
223
|
+
for (const citation of result.citations) {
|
|
224
|
+
sources.push({
|
|
225
|
+
url: citation.url || '',
|
|
226
|
+
title: citation.title || '',
|
|
227
|
+
snippet: citation.snippet || ''
|
|
228
|
+
});
|
|
229
|
+
}
|
|
230
|
+
}
|
|
231
|
+
|
|
232
|
+
return {
|
|
233
|
+
answer,
|
|
234
|
+
sources,
|
|
235
|
+
metadata: {
|
|
236
|
+
model,
|
|
237
|
+
searchDepth: optionsArg.searchDepth || 'basic'
|
|
238
|
+
}
|
|
239
|
+
};
|
|
240
|
+
} catch (error) {
|
|
241
|
+
console.error('Perplexity research error:', error);
|
|
242
|
+
throw new Error(`Failed to perform research: ${error.message}`);
|
|
243
|
+
}
|
|
244
|
+
}
|
|
245
|
+
|
|
246
|
+
/**
|
|
247
|
+
* Image generation is not supported by Perplexity
|
|
248
|
+
*/
|
|
249
|
+
public async imageGenerate(optionsArg: ImageGenerateOptions): Promise<ImageResponse> {
|
|
250
|
+
throw new Error('Image generation is not supported by Perplexity. Please use OpenAI provider for image generation.');
|
|
251
|
+
}
|
|
252
|
+
|
|
253
|
+
/**
|
|
254
|
+
* Image editing is not supported by Perplexity
|
|
255
|
+
*/
|
|
256
|
+
public async imageEdit(optionsArg: ImageEditOptions): Promise<ImageResponse> {
|
|
257
|
+
throw new Error('Image editing is not supported by Perplexity. Please use OpenAI provider for image editing.');
|
|
258
|
+
}
|
|
171
259
|
}
|
package/ts/provider.xai.ts
CHANGED
|
@@ -1,7 +1,16 @@
|
|
|
1
1
|
import * as plugins from './plugins.js';
|
|
2
2
|
import * as paths from './paths.js';
|
|
3
3
|
import { MultiModalModel } from './abstract.classes.multimodal.js';
|
|
4
|
-
import type {
|
|
4
|
+
import type {
|
|
5
|
+
ChatOptions,
|
|
6
|
+
ChatResponse,
|
|
7
|
+
ChatMessage,
|
|
8
|
+
ResearchOptions,
|
|
9
|
+
ResearchResponse,
|
|
10
|
+
ImageGenerateOptions,
|
|
11
|
+
ImageEditOptions,
|
|
12
|
+
ImageResponse
|
|
13
|
+
} from './abstract.classes.multimodal.js';
|
|
5
14
|
import type { ChatCompletionMessageParam } from 'openai/resources/chat/completions';
|
|
6
15
|
|
|
7
16
|
export interface IXAIProviderOptions {
|
|
@@ -181,4 +190,22 @@ export class XAIProvider extends MultiModalModel {
|
|
|
181
190
|
message: completion.choices[0]?.message?.content || ''
|
|
182
191
|
};
|
|
183
192
|
}
|
|
193
|
+
|
|
194
|
+
public async research(optionsArg: ResearchOptions): Promise<ResearchResponse> {
|
|
195
|
+
throw new Error('Research capabilities are not yet supported by xAI provider.');
|
|
196
|
+
}
|
|
197
|
+
|
|
198
|
+
/**
|
|
199
|
+
* Image generation is not supported by xAI
|
|
200
|
+
*/
|
|
201
|
+
public async imageGenerate(optionsArg: ImageGenerateOptions): Promise<ImageResponse> {
|
|
202
|
+
throw new Error('Image generation is not supported by xAI. Please use OpenAI provider for image generation.');
|
|
203
|
+
}
|
|
204
|
+
|
|
205
|
+
/**
|
|
206
|
+
* Image editing is not supported by xAI
|
|
207
|
+
*/
|
|
208
|
+
public async imageEdit(optionsArg: ImageEditOptions): Promise<ImageResponse> {
|
|
209
|
+
throw new Error('Image editing is not supported by xAI. Please use OpenAI provider for image editing.');
|
|
210
|
+
}
|
|
184
211
|
}
|