dsh-plugin-pscad-expert-vyma 1.0.8 → 1.0.9

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 CHANGED
@@ -1,6 +1,6 @@
1
1
  # pscad-dsh-plugin — PSCAD 自动化建模与仿真控制专家插件
2
2
 
3
- > **版本**:1.0.8 | **注册名**:`pscad-automation-expert`
3
+ > **版本**:1.0.9 | **注册名**:`pscad-automation-expert`
4
4
  > **来源**:PSCAD 知识资产固化项目(四阶段:技能文档 → 模板索引 → 工具库 → 插件打包)
5
5
  > 所有知识、工具、模板均来自真实仿真验证(L13~L19 认证轮 + R4 科研轮),**无伪造数据**。
6
6
 
package/index.js CHANGED
@@ -15,27 +15,99 @@
15
15
 
16
16
  import { defineTool } from '@deepseek-ai/dsh-tools'
17
17
  import Schema from '@deepseek-ai/schemastery'
18
- import { spawn } from 'node:child_process'
18
+ import { spawn, spawnSync } from 'node:child_process'
19
19
  import { fileURLToPath } from 'node:url'
20
+ import fs from 'node:fs'
21
+ import path from 'node:path'
20
22
 
21
23
  export const name = 'pscad-expert-bridge'
22
24
  export const inject = ['tools']
23
25
 
24
26
  // ---------------- 插件配置(Schemastery,无硬编码) ----------------
25
27
  export const Config = Schema.object({
26
- pythonExecutable: Schema.string().default('python'),
28
+ pythonExecutable: Schema.string().default('python')
29
+ .description('Python 解释器路径;默认自动探测(PATH→py 启动器→常见安装位置),无需手动配置'),
27
30
  toolsCli: Schema.string().default('./tools/cli.py'),
28
31
  defaultFolder: Schema.string().default(''),
29
32
  timeoutMs: Schema.number().default(120000),
30
33
  })
31
34
 
35
+ // ---------------- Python 解释器自动探测(免 profile YAML 配置) ----------------
36
+ let _resolvedPython = null
37
+
38
+ function pyVersionOk(exe) {
39
+ try {
40
+ const r = spawnSync(exe, ['-c', 'import sys; print(sys.version_info[0], sys.version_info[1])'], {
41
+ timeout: 10000, windowsHide: true, encoding: 'utf8',
42
+ })
43
+ if (r.status !== 0 || r.error) return false
44
+ const m = /^(\d+)\s+(\d+)/.exec((r.stdout || '').trim())
45
+ return !!m && Number(m[1]) >= 3 && Number(m[2]) >= 7
46
+ } catch { return false }
47
+ }
48
+
49
+ function findPythonInDir(parent, prefix) {
50
+ // 升序取最旧版本(越接近 3.7 越稳妥:mhi.pscad 2.2.1 面向 Python 3.7)
51
+ try {
52
+ const dirs = fs.readdirSync(parent, { withFileTypes: true })
53
+ .filter(e => e.isDirectory() && e.name.startsWith(prefix))
54
+ .map(e => e.name).sort()
55
+ for (const d of dirs) {
56
+ const exe = path.join(parent, d, 'python.exe')
57
+ if (fs.existsSync(exe)) return exe
58
+ }
59
+ } catch {}
60
+ return null
61
+ }
62
+
63
+ function resolvePython(config) {
64
+ if (_resolvedPython) return _resolvedPython
65
+ // 用户显式配置(非默认 'python')优先,尊重覆盖
66
+ if (config.pythonExecutable && config.pythonExecutable !== 'python') {
67
+ _resolvedPython = config.pythonExecutable
68
+ return _resolvedPython
69
+ }
70
+ // 1) PATH 上的 python:验证是真实 3.7+(排除微软商店占位 stub,其退出码 9009/2)
71
+ if (pyVersionOk('python')) { _resolvedPython = 'python'; return _resolvedPython }
72
+ // 2) py 启动器枚举已安装版本:取最接近 3.7 的可用版本
73
+ try {
74
+ const r = spawnSync('py', ['-0p'], { timeout: 10000, windowsHide: true, encoding: 'utf8' })
75
+ if (r.status === 0) {
76
+ const picks = []
77
+ for (const line of (r.stdout || '').split(/\r?\n/)) {
78
+ // 兼容含空格路径(如 C:\Program Files\Python37\python.exe)
79
+ const m = /-V:(\d+)\.(\d+)\s+\*?\s*(.+\\python\.exe)\s*$/.exec(line)
80
+ if (m && fs.existsSync(m[3])) {
81
+ const v = Number(m[1]) * 100 + Number(m[2])
82
+ if (Number(m[1]) >= 3 && v >= 307) picks.push({ v, exe: m[3] })
83
+ }
84
+ }
85
+ if (picks.length) {
86
+ picks.sort((a, b) => a.v - b.v)
87
+ _resolvedPython = picks[0].exe
88
+ return _resolvedPython
89
+ }
90
+ }
91
+ } catch {}
92
+ // 3) 常见安装位置(Program Files / 用户级 / 盘符根)
93
+ const home = process.env.LOCALAPPDATA || path.join(process.env.USERPROFILE || '', 'AppData', 'Local')
94
+ const found = findPythonInDir('C:/Program Files', 'Python3') ||
95
+ findPythonInDir(path.join(home, 'Programs', 'Python'), 'Python3') ||
96
+ findPythonInDir('C:/', 'Python3')
97
+ if (found) { _resolvedPython = found; return _resolvedPython }
98
+ // 4) 兜底:保持默认(若 PATH python 为 stub,错误会自然暴露并有明确提示)
99
+ _resolvedPython = 'python'
100
+ return _resolvedPython
101
+ }
102
+
32
103
  // ---------------- Python 桥接(子进程 JSON-RPC,支持取消) ----------------
33
104
  function runPy(tool, args, config, signal) {
34
105
  const cliPath = fileURLToPath(new URL(config.toolsCli, import.meta.url))
106
+ const python = resolvePython(config)
35
107
  return new Promise((resolve, reject) => {
36
108
  let settled = false
37
109
  const done = (fn, v) => { if (!settled) { settled = true; fn(v) } }
38
- const proc = spawn(config.pythonExecutable, [cliPath, tool, JSON.stringify(args)], {
110
+ const proc = spawn(python, [cliPath, tool, JSON.stringify(args)], {
39
111
  windowsHide: true,
40
112
  stdio: ['ignore', 'pipe', 'pipe'],
41
113
  })
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-pscad-expert-vyma",
3
- "version": "1.0.8",
3
+ "version": "1.0.9",
4
4
  "description": "PSCAD 自动化建模与仿真控制专家插件(DSH Agent 工具库 + 基准模板 + 领域知识)",
5
5
  "type": "module",
6
6
  "main": "index.js",
package/plugin.yaml CHANGED
@@ -3,7 +3,7 @@
3
3
  # 由知识资产固化项目自动生成(2026-08-25)· 部署至 Git 仓库
4
4
  # ============================================================
5
5
  name: pscad-automation-expert
6
- version: 1.0.8
6
+ version: 1.0.9
7
7
  description: PSCAD 自动化建模与仿真控制专家插件
8
8
 
9
9
  # ---- 系统提示词(加载到 Agent 上下文最前置位置)----