@qvac/sdk 0.20.0 → 0.21.0
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/NOTICE +134 -66
- package/README.md +39 -3
- package/dist/examples/advisory-model-fit.d.ts +17 -16
- package/dist/examples/advisory-model-fit.js +18 -18
- package/dist/examples/asr/parakeet-indic-conformer-filesystem.js +3 -3
- package/dist/examples/asr/parakeet-unified-coreml.d.ts +2 -0
- package/dist/examples/asr/parakeet-unified-coreml.js +113 -0
- package/dist/examples/assess-model-fit.js +9 -4
- package/dist/examples/model-fit-ui/server.js +5 -2
- package/dist/examples/rpc-inference.d.ts +2 -0
- package/dist/examples/rpc-inference.js +51 -0
- package/dist/examples/rpc-server.d.ts +2 -0
- package/dist/examples/rpc-server.js +32 -0
- package/dist/examples/tools/llamacpp-deferred-tools.d.ts +2 -0
- package/dist/examples/tools/llamacpp-deferred-tools.js +77 -0
- package/dist/examples/tts/audio8.js +4 -0
- package/dist/examples/tts/moss-dialogue.d.ts +2 -0
- package/dist/examples/tts/moss-dialogue.js +63 -0
- package/dist/examples/tts/moss.d.ts +2 -0
- package/dist/examples/tts/moss.js +71 -0
- package/dist/scripts/contract/build-contract.d.ts +2 -1
- package/dist/scripts/contract/build-contract.js +4 -1
- package/dist/scripts/contract/build-numeric-constants.d.ts +15 -0
- package/dist/scripts/contract/build-numeric-constants.js +13 -0
- package/dist/scripts/contract/method-shapes.d.ts +3 -0
- package/dist/scripts/contract/method-shapes.js +3 -0
- package/dist/scripts/enforce-inference-versions.d.ts +18 -0
- package/dist/scripts/enforce-inference-versions.js +158 -0
- package/dist/scripts/generate-bare-kit-runtimes.d.ts +2 -0
- package/dist/scripts/generate-bare-kit-runtimes.js +106 -0
- package/dist/src/client/api/assess-model-fit.d.ts +11 -5
- package/dist/src/client/api/assess-model-fit.js +30 -8
- package/dist/src/client/api/bci-transcribe.d.ts +4 -1
- package/dist/src/client/api/get-system-resources.d.ts +8 -0
- package/dist/src/client/api/get-system-resources.js +8 -0
- package/dist/src/client/api/index.d.ts +1 -0
- package/dist/src/client/api/index.js +1 -0
- package/dist/src/client/api/rpc-server.d.ts +20 -0
- package/dist/src/client/api/rpc-server.js +45 -0
- package/dist/src/client/api/text-to-speech.d.ts +9 -0
- package/dist/src/client/api/text-to-speech.js +9 -0
- package/dist/src/client/api/transcribe.d.ts +21 -15
- package/dist/src/client/api/transcribe.js +65 -20
- package/dist/src/client/rpc/rpc-error.js +11 -7
- package/dist/src/commands/bundle/entry-gen.d.ts +2 -2
- package/dist/src/commands/bundle/entry-gen.js +8 -4
- package/dist/src/commands/bundle/index.d.ts +20 -0
- package/dist/src/commands/bundle/index.js +88 -12
- package/dist/src/commands/bundle/plugins.js +1 -1
- package/dist/src/commands/command-logger.d.ts +6 -0
- package/dist/src/commands/command-logger.js +12 -0
- package/dist/src/commands/host-prebuilds/index.d.ts +71 -0
- package/dist/src/commands/host-prebuilds/index.js +227 -0
- package/dist/src/commands/host-prebuilds/package-manager.d.ts +54 -0
- package/dist/src/commands/host-prebuilds/package-manager.js +278 -0
- package/dist/src/commands/index.d.ts +10 -1
- package/dist/src/commands/index.js +6 -0
- package/dist/src/commands/verify/abi.d.ts +22 -2
- package/dist/src/commands/verify/abi.js +49 -27
- package/dist/src/commands/verify/addon-source.d.ts +22 -0
- package/dist/src/commands/verify/addon-source.js +69 -3
- package/dist/src/commands/verify/bare-kit-runtime.d.ts +38 -0
- package/dist/src/commands/verify/bare-kit-runtime.js +201 -0
- package/dist/src/commands/verify/bare-kit-runtimes.d.ts +12 -0
- package/dist/src/commands/verify/bare-kit-runtimes.js +108 -0
- package/dist/src/commands/verify/bundle-source.js +16 -15
- package/dist/src/commands/verify/engines-advice.d.ts +73 -0
- package/dist/src/commands/verify/engines-advice.js +271 -0
- package/dist/src/commands/verify/index.d.ts +22 -0
- package/dist/src/commands/verify/index.js +151 -13
- package/dist/src/commands/verify/node-modules-source.js +43 -39
- package/dist/src/commands/verify/prebuilds.d.ts +19 -0
- package/dist/src/commands/verify/prebuilds.js +52 -13
- package/dist/src/expo/plugins/index.d.ts +2 -0
- package/dist/src/expo/plugins/withMobileBundle.d.ts +15 -5
- package/dist/src/expo/plugins/withMobileBundle.js +68 -42
- package/dist/src/expo/plugins/withQvacSDK.d.ts +7 -1
- package/dist/src/expo/plugins/withQvacSDK.js +6 -3
- package/dist/src/index.d.ts +5 -2
- package/dist/src/index.js +4 -2
- package/dist/src/schemas/sdk-errors-client.d.ts +2 -0
- package/dist/src/schemas/sdk-errors-client.js +16 -0
- package/dist/src/schemas/sdk-errors-server.d.ts +1 -0
- package/dist/src/schemas/sdk-errors-server.js +5 -0
- package/dist/src/utils/errors-client.d.ts +15 -0
- package/dist/src/utils/errors-client.js +26 -0
- package/dist/src/utils/errors-server.d.ts +1 -0
- package/dist/src/utils/errors-server.js +1 -0
- package/dist/src/utils/mcp-adapter.js +7 -1
- package/dist/src/utils/tool-helpers.d.ts +4 -0
- package/dist/src/utils/tool-helpers.js +2 -0
- package/dist/src/worker/ggml-rpc-server-provider.d.ts +2 -0
- package/dist/src/worker/ggml-rpc-server-provider.js +1 -0
- package/dist/src/worker/rpc-server-provider.d.ts +3 -0
- package/dist/src/worker/rpc-server-provider.js +1 -0
- package/package.json +31 -27
- package/dist/scripts/enforce-inference-peer-dependencies.d.ts +0 -2
- package/dist/scripts/enforce-inference-peer-dependencies.js +0 -39
- package/dist/src/deprecate.d.ts +0 -2
- package/dist/src/deprecate.js +0 -9
- package/dist/src/worker/legacy-worker-entry.d.ts +0 -2
- package/dist/src/worker/legacy-worker-entry.js +0 -3
- package/dist/src/worker/worker-core.d.ts +0 -7
- package/dist/src/worker/worker-core.js +0 -8
|
@@ -0,0 +1,15 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* JSON export of the SDK's numeric public vocabularies (name → number).
|
|
3
|
+
*
|
|
4
|
+
* `constants-registry.ts` emits string vocabularies only, through
|
|
5
|
+
* `enumFromVocabulary`, so numeric ones ride this artifact instead — the same
|
|
6
|
+
* way `error-codes.json` carries the numeric error registries.
|
|
7
|
+
* `sdk-python/scripts/generate.py` renders it into `_generated/numeric_constants.py`.
|
|
8
|
+
*
|
|
9
|
+
* A separate artifact from schema.json, like models.json / error-codes.json.
|
|
10
|
+
*/
|
|
11
|
+
export interface NumericConstants {
|
|
12
|
+
ASR_BACKEND_IDS: Record<string, number>;
|
|
13
|
+
}
|
|
14
|
+
export declare function buildNumericConstants(): NumericConstants;
|
|
15
|
+
//# sourceMappingURL=build-numeric-constants.d.ts.map
|
|
@@ -0,0 +1,13 @@
|
|
|
1
|
+
import { ASR_BACKEND_IDS } from '@qvac/inference/surface';
|
|
2
|
+
function sortedByValue(record) {
|
|
3
|
+
const entries = Object.entries(record);
|
|
4
|
+
entries.sort(function (a, b) {
|
|
5
|
+
return a[1] - b[1];
|
|
6
|
+
});
|
|
7
|
+
return Object.fromEntries(entries);
|
|
8
|
+
}
|
|
9
|
+
export function buildNumericConstants() {
|
|
10
|
+
return {
|
|
11
|
+
ASR_BACKEND_IDS: sortedByValue(ASR_BACKEND_IDS)
|
|
12
|
+
};
|
|
13
|
+
}
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* export runs under Node, where core's native `bare-*` modules cannot load.
|
|
8
8
|
*/
|
|
9
9
|
export declare const methodShapes: {
|
|
10
|
+
readonly startRpcServer: "reply";
|
|
11
|
+
readonly stopRpcServer: "reply";
|
|
12
|
+
readonly discoverRpcServers: "reply";
|
|
10
13
|
readonly assessModelFit: "reply";
|
|
11
14
|
readonly audioEditStream: "stream";
|
|
12
15
|
readonly audioGenStream: "stream";
|
|
@@ -7,6 +7,9 @@
|
|
|
7
7
|
* export runs under Node, where core's native `bare-*` modules cannot load.
|
|
8
8
|
*/
|
|
9
9
|
export const methodShapes = {
|
|
10
|
+
startRpcServer: 'reply',
|
|
11
|
+
stopRpcServer: 'reply',
|
|
12
|
+
discoverRpcServers: 'reply',
|
|
10
13
|
assessModelFit: 'reply',
|
|
11
14
|
audioEditStream: 'stream',
|
|
12
15
|
audioGenStream: 'stream',
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
type Ranges = Record<string, string>;
|
|
2
|
+
export interface Manifest {
|
|
3
|
+
version?: string;
|
|
4
|
+
dependencies?: Ranges;
|
|
5
|
+
devDependencies?: Ranges;
|
|
6
|
+
peerDependencies?: Ranges;
|
|
7
|
+
peerDependenciesMeta?: Record<string, {
|
|
8
|
+
optional?: boolean;
|
|
9
|
+
}>;
|
|
10
|
+
engines?: Ranges;
|
|
11
|
+
}
|
|
12
|
+
export declare function checkAddonRanges(inferencePkg: Manifest, sdkPkg: Manifest): string[];
|
|
13
|
+
export declare function checkSharedMajorMinor(sdkPkg: Manifest): string[];
|
|
14
|
+
export declare function checkBareRuntimeRange(inferencePkg: Manifest, sdkPkg: Manifest): string[];
|
|
15
|
+
export declare function collectVersionFailures(inferencePkg: Manifest, sdkPkg: Manifest): string[];
|
|
16
|
+
export declare function runEnforceInferenceVersionsCli(): void;
|
|
17
|
+
export {};
|
|
18
|
+
//# sourceMappingURL=enforce-inference-versions.d.ts.map
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
// The version rules that tie @qvac/sdk's manifest to @qvac/inference. All are
|
|
2
|
+
// checked here and every failure is reported in one run.
|
|
3
|
+
//
|
|
4
|
+
// 1. Addon ranges. @qvac/inference's peerDependencies is the source of truth for
|
|
5
|
+
// the inference addons. For every addon p in it, inference's
|
|
6
|
+
// devDependencies.p and the SDK's dependencies.p must carry the identical
|
|
7
|
+
// range. Opt-in services may instead use an optional SDK peer plus a dev dependency.
|
|
8
|
+
//
|
|
9
|
+
// 2. Shared major.minor. @qvac/sdk and @qvac/inference expose the same API, so
|
|
10
|
+
// the major and minor of the SDK's own version must equal the major and minor
|
|
11
|
+
// of the @qvac/inference range it depends on. Patch numbers are free on both
|
|
12
|
+
// sides, so @qvac/sdk 0.19.4 may depend on @qvac/inference ^0.19.2. The range
|
|
13
|
+
// operator must hold the dependency inside that one major.minor: a caret does
|
|
14
|
+
// below 1.0.0 (^0.19.0 is >=0.19.0 <0.20.0) but not from 1.0.0 up (^1.19.0
|
|
15
|
+
// also allows 1.20.0), so a tilde is required there.
|
|
16
|
+
//
|
|
17
|
+
// 3. Bare runtime. Every version allowed by the SDK's bare-runtime dependency
|
|
18
|
+
// must satisfy inference's engines.bare requirement, including versions
|
|
19
|
+
// retained by a consumer's existing lockfile.
|
|
20
|
+
//
|
|
21
|
+
// The second rule reads @qvac/sdk's manifest alone and never
|
|
22
|
+
// packages/inference's version. The two move independently between releases —
|
|
23
|
+
// the engine is published first and the SDK follows — so comparing them would
|
|
24
|
+
// fail main for as long as that takes.
|
|
25
|
+
//
|
|
26
|
+
// The checks take manifests rather than reading them, so test/enforce-inference-
|
|
27
|
+
// versions.test.ts can drive them over manifest shapes the repo does not hold.
|
|
28
|
+
import { readFileSync } from 'fs';
|
|
29
|
+
import { join, resolve, dirname } from 'path';
|
|
30
|
+
import { fileURLToPath } from 'url';
|
|
31
|
+
import { subset, validRange } from 'semver';
|
|
32
|
+
const dependency = '@qvac/inference';
|
|
33
|
+
const sdkManifest = 'packages/sdk/package.json';
|
|
34
|
+
export function checkAddonRanges(inferencePkg, sdkPkg) {
|
|
35
|
+
const peers = inferencePkg.peerDependencies ?? {};
|
|
36
|
+
const inferenceDev = inferencePkg.devDependencies ?? {};
|
|
37
|
+
const sdkDeps = sdkPkg.dependencies ?? {};
|
|
38
|
+
const drifts = [];
|
|
39
|
+
for (const [name, peer] of Object.entries(peers)) {
|
|
40
|
+
const dev = inferenceDev[name];
|
|
41
|
+
const optionalPeer = sdkPkg.peerDependenciesMeta?.[name]?.optional === true;
|
|
42
|
+
const dep = sdkDeps[name] ?? (optionalPeer ? sdkPkg.peerDependencies?.[name] : undefined);
|
|
43
|
+
const mismatches = [];
|
|
44
|
+
if (dep !== peer)
|
|
45
|
+
mismatches.push(dep === undefined ? 'SDK is missing it' : `SDK has ${dep}`);
|
|
46
|
+
if (sdkDeps[name] === undefined && optionalPeer && sdkPkg.devDependencies?.[name] !== peer) {
|
|
47
|
+
mismatches.push('SDK devDependencies must match its optional peer');
|
|
48
|
+
}
|
|
49
|
+
if (dev !== peer) {
|
|
50
|
+
mismatches.push(dev === undefined
|
|
51
|
+
? 'inference devDependencies is missing it'
|
|
52
|
+
: `inference devDependencies has ${dev}`);
|
|
53
|
+
}
|
|
54
|
+
if (mismatches.length > 0) {
|
|
55
|
+
drifts.push(`${name}: inference has it as ${peer} in peerDependencies, but ${mismatches.join(' and ')}.`);
|
|
56
|
+
}
|
|
57
|
+
}
|
|
58
|
+
if (drifts.length === 0)
|
|
59
|
+
return [];
|
|
60
|
+
return [
|
|
61
|
+
`${drifts.join('\n')}\n\nPlease ensure the SDK dependencies and inference devDependencies use the same addon versions as inference's peerDependencies.`
|
|
62
|
+
];
|
|
63
|
+
}
|
|
64
|
+
export function checkSharedMajorMinor(sdkPkg) {
|
|
65
|
+
const rawVersion = sdkPkg.version;
|
|
66
|
+
const rawRange = sdkPkg.dependencies?.[dependency];
|
|
67
|
+
if (rawVersion === undefined)
|
|
68
|
+
return [`${sdkManifest} declares no version.`];
|
|
69
|
+
if (rawRange === undefined)
|
|
70
|
+
return [`${sdkManifest} declares no ${dependency} dependency.`];
|
|
71
|
+
// Specs that point somewhere other than the published package: the workspace
|
|
72
|
+
// link used for development and the pod checks (`sdk-source:workspace` writes
|
|
73
|
+
// `file:../inference`), and the npm alias the GPR dev build pins. They carry no
|
|
74
|
+
// major.minor to compare, so there is nothing to check.
|
|
75
|
+
const localPrefixes = ['file:', 'link:', 'npm:'];
|
|
76
|
+
const localSpec = localPrefixes.find(function (prefix) {
|
|
77
|
+
return rawRange.startsWith(prefix);
|
|
78
|
+
});
|
|
79
|
+
if (localSpec !== undefined) {
|
|
80
|
+
console.log(`${dependency} points at "${rawRange}", not a published version; skipping the major.minor check.`);
|
|
81
|
+
return [];
|
|
82
|
+
}
|
|
83
|
+
const versionMatch = /^(\d+)\.(\d+)\.\d+$/.exec(rawVersion);
|
|
84
|
+
if (versionMatch === null) {
|
|
85
|
+
return [`@qvac/sdk version "${rawVersion}" is not a plain x.y.z version.`];
|
|
86
|
+
}
|
|
87
|
+
const sdkMajorMinor = `${versionMatch[1]}.${versionMatch[2]}`;
|
|
88
|
+
const rangeMatch = /^([\^~])(\d+)\.(\d+)\.\d+$/.exec(rawRange);
|
|
89
|
+
if (rangeMatch === null) {
|
|
90
|
+
return [
|
|
91
|
+
`${dependency} is declared as "${rawRange}", which this check cannot read.\n` +
|
|
92
|
+
`Write it as one caret or tilde range over an exact version, e.g. "^${sdkMajorMinor}.0".`
|
|
93
|
+
];
|
|
94
|
+
}
|
|
95
|
+
const operator = rangeMatch[1];
|
|
96
|
+
const rangeMajorMinor = `${rangeMatch[2]}.${rangeMatch[3]}`;
|
|
97
|
+
if (sdkMajorMinor !== rangeMajorMinor) {
|
|
98
|
+
return [
|
|
99
|
+
`Version mismatch: @qvac/sdk is ${rawVersion} (major.minor ${sdkMajorMinor}) but depends ` +
|
|
100
|
+
`on ${dependency} "${rawRange}" (major.minor ${rangeMajorMinor}).\n\n` +
|
|
101
|
+
`The two ship the same API and must share a major.minor. Either set the range to ` +
|
|
102
|
+
`${sdkMajorMinor}, or move @qvac/sdk to ${rangeMajorMinor}.0 — publishing ` +
|
|
103
|
+
`@qvac/inference ${rangeMajorMinor}.0 first, so the range resolves from npm.`
|
|
104
|
+
];
|
|
105
|
+
}
|
|
106
|
+
if (Number(rangeMatch[2]) >= 1 && operator !== '~') {
|
|
107
|
+
return [
|
|
108
|
+
`${dependency} is declared as "${rawRange}". From 1.0.0 up, a caret range also allows the ` +
|
|
109
|
+
`next minor, which is a different API. Use "~${rawRange.slice(1)}".`
|
|
110
|
+
];
|
|
111
|
+
}
|
|
112
|
+
return [];
|
|
113
|
+
}
|
|
114
|
+
export function checkBareRuntimeRange(inferencePkg, sdkPkg) {
|
|
115
|
+
const required = inferencePkg.engines?.['bare'];
|
|
116
|
+
if (required === undefined)
|
|
117
|
+
return [];
|
|
118
|
+
if (validRange(required) === null) {
|
|
119
|
+
return [`@qvac/inference engines.bare "${required}" is not a valid semver range.`];
|
|
120
|
+
}
|
|
121
|
+
const runtime = sdkPkg.dependencies?.['bare-runtime'];
|
|
122
|
+
if (runtime === undefined || validRange(runtime) === null) {
|
|
123
|
+
return [`${sdkManifest} must declare a valid bare-runtime dependency range.`];
|
|
124
|
+
}
|
|
125
|
+
if (!subset(runtime, required)) {
|
|
126
|
+
return [
|
|
127
|
+
`SDK bare-runtime "${runtime}" permits versions outside inference's engines.bare "${required}". ` +
|
|
128
|
+
'Align the runtime dependency so an existing consumer lockfile cannot retain an unsupported worker.'
|
|
129
|
+
];
|
|
130
|
+
}
|
|
131
|
+
return [];
|
|
132
|
+
}
|
|
133
|
+
export function collectVersionFailures(inferencePkg, sdkPkg) {
|
|
134
|
+
return [
|
|
135
|
+
...checkAddonRanges(inferencePkg, sdkPkg),
|
|
136
|
+
...checkSharedMajorMinor(sdkPkg),
|
|
137
|
+
...checkBareRuntimeRange(inferencePkg, sdkPkg)
|
|
138
|
+
];
|
|
139
|
+
}
|
|
140
|
+
function readManifest(dir) {
|
|
141
|
+
return JSON.parse(readFileSync(join(dir, 'package.json'), 'utf8'));
|
|
142
|
+
}
|
|
143
|
+
export function runEnforceInferenceVersionsCli() {
|
|
144
|
+
const sdkDir = resolve(dirname(fileURLToPath(import.meta.url)), '..');
|
|
145
|
+
const inferenceDir = resolve(sdkDir, '..', 'inference');
|
|
146
|
+
const failures = collectVersionFailures(readManifest(inferenceDir), readManifest(sdkDir));
|
|
147
|
+
if (failures.length > 0) {
|
|
148
|
+
console.error(failures.join('\n\n'));
|
|
149
|
+
process.exit(1);
|
|
150
|
+
}
|
|
151
|
+
}
|
|
152
|
+
function isMainModule() {
|
|
153
|
+
const entryPath = process.argv[1];
|
|
154
|
+
return entryPath !== undefined && resolve(entryPath) === fileURLToPath(import.meta.url);
|
|
155
|
+
}
|
|
156
|
+
if (isMainModule()) {
|
|
157
|
+
runEnforceInferenceVersionsCli();
|
|
158
|
+
}
|
|
@@ -0,0 +1,106 @@
|
|
|
1
|
+
import { promises as fsp } from 'node:fs';
|
|
2
|
+
import path from 'node:path';
|
|
3
|
+
import { fileURLToPath } from 'node:url';
|
|
4
|
+
import semver from 'semver';
|
|
5
|
+
import { fetchBareKitVersionFromGitHub, fetchBareVersionFromGitHub, fetchText, REACT_NATIVE_BARE_KIT } from '../src/commands/verify/bare-kit-runtime.js';
|
|
6
|
+
import { BARE_KIT_BARE_VERSIONS, REACT_NATIVE_BARE_KIT_RUNTIMES } from '../src/commands/verify/bare-kit-runtimes.js';
|
|
7
|
+
const CONCURRENCY = 8;
|
|
8
|
+
const OUTPUT_PATH = path.resolve(path.dirname(fileURLToPath(import.meta.url)), '..', 'src', 'commands', 'verify', 'bare-kit-runtimes.ts');
|
|
9
|
+
async function listPublishedVersions() {
|
|
10
|
+
const metadata = JSON.parse(await fetchText(`https://registry.npmjs.org/${REACT_NATIVE_BARE_KIT}`));
|
|
11
|
+
return Object.keys(metadata.versions);
|
|
12
|
+
}
|
|
13
|
+
async function listBareKitTags() {
|
|
14
|
+
const tags = JSON.parse(await fetchText('https://api.github.com/repos/holepunchto/bare-kit/tags?per_page=100'));
|
|
15
|
+
return tags.map((tag) => tag.name.replace(/^v/, ''));
|
|
16
|
+
}
|
|
17
|
+
function latest(versions) {
|
|
18
|
+
const valid = versions.filter((version) => semver.valid(version) !== null);
|
|
19
|
+
return valid.length === 0 ? null : valid.sort(semver.rcompare)[0];
|
|
20
|
+
}
|
|
21
|
+
/**
|
|
22
|
+
* Releases newer than the newest one already in the table, oldest first.
|
|
23
|
+
* Everything at or below it was probed on an earlier run, including the old
|
|
24
|
+
* react-native-bare-kit releases that have no CMakeLists.txt to parse.
|
|
25
|
+
*/
|
|
26
|
+
function newerThan(versions, lastKnown) {
|
|
27
|
+
return versions
|
|
28
|
+
.filter((version) => semver.valid(version) !== null)
|
|
29
|
+
.filter((version) => lastKnown === null || semver.gt(version, lastKnown))
|
|
30
|
+
.sort(semver.compare);
|
|
31
|
+
}
|
|
32
|
+
async function mapConcurrent(items, fn) {
|
|
33
|
+
const results = new Array(items.length);
|
|
34
|
+
let next = 0;
|
|
35
|
+
async function worker() {
|
|
36
|
+
while (next < items.length) {
|
|
37
|
+
const index = next++;
|
|
38
|
+
results[index] = await fn(items[index]);
|
|
39
|
+
}
|
|
40
|
+
}
|
|
41
|
+
await Promise.all(Array.from({ length: CONCURRENCY }, worker));
|
|
42
|
+
return results;
|
|
43
|
+
}
|
|
44
|
+
async function tryFetch(fn) {
|
|
45
|
+
try {
|
|
46
|
+
return await fn();
|
|
47
|
+
}
|
|
48
|
+
catch {
|
|
49
|
+
return null;
|
|
50
|
+
}
|
|
51
|
+
}
|
|
52
|
+
function sortedEntries(record) {
|
|
53
|
+
return Object.entries(record).sort(([a], [b]) => semver.compare(a, b));
|
|
54
|
+
}
|
|
55
|
+
function render(runtimes, bareByBareKit) {
|
|
56
|
+
const lines = [
|
|
57
|
+
'// Generated by scripts/generate-bare-kit-runtimes.ts. Do not edit by hand.',
|
|
58
|
+
'',
|
|
59
|
+
'export interface BareKitRuntime {',
|
|
60
|
+
' bareKit: string',
|
|
61
|
+
' bare: string',
|
|
62
|
+
'}',
|
|
63
|
+
'',
|
|
64
|
+
'/**',
|
|
65
|
+
' * react-native-bare-kit releases whose CMakeLists.txt names the bare-kit',
|
|
66
|
+
' * prebuilds it ships. Older releases carry no such reference.',
|
|
67
|
+
' */',
|
|
68
|
+
'export const REACT_NATIVE_BARE_KIT_RUNTIMES: Record<string, BareKitRuntime> = {'
|
|
69
|
+
];
|
|
70
|
+
lines.push(...entryLines(sortedEntries(runtimes).map(([version, runtime]) => `'${version}': { bareKit: '${runtime.bareKit}', bare: '${runtime.bare}' }`)));
|
|
71
|
+
lines.push('}', '', '/** Bare version each bare-kit release is built against. */');
|
|
72
|
+
lines.push('export const BARE_KIT_BARE_VERSIONS: Record<string, string> = {');
|
|
73
|
+
lines.push(...entryLines(sortedEntries(bareByBareKit).map(([bareKit, bare]) => `'${bareKit}': '${bare}'`)));
|
|
74
|
+
lines.push('}', '');
|
|
75
|
+
return lines.join('\n');
|
|
76
|
+
}
|
|
77
|
+
/** Object entries in the repo's Prettier style: no trailing comma. */
|
|
78
|
+
function entryLines(entries) {
|
|
79
|
+
return entries.map((entry, index) => ` ${entry}${index === entries.length - 1 ? '' : ','}`);
|
|
80
|
+
}
|
|
81
|
+
async function main() {
|
|
82
|
+
const full = process.argv.includes('--full');
|
|
83
|
+
const bareByBareKit = full ? {} : { ...BARE_KIT_BARE_VERSIONS };
|
|
84
|
+
const runtimes = full ? {} : { ...REACT_NATIVE_BARE_KIT_RUNTIMES };
|
|
85
|
+
const bareKitTags = newerThan(await listBareKitTags(), latest(Object.keys(bareByBareKit)));
|
|
86
|
+
console.log(`Resolving ${bareKitTags.length} new bare-kit releases...`);
|
|
87
|
+
const bareVersions = await mapConcurrent(bareKitTags, (bareKit) => tryFetch(() => fetchBareVersionFromGitHub(bareKit)));
|
|
88
|
+
bareKitTags.forEach((bareKit, index) => {
|
|
89
|
+
const bare = bareVersions[index];
|
|
90
|
+
if (bare)
|
|
91
|
+
bareByBareKit[bareKit] = bare;
|
|
92
|
+
});
|
|
93
|
+
const versions = newerThan(await listPublishedVersions(), latest(Object.keys(runtimes)));
|
|
94
|
+
console.log(`Resolving ${versions.length} new ${REACT_NATIVE_BARE_KIT} releases...`);
|
|
95
|
+
const bareKitByVersion = await mapConcurrent(versions, (version) => tryFetch(() => fetchBareKitVersionFromGitHub(version)));
|
|
96
|
+
versions.forEach((version, index) => {
|
|
97
|
+
const bareKit = bareKitByVersion[index];
|
|
98
|
+
const bare = bareKit ? bareByBareKit[bareKit] : undefined;
|
|
99
|
+
if (bareKit && bare)
|
|
100
|
+
runtimes[version] = { bareKit, bare };
|
|
101
|
+
});
|
|
102
|
+
await fsp.writeFile(OUTPUT_PATH, render(runtimes, bareByBareKit));
|
|
103
|
+
console.log(`Wrote ${Object.keys(runtimes).length} ${REACT_NATIVE_BARE_KIT} and ` +
|
|
104
|
+
`${Object.keys(bareByBareKit).length} bare-kit entries to ${OUTPUT_PATH}`);
|
|
105
|
+
}
|
|
106
|
+
await main();
|
|
@@ -3,12 +3,18 @@ import { type AssessModelFitInput, type AssessModelFitResult } from '@qvac/infer
|
|
|
3
3
|
* Assesses, before anything is downloaded, whether the given models are likely
|
|
4
4
|
* to fit in this device's memory.
|
|
5
5
|
*
|
|
6
|
-
* Advisory only: it does not download weights,
|
|
7
|
-
*
|
|
8
|
-
*
|
|
9
|
-
*
|
|
6
|
+
* Advisory only: it does not download weights, block `loadModel`, reserve
|
|
7
|
+
* memory, or make a performance claim. `unknown` is a real answer — it means
|
|
8
|
+
* the available evidence does not support a verdict either way, and callers
|
|
9
|
+
* should treat it as "cannot say", not "no".
|
|
10
10
|
*
|
|
11
|
-
*
|
|
11
|
+
* For a single candidate it fetches the registry's weightless description of
|
|
12
|
+
* every source that load names — tens of KB each, never the weights — and runs
|
|
13
|
+
* the engine's own fitter against them, reported as `native-fit` evidence.
|
|
14
|
+
* Where that is unavailable, and for a set of candidates, the calibrated
|
|
15
|
+
* estimate stands.
|
|
16
|
+
*
|
|
17
|
+
* @param input - Loads to assess in `loadModel`'s own parameters, the declared
|
|
12
18
|
* execution mode, and the headroom policy.
|
|
13
19
|
* @returns Per-model and combined verdicts, with the budget and bounds they came
|
|
14
20
|
* from, plus every assumption that was made.
|
|
@@ -1,22 +1,44 @@
|
|
|
1
|
-
import { assessModelFitInputSchema } from '@qvac/inference/surface';
|
|
1
|
+
import { assessModelFitInputSchema, inferModelTypeFromModelSrc } from '@qvac/inference/surface';
|
|
2
2
|
import { send } from '../rpc/rpc-client.js';
|
|
3
|
-
import { InvalidResponseError } from '../../utils/errors-client.js';
|
|
3
|
+
import { InvalidResponseError, ModelTypeRequiredError } from '../../utils/errors-client.js';
|
|
4
|
+
/**
|
|
5
|
+
* Names the engine a candidate omitted, from the source it carries.
|
|
6
|
+
*
|
|
7
|
+
* @throws {ModelTypeRequiredError} When the source names no engine either.
|
|
8
|
+
*/
|
|
9
|
+
function withModelType(candidate) {
|
|
10
|
+
if (candidate.modelType !== undefined)
|
|
11
|
+
return candidate;
|
|
12
|
+
const inferred = inferModelTypeFromModelSrc(candidate.modelSrc);
|
|
13
|
+
if (inferred === undefined)
|
|
14
|
+
throw new ModelTypeRequiredError();
|
|
15
|
+
return { ...candidate, modelType: inferred };
|
|
16
|
+
}
|
|
4
17
|
/**
|
|
5
18
|
* Assesses, before anything is downloaded, whether the given models are likely
|
|
6
19
|
* to fit in this device's memory.
|
|
7
20
|
*
|
|
8
|
-
* Advisory only: it does not download weights,
|
|
9
|
-
*
|
|
10
|
-
*
|
|
11
|
-
*
|
|
21
|
+
* Advisory only: it does not download weights, block `loadModel`, reserve
|
|
22
|
+
* memory, or make a performance claim. `unknown` is a real answer — it means
|
|
23
|
+
* the available evidence does not support a verdict either way, and callers
|
|
24
|
+
* should treat it as "cannot say", not "no".
|
|
25
|
+
*
|
|
26
|
+
* For a single candidate it fetches the registry's weightless description of
|
|
27
|
+
* every source that load names — tens of KB each, never the weights — and runs
|
|
28
|
+
* the engine's own fitter against them, reported as `native-fit` evidence.
|
|
29
|
+
* Where that is unavailable, and for a set of candidates, the calibrated
|
|
30
|
+
* estimate stands.
|
|
12
31
|
*
|
|
13
|
-
* @param input -
|
|
32
|
+
* @param input - Loads to assess in `loadModel`'s own parameters, the declared
|
|
14
33
|
* execution mode, and the headroom policy.
|
|
15
34
|
* @returns Per-model and combined verdicts, with the budget and bounds they came
|
|
16
35
|
* from, plus every assumption that was made.
|
|
17
36
|
*/
|
|
18
37
|
export async function assessModelFit(input) {
|
|
19
|
-
const parsed = assessModelFitInputSchema.parse(
|
|
38
|
+
const parsed = assessModelFitInputSchema.parse({
|
|
39
|
+
...input,
|
|
40
|
+
models: input.models.map(withModelType)
|
|
41
|
+
});
|
|
20
42
|
const request = { type: 'assessModelFit', ...parsed };
|
|
21
43
|
const response = await send(request);
|
|
22
44
|
if (response.type !== 'assessModelFit') {
|
|
@@ -37,7 +37,10 @@ export declare function bciTranscribe(params: BciTranscribeClientParams, options
|
|
|
37
37
|
* @param params.modelId - The loaded BCI model to use.
|
|
38
38
|
* @param params.metadata - When true, the session yields transcript segment
|
|
39
39
|
* objects (`{ text, startMs, endMs, append, id }`)
|
|
40
|
-
* instead of plain text.
|
|
40
|
+
* instead of plain text. With `emit: 'delta'`, each
|
|
41
|
+
* segment also carries `windowStartTimestep`: its
|
|
42
|
+
* timestamps are window-local, and this maps them
|
|
43
|
+
* onto the stream timeline.
|
|
41
44
|
* @param params.windowTimesteps - Decode window size in timesteps.
|
|
42
45
|
* @param params.hopTimesteps - How far the window advances between decodes.
|
|
43
46
|
* @param params.emit - `'delta'` (default) yields only the newly-discovered
|
|
@@ -1,3 +1,11 @@
|
|
|
1
1
|
import { type GetSystemResourcesInput, type SystemResources } from '@qvac/inference/surface';
|
|
2
|
+
/**
|
|
3
|
+
* Read the worker's system capabilities and optional resource sample.
|
|
4
|
+
*
|
|
5
|
+
* @param input - Optional settings; set `sample` to request a current resource sample.
|
|
6
|
+
* @returns System capabilities with availability information and a sample when provided by the worker.
|
|
7
|
+
* @throws {InvalidResponseError} If the worker returns a different response type.
|
|
8
|
+
* @throws {Error} If the RPC request fails.
|
|
9
|
+
*/
|
|
2
10
|
export declare function getSystemResources(input?: GetSystemResourcesInput): Promise<SystemResources>;
|
|
3
11
|
//# sourceMappingURL=get-system-resources.d.ts.map
|
|
@@ -1,6 +1,14 @@
|
|
|
1
1
|
import {} from '@qvac/inference/surface';
|
|
2
2
|
import { send } from '../rpc/rpc-client.js';
|
|
3
3
|
import { InvalidResponseError } from '../../utils/errors-client.js';
|
|
4
|
+
/**
|
|
5
|
+
* Read the worker's system capabilities and optional resource sample.
|
|
6
|
+
*
|
|
7
|
+
* @param input - Optional settings; set `sample` to request a current resource sample.
|
|
8
|
+
* @returns System capabilities with availability information and a sample when provided by the worker.
|
|
9
|
+
* @throws {InvalidResponseError} If the worker returns a different response type.
|
|
10
|
+
* @throws {Error} If the RPC request fails.
|
|
11
|
+
*/
|
|
4
12
|
export async function getSystemResources(input) {
|
|
5
13
|
const request = {
|
|
6
14
|
type: 'getSystemResources',
|
|
@@ -37,4 +37,5 @@ export { vlaPreprocessImage, vlaPadState, VLA_DEFAULT_IMAGE_SIZE } from './vla-h
|
|
|
37
37
|
export { audioGen } from './audio-gen.js';
|
|
38
38
|
export { audioEdit } from './audio-edit.js';
|
|
39
39
|
export { audioUnderstand } from './audio-understand.js';
|
|
40
|
+
export { startRpcServer, stopRpcServer, discoverRpcServers } from './rpc-server.js';
|
|
40
41
|
//# sourceMappingURL=index.d.ts.map
|
|
@@ -37,3 +37,4 @@ export { vlaPreprocessImage, vlaPadState, VLA_DEFAULT_IMAGE_SIZE } from './vla-h
|
|
|
37
37
|
export { audioGen } from './audio-gen.js';
|
|
38
38
|
export { audioEdit } from './audio-edit.js';
|
|
39
39
|
export { audioUnderstand } from './audio-understand.js';
|
|
40
|
+
export { startRpcServer, stopRpcServer, discoverRpcServers } from './rpc-server.js';
|
|
@@ -0,0 +1,20 @@
|
|
|
1
|
+
import { type StartRpcServerOptions, type StopRpcServerOptions, type DiscoverRpcServersOptions, type RpcServerInfo, type RpcServerCandidate } from '@qvac/inference/surface';
|
|
2
|
+
/**
|
|
3
|
+
* Start a worker-owned native RPC server. Non-loopback binding and advertising require explicit opt-in.
|
|
4
|
+
* Cancel a pending start with its promise.requestId.
|
|
5
|
+
*/
|
|
6
|
+
export declare function startRpcServer(options?: StartRpcServerOptions): Promise<RpcServerInfo> & {
|
|
7
|
+
requestId: string;
|
|
8
|
+
};
|
|
9
|
+
/** Withdraw the announcement and await native stop. Bare stop has no deadline. */
|
|
10
|
+
export declare function stopRpcServer(options: StopRpcServerOptions): Promise<void>;
|
|
11
|
+
/**
|
|
12
|
+
* Find private-network candidates with device inventories and server RDMA availability.
|
|
13
|
+
* RDMA availability is a server-side offer, not a guarantee of the negotiated transport.
|
|
14
|
+
* Use getRpcDeviceMap with the chosen endpoint registration order before loadModel.
|
|
15
|
+
* Cancel a pending search with its promise.requestId.
|
|
16
|
+
*/
|
|
17
|
+
export declare function discoverRpcServers(options: DiscoverRpcServersOptions): Promise<RpcServerCandidate[]> & {
|
|
18
|
+
requestId: string;
|
|
19
|
+
};
|
|
20
|
+
//# sourceMappingURL=rpc-server.d.ts.map
|
|
@@ -0,0 +1,45 @@
|
|
|
1
|
+
import {} from '@qvac/inference/surface';
|
|
2
|
+
import { send } from '../rpc/rpc-client.js';
|
|
3
|
+
import { InvalidResponseError } from '../../utils/errors-client.js';
|
|
4
|
+
import { decoratePromise } from '../../utils/decorate-promise.js';
|
|
5
|
+
import { generateClientRequestId } from './client-request-id.js';
|
|
6
|
+
/**
|
|
7
|
+
* Start a worker-owned native RPC server. Non-loopback binding and advertising require explicit opt-in.
|
|
8
|
+
* Cancel a pending start with its promise.requestId.
|
|
9
|
+
*/
|
|
10
|
+
export function startRpcServer(options = {}) {
|
|
11
|
+
const requestId = generateClientRequestId();
|
|
12
|
+
return decoratePromise(runStartRpcServer(options, requestId), { requestId });
|
|
13
|
+
}
|
|
14
|
+
async function runStartRpcServer(options, requestId) {
|
|
15
|
+
const response = await send({ ...options, type: 'startRpcServer', requestId });
|
|
16
|
+
if (response.type !== 'startRpcServer')
|
|
17
|
+
throw new InvalidResponseError('startRpcServer');
|
|
18
|
+
return {
|
|
19
|
+
serverId: response.serverId,
|
|
20
|
+
url: response.url,
|
|
21
|
+
rdmaCapable: response.rdmaCapable
|
|
22
|
+
};
|
|
23
|
+
}
|
|
24
|
+
/** Withdraw the announcement and await native stop. Bare stop has no deadline. */
|
|
25
|
+
export async function stopRpcServer(options) {
|
|
26
|
+
const response = await send({ ...options, type: 'stopRpcServer' });
|
|
27
|
+
if (response.type !== 'stopRpcServer')
|
|
28
|
+
throw new InvalidResponseError('stopRpcServer');
|
|
29
|
+
}
|
|
30
|
+
/**
|
|
31
|
+
* Find private-network candidates with device inventories and server RDMA availability.
|
|
32
|
+
* RDMA availability is a server-side offer, not a guarantee of the negotiated transport.
|
|
33
|
+
* Use getRpcDeviceMap with the chosen endpoint registration order before loadModel.
|
|
34
|
+
* Cancel a pending search with its promise.requestId.
|
|
35
|
+
*/
|
|
36
|
+
export function discoverRpcServers(options) {
|
|
37
|
+
const requestId = generateClientRequestId();
|
|
38
|
+
return decoratePromise(runDiscoverRpcServers(options, requestId), { requestId });
|
|
39
|
+
}
|
|
40
|
+
async function runDiscoverRpcServers(options, requestId) {
|
|
41
|
+
const response = await send({ ...options, type: 'discoverRpcServers', requestId });
|
|
42
|
+
if (response.type !== 'discoverRpcServers')
|
|
43
|
+
throw new InvalidResponseError('discoverRpcServers');
|
|
44
|
+
return response.servers;
|
|
45
|
+
}
|
|
@@ -43,6 +43,15 @@ export declare class TtsMulticast {
|
|
|
43
43
|
* metadata with the audio. Multiple consumers can iterate the response
|
|
44
44
|
* independently via the underlying `TtsMulticast`.
|
|
45
45
|
*
|
|
46
|
+
* MOSS models stream natively rather than by sentence: under `stream: true`
|
|
47
|
+
* the whole text is one synthesis whose audio arrives every
|
|
48
|
+
* `streamChunkTokens` codec frames (in one piece when that is unset), so
|
|
49
|
+
* `durationTokens` and a MOSS-TTSD dialogue's reference transcripts apply to
|
|
50
|
+
* the text as a whole. `sentenceStream: true` still splits a single-speaker
|
|
51
|
+
* text; a dialogue rejects it. `sentenceStreamLocale` and
|
|
52
|
+
* `sentenceStreamMaxChunkScalars` configure that splitting, so a MOSS request
|
|
53
|
+
* rejects them unless it sets `sentenceStream: true`.
|
|
54
|
+
*
|
|
46
55
|
* `result.done` resolves to `true` when synthesis completes cleanly, `false`
|
|
47
56
|
* if the consumer breaks out before the terminal frame, or rejects on a
|
|
48
57
|
* pipeline error. Awaiting `done` is safe even when no stream is iterated.
|
|
@@ -202,6 +202,15 @@ function buildTextToSpeechStreamRequest(params, requestId) {
|
|
|
202
202
|
* metadata with the audio. Multiple consumers can iterate the response
|
|
203
203
|
* independently via the underlying `TtsMulticast`.
|
|
204
204
|
*
|
|
205
|
+
* MOSS models stream natively rather than by sentence: under `stream: true`
|
|
206
|
+
* the whole text is one synthesis whose audio arrives every
|
|
207
|
+
* `streamChunkTokens` codec frames (in one piece when that is unset), so
|
|
208
|
+
* `durationTokens` and a MOSS-TTSD dialogue's reference transcripts apply to
|
|
209
|
+
* the text as a whole. `sentenceStream: true` still splits a single-speaker
|
|
210
|
+
* text; a dialogue rejects it. `sentenceStreamLocale` and
|
|
211
|
+
* `sentenceStreamMaxChunkScalars` configure that splitting, so a MOSS request
|
|
212
|
+
* rejects them unless it sets `sentenceStream: true`.
|
|
213
|
+
*
|
|
205
214
|
* `result.done` resolves to `true` when synthesis completes cleanly, `false`
|
|
206
215
|
* if the consumer breaks out before the terminal frame, or rejects on a
|
|
207
216
|
* pipeline error. Awaiting `done` is safe even when no stream is iterated.
|