dsh-plugin-local-infer 0.1.2 → 0.1.3
This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
- package/README.md +10 -2
- package/docs/zh/README.md +10 -2
- package/dsh/client.js +669 -191
- package/package.json +6 -1
- package/packages/core/lib/adapter.d.ts +44 -2
- package/packages/core/lib/deps.d.ts +4 -3
- package/packages/core/lib/index.d.ts +1 -1
- package/packages/core/lib/registrar.d.ts +5 -5
- package/packages/core/lib/registrar.js +3 -3
- package/packages/core/package.json +1 -1
- package/packages/providers/lib/acquire.d.ts +5 -3
- package/packages/providers/lib/acquire.js +30 -9
- package/packages/providers/lib/adapters.d.ts +19 -209
- package/packages/providers/lib/adapters.js +13 -886
- package/packages/providers/lib/deps.d.ts +24 -2
- package/packages/providers/lib/deps.js +23 -4
- package/packages/providers/lib/engines/hyperqwenAdapter.d.ts +38 -0
- package/packages/providers/lib/engines/hyperqwenAdapter.js +105 -0
- package/packages/providers/lib/{infernix.js → engines/infernix.js} +1 -1
- package/packages/providers/lib/engines/infernixAdapter.d.ts +53 -0
- package/packages/providers/lib/engines/infernixAdapter.js +202 -0
- package/packages/providers/lib/engines/llamacppAdapter.d.ts +51 -0
- package/packages/providers/lib/engines/llamacppAdapter.js +232 -0
- package/packages/providers/lib/{ninfer.js → engines/ninfer.js} +1 -1
- package/packages/providers/lib/engines/ninferAdapter.d.ts +82 -0
- package/packages/providers/lib/engines/ninferAdapter.js +324 -0
- package/packages/providers/lib/engines/strata.d.ts +53 -0
- package/packages/providers/lib/engines/strata.js +197 -0
- package/packages/providers/lib/engines/strataAdapter.d.ts +98 -0
- package/packages/providers/lib/engines/strataAdapter.js +427 -0
- package/packages/providers/lib/engines.d.ts +5 -4
- package/packages/providers/lib/engines.js +10 -10
- package/packages/providers/lib/guidelines.js +1 -1
- package/packages/providers/lib/index.d.ts +14 -9
- package/packages/providers/lib/index.js +17 -7
- package/packages/providers/lib/model-defaults.d.ts +5 -4
- package/packages/providers/lib/model-defaults.js +22 -4
- package/packages/providers/lib/platform.js +7 -1
- package/packages/providers/package.json +1 -1
- package/packages/service/lib/index.d.ts +13 -4
- package/packages/service/lib/index.js +79 -5
- package/packages/service/lib/types.d.ts +5 -4
- package/packages/service/package.json +1 -1
- package/packages/tool/package.json +1 -1
- package/packages/ui/lib/config.d.ts +79 -0
- package/packages/ui/lib/config.js +235 -0
- package/packages/ui/lib/deps.d.ts +3 -3
- package/packages/ui/lib/ops/engine.d.ts +108 -0
- package/packages/ui/lib/ops/engine.js +493 -0
- package/packages/ui/lib/ops/hf.d.ts +27 -0
- package/packages/ui/lib/ops/hf.js +60 -0
- package/packages/ui/lib/ops/logs.d.ts +23 -0
- package/packages/ui/lib/ops/logs.js +58 -0
- package/packages/ui/lib/ops/model.d.ts +79 -0
- package/packages/ui/lib/ops/model.js +130 -0
- package/packages/ui/lib/request.d.ts +106 -0
- package/packages/ui/lib/request.js +80 -0
- package/packages/ui/lib/route.d.ts +88 -420
- package/packages/ui/lib/route.js +111 -1843
- package/packages/ui/lib/routes/chat-template.d.ts +14 -0
- package/packages/ui/lib/routes/chat-template.js +37 -0
- package/packages/ui/lib/routes/deps.d.ts +16 -0
- package/packages/ui/lib/routes/deps.js +27 -0
- package/packages/ui/lib/routes/download.d.ts +16 -0
- package/packages/ui/lib/routes/download.js +48 -0
- package/packages/ui/lib/routes/get.d.ts +18 -0
- package/packages/ui/lib/routes/get.js +57 -0
- package/packages/ui/lib/routes/install.d.ts +16 -0
- package/packages/ui/lib/routes/install.js +36 -0
- package/packages/ui/lib/routes/launch.d.ts +18 -0
- package/packages/ui/lib/routes/launch.js +50 -0
- package/packages/ui/lib/routes/provider-delete.d.ts +15 -0
- package/packages/ui/lib/routes/provider-delete.js +37 -0
- package/packages/ui/lib/routes/register.d.ts +16 -0
- package/packages/ui/lib/routes/register.js +28 -0
- package/packages/ui/lib/routes/save.d.ts +18 -0
- package/packages/ui/lib/routes/save.js +139 -0
- package/packages/ui/lib/routes/stop.d.ts +16 -0
- package/packages/ui/lib/routes/stop.js +29 -0
- package/packages/ui/lib/routes/summary.d.ts +15 -0
- package/packages/ui/lib/routes/summary.js +26 -0
- package/packages/ui/lib/routes/unregister.d.ts +14 -0
- package/packages/ui/lib/routes/unregister.js +26 -0
- package/packages/ui/lib/viewmodels/deps.d.ts +31 -0
- package/packages/ui/lib/viewmodels/deps.js +89 -0
- package/packages/ui/lib/viewmodels/depsHelpers.d.ts +28 -0
- package/packages/ui/lib/viewmodels/depsHelpers.js +33 -0
- package/packages/ui/lib/viewmodels/summary.d.ts +140 -0
- package/packages/ui/lib/viewmodels/summary.js +225 -0
- package/packages/ui/lib/viewmodels/summaryHelpers.d.ts +30 -0
- package/packages/ui/lib/viewmodels/summaryHelpers.js +42 -0
- package/packages/ui/package.json +1 -1
- package/packages/providers/lib/strata.d.ts +0 -15
- package/packages/providers/lib/strata.js +0 -14
- /package/packages/providers/lib/{hyperqwen.d.ts → engines/hyperqwen.d.ts} +0 -0
- /package/packages/providers/lib/{hyperqwen.js → engines/hyperqwen.js} +0 -0
- /package/packages/providers/lib/{infernix.d.ts → engines/infernix.d.ts} +0 -0
- /package/packages/providers/lib/{llamacpp.d.ts → engines/llamacpp.d.ts} +0 -0
- /package/packages/providers/lib/{llamacpp.js → engines/llamacpp.js} +0 -0
- /package/packages/providers/lib/{ninfer.d.ts → engines/ninfer.d.ts} +0 -0
|
@@ -0,0 +1,14 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The POST /local-infer/chat-template route: the card's auto-download (and
|
|
3
|
+
* the System-dependencies fallback) pulls a selected template into the model
|
|
4
|
+
* directory through this route, so a picked preset works out of the box.
|
|
5
|
+
* @module dsh-plugin-local-infer/ui/routes/chat-template
|
|
6
|
+
*/
|
|
7
|
+
import type { LocalInferService } from 'dsh-plugin-local-infer/service';
|
|
8
|
+
import type { LocalInferRoute } from '../route.ts';
|
|
9
|
+
/**
|
|
10
|
+
* chatTemplateRoute builds the POST /local-infer/chat-template route
|
|
11
|
+
* definition the register step holds by an effect.
|
|
12
|
+
*/
|
|
13
|
+
export declare function chatTemplateRoute(localInfer: LocalInferService): LocalInferRoute;
|
|
14
|
+
//# sourceMappingURL=chat-template.d.ts.map
|
|
@@ -0,0 +1,37 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The POST /local-infer/chat-template route: the card's auto-download (and
|
|
3
|
+
* the System-dependencies fallback) pulls a selected template into the model
|
|
4
|
+
* directory through this route, so a picked preset works out of the box.
|
|
5
|
+
* @module dsh-plugin-local-infer/ui/routes/chat-template
|
|
6
|
+
*/
|
|
7
|
+
import { defineRoute } from "../route.js";
|
|
8
|
+
import { chatTemplateDownloadFor } from "../ops/hf.js";
|
|
9
|
+
/**
|
|
10
|
+
* chatTemplateRoute builds the POST /local-infer/chat-template route
|
|
11
|
+
* definition the register step holds by an effect.
|
|
12
|
+
*/
|
|
13
|
+
export function chatTemplateRoute(localInfer) {
|
|
14
|
+
return defineRoute({
|
|
15
|
+
name: 'local-infer-chat-template',
|
|
16
|
+
path: '/local-infer/chat-template',
|
|
17
|
+
method: 'POST',
|
|
18
|
+
failStatus: 500,
|
|
19
|
+
tooLargeMessage: 'chat template payload too large',
|
|
20
|
+
run: async ({ body }, res) => {
|
|
21
|
+
// exactOptionalPropertyTypes: build the request object with only the
|
|
22
|
+
// keys that are present, so an absent value never writes `undefined`.
|
|
23
|
+
const request = {};
|
|
24
|
+
if (typeof body.engine === 'string') {
|
|
25
|
+
request.engine = body.engine;
|
|
26
|
+
}
|
|
27
|
+
if (typeof body.template === 'string') {
|
|
28
|
+
request.template = body.template;
|
|
29
|
+
}
|
|
30
|
+
if (typeof body.directory === 'string') {
|
|
31
|
+
request.directory = body.directory;
|
|
32
|
+
}
|
|
33
|
+
res.json(200, await chatTemplateDownloadFor(localInfer, request));
|
|
34
|
+
},
|
|
35
|
+
});
|
|
36
|
+
}
|
|
37
|
+
//# sourceMappingURL=chat-template.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GET /local-infer/deps route: the deps panel read model. The handler
|
|
3
|
+
* parses the engine and config query params (an absent engine or a broken
|
|
4
|
+
* config falls back to the stored config) and answers with the dep plan, the
|
|
5
|
+
* per-dep statuses, the copy/paste install string, and the Play/Run trust
|
|
6
|
+
* gate.
|
|
7
|
+
* @module dsh-plugin-local-infer/ui/routes/deps
|
|
8
|
+
*/
|
|
9
|
+
import type { LocalInferService } from 'dsh-plugin-local-infer/service';
|
|
10
|
+
import type { LocalInferRoute } from '../route.ts';
|
|
11
|
+
/**
|
|
12
|
+
* depsRoute builds the GET /local-infer/deps route definition the register
|
|
13
|
+
* step holds by an effect.
|
|
14
|
+
*/
|
|
15
|
+
export declare function depsRoute(localInfer: LocalInferService): LocalInferRoute;
|
|
16
|
+
//# sourceMappingURL=deps.d.ts.map
|
|
@@ -0,0 +1,27 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The GET /local-infer/deps route: the deps panel read model. The handler
|
|
3
|
+
* parses the engine and config query params (an absent engine or a broken
|
|
4
|
+
* config falls back to the stored config) and answers with the dep plan, the
|
|
5
|
+
* per-dep statuses, the copy/paste install string, and the Play/Run trust
|
|
6
|
+
* gate.
|
|
7
|
+
* @module dsh-plugin-local-infer/ui/routes/deps
|
|
8
|
+
*/
|
|
9
|
+
import { defineRoute } from "../route.js";
|
|
10
|
+
import { depsRequestFromUrl } from "../request.js";
|
|
11
|
+
import { buildDeps } from "../viewmodels/deps.js";
|
|
12
|
+
/**
|
|
13
|
+
* depsRoute builds the GET /local-infer/deps route definition the register
|
|
14
|
+
* step holds by an effect.
|
|
15
|
+
*/
|
|
16
|
+
export function depsRoute(localInfer) {
|
|
17
|
+
return defineRoute({
|
|
18
|
+
name: 'local-infer-deps',
|
|
19
|
+
path: '/local-infer/deps',
|
|
20
|
+
method: 'GET',
|
|
21
|
+
failStatus: 500,
|
|
22
|
+
run: async ({ url }, res) => {
|
|
23
|
+
res.json(200, await buildDeps(localInfer, depsRequestFromUrl(url)));
|
|
24
|
+
},
|
|
25
|
+
});
|
|
26
|
+
}
|
|
27
|
+
//# sourceMappingURL=deps.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The POST /local-infer/download route: it runs the hf CLI download for the
|
|
3
|
+
* request's default model, resolving the entry through the providers'
|
|
4
|
+
* default list (a 404 when no entry names the pair) and the directory
|
|
5
|
+
* against the request, the stored config, and the plugin's default model
|
|
6
|
+
* directory in that order.
|
|
7
|
+
* @module dsh-plugin-local-infer/ui/routes/download
|
|
8
|
+
*/
|
|
9
|
+
import type { LocalInferService } from 'dsh-plugin-local-infer/service';
|
|
10
|
+
import type { LocalInferRoute } from '../route.ts';
|
|
11
|
+
/**
|
|
12
|
+
* downloadRoute builds the POST /local-infer/download route definition the
|
|
13
|
+
* register step holds by an effect.
|
|
14
|
+
*/
|
|
15
|
+
export declare function downloadRoute(localInfer: LocalInferService): LocalInferRoute;
|
|
16
|
+
//# sourceMappingURL=download.d.ts.map
|
|
@@ -0,0 +1,48 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The POST /local-infer/download route: it runs the hf CLI download for the
|
|
3
|
+
* request's default model, resolving the entry through the providers'
|
|
4
|
+
* default list (a 404 when no entry names the pair) and the directory
|
|
5
|
+
* against the request, the stored config, and the plugin's default model
|
|
6
|
+
* directory in that order.
|
|
7
|
+
* @module dsh-plugin-local-infer/ui/routes/download
|
|
8
|
+
*/
|
|
9
|
+
import { defineRoute } from "../route.js";
|
|
10
|
+
import { downloadFor } from "../ops/hf.js";
|
|
11
|
+
import { persistDownloadLog } from "../ops/logs.js";
|
|
12
|
+
/**
|
|
13
|
+
* downloadRoute builds the POST /local-infer/download route definition the
|
|
14
|
+
* register step holds by an effect.
|
|
15
|
+
*/
|
|
16
|
+
export function downloadRoute(localInfer) {
|
|
17
|
+
return defineRoute({
|
|
18
|
+
name: 'local-infer-download',
|
|
19
|
+
path: '/local-infer/download',
|
|
20
|
+
method: 'POST',
|
|
21
|
+
failStatus: 500,
|
|
22
|
+
tooLargeMessage: 'download payload too large',
|
|
23
|
+
run: async ({ body }, res) => {
|
|
24
|
+
// exactOptionalPropertyTypes: build the request object with only the
|
|
25
|
+
// keys that are present, so an absent value never writes `undefined`.
|
|
26
|
+
const request = {};
|
|
27
|
+
if (typeof body.engine === 'string') {
|
|
28
|
+
request.engine = body.engine;
|
|
29
|
+
}
|
|
30
|
+
if (typeof body.model === 'string') {
|
|
31
|
+
request.model = body.model;
|
|
32
|
+
}
|
|
33
|
+
if (typeof body.directory === 'string') {
|
|
34
|
+
request.directory = body.directory;
|
|
35
|
+
}
|
|
36
|
+
const result = await downloadFor(localInfer, request);
|
|
37
|
+
// The "Downloading..." separator leads the persisted run, so the Logs
|
|
38
|
+
// section and the log file read the download as a fresh process section,
|
|
39
|
+
// the same line the card writes when the Download button is clicked.
|
|
40
|
+
const line = result.ok
|
|
41
|
+
? 'download complete\n'
|
|
42
|
+
: `!! download failed${result.detail !== undefined ? `: ${result.detail}` : ''}\n`;
|
|
43
|
+
persistDownloadLog(`--- Downloading...\n${line}`);
|
|
44
|
+
res.json(200, result);
|
|
45
|
+
},
|
|
46
|
+
});
|
|
47
|
+
}
|
|
48
|
+
//# sourceMappingURL=download.js.map
|
|
@@ -0,0 +1,18 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The POST /local-infer/get route: the Get step. Its answer streams as plain
|
|
3
|
+
* text, so the card appends the git sync, the dependency run, and the build
|
|
4
|
+
* output to its Logs section as it lands. The full run persists as the
|
|
5
|
+
* last-run logs.
|
|
6
|
+
* @module dsh-plugin-local-infer/ui/routes/get
|
|
7
|
+
*/
|
|
8
|
+
import type { LifecycleHost } from 'dsh-plugin-local-infer/core';
|
|
9
|
+
import type { LocalInferService } from 'dsh-plugin-local-infer/service';
|
|
10
|
+
import type { LocalInferRoute } from '../route.ts';
|
|
11
|
+
/**
|
|
12
|
+
* getRoute builds the POST /local-infer/get route definition the register
|
|
13
|
+
* step holds by an effect. The optional getHost is the lifecycle host the
|
|
14
|
+
* git and build steps run through; it defaults to the node host, and a test
|
|
15
|
+
* injects a stub so the route never clones a real repo in CI.
|
|
16
|
+
*/
|
|
17
|
+
export declare function getRoute(localInfer: LocalInferService, getHost?: LifecycleHost): LocalInferRoute;
|
|
18
|
+
//# sourceMappingURL=get.d.ts.map
|
|
@@ -0,0 +1,57 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The POST /local-infer/get route: the Get step. Its answer streams as plain
|
|
3
|
+
* text, so the card appends the git sync, the dependency run, and the build
|
|
4
|
+
* output to its Logs section as it lands. The full run persists as the
|
|
5
|
+
* last-run logs.
|
|
6
|
+
* @module dsh-plugin-local-infer/ui/routes/get
|
|
7
|
+
*/
|
|
8
|
+
import { parseStoredPlatformConfig } from "../config.js";
|
|
9
|
+
import { getEngine } from "../ops/engine.js";
|
|
10
|
+
import { persistGetLogs } from "../ops/logs.js";
|
|
11
|
+
import { defineRoute } from "../route.js";
|
|
12
|
+
/**
|
|
13
|
+
* getRoute builds the POST /local-infer/get route definition the register
|
|
14
|
+
* step holds by an effect. The optional getHost is the lifecycle host the
|
|
15
|
+
* git and build steps run through; it defaults to the node host, and a test
|
|
16
|
+
* injects a stub so the route never clones a real repo in CI.
|
|
17
|
+
*/
|
|
18
|
+
export function getRoute(localInfer, getHost) {
|
|
19
|
+
return defineRoute({
|
|
20
|
+
name: 'local-infer-get',
|
|
21
|
+
path: '/local-infer/get',
|
|
22
|
+
method: 'POST',
|
|
23
|
+
failStatus: 400,
|
|
24
|
+
tooLargeMessage: 'get payload too large',
|
|
25
|
+
run: async ({ body }, res) => {
|
|
26
|
+
const request = {};
|
|
27
|
+
if (typeof body.engine === 'string') {
|
|
28
|
+
request.engine = body.engine;
|
|
29
|
+
}
|
|
30
|
+
if (body.config && typeof body.config === 'object') {
|
|
31
|
+
request.config = body.config;
|
|
32
|
+
}
|
|
33
|
+
const platform = parseStoredPlatformConfig(body.platform);
|
|
34
|
+
if (platform !== undefined) {
|
|
35
|
+
request.platform = platform;
|
|
36
|
+
}
|
|
37
|
+
res.textStream();
|
|
38
|
+
let collected = '';
|
|
39
|
+
const log = (text) => {
|
|
40
|
+
collected += text;
|
|
41
|
+
res.write(text);
|
|
42
|
+
};
|
|
43
|
+
try {
|
|
44
|
+
await getEngine(localInfer, request, log, getHost);
|
|
45
|
+
}
|
|
46
|
+
catch (error) {
|
|
47
|
+
log(`!! get failed: ${String(error?.message ?? error)}\n`);
|
|
48
|
+
}
|
|
49
|
+
// The "Getting..." separator leads the persisted run, so the Logs
|
|
50
|
+
// section and the log file read the run as a fresh process section, the
|
|
51
|
+
// same line the card writes when the Get button is clicked.
|
|
52
|
+
persistGetLogs(`--- Getting...\n${collected}`);
|
|
53
|
+
res.end();
|
|
54
|
+
},
|
|
55
|
+
});
|
|
56
|
+
}
|
|
57
|
+
//# 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,18 @@
|
|
|
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, then a final
|
|
6
|
+
* result event. The card's Launch control reads the step that is running and
|
|
7
|
+
* times out only the launch (health-poll) step; the rebuild steps run as
|
|
8
|
+
* long as they need to.
|
|
9
|
+
* @module dsh-plugin-local-infer/ui/routes/launch
|
|
10
|
+
*/
|
|
11
|
+
import type { LocalInferService } from 'dsh-plugin-local-infer/service';
|
|
12
|
+
import type { LocalInferRoute } from '../route.ts';
|
|
13
|
+
/**
|
|
14
|
+
* launchRoute builds the POST /local-infer/launch route definition the
|
|
15
|
+
* register step holds by an effect.
|
|
16
|
+
*/
|
|
17
|
+
export declare function launchRoute(localInfer: LocalInferService): LocalInferRoute;
|
|
18
|
+
//# sourceMappingURL=launch.d.ts.map
|
|
@@ -0,0 +1,50 @@
|
|
|
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, then a final
|
|
6
|
+
* result event. The card's Launch control reads the step that is running and
|
|
7
|
+
* times out only the launch (health-poll) step; the rebuild steps run as
|
|
8
|
+
* long as they need to.
|
|
9
|
+
* @module dsh-plugin-local-infer/ui/routes/launch
|
|
10
|
+
*/
|
|
11
|
+
import { launchEngine } from "../ops/engine.js";
|
|
12
|
+
import { defineRoute, RouteError } from "../route.js";
|
|
13
|
+
import { launchRequestFromBody } from "../request.js";
|
|
14
|
+
/**
|
|
15
|
+
* launchRoute builds the POST /local-infer/launch route definition the
|
|
16
|
+
* register step holds by an effect.
|
|
17
|
+
*/
|
|
18
|
+
export function launchRoute(localInfer) {
|
|
19
|
+
return defineRoute({
|
|
20
|
+
name: 'local-infer-launch',
|
|
21
|
+
path: '/local-infer/launch',
|
|
22
|
+
method: 'POST',
|
|
23
|
+
failStatus: 500,
|
|
24
|
+
tooLargeMessage: 'launch payload too large',
|
|
25
|
+
run: async ({ body }, res) => {
|
|
26
|
+
res.ndjsonStream();
|
|
27
|
+
const writeLine = (line) => {
|
|
28
|
+
res.write(JSON.stringify(line) + '\n');
|
|
29
|
+
};
|
|
30
|
+
const onProgress = (step) => {
|
|
31
|
+
writeLine({ step });
|
|
32
|
+
};
|
|
33
|
+
try {
|
|
34
|
+
const result = await launchEngine(localInfer, launchRequestFromBody(body), onProgress);
|
|
35
|
+
writeLine({ result });
|
|
36
|
+
}
|
|
37
|
+
catch (error) {
|
|
38
|
+
// A launch that breaks before a plan renders (an unknown engine, a
|
|
39
|
+
// hardware probe failure) still settles the card's control to the red
|
|
40
|
+
// Logs state through a result event, not a bare 500.
|
|
41
|
+
const detail = error instanceof RouteError
|
|
42
|
+
? error.message
|
|
43
|
+
: String(error?.message ?? error);
|
|
44
|
+
writeLine({ result: { healthy: false, detail } });
|
|
45
|
+
}
|
|
46
|
+
res.end();
|
|
47
|
+
},
|
|
48
|
+
});
|
|
49
|
+
}
|
|
50
|
+
//# sourceMappingURL=launch.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
|
|
@@ -0,0 +1,139 @@
|
|
|
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 { parsePlatformConfigs, readConfig, writeConfig } from "../config.js";
|
|
12
|
+
import { syncPlatformConfigs } from "../ops/engine.js";
|
|
13
|
+
import { syncRegisteredModel } from "../ops/model.js";
|
|
14
|
+
import { defineRoute } from "../route.js";
|
|
15
|
+
import { buildSummary } from "../viewmodels/summary.js";
|
|
16
|
+
/**
|
|
17
|
+
* newProviderId mints the stable id a new provider entry carries: a
|
|
18
|
+
* timestamp base plus a random tail, so two Saves in the same tick never
|
|
19
|
+
* collide. The card edits and deletes against this id.
|
|
20
|
+
*/
|
|
21
|
+
function newProviderId() {
|
|
22
|
+
return `provider-${Date.now().toString(36)}-${Math.random().toString(36).slice(2, 8)}`;
|
|
23
|
+
}
|
|
24
|
+
/**
|
|
25
|
+
* saveRoute builds the POST /local-infer/save route definition the register
|
|
26
|
+
* step holds by an effect.
|
|
27
|
+
*/
|
|
28
|
+
export function saveRoute(localInfer) {
|
|
29
|
+
return defineRoute({
|
|
30
|
+
name: 'local-infer-save',
|
|
31
|
+
path: '/local-infer/save',
|
|
32
|
+
method: 'POST',
|
|
33
|
+
failStatus: 400,
|
|
34
|
+
tooLargeMessage: 'config payload too large',
|
|
35
|
+
run: async ({ body }, res) => {
|
|
36
|
+
const engine = typeof body.engine === 'string' ? body.engine : 'ninfer';
|
|
37
|
+
const config = body.config && typeof body.config === 'object' ? body.config : {};
|
|
38
|
+
const allowRunDeps = typeof body.allowRunDeps === 'boolean' ? body.allowRunDeps : false;
|
|
39
|
+
const platform = parsePlatformConfigs(body.platform);
|
|
40
|
+
// A body that predates the key keeps the descriptions visible.
|
|
41
|
+
const showHelp = typeof body.showHelp === 'boolean' ? body.showHelp : true;
|
|
42
|
+
const providerId = typeof body.id === 'string' && body.id.trim() !== '' ? body.id : undefined;
|
|
43
|
+
const stored = readConfig();
|
|
44
|
+
// A body that omits the log location (or sends a blank one) keeps the
|
|
45
|
+
// stored template, so an unsaved edit never wipes a custom path.
|
|
46
|
+
const logPath = typeof body.logPath === 'string' && body.logPath !== '' ? body.logPath : stored.logPath;
|
|
47
|
+
// Save upserts a provider entry: an id updates the stored entry in
|
|
48
|
+
// place, an absent id updates a stored entry that already matches the
|
|
49
|
+
// engine, config, and platform in place, and only a save with no match
|
|
50
|
+
// mints a new id and prepends the entry, so a Save always adds (or
|
|
51
|
+
// refreshes) a card entry at the top of the list without duplicating a
|
|
52
|
+
// provider that is already stored. The provider's platform config is the
|
|
53
|
+
// per-engine entry the deploy step reads, so a provider never carries a
|
|
54
|
+
// field it cannot price. A save that updates an entry in place carries
|
|
55
|
+
// the entry's launch record over, so editing a running provider's config
|
|
56
|
+
// never drops the record the restart re-link prices. A settings-only
|
|
57
|
+
// save skips the upsert: it persists the global fields the toggle edits
|
|
58
|
+
// and keeps the stored list intact, so the help and allow-run toggles
|
|
59
|
+
// never mint a duplicate entry.
|
|
60
|
+
let providers;
|
|
61
|
+
if (body.settingsOnly === true) {
|
|
62
|
+
providers = stored.providers;
|
|
63
|
+
}
|
|
64
|
+
else if (providerId !== undefined) {
|
|
65
|
+
// An id updates the stored entry in place, carrying its launch record
|
|
66
|
+
// over so editing a running provider's config never drops the record
|
|
67
|
+
// the restart re-link prices.
|
|
68
|
+
const existing = stored.providers.find((entry) => entry.id === providerId);
|
|
69
|
+
const provider = {
|
|
70
|
+
id: providerId,
|
|
71
|
+
engine,
|
|
72
|
+
config,
|
|
73
|
+
platform: platform[engine] ?? {},
|
|
74
|
+
};
|
|
75
|
+
if (existing?.launch !== undefined) {
|
|
76
|
+
provider.launch = existing.launch;
|
|
77
|
+
}
|
|
78
|
+
providers = stored.providers.map((entry) => (entry.id === providerId ? provider : entry));
|
|
79
|
+
}
|
|
80
|
+
else {
|
|
81
|
+
// No id: a "New provider" save. If a stored entry already matches the
|
|
82
|
+
// engine, config, and platform, update it in place (carrying its launch
|
|
83
|
+
// record) instead of minting a duplicate: a "New provider" that restores
|
|
84
|
+
// the cached draft and Saves without a change would otherwise prepend a
|
|
85
|
+
// second copy of the same provider.
|
|
86
|
+
const platformConfig = platform[engine] ?? {};
|
|
87
|
+
const matching = stored.providers.find((entry) => entry.engine === engine &&
|
|
88
|
+
JSON.stringify(entry.config) === JSON.stringify(config) &&
|
|
89
|
+
JSON.stringify(entry.platform) === JSON.stringify(platformConfig));
|
|
90
|
+
if (matching !== undefined) {
|
|
91
|
+
const provider = {
|
|
92
|
+
id: matching.id,
|
|
93
|
+
engine,
|
|
94
|
+
config,
|
|
95
|
+
platform: platformConfig,
|
|
96
|
+
};
|
|
97
|
+
if (matching.launch !== undefined) {
|
|
98
|
+
provider.launch = matching.launch;
|
|
99
|
+
}
|
|
100
|
+
providers = stored.providers.map((entry) => (entry.id === matching.id ? provider : entry));
|
|
101
|
+
}
|
|
102
|
+
else {
|
|
103
|
+
const provider = {
|
|
104
|
+
id: newProviderId(),
|
|
105
|
+
engine,
|
|
106
|
+
config,
|
|
107
|
+
platform: platformConfig,
|
|
108
|
+
};
|
|
109
|
+
providers = [provider, ...stored.providers];
|
|
110
|
+
}
|
|
111
|
+
}
|
|
112
|
+
writeConfig(engine, config, allowRunDeps, platform, showHelp, providers, logPath);
|
|
113
|
+
// Re-sync the service registry with the saved platform map, so the next
|
|
114
|
+
// launch reads the platform config the user just saved.
|
|
115
|
+
syncPlatformConfigs(localInfer, {
|
|
116
|
+
engine,
|
|
117
|
+
config,
|
|
118
|
+
allowRunDeps,
|
|
119
|
+
platform,
|
|
120
|
+
showHelp,
|
|
121
|
+
providers,
|
|
122
|
+
logPath,
|
|
123
|
+
lastLogs: stored.lastLogs,
|
|
124
|
+
});
|
|
125
|
+
// A Save on an already-registered model re-runs the registration, so
|
|
126
|
+
// the DSH model row's input types (the vision flag) stay in step with
|
|
127
|
+
// the config the user just saved. Best-effort: a profile without the
|
|
128
|
+
// settings seam, or an engine no adapter serves, leaves the save intact.
|
|
129
|
+
try {
|
|
130
|
+
await syncRegisteredModel(localInfer, engine, config);
|
|
131
|
+
}
|
|
132
|
+
catch {
|
|
133
|
+
// A sync that cannot run is a no-op for the save.
|
|
134
|
+
}
|
|
135
|
+
res.json(200, await buildSummary(localInfer, { engine, config }));
|
|
136
|
+
},
|
|
137
|
+
});
|
|
138
|
+
}
|
|
139
|
+
//# sourceMappingURL=save.js.map
|
|
@@ -0,0 +1,16 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* The POST /local-infer/stop route: it renders the same plan the launch
|
|
3
|
+
* rendered and runs the service's stop entry point, so the stop targets the
|
|
4
|
+
* exact container or process the launch started. The stop then clears the
|
|
5
|
+
* target entry's launch record, so a recycled pid cannot re-link an engine
|
|
6
|
+
* the user just stopped.
|
|
7
|
+
* @module dsh-plugin-local-infer/ui/routes/stop
|
|
8
|
+
*/
|
|
9
|
+
import type { LocalInferService } from 'dsh-plugin-local-infer/service';
|
|
10
|
+
import type { LocalInferRoute } from '../route.ts';
|
|
11
|
+
/**
|
|
12
|
+
* stopRoute builds the POST /local-infer/stop route definition the register
|
|
13
|
+
* step holds by an effect.
|
|
14
|
+
*/
|
|
15
|
+
export declare function stopRoute(localInfer: LocalInferService): LocalInferRoute;
|
|
16
|
+
//# sourceMappingURL=stop.d.ts.map
|