onairos 2.0.7 → 2.0.9
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/SDK_MIGRATION_SUMMARY.md +140 -0
- package/dist/iframe.bundle.js +1 -1
- package/dist/iframe.bundle.js.map +1 -1
- package/dist/onairos.bundle.js +1 -1
- package/dist/onairos.bundle.js.map +1 -1
- package/dist/onairos.esm.js +1 -1
- package/dist/onairos.esm.js.map +1 -1
- package/onairos.d.ts +0 -182
- package/package.json +8 -18
- package/src/components/DataRequest.js +138 -127
- package/src/components/UniversalOnboarding.js +72 -18
- package/src/components/connectors/GmailConnector.js +177 -0
- package/src/components/connectors/InstagramConnector.js +171 -0
- package/src/components/connectors/LinkedInConnector.js +168 -0
- package/src/components/connectors/PinterestConnector.js +168 -0
- package/src/components/connectors/README.md +292 -0
- package/src/components/connectors/RedditConnector.js +168 -0
- package/src/components/connectors/YoutubeConnector.js +172 -0
- package/src/components/connectors/index.js +21 -0
- package/src/components/utils/UpdateConnections.js +43 -0
- package/src/iframe/DataRequestPage.jsx +5 -1
- package/src/index.js +0 -9
- package/src/onairos.jsx +0 -16
- package/src/onairosButton.jsx +2 -1
- package/src/overlay/overlay.js +1 -1
- package/src/sdk/LLMWrapper.js +0 -221
- package/src/sdk/MemoryManager.js +0 -290
- package/src/sdk/OnairosClient.js +0 -152
- package/src/sdk/SessionManager.js +0 -257
|
@@ -0,0 +1,172 @@
|
|
|
1
|
+
import React, { Component } from 'react';
|
|
2
|
+
|
|
3
|
+
class YoutubeConnector extends Component {
|
|
4
|
+
constructor(props) {
|
|
5
|
+
super(props);
|
|
6
|
+
this.state = {
|
|
7
|
+
connected: false,
|
|
8
|
+
open: false,
|
|
9
|
+
isConnecting: false,
|
|
10
|
+
};
|
|
11
|
+
this.handleClose = this.handleClose.bind(this);
|
|
12
|
+
this.handleOpen = this.handleOpen.bind(this);
|
|
13
|
+
this.youtubeConnect = this.youtubeConnect.bind(this);
|
|
14
|
+
this.setConnected = this.setConnected.bind(this);
|
|
15
|
+
this.setDisconnected = this.setDisconnected.bind(this);
|
|
16
|
+
}
|
|
17
|
+
|
|
18
|
+
setConnected() {
|
|
19
|
+
this.setState({ connected: true });
|
|
20
|
+
if (this.props.onConnectionChange) {
|
|
21
|
+
this.props.onConnectionChange('YouTube', true);
|
|
22
|
+
}
|
|
23
|
+
this.handleClose();
|
|
24
|
+
}
|
|
25
|
+
|
|
26
|
+
setDisconnected() {
|
|
27
|
+
// Call UpdateConnections API to remove connection
|
|
28
|
+
this.updateConnections('Remove', 'Youtube').then(() => {
|
|
29
|
+
this.setState({ connected: false });
|
|
30
|
+
if (this.props.onConnectionChange) {
|
|
31
|
+
this.props.onConnectionChange('YouTube', false);
|
|
32
|
+
}
|
|
33
|
+
this.handleClose();
|
|
34
|
+
}).catch((error) => {
|
|
35
|
+
console.error('Error removing YouTube connection:', error);
|
|
36
|
+
});
|
|
37
|
+
}
|
|
38
|
+
|
|
39
|
+
async updateConnections(updateType, newConnection) {
|
|
40
|
+
const jsonData = {
|
|
41
|
+
session: {
|
|
42
|
+
username: localStorage.getItem("username") || this.props.username
|
|
43
|
+
},
|
|
44
|
+
updateType,
|
|
45
|
+
newConnection
|
|
46
|
+
};
|
|
47
|
+
|
|
48
|
+
try {
|
|
49
|
+
const response = await fetch('https://api2.onairos.uk/connections/update', {
|
|
50
|
+
method: 'POST',
|
|
51
|
+
headers: {
|
|
52
|
+
'Content-Type': 'application/json',
|
|
53
|
+
},
|
|
54
|
+
body: JSON.stringify(jsonData),
|
|
55
|
+
});
|
|
56
|
+
return await response.json();
|
|
57
|
+
} catch (error) {
|
|
58
|
+
console.error('UpdateConnections error:', error);
|
|
59
|
+
throw error;
|
|
60
|
+
}
|
|
61
|
+
}
|
|
62
|
+
|
|
63
|
+
handleOpen() {
|
|
64
|
+
this.setState({ open: true });
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
handleClose() {
|
|
68
|
+
this.setState({ open: false });
|
|
69
|
+
if (this.props.onClose) {
|
|
70
|
+
this.props.onClose();
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
|
|
74
|
+
async youtubeConnect() {
|
|
75
|
+
this.setState({ isConnecting: true });
|
|
76
|
+
|
|
77
|
+
const jsonData = {
|
|
78
|
+
session: {
|
|
79
|
+
username: localStorage.getItem("username") || this.props.username
|
|
80
|
+
},
|
|
81
|
+
};
|
|
82
|
+
|
|
83
|
+
try {
|
|
84
|
+
const response = await fetch('https://api2.onairos.uk/youtube/authorize', {
|
|
85
|
+
method: 'POST',
|
|
86
|
+
headers: {
|
|
87
|
+
'Content-Type': 'application/json',
|
|
88
|
+
},
|
|
89
|
+
body: JSON.stringify(jsonData),
|
|
90
|
+
});
|
|
91
|
+
|
|
92
|
+
const result = await response.json();
|
|
93
|
+
|
|
94
|
+
if (result.youtubeURL) {
|
|
95
|
+
// Open OAuth URL in current window
|
|
96
|
+
window.location.href = result.youtubeURL;
|
|
97
|
+
} else {
|
|
98
|
+
console.error('No YouTube URL received');
|
|
99
|
+
this.setState({ isConnecting: false });
|
|
100
|
+
}
|
|
101
|
+
} catch (error) {
|
|
102
|
+
console.error('YouTube connection error:', error);
|
|
103
|
+
this.setState({ isConnecting: false });
|
|
104
|
+
}
|
|
105
|
+
}
|
|
106
|
+
|
|
107
|
+
render() {
|
|
108
|
+
const { open = this.props.open || this.state.open } = this.props;
|
|
109
|
+
|
|
110
|
+
if (!open) return null;
|
|
111
|
+
|
|
112
|
+
return (
|
|
113
|
+
<div className="fixed inset-0 bg-black bg-opacity-50 flex items-center justify-center z-50">
|
|
114
|
+
<div className="bg-white rounded-lg shadow-xl max-w-md w-full mx-4 max-h-[90vh] overflow-hidden">
|
|
115
|
+
<div className="p-6">
|
|
116
|
+
<h2 className="text-xl font-bold text-gray-900 mb-4">
|
|
117
|
+
Grant Onairos Access to your YouTube Account?
|
|
118
|
+
</h2>
|
|
119
|
+
|
|
120
|
+
<div className="space-y-4 text-gray-700">
|
|
121
|
+
<p>
|
|
122
|
+
Grant Permission to your YouTube Account, so we can build your Data Models.
|
|
123
|
+
</p>
|
|
124
|
+
|
|
125
|
+
<div>
|
|
126
|
+
<p className="font-medium mb-2">We will access your YouTube:</p>
|
|
127
|
+
<ul className="list-disc ml-6 space-y-1">
|
|
128
|
+
<li>Basic Account Info</li>
|
|
129
|
+
<li>Liked and Watched Videos</li>
|
|
130
|
+
<li>Subscribed Channels and Playlist Videos</li>
|
|
131
|
+
</ul>
|
|
132
|
+
</div>
|
|
133
|
+
|
|
134
|
+
<p>
|
|
135
|
+
We will delete all the data used once your Model is Created
|
|
136
|
+
</p>
|
|
137
|
+
|
|
138
|
+
<p className="text-sm">
|
|
139
|
+
<a href="https://onairos.uk/compliance-google-policy" className="text-blue-600 hover:underline">
|
|
140
|
+
Onairos
|
|
141
|
+
</a>{' '}
|
|
142
|
+
complies with{' '}
|
|
143
|
+
<a href="https://policies.google.com/privacy" className="text-blue-600 hover:underline">
|
|
144
|
+
Google API Services User Data Policy
|
|
145
|
+
</a>
|
|
146
|
+
</p>
|
|
147
|
+
</div>
|
|
148
|
+
|
|
149
|
+
<div className="flex space-x-3 mt-6">
|
|
150
|
+
<button
|
|
151
|
+
onClick={this.handleClose}
|
|
152
|
+
disabled={this.state.isConnecting}
|
|
153
|
+
className="flex-1 px-4 py-2 border border-gray-300 rounded-lg text-gray-700 hover:bg-gray-50 disabled:opacity-50"
|
|
154
|
+
>
|
|
155
|
+
Disagree
|
|
156
|
+
</button>
|
|
157
|
+
<button
|
|
158
|
+
onClick={this.youtubeConnect}
|
|
159
|
+
disabled={this.state.isConnecting}
|
|
160
|
+
className="flex-1 px-4 py-2 bg-blue-600 text-white rounded-lg hover:bg-blue-700 disabled:opacity-50"
|
|
161
|
+
>
|
|
162
|
+
{this.state.isConnecting ? 'Connecting...' : 'Agree'}
|
|
163
|
+
</button>
|
|
164
|
+
</div>
|
|
165
|
+
</div>
|
|
166
|
+
</div>
|
|
167
|
+
</div>
|
|
168
|
+
);
|
|
169
|
+
}
|
|
170
|
+
}
|
|
171
|
+
|
|
172
|
+
export default YoutubeConnector;
|
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* OAuth Connectors Index
|
|
3
|
+
* Exports all available OAuth connector components
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
export { default as YoutubeConnector } from './YoutubeConnector';
|
|
7
|
+
export { default as LinkedInConnector } from './LinkedInConnector';
|
|
8
|
+
export { default as InstagramConnector } from './InstagramConnector';
|
|
9
|
+
export { default as PinterestConnector } from './PinterestConnector';
|
|
10
|
+
export { default as RedditConnector } from './RedditConnector';
|
|
11
|
+
export { default as GmailConnector } from './GmailConnector';
|
|
12
|
+
|
|
13
|
+
// Platform configuration for easy reference
|
|
14
|
+
export const SUPPORTED_PLATFORMS = [
|
|
15
|
+
{ name: 'YouTube', connector: 'youtube', endpoint: '/youtube/authorize' },
|
|
16
|
+
{ name: 'LinkedIn', connector: 'linkedin', endpoint: '/linkedin/authorize' },
|
|
17
|
+
{ name: 'Instagram', connector: 'instagram', endpoint: '/instagram/authorize' },
|
|
18
|
+
{ name: 'Pinterest', connector: 'pinterest', endpoint: '/pinterest/authorize' },
|
|
19
|
+
{ name: 'Reddit', connector: 'reddit', endpoint: '/reddit/authorize' },
|
|
20
|
+
{ name: 'Gmail', connector: 'gmail', endpoint: '/gmail/authorize' }
|
|
21
|
+
];
|
|
@@ -0,0 +1,43 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* UpdateConnections Utility
|
|
3
|
+
* Handles adding and removing user connections to/from the Onairos server
|
|
4
|
+
*/
|
|
5
|
+
|
|
6
|
+
/**
|
|
7
|
+
* Update user connections on the Onairos server
|
|
8
|
+
* @param {Object} options - Update options
|
|
9
|
+
* @param {string} options.updateType - 'Add' or 'Remove'
|
|
10
|
+
* @param {string} options.newConnection - The connection name to add/remove
|
|
11
|
+
* @param {string} options.username - Username (optional, will use localStorage if not provided)
|
|
12
|
+
* @returns {Promise} - Promise resolving with the server response
|
|
13
|
+
*/
|
|
14
|
+
export default async function UpdateConnections({ updateType, newConnection, username = null }) {
|
|
15
|
+
const jsonData = {
|
|
16
|
+
session: {
|
|
17
|
+
username: username || localStorage.getItem("username")
|
|
18
|
+
},
|
|
19
|
+
updateType,
|
|
20
|
+
newConnection
|
|
21
|
+
};
|
|
22
|
+
|
|
23
|
+
try {
|
|
24
|
+
const response = await fetch('https://api2.onairos.uk/connections/update', {
|
|
25
|
+
method: 'POST',
|
|
26
|
+
headers: {
|
|
27
|
+
'Content-Type': 'application/json',
|
|
28
|
+
},
|
|
29
|
+
body: JSON.stringify(jsonData),
|
|
30
|
+
});
|
|
31
|
+
|
|
32
|
+
if (!response.ok) {
|
|
33
|
+
throw new Error(`HTTP error! status: ${response.status}`);
|
|
34
|
+
}
|
|
35
|
+
|
|
36
|
+
const result = await response.json();
|
|
37
|
+
console.log(`UpdateConnections: ${updateType} ${newConnection}`, result);
|
|
38
|
+
return result;
|
|
39
|
+
} catch (error) {
|
|
40
|
+
console.error('UpdateConnections error:', error);
|
|
41
|
+
throw error;
|
|
42
|
+
}
|
|
43
|
+
}
|
|
@@ -157,7 +157,11 @@ const DataRequestPage = ({ requestData = {}, dataRequester = 'App', proofMode =
|
|
|
157
157
|
<div className="animate-spin h-8 w-8 border-2 border-blue-600 rounded-full border-t-transparent"></div>
|
|
158
158
|
</div>
|
|
159
159
|
) : activeModels.length === 0 ? (
|
|
160
|
-
<UniversalOnboarding
|
|
160
|
+
<UniversalOnboarding
|
|
161
|
+
appIcon="https://onairos.sirv.com/Images/OnairosBlack.png"
|
|
162
|
+
appName={dataRequester}
|
|
163
|
+
username={localStorage.getItem("username")}
|
|
164
|
+
/>
|
|
161
165
|
) : (
|
|
162
166
|
<div className="max-w-md mx-auto p-6 space-y-4">
|
|
163
167
|
<header className="bg-white p-6 rounded-xl shadow-md">
|
package/src/index.js
CHANGED
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
// src/index.js
|
|
2
2
|
|
|
3
3
|
import { Onairos } from "./onairos.jsx";
|
|
4
|
-
import { OnairosClient } from "./sdk/OnairosClient.js";
|
|
5
4
|
|
|
6
5
|
// Export the original Onairos component
|
|
7
6
|
export { Onairos };
|
|
@@ -9,12 +8,4 @@ export { Onairos };
|
|
|
9
8
|
// Export the new Onairos SDK
|
|
10
9
|
export { OnairosClient };
|
|
11
10
|
|
|
12
|
-
// Export SDK components for advanced usage
|
|
13
|
-
export { LLMWrapper } from "./sdk/LLMWrapper.js";
|
|
14
|
-
export { MemoryManager } from "./sdk/MemoryManager.js";
|
|
15
|
-
export { SessionManager } from "./sdk/SessionManager.js";
|
|
16
|
-
|
|
17
|
-
// Export utility functions
|
|
18
|
-
export { extractMemory, hasMeaningfulMemory, cleanMemoryData } from "./utils/extractMemory.js";
|
|
19
|
-
|
|
20
11
|
// You can also export additional functions or constants if needed
|
package/src/onairos.jsx
CHANGED
|
@@ -1,13 +1,6 @@
|
|
|
1
1
|
import React from 'react';
|
|
2
2
|
import { OnairosButton } from './onairosButton.jsx';
|
|
3
3
|
|
|
4
|
-
// Import SDK components
|
|
5
|
-
import { OnairosClient } from './sdk/OnairosClient.js';
|
|
6
|
-
import { LLMWrapper } from './sdk/LLMWrapper.js';
|
|
7
|
-
import { MemoryManager } from './sdk/MemoryManager.js';
|
|
8
|
-
import { SessionManager } from './sdk/SessionManager.js';
|
|
9
|
-
import { extractMemory } from './utils/extractMemory.js';
|
|
10
|
-
|
|
11
4
|
// Configuration object for the Telegram SDK
|
|
12
5
|
|
|
13
6
|
export function Onairos(props) {
|
|
@@ -19,13 +12,4 @@ export function Onairos(props) {
|
|
|
19
12
|
);
|
|
20
13
|
}
|
|
21
14
|
|
|
22
|
-
// Export SDK components for direct usage
|
|
23
|
-
export {
|
|
24
|
-
OnairosClient,
|
|
25
|
-
LLMWrapper,
|
|
26
|
-
MemoryManager,
|
|
27
|
-
SessionManager,
|
|
28
|
-
extractMemory
|
|
29
|
-
};
|
|
30
|
-
|
|
31
15
|
export default Onairos;
|
package/src/onairosButton.jsx
CHANGED
|
@@ -55,7 +55,7 @@ export function OnairosButton({
|
|
|
55
55
|
const openTerminal = async () => {
|
|
56
56
|
try {
|
|
57
57
|
console.log('🔥 openTerminal called');
|
|
58
|
-
|
|
58
|
+
setShowOverlay(true);
|
|
59
59
|
} catch (error) {
|
|
60
60
|
console.error('Error in openTerminal:', error);
|
|
61
61
|
}
|
|
@@ -156,6 +156,7 @@ export function OnairosButton({
|
|
|
156
156
|
onComplete={handleOnboardingComplete}
|
|
157
157
|
appIcon={appIcon || "https://onairos.sirv.com/Images/OnairosBlack.png"}
|
|
158
158
|
appName={webpageName}
|
|
159
|
+
username={userData?.email || userData?.username}
|
|
159
160
|
/>
|
|
160
161
|
);
|
|
161
162
|
|
package/src/overlay/overlay.js
CHANGED
|
@@ -291,7 +291,7 @@ export default function Overlay({
|
|
|
291
291
|
/>
|
|
292
292
|
);
|
|
293
293
|
case 'onboarding':
|
|
294
|
-
return <UniversalOnboarding onComplete={handleOnboardingComplete} />;
|
|
294
|
+
return <UniversalOnboarding onComplete={handleOnboardingComplete} username={accountInfo?.username || formData.username} />;
|
|
295
295
|
case 'security':
|
|
296
296
|
return <SecuritySetup onComplete={handleSecurityComplete} />;
|
|
297
297
|
case 'datarequests':
|
package/src/sdk/LLMWrapper.js
DELETED
|
@@ -1,221 +0,0 @@
|
|
|
1
|
-
import OpenAI from 'openai';
|
|
2
|
-
import Anthropic from '@anthropic-ai/sdk';
|
|
3
|
-
import { GoogleGenerativeAI } from '@google/generative-ai';
|
|
4
|
-
|
|
5
|
-
/**
|
|
6
|
-
* LLM Wrapper that provides unified interface for multiple LLM providers
|
|
7
|
-
* Supports OpenAI, Anthropic Claude, and Google Gemini
|
|
8
|
-
*/
|
|
9
|
-
export class LLMWrapper {
|
|
10
|
-
constructor({ openaiApiKey, anthropicApiKey, googleApiKey }) {
|
|
11
|
-
// Initialize OpenAI client
|
|
12
|
-
this.openai = openaiApiKey ? new OpenAI({ apiKey: openaiApiKey }) : null;
|
|
13
|
-
|
|
14
|
-
// Initialize Anthropic client
|
|
15
|
-
this.anthropic = anthropicApiKey ? new Anthropic({ apiKey: anthropicApiKey }) : null;
|
|
16
|
-
|
|
17
|
-
// Initialize Google Gemini client
|
|
18
|
-
this.google = googleApiKey ? new GoogleGenerativeAI(googleApiKey) : null;
|
|
19
|
-
}
|
|
20
|
-
|
|
21
|
-
/**
|
|
22
|
-
* Create a completion using the specified model
|
|
23
|
-
* @param {Object} params - Completion parameters
|
|
24
|
-
* @param {string} params.model - Model name
|
|
25
|
-
* @param {Array} params.messages - Messages array
|
|
26
|
-
* @param {Object} params.options - Additional options
|
|
27
|
-
* @returns {Promise<Object>} Standardized response
|
|
28
|
-
*/
|
|
29
|
-
async createCompletion({ model, messages, options = {} }) {
|
|
30
|
-
const modelLower = model.toLowerCase();
|
|
31
|
-
|
|
32
|
-
// OpenAI models
|
|
33
|
-
if (modelLower.includes('gpt') || modelLower.includes('o1')) {
|
|
34
|
-
return this._createOpenAICompletion({ model, messages, options });
|
|
35
|
-
}
|
|
36
|
-
|
|
37
|
-
// Anthropic models
|
|
38
|
-
if (modelLower.includes('claude')) {
|
|
39
|
-
return this._createAnthropicCompletion({ model, messages, options });
|
|
40
|
-
}
|
|
41
|
-
|
|
42
|
-
// Google Gemini models
|
|
43
|
-
if (modelLower.includes('gemini')) {
|
|
44
|
-
return this._createGoogleCompletion({ model, messages, options });
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
throw new Error(`Unsupported model: ${model}`);
|
|
48
|
-
}
|
|
49
|
-
|
|
50
|
-
/**
|
|
51
|
-
* Create OpenAI completion
|
|
52
|
-
*/
|
|
53
|
-
async _createOpenAICompletion({ model, messages, options }) {
|
|
54
|
-
if (!this.openai) {
|
|
55
|
-
throw new Error('OpenAI not configured. Please provide openaiApiKey.');
|
|
56
|
-
}
|
|
57
|
-
|
|
58
|
-
try {
|
|
59
|
-
const completion = await this.openai.chat.completions.create({
|
|
60
|
-
model,
|
|
61
|
-
messages,
|
|
62
|
-
temperature: options.temperature || 0.7,
|
|
63
|
-
max_tokens: options.max_tokens || 1000,
|
|
64
|
-
top_p: options.top_p || 1,
|
|
65
|
-
frequency_penalty: options.frequency_penalty || 0,
|
|
66
|
-
presence_penalty: options.presence_penalty || 0,
|
|
67
|
-
...options
|
|
68
|
-
});
|
|
69
|
-
|
|
70
|
-
return {
|
|
71
|
-
id: completion.id,
|
|
72
|
-
content: completion.choices[0].message.content,
|
|
73
|
-
finish_reason: completion.choices[0].finish_reason,
|
|
74
|
-
usage: completion.usage
|
|
75
|
-
};
|
|
76
|
-
} catch (error) {
|
|
77
|
-
throw new Error(`OpenAI API error: ${error.message}`);
|
|
78
|
-
}
|
|
79
|
-
}
|
|
80
|
-
|
|
81
|
-
/**
|
|
82
|
-
* Create Anthropic completion
|
|
83
|
-
*/
|
|
84
|
-
async _createAnthropicCompletion({ model, messages, options }) {
|
|
85
|
-
if (!this.anthropic) {
|
|
86
|
-
throw new Error('Anthropic not configured. Please provide anthropicApiKey.');
|
|
87
|
-
}
|
|
88
|
-
|
|
89
|
-
try {
|
|
90
|
-
// Convert messages format for Anthropic
|
|
91
|
-
const anthropicMessages = this._convertMessagesForAnthropic(messages);
|
|
92
|
-
|
|
93
|
-
const completion = await this.anthropic.messages.create({
|
|
94
|
-
model,
|
|
95
|
-
messages: anthropicMessages.messages,
|
|
96
|
-
system: anthropicMessages.system,
|
|
97
|
-
max_tokens: options.max_tokens || 1000,
|
|
98
|
-
temperature: options.temperature || 0.7,
|
|
99
|
-
top_p: options.top_p || 1,
|
|
100
|
-
...options
|
|
101
|
-
});
|
|
102
|
-
|
|
103
|
-
return {
|
|
104
|
-
id: completion.id,
|
|
105
|
-
content: completion.content[0].text,
|
|
106
|
-
finish_reason: completion.stop_reason,
|
|
107
|
-
usage: {
|
|
108
|
-
prompt_tokens: completion.usage.input_tokens,
|
|
109
|
-
completion_tokens: completion.usage.output_tokens,
|
|
110
|
-
total_tokens: completion.usage.input_tokens + completion.usage.output_tokens
|
|
111
|
-
}
|
|
112
|
-
};
|
|
113
|
-
} catch (error) {
|
|
114
|
-
throw new Error(`Anthropic API error: ${error.message}`);
|
|
115
|
-
}
|
|
116
|
-
}
|
|
117
|
-
|
|
118
|
-
/**
|
|
119
|
-
* Create Google Gemini completion
|
|
120
|
-
*/
|
|
121
|
-
async _createGoogleCompletion({ model, messages, options }) {
|
|
122
|
-
if (!this.google) {
|
|
123
|
-
throw new Error('Google not configured. Please provide googleApiKey.');
|
|
124
|
-
}
|
|
125
|
-
|
|
126
|
-
try {
|
|
127
|
-
const geminiModel = this.google.getGenerativeModel({ model });
|
|
128
|
-
|
|
129
|
-
// Convert messages to Gemini format
|
|
130
|
-
const geminiMessages = this._convertMessagesForGemini(messages);
|
|
131
|
-
|
|
132
|
-
const result = await geminiModel.generateContent({
|
|
133
|
-
contents: geminiMessages,
|
|
134
|
-
generationConfig: {
|
|
135
|
-
temperature: options.temperature || 0.7,
|
|
136
|
-
maxOutputTokens: options.max_tokens || 1000,
|
|
137
|
-
topP: options.top_p || 1,
|
|
138
|
-
...options
|
|
139
|
-
}
|
|
140
|
-
});
|
|
141
|
-
|
|
142
|
-
const response = await result.response;
|
|
143
|
-
|
|
144
|
-
return {
|
|
145
|
-
id: `gemini-${Date.now()}`,
|
|
146
|
-
content: response.text(),
|
|
147
|
-
finish_reason: 'stop',
|
|
148
|
-
usage: {
|
|
149
|
-
prompt_tokens: 0, // Gemini doesn't provide token counts
|
|
150
|
-
completion_tokens: 0,
|
|
151
|
-
total_tokens: 0
|
|
152
|
-
}
|
|
153
|
-
};
|
|
154
|
-
} catch (error) {
|
|
155
|
-
throw new Error(`Google Gemini API error: ${error.message}`);
|
|
156
|
-
}
|
|
157
|
-
}
|
|
158
|
-
|
|
159
|
-
/**
|
|
160
|
-
* Convert messages format for Anthropic (separate system messages)
|
|
161
|
-
*/
|
|
162
|
-
_convertMessagesForAnthropic(messages) {
|
|
163
|
-
const systemMessages = [];
|
|
164
|
-
const conversationMessages = [];
|
|
165
|
-
|
|
166
|
-
for (const message of messages) {
|
|
167
|
-
if (message.role === 'system') {
|
|
168
|
-
systemMessages.push(message.content);
|
|
169
|
-
} else {
|
|
170
|
-
conversationMessages.push({
|
|
171
|
-
role: message.role,
|
|
172
|
-
content: message.content
|
|
173
|
-
});
|
|
174
|
-
}
|
|
175
|
-
}
|
|
176
|
-
|
|
177
|
-
return {
|
|
178
|
-
system: systemMessages.join('\n'),
|
|
179
|
-
messages: conversationMessages
|
|
180
|
-
};
|
|
181
|
-
}
|
|
182
|
-
|
|
183
|
-
/**
|
|
184
|
-
* Convert messages format for Google Gemini
|
|
185
|
-
*/
|
|
186
|
-
_convertMessagesForGemini(messages) {
|
|
187
|
-
return messages.map(message => ({
|
|
188
|
-
role: message.role === 'assistant' ? 'model' : 'user',
|
|
189
|
-
parts: [{ text: message.content }]
|
|
190
|
-
}));
|
|
191
|
-
}
|
|
192
|
-
|
|
193
|
-
/**
|
|
194
|
-
* Get available models for each provider
|
|
195
|
-
*/
|
|
196
|
-
getAvailableModels() {
|
|
197
|
-
return {
|
|
198
|
-
openai: [
|
|
199
|
-
'gpt-4',
|
|
200
|
-
'gpt-4-turbo',
|
|
201
|
-
'gpt-4-turbo-preview',
|
|
202
|
-
'gpt-3.5-turbo',
|
|
203
|
-
'gpt-3.5-turbo-16k',
|
|
204
|
-
'o1-preview',
|
|
205
|
-
'o1-mini'
|
|
206
|
-
],
|
|
207
|
-
anthropic: [
|
|
208
|
-
'claude-3-opus-20240229',
|
|
209
|
-
'claude-3-sonnet-20240229',
|
|
210
|
-
'claude-3-haiku-20240307',
|
|
211
|
-
'claude-3-5-sonnet-20241022'
|
|
212
|
-
],
|
|
213
|
-
google: [
|
|
214
|
-
'gemini-pro',
|
|
215
|
-
'gemini-pro-vision',
|
|
216
|
-
'gemini-1.5-pro',
|
|
217
|
-
'gemini-1.5-flash'
|
|
218
|
-
]
|
|
219
|
-
};
|
|
220
|
-
}
|
|
221
|
-
}
|