cactus-react-native 0.2.7 → 0.2.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/android/src/main/jniLibs/arm64-v8a/libcactus.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_dotprod.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_dotprod_i8mm.so +0 -0
- package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_i8mm.so +0 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/minja/chat-template.hpp +1 -0
- package/ios/cactus.xcframework/ios-arm64/cactus.framework/Info.plist +0 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/minja/chat-template.hpp +1 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Info.plist +0 -0
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/_CodeSignature/CodeResources +1 -1
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/minja/chat-template.hpp +1 -0
- package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Info.plist +0 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/minja/chat-template.hpp +1 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Info.plist +0 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/_CodeSignature/CodeResources +1 -1
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
- package/lib/commonjs/lm.js +70 -0
- package/lib/commonjs/lm.js.map +1 -1
- package/lib/commonjs/remote.js +36 -89
- package/lib/commonjs/remote.js.map +1 -1
- package/lib/commonjs/tools.js.map +1 -1
- package/lib/commonjs/vlm.js +2 -2
- package/lib/commonjs/vlm.js.map +1 -1
- package/lib/module/lm.js +71 -1
- package/lib/module/lm.js.map +1 -1
- package/lib/module/remote.js +36 -89
- package/lib/module/remote.js.map +1 -1
- package/lib/module/tools.js.map +1 -1
- package/lib/module/vlm.js +2 -2
- package/lib/module/vlm.js.map +1 -1
- package/lib/typescript/lm.d.ts +5 -1
- package/lib/typescript/lm.d.ts.map +1 -1
- package/lib/typescript/remote.d.ts +5 -4
- package/lib/typescript/remote.d.ts.map +1 -1
- package/lib/typescript/tools.d.ts +15 -14
- package/lib/typescript/tools.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/lm.ts +85 -2
- package/src/remote.ts +43 -105
- package/src/tools.ts +14 -1
- package/src/vlm.ts +2 -2
package/src/remote.ts
CHANGED
|
@@ -1,3 +1,5 @@
|
|
|
1
|
+
import type { CactusOAICompatibleMessage } from "./chat";
|
|
2
|
+
|
|
1
3
|
let _cactusToken: string | null = null;
|
|
2
4
|
|
|
3
5
|
export function setCactusToken(token: string | null): void {
|
|
@@ -5,58 +7,12 @@ export function setCactusToken(token: string | null): void {
|
|
|
5
7
|
}
|
|
6
8
|
|
|
7
9
|
export async function getVertexAIEmbedding(text: string): Promise<number[]> {
|
|
8
|
-
|
|
9
|
-
|
|
10
|
-
}
|
|
11
|
-
|
|
12
|
-
const projectId = 'cactus-v1-452518';
|
|
13
|
-
const location = 'us-central1';
|
|
14
|
-
const modelId = 'text-embedding-005';
|
|
15
|
-
|
|
16
|
-
const endpoint = `https://${location}-aiplatform.googleapis.com/v1/projects/${projectId}/locations/${location}/publishers/google/models/${modelId}:predict`;
|
|
17
|
-
|
|
18
|
-
const headers = {
|
|
19
|
-
'Authorization': `Bearer ${_cactusToken}`,
|
|
20
|
-
'Content-Type': 'application/json',
|
|
21
|
-
};
|
|
22
|
-
|
|
23
|
-
const requestBody = {
|
|
24
|
-
instances: [{ content: text }]
|
|
25
|
-
};
|
|
26
|
-
|
|
27
|
-
const response = await fetch(endpoint, {
|
|
28
|
-
method: 'POST',
|
|
29
|
-
headers,
|
|
30
|
-
body: JSON.stringify(requestBody),
|
|
31
|
-
});
|
|
32
|
-
|
|
33
|
-
if (response.status === 401) {
|
|
34
|
-
_cactusToken = null;
|
|
35
|
-
throw new Error('Authentication failed. Please update your cactusToken.');
|
|
36
|
-
} else if (!response.ok) {
|
|
37
|
-
const errorText = await response.text();
|
|
38
|
-
throw new Error(`HTTP ${response.status}: ${errorText}`);
|
|
39
|
-
}
|
|
40
|
-
|
|
41
|
-
const responseBody = await response.json();
|
|
42
|
-
|
|
43
|
-
if (responseBody.error) {
|
|
44
|
-
throw new Error(`API Error: ${responseBody.error.message}`);
|
|
45
|
-
}
|
|
46
|
-
|
|
47
|
-
const predictions = responseBody.predictions;
|
|
48
|
-
if (!predictions || predictions.length === 0) {
|
|
49
|
-
throw new Error('No predictions in response');
|
|
50
|
-
}
|
|
51
|
-
|
|
52
|
-
const embeddings = predictions[0].embeddings;
|
|
53
|
-
const values = embeddings.values;
|
|
54
|
-
|
|
55
|
-
return values;
|
|
10
|
+
text = text
|
|
11
|
+
throw new Error('Remote embedding is not currently supported. The Cactus library is in active development - if you need this functionality, please contact us at founders@cactuscompute.com');
|
|
56
12
|
}
|
|
57
13
|
|
|
58
14
|
export async function getVertexAICompletion(
|
|
59
|
-
|
|
15
|
+
messages: CactusOAICompatibleMessage[],
|
|
60
16
|
imageData?: string,
|
|
61
17
|
imagePath?: string,
|
|
62
18
|
mimeType?: string,
|
|
@@ -64,48 +20,48 @@ export async function getVertexAICompletion(
|
|
|
64
20
|
if (_cactusToken === null) {
|
|
65
21
|
throw new Error('CactusToken not set. Please call CactusVLM.init with cactusToken parameter.');
|
|
66
22
|
}
|
|
67
|
-
|
|
68
|
-
const projectId = 'cactus-v1-452518';
|
|
69
|
-
const location = 'global';
|
|
70
|
-
const modelId = 'gemini-2.5-flash-lite-preview-06-17';
|
|
71
|
-
|
|
72
|
-
const endpoint = `https://aiplatform.googleapis.com/v1/projects/${projectId}/locations/${location}/publishers/google/models/${modelId}:generateContent`;
|
|
23
|
+
const endpoint = 'https://openrouter.ai/api/v1/chat/completions';
|
|
73
24
|
|
|
74
25
|
const headers = {
|
|
75
26
|
'Authorization': `Bearer ${_cactusToken}`,
|
|
76
27
|
'Content-Type': 'application/json',
|
|
77
28
|
};
|
|
78
29
|
|
|
79
|
-
const
|
|
80
|
-
|
|
30
|
+
const requestBody = {
|
|
31
|
+
model: 'google/gemini-2.5-flash-lite',
|
|
32
|
+
messages: messages,
|
|
33
|
+
};
|
|
34
|
+
|
|
35
|
+
let imageUrl = ''
|
|
81
36
|
if (imageData) {
|
|
82
|
-
|
|
83
|
-
parts.push({
|
|
84
|
-
inlineData: {
|
|
85
|
-
mimeType: detectedMimeType,
|
|
86
|
-
data: imageData
|
|
87
|
-
}
|
|
88
|
-
});
|
|
37
|
+
imageUrl = `data:${mimeType || 'image/jpeg'};base64,${imageData}`
|
|
89
38
|
} else if (imagePath) {
|
|
90
|
-
const detectedMimeType = mimeType || detectMimeType(imagePath);
|
|
91
39
|
const RNFS = require('react-native-fs');
|
|
92
40
|
const base64Data = await RNFS.readFile(imagePath, 'base64');
|
|
93
|
-
|
|
94
|
-
inlineData: {
|
|
95
|
-
mimeType: detectedMimeType,
|
|
96
|
-
data: base64Data
|
|
97
|
-
}
|
|
98
|
-
});
|
|
41
|
+
imageUrl = `data:${mimeType || detectMimeType(imagePath)};base64,${base64Data}`
|
|
99
42
|
}
|
|
100
|
-
|
|
101
|
-
parts.push({ text: textPrompt });
|
|
102
43
|
|
|
103
|
-
|
|
104
|
-
|
|
105
|
-
|
|
106
|
-
|
|
44
|
+
if (imageUrl) {
|
|
45
|
+
if (requestBody.messages[requestBody.messages.length - 1]?.role === 'user') {
|
|
46
|
+
requestBody.messages[requestBody.messages.length - 1] = {
|
|
47
|
+
role: 'user',
|
|
48
|
+
content: [
|
|
49
|
+
{
|
|
50
|
+
type: 'text',
|
|
51
|
+
text: requestBody.messages[requestBody.messages.length - 1]?.content || ''
|
|
52
|
+
},
|
|
53
|
+
{
|
|
54
|
+
type: 'image_url',
|
|
55
|
+
image_url: {
|
|
56
|
+
url: imageUrl
|
|
57
|
+
}
|
|
58
|
+
}
|
|
59
|
+
]
|
|
60
|
+
}
|
|
61
|
+
}else{
|
|
62
|
+
console.warn('Image data provided but message is not a user message: ', requestBody.messages);
|
|
107
63
|
}
|
|
108
|
-
}
|
|
64
|
+
}
|
|
109
65
|
|
|
110
66
|
const response = await fetch(endpoint, {
|
|
111
67
|
method: 'POST',
|
|
@@ -122,39 +78,21 @@ export async function getVertexAICompletion(
|
|
|
122
78
|
}
|
|
123
79
|
|
|
124
80
|
const responseBody = await response.json();
|
|
125
|
-
|
|
126
|
-
|
|
127
|
-
|
|
128
|
-
}
|
|
129
|
-
|
|
130
|
-
if (responseBody.error) {
|
|
131
|
-
throw new Error(`API Error: ${responseBody.error.message}`);
|
|
132
|
-
}
|
|
133
|
-
|
|
134
|
-
const candidates = responseBody.candidates;
|
|
135
|
-
if (!candidates || candidates.length === 0) {
|
|
136
|
-
throw new Error('No candidates in response');
|
|
137
|
-
}
|
|
138
|
-
|
|
139
|
-
const content = candidates[0].content;
|
|
140
|
-
const responseParts = content.parts;
|
|
141
|
-
if (!responseParts || responseParts.length === 0) {
|
|
142
|
-
throw new Error('No parts in response');
|
|
143
|
-
}
|
|
144
|
-
|
|
145
|
-
return responseParts[0].text || '';
|
|
81
|
+
const responseText = responseBody.choices[0].message.content;
|
|
82
|
+
|
|
83
|
+
return responseText;
|
|
146
84
|
}
|
|
147
85
|
|
|
148
|
-
export async function getTextCompletion(
|
|
149
|
-
return getVertexAICompletion(
|
|
86
|
+
export async function getTextCompletion(messages: CactusOAICompatibleMessage[]): Promise<string> {
|
|
87
|
+
return getVertexAICompletion(messages);
|
|
150
88
|
}
|
|
151
89
|
|
|
152
|
-
export async function getVisionCompletion(
|
|
153
|
-
return getVertexAICompletion(
|
|
90
|
+
export async function getVisionCompletion(messages: CactusOAICompatibleMessage[], imagePath: string): Promise<string> {
|
|
91
|
+
return getVertexAICompletion(messages, undefined, imagePath);
|
|
154
92
|
}
|
|
155
93
|
|
|
156
|
-
export async function getVisionCompletionFromData(
|
|
157
|
-
return getVertexAICompletion(
|
|
94
|
+
export async function getVisionCompletionFromData(messages: CactusOAICompatibleMessage[], imageData: string, mimeType?: string): Promise<string> {
|
|
95
|
+
return getVertexAICompletion(messages, imageData, undefined, mimeType);
|
|
158
96
|
}
|
|
159
97
|
|
|
160
98
|
function detectMimeType(filePath: string): string {
|
package/src/tools.ts
CHANGED
|
@@ -1,5 +1,18 @@
|
|
|
1
1
|
import type { NativeCompletionResult } from "./NativeCactus";
|
|
2
2
|
|
|
3
|
+
export type OpenAIToolSchema = {
|
|
4
|
+
type: "function",
|
|
5
|
+
function: {
|
|
6
|
+
name: string,
|
|
7
|
+
description: string,
|
|
8
|
+
parameters: {
|
|
9
|
+
type: "object",
|
|
10
|
+
properties: {[key: string]: Parameter},
|
|
11
|
+
required: string[]
|
|
12
|
+
}
|
|
13
|
+
}
|
|
14
|
+
}
|
|
15
|
+
|
|
3
16
|
interface Parameter {
|
|
4
17
|
type: string,
|
|
5
18
|
description: string,
|
|
@@ -32,7 +45,7 @@ export class Tools {
|
|
|
32
45
|
return func;
|
|
33
46
|
}
|
|
34
47
|
|
|
35
|
-
getSchemas() {
|
|
48
|
+
getSchemas(): OpenAIToolSchema[] {
|
|
36
49
|
return Array.from(this.tools.entries()).map(([name, { description, parameters, required }]) => ({
|
|
37
50
|
type: "function",
|
|
38
51
|
function: {
|
package/src/vlm.ts
CHANGED
|
@@ -221,9 +221,9 @@ export class CactusVLM {
|
|
|
221
221
|
|
|
222
222
|
let responseText: string;
|
|
223
223
|
if (imagePath) {
|
|
224
|
-
responseText = await getVisionCompletion(
|
|
224
|
+
responseText = await getVisionCompletion(messages, imagePath);
|
|
225
225
|
} else {
|
|
226
|
-
responseText = await getTextCompletion(
|
|
226
|
+
responseText = await getTextCompletion(messages);
|
|
227
227
|
}
|
|
228
228
|
|
|
229
229
|
if (callback) {
|