@qvac/harness 0.4.0 → 0.6.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 +740 -141
- package/README.md +75 -7
- package/dist/harness.bundle +72 -50
- package/dist-lib/index.d.ts +49 -39
- package/dist-lib/index.js +448 -161
- package/dist-lib/lib/audio-transcode-bare.d.ts +2 -2
- package/dist-lib/lib/audio-transcode-bare.js +28 -18
- package/dist-lib/lib/audio-transcode-node.d.ts +2 -2
- package/dist-lib/lib/capabilities/audio-resample.d.ts +7 -6
- package/dist-lib/lib/capabilities/audio-resample.js +30 -18
- package/dist-lib/lib/capabilities/completion.d.ts +20 -19
- package/dist-lib/lib/capabilities/completion.js +193 -132
- package/dist-lib/lib/capabilities/download.d.ts +6 -6
- package/dist-lib/lib/capabilities/download.js +15 -8
- package/dist-lib/lib/capabilities/embed.js +2 -1
- package/dist-lib/lib/capabilities/enhance.d.ts +6 -1
- package/dist-lib/lib/capabilities/enhance.js +7 -4
- package/dist-lib/lib/capabilities/invoke.js +7 -4
- package/dist-lib/lib/capabilities/kv-cache.js +2 -1
- package/dist-lib/lib/capabilities/preview-model-source.d.ts +9 -7
- package/dist-lib/lib/capabilities/preview-model-source.js +80 -28
- package/dist-lib/lib/capabilities/speech-text.js +5 -4
- package/dist-lib/lib/capabilities/tool-selection.js +10 -9
- package/dist-lib/lib/capabilities/tool-turns.js +30 -16
- package/dist-lib/lib/capabilities/usage-breakdown.js +2 -1
- package/dist-lib/lib/capabilities/voice.d.ts +5 -1
- package/dist-lib/lib/capabilities/voice.js +22 -12
- package/dist-lib/lib/connect.d.ts +13 -32
- package/dist-lib/lib/connect.js +170 -112
- package/dist-lib/lib/context-window.js +25 -21
- package/dist-lib/lib/contract-types.d.ts +35 -15
- package/dist-lib/lib/diagram-repair.d.ts +4 -4
- package/dist-lib/lib/diagram-repair.js +6 -3
- package/dist-lib/lib/docx/index.d.ts +3 -2
- package/dist-lib/lib/{error-fields.d.ts → guards.d.ts} +1 -0
- package/dist-lib/lib/{error-fields.js → guards.js} +3 -0
- package/dist-lib/lib/hardware/capability-probe.js +20 -10
- package/dist-lib/lib/hardware/gpu-classify.js +6 -3
- package/dist-lib/lib/hardware/gpu-probe-addon.js +8 -4
- package/dist-lib/lib/hardware/gpu-probe.js +4 -2
- package/dist-lib/lib/hardware/gpu-stats.native.cjs +8 -9
- package/dist-lib/lib/hardware/parsers.js +8 -4
- package/dist-lib/lib/helpers/buffer-burst.js +4 -2
- package/dist-lib/lib/helpers/control-tokens.js +4 -2
- package/dist-lib/lib/helpers/join-guard.d.ts +2 -2
- package/dist-lib/lib/helpers/join-guard.js +4 -2
- package/dist-lib/lib/helpers/load-stall.js +4 -2
- package/dist-lib/lib/helpers/markup-stream-filter.d.ts +2 -2
- package/dist-lib/lib/helpers/markup-stream-filter.js +6 -3
- package/dist-lib/lib/helpers/race-abort.js +2 -1
- package/dist-lib/lib/helpers/race-timeout.d.ts +5 -0
- package/dist-lib/lib/helpers/race-timeout.js +14 -0
- package/dist-lib/lib/helpers/run-outcome.d.ts +6 -8
- package/dist-lib/lib/helpers/run-outcome.js +36 -20
- package/dist-lib/lib/helpers/spawn-path.js +6 -3
- package/dist-lib/lib/helpers/text-coalescer.js +6 -3
- package/dist-lib/lib/helpers/thinking.js +38 -45
- package/dist-lib/lib/helpers/tool-call-markup.d.ts +9 -7
- package/dist-lib/lib/helpers/tool-call-markup.js +36 -20
- package/dist-lib/lib/helpers/tool-intent.d.ts +3 -2
- package/dist-lib/lib/helpers/tool-intent.js +4 -2
- package/dist-lib/lib/helpers/tool-label.js +18 -9
- package/dist-lib/lib/hooks/built-in/arg-repair.js +23 -13
- package/dist-lib/lib/hooks/built-in/egress.js +2 -1
- package/dist-lib/lib/hooks/built-in/skill-catalog.js +2 -1
- package/dist-lib/lib/hooks/pipeline.d.ts +5 -4
- package/dist-lib/lib/hooks/pipeline.js +6 -3
- package/dist-lib/lib/hooks/run.js +12 -8
- package/dist-lib/lib/model-download-progress.js +10 -8
- package/dist-lib/lib/models/context.d.ts +1 -1
- package/dist-lib/lib/models/context.js +5 -1
- package/dist-lib/lib/models/custom-model-cache.d.ts +10 -1
- package/dist-lib/lib/models/custom-model-cache.js +43 -15
- package/dist-lib/lib/models/gguf-header.d.ts +3 -2
- package/dist-lib/lib/models/gguf-header.js +44 -22
- package/dist-lib/lib/models/idle-unload.d.ts +14 -0
- package/dist-lib/lib/models/idle-unload.js +51 -0
- package/dist-lib/lib/models/kv-cache.d.ts +3 -2
- package/dist-lib/lib/models/kv-cache.js +4 -3
- package/dist-lib/lib/models/llm-presets.d.ts +2 -2
- package/dist-lib/lib/models/llm-presets.js +4 -2
- package/dist-lib/lib/models/model-catalog-constants.js +3 -2
- package/dist-lib/lib/models/model-catalog.d.ts +15 -20
- package/dist-lib/lib/models/model-catalog.js +66 -31
- package/dist-lib/lib/models/model-delete.js +18 -8
- package/dist-lib/lib/models/model-handle.js +2 -1
- package/dist-lib/lib/models/model-list.d.ts +8 -3
- package/dist-lib/lib/models/model-list.js +11 -6
- package/dist-lib/lib/models/model-pool.d.ts +48 -10
- package/dist-lib/lib/models/model-pool.js +106 -45
- package/dist-lib/lib/models/model-source.js +10 -5
- package/dist-lib/lib/models/music-catalog.d.ts +2 -2
- package/dist-lib/lib/models/nmt-catalog.d.ts +4 -3
- package/dist-lib/lib/models/nmt-catalog.js +10 -5
- package/dist-lib/lib/models/opencl-cache.d.ts +6 -1
- package/dist-lib/lib/models/opencl-cache.js +5 -3
- package/dist-lib/lib/models/sdk-faults.d.ts +11 -8
- package/dist-lib/lib/models/sdk-faults.js +9 -6
- package/dist-lib/lib/models/shards.d.ts +11 -0
- package/dist-lib/lib/models/shards.js +15 -0
- package/dist-lib/lib/models/tool-dialect.js +10 -5
- package/dist-lib/lib/no-redirect-fetch-bare.d.ts +3 -3
- package/dist-lib/lib/no-redirect-fetch-bare.js +1 -1
- package/dist-lib/lib/no-redirect-fetch-impl.js +6 -3
- package/dist-lib/lib/no-redirect-fetch-node.d.ts +1 -1
- package/dist-lib/lib/no-redirect-fetch-node.js +9 -9
- package/dist-lib/lib/office/index.d.ts +3 -2
- package/dist-lib/lib/office/python.d.ts +3 -2
- package/dist-lib/lib/office/python.js +2 -1
- package/dist-lib/lib/prompt.d.ts +5 -4
- package/dist-lib/lib/prompt.js +8 -4
- package/dist-lib/lib/queue.js +10 -5
- package/dist-lib/lib/resolution-detector.js +21 -11
- package/dist-lib/lib/rpc-session.js +2 -1
- package/dist-lib/lib/sdk-loader.js +2 -1
- package/dist-lib/lib/sdk-storage.js +4 -2
- package/dist-lib/lib/serve.js +122 -66
- package/dist-lib/lib/spawn.js +7 -4
- package/dist-lib/lib/tmp-path.d.ts +7 -6
- package/dist-lib/lib/tool-call-display.d.ts +2 -2
- package/dist-lib/lib/tools/create-documents.js +18 -10
- package/dist-lib/lib/tools/edit-documents.js +23 -13
- package/dist-lib/lib/tools/edit-image.d.ts +2 -2
- package/dist-lib/lib/tools/edit-image.js +60 -36
- package/dist-lib/lib/tools/exec/adapters/adapter.d.ts +10 -10
- package/dist-lib/lib/tools/exec/adapters/python/attachments.d.ts +17 -11
- package/dist-lib/lib/tools/exec/adapters/python/attachments.js +53 -40
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.d.ts +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/create-effect.js +60 -32
- package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.d.ts +33 -22
- package/dist-lib/lib/tools/exec/adapters/python/guarded-fetch.js +58 -29
- package/dist-lib/lib/tools/exec/adapters/python/interrupt-timer.d.ts +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/loader.js +23 -12
- package/dist-lib/lib/tools/exec/adapters/python/memfs.d.ts +13 -11
- package/dist-lib/lib/tools/exec/adapters/python/memfs.js +10 -5
- package/dist-lib/lib/tools/exec/adapters/python/net-shim.js +3 -1
- package/dist-lib/lib/tools/exec/adapters/python/output-policy.d.ts +6 -4
- package/dist-lib/lib/tools/exec/adapters/python/output-policy.js +20 -10
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.d.ts +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/pyodide.js +14 -7
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.d.ts +41 -34
- package/dist-lib/lib/tools/exec/adapters/python/python-adapter.js +316 -166
- package/dist-lib/lib/tools/exec/adapters/python/run-session.d.ts +9 -8
- package/dist-lib/lib/tools/exec/adapters/python/run-session.js +56 -28
- package/dist-lib/lib/tools/exec/adapters/python/wheels.d.ts +8 -10
- package/dist-lib/lib/tools/exec/adapters/python/wheels.js +22 -11
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.d.ts +3 -2
- package/dist-lib/lib/tools/exec/adapters/python/worker/client.js +41 -26
- package/dist-lib/lib/tools/exec/adapters/python/worker/entry.js +27 -18
- package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.d.ts +2 -2
- package/dist-lib/lib/tools/exec/adapters/python/worker/protocol.js +14 -13
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.d.ts +4 -4
- package/dist-lib/lib/tools/exec/adapters/python/worker/spawn-node.js +10 -5
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.d.ts +4 -4
- package/dist-lib/lib/tools/exec/adapters/shell/shell-adapter.js +2 -1
- package/dist-lib/lib/tools/exec/obsidian/cli-process.d.ts +6 -1
- package/dist-lib/lib/tools/exec/obsidian/cli-process.js +8 -5
- package/dist-lib/lib/tools/exec/obsidian/cli.d.ts +6 -6
- package/dist-lib/lib/tools/exec/obsidian/cli.js +4 -4
- package/dist-lib/lib/tools/exec/obsidian/command.d.ts +3 -2
- package/dist-lib/lib/tools/exec/obsidian/command.js +6 -3
- package/dist-lib/lib/tools/exec/obsidian/output.js +2 -1
- package/dist-lib/lib/tools/exec/obsidian/route.d.ts +4 -6
- package/dist-lib/lib/tools/exec/obsidian/route.js +17 -11
- package/dist-lib/lib/tools/exec/obsidian/safe-path.js +2 -1
- package/dist-lib/lib/tools/exec/obsidian/vault-create.js +15 -7
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.d.ts +2 -2
- package/dist-lib/lib/tools/exec/obsidian/vault-paths.js +20 -10
- package/dist-lib/lib/tools/exec/obsidian/vault-read.js +20 -13
- package/dist-lib/lib/tools/exec/obsidian/vault-write.js +24 -12
- package/dist-lib/lib/tools/exec/runner.d.ts +14 -14
- package/dist-lib/lib/tools/exec/runner.js +5 -3
- package/dist-lib/lib/tools/exec/scope.js +52 -28
- package/dist-lib/lib/tools/exec/shell-argv.js +31 -18
- package/dist-lib/lib/tools/exec/shell-guidance.d.ts +6 -1
- package/dist-lib/lib/tools/exec/shell-guidance.js +35 -20
- package/dist-lib/lib/tools/exec/video-tools.js +2 -2
- package/dist-lib/lib/tools/exec.d.ts +6 -8
- package/dist-lib/lib/tools/exec.js +113 -54
- package/dist-lib/lib/tools/file-glob.d.ts +4 -5
- package/dist-lib/lib/tools/file-glob.js +16 -11
- package/dist-lib/lib/tools/fs/glob.js +13 -18
- package/dist-lib/lib/tools/fs/remote-protocol.d.ts +10 -10
- package/dist-lib/lib/tools/fs/remote.d.ts +3 -2
- package/dist-lib/lib/tools/fs/remote.js +13 -7
- package/dist-lib/lib/tools/fs/scope.d.ts +8 -3
- package/dist-lib/lib/tools/fs/scope.js +20 -12
- package/dist-lib/lib/tools/fs/walk.js +6 -3
- package/dist-lib/lib/tools/fs/write.d.ts +3 -2
- package/dist-lib/lib/tools/generate-image.d.ts +11 -9
- package/dist-lib/lib/tools/generate-image.js +73 -37
- package/dist-lib/lib/tools/generate-music.d.ts +22 -11
- package/dist-lib/lib/tools/generate-music.js +79 -48
- package/dist-lib/lib/tools/grep.js +66 -41
- package/dist-lib/lib/tools/http-request/encode-fields.js +18 -9
- package/dist-lib/lib/tools/http-request/{utils.js → request.js} +20 -11
- package/dist-lib/lib/tools/http-request/truncate-response.js +57 -46
- package/dist-lib/lib/tools/http-request.d.ts +1 -1
- package/dist-lib/lib/tools/http-request.js +33 -18
- package/dist-lib/lib/tools/mcp/protocol.d.ts +53 -0
- package/dist-lib/lib/tools/mcp/{utils.js → protocol.js} +45 -23
- package/dist-lib/lib/tools/mcp-call.d.ts +1 -1
- package/dist-lib/lib/tools/mcp-call.js +37 -16
- package/dist-lib/lib/tools/operations/builders.js +10 -6
- package/dist-lib/lib/tools/operations/compile.js +20 -10
- package/dist-lib/lib/tools/operations/decoders.js +12 -6
- package/dist-lib/lib/tools/operations/gmail-message.js +3 -2
- package/dist-lib/lib/tools/outbound-guard.d.ts +4 -3
- package/dist-lib/lib/tools/outbound-guard.js +14 -8
- package/dist-lib/lib/tools/private-ip.js +8 -7
- package/dist-lib/lib/tools/rag-search.js +14 -7
- package/dist-lib/lib/tools/read-files.js +23 -20
- package/dist-lib/lib/tools/skill.js +19 -10
- package/dist-lib/lib/tools/skills/auth-resolver.d.ts +11 -18
- package/dist-lib/lib/tools/skills/auth-resolver.js +30 -18
- package/dist-lib/lib/tools/skills/bin-check.d.ts +3 -2
- package/dist-lib/lib/tools/skills/bin-check.js +10 -3
- package/dist-lib/lib/tools/skills/bundled-dir.js +20 -10
- package/dist-lib/lib/tools/skills/bundled-hash.d.ts +3 -2
- package/dist-lib/lib/tools/skills/bundled-hash.js +6 -1
- package/dist-lib/lib/tools/skills/catalog.d.ts +3 -2
- package/dist-lib/lib/tools/skills/catalog.js +33 -28
- package/dist-lib/lib/tools/skills/cli-argv.d.ts +3 -2
- package/dist-lib/lib/tools/skills/cli-argv.js +55 -52
- package/dist-lib/lib/tools/skills/cli-schema-check.js +21 -10
- package/dist-lib/lib/tools/skills/cli-schema-load.js +28 -20
- package/dist-lib/lib/tools/skills/cli-schema-types.d.ts +6 -6
- package/dist-lib/lib/tools/skills/cli-schema.js +2 -1
- package/dist-lib/lib/tools/skills/credential-check.d.ts +6 -3
- package/dist-lib/lib/tools/skills/credential-check.js +24 -12
- package/dist-lib/lib/tools/skills/credential-grants.js +1 -6
- package/dist-lib/lib/tools/skills/credential-health.d.ts +5 -1
- package/dist-lib/lib/tools/skills/credential-health.js +5 -3
- package/dist-lib/lib/tools/skills/frontmatter-parser.js +10 -5
- package/dist-lib/lib/tools/skills/manifest-parse.js +84 -64
- package/dist-lib/lib/tools/skills/mention.js +7 -6
- package/dist-lib/lib/tools/skills/obsidian-readiness.d.ts +2 -2
- package/dist-lib/lib/tools/skills/obsidian-readiness.js +11 -3
- package/dist-lib/lib/tools/skills/overlay-crud.d.ts +6 -4
- package/dist-lib/lib/tools/skills/overlay-crud.js +12 -6
- package/dist-lib/lib/tools/skills/overlay-dir.js +4 -2
- package/dist-lib/lib/tools/skills/overlay-watch.d.ts +3 -2
- package/dist-lib/lib/tools/skills/overlay-watch.js +8 -4
- package/dist-lib/lib/tools/skills/setup-routes.js +1 -3
- package/dist-lib/lib/tools/skills/skill-settings.js +4 -1
- package/dist-lib/lib/tools/skills/skill-state.d.ts +6 -11
- package/dist-lib/lib/tools/skills/skill-state.js +48 -29
- package/dist-lib/lib/tools/skills/tool-grants.js +6 -3
- package/dist-lib/lib/tools/toolsets.js +2 -1
- package/dist-lib/lib/tools/translate.d.ts +4 -5
- package/dist-lib/lib/tools/translate.js +31 -14
- package/dist-lib/lib/tools/url-guard.js +2 -1
- package/dist-lib/lib/tools/weather-lookup/place.js +8 -4
- package/dist-lib/lib/tools/weather-lookup/report.d.ts +7 -1
- package/dist-lib/lib/tools/weather-lookup/report.js +46 -9
- package/dist-lib/lib/tools/weather-lookup.js +18 -12
- package/dist-lib/lib/tools/web-fetch.js +47 -24
- package/dist-lib/lib/tools/web-search.js +8 -3
- package/dist-lib/lib/validating-lookup.d.ts +4 -4
- package/dist-lib/lib/wav-encode.d.ts +1 -1
- package/dist-lib/lib/wav-encode.js +11 -10
- package/dist-lib/lib/web-fetch/embedded-state.js +24 -12
- package/dist-lib/lib/web-fetch/extract.js +4 -2
- package/dist-lib/lib/web-fetch/images.js +8 -4
- package/dist-lib/lib/web-fetch/video.d.ts +2 -2
- package/dist-lib/lib/web-fetch/video.js +8 -4
- package/dist-lib/lib/web-search/engine-registry.d.ts +2 -2
- package/dist-lib/lib/web-search/engines/aol.js +1 -1
- package/dist-lib/lib/web-search/engines/bing.js +1 -1
- package/dist-lib/lib/web-search/engines/brave.js +4 -1
- package/dist-lib/lib/web-search/engines/duckduckgo.js +3 -2
- package/dist-lib/lib/web-search/engines/google.js +7 -3
- package/dist-lib/lib/web-search/engines/wikipedia.js +5 -4
- package/dist-lib/lib/web-search/engines/yahoo.js +1 -1
- package/dist-lib/lib/web-search/fetch-html.d.ts +5 -4
- package/dist-lib/lib/web-search/fetch-html.js +13 -7
- package/dist-lib/lib/web-search/orchestrator.d.ts +9 -5
- package/dist-lib/lib/web-search/orchestrator.js +3 -3
- package/dist-lib/lib/wire.d.ts +3 -2
- package/dist-lib/lib/wire.js +23 -15
- package/dist-lib/schema/baseline.js +10 -5
- package/dist-lib/schema/build.js +2 -1
- package/dist-lib/schema/harness.d.ts +15 -2
- package/dist-lib/schema/harness.js +39 -2
- package/dist-lib/schema/release-tags.d.ts +3 -2
- package/dist-lib/schema/release-tags.js +6 -3
- package/dist-lib/spec/bind.js +9 -0
- package/dist-lib/spec/calls.js +3 -0
- package/dist-lib/spec/hrpc/hrpc.json +39 -0
- package/dist-lib/spec/hrpc/index.js +39 -3
- package/dist-lib/spec/hrpc/messages.js +105 -8
- package/dist-lib/spec/hyperschema/index.js +105 -8
- package/dist-lib/spec/hyperschema/schema.json +77 -1
- package/dist-lib/spec/hyperschema/types.d.ts +25 -1
- package/package.json +14 -14
- package/worker/harness-sidecar.mjs +15 -22
- package/worker/stow-entry.mjs +7 -4
- package/dist-lib/lib/tools/mcp/utils.d.ts +0 -47
- /package/dist-lib/lib/tools/http-request/{utils.d.ts → request.d.ts} +0 -0
|
@@ -1,4 +1,4 @@
|
|
|
1
|
-
export
|
|
1
|
+
export interface LlmGenerationParams {
|
|
2
2
|
temp?: number;
|
|
3
3
|
top_p?: number;
|
|
4
4
|
top_k?: number;
|
|
@@ -6,5 +6,5 @@ export type LlmGenerationParams = {
|
|
|
6
6
|
repeat_penalty?: number;
|
|
7
7
|
frequency_penalty?: number;
|
|
8
8
|
reasoning_budget: -1 | 0;
|
|
9
|
-
}
|
|
9
|
+
}
|
|
10
10
|
export declare function resolveLlmGenerationParams(modelName: string | undefined, reasoningEnabled: boolean | undefined, deviceDefault?: boolean): LlmGenerationParams | undefined;
|
|
@@ -31,11 +31,13 @@ export function resolveLlmGenerationParams(modelName, reasoningEnabled, deviceDe
|
|
|
31
31
|
const resolver = modelName
|
|
32
32
|
? PRESET_RESOLVERS.find((entry) => modelName.startsWith(entry.prefix))
|
|
33
33
|
: undefined;
|
|
34
|
-
if (resolver)
|
|
34
|
+
if (resolver) {
|
|
35
35
|
return resolver.resolve(reasoningEnabled);
|
|
36
|
+
}
|
|
36
37
|
const effective = reasoningEnabled ?? deviceDefault;
|
|
37
|
-
if (effective === undefined)
|
|
38
|
+
if (effective === undefined) {
|
|
38
39
|
return undefined;
|
|
40
|
+
}
|
|
39
41
|
return { reasoning_budget: effective ? -1 : 0 };
|
|
40
42
|
}
|
|
41
43
|
function qwen08BPreset(reasoningEnabled) {
|
|
@@ -14,7 +14,7 @@ export const QWEN_38_27B = 'Qwen3.8-27B-UD-Q4_K_XL';
|
|
|
14
14
|
export const MEDPSY_1_7B = 'medpsy-1.7b-q4_k_m-imat';
|
|
15
15
|
export const MEDPSY_4B = 'medpsy-4b-q4_k_m-imat';
|
|
16
16
|
export function isCapabilityProfile(value) {
|
|
17
|
-
return CAPABILITY_PROFILE_ORDER.
|
|
17
|
+
return CAPABILITY_PROFILE_ORDER.some((profile) => profile === value);
|
|
18
18
|
}
|
|
19
19
|
export function meetsMinCapabilityProfile(active, required) {
|
|
20
20
|
return CAPABILITY_PROFILE_ORDER.indexOf(active) >= CAPABILITY_PROFILE_ORDER.indexOf(required);
|
|
@@ -41,8 +41,9 @@ const PROFILE_TO_MODEL_NAME = new Map([
|
|
|
41
41
|
]);
|
|
42
42
|
export function capabilityProfileToModelName(profile) {
|
|
43
43
|
const name = PROFILE_TO_MODEL_NAME.get(profile);
|
|
44
|
-
if (!name)
|
|
44
|
+
if (!name) {
|
|
45
45
|
throw new Error(`no model for capability profile ${profile}`);
|
|
46
|
+
}
|
|
46
47
|
return name;
|
|
47
48
|
}
|
|
48
49
|
export const AGENT_MODEL_NAMES = [
|
|
@@ -1,4 +1,6 @@
|
|
|
1
1
|
import type { ModelRegistryEntry, ToolDialect } from '@qvac/sdk';
|
|
2
|
+
import type { ImageModelSet } from '../tools/generate-image.ts';
|
|
3
|
+
import type { MusicModelStages } from '../tools/generate-music.ts';
|
|
2
4
|
import type { ModelAddon } from './model-source.ts';
|
|
3
5
|
export interface SdkModelAsset extends ModelRegistryEntry {
|
|
4
6
|
readonly src: string;
|
|
@@ -24,10 +26,11 @@ export interface CategoryDefault {
|
|
|
24
26
|
export declare const CATEGORY_DEFAULTS: ReadonlyArray<CategoryDefault>;
|
|
25
27
|
export declare function defaultVoiceModel(category: ModelCategory): string;
|
|
26
28
|
export declare function defaultTtsFor(profile: CapabilityProfile): CategoryDefault;
|
|
27
|
-
export
|
|
28
|
-
name: string;
|
|
29
|
-
addon: ModelAddon;
|
|
30
|
-
}
|
|
29
|
+
export interface CatalogModel {
|
|
30
|
+
readonly name: string;
|
|
31
|
+
readonly addon: ModelAddon;
|
|
32
|
+
}
|
|
33
|
+
export declare function infraModelsFor(profile: CapabilityProfile): CatalogModel[];
|
|
31
34
|
export declare function mediaModelNameFor(category: ModelCategory, profile: CapabilityProfile): string;
|
|
32
35
|
export interface DiffusionCatalogEntry {
|
|
33
36
|
readonly choice: ImageModelChoice;
|
|
@@ -62,12 +65,7 @@ export declare const AUDIOGEN_CATALOG: ReadonlyArray<AudioGenCatalogEntry>;
|
|
|
62
65
|
export declare function musicDefaultSteps(choice: string | undefined): number | undefined;
|
|
63
66
|
export declare function musicChoiceForDit(dit: string): MusicModelChoice | undefined;
|
|
64
67
|
export declare function musicSizeBytes(entry: AudioGenCatalogEntry): number;
|
|
65
|
-
export declare function musicModelSet(choice: string | undefined):
|
|
66
|
-
dit: string;
|
|
67
|
-
textEnc: string;
|
|
68
|
-
lm: string;
|
|
69
|
-
vae: string;
|
|
70
|
-
} | null;
|
|
68
|
+
export declare function musicModelSet(choice: string | undefined): MusicModelStages | null;
|
|
71
69
|
export interface AudioGenDownloadMetadata {
|
|
72
70
|
readonly companions: ReadonlyArray<string>;
|
|
73
71
|
readonly assetSizes: Readonly<Record<string, number>>;
|
|
@@ -80,17 +78,9 @@ export interface AgentSkillModelInput {
|
|
|
80
78
|
readonly imageModelChoice?: ImageModelChoice | null;
|
|
81
79
|
readonly musicModelChoice?: MusicModelChoice | null;
|
|
82
80
|
}
|
|
83
|
-
export declare function skillModelsForAgent(agent: AgentSkillModelInput): ReadonlyArray<
|
|
84
|
-
readonly name: string;
|
|
85
|
-
readonly addon: ModelAddon;
|
|
86
|
-
}>;
|
|
81
|
+
export declare function skillModelsForAgent(agent: AgentSkillModelInput): ReadonlyArray<CatalogModel>;
|
|
87
82
|
export declare function diffusionSizeBytes(entry: DiffusionCatalogEntry): number;
|
|
88
|
-
export declare function imageModelFor(choice: string | undefined):
|
|
89
|
-
model: string;
|
|
90
|
-
llmModel?: string | undefined;
|
|
91
|
-
vaeModel?: string | undefined;
|
|
92
|
-
prediction?: 'flux2_flow' | undefined;
|
|
93
|
-
} | null;
|
|
83
|
+
export declare function imageModelFor(choice: string | undefined): ImageModelSet | null;
|
|
94
84
|
export interface ImageClamps {
|
|
95
85
|
maxDim?: number;
|
|
96
86
|
maxSteps?: number;
|
|
@@ -105,6 +95,8 @@ export interface CuratedListable {
|
|
|
105
95
|
}
|
|
106
96
|
export declare function curatedListables(): CuratedListable[];
|
|
107
97
|
export declare function curatedModelAsset(name: string, addon: ModelRegistryEntry['addon']): SdkModelAsset | undefined;
|
|
98
|
+
export declare function modelAddonOf(model: string): ModelRegistryEntry['addon'];
|
|
99
|
+
export declare function residentSrc(model: string, addon: ModelRegistryEntry['addon']): string;
|
|
108
100
|
export declare const CUSTOM_TASK_TYPES: readonly ['llm'];
|
|
109
101
|
export type CustomTaskType = (typeof CUSTOM_TASK_TYPES)[number];
|
|
110
102
|
export interface CustomModelEntry {
|
|
@@ -113,9 +105,12 @@ export interface CustomModelEntry {
|
|
|
113
105
|
readonly projectionSrc?: string;
|
|
114
106
|
readonly taskType?: CustomTaskType;
|
|
115
107
|
readonly expectedSize?: number;
|
|
108
|
+
readonly label?: string;
|
|
109
|
+
readonly contextLength?: number;
|
|
116
110
|
}
|
|
117
111
|
export declare function setCustomModels(entries: ReadonlyArray<CustomModelEntry>): void;
|
|
118
112
|
export declare function customModels(): ReadonlyArray<CustomModelEntry>;
|
|
113
|
+
export declare function customContextLength(name: string): number | undefined;
|
|
119
114
|
export declare function customModelSrc(name: string, addon: ModelRegistryEntry['addon']): string | undefined;
|
|
120
115
|
export declare function customToolDialect(name: string): ToolDialect | undefined;
|
|
121
116
|
export declare function customProjectionMap(): Record<string, string>;
|
|
@@ -56,8 +56,9 @@ export const LLM_CATALOG = [
|
|
|
56
56
|
export function defaultProjectionMap() {
|
|
57
57
|
const map = {};
|
|
58
58
|
for (const entry of LLM_CATALOG) {
|
|
59
|
-
if (entry.projection)
|
|
59
|
+
if (entry.projection) {
|
|
60
60
|
map[entry.name] = entry.projection.src;
|
|
61
|
+
}
|
|
61
62
|
}
|
|
62
63
|
return map;
|
|
63
64
|
}
|
|
@@ -73,13 +74,18 @@ export const CATEGORY_DEFAULTS = [
|
|
|
73
74
|
];
|
|
74
75
|
export function defaultVoiceModel(category) {
|
|
75
76
|
const entry = CATEGORY_DEFAULTS.find((candidate) => candidate.category === category);
|
|
76
|
-
if (!entry)
|
|
77
|
+
if (!entry) {
|
|
77
78
|
throw new Error(`no default model for category ${category}`);
|
|
79
|
+
}
|
|
78
80
|
return entry.asset.src;
|
|
79
81
|
}
|
|
80
82
|
export function defaultTtsFor(profile) {
|
|
81
83
|
const name = defaultTtsModelName(profile);
|
|
82
|
-
|
|
84
|
+
const entry = CATEGORY_DEFAULTS.find((candidate) => candidate.name === name);
|
|
85
|
+
if (!entry) {
|
|
86
|
+
throw new Error(`no default tts model named ${name}`);
|
|
87
|
+
}
|
|
88
|
+
return entry;
|
|
83
89
|
}
|
|
84
90
|
export function infraModelsFor(profile) {
|
|
85
91
|
const tts = defaultTtsFor(profile);
|
|
@@ -87,11 +93,13 @@ export function infraModelsFor(profile) {
|
|
|
87
93
|
return [tts, ...rest].map((entry) => ({ name: entry.name, addon: entry.asset.addon }));
|
|
88
94
|
}
|
|
89
95
|
export function mediaModelNameFor(category, profile) {
|
|
90
|
-
if (category === 'tts')
|
|
96
|
+
if (category === 'tts') {
|
|
91
97
|
return defaultTtsFor(profile).name;
|
|
98
|
+
}
|
|
92
99
|
const entry = CATEGORY_DEFAULTS.find((candidate) => candidate.category === category);
|
|
93
|
-
if (!entry)
|
|
100
|
+
if (!entry) {
|
|
94
101
|
throw new Error(`no default model for category ${category}`);
|
|
102
|
+
}
|
|
95
103
|
return entry.name;
|
|
96
104
|
}
|
|
97
105
|
const IMAGE_GENERATION_SKILL = 'image-generation';
|
|
@@ -123,10 +131,12 @@ export const DIFFUSION_CATALOG = [
|
|
|
123
131
|
];
|
|
124
132
|
function diffusionAssets(entry) {
|
|
125
133
|
const assets = [entry.model];
|
|
126
|
-
if (entry.llmModel)
|
|
134
|
+
if (entry.llmModel) {
|
|
127
135
|
assets.push(entry.llmModel);
|
|
128
|
-
|
|
136
|
+
}
|
|
137
|
+
if (entry.vaeModel) {
|
|
129
138
|
assets.push(entry.vaeModel);
|
|
139
|
+
}
|
|
130
140
|
return assets;
|
|
131
141
|
}
|
|
132
142
|
function diffusionCatalogEntry(model) {
|
|
@@ -142,12 +152,14 @@ export function diffusionDownloadMetadata(model, addon) {
|
|
|
142
152
|
if (addon !== 'diffusion')
|
|
143
153
|
return undefined;
|
|
144
154
|
const entry = diffusionCatalogEntry(model);
|
|
145
|
-
if (!entry)
|
|
155
|
+
if (!entry) {
|
|
146
156
|
return undefined;
|
|
157
|
+
}
|
|
147
158
|
const assets = diffusionAssets(entry);
|
|
148
159
|
const assetSizes = {};
|
|
149
|
-
for (const asset of assets)
|
|
160
|
+
for (const asset of assets) {
|
|
150
161
|
assetSizes[asset.src] = asset.expectedSize;
|
|
162
|
+
}
|
|
151
163
|
return {
|
|
152
164
|
companions: assets.slice(1).map((asset) => asset.src),
|
|
153
165
|
assetSizes
|
|
@@ -202,8 +214,9 @@ export function musicSizeBytes(entry) {
|
|
|
202
214
|
}
|
|
203
215
|
export function musicModelSet(choice) {
|
|
204
216
|
const entry = AUDIOGEN_CATALOG.find((candidate) => candidate.choice === choice);
|
|
205
|
-
if (!entry)
|
|
217
|
+
if (!entry) {
|
|
206
218
|
return null;
|
|
219
|
+
}
|
|
207
220
|
return {
|
|
208
221
|
dit: entry.dit.src,
|
|
209
222
|
textEnc: entry.textEnc.src,
|
|
@@ -215,12 +228,14 @@ export function audioGenDownloadMetadata(model, addon) {
|
|
|
215
228
|
if (addon !== 'audiogen')
|
|
216
229
|
return undefined;
|
|
217
230
|
const entry = AUDIOGEN_CATALOG.find((candidate) => candidate.name === model || candidate.dit.name === model || candidate.dit.src === model);
|
|
218
|
-
if (!entry)
|
|
231
|
+
if (!entry) {
|
|
219
232
|
return undefined;
|
|
233
|
+
}
|
|
220
234
|
const stages = audioGenStages(entry);
|
|
221
235
|
const assetSizes = {};
|
|
222
|
-
for (const asset of stages)
|
|
236
|
+
for (const asset of stages) {
|
|
223
237
|
assetSizes[asset.src] = asset.expectedSize;
|
|
238
|
+
}
|
|
224
239
|
return {
|
|
225
240
|
companions: stages.slice(1).map((asset) => asset.src),
|
|
226
241
|
assetSizes
|
|
@@ -235,14 +250,16 @@ export function skillModelsForAgent(agent) {
|
|
|
235
250
|
if (agentHasSkill(agent, IMAGE_GENERATION_SKILL)) {
|
|
236
251
|
const choice = agent.imageModelChoice ?? DEFAULT_IMAGE_MODEL_CHOICE;
|
|
237
252
|
const entry = DIFFUSION_CATALOG.find((candidate) => candidate.choice === choice);
|
|
238
|
-
if (entry)
|
|
253
|
+
if (entry) {
|
|
239
254
|
models.push({ name: entry.name, addon: entry.model.addon });
|
|
255
|
+
}
|
|
240
256
|
}
|
|
241
257
|
if (agentHasSkill(agent, MUSIC_GENERATION_SKILL)) {
|
|
242
258
|
const choice = agent.musicModelChoice ?? DEFAULT_MUSIC_MODEL_CHOICE;
|
|
243
259
|
const entry = AUDIOGEN_CATALOG.find((candidate) => candidate.choice === choice);
|
|
244
|
-
if (entry)
|
|
260
|
+
if (entry) {
|
|
245
261
|
models.push({ name: entry.name, addon: entry.dit.addon });
|
|
262
|
+
}
|
|
246
263
|
}
|
|
247
264
|
return models;
|
|
248
265
|
}
|
|
@@ -251,13 +268,14 @@ export function diffusionSizeBytes(entry) {
|
|
|
251
268
|
}
|
|
252
269
|
export function imageModelFor(choice) {
|
|
253
270
|
const entry = DIFFUSION_CATALOG.find((candidate) => candidate.choice === choice);
|
|
254
|
-
if (!entry)
|
|
271
|
+
if (!entry) {
|
|
255
272
|
return null;
|
|
273
|
+
}
|
|
256
274
|
return {
|
|
257
275
|
model: entry.model.src,
|
|
258
|
-
|
|
259
|
-
|
|
260
|
-
|
|
276
|
+
llmModel: entry.llmModel?.src,
|
|
277
|
+
vaeModel: entry.vaeModel?.src,
|
|
278
|
+
prediction: entry.prediction
|
|
261
279
|
};
|
|
262
280
|
}
|
|
263
281
|
export function imageClampsFromEnv(env) {
|
|
@@ -267,9 +285,10 @@ export function imageClampsFromEnv(env) {
|
|
|
267
285
|
};
|
|
268
286
|
const maxDim = positive(env.QVAC_IMAGE_MAX_DIM);
|
|
269
287
|
const maxSteps = positive(env.QVAC_IMAGE_MAX_STEPS);
|
|
270
|
-
if (!maxDim && !maxSteps)
|
|
288
|
+
if (!maxDim && !maxSteps) {
|
|
271
289
|
return undefined;
|
|
272
|
-
|
|
290
|
+
}
|
|
291
|
+
return { maxDim, maxSteps };
|
|
273
292
|
}
|
|
274
293
|
export function imageModelFromEnv(env, onIgnoredCompanions, onIgnoredPrediction) {
|
|
275
294
|
const catalog = imageModelFor(env.QVAC_IMAGE_MODEL);
|
|
@@ -279,12 +298,14 @@ export function imageModelFromEnv(env, onIgnoredCompanions, onIgnoredPrediction)
|
|
|
279
298
|
}
|
|
280
299
|
return catalog;
|
|
281
300
|
}
|
|
282
|
-
if (!env.QVAC_IMAGE_MODEL)
|
|
301
|
+
if (!env.QVAC_IMAGE_MODEL) {
|
|
283
302
|
return undefined;
|
|
303
|
+
}
|
|
284
304
|
const prediction = env.QVAC_IMAGE_PREDICTION || undefined;
|
|
285
305
|
const fluxSet = Boolean(env.QVAC_IMAGE_LLM && env.QVAC_IMAGE_VAE);
|
|
286
|
-
if (prediction && !fluxSet)
|
|
306
|
+
if (prediction && !fluxSet) {
|
|
287
307
|
onIgnoredPrediction?.();
|
|
308
|
+
}
|
|
288
309
|
return {
|
|
289
310
|
model: env.QVAC_IMAGE_MODEL,
|
|
290
311
|
llmModel: env.QVAC_IMAGE_LLM || undefined,
|
|
@@ -304,13 +325,20 @@ export function curatedListables() {
|
|
|
304
325
|
...DIFFUSION_CATALOG.map((entry) => ({
|
|
305
326
|
name: entry.name,
|
|
306
327
|
asset: entry.model,
|
|
307
|
-
companions: [entry.llmModel, entry.vaeModel].filter(
|
|
328
|
+
companions: [entry.llmModel, entry.vaeModel].filter((asset) => asset !== undefined)
|
|
308
329
|
}))
|
|
309
330
|
];
|
|
310
331
|
}
|
|
311
332
|
export function curatedModelAsset(name, addon) {
|
|
312
333
|
return curatedListables().find((entry) => entry.asset.addon === addon && (entry.name === name || entry.asset.name === name))?.asset;
|
|
313
334
|
}
|
|
335
|
+
export function modelAddonOf(model) {
|
|
336
|
+
const known = [...curatedListables(), ...musicListables()].find((entry) => entry.name === model || entry.asset.name === model || entry.asset.src === model);
|
|
337
|
+
return known?.asset.addon ?? 'llm';
|
|
338
|
+
}
|
|
339
|
+
export function residentSrc(model, addon) {
|
|
340
|
+
return curatedModelAsset(model, addon)?.src ?? model;
|
|
341
|
+
}
|
|
314
342
|
export const CUSTOM_TASK_TYPES = ['llm'];
|
|
315
343
|
let CUSTOM_MODELS = new Map();
|
|
316
344
|
export function setCustomModels(entries) {
|
|
@@ -319,34 +347,40 @@ export function setCustomModels(entries) {
|
|
|
319
347
|
export function customModels() {
|
|
320
348
|
return [...CUSTOM_MODELS.values()];
|
|
321
349
|
}
|
|
350
|
+
export function customContextLength(name) {
|
|
351
|
+
return CUSTOM_MODELS.get(name)?.contextLength;
|
|
352
|
+
}
|
|
322
353
|
export function customModelSrc(name, addon) {
|
|
323
354
|
const entry = CUSTOM_MODELS.get(name);
|
|
324
355
|
return entry && (entry.taskType ?? 'llm') === addon ? entry.src : undefined;
|
|
325
356
|
}
|
|
326
357
|
export function customToolDialect(name) {
|
|
327
358
|
const entry = CUSTOM_MODELS.get(name);
|
|
328
|
-
return entry
|
|
359
|
+
return entry
|
|
360
|
+
? detectToolDialect(entry.src, entry.label?.replace(/\s+/g, '-') ?? entry.name)
|
|
361
|
+
: undefined;
|
|
329
362
|
}
|
|
330
363
|
export function customProjectionMap() {
|
|
331
364
|
const map = {};
|
|
332
365
|
for (const entry of CUSTOM_MODELS.values()) {
|
|
333
|
-
if (entry.projectionSrc)
|
|
366
|
+
if (entry.projectionSrc) {
|
|
334
367
|
map[entry.name] = entry.projectionSrc;
|
|
368
|
+
}
|
|
335
369
|
}
|
|
336
370
|
return map;
|
|
337
371
|
}
|
|
338
372
|
export function companionRegistryPaths() {
|
|
339
373
|
const map = new Map();
|
|
340
374
|
for (const entry of LLM_CATALOG) {
|
|
341
|
-
if (entry.projection)
|
|
375
|
+
if (entry.projection) {
|
|
342
376
|
map.set(entry.weight.registryPath, [entry.projection.registryPath]);
|
|
377
|
+
}
|
|
343
378
|
}
|
|
344
379
|
for (const entry of DIFFUSION_CATALOG) {
|
|
345
|
-
const companions = [entry.llmModel, entry.vaeModel]
|
|
346
|
-
|
|
347
|
-
.map((asset) => asset.registryPath);
|
|
348
|
-
if (companions.length)
|
|
380
|
+
const companions = [entry.llmModel, entry.vaeModel].flatMap((asset) => asset ? [asset.registryPath] : []);
|
|
381
|
+
if (companions.length) {
|
|
349
382
|
map.set(entry.model.registryPath, companions);
|
|
383
|
+
}
|
|
350
384
|
}
|
|
351
385
|
for (const entry of AUDIOGEN_CATALOG) {
|
|
352
386
|
map.set(entry.dit.registryPath, [
|
|
@@ -360,8 +394,9 @@ export function companionRegistryPaths() {
|
|
|
360
394
|
export function audioGenModelByName(name) {
|
|
361
395
|
for (const entry of AUDIOGEN_CATALOG) {
|
|
362
396
|
for (const stage of [entry.dit, entry.textEnc, entry.lm, entry.vae]) {
|
|
363
|
-
if (stage.name === name || entry.name === name)
|
|
397
|
+
if (stage.name === name || entry.name === name) {
|
|
364
398
|
return name === entry.name ? entry.dit : stage;
|
|
399
|
+
}
|
|
365
400
|
}
|
|
366
401
|
}
|
|
367
402
|
return undefined;
|
|
@@ -1,30 +1,38 @@
|
|
|
1
1
|
import fs from 'fs';
|
|
2
|
-
import {
|
|
2
|
+
import { customDownloads } from './custom-model-cache.js';
|
|
3
3
|
import { curatedListables, customModels, musicListables } from './model-catalog.js';
|
|
4
4
|
export function summarizeDelete(result) {
|
|
5
5
|
return { name: result.name, removed: result.removed.length, freedBytes: result.freedBytes };
|
|
6
6
|
}
|
|
7
7
|
export async function deleteModelFiles(sdk, name, { modelsDir } = {}) {
|
|
8
8
|
const custom = customModels().find((entry) => entry.name === name);
|
|
9
|
-
const
|
|
9
|
+
const { files, dirs } = custom
|
|
10
|
+
? await customDownloads(custom, modelsDir)
|
|
11
|
+
: { files: await catalogFiles(sdk, name), dirs: [] };
|
|
10
12
|
const removed = [];
|
|
11
|
-
for (const filePath of new Set(
|
|
13
|
+
for (const filePath of new Set(files)) {
|
|
12
14
|
const bytes = await onDiskSize(filePath);
|
|
13
|
-
if (bytes === null)
|
|
15
|
+
if (bytes === null) {
|
|
14
16
|
continue;
|
|
17
|
+
}
|
|
15
18
|
await fs.promises.rm(filePath, { force: true });
|
|
16
19
|
removed.push({ path: filePath, bytes });
|
|
17
20
|
}
|
|
21
|
+
for (const dir of dirs) {
|
|
22
|
+
await fs.promises.rm(dir, { recursive: true, force: true });
|
|
23
|
+
}
|
|
18
24
|
return { name, removed, freedBytes: removed.reduce((sum, file) => sum + file.bytes, 0) };
|
|
19
25
|
}
|
|
20
26
|
async function catalogFiles(sdk, name) {
|
|
21
27
|
const paths = [];
|
|
22
28
|
for (const catalogName of namesToPurge(name)) {
|
|
23
29
|
const info = await sdk.getModelInfo({ name: catalogName }).catch(() => null);
|
|
24
|
-
if (!info)
|
|
30
|
+
if (!info) {
|
|
25
31
|
continue;
|
|
26
|
-
|
|
32
|
+
}
|
|
33
|
+
for (const file of info.cacheFiles) {
|
|
27
34
|
paths.push(file.path);
|
|
35
|
+
}
|
|
28
36
|
}
|
|
29
37
|
return paths;
|
|
30
38
|
}
|
|
@@ -41,12 +49,14 @@ function namesToPurge(name) {
|
|
|
41
49
|
const curated = curatedListables().find((entry) => entry.name === name || entry.asset.name === name);
|
|
42
50
|
if (curated) {
|
|
43
51
|
const names = [curated.asset.name, ...curated.companions.map((companion) => companion.name)];
|
|
44
|
-
if (curated.projection)
|
|
52
|
+
if (curated.projection) {
|
|
45
53
|
names.push(curated.projection.name);
|
|
54
|
+
}
|
|
46
55
|
return names;
|
|
47
56
|
}
|
|
48
57
|
const music = musicListables().find((entry) => entry.name === name || entry.asset.name === name);
|
|
49
|
-
if (music)
|
|
58
|
+
if (music) {
|
|
50
59
|
return [music.asset.name, ...music.companions.map((stage) => stage.name)];
|
|
60
|
+
}
|
|
51
61
|
return [name];
|
|
52
62
|
}
|
|
@@ -18,6 +18,7 @@ export interface ModelInfo {
|
|
|
18
18
|
supportsImages: boolean;
|
|
19
19
|
expectedSize: number;
|
|
20
20
|
actualSize?: number;
|
|
21
|
+
label?: string;
|
|
21
22
|
}
|
|
22
23
|
export interface ListModelsOptions {
|
|
23
24
|
type?: ModelType;
|
|
@@ -31,14 +32,18 @@ interface ModelStatus {
|
|
|
31
32
|
expectedSize?: number;
|
|
32
33
|
actualSize?: number;
|
|
33
34
|
}
|
|
34
|
-
export
|
|
35
|
+
export interface ModelStatusCache {
|
|
35
36
|
readonly entries: Map<string, ModelStatus>;
|
|
36
37
|
epoch: number;
|
|
37
|
-
}
|
|
38
|
+
}
|
|
38
39
|
export declare const MODEL_STATUS_TTL_MS = 30000;
|
|
39
40
|
export declare function createModelStatusCache(): ModelStatusCache;
|
|
40
41
|
export declare function invalidateModelStatusCache(cache: ModelStatusCache): void;
|
|
41
|
-
export
|
|
42
|
+
export interface ListModelsRuntime {
|
|
43
|
+
cache?: ModelStatusCache | undefined;
|
|
44
|
+
projectionFor?: ((name: string) => string | undefined) | undefined;
|
|
45
|
+
}
|
|
46
|
+
export declare function listModels(sdk: ModelListSdk, { type, cachedOnly, fullRegistry }?: ListModelsOptions, { cache, projectionFor }?: ListModelsRuntime): Promise<ModelInfo[]>;
|
|
42
47
|
export interface CustomModelRowsContext {
|
|
43
48
|
readonly modelsDir?: string;
|
|
44
49
|
readonly loaded: ReadonlySet<string>;
|
|
@@ -15,8 +15,9 @@ async function mapPool(items, limit, fn) {
|
|
|
15
15
|
const worker = async () => {
|
|
16
16
|
while (true) {
|
|
17
17
|
const i = cursor++;
|
|
18
|
-
if (i >= items.length)
|
|
18
|
+
if (i >= items.length) {
|
|
19
19
|
return;
|
|
20
|
+
}
|
|
20
21
|
results[i] = await fn(items[i]);
|
|
21
22
|
}
|
|
22
23
|
};
|
|
@@ -46,13 +47,14 @@ async function musicRows(hydrate) {
|
|
|
46
47
|
}
|
|
47
48
|
return rows;
|
|
48
49
|
}
|
|
49
|
-
export async function listModels(sdk, { type, cachedOnly, fullRegistry } = {}, cache, projectionFor) {
|
|
50
|
+
export async function listModels(sdk, { type, cachedOnly, fullRegistry } = {}, { cache, projectionFor } = {}) {
|
|
50
51
|
const now = Date.now();
|
|
51
52
|
const seesImages = (name, addon) => addon === 'llm' && Boolean(projectionFor?.(name));
|
|
52
53
|
const hydrate = async (registryPath, catalogName) => {
|
|
53
54
|
const hit = cache?.entries.get(registryPath);
|
|
54
|
-
if (hit && now - hit.at < MODEL_STATUS_TTL_MS)
|
|
55
|
+
if (hit && now - hit.at < MODEL_STATUS_TTL_MS) {
|
|
55
56
|
return hit;
|
|
57
|
+
}
|
|
56
58
|
const epoch = cache?.epoch;
|
|
57
59
|
const info = catalogName
|
|
58
60
|
? await sdk.getModelInfo({ name: catalogName }).catch(() => null)
|
|
@@ -64,8 +66,9 @@ export async function listModels(sdk, { type, cachedOnly, fullRegistry } = {}, c
|
|
|
64
66
|
expectedSize: info?.expectedSize,
|
|
65
67
|
actualSize: info?.actualSize
|
|
66
68
|
};
|
|
67
|
-
if (cache && cache.epoch === epoch)
|
|
69
|
+
if (cache && cache.epoch === epoch) {
|
|
68
70
|
cache.entries.set(registryPath, status);
|
|
71
|
+
}
|
|
69
72
|
return status;
|
|
70
73
|
};
|
|
71
74
|
if (!fullRegistry) {
|
|
@@ -99,8 +102,9 @@ export async function listModels(sdk, { type, cachedOnly, fullRegistry } = {}, c
|
|
|
99
102
|
}
|
|
100
103
|
const entries = await sdk.modelRegistrySearch(type ? { addon: type } : {});
|
|
101
104
|
const catalog = new Map();
|
|
102
|
-
for (const c of sdk.models)
|
|
105
|
+
for (const c of sdk.models) {
|
|
103
106
|
catalog.set(c.registryPath, c.name);
|
|
107
|
+
}
|
|
104
108
|
const rows = await mapPool(entries, STATUS_CONCURRENCY, async (entry) => {
|
|
105
109
|
const status = await hydrate(entry.registryPath, catalog.get(entry.registryPath));
|
|
106
110
|
const companions = COMPANIONS_BY_WEIGHT.get(entry.registryPath) ?? [];
|
|
@@ -134,7 +138,8 @@ export async function customModelRows({ type, cachedOnly }, { modelsDir, loaded
|
|
|
134
138
|
isCached: await isCustomModelCached(entry, modelsDir),
|
|
135
139
|
isLoaded: loaded.has(entry.name),
|
|
136
140
|
supportsImages: addon === 'llm' && Boolean(entry.projectionSrc),
|
|
137
|
-
expectedSize: entry.expectedSize ?? 0
|
|
141
|
+
expectedSize: entry.expectedSize ?? 0,
|
|
142
|
+
label: entry.label
|
|
138
143
|
};
|
|
139
144
|
}));
|
|
140
145
|
return cachedOnly ? rows.filter((row) => row.isCached) : rows;
|
|
@@ -66,7 +66,16 @@ export interface LoadedModel {
|
|
|
66
66
|
model: string;
|
|
67
67
|
refs: number;
|
|
68
68
|
}
|
|
69
|
-
|
|
69
|
+
interface PuddleEntry {
|
|
70
|
+
readonly id: string;
|
|
71
|
+
readonly refs: number;
|
|
72
|
+
readonly value: ModelHandle;
|
|
73
|
+
}
|
|
74
|
+
declare class ModelPuddle extends ResourcePuddle<string, ModelHandle> {
|
|
75
|
+
readonly resources: Map<string, PuddleEntry>;
|
|
76
|
+
}
|
|
77
|
+
type PoolLike = ModelPuddle;
|
|
78
|
+
export declare function modelOf(key: string): string;
|
|
70
79
|
export declare function releaseModel(pool: PoolLike, key: string): void;
|
|
71
80
|
export declare function loadedModels(pool: PoolLike): LoadedModel[];
|
|
72
81
|
export interface ResidentLease {
|
|
@@ -78,10 +87,21 @@ export declare function leaseResidentModel(pool: PoolLike, wanted?: (model: stri
|
|
|
78
87
|
export declare function isResident(pool: PoolLike, key: string): boolean;
|
|
79
88
|
export declare function leaseCount(pool: PoolLike, key: string): number;
|
|
80
89
|
export declare function evictIdle(pool: PoolLike): Promise<void>;
|
|
81
|
-
export declare function
|
|
82
|
-
|
|
83
|
-
|
|
84
|
-
|
|
90
|
+
export declare function evictIdleWhere(pool: PoolLike, wanted: (key: string) => boolean): Promise<void>;
|
|
91
|
+
export interface DeadlineOptions {
|
|
92
|
+
deadlineMs: number;
|
|
93
|
+
tickMs?: number;
|
|
94
|
+
}
|
|
95
|
+
export interface ModelCapacityOptions extends DeadlineOptions {
|
|
96
|
+
cap: number;
|
|
97
|
+
signal?: {
|
|
98
|
+
aborted?: boolean;
|
|
99
|
+
} | undefined;
|
|
100
|
+
evictable?: (key: string) => boolean;
|
|
101
|
+
}
|
|
102
|
+
export declare function awaitModelCapacity(pool: PoolLike, { cap, deadlineMs, tickMs, signal, evictable }: ModelCapacityOptions): Promise<boolean>;
|
|
103
|
+
export declare function evictModelWithin(pool: PoolLike, key: string, options: DeadlineOptions): Promise<boolean>;
|
|
104
|
+
export declare function evictModel(pool: PoolLike, model: string, options: DeadlineOptions): Promise<boolean>;
|
|
85
105
|
export type LoadSdk = () => Promise<ModelLifecycleSdk>;
|
|
86
106
|
export type EmbedLifecycleSdk = Pick<SdkModule, 'unloadModel' | 'modelRegistrySearch'> & Partial<CancelSdk> & {
|
|
87
107
|
loadModel(params: {
|
|
@@ -104,11 +124,22 @@ interface LoadClockGuardOptions {
|
|
|
104
124
|
sampleMs?: number;
|
|
105
125
|
jumpMs?: number;
|
|
106
126
|
}
|
|
107
|
-
|
|
127
|
+
interface LoadClockGuard {
|
|
108
128
|
race: (pending: TrackedLoad) => Promise<string>;
|
|
109
|
-
}
|
|
110
|
-
export declare function
|
|
111
|
-
export
|
|
129
|
+
}
|
|
130
|
+
export declare function loadClockGuard(model: string, sdk: Partial<CancelSdk>, { now, monoMs, sampleMs, jumpMs }?: LoadClockGuardOptions): LoadClockGuard;
|
|
131
|
+
export interface ModelPoolOptions {
|
|
132
|
+
deviceConfig?: LlmDeviceConfig;
|
|
133
|
+
loads?: LoadTracker;
|
|
134
|
+
}
|
|
135
|
+
export declare function createModelPool(loadSdk: LoadSdk, notify: NotifyFn, { deviceConfig, loads }?: ModelPoolOptions): ModelPuddle;
|
|
136
|
+
export interface EmbedPoolOptions {
|
|
137
|
+
faults: GpuFaultState;
|
|
138
|
+
batchSize?: number;
|
|
139
|
+
openclCacheDir?: (() => string | undefined) | undefined;
|
|
140
|
+
loads?: LoadTracker;
|
|
141
|
+
}
|
|
142
|
+
export declare function createEmbedPool(loadSdk: LoadEmbedSdk, notify: NotifyFn, { faults, batchSize, openclCacheDir, loads }: EmbedPoolOptions): ModelPuddle;
|
|
112
143
|
export type VoiceLifecycleSdk = Pick<SdkModule, 'unloadModel' | 'modelRegistrySearch'> & Partial<CancelSdk> & {
|
|
113
144
|
loadModel(params: {
|
|
114
145
|
modelSrc: ModelSrc;
|
|
@@ -118,5 +149,12 @@ export type VoiceLifecycleSdk = Pick<SdkModule, 'unloadModel' | 'modelRegistrySe
|
|
|
118
149
|
}): TrackedLoad;
|
|
119
150
|
};
|
|
120
151
|
export type LoadVoiceSdk = () => Promise<VoiceLifecycleSdk>;
|
|
121
|
-
export
|
|
152
|
+
export interface VoicePoolOptions {
|
|
153
|
+
modelType: string;
|
|
154
|
+
addon: ModelAddon;
|
|
155
|
+
modelConfig?: Record<string, unknown> | undefined;
|
|
156
|
+
openclCacheDir?: (() => string | undefined) | undefined;
|
|
157
|
+
loads?: LoadTracker;
|
|
158
|
+
}
|
|
159
|
+
export declare function createVoicePool(loadSdk: LoadVoiceSdk, notify: NotifyFn, { modelType, addon, modelConfig, openclCacheDir, loads }: VoicePoolOptions): ModelPuddle;
|
|
122
160
|
export {};
|