@goodandready/dsh-moa 0.2.78 → 0.2.80
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 +2 -0
- package/README.ru.md +2 -0
- package/README.zh.md +2 -0
- package/lib/client.js +204 -3
- package/lib/events.js +4 -0
- package/lib/moa-schema.js +22 -0
- package/lib/pipeline/budget-guard.js +158 -0
- package/lib/pipeline/embedding-clustering.js +456 -0
- package/lib/pipeline/pareto-frontier.js +167 -0
- package/lib/pipeline/rebuttal-debate.js +335 -0
- package/lib/pipeline/runner.js +90 -5
- package/lib/pricing.js +8 -3
- package/package.json +1 -1
package/README.md
CHANGED
|
@@ -58,6 +58,8 @@ Single-model AI generation often suffers from blind spots, single-perspective bi
|
|
|
58
58
|
15. **Mutation Testing Gate for Candidate Tests (#316)**: Injects AST-level fault mutations to compute Mutation Score (killed vs survived mutants), weeding out tautological assertions and fake test suites.
|
|
59
59
|
16. **Hybrid Private Edge MoA & Cloud Judge Sanitizer (#306)**: Preserves confidentiality with local edge proposers on MiniPC while scrubbing absolute paths, internal IPs, and API secrets before external Cloud Judge arbitration.
|
|
60
60
|
17. **Heterogeneous Speculative Decoding (#317)**: High-throughput local edge draft coupled with single-pass cloud model verification, slashing response latency by 2-3x.
|
|
61
|
+
18. **Cost/Quality Pareto Frontier Slider (#307)**: Interactive trade-off slider mapping cost vs quality along the Pareto Frontier with real-time turn cost & latency estimation.
|
|
62
|
+
19. **Hard Token Budget Guard (#319)**: Pre-flight financial cost ceiling with dynamic auto-scaling of cloud models to local edge to guarantee turn budgets.
|
|
61
63
|
|
|
62
64
|
---
|
|
63
65
|
|
package/README.ru.md
CHANGED
|
@@ -58,6 +58,8 @@
|
|
|
58
58
|
15. **Мутационное тестирование тестов кандидатов (#316)**: Внедрение AST-мутаций кода для расчёта Mutation Score (убитые vs выжившие мутанты), устраняющее ложноположительные и тавтологические тесты.
|
|
59
59
|
16. **Гибридный приватный Edge MoA (#306)**: Локальные генераторы на MiniPC сохраняют секреты и кодовую базу в контуре, маскируя пути, IP и токены перед отправкой судье в облако.
|
|
60
60
|
17. **Гетерогенное спекулятивное декодирование (#317)**: Быстрый черновик от локальной edge-модели с пакетной валидацией и доработкой флагманом в облаке с ускорением в 2-3 раза.
|
|
61
|
+
18. **Слайдер фронтира Парето (Стоимость vs Качество) (#307)**: Интерактивный регулятор баланса затрат и качества консенсуса с реактивным прогнозом цены и задержки.
|
|
62
|
+
19. **Защитный барьер бюджета токенов (#319)**: Строгий финансовый лимит стоимости сессии с динамическим авто-масштабированием и заменой облачных слотов на локальные.
|
|
61
63
|
|
|
62
64
|
---
|
|
63
65
|
|
package/README.zh.md
CHANGED
|
@@ -58,6 +58,8 @@
|
|
|
58
58
|
15. **候选测试套件变异测试关卡 (#316)**:注入 AST 级别故障变异以计算变异得分(消灭 vs 存活变异体),剔除恒真废测试与虚假测试套件。
|
|
59
59
|
16. **混合隐私边缘 MoA 与云端裁判脱敏 (#306)**:本地 MiniPC 边缘模型在内网读取代码生成方案,在提交给外部云端裁判前自动脱敏绝对路径、内网 IP 与 API 密钥。
|
|
60
60
|
17. **异构投机解码加速 (#317)**:本地小模型快速生成投机代码草稿块,云端旗舰模型单次批处理验证与完善,首包延迟降低 2-3 倍。
|
|
61
|
+
18. **成本与质量帕累托前沿滑块 (#307)**:互动式调节成本、质量与延迟的帕累托平衡,实时预估单轮开销与耗时。
|
|
62
|
+
19. **刚性 Token 预算保护与动态缩放 (#319)**:发送前严守费用上限,超出时自动将昂贵云端模型降级为本地边缘模型以确保不超支。
|
|
61
63
|
|
|
62
64
|
---
|
|
63
65
|
|
package/lib/client.js
CHANGED
|
@@ -240,7 +240,23 @@ window.__ModuleLoader__.load({
|
|
|
240
240
|
"aggregator.privacy_gate_title": "\u{1F6E1}\uFE0F Hybrid Private Edge MoA (Local Edge Proposers + Cloud Judge)",
|
|
241
241
|
"aggregator.privacy_gate_desc": "Scans and redacts proprietary secrets, local paths, and private network IPs before forwarding proposals to external cloud judges.",
|
|
242
242
|
"aggregator.speculative_gate_title": "\u26A1 Heterogeneous Speculative Decoding (Local Draft + Cloud Verifier)",
|
|
243
|
-
"aggregator.speculative_gate_desc": "Lightweight local edge model generates high-speed token drafts verified and completed in one fast pass by the cloud model."
|
|
243
|
+
"aggregator.speculative_gate_desc": "Lightweight local edge model generates high-speed token drafts verified and completed in one fast pass by the cloud model.",
|
|
244
|
+
"aggregator.pareto_slider_title": "\u{1F4C8} Cost vs Quality Pareto Frontier Slider",
|
|
245
|
+
"aggregator.pareto_slider_desc": "Reactive balance from 100% free local edge models to ultra-rigorous flagship multi-judge consensus.",
|
|
246
|
+
"aggregator.pareto_pos_label": "Frontier Position:",
|
|
247
|
+
"aggregator.hard_budget_title": "\u{1F6E1}\uFE0F Hard Token Budget Guard with Auto-Scaling",
|
|
248
|
+
"aggregator.hard_budget_desc": "Pre-calculates turn costs against a hard financial ceiling, automatically scaling down or halting execution.",
|
|
249
|
+
"aggregator.hard_budget_limit_label": "Max Cost Per Turn (USD):",
|
|
250
|
+
"aggregator.hard_budget_policy_label": "Exceed Policy:",
|
|
251
|
+
"aggregator.hard_budget_policy_downgrade": "Auto-Downgrade to Local/Economic",
|
|
252
|
+
"aggregator.hard_budget_policy_fail": "Fail-Closed (Halt Execution)",
|
|
253
|
+
"aggregator.rebuttal_debate_title": "\u{1F5E3}\uFE0F Multi-Round Rebuttal Debate",
|
|
254
|
+
"aggregator.rebuttal_debate_desc": "Candidates cross-examine peer solutions and expose flaws before judge arbitration.",
|
|
255
|
+
"aggregator.rebuttal_rounds_label": "Debate Rounds:",
|
|
256
|
+
"aggregator.embedding_clustering_title": "\u{1F9ED} Blind Embedding Clustering",
|
|
257
|
+
"aggregator.embedding_clustering_desc": "Bypass LLM Judge when candidate embeddings converge into a dominant cluster (>= threshold).",
|
|
258
|
+
"aggregator.embedding_threshold_label": "Consensus Similarity Threshold:",
|
|
259
|
+
"aggregator.fallback_to_judge_label": "Fallback to Judge if Opinion Splits"
|
|
244
260
|
};
|
|
245
261
|
const zh = {
|
|
246
262
|
title: "\u667A\u80FD\u4F53\u6DF7\u5408 (MoA)",
|
|
@@ -471,7 +487,23 @@ window.__ModuleLoader__.load({
|
|
|
471
487
|
"aggregator.privacy_gate_title": "\u{1F6E1}\uFE0F \u6DF7\u5408\u9690\u79C1\u8FB9\u7F18 MoA (\u672C\u5730\u751F\u6210 + \u4E91\u7AEF\u88C1\u5224)",
|
|
472
488
|
"aggregator.privacy_gate_desc": "\u5728\u5C06\u5019\u9009\u63D0\u6848\u53D1\u9001\u7ED9\u5916\u90E8\u4E91\u7AEF\u88C1\u5224\u4E4B\u524D\uFF0C\u626B\u63CF\u5E76\u8131\u654F\u4E13\u6709\u5BC6\u94A5\u3001\u672C\u5730\u7EDD\u5BF9\u8DEF\u5F84\u4E0E\u79C1\u6709\u7F51\u7EDC IP\u3002",
|
|
473
489
|
"aggregator.speculative_gate_title": "\u26A1 \u5F02\u6784\u6295\u673A\u89E3\u7801 (\u672C\u5730\u8349\u7A3F + \u4E91\u7AEF\u9A8C\u8BC1)",
|
|
474
|
-
"aggregator.speculative_gate_desc": "\u8F7B\u91CF\u7EA7\u672C\u5730\u8FB9\u7F18\u6A21\u578B\u751F\u6210\u9AD8\u901F\u8349\u7A3F\uFF0C\u7531\u5F3A\u5927\u7684\u4E91\u7AEF\u6A21\u578B\u4E00\u6B21\u6027\u5FEB\u901F\u9A8C\u8BC1\u5E76\u5B8C\u5584\u3002"
|
|
490
|
+
"aggregator.speculative_gate_desc": "\u8F7B\u91CF\u7EA7\u672C\u5730\u8FB9\u7F18\u6A21\u578B\u751F\u6210\u9AD8\u901F\u8349\u7A3F\uFF0C\u7531\u5F3A\u5927\u7684\u4E91\u7AEF\u6A21\u578B\u4E00\u6B21\u6027\u5FEB\u901F\u9A8C\u8BC1\u5E76\u5B8C\u5584\u3002",
|
|
491
|
+
"aggregator.pareto_slider_title": "\u{1F4C8} \u6210\u672C\u4E0E\u8D28\u91CF\u5E15\u7D2F\u6258\u524D\u6CBF\u6ED1\u5757 (Pareto Frontier)",
|
|
492
|
+
"aggregator.pareto_slider_desc": "\u4ECE 100% \u514D\u8D39\u672C\u5730\u8FB9\u7F18\u6A21\u578B\u5230\u8D85\u4E25\u8C28\u65D7\u8230\u591A\u88C1\u5224\u5171\u8BC6\u7684\u54CD\u5E94\u5F0F\u5E73\u8861\u8C03\u8282\u3002",
|
|
493
|
+
"aggregator.pareto_pos_label": "\u524D\u6CBF\u5E73\u8861\u4F4D\u7F6E:",
|
|
494
|
+
"aggregator.hard_budget_title": "\u{1F6E1}\uFE0F \u521A\u6027 Token \u9884\u7B97\u4FDD\u62A4\u4E0E\u52A8\u6001\u964D\u7EA7\u7F29\u653E",
|
|
495
|
+
"aggregator.hard_budget_desc": "\u5728\u53D1\u9001\u524D\u4E25\u683C\u6838\u7B97\u6574\u8F6E\u9884\u6D4B\u8D39\u7528\uFF0C\u81EA\u52A8\u964D\u7EA7\u81F3\u7ECF\u6D4E/\u672C\u5730\u6A21\u578B\u6216\u963B\u6B62\u8D85\u51FA\u9884\u7B97\u3002",
|
|
496
|
+
"aggregator.hard_budget_limit_label": "\u5355\u8F6E\u9884\u7B97\u4E0A\u9650 (USD):",
|
|
497
|
+
"aggregator.hard_budget_policy_label": "\u8D85\u989D\u7B56\u7565:",
|
|
498
|
+
"aggregator.hard_budget_policy_downgrade": "\u81EA\u52A8\u964D\u7EA7\u81F3\u672C\u5730/\u7ECF\u6D4E\u6A21\u578B",
|
|
499
|
+
"aggregator.hard_budget_policy_fail": "\u5B89\u5168\u7194\u65AD (\u505C\u6B62\u6267\u884C)",
|
|
500
|
+
"aggregator.rebuttal_debate_title": "\u{1F5E3}\uFE0F \u591A\u8F6E\u53CD\u9A73\u8FA9\u8BBA\u673A\u5236",
|
|
501
|
+
"aggregator.rebuttal_debate_desc": "\u5019\u9009\u6A21\u578B\u5728\u88C1\u5224\u4EF2\u88C1\u524D\u76F8\u4E92\u4EA4\u53C9\u5BA1\u67E5\u5E76\u6307\u51FA\u5BF9\u65B9\u6F0F\u6D1E\u4E0E\u7F3A\u9677\u3002",
|
|
502
|
+
"aggregator.rebuttal_rounds_label": "\u8FA9\u8BBA\u8F6E\u6570:",
|
|
503
|
+
"aggregator.embedding_clustering_title": "\u{1F9ED} \u76F2\u5411\u91CF\u5D4C\u5165\u805A\u7C7B",
|
|
504
|
+
"aggregator.embedding_clustering_desc": "\u5F53\u5019\u9009\u65B9\u6848\u7684\u5411\u91CF\u5D4C\u5165\u9AD8\u5EA6\u6536\u655B\u5E76\u5F62\u6210\u4E3B\u5BFC\u805A\u7C7B\u65F6\uFF0C\u7ED5\u8FC7LLM\u88C1\u5224\u76F4\u63A5\u4EA7\u51FA\u8D28\u5FC3\u5019\u9009\u3002",
|
|
505
|
+
"aggregator.embedding_threshold_label": "\u5171\u8BC6\u76F8\u4F3C\u5EA6\u9608\u503C:",
|
|
506
|
+
"aggregator.fallback_to_judge_label": "\u610F\u89C1\u5206\u6B67\u65F6\u56DE\u9000\u81F3\u88C1\u5224"
|
|
475
507
|
};
|
|
476
508
|
function makeT(dict, fallback) {
|
|
477
509
|
return function t(key, vars) {
|
|
@@ -2386,7 +2418,6 @@ window.__ModuleLoader__.load({
|
|
|
2386
2418
|
)
|
|
2387
2419
|
)
|
|
2388
2420
|
),
|
|
2389
|
-
// --- src/client/86-card-aggregator-ext2.js ---
|
|
2390
2421
|
/* Pre-Judge Local Syntax Gate (#303) & Early Semantic Consensus (#299) */
|
|
2391
2422
|
React.createElement(
|
|
2392
2423
|
"div",
|
|
@@ -2424,6 +2455,86 @@ window.__ModuleLoader__.load({
|
|
|
2424
2455
|
t("aggregator.early_consensus_desc") || "Bypass the expensive judge round when reference models converge on equivalent code solutions."
|
|
2425
2456
|
)
|
|
2426
2457
|
),
|
|
2458
|
+
/* Multi-Round Rebuttal Debate (#298) & Blind Embedding Clustering (#312) */
|
|
2459
|
+
React.createElement(
|
|
2460
|
+
"div",
|
|
2461
|
+
{ style: { display: "flex", flexDirection: "column", gap: 6, padding: "8px 12px", background: "var(--dsw-alias-bg-layer-2)", borderRadius: 8, border: "1px solid var(--dsw-alias-border-l2)", marginTop: 8 } },
|
|
2462
|
+
React.createElement(
|
|
2463
|
+
"label",
|
|
2464
|
+
{ style: { display: "flex", alignItems: "center", gap: 8, cursor: "pointer", fontSize: 13, fontWeight: 500 } },
|
|
2465
|
+
React.createElement("input", {
|
|
2466
|
+
type: "checkbox",
|
|
2467
|
+
checked: Boolean(currentPreset.rebuttal_debate_enabled),
|
|
2468
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, rebuttal_debate_enabled: e.target.checked })),
|
|
2469
|
+
style: { accentColor: "var(--dsw-alias-state-brand-primary, var(--dsw-alias-label-primary))", cursor: "pointer" }
|
|
2470
|
+
}),
|
|
2471
|
+
t("aggregator.rebuttal_debate_title") || "\u{1F5E3}\uFE0F Multi-Round Rebuttal Debate"
|
|
2472
|
+
),
|
|
2473
|
+
React.createElement(
|
|
2474
|
+
"div",
|
|
2475
|
+
{ style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)", marginLeft: 22 } },
|
|
2476
|
+
t("aggregator.rebuttal_debate_desc") || "Candidates cross-examine peer solutions and expose flaws before judge arbitration."
|
|
2477
|
+
),
|
|
2478
|
+
Boolean(currentPreset.rebuttal_debate_enabled) && React.createElement(
|
|
2479
|
+
"div",
|
|
2480
|
+
{ style: { display: "flex", alignItems: "center", gap: 8, marginLeft: 22, marginTop: 4 } },
|
|
2481
|
+
React.createElement("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, t("aggregator.rebuttal_rounds_label") || "Debate Rounds:"),
|
|
2482
|
+
React.createElement("input", {
|
|
2483
|
+
type: "number",
|
|
2484
|
+
min: 1,
|
|
2485
|
+
max: 3,
|
|
2486
|
+
value: currentPreset.rebuttal_rounds || 1,
|
|
2487
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, rebuttal_rounds: Math.min(3, Math.max(1, Number(e.target.value) || 1)) })),
|
|
2488
|
+
style: { width: 50, padding: "2px 6px", fontSize: 12, borderRadius: 4, border: "1px solid var(--dsw-alias-border-l2)", background: "var(--dsw-alias-bg-layer-1)" }
|
|
2489
|
+
})
|
|
2490
|
+
),
|
|
2491
|
+
React.createElement(
|
|
2492
|
+
"label",
|
|
2493
|
+
{ style: { display: "flex", alignItems: "center", gap: 8, cursor: "pointer", fontSize: 13, fontWeight: 500, marginTop: 6 } },
|
|
2494
|
+
React.createElement("input", {
|
|
2495
|
+
type: "checkbox",
|
|
2496
|
+
checked: Boolean(currentPreset.embedding_clustering_enabled),
|
|
2497
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, embedding_clustering_enabled: e.target.checked })),
|
|
2498
|
+
style: { accentColor: "var(--dsw-alias-state-brand-primary, var(--dsw-alias-label-primary))", cursor: "pointer" }
|
|
2499
|
+
}),
|
|
2500
|
+
t("aggregator.embedding_clustering_title") || "\u{1F9ED} Blind Embedding Clustering"
|
|
2501
|
+
),
|
|
2502
|
+
React.createElement(
|
|
2503
|
+
"div",
|
|
2504
|
+
{ style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)", marginLeft: 22 } },
|
|
2505
|
+
t("aggregator.embedding_clustering_desc") || "Bypass LLM Judge when candidate embeddings converge into a dominant cluster (>= threshold)."
|
|
2506
|
+
),
|
|
2507
|
+
Boolean(currentPreset.embedding_clustering_enabled) && React.createElement(
|
|
2508
|
+
"div",
|
|
2509
|
+
{ style: { display: "flex", flexDirection: "column", gap: 4, marginLeft: 22, marginTop: 4 } },
|
|
2510
|
+
React.createElement(
|
|
2511
|
+
"div",
|
|
2512
|
+
{ style: { display: "flex", alignItems: "center", gap: 8 } },
|
|
2513
|
+
React.createElement("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, t("aggregator.embedding_threshold_label") || "Consensus Similarity Threshold:"),
|
|
2514
|
+
React.createElement("input", {
|
|
2515
|
+
type: "number",
|
|
2516
|
+
step: 0.01,
|
|
2517
|
+
min: 0.5,
|
|
2518
|
+
max: 0.99,
|
|
2519
|
+
value: currentPreset.embedding_consensus_threshold ?? 0.88,
|
|
2520
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, embedding_consensus_threshold: Number(e.target.value) || 0.88 })),
|
|
2521
|
+
style: { width: 60, padding: "2px 6px", fontSize: 12, borderRadius: 4, border: "1px solid var(--dsw-alias-border-l2)", background: "var(--dsw-alias-bg-layer-1)" }
|
|
2522
|
+
})
|
|
2523
|
+
),
|
|
2524
|
+
React.createElement(
|
|
2525
|
+
"label",
|
|
2526
|
+
{ style: { display: "flex", alignItems: "center", gap: 6, cursor: "pointer", fontSize: 12 } },
|
|
2527
|
+
React.createElement("input", {
|
|
2528
|
+
type: "checkbox",
|
|
2529
|
+
checked: currentPreset.fallback_to_judge_on_split !== false,
|
|
2530
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, fallback_to_judge_on_split: e.target.checked })),
|
|
2531
|
+
style: { accentColor: "var(--dsw-alias-state-brand-primary, var(--dsw-alias-label-primary))" }
|
|
2532
|
+
}),
|
|
2533
|
+
t("aggregator.fallback_to_judge_label") || "Fallback to Judge if Opinion Splits"
|
|
2534
|
+
)
|
|
2535
|
+
)
|
|
2536
|
+
),
|
|
2537
|
+
// --- src/client/86-card-aggregator-ext2.js ---
|
|
2427
2538
|
/* Multi-Turn Context & Diff Pruning (#176) */
|
|
2428
2539
|
React.createElement(
|
|
2429
2540
|
"div",
|
|
@@ -2760,6 +2871,96 @@ window.__ModuleLoader__.load({
|
|
|
2760
2871
|
t("aggregator.speculative_gate_desc") || "Lightweight local edge model generates high-speed token drafts verified and completed in one fast pass by the cloud model."
|
|
2761
2872
|
)
|
|
2762
2873
|
),
|
|
2874
|
+
/* Pareto Frontier Slider (#307) */
|
|
2875
|
+
React.createElement(
|
|
2876
|
+
"div",
|
|
2877
|
+
{ style: { display: "flex", flexDirection: "column", gap: 6 } },
|
|
2878
|
+
React.createElement(
|
|
2879
|
+
"label",
|
|
2880
|
+
{ style: { display: "flex", alignItems: "center", gap: 8, fontSize: 13, fontWeight: 600, color: "var(--dsw-alias-label-primary)", cursor: "pointer" } },
|
|
2881
|
+
React.createElement("input", {
|
|
2882
|
+
type: "checkbox",
|
|
2883
|
+
checked: Boolean(currentPreset.pareto_slider_enabled),
|
|
2884
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, pareto_slider_enabled: e.target.checked })),
|
|
2885
|
+
style: { accentColor: "var(--dsw-alias-state-brand-primary, var(--dsw-alias-label-primary))", cursor: "pointer" }
|
|
2886
|
+
}),
|
|
2887
|
+
t("aggregator.pareto_slider_title") || "\u{1F4C8} Cost vs Quality Pareto Frontier Slider"
|
|
2888
|
+
),
|
|
2889
|
+
React.createElement(
|
|
2890
|
+
"div",
|
|
2891
|
+
{ style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)", marginLeft: 22 } },
|
|
2892
|
+
t("aggregator.pareto_slider_desc") || "Reactive balance from 100% free local edge models to ultra-rigorous flagship multi-judge consensus."
|
|
2893
|
+
),
|
|
2894
|
+
currentPreset.pareto_slider_enabled && React.createElement(
|
|
2895
|
+
"div",
|
|
2896
|
+
{ style: { marginLeft: 22, marginTop: 4, display: "flex", alignItems: "center", gap: 10 } },
|
|
2897
|
+
React.createElement("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, t("aggregator.pareto_pos_label") || "Frontier Position:"),
|
|
2898
|
+
React.createElement("input", {
|
|
2899
|
+
type: "range",
|
|
2900
|
+
min: 0,
|
|
2901
|
+
max: 100,
|
|
2902
|
+
step: 5,
|
|
2903
|
+
value: currentPreset.pareto_slider_position ?? 50,
|
|
2904
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, pareto_slider_position: Number(e.target.value) })),
|
|
2905
|
+
style: { cursor: "pointer", flex: 1, maxWidth: 200 }
|
|
2906
|
+
}),
|
|
2907
|
+
React.createElement("span", { style: { fontSize: 12, fontWeight: 600, color: "var(--dsw-alias-label-primary)" } }, String(currentPreset.pareto_slider_position ?? 50) + "%")
|
|
2908
|
+
)
|
|
2909
|
+
),
|
|
2910
|
+
/* Hard Token Budget Guard (#319) */
|
|
2911
|
+
React.createElement(
|
|
2912
|
+
"div",
|
|
2913
|
+
{ style: { display: "flex", flexDirection: "column", gap: 6 } },
|
|
2914
|
+
React.createElement(
|
|
2915
|
+
"label",
|
|
2916
|
+
{ style: { display: "flex", alignItems: "center", gap: 8, fontSize: 13, fontWeight: 600, color: "var(--dsw-alias-label-primary)", cursor: "pointer" } },
|
|
2917
|
+
React.createElement("input", {
|
|
2918
|
+
type: "checkbox",
|
|
2919
|
+
checked: Boolean(currentPreset.hard_budget_guard_enabled),
|
|
2920
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, hard_budget_guard_enabled: e.target.checked })),
|
|
2921
|
+
style: { accentColor: "var(--dsw-alias-state-brand-primary, var(--dsw-alias-label-primary))", cursor: "pointer" }
|
|
2922
|
+
}),
|
|
2923
|
+
t("aggregator.hard_budget_title") || "\u{1F6E1}\uFE0F Hard Token Budget Guard with Auto-Scaling"
|
|
2924
|
+
),
|
|
2925
|
+
React.createElement(
|
|
2926
|
+
"div",
|
|
2927
|
+
{ style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)", marginLeft: 22 } },
|
|
2928
|
+
t("aggregator.hard_budget_desc") || "Pre-calculates turn costs against a hard financial ceiling, automatically scaling down or halting execution."
|
|
2929
|
+
),
|
|
2930
|
+
currentPreset.hard_budget_guard_enabled && React.createElement(
|
|
2931
|
+
"div",
|
|
2932
|
+
{ style: { marginLeft: 22, marginTop: 4, display: "flex", flexWrap: "wrap", alignItems: "center", gap: 12 } },
|
|
2933
|
+
React.createElement(
|
|
2934
|
+
"div",
|
|
2935
|
+
{ style: { display: "flex", alignItems: "center", gap: 6 } },
|
|
2936
|
+
React.createElement("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, t("aggregator.hard_budget_limit_label") || "Max Cost (USD):"),
|
|
2937
|
+
React.createElement("input", {
|
|
2938
|
+
type: "number",
|
|
2939
|
+
min: 1e-3,
|
|
2940
|
+
max: 10,
|
|
2941
|
+
step: 5e-3,
|
|
2942
|
+
value: currentPreset.hard_budget_limit_usd ?? 0.02,
|
|
2943
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, hard_budget_limit_usd: Number(e.target.value) })),
|
|
2944
|
+
style: { width: 80, padding: "2px 6px", fontSize: 12, borderRadius: 4, border: "1px solid var(--dsw-alias-border-primary)" }
|
|
2945
|
+
})
|
|
2946
|
+
),
|
|
2947
|
+
React.createElement(
|
|
2948
|
+
"div",
|
|
2949
|
+
{ style: { display: "flex", alignItems: "center", gap: 6 } },
|
|
2950
|
+
React.createElement("span", { style: { fontSize: 12, color: "var(--dsw-alias-label-secondary)" } }, t("aggregator.hard_budget_policy_label") || "Policy:"),
|
|
2951
|
+
React.createElement(
|
|
2952
|
+
"select",
|
|
2953
|
+
{
|
|
2954
|
+
value: currentPreset.hard_budget_policy || "auto_downgrade",
|
|
2955
|
+
onChange: (e) => updateCurrentPreset((p) => ({ ...p, hard_budget_policy: e.target.value })),
|
|
2956
|
+
style: { padding: "2px 6px", fontSize: 12, borderRadius: 4, border: "1px solid var(--dsw-alias-border-primary)" }
|
|
2957
|
+
},
|
|
2958
|
+
React.createElement("option", { value: "auto_downgrade" }, t("aggregator.hard_budget_policy_downgrade") || "Auto-Downgrade"),
|
|
2959
|
+
React.createElement("option", { value: "fail_closed" }, t("aggregator.hard_budget_policy_fail") || "Fail-Closed")
|
|
2960
|
+
)
|
|
2961
|
+
)
|
|
2962
|
+
)
|
|
2963
|
+
),
|
|
2763
2964
|
/* Fallback Judges Chain */
|
|
2764
2965
|
React.createElement(
|
|
2765
2966
|
"div",
|
package/lib/events.js
CHANGED
|
@@ -17,9 +17,13 @@ export const MOA_EVENTS = {
|
|
|
17
17
|
MUTATION_COMPLETE: 'moa/mutation-complete',
|
|
18
18
|
PRIVACY_SANITIZED: 'moa/privacy-sanitized',
|
|
19
19
|
SPECULATIVE_DRAFT: 'moa/speculative-draft',
|
|
20
|
+
PARETO_ADJUSTED: 'moa/pareto-adjusted',
|
|
21
|
+
BUDGET_SCALED: 'moa/budget-scaled',
|
|
20
22
|
CRITIQUE_COMPLETE: 'moa/critique-complete',
|
|
21
23
|
JUDGE_VERDICT: 'moa/judge-verdict',
|
|
22
24
|
CONTEXT_PRUNING: 'moa/context-pruning',
|
|
25
|
+
DEBATE_ROUND: 'moa/debate-round',
|
|
26
|
+
EMBEDDING_CLUSTER: 'moa/embedding-cluster',
|
|
23
27
|
CACHE_HIT: 'moa/cache-hit',
|
|
24
28
|
RUN_FINISH: 'moa/run-finish',
|
|
25
29
|
}
|
package/lib/moa-schema.js
CHANGED
|
@@ -107,6 +107,17 @@ export const PresetSchema = z.object({
|
|
|
107
107
|
redact_ips: z.boolean().default(true),
|
|
108
108
|
speculative_draft_enabled: z.boolean().default(false),
|
|
109
109
|
speculative_block_size: z.number().default(256),
|
|
110
|
+
pareto_slider_enabled: z.boolean().default(false),
|
|
111
|
+
pareto_slider_position: z.number().default(50),
|
|
112
|
+
hard_budget_guard_enabled: z.boolean().default(false),
|
|
113
|
+
hard_budget_limit_usd: z.number().default(0.02),
|
|
114
|
+
hard_budget_policy: z.string().default('auto_downgrade'),
|
|
115
|
+
rebuttal_debate_enabled: z.boolean().default(false),
|
|
116
|
+
rebuttal_rounds: z.number().default(1),
|
|
117
|
+
rebuttal_max_critique_tokens: z.number().default(1024),
|
|
118
|
+
embedding_clustering_enabled: z.boolean().default(false),
|
|
119
|
+
embedding_consensus_threshold: z.number().default(0.88),
|
|
120
|
+
fallback_to_judge_on_split: z.boolean().default(true),
|
|
110
121
|
})
|
|
111
122
|
|
|
112
123
|
export const Config = z.object({
|
|
@@ -160,6 +171,17 @@ export const Config = z.object({
|
|
|
160
171
|
redact_ips: z.boolean().default(true).volatile(),
|
|
161
172
|
speculative_draft_enabled: z.boolean().default(false).volatile(),
|
|
162
173
|
speculative_block_size: z.number().default(256).volatile(),
|
|
174
|
+
pareto_slider_enabled: z.boolean().default(false).volatile(),
|
|
175
|
+
pareto_slider_position: z.number().default(50).volatile(),
|
|
176
|
+
hard_budget_guard_enabled: z.boolean().default(false).volatile(),
|
|
177
|
+
hard_budget_limit_usd: z.number().default(0.02).volatile(),
|
|
178
|
+
hard_budget_policy: z.string().default('auto_downgrade').volatile(),
|
|
179
|
+
rebuttal_debate_enabled: z.boolean().default(false).volatile(),
|
|
180
|
+
rebuttal_rounds: z.number().default(1).volatile(),
|
|
181
|
+
rebuttal_max_critique_tokens: z.number().default(1024).volatile(),
|
|
182
|
+
embedding_clustering_enabled: z.boolean().default(false).volatile(),
|
|
183
|
+
embedding_consensus_threshold: z.number().default(0.88).volatile(),
|
|
184
|
+
fallback_to_judge_on_split: z.boolean().default(true).volatile(),
|
|
163
185
|
smart_routing_model: ModelSlotSchema.default({ provider: '', model: '' }).volatile(),
|
|
164
186
|
prices: z.dict(PriceRow).default({}).volatile(),
|
|
165
187
|
presets: z.array(PresetSchema).default([
|
|
@@ -0,0 +1,158 @@
|
|
|
1
|
+
/**
|
|
2
|
+
* DeepSeek Harness Mixture of Agents (MoA) — Hard Token Budget Guard & Auto-Scaling (#319)
|
|
3
|
+
*
|
|
4
|
+
* Enforces strict financial limits on inference costs. Pre-calculates end-to-end turn
|
|
5
|
+
* expenses (proposers + multi-judge + synthesis) against hard_budget_limit_usd before dispatching.
|
|
6
|
+
*
|
|
7
|
+
* Supports two operational policies when anticipated cost exceeds limit:
|
|
8
|
+
* - auto_downgrade: Automatically substitutes costly cloud slots with zero-cost local edge
|
|
9
|
+
* models or economic tiers, and scales down candidate slots until cost fits under the ceiling.
|
|
10
|
+
* - fail_closed: Halts execution immediately to eliminate unexpected API billing surprises.
|
|
11
|
+
*/
|
|
12
|
+
|
|
13
|
+
import { MOA_EVENTS, emitEvent } from '../events.js'
|
|
14
|
+
import { estimateCandidateRunCost, estimateDownstreamCost } from '../moa-budget.js'
|
|
15
|
+
|
|
16
|
+
/**
|
|
17
|
+
* Evaluates projected turn expenses and dynamically scales down ensemble if needed.
|
|
18
|
+
*
|
|
19
|
+
* @param {object} params
|
|
20
|
+
* @param {Array<object>} params.references
|
|
21
|
+
* @param {object} params.aggregator
|
|
22
|
+
* @param {number} params.limitUsd
|
|
23
|
+
* @param {string} [params.policy='auto_downgrade']
|
|
24
|
+
* @param {object} [params.prices={}]
|
|
25
|
+
* @param {number} [params.promptTokens=1500]
|
|
26
|
+
* @param {number} [params.expectedOutputTokens=2048]
|
|
27
|
+
* @param {object} [params.options]
|
|
28
|
+
* @returns {object} Budget evaluation result
|
|
29
|
+
*/
|
|
30
|
+
export function evaluateHardBudgetLimit({
|
|
31
|
+
references = [],
|
|
32
|
+
aggregator = {},
|
|
33
|
+
limitUsd = 0.02,
|
|
34
|
+
policy = 'auto_downgrade',
|
|
35
|
+
prices = {},
|
|
36
|
+
promptTokens = 1500,
|
|
37
|
+
expectedOutputTokens = 2048,
|
|
38
|
+
options = {},
|
|
39
|
+
}) {
|
|
40
|
+
const { ctx, runId, onProgress } = options
|
|
41
|
+
|
|
42
|
+
// Calculate baseline projected cost
|
|
43
|
+
const candCost = estimateCandidateRunCost(references, prices, promptTokens, expectedOutputTokens)
|
|
44
|
+
const downstreamCost = estimateDownstreamCost(
|
|
45
|
+
aggregator,
|
|
46
|
+
[],
|
|
47
|
+
references.length,
|
|
48
|
+
prices,
|
|
49
|
+
expectedOutputTokens,
|
|
50
|
+
promptTokens
|
|
51
|
+
)
|
|
52
|
+
const initialProjectedCost = Number((candCost.totalEstimatedUsd + downstreamCost).toFixed(5))
|
|
53
|
+
|
|
54
|
+
if (initialProjectedCost <= limitUsd) {
|
|
55
|
+
return {
|
|
56
|
+
ok: true,
|
|
57
|
+
scaled: false,
|
|
58
|
+
references,
|
|
59
|
+
aggregator,
|
|
60
|
+
projectedCostUsd: initialProjectedCost,
|
|
61
|
+
initialProjectedCost,
|
|
62
|
+
limitUsd,
|
|
63
|
+
warning: null,
|
|
64
|
+
}
|
|
65
|
+
}
|
|
66
|
+
|
|
67
|
+
// Cost exceeds limit
|
|
68
|
+
if (policy === 'fail_closed') {
|
|
69
|
+
const errorMsg = `[BudgetGuard] Projected turn cost ($${initialProjectedCost}) exceeds hard limit ($${limitUsd}). Execution halted.`
|
|
70
|
+
if (typeof onProgress === 'function') {
|
|
71
|
+
onProgress(`🛑 *${errorMsg}*\n`)
|
|
72
|
+
}
|
|
73
|
+
return {
|
|
74
|
+
ok: false,
|
|
75
|
+
scaled: false,
|
|
76
|
+
error: errorMsg,
|
|
77
|
+
projectedCostUsd: initialProjectedCost,
|
|
78
|
+
initialProjectedCost,
|
|
79
|
+
limitUsd,
|
|
80
|
+
}
|
|
81
|
+
}
|
|
82
|
+
|
|
83
|
+
// policy: auto_downgrade
|
|
84
|
+
let workingRefs = [...references]
|
|
85
|
+
let workingAggregator = { ...aggregator }
|
|
86
|
+
let scaled = false
|
|
87
|
+
|
|
88
|
+
// Step 1: Replace expensive cloud proposers with local edge models (zero cost)
|
|
89
|
+
for (let i = workingRefs.length - 1; i >= 0; i--) {
|
|
90
|
+
const currentSlot = workingRefs[i]
|
|
91
|
+
if (currentSlot.provider !== 'ollama' && currentSlot.provider !== 'local') {
|
|
92
|
+
workingRefs[i] = {
|
|
93
|
+
...currentSlot,
|
|
94
|
+
provider: 'ollama',
|
|
95
|
+
model: 'qwen2.5-coder:7b',
|
|
96
|
+
role_persona: currentSlot.role_persona || 'proposer',
|
|
97
|
+
}
|
|
98
|
+
scaled = true
|
|
99
|
+
}
|
|
100
|
+
|
|
101
|
+
const testCandCost = estimateCandidateRunCost(workingRefs, prices, promptTokens, expectedOutputTokens)
|
|
102
|
+
const testDownstream = estimateDownstreamCost(workingAggregator, [], workingRefs.length, prices, expectedOutputTokens, promptTokens)
|
|
103
|
+
if ((testCandCost.totalEstimatedUsd + testDownstream) <= limitUsd) {
|
|
104
|
+
break
|
|
105
|
+
}
|
|
106
|
+
}
|
|
107
|
+
|
|
108
|
+
// Step 2: If still exceeding, replace expensive aggregator with economical model or local
|
|
109
|
+
let currentCost = Number((estimateCandidateRunCost(workingRefs, prices, promptTokens, expectedOutputTokens).totalEstimatedUsd +
|
|
110
|
+
estimateDownstreamCost(workingAggregator, [], workingRefs.length, prices, expectedOutputTokens, promptTokens)).toFixed(5))
|
|
111
|
+
|
|
112
|
+
if (currentCost > limitUsd && workingAggregator.provider !== 'ollama') {
|
|
113
|
+
workingAggregator = { provider: 'deepseek', model: 'deepseek-chat' }
|
|
114
|
+
scaled = true
|
|
115
|
+
currentCost = Number((estimateCandidateRunCost(workingRefs, prices, promptTokens, expectedOutputTokens).totalEstimatedUsd +
|
|
116
|
+
estimateDownstreamCost(workingAggregator, [], workingRefs.length, prices, expectedOutputTokens, promptTokens)).toFixed(5))
|
|
117
|
+
|
|
118
|
+
if (currentCost > limitUsd) {
|
|
119
|
+
workingAggregator = { provider: 'ollama', model: 'qwen2.5-coder:7b' }
|
|
120
|
+
currentCost = 0.0
|
|
121
|
+
}
|
|
122
|
+
}
|
|
123
|
+
|
|
124
|
+
// Step 3: If still exceeding, prune candidates down to 1
|
|
125
|
+
if (currentCost > limitUsd && workingRefs.length > 1) {
|
|
126
|
+
workingRefs = [workingRefs[0]]
|
|
127
|
+
scaled = true
|
|
128
|
+
currentCost = Number((estimateCandidateRunCost(workingRefs, prices, promptTokens, expectedOutputTokens).totalEstimatedUsd +
|
|
129
|
+
estimateDownstreamCost(workingAggregator, [], workingRefs.length, prices, expectedOutputTokens, promptTokens)).toFixed(5))
|
|
130
|
+
}
|
|
131
|
+
|
|
132
|
+
if (scaled) {
|
|
133
|
+
if (typeof onProgress === 'function') {
|
|
134
|
+
onProgress(`🛡️ *Budget Guard Auto-Scaling*: Scaled ensemble from $${initialProjectedCost} to $${currentCost} to fit under $${limitUsd} ceiling.\n`)
|
|
135
|
+
}
|
|
136
|
+
|
|
137
|
+
if (ctx) {
|
|
138
|
+
emitEvent(ctx, MOA_EVENTS.BUDGET_SCALED, {
|
|
139
|
+
runId,
|
|
140
|
+
originalCostUsd: initialProjectedCost,
|
|
141
|
+
scaledCostUsd: currentCost,
|
|
142
|
+
limitUsd,
|
|
143
|
+
policy,
|
|
144
|
+
})
|
|
145
|
+
}
|
|
146
|
+
}
|
|
147
|
+
|
|
148
|
+
return {
|
|
149
|
+
ok: true,
|
|
150
|
+
scaled,
|
|
151
|
+
references: workingRefs,
|
|
152
|
+
aggregator: workingAggregator,
|
|
153
|
+
projectedCostUsd: currentCost,
|
|
154
|
+
initialProjectedCost,
|
|
155
|
+
limitUsd,
|
|
156
|
+
warning: scaled ? `Budget Guard Auto-Scaled: initial $${initialProjectedCost} $\\to$ $${currentCost} (ceiling $${limitUsd})` : null,
|
|
157
|
+
}
|
|
158
|
+
}
|