cactus-react-native 0.2.4 → 0.2.6

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 (54) hide show
  1. package/README.md +48 -0
  2. package/android/src/main/jni.cpp +1 -1
  3. package/android/src/main/jniLibs/arm64-v8a/libcactus.so +0 -0
  4. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8.so +0 -0
  5. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2.so +0 -0
  6. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_dotprod.so +0 -0
  7. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_dotprod_i8mm.so +0 -0
  8. package/android/src/main/jniLibs/arm64-v8a/libcactus_v8_2_i8mm.so +0 -0
  9. package/ios/CactusContext.mm +2 -2
  10. package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
  11. package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
  12. package/lib/commonjs/agent.js +74 -0
  13. package/lib/commonjs/agent.js.map +1 -0
  14. package/lib/commonjs/chat.js +3 -0
  15. package/lib/commonjs/chat.js.map +1 -1
  16. package/lib/commonjs/index.js +17 -16
  17. package/lib/commonjs/index.js.map +1 -1
  18. package/lib/commonjs/lm.js +73 -50
  19. package/lib/commonjs/lm.js.map +1 -1
  20. package/lib/commonjs/telemetry.js +0 -1
  21. package/lib/commonjs/telemetry.js.map +1 -1
  22. package/lib/commonjs/vlm.js +74 -24
  23. package/lib/commonjs/vlm.js.map +1 -1
  24. package/lib/module/agent.js +69 -0
  25. package/lib/module/agent.js.map +1 -0
  26. package/lib/module/chat.js +3 -0
  27. package/lib/module/chat.js.map +1 -1
  28. package/lib/module/index.js +4 -17
  29. package/lib/module/index.js.map +1 -1
  30. package/lib/module/lm.js +73 -50
  31. package/lib/module/lm.js.map +1 -1
  32. package/lib/module/telemetry.js +0 -1
  33. package/lib/module/telemetry.js.map +1 -1
  34. package/lib/module/vlm.js +74 -24
  35. package/lib/module/vlm.js.map +1 -1
  36. package/lib/typescript/agent.d.ts +31 -0
  37. package/lib/typescript/agent.d.ts.map +1 -0
  38. package/lib/typescript/chat.d.ts +3 -0
  39. package/lib/typescript/chat.d.ts.map +1 -1
  40. package/lib/typescript/index.d.ts +2 -7
  41. package/lib/typescript/index.d.ts.map +1 -1
  42. package/lib/typescript/lm.d.ts +3 -0
  43. package/lib/typescript/lm.d.ts.map +1 -1
  44. package/lib/typescript/telemetry.d.ts.map +1 -1
  45. package/lib/typescript/vlm.d.ts +7 -1
  46. package/lib/typescript/vlm.d.ts.map +1 -1
  47. package/package.json +1 -1
  48. package/src/agent.ts +114 -0
  49. package/src/chat.ts +7 -1
  50. package/src/index.ts +10 -16
  51. package/src/lm.ts +76 -49
  52. package/src/telemetry.ts +0 -1
  53. package/src/tools.ts +1 -1
  54. package/src/vlm.ts +77 -18
package/src/lm.ts CHANGED
@@ -23,6 +23,12 @@ export class CactusLM {
23
23
  protected context: LlamaContext
24
24
  protected conversationHistoryManager: ConversationHistoryManager
25
25
 
26
+ private static _initCache: Map<string, Promise<CactusLMReturn>> = new Map();
27
+
28
+ private static getCacheKey(params: ContextParams, cactusToken?: string, retryOptions?: { maxRetries?: number; delayMs?: number }): string {
29
+ return JSON.stringify({ params, cactusToken, retryOptions });
30
+ }
31
+
26
32
  protected constructor(context: LlamaContext) {
27
33
  this.context = context
28
34
  this.conversationHistoryManager = new ConversationHistoryManager()
@@ -34,64 +40,80 @@ export class CactusLM {
34
40
  cactusToken?: string,
35
41
  retryOptions?: { maxRetries?: number; delayMs?: number },
36
42
  ): Promise<CactusLMReturn> {
43
+
37
44
  if (cactusToken) {
38
45
  setCactusToken(cactusToken);
39
46
  }
40
47
 
41
- const maxRetries = retryOptions?.maxRetries ?? 3;
42
- const delayMs = retryOptions?.delayMs ?? 1000;
43
-
44
- const configs = [
45
- params,
46
- { ...params, n_gpu_layers: 0 }
47
- ];
48
-
49
- const sleep = (ms: number): Promise<void> => {
50
- return new Promise(resolve => {
51
- const start = Date.now();
52
- const wait = () => {
53
- if (Date.now() - start >= ms) {
54
- resolve();
55
- } else {
56
- Promise.resolve().then(wait);
57
- }
58
- };
59
- wait();
60
- });
61
- };
48
+ const key = CactusLM.getCacheKey(params, cactusToken, retryOptions);
49
+ if (CactusLM._initCache.has(key)) {
50
+ return CactusLM._initCache.get(key)!;
51
+ }
62
52
 
63
- for (const config of configs) {
64
- let lastError: Error | null = null;
65
-
66
- for (let attempt = 1; attempt <= maxRetries; attempt++) {
67
- try {
68
- const context = await initLlama(config, onProgress);
69
- return { lm: new CactusLM(context), error: null };
70
- } catch (e) {
71
- lastError = e as Error;
72
- const isLastConfig = configs.indexOf(config) === configs.length - 1;
73
- const isLastAttempt = attempt === maxRetries;
74
-
75
- Telemetry.error(e as Error, {
76
- n_gpu_layers: config.n_gpu_layers ?? null,
77
- n_ctx: config.n_ctx ?? null,
78
- model: config.model ?? null,
79
- });
80
-
81
- if (!isLastAttempt) {
82
- const delay = delayMs * Math.pow(2, attempt - 1);
83
- await sleep(delay);
84
- } else if (!isLastConfig) {
85
- break;
53
+ const initPromise = (async () => {
54
+ const maxRetries = retryOptions?.maxRetries ?? 3;
55
+ const delayMs = retryOptions?.delayMs ?? 1000;
56
+
57
+ const configs = [
58
+ params,
59
+ { ...params, n_gpu_layers: 0 }
60
+ ];
61
+
62
+ const sleep = (ms: number): Promise<void> => {
63
+ return new Promise(resolve => {
64
+ const start = Date.now();
65
+ const wait = () => {
66
+ if (Date.now() - start >= ms) {
67
+ resolve();
68
+ } else {
69
+ Promise.resolve().then(wait);
70
+ }
71
+ };
72
+ wait();
73
+ });
74
+ };
75
+
76
+ for (const config of configs) {
77
+ let lastError: Error | null = null;
78
+
79
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
80
+ try {
81
+ const context = await initLlama(config, onProgress);
82
+ return { lm: new CactusLM(context), error: null };
83
+ } catch (e) {
84
+ lastError = e as Error;
85
+ const isLastConfig = configs.indexOf(config) === configs.length - 1;
86
+ const isLastAttempt = attempt === maxRetries;
87
+
88
+ Telemetry.error(e as Error, {
89
+ n_gpu_layers: config.n_gpu_layers ?? null,
90
+ n_ctx: config.n_ctx ?? null,
91
+ model: config.model ?? null,
92
+ });
93
+
94
+ if (!isLastAttempt) {
95
+ const delay = delayMs * Math.pow(2, attempt - 1);
96
+ await sleep(delay);
97
+ } else if (!isLastConfig) {
98
+ break;
99
+ }
86
100
  }
87
101
  }
102
+
103
+ if (configs.indexOf(config) === configs.length - 1 && lastError) {
104
+ return { lm: null, error: lastError };
105
+ }
88
106
  }
89
-
90
- if (configs.indexOf(config) === configs.length - 1 && lastError) {
91
- return { lm: null, error: lastError };
92
- }
107
+ return { lm: null, error: new Error('Failed to initialize CactusLM after all retries') };
108
+ })();
109
+
110
+ CactusLM._initCache.set(key, initPromise);
111
+
112
+ const result = await initPromise;
113
+ if (result.error) {
114
+ CactusLM._initCache.delete(key);
93
115
  }
94
- return { lm: null, error: new Error('Failed to initialize CactusLM after all retries') };
116
+ return result;
95
117
  }
96
118
 
97
119
  completion = async (
@@ -179,4 +201,9 @@ export class CactusLM {
179
201
  async release(): Promise<void> {
180
202
  return this.context.release()
181
203
  }
204
+
205
+ async stopCompletion(): Promise<void> {
206
+ return await this.context.stopCompletion()
207
+ }
208
+
182
209
  }
package/src/telemetry.ts CHANGED
@@ -1,5 +1,4 @@
1
1
  import { Platform } from 'react-native'
2
- // Import package.json to get version
3
2
  const packageJson = require('../package.json');
4
3
  import { PROJECT_ID } from './projectId';
5
4
 
package/src/tools.ts CHANGED
@@ -3,7 +3,7 @@ import type { NativeCompletionResult } from "./NativeCactus";
3
3
  interface Parameter {
4
4
  type: string,
5
5
  description: string,
6
- required?: boolean // parameter is optional if not specified
6
+ required?: boolean
7
7
  }
8
8
 
9
9
  interface Tool {
package/src/vlm.ts CHANGED
@@ -31,6 +31,12 @@ export class CactusVLM {
31
31
  private context: LlamaContext
32
32
  protected conversationHistoryManager: ConversationHistoryManager
33
33
 
34
+ private static _initCache: Map<string, Promise<CactusVLMReturn>> = new Map();
35
+
36
+ private static getCacheKey(params: VLMContextParams, cactusToken?: string, retryOptions?: { maxRetries?: number; delayMs?: number }): string {
37
+ return JSON.stringify({ params, cactusToken, retryOptions });
38
+ }
39
+
34
40
  private constructor(context: LlamaContext) {
35
41
  this.context = context
36
42
  this.conversationHistoryManager = new ConversationHistoryManager()
@@ -40,34 +46,83 @@ export class CactusVLM {
40
46
  params: VLMContextParams,
41
47
  onProgress?: (progress: number) => void,
42
48
  cactusToken?: string,
49
+ retryOptions?: { maxRetries?: number; delayMs?: number },
43
50
  ): Promise<CactusVLMReturn> {
44
51
  if (cactusToken) {
45
52
  setCactusToken(cactusToken);
46
53
  }
47
54
 
48
- const configs = [
49
- params,
50
- { ...params, n_gpu_layers: 0 }
51
- ];
55
+ const key = CactusVLM.getCacheKey(params, cactusToken, retryOptions);
56
+ if (CactusVLM._initCache.has(key)) {
57
+ return CactusVLM._initCache.get(key)!;
58
+ }
52
59
 
53
- for (const config of configs) {
54
- try {
55
- const context = await initLlama(config, onProgress)
56
- await initMultimodal(context.id, params.mmproj, false)
57
- return {vlm: new CactusVLM(context), error: null}
58
- } catch (e) {
59
- Telemetry.error(e as Error, {
60
- n_gpu_layers: config.n_gpu_layers ?? null,
61
- n_ctx: config.n_ctx ?? null,
62
- model: config.model ?? null,
60
+ const initPromise = (async () => {
61
+ const maxRetries = retryOptions?.maxRetries ?? 3;
62
+ const delayMs = retryOptions?.delayMs ?? 1000;
63
+
64
+ const configs = [
65
+ params,
66
+ { ...params, n_gpu_layers: 0 }
67
+ ];
68
+
69
+ const sleep = (ms: number): Promise<void> => {
70
+ return new Promise(resolve => {
71
+ const start = Date.now();
72
+ const wait = () => {
73
+ if (Date.now() - start >= ms) {
74
+ resolve();
75
+ } else {
76
+ Promise.resolve().then(wait);
77
+ }
78
+ };
79
+ wait();
63
80
  });
64
- if (configs.indexOf(config) === configs.length - 1) {
65
- return {vlm: null, error: e as Error}
81
+ };
82
+
83
+ for (const config of configs) {
84
+ let lastError: Error | null = null;
85
+
86
+ for (let attempt = 1; attempt <= maxRetries; attempt++) {
87
+ try {
88
+ const context = await initLlama(config, onProgress)
89
+ await initMultimodal(context.id, params.mmproj, false)
90
+ return {vlm: new CactusVLM(context), error: null}
91
+ } catch (e) {
92
+ lastError = e as Error;
93
+ const isLastConfig = configs.indexOf(config) === configs.length - 1;
94
+ const isLastAttempt = attempt === maxRetries;
95
+
96
+ Telemetry.error(e as Error, {
97
+ n_gpu_layers: config.n_gpu_layers ?? null,
98
+ n_ctx: config.n_ctx ?? null,
99
+ model: config.model ?? null,
100
+ });
101
+
102
+ if (!isLastAttempt) {
103
+ const delay = delayMs * Math.pow(2, attempt - 1);
104
+ await sleep(delay);
105
+ } else if (!isLastConfig) {
106
+ break;
107
+ }
108
+ }
109
+ }
110
+
111
+ if (configs.indexOf(config) === configs.length - 1 && lastError) {
112
+ return {vlm: null, error: lastError}
66
113
  }
67
114
  }
68
- }
69
115
 
70
- return {vlm: null, error: new Error('Failed to initialize CactusVLM')}
116
+ return {vlm: null, error: new Error('Failed to initialize CactusVLM')}
117
+ })();
118
+
119
+ CactusVLM._initCache.set(key, initPromise);
120
+
121
+ const result = await initPromise;
122
+ if (result.error) {
123
+ CactusVLM._initCache.delete(key);
124
+ }
125
+ return result;
71
126
  }
72
127
 
73
128
  async completion(
@@ -210,4 +265,8 @@ export class CactusVLM {
210
265
  async release(): Promise<void> {
211
266
  return this.context.release()
212
267
  }
268
+
269
+ async stopCompletion(): Promise<void> {
270
+ return await this.context.stopCompletion()
271
+ }
213
272
  }