@qvac/sdk 0.20.1 → 0.21.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.
Files changed (104) hide show
  1. package/NOTICE +130 -62
  2. package/README.md +39 -5
  3. package/dist/examples/advisory-model-fit.d.ts +17 -16
  4. package/dist/examples/advisory-model-fit.js +18 -18
  5. package/dist/examples/asr/parakeet-indic-conformer-filesystem.js +3 -3
  6. package/dist/examples/asr/parakeet-unified-coreml.d.ts +2 -0
  7. package/dist/examples/asr/parakeet-unified-coreml.js +113 -0
  8. package/dist/examples/assess-model-fit.js +9 -4
  9. package/dist/examples/model-fit-ui/server.js +5 -2
  10. package/dist/examples/rpc-inference.d.ts +2 -0
  11. package/dist/examples/rpc-inference.js +51 -0
  12. package/dist/examples/rpc-server.d.ts +2 -0
  13. package/dist/examples/rpc-server.js +32 -0
  14. package/dist/examples/tools/llamacpp-deferred-tools.d.ts +2 -0
  15. package/dist/examples/tools/llamacpp-deferred-tools.js +77 -0
  16. package/dist/examples/tts/audio8.js +4 -0
  17. package/dist/examples/tts/moss-dialogue.d.ts +2 -0
  18. package/dist/examples/tts/moss-dialogue.js +63 -0
  19. package/dist/examples/tts/moss.d.ts +2 -0
  20. package/dist/examples/tts/moss.js +71 -0
  21. package/dist/scripts/contract/build-contract.d.ts +2 -1
  22. package/dist/scripts/contract/build-contract.js +4 -1
  23. package/dist/scripts/contract/build-numeric-constants.d.ts +15 -0
  24. package/dist/scripts/contract/build-numeric-constants.js +13 -0
  25. package/dist/scripts/contract/method-shapes.d.ts +3 -0
  26. package/dist/scripts/contract/method-shapes.js +3 -0
  27. package/dist/scripts/enforce-inference-versions.d.ts +18 -0
  28. package/dist/scripts/enforce-inference-versions.js +158 -0
  29. package/dist/scripts/generate-bare-kit-runtimes.d.ts +2 -0
  30. package/dist/scripts/generate-bare-kit-runtimes.js +106 -0
  31. package/dist/src/client/api/assess-model-fit.d.ts +5 -4
  32. package/dist/src/client/api/assess-model-fit.js +24 -7
  33. package/dist/src/client/api/bci-transcribe.d.ts +4 -1
  34. package/dist/src/client/api/get-system-resources.d.ts +8 -0
  35. package/dist/src/client/api/get-system-resources.js +8 -0
  36. package/dist/src/client/api/index.d.ts +1 -0
  37. package/dist/src/client/api/index.js +1 -0
  38. package/dist/src/client/api/rpc-server.d.ts +20 -0
  39. package/dist/src/client/api/rpc-server.js +45 -0
  40. package/dist/src/client/api/text-to-speech.d.ts +9 -0
  41. package/dist/src/client/api/text-to-speech.js +9 -0
  42. package/dist/src/client/api/transcribe.d.ts +21 -15
  43. package/dist/src/client/api/transcribe.js +65 -20
  44. package/dist/src/client/rpc/rpc-error.js +11 -7
  45. package/dist/src/commands/bundle/entry-gen.d.ts +2 -2
  46. package/dist/src/commands/bundle/entry-gen.js +8 -4
  47. package/dist/src/commands/bundle/index.d.ts +20 -0
  48. package/dist/src/commands/bundle/index.js +88 -12
  49. package/dist/src/commands/bundle/plugins.js +1 -1
  50. package/dist/src/commands/command-logger.d.ts +6 -0
  51. package/dist/src/commands/command-logger.js +12 -0
  52. package/dist/src/commands/host-prebuilds/index.d.ts +71 -0
  53. package/dist/src/commands/host-prebuilds/index.js +227 -0
  54. package/dist/src/commands/host-prebuilds/package-manager.d.ts +54 -0
  55. package/dist/src/commands/host-prebuilds/package-manager.js +278 -0
  56. package/dist/src/commands/index.d.ts +10 -1
  57. package/dist/src/commands/index.js +6 -0
  58. package/dist/src/commands/verify/abi.d.ts +22 -2
  59. package/dist/src/commands/verify/abi.js +49 -27
  60. package/dist/src/commands/verify/addon-source.d.ts +22 -0
  61. package/dist/src/commands/verify/addon-source.js +69 -3
  62. package/dist/src/commands/verify/bare-kit-runtime.d.ts +38 -0
  63. package/dist/src/commands/verify/bare-kit-runtime.js +201 -0
  64. package/dist/src/commands/verify/bare-kit-runtimes.d.ts +12 -0
  65. package/dist/src/commands/verify/bare-kit-runtimes.js +108 -0
  66. package/dist/src/commands/verify/bundle-source.js +16 -15
  67. package/dist/src/commands/verify/engines-advice.d.ts +73 -0
  68. package/dist/src/commands/verify/engines-advice.js +271 -0
  69. package/dist/src/commands/verify/index.d.ts +22 -0
  70. package/dist/src/commands/verify/index.js +151 -13
  71. package/dist/src/commands/verify/node-modules-source.js +43 -39
  72. package/dist/src/commands/verify/prebuilds.d.ts +19 -0
  73. package/dist/src/commands/verify/prebuilds.js +52 -13
  74. package/dist/src/expo/plugins/index.d.ts +2 -0
  75. package/dist/src/expo/plugins/withMobileBundle.d.ts +15 -5
  76. package/dist/src/expo/plugins/withMobileBundle.js +68 -42
  77. package/dist/src/expo/plugins/withQvacSDK.d.ts +7 -1
  78. package/dist/src/expo/plugins/withQvacSDK.js +6 -3
  79. package/dist/src/index.d.ts +5 -2
  80. package/dist/src/index.js +4 -2
  81. package/dist/src/schemas/sdk-errors-client.d.ts +2 -0
  82. package/dist/src/schemas/sdk-errors-client.js +16 -0
  83. package/dist/src/schemas/sdk-errors-server.d.ts +1 -0
  84. package/dist/src/schemas/sdk-errors-server.js +5 -0
  85. package/dist/src/utils/errors-client.d.ts +15 -0
  86. package/dist/src/utils/errors-client.js +26 -0
  87. package/dist/src/utils/errors-server.d.ts +1 -0
  88. package/dist/src/utils/errors-server.js +1 -0
  89. package/dist/src/utils/mcp-adapter.js +7 -1
  90. package/dist/src/utils/tool-helpers.d.ts +4 -0
  91. package/dist/src/utils/tool-helpers.js +2 -0
  92. package/dist/src/worker/ggml-rpc-server-provider.d.ts +2 -0
  93. package/dist/src/worker/ggml-rpc-server-provider.js +1 -0
  94. package/dist/src/worker/rpc-server-provider.d.ts +3 -0
  95. package/dist/src/worker/rpc-server-provider.js +1 -0
  96. package/package.json +30 -25
  97. package/dist/scripts/enforce-inference-peer-dependencies.d.ts +0 -2
  98. package/dist/scripts/enforce-inference-peer-dependencies.js +0 -39
  99. package/dist/src/deprecate.d.ts +0 -2
  100. package/dist/src/deprecate.js +0 -9
  101. package/dist/src/worker/legacy-worker-entry.d.ts +0 -2
  102. package/dist/src/worker/legacy-worker-entry.js +0 -3
  103. package/dist/src/worker/worker-core.d.ts +0 -7
  104. 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,2 @@
1
+ export {};
2
+ //# sourceMappingURL=generate-bare-kit-runtimes.d.ts.map
@@ -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();
@@ -9,11 +9,12 @@ import { type AssessModelFitInput, type AssessModelFitResult } from '@qvac/infer
9
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
- * the artifact — tens of KB, never the weights — and runs the engine's own
13
- * fitter against it, reported as `native-fit` evidence. Where that is
14
- * unavailable, and for a set of candidates, the calibrated estimate stands.
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.
15
16
  *
16
- * @param input - Candidates with their intended workloads, the declared
17
+ * @param input - Loads to assess in `loadModel`'s own parameters, the declared
17
18
  * execution mode, and the headroom policy.
18
19
  * @returns Per-model and combined verdicts, with the budget and bounds they came
19
20
  * from, plus every assumption that was made.
@@ -1,6 +1,19 @@
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.
@@ -11,17 +24,21 @@ import { InvalidResponseError } from '../../utils/errors-client.js';
11
24
  * should treat it as "cannot say", not "no".
12
25
  *
13
26
  * For a single candidate it fetches the registry's weightless description of
14
- * the artifact — tens of KB, never the weights — and runs the engine's own
15
- * fitter against it, reported as `native-fit` evidence. Where that is
16
- * unavailable, and for a set of candidates, the calibrated estimate stands.
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.
17
31
  *
18
- * @param input - Candidates with their intended workloads, the declared
32
+ * @param input - Loads to assess in `loadModel`'s own parameters, the declared
19
33
  * execution mode, and the headroom policy.
20
34
  * @returns Per-model and combined verdicts, with the budget and bounds they came
21
35
  * from, plus every assumption that was made.
22
36
  */
23
37
  export async function assessModelFit(input) {
24
- const parsed = assessModelFitInputSchema.parse(input);
38
+ const parsed = assessModelFitInputSchema.parse({
39
+ ...input,
40
+ models: input.models.map(withModelType)
41
+ });
25
42
  const request = { type: 'assessModelFit', ...parsed };
26
43
  const response = await send(request);
27
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.
@@ -1,5 +1,5 @@
1
- import { type TranscribeClientParams, type RPCOptions, type TranscribeSegment, type TranscribeStreamRequest, type TranscribeStreamClientParams, type TranscribeStreamSession, type TranscribeStreamMetadataSession, type TranscribeStreamConversationSession, type TranscribeStats } from '@qvac/inference/surface';
2
- import { duplex } from '../rpc/rpc-client.js';
1
+ import { type TranscribeClientParams, type RPCOptions, type TranscribeSegment, type TranscribeStreamRequest, type TranscribeStreamClientParams, type TranscribeStreamSession, type TranscribeStreamMetadataSession, type TranscribeStreamConversationSession, type TranscribeStreamEvent, type TranscribeStats, type InferenceBackendDiagnostics } from '@qvac/inference/surface';
2
+ import { stream, duplex } from '../rpc/rpc-client.js';
3
3
  type TranscribeDuplexFactory = (request: TranscribeStreamRequest, options?: RPCOptions) => ReturnType<typeof duplex>;
4
4
  /**
5
5
  * Transcribe audio and return the complete text. Accepts either a file
@@ -10,24 +10,27 @@ type TranscribeDuplexFactory = (request: TranscribeStreamRequest, options?: RPCO
10
10
  * @param params.audioChunk - Audio input as either a file path (string) or audio buffer
11
11
  * @param params.prompt - Optional initial prompt to guide the transcription
12
12
  * @param params.metadata - When true, resolves to an array of transcript
13
- * segments (`{ text, startMs, endMs, append, id }`)
14
- * instead of joined text. Whisper engine only.
13
+ * segments (`{ text, startMs, endMs, append, id }`,
14
+ * plus `isEndOfTurn` and `startsWord` on parakeet)
15
+ * instead of joined text.
15
16
  * @param options - Optional RPC options including per-call profiling
16
17
  * @returns A promise (decorated with `requestId`) resolving to the
17
18
  * complete transcribed text, or — when `metadata` is true —
18
19
  * the list of transcript segments in emission order. The
19
20
  * `requestId` is reachable synchronously so callers can target
20
21
  * this in-flight transcription with `cancel({ requestId })`
21
- * before `await` resolves.
22
+ * before `await` resolves. `stats` resolves to the terminal engine
23
+ * statistics, including Parakeet's per-run Core ML usage.
22
24
  */
23
- export declare function transcribe(params: TranscribeClientParams & {
24
- metadata: true;
25
- }, options?: RPCOptions): Promise<TranscribeSegment[]> & {
26
- requestId: string;
27
- };
28
- export declare function transcribe(params: TranscribeClientParams, options?: RPCOptions): Promise<string> & {
25
+ type TranscribeCall<T> = Promise<T> & {
29
26
  requestId: string;
27
+ stats: Promise<TranscribeStats | undefined>;
30
28
  };
29
+ export declare function transcribe(params: TranscribeClientParams & {
30
+ metadata: true;
31
+ }, options?: RPCOptions): TranscribeCall<TranscribeSegment[]>;
32
+ export declare function transcribe(params: TranscribeClientParams, options?: RPCOptions): TranscribeCall<string>;
33
+ export declare function createTranscribeCall(params: TranscribeClientParams, options?: RPCOptions, responseStream?: typeof stream): TranscribeCall<string | TranscribeSegment[]>;
31
34
  /**
32
35
  * @deprecated Pass audio via `transcribe()` instead. This overload will be
33
36
  * removed in the next major version.
@@ -57,8 +60,9 @@ export declare function transcribeStream(params: TranscribeClientParams, options
57
60
  * @param params.modelId - The loaded transcription model to use
58
61
  * @param params.prompt - Optional initial prompt to guide transcription
59
62
  * @param params.metadata - When true, the session yields transcript segment
60
- * objects (`{ text, startMs, endMs, append, id }`)
61
- * instead of plain text. Whisper engine only.
63
+ * objects (`{ text, startMs, endMs, append, id }`,
64
+ * plus `isEndOfTurn` and `startsWord` on parakeet)
65
+ * instead of plain text.
62
66
  * @param options - Optional RPC options including per-call profiling.
63
67
  * @returns A session object: call `write(audioChunk)` with a `Uint8Array`
64
68
  * (Node `Buffer` is a `Uint8Array` subtype) to feed audio,
@@ -81,13 +85,15 @@ export declare function transcribeStream(params: TranscribeStreamClientParams, o
81
85
  * to surface strings or segments; `sessionName` is only used to label the
82
86
  * "already iterated" error so callers see the correct session type.
83
87
  */
84
- export declare function createTranscribeStreamSession<T>(params: TranscribeStreamClientParams, options: RPCOptions | undefined, process: (line: string, onStats: (stats: TranscribeStats | undefined) => void) => T | undefined | null, sessionName: string, duplexFactory?: TranscribeDuplexFactory): Promise<{
88
+ export declare function createTranscribeStreamSession<T>(params: TranscribeStreamClientParams, options: RPCOptions | undefined, process: (line: string, onTerminal: (stats: TranscribeStats | undefined, diagnostics: InferenceBackendDiagnostics | undefined) => void) => T | undefined | null, sessionName: string, duplexFactory?: TranscribeDuplexFactory): Promise<{
85
89
  stats: Promise<TranscribeStats | undefined>;
90
+ diagnostics: Promise<InferenceBackendDiagnostics | undefined>;
86
91
  write(audioChunk: Uint8Array): void;
87
92
  end(): void;
88
93
  destroy(): void;
89
94
  [Symbol.asyncIterator](): AsyncIterator<T>;
90
95
  }>;
91
- export declare function processLine(line: string, onStats: (stats: TranscribeStats | undefined) => void): string | undefined | null;
96
+ export declare function processLine(line: string, onTerminal: (stats: TranscribeStats | undefined, diagnostics: InferenceBackendDiagnostics | undefined) => void): string | undefined | null;
97
+ export declare function processLineConversation(line: string, wantsMetadata: boolean, onTerminal: (stats: TranscribeStats | undefined, diagnostics: InferenceBackendDiagnostics | undefined) => void): TranscribeStreamEvent | undefined | null;
92
98
  export {};
93
99
  //# sourceMappingURL=transcribe.d.ts.map