cactus-react-native 1.10.0 → 1.10.1
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 +61 -0
- package/android/gradle.properties +1 -1
- package/lib/module/index.js +3 -0
- package/lib/module/index.js.map +1 -1
- package/lib/module/modelRegistry.js +27 -2
- package/lib/module/modelRegistry.js.map +1 -1
- package/lib/typescript/src/index.d.ts +1 -0
- package/lib/typescript/src/index.d.ts.map +1 -1
- package/package.json +1 -1
- package/src/index.tsx +3 -0
- package/src/modelRegistry.ts +42 -2
package/README.md
CHANGED
|
@@ -1018,6 +1018,10 @@ Releases all resources associated with the model. Automatically calls `stop()` f
|
|
|
1018
1018
|
|
|
1019
1019
|
Returns available models.
|
|
1020
1020
|
|
|
1021
|
+
**`getModelName(): string`**
|
|
1022
|
+
|
|
1023
|
+
Returns the model slug or path the instance was created with.
|
|
1024
|
+
|
|
1021
1025
|
### useCactusLM Hook
|
|
1022
1026
|
|
|
1023
1027
|
The `useCactusLM` hook manages a `CactusLM` instance with reactive state. When model parameters (`model`, `corpusDir`, `cacheIndex`, `options`) change, the hook creates a new instance and resets all state. The hook automatically cleans up resources when the component unmounts.
|
|
@@ -1111,6 +1115,15 @@ Feeds audio samples into the streaming session and returns the current transcrip
|
|
|
1111
1115
|
|
|
1112
1116
|
Stops the streaming session and returns the final confirmed transcription text. Throws an error if no session is active.
|
|
1113
1117
|
|
|
1118
|
+
**`detectLanguage(params: CactusSTTDetectLanguageParams): Promise<CactusSTTDetectLanguageResult>`**
|
|
1119
|
+
|
|
1120
|
+
Detects the spoken language in the given audio. Automatically calls `init()` if not already initialized. Throws an error if a generation is already in progress.
|
|
1121
|
+
|
|
1122
|
+
**Parameters:**
|
|
1123
|
+
- `audio` - Path to the audio file or raw PCM samples as a byte array.
|
|
1124
|
+
- `options`:
|
|
1125
|
+
- `useVad` - Whether to apply VAD before detection (default: `true`).
|
|
1126
|
+
|
|
1114
1127
|
**`audioEmbed(params: CactusSTTAudioEmbedParams): Promise<CactusSTTAudioEmbedResult>`**
|
|
1115
1128
|
|
|
1116
1129
|
Generates embeddings for the given audio file. Automatically calls `init()` if not already initialized. Throws an error if a generation is already in progress.
|
|
@@ -1134,6 +1147,10 @@ Releases all resources associated with the model. Stops any active streaming ses
|
|
|
1134
1147
|
|
|
1135
1148
|
Returns available speech-to-text models.
|
|
1136
1149
|
|
|
1150
|
+
**`getModelName(): string`**
|
|
1151
|
+
|
|
1152
|
+
Returns the model slug or path the instance was created with.
|
|
1153
|
+
|
|
1137
1154
|
### useCactusSTT Hook
|
|
1138
1155
|
|
|
1139
1156
|
The `useCactusSTT` hook manages a `CactusSTT` instance with reactive state. When model parameters (`model`, `options`) change, the hook creates a new instance and resets all state. The hook automatically cleans up resources when the component unmounts.
|
|
@@ -1216,6 +1233,10 @@ Releases all resources associated with the model. Safe to call even if the model
|
|
|
1216
1233
|
|
|
1217
1234
|
Returns available VAD models.
|
|
1218
1235
|
|
|
1236
|
+
**`getModelName(): string`**
|
|
1237
|
+
|
|
1238
|
+
Returns the model slug or path the instance was created with.
|
|
1239
|
+
|
|
1219
1240
|
### useCactusVAD Hook
|
|
1220
1241
|
|
|
1221
1242
|
The `useCactusVAD` hook manages a `CactusVAD` instance with reactive state. When model parameters (`model`, `options`) change, the hook creates a new instance and resets all state. The hook automatically cleans up resources when the component unmounts.
|
|
@@ -1314,6 +1335,20 @@ The `useCactusIndex` hook manages a `CactusIndex` instance with reactive state.
|
|
|
1314
1335
|
- `compact(): Promise<void>` - Optimizes the index. Sets `isProcessing` to `true` during operation.
|
|
1315
1336
|
- `destroy(): Promise<void>` - Releases all resources. Automatically called when the component unmounts.
|
|
1316
1337
|
|
|
1338
|
+
### getRegistry
|
|
1339
|
+
|
|
1340
|
+
**`getRegistry(): Promise<{ [key: string]: CactusModel }>`**
|
|
1341
|
+
|
|
1342
|
+
Returns all available models from HuggingFace, keyed by model slug. Result is cached across calls.
|
|
1343
|
+
|
|
1344
|
+
```typescript
|
|
1345
|
+
import { getRegistry } from 'cactus-react-native';
|
|
1346
|
+
|
|
1347
|
+
const registry = await getRegistry();
|
|
1348
|
+
const model = registry['qwen3-0.6b'];
|
|
1349
|
+
console.log(model.quantization.int4.url);
|
|
1350
|
+
```
|
|
1351
|
+
|
|
1317
1352
|
## Type Definitions
|
|
1318
1353
|
|
|
1319
1354
|
### CactusLMParams
|
|
@@ -1647,6 +1682,32 @@ interface CactusSTTStreamTranscribeStopResult {
|
|
|
1647
1682
|
}
|
|
1648
1683
|
```
|
|
1649
1684
|
|
|
1685
|
+
### CactusSTTDetectLanguageOptions
|
|
1686
|
+
|
|
1687
|
+
```typescript
|
|
1688
|
+
interface CactusSTTDetectLanguageOptions {
|
|
1689
|
+
useVad?: boolean;
|
|
1690
|
+
}
|
|
1691
|
+
```
|
|
1692
|
+
|
|
1693
|
+
### CactusSTTDetectLanguageParams
|
|
1694
|
+
|
|
1695
|
+
```typescript
|
|
1696
|
+
interface CactusSTTDetectLanguageParams {
|
|
1697
|
+
audio: string | number[];
|
|
1698
|
+
options?: CactusSTTDetectLanguageOptions;
|
|
1699
|
+
}
|
|
1700
|
+
```
|
|
1701
|
+
|
|
1702
|
+
### CactusSTTDetectLanguageResult
|
|
1703
|
+
|
|
1704
|
+
```typescript
|
|
1705
|
+
interface CactusSTTDetectLanguageResult {
|
|
1706
|
+
language: string;
|
|
1707
|
+
confidence?: number;
|
|
1708
|
+
}
|
|
1709
|
+
```
|
|
1710
|
+
|
|
1650
1711
|
### CactusVADParams
|
|
1651
1712
|
|
|
1652
1713
|
```typescript
|
package/lib/module/index.js
CHANGED
|
@@ -12,5 +12,8 @@ export { useCactusSTT } from "./hooks/useCactusSTT.js";
|
|
|
12
12
|
export { useCactusVAD } from "./hooks/useCactusVAD.js";
|
|
13
13
|
export { useCactusIndex } from "./hooks/useCactusIndex.js";
|
|
14
14
|
|
|
15
|
+
// Registry
|
|
16
|
+
export { getRegistry } from "./modelRegistry.js";
|
|
17
|
+
|
|
15
18
|
// Types
|
|
16
19
|
//# sourceMappingURL=index.js.map
|
package/lib/module/index.js.map
CHANGED
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["CactusLM","CactusSTT","CactusVAD","CactusIndex","useCactusLM","useCactusSTT","useCactusVAD","useCactusIndex"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA;AACA,SAASA,QAAQ,QAAQ,uBAAoB;AAC7C,SAASC,SAAS,QAAQ,wBAAqB;AAC/C,SAASC,SAAS,QAAQ,wBAAqB;AAC/C,SAASC,WAAW,QAAQ,0BAAuB;;AAEnD;AACA,SAASC,WAAW,QAAQ,wBAAqB;AACjD,SAASC,YAAY,QAAQ,yBAAsB;AACnD,SAASC,YAAY,QAAQ,yBAAsB;AACnD,SAASC,cAAc,QAAQ,2BAAwB;;AAEvD","ignoreList":[]}
|
|
1
|
+
{"version":3,"names":["CactusLM","CactusSTT","CactusVAD","CactusIndex","useCactusLM","useCactusSTT","useCactusVAD","useCactusIndex","getRegistry"],"sourceRoot":"../../src","sources":["index.tsx"],"mappings":";;AAAA;AACA,SAASA,QAAQ,QAAQ,uBAAoB;AAC7C,SAASC,SAAS,QAAQ,wBAAqB;AAC/C,SAASC,SAAS,QAAQ,wBAAqB;AAC/C,SAASC,WAAW,QAAQ,0BAAuB;;AAEnD;AACA,SAASC,WAAW,QAAQ,wBAAqB;AACjD,SAASC,YAAY,QAAQ,yBAAsB;AACnD,SAASC,YAAY,QAAQ,yBAAsB;AACnD,SAASC,cAAc,QAAQ,2BAAwB;;AAEvD;AACA,SAASC,WAAW,QAAQ,oBAAiB;;AAE7C","ignoreList":[]}
|
|
@@ -1,10 +1,30 @@
|
|
|
1
1
|
"use strict";
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const RUNTIME_VERSION = '1.10.1';
|
|
4
4
|
let registryPromise = null;
|
|
5
5
|
export function getRegistry() {
|
|
6
6
|
return registryPromise ??= fetchRegistry();
|
|
7
7
|
}
|
|
8
|
+
function parseVersionTag(tag) {
|
|
9
|
+
const m = tag.match(/^v(\d+)\.(\d+)(?:\.(\d+))?$/);
|
|
10
|
+
if (!m) return null;
|
|
11
|
+
return [+m[1], +m[2], +(m[3] ?? '0')];
|
|
12
|
+
}
|
|
13
|
+
function compareVersions(a, b) {
|
|
14
|
+
return a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
|
|
15
|
+
}
|
|
16
|
+
async function resolveWeightVersion(modelId) {
|
|
17
|
+
const runtime = parseVersionTag(`v${RUNTIME_VERSION}`);
|
|
18
|
+
if (!runtime) throw new Error(`Invalid runtime version: ${RUNTIME_VERSION}`);
|
|
19
|
+
const res = await fetch(`https://huggingface.co/api/models/${modelId}/refs`);
|
|
20
|
+
if (!res.ok) throw new Error(`Failed to fetch refs for ${modelId}: ${res.status}`);
|
|
21
|
+
const {
|
|
22
|
+
tags = []
|
|
23
|
+
} = await res.json();
|
|
24
|
+
const compatible = tags.map(t => t.name).filter(name => parseVersionTag(name) !== null).filter(name => compareVersions(parseVersionTag(name), runtime) <= 0).sort((a, b) => compareVersions(parseVersionTag(b), parseVersionTag(a)));
|
|
25
|
+
if (!compatible.length) throw new Error('No compatible weight version found');
|
|
26
|
+
return compatible[0];
|
|
27
|
+
}
|
|
8
28
|
async function fetchRegistry() {
|
|
9
29
|
const response = await fetch('https://huggingface.co/api/models?author=Cactus-Compute&full=true').catch(e => {
|
|
10
30
|
registryPromise = null;
|
|
@@ -15,6 +35,11 @@ async function fetchRegistry() {
|
|
|
15
35
|
throw new Error(`Failed to fetch model registry: ${response.status}`);
|
|
16
36
|
}
|
|
17
37
|
const models = await response.json();
|
|
38
|
+
if (!models.length) return {};
|
|
39
|
+
const version = await resolveWeightVersion(models[0].id).catch(e => {
|
|
40
|
+
registryPromise = null;
|
|
41
|
+
throw e;
|
|
42
|
+
});
|
|
18
43
|
const registry = {};
|
|
19
44
|
for (const {
|
|
20
45
|
id,
|
|
@@ -23,7 +48,7 @@ async function fetchRegistry() {
|
|
|
23
48
|
const weights = siblings.map(s => s.rfilename).filter(f => f.startsWith('weights/') && f.endsWith('.zip'));
|
|
24
49
|
if (!weights.some(f => f.endsWith('-int4.zip')) || !weights.some(f => f.endsWith('-int8.zip'))) continue;
|
|
25
50
|
const key = weights.find(f => f.endsWith('-int4.zip')).replace('weights/', '').replace('-int4.zip', '');
|
|
26
|
-
const base = `https://huggingface.co/${id}/resolve/${
|
|
51
|
+
const base = `https://huggingface.co/${id}/resolve/${version}/weights/${key}`;
|
|
27
52
|
registry[key] = {
|
|
28
53
|
quantization: {
|
|
29
54
|
int4: {
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"names":["
|
|
1
|
+
{"version":3,"names":["RUNTIME_VERSION","registryPromise","getRegistry","fetchRegistry","parseVersionTag","tag","m","match","compareVersions","a","b","resolveWeightVersion","modelId","runtime","Error","res","fetch","ok","status","tags","json","compatible","map","t","name","filter","sort","length","response","catch","e","models","version","id","registry","siblings","weights","s","rfilename","f","startsWith","endsWith","some","key","find","replace","base","quantization","int4","sizeMb","url","pro","apple","int8"],"sourceRoot":"../../src","sources":["modelRegistry.ts"],"mappings":"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","ignoreList":[]}
|
|
@@ -6,6 +6,7 @@ export { useCactusLM } from './hooks/useCactusLM';
|
|
|
6
6
|
export { useCactusSTT } from './hooks/useCactusSTT';
|
|
7
7
|
export { useCactusVAD } from './hooks/useCactusVAD';
|
|
8
8
|
export { useCactusIndex } from './hooks/useCactusIndex';
|
|
9
|
+
export { getRegistry } from './modelRegistry';
|
|
9
10
|
export type { CactusModel, CactusModelOptions } from './types/common';
|
|
10
11
|
export type { CactusLMParams, CactusLMDownloadParams, CactusLMMessage, CactusLMCompleteOptions, CactusLMTool, CactusLMCompleteParams, CactusLMCompleteResult, CactusLMTokenizeParams, CactusLMTokenizeResult, CactusLMScoreWindowParams, CactusLMScoreWindowResult, CactusLMEmbedParams, CactusLMEmbedResult, CactusLMImageEmbedParams, CactusLMImageEmbedResult, } from './types/CactusLM';
|
|
11
12
|
export type { CactusSTTParams, CactusSTTDownloadParams, CactusSTTTranscribeOptions, CactusSTTTranscribeParams, CactusSTTTranscribeResult, CactusSTTAudioEmbedParams, CactusSTTAudioEmbedResult, CactusSTTStreamTranscribeStartOptions, CactusSTTStreamTranscribeProcessParams, CactusSTTStreamTranscribeProcessResult, CactusSTTStreamTranscribeStopResult, CactusSTTDetectLanguageOptions, CactusSTTDetectLanguageParams, CactusSTTDetectLanguageResult, } from './types/CactusSTT';
|
|
@@ -1 +1 @@
|
|
|
1
|
-
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACtE,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,qCAAqC,EACrC,sCAAsC,EACtC,sCAAsC,EACtC,mCAAmC,EACnC,8BAA8B,EAC9B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC"}
|
|
1
|
+
{"version":3,"file":"index.d.ts","sourceRoot":"","sources":["../../../src/index.tsx"],"names":[],"mappings":"AACA,OAAO,EAAE,QAAQ,EAAE,MAAM,oBAAoB,CAAC;AAC9C,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,SAAS,EAAE,MAAM,qBAAqB,CAAC;AAChD,OAAO,EAAE,WAAW,EAAE,MAAM,uBAAuB,CAAC;AAGpD,OAAO,EAAE,WAAW,EAAE,MAAM,qBAAqB,CAAC;AAClD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,YAAY,EAAE,MAAM,sBAAsB,CAAC;AACpD,OAAO,EAAE,cAAc,EAAE,MAAM,wBAAwB,CAAC;AAGxD,OAAO,EAAE,WAAW,EAAE,MAAM,iBAAiB,CAAC;AAG9C,YAAY,EAAE,WAAW,EAAE,kBAAkB,EAAE,MAAM,gBAAgB,CAAC;AACtE,YAAY,EACV,cAAc,EACd,sBAAsB,EACtB,eAAe,EACf,uBAAuB,EACvB,YAAY,EACZ,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,sBAAsB,EACtB,yBAAyB,EACzB,yBAAyB,EACzB,mBAAmB,EACnB,mBAAmB,EACnB,wBAAwB,EACxB,wBAAwB,GACzB,MAAM,kBAAkB,CAAC;AAC1B,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,0BAA0B,EAC1B,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,yBAAyB,EACzB,qCAAqC,EACrC,sCAAsC,EACtC,sCAAsC,EACtC,mCAAmC,EACnC,8BAA8B,EAC9B,6BAA6B,EAC7B,6BAA6B,GAC9B,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,eAAe,EACf,uBAAuB,EACvB,kBAAkB,EAClB,gBAAgB,EAChB,gBAAgB,EAChB,eAAe,GAChB,MAAM,mBAAmB,CAAC;AAC3B,YAAY,EACV,iBAAiB,EACjB,oBAAoB,EACpB,oBAAoB,EACpB,oBAAoB,EACpB,uBAAuB,EACvB,sBAAsB,EACtB,sBAAsB,EACtB,uBAAuB,GACxB,MAAM,qBAAqB,CAAC"}
|
package/package.json
CHANGED
package/src/index.tsx
CHANGED
|
@@ -10,6 +10,9 @@ export { useCactusSTT } from './hooks/useCactusSTT';
|
|
|
10
10
|
export { useCactusVAD } from './hooks/useCactusVAD';
|
|
11
11
|
export { useCactusIndex } from './hooks/useCactusIndex';
|
|
12
12
|
|
|
13
|
+
// Registry
|
|
14
|
+
export { getRegistry } from './modelRegistry';
|
|
15
|
+
|
|
13
16
|
// Types
|
|
14
17
|
export type { CactusModel, CactusModelOptions } from './types/common';
|
|
15
18
|
export type {
|
package/src/modelRegistry.ts
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
import type { CactusModel } from './types/common';
|
|
2
2
|
|
|
3
|
-
const
|
|
3
|
+
const RUNTIME_VERSION = '1.10.1';
|
|
4
4
|
|
|
5
5
|
let registryPromise: Promise<{ [key: string]: CactusModel }> | null = null;
|
|
6
6
|
|
|
@@ -8,6 +8,39 @@ export function getRegistry(): Promise<{ [key: string]: CactusModel }> {
|
|
|
8
8
|
return (registryPromise ??= fetchRegistry());
|
|
9
9
|
}
|
|
10
10
|
|
|
11
|
+
function parseVersionTag(tag: string): [number, number, number] | null {
|
|
12
|
+
const m = tag.match(/^v(\d+)\.(\d+)(?:\.(\d+))?$/);
|
|
13
|
+
if (!m) return null;
|
|
14
|
+
return [+m[1]!, +m[2]!, +(m[3] ?? '0')];
|
|
15
|
+
}
|
|
16
|
+
|
|
17
|
+
function compareVersions(
|
|
18
|
+
a: [number, number, number],
|
|
19
|
+
b: [number, number, number]
|
|
20
|
+
): number {
|
|
21
|
+
return a[0] - b[0] || a[1] - b[1] || a[2] - b[2];
|
|
22
|
+
}
|
|
23
|
+
|
|
24
|
+
async function resolveWeightVersion(modelId: string): Promise<string> {
|
|
25
|
+
const runtime = parseVersionTag(`v${RUNTIME_VERSION}`);
|
|
26
|
+
if (!runtime) throw new Error(`Invalid runtime version: ${RUNTIME_VERSION}`);
|
|
27
|
+
|
|
28
|
+
const res = await fetch(`https://huggingface.co/api/models/${modelId}/refs`);
|
|
29
|
+
if (!res.ok)
|
|
30
|
+
throw new Error(`Failed to fetch refs for ${modelId}: ${res.status}`);
|
|
31
|
+
|
|
32
|
+
const { tags = [] } = (await res.json()) as { tags: { name: string }[] };
|
|
33
|
+
|
|
34
|
+
const compatible = tags
|
|
35
|
+
.map((t) => t.name)
|
|
36
|
+
.filter((name) => parseVersionTag(name) !== null)
|
|
37
|
+
.filter((name) => compareVersions(parseVersionTag(name)!, runtime) <= 0)
|
|
38
|
+
.sort((a, b) => compareVersions(parseVersionTag(b)!, parseVersionTag(a)!));
|
|
39
|
+
|
|
40
|
+
if (!compatible.length) throw new Error('No compatible weight version found');
|
|
41
|
+
return compatible[0]!;
|
|
42
|
+
}
|
|
43
|
+
|
|
11
44
|
async function fetchRegistry(): Promise<{ [key: string]: CactusModel }> {
|
|
12
45
|
const response = await fetch(
|
|
13
46
|
'https://huggingface.co/api/models?author=Cactus-Compute&full=true'
|
|
@@ -21,6 +54,13 @@ async function fetchRegistry(): Promise<{ [key: string]: CactusModel }> {
|
|
|
21
54
|
}
|
|
22
55
|
|
|
23
56
|
const models: any[] = await response.json();
|
|
57
|
+
if (!models.length) return {};
|
|
58
|
+
|
|
59
|
+
const version = await resolveWeightVersion(models[0]!.id).catch((e) => {
|
|
60
|
+
registryPromise = null;
|
|
61
|
+
throw e;
|
|
62
|
+
});
|
|
63
|
+
|
|
24
64
|
const registry: { [key: string]: CactusModel } = {};
|
|
25
65
|
|
|
26
66
|
for (const { id, siblings = [] } of models) {
|
|
@@ -39,7 +79,7 @@ async function fetchRegistry(): Promise<{ [key: string]: CactusModel }> {
|
|
|
39
79
|
.replace('weights/', '')
|
|
40
80
|
.replace('-int4.zip', '');
|
|
41
81
|
|
|
42
|
-
const base = `https://huggingface.co/${id}/resolve/${
|
|
82
|
+
const base = `https://huggingface.co/${id}/resolve/${version}/weights/${key}`;
|
|
43
83
|
|
|
44
84
|
registry[key] = {
|
|
45
85
|
quantization: {
|