@qvac/sdk 0.17.0 → 0.18.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.
Files changed (154) hide show
  1. package/NOTICE +83 -18
  2. package/README.md +19 -0
  3. package/dist/client/api/audio-gen.d.ts +17 -0
  4. package/dist/client/api/audio-gen.js +17 -0
  5. package/dist/client/api/finetune.d.ts +2 -0
  6. package/dist/client/api/finetune.js +7 -1
  7. package/dist/client/api/index.d.ts +1 -1
  8. package/dist/client/api/index.js +1 -1
  9. package/dist/client/api/load-model.d.ts +8 -0
  10. package/dist/client/api/transcribe.d.ts +19 -2
  11. package/dist/client/api/transcribe.js +66 -27
  12. package/dist/client/api/translate.d.ts +3 -2
  13. package/dist/client/api/translate.js +42 -21
  14. package/dist/client/api/vla.d.ts +42 -1
  15. package/dist/client/api/vla.js +50 -1
  16. package/dist/commands/bundle/entry-gen.d.ts +4 -0
  17. package/dist/commands/bundle/entry-gen.js +6 -0
  18. package/dist/commands/bundle/index.js +19 -12
  19. package/dist/examples/asr/parakeet-indic-conformer-filesystem.d.ts +2 -0
  20. package/dist/examples/asr/parakeet-indic-conformer-filesystem.js +52 -0
  21. package/dist/examples/audiogen/generate-cover.d.ts +2 -0
  22. package/dist/examples/audiogen/generate-cover.js +100 -0
  23. package/dist/examples/llamacpp-fallback.d.ts +2 -0
  24. package/dist/examples/llamacpp-fallback.js +34 -0
  25. package/dist/examples/multi-job-completion.d.ts +28 -0
  26. package/dist/examples/multi-job-completion.js +128 -0
  27. package/dist/examples/profiling/basic.js +32 -1
  28. package/dist/examples/system-resources.d.ts +2 -0
  29. package/dist/examples/system-resources.js +86 -0
  30. package/dist/examples/tts/audio8.d.ts +2 -0
  31. package/dist/examples/tts/audio8.js +54 -0
  32. package/dist/examples/tts/cosyvoice3.d.ts +2 -0
  33. package/dist/examples/tts/cosyvoice3.js +52 -0
  34. package/dist/examples/vla-groot.js +92 -49
  35. package/dist/index.d.ts +2 -2
  36. package/dist/index.js +2 -2
  37. package/dist/models/registry/models.d.ts +782 -6
  38. package/dist/models/registry/models.js +2664 -1859
  39. package/dist/schemas/audio-gen.d.ts +103 -0
  40. package/dist/schemas/audio-gen.js +135 -4
  41. package/dist/schemas/common.d.ts +550 -11
  42. package/dist/schemas/constants-registry.d.ts +18 -4
  43. package/dist/schemas/constants-registry.js +16 -3
  44. package/dist/schemas/index.d.ts +1 -1
  45. package/dist/schemas/index.js +1 -1
  46. package/dist/schemas/llamacpp-config.d.ts +10 -10
  47. package/dist/schemas/llamacpp-config.js +12 -5
  48. package/dist/schemas/load-model.d.ts +3678 -323
  49. package/dist/schemas/load-model.js +21 -3
  50. package/dist/schemas/sdk-config.d.ts +60 -24
  51. package/dist/schemas/sdk-errors-server.d.ts +1 -0
  52. package/dist/schemas/sdk-errors-server.js +5 -0
  53. package/dist/schemas/text-to-speech.d.ts +1086 -110
  54. package/dist/schemas/text-to-speech.js +194 -4
  55. package/dist/schemas/tools.d.ts +0 -16
  56. package/dist/schemas/tools.js +0 -15
  57. package/dist/schemas/transcription-config.d.ts +2 -0
  58. package/dist/schemas/transcription-config.js +10 -4
  59. package/dist/schemas/transcription.d.ts +3 -0
  60. package/dist/schemas/vla.d.ts +83 -0
  61. package/dist/schemas/vla.js +105 -2
  62. package/dist/scripts/link-workspace-inference.d.ts +2 -0
  63. package/dist/scripts/link-workspace-inference.js +31 -0
  64. package/dist/server/bare/ops/cancel.d.ts +1 -1
  65. package/dist/server/bare/ops/cancel.js +1 -1
  66. package/dist/server/bare/ops/kv-cache-retention.js +11 -0
  67. package/dist/server/bare/ops/kv-cache-utils.d.ts +1 -1
  68. package/dist/server/bare/ops/kv-cache-utils.js +40 -12
  69. package/dist/server/bare/ops/transcribe.d.ts +2 -2
  70. package/dist/server/bare/ops/transcribe.js +54 -48
  71. package/dist/server/bare/ops/translate-stats.d.ts +5 -0
  72. package/dist/server/bare/ops/translate-stats.js +11 -0
  73. package/dist/server/bare/ops/translate.js +66 -38
  74. package/dist/server/bare/ops/unload-model.js +30 -24
  75. package/dist/server/bare/plugins/audiogen-ggml/ops/audio-gen-input.d.ts +20 -0
  76. package/dist/server/bare/plugins/audiogen-ggml/ops/audio-gen-input.js +153 -0
  77. package/dist/server/bare/plugins/audiogen-ggml/ops/audio-gen-stream.js +52 -1
  78. package/dist/server/bare/plugins/audiogen-ggml/plugin.d.ts +28 -0
  79. package/dist/server/bare/plugins/ggml-ocr/plugin.js +3 -1
  80. package/dist/server/bare/plugins/ggml-vla/ops/vla-set-embodiment.d.ts +3 -0
  81. package/dist/server/bare/plugins/ggml-vla/ops/vla-set-embodiment.js +9 -0
  82. package/dist/server/bare/plugins/ggml-vla/plugin.d.ts +37 -0
  83. package/dist/server/bare/plugins/ggml-vla/plugin.js +21 -4
  84. package/dist/server/bare/plugins/llamacpp-completion/ops/batch-completion-stream.js +16 -15
  85. package/dist/server/bare/plugins/llamacpp-completion/ops/cache-logger.d.ts +1 -1
  86. package/dist/server/bare/plugins/llamacpp-completion/ops/cache-logger.js +2 -2
  87. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.d.ts +6 -0
  88. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stats.js +10 -0
  89. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.d.ts +1 -0
  90. package/dist/server/bare/plugins/llamacpp-completion/ops/completion-stream.js +131 -123
  91. package/dist/server/bare/plugins/llamacpp-completion/ops/finetune.js +110 -20
  92. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-session.d.ts +49 -23
  93. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-session.js +308 -143
  94. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.d.ts +1 -0
  95. package/dist/server/bare/plugins/llamacpp-completion/ops/kv-cache-state.js +2 -2
  96. package/dist/server/bare/plugins/llamacpp-completion/plugin.d.ts +6 -6
  97. package/dist/server/bare/plugins/llamacpp-completion/plugin.js +55 -36
  98. package/dist/server/bare/plugins/llamacpp-completion/transform.js +1 -7
  99. package/dist/server/bare/plugins/llamacpp-embedding/plugin.js +2 -3
  100. package/dist/server/bare/plugins/nmtcpp-translation/plugin.js +6 -5
  101. package/dist/server/bare/plugins/parakeet-transcription/plugin.js +27 -16
  102. package/dist/server/bare/plugins/tts-ggml/ops/parler-options.js +23 -3
  103. package/dist/server/bare/plugins/tts-ggml/plugin.d.ts +302 -4
  104. package/dist/server/bare/plugins/tts-ggml/plugin.js +131 -0
  105. package/dist/server/bare/plugins/whispercpp-transcription/plugin.js +48 -39
  106. package/dist/server/bare/registry/model-registry.d.ts +1 -0
  107. package/dist/server/bare/runtime/request-registry-singleton.js +29 -15
  108. package/dist/server/bare/runtime/request-registry.d.ts +27 -0
  109. package/dist/server/bare/runtime/request-registry.js +246 -76
  110. package/dist/server/bare/types/addon-responses.d.ts +4 -12
  111. package/dist/server/rpc/handlers/load-model/handler.js +2 -2
  112. package/dist/server/rpc/handlers/load-model/resolve-session.d.ts +1 -1
  113. package/dist/server/rpc/handlers/load-model/resolve-session.js +3 -3
  114. package/dist/server/rpc/handlers/load-model/resolve.d.ts +12 -2
  115. package/dist/server/rpc/handlers/load-model/resolve.js +90 -12
  116. package/dist/server/utils/audio/decoder.d.ts +37 -1
  117. package/dist/server/utils/audio/decoder.js +81 -51
  118. package/dist/server/utils/config-transform.d.ts +3 -0
  119. package/dist/server/utils/config-transform.js +6 -0
  120. package/dist/server/utils/index.d.ts +0 -1
  121. package/dist/server/utils/index.js +0 -1
  122. package/dist/server/utils/shard-utils.d.ts +1 -0
  123. package/dist/server/utils/shard-utils.js +14 -0
  124. package/dist/server/utils/tool-integration.d.ts +3 -10
  125. package/dist/server/utils/tool-integration.js +3 -12
  126. package/dist/utils/errors-server.d.ts +3 -0
  127. package/dist/utils/errors-server.js +5 -0
  128. package/package.json +12 -14
  129. package/dist/examples/llamacpp-dynamic-tools.d.ts +0 -2
  130. package/dist/examples/llamacpp-dynamic-tools.js +0 -152
  131. package/dist/models/update-models/codegen.d.ts +0 -3
  132. package/dist/models/update-models/codegen.js +0 -196
  133. package/dist/models/update-models/companions.d.ts +0 -30
  134. package/dist/models/update-models/companions.js +0 -296
  135. package/dist/models/update-models/history.d.ts +0 -24
  136. package/dist/models/update-models/history.js +0 -107
  137. package/dist/models/update-models/index.d.ts +0 -2
  138. package/dist/models/update-models/index.js +0 -123
  139. package/dist/models/update-models/naming.d.ts +0 -4
  140. package/dist/models/update-models/naming.js +0 -396
  141. package/dist/models/update-models/processing.d.ts +0 -8
  142. package/dist/models/update-models/processing.js +0 -65
  143. package/dist/models/update-models/registry.d.ts +0 -5
  144. package/dist/models/update-models/registry.js +0 -87
  145. package/dist/models/update-models/shards.d.ts +0 -4
  146. package/dist/models/update-models/shards.js +0 -57
  147. package/dist/models/update-models/types.d.ts +0 -88
  148. package/dist/models/update-models/types.js +0 -1
  149. package/dist/models/update-models/utils.d.ts +0 -3
  150. package/dist/models/update-models/utils.js +0 -21
  151. package/dist/server/bare/plugins/llamacpp-completion/ops/batch-cancelled.d.ts +0 -23
  152. package/dist/server/bare/plugins/llamacpp-completion/ops/batch-cancelled.js +0 -30
  153. package/dist/server/utils/expand-gguf-shards.d.ts +0 -3
  154. package/dist/server/utils/expand-gguf-shards.js +0 -22
@@ -1,152 +0,0 @@
1
- /**
2
- * Dynamic-tools mode example.
3
- *
4
- * In `dynamic` mode each user prompt can carry its own tool set: the addon
5
- * anchors tools after the last user message, runs the tool-call chain, then
6
- * trims the tools + chain output from the kv-cache so a later turn can ship
7
- * a different tool list without poisoning the cache. Compare with
8
- * `llamacpp-native-tools.ts`, which uses the default `static` mode where
9
- * one shared tool set lives at the top of the session.
10
- *
11
- * Run with:
12
- * bun run build
13
- * bun run bare:example dist/examples/llamacpp-dynamic-tools.js
14
- */
15
- import { z } from 'zod';
16
- import { completion, loadModel, unloadModel, QWEN3_1_7B_INST_Q4 } from '@qvac/sdk';
17
- const weatherSchema = z.object({
18
- city: z.string().describe('City name')
19
- });
20
- const horoscopeSchema = z.object({
21
- sign: z.string().describe('An astrological sign, e.g. Taurus or Aquarius')
22
- });
23
- const dateSchema = z.object({});
24
- const toolSchemas = {
25
- get_weather: weatherSchema,
26
- get_horoscope: horoscopeSchema,
27
- get_date: dateSchema
28
- };
29
- const weatherTools = [
30
- {
31
- name: 'get_weather',
32
- description: 'Get current weather for a city',
33
- parameters: weatherSchema
34
- }
35
- ];
36
- const horoscopeTools = [
37
- {
38
- name: 'get_horoscope',
39
- description: "Get today's horoscope for an astrological sign",
40
- parameters: horoscopeSchema
41
- }
42
- ];
43
- const dateTools = [
44
- {
45
- name: 'get_date',
46
- description: "Get today's date",
47
- parameters: dateSchema
48
- }
49
- ];
50
- function executeToolCall(call) {
51
- if (call.name === 'get_weather') {
52
- const args = call.arguments;
53
- return `The weather in ${args.city} is rainy, 8°C with heavy clouds.`;
54
- }
55
- if (call.name === 'get_horoscope') {
56
- const args = call.arguments;
57
- return `Horoscope for ${args.sign}: a great day for new beginnings.`;
58
- }
59
- if (call.name === 'get_date') {
60
- return new Date().toISOString().slice(0, 10);
61
- }
62
- return `Unknown tool: ${call.name}`;
63
- }
64
- async function chatTurn({ modelId, kvCache, history, tools }) {
65
- const result = completion({
66
- modelId,
67
- history,
68
- tools,
69
- kvCache,
70
- stream: true
71
- });
72
- const tokensTask = (async () => {
73
- for await (const token of result.tokenStream) {
74
- process.stdout.write(token);
75
- }
76
- })();
77
- const toolEventsTask = (async () => {
78
- for await (const evt of result.toolCallStream) {
79
- console.log(`\n▸ tool call: ${evt.call.name}(${JSON.stringify(evt.call.arguments)})`);
80
- }
81
- })();
82
- await Promise.all([tokensTask, toolEventsTask]);
83
- const text = await result.text;
84
- const toolCalls = await result.toolCalls;
85
- if (toolCalls.length === 0) {
86
- history.push({ role: 'assistant', content: text });
87
- return;
88
- }
89
- for (const call of toolCalls) {
90
- const schema = toolSchemas[call.name];
91
- if (schema) {
92
- const parsed = schema.safeParse(call.arguments);
93
- if (!parsed.success) {
94
- console.log(`✖ validation failed for ${call.name}:`, parsed.error);
95
- }
96
- }
97
- }
98
- history.push({ role: 'assistant', content: text });
99
- for (const call of toolCalls) {
100
- history.push({ role: 'tool', content: executeToolCall(call) });
101
- }
102
- // Follow-up turn so the model can incorporate the tool results.
103
- await chatTurn({ modelId, kvCache, history, tools });
104
- }
105
- async function main() {
106
- const modelId = await loadModel({
107
- modelSrc: QWEN3_1_7B_INST_Q4,
108
- modelConfig: {
109
- ctx_size: 4096,
110
- tools: true,
111
- toolsMode: 'dynamic'
112
- },
113
- onProgress: (p) => {
114
- const mb = (n) => (n / 1e6).toFixed(1);
115
- const line = `▸ Downloading ${p.percentage.toFixed(0)}% (${mb(p.downloaded)}/${mb(p.total)} MB)`;
116
- process.stderr.write(process.stderr.isTTY ? `\r${line}` : `${line}\n`);
117
- if (p.percentage >= 100)
118
- process.stderr.write('\n');
119
- }
120
- });
121
- console.log(`▸ Model loaded: ${modelId}`);
122
- const kvCache = `dynamic-tools-${Date.now()}`;
123
- const history = [
124
- {
125
- role: 'system',
126
- content: 'You are a helpful assistant that uses tools when they are available. ' +
127
- "User's cat is named Windy and dog is named Butch."
128
- }
129
- ];
130
- // Turn 1 — only weather tools available.
131
- history.push({ role: 'user', content: "What's the weather in Tokyo?" });
132
- console.log('\n▸ Turn 1 (tools=weather):\n');
133
- await chatTurn({ modelId, kvCache, history, tools: weatherTools });
134
- // Turn 2 — same session, swap to horoscope tools. Dynamic mode lets the
135
- // model see a different tool set without invalidating the kv-cache.
136
- history.push({
137
- role: 'user',
138
- content: 'Now check my horoscope for Aquarius.'
139
- });
140
- console.log('\n\n▸ Turn 2 (tools=horoscope):\n');
141
- await chatTurn({ modelId, kvCache, history, tools: horoscopeTools });
142
- // Turn 3 — swap to a parameterless tool to confirm empty-arg flows work.
143
- history.push({ role: 'user', content: "What's today's date?" });
144
- console.log('\n\n▸ Turn 3 (tools=date):\n');
145
- await chatTurn({ modelId, kvCache, history, tools: dateTools });
146
- console.log('\n\n▸ Done.');
147
- await unloadModel({ modelId, clearStorage: false });
148
- }
149
- main().catch((err) => {
150
- console.error('✖', err);
151
- process.exit(1);
152
- });
@@ -1,3 +0,0 @@
1
- import type { ProcessedModel } from './types.js';
2
- export declare function generateModelsFileContent(models: ProcessedModel[]): string;
3
- //# sourceMappingURL=codegen.d.ts.map
@@ -1,196 +0,0 @@
1
- import { generateExportName } from './naming.js';
2
- export function generateModelsFileContent(models) {
3
- const usedNames = new Set();
4
- const named = new Map();
5
- const exportable = models.filter((m) => !m.isCompanionOnly);
6
- const companionOnly = models.filter((m) => m.isCompanionOnly);
7
- for (const m of exportable) {
8
- named.set(m, assignName(m, usedNames));
9
- }
10
- for (const m of companionOnly) {
11
- named.set(m, assignName(m, usedNames));
12
- }
13
- const modelsWithNames = models.map((m) => ({
14
- ...m,
15
- name: named.get(m)
16
- }));
17
- return generateFileContentWithNames(modelsWithNames);
18
- }
19
- function assignName(m, usedNames) {
20
- return generateExportName({
21
- path: m.registryPath,
22
- engine: m.engine,
23
- name: m.modelName,
24
- quantization: m.quantization,
25
- params: m.params,
26
- tags: m.tags,
27
- usedNames
28
- });
29
- }
30
- function generateFileContentWithNames(modelsWithNames) {
31
- const entries = modelsWithNames
32
- .map((m) => {
33
- const addonAlias = m.addon;
34
- let entry = ` {
35
- name: "${m.name}",
36
- registryPath: "${m.registryPath}",
37
- registrySource: "${m.registrySource}",
38
- blobCoreKey: "${m.blobCoreKey}",
39
- blobBlockOffset: ${m.blobBlockOffset},
40
- blobBlockLength: ${m.blobBlockLength},
41
- blobByteOffset: ${m.blobByteOffset},
42
- modelId: "${m.modelId}",
43
- addon: "${addonAlias}",
44
- expectedSize: ${m.expectedSize},
45
- sha256Checksum: "${m.sha256Checksum}",
46
- engine: "${m.engine}",
47
- quantization: "${m.quantization || ''}",
48
- params: "${m.params || ''}"`;
49
- if (m.shardMetadata) {
50
- entry += `,\n shardMetadata: ${JSON.stringify(m.shardMetadata)}`;
51
- }
52
- if (m.companionSet) {
53
- entry += `,\n companionSet: ${JSON.stringify(m.companionSet)}`;
54
- }
55
- entry += '\n }';
56
- return entry;
57
- })
58
- .join(',\n');
59
- const exports = modelsWithNames
60
- .filter((m) => !m.isCompanionOnly)
61
- .map((m) => {
62
- const i = modelsWithNames.indexOf(m);
63
- return `export const ${m.name} = {
64
- name: "${m.name}",
65
- src: \`registry://\${models[${i}].registrySource}/\${models[${i}].registryPath}\`,
66
- registryPath: models[${i}].registryPath,
67
- registrySource: models[${i}].registrySource,
68
- blobCoreKey: models[${i}].blobCoreKey,
69
- blobBlockOffset: models[${i}].blobBlockOffset,
70
- blobBlockLength: models[${i}].blobBlockLength,
71
- blobByteOffset: models[${i}].blobByteOffset,
72
- modelId: models[${i}].modelId,
73
- expectedSize: models[${i}].expectedSize,
74
- sha256Checksum: models[${i}].sha256Checksum,
75
- addon: models[${i}].addon,
76
- engine: models[${i}].engine,
77
- quantization: models[${i}].quantization,
78
- params: models[${i}].params,
79
- } as const;`;
80
- })
81
- .join('\n\n');
82
- return `// THIS FILE IS AUTO-GENERATED BY models/update-models
83
- // DO NOT MODIFY MANUALLY
84
-
85
- import type {
86
- ModelRegistryEngine,
87
- ModelRegistryEntryAddon,
88
- } from "../../schemas/registry.js";
89
- import type { ENGINE_TO_ADDON } from "../../schemas/engine-addon-map.js";
90
-
91
- type AddonOfEngine<E extends ModelRegistryEngine> = (typeof ENGINE_TO_ADDON)[E];
92
-
93
- export type RegistryItem = {
94
- name: string;
95
- registryPath: string;
96
- registrySource: string;
97
- blobCoreKey: string;
98
- blobBlockOffset: number;
99
- blobBlockLength: number;
100
- blobByteOffset: number;
101
- modelId: string;
102
- addon: ModelRegistryEntryAddon;
103
- expectedSize: number;
104
- sha256Checksum: string;
105
- engine: ModelRegistryEngine;
106
- quantization: string;
107
- params: string;
108
- shardMetadata?: readonly {
109
- filename: string;
110
- expectedSize: number;
111
- sha256Checksum: string;
112
- blobCoreKey: string;
113
- blobBlockOffset: number;
114
- blobBlockLength: number;
115
- blobByteOffset: number;
116
- }[];
117
- companionSet?: {
118
- setKey: string;
119
- primaryKey: string;
120
- files: readonly {
121
- key: string;
122
- registryPath: string;
123
- registrySource: string;
124
- targetName: string;
125
- expectedSize: number;
126
- sha256Checksum: string;
127
- blobCoreKey: string;
128
- blobBlockOffset: number;
129
- blobBlockLength: number;
130
- blobByteOffset: number;
131
- primary?: boolean;
132
- }[];
133
- };
134
- };
135
-
136
- /** Generic so callers can preserve per-constant literals: \`ModelConstant<"llamacpp-completion">\`. */
137
- export type ModelConstant<
138
- TEngine extends ModelRegistryEngine = ModelRegistryEngine,
139
- > = {
140
- name: string;
141
- src: string;
142
- registryPath: string;
143
- registrySource: string;
144
- blobCoreKey: string;
145
- blobBlockOffset: number;
146
- blobBlockLength: number;
147
- blobByteOffset: number;
148
- modelId: string;
149
- expectedSize: number;
150
- sha256Checksum: string;
151
- addon: AddonOfEngine<TEngine>;
152
- engine: TEngine;
153
- quantization: string;
154
- params: string;
155
- };
156
-
157
- export const models = [
158
- ${entries}
159
- ] as const satisfies readonly RegistryItem[];
160
-
161
- // Individual model constants for direct import/use with loadModel
162
- // These contain all metadata and can be used directly: loadModel({ modelSrc: WHISPER_TINY, ... })
163
- ${exports}
164
-
165
- /**
166
- * Looks up a model in the built-in catalog by its constant name.
167
- *
168
- * @param name - The model constant name (e.g. \`"WHISPER_TINY"\`) to look up.
169
- * @returns The matching \`RegistryItem\`, or \`undefined\` when no catalog entry has that name.
170
- */
171
- export function getModelByName(name: string): RegistryItem | undefined {
172
- return models.find((model) => model.name === name);
173
- }
174
-
175
- /**
176
- * Looks up a model in the built-in catalog by its registry path.
177
- *
178
- * @param registryPath - Registry-relative path of the model to look up.
179
- * @returns The matching \`RegistryItem\`, or \`undefined\` when no catalog entry has that registry path.
180
- */
181
- export function getModelByPath(registryPath: string): RegistryItem | undefined {
182
- return models.find((model) => model.registryPath === registryPath);
183
- }
184
-
185
- /**
186
- * Looks up a model in the built-in catalog by model file ID and blob core key.
187
- *
188
- * @param modelId - The model file ID to match against the catalog.
189
- * @param blobCoreKey - The Hyperdrive blob core key to match against the catalog.
190
- * @returns The matching \`RegistryItem\`, or \`undefined\` when no catalog entry has both the given \`modelId\` and \`blobCoreKey\`.
191
- */
192
- export function getModelBySrc(modelId: string, blobCoreKey: string): RegistryItem | undefined {
193
- return models.find((model) => model.modelId === modelId && model.blobCoreKey === blobCoreKey);
194
- }
195
- `;
196
- }
@@ -1,30 +0,0 @@
1
- import type { ProcessedModel } from './types.js';
2
- /**
3
- * Detects companion file relationships among processed models and
4
- * attaches `companionSet` metadata to each primary entry.
5
- * Companion-only entries are marked with `isCompanionOnly` so
6
- * codegen can exclude them from exported model constants.
7
- *
8
- * Detection families:
9
- * ONNX pairs:
10
- * Primary: registryPath ends with `.onnx`
11
- * Companion: `${primaryPath}_data` or `${primaryPath}.data`
12
- *
13
- * Bergamot NMT sets (directory-based):
14
- * Primary: `model.<langPair>.intgemm.alphas.bin`
15
- * Companions in same directory: lex, vocab/srcvocab+trgvocab, metadata
16
- *
17
- * BCI whisper.cpp sets (directory-based):
18
- * Primary: `ggml-bci-windowed.bin`
19
- * Companion in same directory: `bci-embedder.bin`
20
- * The addon resolves the embedder by exact filename next to the model
21
- * (`dirname(model)/bci-embedder.bin`), so the two files must be
22
- * physically co-located — which the companion-set cache layout guarantees.
23
- *
24
- * Chatterbox MeCab/IPAdic sets (directory-based):
25
- * Primary: `char.bin`
26
- * Companions in same directory: dicrc, matrix.bin, mecabrc, sys.dic, unk.dic
27
- * The TTS addon receives the containing directory for Japanese tokenization.
28
- */
29
- export declare function groupCompanionSets(models: ProcessedModel[]): ProcessedModel[];
30
- //# sourceMappingURL=companions.d.ts.map
@@ -1,296 +0,0 @@
1
- import { createHash } from 'crypto';
2
- import { BERGAMOT_MODEL_RE } from '../../schemas/index.js';
3
- /**
4
- * Detects companion file relationships among processed models and
5
- * attaches `companionSet` metadata to each primary entry.
6
- * Companion-only entries are marked with `isCompanionOnly` so
7
- * codegen can exclude them from exported model constants.
8
- *
9
- * Detection families:
10
- * ONNX pairs:
11
- * Primary: registryPath ends with `.onnx`
12
- * Companion: `${primaryPath}_data` or `${primaryPath}.data`
13
- *
14
- * Bergamot NMT sets (directory-based):
15
- * Primary: `model.<langPair>.intgemm.alphas.bin`
16
- * Companions in same directory: lex, vocab/srcvocab+trgvocab, metadata
17
- *
18
- * BCI whisper.cpp sets (directory-based):
19
- * Primary: `ggml-bci-windowed.bin`
20
- * Companion in same directory: `bci-embedder.bin`
21
- * The addon resolves the embedder by exact filename next to the model
22
- * (`dirname(model)/bci-embedder.bin`), so the two files must be
23
- * physically co-located — which the companion-set cache layout guarantees.
24
- *
25
- * Chatterbox MeCab/IPAdic sets (directory-based):
26
- * Primary: `char.bin`
27
- * Companions in same directory: dicrc, matrix.bin, mecabrc, sys.dic, unk.dic
28
- * The TTS addon receives the containing directory for Japanese tokenization.
29
- */
30
- export function groupCompanionSets(models) {
31
- const bySourcePath = new Map();
32
- for (const model of models) {
33
- bySourcePath.set(sourceKey(model.registrySource, model.registryPath), model);
34
- }
35
- const companionKeys = new Set();
36
- groupOnnxCompanions(models, bySourcePath, companionKeys);
37
- groupBergamotCompanions(models, bySourcePath, companionKeys);
38
- groupBciCompanions(models, bySourcePath, companionKeys);
39
- groupMecabCompanions(models, bySourcePath, companionKeys);
40
- return models.map((model) => {
41
- const key = sourceKey(model.registrySource, model.registryPath);
42
- if (companionKeys.has(key)) {
43
- return { ...model, isCompanionOnly: true };
44
- }
45
- return model;
46
- });
47
- }
48
- function groupOnnxCompanions(models, bySourcePath, companionKeys) {
49
- for (const model of models) {
50
- if (!model.registryPath.endsWith('.onnx'))
51
- continue;
52
- const dataKey = findOnnxCompanionKey(model.registrySource, model.registryPath, bySourcePath);
53
- if (!dataKey)
54
- continue;
55
- const companion = bySourcePath.get(dataKey);
56
- const primaryFilename = model.registryPath.split('/').pop() || model.registryPath;
57
- const dataFilename = companion.registryPath.split('/').pop() || companion.registryPath;
58
- const setKey = shortHash(`${model.registrySource}:${model.registryPath}`);
59
- const primaryEntry = {
60
- key: 'modelPath',
61
- registryPath: model.registryPath,
62
- registrySource: model.registrySource,
63
- targetName: primaryFilename,
64
- expectedSize: model.expectedSize,
65
- sha256Checksum: model.sha256Checksum,
66
- blobCoreKey: model.blobCoreKey,
67
- blobBlockOffset: model.blobBlockOffset,
68
- blobBlockLength: model.blobBlockLength,
69
- blobByteOffset: model.blobByteOffset,
70
- primary: true
71
- };
72
- const dataEntry = {
73
- key: 'dataPath',
74
- registryPath: companion.registryPath,
75
- registrySource: companion.registrySource,
76
- targetName: dataFilename,
77
- expectedSize: companion.expectedSize,
78
- sha256Checksum: companion.sha256Checksum,
79
- blobCoreKey: companion.blobCoreKey,
80
- blobBlockOffset: companion.blobBlockOffset,
81
- blobBlockLength: companion.blobBlockLength,
82
- blobByteOffset: companion.blobByteOffset
83
- };
84
- const companionSetMetadata = {
85
- setKey,
86
- primaryKey: 'modelPath',
87
- files: [primaryEntry, dataEntry]
88
- };
89
- model.companionSet = companionSetMetadata;
90
- companionKeys.add(dataKey);
91
- }
92
- }
93
- function groupBergamotCompanions(models, bySourcePath, companionKeys) {
94
- for (const model of models) {
95
- const match = model.registryPath.match(BERGAMOT_MODEL_RE);
96
- if (!match?.[1] || !match[2])
97
- continue;
98
- const dirPrefix = match[1];
99
- const langPair = match[2];
100
- const source = model.registrySource;
101
- const companions = findBergamotCompanions(source, dirPrefix, langPair, bySourcePath);
102
- if (companions.length === 0)
103
- continue;
104
- const primaryFilename = model.registryPath.split('/').pop();
105
- const setKey = shortHash(`${source}:${model.registryPath}`);
106
- const primaryEntry = {
107
- key: 'modelPath',
108
- registryPath: model.registryPath,
109
- registrySource: source,
110
- targetName: primaryFilename,
111
- expectedSize: model.expectedSize,
112
- sha256Checksum: model.sha256Checksum,
113
- blobCoreKey: model.blobCoreKey,
114
- blobBlockOffset: model.blobBlockOffset,
115
- blobBlockLength: model.blobBlockLength,
116
- blobByteOffset: model.blobByteOffset,
117
- primary: true
118
- };
119
- const companionEntries = [];
120
- for (const { key: entryKey, model: comp } of companions) {
121
- const filename = comp.registryPath.split('/').pop();
122
- companionEntries.push({
123
- key: entryKey,
124
- registryPath: comp.registryPath,
125
- registrySource: comp.registrySource,
126
- targetName: filename,
127
- expectedSize: comp.expectedSize,
128
- sha256Checksum: comp.sha256Checksum,
129
- blobCoreKey: comp.blobCoreKey,
130
- blobBlockOffset: comp.blobBlockOffset,
131
- blobBlockLength: comp.blobBlockLength,
132
- blobByteOffset: comp.blobByteOffset
133
- });
134
- companionKeys.add(sourceKey(comp.registrySource, comp.registryPath));
135
- }
136
- model.companionSet = {
137
- setKey,
138
- primaryKey: 'modelPath',
139
- files: [primaryEntry, ...companionEntries]
140
- };
141
- }
142
- }
143
- const BCI_PRIMARY_FILENAME = 'ggml-bci-windowed.bin';
144
- const BCI_EMBEDDER_FILENAME = 'bci-embedder.bin';
145
- function groupBciCompanions(models, bySourcePath, companionKeys) {
146
- for (const model of models) {
147
- const filename = model.registryPath.split('/').pop();
148
- if (filename !== BCI_PRIMARY_FILENAME)
149
- continue;
150
- const lastSep = model.registryPath.lastIndexOf('/');
151
- const dirPrefix = lastSep >= 0 ? model.registryPath.slice(0, lastSep + 1) : '';
152
- const source = model.registrySource;
153
- const embedderPath = `${dirPrefix}${BCI_EMBEDDER_FILENAME}`;
154
- const embedder = bySourcePath.get(sourceKey(source, embedderPath));
155
- if (!embedder)
156
- continue;
157
- const setKey = shortHash(`${source}:${model.registryPath}`);
158
- const primaryEntry = {
159
- key: 'modelPath',
160
- registryPath: model.registryPath,
161
- registrySource: source,
162
- targetName: BCI_PRIMARY_FILENAME,
163
- expectedSize: model.expectedSize,
164
- sha256Checksum: model.sha256Checksum,
165
- blobCoreKey: model.blobCoreKey,
166
- blobBlockOffset: model.blobBlockOffset,
167
- blobBlockLength: model.blobBlockLength,
168
- blobByteOffset: model.blobByteOffset,
169
- primary: true
170
- };
171
- const embedderEntry = {
172
- key: 'embedderPath',
173
- registryPath: embedder.registryPath,
174
- registrySource: embedder.registrySource,
175
- targetName: BCI_EMBEDDER_FILENAME,
176
- expectedSize: embedder.expectedSize,
177
- sha256Checksum: embedder.sha256Checksum,
178
- blobCoreKey: embedder.blobCoreKey,
179
- blobBlockOffset: embedder.blobBlockOffset,
180
- blobBlockLength: embedder.blobBlockLength,
181
- blobByteOffset: embedder.blobByteOffset
182
- };
183
- model.companionSet = {
184
- setKey,
185
- primaryKey: 'modelPath',
186
- files: [primaryEntry, embedderEntry]
187
- };
188
- companionKeys.add(sourceKey(embedder.registrySource, embedder.registryPath));
189
- }
190
- }
191
- const MECAB_PRIMARY_FILENAME = 'char.bin';
192
- const MECAB_REQUIRED_FILENAMES = ['dicrc', 'matrix.bin', 'mecabrc', 'sys.dic', 'unk.dic'];
193
- const MECAB_IPADIC_DIR_SUFFIX = '/mecab-ipadic/';
194
- function groupMecabCompanions(models, bySourcePath, companionKeys) {
195
- for (const model of models) {
196
- if (!model.registryPath.includes(MECAB_IPADIC_DIR_SUFFIX))
197
- continue;
198
- const lastSep = model.registryPath.lastIndexOf('/');
199
- const filename = lastSep >= 0 ? model.registryPath.slice(lastSep + 1) : model.registryPath;
200
- if (filename !== MECAB_PRIMARY_FILENAME)
201
- continue;
202
- const dirPrefix = lastSep >= 0 ? model.registryPath.slice(0, lastSep + 1) : '';
203
- const source = model.registrySource;
204
- const companions = findMecabCompanions(source, dirPrefix, bySourcePath);
205
- if (companions.length !== MECAB_REQUIRED_FILENAMES.length)
206
- continue;
207
- const setKey = shortHash(`${source}:${dirPrefix}`);
208
- const primaryEntry = {
209
- key: 'mecabDictPath',
210
- registryPath: model.registryPath,
211
- registrySource: source,
212
- targetName: MECAB_PRIMARY_FILENAME,
213
- expectedSize: model.expectedSize,
214
- sha256Checksum: model.sha256Checksum,
215
- blobCoreKey: model.blobCoreKey,
216
- blobBlockOffset: model.blobBlockOffset,
217
- blobBlockLength: model.blobBlockLength,
218
- blobByteOffset: model.blobByteOffset,
219
- primary: true
220
- };
221
- const companionEntries = companions.map(({ filename, model: comp }) => {
222
- companionKeys.add(sourceKey(comp.registrySource, comp.registryPath));
223
- return {
224
- key: `mecab:${filename}`,
225
- registryPath: comp.registryPath,
226
- registrySource: comp.registrySource,
227
- targetName: filename,
228
- expectedSize: comp.expectedSize,
229
- sha256Checksum: comp.sha256Checksum,
230
- blobCoreKey: comp.blobCoreKey,
231
- blobBlockOffset: comp.blobBlockOffset,
232
- blobBlockLength: comp.blobBlockLength,
233
- blobByteOffset: comp.blobByteOffset
234
- };
235
- });
236
- model.companionSet = {
237
- setKey,
238
- primaryKey: 'mecabDictPath',
239
- files: [primaryEntry, ...companionEntries]
240
- };
241
- }
242
- }
243
- function findBergamotCompanions(source, dirPrefix, langPair, bySourcePath) {
244
- const found = [];
245
- const lexPath = `${dirPrefix}lex.50.50.${langPair}.s2t.bin`;
246
- const lexModel = bySourcePath.get(sourceKey(source, lexPath));
247
- if (lexModel) {
248
- found.push({ key: 'lexPath', model: lexModel });
249
- }
250
- const sharedVocabPath = `${dirPrefix}vocab.${langPair}.spm`;
251
- const sharedVocab = bySourcePath.get(sourceKey(source, sharedVocabPath));
252
- if (sharedVocab) {
253
- found.push({ key: 'sharedVocabPath', model: sharedVocab });
254
- }
255
- else {
256
- const srcVocabPath = `${dirPrefix}srcvocab.${langPair}.spm`;
257
- const trgVocabPath = `${dirPrefix}trgvocab.${langPair}.spm`;
258
- const srcVocab = bySourcePath.get(sourceKey(source, srcVocabPath));
259
- const trgVocab = bySourcePath.get(sourceKey(source, trgVocabPath));
260
- if (srcVocab && trgVocab) {
261
- found.push({ key: 'srcVocabPath', model: srcVocab });
262
- found.push({ key: 'dstVocabPath', model: trgVocab });
263
- }
264
- }
265
- const metadataPath = `${dirPrefix}metadata.json`;
266
- const metadata = bySourcePath.get(sourceKey(source, metadataPath));
267
- if (metadata) {
268
- found.push({ key: 'metadataPath', model: metadata });
269
- }
270
- return found;
271
- }
272
- function findMecabCompanions(source, dirPrefix, bySourcePath) {
273
- const found = [];
274
- for (const filename of MECAB_REQUIRED_FILENAMES) {
275
- const model = bySourcePath.get(sourceKey(source, `${dirPrefix}${filename}`));
276
- if (!model)
277
- return [];
278
- found.push({ filename, model });
279
- }
280
- return found;
281
- }
282
- function sourceKey(source, path) {
283
- return `${source}:${path}`;
284
- }
285
- function findOnnxCompanionKey(source, primaryPath, bySourcePath) {
286
- const candidates = [`${primaryPath}_data`, `${primaryPath}.data`];
287
- for (const candidate of candidates) {
288
- const key = sourceKey(source, candidate);
289
- if (bySourcePath.has(key))
290
- return key;
291
- }
292
- return undefined;
293
- }
294
- function shortHash(input) {
295
- return createHash('sha256').update(input).digest('hex').substring(0, 16);
296
- }