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
|
@@ -0,0 +1,98 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shared Get-steps routine both getEngine and launchEngine route through:
|
|
3
|
+
* it runs, in order, (1) the engine's system-dependency install for the host
|
|
4
|
+
* OS (gated by the Play/Run trust gate), (2) the git clone of the engine repo
|
|
5
|
+
* (or the fork) plus the fetch/rebase of a clean checkout, (3) the source
|
|
6
|
+
* build step (the compose engines carry no local build steps), (4) the hf
|
|
7
|
+
* download of the selected model when it is not already present, and (5) the
|
|
8
|
+
* hf download of any selected chat template when it is not already present.
|
|
9
|
+
* Every step streams through the log sink as it lands, and an already-
|
|
10
|
+
* satisfied step is skipped and logged as such, so a Launch that runs the
|
|
11
|
+
* routine before the deploy is idempotent. With an `onStep` reporter (a
|
|
12
|
+
* Launch's progress sink; a standalone Get passes none) each step announces
|
|
13
|
+
* its launch phase only when its work actually starts, so the card's button
|
|
14
|
+
* reads the phase that is running. A Launch can set
|
|
15
|
+
* `continueOnSyncFailure` on the request: when the git sync (rebase) of an
|
|
16
|
+
* existing checkout fails, the run keeps going with the checkout's current
|
|
17
|
+
* version and reports `syncFailed` on the result, so a broken rebase never
|
|
18
|
+
* halts the launch. A standalone Get omits the flag and keeps stopping on a
|
|
19
|
+
* sync failure.
|
|
20
|
+
* @module dsh-plugin-local-infer/ui/ops/get-steps
|
|
21
|
+
*/
|
|
22
|
+
import type { Config, LaunchProgress, LifecycleHost } from 'dsh-plugin-local-infer/core';
|
|
23
|
+
import type { LocalInferService } from 'dsh-plugin-local-infer/service';
|
|
24
|
+
import type { StoredPlatformConfig } from '../config.ts';
|
|
25
|
+
/**
|
|
26
|
+
* GetStepsRequest names the run: the engine, the config the dep plan, build
|
|
27
|
+
* mode, model, and chat template read from, the platform entry the checkout
|
|
28
|
+
* directory and fork resolve against, the Play/Run trust gate that decides
|
|
29
|
+
* whether the dependency install runs, and the lifecycle host the git and
|
|
30
|
+
* build steps run through. `autoRebuild` false (the card's Auto Rebuild
|
|
31
|
+
* checkbox off) skips the sync and build steps, so a launch reads the
|
|
32
|
+
* checkout as-is, the same rule the adapter's deploy step applies. `signal`
|
|
33
|
+
* is the card's cancel: an abort interrupts the in-flight hf download child
|
|
34
|
+
* (SIGINT, then SIGTERM), resume is within-invocation only (the hf CLI resumes a network blip via
|
|
35
|
+
* HTTP Range inside one run); a killed run re-downloads from zero on the
|
|
36
|
+
* re-run, and the orphaned `.incomplete` blob lingers until `hf cache prune`.
|
|
37
|
+
* `onChunk` is the hf download's raw stderr progress sink: the download
|
|
38
|
+
* runner hands each streamed stdout and stderr chunk to it as it lands,
|
|
39
|
+
* separate from the log text sink the step lines stream through, so the
|
|
40
|
+
* caller parses the tqdm lines into progress events. `onStep` is the launch
|
|
41
|
+
* phase reporter (the card's button reader): a step announces its phase only
|
|
42
|
+
* when its work actually starts (the dep install, the sync/build, a model or
|
|
43
|
+
* template download), so a satisfied-and-skipped step announces nothing. A
|
|
44
|
+
* standalone Get passes none (its control keeps its throbber); a Launch
|
|
45
|
+
* threads its route progress sink here. `continueOnSyncFailure`
|
|
46
|
+
* (a Launch-only flag) keeps the run going when the git sync of an existing
|
|
47
|
+
* checkout fails: the run reports `syncFailed` on the result and the launch
|
|
48
|
+
* continues with the checkout's current version, so a broken rebase never
|
|
49
|
+
* halts it. A standalone Get omits it and stops on a sync failure.
|
|
50
|
+
*/
|
|
51
|
+
export interface GetStepsRequest {
|
|
52
|
+
engineId: string;
|
|
53
|
+
config: Config;
|
|
54
|
+
platform?: StoredPlatformConfig;
|
|
55
|
+
allowRunDeps: boolean;
|
|
56
|
+
autoRebuild?: boolean;
|
|
57
|
+
continueOnSyncFailure?: boolean;
|
|
58
|
+
host: LifecycleHost;
|
|
59
|
+
signal?: AbortSignal;
|
|
60
|
+
onChunk?: (chunk: string) => void;
|
|
61
|
+
onStep?: LaunchProgress;
|
|
62
|
+
}
|
|
63
|
+
/**
|
|
64
|
+
* GetStepsResult reports the run: whether every step passed, a detail the
|
|
65
|
+
* Logs section shows when one did not, and the captured log text (every step
|
|
66
|
+
* line, in order) the caller persists or streams to the card. `syncFailed`
|
|
67
|
+
* marks a run that kept going after a non-fatal git sync failure (the
|
|
68
|
+
* `continueOnSyncFailure` override): `ok` stays true and the caller threads
|
|
69
|
+
* the flag into the launch so the deploy skips its own git sync and launches
|
|
70
|
+
* the checkout's current version.
|
|
71
|
+
*/
|
|
72
|
+
export interface GetStepsResult {
|
|
73
|
+
ok: boolean;
|
|
74
|
+
logs: string;
|
|
75
|
+
detail?: string;
|
|
76
|
+
syncFailed?: boolean;
|
|
77
|
+
}
|
|
78
|
+
/**
|
|
79
|
+
* resolveEngineDirectory picks the checkout the Get step syncs: the Engine
|
|
80
|
+
* Directory override when it names a path, else the engine's default
|
|
81
|
+
* checkout home `~/.cache/dsh/infer/{engineId}` (one checkout per engine,
|
|
82
|
+
* never a subfolder of a model directory), so a Get with no override still
|
|
83
|
+
* has a real place to live.
|
|
84
|
+
*/
|
|
85
|
+
export declare function resolveEngineDirectory(engineId: string, platform: StoredPlatformConfig | undefined): string;
|
|
86
|
+
/**
|
|
87
|
+
* runGetSteps is the shared Get-steps routine. It runs the five steps in
|
|
88
|
+
* order, streaming each through log and collecting the same text as the
|
|
89
|
+
* result's logs, so a caller can persist the run (a Get) or thread it into
|
|
90
|
+
* the launch's persisted logs (a Launch) without re-running the steps. A
|
|
91
|
+
* step that is already satisfied is skipped and logged as such; a failing
|
|
92
|
+
* step stops the run and names the broken step in the detail. A step that
|
|
93
|
+
* fails non-fatally (the git sync under the `continueOnSyncFailure`
|
|
94
|
+
* override) keeps the run going and threads `syncFailed` into the result, so
|
|
95
|
+
* the launch continues with the checkout's current version.
|
|
96
|
+
*/
|
|
97
|
+
export declare function runGetSteps(localInfer: LocalInferService, request: GetStepsRequest, log: (chunk: string) => void): Promise<GetStepsResult>;
|
|
98
|
+
//# sourceMappingURL=get-steps.d.ts.map
|
|
@@ -0,0 +1,359 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The shared Get-steps routine both getEngine and launchEngine route through:
|
|
3
|
+
* it runs, in order, (1) the engine's system-dependency install for the host
|
|
4
|
+
* OS (gated by the Play/Run trust gate), (2) the git clone of the engine repo
|
|
5
|
+
* (or the fork) plus the fetch/rebase of a clean checkout, (3) the source
|
|
6
|
+
* build step (the compose engines carry no local build steps), (4) the hf
|
|
7
|
+
* download of the selected model when it is not already present, and (5) the
|
|
8
|
+
* hf download of any selected chat template when it is not already present.
|
|
9
|
+
* Every step streams through the log sink as it lands, and an already-
|
|
10
|
+
* satisfied step is skipped and logged as such, so a Launch that runs the
|
|
11
|
+
* routine before the deploy is idempotent. With an `onStep` reporter (a
|
|
12
|
+
* Launch's progress sink; a standalone Get passes none) each step announces
|
|
13
|
+
* its launch phase only when its work actually starts, so the card's button
|
|
14
|
+
* reads the phase that is running. A Launch can set
|
|
15
|
+
* `continueOnSyncFailure` on the request: when the git sync (rebase) of an
|
|
16
|
+
* existing checkout fails, the run keeps going with the checkout's current
|
|
17
|
+
* version and reports `syncFailed` on the result, so a broken rebase never
|
|
18
|
+
* halts the launch. A standalone Get omits the flag and keeps stopping on a
|
|
19
|
+
* sync failure.
|
|
20
|
+
* @module dsh-plugin-local-infer/ui/ops/get-steps
|
|
21
|
+
*/
|
|
22
|
+
import { autoRebuildEnabled, chatTemplatePresent, checkDeps, commandLogLine, dshEngineCacheDirectory, modelArtifactPresent, resolveModelDirectory, } from '../../../core/lib/index.js';
|
|
23
|
+
import { buildEngineRepo, defaultModelFor, ENGINES, infernixGetDownloads, syncEngineRepo, } from '../../../providers/lib/index.js';
|
|
24
|
+
import { isHfRepoReference } from "../viewmodels/summaryHelpers.js";
|
|
25
|
+
import { resolveBuildMode } from "../viewmodels/deps.js";
|
|
26
|
+
/**
|
|
27
|
+
* resolveEngineDirectory picks the checkout the Get step syncs: the Engine
|
|
28
|
+
* Directory override when it names a path, else the engine's default
|
|
29
|
+
* checkout home `~/.cache/dsh/infer/{engineId}` (one checkout per engine,
|
|
30
|
+
* never a subfolder of a model directory), so a Get with no override still
|
|
31
|
+
* has a real place to live.
|
|
32
|
+
*/
|
|
33
|
+
export function resolveEngineDirectory(engineId, platform) {
|
|
34
|
+
const override = platform?.engineDirectory;
|
|
35
|
+
if (override !== undefined && override.trim() !== '') {
|
|
36
|
+
return override;
|
|
37
|
+
}
|
|
38
|
+
return dshEngineCacheDirectory(engineId);
|
|
39
|
+
}
|
|
40
|
+
/**
|
|
41
|
+
* The marker a Get step reports when it fails non-fatally: the git sync of
|
|
42
|
+
* an existing checkout failed while the `continueOnSyncFailure` override is
|
|
43
|
+
* on, so the runner keeps going (skipping the build) and threads
|
|
44
|
+
* `syncFailed` into the result while the launch continues.
|
|
45
|
+
*/
|
|
46
|
+
const SYNC_FAILED = { kind: 'syncFailed' };
|
|
47
|
+
/**
|
|
48
|
+
* downloadOptions builds the exactOptionalPropertyTypes-safe download options
|
|
49
|
+
* a Get step's hf download runs with: the hub-cache layout flag, the run's
|
|
50
|
+
* cancel signal, the onChunk progress sink, and the run's log sink (emit) so
|
|
51
|
+
* the service writes the `$ <hf command>` line into the same log text the step
|
|
52
|
+
* streams, ahead of the download's output. Each field is present only when the
|
|
53
|
+
* run carries it, so an absent field never writes `undefined`. The model and
|
|
54
|
+
* chat-template steps share it, so the option group (the directory layout, the
|
|
55
|
+
* cancel, the progress sink, the log sink) is built in one place.
|
|
56
|
+
*/
|
|
57
|
+
function downloadOptions(ctx) {
|
|
58
|
+
return {
|
|
59
|
+
useHubCache: ctx.target.useHubCache,
|
|
60
|
+
onLog: ctx.emit,
|
|
61
|
+
...(ctx.request.signal !== undefined ? { signal: ctx.request.signal } : {}),
|
|
62
|
+
...(ctx.onChunk !== undefined ? { onChunk: ctx.onChunk } : {}),
|
|
63
|
+
};
|
|
64
|
+
}
|
|
65
|
+
/**
|
|
66
|
+
* runDepsStep is the Get step's system-dependency install: it runs the
|
|
67
|
+
* install while the Play/Run trust gate is on, and re-checks the deps with
|
|
68
|
+
* a copy/paste note when the gate is off, so a missing dependency aborts the
|
|
69
|
+
* run instead of a broken build.
|
|
70
|
+
*/
|
|
71
|
+
async function runDepsStep(ctx) {
|
|
72
|
+
const { localInfer, request, engine, hardware, emit } = ctx;
|
|
73
|
+
const buildMode = resolveBuildMode(engine, request.config);
|
|
74
|
+
emit(`system dependencies (${buildMode})\n`);
|
|
75
|
+
if (request.allowRunDeps === true) {
|
|
76
|
+
// The prereqs phase runs only here: with the gate on the install actually
|
|
77
|
+
// runs, so the step announces it as it starts (the gate-off re-check
|
|
78
|
+
// below is not a prereqs phase and announces nothing).
|
|
79
|
+
request.onStep?.('prereqs');
|
|
80
|
+
// The install run's log sink is this step's emit, so the service writes
|
|
81
|
+
// each dependency install command's `$ <command>` line into the same run
|
|
82
|
+
// text (ahead of the per-dep results below) before the guarded runner
|
|
83
|
+
// spawns the child.
|
|
84
|
+
const install = await localInfer.runInstall(request.engineId, buildMode, hardware, {
|
|
85
|
+
onLog: emit,
|
|
86
|
+
});
|
|
87
|
+
for (const entry of install.results) {
|
|
88
|
+
emit(` ${entry.id}: ${entry.status}${entry.detail !== undefined ? ` (${entry.detail})` : ''}\n`);
|
|
89
|
+
}
|
|
90
|
+
if (!install.ok) {
|
|
91
|
+
emit('!! a system dependency install failed; copy the install string from the panel\n');
|
|
92
|
+
return { ok: false, detail: 'a system dependency install failed' };
|
|
93
|
+
}
|
|
94
|
+
return null;
|
|
95
|
+
}
|
|
96
|
+
const deps = await localInfer.deps(request.engineId, buildMode, hardware);
|
|
97
|
+
const checks = await checkDeps(deps, hardware);
|
|
98
|
+
let missing = false;
|
|
99
|
+
for (const check of checks) {
|
|
100
|
+
emit(` ${check.dep.id}: ${check.status}\n`);
|
|
101
|
+
if (check.status !== 'satisfied')
|
|
102
|
+
missing = true;
|
|
103
|
+
}
|
|
104
|
+
if (missing) {
|
|
105
|
+
emit('!! a system dependency is missing and one-click install is off; copy the install string from the panel\n');
|
|
106
|
+
return { ok: false, detail: 'a system dependency is missing' };
|
|
107
|
+
}
|
|
108
|
+
return null;
|
|
109
|
+
}
|
|
110
|
+
/**
|
|
111
|
+
* runSyncBuildStep is the Get step's git clone (or fork) of the engine repo,
|
|
112
|
+
* the fetch and rebase of a clean checkout, and the source build step (the
|
|
113
|
+
* compose engines carry no local build steps and pass through). A checkout
|
|
114
|
+
* with local changes aborts, so the user's work is never rebased away. The
|
|
115
|
+
* Auto Rebuild checkbox off skips both, so a launch reads the checkout as-is.
|
|
116
|
+
* Under the `continueOnSyncFailure` override, a failed sync of an existing
|
|
117
|
+
* checkout reports the SYNC_FAILED marker (the run keeps going with the
|
|
118
|
+
* checkout's current version and the build is skipped); a failed clone of a
|
|
119
|
+
* missing checkout stays fatal, since there is no current version to launch.
|
|
120
|
+
*/
|
|
121
|
+
async function runSyncBuildStep(ctx) {
|
|
122
|
+
const { request, directory, emit } = ctx;
|
|
123
|
+
if (!autoRebuildEnabled(request.autoRebuild)) {
|
|
124
|
+
emit('engine sync and build: auto rebuild off, skipped\n');
|
|
125
|
+
return null;
|
|
126
|
+
}
|
|
127
|
+
// The sync and build actually run (the Auto Rebuild checkbox is not off),
|
|
128
|
+
// so the step announces its build phase as it starts; a skipped step
|
|
129
|
+
// announces nothing.
|
|
130
|
+
request.onStep?.('build');
|
|
131
|
+
// The distinct clone and build headers let the Logs-header step chips track
|
|
132
|
+
// the two sub-steps separately: the clone chip runs until the build header
|
|
133
|
+
// lands, and the build chip runs until the model header lands.
|
|
134
|
+
emit(`engine clone: ${request.engineId}\n`);
|
|
135
|
+
const fork = request.platform?.engineFork;
|
|
136
|
+
const sync = await syncEngineRepo(request.host, {
|
|
137
|
+
engineId: request.engineId,
|
|
138
|
+
directory,
|
|
139
|
+
...(fork !== undefined && fork.trim() !== '' ? { fork } : {}),
|
|
140
|
+
}, emit);
|
|
141
|
+
if (!sync.ok) {
|
|
142
|
+
// A dirty checkout already alerted in the sync step; any other failure
|
|
143
|
+
// names its step here.
|
|
144
|
+
if (sync.aborted !== true && sync.detail !== undefined) {
|
|
145
|
+
emit(`!! ${sync.detail}\n`);
|
|
146
|
+
}
|
|
147
|
+
// The `continueOnSyncFailure` override (a Launch-only flag): when the git
|
|
148
|
+
// sync of an existing checkout fails, the run keeps going with the
|
|
149
|
+
// checkout's current version (the build is skipped, since the rebase
|
|
150
|
+
// failed and the checkout stays where it is) and reports the failure
|
|
151
|
+
// non-fatally, so a broken rebase never halts the launch. The sync result
|
|
152
|
+
// names the path it took: a fresh clone (cloned) means no prior checkout
|
|
153
|
+
// to launch, so a clone failure stays fatal; a rebase, fetch, or dirty
|
|
154
|
+
// checkout of an existing checkout (no clone) is non-fatal under the
|
|
155
|
+
// override. Reading the flag keeps the checkout-presence decision in the
|
|
156
|
+
// one place that probes it (the git rev-parse in the sync step).
|
|
157
|
+
if (request.continueOnSyncFailure === true && sync.cloned !== true) {
|
|
158
|
+
emit('!! engine sync failed; continuing with the current version\n');
|
|
159
|
+
return SYNC_FAILED;
|
|
160
|
+
}
|
|
161
|
+
return {
|
|
162
|
+
ok: false,
|
|
163
|
+
...(sync.detail !== undefined ? { detail: sync.detail } : {}),
|
|
164
|
+
};
|
|
165
|
+
}
|
|
166
|
+
// The user's local build command (the card's Build commands field)
|
|
167
|
+
// overrides the engine's default build steps; absent runs the engine's
|
|
168
|
+
// acquisition steps. The host OS picks the engine's OS profile (the
|
|
169
|
+
// Windows vcpkg route and its pwsh.exe shell on a Windows host, the
|
|
170
|
+
// cmake route elsewhere).
|
|
171
|
+
emit(`engine build: ${request.engineId}\n`);
|
|
172
|
+
const build = await buildEngineRepo(request.host, request.engineId, directory, emit, request.platform?.buildCommands, ctx.hardware.os);
|
|
173
|
+
if (!build.ok) {
|
|
174
|
+
if (build.detail !== undefined) {
|
|
175
|
+
emit(`!! ${build.detail}\n`);
|
|
176
|
+
}
|
|
177
|
+
return {
|
|
178
|
+
ok: false,
|
|
179
|
+
...(build.detail !== undefined ? { detail: build.detail } : {}),
|
|
180
|
+
};
|
|
181
|
+
}
|
|
182
|
+
return null;
|
|
183
|
+
}
|
|
184
|
+
/**
|
|
185
|
+
* runModelDownloadStep is the Get step's hf download of the selected model,
|
|
186
|
+
* skipped when the artifact is already present in the model directory (the
|
|
187
|
+
* hub cache under the cache layout; the single presence check the card's
|
|
188
|
+
* Model dropdown and the download route share), plus the Infernix extras a
|
|
189
|
+
* Get leaves ready to launch (the selected DFlash2 drafter and the PLE n-gram
|
|
190
|
+
* volume, pulled through the hf CLI into the model directory). A download
|
|
191
|
+
* failure aborts the run, so a launch never reads a missing model.
|
|
192
|
+
*/
|
|
193
|
+
async function runModelDownloadStep(ctx) {
|
|
194
|
+
const { localInfer, request, target, emit } = ctx;
|
|
195
|
+
const modelId = typeof request.config.model === 'string' ? request.config.model : undefined;
|
|
196
|
+
if (modelId !== undefined) {
|
|
197
|
+
const entry = ctx.modelEntry;
|
|
198
|
+
if (entry === undefined) {
|
|
199
|
+
emit(`model download: ${modelId} has no registered default, skipped\n`);
|
|
200
|
+
}
|
|
201
|
+
else {
|
|
202
|
+
// The shared presence check resolves the deterministic hub-cache
|
|
203
|
+
// snapshot under the cache layout and joins the artifact onto the
|
|
204
|
+
// override under the flat layout (the target's base).
|
|
205
|
+
if (modelArtifactPresent(entry, target.baseDir, target.useHubCache)) {
|
|
206
|
+
emit(`model download: ${modelId} is already present, skipped\n`);
|
|
207
|
+
}
|
|
208
|
+
else {
|
|
209
|
+
// The download actually runs, so the step announces its download
|
|
210
|
+
// phase as it starts; an already-present artifact announces nothing.
|
|
211
|
+
request.onStep?.('download');
|
|
212
|
+
// The `$ <hf download ...>` line is written by the service's download
|
|
213
|
+
// exec site (through downloadOptions' onLog), so the command logs
|
|
214
|
+
// exactly once per run, from wherever the child actually spawns.
|
|
215
|
+
const download = await localInfer.downloadModel(entry, target.directory, downloadOptions(ctx));
|
|
216
|
+
if (!download.ok) {
|
|
217
|
+
emit(`!! ${download.detail ?? 'model download failed'}\n`);
|
|
218
|
+
return { ok: false, detail: download.detail ?? 'a model download failed' };
|
|
219
|
+
}
|
|
220
|
+
}
|
|
221
|
+
}
|
|
222
|
+
}
|
|
223
|
+
else {
|
|
224
|
+
emit('model download: no model selected, skipped\n');
|
|
225
|
+
}
|
|
226
|
+
if (request.engineId === 'infernix') {
|
|
227
|
+
const extras = infernixGetDownloads(request.config, target.directory, target.useHubCache);
|
|
228
|
+
if (extras.length > 0) {
|
|
229
|
+
// The extras actually download (even when the selected artifact was
|
|
230
|
+
// already present), so the step announces its download phase once here.
|
|
231
|
+
request.onStep?.('download');
|
|
232
|
+
}
|
|
233
|
+
for (const command of extras) {
|
|
234
|
+
emit(commandLogLine(command));
|
|
235
|
+
// The Infernix extra downloads stream through the host, so their tqdm
|
|
236
|
+
// lines reach the log sink and the onChunk progress sink together, the
|
|
237
|
+
// way the model and template downloads do. A caller that does not
|
|
238
|
+
// stream progress (onChunk absent) still lands the chunk in the log
|
|
239
|
+
// sink only.
|
|
240
|
+
const stream = request.host.runStream;
|
|
241
|
+
const outcome = stream !== undefined
|
|
242
|
+
? await stream.call(request.host, command, (chunk) => {
|
|
243
|
+
emit(chunk);
|
|
244
|
+
ctx.onChunk?.(chunk);
|
|
245
|
+
}, {
|
|
246
|
+
...(request.signal !== undefined ? { signal: request.signal } : {}),
|
|
247
|
+
})
|
|
248
|
+
: await request.host.run(command);
|
|
249
|
+
if (!outcome.ok) {
|
|
250
|
+
emit(`!! ${command} failed: ${outcome.detail ?? 'unknown'}\n`);
|
|
251
|
+
return { ok: false, detail: 'a model artifact download failed' };
|
|
252
|
+
}
|
|
253
|
+
// The plain-run fallback cannot stream, so the outcome's capped success
|
|
254
|
+
// output tail lands after the `$ <command>` line: the exec rule's
|
|
255
|
+
// append-results half, the way the streaming path already does.
|
|
256
|
+
if (stream === undefined &&
|
|
257
|
+
outcome.stdout !== undefined &&
|
|
258
|
+
outcome.stdout !== '') {
|
|
259
|
+
emit(outcome.stdout.endsWith('\n') ? outcome.stdout : `${outcome.stdout}\n`);
|
|
260
|
+
}
|
|
261
|
+
}
|
|
262
|
+
}
|
|
263
|
+
return null;
|
|
264
|
+
}
|
|
265
|
+
/**
|
|
266
|
+
* runChatTemplateStep is the Get step's hf download of the selected chat
|
|
267
|
+
* template (an HF repo reference the form's combo control offers), skipped
|
|
268
|
+
* when the template file is already present in the model directory.
|
|
269
|
+
*/
|
|
270
|
+
async function runChatTemplateStep(ctx) {
|
|
271
|
+
const { localInfer, request, target, emit } = ctx;
|
|
272
|
+
const template = typeof request.config.chatTemplate === 'string' ? request.config.chatTemplate : '';
|
|
273
|
+
if (template !== '' && isHfRepoReference(template)) {
|
|
274
|
+
// Same shared presence check as the summary's template row: the cache
|
|
275
|
+
// layout resolves the deterministic snapshot, the flat layout joins onto
|
|
276
|
+
// the override.
|
|
277
|
+
if (chatTemplatePresent(template, target.baseDir, target.useHubCache)) {
|
|
278
|
+
emit(`chat template: ${template} is already present, skipped\n`);
|
|
279
|
+
}
|
|
280
|
+
else {
|
|
281
|
+
// The template download actually runs, so the step announces its
|
|
282
|
+
// download phase as it starts.
|
|
283
|
+
request.onStep?.('download');
|
|
284
|
+
// The `$ <hf chat-template ...>` line is written by the service's
|
|
285
|
+
// download exec site (through downloadOptions' onLog), logging once.
|
|
286
|
+
const download = await localInfer.downloadChatTemplate(template, target.directory, downloadOptions(ctx));
|
|
287
|
+
if (!download.ok) {
|
|
288
|
+
emit(`!! ${download.detail ?? 'chat template download failed'}\n`);
|
|
289
|
+
return { ok: false, detail: download.detail ?? 'a chat template download failed' };
|
|
290
|
+
}
|
|
291
|
+
}
|
|
292
|
+
}
|
|
293
|
+
return null;
|
|
294
|
+
}
|
|
295
|
+
/**
|
|
296
|
+
* runGetSteps is the shared Get-steps routine. It runs the five steps in
|
|
297
|
+
* order, streaming each through log and collecting the same text as the
|
|
298
|
+
* result's logs, so a caller can persist the run (a Get) or thread it into
|
|
299
|
+
* the launch's persisted logs (a Launch) without re-running the steps. A
|
|
300
|
+
* step that is already satisfied is skipped and logged as such; a failing
|
|
301
|
+
* step stops the run and names the broken step in the detail. A step that
|
|
302
|
+
* fails non-fatally (the git sync under the `continueOnSyncFailure`
|
|
303
|
+
* override) keeps the run going and threads `syncFailed` into the result, so
|
|
304
|
+
* the launch continues with the checkout's current version.
|
|
305
|
+
*/
|
|
306
|
+
export async function runGetSteps(localInfer, request, log) {
|
|
307
|
+
const chunks = [];
|
|
308
|
+
const emit = (chunk) => {
|
|
309
|
+
chunks.push(chunk);
|
|
310
|
+
log(chunk);
|
|
311
|
+
};
|
|
312
|
+
// ENGINES is a known non-empty constant, so the fallback is always defined.
|
|
313
|
+
const engine = ENGINES.find((entry) => entry.id === request.engineId) ?? ENGINES[0];
|
|
314
|
+
// The shared resolution owns the layout rule: the hub-cache layout (no
|
|
315
|
+
// --local-dir, the models--{ns}--{name} dirs) applies only when the raw
|
|
316
|
+
// config names no model directory; a user override keeps the flat
|
|
317
|
+
// --local-dir target. The target's base is what the presence checks join
|
|
318
|
+
// onto, and its directory names the model directory the steps run: the
|
|
319
|
+
// override, the hub-cache snapshot holding a cached artifact (the hf
|
|
320
|
+
// download result), or the hub cache root when nothing is cached yet. The
|
|
321
|
+
// hub cache root comes from the service seam (created when absent), the
|
|
322
|
+
// same source the summary and the download routes read.
|
|
323
|
+
const selectedModelId = typeof request.config.model === 'string' ? request.config.model : undefined;
|
|
324
|
+
const modelEntry = selectedModelId === undefined ? undefined : defaultModelFor(request.engineId, selectedModelId);
|
|
325
|
+
const ctx = {
|
|
326
|
+
localInfer,
|
|
327
|
+
request,
|
|
328
|
+
engine,
|
|
329
|
+
directory: resolveEngineDirectory(request.engineId, request.platform),
|
|
330
|
+
target: resolveModelDirectory(request.config.modelDirectory, modelEntry, localInfer.defaultModelDirectory()),
|
|
331
|
+
...(modelEntry !== undefined ? { modelEntry } : {}),
|
|
332
|
+
hardware: await localInfer.detectHardware(),
|
|
333
|
+
emit,
|
|
334
|
+
...(request.onChunk !== undefined ? { onChunk: request.onChunk } : {}),
|
|
335
|
+
};
|
|
336
|
+
ctx.emit(`get ${request.engineId} in ${ctx.directory}\n`);
|
|
337
|
+
// A non-fatal sync failure (the `continueOnSyncFailure` override) keeps the
|
|
338
|
+
// run going through the remaining steps; the flag threads into the result
|
|
339
|
+
// so the launch skips the deploy's own git sync and launches the checkout's
|
|
340
|
+
// current version.
|
|
341
|
+
let syncFailed = false;
|
|
342
|
+
for (const step of [runDepsStep, runSyncBuildStep, runModelDownloadStep, runChatTemplateStep]) {
|
|
343
|
+
const failure = await step(ctx);
|
|
344
|
+
if (failure !== null) {
|
|
345
|
+
if ('kind' in failure) {
|
|
346
|
+
syncFailed = true;
|
|
347
|
+
continue;
|
|
348
|
+
}
|
|
349
|
+
return { ...failure, logs: chunks.join('') };
|
|
350
|
+
}
|
|
351
|
+
}
|
|
352
|
+
ctx.emit('get complete\n');
|
|
353
|
+
return {
|
|
354
|
+
ok: true,
|
|
355
|
+
logs: chunks.join(''),
|
|
356
|
+
...(syncFailed ? { syncFailed: true } : {}),
|
|
357
|
+
};
|
|
358
|
+
}
|
|
359
|
+
//# sourceMappingURL=get-steps.js.map
|
|
@@ -0,0 +1,42 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hf CLI download operations: downloadFor runs the download for a default
|
|
3
|
+
* model, and chatTemplateDownloadFor pulls a selected chat template into the
|
|
4
|
+
* model directory. Both resolve the directory through resolveDownloadTarget
|
|
5
|
+
* (the request, the stored config, and the hub cache root in that order,
|
|
6
|
+
* through the shared override rule), so the hub-cache layout rule has one
|
|
7
|
+
* home across the download routes and the card.
|
|
8
|
+
* @module dsh-plugin-local-infer/ui/ops/hf
|
|
9
|
+
*/
|
|
10
|
+
import type { DownloadResult, LocalInferService } from 'dsh-plugin-local-infer/service';
|
|
11
|
+
import type { ChatTemplateDownloadRequest, DownloadRequest } from '../request.ts';
|
|
12
|
+
/**
|
|
13
|
+
* downloadFor runs the hf CLI download for the request's default model: it
|
|
14
|
+
* resolves the entry through the providers' default list (a 404 when no
|
|
15
|
+
* entry names the pair), resolves the directory through
|
|
16
|
+
* resolveDownloadTarget, and runs the download through the service. The run
|
|
17
|
+
* brackets one live hub run under the runLogKey rule keyed on the entry's
|
|
18
|
+
* engine and model (a draft falls back to the engine id): the seed is the
|
|
19
|
+
* "Downloading..." separator, the hf CLI's streamed chunks append as they
|
|
20
|
+
* land, and the settled completion or failure line reaches the hub and the
|
|
21
|
+
* persisted run from one text before the run ends. The optional signal is
|
|
22
|
+
* the card's cancel (the download route's response-close abort, the Get and
|
|
23
|
+
* launch routes' rule): an abort interrupts the in-flight hf child (SIGINT,
|
|
24
|
+
* then SIGTERM) and the run carries the shared "Canceled" line, live and
|
|
25
|
+
* persisted.
|
|
26
|
+
*/
|
|
27
|
+
export declare function downloadFor(localInfer: LocalInferService, request: DownloadRequest, signal?: AbortSignal): Promise<DownloadResult>;
|
|
28
|
+
/**
|
|
29
|
+
* chatTemplateDownloadFor runs the hf CLI download for the request's chat
|
|
30
|
+
* template: it resolves the template repo reference from the request or the
|
|
31
|
+
* stored config's chatTemplate (a 400 when neither names an HF repo
|
|
32
|
+
* reference), resolves the directory through resolveDownloadTarget, and
|
|
33
|
+
* runs the download through the service. The run brackets one live hub run
|
|
34
|
+
* under the "Downloading..." seed and the runLogKey rule (the stored entry
|
|
35
|
+
* matching the engine and model, else the engine id): the hf CLI's streamed
|
|
36
|
+
* chunks append as they land, and the run ends at settle. The optional
|
|
37
|
+
* signal is the card's cancel (the chat-template route's response-close
|
|
38
|
+
* abort, the Get and launch routes' rule): an abort interrupts the in-flight
|
|
39
|
+
* hf child and the live run carries the shared "Canceled" line.
|
|
40
|
+
*/
|
|
41
|
+
export declare function chatTemplateDownloadFor(localInfer: LocalInferService, request: ChatTemplateDownloadRequest, signal?: AbortSignal): Promise<DownloadResult>;
|
|
42
|
+
//# sourceMappingURL=hf.d.ts.map
|
|
@@ -0,0 +1,150 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The hf CLI download operations: downloadFor runs the download for a default
|
|
3
|
+
* model, and chatTemplateDownloadFor pulls a selected chat template into the
|
|
4
|
+
* model directory. Both resolve the directory through resolveDownloadTarget
|
|
5
|
+
* (the request, the stored config, and the hub cache root in that order,
|
|
6
|
+
* through the shared override rule), so the hub-cache layout rule has one
|
|
7
|
+
* home across the download routes and the card.
|
|
8
|
+
* @module dsh-plugin-local-infer/ui/ops/hf
|
|
9
|
+
*/
|
|
10
|
+
import { isModelDirectoryOverridden, modelDownloadTarget } from '../../../core/lib/index.js';
|
|
11
|
+
import { runLogKey } from '../../../service/lib/index.js';
|
|
12
|
+
import { defaultModelFor } from '../../../providers/lib/index.js';
|
|
13
|
+
import { readConfig } from "../config.js";
|
|
14
|
+
import { CANCELED_LINE, DOWNLOAD_RUN_SEED, persistProcessLog } from "./logs.js";
|
|
15
|
+
import { RouteError } from "../route.js";
|
|
16
|
+
import { isHfRepoReference } from "../viewmodels/summaryHelpers.js";
|
|
17
|
+
/**
|
|
18
|
+
* resolveDownloadTarget resolves the directory a download route targets: the
|
|
19
|
+
* request's directory, the stored config's model directory, and the hub
|
|
20
|
+
* cache root, in that order. The first named directory wins (the shared
|
|
21
|
+
* override predicate), then the shared modelDownloadTarget rule decides the
|
|
22
|
+
* layout: a named directory keeps the flat --local-dir target; only when
|
|
23
|
+
* neither names one does the hub-cache layout apply, based on the hub cache
|
|
24
|
+
* root (the service seam: the hf CLI's own download home, which resolves its
|
|
25
|
+
* own snapshot destination and creates the directory when absent), so a
|
|
26
|
+
* download never materializes a snapshot-directory or hub-root override into
|
|
27
|
+
* the config.
|
|
28
|
+
*/
|
|
29
|
+
function resolveDownloadTarget(localInfer, requestDirectory, stored) {
|
|
30
|
+
const named = isModelDirectoryOverridden(requestDirectory)
|
|
31
|
+
? requestDirectory
|
|
32
|
+
: stored.config.modelDirectory;
|
|
33
|
+
return modelDownloadTarget(named, localInfer.defaultModelDirectory());
|
|
34
|
+
}
|
|
35
|
+
/**
|
|
36
|
+
* downloadFor runs the hf CLI download for the request's default model: it
|
|
37
|
+
* resolves the entry through the providers' default list (a 404 when no
|
|
38
|
+
* entry names the pair), resolves the directory through
|
|
39
|
+
* resolveDownloadTarget, and runs the download through the service. The run
|
|
40
|
+
* brackets one live hub run under the runLogKey rule keyed on the entry's
|
|
41
|
+
* engine and model (a draft falls back to the engine id): the seed is the
|
|
42
|
+
* "Downloading..." separator, the hf CLI's streamed chunks append as they
|
|
43
|
+
* land, and the settled completion or failure line reaches the hub and the
|
|
44
|
+
* persisted run from one text before the run ends. The optional signal is
|
|
45
|
+
* the card's cancel (the download route's response-close abort, the Get and
|
|
46
|
+
* launch routes' rule): an abort interrupts the in-flight hf child (SIGINT,
|
|
47
|
+
* then SIGTERM) and the run carries the shared "Canceled" line, live and
|
|
48
|
+
* persisted.
|
|
49
|
+
*/
|
|
50
|
+
export async function downloadFor(localInfer, request, signal) {
|
|
51
|
+
const stored = readConfig();
|
|
52
|
+
const engineId = request.engine ?? stored.engine;
|
|
53
|
+
const modelId = request.model ?? (typeof stored.config.model === 'string' ? stored.config.model : '');
|
|
54
|
+
const entry = defaultModelFor(engineId, modelId);
|
|
55
|
+
if (entry === undefined) {
|
|
56
|
+
throw new RouteError(404, `no default model is registered for "${engineId}/${modelId}"`);
|
|
57
|
+
}
|
|
58
|
+
const { baseDir, useHubCache } = resolveDownloadTarget(localInfer, request.directory, stored);
|
|
59
|
+
// The key rule prices the model this download fetches, so the run lands on
|
|
60
|
+
// the stored entry for that engine and model, not the draft's.
|
|
61
|
+
const runKey = runLogKey(stored.providers, engineId, undefined, {
|
|
62
|
+
...stored.config,
|
|
63
|
+
...(modelId === '' ? {} : { model: modelId }),
|
|
64
|
+
});
|
|
65
|
+
localInfer.beginRun(runKey, DOWNLOAD_RUN_SEED);
|
|
66
|
+
// The service writes the rendered hf command's `$ <command>` line through
|
|
67
|
+
// onLog before it spawns the child: it streams into the live hub right away
|
|
68
|
+
// and rides the persisted section below, so the command line reads exactly
|
|
69
|
+
// once per run in both readers, ahead of the CLI's output.
|
|
70
|
+
let commandLine = '';
|
|
71
|
+
try {
|
|
72
|
+
const result = await localInfer.downloadModel(entry, baseDir, {
|
|
73
|
+
useHubCache,
|
|
74
|
+
...(signal !== undefined ? { signal } : {}),
|
|
75
|
+
onChunk: (chunk) => {
|
|
76
|
+
localInfer.appendRunLog(runKey, chunk);
|
|
77
|
+
},
|
|
78
|
+
onLog: (line) => {
|
|
79
|
+
commandLine += line;
|
|
80
|
+
localInfer.appendRunLog(runKey, line);
|
|
81
|
+
},
|
|
82
|
+
});
|
|
83
|
+
// The settle line reads the same in the live run and the persisted one:
|
|
84
|
+
// the "Downloading..." separator leads the stored run so the Logs
|
|
85
|
+
// section and the log file read the download as a fresh process section.
|
|
86
|
+
// A cancel appends the shared "Canceled" line, the Get and launch
|
|
87
|
+
// routes' mark, so the run reads as canceled wherever it is read.
|
|
88
|
+
const line = result.ok
|
|
89
|
+
? 'download complete\n'
|
|
90
|
+
: `!! download failed${result.detail !== undefined ? `: ${result.detail}` : ''}\n`;
|
|
91
|
+
const settled = signal?.aborted === true ? `${line}${CANCELED_LINE}` : line;
|
|
92
|
+
localInfer.appendRunLog(runKey, settled);
|
|
93
|
+
persistProcessLog(`${DOWNLOAD_RUN_SEED}${commandLine}${settled}`);
|
|
94
|
+
return result;
|
|
95
|
+
}
|
|
96
|
+
finally {
|
|
97
|
+
localInfer.endRun(runKey);
|
|
98
|
+
}
|
|
99
|
+
}
|
|
100
|
+
/**
|
|
101
|
+
* chatTemplateDownloadFor runs the hf CLI download for the request's chat
|
|
102
|
+
* template: it resolves the template repo reference from the request or the
|
|
103
|
+
* stored config's chatTemplate (a 400 when neither names an HF repo
|
|
104
|
+
* reference), resolves the directory through resolveDownloadTarget, and
|
|
105
|
+
* runs the download through the service. The run brackets one live hub run
|
|
106
|
+
* under the "Downloading..." seed and the runLogKey rule (the stored entry
|
|
107
|
+
* matching the engine and model, else the engine id): the hf CLI's streamed
|
|
108
|
+
* chunks append as they land, and the run ends at settle. The optional
|
|
109
|
+
* signal is the card's cancel (the chat-template route's response-close
|
|
110
|
+
* abort, the Get and launch routes' rule): an abort interrupts the in-flight
|
|
111
|
+
* hf child and the live run carries the shared "Canceled" line.
|
|
112
|
+
*/
|
|
113
|
+
export async function chatTemplateDownloadFor(localInfer, request, signal) {
|
|
114
|
+
const stored = readConfig();
|
|
115
|
+
let template = typeof request.template === 'string' ? request.template : '';
|
|
116
|
+
if (template.trim() === '') {
|
|
117
|
+
template = typeof stored.config.chatTemplate === 'string' ? stored.config.chatTemplate : '';
|
|
118
|
+
}
|
|
119
|
+
if (!isHfRepoReference(template)) {
|
|
120
|
+
throw new RouteError(400, `the chat template must be an HF repo reference, got "${template || '(none)'}"`);
|
|
121
|
+
}
|
|
122
|
+
const { baseDir, useHubCache } = resolveDownloadTarget(localInfer, request.directory, stored);
|
|
123
|
+
const runKey = runLogKey(stored.providers, request.engine ?? stored.engine, undefined, stored.config);
|
|
124
|
+
localInfer.beginRun(runKey, DOWNLOAD_RUN_SEED);
|
|
125
|
+
try {
|
|
126
|
+
const result = await localInfer.downloadChatTemplate(template, baseDir, {
|
|
127
|
+
useHubCache,
|
|
128
|
+
...(signal !== undefined ? { signal } : {}),
|
|
129
|
+
onChunk: (chunk) => {
|
|
130
|
+
localInfer.appendRunLog(runKey, chunk);
|
|
131
|
+
},
|
|
132
|
+
// The service writes the rendered chat-template pull's `$ <command>`
|
|
133
|
+
// line through onLog before it spawns the child, so the live run reads
|
|
134
|
+
// the command ahead of the CLI's output, exactly once.
|
|
135
|
+
onLog: (line) => {
|
|
136
|
+
localInfer.appendRunLog(runKey, line);
|
|
137
|
+
},
|
|
138
|
+
});
|
|
139
|
+
// A cancel marks the live run canceled; the template pull's outcome
|
|
140
|
+
// rides the card's template cell, not the persisted run, so no persist.
|
|
141
|
+
if (signal?.aborted === true) {
|
|
142
|
+
localInfer.appendRunLog(runKey, CANCELED_LINE);
|
|
143
|
+
}
|
|
144
|
+
return result;
|
|
145
|
+
}
|
|
146
|
+
finally {
|
|
147
|
+
localInfer.endRun(runKey);
|
|
148
|
+
}
|
|
149
|
+
}
|
|
150
|
+
//# sourceMappingURL=hf.js.map
|