dpgen-lsp 0.0.1__tar.gz

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 (66) hide show
  1. dpgen_lsp-0.0.1/.coverage +0 -0
  2. dpgen_lsp-0.0.1/.gitignore +17 -0
  3. dpgen_lsp-0.0.1/LICENSE +21 -0
  4. dpgen_lsp-0.0.1/PKG-INFO +155 -0
  5. dpgen_lsp-0.0.1/README.md +121 -0
  6. dpgen_lsp-0.0.1/diagnostics/diagnostic-engine-v1.schema.json +57 -0
  7. dpgen_lsp-0.0.1/dpdispatcher.log +4 -0
  8. dpgen_lsp-0.0.1/lsp-capabilities.json +29 -0
  9. dpgen_lsp-0.0.1/pyproject.toml +88 -0
  10. dpgen_lsp-0.0.1/scripts/download_templates.py +50 -0
  11. dpgen_lsp-0.0.1/src/dpgen_lsp/__init__.py +3 -0
  12. dpgen_lsp-0.0.1/src/dpgen_lsp/agent_lsp.py +79 -0
  13. dpgen_lsp-0.0.1/src/dpgen_lsp/agent_operations.py +457 -0
  14. dpgen_lsp-0.0.1/src/dpgen_lsp/constants.py +2 -0
  15. dpgen_lsp-0.0.1/src/dpgen_lsp/features/__init__.py +0 -0
  16. dpgen_lsp-0.0.1/src/dpgen_lsp/features/code_actions.py +14 -0
  17. dpgen_lsp-0.0.1/src/dpgen_lsp/features/completion.py +94 -0
  18. dpgen_lsp-0.0.1/src/dpgen_lsp/features/diagnostic.py +488 -0
  19. dpgen_lsp-0.0.1/src/dpgen_lsp/features/formatting.py +31 -0
  20. dpgen_lsp-0.0.1/src/dpgen_lsp/features/hover.py +41 -0
  21. dpgen_lsp-0.0.1/src/dpgen_lsp/features/lint.py +10 -0
  22. dpgen_lsp-0.0.1/src/dpgen_lsp/features/typecheck.py +10 -0
  23. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/__init__.py +0 -0
  24. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/code_action.py +9 -0
  25. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/completion.py +44 -0
  26. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/definition.py +7 -0
  27. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/diagnostic.py +60 -0
  28. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/document_symbol.py +7 -0
  29. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/hover.py +30 -0
  30. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/references.py +7 -0
  31. dpgen_lsp-0.0.1/src/dpgen_lsp/handlers/rename.py +11 -0
  32. dpgen_lsp-0.0.1/src/dpgen_lsp/registry.py +33 -0
  33. dpgen_lsp-0.0.1/src/dpgen_lsp/rich_diagnostics.py +225 -0
  34. dpgen_lsp-0.0.1/src/dpgen_lsp/schema/__init__.py +0 -0
  35. dpgen_lsp-0.0.1/src/dpgen_lsp/schema/json_path.py +122 -0
  36. dpgen_lsp-0.0.1/src/dpgen_lsp/schema/loader.py +296 -0
  37. dpgen_lsp-0.0.1/src/dpgen_lsp/server.py +140 -0
  38. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/NOTICE +10 -0
  39. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/__init__.py +140 -0
  40. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/index.json +125 -0
  41. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/machine/lebesgue-v2.json +106 -0
  42. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/amber-dprc.json +370 -0
  43. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/calypso-vasp.json +409 -0
  44. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/gromacs-gaussian.json +281 -0
  45. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-abacus-lcao-dpks.json +170 -0
  46. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-abacus-lcao.json +149 -0
  47. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-abacus-pw.json +161 -0
  48. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-cp2k.json +135 -0
  49. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-gaussian.json +149 -0
  50. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-pwscf.json +159 -0
  51. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-vasp-electron-temp.json +130 -0
  52. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-vasp-plumed.json +222 -0
  53. dpgen_lsp-0.0.1/src/dpgen_lsp/templates/param/lammps-vasp.json +136 -0
  54. dpgen_lsp-0.0.1/src/dpgen_lsp/tool.py +188 -0
  55. dpgen_lsp-0.0.1/src/dpgen_lsp/wiki/concepts/.gitkeep +0 -0
  56. dpgen_lsp-0.0.1/src/dpgen_lsp/wiki/concepts/active_learning.md +18 -0
  57. dpgen_lsp-0.0.1/src/dpgen_lsp/wiki/entities/.gitkeep +0 -0
  58. dpgen_lsp-0.0.1/src/dpgen_lsp/wiki/entities/type_map.md +19 -0
  59. dpgen_lsp-0.0.1/src/dpgen_lsp/wiki/synthesis/.gitkeep +0 -0
  60. dpgen_lsp-0.0.1/src/dpgen_lsp/wiki/synthesis/fp_style_selection.md +29 -0
  61. dpgen_lsp-0.0.1/tests/test_completion.py +18 -0
  62. dpgen_lsp-0.0.1/tests/test_diagnostic.py +43 -0
  63. dpgen_lsp-0.0.1/tests/test_hover.py +21 -0
  64. dpgen_lsp-0.0.1/tests/test_init.py +368 -0
  65. dpgen_lsp-0.0.1/tests/test_json_path.py +36 -0
  66. dpgen_lsp-0.0.1/tests/test_loader.py +62 -0
Binary file
@@ -0,0 +1,17 @@
1
+ __pycache__/
2
+ *.pyc
3
+ *.pyo
4
+ *.egg-info/
5
+ dist/
6
+ build/
7
+ .pytest_cache/
8
+ .mypy_cache/
9
+ .ruff_cache/
10
+ *.egg
11
+ .DS_Store
12
+ .venv/
13
+ venv/
14
+ .vscode/
15
+ *.swp
16
+ *.swo
17
+ *~
@@ -0,0 +1,21 @@
1
+ MIT License
2
+
3
+ Copyright (c) 2026 guomingyu
4
+
5
+ Permission is hereby granted, free of charge, to any person obtaining a copy
6
+ of this software and associated documentation files (the "Software"), to deal
7
+ in the Software without restriction, including without limitation the rights
8
+ to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
9
+ copies of the Software, and to permit persons to whom the Software is
10
+ furnished to do so, subject to the following conditions:
11
+
12
+ The above copyright notice and this permission notice shall be included in all
13
+ copies or substantial portions of the Software.
14
+
15
+ THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
16
+ IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
17
+ FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
18
+ AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
19
+ LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
20
+ OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
21
+ SOFTWARE.
@@ -0,0 +1,155 @@
1
+ Metadata-Version: 2.4
2
+ Name: dpgen-lsp
3
+ Version: 0.0.1
4
+ Summary: Language Server Protocol and CLI toolkit for DP-GEN input files
5
+ Project-URL: Homepage, https://github.com/SchrodingersCattt/dpgen-lsp
6
+ Project-URL: Repository, https://github.com/SchrodingersCattt/dpgen-lsp
7
+ Project-URL: Issues, https://github.com/SchrodingersCattt/dpgen-lsp/issues
8
+ Author: SchrodingersCattt
9
+ License: MIT
10
+ License-File: LICENSE
11
+ Keywords: deepmd,dpgen,language-server,lsp,molecular-dynamics
12
+ Classifier: Development Status :: 3 - Alpha
13
+ Classifier: Intended Audience :: Science/Research
14
+ Classifier: License :: OSI Approved :: MIT License
15
+ Classifier: Programming Language :: Python :: 3
16
+ Classifier: Programming Language :: Python :: 3.9
17
+ Classifier: Programming Language :: Python :: 3.10
18
+ Classifier: Programming Language :: Python :: 3.11
19
+ Classifier: Programming Language :: Python :: 3.12
20
+ Classifier: Topic :: Scientific/Engineering :: Chemistry
21
+ Classifier: Topic :: Scientific/Engineering :: Physics
22
+ Classifier: Topic :: Text Editors :: Integrated Development Environments (IDE)
23
+ Requires-Python: >=3.9
24
+ Requires-Dist: lsprotocol>=2023.0.0
25
+ Requires-Dist: pygls>=1.2.0
26
+ Provides-Extra: dev
27
+ Requires-Dist: black>=23.0; extra == 'dev'
28
+ Requires-Dist: mypy>=1.0; extra == 'dev'
29
+ Requires-Dist: pre-commit>=3.0; extra == 'dev'
30
+ Requires-Dist: pytest-cov>=4.0; extra == 'dev'
31
+ Requires-Dist: pytest>=7.0; extra == 'dev'
32
+ Requires-Dist: ruff>=0.1.0; extra == 'dev'
33
+ Description-Content-Type: text/markdown
34
+
35
+ # dpgen-lsp
36
+
37
+ Language Server Protocol implementation for DP-GEN (Deep Potential GENerator) input files.
38
+
39
+ ## Features
40
+
41
+ - **Auto-completion** for dpgen JSON input parameters (run, simplify workflows)
42
+ - **Diagnostics** with error and warning detection (JSON syntax, schema validation, semantic checks)
43
+ - **Hover documentation** for dpgen parameters from official arginfo documentation
44
+ - **Code formatting** for consistent JSON structure
45
+ - Support for `param.json` and `machine.json` input files
46
+
47
+ ## Installation
48
+
49
+ ```bash
50
+ pip install dpgen-lsp
51
+ ```
52
+
53
+ ## Usage
54
+
55
+ Start the language server:
56
+
57
+ ```bash
58
+ dpgen-lsp
59
+ ```
60
+
61
+ Agent-facing CLI:
62
+
63
+ ```bash
64
+ dpgen-lsp-tool check param.json
65
+ dpgen-lsp-tool complete param.json --line 5 --character 10
66
+ dpgen-lsp-tool hover param.json --line 5 --character 10
67
+ ```
68
+
69
+ ### Editor Integration
70
+
71
+ This package provides the language server executable. To use it in an editor, connect an LSP client to the `dpgen-lsp` command and register `.json` files as dpgen input files.
72
+
73
+ ## Supported Workflows
74
+
75
+ - **dpgen run**: `param.json` with type_map, training, model_devi, fp settings
76
+ - **dpgen simplify**: `param.json` with pick_data, iterative selection parameters
77
+
78
+ ## Supported FP Engines
79
+
80
+ - VASP, Gaussian, CP2K, ABACUS, PWSCF (Quantum ESPRESSO), SIESTA, PWmat, CPX, Amber/Diff, Custom
81
+
82
+ ## Example Input File
83
+
84
+ ```json
85
+ {
86
+ "type_map": ["H", "C"],
87
+ "mass_map": [1, 12],
88
+ "init_data_sys": ["CH4/deepmd"],
89
+ "sys_configs": [["CH4/scale*/00000*/POSCAR"]],
90
+ "numb_models": 4,
91
+ "default_training_param": {
92
+ "model": {
93
+ "type_map": ["H", "C"],
94
+ "descriptor": {
95
+ "type": "se_a",
96
+ "sel": [16, 4],
97
+ "rcut_smth": 0.5,
98
+ "rcut": 5.0,
99
+ "neuron": [120, 120, 120],
100
+ "resnet_dt": true,
101
+ "axis_neuron": 12,
102
+ "seed": 1
103
+ },
104
+ "fitting_net": {
105
+ "neuron": [25, 50, 100],
106
+ "resnet_dt": false,
107
+ "seed": 1
108
+ }
109
+ },
110
+ "learning_rate": {
111
+ "type": "exp",
112
+ "start_lr": 0.001,
113
+ "decay_steps": 100
114
+ },
115
+ "loss": {
116
+ "start_pref_e": 0.02,
117
+ "limit_pref_e": 2,
118
+ "start_pref_f": 1000,
119
+ "limit_pref_f": 1,
120
+ "start_pref_v": 0.0,
121
+ "limit_pref_v": 0.0
122
+ },
123
+ "training": {
124
+ "numb_steps": 2000,
125
+ "disp_file": "lcurve.out",
126
+ "disp_freq": 1000,
127
+ "save_freq": 1000
128
+ }
129
+ },
130
+ "model_devi_dt": 0.002,
131
+ "model_devi_skip": 0,
132
+ "model_devi_f_trust_lo": 0.05,
133
+ "model_devi_f_trust_hi": 0.15,
134
+ "model_devi_jobs": [
135
+ {
136
+ "sys_idx": [0],
137
+ "temps": [100],
138
+ "press": [1.0],
139
+ "trj_freq": 10,
140
+ "nsteps": 300,
141
+ "ensemble": "nvt"
142
+ }
143
+ ],
144
+ "fp_style": "vasp",
145
+ "fp_task_max": 20,
146
+ "fp_task_min": 5,
147
+ "fp_pp_path": "./",
148
+ "fp_pp_files": ["POTCAR_H", "POTCAR_C"],
149
+ "fp_incar": "./INCAR_methane"
150
+ }
151
+ ```
152
+
153
+ ## License
154
+
155
+ MIT
@@ -0,0 +1,121 @@
1
+ # dpgen-lsp
2
+
3
+ Language Server Protocol implementation for DP-GEN (Deep Potential GENerator) input files.
4
+
5
+ ## Features
6
+
7
+ - **Auto-completion** for dpgen JSON input parameters (run, simplify workflows)
8
+ - **Diagnostics** with error and warning detection (JSON syntax, schema validation, semantic checks)
9
+ - **Hover documentation** for dpgen parameters from official arginfo documentation
10
+ - **Code formatting** for consistent JSON structure
11
+ - Support for `param.json` and `machine.json` input files
12
+
13
+ ## Installation
14
+
15
+ ```bash
16
+ pip install dpgen-lsp
17
+ ```
18
+
19
+ ## Usage
20
+
21
+ Start the language server:
22
+
23
+ ```bash
24
+ dpgen-lsp
25
+ ```
26
+
27
+ Agent-facing CLI:
28
+
29
+ ```bash
30
+ dpgen-lsp-tool check param.json
31
+ dpgen-lsp-tool complete param.json --line 5 --character 10
32
+ dpgen-lsp-tool hover param.json --line 5 --character 10
33
+ ```
34
+
35
+ ### Editor Integration
36
+
37
+ This package provides the language server executable. To use it in an editor, connect an LSP client to the `dpgen-lsp` command and register `.json` files as dpgen input files.
38
+
39
+ ## Supported Workflows
40
+
41
+ - **dpgen run**: `param.json` with type_map, training, model_devi, fp settings
42
+ - **dpgen simplify**: `param.json` with pick_data, iterative selection parameters
43
+
44
+ ## Supported FP Engines
45
+
46
+ - VASP, Gaussian, CP2K, ABACUS, PWSCF (Quantum ESPRESSO), SIESTA, PWmat, CPX, Amber/Diff, Custom
47
+
48
+ ## Example Input File
49
+
50
+ ```json
51
+ {
52
+ "type_map": ["H", "C"],
53
+ "mass_map": [1, 12],
54
+ "init_data_sys": ["CH4/deepmd"],
55
+ "sys_configs": [["CH4/scale*/00000*/POSCAR"]],
56
+ "numb_models": 4,
57
+ "default_training_param": {
58
+ "model": {
59
+ "type_map": ["H", "C"],
60
+ "descriptor": {
61
+ "type": "se_a",
62
+ "sel": [16, 4],
63
+ "rcut_smth": 0.5,
64
+ "rcut": 5.0,
65
+ "neuron": [120, 120, 120],
66
+ "resnet_dt": true,
67
+ "axis_neuron": 12,
68
+ "seed": 1
69
+ },
70
+ "fitting_net": {
71
+ "neuron": [25, 50, 100],
72
+ "resnet_dt": false,
73
+ "seed": 1
74
+ }
75
+ },
76
+ "learning_rate": {
77
+ "type": "exp",
78
+ "start_lr": 0.001,
79
+ "decay_steps": 100
80
+ },
81
+ "loss": {
82
+ "start_pref_e": 0.02,
83
+ "limit_pref_e": 2,
84
+ "start_pref_f": 1000,
85
+ "limit_pref_f": 1,
86
+ "start_pref_v": 0.0,
87
+ "limit_pref_v": 0.0
88
+ },
89
+ "training": {
90
+ "numb_steps": 2000,
91
+ "disp_file": "lcurve.out",
92
+ "disp_freq": 1000,
93
+ "save_freq": 1000
94
+ }
95
+ },
96
+ "model_devi_dt": 0.002,
97
+ "model_devi_skip": 0,
98
+ "model_devi_f_trust_lo": 0.05,
99
+ "model_devi_f_trust_hi": 0.15,
100
+ "model_devi_jobs": [
101
+ {
102
+ "sys_idx": [0],
103
+ "temps": [100],
104
+ "press": [1.0],
105
+ "trj_freq": 10,
106
+ "nsteps": 300,
107
+ "ensemble": "nvt"
108
+ }
109
+ ],
110
+ "fp_style": "vasp",
111
+ "fp_task_max": 20,
112
+ "fp_task_min": 5,
113
+ "fp_pp_path": "./",
114
+ "fp_pp_files": ["POTCAR_H", "POTCAR_C"],
115
+ "fp_incar": "./INCAR_methane"
116
+ }
117
+ ```
118
+
119
+ ## License
120
+
121
+ MIT
@@ -0,0 +1,57 @@
1
+ {
2
+ "$schema": "http://json-schema.org/draft-07/schema#",
3
+ "title": "Diagnostic Engine v1",
4
+ "version": "1.0",
5
+ "type": "object",
6
+ "properties": {
7
+ "uri": {"type": "string"},
8
+ "operation": {"type": "string"},
9
+ "ok": {"type": "boolean"},
10
+ "version": {"type": "string"},
11
+ "software": {"type": "string"},
12
+ "diagnostic_engine": {"type": "string"},
13
+ "diagnostics": {
14
+ "type": "array",
15
+ "items": {
16
+ "type": "object",
17
+ "properties": {
18
+ "code": {"type": "string"},
19
+ "severity": {"enum": ["error", "warning", "information", "hint"]},
20
+ "category": {
21
+ "enum": [
22
+ "syntax",
23
+ "schema",
24
+ "type/value",
25
+ "cross-file reference",
26
+ "semantic consistency",
27
+ "preflight/runtime-risk",
28
+ "style/deprecation"
29
+ ]
30
+ },
31
+ "confidence": {"type": "number"},
32
+ "source": {"type": "string"},
33
+ "range": {
34
+ "type": "object",
35
+ "properties": {
36
+ "start": {"type": "object", "properties": {"line": {"type": "integer"}, "character": {"type": "integer"}}},
37
+ "end": {"type": "object", "properties": {"line": {"type": "integer"}, "character": {"type": "integer"}}}
38
+ }
39
+ },
40
+ "message": {"type": "string"},
41
+ "blocking": {"type": "boolean"},
42
+ "fix_hints": {"type": "array", "items": {"type": "string"}},
43
+ "manual_ref": {"type": "string"}
44
+ }
45
+ }
46
+ },
47
+ "summary": {
48
+ "type": "object",
49
+ "properties": {
50
+ "count": {"type": "integer"},
51
+ "blocking": {"type": "integer"},
52
+ "errors": {"type": "integer"},
53
+ "warnings": {"type": "integer"}
54
+ }
55
+ }
56
+ }
57
+ }
@@ -0,0 +1,4 @@
1
+ LOG INIT:dpdispatcher log direct to /123/guomingyu/TOOLS_IN_DEV/dpgen-lsp/dpdispatcher.log
2
+ LOG INIT:dpdispatcher log direct to /123/guomingyu/TOOLS_IN_DEV/dpgen-lsp/dpdispatcher.log
3
+ LOG INIT:dpdispatcher log direct to /123/guomingyu/TOOLS_IN_DEV/dpgen-lsp/dpdispatcher.log
4
+ LOG INIT:dpdispatcher log direct to /123/guomingyu/TOOLS_IN_DEV/dpgen-lsp/dpdispatcher.log
@@ -0,0 +1,29 @@
1
+ {
2
+ "schema": "OpenQCLspCapabilities",
3
+ "version": 1,
4
+ "software": "dpgen",
5
+ "capabilities": [
6
+ "diagnostics",
7
+ "rich-diagnostics",
8
+ "completion",
9
+ "hover",
10
+ "symbols",
11
+ "fix-preview",
12
+ "llm-wiki",
13
+ "openqc-context"
14
+ ],
15
+ "agentCli": {
16
+ "operations": [
17
+ "capabilities",
18
+ "init",
19
+ "check",
20
+ "context",
21
+ "complete",
22
+ "hover",
23
+ "symbols",
24
+ "fix"
25
+ ],
26
+ "jsonFormat": true,
27
+ "failOnBlocking": true
28
+ }
29
+ }
@@ -0,0 +1,88 @@
1
+ [build-system]
2
+ requires = ["hatchling"]
3
+ build-backend = "hatchling.build"
4
+
5
+ [project]
6
+ name = "dpgen-lsp"
7
+ version = "0.0.1"
8
+ description = "Language Server Protocol and CLI toolkit for DP-GEN input files"
9
+ readme = "README.md"
10
+ license = {text = "MIT"}
11
+ requires-python = ">=3.9"
12
+ authors = [
13
+ {name = "SchrodingersCattt"},
14
+ ]
15
+ classifiers = [
16
+ "Development Status :: 3 - Alpha",
17
+ "Intended Audience :: Science/Research",
18
+ "License :: OSI Approved :: MIT License",
19
+ "Programming Language :: Python :: 3",
20
+ "Programming Language :: Python :: 3.9",
21
+ "Programming Language :: Python :: 3.10",
22
+ "Programming Language :: Python :: 3.11",
23
+ "Programming Language :: Python :: 3.12",
24
+ "Topic :: Scientific/Engineering :: Chemistry",
25
+ "Topic :: Scientific/Engineering :: Physics",
26
+ "Topic :: Text Editors :: Integrated Development Environments (IDE)",
27
+ ]
28
+ keywords = ["dpgen", "deepmd", "lsp", "language-server", "molecular-dynamics"]
29
+ dependencies = [
30
+ "pygls>=1.2.0",
31
+ "lsprotocol>=2023.0.0",
32
+ ]
33
+
34
+ [project.urls]
35
+ Homepage = "https://github.com/SchrodingersCattt/dpgen-lsp"
36
+ Repository = "https://github.com/SchrodingersCattt/dpgen-lsp"
37
+ Issues = "https://github.com/SchrodingersCattt/dpgen-lsp/issues"
38
+
39
+ [project.optional-dependencies]
40
+ dev = [
41
+ "pytest>=7.0",
42
+ "pytest-cov>=4.0",
43
+ "pre-commit>=3.0",
44
+ "black>=23.0",
45
+ "ruff>=0.1.0",
46
+ "mypy>=1.0",
47
+ ]
48
+
49
+ [project.scripts]
50
+ dpgen-lsp = "dpgen_lsp.server:main"
51
+ dpgen-lsp-tool = "dpgen_lsp.tool:main"
52
+
53
+ [tool.hatch.build.targets.wheel]
54
+ packages = ["src/dpgen_lsp"]
55
+
56
+ [tool.black]
57
+ line-length = 100
58
+ target-version = ['py39']
59
+
60
+ [tool.ruff]
61
+ line-length = 100
62
+ target-version = "py39"
63
+
64
+ [tool.pytest.ini_options]
65
+ testpaths = ["tests"]
66
+ addopts = "--cov=src/dpgen_lsp --cov-report=term-missing -v"
67
+
68
+ [tool.coverage.run]
69
+ source = ["src"]
70
+ omit = ["*/tests/*", "*/test_*", "*/__pycache__/*"]
71
+
72
+ [tool.coverage.report]
73
+ exclude_lines = [
74
+ "pragma: no cover",
75
+ "def __repr__",
76
+ "raise AssertionError",
77
+ "raise NotImplementedError",
78
+ "if __name__ == .__main__.:",
79
+ "if TYPE_CHECKING:",
80
+ "pass",
81
+ "..."
82
+ ]
83
+
84
+ [tool.mypy]
85
+ python_version = "3.9"
86
+ warn_return_any = true
87
+ warn_unused_configs = true
88
+ ignore_missing_imports = true
@@ -0,0 +1,50 @@
1
+ #!/usr/bin/env python3
2
+ """Download DP-GEN example templates from GitHub and save to local template dir."""
3
+ import json
4
+ import os
5
+ import urllib.request
6
+
7
+ BASE_URL = "https://raw.githubusercontent.com/deepmodeling/dpgen/master"
8
+ TEMPLATE_ROOT = os.path.join(os.path.dirname(__file__), "..", "..", "..", "src", "dpgen_lsp", "templates")
9
+
10
+ INDEX_PATH = os.path.join(TEMPLATE_ROOT, "index.json")
11
+
12
+ def download(url, dest):
13
+ os.makedirs(os.path.dirname(dest), exist_ok=True)
14
+ try:
15
+ with urllib.request.urlopen(url) as resp:
16
+ data = resp.read()
17
+ with open(dest, "wb") as f:
18
+ f.write(data)
19
+ try:
20
+ json.loads(data)
21
+ print(f" OK: {dest}")
22
+ except json.JSONDecodeError as e:
23
+ print(f" JSON ERROR: {dest}: {e}")
24
+ except Exception as e:
25
+ print(f" FAIL: {url} -> {dest}: {e}")
26
+
27
+ def main():
28
+ with open(INDEX_PATH) as f:
29
+ index = json.load(f)
30
+
31
+ for entry in index.get("param", []):
32
+ upstream = entry["upstream_path"]
33
+ resource = entry["resource"]
34
+ url = f"{BASE_URL}/{upstream}"
35
+ dest = os.path.join(TEMPLATE_ROOT, resource)
36
+ print(f"Downloading param: {upstream}")
37
+ download(url, dest)
38
+
39
+ for entry in index.get("machine", []):
40
+ upstream = entry["upstream_path"]
41
+ resource = entry["resource"]
42
+ url = f"{BASE_URL}/{upstream}"
43
+ dest = os.path.join(TEMPLATE_ROOT, resource)
44
+ print(f"Downloading machine: {upstream}")
45
+ download(url, dest)
46
+
47
+ print("\nDone.")
48
+
49
+ if __name__ == "__main__":
50
+ main()
@@ -0,0 +1,3 @@
1
+ """dpgen Language Server Protocol implementation."""
2
+
3
+ __version__ = "0.1.0"
@@ -0,0 +1,79 @@
1
+ """Small Python API wrapper around the Diagnostic Engine v1 CLI contract."""
2
+
3
+ from __future__ import annotations
4
+
5
+ from pathlib import Path
6
+ from tempfile import TemporaryDirectory
7
+ from typing import Any
8
+ from urllib.parse import urlparse
9
+
10
+ from .agent_operations import operation_path, with_capabilities
11
+ from .tool import SOFTWARE, _collect_diagnostics, _file_type, check_path
12
+
13
+
14
+ class AgentLSP:
15
+ """Agent-facing wrapper for non-editor LSP diagnostics."""
16
+
17
+ def __init__(self, text: str | None = None, uri: str = "file:///input") -> None:
18
+ self.text = text
19
+ self.uri = uri
20
+
21
+ @classmethod
22
+ def from_text(cls, text: str, uri: str = "file:///input") -> "AgentLSP":
23
+ return cls(text=text, uri=uri)
24
+
25
+ @classmethod
26
+ def from_path(cls, path: str | Path) -> "AgentLSP":
27
+ return cls(text=None, uri=Path(path).resolve().as_uri())
28
+
29
+ def check(self) -> dict[str, Any]:
30
+ parsed = urlparse(self.uri)
31
+ if self.text is None and parsed.scheme == "file":
32
+ return with_capabilities(check_path(Path(parsed.path)), "check")
33
+ suffix = Path(parsed.path).suffix if parsed.path else ""
34
+ with TemporaryDirectory() as tmp:
35
+ path = Path(tmp) / f"input{suffix}"
36
+ path.write_text(self.text or "", encoding="utf-8")
37
+ payload = check_path(path)
38
+ payload["uri"] = self.uri
39
+ return with_capabilities(payload, "check")
40
+
41
+ def _operation(self, operation: str, line: int = 0, character: int = 0) -> dict[str, Any]:
42
+ parsed = urlparse(self.uri)
43
+ if self.text is None and parsed.scheme == "file":
44
+ return operation_path(
45
+ Path(parsed.path),
46
+ operation,
47
+ software=SOFTWARE,
48
+ file_type_func=_file_type,
49
+ collect_diagnostics=_collect_diagnostics,
50
+ line=line,
51
+ character=character,
52
+ )
53
+ suffix = Path(parsed.path).suffix if parsed.path else ""
54
+ with TemporaryDirectory() as tmp:
55
+ path = Path(tmp) / f"input{suffix}"
56
+ path.write_text(self.text or "", encoding="utf-8")
57
+ payload = operation_path(
58
+ path,
59
+ operation,
60
+ software=SOFTWARE,
61
+ file_type_func=_file_type,
62
+ collect_diagnostics=_collect_diagnostics,
63
+ line=line,
64
+ character=character,
65
+ )
66
+ payload["uri"] = self.uri
67
+ return payload
68
+
69
+ def context(self, line: int = 0, character: int = 0) -> dict[str, Any]:
70
+ return self._operation("context", line, character)
71
+
72
+ def complete(self, line: int = 0, character: int = 0) -> dict[str, Any]:
73
+ return self._operation("complete", line, character)
74
+
75
+ def hover(self, line: int = 0, character: int = 0) -> dict[str, Any]:
76
+ return self._operation("hover", line, character)
77
+
78
+ def symbols(self) -> dict[str, Any]:
79
+ return self._operation("symbols")