@huanlin/dsh-plugin-interpreters 0.1.0
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/LICENSE +664 -0
- package/README.md +69 -0
- package/cordis.patch.yml +11 -0
- package/lib/client.js +457 -0
- package/lib/config.js +29 -0
- package/lib/gateway.js +163 -0
- package/lib/index.js +58 -0
- package/lib/runner.js +120 -0
- package/lib/settings.js +83 -0
- package/lib/tools.js +110 -0
- package/lib/types/client/InterpretersCard.d.ts +42 -0
- package/lib/types/client/InterpretersCard.js +74 -0
- package/lib/types/client/index.d.ts +39 -0
- package/lib/types/client/index.js +72 -0
- package/lib/types/client/locales.d.ts +13 -0
- package/lib/types/client/locales.js +50 -0
- package/lib/types/client/store.d.ts +88 -0
- package/lib/types/client/store.js +196 -0
- package/lib/types/config.d.ts +32 -0
- package/lib/types/config.js +29 -0
- package/lib/types/gateway.d.ts +63 -0
- package/lib/types/gateway.js +163 -0
- package/lib/types/index.d.ts +42 -0
- package/lib/types/index.js +58 -0
- package/lib/types/runner.d.ts +31 -0
- package/lib/types/runner.js +120 -0
- package/lib/types/settings.d.ts +43 -0
- package/lib/types/settings.js +83 -0
- package/lib/types/tools.d.ts +41 -0
- package/lib/types/tools.js +110 -0
- package/package.json +102 -0
|
@@ -0,0 +1,110 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* tools.ts — `run_python` and `run_node` model-facing tools.
|
|
3
|
+
*
|
|
4
|
+
* Conventions (per plugin-development-guide.md §3):
|
|
5
|
+
* C4 — execute returns a canonical JSON value; render is a separate pure projection.
|
|
6
|
+
* C5 — timeout and cancellation are non-ideal business outcomes, represented in
|
|
7
|
+
* the value (timed_out / cancelled) rather than thrown.
|
|
8
|
+
* C6 — exec.signal is forwarded to the subprocess via runCode().
|
|
9
|
+
* C10 — no UI-specific formats in the canonical value.
|
|
10
|
+
*
|
|
11
|
+
* The tool `description` is computed from the resolved config at registration
|
|
12
|
+
* time so the model sees the interpreter path. Settings changes dispose the
|
|
13
|
+
* old registration and re-register with the fresh description (host index.ts).
|
|
14
|
+
*
|
|
15
|
+
* @module dsh-interpreters/tools
|
|
16
|
+
*/
|
|
17
|
+
import { defineTool } from '@deepseek-ai/dsh-tools';
|
|
18
|
+
import { runCode } from './runner.js';
|
|
19
|
+
/**
|
|
20
|
+
* Build the model-visible description for `run_python`, embedding the
|
|
21
|
+
* configured interpreter path so the model knows exactly which executable
|
|
22
|
+
* will be invoked.
|
|
23
|
+
*/
|
|
24
|
+
export function buildPythonDescription(cfg) {
|
|
25
|
+
return 'Execute Python code and return stdout, stderr, and exit code. '
|
|
26
|
+
+ 'Code is passed via stdin (`' + cfg.pythonPath + ' -`), so there is no '
|
|
27
|
+
+ 'command-line length limit. '
|
|
28
|
+
+ 'The Python interpreter is located at: ' + cfg.pythonPath + '\n'
|
|
29
|
+
+ 'Use the optional `cwd` parameter to set the working directory.';
|
|
30
|
+
}
|
|
31
|
+
/**
|
|
32
|
+
* Build the model-visible description for `run_node`, embedding the
|
|
33
|
+
* configured interpreter path.
|
|
34
|
+
*/
|
|
35
|
+
export function buildNodeDescription(cfg) {
|
|
36
|
+
return 'Execute Node.js code and return stdout, stderr, and exit code. '
|
|
37
|
+
+ 'Code is passed via stdin (`' + cfg.nodePath + ' -`), so there is no '
|
|
38
|
+
+ 'command-line length limit. '
|
|
39
|
+
+ 'The Node.js interpreter is located at: ' + cfg.nodePath + '\n'
|
|
40
|
+
+ 'Use the optional `cwd` parameter to set the working directory.';
|
|
41
|
+
}
|
|
42
|
+
function textRender(fn) {
|
|
43
|
+
return (_args, value) => [{ type: 'text', text: fn(value) }];
|
|
44
|
+
}
|
|
45
|
+
export function renderRunCodeOutput(value) {
|
|
46
|
+
const lines = [];
|
|
47
|
+
lines.push(`Exit code: ${value.exit_code} (${value.duration_ms}ms)`);
|
|
48
|
+
if (value.timed_out)
|
|
49
|
+
lines.push('Process was killed after exceeding the timeout.');
|
|
50
|
+
if (value.cancelled)
|
|
51
|
+
lines.push('Process was cancelled by an abort signal.');
|
|
52
|
+
if (value.stdout)
|
|
53
|
+
lines.push(`--- stdout ---\n${value.stdout}`);
|
|
54
|
+
if (value.stderr)
|
|
55
|
+
lines.push(`--- stderr ---\n${value.stderr}`);
|
|
56
|
+
return lines.join('\n');
|
|
57
|
+
}
|
|
58
|
+
const parametersSchema = {
|
|
59
|
+
code: { type: 'string', required: true, description: 'The code to execute.' },
|
|
60
|
+
cwd: { type: 'string', description: 'Optional working directory for the process.' },
|
|
61
|
+
};
|
|
62
|
+
const outputSchema = {
|
|
63
|
+
type: 'object',
|
|
64
|
+
additionalProperties: false,
|
|
65
|
+
properties: {
|
|
66
|
+
ok: { type: 'boolean', required: true, description: 'True if the process exited with code 0.' },
|
|
67
|
+
exit_code: { type: 'integer', required: true, description: 'Process exit code (-1 if the process failed to start).' },
|
|
68
|
+
stdout: { type: 'string', required: true, description: 'Captured stdout output.' },
|
|
69
|
+
stderr: { type: 'string', required: true, description: 'Captured stderr output.' },
|
|
70
|
+
duration_ms: { type: 'integer', required: true, description: 'Wall-clock execution time in milliseconds.' },
|
|
71
|
+
timed_out: { type: 'boolean', required: true, description: 'True if the process was killed due to timeout.' },
|
|
72
|
+
cancelled: { type: 'boolean', required: true, description: 'True if the process was killed due to an abort signal.' },
|
|
73
|
+
},
|
|
74
|
+
};
|
|
75
|
+
/**
|
|
76
|
+
* Register `run_python` and `run_node` tools with descriptions that embed
|
|
77
|
+
* the interpreter paths from `cfg`. Returns a disposer that unregisters
|
|
78
|
+
* both tools — call it before re-registering with a fresh config.
|
|
79
|
+
*/
|
|
80
|
+
export function registerTools(ctx, cfg) {
|
|
81
|
+
const disposers = [];
|
|
82
|
+
disposers.push(ctx.tools.register(defineTool({
|
|
83
|
+
name: 'run_python',
|
|
84
|
+
description: buildPythonDescription(cfg),
|
|
85
|
+
parameters: parametersSchema,
|
|
86
|
+
output: {
|
|
87
|
+
schema: outputSchema,
|
|
88
|
+
render: textRender(renderRunCodeOutput),
|
|
89
|
+
},
|
|
90
|
+
execute: async (args, exec) => {
|
|
91
|
+
const a = args;
|
|
92
|
+
return runCode(cfg.pythonPath, a.code, a.cwd, cfg.timeoutMs, exec.signal);
|
|
93
|
+
},
|
|
94
|
+
})));
|
|
95
|
+
disposers.push(ctx.tools.register(defineTool({
|
|
96
|
+
name: 'run_node',
|
|
97
|
+
description: buildNodeDescription(cfg),
|
|
98
|
+
parameters: parametersSchema,
|
|
99
|
+
output: {
|
|
100
|
+
schema: outputSchema,
|
|
101
|
+
render: textRender(renderRunCodeOutput),
|
|
102
|
+
},
|
|
103
|
+
execute: async (args, exec) => {
|
|
104
|
+
const a = args;
|
|
105
|
+
return runCode(cfg.nodePath, a.code, a.cwd, cfg.timeoutMs, exec.signal);
|
|
106
|
+
},
|
|
107
|
+
})));
|
|
108
|
+
return () => { for (const dispose of disposers)
|
|
109
|
+
dispose(); };
|
|
110
|
+
}
|
package/package.json
ADDED
|
@@ -0,0 +1,102 @@
|
|
|
1
|
+
{
|
|
2
|
+
"name": "@huanlin/dsh-plugin-interpreters",
|
|
3
|
+
"version": "0.1.0",
|
|
4
|
+
"publishConfig": {
|
|
5
|
+
"access": "public"
|
|
6
|
+
},
|
|
7
|
+
"keywords": ["dsh-plugin"],
|
|
8
|
+
"description": "Exposes run_python and run_node tools with configurable interpreter paths; settings card (via /interpreters/api HTTP route) lets users set the executable locations.",
|
|
9
|
+
"type": "module",
|
|
10
|
+
"license": "AGPL-3.0",
|
|
11
|
+
"main": "./lib/index.js",
|
|
12
|
+
"types": "./lib/types/index.d.ts",
|
|
13
|
+
"exports": {
|
|
14
|
+
".": {
|
|
15
|
+
"types": "./lib/types/index.d.ts",
|
|
16
|
+
"import": "./lib/index.js"
|
|
17
|
+
},
|
|
18
|
+
"./client": {
|
|
19
|
+
"types": "./lib/types/client/index.d.ts",
|
|
20
|
+
"default": "./lib/client.js"
|
|
21
|
+
},
|
|
22
|
+
"./package.json": "./package.json"
|
|
23
|
+
},
|
|
24
|
+
"files": [
|
|
25
|
+
"lib/",
|
|
26
|
+
"cordis.patch.yml"
|
|
27
|
+
],
|
|
28
|
+
"dsh": {
|
|
29
|
+
"bundle": {
|
|
30
|
+
"patch": "./cordis.patch.yml"
|
|
31
|
+
},
|
|
32
|
+
"client": {
|
|
33
|
+
"inject": [
|
|
34
|
+
"@deepseek-ai/dsh-client-runtime",
|
|
35
|
+
"@deepseek-ai/dsh-client-locale",
|
|
36
|
+
"@deepseek-ai/dsh-client-connection",
|
|
37
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins",
|
|
38
|
+
"@deepseek-ai/dsh-client-ui-slots"
|
|
39
|
+
],
|
|
40
|
+
"platform": "web"
|
|
41
|
+
}
|
|
42
|
+
},
|
|
43
|
+
"scripts": {
|
|
44
|
+
"typecheck": "tsc --noEmit -p tsconfig.json",
|
|
45
|
+
"test": "vitest run",
|
|
46
|
+
"test:watch": "vitest",
|
|
47
|
+
"build": "tsc -p tsconfig.build.json && node scripts/build-client.mjs && tsc -p tsconfig.json"
|
|
48
|
+
},
|
|
49
|
+
"peerDependencies": {
|
|
50
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1",
|
|
51
|
+
"@deepseek-ai/dsh-client-connection": "^0.0.1-rc.1",
|
|
52
|
+
"@deepseek-ai/dsh-client-locale": "^0.0.1-rc.1",
|
|
53
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.1",
|
|
54
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "^0.0.1-rc.1",
|
|
55
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.0.1-rc.1",
|
|
56
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.1",
|
|
57
|
+
"@deepseek-ai/dsh-client-web-react": "^0.0.1-rc.1",
|
|
58
|
+
"@deepseek-ai/dsh-host-webserver": "^0.0.1-rc.1",
|
|
59
|
+
"@deepseek-ai/dsh-settings": "^0.0.1-rc.1",
|
|
60
|
+
"@deepseek-ai/dsh-tools": "^0.0.1-rc.1",
|
|
61
|
+
"react": "^18.2.0",
|
|
62
|
+
"schemastery": "^3.18.0"
|
|
63
|
+
},
|
|
64
|
+
"peerDependenciesMeta": {
|
|
65
|
+
"@deepseek-ai/cordis": { "optional": true },
|
|
66
|
+
"@deepseek-ai/dsh-client-connection": { "optional": true },
|
|
67
|
+
"@deepseek-ai/dsh-client-locale": { "optional": true },
|
|
68
|
+
"@deepseek-ai/dsh-client-runtime": { "optional": true },
|
|
69
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": { "optional": true },
|
|
70
|
+
"@deepseek-ai/dsh-client-ui-primitives": { "optional": true },
|
|
71
|
+
"@deepseek-ai/dsh-client-ui-slots": { "optional": true },
|
|
72
|
+
"@deepseek-ai/dsh-client-web-react": { "optional": true },
|
|
73
|
+
"@deepseek-ai/dsh-host-webserver": { "optional": true },
|
|
74
|
+
"@deepseek-ai/dsh-settings": { "optional": true },
|
|
75
|
+
"@deepseek-ai/dsh-tools": { "optional": true },
|
|
76
|
+
"react": { "optional": true },
|
|
77
|
+
"schemastery": { "optional": true }
|
|
78
|
+
},
|
|
79
|
+
"devDependencies": {
|
|
80
|
+
"@deepseek-ai/cordis": "^4.0.1-rc.1",
|
|
81
|
+
"@deepseek-ai/dsh-client-connection": "^0.0.1-rc.1",
|
|
82
|
+
"@deepseek-ai/dsh-client-locale": "^0.0.1-rc.1",
|
|
83
|
+
"@deepseek-ai/dsh-client-runtime": "^0.0.1-rc.1",
|
|
84
|
+
"@deepseek-ai/dsh-client-ui-settings-plugins": "^0.0.1-rc.1",
|
|
85
|
+
"@deepseek-ai/dsh-client-ui-primitives": "^0.0.1-rc.1",
|
|
86
|
+
"@deepseek-ai/dsh-client-ui-slots": "^0.0.1-rc.1",
|
|
87
|
+
"@deepseek-ai/dsh-client-web-react": "^0.0.1-rc.1",
|
|
88
|
+
"@deepseek-ai/dsh-host-webserver": "^0.0.1-rc.1",
|
|
89
|
+
"@deepseek-ai/dsh-settings": "^0.0.1-rc.1",
|
|
90
|
+
"@deepseek-ai/dsh-tools": "^0.0.1-rc.1",
|
|
91
|
+
"@types/node": "^22.20.0",
|
|
92
|
+
"@types/react": "~18.3.1",
|
|
93
|
+
"esbuild": "^0.28.2",
|
|
94
|
+
"lightningcss": "^1.29.2",
|
|
95
|
+
"tsdown": "^0.22.2",
|
|
96
|
+
"typescript": "^5.9.0",
|
|
97
|
+
"vitest": "^3.2.0"
|
|
98
|
+
},
|
|
99
|
+
"engines": {
|
|
100
|
+
"node": ">=18.0.0"
|
|
101
|
+
}
|
|
102
|
+
}
|