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,111 @@
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
+ import { existsSync, mkdirSync, readFileSync, writeFileSync } from 'node:fs';
11
+ import { homedir } from 'node:os';
12
+ import { dirname, join } from 'node:path';
13
+ /**
14
+ * orchestratorConfigPath names the file this package owns. It sits in the
15
+ * shared local-infer dir beside the ui config so one place holds everything
16
+ * the plugin persists.
17
+ */
18
+ export function orchestratorConfigPath() {
19
+ return join(homedir(), '.dsh', 'local-infer', 'orchestrator.json');
20
+ }
21
+ /**
22
+ * readOrchestratorConfig reads the saved prompt. A missing or broken file,
23
+ * or a prompt field that is not a string, reads as no saved prompt (empty),
24
+ * so a first open and a by-hand edit both land on the default instead of
25
+ * throwing.
26
+ */
27
+ export function readOrchestratorConfig() {
28
+ const path = orchestratorConfigPath();
29
+ if (!existsSync(path)) {
30
+ return { prompt: '' };
31
+ }
32
+ try {
33
+ const parsed = JSON.parse(readFileSync(path, 'utf8'));
34
+ return { prompt: typeof parsed.prompt === 'string' ? parsed.prompt : '' };
35
+ }
36
+ catch {
37
+ return { prompt: '' };
38
+ }
39
+ }
40
+ /**
41
+ * writeOrchestratorConfig persists the prompt, creating the directory tree
42
+ * on first write the same way the ui config write does.
43
+ */
44
+ export function writeOrchestratorConfig(config) {
45
+ const path = orchestratorConfigPath();
46
+ mkdirSync(dirname(path), { recursive: true });
47
+ writeFileSync(path, JSON.stringify({ prompt: config.prompt }, null, 2));
48
+ }
49
+ // Cache of the shipped prompt.md text: the file never changes while the
50
+ // process runs, so only a successful read is kept and a failed read retries
51
+ // on the next call instead of locking in the empty fallback.
52
+ let defaultPromptCache;
53
+ /**
54
+ * defaultOrchestratorPrompt returns the shipped prompt.md text read from the
55
+ * package root. The URL hop is relative to this module, so src/ and lib/
56
+ * depths both resolve one level up to the package root. The read is cached;
57
+ * an unreadable file yields '' without throwing.
58
+ */
59
+ export function defaultOrchestratorPrompt() {
60
+ if (defaultPromptCache === undefined) {
61
+ try {
62
+ defaultPromptCache = readFileSync(new URL('../prompt.md', import.meta.url), 'utf8');
63
+ }
64
+ catch {
65
+ return '';
66
+ }
67
+ }
68
+ return defaultPromptCache;
69
+ }
70
+ // The effective prompt holder: null until the first read refreshes it from
71
+ // the file, then the saved value or the default until the setter persists a
72
+ // new one.
73
+ let effectivePrompt = null;
74
+ /**
75
+ * getOrchestratorPrompt returns the effective prompt: the saved value when a
76
+ * non-empty one exists, otherwise the shipped default. The first call reads
77
+ * the file once and caches, so the system-prompt section pays no per-message
78
+ * disk read.
79
+ */
80
+ export function getOrchestratorPrompt() {
81
+ if (effectivePrompt === null) {
82
+ effectivePrompt = toEffective(readOrchestratorConfig().prompt);
83
+ }
84
+ return effectivePrompt;
85
+ }
86
+ /**
87
+ * setOrchestratorPrompt persists the prompt and refreshes the holder, so the
88
+ * injected section picks the new text up without another file read. An empty
89
+ * save means "no saved prompt" and falls back to the default.
90
+ */
91
+ export function setOrchestratorPrompt(prompt) {
92
+ writeOrchestratorConfig({ prompt });
93
+ effectivePrompt = toEffective(prompt);
94
+ }
95
+ /**
96
+ * hasSavedOrchestratorPrompt reports whether the file holds a saved prompt
97
+ * override. The empty string is the store's sentinel for "no saved prompt",
98
+ * so the settings routes read the flag through here instead of re-deriving
99
+ * the sentinel rule the holder already applies.
100
+ */
101
+ export function hasSavedOrchestratorPrompt() {
102
+ return readOrchestratorConfig().prompt !== '';
103
+ }
104
+ /**
105
+ * toEffective resolves one saved value against the default: an empty saved
106
+ * prompt reads as no saved prompt.
107
+ */
108
+ function toEffective(saved) {
109
+ return saved === '' ? defaultOrchestratorPrompt() : saved;
110
+ }
111
+ //# sourceMappingURL=config.js.map
@@ -0,0 +1,51 @@
1
+ /**
2
+ * The Orchestrator capability: an editable "Orchestrator Prompt" persisted
3
+ * under `~/.dsh/local-infer`, defaulted from the shipped `prompt.md`, and
4
+ * injected into the system prompt while the component is enabled.
5
+ *
6
+ * The prompt store (saved file, shipped default, effective-prompt holder)
7
+ * lives in ./config.js and is re-exported here as the single source of truth
8
+ * the system-prompt seam (TASK-003) and the settings routes (TASK-004) pull
9
+ * from.
10
+ * @module dsh-plugin-local-infer/orchestrator
11
+ */
12
+ import type { Context } from '@deepseek-ai/cordis';
13
+ export { defaultOrchestratorPrompt, getOrchestratorPrompt, hasSavedOrchestratorPrompt, orchestratorConfigPath, readOrchestratorConfig, setOrchestratorPrompt, writeOrchestratorConfig, } from './config.js';
14
+ export type { StoredOrchestratorConfig } from './config.js';
15
+ export declare const name = "local-infer-orchestrator";
16
+ export declare const inject: string[];
17
+ /**
18
+ * SystemPromptService narrows the dsh-system-prompt service to the one
19
+ * member this package uses. That package augments the cordis Context with
20
+ * `systemPrompt` and is not a dependency here, so the scoped inject casts
21
+ * the scope locally (same shape as the ui's WebServerService narrowing).
22
+ */
23
+ export interface SystemPromptService {
24
+ /**
25
+ * Registers one ordered prompt section in the calling scope and returns
26
+ * the Cordis effect disposer. `text` may be a provider re-evaluated at
27
+ * each assembly.
28
+ */
29
+ section(section: {
30
+ name: string;
31
+ order: number;
32
+ text: string | (() => string);
33
+ interpolate?: boolean;
34
+ }): () => void;
35
+ }
36
+ /**
37
+ * Mount the Orchestrator prompt. The scoped `systemPrompt` inject registers
38
+ * the one global `orchestrator` section where the seam exists; the effect
39
+ * scope ties the registration to the plugin, so it unregisters with the
40
+ * plugin. The scoped `webServer` inject registers the /local-infer/
41
+ * orchestrator settings routes where that seam exists, so a headless profile
42
+ * keeps no routes.
43
+ */
44
+ export declare function apply(ctx: Context): void;
45
+ declare const plugin: {
46
+ name: string;
47
+ inject: string[];
48
+ apply: typeof apply;
49
+ };
50
+ export default plugin;
51
+ //# sourceMappingURL=index.d.ts.map
@@ -0,0 +1,73 @@
1
+ /**
2
+ * The Orchestrator capability: an editable "Orchestrator Prompt" persisted
3
+ * under `~/.dsh/local-infer`, defaulted from the shipped `prompt.md`, and
4
+ * injected into the system prompt while the component is enabled.
5
+ *
6
+ * The prompt store (saved file, shipped default, effective-prompt holder)
7
+ * lives in ./config.js and is re-exported here as the single source of truth
8
+ * the system-prompt seam (TASK-003) and the settings routes (TASK-004) pull
9
+ * from.
10
+ * @module dsh-plugin-local-infer/orchestrator
11
+ */
12
+ import { getOrchestratorPrompt } from './config.js';
13
+ import { registerOrchestratorRoutes } from './route.js';
14
+ export { defaultOrchestratorPrompt, getOrchestratorPrompt, hasSavedOrchestratorPrompt, orchestratorConfigPath, readOrchestratorConfig, setOrchestratorPrompt, writeOrchestratorConfig, } from './config.js';
15
+ export const name = 'local-infer-orchestrator';
16
+ // No required top-level services: the `systemPrompt` and `webServer` seams
17
+ // are pulled with scoped injects in their own effects, so the component
18
+ // stays loadable in profiles that lack either service.
19
+ export const inject = [];
20
+ // The section placement: the deployment persona prefix sits at 0 and the
21
+ // first centrally allocated policy section (PLAN_POLICY) at 500, so 100
22
+ // puts the Orchestrator instructions just after the persona and ahead of
23
+ // first-party guidance. dsh-system-prompt allocates nothing between 0 and
24
+ // 500, and external contributions may pick any finite order.
25
+ const orchestratorSectionOrder = 100;
26
+ /**
27
+ * mountSeam pulls one optional service through a scoped inject and mounts
28
+ * the half that needs it. A profile without the seam never runs the
29
+ * callback, and a mount failure is logged and swallowed so the component
30
+ * still loads without that half. `skipped` names the half in the catch log.
31
+ */
32
+ function mountSeam(ctx, service, skipped, mount) {
33
+ ctx.inject([service], (scope) => {
34
+ try {
35
+ mount(scope);
36
+ }
37
+ catch (error) {
38
+ console.error(`[local-infer] orchestrator ${skipped}: ${error}`);
39
+ }
40
+ });
41
+ }
42
+ /**
43
+ * Mount the Orchestrator prompt. The scoped `systemPrompt` inject registers
44
+ * the one global `orchestrator` section where the seam exists; the effect
45
+ * scope ties the registration to the plugin, so it unregisters with the
46
+ * plugin. The scoped `webServer` inject registers the /local-infer/
47
+ * orchestrator settings routes where that seam exists, so a headless profile
48
+ * keeps no routes.
49
+ */
50
+ export function apply(ctx) {
51
+ if (typeof ctx.inject !== 'function') {
52
+ return;
53
+ }
54
+ mountSeam(ctx, 'systemPrompt', 'prompt section skipped', (scope) => {
55
+ const systemPrompt = scope.systemPrompt;
56
+ systemPrompt.section({
57
+ name: 'orchestrator',
58
+ order: orchestratorSectionOrder,
59
+ // The prompt is user-editable text: a stray {{var}} stays literal
60
+ // instead of failing every later prompt assembly.
61
+ interpolate: false,
62
+ // Provider form re-reads the holder per assembly, so a settings
63
+ // Save reaches the next assembly without a host restart.
64
+ text: () => getOrchestratorPrompt(),
65
+ });
66
+ });
67
+ mountSeam(ctx, 'webServer', 'settings routes skipped', (scope) => {
68
+ registerOrchestratorRoutes(scope);
69
+ });
70
+ }
71
+ const plugin = { name, inject, apply };
72
+ export default plugin;
73
+ //# sourceMappingURL=index.js.map
@@ -0,0 +1,60 @@
1
+ /**
2
+ * The Orchestrator settings routes the Web card talks to: GET
3
+ * /local-infer/orchestrator answers { prompt, defaultPrompt, saved } (the
4
+ * effective prompt, the shipped prompt.md default, and whether the effective
5
+ * prompt is a saved value), and POST /local-infer/orchestrator/save persists
6
+ * { prompt } through the config setter (an empty string clears the saved
7
+ * override back to the default) and answers with the same payload. The routes
8
+ * are held by an effect, so they go when the component does.
9
+ *
10
+ * The HTTP plumbing is a minimal local mirror of the ui package's defineRoute
11
+ * template (method guard 405, bounded body 413, JSON answer). The ui package
12
+ * does export its template, but this package deliberately keeps no dependency
13
+ * on ui: importing ui's route module would load its whole route graph (the
14
+ * service, providers, and core packages) into a component that ships disabled
15
+ * and must stay loadable headless, so the shared shape is copied rather than
16
+ * imported, and the two copies change together by hand. The stream helpers
17
+ * the ui template carries are dropped; these two routes only ever answer with
18
+ * one JSON body.
19
+ * @module dsh-plugin-local-infer/orchestrator/route
20
+ */
21
+ import type { Context } from '@deepseek-ai/cordis';
22
+ /**
23
+ * OrchestratorRoute is one webServer route definition the register step holds
24
+ * by an effect: the stable name, the exact-match path, and the handler the web
25
+ * server invokes per request.
26
+ */
27
+ export interface OrchestratorRoute {
28
+ name: string;
29
+ kind: 'exact';
30
+ path: string;
31
+ handler: (req: IncomingLike, res: OutgoingLike) => void | Promise<void>;
32
+ }
33
+ /**
34
+ * The webServer service is dsh-specific and absent from the cordis Context
35
+ * type, so the route narrows the scoped context to the one member it needs
36
+ * (same shape as the ui's WebServerService narrowing).
37
+ */
38
+ export interface WebServerService {
39
+ register(route: OrchestratorRoute): () => void;
40
+ }
41
+ interface IncomingLike extends AsyncIterable<Buffer> {
42
+ method: string;
43
+ url: string;
44
+ destroy(): void;
45
+ }
46
+ interface OutgoingLike {
47
+ writeHead(status: number, headers?: Record<string, string>): OutgoingLike;
48
+ end(body?: string): void;
49
+ }
50
+ /**
51
+ * registerOrchestratorRoutes registers the GET and save routes on the web
52
+ * server and holds them by an effect, so a component switch off removes them
53
+ * before the next switch on re-registers. The scoped context carries the
54
+ * webServer.
55
+ */
56
+ export declare function registerOrchestratorRoutes(scope: Context & {
57
+ webServer: WebServerService;
58
+ }): void;
59
+ export {};
60
+ //# sourceMappingURL=route.d.ts.map
@@ -0,0 +1,159 @@
1
+ /**
2
+ * The Orchestrator settings routes the Web card talks to: GET
3
+ * /local-infer/orchestrator answers { prompt, defaultPrompt, saved } (the
4
+ * effective prompt, the shipped prompt.md default, and whether the effective
5
+ * prompt is a saved value), and POST /local-infer/orchestrator/save persists
6
+ * { prompt } through the config setter (an empty string clears the saved
7
+ * override back to the default) and answers with the same payload. The routes
8
+ * are held by an effect, so they go when the component does.
9
+ *
10
+ * The HTTP plumbing is a minimal local mirror of the ui package's defineRoute
11
+ * template (method guard 405, bounded body 413, JSON answer). The ui package
12
+ * does export its template, but this package deliberately keeps no dependency
13
+ * on ui: importing ui's route module would load its whole route graph (the
14
+ * service, providers, and core packages) into a component that ships disabled
15
+ * and must stay loadable headless, so the shared shape is copied rather than
16
+ * imported, and the two copies change together by hand. The stream helpers
17
+ * the ui template carries are dropped; these two routes only ever answer with
18
+ * one JSON body.
19
+ * @module dsh-plugin-local-infer/orchestrator/route
20
+ */
21
+ import { defaultOrchestratorPrompt, getOrchestratorPrompt, hasSavedOrchestratorPrompt, setOrchestratorPrompt, } from './config.js';
22
+ /**
23
+ * RouteError is a route failure that carries its own HTTP status, so a
24
+ * handler can answer a validation rejection with its own code instead of the
25
+ * spec's failStatus.
26
+ */
27
+ class RouteError extends Error {
28
+ status;
29
+ constructor(status, message) {
30
+ super(message);
31
+ this.name = 'RouteError';
32
+ this.status = status;
33
+ }
34
+ }
35
+ /**
36
+ * The request body size cap the save route enforces: a prompt is a few
37
+ * kilobytes at most, so a body past 64 KiB is a client bug, not a prompt.
38
+ * Deliberately mirrors the cap in packages/ui/src/route.ts (ui is not a
39
+ * dependency here): one malformed client misbehaves the same on every
40
+ * /local-infer route, so edit the two together.
41
+ */
42
+ const MAX_BODY_BYTES = 64 * 1024;
43
+ /**
44
+ * readJsonBody collects a bounded JSON request body: chunks up to the cap,
45
+ * then parses. A body past the cap destroys the request and throws a 413
46
+ * RouteError carrying the route's own message, so the answer names the route
47
+ * that rejected the body.
48
+ */
49
+ async function readJsonBody(req, tooLargeMessage) {
50
+ const chunks = [];
51
+ let total = 0;
52
+ for await (const chunk of req) {
53
+ total += chunk.length;
54
+ if (total > MAX_BODY_BYTES) {
55
+ req.destroy();
56
+ throw new RouteError(413, tooLargeMessage);
57
+ }
58
+ chunks.push(chunk);
59
+ }
60
+ return JSON.parse(Buffer.concat(chunks).toString('utf8'));
61
+ }
62
+ /** Writes one JSON answer (status head plus body) on the response. */
63
+ function writeJson(res, status, body) {
64
+ res.writeHead(status, { 'content-type': 'application/json' });
65
+ res.end(JSON.stringify(body));
66
+ }
67
+ /**
68
+ * defineRoute is the local template both route specs build on: it guards the
69
+ * method (405), reads the bounded body (413, POST only), and maps the
70
+ * handler's answer to a status: a RouteError carries its own status, any
71
+ * other failure answers with the spec's failStatus.
72
+ */
73
+ function defineRoute(spec) {
74
+ return {
75
+ name: spec.name,
76
+ kind: 'exact',
77
+ path: spec.path,
78
+ handler: async (req, res) => {
79
+ if (req.method !== spec.method) {
80
+ res.writeHead(405).end();
81
+ return;
82
+ }
83
+ try {
84
+ const body = spec.method === 'POST' ? await readJsonBody(req, spec.tooLargeMessage) : {};
85
+ await spec.run({ url: new URL(req.url, 'http://localhost'), body }, (status, answer) => writeJson(res, status, answer));
86
+ }
87
+ catch (error) {
88
+ if (error instanceof RouteError) {
89
+ writeJson(res, error.status, { error: error.message });
90
+ return;
91
+ }
92
+ writeJson(res, spec.failStatus, { error: String(error?.message ?? error) });
93
+ }
94
+ },
95
+ };
96
+ }
97
+ function orchestratorPayload() {
98
+ return {
99
+ prompt: getOrchestratorPrompt(),
100
+ defaultPrompt: defaultOrchestratorPrompt(),
101
+ saved: hasSavedOrchestratorPrompt(),
102
+ };
103
+ }
104
+ /**
105
+ * orchestratorGetRoute builds the GET /local-infer/orchestrator route. The
106
+ * client treats any non-404 answer as proof the route is mounted, so the
107
+ * payload answers 200 even before anything is saved.
108
+ */
109
+ function orchestratorGetRoute() {
110
+ return defineRoute({
111
+ name: 'local-infer-orchestrator',
112
+ path: '/local-infer/orchestrator',
113
+ method: 'GET',
114
+ failStatus: 500,
115
+ run: async (_input, json) => {
116
+ json(200, orchestratorPayload());
117
+ },
118
+ });
119
+ }
120
+ /**
121
+ * orchestratorSaveRoute builds the POST /local-infer/orchestrator/save route:
122
+ * a string prompt persists through setOrchestratorPrompt (an empty string
123
+ * clears the saved override back to the default) and the answer carries the
124
+ * GET payload shape so the card re-renders from one response.
125
+ */
126
+ function orchestratorSaveRoute() {
127
+ return defineRoute({
128
+ name: 'local-infer-orchestrator-save',
129
+ path: '/local-infer/orchestrator/save',
130
+ method: 'POST',
131
+ failStatus: 400,
132
+ tooLargeMessage: 'orchestrator prompt payload too large',
133
+ run: async ({ body }, json) => {
134
+ if (typeof body.prompt !== 'string') {
135
+ throw new RouteError(400, 'prompt must be a string');
136
+ }
137
+ setOrchestratorPrompt(body.prompt);
138
+ json(200, orchestratorPayload());
139
+ },
140
+ });
141
+ }
142
+ /**
143
+ * registerOrchestratorRoutes registers the GET and save routes on the web
144
+ * server and holds them by an effect, so a component switch off removes them
145
+ * before the next switch on re-registers. The scoped context carries the
146
+ * webServer.
147
+ */
148
+ export function registerOrchestratorRoutes(scope) {
149
+ const routes = [orchestratorGetRoute(), orchestratorSaveRoute()];
150
+ scope.effect(() => {
151
+ const disposers = routes.map((route) => scope.webServer.register(route));
152
+ return () => {
153
+ for (const dispose of disposers) {
154
+ dispose();
155
+ }
156
+ };
157
+ }, 'local-infer-orchestrator: settings routes');
158
+ }
159
+ //# sourceMappingURL=route.js.map
@@ -0,0 +1,6 @@
1
+ {
2
+ "meta": {
3
+ "title": "Orchestrator",
4
+ "description": "Edit the Orchestrator Prompt the component injects into the system prompt while it is enabled."
5
+ }
6
+ }
@@ -0,0 +1,39 @@
1
+ {
2
+ "name": "dsh-plugin-local-infer-orchestrator",
3
+ "version": "0.1.4",
4
+ "description": "Orchestrator component for the dsh local-inference plugin: an editable Orchestrator Prompt persisted under ~/.dsh/local-infer, defaulted from the shipped prompt.md, injected into the system prompt while the component is enabled",
5
+ "keywords": [
6
+ "dsh",
7
+ "dsh-plugin",
8
+ "deepseek-harness",
9
+ "local-inference",
10
+ "orchestrator",
11
+ "system-prompt"
12
+ ],
13
+ "license": "MIT",
14
+ "type": "module",
15
+ "main": "lib/index.js",
16
+ "types": "lib/index.d.ts",
17
+ "exports": {
18
+ ".": {
19
+ "types": "./lib/index.d.ts",
20
+ "default": "./lib/index.js"
21
+ },
22
+ "./package.json": "./package.json"
23
+ },
24
+ "files": [
25
+ "lib/**/*.js",
26
+ "lib/**/*.d.ts",
27
+ "prompt.md",
28
+ "locale/en.json"
29
+ ],
30
+ "publishConfig": {
31
+ "access": "public"
32
+ },
33
+ "peerDependencies": {
34
+ "@deepseek-ai/cordis": ">=4.0.1"
35
+ },
36
+ "devDependencies": {
37
+ "@deepseek-ai/cordis": "^4.0.6-alpha.2"
38
+ }
39
+ }
@@ -0,0 +1,87 @@
1
+ # Role & Core Objective
2
+ You are an advanced software engineering orchestration agent.
3
+ Your goal is to systematically plan, execute, and finalize user requests using micro-tasks and subagents.
4
+ Always adhere strictly to the following execution sequence.
5
+
6
+ ---
7
+
8
+ ## Step 1: Initialization & Planning
9
+ 1. **Gather Context**: Analyze the user request.
10
+ 2. **Initialize Plan**: Execute the `todo_write` tool. Include an initial strategy containing a Phase Plan, Task Breakdown, and a Questionnaire step.
11
+ Do not include individual tasks at this time.
12
+ 3. **Generate Plan File**: Create a Markdown file named `PLAN-{{1OR2WORD-SLUG}}.md` in the root directory containing:
13
+ - A short description of the objective at the very top.
14
+ - Verification guidelines (Do not duplicate any rules found in `AGENTS.md`).
15
+ - A sequential list of open questions for the user.
16
+ - An ordered list of micro-tasks, group logically by Phase.
17
+ Each task must represent the smallest possible unit of work with a concrete, verifiable "Definition of Done".
18
+ 4. **Review Plan File**: Remove any duplicative context so that each statement
19
+ the single source of truth. Remove reasoning notes about task ordering,
20
+ replacing with a clear Markdown list of task dependencies.
21
+
22
+ ## Step 2: Refactoring Tasks Injection
23
+ Where appropriate, insert specialized tasks starting with `Refactor:` into your task sequence.
24
+ These tasks must contain the exact following instruction block,
25
+ with the `{{N}}` count template replaced by the number of Tasks in the Phase:
26
+ ```text
27
+ Review the files touched by the previous {{N}} commits and identify the following code risks:
28
+ - **Multiple Sources of Truth**: Same calculations done in multiple places.
29
+ - **Duplicate Code**: Nearly-identical code in multiple methods.
30
+ - **Bloaters**: Too many things done in a single method or class.
31
+ - **Data Clumps**: Single variables that travel in a group for multiple methods.
32
+ - **Shotgun Edits**: Commits with singular changes that touch multiple files.
33
+ - **Feature Envy**: Method where over 50% of the code manipulates a different class.
34
+ - **Magic Numbers**: Literals without context in method bodies.
35
+ Then address and resolve each risk.
36
+ ```
37
+
38
+ ## Step 3: Architecture-Dependent Architecture Selection
39
+ Count the total number of sequential tasks generated. Execute branch **A** or **B** based on the count:
40
+
41
+ ### Branch A: High-Complexity Architecture (5 or More Tasks)
42
+ 1. **Deconstruct Plan**: Extract each task body out of the main index file.
43
+ 2. **Create Task Files**: Save each task into its own file using this naming convention: `docs/PLAN-{{1OR2WORD-SLUG}}-TASK-###-{{SHORT-DESC-SLUG}}.md`.
44
+ 3. **Update Main Index**: Ensure `PLAN-{{1OR2WORD-SLUG}}.md` becomes a slim index where tasks are grouped logically by section and linked using exact Markdown checklist syntax:
45
+ ` - [ ] [TASK-###-{{SHORT-DESC-SLUG}}](docs/PLAN-{{1OR2WORD-SLUG}}-TASK-###-{{SHORT-DESC-SLUG}}.md)`
46
+ 4. **Set Session Goals**: Use the `create_goal` tool to register all session goals.
47
+
48
+ ### Branch B: Low-Complexity Architecture (Less Than 5 Tasks)
49
+ 1. **Deconstruct Tasks**: Break down each task into a series of todos.
50
+ In Step 4, when writing each task to the global todo list, include the
51
+ series of todos for each task as an individual todo between tasks.
52
+
53
+ ## Step 4: Questionnaire & Baseline Commit
54
+ 1. **Append To-Dos**: Use the `todo_write` tool to insert your tasks directly into the global todo list.
55
+ 2. **Add Finalizer To-Do**: Append a final `Finalize` item to the end of that list.
56
+ 3. **Interview User**: For every open question identified in Step 1, invoke the `ask_user_question` tool individually.
57
+ Provide at least one recommended answer and leave a spot open for the user to answer with their own input.
58
+ 4. **Persist Answers**: As answers arrive, write them directly into `PLAN-{{1OR2WORD-SLUG}}.md` (or the specific task file if using Branch A).
59
+ 5. **Close Questionnaire**: Mark the Questionnaire task as complete.
60
+ 6. **Commit Blueprint**: If on Branch A (High-Complexity), commit the created `PLAN` file (and accompanying `docs/` task files if applicable) to repository version control.
61
+
62
+ ## Step 5: Subagent Execution Loop
63
+ Loop through the tasks sequentially. For **each** incomplete task:
64
+ 1. **Launch Subagent**: Trigger the `subagent` tool with this exact prompt,
65
+ replacing the PLAN filename template:
66
+ ```text
67
+ 1. Complete the next Task in @PLAN-{{1OR2WORD-SLUG}}.md .
68
+ 2. Use the `todo_write` tool to plan your work.
69
+ 3. Check ('[x]') the task in the file when done, then commit the completed work.
70
+ 4. List any discovered pre-existing issues for the parent agent to review.
71
+ 5. Then you are finished; resolve remaining todos and end the turn.
72
+ ```
73
+ 2. **Confirm Subagent** Trigger the `list_agents` tool to confirm the subagent is running, then end turn.
74
+ 3. **Resume and Evaluate Subagent Output**: The subagent will resume with a `notify` in a new turn.
75
+ If the subagent discovers pre-existing codebase issues, insert new tasks immediately after the current task in the appropriate execution order.
76
+ 4. **Sync State**: Invoke the `todo_write` tool to check off progress.
77
+ 5. **Repeat**: Proceed to the next task until all items in the plan are checked `[x]`.
78
+
79
+ ## Step 6: Finalization & Handoff
80
+ 1. **Cleanup Artifacts**: Delete all generated `PLAN-{{1OR2WORD-SLUG}}.md` and `docs/PLAN-{{1OR2WORD-SLUG}}-TASK*` files.
81
+ Remove all memory and file references, restoring the repo development to a stateless condition.
82
+ 2. **Commit Cleanup**: Commit these deletions to repository version control.
83
+ 3. **Wrap up tasks**: Sync and close out any lingering task tracking states using the appropriate tool.
84
+ 4. **Present Results**: Invoke the `present` tool to officially deliver the completed work to the user.
85
+ 5. **Complete**: End the turn.
86
+
87
+ ---