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.
- package/README.md +48 -0
- package/android/src/main/jni.cpp +1 -1
- 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/CactusContext.mm +2 -2
- package/ios/cactus.xcframework/ios-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
- package/ios/cactus.xcframework/tvos-arm64_x86_64-simulator/cactus.framework/cactus +0 -0
- package/lib/commonjs/agent.js +74 -0
- package/lib/commonjs/agent.js.map +1 -0
- package/lib/commonjs/chat.js +3 -0
- package/lib/commonjs/chat.js.map +1 -1
- package/lib/commonjs/index.js +17 -16
- package/lib/commonjs/index.js.map +1 -1
- package/lib/commonjs/lm.js +73 -50
- package/lib/commonjs/lm.js.map +1 -1
- package/lib/commonjs/telemetry.js +0 -1
- package/lib/commonjs/telemetry.js.map +1 -1
- package/lib/commonjs/vlm.js +74 -24
- package/lib/commonjs/vlm.js.map +1 -1
- package/lib/module/agent.js +69 -0
- package/lib/module/agent.js.map +1 -0
- package/lib/module/chat.js +3 -0
- package/lib/module/chat.js.map +1 -1
- package/lib/module/index.js +4 -17
- package/lib/module/index.js.map +1 -1
- package/lib/module/lm.js +73 -50
- package/lib/module/lm.js.map +1 -1
- package/lib/module/telemetry.js +0 -1
- package/lib/module/telemetry.js.map +1 -1
- package/lib/module/vlm.js +74 -24
- package/lib/module/vlm.js.map +1 -1
- package/lib/typescript/agent.d.ts +31 -0
- package/lib/typescript/agent.d.ts.map +1 -0
- package/lib/typescript/chat.d.ts +3 -0
- package/lib/typescript/chat.d.ts.map +1 -1
- package/lib/typescript/index.d.ts +2 -7
- package/lib/typescript/index.d.ts.map +1 -1
- package/lib/typescript/lm.d.ts +3 -0
- package/lib/typescript/lm.d.ts.map +1 -1
- package/lib/typescript/telemetry.d.ts.map +1 -1
- package/lib/typescript/vlm.d.ts +7 -1
- package/lib/typescript/vlm.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/agent.ts +114 -0
- package/src/chat.ts +7 -1
- package/src/index.ts +10 -16
- package/src/lm.ts +76 -49
- package/src/telemetry.ts +0 -1
- package/src/tools.ts +1 -1
- 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
|
|
42
|
-
|
|
43
|
-
|
|
44
|
-
|
|
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
|
-
|
|
64
|
-
|
|
65
|
-
|
|
66
|
-
|
|
67
|
-
|
|
68
|
-
|
|
69
|
-
|
|
70
|
-
|
|
71
|
-
|
|
72
|
-
|
|
73
|
-
|
|
74
|
-
|
|
75
|
-
|
|
76
|
-
|
|
77
|
-
|
|
78
|
-
|
|
79
|
-
|
|
80
|
-
|
|
81
|
-
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
85
|
-
|
|
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
|
-
|
|
91
|
-
|
|
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
|
|
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
package/src/tools.ts
CHANGED
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
|
|
49
|
-
|
|
50
|
-
|
|
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
|
-
|
|
54
|
-
|
|
55
|
-
|
|
56
|
-
|
|
57
|
-
|
|
58
|
-
|
|
59
|
-
|
|
60
|
-
|
|
61
|
-
|
|
62
|
-
|
|
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
|
-
|
|
65
|
-
|
|
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
|
-
|
|
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
|
}
|