cactus-react-native 0.2.8 → 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.
Files changed (43) hide show
  1. package/android/src/main/jniLibs/arm64-v8a/libcactus.so +0 -0
  2. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8.so +0 -0
  3. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2.so +0 -0
  4. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_dotprod.so +0 -0
  5. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_dotprod_i8mm.so +0 -0
  6. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_i8mm.so +0 -0
  7. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Headers/minja/chat-template.hpp +1 -0
  8. package/ios/cactus.xcframework/ios-arm64/cactus.framework/Info.plist +0 -0
  9. package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Headers/minja/chat-template.hpp +1 -0
  10. package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/Info.plist +0 -0
  11. package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/_CodeSignature/CodeResources +1 -1
  12. package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
  13. package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Headers/minja/chat-template.hpp +1 -0
  14. package/ios/cactus.xcframework/tvos-arm64/cactus.framework/Info.plist +0 -0
  15. package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Headers/minja/chat-template.hpp +1 -0
  16. package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/Info.plist +0 -0
  17. package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/_CodeSignature/CodeResources +1 -1
  18. package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
  19. package/lib/commonjs/lm.js +70 -0
  20. package/lib/commonjs/lm.js.map +1 -1
  21. package/lib/commonjs/remote.js +36 -89
  22. package/lib/commonjs/remote.js.map +1 -1
  23. package/lib/commonjs/tools.js.map +1 -1
  24. package/lib/commonjs/vlm.js +2 -2
  25. package/lib/commonjs/vlm.js.map +1 -1
  26. package/lib/module/lm.js +71 -1
  27. package/lib/module/lm.js.map +1 -1
  28. package/lib/module/remote.js +36 -89
  29. package/lib/module/remote.js.map +1 -1
  30. package/lib/module/tools.js.map +1 -1
  31. package/lib/module/vlm.js +2 -2
  32. package/lib/module/vlm.js.map +1 -1
  33. package/lib/typescript/lm.d.ts +5 -1
  34. package/lib/typescript/lm.d.ts.map +1 -1
  35. package/lib/typescript/remote.d.ts +5 -4
  36. package/lib/typescript/remote.d.ts.map +1 -1
  37. package/lib/typescript/tools.d.ts +15 -14
  38. package/lib/typescript/tools.d.ts.map +1 -1
  39. package/package.json +1 -1
  40. package/src/lm.ts +85 -2
  41. package/src/remote.ts +43 -105
  42. package/src/tools.ts +14 -1
  43. 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
- if (_cactusToken === null) {
9
- throw new Error('CactusToken not set. Please call CactusLM.init with cactusToken parameter.');
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
- textPrompt: string,
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 parts: any[] = [];
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
- const detectedMimeType = mimeType || 'image/jpeg';
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
- parts.push({
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
- const requestBody = {
104
- contents: {
105
- role: 'user',
106
- parts: parts,
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
- if (Array.isArray(responseBody)) {
127
- throw new Error('Unexpected response format: received array instead of object');
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(prompt: string): Promise<string> {
149
- return getVertexAICompletion(prompt);
86
+ export async function getTextCompletion(messages: CactusOAICompatibleMessage[]): Promise<string> {
87
+ return getVertexAICompletion(messages);
150
88
  }
151
89
 
152
- export async function getVisionCompletion(prompt: string, imagePath: string): Promise<string> {
153
- return getVertexAICompletion(prompt, undefined, imagePath);
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(prompt: string, imageData: string, mimeType?: string): Promise<string> {
157
- return getVertexAICompletion(prompt, imageData, undefined, mimeType);
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(prompt, imagePath);
224
+ responseText = await getVisionCompletion(messages, imagePath);
225
225
  } else {
226
- responseText = await getTextCompletion(prompt);
226
+ responseText = await getTextCompletion(messages);
227
227
  }
228
228
 
229
229
  if (callback) {