@qvac/harness 0.5.0 → 0.7.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/CHANGELOG.md +142 -1
- package/README.md +78 -27
- package/dist-lib/index.d.ts +15 -1
- package/dist-lib/index.js +175 -53
- package/dist-lib/lib/capabilities/preview-model-source.d.ts +0 -1
- package/dist-lib/lib/connect.d.ts +3 -1
- package/dist-lib/lib/connect.js +23 -2
- package/dist-lib/lib/contract-types.d.ts +14 -0
- package/dist-lib/lib/docx/index.d.ts +1 -1
- package/dist-lib/lib/docx/index.js +1 -1
- package/dist-lib/lib/hardware/capability-probe.js +9 -4
- package/dist-lib/lib/hooks/built-in/sandbox.js +0 -5
- package/dist-lib/lib/models/model-catalog-constants.d.ts +7 -0
- package/dist-lib/lib/models/model-catalog-constants.js +17 -0
- package/dist-lib/lib/models/model-catalog.d.ts +16 -6
- package/dist-lib/lib/models/model-catalog.js +21 -6
- package/dist-lib/lib/models/model-list.d.ts +2 -0
- package/dist-lib/lib/models/model-list.js +9 -4
- package/dist-lib/lib/models/model-pool.d.ts +6 -2
- package/dist-lib/lib/models/model-pool.js +67 -11
- package/dist-lib/lib/models/model-task.d.ts +3 -0
- package/dist-lib/lib/models/model-task.js +14 -0
- package/dist-lib/lib/models/music-catalog.d.ts +2 -0
- package/dist-lib/lib/models/music-catalog.js +9 -0
- package/dist-lib/lib/office/index.d.ts +1 -1
- package/dist-lib/lib/office/index.js +1 -1
- package/dist-lib/lib/office/python.js +1 -2
- package/dist-lib/lib/serve.js +12 -0
- package/dist-lib/lib/tools/exec/adapters/python/deadline-state.d.ts +10 -0
- package/dist-lib/lib/tools/exec/adapters/python/deadline-state.js +5 -0
- package/dist-lib/lib/tools/exec/adapters/python/interrupt-timer.js +10 -17
- package/dist-lib/lib/tools/exec/adapters/python/loader.js +15 -11
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +1 -15
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +1 -0
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +13 -2
- package/dist-lib/lib/tools/exec/adapters/python/wheels.d.ts +3 -3
- package/dist-lib/lib/tools/exec/adapters/python/wheels.js +3 -14
- package/dist-lib/lib/tools/exec/adapters/python/worker/active.d.ts +19 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/active.js +72 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts +0 -1
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +8 -76
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +2 -126
- package/dist-lib/lib/tools/exec/adapters/python/worker/interrupt-deadline.d.ts +1 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/interrupt-deadline.js +21 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/serve.d.ts +2 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/serve.js +90 -0
- package/dist-lib/lib/tools/exec/adapters/python/worker/{spawn-node.d.ts → spawn.d.ts} +0 -1
- package/dist-lib/lib/tools/exec/adapters/python/worker/{spawn-node.js → spawn.js} +0 -8
- package/dist-lib/lib/tools/exec/bare-runtime.d.ts +2 -0
- package/dist-lib/lib/tools/exec/bare-runtime.js +10 -0
- package/dist-lib/lib/tools/exec.d.ts +0 -2
- package/dist-lib/lib/tools/exec.js +6 -11
- package/dist-lib/schema/harness.js +27 -1
- package/dist-lib/spec/bind.js +6 -0
- package/dist-lib/spec/calls.js +2 -0
- package/dist-lib/spec/hrpc/hrpc.json +26 -0
- package/dist-lib/spec/hrpc/index.js +27 -3
- package/dist-lib/spec/hrpc/messages.js +72 -5
- package/dist-lib/spec/hyperschema/index.js +72 -5
- package/dist-lib/spec/hyperschema/schema.json +53 -1
- package/dist-lib/spec/hyperschema/types.d.ts +18 -1
- package/package.json +40 -20
- package/dist/harness.bundle +0 -42312
- package/dist/harness.cjs +0 -18
- package/dist/harness.d.ts +0 -8
- package/dist/prebuilds-manifest.json +0 -372
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-bare.d.ts +0 -3
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-bare.js +0 -38
package/dist-lib/index.js
CHANGED
|
@@ -4,7 +4,7 @@ import process from 'process';
|
|
|
4
4
|
import ReadyResource from 'ready-resource';
|
|
5
5
|
import { probeGpuStats } from './lib/hardware/gpu-probe.js';
|
|
6
6
|
import { probeCapabilityProfile } from './lib/hardware/capability-probe.js';
|
|
7
|
-
import { closePythonWorker } from './lib/tools/exec/adapters/python/worker/
|
|
7
|
+
import { closePythonWorker } from './lib/tools/exec/adapters/python/worker/active.js';
|
|
8
8
|
import { completion, imageSettingsFrom } from './lib/capabilities/completion.js';
|
|
9
9
|
import { detectLanguage } from './lib/capabilities/detect-language.js';
|
|
10
10
|
import { invoke } from './lib/capabilities/invoke.js';
|
|
@@ -21,10 +21,11 @@ import { buildWavBuffer } from './lib/wav-encode.js';
|
|
|
21
21
|
import { createVoiceLane, packSamples, speakOnce, speakStreamOnce, transcribeOnce, transcribeStreaming, SUPERTONIC_SAMPLE_RATE } from './lib/capabilities/voice.js';
|
|
22
22
|
import { pushQueue } from './lib/queue.js';
|
|
23
23
|
import { AbortedError, raceAbort } from './lib/helpers/race-abort.js';
|
|
24
|
-
import { audioGenDownloadMetadata, customProjectionMap, defaultProjectionMap, defaultTtsFor, defaultVoiceModel, diffusionDownloadMetadata, infraModelsFor, modelNameToCapabilityProfile, musicModelSet, setCustomModels } from './lib/models/model-catalog.js';
|
|
24
|
+
import { audioGenDownloadMetadata, customProjectionMap, defaultProjectionMap, defaultTtsFor, defaultVoiceModel, diffusionDownloadMetadata, curatedModelAsset, infraModelsFor, modelAddonOf, modelNameToCapabilityProfile, musicModelSet, residentSrc, setCustomModels } from './lib/models/model-catalog.js';
|
|
25
25
|
import { createModelStatusCache, customModelRows, invalidateModelStatusCache, mergeCustomRows, listModels } from './lib/models/model-list.js';
|
|
26
26
|
import { deleteModelFiles, summarizeDelete } from './lib/models/model-delete.js';
|
|
27
|
-
import { createEmbedPool, createLoadTracker, createModelPool, createVoicePool, awaitModelCapacity, evictIdle, evictModelWithin, isResident, leaseResidentModel, leaseCount, loadedModels, modelKey, releaseModel, resolveLoadOptions, progressState } from './lib/models/model-pool.js';
|
|
27
|
+
import { createEmbedPool, createLoadTracker, createModelPool, createVoicePool, awaitModelCapacity, evictIdle, evictIdleWhere, evictModel, evictModelWithin, isResident, leaseResidentModel, leaseCount, loadedModels, modelKey, modelOf, releaseModel, resolveLoadOptions, progressState } from './lib/models/model-pool.js';
|
|
28
|
+
import { defaultContextSize } from './lib/models/context.js';
|
|
28
29
|
import { resolveMainGpu } from './lib/models/gpu-selection.js';
|
|
29
30
|
import { createIdleReaper } from './lib/models/idle-unload.js';
|
|
30
31
|
import { openclCacheDir } from './lib/models/opencl-cache.js';
|
|
@@ -45,7 +46,7 @@ import { hlog } from './lib/log.js';
|
|
|
45
46
|
import { harness } from './spec/index.js';
|
|
46
47
|
import { installResolutionDetector, resolutionDetail } from './lib/resolution-detector.js';
|
|
47
48
|
import { probeBinVersions } from './lib/tools/skills/bin-check.js';
|
|
48
|
-
import { bareRuntime } from './lib/tools/exec.js';
|
|
49
|
+
import { bareRuntime } from './lib/tools/exec/bare-runtime.js';
|
|
49
50
|
import { runCommand } from './lib/tools/exec/runner.js';
|
|
50
51
|
import { createLocalRoots } from './lib/tools/fs/local.js';
|
|
51
52
|
import { createRemoteRoots } from './lib/tools/fs/remote.js';
|
|
@@ -81,6 +82,7 @@ const MUSIC_EVICT_WAIT_MS = 15_000;
|
|
|
81
82
|
const WEDGED_EVICT_WAIT_MS = 10_000;
|
|
82
83
|
const MODEL_ROOM_WAIT_MS = 300_000;
|
|
83
84
|
const WARM_ROOM_WAIT_MS = 2_000;
|
|
85
|
+
const UNLOAD_LEASE_WAIT_MS = 10_000;
|
|
84
86
|
const DEFAULT_COMPLETION_MODEL_CAP = 1;
|
|
85
87
|
const WEDGED_EVICT_LEASED_MS = 120_000;
|
|
86
88
|
const TTS_MODEL_CONFIG = {
|
|
@@ -93,6 +95,8 @@ export class Harness extends ReadyResource {
|
|
|
93
95
|
_tools;
|
|
94
96
|
_sdk;
|
|
95
97
|
_loads = createLoadTracker();
|
|
98
|
+
_pinned = new Set();
|
|
99
|
+
_replying = [];
|
|
96
100
|
_modelStatus = createModelStatusCache();
|
|
97
101
|
_models;
|
|
98
102
|
_embedModels;
|
|
@@ -520,19 +524,18 @@ export class Harness extends ReadyResource {
|
|
|
520
524
|
this._idle.configure(ms);
|
|
521
525
|
}
|
|
522
526
|
previewModelSource(context) {
|
|
523
|
-
return previewModelSource(context, {
|
|
524
|
-
|
|
525
|
-
|
|
526
|
-
|
|
527
|
-
|
|
528
|
-
|
|
529
|
-
const model = result.models[0];
|
|
530
|
-
return {
|
|
531
|
-
fit: model?.verdict ?? result.verdict,
|
|
532
|
-
fitReasons: [...(model?.reasons ?? result.reasons)]
|
|
533
|
-
};
|
|
534
|
-
}
|
|
527
|
+
return previewModelSource(context, { assessFit: (query) => this._assessFit(query) });
|
|
528
|
+
}
|
|
529
|
+
async _assessFit({ sha256Checksum, name, contextTokens }) {
|
|
530
|
+
const sdk = await this._sdk.load();
|
|
531
|
+
const result = await sdk.assessModelFit({
|
|
532
|
+
models: [{ model: { sha256Checksum, name }, workload: { kind: 'llm', contextTokens } }]
|
|
535
533
|
});
|
|
534
|
+
const model = result.models[0];
|
|
535
|
+
return {
|
|
536
|
+
fit: model?.verdict ?? result.verdict,
|
|
537
|
+
fitReasons: [...(model?.reasons ?? result.reasons)]
|
|
538
|
+
};
|
|
536
539
|
}
|
|
537
540
|
async describe() {
|
|
538
541
|
if (!this.opened)
|
|
@@ -595,7 +598,7 @@ export class Harness extends ReadyResource {
|
|
|
595
598
|
const key = modelKey(model, loadOpts);
|
|
596
599
|
const pool = this._models;
|
|
597
600
|
if (!isResident(pool, key)) {
|
|
598
|
-
await this._makeRoomForCompletion(signal);
|
|
601
|
+
await this._makeRoomForCompletion(model, { ctxSize: loadOpts.ctxSize, signal });
|
|
599
602
|
}
|
|
600
603
|
try {
|
|
601
604
|
const { modelId } = await raceAbort(pool.open(key, model, loadOpts).load(), signal);
|
|
@@ -630,7 +633,7 @@ export class Harness extends ReadyResource {
|
|
|
630
633
|
}
|
|
631
634
|
_createPool() {
|
|
632
635
|
const loadSdk = this._sdk.load;
|
|
633
|
-
return createModelPool(loadSdk, (state) => this._notifyModel(state
|
|
636
|
+
return createModelPool(loadSdk, (state) => this._notifyModel(state), {
|
|
634
637
|
deviceConfig: this._deviceConfig(),
|
|
635
638
|
loads: this._loads
|
|
636
639
|
});
|
|
@@ -663,11 +666,18 @@ export class Harness extends ReadyResource {
|
|
|
663
666
|
loads: this._loads
|
|
664
667
|
});
|
|
665
668
|
}
|
|
666
|
-
_notifyModel(state
|
|
667
|
-
const catalogChanged =
|
|
669
|
+
_notifyModel(state) {
|
|
670
|
+
const catalogChanged = state.status === 'ready' || state.status === 'unloaded';
|
|
668
671
|
if (catalogChanged) {
|
|
669
672
|
invalidateModelStatusCache(this._modelStatus);
|
|
670
673
|
}
|
|
674
|
+
if (state.status === 'unloaded') {
|
|
675
|
+
for (const key of this._pinned) {
|
|
676
|
+
if (!isResident(this._models, key)) {
|
|
677
|
+
this._pinned.delete(key);
|
|
678
|
+
}
|
|
679
|
+
}
|
|
680
|
+
}
|
|
671
681
|
this.emit('model', { ...state, catalogChanged, loaded: this._loadedModels() });
|
|
672
682
|
}
|
|
673
683
|
async _collectRetiredEmbedPool(pool) {
|
|
@@ -874,7 +884,7 @@ export class Harness extends ReadyResource {
|
|
|
874
884
|
const pool = this._embedModels;
|
|
875
885
|
const faults = this._embedFaults;
|
|
876
886
|
const generation = faults.generation;
|
|
877
|
-
const key = faults.key(model);
|
|
887
|
+
const key = faults.key(residentSrc(model, 'embeddings'));
|
|
878
888
|
const handle = pool.open(key, model);
|
|
879
889
|
let loaded = null;
|
|
880
890
|
let job = null;
|
|
@@ -929,7 +939,8 @@ export class Harness extends ReadyResource {
|
|
|
929
939
|
await this.ready();
|
|
930
940
|
if (this.suspended)
|
|
931
941
|
throw new Error('harness is suspended');
|
|
932
|
-
const
|
|
942
|
+
const addon = category === 'tts' ? 'tts' : 'parakeet';
|
|
943
|
+
const name = residentSrc(model || (await this._defaultVoiceSrc(category)), addon);
|
|
933
944
|
const handle = pool.open(name, name);
|
|
934
945
|
let job = null;
|
|
935
946
|
let releaseAfter = null;
|
|
@@ -997,7 +1008,7 @@ export class Harness extends ReadyResource {
|
|
|
997
1008
|
await this.ready();
|
|
998
1009
|
if (this.suspended)
|
|
999
1010
|
throw new Error('harness is suspended');
|
|
1000
|
-
const name = model || (await this._defaultVoiceSrc('tts'));
|
|
1011
|
+
const name = residentSrc(model || (await this._defaultVoiceSrc('tts')), 'tts');
|
|
1001
1012
|
const pool = this._ttsModels;
|
|
1002
1013
|
const handle = pool.open(name, name);
|
|
1003
1014
|
const chunks = pushQueue();
|
|
@@ -1123,29 +1134,143 @@ export class Harness extends ReadyResource {
|
|
|
1123
1134
|
await this.ready();
|
|
1124
1135
|
if (this.suspended)
|
|
1125
1136
|
return;
|
|
1126
|
-
const
|
|
1127
|
-
const
|
|
1128
|
-
|
|
1129
|
-
|
|
1130
|
-
|
|
1131
|
-
|
|
1132
|
-
|
|
1133
|
-
|
|
1134
|
-
|
|
1135
|
-
|
|
1136
|
-
if (!isResident(pool, key)) {
|
|
1137
|
-
if (!(await this._makeRoomForCompletion(signal, WARM_ROOM_WAIT_MS))) {
|
|
1137
|
+
const target = this._residency(model, agent);
|
|
1138
|
+
const resident = isResident(target.pool, target.key);
|
|
1139
|
+
hlog('warm model', { model, resident });
|
|
1140
|
+
if (target.pool === this._models && !resident) {
|
|
1141
|
+
const roomed = await this._makeRoomForCompletion(model, {
|
|
1142
|
+
ctxSize: target.ctxSize,
|
|
1143
|
+
signal,
|
|
1144
|
+
deadlineMs: WARM_ROOM_WAIT_MS
|
|
1145
|
+
});
|
|
1146
|
+
if (!roomed) {
|
|
1138
1147
|
return;
|
|
1139
1148
|
}
|
|
1140
|
-
await this.
|
|
1149
|
+
await this._unloadIdleGenerators();
|
|
1150
|
+
}
|
|
1151
|
+
await this._loadAndRelease(target, signal);
|
|
1152
|
+
}
|
|
1153
|
+
loadModel(context) {
|
|
1154
|
+
return this._busy(() => this._loadModel(context));
|
|
1155
|
+
}
|
|
1156
|
+
async _loadModel({ model, agent, signal }) {
|
|
1157
|
+
if (!this.opened)
|
|
1158
|
+
await this.ready();
|
|
1159
|
+
if (this.suspended) {
|
|
1160
|
+
throw new Error('harness is suspended');
|
|
1161
|
+
}
|
|
1162
|
+
const target = this._residency(model, agent);
|
|
1163
|
+
const resident = isResident(target.pool, target.key);
|
|
1164
|
+
hlog('load model', { model, resident });
|
|
1165
|
+
if (target.pool !== this._models) {
|
|
1166
|
+
await this._loadAndRelease(target, signal);
|
|
1167
|
+
return { loaded: true };
|
|
1168
|
+
}
|
|
1169
|
+
if (!resident) {
|
|
1170
|
+
if (!(await this._fits(model, target.ctxSize))) {
|
|
1171
|
+
return { loaded: false, reason: 'memory' };
|
|
1172
|
+
}
|
|
1173
|
+
await evictIdleWhere(this._models, (key) => modelOf(key) === model && !this._replying.includes(key));
|
|
1174
|
+
await this._unloadIdleGenerators();
|
|
1175
|
+
}
|
|
1176
|
+
this._pinned.add(target.key);
|
|
1177
|
+
try {
|
|
1178
|
+
await this._loadAndRelease(target, signal);
|
|
1179
|
+
}
|
|
1180
|
+
catch (err) {
|
|
1181
|
+
this._pinned.delete(target.key);
|
|
1182
|
+
throw err;
|
|
1183
|
+
}
|
|
1184
|
+
return { loaded: true };
|
|
1185
|
+
}
|
|
1186
|
+
unloadModel(context) {
|
|
1187
|
+
return this._busy(() => this._unloadModel(context));
|
|
1188
|
+
}
|
|
1189
|
+
async _unloadModel({ model }) {
|
|
1190
|
+
if (!this.opened)
|
|
1191
|
+
await this.ready();
|
|
1192
|
+
const target = this._residency(model);
|
|
1193
|
+
const name = modelOf(target.key);
|
|
1194
|
+
const unloaded = await evictModel(target.pool, name, { deadlineMs: UNLOAD_LEASE_WAIT_MS });
|
|
1195
|
+
hlog('unload model', { model, unloaded });
|
|
1196
|
+
if (unloaded) {
|
|
1197
|
+
for (const key of this._pinned) {
|
|
1198
|
+
if (modelOf(key) === name) {
|
|
1199
|
+
this._pinned.delete(key);
|
|
1200
|
+
}
|
|
1201
|
+
}
|
|
1141
1202
|
}
|
|
1203
|
+
return { unloaded };
|
|
1204
|
+
}
|
|
1205
|
+
async _loadAndRelease(target, signal) {
|
|
1142
1206
|
try {
|
|
1143
|
-
await raceAbort(
|
|
1207
|
+
await raceAbort(target.open().load(), signal);
|
|
1144
1208
|
}
|
|
1145
1209
|
finally {
|
|
1146
|
-
releaseModel(pool, key);
|
|
1210
|
+
releaseModel(target.pool, target.key);
|
|
1147
1211
|
}
|
|
1148
1212
|
}
|
|
1213
|
+
async _unloadIdleGenerators() {
|
|
1214
|
+
await this._imageRuntime?.unloadIdle().catch(noop);
|
|
1215
|
+
await this._musicRuntime?.unloadIdle().catch(noop);
|
|
1216
|
+
}
|
|
1217
|
+
async _fits(model, ctxSize) {
|
|
1218
|
+
const asset = curatedModelAsset(model, 'llm');
|
|
1219
|
+
if (!asset) {
|
|
1220
|
+
return true;
|
|
1221
|
+
}
|
|
1222
|
+
const assessed = await this._assessFit({
|
|
1223
|
+
sha256Checksum: asset.sha256Checksum,
|
|
1224
|
+
name: asset.name,
|
|
1225
|
+
contextTokens: ctxSize || defaultContextSize(asset)
|
|
1226
|
+
}).catch((err) => {
|
|
1227
|
+
hlog('fit estimate failed', { model, err: errorMessage(err) });
|
|
1228
|
+
return null;
|
|
1229
|
+
});
|
|
1230
|
+
return assessed?.fit !== 'likely-too-large';
|
|
1231
|
+
}
|
|
1232
|
+
async _yieldPins(model, ctxSize) {
|
|
1233
|
+
for (const key of this._pinned) {
|
|
1234
|
+
if (leaseCount(this._models, key) > 0 || this._replying.includes(key)) {
|
|
1235
|
+
continue;
|
|
1236
|
+
}
|
|
1237
|
+
if (await this._fits(model, ctxSize))
|
|
1238
|
+
return;
|
|
1239
|
+
this._pinned.delete(key);
|
|
1240
|
+
await evictModelWithin(this._models, key, { deadlineMs: WEDGED_EVICT_WAIT_MS });
|
|
1241
|
+
}
|
|
1242
|
+
}
|
|
1243
|
+
_residency(model, agent) {
|
|
1244
|
+
const addon = modelAddonOf(model);
|
|
1245
|
+
if (addon === 'llm') {
|
|
1246
|
+
const loadOpts = this._completionLoadOptions(model, agent);
|
|
1247
|
+
const key = modelKey(model, loadOpts);
|
|
1248
|
+
return {
|
|
1249
|
+
pool: this._models,
|
|
1250
|
+
key,
|
|
1251
|
+
ctxSize: loadOpts.ctxSize,
|
|
1252
|
+
open: () => this._models.open(key, model, loadOpts)
|
|
1253
|
+
};
|
|
1254
|
+
}
|
|
1255
|
+
if (addon === 'embeddings') {
|
|
1256
|
+
const key = this._embedFaults.key(residentSrc(model, addon));
|
|
1257
|
+
return { pool: this._embedModels, key, open: () => this._embedModels.open(key, model) };
|
|
1258
|
+
}
|
|
1259
|
+
if (addon === 'tts' || addon === 'parakeet') {
|
|
1260
|
+
const pool = addon === 'tts' ? this._ttsModels : this._transcriptionModels;
|
|
1261
|
+
const key = residentSrc(model, addon);
|
|
1262
|
+
return { pool, key, open: () => pool.open(key, key) };
|
|
1263
|
+
}
|
|
1264
|
+
throw new Error(`${model} loads for each generation and is not kept in memory`);
|
|
1265
|
+
}
|
|
1266
|
+
_completionLoadOptions(model, agent) {
|
|
1267
|
+
return resolveLoadOptions({
|
|
1268
|
+
ctxSize: agent?.ctxSize ?? undefined,
|
|
1269
|
+
kvCacheK: agent?.kvCacheK ?? undefined,
|
|
1270
|
+
kvCacheV: agent?.kvCacheV ?? undefined,
|
|
1271
|
+
projectionModel: this._projectionFor(model)
|
|
1272
|
+
}, this._deviceConfig());
|
|
1273
|
+
}
|
|
1149
1274
|
invoke(context) {
|
|
1150
1275
|
return this._busyStream(() => this._invoke(context));
|
|
1151
1276
|
}
|
|
@@ -1184,27 +1309,20 @@ export class Harness extends ReadyResource {
|
|
|
1184
1309
|
await this.ready();
|
|
1185
1310
|
if (this.suspended)
|
|
1186
1311
|
throw new Error('harness is suspended');
|
|
1187
|
-
const
|
|
1188
|
-
const
|
|
1189
|
-
ctxSize: agent?.ctxSize ?? undefined,
|
|
1190
|
-
kvCacheK: agent?.kvCacheK ?? undefined,
|
|
1191
|
-
kvCacheV: agent?.kvCacheV ?? undefined,
|
|
1192
|
-
projectionModel
|
|
1193
|
-
}, this._deviceConfig());
|
|
1312
|
+
const loadOpts = this._completionLoadOptions(model, agent);
|
|
1313
|
+
const projectionModel = loadOpts.projectionModel;
|
|
1194
1314
|
const key = modelKey(model, loadOpts);
|
|
1195
1315
|
const pool = this._models;
|
|
1196
1316
|
const resident = isResident(pool, key);
|
|
1197
1317
|
hlog('completion start', { model, resident, projection: Boolean(projectionModel) });
|
|
1198
1318
|
if (!resident) {
|
|
1199
|
-
await this._makeRoomForCompletion(signal);
|
|
1200
|
-
await this.
|
|
1201
|
-
await this._musicRuntime?.unloadIdle().catch(noop);
|
|
1319
|
+
await this._makeRoomForCompletion(model, { ctxSize: loadOpts.ctxSize, signal });
|
|
1320
|
+
await this._unloadIdleGenerators();
|
|
1202
1321
|
}
|
|
1203
1322
|
const acquireRound = async () => {
|
|
1204
1323
|
if (!isResident(pool, key)) {
|
|
1205
|
-
await this._makeRoomForCompletion(signal);
|
|
1206
|
-
await this.
|
|
1207
|
-
await this._musicRuntime?.unloadIdle().catch(noop);
|
|
1324
|
+
await this._makeRoomForCompletion(model, { ctxSize: loadOpts.ctxSize, signal });
|
|
1325
|
+
await this._unloadIdleGenerators();
|
|
1208
1326
|
}
|
|
1209
1327
|
try {
|
|
1210
1328
|
const { modelId } = await raceAbort(pool.open(key, model, loadOpts).load(), signal);
|
|
@@ -1228,6 +1346,7 @@ export class Harness extends ReadyResource {
|
|
|
1228
1346
|
held = false;
|
|
1229
1347
|
releaseModel(pool, key);
|
|
1230
1348
|
};
|
|
1349
|
+
this._replying.push(key);
|
|
1231
1350
|
try {
|
|
1232
1351
|
const { modelId, ctxSize } = await raceAbort(handle.load(), signal);
|
|
1233
1352
|
hlog('model ready', { model });
|
|
@@ -1287,6 +1406,7 @@ export class Harness extends ReadyResource {
|
|
|
1287
1406
|
}
|
|
1288
1407
|
finally {
|
|
1289
1408
|
hlog('completion end', { model });
|
|
1409
|
+
this._replying.splice(this._replying.indexOf(key), 1);
|
|
1290
1410
|
releaseHeld();
|
|
1291
1411
|
void this._imageRuntime?.unloadIdle().catch(noop);
|
|
1292
1412
|
void this._musicRuntime?.unloadIdle().catch(noop);
|
|
@@ -1315,11 +1435,12 @@ export class Harness extends ReadyResource {
|
|
|
1315
1435
|
}
|
|
1316
1436
|
};
|
|
1317
1437
|
}
|
|
1318
|
-
async _makeRoomForCompletion(signal, deadlineMs = MODEL_ROOM_WAIT_MS) {
|
|
1438
|
+
async _makeRoomForCompletion(model, { ctxSize, signal, deadlineMs = MODEL_ROOM_WAIT_MS } = {}) {
|
|
1319
1439
|
const roomed = await awaitModelCapacity(this._models, {
|
|
1320
1440
|
cap: this._completionModelCap,
|
|
1321
1441
|
deadlineMs,
|
|
1322
|
-
signal
|
|
1442
|
+
signal,
|
|
1443
|
+
evictable: (key) => !this._pinned.has(key) || modelOf(key) === model
|
|
1323
1444
|
});
|
|
1324
1445
|
if (!roomed) {
|
|
1325
1446
|
hlog('model room wait gave up', {
|
|
@@ -1327,6 +1448,7 @@ export class Harness extends ReadyResource {
|
|
|
1327
1448
|
loaded: loadedModels(this._models).length
|
|
1328
1449
|
});
|
|
1329
1450
|
}
|
|
1451
|
+
await this._yieldPins(model, ctxSize);
|
|
1330
1452
|
return roomed;
|
|
1331
1453
|
}
|
|
1332
1454
|
async _evictWedgedModel(model, key) {
|
|
@@ -1,7 +1,6 @@
|
|
|
1
1
|
import type { HarnessPreviewModelSourceResponse } from '../../spec/hyperschema/types.d.ts';
|
|
2
2
|
export type ModelFitVerdict = 'likely-fits' | 'likely-too-large' | 'unknown';
|
|
3
3
|
export type ModelSourceRefusal = 'invalid-source' | 'not-found' | 'private' | 'gated' | 'web-page' | 'unreachable' | 'not-gguf' | 'not-a-model' | 'no-model-files' | 'invalid-projection';
|
|
4
|
-
export type ModelTaskType = 'llm' | 'embeddings' | 'speech-to-text' | 'text-to-speech' | 'image-generation';
|
|
5
4
|
export interface ModelSourceFile {
|
|
6
5
|
src: string;
|
|
7
6
|
label: string;
|
|
@@ -3,7 +3,7 @@ import { type Transport } from './rpc-session.ts';
|
|
|
3
3
|
import { type KvCacheDeletionResult } from './capabilities/kv-cache.ts';
|
|
4
4
|
import type { CustomModelEntry } from './models/model-catalog.ts';
|
|
5
5
|
import { type ModelSourcePreview, type PreviewModelSourceContext } from './capabilities/preview-model-source.ts';
|
|
6
|
-
import type { CapabilityInfo, CompletionContext, CredentialEntry, DetectedLanguage, DetectLanguageContext, DownloadContext, EmbedContext, HarnessContract, HarnessDiagnostics, HarnessEvent, HarnessInfo, InfraModel, InvokeContext, ListModelsOptions, ModelInfo, ResolvedSkillCatalogEntry, SkillsOptions, SkillWriteResult, SpeakContext, SpeakResult, SpeakStreamContext, ToolCatalogEntry, TranscribeContext, WarmModelContext } from './contract-types.ts';
|
|
6
|
+
import type { CapabilityInfo, CompletionContext, CredentialEntry, DetectedLanguage, DetectLanguageContext, DownloadContext, EmbedContext, HarnessContract, HarnessDiagnostics, HarnessEvent, HarnessInfo, InfraModel, InvokeContext, ListModelsOptions, ModelInfo, ResolvedSkillCatalogEntry, SkillsOptions, SkillWriteResult, SpeakContext, SpeakResult, SpeakStreamContext, ToolCatalogEntry, TranscribeContext, LoadModelContext, LoadModelResult, UnloadModelContext, UnloadModelResult, WarmModelContext } from './contract-types.ts';
|
|
7
7
|
import { type EmbedDevice } from './models/embed-config.ts';
|
|
8
8
|
import type { DeleteModelSummary } from './models/model-delete.ts';
|
|
9
9
|
import type { CopyBaseResult, DeleteOverlayResult, ManagedSkill, SkillFileContent } from './tools/skills/overlay-crud.ts';
|
|
@@ -46,6 +46,8 @@ export declare class RemoteHarness extends EventEmitter implements HarnessContra
|
|
|
46
46
|
skills(agentId?: string | null, modelName?: string | null, options?: SkillsOptions): Promise<ResolvedSkillCatalogEntry[]>;
|
|
47
47
|
tools(): Promise<ToolCatalogEntry[]>;
|
|
48
48
|
warmModel(context: WarmModelContext): Promise<void>;
|
|
49
|
+
loadModel(context: LoadModelContext): Promise<LoadModelResult>;
|
|
50
|
+
unloadModel(context: UnloadModelContext): Promise<UnloadModelResult>;
|
|
49
51
|
list(options?: ListModelsOptions): Promise<ModelInfo[]>;
|
|
50
52
|
deleteModel(name: string): Promise<DeleteModelSummary>;
|
|
51
53
|
clearKvCache(): Promise<KvCacheDeletionResult>;
|
package/dist-lib/lib/connect.js
CHANGED
|
@@ -8,6 +8,7 @@ import { unsupportedKvCacheDeletion } from './capabilities/kv-cache.js';
|
|
|
8
8
|
import { readModelSourcePreview } from './capabilities/preview-model-source.js';
|
|
9
9
|
import { hlog } from './log.js';
|
|
10
10
|
import { assertEmbedDevice } from './models/embed-config.js';
|
|
11
|
+
import { addonTaskType } from './models/model-task.js';
|
|
11
12
|
import { errorCode, errorMessage, isRecord } from './guards.js';
|
|
12
13
|
import { pushQueue } from './queue.js';
|
|
13
14
|
import { stageFile, sweepStaging } from './staging.js';
|
|
@@ -540,6 +541,24 @@ export class RemoteHarness extends EventEmitter {
|
|
|
540
541
|
agent: context.agent ? knobs(context.agent) : undefined
|
|
541
542
|
}), context.signal);
|
|
542
543
|
}
|
|
544
|
+
async loadModel(context) {
|
|
545
|
+
const { client } = await this._ensure();
|
|
546
|
+
const response = await abortable(client.loadModel({
|
|
547
|
+
model: context.model,
|
|
548
|
+
agent: context.agent ? knobs(context.agent) : undefined
|
|
549
|
+
}), context.signal);
|
|
550
|
+
return {
|
|
551
|
+
loaded: response.loaded === true,
|
|
552
|
+
reason: response.reason === 'memory' ? 'memory' : undefined
|
|
553
|
+
};
|
|
554
|
+
}
|
|
555
|
+
async unloadModel(context) {
|
|
556
|
+
const { client } = await this._ensure();
|
|
557
|
+
const response = await client.unloadModel({
|
|
558
|
+
model: context.model
|
|
559
|
+
});
|
|
560
|
+
return { unloaded: response.unloaded === true };
|
|
561
|
+
}
|
|
543
562
|
async list(options = {}) {
|
|
544
563
|
const { client } = await this._ensure();
|
|
545
564
|
const response = await client.listModels({
|
|
@@ -550,7 +569,8 @@ export class RemoteHarness extends EventEmitter {
|
|
|
550
569
|
return (response.models ?? []).map(({ actualSize, label, ...row }) => ({
|
|
551
570
|
...row,
|
|
552
571
|
actualSize: actualSize || undefined,
|
|
553
|
-
label: label || undefined
|
|
572
|
+
label: label || undefined,
|
|
573
|
+
taskType: addonTaskType(row.type)
|
|
554
574
|
}));
|
|
555
575
|
}
|
|
556
576
|
async deleteModel(name) {
|
|
@@ -606,7 +626,8 @@ export class RemoteHarness extends EventEmitter {
|
|
|
606
626
|
source: memoryBudget.source,
|
|
607
627
|
gpuClass: memoryBudget.gpuClass || undefined
|
|
608
628
|
}
|
|
609
|
-
: undefined
|
|
629
|
+
: undefined,
|
|
630
|
+
mobile: response.mobile === true
|
|
610
631
|
};
|
|
611
632
|
}
|
|
612
633
|
close() {
|
|
@@ -113,6 +113,17 @@ export interface WarmModelContext {
|
|
|
113
113
|
agent?: AgentKnobs;
|
|
114
114
|
signal?: CompletionContext['signal'];
|
|
115
115
|
}
|
|
116
|
+
export type LoadModelContext = WarmModelContext;
|
|
117
|
+
export interface LoadModelResult {
|
|
118
|
+
loaded: boolean;
|
|
119
|
+
reason?: 'memory';
|
|
120
|
+
}
|
|
121
|
+
export interface UnloadModelContext {
|
|
122
|
+
model: string;
|
|
123
|
+
}
|
|
124
|
+
export interface UnloadModelResult {
|
|
125
|
+
unloaded: boolean;
|
|
126
|
+
}
|
|
116
127
|
export interface DownloadContext {
|
|
117
128
|
model: string;
|
|
118
129
|
addon?: string;
|
|
@@ -164,6 +175,7 @@ export interface CapabilityInfo {
|
|
|
164
175
|
capabilityProfile: HarnessCapabilityProfile;
|
|
165
176
|
recommendedModelName: string;
|
|
166
177
|
memoryBudget?: MemoryBudget;
|
|
178
|
+
mobile: boolean;
|
|
167
179
|
}
|
|
168
180
|
export interface CredentialEntry {
|
|
169
181
|
key: string;
|
|
@@ -224,6 +236,8 @@ export interface HarnessContract {
|
|
|
224
236
|
}>;
|
|
225
237
|
list?(options?: ListModelsOptions): Promise<ModelInfo[]>;
|
|
226
238
|
warmModel?(context: WarmModelContext): Promise<void>;
|
|
239
|
+
loadModel?(context: LoadModelContext): Promise<LoadModelResult>;
|
|
240
|
+
unloadModel?(context: UnloadModelContext): Promise<UnloadModelResult>;
|
|
227
241
|
deleteModel?(name: string): Promise<DeleteModelSummary>;
|
|
228
242
|
clearKvCache?(): Promise<KvCacheDeletionResult>;
|
|
229
243
|
deleteKvCache?(kvCacheKey: string): Promise<KvCacheDeletionResult>;
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import type { AbortSignal } from 'bare-abort-controller';
|
|
2
|
-
export { closePythonWorker as closeDocxWorker } from '../tools/exec/adapters/python/worker/
|
|
2
|
+
export { closePythonWorker as closeDocxWorker } from '../tools/exec/adapters/python/worker/active.ts';
|
|
3
3
|
export interface DocxExtractOptions {
|
|
4
4
|
readonly signal?: AbortSignal;
|
|
5
5
|
}
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import { extractWithPython } from '../office/python.js';
|
|
2
|
-
export { closePythonWorker as closeDocxWorker } from '../tools/exec/adapters/python/worker/
|
|
2
|
+
export { closePythonWorker as closeDocxWorker } from '../tools/exec/adapters/python/worker/active.js';
|
|
3
3
|
const PACKAGES = ['python-docx==1.2.0'];
|
|
4
4
|
const EXTRACT = `from docx import Document
|
|
5
5
|
from docx.text.paragraph import Paragraph
|
|
@@ -1,5 +1,5 @@
|
|
|
1
1
|
import process from 'process';
|
|
2
|
-
import { capabilityProfileToModelName } from '../models/model-catalog.js';
|
|
2
|
+
import { capabilityProfileToModelName, isMobilePlatform } from '../models/model-catalog.js';
|
|
3
3
|
import { probeWithAddon } from './gpu-probe-addon.js';
|
|
4
4
|
import { mobileBudget, parseNvidiaSmiOutput, parseRocmSmiOutput, parseWindowsRegistryOutput, sharedRamBudget } from './parsers.js';
|
|
5
5
|
const GIB = 1024 * 1024 * 1024;
|
|
@@ -85,7 +85,7 @@ async function isPixel(reads) {
|
|
|
85
85
|
}
|
|
86
86
|
async function probeMemoryBudget(reads) {
|
|
87
87
|
const os = reads.platform();
|
|
88
|
-
if (os
|
|
88
|
+
if (isMobilePlatform(os)) {
|
|
89
89
|
return mobileBudget(reads.totalmem(), await isPixel(reads));
|
|
90
90
|
}
|
|
91
91
|
if (os === 'darwin') {
|
|
@@ -101,9 +101,14 @@ function forcedProfile() {
|
|
|
101
101
|
return undefined;
|
|
102
102
|
}
|
|
103
103
|
export async function probeCapabilityProfile(reads) {
|
|
104
|
+
const mobile = isMobilePlatform(reads.platform());
|
|
104
105
|
const forced = forcedProfile();
|
|
105
106
|
if (forced) {
|
|
106
|
-
return {
|
|
107
|
+
return {
|
|
108
|
+
capabilityProfile: forced,
|
|
109
|
+
recommendedModelName: capabilityProfileToModelName(forced),
|
|
110
|
+
mobile
|
|
111
|
+
};
|
|
107
112
|
}
|
|
108
|
-
return recommend(await probeMemoryBudget(reads));
|
|
113
|
+
return { ...recommend(await probeMemoryBudget(reads)), mobile };
|
|
109
114
|
}
|
|
@@ -1,4 +1,3 @@
|
|
|
1
|
-
import { planVendoredInstall } from '../../tools/exec/adapters/python/wheels.js';
|
|
2
1
|
import { bareBin, firstCommandToken } from '../../tools/exec/scope.js';
|
|
3
2
|
const NETWORK_BINS = new Set([
|
|
4
3
|
'curl',
|
|
@@ -33,10 +32,6 @@ export class SandboxHook {
|
|
|
33
32
|
return;
|
|
34
33
|
if (!ctx.sandboxMode || ctx.toolName !== 'exec')
|
|
35
34
|
return;
|
|
36
|
-
const packages = ctx.args.packages;
|
|
37
|
-
if (Array.isArray(packages) && packages.length && !planVendoredInstall(packages.map(String))) {
|
|
38
|
-
return { error: 'sandbox mode: installing packages reaches the network', guidance: true };
|
|
39
|
-
}
|
|
40
35
|
const bin = bareBin(firstCommandToken(String(ctx.args.command ?? '')).replace(/^.*[/\\]/, ''));
|
|
41
36
|
if (bin && NETWORK_BINS.has(bin)) {
|
|
42
37
|
return { error: `sandbox mode: ${bin} reaches the network`, guidance: true };
|
|
@@ -11,6 +11,13 @@ export declare const MEDPSY_4B = "medpsy-4b-q4_k_m-imat";
|
|
|
11
11
|
export declare function isCapabilityProfile(value: string): value is CapabilityProfile;
|
|
12
12
|
export declare function meetsMinCapabilityProfile(active: CapabilityProfile, required: CapabilityProfile): boolean;
|
|
13
13
|
export declare function modelNameToCapabilityProfile(modelName: string): CapabilityProfile | undefined;
|
|
14
|
+
export interface HostCapability {
|
|
15
|
+
readonly capabilityProfile: string;
|
|
16
|
+
readonly recommendedModelName: string;
|
|
17
|
+
readonly mobile: boolean;
|
|
18
|
+
}
|
|
19
|
+
export declare function isMobilePlatform(platform: string): boolean;
|
|
20
|
+
export declare function runnableModelName(requested: string, host: HostCapability | null): string;
|
|
14
21
|
export declare function capabilityProfileToModelName(profile: CapabilityProfile): string;
|
|
15
22
|
export declare const AGENT_MODEL_NAMES: readonly ["Qwen3.5-2B-Q4_K_M", "Qwen3.5-4B-Q4_K_M", "Qwen3.5-9B-Q4_K_M", "Qwen3.6-27B-UD-Q4_K_XL", "Qwen3.6-35B-A3B-UD-Q4_K_M", "Qwen3.8-27B-UD-Q4_K_XL", "medpsy-1.7b-q4_k_m-imat", "medpsy-4b-q4_k_m-imat"];
|
|
16
23
|
export declare function modelDisplayName(modelName: string): string;
|
|
@@ -32,6 +32,23 @@ const MODEL_NAME_TO_PROFILE = new Map([
|
|
|
32
32
|
export function modelNameToCapabilityProfile(modelName) {
|
|
33
33
|
return MODEL_NAME_TO_PROFILE.get(modelName);
|
|
34
34
|
}
|
|
35
|
+
export function isMobilePlatform(platform) {
|
|
36
|
+
return platform === 'android' || platform === 'ios';
|
|
37
|
+
}
|
|
38
|
+
export function runnableModelName(requested, host) {
|
|
39
|
+
if (!host?.mobile || !isCapabilityProfile(host.capabilityProfile)) {
|
|
40
|
+
return requested;
|
|
41
|
+
}
|
|
42
|
+
const required = modelNameToCapabilityProfile(requested);
|
|
43
|
+
if (!required || meetsMinCapabilityProfile(host.capabilityProfile, required)) {
|
|
44
|
+
return requested;
|
|
45
|
+
}
|
|
46
|
+
const fallback = modelNameToCapabilityProfile(host.recommendedModelName);
|
|
47
|
+
if (!fallback || !meetsMinCapabilityProfile(required, fallback)) {
|
|
48
|
+
return requested;
|
|
49
|
+
}
|
|
50
|
+
return host.recommendedModelName;
|
|
51
|
+
}
|
|
35
52
|
const PROFILE_TO_MODEL_NAME = new Map([
|
|
36
53
|
['tiny', QWEN_35_2B],
|
|
37
54
|
['low', QWEN_35_2B],
|
|
@@ -5,9 +5,9 @@ import type { ModelAddon } from './model-source.ts';
|
|
|
5
5
|
export interface SdkModelAsset extends ModelRegistryEntry {
|
|
6
6
|
readonly src: string;
|
|
7
7
|
}
|
|
8
|
-
import { CAPABILITY_PROFILE_ORDER, QWEN_35_2B, QWEN_35_4B, QWEN_35_9B, QWEN_36_27B, QWEN_36_35B_A3B, QWEN_38_27B, MEDPSY_1_7B, MEDPSY_4B, isCapabilityProfile, meetsMinCapabilityProfile, modelNameToCapabilityProfile, capabilityProfileToModelName, isMultimodalLlm, AGENT_MODEL_NAMES, modelDisplayName, capabilityProfileModelLabel, DEFAULT_IMAGE_MODEL_CHOICE, IMAGE_CHOICE_CATALOG, type CapabilityProfile, type ImageModelChoice, type ImageChoiceEntry } from './model-catalog-constants.ts';
|
|
9
|
-
export { CAPABILITY_PROFILE_ORDER, QWEN_35_2B, QWEN_35_4B, QWEN_35_9B, QWEN_36_27B, QWEN_36_35B_A3B, QWEN_38_27B, MEDPSY_1_7B, MEDPSY_4B, isCapabilityProfile, meetsMinCapabilityProfile, modelNameToCapabilityProfile, capabilityProfileToModelName, isMultimodalLlm, AGENT_MODEL_NAMES, modelDisplayName, capabilityProfileModelLabel, DEFAULT_IMAGE_MODEL_CHOICE, IMAGE_CHOICE_CATALOG };
|
|
10
|
-
export type { CapabilityProfile, ImageModelChoice, ImageChoiceEntry };
|
|
8
|
+
import { CAPABILITY_PROFILE_ORDER, QWEN_35_2B, QWEN_35_4B, QWEN_35_9B, QWEN_36_27B, QWEN_36_35B_A3B, QWEN_38_27B, MEDPSY_1_7B, MEDPSY_4B, isCapabilityProfile, meetsMinCapabilityProfile, modelNameToCapabilityProfile, capabilityProfileToModelName, isMultimodalLlm, AGENT_MODEL_NAMES, modelDisplayName, capabilityProfileModelLabel, DEFAULT_IMAGE_MODEL_CHOICE, IMAGE_CHOICE_CATALOG, isMobilePlatform, runnableModelName, type CapabilityProfile, type HostCapability, type ImageModelChoice, type ImageChoiceEntry } from './model-catalog-constants.ts';
|
|
9
|
+
export { CAPABILITY_PROFILE_ORDER, QWEN_35_2B, QWEN_35_4B, QWEN_35_9B, QWEN_36_27B, QWEN_36_35B_A3B, QWEN_38_27B, MEDPSY_1_7B, MEDPSY_4B, isCapabilityProfile, meetsMinCapabilityProfile, modelNameToCapabilityProfile, capabilityProfileToModelName, isMultimodalLlm, AGENT_MODEL_NAMES, modelDisplayName, capabilityProfileModelLabel, DEFAULT_IMAGE_MODEL_CHOICE, IMAGE_CHOICE_CATALOG, isMobilePlatform, runnableModelName };
|
|
10
|
+
export type { CapabilityProfile, HostCapability, ImageModelChoice, ImageChoiceEntry };
|
|
11
11
|
export interface LlmCatalogEntry {
|
|
12
12
|
readonly name: string;
|
|
13
13
|
readonly weight: SdkModelAsset;
|
|
@@ -49,8 +49,8 @@ export interface DiffusionDownloadMetadata {
|
|
|
49
49
|
}
|
|
50
50
|
export declare function diffusionDownloadName(model: string): string | null;
|
|
51
51
|
export declare function diffusionDownloadMetadata(model: string, addon: ModelAddon | undefined): DiffusionDownloadMetadata | undefined;
|
|
52
|
-
import { DEFAULT_MUSIC_MODEL_CHOICE, type MusicModelChoice } from './music-catalog.ts';
|
|
53
|
-
export { DEFAULT_MUSIC_MODEL_CHOICE, type MusicModelChoice };
|
|
52
|
+
import { DEFAULT_MUSIC_MODEL_CHOICE, isMusicModelChoice, musicModelChoiceFrom, type MusicModelChoice } from './music-catalog.ts';
|
|
53
|
+
export { DEFAULT_MUSIC_MODEL_CHOICE, isMusicModelChoice, musicModelChoiceFrom, type MusicModelChoice };
|
|
54
54
|
export interface AudioGenCatalogEntry {
|
|
55
55
|
readonly choice: MusicModelChoice;
|
|
56
56
|
readonly name: string;
|
|
@@ -78,7 +78,15 @@ export interface AgentSkillModelInput {
|
|
|
78
78
|
readonly imageModelChoice?: ImageModelChoice | null;
|
|
79
79
|
readonly musicModelChoice?: MusicModelChoice | null;
|
|
80
80
|
}
|
|
81
|
-
export
|
|
81
|
+
export type AgentModelUse = 'chat' | 'image' | 'music';
|
|
82
|
+
export interface AgentModel extends CatalogModel {
|
|
83
|
+
readonly use: AgentModelUse;
|
|
84
|
+
}
|
|
85
|
+
export interface AgentModelInput extends AgentSkillModelInput {
|
|
86
|
+
readonly modelName?: string | null;
|
|
87
|
+
}
|
|
88
|
+
export declare function skillModelsForAgent(agent: AgentSkillModelInput): ReadonlyArray<AgentModel>;
|
|
89
|
+
export declare function modelsForAgent(agent: AgentModelInput, host: HostCapability | null): ReadonlyArray<AgentModel>;
|
|
82
90
|
export declare function diffusionSizeBytes(entry: DiffusionCatalogEntry): number;
|
|
83
91
|
export declare function imageModelFor(choice: string | undefined): ImageModelSet | null;
|
|
84
92
|
export interface ImageClamps {
|
|
@@ -95,6 +103,8 @@ export interface CuratedListable {
|
|
|
95
103
|
}
|
|
96
104
|
export declare function curatedListables(): CuratedListable[];
|
|
97
105
|
export declare function curatedModelAsset(name: string, addon: ModelRegistryEntry['addon']): SdkModelAsset | undefined;
|
|
106
|
+
export declare function modelAddonOf(model: string): ModelRegistryEntry['addon'];
|
|
107
|
+
export declare function residentSrc(model: string, addon: ModelRegistryEntry['addon']): string;
|
|
98
108
|
export declare const CUSTOM_TASK_TYPES: readonly ['llm'];
|
|
99
109
|
export type CustomTaskType = (typeof CUSTOM_TASK_TYPES)[number];
|
|
100
110
|
export interface CustomModelEntry {
|