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.
Files changed (251) hide show
  1. package/README.md +32 -6
  2. package/cordis.patch.yml +7 -0
  3. package/docs/zh/README.md +24 -4
  4. package/dsh/client.js +4200 -4049
  5. package/package.json +33 -11
  6. package/packages/core/lib/adapter.d.ts +177 -11
  7. package/packages/core/lib/adapter.js +74 -1
  8. package/packages/core/lib/config.d.ts +1 -1
  9. package/packages/core/lib/config.js +1 -1
  10. package/packages/core/lib/debug.d.ts +1 -1
  11. package/packages/core/lib/debug.js +1 -1
  12. package/packages/core/lib/defaults.d.ts +1 -1
  13. package/packages/core/lib/defaults.js +1 -1
  14. package/packages/core/lib/deps.d.ts +48 -20
  15. package/packages/core/lib/deps.js +24 -8
  16. package/packages/core/lib/estimator.d.ts +1 -1
  17. package/packages/core/lib/estimator.js +1 -1
  18. package/packages/core/lib/guideline.d.ts +1 -1
  19. package/packages/core/lib/guideline.js +1 -1
  20. package/packages/core/lib/hardware.d.ts +1 -1
  21. package/packages/core/lib/hardware.js +1 -1
  22. package/packages/core/lib/hf-cache.d.ts +70 -0
  23. package/packages/core/lib/hf-cache.js +83 -0
  24. package/packages/core/lib/index.d.ts +16 -9
  25. package/packages/core/lib/index.js +10 -6
  26. package/packages/core/lib/infer-cache.d.ts +39 -0
  27. package/packages/core/lib/infer-cache.js +53 -0
  28. package/packages/core/lib/launch-command.d.ts +8 -4
  29. package/packages/core/lib/launch-command.js +13 -6
  30. package/packages/core/lib/launch-record.d.ts +1 -1
  31. package/packages/core/lib/launch-record.js +1 -1
  32. package/packages/core/lib/logs.d.ts +8 -1
  33. package/packages/core/lib/logs.js +12 -4
  34. package/packages/core/lib/models.d.ts +120 -14
  35. package/packages/core/lib/models.js +209 -17
  36. package/packages/core/lib/parameter.d.ts +31 -3
  37. package/packages/core/lib/parameter.js +1 -1
  38. package/packages/core/lib/progress.d.ts +54 -0
  39. package/packages/core/lib/progress.js +120 -0
  40. package/packages/core/lib/registrar.d.ts +25 -14
  41. package/packages/core/lib/registrar.js +30 -10
  42. package/packages/core/lib/reserve.d.ts +11 -3
  43. package/packages/core/lib/reserve.js +6 -4
  44. package/packages/core/lib/status.d.ts +12 -6
  45. package/packages/core/lib/status.js +21 -10
  46. package/packages/core/lib/sudo.d.ts +80 -0
  47. package/packages/core/lib/sudo.js +78 -0
  48. package/packages/core/package.json +1 -1
  49. package/packages/orchestrator/lib/config.d.ts +63 -0
  50. package/packages/orchestrator/lib/config.js +111 -0
  51. package/packages/orchestrator/lib/index.d.ts +51 -0
  52. package/packages/orchestrator/lib/index.js +73 -0
  53. package/packages/orchestrator/lib/route.d.ts +60 -0
  54. package/packages/orchestrator/lib/route.js +159 -0
  55. package/packages/orchestrator/locale/en.json +6 -0
  56. package/packages/orchestrator/package.json +39 -0
  57. package/packages/orchestrator/prompt.md +87 -0
  58. package/packages/providers/lib/acquire.d.ts +95 -15
  59. package/packages/providers/lib/acquire.js +239 -40
  60. package/packages/providers/lib/adapters.d.ts +155 -221
  61. package/packages/providers/lib/adapters.js +589 -935
  62. package/packages/providers/lib/debug.d.ts +1 -1
  63. package/packages/providers/lib/debug.js +1 -1
  64. package/packages/providers/lib/deps.d.ts +31 -212
  65. package/packages/providers/lib/deps.js +71 -205
  66. package/packages/providers/lib/engines/basalt/basalt.d.ts +130 -0
  67. package/packages/providers/lib/engines/basalt/basalt.js +304 -0
  68. package/packages/providers/lib/engines/basalt/basaltAdapter.d.ts +85 -0
  69. package/packages/providers/lib/engines/basalt/basaltAdapter.js +439 -0
  70. package/packages/providers/lib/engines/basalt/basaltLinux.d.ts +23 -0
  71. package/packages/providers/lib/engines/basalt/basaltLinux.js +47 -0
  72. package/packages/providers/lib/engines/basalt/basaltMacOS.d.ts +17 -0
  73. package/packages/providers/lib/engines/basalt/basaltMacOS.js +19 -0
  74. package/packages/providers/lib/engines/basalt/basaltWindows.d.ts +24 -0
  75. package/packages/providers/lib/engines/basalt/basaltWindows.js +49 -0
  76. package/packages/providers/lib/engines/engineOs.d.ts +24 -0
  77. package/packages/providers/lib/engines/engineOs.js +17 -0
  78. package/packages/providers/lib/{hyperqwen.d.ts → engines/hyperqwen/hyperqwen.d.ts} +2 -2
  79. package/packages/providers/lib/{hyperqwen.js → engines/hyperqwen/hyperqwen.js} +14 -2
  80. package/packages/providers/lib/engines/hyperqwen/hyperqwenAdapter.d.ts +38 -0
  81. package/packages/providers/lib/engines/hyperqwen/hyperqwenAdapter.js +115 -0
  82. package/packages/providers/lib/engines/hyperqwen/hyperqwenArch.d.ts +9 -0
  83. package/packages/providers/lib/engines/hyperqwen/hyperqwenArch.js +9 -0
  84. package/packages/providers/lib/engines/hyperqwen/hyperqwenDebian.d.ts +9 -0
  85. package/packages/providers/lib/engines/hyperqwen/hyperqwenDebian.js +9 -0
  86. package/packages/providers/lib/engines/hyperqwen/hyperqwenFedora.d.ts +9 -0
  87. package/packages/providers/lib/engines/hyperqwen/hyperqwenFedora.js +9 -0
  88. package/packages/providers/lib/engines/hyperqwen/hyperqwenLinux.d.ts +10 -0
  89. package/packages/providers/lib/engines/hyperqwen/hyperqwenLinux.js +14 -0
  90. package/packages/providers/lib/engines/hyperqwen/hyperqwenMacOS.d.ts +9 -0
  91. package/packages/providers/lib/engines/hyperqwen/hyperqwenMacOS.js +9 -0
  92. package/packages/providers/lib/engines/hyperqwen/hyperqwenWindows.d.ts +9 -0
  93. package/packages/providers/lib/engines/hyperqwen/hyperqwenWindows.js +9 -0
  94. package/packages/providers/lib/{infernix.d.ts → engines/infernix/infernix.d.ts} +7 -4
  95. package/packages/providers/lib/{infernix.js → engines/infernix/infernix.js} +53 -8
  96. package/packages/providers/lib/engines/infernix/infernixAdapter.d.ts +52 -0
  97. package/packages/providers/lib/engines/infernix/infernixAdapter.js +235 -0
  98. package/packages/providers/lib/engines/infernix/infernixArch.d.ts +9 -0
  99. package/packages/providers/lib/engines/infernix/infernixArch.js +9 -0
  100. package/packages/providers/lib/engines/infernix/infernixDebian.d.ts +9 -0
  101. package/packages/providers/lib/engines/infernix/infernixDebian.js +9 -0
  102. package/packages/providers/lib/engines/infernix/infernixFedora.d.ts +9 -0
  103. package/packages/providers/lib/engines/infernix/infernixFedora.js +9 -0
  104. package/packages/providers/lib/engines/infernix/infernixLinux.d.ts +17 -0
  105. package/packages/providers/lib/engines/infernix/infernixLinux.js +35 -0
  106. package/packages/providers/lib/engines/infernix/infernixMacOS.d.ts +16 -0
  107. package/packages/providers/lib/engines/infernix/infernixMacOS.js +18 -0
  108. package/packages/providers/lib/engines/infernix/infernixWindows.d.ts +16 -0
  109. package/packages/providers/lib/engines/infernix/infernixWindows.js +34 -0
  110. package/packages/providers/lib/{llamacpp.d.ts → engines/llamacpp/llamacpp.d.ts} +2 -2
  111. package/packages/providers/lib/{llamacpp.js → engines/llamacpp/llamacpp.js} +12 -2
  112. package/packages/providers/lib/engines/llamacpp/llamacppAdapter.d.ts +50 -0
  113. package/packages/providers/lib/engines/llamacpp/llamacppAdapter.js +274 -0
  114. package/packages/providers/lib/engines/llamacpp/llamacppArch.d.ts +9 -0
  115. package/packages/providers/lib/engines/llamacpp/llamacppArch.js +9 -0
  116. package/packages/providers/lib/engines/llamacpp/llamacppDebian.d.ts +9 -0
  117. package/packages/providers/lib/engines/llamacpp/llamacppDebian.js +9 -0
  118. package/packages/providers/lib/engines/llamacpp/llamacppFedora.d.ts +9 -0
  119. package/packages/providers/lib/engines/llamacpp/llamacppFedora.js +9 -0
  120. package/packages/providers/lib/engines/llamacpp/llamacppLinux.d.ts +17 -0
  121. package/packages/providers/lib/engines/llamacpp/llamacppLinux.js +28 -0
  122. package/packages/providers/lib/engines/llamacpp/llamacppMacOS.d.ts +15 -0
  123. package/packages/providers/lib/engines/llamacpp/llamacppMacOS.js +17 -0
  124. package/packages/providers/lib/engines/llamacpp/llamacppWindows.d.ts +15 -0
  125. package/packages/providers/lib/engines/llamacpp/llamacppWindows.js +26 -0
  126. package/packages/providers/lib/{ninfer.d.ts → engines/ninfer/ninfer.d.ts} +2 -2
  127. package/packages/providers/lib/{ninfer.js → engines/ninfer/ninfer.js} +25 -3
  128. package/packages/providers/lib/engines/ninfer/ninferAdapter.d.ts +81 -0
  129. package/packages/providers/lib/engines/ninfer/ninferAdapter.js +392 -0
  130. package/packages/providers/lib/engines/ninfer/ninferArch.d.ts +9 -0
  131. package/packages/providers/lib/engines/ninfer/ninferArch.js +9 -0
  132. package/packages/providers/lib/engines/ninfer/ninferDebian.d.ts +9 -0
  133. package/packages/providers/lib/engines/ninfer/ninferDebian.js +9 -0
  134. package/packages/providers/lib/engines/ninfer/ninferFedora.d.ts +9 -0
  135. package/packages/providers/lib/engines/ninfer/ninferFedora.js +9 -0
  136. package/packages/providers/lib/engines/ninfer/ninferLinux.d.ts +17 -0
  137. package/packages/providers/lib/engines/ninfer/ninferLinux.js +37 -0
  138. package/packages/providers/lib/engines/ninfer/ninferMacOS.d.ts +15 -0
  139. package/packages/providers/lib/engines/ninfer/ninferMacOS.js +17 -0
  140. package/packages/providers/lib/engines/ninfer/ninferWindows.d.ts +29 -0
  141. package/packages/providers/lib/engines/ninfer/ninferWindows.js +59 -0
  142. package/packages/providers/lib/engines/strata/strata.d.ts +1 -0
  143. package/packages/providers/lib/engines/strata/strata.js +264 -0
  144. package/packages/providers/lib/engines/strata/strataAdapter.d.ts +97 -0
  145. package/packages/providers/lib/engines/strata/strataAdapter.js +463 -0
  146. package/packages/providers/lib/engines/strata/strataArch.d.ts +9 -0
  147. package/packages/providers/lib/engines/strata/strataArch.js +9 -0
  148. package/packages/providers/lib/engines/strata/strataDebian.d.ts +9 -0
  149. package/packages/providers/lib/engines/strata/strataDebian.js +9 -0
  150. package/packages/providers/lib/engines/strata/strataFedora.d.ts +9 -0
  151. package/packages/providers/lib/engines/strata/strataFedora.js +9 -0
  152. package/packages/providers/lib/engines/strata/strataLinux.d.ts +21 -0
  153. package/packages/providers/lib/engines/strata/strataLinux.js +30 -0
  154. package/packages/providers/lib/engines/strata/strataMacOS.d.ts +16 -0
  155. package/packages/providers/lib/engines/strata/strataMacOS.js +17 -0
  156. package/packages/providers/lib/engines/strata/strataWindows.d.ts +27 -0
  157. package/packages/providers/lib/engines/strata/strataWindows.js +37 -0
  158. package/packages/providers/lib/engines.d.ts +8 -5
  159. package/packages/providers/lib/engines.js +22 -11
  160. package/packages/providers/lib/guidelines.d.ts +5 -4
  161. package/packages/providers/lib/guidelines.js +18 -5
  162. package/packages/providers/lib/index.d.ts +33 -24
  163. package/packages/providers/lib/index.js +46 -24
  164. package/packages/providers/lib/model-defaults.d.ts +10 -5
  165. package/packages/providers/lib/model-defaults.js +47 -5
  166. package/packages/providers/lib/platform.d.ts +8 -5
  167. package/packages/providers/lib/platform.js +27 -7
  168. package/packages/providers/lib/presets.d.ts +6 -4
  169. package/packages/providers/lib/presets.js +53 -5
  170. package/packages/providers/lib/systemDeps.d.ts +313 -0
  171. package/packages/providers/lib/systemDeps.js +284 -0
  172. package/packages/providers/lib/vram.d.ts +34 -8
  173. package/packages/providers/lib/vram.js +81 -8
  174. package/packages/providers/package.json +2 -2
  175. package/packages/service/lib/index.d.ts +187 -23
  176. package/packages/service/lib/index.js +667 -90
  177. package/packages/service/lib/launch-target.d.ts +19 -0
  178. package/packages/service/lib/launch-target.js +28 -0
  179. package/packages/service/lib/run-logs.d.ts +72 -0
  180. package/packages/service/lib/run-logs.js +125 -0
  181. package/packages/service/lib/types.d.ts +166 -8
  182. package/packages/service/lib/types.js +1 -1
  183. package/packages/service/package.json +2 -2
  184. package/packages/tool/lib/index.d.ts +1 -1
  185. package/packages/tool/lib/index.js +1 -1
  186. package/packages/tool/package.json +2 -2
  187. package/packages/ui/lib/config.d.ts +89 -0
  188. package/packages/ui/lib/config.js +251 -0
  189. package/packages/ui/lib/deps.d.ts +4 -4
  190. package/packages/ui/lib/deps.js +1 -1
  191. package/packages/ui/lib/form.d.ts +1 -1
  192. package/packages/ui/lib/form.js +1 -1
  193. package/packages/ui/lib/index.d.ts +7 -1
  194. package/packages/ui/lib/index.js +12 -2
  195. package/packages/ui/lib/meter.d.ts +1 -1
  196. package/packages/ui/lib/meter.js +1 -1
  197. package/packages/ui/lib/ops/engine.d.ts +216 -0
  198. package/packages/ui/lib/ops/engine.js +697 -0
  199. package/packages/ui/lib/ops/get-steps.d.ts +98 -0
  200. package/packages/ui/lib/ops/get-steps.js +359 -0
  201. package/packages/ui/lib/ops/hf.d.ts +42 -0
  202. package/packages/ui/lib/ops/hf.js +150 -0
  203. package/packages/ui/lib/ops/logs.d.ts +78 -0
  204. package/packages/ui/lib/ops/logs.js +119 -0
  205. package/packages/ui/lib/ops/model.d.ts +71 -0
  206. package/packages/ui/lib/ops/model.js +123 -0
  207. package/packages/ui/lib/request.d.ts +106 -0
  208. package/packages/ui/lib/request.js +80 -0
  209. package/packages/ui/lib/route.d.ts +106 -422
  210. package/packages/ui/lib/route.js +136 -1845
  211. package/packages/ui/lib/routes/chat-template.d.ts +1 -0
  212. package/packages/ui/lib/routes/chat-template.js +1 -0
  213. package/packages/ui/lib/routes/deps.d.ts +1 -0
  214. package/packages/ui/lib/routes/deps.js +1 -0
  215. package/packages/ui/lib/routes/download.d.ts +1 -0
  216. package/packages/ui/lib/routes/download.js +1 -0
  217. package/packages/ui/lib/routes/get.d.ts +1 -0
  218. package/packages/ui/lib/routes/get.js +106 -0
  219. package/packages/ui/lib/routes/install.d.ts +16 -0
  220. package/packages/ui/lib/routes/install.js +36 -0
  221. package/packages/ui/lib/routes/launch.d.ts +24 -0
  222. package/packages/ui/lib/routes/launch.js +74 -0
  223. package/packages/ui/lib/routes/logs.d.ts +57 -0
  224. package/packages/ui/lib/routes/logs.js +117 -0
  225. package/packages/ui/lib/routes/provider-delete.d.ts +15 -0
  226. package/packages/ui/lib/routes/provider-delete.js +37 -0
  227. package/packages/ui/lib/routes/register.d.ts +16 -0
  228. package/packages/ui/lib/routes/register.js +28 -0
  229. package/packages/ui/lib/routes/save.d.ts +18 -0
  230. package/packages/ui/lib/routes/save.js +159 -0
  231. package/packages/ui/lib/routes/stop.d.ts +19 -0
  232. package/packages/ui/lib/routes/stop.js +32 -0
  233. package/packages/ui/lib/routes/stream.d.ts +40 -0
  234. package/packages/ui/lib/routes/stream.js +68 -0
  235. package/packages/ui/lib/routes/summary.d.ts +15 -0
  236. package/packages/ui/lib/routes/summary.js +26 -0
  237. package/packages/ui/lib/routes/unregister.d.ts +14 -0
  238. package/packages/ui/lib/routes/unregister.js +26 -0
  239. package/packages/ui/lib/viewmodels/deps.d.ts +1 -0
  240. package/packages/ui/lib/viewmodels/deps.js +1 -0
  241. package/packages/ui/lib/viewmodels/depsHelpers.d.ts +1 -0
  242. package/packages/ui/lib/viewmodels/depsHelpers.js +94 -0
  243. package/packages/ui/lib/viewmodels/summary.d.ts +145 -0
  244. package/packages/ui/lib/viewmodels/summary.js +245 -0
  245. package/packages/ui/lib/viewmodels/summaryHelpers.d.ts +30 -0
  246. package/packages/ui/lib/viewmodels/summaryHelpers.js +42 -0
  247. package/packages/ui/lib/warnings.d.ts +1 -1
  248. package/packages/ui/lib/warnings.js +1 -1
  249. package/packages/ui/package.json +4 -4
  250. package/packages/providers/lib/strata.d.ts +0 -15
  251. package/packages/providers/lib/strata.js +0 -14
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+
@@ -0,0 +1 @@
1
+
@@ -0,0 +1,106 @@
1
+ /**
2
+ * The POST /local-infer/get route: the Get step. Its answer streams as
3
+ * NDJSON progress events only (a structured download state folded from the
4
+ * hf download's tqdm stderr): the run's log text reaches the card through
5
+ * the per-provider run-log stream (the GET /local-infer/logs route fed by the
6
+ * hub), so one line never arrives twice. The full run still collects,
7
+ * persists as the last-run logs in plain text, and feeds the live hub, so
8
+ * the log file, the Logs section, and the streamed run read the run the same
9
+ * way.
10
+ * @module dsh-plugin-local-infer/ui/routes/get
11
+ */
12
+ import { runLogKey } from '../../../service/lib/index.js';
13
+ import { parseStoredPlatformConfig } from "../config.js";
14
+ import { CANCELED_LINE, GET_EVENT_PREFIX, getEngine, resolveStoredRequest } from "../ops/engine.js";
15
+ import { captureRunBaseline, finishRunSection, GET_RUN_SEED } from "../ops/logs.js";
16
+ import { defineRoute } from "../route.js";
17
+ import { abortOnResponseClose, ndjsonLine, throttledProgressSink } from "./stream.js";
18
+ /**
19
+ * getRoute builds the POST /local-infer/get route definition the register
20
+ * step holds by an effect. The optional getHost is the lifecycle host the
21
+ * git and build steps run through; it defaults to the node host, and a test
22
+ * injects a stub so the route never clones a real repo in CI.
23
+ */
24
+ export function getRoute(localInfer, getHost) {
25
+ return defineRoute({
26
+ name: 'local-infer-get',
27
+ path: '/local-infer/get',
28
+ method: 'POST',
29
+ failStatus: 400,
30
+ tooLargeMessage: 'get payload too large',
31
+ run: async ({ body }, res) => {
32
+ const request = {};
33
+ if (typeof body.engine === 'string') {
34
+ request.engine = body.engine;
35
+ }
36
+ if (body.config && typeof body.config === 'object') {
37
+ request.config = body.config;
38
+ }
39
+ const platform = parseStoredPlatformConfig(body.platform);
40
+ if (platform !== undefined) {
41
+ request.platform = platform;
42
+ }
43
+ res.ndjsonStream();
44
+ // The run key the live hub buffers this Get under, the shared runLogKey
45
+ // rule (the request names no provider, so the stored entry matching the
46
+ // engine and model wins, and a draft falls back to the engine id).
47
+ const { stored, engineId, config } = resolveStoredRequest(request);
48
+ const runKey = runLogKey(stored.providers, engineId, undefined, config);
49
+ localInfer.beginRun(runKey, GET_RUN_SEED);
50
+ // The stored last-run logs as they stand before the run persists
51
+ // anything: the sudo observer persists its note while the run hangs on
52
+ // the prompt, and finishRunSection closes the run over the baseline so
53
+ // that provisional line and the collected run text persist once.
54
+ const baseline = captureRunBaseline();
55
+ let collected = '';
56
+ // The log sink collects the plain-text run (the persisted log) and
57
+ // appends the same chunk to the live hub, whose run-log stream carries
58
+ // the text to the card's Logs pane (Q2: one streamed display path).
59
+ // The route's own answer no longer mirrors the text as log events, so
60
+ // a line never lands twice.
61
+ const log = (text) => {
62
+ collected += text;
63
+ localInfer.appendRunLog(runKey, text);
64
+ };
65
+ // The hf download's raw stderr sink: the core chunk folder turns the
66
+ // tqdm lines into a structured state, and the sink emits a progress
67
+ // event when a fold yields one (throttled to the half-second cadence).
68
+ const onChunk = throttledProgressSink((progress) => ndjsonLine(res, { progress }));
69
+ // The card's provider-form Cancel aborts the fetch, which closes the
70
+ // response: the abort interrupts the in-flight hf child (SIGINT, then
71
+ // SIGTERM). Resume is within-invocation only; a killed run re-downloads
72
+ // from zero on the re-run (the orphaned .incomplete blob lingers until
73
+ // `hf cache prune`). A close after the run settled is the normal end,
74
+ // not a cancel.
75
+ const { signal, markFinished } = abortOnResponseClose(res);
76
+ try {
77
+ try {
78
+ await getEngine(localInfer, request, log, getHost, signal, onChunk);
79
+ }
80
+ catch (error) {
81
+ log(`${GET_EVENT_PREFIX}get failed: ${String(error?.message ?? error)}\n`);
82
+ }
83
+ // A cancel that closed the stream appends the "Canceled" line, so the
84
+ // persisted run (and the log file) read the run as canceled, the same
85
+ // line the card writes to its Logs buffer on the Cancel.
86
+ if (signal.aborted) {
87
+ log(`${CANCELED_LINE}`);
88
+ }
89
+ markFinished();
90
+ // The "Getting engine and model..." separator leads the persisted
91
+ // run and the live run's seed, so the Logs section, the log file, and
92
+ // the streamed run read the run as one fresh process section.
93
+ // finishRunSection closes the run over the baseline captured before
94
+ // it started, not a second append over its own provisional notes.
95
+ finishRunSection(baseline, `${GET_RUN_SEED}${collected}`);
96
+ res.end();
97
+ }
98
+ finally {
99
+ // The bracket closes on every settle path, cancel and failure
100
+ // included: the key's running flag clears after finishRunSection.
101
+ localInfer.endRun(runKey);
102
+ }
103
+ },
104
+ });
105
+ }
106
+ //# sourceMappingURL=get.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The POST /local-infer/install route: the Play/Run path. It refuses with a
3
+ * 409 while the trust gate is off (the copy/paste path is always the
4
+ * fallback), runs the install through the service, and answers with the
5
+ * install result and the refreshed deps model, so the card re-renders the
6
+ * gate from the same re-check the install ran.
7
+ * @module dsh-plugin-local-infer/ui/routes/install
8
+ */
9
+ import type { LocalInferService } from 'dsh-plugin-local-infer/service';
10
+ import type { LocalInferRoute } from '../route.ts';
11
+ /**
12
+ * installRoute builds the POST /local-infer/install route definition the
13
+ * register step holds by an effect.
14
+ */
15
+ export declare function installRoute(localInfer: LocalInferService): LocalInferRoute;
16
+ //# sourceMappingURL=install.d.ts.map
@@ -0,0 +1,36 @@
1
+ /**
2
+ * The POST /local-infer/install route: the Play/Run path. It refuses with a
3
+ * 409 while the trust gate is off (the copy/paste path is always the
4
+ * fallback), runs the install through the service, and answers with the
5
+ * install result and the refreshed deps model, so the card re-renders the
6
+ * gate from the same re-check the install ran.
7
+ * @module dsh-plugin-local-infer/ui/routes/install
8
+ */
9
+ import { defineRoute } from "../route.js";
10
+ import { runInstallFor } from "../viewmodels/depsHelpers.js";
11
+ /**
12
+ * installRoute builds the POST /local-infer/install route definition the
13
+ * register step holds by an effect.
14
+ */
15
+ export function installRoute(localInfer) {
16
+ return defineRoute({
17
+ name: 'local-infer-install',
18
+ path: '/local-infer/install',
19
+ method: 'POST',
20
+ failStatus: 500,
21
+ tooLargeMessage: 'install payload too large',
22
+ run: async ({ body }, res) => {
23
+ // exactOptionalPropertyTypes: build the request object with only the
24
+ // keys that are present, so an absent value never writes `undefined`.
25
+ const request = {};
26
+ if (typeof body.engine === 'string') {
27
+ request.engine = body.engine;
28
+ }
29
+ if (body.config && typeof body.config === 'object') {
30
+ request.config = body.config;
31
+ }
32
+ res.json(200, await runInstallFor(localInfer, request));
33
+ },
34
+ });
35
+ }
36
+ //# sourceMappingURL=install.js.map
@@ -0,0 +1,24 @@
1
+ /**
2
+ * The POST /local-infer/launch route: it renders the plan the registered
3
+ * adapter produces and runs the service's launch entry point (deploy, then
4
+ * the health poll). The launch streams its progress as NDJSON: a step event
5
+ * as each phase (prereqs, download, build, launch) begins, a progress event
6
+ * when the Get-steps hf download's tqdm stderr folds into a structured
7
+ * state, a sudo event when a guarded command waits for the user's password
8
+ * on the launching CLI, then a final result event. The card's Launch control
9
+ * reads the step that is running and times out only the launch (health-poll)
10
+ * step; the rebuild steps run as long as they need to.
11
+ * @module dsh-plugin-local-infer/ui/routes/launch
12
+ */
13
+ import type { LifecycleHost } from 'dsh-plugin-local-infer/core';
14
+ import type { LocalInferService } from 'dsh-plugin-local-infer/service';
15
+ import type { LocalInferRoute } from '../route.ts';
16
+ /**
17
+ * launchRoute builds the POST /local-infer/launch route definition the
18
+ * register step holds by an effect. The optional launchHost is the lifecycle
19
+ * host the launch's Get steps (git sync, build) run through; it defaults to
20
+ * the node host, and a test injects a stub so the route never clones a real
21
+ * repo in CI.
22
+ */
23
+ export declare function launchRoute(localInfer: LocalInferService, launchHost?: LifecycleHost): LocalInferRoute;
24
+ //# sourceMappingURL=launch.d.ts.map
@@ -0,0 +1,74 @@
1
+ /**
2
+ * The POST /local-infer/launch route: it renders the plan the registered
3
+ * adapter produces and runs the service's launch entry point (deploy, then
4
+ * the health poll). The launch streams its progress as NDJSON: a step event
5
+ * as each phase (prereqs, download, build, launch) begins, a progress event
6
+ * when the Get-steps hf download's tqdm stderr folds into a structured
7
+ * state, a sudo event when a guarded command waits for the user's password
8
+ * on the launching CLI, then a final result event. The card's Launch control
9
+ * reads the step that is running and times out only the launch (health-poll)
10
+ * step; the rebuild steps run as long as they need to.
11
+ * @module dsh-plugin-local-infer/ui/routes/launch
12
+ */
13
+ import { nodeLifecycleHost } from '../../../providers/lib/index.js';
14
+ import { launchEngine } from "../ops/engine.js";
15
+ import { defineRoute, RouteError } from "../route.js";
16
+ import { launchRequestFromBody } from "../request.js";
17
+ import { abortOnResponseClose, ndjsonLine, throttledProgressSink } from "./stream.js";
18
+ /**
19
+ * launchRoute builds the POST /local-infer/launch route definition the
20
+ * register step holds by an effect. The optional launchHost is the lifecycle
21
+ * host the launch's Get steps (git sync, build) run through; it defaults to
22
+ * the node host, and a test injects a stub so the route never clones a real
23
+ * repo in CI.
24
+ */
25
+ export function launchRoute(localInfer, launchHost = nodeLifecycleHost) {
26
+ return defineRoute({
27
+ name: 'local-infer-launch',
28
+ path: '/local-infer/launch',
29
+ method: 'POST',
30
+ failStatus: 500,
31
+ tooLargeMessage: 'launch payload too large',
32
+ run: async ({ body }, res) => {
33
+ res.ndjsonStream();
34
+ const writeLine = (line) => {
35
+ ndjsonLine(res, line);
36
+ };
37
+ const onProgress = (step) => {
38
+ writeLine({ step });
39
+ };
40
+ // The Get-steps hf download's raw stderr sink: the core chunk folder
41
+ // turns the tqdm lines into a structured state, and the sink emits a
42
+ // progress event when a fold yields one (throttled to the half-second
43
+ // cadence), between the step and result events.
44
+ const onChunk = throttledProgressSink((progress) => writeLine({ progress }));
45
+ // The run's sudo observer calls this when a guarded command waits for
46
+ // the password on the launching CLI (see launchEngine): the card reads
47
+ // the line as "Sudo needed" on its Launch control.
48
+ const onSudo = () => {
49
+ writeLine({ sudo: true });
50
+ };
51
+ // The card's provider-form Cancel aborts the fetch, which closes the
52
+ // response: the abort interrupts the in-flight Get-step hf child
53
+ // (SIGINT, then SIGTERM), and the persisted run carries the "Canceled"
54
+ // line. A close after the run settled is the normal end, not a cancel.
55
+ const { signal, markFinished } = abortOnResponseClose(res);
56
+ try {
57
+ const result = await launchEngine(localInfer, launchRequestFromBody(body), onProgress, launchHost, signal, onChunk, onSudo);
58
+ writeLine({ result });
59
+ }
60
+ catch (error) {
61
+ // A launch that breaks before a plan renders (an unknown engine, a
62
+ // hardware probe failure) still settles the card's control to the red
63
+ // Logs state through a result event, not a bare 500.
64
+ const detail = error instanceof RouteError
65
+ ? error.message
66
+ : String(error?.message ?? error);
67
+ writeLine({ result: { healthy: false, detail } });
68
+ }
69
+ markFinished();
70
+ res.end();
71
+ },
72
+ });
73
+ }
74
+ //# sourceMappingURL=launch.js.map
@@ -0,0 +1,57 @@
1
+ /**
2
+ * The GET /local-infer/logs route: the per-provider live run-log stream the
3
+ * card's Logs pane holds open (Q2: all live log display streams, nothing
4
+ * polls). The handler subscribes to the run-log hub before reading the
5
+ * catch-up snapshot, so an append that lands between the two is deduped by
6
+ * seq against the snapshot instead of doubling or being lost. One attached
7
+ * connection sees, in order: one `{ snapshot, seq, running }` catch-up line,
8
+ * then one `{ log, seq }` line per append, a `{ runBegin, seq }` line when a
9
+ * new run resets the buffer (the pane replaces, never appends), and a
10
+ * `{ runEnd, seq }` line when the run settles. The connection stays attached
11
+ * across runs. An unknown or blank provider key streams the empty snapshot
12
+ * and stays attached, so a client racing a run start never sees a 404; the
13
+ * client disconnect disposes the hub subscription.
14
+ * @module dsh-plugin-local-infer/ui/routes/logs
15
+ */
16
+ import type { LocalInferService } from 'dsh-plugin-local-infer/service';
17
+ import type { LocalInferRoute } from '../route.ts';
18
+ /**
19
+ * LogsStreamEvent is one NDJSON line the logs route streams: the catch-up
20
+ * snapshot (the bounded buffer text, the seq it reached, the running flag),
21
+ * one appended chunk, a run begin (the new run's seed line, seq back at 0,
22
+ * so the pane replaces its display), or the run end (the seq it settled at).
23
+ * Every line carries the seq the next append continues, so the card can drop
24
+ * any line whose seq the text it holds already covers.
25
+ */
26
+ export type LogsStreamEvent = {
27
+ snapshot: string;
28
+ seq: number;
29
+ running: boolean;
30
+ } | {
31
+ log: string;
32
+ seq: number;
33
+ } | {
34
+ runBegin: string;
35
+ seq: number;
36
+ } | {
37
+ runEnd: true;
38
+ seq: number;
39
+ };
40
+ /**
41
+ * LogsStreamRoute is the logs route's definition plus the open-stream
42
+ * registry the route effect's disposer drains. A bundle switch off
43
+ * unregisters the route, but browser panes that still hold a stream open
44
+ * leave their hub subscriptions behind unless something closes them; the
45
+ * effect disposer calls closeOpenStreams for that.
46
+ */
47
+ export interface LogsStreamRoute extends LocalInferRoute {
48
+ closeOpenStreams(): void;
49
+ }
50
+ /**
51
+ * logsRoute builds the GET /local-infer/logs?provider=<key> route definition
52
+ * the register step holds by an effect. The `provider` query is the run key
53
+ * every run path shares (the runLogKey rule the card's requests mirror); a
54
+ * missing or unknown key is a live stream of nothing until someone runs it.
55
+ */
56
+ export declare function logsRoute(localInfer: LocalInferService): LogsStreamRoute;
57
+ //# sourceMappingURL=logs.d.ts.map
@@ -0,0 +1,117 @@
1
+ /**
2
+ * The GET /local-infer/logs route: the per-provider live run-log stream the
3
+ * card's Logs pane holds open (Q2: all live log display streams, nothing
4
+ * polls). The handler subscribes to the run-log hub before reading the
5
+ * catch-up snapshot, so an append that lands between the two is deduped by
6
+ * seq against the snapshot instead of doubling or being lost. One attached
7
+ * connection sees, in order: one `{ snapshot, seq, running }` catch-up line,
8
+ * then one `{ log, seq }` line per append, a `{ runBegin, seq }` line when a
9
+ * new run resets the buffer (the pane replaces, never appends), and a
10
+ * `{ runEnd, seq }` line when the run settles. The connection stays attached
11
+ * across runs. An unknown or blank provider key streams the empty snapshot
12
+ * and stays attached, so a client racing a run start never sees a 404; the
13
+ * client disconnect disposes the hub subscription.
14
+ * @module dsh-plugin-local-infer/ui/routes/logs
15
+ */
16
+ import { defineRoute } from "../route.js";
17
+ import { ndjsonLine } from "./stream.js";
18
+ /**
19
+ * logsRoute builds the GET /local-infer/logs?provider=<key> route definition
20
+ * the register step holds by an effect. The `provider` query is the run key
21
+ * every run path shares (the runLogKey rule the card's requests mirror); a
22
+ * missing or unknown key is a live stream of nothing until someone runs it.
23
+ */
24
+ export function logsRoute(localInfer) {
25
+ // One closer per attached connection, so the effect disposer can detach
26
+ // every stream still open when the bundle switches off.
27
+ const openConnections = new Set();
28
+ const route = defineRoute({
29
+ name: 'local-infer-logs',
30
+ path: '/local-infer/logs',
31
+ method: 'GET',
32
+ failStatus: 500,
33
+ run: async ({ url }, res) => {
34
+ res.ndjsonStream();
35
+ const key = url.searchParams.get('provider') ?? '';
36
+ // The highest hub seq the client's text already covers: the snapshot
37
+ // line, then every forwarded log append. A log event at or below it is
38
+ // already in text the client holds, so it is dropped.
39
+ let coveredSeq = 0;
40
+ // True until the snapshot line is on the wire. Hub events that land in
41
+ // the window between subscribe and the snapshot read queue here and
42
+ // then run through the same seq rule, so the snapshot is always the
43
+ // stream's first line.
44
+ let catchingUp = true;
45
+ const queued = [];
46
+ // A client disconnect stops forwarding before the hub hands another
47
+ // event to a write on the closed response.
48
+ let closed = false;
49
+ const forward = (event) => {
50
+ if (event.kind === 'log') {
51
+ if (event.seq <= coveredSeq)
52
+ return;
53
+ coveredSeq = event.seq;
54
+ ndjsonLine(res, { log: event.text, seq: event.seq });
55
+ return;
56
+ }
57
+ if (event.kind === 'reset') {
58
+ // A new run restarted the key's seq at 0 with the seed line; the
59
+ // pane replaces its buffer, and the seq count restarts with it.
60
+ coveredSeq = event.seq;
61
+ ndjsonLine(res, { runBegin: event.text, seq: event.seq });
62
+ return;
63
+ }
64
+ ndjsonLine(res, { runEnd: true, seq: event.seq });
65
+ };
66
+ // Subscribe first, then read: an append racing between the two is
67
+ // caught by the listener (queued) and deduped against the snapshot
68
+ // that already holds its text, never lost or doubled.
69
+ const dispose = localInfer.subscribeRunLog(key, (event) => {
70
+ if (closed)
71
+ return;
72
+ if (catchingUp) {
73
+ queued.push(event);
74
+ return;
75
+ }
76
+ forward(event);
77
+ });
78
+ const snapshot = localInfer.readRunLog(key);
79
+ coveredSeq = snapshot.seq;
80
+ ndjsonLine(res, {
81
+ snapshot: snapshot.text,
82
+ seq: snapshot.seq,
83
+ running: snapshot.running,
84
+ });
85
+ catchingUp = false;
86
+ for (const event of queued) {
87
+ forward(event);
88
+ }
89
+ // The bundle switching off while this pane still streams: end the
90
+ // response and drop the hub subscription, so no listener outlives the
91
+ // route it was opened by (the effect disposer runs closeOpenStreams).
92
+ const closeConnection = () => {
93
+ closed = true;
94
+ dispose();
95
+ openConnections.delete(closeConnection);
96
+ res.end();
97
+ };
98
+ openConnections.add(closeConnection);
99
+ // The card unmounting or refreshing closes the response: dispose the
100
+ // subscription so a gone pane never leaves a listener behind.
101
+ res.onClose(() => {
102
+ closed = true;
103
+ dispose();
104
+ openConnections.delete(closeConnection);
105
+ });
106
+ },
107
+ });
108
+ return {
109
+ ...route,
110
+ closeOpenStreams() {
111
+ for (const closeConnection of [...openConnections]) {
112
+ closeConnection();
113
+ }
114
+ },
115
+ };
116
+ }
117
+ //# sourceMappingURL=logs.js.map
@@ -0,0 +1,15 @@
1
+ /**
2
+ * The POST /local-infer/provider-delete route: it removes the stored
3
+ * provider entry named by the body's id, keeps the rest of the list and the
4
+ * active config intact, and re-syncs the service's platform registry so a
5
+ * launch never reads a platform config the user just removed.
6
+ * @module dsh-plugin-local-infer/ui/routes/provider-delete
7
+ */
8
+ import type { LocalInferService } from 'dsh-plugin-local-infer/service';
9
+ import type { LocalInferRoute } from '../route.ts';
10
+ /**
11
+ * providerDeleteRoute builds the POST /local-infer/provider-delete route
12
+ * definition the register step holds by an effect.
13
+ */
14
+ export declare function providerDeleteRoute(localInfer: LocalInferService): LocalInferRoute;
15
+ //# sourceMappingURL=provider-delete.d.ts.map
@@ -0,0 +1,37 @@
1
+ /**
2
+ * The POST /local-infer/provider-delete route: it removes the stored
3
+ * provider entry named by the body's id, keeps the rest of the list and the
4
+ * active config intact, and re-syncs the service's platform registry so a
5
+ * launch never reads a platform config the user just removed.
6
+ * @module dsh-plugin-local-infer/ui/routes/provider-delete
7
+ */
8
+ import { readConfig, writeConfig } from "../config.js";
9
+ import { syncPlatformConfigs } from "../ops/engine.js";
10
+ import { defineRoute } from "../route.js";
11
+ import { buildSummary } from "../viewmodels/summary.js";
12
+ /**
13
+ * providerDeleteRoute builds the POST /local-infer/provider-delete route
14
+ * definition the register step holds by an effect.
15
+ */
16
+ export function providerDeleteRoute(localInfer) {
17
+ return defineRoute({
18
+ name: 'local-infer-provider-delete',
19
+ path: '/local-infer/provider-delete',
20
+ method: 'POST',
21
+ failStatus: 400,
22
+ tooLargeMessage: 'payload too large',
23
+ run: async ({ body }, res) => {
24
+ const id = typeof body.id === 'string' ? body.id : undefined;
25
+ if (id === undefined) {
26
+ res.json(400, { error: 'the provider id is required' });
27
+ return;
28
+ }
29
+ const stored = readConfig();
30
+ const providers = stored.providers.filter((entry) => entry.id !== id);
31
+ writeConfig(stored.engine, stored.config, stored.allowRunDeps, stored.platform, stored.showHelp, providers, stored.logPath, stored.lastLogs);
32
+ syncPlatformConfigs(localInfer, stored);
33
+ res.json(200, await buildSummary(localInfer));
34
+ },
35
+ });
36
+ }
37
+ //# sourceMappingURL=provider-delete.js.map
@@ -0,0 +1,16 @@
1
+ /**
2
+ * The POST /local-infer/register route: it renders the plan through the
3
+ * registered adapter, resolves the model row and the context window, and
4
+ * runs the service's register entry point, which upserts the provider and
5
+ * model through the settings seam. The result carries the entry the
6
+ * registrar wrote, so the card names the model it published.
7
+ * @module dsh-plugin-local-infer/ui/routes/register
8
+ */
9
+ import type { LocalInferService } from 'dsh-plugin-local-infer/service';
10
+ import type { LocalInferRoute } from '../route.ts';
11
+ /**
12
+ * registerRoute builds the POST /local-infer/register route definition the
13
+ * register step holds by an effect.
14
+ */
15
+ export declare function registerRoute(localInfer: LocalInferService): LocalInferRoute;
16
+ //# sourceMappingURL=register.d.ts.map
@@ -0,0 +1,28 @@
1
+ /**
2
+ * The POST /local-infer/register route: it renders the plan through the
3
+ * registered adapter, resolves the model row and the context window, and
4
+ * runs the service's register entry point, which upserts the provider and
5
+ * model through the settings seam. The result carries the entry the
6
+ * registrar wrote, so the card names the model it published.
7
+ * @module dsh-plugin-local-infer/ui/routes/register
8
+ */
9
+ import { registerFor } from "../ops/model.js";
10
+ import { defineRoute } from "../route.js";
11
+ import { registerRequestFromBody } from "../request.js";
12
+ /**
13
+ * registerRoute builds the POST /local-infer/register route definition the
14
+ * register step holds by an effect.
15
+ */
16
+ export function registerRoute(localInfer) {
17
+ return defineRoute({
18
+ name: 'local-infer-register',
19
+ path: '/local-infer/register',
20
+ method: 'POST',
21
+ failStatus: 500,
22
+ tooLargeMessage: 'register payload too large',
23
+ run: async ({ body }, res) => {
24
+ res.json(200, await registerFor(localInfer, registerRequestFromBody(body)));
25
+ },
26
+ });
27
+ }
28
+ //# sourceMappingURL=register.js.map
@@ -0,0 +1,18 @@
1
+ /**
2
+ * The POST /local-infer/save route: it upserts a provider entry (an id
3
+ * updates the stored entry in place, an absent id updates a stored entry that
4
+ * already matches the engine, config, and platform in place, and only a save
5
+ * with no match mints a new id and prepends the entry), persists the global
6
+ * fields the card's toggles edit, re-syncs the service's platform registry with
7
+ * the saved map, and re-runs the registration for an already-registered model
8
+ * so its input types stay in step with the saved config.
9
+ * @module dsh-plugin-local-infer/ui/routes/save
10
+ */
11
+ import type { LocalInferService } from 'dsh-plugin-local-infer/service';
12
+ import type { LocalInferRoute } from '../route.ts';
13
+ /**
14
+ * saveRoute builds the POST /local-infer/save route definition the register
15
+ * step holds by an effect.
16
+ */
17
+ export declare function saveRoute(localInfer: LocalInferService): LocalInferRoute;
18
+ //# sourceMappingURL=save.d.ts.map