dsh-plugin-local-infer 0.1.2 → 0.1.4
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/README.md +32 -6
- package/cordis.patch.yml +7 -0
- package/docs/zh/README.md +24 -4
- package/dsh/client.js +4200 -4049
- package/package.json +33 -11
- package/packages/core/lib/adapter.d.ts +177 -11
- package/packages/core/lib/adapter.js +74 -1
- package/packages/core/lib/config.d.ts +1 -1
- package/packages/core/lib/config.js +1 -1
- package/packages/core/lib/debug.d.ts +1 -1
- package/packages/core/lib/debug.js +1 -1
- package/packages/core/lib/defaults.d.ts +1 -1
- package/packages/core/lib/defaults.js +1 -1
- package/packages/core/lib/deps.d.ts +48 -20
- package/packages/core/lib/deps.js +24 -8
- package/packages/core/lib/estimator.d.ts +1 -1
- package/packages/core/lib/estimator.js +1 -1
- package/packages/core/lib/guideline.d.ts +1 -1
- package/packages/core/lib/guideline.js +1 -1
- package/packages/core/lib/hardware.d.ts +1 -1
- package/packages/core/lib/hardware.js +1 -1
- package/packages/core/lib/hf-cache.d.ts +70 -0
- package/packages/core/lib/hf-cache.js +83 -0
- package/packages/core/lib/index.d.ts +16 -9
- package/packages/core/lib/index.js +10 -6
- package/packages/core/lib/infer-cache.d.ts +39 -0
- package/packages/core/lib/infer-cache.js +53 -0
- package/packages/core/lib/launch-command.d.ts +8 -4
- package/packages/core/lib/launch-command.js +13 -6
- package/packages/core/lib/launch-record.d.ts +1 -1
- package/packages/core/lib/launch-record.js +1 -1
- package/packages/core/lib/logs.d.ts +8 -1
- package/packages/core/lib/logs.js +12 -4
- package/packages/core/lib/models.d.ts +120 -14
- package/packages/core/lib/models.js +209 -17
- package/packages/core/lib/parameter.d.ts +31 -3
- package/packages/core/lib/parameter.js +1 -1
- package/packages/core/lib/progress.d.ts +54 -0
- package/packages/core/lib/progress.js +120 -0
- package/packages/core/lib/registrar.d.ts +25 -14
- package/packages/core/lib/registrar.js +30 -10
- package/packages/core/lib/reserve.d.ts +11 -3
- package/packages/core/lib/reserve.js +6 -4
- package/packages/core/lib/status.d.ts +12 -6
- package/packages/core/lib/status.js +21 -10
- package/packages/core/lib/sudo.d.ts +80 -0
- package/packages/core/lib/sudo.js +78 -0
- package/packages/core/package.json +1 -1
- package/packages/orchestrator/lib/config.d.ts +63 -0
- package/packages/orchestrator/lib/config.js +111 -0
- package/packages/orchestrator/lib/index.d.ts +51 -0
- package/packages/orchestrator/lib/index.js +73 -0
- package/packages/orchestrator/lib/route.d.ts +60 -0
- package/packages/orchestrator/lib/route.js +159 -0
- package/packages/orchestrator/locale/en.json +6 -0
- package/packages/orchestrator/package.json +39 -0
- package/packages/orchestrator/prompt.md +87 -0
- package/packages/providers/lib/acquire.d.ts +95 -15
- package/packages/providers/lib/acquire.js +239 -40
- package/packages/providers/lib/adapters.d.ts +155 -221
- package/packages/providers/lib/adapters.js +589 -935
- package/packages/providers/lib/debug.d.ts +1 -1
- package/packages/providers/lib/debug.js +1 -1
- package/packages/providers/lib/deps.d.ts +31 -212
- package/packages/providers/lib/deps.js +71 -205
- package/packages/providers/lib/engines/basalt/basalt.d.ts +130 -0
- package/packages/providers/lib/engines/basalt/basalt.js +304 -0
- package/packages/providers/lib/engines/basalt/basaltAdapter.d.ts +85 -0
- package/packages/providers/lib/engines/basalt/basaltAdapter.js +439 -0
- package/packages/providers/lib/engines/basalt/basaltLinux.d.ts +23 -0
- package/packages/providers/lib/engines/basalt/basaltLinux.js +47 -0
- package/packages/providers/lib/engines/basalt/basaltMacOS.d.ts +17 -0
- package/packages/providers/lib/engines/basalt/basaltMacOS.js +19 -0
- package/packages/providers/lib/engines/basalt/basaltWindows.d.ts +24 -0
- package/packages/providers/lib/engines/basalt/basaltWindows.js +49 -0
- package/packages/providers/lib/engines/engineOs.d.ts +24 -0
- package/packages/providers/lib/engines/engineOs.js +17 -0
- package/packages/providers/lib/{hyperqwen.d.ts → engines/hyperqwen/hyperqwen.d.ts} +2 -2
- package/packages/providers/lib/{hyperqwen.js → engines/hyperqwen/hyperqwen.js} +14 -2
- package/packages/providers/lib/engines/hyperqwen/hyperqwenAdapter.d.ts +38 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenAdapter.js +115 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenArch.d.ts +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenArch.js +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenDebian.d.ts +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenDebian.js +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenFedora.d.ts +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenFedora.js +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenLinux.d.ts +10 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenLinux.js +14 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenMacOS.d.ts +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenMacOS.js +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenWindows.d.ts +9 -0
- package/packages/providers/lib/engines/hyperqwen/hyperqwenWindows.js +9 -0
- package/packages/providers/lib/{infernix.d.ts → engines/infernix/infernix.d.ts} +7 -4
- package/packages/providers/lib/{infernix.js → engines/infernix/infernix.js} +53 -8
- package/packages/providers/lib/engines/infernix/infernixAdapter.d.ts +52 -0
- package/packages/providers/lib/engines/infernix/infernixAdapter.js +235 -0
- package/packages/providers/lib/engines/infernix/infernixArch.d.ts +9 -0
- package/packages/providers/lib/engines/infernix/infernixArch.js +9 -0
- package/packages/providers/lib/engines/infernix/infernixDebian.d.ts +9 -0
- package/packages/providers/lib/engines/infernix/infernixDebian.js +9 -0
- package/packages/providers/lib/engines/infernix/infernixFedora.d.ts +9 -0
- package/packages/providers/lib/engines/infernix/infernixFedora.js +9 -0
- package/packages/providers/lib/engines/infernix/infernixLinux.d.ts +17 -0
- package/packages/providers/lib/engines/infernix/infernixLinux.js +35 -0
- package/packages/providers/lib/engines/infernix/infernixMacOS.d.ts +16 -0
- package/packages/providers/lib/engines/infernix/infernixMacOS.js +18 -0
- package/packages/providers/lib/engines/infernix/infernixWindows.d.ts +16 -0
- package/packages/providers/lib/engines/infernix/infernixWindows.js +34 -0
- package/packages/providers/lib/{llamacpp.d.ts → engines/llamacpp/llamacpp.d.ts} +2 -2
- package/packages/providers/lib/{llamacpp.js → engines/llamacpp/llamacpp.js} +12 -2
- package/packages/providers/lib/engines/llamacpp/llamacppAdapter.d.ts +50 -0
- package/packages/providers/lib/engines/llamacpp/llamacppAdapter.js +274 -0
- package/packages/providers/lib/engines/llamacpp/llamacppArch.d.ts +9 -0
- package/packages/providers/lib/engines/llamacpp/llamacppArch.js +9 -0
- package/packages/providers/lib/engines/llamacpp/llamacppDebian.d.ts +9 -0
- package/packages/providers/lib/engines/llamacpp/llamacppDebian.js +9 -0
- package/packages/providers/lib/engines/llamacpp/llamacppFedora.d.ts +9 -0
- package/packages/providers/lib/engines/llamacpp/llamacppFedora.js +9 -0
- package/packages/providers/lib/engines/llamacpp/llamacppLinux.d.ts +17 -0
- package/packages/providers/lib/engines/llamacpp/llamacppLinux.js +28 -0
- package/packages/providers/lib/engines/llamacpp/llamacppMacOS.d.ts +15 -0
- package/packages/providers/lib/engines/llamacpp/llamacppMacOS.js +17 -0
- package/packages/providers/lib/engines/llamacpp/llamacppWindows.d.ts +15 -0
- package/packages/providers/lib/engines/llamacpp/llamacppWindows.js +26 -0
- package/packages/providers/lib/{ninfer.d.ts → engines/ninfer/ninfer.d.ts} +2 -2
- package/packages/providers/lib/{ninfer.js → engines/ninfer/ninfer.js} +25 -3
- package/packages/providers/lib/engines/ninfer/ninferAdapter.d.ts +81 -0
- package/packages/providers/lib/engines/ninfer/ninferAdapter.js +392 -0
- package/packages/providers/lib/engines/ninfer/ninferArch.d.ts +9 -0
- package/packages/providers/lib/engines/ninfer/ninferArch.js +9 -0
- package/packages/providers/lib/engines/ninfer/ninferDebian.d.ts +9 -0
- package/packages/providers/lib/engines/ninfer/ninferDebian.js +9 -0
- package/packages/providers/lib/engines/ninfer/ninferFedora.d.ts +9 -0
- package/packages/providers/lib/engines/ninfer/ninferFedora.js +9 -0
- package/packages/providers/lib/engines/ninfer/ninferLinux.d.ts +17 -0
- package/packages/providers/lib/engines/ninfer/ninferLinux.js +37 -0
- package/packages/providers/lib/engines/ninfer/ninferMacOS.d.ts +15 -0
- package/packages/providers/lib/engines/ninfer/ninferMacOS.js +17 -0
- package/packages/providers/lib/engines/ninfer/ninferWindows.d.ts +29 -0
- package/packages/providers/lib/engines/ninfer/ninferWindows.js +59 -0
- package/packages/providers/lib/engines/strata/strata.d.ts +1 -0
- package/packages/providers/lib/engines/strata/strata.js +264 -0
- package/packages/providers/lib/engines/strata/strataAdapter.d.ts +97 -0
- package/packages/providers/lib/engines/strata/strataAdapter.js +463 -0
- package/packages/providers/lib/engines/strata/strataArch.d.ts +9 -0
- package/packages/providers/lib/engines/strata/strataArch.js +9 -0
- package/packages/providers/lib/engines/strata/strataDebian.d.ts +9 -0
- package/packages/providers/lib/engines/strata/strataDebian.js +9 -0
- package/packages/providers/lib/engines/strata/strataFedora.d.ts +9 -0
- package/packages/providers/lib/engines/strata/strataFedora.js +9 -0
- package/packages/providers/lib/engines/strata/strataLinux.d.ts +21 -0
- package/packages/providers/lib/engines/strata/strataLinux.js +30 -0
- package/packages/providers/lib/engines/strata/strataMacOS.d.ts +16 -0
- package/packages/providers/lib/engines/strata/strataMacOS.js +17 -0
- package/packages/providers/lib/engines/strata/strataWindows.d.ts +27 -0
- package/packages/providers/lib/engines/strata/strataWindows.js +37 -0
- package/packages/providers/lib/engines.d.ts +8 -5
- package/packages/providers/lib/engines.js +22 -11
- package/packages/providers/lib/guidelines.d.ts +5 -4
- package/packages/providers/lib/guidelines.js +18 -5
- package/packages/providers/lib/index.d.ts +33 -24
- package/packages/providers/lib/index.js +46 -24
- package/packages/providers/lib/model-defaults.d.ts +10 -5
- package/packages/providers/lib/model-defaults.js +47 -5
- package/packages/providers/lib/platform.d.ts +8 -5
- package/packages/providers/lib/platform.js +27 -7
- package/packages/providers/lib/presets.d.ts +6 -4
- package/packages/providers/lib/presets.js +53 -5
- package/packages/providers/lib/systemDeps.d.ts +313 -0
- package/packages/providers/lib/systemDeps.js +284 -0
- package/packages/providers/lib/vram.d.ts +34 -8
- package/packages/providers/lib/vram.js +81 -8
- package/packages/providers/package.json +2 -2
- package/packages/service/lib/index.d.ts +187 -23
- package/packages/service/lib/index.js +667 -90
- package/packages/service/lib/launch-target.d.ts +19 -0
- package/packages/service/lib/launch-target.js +28 -0
- package/packages/service/lib/run-logs.d.ts +72 -0
- package/packages/service/lib/run-logs.js +125 -0
- package/packages/service/lib/types.d.ts +166 -8
- package/packages/service/lib/types.js +1 -1
- package/packages/service/package.json +2 -2
- package/packages/tool/lib/index.d.ts +1 -1
- package/packages/tool/lib/index.js +1 -1
- package/packages/tool/package.json +2 -2
- package/packages/ui/lib/config.d.ts +89 -0
- package/packages/ui/lib/config.js +251 -0
- package/packages/ui/lib/deps.d.ts +4 -4
- package/packages/ui/lib/deps.js +1 -1
- package/packages/ui/lib/form.d.ts +1 -1
- package/packages/ui/lib/form.js +1 -1
- package/packages/ui/lib/index.d.ts +7 -1
- package/packages/ui/lib/index.js +12 -2
- package/packages/ui/lib/meter.d.ts +1 -1
- package/packages/ui/lib/meter.js +1 -1
- package/packages/ui/lib/ops/engine.d.ts +216 -0
- package/packages/ui/lib/ops/engine.js +697 -0
- package/packages/ui/lib/ops/get-steps.d.ts +98 -0
- package/packages/ui/lib/ops/get-steps.js +359 -0
- package/packages/ui/lib/ops/hf.d.ts +42 -0
- package/packages/ui/lib/ops/hf.js +150 -0
- package/packages/ui/lib/ops/logs.d.ts +78 -0
- package/packages/ui/lib/ops/logs.js +119 -0
- package/packages/ui/lib/ops/model.d.ts +71 -0
- package/packages/ui/lib/ops/model.js +123 -0
- package/packages/ui/lib/request.d.ts +106 -0
- package/packages/ui/lib/request.js +80 -0
- package/packages/ui/lib/route.d.ts +106 -422
- package/packages/ui/lib/route.js +136 -1845
- package/packages/ui/lib/routes/chat-template.d.ts +1 -0
- package/packages/ui/lib/routes/chat-template.js +1 -0
- package/packages/ui/lib/routes/deps.d.ts +1 -0
- package/packages/ui/lib/routes/deps.js +1 -0
- package/packages/ui/lib/routes/download.d.ts +1 -0
- package/packages/ui/lib/routes/download.js +1 -0
- package/packages/ui/lib/routes/get.d.ts +1 -0
- package/packages/ui/lib/routes/get.js +106 -0
- package/packages/ui/lib/routes/install.d.ts +16 -0
- package/packages/ui/lib/routes/install.js +36 -0
- package/packages/ui/lib/routes/launch.d.ts +24 -0
- package/packages/ui/lib/routes/launch.js +74 -0
- package/packages/ui/lib/routes/logs.d.ts +57 -0
- package/packages/ui/lib/routes/logs.js +117 -0
- package/packages/ui/lib/routes/provider-delete.d.ts +15 -0
- package/packages/ui/lib/routes/provider-delete.js +37 -0
- package/packages/ui/lib/routes/register.d.ts +16 -0
- package/packages/ui/lib/routes/register.js +28 -0
- package/packages/ui/lib/routes/save.d.ts +18 -0
- package/packages/ui/lib/routes/save.js +159 -0
- package/packages/ui/lib/routes/stop.d.ts +19 -0
- package/packages/ui/lib/routes/stop.js +32 -0
- package/packages/ui/lib/routes/stream.d.ts +40 -0
- package/packages/ui/lib/routes/stream.js +68 -0
- package/packages/ui/lib/routes/summary.d.ts +15 -0
- package/packages/ui/lib/routes/summary.js +26 -0
- package/packages/ui/lib/routes/unregister.d.ts +14 -0
- package/packages/ui/lib/routes/unregister.js +26 -0
- package/packages/ui/lib/viewmodels/deps.d.ts +1 -0
- package/packages/ui/lib/viewmodels/deps.js +1 -0
- package/packages/ui/lib/viewmodels/depsHelpers.d.ts +1 -0
- package/packages/ui/lib/viewmodels/depsHelpers.js +94 -0
- package/packages/ui/lib/viewmodels/summary.d.ts +145 -0
- package/packages/ui/lib/viewmodels/summary.js +245 -0
- package/packages/ui/lib/viewmodels/summaryHelpers.d.ts +30 -0
- package/packages/ui/lib/viewmodels/summaryHelpers.js +42 -0
- package/packages/ui/lib/warnings.d.ts +1 -1
- package/packages/ui/lib/warnings.js +1 -1
- package/packages/ui/package.json +4 -4
- package/packages/providers/lib/strata.d.ts +0 -15
- package/packages/providers/lib/strata.js +0 -14
|
@@ -14,6 +14,14 @@ export interface DefaultModel {
|
|
|
14
14
|
url: string;
|
|
15
15
|
file?: string;
|
|
16
16
|
}
|
|
17
|
+
/**
|
|
18
|
+
* ModelDownloadSource is the half of a DefaultModel the presence check, the
|
|
19
|
+
* hf CLI command, and the hub-cache lookup read: the Hugging Face repo URL
|
|
20
|
+
* and the optional artifact file. A full list entry satisfies it, and an
|
|
21
|
+
* adapter that only resolves the download pair composes just these fields
|
|
22
|
+
* instead of restating the entry's inert registry data.
|
|
23
|
+
*/
|
|
24
|
+
export type ModelDownloadSource = Pick<DefaultModel, 'url' | 'file'>;
|
|
17
25
|
/**
|
|
18
26
|
* repoIdFromUrl turns a Hugging Face repo URL into the `owner/name` repo id
|
|
19
27
|
* the hf CLI takes. A URL with no owner/name pair reads as an empty id, which
|
|
@@ -27,18 +35,57 @@ export declare function repoIdFromUrl(url: string): string;
|
|
|
27
35
|
*/
|
|
28
36
|
export declare function repoNameFromUrl(url: string): string;
|
|
29
37
|
/**
|
|
30
|
-
*
|
|
31
|
-
*
|
|
32
|
-
* directory
|
|
38
|
+
* hubCacheModelDirectory is the per-model directory the hf CLI creates in the
|
|
39
|
+
* hub cache for one repo id: `models--{namespace}--{name}`. A repo id without
|
|
40
|
+
* an owner/name pair reads as an empty directory name, which the callers
|
|
41
|
+
* handle as an absent model.
|
|
42
|
+
*/
|
|
43
|
+
export declare function hubCacheModelDirectory(repoId: string): string;
|
|
44
|
+
/**
|
|
45
|
+
* isModelDirectoryOverridden reports whether a model directory field (the
|
|
46
|
+
* config's or a download request's) names a path (a non-blank string), the
|
|
47
|
+
* one rule every download route and view model shares to decide the layout:
|
|
48
|
+
* a named directory targets that directory flat (`--local-dir`), an unnamed
|
|
49
|
+
* one takes the hub-cache layout (no `--local-dir`, the
|
|
50
|
+
* `models--{ns}--{name}` directories the hf CLI writes into the hub cache).
|
|
51
|
+
* The predicate form lets callers narrow the field to a string without
|
|
52
|
+
* restating the blank check.
|
|
53
|
+
*/
|
|
54
|
+
export declare function isModelDirectoryOverridden(modelDirectory: unknown): modelDirectory is string;
|
|
55
|
+
/**
|
|
56
|
+
* modelArtifactPath is the path a model download's artifact lands at in the
|
|
57
|
+
* model directory: the entry's artifact file when it names one, else the
|
|
58
|
+
* repo-name directory a whole-repo download leaves behind. With the hub-cache
|
|
59
|
+
* layout (`useHubCache`), it resolves into the per-model cache directory's
|
|
60
|
+
* `blobs` folder, the content-addressed store the hf CLI writes without
|
|
61
|
+
* `--local-dir`; the `directory` is then the hub cache root, not the per-model
|
|
62
|
+
* folder. Every presence decision (the card-facing checks and the engines'
|
|
63
|
+
* deploy re-fetch gates) resolves the deterministic snapshot instead
|
|
64
|
+
* (modelArtifactPresent); the hub-cache form here stays the blobs-store path.
|
|
33
65
|
*/
|
|
34
|
-
export declare function modelArtifactPath(entry:
|
|
66
|
+
export declare function modelArtifactPath(entry: ModelDownloadSource, directory: string, useHubCache?: boolean): string;
|
|
35
67
|
/**
|
|
36
|
-
*
|
|
37
|
-
* repo, the
|
|
38
|
-
* target
|
|
39
|
-
*
|
|
68
|
+
* hfDownloadFileCommand renders the hf CLI download for one repo and file
|
|
69
|
+
* pair: the repo, the file (omitted when blank, a whole-repo download), the
|
|
70
|
+
* `--local-dir` target when the hub-cache layout does not apply, and the
|
|
71
|
+
* `--format human` flag. The flag overrides the non-TTY default (`auto` picks
|
|
72
|
+
* `agent`, which prints no progress) so the hf CLI prints tqdm progress
|
|
73
|
+
* lines to stderr, which the progress streaming tasks consume. The string is
|
|
74
|
+
* the single source every hf download command renders through: the model and
|
|
75
|
+
* chat-template builders below, and the Infernix extra-download commands the
|
|
76
|
+
* Get step streams.
|
|
40
77
|
*/
|
|
41
|
-
export declare function
|
|
78
|
+
export declare function hfDownloadFileCommand(repo: string, file: string, directory: string, useHubCache?: boolean): string;
|
|
79
|
+
/**
|
|
80
|
+
* hfDownloadCommand renders the hf CLI download for one model download
|
|
81
|
+
* source: the repo, the artifact file when the entry names one, and the
|
|
82
|
+
* `--local-dir` target. With the hub-cache layout (`useHubCache`), the `--local-dir` is
|
|
83
|
+
* dropped so the hf CLI writes into the hub cache's `models--{ns}--{name}`
|
|
84
|
+
* directory (the content-addressed `blobs/` plus the `snapshots/`). The
|
|
85
|
+
* string is the single source the download route runs and the card shows
|
|
86
|
+
* beside its Download button, rendered through hfDownloadFileCommand.
|
|
87
|
+
*/
|
|
88
|
+
export declare function hfDownloadCommand(entry: ModelDownloadSource, directory: string, useHubCache?: boolean): string;
|
|
42
89
|
/**
|
|
43
90
|
* The chat template file the hf CLI pulls into the model directory. The
|
|
44
91
|
* NInfer deploy step and the template download route both target this name, so
|
|
@@ -48,11 +95,50 @@ export declare const CHAT_TEMPLATE_FILE = "chat_template.jinja";
|
|
|
48
95
|
/**
|
|
49
96
|
* hfChatTemplateCommand renders the hf CLI download for one chat template repo
|
|
50
97
|
* reference into the model directory: the repo, the template file, and the
|
|
51
|
-
* `--local-dir` target.
|
|
52
|
-
*
|
|
53
|
-
*
|
|
98
|
+
* `--local-dir` target. With the hub-cache layout (`useHubCache`), the
|
|
99
|
+
* `--local-dir` is dropped so the template lands in the hub cache's
|
|
100
|
+
* `models--{ns}--{name}` directory. The string is the single source the
|
|
101
|
+
* template download route runs and the card shows beside its Download button
|
|
102
|
+
* and in the System dependencies box when the auto-download is unavailable,
|
|
103
|
+
* rendered through hfDownloadFileCommand.
|
|
54
104
|
*/
|
|
55
|
-
export declare function hfChatTemplateCommand(repo: string, directory: string): string;
|
|
105
|
+
export declare function hfChatTemplateCommand(repo: string, directory: string, useHubCache?: boolean): string;
|
|
106
|
+
/**
|
|
107
|
+
* chatTemplateArtifactPath is the path the flat-layout chat-template presence
|
|
108
|
+
* check looks for: the template file joined onto the model directory. The
|
|
109
|
+
* hub-cache layout resolves through chatTemplatePresent instead (the
|
|
110
|
+
* deterministic snapshot pick), not through this join.
|
|
111
|
+
*/
|
|
112
|
+
export declare function chatTemplateArtifactPath(directory: string): string;
|
|
113
|
+
/**
|
|
114
|
+
* modelArtifactPresent reports whether a model download source's artifact is
|
|
115
|
+
* on disk. With the hub-cache layout it resolves the deterministic hub-cache
|
|
116
|
+
* snapshot holding the file (the same pick the model-directory display uses),
|
|
117
|
+
* so a `blobs` folder left by any download never reads as present on its
|
|
118
|
+
* own; a blank `file` (a whole-repo download) reads the repo's snapshot
|
|
119
|
+
* directories. With the flat layout it checks the artifact path joined onto
|
|
120
|
+
* the base directory. `baseDir` is the hub cache root under the cache layout,
|
|
121
|
+
* the flat override otherwise.
|
|
122
|
+
*/
|
|
123
|
+
export declare function modelArtifactPresent(entry: ModelDownloadSource, baseDir: string, useHubCache?: boolean): boolean;
|
|
124
|
+
/**
|
|
125
|
+
* chatTemplatePresent reports whether a chat template repo's template file is
|
|
126
|
+
* on disk: the deterministic hub-cache snapshot pick under the hub-cache
|
|
127
|
+
* layout (a per-repo `snapshots` folder alone never reads as present), the
|
|
128
|
+
* flat file join otherwise. `baseDir` follows the modelArtifactPresent rule.
|
|
129
|
+
*/
|
|
130
|
+
export declare function chatTemplatePresent(repo: string, baseDir: string, useHubCache?: boolean): boolean;
|
|
131
|
+
/**
|
|
132
|
+
* hubCacheSnapshotFilePath resolves the concrete file path of one file in the
|
|
133
|
+
* hub cache's snapshots, matching what the hf CLI treats as the active
|
|
134
|
+
* revision: the commit recorded in `refs/main` wins when its directory under
|
|
135
|
+
* `models--{ns}--{name}/snapshots/` holds the file; otherwise the snapshot
|
|
136
|
+
* with the newest mtime wins, covering a repo with no ref and a ref naming a
|
|
137
|
+
* commit that lacks the file. Ties break on readdir order. Returns null when
|
|
138
|
+
* no snapshot holds the file (the file is not downloaded), which the caller
|
|
139
|
+
* reads as absent. The `hubCache` is the hub cache root.
|
|
140
|
+
*/
|
|
141
|
+
export declare function hubCacheSnapshotFilePath(hubCache: string, repoId: string, file: string): string | null;
|
|
56
142
|
/**
|
|
57
143
|
* ModelDirectoryEntry is one top-level entry of a model directory listing:
|
|
58
144
|
* the entry name, whether it is a directory, and for directories whether the
|
|
@@ -74,4 +160,24 @@ export interface ModelDirectoryEntry {
|
|
|
74
160
|
* sorted, so the dropdown order is stable across summary fetches.
|
|
75
161
|
*/
|
|
76
162
|
export declare function modelEntriesForEngine(entries: readonly ModelDirectoryEntry[], engineId: string): string[];
|
|
77
|
-
|
|
163
|
+
/**
|
|
164
|
+
* ModelCacheEntry is one `models--*` directory in the hub cache: the repo id
|
|
165
|
+
* the directory names (the `{namespace}/{name}` decoded from the
|
|
166
|
+
* `models--{ns}--{name}` form) and the artifact file names the snapshots hold
|
|
167
|
+
* (the union across every commit), the data the per-engine cache scan filters.
|
|
168
|
+
*/
|
|
169
|
+
export interface ModelCacheEntry {
|
|
170
|
+
repoId: string;
|
|
171
|
+
files: string[];
|
|
172
|
+
}
|
|
173
|
+
/**
|
|
174
|
+
* modelCacheEntriesForEngine filters the hub cache's `models--*` directories
|
|
175
|
+
* down to the models the engine's Model dropdown offers, by the artifact types
|
|
176
|
+
* each engine serves: Basalt `.basalt`, NInfer `.ninfer`, Infernix
|
|
177
|
+
* `.ninfer`/`.infernix`, llama.cpp `.gguf`, Hyper-Qwen a repo holding a
|
|
178
|
+
* `.safetensors` weight file, and Strata `.gguf`/`.safetensors`. An engine with
|
|
179
|
+
* no matching cached model lists none. The result is the repo ids the
|
|
180
|
+
* dropdown shows, sorted for a stable order across summary fetches.
|
|
181
|
+
*/
|
|
182
|
+
export declare function modelCacheEntriesForEngine(entries: readonly ModelCacheEntry[], engineId: string): string[];
|
|
183
|
+
//# sourceMappingURL=models.d.ts.map
|
|
@@ -1,3 +1,4 @@
|
|
|
1
|
+
import { existsSync, readdirSync, readFileSync, statSync } from 'node:fs';
|
|
1
2
|
import { join } from 'node:path';
|
|
2
3
|
/**
|
|
3
4
|
* repoIdFromUrl turns a Hugging Face repo URL into the `owner/name` repo id
|
|
@@ -21,26 +22,81 @@ export function repoNameFromUrl(url) {
|
|
|
21
22
|
return slash >= 0 ? repo.slice(slash + 1) : repo;
|
|
22
23
|
}
|
|
23
24
|
/**
|
|
24
|
-
*
|
|
25
|
-
*
|
|
26
|
-
* directory
|
|
25
|
+
* hubCacheModelDirectory is the per-model directory the hf CLI creates in the
|
|
26
|
+
* hub cache for one repo id: `models--{namespace}--{name}`. A repo id without
|
|
27
|
+
* an owner/name pair reads as an empty directory name, which the callers
|
|
28
|
+
* handle as an absent model.
|
|
27
29
|
*/
|
|
28
|
-
export function
|
|
30
|
+
export function hubCacheModelDirectory(repoId) {
|
|
31
|
+
const slash = repoId.lastIndexOf('/');
|
|
32
|
+
if (slash <= 0)
|
|
33
|
+
return '';
|
|
34
|
+
return `models--${repoId.slice(0, slash)}--${repoId.slice(slash + 1)}`;
|
|
35
|
+
}
|
|
36
|
+
/**
|
|
37
|
+
* isModelDirectoryOverridden reports whether a model directory field (the
|
|
38
|
+
* config's or a download request's) names a path (a non-blank string), the
|
|
39
|
+
* one rule every download route and view model shares to decide the layout:
|
|
40
|
+
* a named directory targets that directory flat (`--local-dir`), an unnamed
|
|
41
|
+
* one takes the hub-cache layout (no `--local-dir`, the
|
|
42
|
+
* `models--{ns}--{name}` directories the hf CLI writes into the hub cache).
|
|
43
|
+
* The predicate form lets callers narrow the field to a string without
|
|
44
|
+
* restating the blank check.
|
|
45
|
+
*/
|
|
46
|
+
export function isModelDirectoryOverridden(modelDirectory) {
|
|
47
|
+
return typeof modelDirectory === 'string' && modelDirectory.trim() !== '';
|
|
48
|
+
}
|
|
49
|
+
/**
|
|
50
|
+
* modelArtifactPath is the path a model download's artifact lands at in the
|
|
51
|
+
* model directory: the entry's artifact file when it names one, else the
|
|
52
|
+
* repo-name directory a whole-repo download leaves behind. With the hub-cache
|
|
53
|
+
* layout (`useHubCache`), it resolves into the per-model cache directory's
|
|
54
|
+
* `blobs` folder, the content-addressed store the hf CLI writes without
|
|
55
|
+
* `--local-dir`; the `directory` is then the hub cache root, not the per-model
|
|
56
|
+
* folder. Every presence decision (the card-facing checks and the engines'
|
|
57
|
+
* deploy re-fetch gates) resolves the deterministic snapshot instead
|
|
58
|
+
* (modelArtifactPresent); the hub-cache form here stays the blobs-store path.
|
|
59
|
+
*/
|
|
60
|
+
export function modelArtifactPath(entry, directory, useHubCache = false) {
|
|
61
|
+
if (useHubCache) {
|
|
62
|
+
const modelDir = hubCacheModelDirectory(repoIdFromUrl(entry.url));
|
|
63
|
+
if (modelDir !== '')
|
|
64
|
+
return join(directory, modelDir, 'blobs');
|
|
65
|
+
}
|
|
29
66
|
if (entry.file !== undefined && entry.file !== '') {
|
|
30
67
|
return join(directory, entry.file);
|
|
31
68
|
}
|
|
32
69
|
return join(directory, repoNameFromUrl(entry.url));
|
|
33
70
|
}
|
|
34
71
|
/**
|
|
35
|
-
*
|
|
36
|
-
* repo, the
|
|
37
|
-
* target
|
|
38
|
-
*
|
|
72
|
+
* hfDownloadFileCommand renders the hf CLI download for one repo and file
|
|
73
|
+
* pair: the repo, the file (omitted when blank, a whole-repo download), the
|
|
74
|
+
* `--local-dir` target when the hub-cache layout does not apply, and the
|
|
75
|
+
* `--format human` flag. The flag overrides the non-TTY default (`auto` picks
|
|
76
|
+
* `agent`, which prints no progress) so the hf CLI prints tqdm progress
|
|
77
|
+
* lines to stderr, which the progress streaming tasks consume. The string is
|
|
78
|
+
* the single source every hf download command renders through: the model and
|
|
79
|
+
* chat-template builders below, and the Infernix extra-download commands the
|
|
80
|
+
* Get step streams.
|
|
81
|
+
*/
|
|
82
|
+
export function hfDownloadFileCommand(repo, file, directory, useHubCache = false) {
|
|
83
|
+
const filePart = file !== '' ? ` ${file}` : '';
|
|
84
|
+
const localDir = useHubCache ? '' : ` --local-dir ${directory}`;
|
|
85
|
+
return `hf download ${repo}${filePart}${localDir} --format human`;
|
|
86
|
+
}
|
|
87
|
+
/**
|
|
88
|
+
* hfDownloadCommand renders the hf CLI download for one model download
|
|
89
|
+
* source: the repo, the artifact file when the entry names one, and the
|
|
90
|
+
* `--local-dir` target. With the hub-cache layout (`useHubCache`), the `--local-dir` is
|
|
91
|
+
* dropped so the hf CLI writes into the hub cache's `models--{ns}--{name}`
|
|
92
|
+
* directory (the content-addressed `blobs/` plus the `snapshots/`). The
|
|
93
|
+
* string is the single source the download route runs and the card shows
|
|
94
|
+
* beside its Download button, rendered through hfDownloadFileCommand.
|
|
39
95
|
*/
|
|
40
|
-
export function hfDownloadCommand(entry, directory) {
|
|
96
|
+
export function hfDownloadCommand(entry, directory, useHubCache = false) {
|
|
41
97
|
const repo = repoIdFromUrl(entry.url);
|
|
42
|
-
const file = entry.file !== undefined && entry.file !== '' ?
|
|
43
|
-
return
|
|
98
|
+
const file = entry.file !== undefined && entry.file !== '' ? entry.file : '';
|
|
99
|
+
return hfDownloadFileCommand(repo, file, directory, useHubCache);
|
|
44
100
|
}
|
|
45
101
|
/**
|
|
46
102
|
* The chat template file the hf CLI pulls into the model directory. The
|
|
@@ -51,12 +107,115 @@ export const CHAT_TEMPLATE_FILE = 'chat_template.jinja';
|
|
|
51
107
|
/**
|
|
52
108
|
* hfChatTemplateCommand renders the hf CLI download for one chat template repo
|
|
53
109
|
* reference into the model directory: the repo, the template file, and the
|
|
54
|
-
* `--local-dir` target.
|
|
55
|
-
*
|
|
56
|
-
*
|
|
110
|
+
* `--local-dir` target. With the hub-cache layout (`useHubCache`), the
|
|
111
|
+
* `--local-dir` is dropped so the template lands in the hub cache's
|
|
112
|
+
* `models--{ns}--{name}` directory. The string is the single source the
|
|
113
|
+
* template download route runs and the card shows beside its Download button
|
|
114
|
+
* and in the System dependencies box when the auto-download is unavailable,
|
|
115
|
+
* rendered through hfDownloadFileCommand.
|
|
116
|
+
*/
|
|
117
|
+
export function hfChatTemplateCommand(repo, directory, useHubCache = false) {
|
|
118
|
+
return hfDownloadFileCommand(repo, CHAT_TEMPLATE_FILE, directory, useHubCache);
|
|
119
|
+
}
|
|
120
|
+
/**
|
|
121
|
+
* chatTemplateArtifactPath is the path the flat-layout chat-template presence
|
|
122
|
+
* check looks for: the template file joined onto the model directory. The
|
|
123
|
+
* hub-cache layout resolves through chatTemplatePresent instead (the
|
|
124
|
+
* deterministic snapshot pick), not through this join.
|
|
125
|
+
*/
|
|
126
|
+
export function chatTemplateArtifactPath(directory) {
|
|
127
|
+
return join(directory, CHAT_TEMPLATE_FILE);
|
|
128
|
+
}
|
|
129
|
+
/**
|
|
130
|
+
* modelArtifactPresent reports whether a model download source's artifact is
|
|
131
|
+
* on disk. With the hub-cache layout it resolves the deterministic hub-cache
|
|
132
|
+
* snapshot holding the file (the same pick the model-directory display uses),
|
|
133
|
+
* so a `blobs` folder left by any download never reads as present on its
|
|
134
|
+
* own; a blank `file` (a whole-repo download) reads the repo's snapshot
|
|
135
|
+
* directories. With the flat layout it checks the artifact path joined onto
|
|
136
|
+
* the base directory. `baseDir` is the hub cache root under the cache layout,
|
|
137
|
+
* the flat override otherwise.
|
|
138
|
+
*/
|
|
139
|
+
export function modelArtifactPresent(entry, baseDir, useHubCache = false) {
|
|
140
|
+
if (useHubCache) {
|
|
141
|
+
return hubCacheSnapshotFilePath(baseDir, repoIdFromUrl(entry.url), entry.file ?? '') !== null;
|
|
142
|
+
}
|
|
143
|
+
return existsSync(modelArtifactPath(entry, baseDir));
|
|
144
|
+
}
|
|
145
|
+
/**
|
|
146
|
+
* chatTemplatePresent reports whether a chat template repo's template file is
|
|
147
|
+
* on disk: the deterministic hub-cache snapshot pick under the hub-cache
|
|
148
|
+
* layout (a per-repo `snapshots` folder alone never reads as present), the
|
|
149
|
+
* flat file join otherwise. `baseDir` follows the modelArtifactPresent rule.
|
|
57
150
|
*/
|
|
58
|
-
export function
|
|
59
|
-
|
|
151
|
+
export function chatTemplatePresent(repo, baseDir, useHubCache = false) {
|
|
152
|
+
if (useHubCache) {
|
|
153
|
+
return hubCacheSnapshotFilePath(baseDir, repo, CHAT_TEMPLATE_FILE) !== null;
|
|
154
|
+
}
|
|
155
|
+
return existsSync(chatTemplateArtifactPath(baseDir));
|
|
156
|
+
}
|
|
157
|
+
/**
|
|
158
|
+
* hubCacheSnapshotFilePath resolves the concrete file path of one file in the
|
|
159
|
+
* hub cache's snapshots, matching what the hf CLI treats as the active
|
|
160
|
+
* revision: the commit recorded in `refs/main` wins when its directory under
|
|
161
|
+
* `models--{ns}--{name}/snapshots/` holds the file; otherwise the snapshot
|
|
162
|
+
* with the newest mtime wins, covering a repo with no ref and a ref naming a
|
|
163
|
+
* commit that lacks the file. Ties break on readdir order. Returns null when
|
|
164
|
+
* no snapshot holds the file (the file is not downloaded), which the caller
|
|
165
|
+
* reads as absent. The `hubCache` is the hub cache root.
|
|
166
|
+
*/
|
|
167
|
+
export function hubCacheSnapshotFilePath(hubCache, repoId, file) {
|
|
168
|
+
const modelDir = hubCacheModelDirectory(repoId);
|
|
169
|
+
if (modelDir === '')
|
|
170
|
+
return null;
|
|
171
|
+
const modelRoot = join(hubCache, modelDir);
|
|
172
|
+
const snapshots = join(modelRoot, 'snapshots');
|
|
173
|
+
// The hf CLI writes the revision it last downloaded into refs/main; that
|
|
174
|
+
// commit is the cache's active one, so it outranks mtime.
|
|
175
|
+
const active = readHubCacheRef(join(modelRoot, 'refs', 'main'));
|
|
176
|
+
if (active !== '') {
|
|
177
|
+
const activePath = join(snapshots, active, file);
|
|
178
|
+
if (existsSync(activePath))
|
|
179
|
+
return activePath;
|
|
180
|
+
}
|
|
181
|
+
let commits;
|
|
182
|
+
try {
|
|
183
|
+
commits = readdirSync(snapshots);
|
|
184
|
+
}
|
|
185
|
+
catch {
|
|
186
|
+
return null;
|
|
187
|
+
}
|
|
188
|
+
let newestPath = null;
|
|
189
|
+
let newestMtime = -Infinity;
|
|
190
|
+
for (const commit of commits) {
|
|
191
|
+
const path = join(snapshots, commit, file);
|
|
192
|
+
if (!existsSync(path))
|
|
193
|
+
continue;
|
|
194
|
+
const snapshotDir = join(snapshots, commit);
|
|
195
|
+
let mtime;
|
|
196
|
+
try {
|
|
197
|
+
mtime = statSync(snapshotDir).mtimeMs;
|
|
198
|
+
}
|
|
199
|
+
catch {
|
|
200
|
+
// A directory that cannot be stat'ed mid-scan cannot win the pick.
|
|
201
|
+
continue;
|
|
202
|
+
}
|
|
203
|
+
if (mtime > newestMtime) {
|
|
204
|
+
newestMtime = mtime;
|
|
205
|
+
newestPath = path;
|
|
206
|
+
}
|
|
207
|
+
}
|
|
208
|
+
return newestPath;
|
|
209
|
+
}
|
|
210
|
+
// readHubCacheRef returns the commit the hf CLI ref file names, or '' when
|
|
211
|
+
// the ref is absent or unreadable (a cache written by an older CLI).
|
|
212
|
+
function readHubCacheRef(refPath) {
|
|
213
|
+
try {
|
|
214
|
+
return readFileSync(refPath, 'utf8').trim();
|
|
215
|
+
}
|
|
216
|
+
catch {
|
|
217
|
+
return '';
|
|
218
|
+
}
|
|
60
219
|
}
|
|
61
220
|
/**
|
|
62
221
|
* modelEntriesForEngine filters a model directory listing down to the model
|
|
@@ -98,4 +257,37 @@ export function modelEntriesForEngine(entries, engineId) {
|
|
|
98
257
|
}
|
|
99
258
|
return names.sort();
|
|
100
259
|
}
|
|
101
|
-
|
|
260
|
+
/**
|
|
261
|
+
* modelCacheEntriesForEngine filters the hub cache's `models--*` directories
|
|
262
|
+
* down to the models the engine's Model dropdown offers, by the artifact types
|
|
263
|
+
* each engine serves: Basalt `.basalt`, NInfer `.ninfer`, Infernix
|
|
264
|
+
* `.ninfer`/`.infernix`, llama.cpp `.gguf`, Hyper-Qwen a repo holding a
|
|
265
|
+
* `.safetensors` weight file, and Strata `.gguf`/`.safetensors`. An engine with
|
|
266
|
+
* no matching cached model lists none. The result is the repo ids the
|
|
267
|
+
* dropdown shows, sorted for a stable order across summary fetches.
|
|
268
|
+
*/
|
|
269
|
+
export function modelCacheEntriesForEngine(entries, engineId) {
|
|
270
|
+
const serves = (files) => {
|
|
271
|
+
switch (engineId) {
|
|
272
|
+
case 'basalt':
|
|
273
|
+
return files.some((file) => file.endsWith('.basalt'));
|
|
274
|
+
case 'ninfer':
|
|
275
|
+
return files.some((file) => file.endsWith('.ninfer'));
|
|
276
|
+
case 'infernix':
|
|
277
|
+
return files.some((file) => file.endsWith('.ninfer') || file.endsWith('.infernix'));
|
|
278
|
+
case 'llamacpp':
|
|
279
|
+
return files.some((file) => file.endsWith('.gguf'));
|
|
280
|
+
case 'hyperqwen':
|
|
281
|
+
return files.some((file) => file.endsWith('.safetensors'));
|
|
282
|
+
case 'strata':
|
|
283
|
+
return files.some((file) => file.endsWith('.gguf') || file.endsWith('.safetensors'));
|
|
284
|
+
default:
|
|
285
|
+
return false;
|
|
286
|
+
}
|
|
287
|
+
};
|
|
288
|
+
return entries
|
|
289
|
+
.filter((entry) => serves(entry.files))
|
|
290
|
+
.map((entry) => entry.repoId)
|
|
291
|
+
.sort();
|
|
292
|
+
}
|
|
293
|
+
//# sourceMappingURL=models.js.map
|
|
@@ -68,6 +68,29 @@ export type ParameterForm = {
|
|
|
68
68
|
kind: 'combo';
|
|
69
69
|
options: ComboOption[];
|
|
70
70
|
};
|
|
71
|
+
/**
|
|
72
|
+
* ParameterDeploy declares where a parameter's value lands at deploy time:
|
|
73
|
+
* on the command line, in the process environment, or in a config file the
|
|
74
|
+
* deploy step writes. A `config` target names the file format and the
|
|
75
|
+
* nesting path: `block` is the top-level key, `key` the leaf. The config-file
|
|
76
|
+
* renderer nests `toConfig(value)` (or the raw value) under that path. A
|
|
77
|
+
* `block` ending in `[]` (e.g. `models[]`) is the array-entry convention: the
|
|
78
|
+
* key lands inside the single object of a one-element array named by the
|
|
79
|
+
* prefix, and specs sharing that block merge into that one entry. A spec
|
|
80
|
+
* declares one target, or a list of targets when the value lands in more than
|
|
81
|
+
* one place (a Strata shared spec lands on the CLI in the binary mode and in
|
|
82
|
+
* the env in the docker mode).
|
|
83
|
+
*/
|
|
84
|
+
export type ParameterDeploy = {
|
|
85
|
+
target: 'cli';
|
|
86
|
+
} | {
|
|
87
|
+
target: 'env';
|
|
88
|
+
} | {
|
|
89
|
+
target: 'config';
|
|
90
|
+
format: 'json' | 'yaml' | 'env';
|
|
91
|
+
block?: string;
|
|
92
|
+
key?: string;
|
|
93
|
+
};
|
|
71
94
|
/**
|
|
72
95
|
* ParameterSpec is the unit of parameter management: a declarative description
|
|
73
96
|
* of one engine parameter. It is the object that makes the parameter-to-
|
|
@@ -77,8 +100,11 @@ export type ParameterForm = {
|
|
|
77
100
|
* of adding these specs, never rewiring the core.
|
|
78
101
|
*
|
|
79
102
|
* `description` is behavior-first: it says what the parameter does to the run,
|
|
80
|
-
* not what it is. `toArgv` and `
|
|
81
|
-
* turn a value into a CLI flag
|
|
103
|
+
* not what it is. `toArgv`, `toEnv`, and `toConfig` are the engine-specific
|
|
104
|
+
* spellings that turn a value into a CLI flag, an environment variable, or a
|
|
105
|
+
* config-file entry. `deploy` declares which spelling the deploy step uses;
|
|
106
|
+
* a list declares several, so one spec can serve more than one build mode
|
|
107
|
+
* (the flags in the binary mode and the env vars in the docker mode).
|
|
82
108
|
*/
|
|
83
109
|
export interface ParameterSpec {
|
|
84
110
|
key: string;
|
|
@@ -92,5 +118,7 @@ export interface ParameterSpec {
|
|
|
92
118
|
requires?: (config: Config) => string | null;
|
|
93
119
|
toArgv?: (value: unknown) => string[];
|
|
94
120
|
toEnv?: (value: unknown) => [string, string];
|
|
121
|
+
toConfig?: (value: unknown) => unknown;
|
|
122
|
+
deploy?: ParameterDeploy | readonly ParameterDeploy[];
|
|
95
123
|
}
|
|
96
|
-
//# sourceMappingURL=parameter.d.ts.map
|
|
124
|
+
//# sourceMappingURL=parameter.d.ts.map
|
|
@@ -1,2 +1,2 @@
|
|
|
1
1
|
export {};
|
|
2
|
-
//# sourceMappingURL=parameter.js.map
|
|
2
|
+
//# sourceMappingURL=parameter.js.map
|
|
@@ -0,0 +1,54 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure hf (huggingface_hub) tqdm progress parser the get and launch routes
|
|
3
|
+
* share: it turns the raw tqdm stderr lines into a structured HfProgress
|
|
4
|
+
* state, so a route's onChunk sink (the download runner's streamed stderr)
|
|
5
|
+
* feeds the card's progress events without a node import. The parser
|
|
6
|
+
* recognizes the two tqdm bar shapes the hf CLI emits with `--format human`:
|
|
7
|
+
* the file-count bar (`Fetching 102 files: 42%|...| 43/102 [00:01<00:02,
|
|
8
|
+
* 20.5it/s]`, where the done/total fields carry file counts, not bytes) and
|
|
9
|
+
* the byte bar (`Downloading x.safetensors: 12% | 5.2G/43.5G [01:23<10:11,
|
|
10
|
+
* 72.3MB/s]`, where the done/total fields carry human byte sizes). It
|
|
11
|
+
* converts the human byte sizes to bytes and the `[elapsed<remaining, rate]`
|
|
12
|
+
* tail to remaining seconds, and marks the unit the done/total amounts carry
|
|
13
|
+
* (`'files'` for the file-count bar, `'bytes'` for the byte bar), so a
|
|
14
|
+
* readout renders the amounts in the unit the bar measured. The client
|
|
15
|
+
* package mirrors this parser in
|
|
16
|
+
* `packages/client/src/store/progress.ts` (the TASK-006 browser-side copy):
|
|
17
|
+
* the core package is not browser-safe, so the client bundle keeps its own
|
|
18
|
+
* copy and the two shapes (`HfProgress` and the client's `HfProgressShape`)
|
|
19
|
+
* must stay in sync when a tqdm bar shape changes.
|
|
20
|
+
* @module dsh-plugin-local-infer/core/progress
|
|
21
|
+
*/
|
|
22
|
+
/**
|
|
23
|
+
* HfProgress is the structured state one tqdm bar update folds to: the step
|
|
24
|
+
* label the bar names (the file, or the file-count fetch), the percent
|
|
25
|
+
* complete, the done and total amounts (bytes for the byte bar, file counts
|
|
26
|
+
* for the file-count bar), the remaining time in seconds (0 when the bar
|
|
27
|
+
* carries no tail), and the unit the done/total amounts carry ('bytes' for
|
|
28
|
+
* the byte bar, 'files' for the file-count bar), so a readout renders the
|
|
29
|
+
* amounts in the unit the bar measured.
|
|
30
|
+
*/
|
|
31
|
+
export interface HfProgress {
|
|
32
|
+
step: string;
|
|
33
|
+
percent: number;
|
|
34
|
+
doneBytes: number;
|
|
35
|
+
totalBytes: number;
|
|
36
|
+
etaSeconds: number;
|
|
37
|
+
unit: 'bytes' | 'files';
|
|
38
|
+
}
|
|
39
|
+
/**
|
|
40
|
+
* parseHfProgressLine parses one tqdm bar line into an HfProgress state, or
|
|
41
|
+
* undefined when the line is not a bar update (a plain log line, a command
|
|
42
|
+
* echo). It recognizes the file-count and byte shapes above.
|
|
43
|
+
*/
|
|
44
|
+
export declare function parseHfProgressLine(line: string): HfProgress | undefined;
|
|
45
|
+
/**
|
|
46
|
+
* foldHfProgressChunk folds a raw stderr chunk into the latest HfProgress
|
|
47
|
+
* state it carries: the chunk splits on the line separators tqdm writes
|
|
48
|
+
* (carriage returns between bar redraws, newlines between steps), each line
|
|
49
|
+
* parses through parseHfProgressLine, and the last parseable line wins. A
|
|
50
|
+
* chunk with no bar update returns the prior state, so a caller threads the
|
|
51
|
+
* fold across chunks and always holds the newest state.
|
|
52
|
+
*/
|
|
53
|
+
export declare function foldHfProgressChunk(chunk: string, prior: HfProgress | undefined): HfProgress | undefined;
|
|
54
|
+
//# sourceMappingURL=progress.d.ts.map
|
|
@@ -0,0 +1,120 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The pure hf (huggingface_hub) tqdm progress parser the get and launch routes
|
|
3
|
+
* share: it turns the raw tqdm stderr lines into a structured HfProgress
|
|
4
|
+
* state, so a route's onChunk sink (the download runner's streamed stderr)
|
|
5
|
+
* feeds the card's progress events without a node import. The parser
|
|
6
|
+
* recognizes the two tqdm bar shapes the hf CLI emits with `--format human`:
|
|
7
|
+
* the file-count bar (`Fetching 102 files: 42%|...| 43/102 [00:01<00:02,
|
|
8
|
+
* 20.5it/s]`, where the done/total fields carry file counts, not bytes) and
|
|
9
|
+
* the byte bar (`Downloading x.safetensors: 12% | 5.2G/43.5G [01:23<10:11,
|
|
10
|
+
* 72.3MB/s]`, where the done/total fields carry human byte sizes). It
|
|
11
|
+
* converts the human byte sizes to bytes and the `[elapsed<remaining, rate]`
|
|
12
|
+
* tail to remaining seconds, and marks the unit the done/total amounts carry
|
|
13
|
+
* (`'files'` for the file-count bar, `'bytes'` for the byte bar), so a
|
|
14
|
+
* readout renders the amounts in the unit the bar measured. The client
|
|
15
|
+
* package mirrors this parser in
|
|
16
|
+
* `packages/client/src/store/progress.ts` (the TASK-006 browser-side copy):
|
|
17
|
+
* the core package is not browser-safe, so the client bundle keeps its own
|
|
18
|
+
* copy and the two shapes (`HfProgress` and the client's `HfProgressShape`)
|
|
19
|
+
* must stay in sync when a tqdm bar shape changes.
|
|
20
|
+
* @module dsh-plugin-local-infer/core/progress
|
|
21
|
+
*/
|
|
22
|
+
// The file-count bar: `Fetching 102 files: 42%|...| 43/102 [00:01<00:02, ...]`.
|
|
23
|
+
// The bar glyph run between the pipes is skipped, and the counts are plain
|
|
24
|
+
// integers.
|
|
25
|
+
const FILES_LINE = /^Fetching (\d+) files:\s*(\d+(?:\.\d+)?)%\|[^|]*\|\s*(\d+)\s*\/\s*(\d+)(?:\s*\[([^\]]*)\])?/;
|
|
26
|
+
// The byte bar: `Downloading x.safetensors: 12% | 5.2G/43.5G [01:23<10:11, ...]`.
|
|
27
|
+
// The sizes carry an optional K/M/G/T/P unit (decimal, or binary with an
|
|
28
|
+
// `i`), and the tail is optional (a finished bar drops it).
|
|
29
|
+
const BYTES_LINE = /^(?:Downloading|Fetching)\s+([^:]+):\s*(\d+(?:\.\d+)?)%\s*\|\s*(\d+(?:\.\d+)?[KMGTP]?i?B?)\s*\/\s*(\d+(?:\.\d+)?[KMGTP]?i?B?)\s*(?:\[([^\]]*)\])?/;
|
|
30
|
+
// The unit exponents for the decimal (1000-based) sizes the hf CLI's tqdm
|
|
31
|
+
// renders; a binary `i` suffix (Gi, Mi, ...) switches the base to 1024.
|
|
32
|
+
const UNIT_EXPONENTS = { K: 1, M: 2, G: 3, T: 4, P: 5 };
|
|
33
|
+
// parseHumanSize converts one human byte size (`5.2G`) to bytes: the decimal
|
|
34
|
+
// base the hf CLI's tqdm uses, with a 1024 base when the unit carries the
|
|
35
|
+
// binary `i` suffix. A size with no unit is a plain byte count.
|
|
36
|
+
function parseHumanSize(text) {
|
|
37
|
+
const match = /^(\d+(?:\.\d+)?)([KMGTP]?)i?B?$/.exec(text);
|
|
38
|
+
if (match === null)
|
|
39
|
+
return 0;
|
|
40
|
+
const exponent = UNIT_EXPONENTS[match[2]] ?? 0;
|
|
41
|
+
const base = text.includes('i') ? 1024 : 1000;
|
|
42
|
+
return Number(match[1]) * base ** exponent;
|
|
43
|
+
}
|
|
44
|
+
// durationSeconds converts a `MM:SS`, `H:MM:SS`, or `D:H:MM:SS` clock string
|
|
45
|
+
// to seconds, the tqdm tail's remaining-time format.
|
|
46
|
+
function durationSeconds(text) {
|
|
47
|
+
let seconds = 0;
|
|
48
|
+
for (const part of text.split(':')) {
|
|
49
|
+
seconds = seconds * 60 + Number(part);
|
|
50
|
+
}
|
|
51
|
+
return seconds;
|
|
52
|
+
}
|
|
53
|
+
// etaSecondsFromTail reads the remaining time out of a tqdm tail
|
|
54
|
+
// (`01:23<10:11, 72.3MB/s`): the clock string after the `<`, 0 when the tail
|
|
55
|
+
// is absent or carries no remaining time.
|
|
56
|
+
function etaSecondsFromTail(tail) {
|
|
57
|
+
if (tail === undefined)
|
|
58
|
+
return 0;
|
|
59
|
+
const match = /<\s*(\d+(?::\d+)+)/.exec(tail);
|
|
60
|
+
if (match === null)
|
|
61
|
+
return 0;
|
|
62
|
+
return durationSeconds(match[1]);
|
|
63
|
+
}
|
|
64
|
+
/**
|
|
65
|
+
* parseHfProgressLine parses one tqdm bar line into an HfProgress state, or
|
|
66
|
+
* undefined when the line is not a bar update (a plain log line, a command
|
|
67
|
+
* echo). It recognizes the file-count and byte shapes above.
|
|
68
|
+
*/
|
|
69
|
+
export function parseHfProgressLine(line) {
|
|
70
|
+
const trimmed = line.trim();
|
|
71
|
+
if (trimmed === '')
|
|
72
|
+
return undefined;
|
|
73
|
+
const files = FILES_LINE.exec(trimmed);
|
|
74
|
+
if (files !== null) {
|
|
75
|
+
// The file-count bar carries counts, not bytes: the done/total fields
|
|
76
|
+
// hold the file numbers, the step label names the fetch, and the unit
|
|
77
|
+
// marks the amounts as file counts, so a readout renders them as files.
|
|
78
|
+
return {
|
|
79
|
+
step: `Fetching ${files[1]} files`,
|
|
80
|
+
percent: Number(files[2]),
|
|
81
|
+
doneBytes: Number(files[3]),
|
|
82
|
+
totalBytes: Number(files[4]),
|
|
83
|
+
etaSeconds: etaSecondsFromTail(files[5]),
|
|
84
|
+
unit: 'files',
|
|
85
|
+
};
|
|
86
|
+
}
|
|
87
|
+
const bytes = BYTES_LINE.exec(trimmed);
|
|
88
|
+
if (bytes !== null) {
|
|
89
|
+
const verb = trimmed.startsWith('Fetching') ? 'Fetching' : 'Downloading';
|
|
90
|
+
// The byte bar carries human byte sizes: the done/total fields hold the
|
|
91
|
+
// parsed byte counts, and the unit marks the amounts as bytes.
|
|
92
|
+
return {
|
|
93
|
+
step: `${verb} ${bytes[1].trim()}`,
|
|
94
|
+
percent: Number(bytes[2]),
|
|
95
|
+
doneBytes: parseHumanSize(bytes[3]),
|
|
96
|
+
totalBytes: parseHumanSize(bytes[4]),
|
|
97
|
+
etaSeconds: etaSecondsFromTail(bytes[5]),
|
|
98
|
+
unit: 'bytes',
|
|
99
|
+
};
|
|
100
|
+
}
|
|
101
|
+
return undefined;
|
|
102
|
+
}
|
|
103
|
+
/**
|
|
104
|
+
* foldHfProgressChunk folds a raw stderr chunk into the latest HfProgress
|
|
105
|
+
* state it carries: the chunk splits on the line separators tqdm writes
|
|
106
|
+
* (carriage returns between bar redraws, newlines between steps), each line
|
|
107
|
+
* parses through parseHfProgressLine, and the last parseable line wins. A
|
|
108
|
+
* chunk with no bar update returns the prior state, so a caller threads the
|
|
109
|
+
* fold across chunks and always holds the newest state.
|
|
110
|
+
*/
|
|
111
|
+
export function foldHfProgressChunk(chunk, prior) {
|
|
112
|
+
let folded = prior;
|
|
113
|
+
for (const line of chunk.split(/\r\n|\r|\n/)) {
|
|
114
|
+
const parsed = parseHfProgressLine(line);
|
|
115
|
+
if (parsed !== undefined)
|
|
116
|
+
folded = parsed;
|
|
117
|
+
}
|
|
118
|
+
return folded;
|
|
119
|
+
}
|
|
120
|
+
//# sourceMappingURL=progress.js.map
|