progmune-runtime 2.1.6 → 3.2.0
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 +108 -468
- package/dist/ablation-study.js +144 -0
- package/dist/ablation-study.test.js +18 -0
- package/dist/action-runtime.js +3 -1
- package/dist/active-learning.js +211 -0
- package/dist/analytics.js +139 -0
- package/dist/asset-factory.js +309 -0
- package/dist/asset-growth.js +244 -0
- package/dist/asset-promotion.js +382 -0
- package/dist/asset-quality.js +550 -0
- package/dist/audit/business-translator.js +285 -0
- package/dist/audit/cli.js +66 -0
- package/dist/audit/formatters/html.js +379 -0
- package/dist/audit/formatters/json.js +11 -0
- package/dist/audit/formatters/markdown.js +192 -0
- package/dist/audit/formatters/terminal.js +189 -0
- package/dist/audit/index.js +25 -0
- package/dist/audit/report-builder.js +318 -0
- package/dist/audit/types.js +8 -0
- package/dist/audit.js +3 -3
- package/dist/auto-benchmark-generator.js +137 -0
- package/dist/auto-benchmark-generator.test.js +45 -0
- package/dist/auto-protocol-synthesizer.js +362 -0
- package/dist/auto-protocol-synthesizer.test.js +82 -0
- package/dist/autonomous-patch.js +175 -0
- package/dist/autonomous-patch.test.js +128 -0
- package/dist/badge/badge-server.js +98 -0
- package/dist/behavior-miner.js +442 -0
- package/dist/belief-layer.js +475 -0
- package/dist/benchmark-count.js +5 -0
- package/dist/benchmark-generator.js +211 -0
- package/dist/benchmark-harness.js +201 -0
- package/dist/benchmark-pass-rate.js +7 -0
- package/dist/benchmark-report.js +8 -3
- package/dist/benchmark-save.js +14 -1
- package/dist/bootstrap-validation.js +197 -0
- package/dist/bootstrap-validation.test.js +51 -0
- package/dist/branch-ledger.js +1 -1
- package/dist/capability-gap.js +130 -0
- package/dist/certify-html.js +351 -0
- package/dist/certify.js +326 -0
- package/dist/check.js +4 -4
- package/dist/compliance-miner.js +447 -0
- package/dist/continuous-benchmark.js +194 -0
- package/dist/continuous-benchmark.test.js +116 -0
- package/dist/corpus-stats.js +173 -0
- package/dist/counterfactual-engine.js +288 -0
- package/dist/coverage-dashboard.js +109 -0
- package/dist/coverage-system.test.js +205 -0
- package/dist/cross-repo-precision.js +352 -0
- package/dist/cve-benchmark.js +180 -0
- package/dist/cve-benchmark.test.js +28 -0
- package/dist/cve-collector.js +73 -0
- package/dist/data-quality.js +141 -0
- package/dist/decision-engine.js +388 -0
- package/dist/derive-metadata.js +250 -0
- package/dist/difficulty-active.test.js +198 -0
- package/dist/difficulty-map.js +244 -0
- package/dist/discovery-analytics.js +125 -0
- package/dist/discovery-model.js +149 -0
- package/dist/discovery-optimize.test.js +199 -0
- package/dist/discovery-trace.js +276 -0
- package/dist/discovery-trace.test.js +97 -0
- package/dist/emitter.js +83 -1
- package/dist/enterprise-dashboard.js +405 -0
- package/dist/eval-hardening.js +297 -0
- package/dist/eval-hardening.test.js +85 -0
- package/dist/evaluation-campaign.js +359 -0
- package/dist/evaluation-campaign.test.js +181 -0
- package/dist/evidence-growth.js +143 -0
- package/dist/evidence-repository.js +209 -0
- package/dist/evidence-system.js +441 -0
- package/dist/execute.js +15 -7
- package/dist/experimental/software-physics.js +291 -0
- package/dist/experimental/state-inference.js +516 -0
- package/dist/experimental/unsupervised-physics.js +230 -0
- package/dist/extract-ir-python.js +54 -7
- package/dist/extract-ir.js +376 -12
- package/dist/failure-collector.js +2 -2
- package/dist/failure-corpus.js +322 -9
- package/dist/feedback.js +16 -5
- package/dist/feedback.test.js +49 -0
- package/dist/file-lock.js +1 -1
- package/dist/flywheel-batch.js +292 -0
- package/dist/frameworks/express-cli.js +237 -0
- package/dist/frameworks/express-detector.js +445 -0
- package/dist/frameworks/express-detector.test.js +206 -0
- package/dist/frameworks/index.js +30 -0
- package/dist/frameworks/nestjs-detector.js +302 -0
- package/dist/frameworks/trpc-detector.js +161 -0
- package/dist/frameworks/version-awareness.js +179 -0
- package/dist/function-synonyms.js +164 -0
- package/dist/function-synonyms.test.js +68 -0
- package/dist/generalization.test.js +352 -0
- package/dist/goal-annotator.js +113 -0
- package/dist/goal-planner.js +563 -0
- package/dist/gold-cve.js +164 -0
- package/dist/gold-cve.test.js +104 -0
- package/dist/gold-quality.js +206 -0
- package/dist/gold-tiers.js +241 -0
- package/dist/governance-dashboard.js +327 -0
- package/dist/graph-viz.js +240 -0
- package/dist/guided-frontier.js +195 -0
- package/dist/hierarchical-planner.js +148 -0
- package/dist/identifier-parser.js +260 -0
- package/dist/immune-metrics.js +93 -0
- package/dist/immune-receiver.js +158 -0
- package/dist/immune-reporter.js +1 -1
- package/dist/improvement-orchestrator.js +206 -0
- package/dist/inject-p0-vocabulary.js +300 -0
- package/dist/intent-parser.js +218 -0
- package/dist/invariant-algebra.js +476 -0
- package/dist/invariant-calculus.js +533 -0
- package/dist/ir-utils.js +70 -0
- package/dist/ir-utils.test.js +50 -0
- package/dist/knowledge-api.js +312 -0
- package/dist/knowledge-evolution.js +452 -0
- package/dist/knowledge-explorer.js +506 -0
- package/dist/knowledge-flywheel.js +274 -0
- package/dist/knowledge-governance.js +338 -0
- package/dist/knowledge-governance.test.js +150 -0
- package/dist/knowledge-graph.js +181 -0
- package/dist/knowledge-guided-synth.js +246 -0
- package/dist/knowledge-loop.test.js +77 -0
- package/dist/knowledge-object.js +316 -0
- package/dist/knowledge-package.js +98 -0
- package/dist/kpi-dashboard.js +561 -0
- package/dist/l3-cross-function.js +280 -0
- package/dist/learning-ranker.js +148 -0
- package/dist/learning-ranker.test.js +291 -0
- package/dist/ledger/accountability.js +322 -0
- package/dist/ledger/chain-builder.js +185 -0
- package/dist/ledger/cli.js +222 -0
- package/dist/ledger/index.js +13 -0
- package/dist/ledger/signatures.js +193 -0
- package/dist/ledger/types.js +9 -0
- package/dist/llm.js +74 -3
- package/dist/load-benchmarks.js +8 -3
- package/dist/logger.js +66 -0
- package/dist/logger.test.js +37 -0
- package/dist/logistic-reward.js +339 -0
- package/dist/logistic-reward.test.js +180 -0
- package/dist/macro-graph.js +193 -0
- package/dist/macro-repair.js +183 -0
- package/dist/mcp-server.mjs +1202 -483
- package/dist/memory-layer.js +42 -5
- package/dist/multi-repo-precision.js +422 -0
- package/dist/name-free-protocol.js +425 -0
- package/dist/name-free-protocol.test.js +170 -0
- package/dist/name-scrambling.js +138 -0
- package/dist/name-scrambling.test.js +16 -0
- package/dist/p3-observability.test.js +281 -0
- package/dist/p5-orchestrator.test.js +225 -0
- package/dist/pairwise-preference.js +294 -0
- package/dist/pairwise-preference.test.js +140 -0
- package/dist/planner-constraints.js +104 -0
- package/dist/planner-prompts.js +155 -0
- package/dist/planner-telemetry.js +415 -0
- package/dist/planner-trace.js +214 -0
- package/dist/planner.js +162 -167
- package/dist/plsb/artifact.js +116 -0
- package/dist/plsb/cli.js +71 -0
- package/dist/plsb/index.js +19 -0
- package/dist/plsb/leaderboard.js +249 -0
- package/dist/plsb/report-md.js +156 -0
- package/dist/plsb/schema.js +179 -0
- package/dist/plsb-benchmark.js +284 -0
- package/dist/plsb-benchmark.test.js +119 -0
- package/dist/policy/cli.js +134 -0
- package/dist/policy/engine.js +333 -0
- package/dist/policy/index.js +12 -0
- package/dist/policy/types.js +59 -0
- package/dist/policy-miner.js +505 -0
- package/dist/precision-analyze.js +229 -0
- package/dist/precision-benchmark.js +147 -0
- package/dist/precision-label-c.js +134 -0
- package/dist/precision-label.js +193 -0
- package/dist/precision-report-c.js +149 -0
- package/dist/precision-report.js +246 -0
- package/dist/progmune-status.js +108 -0
- package/dist/proof-engine.js +479 -0
- package/dist/proof-provenance.js +315 -0
- package/dist/protocol-coverage.js +294 -0
- package/dist/protocol-detector.js +1189 -0
- package/dist/protocol-embedding-expanded.js +297 -0
- package/dist/protocol-embedding-expanded.test.js +97 -0
- package/dist/protocol-embedding.js +195 -0
- package/dist/protocol-embedding.test.js +82 -0
- package/dist/protocol-extractor-v2.js +354 -0
- package/dist/protocol-extractor-v2.test.js +140 -0
- package/dist/protocol-extractor.js +310 -0
- package/dist/protocol-extractor.test.js +113 -0
- package/dist/protocol-foundation.js +322 -0
- package/dist/protocol-foundation.test.js +163 -0
- package/dist/protocol-frontier.js +243 -0
- package/dist/protocol-frontier.test.js +92 -0
- package/dist/protocol-gap-analyzer.js +228 -0
- package/dist/protocol-gap-analyzer.test.js +49 -0
- package/dist/protocol-invariants.js +276 -0
- package/dist/protocol-invariants.test.js +111 -0
- package/dist/protocol-knowledge.js +464 -0
- package/dist/protocol-miner.js +343 -0
- package/dist/protocol-mining.js +207 -0
- package/dist/protocol-mining.test.js +37 -0
- package/dist/protocol-registry.js +1 -1
- package/dist/protocol-security-benchmark.js +222 -0
- package/dist/protocol-vulnerability.js +257 -0
- package/dist/protocol-vulnerability.test.js +60 -0
- package/dist/python-benchmark.js +120 -0
- package/dist/python-emitter.js +163 -45
- package/dist/python-protocol-extractor.js +187 -0
- package/dist/python-protocol-extractor.test.js +116 -0
- package/dist/realworld-benchmark.js +646 -0
- package/dist/realworld-benchmark.test.js +36 -0
- package/dist/repair-arch.test.js +411 -0
- package/dist/repair-evolution.test.js +454 -0
- package/dist/repair-executor.js +719 -0
- package/dist/repair-proposal.js +4 -4
- package/dist/repair-ranker.js +141 -0
- package/dist/repair-strategies.js +419 -0
- package/dist/repair-taxonomy.js +234 -0
- package/dist/repair-types.js +12 -0
- package/dist/repo-evaluator.js +250 -0
- package/dist/repo-evaluator.test.js +128 -0
- package/dist/resource-abstraction.js +242 -0
- package/dist/resource-detector.js +211 -0
- package/dist/result.test.js +43 -0
- package/dist/reward-system.js +411 -0
- package/dist/reward-system.test.js +175 -0
- package/dist/risk-model.js +215 -0
- package/dist/rule-miner.js +234 -7
- package/dist/rule-specificity.js +254 -0
- package/dist/runtime-types.js +27 -0
- package/dist/scaffold.js +208 -0
- package/dist/scale-collector.test.js +101 -0
- package/dist/scale-trajectory-collector.js +128 -0
- package/dist/sdk.js +250 -0
- package/dist/search-planner.js +4 -41
- package/dist/semantic-snapshot.js +1 -1
- package/dist/semantic-topology.js +121 -0
- package/dist/semantic-trace.js +310 -317
- package/dist/sequence-extractor.js +343 -0
- package/dist/skill-library.js +245 -0
- package/dist/skill-planner.test.js +189 -0
- package/dist/software-physics.js +291 -0
- package/dist/software-physics.test.js +81 -0
- package/dist/ssg-precision.js +478 -0
- package/dist/ssg-validator.js +71 -21
- package/dist/state-inference-doubleblind.test.js +160 -0
- package/dist/state-inference.js +516 -0
- package/dist/state-inference.test.js +115 -0
- package/dist/state-machine-fingerprint.js +345 -0
- package/dist/state-machine-fingerprint.test.js +120 -0
- package/dist/state-miner.js +386 -0
- package/dist/state-name-inference.js +213 -0
- package/dist/state-name-inference.test.js +69 -0
- package/dist/strategy-planner.js +262 -96
- package/dist/strategy-planner.test.js +135 -0
- package/dist/telemetry-analytics.test.js +402 -0
- package/dist/terminal-format.js +68 -0
- package/dist/terminal-format.test.js +83 -0
- package/dist/topology-factory.js +196 -0
- package/dist/topology-representation.js +242 -0
- package/dist/topology-representation.test.js +27 -0
- package/dist/trajectory-augmentation.js +254 -0
- package/dist/trajectory-augmentation.test.js +63 -0
- package/dist/trajectory-corpus.js +440 -0
- package/dist/trajectory-corpus.test.js +32 -0
- package/dist/trajectory-feedback.test.js +116 -0
- package/dist/transition-synthesizer.js +286 -0
- package/dist/transition-synthesizer.test.js +123 -0
- package/dist/trust/api-semantic-mapper.js +809 -0
- package/dist/trust/call-graph-propagator.js +225 -0
- package/dist/trust/cli.js +122 -0
- package/dist/trust/compliance-scorer.js +283 -0
- package/dist/trust/confidence-calculator.js +261 -0
- package/dist/trust/engine.js +1145 -0
- package/dist/trust/explainability.js +85 -0
- package/dist/trust/formatters/ci.js +42 -0
- package/dist/trust/formatters/json.js +11 -0
- package/dist/trust/formatters/terminal.js +152 -0
- package/dist/trust/index.js +39 -0
- package/dist/trust/phase1-verify.js +171 -0
- package/dist/trust/protocol-domain-validator.js +697 -0
- package/dist/trust/score-calculator.js +282 -0
- package/dist/trust/ssg-bridge.js +641 -0
- package/dist/trust/ssg-bridge.test.js +269 -0
- package/dist/trust/types.js +67 -0
- package/dist/trust/violation-trace.js +335 -0
- package/dist/trust-api.js +179 -0
- package/dist/trust-calibration.js +279 -0
- package/dist/unknown-protocol-discovery.js +339 -0
- package/dist/unknown-protocol-discovery.test.js +102 -0
- package/dist/unsupervised-physics.js +230 -0
- package/dist/unsupervised-physics.test.js +95 -0
- package/dist/utils.test.js +37 -0
- package/dist/validator.js +187 -10
- package/dist/verification-intelligence.js +475 -0
- package/dist/verify-api.js +432 -0
- package/dist/vi-impact-report.js +293 -0
- package/dist/wl-fingerprint.js +162 -0
- package/dist/wl-fingerprint.test.js +130 -0
- package/dist/zeroshot-strategy.js +139 -0
- 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
- package/docs/Progmune_/351/241/271/347/233/256/345/205/250/350/247/243.html +710 -0
- package/package.json +74 -7
- package/protocols.json +1956 -50
- package/.dockerignore +0 -14
- package/.mcp.json +0 -11
- package/.progmune_allowlist +0 -50
- package/.test_report/test_report.md +0 -87
- package/Dockerfile +0 -9
- package/FAQ.md +0 -167
- package/WHITEPAPER.md +0 -540
- package/demo-project/auth.ts +0 -55
- package/demo-project/tsconfig.json +0 -8
- package/dist/acl-breakdown.js +0 -13
- package/dist/all-sessions.js +0 -11
- package/dist/antibody-stats.js +0 -11
- package/dist/branch-tree-count.js +0 -14
- package/dist/common-fixpath.js +0 -12
- package/dist/constraint-types.js +0 -12
- package/dist/exec-metrics.js +0 -11
- package/dist/failure-report.js +0 -11
- package/dist/fast-path-hits.js +0 -13
- package/dist/fingerprint-list.js +0 -15
- package/dist/gen-history-log.js +0 -13
- package/dist/heatmap-data.js +0 -11
- package/dist/recent-session.js +0 -12
- package/dist/svl-distribution.js +0 -11
- package/dist/terminal-status.js +0 -11
- package/dist/token-savings.js +0 -11
- package/dist/total-repairs.js +0 -12
- package/dist/unresolved-count.js +0 -12
- package/dist/valid-fingerprints.js +0 -13
- package/dist/verify-ledgers.js +0 -11
- package/docs/whitepaper-style.css +0 -77
- package/docs/whitepaper-v2.1.md +0 -609
- package/docs/whitepaper-v2.2.md +0 -1064
- package/docs/whitepaper-v2.2.pdf +0 -0
- package/fly.toml +0 -31
- package/public/dashboard.html +0 -119
- package/server/hub.js +0 -116
- package/test/replay-golden/sess_1780063202050_mgeld.json +0 -9
- package/test/replay-golden/sess_1780064032560_gocld.json +0 -354
- package/test/replay-golden/sess_1780064413331_s2709.json +0 -606
- package/test/replay-golden/sess_1780064792710_y3avo.json +0 -614
- package/test/replay-golden.ts +0 -84
- package/test_benchmark.js +0 -165
- package/test_comprehensive.mjs +0 -638
- package/test_concurrency.js +0 -129
- package/test_ir_robustness.js +0 -85
- package/test_semantic_contracts.js +0 -269
- package/test_ssg_stress.js +0 -156
- package/test_svl3.js +0 -58
- package/tsconfig.json +0 -17
|
@@ -0,0 +1,240 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* Capability Graph Visualization
|
|
4
|
+
*
|
|
5
|
+
* Renders the capability network as a Mermaid diagram + DOT graph.
|
|
6
|
+
* The graph has become the most valuable engineering asset —
|
|
7
|
+
* this module makes it visible.
|
|
8
|
+
*/
|
|
9
|
+
var __createBinding = (this && this.__createBinding) || (Object.create ? (function(o, m, k, k2) {
|
|
10
|
+
if (k2 === undefined) k2 = k;
|
|
11
|
+
var desc = Object.getOwnPropertyDescriptor(m, k);
|
|
12
|
+
if (!desc || ("get" in desc ? !m.__esModule : desc.writable || desc.configurable)) {
|
|
13
|
+
desc = { enumerable: true, get: function() { return m[k]; } };
|
|
14
|
+
}
|
|
15
|
+
Object.defineProperty(o, k2, desc);
|
|
16
|
+
}) : (function(o, m, k, k2) {
|
|
17
|
+
if (k2 === undefined) k2 = k;
|
|
18
|
+
o[k2] = m[k];
|
|
19
|
+
}));
|
|
20
|
+
var __setModuleDefault = (this && this.__setModuleDefault) || (Object.create ? (function(o, v) {
|
|
21
|
+
Object.defineProperty(o, "default", { enumerable: true, value: v });
|
|
22
|
+
}) : function(o, v) {
|
|
23
|
+
o["default"] = v;
|
|
24
|
+
});
|
|
25
|
+
var __importStar = (this && this.__importStar) || (function () {
|
|
26
|
+
var ownKeys = function(o) {
|
|
27
|
+
ownKeys = Object.getOwnPropertyNames || function (o) {
|
|
28
|
+
var ar = [];
|
|
29
|
+
for (var k in o) if (Object.prototype.hasOwnProperty.call(o, k)) ar[ar.length] = k;
|
|
30
|
+
return ar;
|
|
31
|
+
};
|
|
32
|
+
return ownKeys(o);
|
|
33
|
+
};
|
|
34
|
+
return function (mod) {
|
|
35
|
+
if (mod && mod.__esModule) return mod;
|
|
36
|
+
var result = {};
|
|
37
|
+
if (mod != null) for (var k = ownKeys(mod), i = 0; i < k.length; i++) if (k[i] !== "default") __createBinding(result, mod, k[i]);
|
|
38
|
+
__setModuleDefault(result, mod);
|
|
39
|
+
return result;
|
|
40
|
+
};
|
|
41
|
+
})();
|
|
42
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
43
|
+
exports.generateMermaid = generateMermaid;
|
|
44
|
+
exports.generateDOT = generateDOT;
|
|
45
|
+
exports.generateChainViz = generateChainViz;
|
|
46
|
+
exports.generateGraphReport = generateGraphReport;
|
|
47
|
+
const fs = __importStar(require("fs"));
|
|
48
|
+
const strategy_planner_1 = require("./strategy-planner");
|
|
49
|
+
/**
|
|
50
|
+
* Generate a Mermaid flowchart of the capability graph.
|
|
51
|
+
*/
|
|
52
|
+
function generateMermaid(ir, opts = {}) {
|
|
53
|
+
const maxNodes = opts.maxNodes || 50;
|
|
54
|
+
const showDataFlow = opts.showDataFlow !== false;
|
|
55
|
+
const showTopology = opts.showTopology !== false;
|
|
56
|
+
const minWeight = opts.minEdgeWeight || 0.2;
|
|
57
|
+
const lines = ["```mermaid", "graph LR"];
|
|
58
|
+
// Collect nodes
|
|
59
|
+
const exported = ir.filter((f) => f.exported).slice(0, maxNodes);
|
|
60
|
+
// Node styling by score/domain
|
|
61
|
+
for (const f of exported) {
|
|
62
|
+
const hasProduces = (f.produces || []).length > 0;
|
|
63
|
+
const hasRequires = (f.requires || []).length > 0;
|
|
64
|
+
const hasPurpose = !!f.purpose;
|
|
65
|
+
let style = "";
|
|
66
|
+
if (hasProduces && hasRequires)
|
|
67
|
+
style = "[/";
|
|
68
|
+
else if (hasProduces)
|
|
69
|
+
style = "[(";
|
|
70
|
+
else
|
|
71
|
+
style = "[";
|
|
72
|
+
const endStyle = hasProduces && hasRequires ? "/]" : hasProduces ? ")]" : "]";
|
|
73
|
+
// Tag-based coloring
|
|
74
|
+
const tags = (f.tags || []).join(",");
|
|
75
|
+
const tooltip = (f.purpose || f.name).slice(0, 40).replace(/"/g, "'");
|
|
76
|
+
const nodeId = f.name.replace(/[^a-zA-Z0-9]/g, "_");
|
|
77
|
+
lines.push(` ${nodeId}${style}"${f.name}"${endStyle}`);
|
|
78
|
+
}
|
|
79
|
+
// Data-flow edges
|
|
80
|
+
if (showDataFlow) {
|
|
81
|
+
const nameSet = new Set(exported.map(f => f.name));
|
|
82
|
+
for (const f of exported) {
|
|
83
|
+
if (!f.produces)
|
|
84
|
+
continue;
|
|
85
|
+
for (const p of f.produces) {
|
|
86
|
+
for (const other of exported) {
|
|
87
|
+
if (other.name === f.name)
|
|
88
|
+
continue;
|
|
89
|
+
if ((other.requires || []).includes(p)) {
|
|
90
|
+
lines.push(` ${f.name.replace(/[^a-zA-Z0-9]/g, "_")} -->|"${p}"| ${other.name.replace(/[^a-zA-Z0-9]/g, "_")}`);
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
}
|
|
94
|
+
}
|
|
95
|
+
}
|
|
96
|
+
lines.push("```");
|
|
97
|
+
return lines.join("\n");
|
|
98
|
+
}
|
|
99
|
+
/**
|
|
100
|
+
* Generate a DOT graph for use with Graphviz.
|
|
101
|
+
*/
|
|
102
|
+
function generateDOT(ir, opts = {}) {
|
|
103
|
+
const maxNodes = opts.maxNodes || 100;
|
|
104
|
+
const lines = [
|
|
105
|
+
"digraph CapabilityGraph {",
|
|
106
|
+
' rankdir=LR;',
|
|
107
|
+
' node [shape=box, style=rounded];',
|
|
108
|
+
' edge [fontsize=8];',
|
|
109
|
+
];
|
|
110
|
+
const exported = ir.filter((f) => f.exported).slice(0, maxNodes);
|
|
111
|
+
for (const f of exported) {
|
|
112
|
+
const label = `${f.name}\\n${(f.purpose || "").slice(0, 30)}`;
|
|
113
|
+
const color = (f.produces || []).length > 0 ? "lightblue" : "lightgray";
|
|
114
|
+
lines.push(` "${f.name}" [label="${label}", fillcolor=${color}, style="filled,rounded"];`);
|
|
115
|
+
}
|
|
116
|
+
for (const f of exported) {
|
|
117
|
+
if (!f.produces)
|
|
118
|
+
continue;
|
|
119
|
+
for (const p of f.produces) {
|
|
120
|
+
for (const other of exported) {
|
|
121
|
+
if (other.name === f.name)
|
|
122
|
+
continue;
|
|
123
|
+
if ((other.requires || []).includes(p)) {
|
|
124
|
+
lines.push(` "${f.name}" -> "${other.name}" [label="${p}"];`);
|
|
125
|
+
}
|
|
126
|
+
}
|
|
127
|
+
}
|
|
128
|
+
}
|
|
129
|
+
lines.push("}");
|
|
130
|
+
return lines.join("\n");
|
|
131
|
+
}
|
|
132
|
+
/**
|
|
133
|
+
* Generate a focused visualization of a single intent's chain.
|
|
134
|
+
*/
|
|
135
|
+
function generateChainViz(intent, ir, maxChains = 1) {
|
|
136
|
+
const { chains } = (0, strategy_planner_1.selectCapabilityChains)(intent, ir, maxChains);
|
|
137
|
+
if (chains.length === 0)
|
|
138
|
+
return `// No chains found for "${intent}"`;
|
|
139
|
+
const chain = chains[0];
|
|
140
|
+
const lines = [
|
|
141
|
+
`## Chain: "${intent}" (score: ${chain.score.toFixed(1)})`,
|
|
142
|
+
"",
|
|
143
|
+
"```mermaid",
|
|
144
|
+
"graph LR",
|
|
145
|
+
];
|
|
146
|
+
for (let i = 0; i < chain.nodes.length; i++) {
|
|
147
|
+
const node = chain.nodes[i];
|
|
148
|
+
const nodeId = node.name.replace(/[^a-zA-Z0-9]/g, "_");
|
|
149
|
+
const meta = [
|
|
150
|
+
`★${node.score.toFixed(1)}`,
|
|
151
|
+
...(node.produces || []).slice(0, 2),
|
|
152
|
+
].join("<br/>");
|
|
153
|
+
lines.push(` ${nodeId}["${node.name}<br/><small>${meta}</small>"]`);
|
|
154
|
+
if (i > 0) {
|
|
155
|
+
const prev = chain.nodes[i - 1];
|
|
156
|
+
// Show data-flow if exists
|
|
157
|
+
const flow = (prev.produces || []).filter(p => (node.requires || []).includes(p));
|
|
158
|
+
const label = flow.length > 0 ? flow[0] : "→";
|
|
159
|
+
lines.push(` ${prev.name.replace(/[^a-zA-Z0-9]/g, "_")} -->|"${label}"| ${nodeId}`);
|
|
160
|
+
}
|
|
161
|
+
}
|
|
162
|
+
lines.push("```");
|
|
163
|
+
return lines.join("\n");
|
|
164
|
+
}
|
|
165
|
+
/**
|
|
166
|
+
* Generate a summary report of the capability graph.
|
|
167
|
+
*/
|
|
168
|
+
function generateGraphReport(ir) {
|
|
169
|
+
const fns = ir.length;
|
|
170
|
+
const exported = ir.filter((f) => f.exported).length;
|
|
171
|
+
const withProduces = ir.filter((f) => (f.produces || []).length > 0).length;
|
|
172
|
+
const withRequires = ir.filter((f) => (f.requires || []).length > 0).length;
|
|
173
|
+
const withPurpose = ir.filter((f) => f.purpose).length;
|
|
174
|
+
// Count data-flow edges
|
|
175
|
+
let edges = 0;
|
|
176
|
+
for (const f of ir) {
|
|
177
|
+
if (!f.produces)
|
|
178
|
+
continue;
|
|
179
|
+
for (const p of f.produces) {
|
|
180
|
+
for (const other of ir) {
|
|
181
|
+
if (other.name === f.name)
|
|
182
|
+
continue;
|
|
183
|
+
if ((other.requires || []).includes(p))
|
|
184
|
+
edges++;
|
|
185
|
+
}
|
|
186
|
+
}
|
|
187
|
+
}
|
|
188
|
+
// Top domains by tag
|
|
189
|
+
const tagCounts = new Map();
|
|
190
|
+
for (const f of ir) {
|
|
191
|
+
for (const t of (f.tags || [])) {
|
|
192
|
+
tagCounts.set(t, (tagCounts.get(t) || 0) + 1);
|
|
193
|
+
}
|
|
194
|
+
}
|
|
195
|
+
const topTags = [...tagCounts.entries()]
|
|
196
|
+
.sort((a, b) => b[1] - a[1])
|
|
197
|
+
.slice(0, 10);
|
|
198
|
+
const lines = [
|
|
199
|
+
"# Capability Graph Report",
|
|
200
|
+
"",
|
|
201
|
+
"## Overview",
|
|
202
|
+
`- Total functions: **${fns}**`,
|
|
203
|
+
`- Exported: **${exported}**`,
|
|
204
|
+
`- With produces: **${withProduces}** (${Math.round(withProduces / fns * 100)}%)`,
|
|
205
|
+
`- With requires: **${withRequires}** (${Math.round(withRequires / fns * 100)}%)`,
|
|
206
|
+
`- With purpose: **${withPurpose}** (${Math.round(withPurpose / fns * 100)}%)`,
|
|
207
|
+
`- Data-flow edges: **${edges}**`,
|
|
208
|
+
"",
|
|
209
|
+
"## Top Domains",
|
|
210
|
+
"| Tag | Functions |",
|
|
211
|
+
"|-----|----------|",
|
|
212
|
+
...topTags.map(([tag, count]) => `| ${tag} | ${count} |`),
|
|
213
|
+
"",
|
|
214
|
+
"## Coverage Trend",
|
|
215
|
+
`- v2.1.4: requires ~26%, produces ~26%, purpose ~30%`,
|
|
216
|
+
`- v2.5.x: requires **46%**, produces **62%**, purpose **100%**`,
|
|
217
|
+
`- Target (v2.6): requires **80%+**, produces **80%+**`,
|
|
218
|
+
];
|
|
219
|
+
return lines.join("\n");
|
|
220
|
+
}
|
|
221
|
+
/** CLI: generate report + DOT file */
|
|
222
|
+
if (require.main === module) {
|
|
223
|
+
const ir = JSON.parse(fs.readFileSync("ir.json", "utf-8")).functions || [];
|
|
224
|
+
const report = generateGraphReport(ir);
|
|
225
|
+
console.log(report);
|
|
226
|
+
const dot = generateDOT(ir, { maxNodes: 100 });
|
|
227
|
+
fs.writeFileSync("capability_graph.dot", dot);
|
|
228
|
+
console.log(`\nDOT file written to capability_graph.dot`);
|
|
229
|
+
console.log(`Render: dot -Tpng capability_graph.dot -o capability_graph.png`);
|
|
230
|
+
// Generate sample chain visualizations
|
|
231
|
+
const chains = [
|
|
232
|
+
"generate benchmark report",
|
|
233
|
+
"validate actions and extract IR",
|
|
234
|
+
"list all sessions and find failure patterns",
|
|
235
|
+
];
|
|
236
|
+
for (const intent of chains) {
|
|
237
|
+
const viz = generateChainViz(intent, ir);
|
|
238
|
+
console.log(`\n${viz}`);
|
|
239
|
+
}
|
|
240
|
+
}
|
|
@@ -0,0 +1,195 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P4.5: Reward-Guided Frontier
|
|
4
|
+
*
|
|
5
|
+
* Priority queue BFS that uses learned reward signals to guide search.
|
|
6
|
+
*
|
|
7
|
+
* priority = rewardProbability + bridgeBonus + coverageBonus
|
|
8
|
+
*
|
|
9
|
+
* Where:
|
|
10
|
+
* - rewardProbability: from LogisticRewardModel (how likely is this path to be accepted?)
|
|
11
|
+
* - bridgeBonus: bonus for paths that cross protocol boundaries (diversity)
|
|
12
|
+
* - coverageBonus: bonus for paths that visit rarely-seen states (exploration)
|
|
13
|
+
*
|
|
14
|
+
* Unlike standard BFS (FIFO), this explores promising paths first,
|
|
15
|
+
* increasing the chance of finding high-quality candidates within depth limits.
|
|
16
|
+
*/
|
|
17
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
18
|
+
exports.guidedSearch = guidedSearch;
|
|
19
|
+
exports.guidedSearchMulti = guidedSearchMulti;
|
|
20
|
+
const DEFAULT_GUIDED_CONFIG = {
|
|
21
|
+
rewardWeight: 0.5,
|
|
22
|
+
bridgeWeight: 0.3,
|
|
23
|
+
coverageWeight: 0.2,
|
|
24
|
+
maxPaths: 15,
|
|
25
|
+
maxDepth: 10,
|
|
26
|
+
};
|
|
27
|
+
// ═══════════════════════════════════════════════════════════════
|
|
28
|
+
// Priority Queue
|
|
29
|
+
// ═══════════════════════════════════════════════════════════════
|
|
30
|
+
class PriorityQueue {
|
|
31
|
+
constructor() {
|
|
32
|
+
this.items = [];
|
|
33
|
+
}
|
|
34
|
+
enqueue(item, priority) {
|
|
35
|
+
this.items.push({ item, priority });
|
|
36
|
+
this.items.sort((a, b) => b.priority - a.priority); // descending
|
|
37
|
+
}
|
|
38
|
+
dequeue() {
|
|
39
|
+
return this.items.shift()?.item;
|
|
40
|
+
}
|
|
41
|
+
get length() { return this.items.length; }
|
|
42
|
+
}
|
|
43
|
+
// ═══════════════════════════════════════════════════════════════
|
|
44
|
+
// Reward Estimator
|
|
45
|
+
// ═══════════════════════════════════════════════════════════════
|
|
46
|
+
/** Heuristic reward: shorter paths are safer (proxy for reward probability). */
|
|
47
|
+
function estimateReward(actions) {
|
|
48
|
+
if (actions.length === 0)
|
|
49
|
+
return 0.5;
|
|
50
|
+
const normLength = Math.min(1, actions.length / 10);
|
|
51
|
+
return 1.0 - normLength * 0.5; // 0.5 ~ 1.0
|
|
52
|
+
}
|
|
53
|
+
/** Check if a function name bridges two protocols. */
|
|
54
|
+
function isBridgeAction(fn) {
|
|
55
|
+
// Functions that produce states consumed by other protocols
|
|
56
|
+
const bridges = ["create_session", "logout", "open_file", "close_file", "connect_db", "disconnect_db", "extractIR", "recordSession"];
|
|
57
|
+
return bridges.includes(fn);
|
|
58
|
+
}
|
|
59
|
+
/** Track state visit frequency for coverage bonus. */
|
|
60
|
+
class StateCoverage {
|
|
61
|
+
constructor() {
|
|
62
|
+
this.visits = new Map();
|
|
63
|
+
}
|
|
64
|
+
visit(state) {
|
|
65
|
+
this.visits.set(state, (this.visits.get(state) || 0) + 1);
|
|
66
|
+
}
|
|
67
|
+
bonus(state) {
|
|
68
|
+
const count = this.visits.get(state) || 0;
|
|
69
|
+
// Rarely visited states get higher bonus
|
|
70
|
+
return Math.max(0, 1.0 - count / 5);
|
|
71
|
+
}
|
|
72
|
+
}
|
|
73
|
+
// ═══════════════════════════════════════════════════════════════
|
|
74
|
+
// Guided Frontier Search
|
|
75
|
+
// ═══════════════════════════════════════════════════════════════
|
|
76
|
+
/**
|
|
77
|
+
* Reward-guided frontier search.
|
|
78
|
+
*
|
|
79
|
+
* Uses a priority queue where each partial path is scored by:
|
|
80
|
+
* priority = rewardWeight × rewardProbability
|
|
81
|
+
* + bridgeWeight × bridgeBonus
|
|
82
|
+
* + coverageWeight × coverageBonus
|
|
83
|
+
*
|
|
84
|
+
* This biases exploration toward paths that are:
|
|
85
|
+
* 1. Likely to be accepted (short, safe)
|
|
86
|
+
* 2. Cross protocol boundaries (diverse)
|
|
87
|
+
* 3. Visit rarely-seen states (exploratory)
|
|
88
|
+
*/
|
|
89
|
+
function guidedSearch(rules, currentStates, targetStates, config) {
|
|
90
|
+
const cfg = { ...DEFAULT_GUIDED_CONFIG, ...config };
|
|
91
|
+
const results = [];
|
|
92
|
+
const coverage = new StateCoverage();
|
|
93
|
+
const queue = new PriorityQueue();
|
|
94
|
+
// Enqueue initial state
|
|
95
|
+
const initPriority = cfg.rewardWeight * 0.5 + cfg.bridgeWeight * 0.3 + cfg.coverageWeight * 0.2;
|
|
96
|
+
queue.enqueue({
|
|
97
|
+
states: new Set(currentStates),
|
|
98
|
+
actions: [],
|
|
99
|
+
stateList: [...currentStates],
|
|
100
|
+
depth: 0,
|
|
101
|
+
}, initPriority);
|
|
102
|
+
const visited = new Set();
|
|
103
|
+
visited.add([...currentStates].sort().join(","));
|
|
104
|
+
while (queue.length > 0 && results.length < cfg.maxPaths) {
|
|
105
|
+
const current = queue.dequeue();
|
|
106
|
+
if (!current)
|
|
107
|
+
break;
|
|
108
|
+
if (current.depth >= cfg.maxDepth)
|
|
109
|
+
continue;
|
|
110
|
+
const { states, actions, stateList, depth } = current;
|
|
111
|
+
// Check target reached
|
|
112
|
+
if (targetStates.length > 0 && targetStates.every(t => states.has(t)) && actions.length > 0) {
|
|
113
|
+
results.push({
|
|
114
|
+
actions: [...actions],
|
|
115
|
+
states: [...stateList],
|
|
116
|
+
cost: depth,
|
|
117
|
+
found: true,
|
|
118
|
+
rewardScore: estimateReward(actions),
|
|
119
|
+
priority: 0, // filled below
|
|
120
|
+
});
|
|
121
|
+
continue;
|
|
122
|
+
}
|
|
123
|
+
// Resource cleanup detection
|
|
124
|
+
if (targetStates.length === 0 && actions.length > 0) {
|
|
125
|
+
const hasOpen = states.has("FILE_OPEN") || states.has("DB_CONNECTED");
|
|
126
|
+
if (!hasOpen) {
|
|
127
|
+
results.push({
|
|
128
|
+
actions: [...actions],
|
|
129
|
+
states: [...stateList],
|
|
130
|
+
cost: depth,
|
|
131
|
+
found: true,
|
|
132
|
+
rewardScore: estimateReward(actions),
|
|
133
|
+
priority: 0,
|
|
134
|
+
});
|
|
135
|
+
continue;
|
|
136
|
+
}
|
|
137
|
+
}
|
|
138
|
+
for (const [fn, rule] of rules) {
|
|
139
|
+
const preOk = rule.pre_states.length === 0 || rule.pre_states.every(p => states.has(p));
|
|
140
|
+
if (!preOk)
|
|
141
|
+
continue;
|
|
142
|
+
const nextStates = new Set(states);
|
|
143
|
+
if (rule.invalidate)
|
|
144
|
+
rule.invalidate.forEach(s => { nextStates.delete(s); coverage.visit(s); });
|
|
145
|
+
for (const post of rule.post_states) {
|
|
146
|
+
nextStates.add(post);
|
|
147
|
+
coverage.visit(post);
|
|
148
|
+
}
|
|
149
|
+
const nextKey = [...nextStates].sort().join(",");
|
|
150
|
+
if (visited.has(nextKey))
|
|
151
|
+
continue;
|
|
152
|
+
visited.add(nextKey);
|
|
153
|
+
const newActions = [...actions, fn];
|
|
154
|
+
// Compute priority
|
|
155
|
+
const rewardProb = estimateReward(newActions);
|
|
156
|
+
const bridgeBonus = isBridgeAction(fn) ? 0.3 : 0;
|
|
157
|
+
const covBonus = [...nextStates].reduce((s, st) => s + coverage.bonus(st), 0) / Math.max(1, nextStates.size);
|
|
158
|
+
const priority = cfg.rewardWeight * rewardProb +
|
|
159
|
+
cfg.bridgeWeight * bridgeBonus +
|
|
160
|
+
cfg.coverageWeight * covBonus;
|
|
161
|
+
queue.enqueue({
|
|
162
|
+
states: nextStates,
|
|
163
|
+
actions: newActions,
|
|
164
|
+
stateList: [...stateList, ...rule.post_states],
|
|
165
|
+
depth: depth + 1,
|
|
166
|
+
}, priority);
|
|
167
|
+
}
|
|
168
|
+
}
|
|
169
|
+
// Fill priority scores
|
|
170
|
+
for (const r of results) {
|
|
171
|
+
r.priority = cfg.rewardWeight * r.rewardScore;
|
|
172
|
+
}
|
|
173
|
+
return results.sort((a, b) => b.priority - a.priority);
|
|
174
|
+
}
|
|
175
|
+
/**
|
|
176
|
+
* Multi-start guided search: try multiple initial states.
|
|
177
|
+
*/
|
|
178
|
+
function guidedSearchMulti(rules, currentStatesCandidates, targetStates, config) {
|
|
179
|
+
const allResults = [];
|
|
180
|
+
for (const startStates of currentStatesCandidates) {
|
|
181
|
+
const paths = guidedSearch(rules, startStates, targetStates, config);
|
|
182
|
+
allResults.push(...paths);
|
|
183
|
+
}
|
|
184
|
+
// Deduplicate and sort by priority
|
|
185
|
+
const seen = new Set();
|
|
186
|
+
const unique = [];
|
|
187
|
+
for (const p of allResults) {
|
|
188
|
+
const key = p.actions.join("→");
|
|
189
|
+
if (seen.has(key))
|
|
190
|
+
continue;
|
|
191
|
+
seen.add(key);
|
|
192
|
+
unique.push(p);
|
|
193
|
+
}
|
|
194
|
+
return unique.sort((a, b) => b.priority - a.priority);
|
|
195
|
+
}
|
|
@@ -0,0 +1,148 @@
|
|
|
1
|
+
"use strict";
|
|
2
|
+
/**
|
|
3
|
+
* P5.2: Hierarchical Planner
|
|
4
|
+
*
|
|
5
|
+
* Three-level search: Goal → Skill → Action
|
|
6
|
+
*
|
|
7
|
+
* Uses SkillLibrary to lift planning from the action space into
|
|
8
|
+
* the skill space, reducing search depth by an order of magnitude.
|
|
9
|
+
*
|
|
10
|
+
* When a Goal matches a known Skill chain, the planner expands
|
|
11
|
+
* the skill into its action sequence directly — no BFS needed.
|
|
12
|
+
*
|
|
13
|
+
* When no skills match, falls back to action-level Frontier BFS.
|
|
14
|
+
*
|
|
15
|
+
* DiscoveryModel guides the search toward discoverable paths,
|
|
16
|
+
* prioritizing skill chains that are most likely to yield candidates.
|
|
17
|
+
*/
|
|
18
|
+
Object.defineProperty(exports, "__esModule", { value: true });
|
|
19
|
+
exports.HierarchicalPlanner = void 0;
|
|
20
|
+
exports.createHierarchicalPlanner = createHierarchicalPlanner;
|
|
21
|
+
const skill_library_1 = require("./skill-library");
|
|
22
|
+
const guided_frontier_1 = require("./guided-frontier");
|
|
23
|
+
// ═══════════════════════════════════════════════════════════════
|
|
24
|
+
// Hierarchical Planner
|
|
25
|
+
// ═══════════════════════════════════════════════════════════════
|
|
26
|
+
class HierarchicalPlanner {
|
|
27
|
+
constructor(library, rules, discoveryModel) {
|
|
28
|
+
this.library = library;
|
|
29
|
+
this.rules = rules;
|
|
30
|
+
this.discoveryModel = discoveryModel;
|
|
31
|
+
}
|
|
32
|
+
/**
|
|
33
|
+
* Plan a repair using Goal → Skill → Action hierarchy.
|
|
34
|
+
*
|
|
35
|
+
* 1. Check if any single skill directly satisfies the goal
|
|
36
|
+
* 2. If not, try composing multiple skills into a chain
|
|
37
|
+
* 3. If no skill chain works, fall back to action-level Frontier BFS
|
|
38
|
+
*
|
|
39
|
+
* @param goal Natural language goal (for discovery scoring)
|
|
40
|
+
* @param currentStates Current protocol states
|
|
41
|
+
* @param targetStates Desired protocol states
|
|
42
|
+
* @param violationType Type of violation
|
|
43
|
+
* @param maxCandidates Max number of candidates to return
|
|
44
|
+
*/
|
|
45
|
+
plan(goal, currentStates, targetStates, violationType, maxCandidates = 10) {
|
|
46
|
+
const candidates = [];
|
|
47
|
+
// ── Level 1: Direct skill match ──
|
|
48
|
+
const applicable = this.library.findApplicable(currentStates);
|
|
49
|
+
for (const skill of applicable) {
|
|
50
|
+
// Does this skill's effects satisfy the target?
|
|
51
|
+
const effectsMatch = targetStates.length === 0 || targetStates.every(t => skill.effects.includes(t));
|
|
52
|
+
// Or does the skill produce a cleanup effect?
|
|
53
|
+
const cleanupMatch = targetStates.length === 0 && skill.effects.length > 0;
|
|
54
|
+
if (effectsMatch || cleanupMatch) {
|
|
55
|
+
const score = this.scoreSkill(skill, goal, violationType);
|
|
56
|
+
candidates.push({
|
|
57
|
+
actions: skill.macro,
|
|
58
|
+
skillChain: [skill.id],
|
|
59
|
+
source: "skill",
|
|
60
|
+
score,
|
|
61
|
+
});
|
|
62
|
+
}
|
|
63
|
+
}
|
|
64
|
+
// ── Level 2: Composed skill chain ──
|
|
65
|
+
if (targetStates.length > 0) {
|
|
66
|
+
const chains = this.library.compose(currentStates, targetStates, 4);
|
|
67
|
+
for (const chain of chains) {
|
|
68
|
+
const actions = this.library.expand(chain);
|
|
69
|
+
const avgScore = chain.reduce((s, sk) => s + this.scoreSkill(sk, goal, violationType), 0) / chain.length;
|
|
70
|
+
candidates.push({
|
|
71
|
+
actions,
|
|
72
|
+
skillChain: chain.map(s => s.id),
|
|
73
|
+
source: "skill-compose",
|
|
74
|
+
score: avgScore,
|
|
75
|
+
});
|
|
76
|
+
}
|
|
77
|
+
}
|
|
78
|
+
// ── Level 3: Action-level Frontier BFS (fallback) ──
|
|
79
|
+
const frontierPaths = (0, guided_frontier_1.guidedSearch)(this.rules, currentStates, targetStates);
|
|
80
|
+
for (const path of frontierPaths.slice(0, maxCandidates)) {
|
|
81
|
+
// Skip if this path is already covered by a skill
|
|
82
|
+
const alreadyCovered = candidates.some(c => c.actions.length === path.actions.length &&
|
|
83
|
+
c.actions.every((a, i) => a === path.actions[i]));
|
|
84
|
+
if (!alreadyCovered) {
|
|
85
|
+
candidates.push({
|
|
86
|
+
actions: path.actions,
|
|
87
|
+
skillChain: [],
|
|
88
|
+
source: "frontier",
|
|
89
|
+
score: path.priority || 0.5,
|
|
90
|
+
});
|
|
91
|
+
}
|
|
92
|
+
}
|
|
93
|
+
// Sort by score descending, deduplicate, return top K
|
|
94
|
+
const seen = new Set();
|
|
95
|
+
const unique = [];
|
|
96
|
+
for (const c of candidates.sort((a, b) => b.score - a.score)) {
|
|
97
|
+
const key = c.actions.join("→");
|
|
98
|
+
if (seen.has(key))
|
|
99
|
+
continue;
|
|
100
|
+
seen.add(key);
|
|
101
|
+
unique.push(c);
|
|
102
|
+
}
|
|
103
|
+
return unique.slice(0, maxCandidates);
|
|
104
|
+
}
|
|
105
|
+
/**
|
|
106
|
+
* Score a skill using discovery model + acceptance rate.
|
|
107
|
+
*
|
|
108
|
+
* score = discoveryProb × 0.5 + acceptanceRate × 0.3 + matchBonus × 0.2
|
|
109
|
+
*/
|
|
110
|
+
scoreSkill(skill, goal, violationType) {
|
|
111
|
+
let discoveryProb = 0.5;
|
|
112
|
+
if (this.discoveryModel) {
|
|
113
|
+
discoveryProb = this.discoveryModel.predict({
|
|
114
|
+
protocol: skill.protocol,
|
|
115
|
+
violationType,
|
|
116
|
+
isResourceLeak: violationType === "resource_leak" ? 1 : 0,
|
|
117
|
+
isMissingPrereq: violationType === "missing_prerequisite" ? 1 : 0,
|
|
118
|
+
isIllegalState: violationType === "illegal_state_transition" ? 1 : 0,
|
|
119
|
+
currentStateCount: skill.preconditions.length,
|
|
120
|
+
});
|
|
121
|
+
}
|
|
122
|
+
const matchBonus = skill.goal.toLowerCase().includes(goal.toLowerCase().slice(0, 10)) ? 1.0 : 0.5;
|
|
123
|
+
return discoveryProb * 0.5 + skill.acceptanceRate * 0.3 + matchBonus * 0.2;
|
|
124
|
+
}
|
|
125
|
+
/**
|
|
126
|
+
* Quick plan: return only skill-based candidates (no BFS fallback).
|
|
127
|
+
* Fast path for common repairs.
|
|
128
|
+
*/
|
|
129
|
+
quickPlan(goal, currentStates) {
|
|
130
|
+
const applicable = this.library.findApplicable(currentStates);
|
|
131
|
+
return applicable.map(skill => ({
|
|
132
|
+
actions: skill.macro,
|
|
133
|
+
skillChain: [skill.id],
|
|
134
|
+
source: "skill",
|
|
135
|
+
score: skill.acceptanceRate,
|
|
136
|
+
})).sort((a, b) => b.score - a.score);
|
|
137
|
+
}
|
|
138
|
+
}
|
|
139
|
+
exports.HierarchicalPlanner = HierarchicalPlanner;
|
|
140
|
+
// ═══════════════════════════════════════════════════════════════
|
|
141
|
+
// Convenience factory
|
|
142
|
+
// ═══════════════════════════════════════════════════════════════
|
|
143
|
+
function createHierarchicalPlanner(telemetry, // PlannerTelemetry
|
|
144
|
+
rules, discoveryModel) {
|
|
145
|
+
const library = new skill_library_1.SkillLibrary();
|
|
146
|
+
library.learn(telemetry, rules);
|
|
147
|
+
return new HierarchicalPlanner(library, rules, discoveryModel);
|
|
148
|
+
}
|