progmune-runtime 2.1.6 → 3.2.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.
Files changed (356) hide show
  1. package/README.md +119 -461
  2. package/dist/ablation-study.js +144 -0
  3. package/dist/ablation-study.test.js +18 -0
  4. package/dist/action-runtime.js +3 -1
  5. package/dist/active-learning.js +211 -0
  6. package/dist/analytics.js +139 -0
  7. package/dist/asset-factory.js +309 -0
  8. package/dist/asset-growth.js +244 -0
  9. package/dist/asset-promotion.js +382 -0
  10. package/dist/asset-quality.js +550 -0
  11. package/dist/audit/business-translator.js +285 -0
  12. package/dist/audit/cli.js +66 -0
  13. package/dist/audit/formatters/html.js +379 -0
  14. package/dist/audit/formatters/json.js +11 -0
  15. package/dist/audit/formatters/markdown.js +192 -0
  16. package/dist/audit/formatters/terminal.js +189 -0
  17. package/dist/audit/index.js +25 -0
  18. package/dist/audit/report-builder.js +318 -0
  19. package/dist/audit/types.js +8 -0
  20. package/dist/audit.js +3 -3
  21. package/dist/auto-benchmark-generator.js +137 -0
  22. package/dist/auto-benchmark-generator.test.js +45 -0
  23. package/dist/auto-protocol-synthesizer.js +362 -0
  24. package/dist/auto-protocol-synthesizer.test.js +82 -0
  25. package/dist/autonomous-patch.js +175 -0
  26. package/dist/autonomous-patch.test.js +128 -0
  27. package/dist/badge/badge-server.js +98 -0
  28. package/dist/behavior-miner.js +442 -0
  29. package/dist/belief-layer.js +475 -0
  30. package/dist/benchmark-count.js +5 -0
  31. package/dist/benchmark-generator.js +211 -0
  32. package/dist/benchmark-harness.js +201 -0
  33. package/dist/benchmark-pass-rate.js +7 -0
  34. package/dist/benchmark-report.js +8 -3
  35. package/dist/benchmark-save.js +14 -1
  36. package/dist/bootstrap-validation.js +197 -0
  37. package/dist/bootstrap-validation.test.js +51 -0
  38. package/dist/branch-ledger.js +1 -1
  39. package/dist/capability-gap.js +130 -0
  40. package/dist/certify-html.js +351 -0
  41. package/dist/certify.js +326 -0
  42. package/dist/check.js +4 -4
  43. package/dist/compliance-miner.js +447 -0
  44. package/dist/continuous-benchmark.js +194 -0
  45. package/dist/continuous-benchmark.test.js +116 -0
  46. package/dist/corpus-stats.js +173 -0
  47. package/dist/counterfactual-engine.js +288 -0
  48. package/dist/coverage-dashboard.js +109 -0
  49. package/dist/coverage-system.test.js +205 -0
  50. package/dist/cross-repo-precision.js +352 -0
  51. package/dist/cve-benchmark.js +180 -0
  52. package/dist/cve-benchmark.test.js +28 -0
  53. package/dist/cve-collector.js +73 -0
  54. package/dist/data-quality.js +141 -0
  55. package/dist/decision-engine.js +388 -0
  56. package/dist/derive-metadata.js +250 -0
  57. package/dist/difficulty-active.test.js +198 -0
  58. package/dist/difficulty-map.js +244 -0
  59. package/dist/discovery-analytics.js +125 -0
  60. package/dist/discovery-model.js +149 -0
  61. package/dist/discovery-optimize.test.js +199 -0
  62. package/dist/discovery-trace.js +276 -0
  63. package/dist/discovery-trace.test.js +97 -0
  64. package/dist/emitter.js +83 -1
  65. package/dist/enterprise-dashboard.js +405 -0
  66. package/dist/eval-hardening.js +297 -0
  67. package/dist/eval-hardening.test.js +85 -0
  68. package/dist/evaluation-campaign.js +359 -0
  69. package/dist/evaluation-campaign.test.js +181 -0
  70. package/dist/evidence-growth.js +143 -0
  71. package/dist/evidence-repository.js +209 -0
  72. package/dist/evidence-system.js +441 -0
  73. package/dist/execute.js +15 -7
  74. package/dist/experimental/software-physics.js +291 -0
  75. package/dist/experimental/state-inference.js +516 -0
  76. package/dist/experimental/unsupervised-physics.js +230 -0
  77. package/dist/extract-ir-python.js +54 -7
  78. package/dist/extract-ir.js +376 -12
  79. package/dist/failure-collector.js +2 -2
  80. package/dist/failure-corpus.js +322 -9
  81. package/dist/feedback.js +16 -5
  82. package/dist/feedback.test.js +49 -0
  83. package/dist/file-lock.js +1 -1
  84. package/dist/flywheel-batch.js +292 -0
  85. package/dist/frameworks/express-cli.js +237 -0
  86. package/dist/frameworks/express-detector.js +445 -0
  87. package/dist/frameworks/express-detector.test.js +206 -0
  88. package/dist/frameworks/index.js +30 -0
  89. package/dist/frameworks/nestjs-detector.js +302 -0
  90. package/dist/frameworks/trpc-detector.js +161 -0
  91. package/dist/frameworks/version-awareness.js +179 -0
  92. package/dist/function-synonyms.js +164 -0
  93. package/dist/function-synonyms.test.js +68 -0
  94. package/dist/generalization.test.js +352 -0
  95. package/dist/goal-annotator.js +113 -0
  96. package/dist/goal-planner.js +563 -0
  97. package/dist/gold-cve.js +164 -0
  98. package/dist/gold-cve.test.js +104 -0
  99. package/dist/gold-quality.js +206 -0
  100. package/dist/gold-tiers.js +241 -0
  101. package/dist/governance-dashboard.js +327 -0
  102. package/dist/graph-viz.js +240 -0
  103. package/dist/guided-frontier.js +195 -0
  104. package/dist/hierarchical-planner.js +148 -0
  105. package/dist/identifier-parser.js +260 -0
  106. package/dist/immune-metrics.js +93 -0
  107. package/dist/immune-receiver.js +158 -0
  108. package/dist/immune-reporter.js +1 -1
  109. package/dist/improvement-orchestrator.js +206 -0
  110. package/dist/inject-p0-vocabulary.js +300 -0
  111. package/dist/intent-parser.js +218 -0
  112. package/dist/invariant-algebra.js +476 -0
  113. package/dist/invariant-calculus.js +533 -0
  114. package/dist/ir-utils.js +70 -0
  115. package/dist/ir-utils.test.js +50 -0
  116. package/dist/knowledge-api.js +312 -0
  117. package/dist/knowledge-evolution.js +452 -0
  118. package/dist/knowledge-explorer.js +506 -0
  119. package/dist/knowledge-flywheel.js +274 -0
  120. package/dist/knowledge-governance.js +338 -0
  121. package/dist/knowledge-governance.test.js +150 -0
  122. package/dist/knowledge-graph.js +181 -0
  123. package/dist/knowledge-guided-synth.js +246 -0
  124. package/dist/knowledge-loop.test.js +77 -0
  125. package/dist/knowledge-object.js +316 -0
  126. package/dist/knowledge-package.js +98 -0
  127. package/dist/kpi-dashboard.js +561 -0
  128. package/dist/l3-cross-function.js +280 -0
  129. package/dist/learning-ranker.js +148 -0
  130. package/dist/learning-ranker.test.js +291 -0
  131. package/dist/ledger/accountability.js +322 -0
  132. package/dist/ledger/chain-builder.js +185 -0
  133. package/dist/ledger/cli.js +222 -0
  134. package/dist/ledger/index.js +13 -0
  135. package/dist/ledger/signatures.js +193 -0
  136. package/dist/ledger/types.js +9 -0
  137. package/dist/llm.js +74 -3
  138. package/dist/load-benchmarks.js +8 -3
  139. package/dist/logger.js +66 -0
  140. package/dist/logger.test.js +37 -0
  141. package/dist/logistic-reward.js +339 -0
  142. package/dist/logistic-reward.test.js +180 -0
  143. package/dist/macro-graph.js +193 -0
  144. package/dist/macro-repair.js +183 -0
  145. package/dist/mcp-server.mjs +1202 -483
  146. package/dist/memory-layer.js +42 -5
  147. package/dist/multi-repo-precision.js +422 -0
  148. package/dist/name-free-protocol.js +425 -0
  149. package/dist/name-free-protocol.test.js +170 -0
  150. package/dist/name-scrambling.js +138 -0
  151. package/dist/name-scrambling.test.js +16 -0
  152. package/dist/p3-observability.test.js +281 -0
  153. package/dist/p5-orchestrator.test.js +225 -0
  154. package/dist/pairwise-preference.js +294 -0
  155. package/dist/pairwise-preference.test.js +140 -0
  156. package/dist/planner-constraints.js +104 -0
  157. package/dist/planner-prompts.js +155 -0
  158. package/dist/planner-telemetry.js +415 -0
  159. package/dist/planner-trace.js +214 -0
  160. package/dist/planner.js +162 -167
  161. package/dist/plsb/artifact.js +116 -0
  162. package/dist/plsb/cli.js +71 -0
  163. package/dist/plsb/index.js +19 -0
  164. package/dist/plsb/leaderboard.js +249 -0
  165. package/dist/plsb/report-md.js +156 -0
  166. package/dist/plsb/schema.js +179 -0
  167. package/dist/plsb-benchmark.js +284 -0
  168. package/dist/plsb-benchmark.test.js +119 -0
  169. package/dist/policy/cli.js +134 -0
  170. package/dist/policy/engine.js +333 -0
  171. package/dist/policy/index.js +12 -0
  172. package/dist/policy/types.js +59 -0
  173. package/dist/policy-miner.js +505 -0
  174. package/dist/precision-analyze.js +229 -0
  175. package/dist/precision-benchmark.js +147 -0
  176. package/dist/precision-label-c.js +134 -0
  177. package/dist/precision-label.js +193 -0
  178. package/dist/precision-report-c.js +149 -0
  179. package/dist/precision-report.js +246 -0
  180. package/dist/progmune-status.js +108 -0
  181. package/dist/proof-engine.js +479 -0
  182. package/dist/proof-provenance.js +315 -0
  183. package/dist/protocol-coverage.js +294 -0
  184. package/dist/protocol-detector.js +1189 -0
  185. package/dist/protocol-embedding-expanded.js +297 -0
  186. package/dist/protocol-embedding-expanded.test.js +97 -0
  187. package/dist/protocol-embedding.js +195 -0
  188. package/dist/protocol-embedding.test.js +82 -0
  189. package/dist/protocol-extractor-v2.js +354 -0
  190. package/dist/protocol-extractor-v2.test.js +140 -0
  191. package/dist/protocol-extractor.js +310 -0
  192. package/dist/protocol-extractor.test.js +113 -0
  193. package/dist/protocol-foundation.js +322 -0
  194. package/dist/protocol-foundation.test.js +163 -0
  195. package/dist/protocol-frontier.js +243 -0
  196. package/dist/protocol-frontier.test.js +92 -0
  197. package/dist/protocol-gap-analyzer.js +228 -0
  198. package/dist/protocol-gap-analyzer.test.js +49 -0
  199. package/dist/protocol-invariants.js +276 -0
  200. package/dist/protocol-invariants.test.js +111 -0
  201. package/dist/protocol-knowledge.js +464 -0
  202. package/dist/protocol-miner.js +343 -0
  203. package/dist/protocol-mining.js +207 -0
  204. package/dist/protocol-mining.test.js +37 -0
  205. package/dist/protocol-registry.js +1 -1
  206. package/dist/protocol-security-benchmark.js +222 -0
  207. package/dist/protocol-vulnerability.js +257 -0
  208. package/dist/protocol-vulnerability.test.js +60 -0
  209. package/dist/python-benchmark.js +120 -0
  210. package/dist/python-emitter.js +163 -45
  211. package/dist/python-protocol-extractor.js +187 -0
  212. package/dist/python-protocol-extractor.test.js +116 -0
  213. package/dist/realworld-benchmark.js +646 -0
  214. package/dist/realworld-benchmark.test.js +36 -0
  215. package/dist/repair-arch.test.js +411 -0
  216. package/dist/repair-evolution.test.js +454 -0
  217. package/dist/repair-executor.js +719 -0
  218. package/dist/repair-proposal.js +4 -4
  219. package/dist/repair-ranker.js +141 -0
  220. package/dist/repair-strategies.js +419 -0
  221. package/dist/repair-taxonomy.js +234 -0
  222. package/dist/repair-types.js +12 -0
  223. package/dist/repo-evaluator.js +250 -0
  224. package/dist/repo-evaluator.test.js +128 -0
  225. package/dist/resource-abstraction.js +242 -0
  226. package/dist/resource-detector.js +211 -0
  227. package/dist/result.test.js +43 -0
  228. package/dist/reward-system.js +411 -0
  229. package/dist/reward-system.test.js +175 -0
  230. package/dist/risk-model.js +215 -0
  231. package/dist/rule-miner.js +234 -7
  232. package/dist/rule-specificity.js +254 -0
  233. package/dist/runtime-types.js +27 -0
  234. package/dist/scaffold.js +208 -0
  235. package/dist/scale-collector.test.js +101 -0
  236. package/dist/scale-trajectory-collector.js +128 -0
  237. package/dist/sdk.js +250 -0
  238. package/dist/search-planner.js +4 -41
  239. package/dist/semantic-snapshot.js +1 -1
  240. package/dist/semantic-topology.js +121 -0
  241. package/dist/semantic-trace.js +310 -317
  242. package/dist/sequence-extractor.js +343 -0
  243. package/dist/skill-library.js +245 -0
  244. package/dist/skill-planner.test.js +189 -0
  245. package/dist/software-physics.js +291 -0
  246. package/dist/software-physics.test.js +81 -0
  247. package/dist/ssg-precision.js +478 -0
  248. package/dist/ssg-validator.js +71 -21
  249. package/dist/state-inference-doubleblind.test.js +160 -0
  250. package/dist/state-inference.js +516 -0
  251. package/dist/state-inference.test.js +115 -0
  252. package/dist/state-machine-fingerprint.js +345 -0
  253. package/dist/state-machine-fingerprint.test.js +120 -0
  254. package/dist/state-miner.js +386 -0
  255. package/dist/state-name-inference.js +213 -0
  256. package/dist/state-name-inference.test.js +69 -0
  257. package/dist/strategy-planner.js +262 -96
  258. package/dist/strategy-planner.test.js +135 -0
  259. package/dist/telemetry-analytics.test.js +402 -0
  260. package/dist/terminal-format.js +68 -0
  261. package/dist/terminal-format.test.js +83 -0
  262. package/dist/topology-factory.js +196 -0
  263. package/dist/topology-representation.js +242 -0
  264. package/dist/topology-representation.test.js +27 -0
  265. package/dist/trajectory-augmentation.js +254 -0
  266. package/dist/trajectory-augmentation.test.js +63 -0
  267. package/dist/trajectory-corpus.js +440 -0
  268. package/dist/trajectory-corpus.test.js +32 -0
  269. package/dist/trajectory-feedback.test.js +116 -0
  270. package/dist/transition-synthesizer.js +286 -0
  271. package/dist/transition-synthesizer.test.js +123 -0
  272. package/dist/trust/api-semantic-mapper.js +809 -0
  273. package/dist/trust/call-graph-propagator.js +225 -0
  274. package/dist/trust/cli.js +122 -0
  275. package/dist/trust/compliance-scorer.js +283 -0
  276. package/dist/trust/confidence-calculator.js +261 -0
  277. package/dist/trust/engine.js +1145 -0
  278. package/dist/trust/explainability.js +85 -0
  279. package/dist/trust/formatters/ci.js +42 -0
  280. package/dist/trust/formatters/json.js +11 -0
  281. package/dist/trust/formatters/terminal.js +152 -0
  282. package/dist/trust/index.js +39 -0
  283. package/dist/trust/phase1-verify.js +171 -0
  284. package/dist/trust/protocol-domain-validator.js +697 -0
  285. package/dist/trust/score-calculator.js +282 -0
  286. package/dist/trust/ssg-bridge.js +641 -0
  287. package/dist/trust/ssg-bridge.test.js +269 -0
  288. package/dist/trust/types.js +67 -0
  289. package/dist/trust/violation-trace.js +335 -0
  290. package/dist/trust-api.js +179 -0
  291. package/dist/trust-calibration.js +279 -0
  292. package/dist/unknown-protocol-discovery.js +339 -0
  293. package/dist/unknown-protocol-discovery.test.js +102 -0
  294. package/dist/unsupervised-physics.js +230 -0
  295. package/dist/unsupervised-physics.test.js +95 -0
  296. package/dist/utils.test.js +37 -0
  297. package/dist/validator.js +187 -10
  298. package/dist/verification-intelligence.js +475 -0
  299. package/dist/verify-api.js +432 -0
  300. package/dist/vi-impact-report.js +293 -0
  301. package/dist/wl-fingerprint.js +162 -0
  302. package/dist/wl-fingerprint.test.js +130 -0
  303. package/dist/zeroshot-strategy.js +139 -0
  304. package/docs/Progmune_/346/212/225/350/265/204/344/272/272/347/231/275/347/232/256/344/271/246_v2.0.html +576 -0
  305. package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +721 -0
  306. package/package.json +73 -6
  307. package/protocols.json +1956 -50
  308. package/.dockerignore +0 -14
  309. package/.mcp.json +0 -11
  310. package/.progmune_allowlist +0 -50
  311. package/.test_report/test_report.md +0 -87
  312. package/Dockerfile +0 -9
  313. package/FAQ.md +0 -167
  314. package/WHITEPAPER.md +0 -540
  315. package/demo-project/auth.ts +0 -55
  316. package/demo-project/tsconfig.json +0 -8
  317. package/dist/acl-breakdown.js +0 -13
  318. package/dist/all-sessions.js +0 -11
  319. package/dist/antibody-stats.js +0 -11
  320. package/dist/branch-tree-count.js +0 -14
  321. package/dist/common-fixpath.js +0 -12
  322. package/dist/constraint-types.js +0 -12
  323. package/dist/exec-metrics.js +0 -11
  324. package/dist/failure-report.js +0 -11
  325. package/dist/fast-path-hits.js +0 -13
  326. package/dist/fingerprint-list.js +0 -15
  327. package/dist/gen-history-log.js +0 -13
  328. package/dist/heatmap-data.js +0 -11
  329. package/dist/recent-session.js +0 -12
  330. package/dist/svl-distribution.js +0 -11
  331. package/dist/terminal-status.js +0 -11
  332. package/dist/token-savings.js +0 -11
  333. package/dist/total-repairs.js +0 -12
  334. package/dist/unresolved-count.js +0 -12
  335. package/dist/valid-fingerprints.js +0 -13
  336. package/dist/verify-ledgers.js +0 -11
  337. package/docs/whitepaper-style.css +0 -77
  338. package/docs/whitepaper-v2.1.md +0 -609
  339. package/docs/whitepaper-v2.2.md +0 -1064
  340. package/docs/whitepaper-v2.2.pdf +0 -0
  341. package/fly.toml +0 -31
  342. package/public/dashboard.html +0 -119
  343. package/server/hub.js +0 -116
  344. package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
  345. package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
  346. package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
  347. package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
  348. package/test/replay-golden.ts +0 -84
  349. package/test_benchmark.js +0 -165
  350. package/test_comprehensive.mjs +0 -638
  351. package/test_concurrency.js +0 -129
  352. package/test_ir_robustness.js +0 -85
  353. package/test_semantic_contracts.js +0 -269
  354. package/test_ssg_stress.js +0 -156
  355. package/test_svl3.js +0 -58
  356. package/tsconfig.json +0 -17
package/dist/planner.js CHANGED
@@ -48,6 +48,7 @@ const protocol_registry_1 = require("./protocol-registry");
48
48
  const semantic_snapshot_1 = require("./semantic-snapshot");
49
49
  const strategy_planner_1 = require("./strategy-planner");
50
50
  const semantic_topology_1 = require("./semantic-topology");
51
+ const planner_prompts_1 = require("./planner-prompts");
51
52
  const fs = __importStar(require("fs"));
52
53
  function enrichActions(actions, ir) {
53
54
  return actions.map(a => {
@@ -93,98 +94,6 @@ function determineConstraintType(svl) {
93
94
  case "SVL-4": return "protocol";
94
95
  }
95
96
  }
96
- /** 构建紧凑函数列表 — 包含能力元数据帮助 LLM 理解函数语义 */
97
- function buildCompactFuncList(funcs, allFuncs) {
98
- // Known string enums with example values
99
- const ENUM_DEFAULTS = {
100
- "SVL": '"SVL-4"', "RootCause": '"F01"', "BranchReason": '"repair_attempt"',
101
- "RepairStrategy": '"insert"', "ConstraintType": '"protocol"',
102
- };
103
- return funcs.map((f) => {
104
- const params = (f.params || []).map((p) => {
105
- const t = (p.type || "any").replace(/\[\]$/, "");
106
- const def = ENUM_DEFAULTS[t];
107
- return def ? `${p.name}: ${def}` : `${p.name}: ${p.type}`;
108
- }).join(",");
109
- let line = `${f.name}(${params})->${f.returnType || "any"}`;
110
- // Add capability metadata + score
111
- const meta = [];
112
- if (f.score && f.score > 0)
113
- meta.push(`★${f.score.toFixed(1)}`);
114
- if (f.purpose)
115
- meta.push(f.purpose.slice(0, 50));
116
- if (f.produces && f.produces.length > 0)
117
- meta.push(`→${f.produces.join(",")}`);
118
- if (meta.length > 0)
119
- line += ` // ${meta.join(" | ")}`;
120
- return line;
121
- }).join("\n");
122
- }
123
- /** Semantic matching: check if two capability labels are related.
124
- * Uses SemanticTopology (structural graph) instead of string matching. */
125
- function semanticMatch(a, b) {
126
- try {
127
- const topo = (0, semantic_topology_1.getTopology)();
128
- if (topo.size > 0)
129
- return topo.capabilityMatch(a, b);
130
- }
131
- catch { }
132
- // Fallback: exact + substring
133
- if (a === b)
134
- return true;
135
- if (a.includes(b) || b.includes(a))
136
- return true;
137
- return false;
138
- }
139
- /** Build capability chain hints from IR: producer→consumer relationships.
140
- * Uses semantic matching for fuzzy capability linking. */
141
- function buildChainHints(funcs) {
142
- const chains = [];
143
- const seen = new Set();
144
- for (const f of funcs) {
145
- if (!f.produces)
146
- continue;
147
- for (const p of f.produces) {
148
- const consumers = funcs.filter((x) => x.name !== f.name &&
149
- (x.requires || []).some((r) => semanticMatch(p, r)));
150
- for (const c of consumers) {
151
- const key = `${f.name}→${c.name}`;
152
- if (seen.has(key))
153
- continue;
154
- seen.add(key);
155
- const matchedReq = (c.requires || []).find((r) => semanticMatch(p, r));
156
- chains.push(`${f.name}()→${c.name}() // ${p} ≈ ${matchedReq || "?"}`);
157
- }
158
- }
159
- }
160
- if (chains.length === 0)
161
- return "";
162
- return "\n推荐调用链(先调生产者,用 $变量名 传给消费者):\n" + chains.map(c => ` ${c}`).join("\n");
163
- }
164
- const SYSTEM_PROMPT = `你是程序合成助手。只输出 JSON 数组,不输出解释。
165
-
166
- 格式:[{"f":"函数名","to":"变量名","a":[{"n":"参数名","t":"类型","v":值}]},{"r":"变量名"}]
167
-
168
- 规则:
169
- - 函数名从可用列表中选择,优先选注释中 purpose 匹配需求的函数
170
- - 0参数函数直接用 "a":[]:{"f":"getAllSessions","to":"s","a":[]}
171
- - 参数值规则(重要!):
172
- - 字符串: "v":""(空串)或 "v":"SVL-4"(已知枚举值)
173
- - 数字: "v":0 或 "v":1
174
- - 布尔: "v":false
175
- - 对象/数组: "v":{} as Type
176
- - 上一个函数返回值: "v":"$变量名"($前缀引用)
177
- - 返回值: {"r":"变量名"} — 必须返回,不能只调用不返回
178
- - 链式调用:看到推荐调用链时,用 $变量名 把生产者输出传给消费者
179
-
180
- 铁律:
181
- - 函数签名中带引号的参数(如 "SVL-4")是字符串值,直接 v 中
182
- - 字符串枚举(SVL等)用带引号的值,禁止 {} as Type
183
- - 每个call的返回值用"to"命名变量,下一个call通过"$变量名"引用
184
- - 最后一个action必须是{"r":"变量名"},不能以call结尾
185
- - 如果你调了函数,必须return它的结果
186
- - 只输出JSON`;
187
- const RETRY_HINT = `输出格式:紧凑 JSON 数组 [{"f":"函数名","to":"变量名","a":[...]}]`;
188
97
  /** 构建重试 prompt:精简但包含必要的 IR 语法提示 */
189
98
  /** 解析 LLM 输出的紧凑 JSON 为 Action[]。
190
99
  * 格式: [{"f":"fn","to":"var","a":[{"n":"p","t":"str","v":"x"}]}, {"r":"var"}, ...]
@@ -273,6 +182,15 @@ function correctFunctionNames(actions, ir) {
273
182
  /** 参数签名预检:确保 call action 的参数数量与 IR 函数签名一致 */
274
183
  function fixParameterCounts(actions, ir) {
275
184
  const fixes = [];
185
+ // Find the most recent preceding call with assignTo for chain defaults
186
+ function findPrevVar(idx) {
187
+ for (let k = idx - 1; k >= 0; k--) {
188
+ const prev = actions[k];
189
+ if (prev.kind === "call" && prev.assignTo)
190
+ return prev.assignTo;
191
+ }
192
+ return undefined;
193
+ }
276
194
  const corrected = actions.map((a, i) => {
277
195
  if (a.kind !== "call" || !a.function)
278
196
  return a;
@@ -284,16 +202,17 @@ function fixParameterCounts(actions, ir) {
284
202
  if (actual === expected)
285
203
  return a;
286
204
  if (actual < expected) {
287
- // 参数太少:填充缺失参数
288
205
  const padded = [...(a.args || [])];
206
+ const prevVar = findPrevVar(i);
289
207
  for (let j = actual; j < expected; j++) {
290
- padded.push({ name: def.params[j].name, type: def.params[j].type || "any", value: "" });
208
+ // Smart default: chain from previous call if available
209
+ const defaultValue = prevVar ? `$${prevVar}` : "";
210
+ padded.push({ name: def.params[j].name, type: def.params[j].type || "any", value: defaultValue });
291
211
  }
292
- fixes.push(`action[${i}] ${a.function}: 参数 ${actual}→${expected} (填充 ${expected - actual} 个缺失参数)`);
212
+ fixes.push(`action[${i}] ${a.function}: 参数 ${actual}→${expected} (填充 ${expected - actual} 个缺失参数${prevVar ? ", 链自 $" + prevVar : ""})`);
293
213
  return { ...a, args: padded };
294
214
  }
295
215
  else {
296
- // 参数太多:截断多余参数
297
216
  fixes.push(`action[${i}] ${a.function}: 参数 ${actual}→${expected} (截断 ${actual - expected} 个多余参数)`);
298
217
  return { ...a, args: a.args.slice(0, expected) };
299
218
  }
@@ -301,30 +220,6 @@ function fixParameterCounts(actions, ir) {
301
220
  return { actions: corrected, fixes };
302
221
  }
303
222
  /** 构建协议链提示:为 LLM 显示协议状态机的合法调用顺序 */
304
- function buildProtocolChainHint(protocols) {
305
- if (protocols.length === 0)
306
- return "";
307
- // 按命名空间分组
308
- const byNs = new Map();
309
- for (const p of protocols) {
310
- const ns = p.protocol.namespace || "_global";
311
- if (!byNs.has(ns))
312
- byNs.set(ns, []);
313
- byNs.get(ns).push(p);
314
- }
315
- const lines = ["\n⚠️ 协议约束(必须严格遵循调用顺序):"];
316
- for (const [ns, fns] of byNs) {
317
- if (ns === "_global" || fns.length <= 1)
318
- continue;
319
- lines.push(` [${ns}] 合法调用链: ${fns.map(p => p.function).join(" → ")}`);
320
- for (const p of fns) {
321
- const pre = p.protocol.pre_states?.join(",") || "(无)";
322
- const post = p.protocol.post_states?.join(",") || "(无)";
323
- lines.push(` ${p.function}: 前置状态=[${pre}] → 后置状态=[${post}]`);
324
- }
325
- }
326
- return lines.join("\n");
327
- }
328
223
  /** JSON schema pre-validation: structural checks before IR-aware validation.
329
224
  * Catches malformed actions that parseActionJSON() accepted but are semantically invalid. */
330
225
  function validateActionSchema(actions) {
@@ -451,7 +346,7 @@ function loadProtocols(ir) {
451
346
  const protoDef = JSON.parse(fs.readFileSync("protocols.json", "utf-8"));
452
347
  jsonProtocols = (0, ssg_validator_1.parseProtocolsFromJSON)(protoDef);
453
348
  }
454
- catch { }
349
+ catch { /* topology rebuild — optional */ }
455
350
  // Merge: IR @protocol takes priority, but inherits JSON namespace
456
351
  const merged = new Map();
457
352
  for (const p of jsonProtocols)
@@ -551,7 +446,7 @@ function attemptSSGRepair(actions, rejection, ir, protocols, namespaceInitialSta
551
446
  return null;
552
447
  }
553
448
  /** @requires INTENT @produces ACTION_PLAN */
554
- async function plan(userIntent) {
449
+ async function plan(userIntent, llmSeeds) {
555
450
  (0, llm_1.resetCallCount)();
556
451
  const irRaw = JSON.parse(fs.readFileSync("ir.json", "utf-8"));
557
452
  // Support both old (array) and new ({typeMap, functions}) formats
@@ -560,13 +455,14 @@ async function plan(userIntent) {
560
455
  try {
561
456
  (0, semantic_topology_1.rebuildTopology)(ir);
562
457
  }
563
- catch { }
458
+ catch { /* topology rebuild — optional */ }
564
459
  // Helper: wrap actions into PlanResult
565
460
  let repairMetrics = { applied: false, count: 0, branchIds: [] };
566
- const wrapResult = (actions, repair) => ({
461
+ const wrapResult = (actions, repair, degraded = false) => ({
567
462
  actions,
568
463
  sessionId: session?.sessionId || "",
569
464
  ruleHash: session?.ruleHash,
465
+ degraded,
570
466
  repairApplied: repair?.applied ?? repairMetrics.applied,
571
467
  repairCount: repair?.count ?? repairMetrics.count,
572
468
  repairBranchIds: repair?.branchIds ?? repairMetrics.branchIds,
@@ -591,15 +487,45 @@ async function plan(userIntent) {
591
487
  }
592
488
  // 提前加载协议(后续多处使用)
593
489
  const { protocols, namespaceInitialStates } = loadProtocols(ir);
594
- // 抗体免疫快速通道:查询高置信度抗体(ACL-3+),匹配则约束或跳过 LLM
595
- const antibodies = (0, failure_corpus_1.queryAntibodies)(userIntent, "ACL-3");
490
+ // ── Auto Router: repo-specific tasks → Graph ON, generic tasks → OFF ──
491
+ const explicitMode = process.env.PROGMUNE_GRAPH_MODE;
492
+ let graphMode = explicitMode || "off"; // default OFF
493
+ if (!explicitMode) {
494
+ // Extract repo-specific terms from IR
495
+ const repoNames = new Set();
496
+ for (const f of ir) {
497
+ for (const word of f.name.replace(/([A-Z])/g, " $1").toLowerCase().split(/[\s_]+/))
498
+ if (word.length > 3)
499
+ repoNames.add(word);
500
+ for (const tag of (f.tags || []))
501
+ repoNames.add(tag.toLowerCase());
502
+ }
503
+ const stopWords = new Set(["this", "that", "with", "from", "have", "been", "their", "will", "would", "could", "should", "about", "which", "there"]);
504
+ for (const w of stopWords)
505
+ repoNames.delete(w);
506
+ // Split intent words the same way as function names: split on whitespace + camelCase
507
+ const intentWords = userIntent
508
+ .replace(/([A-Z])/g, " $1") // camelCase → "camel Case" (before toLowerCase!)
509
+ .toLowerCase()
510
+ .split(/[\s,,]+/)
511
+ .filter((w) => w.length > 2);
512
+ const repoHits = intentWords.filter((w) => repoNames.has(w)).length;
513
+ const density = intentWords.length > 0 ? repoHits / intentWords.length : 0;
514
+ // 0.20 threshold — lower bound for short intents (3-5 words) still triggers correctly
515
+ if (density > 0.20) {
516
+ graphMode = "on";
517
+ console.error("[AutoRouter] " + Math.round(density * 100) + "% repo terms → Graph ON");
518
+ }
519
+ }
520
+ // ── 抗体免疫系统:查询历史失败模式,注入知识回流 ──
521
+ const antibodies = graphMode !== "off" ? (0, failure_corpus_1.queryAntibodies)(userIntent, "ACL-3") : [];
596
522
  let antibodyHint = "";
597
523
  if (antibodies.length > 0) {
598
524
  const top = antibodies[0];
599
525
  const aclLabel = top.antibodyLevel;
600
526
  console.error(`🛡️ 命中抗体: ${aclLabel} | 模式: ${top.signature} | 相似度: ${top._score.toFixed(2)}`);
601
527
  console.error(` 修复路径: ${top.fixPath.join(" → ")}`);
602
- // ACL-4: 全局稳定抗体 → 直接构建动作序列,跳过 LLM
528
+ // L2: ACL-4 全局稳定抗体 → 快速通道,绕过 LLM
603
529
  if (aclLabel === "ACL-4" && top.fixPath.length > 0) {
604
530
  const antibodyActions = top.fixPath.map((fnName) => {
605
531
  const def = ir.find((f) => f.name === fnName);
@@ -621,7 +547,7 @@ async function plan(userIntent) {
621
547
  similarityScore: top._score,
622
548
  action: "fast_path",
623
549
  llmCallsSaved: 1,
624
- estimatedTokensSaved: Math.ceil((0, llm_1.estimateTokens)(SYSTEM_PROMPT + userIntent) * 1.2),
550
+ estimatedTokensSaved: Math.ceil((0, llm_1.estimateTokens)(planner_prompts_1.SYSTEM_PROMPT + userIntent) * 1.2),
625
551
  };
626
552
  // 验证抗体序列
627
553
  const antibodyRuleHash = (() => {
@@ -633,7 +559,7 @@ async function plan(userIntent) {
633
559
  if (protocols.length > 0) {
634
560
  const validation = validateProtocolWithTransitions(antibodyActions, protocols, namespaceInitialStates);
635
561
  if (validation.valid) {
636
- console.error(`⚡ ACL-4 抗体快速通道: 0 LLM 调用,节省 ~${Math.ceil((0, llm_1.estimateTokens)(SYSTEM_PROMPT + userIntent) * 1.2)} tokens (est.)`);
562
+ console.error(`⚡ ACL-4 抗体快速通道: 0 LLM 调用,节省 ~${Math.ceil((0, llm_1.estimateTokens)(planner_prompts_1.SYSTEM_PROMPT + userIntent) * 1.2)} tokens (est.)`);
637
563
  const antibodyAttempt = {
638
564
  id: (0, runtime_types_1.generateAttemptId)(),
639
565
  sessionId: session.sessionId,
@@ -664,7 +590,7 @@ async function plan(userIntent) {
664
590
  }
665
591
  else {
666
592
  // 无协议规则,直接信任抗体
667
- console.error(`⚡ ACL-4 抗体快速通道: 0 LLM 调用(无协议约束),节省 ~${Math.ceil((0, llm_1.estimateTokens)(SYSTEM_PROMPT + userIntent) * 1.2)} tokens (est.)`);
593
+ console.error(`⚡ ACL-4 抗体快速通道: 0 LLM 调用(无协议约束),节省 ~${Math.ceil((0, llm_1.estimateTokens)(planner_prompts_1.SYSTEM_PROMPT + userIntent) * 1.2)} tokens (est.)`);
668
594
  const antibodyAttempt = {
669
595
  id: (0, runtime_types_1.generateAttemptId)(),
670
596
  sessionId: session.sessionId,
@@ -693,9 +619,24 @@ async function plan(userIntent) {
693
619
  return wrapResult(antibodyActions);
694
620
  }
695
621
  }
696
- // ACL-3: 注入修复路径作为提示约束
697
- antibodyHint = `\n已知正确调用顺序: ${top.fixPath.join(" → ")}。请遵循此顺序。`;
698
- console.error(`💉 ACL-3 抗体注入提示: ${top.fixPath.join(" ")}`);
622
+ // L1: ACL-3 抗体注入提示 — 知识回流到 Planner
623
+ const hints = [];
624
+ for (let i = 0; i < Math.min(antibodies.length, 3); i++) {
625
+ const ab = antibodies[i];
626
+ const level = ab.antibodyLevel;
627
+ const sig = ab.signature;
628
+ const count = ab.occurrenceCount;
629
+ const fix = ab.fixPath.join(" → ");
630
+ // 为每种违规类型生成具体的避错指南
631
+ const avoidance = sig.includes("F07") ? "确保在调用 .map/.filter 前检查对象是否为数组,使用 (obj || [])"
632
+ : sig.includes("SVL-1") ? "只使用可用函数列表中的函数名,禁止编造"
633
+ : sig.includes("SVL-2") ? `检查函数参数类型是否与 IR 签名一致`
634
+ : sig.includes("SVL-4") ? `严格遵循 SSG 协议状态顺序:${fix}`
635
+ : `避免此模式:${sig}`;
636
+ hints.push(`${i + 1}. [${level}] ${sig}(累计 ${count} 次)→ ${avoidance}`);
637
+ }
638
+ antibodyHint = `\n\n⚠️ 免疫系统警告(来自 ${antibodies.length} 条历史抗体记录):\n${hints.join("\n")}\n请避免上述已知错误模式。`;
639
+ console.error(`💉 L1 抗体注入: ${antibodies.length} 条抗体 → ${hints.length} 条注入提示`);
699
640
  }
700
641
  const keywords = (0, utils_1.extractKeywords)(userIntent);
701
642
  const intentLower = userIntent.toLowerCase();
@@ -778,8 +719,9 @@ async function plan(userIntent) {
778
719
  scored.sort((a, b) => b.score - a.score);
779
720
  const topFuncs = scored.slice(0, 15);
780
721
  // Strategy Layer: select capability chain (local, 0 LLM calls)
781
- const chains = (0, strategy_planner_1.selectCapabilityChains)(userIntent, ir, 3);
782
- const strategyHint = (0, strategy_planner_1.formatChainHint)(chains);
722
+ const chainResult = graphMode !== "off" ? (0, strategy_planner_1.selectCapabilityChains)(userIntent, ir, 3, llmSeeds) : { chains: [], needsLLM: false };
723
+ const chains = chainResult.chains;
724
+ const strategyHint = graphMode !== "off" ? (0, strategy_planner_1.formatChainHint)(chains) : "";
783
725
  // Action Layer: filter functions to those in selected chains
784
726
  let chainFuncs = topFuncs;
785
727
  if (chains.length > 0) {
@@ -793,8 +735,10 @@ async function plan(userIntent) {
793
735
  const outChain = topFuncs.filter((f) => !chainNames.has(f.name));
794
736
  chainFuncs = [...inChain, ...outChain].slice(0, 15);
795
737
  }
796
- const compactFuncList = buildCompactFuncList(chainFuncs, ir);
797
- const chainHints = buildChainHints(topFuncs);
738
+ const compactFuncList = (0, planner_prompts_1.buildCompactFuncList)(chainFuncs, ir);
739
+ // Graph recommendations: only inject when explicitly enabled (default: off)
740
+ // Graph validation (SVL, protocol, dataflow) always runs regardless
741
+ const chainHints = graphMode === "on" ? (0, planner_prompts_1.buildChainHints)(topFuncs) : "";
798
742
  // Known string-enum types: tell LLM these are strings, not objects
799
743
  const STRING_ENUMS = {
800
744
  "SVL": '"SVL-1"|"SVL-2"|"SVL-3"|"SVL-4"',
@@ -813,15 +757,15 @@ async function plan(userIntent) {
813
757
  forbiddenFuncs.push(targetName);
814
758
  }
815
759
  }
816
- const protocolChainHint = buildProtocolChainHint(protocols);
760
+ const protocolChainHint = (0, planner_prompts_1.buildProtocolChainHint)(protocols);
817
761
  const userPrompt = `可用函数:
818
762
  ${compactFuncList}${protocolChainHint}${chainHints}${typeHints}${strategyHint}
819
763
 
820
764
  需求:${userIntent}${antibodyHint}
821
765
 
822
- ${RETRY_HINT}
766
+ ${planner_prompts_1.RETRY_HINT}
823
767
  只输出 JSON。`;
824
- const estimatedTokens = (0, llm_1.estimateTokens)(SYSTEM_PROMPT + userPrompt);
768
+ const estimatedTokens = (0, llm_1.estimateTokens)(planner_prompts_1.SYSTEM_PROMPT + userPrompt);
825
769
  console.error(`💰 估算 prompt token: ${estimatedTokens}`);
826
770
  // ── 执行持久化:检查是否有未完成的 checkpoint ──
827
771
  const cp = (0, failure_corpus_1.loadCheckpoint)(userIntent);
@@ -862,14 +806,14 @@ ${RETRY_HINT}
862
806
  });
863
807
  if (legalFuncs.length === topFuncs.length)
864
808
  return compactFuncList;
865
- return buildCompactFuncList(legalFuncs, ir);
809
+ return (0, planner_prompts_1.buildCompactFuncList)(legalFuncs, ir);
866
810
  }
867
811
  const maxRetries = 3;
868
812
  for (let r = startRetry; r < maxRetries; r++) {
869
813
  let text;
870
814
  try {
871
815
  text = useSystem
872
- ? await (0, llm_1.chat)(SYSTEM_PROMPT, currentPrompt)
816
+ ? await (0, llm_1.chat)(planner_prompts_1.SYSTEM_PROMPT, currentPrompt)
873
817
  : await (0, llm_1.generate)(`你是程序合成助手。\n\n${currentPrompt}`);
874
818
  }
875
819
  catch (e) {
@@ -878,7 +822,12 @@ ${RETRY_HINT}
878
822
  if (!text)
879
823
  continue;
880
824
  text = text.replace(/```(?:json|javascript)?\s*/gi, '').replace(/```\s*/g, '').trim();
881
- console.error("📝 LLM 输出:\n", text);
825
+ if ((0, llm_1.isVerbose)()) {
826
+ console.error(`\n📝 [VERBOSE] LLM raw output (attempt ${r + 1}/${maxRetries}):\n${text.slice(0, 3000)}${text.length > 3000 ? `\n... [${text.length - 3000} more chars]` : ""}\n`);
827
+ }
828
+ else {
829
+ console.error("📝 LLM 输出:\n", text);
830
+ }
882
831
  // 优先尝试 JSON 解析,失败则回退到 DSL 执行
883
832
  let rawActions = parseActionJSON(text);
884
833
  if (!rawActions || !Array.isArray(rawActions)) {
@@ -887,7 +836,7 @@ ${RETRY_HINT}
887
836
  }
888
837
  if (!rawActions || !Array.isArray(rawActions) || rawActions.length === 0) {
889
838
  console.error("⚠️ 解析失败,重试...");
890
- currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}\n\n上一次输出无效。请严格输出 JSON 数组。\n${RETRY_HINT}\n只输出 JSON。`;
839
+ currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}${antibodyHint}\n\n上一次输出无效。请严格输出 JSON 数组。\n${planner_prompts_1.RETRY_HINT}\n只输出 JSON。`;
891
840
  useSystem = false;
892
841
  continue;
893
842
  }
@@ -911,7 +860,7 @@ ${RETRY_HINT}
911
860
  const schemaCheck = validateActionSchema(rawActions);
912
861
  if (!schemaCheck.valid) {
913
862
  console.error("⚠️ JSON schema 校验失败:", schemaCheck.errors.join("; "));
914
- currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}\n\n输出格式错误:${schemaCheck.errors.join(";")}。请修正 JSON 结构。\n${RETRY_HINT}\n只输出 JSON。`;
863
+ currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}${antibodyHint}\n\n输出格式错误:${schemaCheck.errors.join(";")}。请修正 JSON 结构。\n${planner_prompts_1.RETRY_HINT}\n只输出 JSON。`;
915
864
  useSystem = false;
916
865
  const schemaViolation = {
917
866
  svl: 1,
@@ -955,11 +904,25 @@ ${RETRY_HINT}
955
904
  const enriched = enrichActions(rawActions, ir);
956
905
  const filtered = enriched.filter(a => !forbiddenFuncs.includes(a.kind === "call" ? a.function : ''));
957
906
  let ssgTransitions = [];
907
+ if ((0, llm_1.isVerbose)()) {
908
+ console.error(`🔬 [VERBOSE] Parsed ${rawActions.length} actions → ${enriched.length} enriched → ${filtered.length} after filtering`);
909
+ for (let ai = 0; ai < filtered.length; ai++) {
910
+ const a = filtered[ai];
911
+ if (a.kind === "call") {
912
+ console.error(` [${ai}] call ${a.function}(${(a.args || []).map((x) => `${x.name}=${JSON.stringify(x.value)}`).join(", ")})`);
913
+ }
914
+ else {
915
+ console.error(` [${ai}] ${a.kind}`);
916
+ }
917
+ }
918
+ }
958
919
  // 0) Hard Constraint Pre-check: local scan before full validation
959
920
  // Saves LLM tokens by detecting obvious violations first
960
921
  const preCheckRules = new Map();
961
922
  for (const p of protocols)
962
923
  preCheckRules.set(p.function, p.protocol);
924
+ // Protocol pre-check: state must accumulate across the sequence
925
+ const preCheckCtx = { ledger: [], currentState: (0, ssg_validator_1.rebuildState)([], namespaceInitialStates) };
963
926
  const preCheckErrors = [];
964
927
  for (let ai = 0; ai < filtered.length; ai++) {
965
928
  const a = filtered[ai];
@@ -973,24 +936,30 @@ ${RETRY_HINT}
973
936
  if (def.params && a.args && a.args.length !== def.params.length) {
974
937
  preCheckErrors.push(`${a.function}: 参数数量错误 (期望${def.params.length}, 实际${a.args.length})`);
975
938
  }
976
- // Protocol pre-check: verify function is callable in current namespace state
939
+ // Protocol pre-check: verify function is callable in ACCUMULATED namespace state
977
940
  if (def.protocol && preCheckRules.size > 0) {
978
- const ctx = { ledger: [], currentState: (0, ssg_validator_1.rebuildState)([], namespaceInitialStates) };
979
- const { valid, rejection } = (0, ssg_validator_1.validateTransition)(ctx, a.function, ai, preCheckRules, namespaceInitialStates);
941
+ const { valid, transition, rejection } = (0, ssg_validator_1.validateTransition)(preCheckCtx, a.function, ai, preCheckRules, namespaceInitialStates);
980
942
  if (!valid && rejection) {
981
943
  preCheckErrors.push(`${a.function}: 协议违规 — 需要先调用 ${rejection.fixPath?.join(" → ") || "?"}`);
982
944
  }
945
+ // Update accumulated state: validateTransition computes statesAfter but doesn't mutate ctx
946
+ if (transition.valid) {
947
+ preCheckCtx.currentState = transition.statesAfter;
948
+ }
983
949
  }
984
950
  }
985
- // P0: Strategy Enforcement LLM must follow recommended chain
951
+ // Strategy hint: warn if LLM missed all recommended nodes, record negative feedback
986
952
  if (chains.length > 0 && chains[0].nodes.length >= 2) {
987
953
  const topChain = chains[0];
988
- const requiredFuncs = topChain.nodes.map(n => n.name);
954
+ const recommendedFuncs = topChain.nodes.map(n => n.name);
989
955
  const chosenFuncs = filtered.filter(a => a.kind === "call").map(a => a.function);
990
- const missing = requiredFuncs.filter(fn => !chosenFuncs.includes(fn));
991
- if (missing.length >= requiredFuncs.length * 0.5) {
992
- // More than 50% of the chain is missing — LLM ignored the strategy
993
- preCheckErrors.push(`策略违规: 推荐链 ${topChain.explanation},但缺少 ${missing.join(", ")}`);
956
+ const hasAny = recommendedFuncs.some(fn => chosenFuncs.includes(fn));
957
+ if (!hasAny && recommendedFuncs.length >= 3) {
958
+ console.error(`⚠️ 策略提示: LLM 未使用推荐链中的任何函数 (推荐: ${topChain.explanation})`);
959
+ // Record negative feedback on recommended edges
960
+ for (let i = 0; i < topChain.nodes.length - 1; i++) {
961
+ (0, failure_corpus_1.recordEdgeRejection)(topChain.nodes[i].name, topChain.nodes[i + 1].name);
962
+ }
994
963
  }
995
964
  }
996
965
  // 1) 基础序列校验
@@ -1038,7 +1007,7 @@ ${RETRY_HINT}
1038
1007
  const specificErrors = preCheckErrors.length > 0
1039
1008
  ? `精确错误:\n${preCheckErrors.map(e => ` - ${e}`).join("\n")}`
1040
1009
  : `错误:${errorsFlat.join(";")}`;
1041
- currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}\n\n${specificErrors}\n请修正上述问题。\n${RETRY_HINT}\n只输出 JSON。`;
1010
+ currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}${antibodyHint}\n\n${specificErrors}\n请修正上述问题。\n${planner_prompts_1.RETRY_HINT}\n只输出 JSON。`;
1042
1011
  useSystem = false;
1043
1012
  (0, failure_corpus_1.saveCheckpoint)(userIntent, { attemptIndex: r + 1, sessionAttempts: session.attempts, currentPrompt, useSystem });
1044
1013
  continue;
@@ -1130,21 +1099,33 @@ ${RETRY_HINT}
1130
1099
  };
1131
1100
  fs.writeFileSync(`${repairDir}/repair_${session.sessionId}.json`, JSON.stringify(repairRecord, null, 2), "utf-8");
1132
1101
  }
1133
- catch { }
1102
+ catch { /* topology rebuild — optional */ }
1134
1103
  finalActions = repaired;
1135
1104
  break;
1136
1105
  }
1137
1106
  const maskedFuncList = getMaskedFuncList();
1138
- currentPrompt = `当前协议状态只允许以下函数:\n${maskedFuncList}${protocolChainHint}\n\n需求:${userIntent}\n\n协议违规:${explain.replace(/\n/g, ';')}。请修正。\n${RETRY_HINT}\n只输出 JSON。`;
1107
+ currentPrompt = `当前协议状态只允许以下函数:\n${maskedFuncList}${protocolChainHint}\n\n需求:${userIntent}${antibodyHint}\n\n协议违规:${explain.replace(/\n/g, ';')}。请修正。\n${planner_prompts_1.RETRY_HINT}\n只输出 JSON。`;
1139
1108
  useSystem = false;
1140
1109
  (0, failure_corpus_1.saveCheckpoint)(userIntent, { attemptIndex: r + 1, sessionAttempts: session.attempts, currentPrompt, useSystem });
1141
1110
  continue;
1142
1111
  }
1143
1112
  // SSG passed — capture transitions
1144
1113
  ssgTransitions = protoResult.transitions;
1114
+ if ((0, llm_1.isVerbose)()) {
1115
+ console.error(`✅ [VERBOSE] Protocol (SSG) validation passed — ${ssgTransitions.length} transitions recorded`);
1116
+ for (const t of ssgTransitions.slice(0, 5)) {
1117
+ const ns = t.namespace || "_global";
1118
+ const before = t.statesBefore?.[ns] || [];
1119
+ const after = t.statesAfter?.[ns] || [];
1120
+ console.error(` ${t.function}: [${before.join(",") || "·"}] → [${after.join(",") || "·"}] (ns=${ns})`);
1121
+ }
1122
+ }
1145
1123
  }
1146
1124
  // 3) 语义合约校验
1147
1125
  const semResult = (0, semantic_validator_1.checkSemantic)(userIntent, filtered);
1126
+ if ((0, llm_1.isVerbose)() && semResult.valid) {
1127
+ console.error(`✅ [VERBOSE] Semantic contract validation passed`);
1128
+ }
1148
1129
  if (!semResult.valid) {
1149
1130
  console.error("⚠️ 语义校验失败:", semResult.errors.join(", "));
1150
1131
  const violation = {
@@ -1181,7 +1162,7 @@ ${RETRY_HINT}
1181
1162
  plannerRetryTotal: maxRetries,
1182
1163
  });
1183
1164
  (0, memory_layer_1.recordEpisode)({ intent: userIntent, actions: filtered, success: false, svlViolated: "SVL-4" });
1184
- currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}\n\n语义错误:${semResult.errors.join(";")}。请修正。\n${RETRY_HINT}\n只输出 JSON。`;
1165
+ currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}${antibodyHint}\n\n语义错误:${semResult.errors.join(";")}。请修正。\n${planner_prompts_1.RETRY_HINT}\n只输出 JSON。`;
1185
1166
  useSystem = false;
1186
1167
  (0, failure_corpus_1.saveCheckpoint)(userIntent, { attemptIndex: r + 1, sessionAttempts: session.attempts, currentPrompt, useSystem });
1187
1168
  continue;
@@ -1200,10 +1181,11 @@ ${RETRY_HINT}
1200
1181
  }
1201
1182
  }
1202
1183
  }
1203
- if (emptyArgs.length > 0 && r < maxRetries - 1) {
1184
+ // Only refine empty args if validation also failed don't break good chains
1185
+ if (emptyArgs.length > 0 && r < maxRetries - 1 && (!seqResult.valid || preCheckErrors.length > 0)) {
1204
1186
  const argDetails = emptyArgs.map(e => ` ${e.fn}() 参数 "${e.param}" (${e.type}) 是空值`).join("\n");
1205
1187
  console.error(`🔍 检测到 ${emptyArgs.length} 个空参数,启动精炼...`);
1206
- currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}\n\n上一次生成的 JSON 中以下参数为空值:\n${argDetails}\n\n请为这些参数填入有意义的示例值(字符串用描述性值,数字用合理数值,对象用 {} as Type)。\n${RETRY_HINT}\n只输出 JSON。`;
1188
+ currentPrompt = `可用函数:\n${compactFuncList}${protocolChainHint}\n\n需求:${userIntent}${antibodyHint}\n\n上一次生成的 JSON 中以下参数为空值:\n${argDetails}\n\n请为这些参数填入有意义的示例值(字符串用描述性值,数字用合理数值,对象用 {} as Type)。\n${planner_prompts_1.RETRY_HINT}\n只输出 JSON。`;
1207
1189
  useSystem = false;
1208
1190
  continue;
1209
1191
  }
@@ -1299,7 +1281,8 @@ ${RETRY_HINT}
1299
1281
  session.endedAt = Date.now();
1300
1282
  (0, failure_corpus_1.recordSession)(session);
1301
1283
  (0, failure_corpus_1.clearCheckpoint)(userIntent);
1302
- return wrapResult(fallback);
1284
+ console.error("[降级] 返回回退结果 — 代码质量可能不高,建议人工审核。");
1285
+ return wrapResult(fallback, undefined, true);
1303
1286
  }
1304
1287
  (0, memory_layer_1.recordEpisode)({ intent: userIntent, actions: [], success: false });
1305
1288
  session.resolved = false;
@@ -1310,7 +1293,8 @@ ${RETRY_HINT}
1310
1293
  }
1311
1294
  return wrapResult(finalActions);
1312
1295
  }
1313
- /** 本地规则回退:当 LLM 不可用时,根据意图关键词生成简单动作序列 */
1296
+ /** 本地规则回退:当 LLM 不可用时,根据意图关键词生成简单动作序列。
1297
+ * 使用实际的默认值(而非占位符),确保生成的代码至少可以编译运行。 */
1314
1298
  function generateFallbackPlan(intent, ir) {
1315
1299
  const intentLower = intent.toLowerCase();
1316
1300
  const actions = [];
@@ -1325,19 +1309,30 @@ function generateFallbackPlan(intent, ir) {
1325
1309
  }
1326
1310
  if (matchedFuncs.length === 0)
1327
1311
  return [];
1312
+ // Sensible default values per type — no placeholder strings
1313
+ function defaultValue(typeName) {
1314
+ const t = (typeName || "string").toLowerCase();
1315
+ if (t === "number")
1316
+ return 0;
1317
+ if (t === "boolean")
1318
+ return false;
1319
+ if (t.includes("[]") || t.includes("array"))
1320
+ return [];
1321
+ return ""; // string default
1322
+ }
1328
1323
  for (const fn of matchedFuncs) {
1329
1324
  const args = (fn.params || []).map((p, i) => ({
1330
1325
  name: p.name || `p${i}`,
1331
- type: p.type || 'any',
1332
- value: `{{${p.name || `p${i}`}}}`
1326
+ type: p.type || "string",
1327
+ value: defaultValue(p.type || "string"),
1333
1328
  }));
1334
- const assignTo = fn.returnType && fn.returnType !== 'void' && fn.returnType !== 'undefined'
1329
+ const assignTo = fn.returnType && fn.returnType !== "void" && fn.returnType !== "undefined"
1335
1330
  ? `${fn.name}_result` : undefined;
1336
1331
  if (assignTo) {
1337
- actions.push({ kind: 'call', function: fn.name, args, assignTo });
1332
+ actions.push({ kind: "call", function: fn.name, args, assignTo });
1338
1333
  }
1339
1334
  else {
1340
- actions.push({ kind: 'call', function: fn.name, args });
1335
+ actions.push({ kind: "call", function: fn.name, args });
1341
1336
  }
1342
1337
  }
1343
1338
  return actions;