dsh-plugin-pscad-expert-vyma 1.0.11 → 1.0.13

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.11 | **注册名**:`pscad-automation-expert`
3
+ > **版本**:1.0.13 | **注册名**:`pscad-automation-expert`
4
4
  > **来源**:PSCAD 知识资产固化项目(四阶段:技能文档 → 模板索引 → 工具库 → 插件打包)
5
5
  > 所有知识、工具、模板均来自真实仿真验证(L13~L19 认证轮 + R4 科研轮),**无伪造数据**。
6
6
 
package/package.json CHANGED
@@ -1,6 +1,6 @@
1
1
  {
2
2
  "name": "dsh-plugin-pscad-expert-vyma",
3
- "version": "1.0.11",
3
+ "version": "1.0.13",
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.11
6
+ version: 1.0.13
7
7
  description: PSCAD 自动化建模与仿真控制专家插件
8
8
 
9
9
  # ---- 系统提示词(加载到 Agent 上下文最前置位置)----
package/tools/main.py CHANGED
@@ -522,6 +522,57 @@ def _gen_name(comp_type: str) -> str:
522
522
  # ---------------------------------------------------------------------------
523
523
  # 工具集 1:连接与工程加载(懒加载 mhi)
524
524
  # ---------------------------------------------------------------------------
525
+ def _persist_case(prj: Any, project_name: str, folder: str) -> Optional[str]:
526
+ """尽力把会话内新建工程落盘,返回实际 .pscx 路径;找不到返回 None。
527
+
528
+ mhi-pscad 2.9.7 的 create_case(project_name, folder=...) 与 save() 都可能
529
+ 不按 folder 写 .pscx(工程仅在 PSCAD 会话内存)。依次尝试:
530
+ ① save/save_as/save_case 变体;② prj 路径属性;③ 候选目录全盘搜同名文件。
531
+ """
532
+ expected = os.path.join(folder, project_name + '.pscx')
533
+ try:
534
+ # ① 常见保存 API
535
+ for meth, args in (('save', ()), ('save_as', (expected,)),
536
+ ('save_case', (expected,))):
537
+ try:
538
+ fn = getattr(prj, meth)
539
+ fn(*args)
540
+ except Exception:
541
+ continue
542
+ if os.path.isfile(expected):
543
+ return expected
544
+ # ② prj 自带路径属性
545
+ for attr in ('path', 'filename', 'file_name', 'case_path',
546
+ 'project_path'):
547
+ try:
548
+ p = getattr(prj, attr)
549
+ if callable(p):
550
+ p = p()
551
+ if isinstance(p, str) and p.lower().endswith('.pscx') \
552
+ and os.path.isfile(p):
553
+ return p
554
+ except Exception:
555
+ continue
556
+ # ③ 候选目录搜最近生成的同名文件
557
+ import glob as _glob
558
+ bases = [folder, os.getcwd(), os.path.expanduser('~/Documents'),
559
+ os.path.expanduser('~/PSCAD')]
560
+ best = None
561
+ for base in bases:
562
+ try:
563
+ hits = _glob.glob(os.path.join(base, '**',
564
+ project_name + '.pscx'),
565
+ recursive=True)
566
+ except Exception:
567
+ hits = []
568
+ for h in hits:
569
+ if best is None or os.path.getmtime(h) > os.path.getmtime(best):
570
+ best = h
571
+ return best
572
+ except Exception:
573
+ return None
574
+
575
+
525
576
  def connect_and_load_project(project_name: str,
526
577
  folder: Optional[str] = None,
527
578
  create_if_missing: bool = False,
@@ -556,8 +607,11 @@ def connect_and_load_project(project_name: str,
556
607
  if not ok:
557
608
  return _err(msg)
558
609
 
559
- folder = folder or (DEFAULT_FOLDER or os.getcwd())
610
+ # folder 回退链:显式传入 → PSCAD_WORK_DIR 环境变量 → 用户目录 ~/pscad_cases
611
+ # (无盘符依赖,任何机器开箱即用;create_case 分支会自动创建该目录)
612
+ folder = folder or DEFAULT_FOLDER or os.path.expanduser('~/pscad_cases')
560
613
  _prj_folder = folder
614
+ pscx_path: Optional[str] = None # 实际落盘的 .pscx 路径(探测后回报)
561
615
 
562
616
  prj = None
563
617
  try:
@@ -571,19 +625,23 @@ def connect_and_load_project(project_name: str,
571
625
  try:
572
626
  _pscad.load(pscx.replace('\\', '/'))
573
627
  prj = _pscad.project(project_name)
628
+ pscx_path = pscx
574
629
  except Exception as exc:
575
630
  return _err('加载 %s 失败: %s' % (pscx, exc))
576
631
 
577
632
  if prj is None and create_if_missing:
578
633
  try:
579
- _pscad.create_case(project_name, folder=folder)
580
- prj = _pscad.project(project_name)
581
- # mhi 2.9.7 的 create_case 可能只在 PSCAD 会话内存建工程、不落盘
582
- # (与 2.2.1 语义差异);显式 save() 保证 folder 下生成 .pscx
634
+ # 目录不存在可能导致 create_case 静默不落盘:先确保目标目录存在
583
635
  try:
584
- prj.save()
636
+ os.makedirs(folder, exist_ok=True)
585
637
  except Exception:
586
638
  pass
639
+ _pscad.create_case(project_name, folder=folder)
640
+ prj = _pscad.project(project_name)
641
+ pscx_path = _persist_case(prj, project_name, folder)
642
+ if pscx_path:
643
+ folder = os.path.dirname(pscx_path) # 会话状态跟随真实落盘目录
644
+ _prj_folder = folder
587
645
  except Exception as exc:
588
646
  return _err('create_case 失败: %s' % exc)
589
647
 
@@ -599,7 +657,13 @@ def connect_and_load_project(project_name: str,
599
657
  except Exception as exc:
600
658
  _main = None
601
659
  return _err('打开 Main 画布失败: %s' % exc)
602
- return _ok({'project': project_name, 'canvas': 'Main'})
660
+ result = {'project': project_name, 'canvas': 'Main',
661
+ 'pscx_path': pscx_path}
662
+ if create_if_missing and not pscx_path:
663
+ result['warning'] = ('create_case 未能在磁盘找到 .pscx(mhi 2.9.7 可能仅'
664
+ '内存建工程):工程仅存在于当前 PSCAD 会话,退出即丢;'
665
+ '建议改用已有模板 .pscx 加载,或提供可写目录。')
666
+ return _ok(result)
603
667
  except Exception as exc:
604
668
  return _err(exc)
605
669