dsh-vibe-math 2.7.0 → 2.7.1
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.en.md +5 -0
- package/README.md +5 -0
- package/cordis.patch.yml +6 -0
- package/docs/math-computation.md +44 -2
- package/docs/release-notes/RELEASE-NOTES-2.7.1.en.md +86 -0
- package/docs/release-notes/RELEASE-NOTES-2.7.1.md +86 -0
- package/package.json +5 -3
- package/prompt-corpus-persona/persona-corpus.json +8 -8
- package/prompt-corpus-persona/persona-corpus.md +12 -0
- package/prompt-corpus-v2/formal-verify-v2.json +162 -96
- package/prompt-corpus-v2/formal-verify-v2.md +949 -0
- package/prompt-corpus-v3/formal-verify-v3.json +171 -57
- package/prompt-corpus-v3/formal-verify-v3.md +1146 -0
- package/prompt-corpus-v4/formal-verify-v4.json +10 -10
- package/prompt-corpus-v4/formal-verify-v4.md +20 -0
- package/prompt-corpus-v5/prompt-corpus-v5.json +61 -61
- package/prompt-corpus-v5/prompt-corpus-v5.md +61 -0
- package/tests/audit-math-computation-contract.mjs +13 -0
- package/tests/audit-math-computation-parity.mjs +30 -1
- package/tests/audit-math-computation-sensitivity.mjs +1 -1
- package/tests/e2e-v5-round2.test.mjs +7 -0
- package/tests/formal-verify-v2.test.mjs +70 -2
- package/tests/formal-verify-v3.test.mjs +84 -2
- package/tests/helpers/math-computation-fake-seam.mjs +30 -2
- package/tests/math-computation-shared.test.mjs +304 -2
- package/vibe-math-v2/agent.cordis.yml +2 -0
- package/vibe-math-v2/math-computation.js +390 -47
- package/vibe-math-v2/math-engines.js +47 -6
- package/vibe-math-v2/vibe-math-v2.js +17 -1
- package/vibe-math-v3/agent.cordis.yml +2 -0
- package/vibe-math-v3/math-computation.js +390 -47
- package/vibe-math-v3/math-engines.js +47 -6
- package/vibe-math-v3/vibe-math-v3.js +17 -1
- package/vibe-math-v4/agent.cordis.yml +4 -0
- package/vibe-math-v4/math-computation.js +390 -47
- package/vibe-math-v4/math-engines.js +47 -6
- package/vibe-math-v4/vibe-math-v4.js +15 -0
- package/vibe-math-v5/agent.cordis.yml +4 -0
- package/vibe-math-v5/math-computation.js +390 -47
- package/vibe-math-v5/math-engines.js +47 -6
- package/vibe-math-v5/vibe-math-v5.js +15 -3
|
@@ -22,14 +22,47 @@ export const MATH_ENGINES = {
|
|
|
22
22
|
candidates: ['python3', 'python', 'py'], winPrefix: ['-3'],
|
|
23
23
|
versionArgv: ['--version'], versionRe: '(\\d+\\.\\d+\\.\\d+)',
|
|
24
24
|
scriptArgv: ['<script>'], evalArgv: ['-c', '<expr>'], stdinArgv: ['-'], ext: '.py',
|
|
25
|
-
|
|
26
|
-
|
|
25
|
+
// round-7 (live): NO shell metacharacters (`|`, `%`) in any probe argv - a real host rejected
|
|
26
|
+
// them with a null spawn. One line per package: "name ok|missing".
|
|
27
|
+
probeCode: "import importlib.util,sys\nfor p in sys.argv[1:]: print(p, 'ok' if importlib.util.find_spec(p) is not None else 'missing')",
|
|
28
|
+
// round-7 (finding 6, found on the real bundled python): the probe code iterates `sys.argv[1:]`,
|
|
29
|
+
// so the names must be SEPARATE argv items - the old comma-joined `<pkgs>` made it look up one
|
|
30
|
+
// package literally named "numpy,pandas" and reported everything missing.
|
|
31
|
+
packageProbe: { argv: ['-c', '<probeCode>', '<pkgs...>'], parse: 'pairs' },
|
|
27
32
|
license: 'free', argErrorHints: ARG_ERROR_HINTS,
|
|
28
33
|
install: {
|
|
29
34
|
manager: 'pip',
|
|
30
35
|
userArgv: ['<exe>', '-m', 'pip', 'install', '--user', '<pkg>'],
|
|
31
36
|
systemArgv: ['<exe>', '-m', 'pip', 'install', '<pkg>'],
|
|
32
37
|
uninstallArgv: ['<exe>', '-m', 'pip', 'uninstall', '-y', '<pkg>'],
|
|
38
|
+
// Round-6 (B): DISPATCH by the detected interpreter environment. `pip` is the documented
|
|
39
|
+
// fallback; the module picks conda/mamba/uv only when the interpreter's OWN environment says so
|
|
40
|
+
// (detect, don't guess) and the plan states which manager it assumed.
|
|
41
|
+
managers: {
|
|
42
|
+
conda: {
|
|
43
|
+
detect: 'conda-markers',
|
|
44
|
+
userArgv: ['conda', 'install', '-y', '-c', 'conda-forge', '<pkg>'],
|
|
45
|
+
uninstallArgv: ['conda', 'remove', '-y', '<pkg>'],
|
|
46
|
+
systemUnsupportedReason: 'conda 环境是用户级的;系统级安装不在 conda 的概念里(本工具只出用户级计划)',
|
|
47
|
+
},
|
|
48
|
+
mamba: {
|
|
49
|
+
detect: 'conda-markers',
|
|
50
|
+
userArgv: ['mamba', 'install', '-y', '-c', 'conda-forge', '<pkg>'],
|
|
51
|
+
uninstallArgv: ['mamba', 'remove', '-y', '<pkg>'],
|
|
52
|
+
systemUnsupportedReason: 'mamba 环境是用户级的;系统级安装不在 mamba 的概念里(本工具只出用户级计划)',
|
|
53
|
+
},
|
|
54
|
+
uv: {
|
|
55
|
+
detect: 'uv-next-to-interpreter',
|
|
56
|
+
userArgv: ['uv', 'pip', 'install', '<pkg>'],
|
|
57
|
+
uninstallArgv: ['uv', 'pip', 'uninstall', '<pkg>'],
|
|
58
|
+
systemUnsupportedReason: 'uv 装进当前虚拟环境(用户级);系统级需要发行版包管理器,本工具只出用户级计划',
|
|
59
|
+
},
|
|
60
|
+
pip: {
|
|
61
|
+
detect: 'fallback',
|
|
62
|
+
systemArgv: ['<exe>', '-m', 'pip', 'install', '<pkg>'],
|
|
63
|
+
uninstallArgv: ['<exe>', '-m', 'pip', 'uninstall', '-y', '<pkg>'],
|
|
64
|
+
},
|
|
65
|
+
},
|
|
33
66
|
},
|
|
34
67
|
userInstall: { windows: 'winget install --id Python.Python.3.12', macos: 'brew install python', linux: 'apt install python3' },
|
|
35
68
|
},
|
|
@@ -38,13 +71,16 @@ export const MATH_ENGINES = {
|
|
|
38
71
|
candidates: ['Rscript', 'R'],
|
|
39
72
|
versionArgv: ['--version'], versionRe: '(\\d+\\.\\d+\\.\\d+)',
|
|
40
73
|
scriptArgv: ['<script>'], evalArgv: ['-e', '<expr>'], stdinArgv: ['--no-save', '--slave'], ext: '.R',
|
|
41
|
-
|
|
74
|
+
// round-7 (live): line-per-package, no `|` in the argv.
|
|
75
|
+
probeCode: "for (p in strsplit('__PKGS__',',')[[1]]) cat(p, if (requireNamespace(p, quietly=TRUE)) 'ok' else 'missing', '\\n')",
|
|
42
76
|
packageProbe: { argv: ['-e', '<probeCode>'], parse: 'pairs' },
|
|
43
77
|
license: 'free', argErrorHints: ARG_ERROR_HINTS,
|
|
44
78
|
install: {
|
|
45
79
|
manager: 'r',
|
|
46
80
|
userArgv: ['<exe>', '-e', "install.packages('__PKG__',lib=Sys.getenv('R_LIBS_USER'),repos='https://cloud.r-project.org')"],
|
|
47
81
|
uninstallArgv: ['<exe>', '-e', "remove.packages('__PKG__',lib=Sys.getenv('R_LIBS_USER'))"],
|
|
82
|
+
// Round-6 (C): user-only BY DESIGN, and the refusal now says why per engine.
|
|
83
|
+
systemUnsupportedReason: 'R 的用户库是 R_LIBS_USER;系统级安装要写发行版的包目录(需 root 或发行版包管理器),本工具只出用户级计划',
|
|
48
84
|
},
|
|
49
85
|
userInstall: { windows: 'winget install --id RProject.R', macos: 'brew install r', linux: 'apt install r-base' },
|
|
50
86
|
},
|
|
@@ -54,13 +90,15 @@ export const MATH_ENGINES = {
|
|
|
54
90
|
versionArgv: ['--version'], versionRe: '(\\d+\\.\\d+\\.\\d+)',
|
|
55
91
|
scriptArgv: ['--no-gui', '--quiet', '<script>'], evalArgv: ['--no-gui', '--quiet', '--eval', '<expr>'],
|
|
56
92
|
stdinArgv: ['--no-gui', '--quiet'], ext: '.m',
|
|
57
|
-
|
|
93
|
+
// round-7 (live): line-per-package via disp, no `|` and no `%` in the argv.
|
|
94
|
+
probeCode: "s=pkg('list'); n={'__QPKGS__'}; for i=1:numel(n); if any(cellfun(@(x) strcmp(x.name,n{i}),s)); disp([n{i} ' ok']); else; disp([n{i} ' missing']); end; end",
|
|
58
95
|
packageProbe: { argv: ['--no-gui', '--quiet', '--eval', '<probeCode>'], parse: 'pairs' },
|
|
59
96
|
license: 'free', argErrorHints: ARG_ERROR_HINTS,
|
|
60
97
|
install: {
|
|
61
98
|
manager: 'octave-pkg',
|
|
62
99
|
userArgv: ['<exe>', '--no-gui', '--quiet', '--eval', "pkg install -forge __PKG__"],
|
|
63
100
|
uninstallArgv: ['<exe>', '--no-gui', '--quiet', '--eval', 'pkg uninstall __PKG__'],
|
|
101
|
+
systemUnsupportedReason: 'Octave 的 pkg install 装进用户包目录;系统级要写 Octave 的 share/packages(需 root),本工具只出用户级计划',
|
|
64
102
|
},
|
|
65
103
|
userInstall: { windows: 'winget install --id GNU.Octave', macos: 'brew install octave', linux: 'apt install octave' },
|
|
66
104
|
},
|
|
@@ -76,6 +114,7 @@ export const MATH_ENGINES = {
|
|
|
76
114
|
manager: 'julia-pkg',
|
|
77
115
|
userArgv: ['<exe>', '-e', 'using Pkg; Pkg.add("__PKG__")'],
|
|
78
116
|
uninstallArgv: ['<exe>', '-e', 'using Pkg; Pkg.rm("__PKG__")'],
|
|
117
|
+
systemUnsupportedReason: 'Julia 的 Pkg.add 装进当前活动环境 / 用户 depot(JULIA_DEPOT_PATH);系统级不是 Julia 的概念,本工具只出用户级计划',
|
|
79
118
|
},
|
|
80
119
|
userInstall: { windows: 'winget install --id Julialang.Julia', macos: 'brew install julia', linux: 'apt install julia' },
|
|
81
120
|
},
|
|
@@ -84,7 +123,8 @@ export const MATH_ENGINES = {
|
|
|
84
123
|
candidates: ['matlab'],
|
|
85
124
|
versionArgv: ['-batch', 'disp(version)'], versionRe: '(\\d+\\.\\d+)',
|
|
86
125
|
scriptArgv: ['-batch', "run('<script>')"], evalArgv: ['-batch', '<expr>'], stdinArgv: null, ext: '.m',
|
|
87
|
-
|
|
126
|
+
// round-7 (live): no `|`/`%` in any probe argv (a real host rejected such argv with a null spawn).
|
|
127
|
+
probeCode: "t={'__QPKGS__'}; for i=1:numel(t); if license('test',t{i}); disp([t{i} ' ok']); else; disp([t{i} ' missing']); end; end",
|
|
88
128
|
packageProbe: { argv: ['-batch', '<probeCode>'], parse: 'pairs' },
|
|
89
129
|
license: 'commercial', argErrorHints: ARG_ERROR_HINTS,
|
|
90
130
|
licenseProbe: { argv: ['-batch', "disp(license('test','MATLAB'))"], okWhen: 'trim-1' },
|
|
@@ -96,7 +136,8 @@ export const MATH_ENGINES = {
|
|
|
96
136
|
candidates: ['maple'],
|
|
97
137
|
versionArgv: ['--version'], versionRe: '(\\d+\\.\\d+)',
|
|
98
138
|
scriptArgv: ['-q', '<script>'], evalArgv: ['-q', '-c', '<expr>'], stdinArgv: null, ext: '.mpl',
|
|
99
|
-
|
|
139
|
+
// round-7 (live): `print` instead of printf so the argv carries no `|`/`%`.
|
|
140
|
+
probeCode: 'for p in ["__PKGS__"] do try with(p) catch: print(p, " missing"); next end try; print(p, " ok") end do',
|
|
100
141
|
packageProbe: { argv: ['-q', '-c', '<probeCode>'], parse: 'pairs' },
|
|
101
142
|
license: 'commercial', argErrorHints: ARG_ERROR_HINTS,
|
|
102
143
|
licenseProbe: { argv: ['-q', '-c', 'printf("1")'], okWhen: 'exit-0' },
|
|
@@ -30,6 +30,7 @@ import {
|
|
|
30
30
|
MATH_TOOL_DESCRIPTION,
|
|
31
31
|
MATH_TOOL_SCHEMA,
|
|
32
32
|
MATH_ARCHIVE_WORKFLOW_LINE,
|
|
33
|
+
MATH_SUBSTITUTION_RULE_LINE,
|
|
33
34
|
MATH_PERSONA_TOOL_LINE,
|
|
34
35
|
MATH_RULE_LINES,
|
|
35
36
|
normalizeMathParams,
|
|
@@ -536,6 +537,11 @@ export function apply(ctx) {
|
|
|
536
537
|
// **可选能力,按宿主实际情况声明**:宿主 fs 没有 listDir 就不给这个回调(模块据此跳过
|
|
537
538
|
// "每项目 run 目录数 >200" 的保留检查,而不是每次运行都白问一次)。
|
|
538
539
|
listDir: (typeof fs.listDir === 'function') ? mathListDir : undefined,
|
|
540
|
+
// round-7 (fix 2): DSH's own bundled runtimes (`<home>/.dsh/dsh-runtimes/*/dependencies/<engine>/`)
|
|
541
|
+
// as a LAST resort after PATH. Only generic roots are supplied here; the module globs the tree
|
|
542
|
+
// name (never `dsh-primary-runtime`) and only accepts the descriptor's own candidate names.
|
|
543
|
+
runtimeRoots: () => { const env = process.env.DSH_HOME; if (env) return [String(env)]; const home = String(process.env.HOME || process.env.USERPROFILE || ''); return home ? [home.replace(/[\\/]+$/, '') + '/.dsh'] : [] },
|
|
544
|
+
listDirAbs: async function (abs) { try { const t = await fsTarget(abs); const st = await fs.stat(t); if (!st) return []; return (await fs.listDir(t)) || [] } catch (e) { return [] } },
|
|
539
545
|
writeText: async function (rel, text) { return await writeText(rel, text) },
|
|
540
546
|
readText: async function (rel) { return await readText(rel) },
|
|
541
547
|
exists: mathExists,
|
|
@@ -557,7 +563,15 @@ export function apply(ctx) {
|
|
|
557
563
|
async function refreshMathProbe(force) {
|
|
558
564
|
if (params.mathComputation === 'off') { mathProbe = null; mathProbeAt = 0; return null }
|
|
559
565
|
if (!mathTool) return null
|
|
560
|
-
try {
|
|
566
|
+
try {
|
|
567
|
+
mathProbe = await mathTool.probe(force ? { refresh: true } : undefined)
|
|
568
|
+
mathProbeAt = now()
|
|
569
|
+
// 规则漂移自检(A 项):可用性行必须带"替代必须声明(诚实性)"这条规则。这里引用**常量**
|
|
570
|
+
// 而不是比对文本——模块以后改措辞不会误报,只有整条规则从 MATH_RULE_LINES 里消失才会响。
|
|
571
|
+
if (mathProbe && mathAvailabilityLine(mathProbe, 'zh', params.mathMode).indexOf(MATH_SUBSTITUTION_RULE_LINE) === -1) {
|
|
572
|
+
console.error('vibe-math-v2: 可用性行缺少替代声明规则(MATH_SUBSTITUTION_RULE_LINE)')
|
|
573
|
+
}
|
|
574
|
+
} catch (e) { mathProbe = null }
|
|
561
575
|
return mathProbe
|
|
562
576
|
}
|
|
563
577
|
/** 心跳里的 TTL 刷新(每拍一次布尔判断,成本可忽略)。 */
|
|
@@ -4074,6 +4088,8 @@ export function apply(ctx) {
|
|
|
4074
4088
|
mathProbe: function () { return mathProbe },
|
|
4075
4089
|
// P2a:persona 两个文本块必须含的「归档→编辑→重跑」规则(文本取自共享模块常量,persona 不手抄)。
|
|
4076
4090
|
mathArchiveWorkflowLine: MATH_ARCHIVE_WORKFLOW_LINE,
|
|
4091
|
+
// A 项:替代声明规则(文本由共享模块给出;persona 两块与每轮可用性行都必须带它)。
|
|
4092
|
+
mathSubstitutionRuleLine: MATH_SUBSTITUTION_RULE_LINE,
|
|
4077
4093
|
leanQueueSize: function () { return leanQueue.length },
|
|
4078
4094
|
leanJobsPublic: function () { const out = []; for (const j of leanJobs.values()) out.push(leanJobPublic(j)); return out },
|
|
4079
4095
|
// childOwner 裁剪用:这个会话当前仍"可能再发 subagent/end"的 child(在册的 + 任务正在等的)。
|
|
@@ -68,6 +68,7 @@
|
|
|
68
68
|
mode.
|
|
69
69
|
|
|
70
70
|
- math_computation {op: probe|run|receipt|install, engine, mode: code|file|expr, …} — 先 probe 预检引擎/包/许可,再调引擎计算并把脚本与输出归档成可复核回执;缺引擎/缺包只报告与给安装指引/计划;shell 兜底不算归档。
|
|
71
|
+
- 替代必须声明(诚实性):当替代方案改变了**精确性或结论强度**时(精确符号解 → 数值近似、闭式解 → 采样/求积、改了精度/容差/假设、换了算法类),结论里**必须写明**,不得读起来像得到了原本(精确/所要求的)结果;拿不到精确结果就直说。
|
|
71
72
|
- 归档→编辑→重跑:mode:'code' 的脚本原件在回执的 scriptPath(Computation/<id>/script.<ext>),你可以用普通文件工具打开并编辑它;编辑后用 mode:'file' 指向它重跑,会写出一份**新回执/新 attempt**(含新的 scriptHash)。**旧回执对修改后的代码无效**——报告里必须引用与当前代码哈希一致的那份回执;工具会在 scriptChanged / scriptChangedDuringRun 为 true 时显式告警。
|
|
72
73
|
|
|
73
74
|
A /vibe slash command mirrors the main controls (/vibe start [override]|resume [override]|pause|abort|status|report|mode
|
|
@@ -159,6 +160,7 @@
|
|
|
159
160
|
mode.
|
|
160
161
|
|
|
161
162
|
- math_computation {op: probe|run|receipt|install, engine, mode: code|file|expr, …} — 先 probe 预检引擎/包/许可,再调引擎计算并把脚本与输出归档成可复核回执;缺引擎/缺包只报告与给安装指引/计划;shell 兜底不算归档。
|
|
163
|
+
- 替代必须声明(诚实性):当替代方案改变了**精确性或结论强度**时(精确符号解 → 数值近似、闭式解 → 采样/求积、改了精度/容差/假设、换了算法类),结论里**必须写明**,不得读起来像得到了原本(精确/所要求的)结果;拿不到精确结果就直说。
|
|
162
164
|
- 归档→编辑→重跑:mode:'code' 的脚本原件在回执的 scriptPath(Computation/<id>/script.<ext>),你可以用普通文件工具打开并编辑它;编辑后用 mode:'file' 指向它重跑,会写出一份**新回执/新 attempt**(含新的 scriptHash)。**旧回执对修改后的代码无效**——报告里必须引用与当前代码哈希一致的那份回执;工具会在 scriptChanged / scriptChangedDuringRun 为 true 时显式告警。
|
|
163
165
|
|
|
164
166
|
A /vibe slash command mirrors the main controls (/vibe start [override]|resume [override]|pause|abort|status|report|mode
|