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
@@ -1,9 +1,10 @@
1
- import type { LaunchPlan } from './adapter.ts';
1
+ import type { BuildMode, LaunchPlan } from './adapter.ts';
2
2
  /**
3
3
  * DshModelEntry is the shape of the model row the registrar writes into the
4
4
  * dsh-llm-pi-ai provider: the provider id, the model id and display name, the
5
- * context window, the engine's base URL, and the env-var name the provider
6
- * reads its optional API key from.
5
+ * context window, the engine's base URL, the env-var name the provider reads
6
+ * its optional API key from, and the placeholder API key value the engine
7
+ * ships with so a model the user has not keyed still activates.
7
8
  */
8
9
  export interface DshModelEntry {
9
10
  providerId: string;
@@ -12,6 +13,7 @@ export interface DshModelEntry {
12
13
  contextWindow: number;
13
14
  baseURL: string;
14
15
  apiKeyEnv: string;
16
+ apiKey: string;
15
17
  input?: string[];
16
18
  }
17
19
  /**
@@ -83,24 +85,33 @@ export interface DshModelRegistrar {
83
85
  export declare function modelSlug(modelId: string): string;
84
86
  /**
85
87
  * providerIdFor derives the provider id the registrar writes for an engine
86
- * and model: the engine id, the build mode (local or docker), and the model
87
- * slug, so a profile can carry the same engine in both build modes and
88
- * several models per engine without a collision.
88
+ * and model: the engine id, the build mode (local, docker, or binary), and the
89
+ * model slug, so a profile can carry the same engine in several build modes
90
+ * and several models per engine without a collision.
89
91
  */
90
- export declare function providerIdFor(engineId: string, modelId: string, buildMode: 'local' | 'docker'): string;
92
+ export declare function providerIdFor(engineId: string, modelId: string, buildMode: BuildMode): string;
91
93
  /**
92
94
  * apiKeyEnvFor derives the env-var name a local provider reads its optional
93
95
  * API key from: the engine id, uppercased and non-alphanumerics mapped to
94
96
  * underscores, plus _LOCAL_API_KEY.
95
97
  */
96
98
  export declare function apiKeyEnvFor(engineId: string): string;
99
+ /**
100
+ * defaultApiKeyFor derives the placeholder API key value a local engine ships
101
+ * with: the engine id, uppercased and non-alphanumerics mapped to underscores,
102
+ * wrapped in double braces plus _LOCAL_API_KEY. The double braces mark the
103
+ * value as a placeholder, not a real key, so a model the user has not keyed
104
+ * still activates the pi-ai OpenAI route. A user-added key replaces it in a
105
+ * future turn.
106
+ */
107
+ export declare function defaultApiKeyFor(engineId: string): string;
97
108
  /**
98
109
  * buildModelEntry turns a launch plan and a model row into the DshModelEntry
99
110
  * the registrar writes. The provider id is the engine, build mode, and model
100
111
  * slug; the display name is the engine, the build mode in parentheses, and
101
112
  * the model name (falling back to the slug when the row carries none). The
102
- * API-key env name derives from the engine id, and the base URL is the
103
- * engine's OpenAI endpoint on its port.
113
+ * API-key env name and the placeholder API key value derive from the engine
114
+ * id, and the base URL is the engine's OpenAI endpoint on its port.
104
115
  */
105
116
  export declare function buildModelEntry(plan: LaunchPlan, model: ModelRow): DshModelEntry;
106
117
  /**
@@ -118,10 +129,10 @@ export declare function upsertModelRow(rows: readonly ModelRow[], row: ModelRow)
118
129
  export declare function removeModelRow(rows: readonly ModelRow[], modelId: string): ModelRow[];
119
130
  /**
120
131
  * providerRegistrationOps computes the settings ops that upsert a provider
121
- * entry: the API-key env name, the openai-completions api, the base URL, and
122
- * the models list with the entry's row upserted. The ops write the provider
123
- * fields by path, so a provider the user edited by hand keeps every field
124
- * the registrar does not own.
132
+ * entry: the API-key env name, the openai-completions api, the base URL, the
133
+ * placeholder Authorization header, and the models list with the entry's row
134
+ * upserted. The ops write the provider fields by path, so a provider the user
135
+ * edited by hand keeps every field the registrar does not own.
125
136
  */
126
137
  export declare function providerRegistrationOps(entry: DshModelEntry, rows: readonly ModelRow[]): SettingsOp[];
127
138
  /**
@@ -154,4 +165,4 @@ export declare function modelRowsFrom(value: unknown, providerId: string): reado
154
165
  * when it names the removed pair.
155
166
  */
156
167
  export declare function agentDefaultPointsAt(value: unknown, providerId: string, modelId: string): boolean;
157
- //# sourceMappingURL=registrar.d.ts.map
168
+ //# sourceMappingURL=registrar.d.ts.map
@@ -27,9 +27,9 @@ export function modelSlug(modelId) {
27
27
  }
28
28
  /**
29
29
  * providerIdFor derives the provider id the registrar writes for an engine
30
- * and model: the engine id, the build mode (local or docker), and the model
31
- * slug, so a profile can carry the same engine in both build modes and
32
- * several models per engine without a collision.
30
+ * and model: the engine id, the build mode (local, docker, or binary), and the
31
+ * model slug, so a profile can carry the same engine in several build modes
32
+ * and several models per engine without a collision.
33
33
  */
34
34
  export function providerIdFor(engineId, modelId, buildMode) {
35
35
  return `${engineId}-${buildMode}-${modelSlug(modelId)}`;
@@ -42,6 +42,17 @@ export function providerIdFor(engineId, modelId, buildMode) {
42
42
  export function apiKeyEnvFor(engineId) {
43
43
  return `${engineId.toUpperCase().replace(/[^A-Z0-9]/g, '_')}_LOCAL_API_KEY`;
44
44
  }
45
+ /**
46
+ * defaultApiKeyFor derives the placeholder API key value a local engine ships
47
+ * with: the engine id, uppercased and non-alphanumerics mapped to underscores,
48
+ * wrapped in double braces plus _LOCAL_API_KEY. The double braces mark the
49
+ * value as a placeholder, not a real key, so a model the user has not keyed
50
+ * still activates the pi-ai OpenAI route. A user-added key replaces it in a
51
+ * future turn.
52
+ */
53
+ export function defaultApiKeyFor(engineId) {
54
+ return `{{${engineId.toUpperCase().replace(/[^A-Z0-9]/g, '_')}}}_LOCAL_API_KEY`;
55
+ }
45
56
  /**
46
57
  * engineDisplayName capitalizes the first letter of an engine id for the
47
58
  * display name: `ninfer` reads as `Ninfer`, `hyperqwen` as `Hyperqwen`.
@@ -54,8 +65,8 @@ function engineDisplayName(engineId) {
54
65
  * the registrar writes. The provider id is the engine, build mode, and model
55
66
  * slug; the display name is the engine, the build mode in parentheses, and
56
67
  * the model name (falling back to the slug when the row carries none). The
57
- * API-key env name derives from the engine id, and the base URL is the
58
- * engine's OpenAI endpoint on its port.
68
+ * API-key env name and the placeholder API key value derive from the engine
69
+ * id, and the base URL is the engine's OpenAI endpoint on its port.
59
70
  */
60
71
  export function buildModelEntry(plan, model) {
61
72
  const buildMode = plan.kind === 'docker' ? 'docker' : 'local';
@@ -68,6 +79,7 @@ export function buildModelEntry(plan, model) {
68
79
  contextWindow: model.contextWindow,
69
80
  baseURL: `http://127.0.0.1:${plan.port}/v1`,
70
81
  apiKeyEnv: apiKeyEnvFor(plan.engineId),
82
+ apiKey: defaultApiKeyFor(plan.engineId),
71
83
  };
72
84
  // exactOptionalPropertyTypes: carry the input modalities only when the row
73
85
  // names them, so a text-only registration never writes an empty list.
@@ -101,10 +113,10 @@ export function removeModelRow(rows, modelId) {
101
113
  }
102
114
  /**
103
115
  * providerRegistrationOps computes the settings ops that upsert a provider
104
- * entry: the API-key env name, the openai-completions api, the base URL, and
105
- * the models list with the entry's row upserted. The ops write the provider
106
- * fields by path, so a provider the user edited by hand keeps every field
107
- * the registrar does not own.
116
+ * entry: the API-key env name, the openai-completions api, the base URL, the
117
+ * placeholder Authorization header, and the models list with the entry's row
118
+ * upserted. The ops write the provider fields by path, so a provider the user
119
+ * edited by hand keeps every field the registrar does not own.
108
120
  */
109
121
  export function providerRegistrationOps(entry, rows) {
110
122
  const providerPath = ['providers', entry.providerId];
@@ -119,10 +131,18 @@ export function providerRegistrationOps(entry, rows) {
119
131
  if (entry.input !== undefined) {
120
132
  row.input = entry.input;
121
133
  }
134
+ // The pi-ai OpenAI route requires an API key or an Authorization header, so
135
+ // a keyless local server ships the placeholder key as a Bearer header. The
136
+ // profile schema has no literal apiKey field; headers carry the value.
122
137
  return [
123
138
  { op: 'set', path: [...providerPath, 'apiKeyEnv'], value: entry.apiKeyEnv },
124
139
  { op: 'set', path: [...providerPath, 'api'], value: 'openai-completions' },
125
140
  { op: 'set', path: [...providerPath, 'baseURL'], value: entry.baseURL },
141
+ {
142
+ op: 'set',
143
+ path: [...providerPath, 'headers', 'Authorization'],
144
+ value: `Bearer ${entry.apiKey}`,
145
+ },
126
146
  { op: 'set', path: [...providerPath, 'models'], value: upsertModelRow(rows, row) },
127
147
  ];
128
148
  }
@@ -205,4 +225,4 @@ export function agentDefaultPointsAt(value, providerId, modelId) {
205
225
  const section = value;
206
226
  return section.provider === providerId && section.model === modelId;
207
227
  }
208
- //# sourceMappingURL=registrar.js.map
228
+ //# sourceMappingURL=registrar.js.map
@@ -25,6 +25,13 @@ export declare function parseNvidiaSmiGpuUsage(output: string): GpuUsageProbe |
25
25
  export interface EngineLaunchSignature {
26
26
  binary: string;
27
27
  port?: number;
28
+ /**
29
+ * When false the engine binds its port from a file (Basalt's
30
+ * basalt_config.json server block), so the matcher never sees the number
31
+ * in the command line and must skip the port element. Undefined reads as
32
+ * true: the port must appear as a standalone number, the current rule.
33
+ */
34
+ portInArgv?: boolean;
28
35
  envKeys?: readonly string[];
29
36
  }
30
37
  /**
@@ -44,8 +51,9 @@ export interface ProcessLine {
44
51
  * signature. The binary marker must appear in the command line (the image
45
52
  * name for a docker plan, the engine binary for a local one); a declared port
46
53
  * must appear as a standalone number (the `--port N` flag or the docker
47
- * `-p host:port:port` mapping); a declared env key must be set when the line
48
- * carries env data, and is neutral when it does not.
54
+ * `-p host:port:port` mapping) unless `portInArgv` is false, which means the
55
+ * engine binds its port from a file; a declared env key must be set when the
56
+ * line carries env data, and is neutral when it does not.
49
57
  */
50
58
  export declare function matchLaunchSignature(line: ProcessLine, signature: EngineLaunchSignature): boolean;
51
59
  /**
@@ -86,4 +94,4 @@ export declare function resolveOsReserve(input: {
86
94
  foreignProcess?: boolean;
87
95
  gpuUsage?: GpuUsageProbe | null;
88
96
  }): ReserveResolution;
89
- //# sourceMappingURL=reserve.d.ts.map
97
+ //# sourceMappingURL=reserve.d.ts.map
@@ -29,14 +29,16 @@ export function parseNvidiaSmiGpuUsage(output) {
29
29
  * signature. The binary marker must appear in the command line (the image
30
30
  * name for a docker plan, the engine binary for a local one); a declared port
31
31
  * must appear as a standalone number (the `--port N` flag or the docker
32
- * `-p host:port:port` mapping); a declared env key must be set when the line
33
- * carries env data, and is neutral when it does not.
32
+ * `-p host:port:port` mapping) unless `portInArgv` is false, which means the
33
+ * engine binds its port from a file; a declared env key must be set when the
34
+ * line carries env data, and is neutral when it does not.
34
35
  */
35
36
  export function matchLaunchSignature(line, signature) {
36
37
  if (!line.command.includes(signature.binary))
37
38
  return false;
38
- if (signature.port !== undefined && !portAppears(line.command, signature.port))
39
+ if (signature.portInArgv !== false && signature.port !== undefined && !portAppears(line.command, signature.port)) {
39
40
  return false;
41
+ }
40
42
  if (signature.envKeys !== undefined && signature.envKeys.length > 0 && line.env !== undefined) {
41
43
  const hit = signature.envKeys.some(key => key in line.env);
42
44
  if (!hit)
@@ -90,4 +92,4 @@ export function resolveOsReserve(input) {
90
92
  }
91
93
  return { reserveMiB: DEFAULT_OS_RESERVE_MIB, source: 'default' };
92
94
  }
93
- //# sourceMappingURL=reserve.js.map
95
+ //# sourceMappingURL=reserve.js.map
@@ -10,8 +10,10 @@ export type ProviderStatus = 'running' | 'stopped' | 'unsure';
10
10
  /**
11
11
  * ProviderRef is the identity side of one saved provider config: the stable
12
12
  * id the card renders and the engine and model it serves. The model is
13
- * optional because a config that names no model cannot be confirmed against
14
- * a running engine, and reads as unsure rather than a guess. The config is
13
+ * optional: a config that names no model (an absent or empty value) confirms
14
+ * against a plugin-launched engine the detector tied to any model on its
15
+ * port, and reads as unsure only while no running engine carries a model tie.
16
+ * The config is
15
17
  * optional and lets the detector price the provider's own launch signature
16
18
  * (the engine binary the build mode runs, the port it binds) rather than the
17
19
  * adapter's default-port signature; the port is the resolved bind port the
@@ -60,9 +62,13 @@ export declare function isGpuBusy(usage?: GpuUsageProbe | null): boolean;
60
62
  * the detector's answer. The order is the plan's contract:
61
63
  * 1. A provider whose engine the process probe confirmed running is running
62
64
  * (green) when the detector tied that engine to the provider's exact model,
63
- * and unsure (yellow) when the engine serves an unidentified or a
64
- * different model. A running engine using its VRAM does not read as a busy
65
- * card, so the dot is green, not the unattributable yellow.
65
+ * or when the provider names no model and the detector tied the engine to
66
+ * any model: only this plugin's launches and re-links stamp a model tie, so
67
+ * a model-tied engine on the provider's port is that provider's own engine.
68
+ * A provider reads as unsure (yellow) when the engine serves an
69
+ * unidentified or a different model. A running engine using its VRAM does
70
+ * not read as a busy card, so the dot is green, not the unattributable
71
+ * yellow.
66
72
  * 2. A provider whose engine is not running falls back to the card state: a
67
73
  * busy card (a foreign engine holding the VRAM at 75% or more) reads as
68
74
  * unsure, because a full card cannot be attributed to a single model, and
@@ -70,4 +76,4 @@ export declare function isGpuBusy(usage?: GpuUsageProbe | null): boolean;
70
76
  * a saved config whose engine is down is stopped.
71
77
  */
72
78
  export declare function computeProviderStatuses(input: ProviderStatusInput): Record<string, ProviderStatus>;
73
- //# sourceMappingURL=status.d.ts.map
79
+ //# sourceMappingURL=status.d.ts.map
@@ -11,14 +11,26 @@ export function isGpuBusy(usage) {
11
11
  return false;
12
12
  return usage.usedMiB / usage.totalMiB >= GPU_USAGE_BUSY_THRESHOLD;
13
13
  }
14
+ /**
15
+ * namesNoModel reports whether one model field names no model: the absent
16
+ * value or the empty string. The provider side and the engine-ref side of the
17
+ * status tie both read it, so one rule decides both representations.
18
+ */
19
+ function namesNoModel(model) {
20
+ return model === undefined || model === '';
21
+ }
14
22
  /**
15
23
  * computeProviderStatuses resolves each saved provider's running-state from
16
24
  * the detector's answer. The order is the plan's contract:
17
25
  * 1. A provider whose engine the process probe confirmed running is running
18
26
  * (green) when the detector tied that engine to the provider's exact model,
19
- * and unsure (yellow) when the engine serves an unidentified or a
20
- * different model. A running engine using its VRAM does not read as a busy
21
- * card, so the dot is green, not the unattributable yellow.
27
+ * or when the provider names no model and the detector tied the engine to
28
+ * any model: only this plugin's launches and re-links stamp a model tie, so
29
+ * a model-tied engine on the provider's port is that provider's own engine.
30
+ * A provider reads as unsure (yellow) when the engine serves an
31
+ * unidentified or a different model. A running engine using its VRAM does
32
+ * not read as a busy card, so the dot is green, not the unattributable
33
+ * yellow.
22
34
  * 2. A provider whose engine is not running falls back to the card state: a
23
35
  * busy card (a foreign engine holding the VRAM at 75% or more) reads as
24
36
  * unsure, because a full card cannot be attributed to a single model, and
@@ -37,16 +49,15 @@ export function computeProviderStatuses(input) {
37
49
  if (matches.length > 0) {
38
50
  // The engine is running. The question is which model it serves: the
39
51
  // detector's identified model, if it tied one, else unknown.
40
- const identified = matches.find((ref) => ref.modelId !== undefined && ref.modelId !== '');
52
+ const identified = matches.find((ref) => !namesNoModel(ref.modelId));
41
53
  if (identified !== undefined &&
42
- provider.model !== undefined &&
43
- identified.modelId === provider.model) {
54
+ (namesNoModel(provider.model) || identified.modelId === provider.model)) {
44
55
  statuses[provider.id] = 'running';
45
56
  continue;
46
57
  }
47
- // The engine is running but the model is not identified, the provider
48
- // names no model, or the engine serves a different model: unsure, not
49
- // a guess.
58
+ // The engine is running but the detector could not tie it to a model, or
59
+ // it serves a different model than the provider names: unsure, not a
60
+ // guess.
50
61
  statuses[provider.id] = 'unsure';
51
62
  continue;
52
63
  }
@@ -56,4 +67,4 @@ export function computeProviderStatuses(input) {
56
67
  }
57
68
  return statuses;
58
69
  }
59
- //# sourceMappingURL=status.js.map
70
+ //# sourceMappingURL=status.js.map
@@ -0,0 +1,80 @@
1
+ /**
2
+ * The pure half of the sudo-prompt rule. A sudo command run by the plugin
3
+ * prompts on the terminal that launched the host, where the card user cannot
4
+ * see it, so the runners announce the prompt and cap how long it may wait.
5
+ * This module holds the constants and the injected-callback guard both
6
+ * runners drive; the child-process wiring stays in the service and the
7
+ * providers, so core never touches node.
8
+ * @module dsh-plugin-local-infer/core/sudo
9
+ */
10
+ /**
11
+ * SUDO_CLI_NOTE is the line the Logs section, the log file, and the streamed
12
+ * run show when a sudo command is waiting for the user to type the password
13
+ * on the CLI.
14
+ */
15
+ export declare const SUDO_CLI_NOTE = "Check your CLI for a sudo prompt";
16
+ /**
17
+ * SUDO_PASSWORD_TIMEOUT_MS caps how long a sudo command may wait for the user
18
+ * to type the password on the CLI before the run kills it and fails.
19
+ */
20
+ export declare const SUDO_PASSWORD_TIMEOUT_MS = 60000;
21
+ /**
22
+ * SUDO_PROBE_COMMAND is the non-interactive probe that answers whether sudo
23
+ * already holds cached credentials (exit 0) or is about to prompt on the
24
+ * terminal (non-zero). The runners execute it; core only declares it.
25
+ */
26
+ export declare const SUDO_PROBE_COMMAND: readonly string[];
27
+ /**
28
+ * sudoFailureDetail builds the CommandOutcome.detail text for a command the
29
+ * sudo deadline killed, naming the CLI note and the timeout seconds so the
30
+ * Logs section explains what the user missed.
31
+ */
32
+ export declare function sudoFailureDetail(command: string): string;
33
+ /**
34
+ * SudoTimer is the injectable set/clear pair a sudo guard arms and disarms.
35
+ * Tests drive the clock through a fake; the default is setTimeout and
36
+ * clearTimeout.
37
+ */
38
+ export interface SudoTimer {
39
+ set: (callback: () => void, ms: number) => unknown;
40
+ clear: (handle: unknown) => void;
41
+ }
42
+ /**
43
+ * SudoGuardOptions tunes one guarded command run. `needsSudo` is the caller's
44
+ * declaration (SystemDep.requiresSudo on the install path, RunOptions.needsSudo
45
+ * on the lifecycle path), never inferred from the command text. `probe`
46
+ * answers whether sudo already holds cached credentials, `notify` announces
47
+ * the coming prompt once, `kill` stops the command, `timeoutMs` overrides the
48
+ * deadline, and `timer` swaps the clock.
49
+ */
50
+ export interface SudoGuardOptions {
51
+ needsSudo?: boolean;
52
+ command: string;
53
+ probe: () => Promise<boolean>;
54
+ notify: (command: string) => void;
55
+ kill: () => void;
56
+ timeoutMs?: number;
57
+ timer?: SudoTimer;
58
+ }
59
+ /**
60
+ * SudoGuard is the guard's answer, read by the caller around the command run.
61
+ * `announced` says the prompt was announced and a deadline is armed;
62
+ * `disarm` clears the armed deadline once the command finishes; `timedOut`
63
+ * reads whether the deadline already fired, so a failed run can carry
64
+ * sudoFailureDetail instead of a bare exit.
65
+ */
66
+ export interface SudoGuard {
67
+ announced: boolean;
68
+ disarm(): void;
69
+ timedOut(): boolean;
70
+ }
71
+ /**
72
+ * guardSudoCommand applies the shared sudo-prompt rule for one command, so
73
+ * the service install runner and the providers lifecycle host drive one rule.
74
+ * A command the caller does not declare sudo runs through unguarded: no
75
+ * probe, no announcement, no timer. A declared command probes first; cached
76
+ * credentials (probe resolves true) run through the same way. Otherwise the
77
+ * guard calls notify once and arms the timeout whose fire calls kill.
78
+ */
79
+ export declare function guardSudoCommand(options: SudoGuardOptions): Promise<SudoGuard>;
80
+ //# sourceMappingURL=sudo.d.ts.map
@@ -0,0 +1,78 @@
1
+ /**
2
+ * The pure half of the sudo-prompt rule. A sudo command run by the plugin
3
+ * prompts on the terminal that launched the host, where the card user cannot
4
+ * see it, so the runners announce the prompt and cap how long it may wait.
5
+ * This module holds the constants and the injected-callback guard both
6
+ * runners drive; the child-process wiring stays in the service and the
7
+ * providers, so core never touches node.
8
+ * @module dsh-plugin-local-infer/core/sudo
9
+ */
10
+ /**
11
+ * SUDO_CLI_NOTE is the line the Logs section, the log file, and the streamed
12
+ * run show when a sudo command is waiting for the user to type the password
13
+ * on the CLI.
14
+ */
15
+ export const SUDO_CLI_NOTE = 'Check your CLI for a sudo prompt';
16
+ /**
17
+ * SUDO_PASSWORD_TIMEOUT_MS caps how long a sudo command may wait for the user
18
+ * to type the password on the CLI before the run kills it and fails.
19
+ */
20
+ export const SUDO_PASSWORD_TIMEOUT_MS = 60_000;
21
+ /**
22
+ * SUDO_PROBE_COMMAND is the non-interactive probe that answers whether sudo
23
+ * already holds cached credentials (exit 0) or is about to prompt on the
24
+ * terminal (non-zero). The runners execute it; core only declares it.
25
+ */
26
+ export const SUDO_PROBE_COMMAND = ['sudo', '-n', 'true'];
27
+ /**
28
+ * sudoFailureDetail builds the CommandOutcome.detail text for a command the
29
+ * sudo deadline killed, naming the CLI note and the timeout seconds so the
30
+ * Logs section explains what the user missed.
31
+ */
32
+ export function sudoFailureDetail(command) {
33
+ return (`${command} was killed: no sudo password was entered within ` +
34
+ `${SUDO_PASSWORD_TIMEOUT_MS / 1000} seconds. ${SUDO_CLI_NOTE}`);
35
+ }
36
+ /** DEFAULT_SUDO_TIMER is the guard clock when the caller injects none. */
37
+ const DEFAULT_SUDO_TIMER = {
38
+ set: (callback, ms) => setTimeout(callback, ms),
39
+ clear: (handle) => clearTimeout(handle),
40
+ };
41
+ /**
42
+ * guardSudoCommand applies the shared sudo-prompt rule for one command, so
43
+ * the service install runner and the providers lifecycle host drive one rule.
44
+ * A command the caller does not declare sudo runs through unguarded: no
45
+ * probe, no announcement, no timer. A declared command probes first; cached
46
+ * credentials (probe resolves true) run through the same way. Otherwise the
47
+ * guard calls notify once and arms the timeout whose fire calls kill.
48
+ */
49
+ export async function guardSudoCommand(options) {
50
+ if (options.needsSudo !== true) {
51
+ return unguarded();
52
+ }
53
+ if (await options.probe()) {
54
+ return unguarded();
55
+ }
56
+ options.notify(options.command);
57
+ const timer = options.timer ?? DEFAULT_SUDO_TIMER;
58
+ const timeoutMs = options.timeoutMs ?? SUDO_PASSWORD_TIMEOUT_MS;
59
+ let timedOut = false;
60
+ const handle = timer.set(() => {
61
+ timedOut = true;
62
+ options.kill();
63
+ }, timeoutMs);
64
+ return {
65
+ announced: true,
66
+ disarm: () => timer.clear(handle),
67
+ timedOut: () => timedOut,
68
+ };
69
+ }
70
+ /** unguarded is the pass-through guard for a run nothing was armed for. */
71
+ function unguarded() {
72
+ return {
73
+ announced: false,
74
+ disarm: () => { },
75
+ timedOut: () => false,
76
+ };
77
+ }
78
+ //# sourceMappingURL=sudo.js.map
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-local-infer-core",
3
- "version": "0.1.0",
3
+ "version": "0.1.4",
4
4
  "description": "Pure, framework-free domain model for the dsh local-inference plugin: ParameterSpec, HardwareProfile, EngineAdapter, VramEstimator, GuidelineEngine, DefaultsResolver, DshModelRegistrar, and SystemDepProvisioner primitives shared by every engine and model",
5
5
  "keywords": [
6
6
  "dsh",
@@ -0,0 +1,63 @@
1
+ /**
2
+ * The Orchestrator prompt store: the saved prompt file under
3
+ * ~/.dsh/local-infer/orchestrator.json, the shipped prompt.md default, and
4
+ * the in-memory holder the system-prompt section and the settings routes
5
+ * share. Every read sanitizes the file, so a by-hand edit never poisons the
6
+ * injected prompt. Mirrors the sanitize-on-read discipline of
7
+ * packages/ui/src/config.ts.
8
+ * @module dsh-plugin-local-infer/orchestrator/config
9
+ */
10
+ /**
11
+ * orchestratorConfigPath names the file this package owns. It sits in the
12
+ * shared local-infer dir beside the ui config so one place holds everything
13
+ * the plugin persists.
14
+ */
15
+ export declare function orchestratorConfigPath(): string;
16
+ /**
17
+ * StoredOrchestratorConfig is the whole persisted shape: the saved prompt,
18
+ * where an empty string carries "no saved prompt" so the holder falls back
19
+ * to the shipped default.
20
+ */
21
+ export interface StoredOrchestratorConfig {
22
+ prompt: string;
23
+ }
24
+ /**
25
+ * readOrchestratorConfig reads the saved prompt. A missing or broken file,
26
+ * or a prompt field that is not a string, reads as no saved prompt (empty),
27
+ * so a first open and a by-hand edit both land on the default instead of
28
+ * throwing.
29
+ */
30
+ export declare function readOrchestratorConfig(): StoredOrchestratorConfig;
31
+ /**
32
+ * writeOrchestratorConfig persists the prompt, creating the directory tree
33
+ * on first write the same way the ui config write does.
34
+ */
35
+ export declare function writeOrchestratorConfig(config: StoredOrchestratorConfig): void;
36
+ /**
37
+ * defaultOrchestratorPrompt returns the shipped prompt.md text read from the
38
+ * package root. The URL hop is relative to this module, so src/ and lib/
39
+ * depths both resolve one level up to the package root. The read is cached;
40
+ * an unreadable file yields '' without throwing.
41
+ */
42
+ export declare function defaultOrchestratorPrompt(): string;
43
+ /**
44
+ * getOrchestratorPrompt returns the effective prompt: the saved value when a
45
+ * non-empty one exists, otherwise the shipped default. The first call reads
46
+ * the file once and caches, so the system-prompt section pays no per-message
47
+ * disk read.
48
+ */
49
+ export declare function getOrchestratorPrompt(): string;
50
+ /**
51
+ * setOrchestratorPrompt persists the prompt and refreshes the holder, so the
52
+ * injected section picks the new text up without another file read. An empty
53
+ * save means "no saved prompt" and falls back to the default.
54
+ */
55
+ export declare function setOrchestratorPrompt(prompt: string): void;
56
+ /**
57
+ * hasSavedOrchestratorPrompt reports whether the file holds a saved prompt
58
+ * override. The empty string is the store's sentinel for "no saved prompt",
59
+ * so the settings routes read the flag through here instead of re-deriving
60
+ * the sentinel rule the holder already applies.
61
+ */
62
+ export declare function hasSavedOrchestratorPrompt(): boolean;
63
+ //# sourceMappingURL=config.d.ts.map