@olane/o-intelligence 0.7.59 → 0.7.60
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/src/base-intelligence-router.tool.d.ts +135 -0
- package/dist/src/base-intelligence-router.tool.d.ts.map +1 -0
- package/dist/src/base-intelligence-router.tool.js +338 -0
- package/dist/src/base-intelligence.tool.d.ts +140 -0
- package/dist/src/base-intelligence.tool.d.ts.map +1 -0
- package/dist/src/base-intelligence.tool.js +153 -0
- package/dist/src/gemini-intelligence.tool.d.ts +12 -0
- package/dist/src/gemini-intelligence.tool.d.ts.map +1 -1
- package/dist/src/gemini-intelligence.tool.js +259 -0
- package/dist/src/index.d.ts +1 -0
- package/dist/src/index.d.ts.map +1 -1
- package/dist/src/index.js +1 -0
- package/dist/src/interfaces/provider-types.d.ts +421 -0
- package/dist/src/interfaces/provider-types.d.ts.map +1 -0
- package/dist/src/interfaces/provider-types.js +8 -0
- package/dist/src/methods/llm.methods.d.ts.map +1 -1
- package/dist/src/methods/llm.methods.js +84 -0
- package/dist/src/o-intelligence.tool.d.ts +1 -0
- package/dist/src/o-intelligence.tool.d.ts.map +1 -1
- package/dist/src/o-intelligence.tool.js +5 -2
- package/dist/src/openai-intelligence.tool.d.ts +4 -0
- package/dist/src/openai-intelligence.tool.d.ts.map +1 -1
- package/dist/src/openai-intelligence.tool.js +83 -0
- package/package.json +7 -7
|
@@ -0,0 +1,153 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* BaseIntelligenceTool - Abstract base class for LLM provider tools
|
|
3
|
+
*
|
|
4
|
+
* This base class extracts common patterns from all provider intelligence tools:
|
|
5
|
+
* - Validation (API keys, messages, prompts)
|
|
6
|
+
* - Error handling (throw errors, no error returns)
|
|
7
|
+
* - Streaming vs non-streaming patterns
|
|
8
|
+
* - Tool method templates (_tool_completion, _tool_generate, etc.)
|
|
9
|
+
*
|
|
10
|
+
* Provider-specific implementations extend this class and implement:
|
|
11
|
+
* - getApiKeyEnvVar(): Returns the environment variable name for the API key
|
|
12
|
+
* - callCompletion(params): Makes the actual API call for completion
|
|
13
|
+
* - streamCompletion(params): Handles streaming completion
|
|
14
|
+
* - callGenerate(params): Makes the actual API call for generation
|
|
15
|
+
* - streamGenerate(params): Handles streaming generation
|
|
16
|
+
*
|
|
17
|
+
* Subclasses can use either HTTP fetch() or official SDKs with Braintrust instrumentation.
|
|
18
|
+
*/
|
|
19
|
+
import { oLaneTool } from '@olane/o-lane';
|
|
20
|
+
import { StreamUtils } from '@olane/o-node';
|
|
21
|
+
/**
|
|
22
|
+
* Abstract base class for intelligence provider tools
|
|
23
|
+
*
|
|
24
|
+
* Usage (subclass example):
|
|
25
|
+
* ```typescript
|
|
26
|
+
* export class AnthropicIntelligenceTool extends BaseIntelligenceTool {
|
|
27
|
+
* constructor(config: oNodeToolConfig) {
|
|
28
|
+
* super({
|
|
29
|
+
* ...config,
|
|
30
|
+
* address: new oAddress('o://anthropic'),
|
|
31
|
+
* description: 'Anthropic LLM provider',
|
|
32
|
+
* defaultModel: 'claude-sonnet-4-5-20250929',
|
|
33
|
+
* });
|
|
34
|
+
* }
|
|
35
|
+
*
|
|
36
|
+
* protected getApiKeyEnvVar(): string {
|
|
37
|
+
* return 'ANTHROPIC_API_KEY';
|
|
38
|
+
* }
|
|
39
|
+
*
|
|
40
|
+
* protected async callCompletion(params: any): Promise<ToolResult> {
|
|
41
|
+
* // Anthropic-specific HTTP implementation or SDK call
|
|
42
|
+
* }
|
|
43
|
+
*
|
|
44
|
+
* protected async *streamCompletion(params: any): AsyncGenerator<ToolResult> {
|
|
45
|
+
* // Anthropic-specific streaming implementation
|
|
46
|
+
* }
|
|
47
|
+
* }
|
|
48
|
+
* ```
|
|
49
|
+
*/
|
|
50
|
+
export class BaseIntelligenceTool extends oLaneTool {
|
|
51
|
+
constructor(config) {
|
|
52
|
+
super({
|
|
53
|
+
...config,
|
|
54
|
+
dependencies: config.dependencies || [],
|
|
55
|
+
});
|
|
56
|
+
this.defaultModel = config.defaultModel || '';
|
|
57
|
+
this.apiKey = config.apiKey || process.env[this.getApiKeyEnvVar()] || '';
|
|
58
|
+
}
|
|
59
|
+
/**
|
|
60
|
+
* Shared validation: API key
|
|
61
|
+
* ✅ Throws error for validation failure
|
|
62
|
+
*/
|
|
63
|
+
validateApiKey(apiKey) {
|
|
64
|
+
if (!apiKey) {
|
|
65
|
+
throw new Error(`${this.getApiKeyEnvVar()} is required`);
|
|
66
|
+
}
|
|
67
|
+
}
|
|
68
|
+
/**
|
|
69
|
+
* Shared validation: Messages array
|
|
70
|
+
* ✅ Throws error for validation failure
|
|
71
|
+
*/
|
|
72
|
+
validateMessages(messages) {
|
|
73
|
+
if (!messages || !Array.isArray(messages)) {
|
|
74
|
+
throw new Error('"messages" array is required');
|
|
75
|
+
}
|
|
76
|
+
if (messages.length === 0) {
|
|
77
|
+
throw new Error('"messages" array cannot be empty');
|
|
78
|
+
}
|
|
79
|
+
}
|
|
80
|
+
/**
|
|
81
|
+
* Shared validation: Prompt string
|
|
82
|
+
* ✅ Throws error for validation failure
|
|
83
|
+
*/
|
|
84
|
+
validatePrompt(prompt) {
|
|
85
|
+
if (!prompt) {
|
|
86
|
+
throw new Error('Prompt is required');
|
|
87
|
+
}
|
|
88
|
+
if (typeof prompt !== 'string') {
|
|
89
|
+
throw new Error('Prompt must be a string');
|
|
90
|
+
}
|
|
91
|
+
}
|
|
92
|
+
/**
|
|
93
|
+
* Tool method: Chat completion
|
|
94
|
+
* ✅ Template method pattern - delegates to subclass
|
|
95
|
+
* ✅ Handles streaming vs non-streaming
|
|
96
|
+
* ✅ Throws errors (base class wraps them)
|
|
97
|
+
*/
|
|
98
|
+
async _tool_completion(request) {
|
|
99
|
+
const params = request.params;
|
|
100
|
+
const { _isStreaming = false } = params;
|
|
101
|
+
if (_isStreaming) {
|
|
102
|
+
this.logger.debug('Streaming completion...');
|
|
103
|
+
const gen = this.streamCompletion(params);
|
|
104
|
+
return StreamUtils.processGenerator(request, gen, request.stream);
|
|
105
|
+
}
|
|
106
|
+
try {
|
|
107
|
+
return await this.callCompletion(params);
|
|
108
|
+
}
|
|
109
|
+
catch (error) {
|
|
110
|
+
throw new Error(`Failed to complete chat: ${error.message}`);
|
|
111
|
+
}
|
|
112
|
+
}
|
|
113
|
+
/**
|
|
114
|
+
* Tool method: Text generation
|
|
115
|
+
* ✅ Template method pattern - delegates to subclass
|
|
116
|
+
* ✅ Handles streaming vs non-streaming
|
|
117
|
+
* ✅ Throws errors (base class wraps them)
|
|
118
|
+
*/
|
|
119
|
+
async _tool_generate(request) {
|
|
120
|
+
const params = request.params;
|
|
121
|
+
const { _isStreaming = false } = params;
|
|
122
|
+
if (_isStreaming) {
|
|
123
|
+
return StreamUtils.processGenerator(request, this.streamGenerate(params), request.stream);
|
|
124
|
+
}
|
|
125
|
+
try {
|
|
126
|
+
return await this.callGenerate(params);
|
|
127
|
+
}
|
|
128
|
+
catch (error) {
|
|
129
|
+
throw new Error(`Failed to generate text: ${error.message}`);
|
|
130
|
+
}
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Tool method: List models
|
|
134
|
+
* Default implementation - subclasses can override
|
|
135
|
+
*/
|
|
136
|
+
async _tool_list_models(request) {
|
|
137
|
+
throw new Error('list_models not implemented for this provider');
|
|
138
|
+
}
|
|
139
|
+
/**
|
|
140
|
+
* Tool method: Get model info
|
|
141
|
+
* Default implementation - subclasses can override
|
|
142
|
+
*/
|
|
143
|
+
async _tool_model_info(request) {
|
|
144
|
+
throw new Error('model_info not implemented for this provider');
|
|
145
|
+
}
|
|
146
|
+
/**
|
|
147
|
+
* Tool method: Check API status
|
|
148
|
+
* Default implementation - subclasses can override
|
|
149
|
+
*/
|
|
150
|
+
async _tool_status(request) {
|
|
151
|
+
throw new Error('status check not implemented for this provider');
|
|
152
|
+
}
|
|
153
|
+
}
|
|
@@ -35,5 +35,17 @@ export declare class GeminiIntelligenceTool extends oLaneTool {
|
|
|
35
35
|
* Check Gemini API status
|
|
36
36
|
*/
|
|
37
37
|
_tool_status(request: oRequest): Promise<ToolResult>;
|
|
38
|
+
/**
|
|
39
|
+
* Generate image from text prompt using Gemini nano-banana models
|
|
40
|
+
*/
|
|
41
|
+
_tool_generate_image(request: oRequest): Promise<ToolResult>;
|
|
42
|
+
/**
|
|
43
|
+
* Edit or transform an existing image using Gemini nano-banana models
|
|
44
|
+
*/
|
|
45
|
+
_tool_edit_image(request: oRequest): Promise<ToolResult>;
|
|
46
|
+
/**
|
|
47
|
+
* Helper method to encode image file to base64
|
|
48
|
+
*/
|
|
49
|
+
private encodeImageToBase64;
|
|
38
50
|
}
|
|
39
51
|
//# sourceMappingURL=gemini-intelligence.tool.d.ts.map
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"gemini-intelligence.tool.d.ts","sourceRoot":"","sources":["../../src/gemini-intelligence.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAEL,eAAe,EACf,cAAc,EAEf,MAAM,eAAe,CAAC;
|
|
1
|
+
{"version":3,"file":"gemini-intelligence.tool.d.ts","sourceRoot":"","sources":["../../src/gemini-intelligence.tool.ts"],"names":[],"mappings":"AAAA,OAAO,EAAY,QAAQ,EAAE,MAAM,eAAe,CAAC;AACnD,OAAO,EAAE,UAAU,EAAE,MAAM,eAAe,CAAC;AAE3C,OAAO,EAAE,SAAS,EAAE,MAAM,eAAe,CAAC;AAC1C,OAAO,EAEL,eAAe,EACf,cAAc,EAEf,MAAM,eAAe,CAAC;AAiJvB,qBAAa,sBAAuB,SAAQ,SAAS;IACnD,OAAO,CAAC,MAAM,CAA4C;IAC1D,OAAO,CAAC,OAAO,CAAU;IACzB,OAAO,CAAC,YAAY,CAAU;gBAElB,MAAM,EAAE,eAAe;IAUnC;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IA6FpE;;OAEG;YACY,iBAAiB;IA8HhC;;OAEG;IACG,cAAc,CAAC,OAAO,EAAE,cAAc,GAAG,OAAO,CAAC,UAAU,CAAC;IA8FlE;;OAEG;YACY,eAAe;IA+H9B;;OAEG;IACG,iBAAiB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IA0C/D;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IA4C9D;;OAEG;IACG,YAAY,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAkC1D;;OAEG;IACG,oBAAoB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IA+GlE;;OAEG;IACG,gBAAgB,CAAC,OAAO,EAAE,QAAQ,GAAG,OAAO,CAAC,UAAU,CAAC;IAyJ9D;;OAEG;YACW,mBAAmB;CA4BlC"}
|
|
@@ -2,6 +2,7 @@ import { oAddress } from '@olane/o-core';
|
|
|
2
2
|
import { LLM_PARAMS } from './methods/llm.methods.js';
|
|
3
3
|
import { oLaneTool } from '@olane/o-lane';
|
|
4
4
|
import { StreamUtils, } from '@olane/o-node';
|
|
5
|
+
import { readFile } from 'fs/promises';
|
|
5
6
|
export class GeminiIntelligenceTool extends oLaneTool {
|
|
6
7
|
constructor(config) {
|
|
7
8
|
super({
|
|
@@ -497,4 +498,262 @@ export class GeminiIntelligenceTool extends oLaneTool {
|
|
|
497
498
|
};
|
|
498
499
|
}
|
|
499
500
|
}
|
|
501
|
+
/**
|
|
502
|
+
* Generate image from text prompt using Gemini nano-banana models
|
|
503
|
+
*/
|
|
504
|
+
async _tool_generate_image(request) {
|
|
505
|
+
try {
|
|
506
|
+
const params = request.params;
|
|
507
|
+
const { model = 'gemini-2.5-flash-image', prompt, aspectRatio = '1:1', imageSize = '2K', negativePrompt, } = params;
|
|
508
|
+
if (!this.apiKey) {
|
|
509
|
+
return {
|
|
510
|
+
success: false,
|
|
511
|
+
error: 'Gemini API key is required',
|
|
512
|
+
};
|
|
513
|
+
}
|
|
514
|
+
if (!prompt) {
|
|
515
|
+
return {
|
|
516
|
+
success: false,
|
|
517
|
+
error: 'Prompt is required',
|
|
518
|
+
};
|
|
519
|
+
}
|
|
520
|
+
// Build the full prompt with negative prompt if provided
|
|
521
|
+
const fullPrompt = negativePrompt
|
|
522
|
+
? `${prompt}\n\nAvoid: ${negativePrompt}`
|
|
523
|
+
: prompt;
|
|
524
|
+
const imageRequest = {
|
|
525
|
+
contents: [
|
|
526
|
+
{
|
|
527
|
+
parts: [{ text: fullPrompt }],
|
|
528
|
+
},
|
|
529
|
+
],
|
|
530
|
+
generationConfig: {
|
|
531
|
+
responseModalities: ['TEXT', 'IMAGE'],
|
|
532
|
+
imageConfig: {
|
|
533
|
+
aspectRatio: aspectRatio,
|
|
534
|
+
imageSize: imageSize,
|
|
535
|
+
},
|
|
536
|
+
},
|
|
537
|
+
};
|
|
538
|
+
const response = await fetch(`${this.baseUrl}/models/${model}:generateContent?key=${this.apiKey}`, {
|
|
539
|
+
method: 'POST',
|
|
540
|
+
headers: {
|
|
541
|
+
'Content-Type': 'application/json',
|
|
542
|
+
},
|
|
543
|
+
body: JSON.stringify(imageRequest),
|
|
544
|
+
});
|
|
545
|
+
if (!response.ok) {
|
|
546
|
+
const errorText = await response.text();
|
|
547
|
+
return {
|
|
548
|
+
success: false,
|
|
549
|
+
error: `Gemini API error: ${response.status} - ${errorText}`,
|
|
550
|
+
};
|
|
551
|
+
}
|
|
552
|
+
const result = (await response.json());
|
|
553
|
+
if (!result.candidates || result.candidates.length === 0) {
|
|
554
|
+
return {
|
|
555
|
+
success: false,
|
|
556
|
+
error: 'No response generated from Gemini',
|
|
557
|
+
};
|
|
558
|
+
}
|
|
559
|
+
// Extract image and text from response parts
|
|
560
|
+
const parts = result.candidates[0].content.parts;
|
|
561
|
+
let imageData;
|
|
562
|
+
let description;
|
|
563
|
+
for (const part of parts) {
|
|
564
|
+
if (part.inline_data) {
|
|
565
|
+
imageData = part.inline_data.data;
|
|
566
|
+
}
|
|
567
|
+
else if (part.text) {
|
|
568
|
+
description = part.text;
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
if (!imageData) {
|
|
572
|
+
return {
|
|
573
|
+
success: false,
|
|
574
|
+
error: 'No image data in response',
|
|
575
|
+
};
|
|
576
|
+
}
|
|
577
|
+
return {
|
|
578
|
+
success: true,
|
|
579
|
+
imageData,
|
|
580
|
+
description,
|
|
581
|
+
model,
|
|
582
|
+
aspectRatio,
|
|
583
|
+
imageSize,
|
|
584
|
+
usage: result.usageMetadata,
|
|
585
|
+
};
|
|
586
|
+
}
|
|
587
|
+
catch (error) {
|
|
588
|
+
return {
|
|
589
|
+
success: false,
|
|
590
|
+
error: `Failed to generate image: ${error.message}`,
|
|
591
|
+
};
|
|
592
|
+
}
|
|
593
|
+
}
|
|
594
|
+
/**
|
|
595
|
+
* Edit or transform an existing image using Gemini nano-banana models
|
|
596
|
+
*/
|
|
597
|
+
async _tool_edit_image(request) {
|
|
598
|
+
try {
|
|
599
|
+
const params = request.params;
|
|
600
|
+
const { model = 'gemini-2.5-flash-image', prompt, image, aspectRatio, imageSize = '2K', } = params;
|
|
601
|
+
if (!this.apiKey) {
|
|
602
|
+
return {
|
|
603
|
+
success: false,
|
|
604
|
+
error: 'Gemini API key is required',
|
|
605
|
+
};
|
|
606
|
+
}
|
|
607
|
+
if (!prompt) {
|
|
608
|
+
return {
|
|
609
|
+
success: false,
|
|
610
|
+
error: 'Prompt is required',
|
|
611
|
+
};
|
|
612
|
+
}
|
|
613
|
+
if (!image) {
|
|
614
|
+
return {
|
|
615
|
+
success: false,
|
|
616
|
+
error: 'Image is required',
|
|
617
|
+
};
|
|
618
|
+
}
|
|
619
|
+
// Process image input (base64 or file path)
|
|
620
|
+
let imageBase64;
|
|
621
|
+
let mimeType = 'image/jpeg';
|
|
622
|
+
if (image.startsWith('data:')) {
|
|
623
|
+
// Extract base64 from data URL
|
|
624
|
+
const matches = image.match(/^data:([^;]+);base64,(.+)$/);
|
|
625
|
+
if (matches) {
|
|
626
|
+
mimeType = matches[1];
|
|
627
|
+
imageBase64 = matches[2];
|
|
628
|
+
}
|
|
629
|
+
else {
|
|
630
|
+
return {
|
|
631
|
+
success: false,
|
|
632
|
+
error: 'Invalid data URL format',
|
|
633
|
+
};
|
|
634
|
+
}
|
|
635
|
+
}
|
|
636
|
+
else if (image.startsWith('/') || image.includes(':\\')) {
|
|
637
|
+
// File path - convert to base64
|
|
638
|
+
const result = await this.encodeImageToBase64(image);
|
|
639
|
+
imageBase64 = result.data;
|
|
640
|
+
mimeType = result.mimeType;
|
|
641
|
+
}
|
|
642
|
+
else {
|
|
643
|
+
// Assume it's raw base64
|
|
644
|
+
imageBase64 = image;
|
|
645
|
+
// Try to detect mime type from base64 header
|
|
646
|
+
if (image.startsWith('/9j/')) {
|
|
647
|
+
mimeType = 'image/jpeg';
|
|
648
|
+
}
|
|
649
|
+
else if (image.startsWith('iVBORw0KGgo')) {
|
|
650
|
+
mimeType = 'image/png';
|
|
651
|
+
}
|
|
652
|
+
}
|
|
653
|
+
const imageRequest = {
|
|
654
|
+
contents: [
|
|
655
|
+
{
|
|
656
|
+
parts: [
|
|
657
|
+
{ text: prompt },
|
|
658
|
+
{
|
|
659
|
+
inline_data: {
|
|
660
|
+
mime_type: mimeType,
|
|
661
|
+
data: imageBase64,
|
|
662
|
+
},
|
|
663
|
+
},
|
|
664
|
+
],
|
|
665
|
+
},
|
|
666
|
+
],
|
|
667
|
+
generationConfig: {
|
|
668
|
+
responseModalities: ['TEXT', 'IMAGE'],
|
|
669
|
+
imageConfig: {
|
|
670
|
+
aspectRatio: aspectRatio,
|
|
671
|
+
imageSize: imageSize,
|
|
672
|
+
},
|
|
673
|
+
},
|
|
674
|
+
};
|
|
675
|
+
const response = await fetch(`${this.baseUrl}/models/${model}:generateContent?key=${this.apiKey}`, {
|
|
676
|
+
method: 'POST',
|
|
677
|
+
headers: {
|
|
678
|
+
'Content-Type': 'application/json',
|
|
679
|
+
},
|
|
680
|
+
body: JSON.stringify(imageRequest),
|
|
681
|
+
});
|
|
682
|
+
if (!response.ok) {
|
|
683
|
+
const errorText = await response.text();
|
|
684
|
+
return {
|
|
685
|
+
success: false,
|
|
686
|
+
error: `Gemini API error: ${response.status} - ${errorText}`,
|
|
687
|
+
};
|
|
688
|
+
}
|
|
689
|
+
const result = (await response.json());
|
|
690
|
+
if (!result.candidates || result.candidates.length === 0) {
|
|
691
|
+
return {
|
|
692
|
+
success: false,
|
|
693
|
+
error: 'No response generated from Gemini',
|
|
694
|
+
};
|
|
695
|
+
}
|
|
696
|
+
// Extract image and text from response parts
|
|
697
|
+
const parts = result.candidates[0].content.parts;
|
|
698
|
+
let outputImageData;
|
|
699
|
+
let description;
|
|
700
|
+
for (const part of parts) {
|
|
701
|
+
if (part.inline_data) {
|
|
702
|
+
outputImageData = part.inline_data.data;
|
|
703
|
+
}
|
|
704
|
+
else if (part.text) {
|
|
705
|
+
description = part.text;
|
|
706
|
+
}
|
|
707
|
+
}
|
|
708
|
+
if (!outputImageData) {
|
|
709
|
+
return {
|
|
710
|
+
success: false,
|
|
711
|
+
error: 'No image data in response',
|
|
712
|
+
};
|
|
713
|
+
}
|
|
714
|
+
return {
|
|
715
|
+
success: true,
|
|
716
|
+
imageData: outputImageData,
|
|
717
|
+
description,
|
|
718
|
+
model,
|
|
719
|
+
aspectRatio,
|
|
720
|
+
imageSize,
|
|
721
|
+
usage: result.usageMetadata,
|
|
722
|
+
};
|
|
723
|
+
}
|
|
724
|
+
catch (error) {
|
|
725
|
+
return {
|
|
726
|
+
success: false,
|
|
727
|
+
error: `Failed to edit image: ${error.message}`,
|
|
728
|
+
};
|
|
729
|
+
}
|
|
730
|
+
}
|
|
731
|
+
/**
|
|
732
|
+
* Helper method to encode image file to base64
|
|
733
|
+
*/
|
|
734
|
+
async encodeImageToBase64(filePath) {
|
|
735
|
+
try {
|
|
736
|
+
const buffer = await readFile(filePath);
|
|
737
|
+
const base64 = buffer.toString('base64');
|
|
738
|
+
// Detect MIME type from file extension
|
|
739
|
+
let mimeType = 'image/jpeg';
|
|
740
|
+
const lowerPath = filePath.toLowerCase();
|
|
741
|
+
if (lowerPath.endsWith('.png')) {
|
|
742
|
+
mimeType = 'image/png';
|
|
743
|
+
}
|
|
744
|
+
else if (lowerPath.endsWith('.jpg') || lowerPath.endsWith('.jpeg')) {
|
|
745
|
+
mimeType = 'image/jpeg';
|
|
746
|
+
}
|
|
747
|
+
else if (lowerPath.endsWith('.gif')) {
|
|
748
|
+
mimeType = 'image/gif';
|
|
749
|
+
}
|
|
750
|
+
else if (lowerPath.endsWith('.webp')) {
|
|
751
|
+
mimeType = 'image/webp';
|
|
752
|
+
}
|
|
753
|
+
return { data: base64, mimeType };
|
|
754
|
+
}
|
|
755
|
+
catch (error) {
|
|
756
|
+
throw new Error(`Failed to read image file: ${error.message}`);
|
|
757
|
+
}
|
|
758
|
+
}
|
|
500
759
|
}
|
package/dist/src/index.d.ts
CHANGED
|
@@ -5,4 +5,5 @@ export * from './gemini-intelligence.tool.js';
|
|
|
5
5
|
export * from './grok-intelligence.tool.js';
|
|
6
6
|
export * from './o-intelligence.tool.js';
|
|
7
7
|
export * from './methods/intelligence.methods.js';
|
|
8
|
+
export * from './perplexity-intelligence.tool.js';
|
|
8
9
|
//# sourceMappingURL=index.d.ts.map
|
package/dist/src/index.d.ts.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../src/index.ts"],"names":[],"mappings":"AAAA,cAAc,+BAA+B,CAAC;AAC9C,cAAc,+BAA+B,CAAC;AAC9C,cAAc,kCAAkC,CAAC;AACjD,cAAc,+BAA+B,CAAC;AAC9C,cAAc,6BAA6B,CAAC;AAC5C,cAAc,0BAA0B,CAAC;AACzC,cAAc,mCAAmC,CAAC;AAClD,cAAc,mCAAmC,CAAC"}
|
package/dist/src/index.js
CHANGED