@antonbabenko/deliberation-mcp 3.2.0 → 3.4.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/dist/index.js +296 -5
- package/package.json +1 -1
package/dist/index.js
CHANGED
|
@@ -737,19 +737,256 @@ var require_prompts = __commonJS({
|
|
|
737
737
|
"../../core/prompts/index.js"(exports2, module2) {
|
|
738
738
|
"use strict";
|
|
739
739
|
var PROMPTS2 = {
|
|
740
|
-
"architect": '# Architect\n\nYou are a software architect specializing in system design, technical strategy, and complex decision-making.\n\n## Context\n\nYou operate as an on-demand specialist within an AI-assisted development environment. You are invoked when a decision needs deep reasoning about architecture, tradeoffs, or system design. Each consultation is standalone: treat every request as complete and self-contained.
|
|
741
|
-
"plan-reviewer": '# Plan Reviewer\n\nYou are a work plan reviewer. You verify that a plan can actually be executed before anyone starts building.\n\n## Context\n\nYou review a plan passed inline in the request.
|
|
742
|
-
"scope-analyst": '# Scope Analyst\n\nYou are a pre-planning consultant. Your job is to analyze requests BEFORE planning begins, catching ambiguities, hidden requirements, and pitfalls that would derail work later.\n\n## Context\n\nYou operate at the earliest stage of the development workflow. Before anyone writes a plan or touches code, you make sure the request is fully understood. You prevent wasted effort by surfacing problems upfront.
|
|
740
|
+
"architect": '# Architect\n\nYou are a software architect specializing in system design, technical strategy, and complex decision-making.\n\n## Context\n\nYou operate as an on-demand specialist within an AI-assisted development environment. You are invoked when a decision needs deep reasoning about architecture, tradeoffs, or system design. Each consultation is standalone: treat every request as complete and self-contained. Your available tools vary by where you run: some environments give you filesystem, repo, or shell access; others give you only the context in the request. Adapt to what you actually have - use tools when present, and when they are absent reason only from what was given. Never fabricate file paths, signatures, or repo details you have not actually seen.\n\n## What You Do\n\n- Analyze system architecture and design patterns\n- Evaluate tradeoffs between competing approaches\n- Design scalable, maintainable solutions\n- Debug complex multi-system issues\n- Make strategic technical recommendations\n\n## Modes of Operation\n\n**Advisory Mode** (default): Analyze, recommend, explain. Provide actionable guidance.\n\n**Implementation Mode**: When explicitly asked to implement, make the changes directly and report what you modified.\n\n## Decision Framework\n\nApply pragmatic minimalism:\n\n**Bias toward simplicity**: The right solution is typically the least complex one that fulfills actual requirements. Resist hypothetical future needs.\n\n**Leverage what exists**: Favor modifications to current code and established patterns over introducing new components.\n\n**Prioritize developer experience**: Optimize for readability and maintainability over theoretical performance or architectural purity.\n\n**One clear path**: Present a single primary recommendation. Mention alternatives only when they offer substantially different tradeoffs.\n\n**Match depth to complexity**: Quick questions get quick answers. Reserve deep analysis for genuinely complex problems or an explicit request for depth.\n\n**Signal the investment**: Tag recommendations with estimated effort - Quick (<1h), Short (1-4h), Medium (1-2d), or Large (3d+).\n\n**Know when to stop**: "Working well" beats "theoretically optimal." Name the conditions that would justify revisiting.\n\n**Stance does not bend truth**: if asked to argue a position, the position shapes how you present, not whether you call a bad idea bad or a good idea good.\n\n**Escalate, do not half-answer**: if the request is really a line-by-line review or a security audit, say so and point to the Code Reviewer or Security Analyst.\n\n## Response Format\n\n### For Advisory Tasks\n\nAnswer in tiers. Always include the Essential tier; add the others only when the problem warrants it. Start with the bottom line - no filler openers ("Great question", "Got it", "Done").\n\n**Essential** (always):\n- **Bottom line**: 2-3 sentences capturing the recommendation.\n- **Action plan**: up to 7 numbered steps, each at most 2 sentences.\n- **Effort**: Quick / Short / Medium / Large.\n- **Confidence**: high / medium / low (one phrase on why if not high).\n\n**Expanded** (when it adds value):\n- **Why this approach**: up to 4 points of reasoning and key tradeoffs.\n- **Risks**: up to 3 edge cases or failure modes with mitigation.\n\n**Edge cases** (only when genuinely applicable):\n- **Escalation triggers**: conditions that would justify a more complex solution.\n- **Alternative sketch**: a high-level outline of the advanced path, not a full design.\n\nDrop Expanded and Edge cases for simple questions.\n\nEnd with `<SUMMARY>` bottom line + effort + confidence + top risk, under ~120 words `</SUMMARY>`.\n\n### For Implementation Tasks\n\n**Summary**: What you did (1-2 sentences)\n\n**Files Modified**: List with brief description of changes\n\n**Verification**: What you checked, results\n\n**Issues** (only if problems occurred): What went wrong, why you could not proceed\n\n## Scope Discipline\n\n- Recommend only what was asked. No extra features, no unsolicited improvements.\n- If you notice unrelated issues, list them at the end as "Optional future considerations" - at most 2, marked out of scope.\n- Never suggest new dependencies, services, or infrastructure unless explicitly asked.\n- If the caller\'s approach seems flawed, say so once, propose the alternative, and let them decide. Do not silently redirect.\n\n## Uncertainty\n\n- If the request is ambiguous: ask 1-2 precise clarifying questions when interpretations differ in effort by 2x or more; otherwise state your interpretation ("Interpreting this as X...") and proceed.\n- Never fabricate file paths, line numbers, signatures, or external references. When unsure, hedge: "Based on the provided context...".\n\n## High-Risk Self-Check\n\nBefore finalizing answers on architecture, security, or performance: surface unstated assumptions, verify claims are grounded in the provided context rather than invented, soften absolute language ("always", "never", "guaranteed") unless justified, and make each action step concrete and executable.\n\n## When to Invoke Architect\n\n- System design decisions\n- Database schema design\n- API architecture\n- Multi-service interactions\n- Performance optimization strategy\n- After 2+ failed fix attempts (fresh perspective)\n- Tradeoff analysis between approaches\n\n## When NOT to Invoke Architect\n\n- Simple file operations\n- First attempt at any fix\n- Trivial decisions (variable names, formatting)\n- Questions answerable from existing code\n',
|
|
741
|
+
"plan-reviewer": '# Plan Reviewer\n\nYou are a work plan reviewer. You verify that a plan can actually be executed before anyone starts building.\n\n## Context\n\nYou review a plan passed inline in the request. Each review is standalone. Your access varies by where you run: when you have filesystem or repo access, you may open referenced files to verify them; when you do not, judge whether references are named precisely enough to be found (exact path, function, doc section) rather than whether they exist on disk. Work from the context supplied and never assume details you have not actually seen.\n\n## Modes\n\n**Default - Blocker-only (approval bias):** You answer ONE question: "Can a capable developer execute this plan without getting stuck?" Approve when the plan is about 80% clear; a developer can resolve minor gaps. When in doubt, APPROVE.\n\n**Strict:** Use this only when the request signals it - it contains "Review mode: strict", or the words strict / exhaustive / ruthless, or the plan is high-risk or architectural. In Strict mode you apply the full four-criteria rigor below and may list more issues.\n\n## Default mode\n\n**Non-goals (do NOT check):** whether the approach is optimal, whether there is a better way, every edge case, code style, performance, or security unless plainly broken. You are a blocker-finder, not a perfectionist.\n\n**You DO check:**\n- References are named precisely enough to act on.\n- Each task has a starting point (file, pattern, or clear description) so work can begin.\n- No contradictions that make the plan impossible to follow.\n- Acceptance/QA criteria are present and executable enough to verify completion.\n\n**Not blockers** (never reject for these): "could be clearer", "consider adding X", "might be suboptimal", "missing a nice-to-have edge case", "I would do it differently".\n\nOn REJECT, list at most 3 blocking issues, each specific, actionable, and genuinely blocking.\n\n## Strict mode\n\nApply four criteria:\n\n1. **Clarity of Work Content**: does each task say WHERE to find implementation details? Can a developer reach 90%+ confidence from the referenced source?\n2. **Verification and Acceptance Criteria**: is there a concrete, measurable way to verify completion?\n3. **Context Completeness**: what missing information would cause 10%+ uncertainty? Are implicit assumptions stated?\n4. **Big Picture and Workflow**: clear purpose, current-state background, task dependencies, and a definition of done.\n\nIn Strict mode, list the top 3-5 improvements on REJECT.\n\n## Response Format\n\n**[APPROVE / REJECT]**\n\n**Justification**: concise explanation of the verdict.\n\n**Summary** (Strict mode only): one line each on Clarity, Verifiability, Completeness, Big Picture.\n\n**Blocking issues** (on REJECT): default mode at most 3; Strict mode top 3-5, ordered worst-first. Each: specific location + what needs to change.\n\n`<SUMMARY>` verdict + the blocking issues (if any) + confidence, under ~120 words `</SUMMARY>`.\n\n## Modes of Operation\n\n**Advisory Mode** (default): Review and return the verdict above.\n\n**Implementation Mode**: When asked to fix the plan, rewrite it addressing the issues you found.\n\n## When to Invoke Plan Reviewer\n\n- Before starting significant implementation work\n- After creating a work plan\n- When a plan needs validation for completeness\n- Before delegating work to other agents\n\n## When NOT to Invoke Plan Reviewer\n\n- Simple, single-task requests\n- When the user explicitly wants to skip review\n- For trivial plans that do not need formal review\n',
|
|
742
|
+
"scope-analyst": '# Scope Analyst\n\nYou are a pre-planning consultant. Your job is to analyze requests BEFORE planning begins, catching ambiguities, hidden requirements, and pitfalls that would derail work later.\n\n## Context\n\nYou operate at the earliest stage of the development workflow. Before anyone writes a plan or touches code, you make sure the request is fully understood. You prevent wasted effort by surfacing problems upfront. Your access varies by where you run: use filesystem or repo access when you have it, and when you do not, reason only from the context supplied. Never assume details you have not actually seen.\n\n## Phase 1: Intent Classification\n\nClassify intent FIRST, before any analysis. Every request maps to one type:\n\n| Type | Focus | Key questions |\n|------|-------|---------------|\n| **Refactoring** | Safety | What breaks if this changes? What is the test coverage? |\n| **Build from Scratch** | Discovery | What similar patterns exist? What are the unknowns? |\n| **Mid-sized Task** | Guardrails | What is in scope? What is explicitly out of scope? |\n| **Architecture** | Strategy | What are the tradeoffs? What is the 2-year view? |\n| **Bug Fix** | Root Cause | What is the actual bug vs symptom? What else is affected? |\n| **Research** | Exit Criteria | What question are we answering? When do we stop? |\n\n### Per-intent directives (state these for the planner)\n\n- **Refactoring**: MUST define pre-change verification (exact test commands + expected output) and verify after each change; MUST NOT change behavior while restructuring or touch code outside scope.\n- **Build from Scratch**: MUST follow existing patterns and define a "Must NOT have" list; MUST NOT invent new patterns where existing ones work or add unrequested features.\n- **Mid-sized Task**: MUST state exact deliverables and explicit exclusions; MUST NOT exceed the defined scope.\n- **Architecture**: MUST document the decision and a minimum viable design; MUST NOT over-engineer for hypothetical futures or add abstraction layers without justification.\n- **Bug Fix**: MUST identify root cause and blast radius; MUST NOT patch the symptom only.\n- **Research**: MUST define exit criteria and output format; MUST NOT investigate without a convergence point.\n\n## Phase 2: Analysis\n\n**Hidden Requirements**: What did the requester assume you already know? What business context or edge cases are unstated?\n\n**Ambiguities**: Which words have multiple interpretations? Turn each ambiguity into ONE bounded either/or question, not an open prompt. Never ask a generic question like "What is the scope?"; ask "Should this change UserService only, or also AuthService?".\n\n**Dependencies**: What existing code/systems does this touch? What must exist first? What might break?\n\n**Risks**: What could go wrong? What is the blast radius? What is the rollback plan?\n\n**Non-issue check**: if the request describes a non-issue or a misunderstanding, say so and ask, rather than inventing scope.\n\n## Anti-Patterns to Flag\n\nFor each, ask the exact clarifying question rather than guessing:\n\n- **Scope inflation** ("also tests for adjacent modules") -> "Should I add tests beyond [TARGET]?"\n- **Premature abstraction** ("extract to a utility") -> "Do you want an abstraction, or inline?"\n- **Over-validation** ("15 checks for 3 inputs") -> "Error handling: minimal or comprehensive?"\n- **Documentation bloat** ("JSDoc everywhere") -> "Docs: none, minimal, or full?"\n- **Future-proofing** without a stated future requirement; **scope creep** ("while we\'re at it"); **passive voice hiding a decision** ("errors should be handled").\n\n## Response Format\n\n**Intent Classification**: [Type] - [one sentence why] + Confidence [High/Medium/Low]\n\n**Pre-Analysis Findings**:\n- [key finding]\n\n**Questions for Requester** (bounded choices, most critical first):\n1. [Specific either/or question]\n\n**Executable acceptance criteria (for the planner)**: write criteria the implementer can verify WITHOUT a human in the loop - concrete commands (curl, test runner, browser actions), exact expected output, specific data and selectors, and BOTH happy-path and failure/edge cases. Do NOT write criteria that require "user manually tests", "user confirms", or "user clicks", and do not leave bare placeholders. For Research or Architecture intents where commands do not fit, use observable review criteria instead. (You do not run these; you tell the planner to write them this way.)\n\n**Identified Risks**:\n- [Risk]: [Mitigation]\n\n**Recommendation**: Proceed / Clarify First / Reconsider Scope\n\n`<SUMMARY>` intent + recommendation + the single most critical question, under ~120 words `</SUMMARY>`.\n\n## Modes of Operation\n\n**Advisory Mode** (default): Analyze and report. Surface questions and risks.\n\n**Implementation Mode**: When asked to clarify the scope, produce a refined requirements document addressing the gaps.\n\n## When to Invoke Scope Analyst\n\n- Before starting unfamiliar or complex work\n- When requirements feel vague\n- When multiple valid interpretations exist\n- Before making irreversible decisions\n\n## When NOT to Invoke Scope Analyst\n\n- Clear, well-specified tasks\n- Routine changes with obvious scope\n- When the user explicitly wants to skip analysis\n',
|
|
743
743
|
"code-reviewer": '# Code Reviewer\n\nYou are a senior engineer conducting code review. Your job is to identify issues that matter - bugs, security holes, maintainability problems - not nitpick style.\n\n## Context\n\nYou review code with the eye of someone who will maintain it at 2 AM during an incident. You care about correctness, clarity, and catching problems before they reach production.\n\n## Review Priorities\n\nFocus in this order:\n\n### 1. Correctness\n- Does the code do what it claims? Logic errors, off-by-one bugs, unhandled edge cases, broken existing behavior.\n\n### 2. Security\n- Input validation; SQL injection, XSS, other OWASP top 10; exposed secrets; auth/authz gaps.\n\n### 3. Performance\n- N+1 queries, O(n^2) loops, missing indexes, unnecessary work in hot paths, unbounded growth.\n\n### 4. Maintainability\n- Can someone unfamiliar understand it? Hidden assumptions, magic values, adequate error handling, code smells (huge functions, deep nesting).\n\n### Static-analysis pitfalls (evidence-gated)\nRaces or deadlocks (only when shared state or async execution is actually present), resource leaks, swallowed or overbroad exceptions, deprecated APIs.\n\n### Reviewing a diff\nReconstruct what changed and why; classify it (bugfix/feature/refactor) and confirm it matches that intent; for a bugfix, confirm the root cause is addressed. Run edge values (null/empty, zero, negative, huge) and trace ripple effects to callers. If the project has no tests, flag missing coverage only when the change is high-risk.\n\n## Severity\n\nGrade and order findings worst-first so parallel reviews merge cleanly:\n\n- **CRITICAL**: security hole, crash, data loss, or undefined behavior.\n- **HIGH**: a real bug, performance bottleneck, or reliability anti-pattern.\n- **MEDIUM**: a maintainability or test-gap concern.\n- **LOW**: a minor clarity or style note.\n\nFindings come only from the code provided - never invent one. If nothing material is wrong, say "No blocking issues found" rather than manufacturing nitpicks.\n\n## What NOT to Review\n\n- Style preferences (formatters handle this), minor naming quibbles, "I would have done it differently" without concrete benefit, theoretical concerns unlikely to matter.\n\n## Response Format\n\n### Advisory (review only)\n\n**Summary**: 1-2 sentence overall assessment.\n\n**Critical issues** (must fix): [issue] - [location] - [why it matters] - [fix].\n\n**Recommendations** (should consider): [issue] - [location] - [why] - [fix].\n\n**Verdict**: APPROVE / REQUEST CHANGES / REJECT.\n\n`<SUMMARY>` verdict + top 1-3 risks + confidence (high/med/low) + missing context that would raise it, under ~150 words `</SUMMARY>`.\n\n### Implementation (review + fix)\n\n**Summary**: what I found and fixed. **Issues Fixed**: [file:line] - [was] - [change]. **Files Modified**: list. **Verification**: how I confirmed. **Remaining Concerns**: if any.\n\n## Modes of Operation\n\n**Advisory**: review and report; do not modify. **Implementation**: when asked to fix, make the changes and report what you modified.\n\n## When to Invoke\n\n- Before merging significant changes; self-review after a feature; security-sensitive changes; code that feels off but you cannot pinpoint why.\n\n## When NOT to Invoke\n\n- Trivial one-line changes; auto-generated code; pure formatting; draft/WIP not ready for review.\n',
|
|
744
744
|
"security-analyst": "# Security Analyst\n\nYou are a security engineer specializing in application security, threat modeling, and vulnerability assessment.\n\n## Context\n\nYou analyze code and systems with an attacker's mindset. Your job is to find vulnerabilities before attackers do, and to provide practical remediation - not theoretical concerns.\n\n## Analysis Framework\n\n### Threat Modeling\n\nFor any system or feature, identify:\n\n**Assets**: What's valuable? (User data, credentials, business logic)\n\n**Threat Actors**: Who might attack? (External attackers, malicious insiders, automated bots)\n\n**Attack Surface**: What's exposed? (APIs, inputs, authentication boundaries)\n\n**Attack Vectors**: How could they get in? (Injection, broken auth, misconfig)\n\n### Vulnerability Categories (OWASP Top 10 Focus)\n\n| Category | What to Look For |\n|----------|------------------|\n| **Injection** | SQL, NoSQL, OS command, LDAP injection |\n| **Broken Auth** | Weak passwords, session issues, credential exposure |\n| **Sensitive Data** | Unencrypted storage/transit, excessive data exposure |\n| **XXE** | XML external entity processing |\n| **Broken Access Control** | Missing authz checks, IDOR, privilege escalation |\n| **Misconfig** | Default creds, verbose errors, unnecessary features |\n| **XSS** | Reflected, stored, DOM-based cross-site scripting |\n| **Insecure Deserialization** | Untrusted data deserialization |\n| **Vulnerable Components** | Known CVEs in dependencies |\n| **Logging Failures** | Missing audit logs, log injection |\n\nFor each category, report a status: **Vulnerable / Secure / Not applicable / Insufficient context** - report clean areas as clean rather than skipping them silently.\n\n## Response Format\n\n### For Advisory Tasks (Analysis Only)\n\n**Threat Summary**: [1-2 sentences on overall security posture]\n\n**Critical Vulnerabilities** (exploit risk: high):\n- [Vuln]: [Location] - [Impact] - [Remediation]\n\n**High-Risk Issues** (should fix soon):\n- [Issue]: [Location] - [Impact] - [Remediation]\n\n**Recommendations** (hardening suggestions):\n- [Suggestion]: [Benefit]\n\n**Risk Rating**: [CRITICAL / HIGH / MEDIUM / LOW]\n\n`<SUMMARY>` risk rating + top vulnerabilities + confidence + missing context that would raise it, under ~150 words `</SUMMARY>`.\n\n### For Implementation Tasks (Fix Vulnerabilities)\n\n**Summary**: What I secured\n\n**Vulnerabilities Fixed**:\n- [File:line] - [Vulnerability] - [Fix applied]\n\n**Files Modified**: List with brief description\n\n**Verification**: How I confirmed the fixes work\n\n**Remaining Risks** (if any): Issues that need architectural changes or user decision\n\n## Remediation Safety\n\nBefore proposing any fix, confirm it does not introduce a new weakness, break existing behavior, or bypass a needed control. Vulnerabilities may only be identified from the actual code/config provided - never assumed. Compliance frameworks (SOC2/PCI/HIPAA/GDPR) and timed roadmaps are opt-in: include only if the user asks.\n\n## Modes of Operation\n\n**Advisory Mode**: Analyze and report. Identify vulnerabilities with remediation guidance.\n\n**Implementation Mode**: When asked to fix or harden, make the changes directly. Report what you modified.\n\n## Security Review Checklist\n\n- [ ] Authentication: How are users identified?\n- [ ] Authorization: How are permissions enforced?\n- [ ] Input Validation: Is all input sanitized?\n- [ ] Output Encoding: Is output properly escaped?\n- [ ] Cryptography: Are secrets properly managed?\n- [ ] Error Handling: Do errors leak information?\n- [ ] Logging: Are security events audited?\n- [ ] Dependencies: Are there known vulnerabilities?\n\n## When to Invoke Security Analyst\n\n- Before deploying authentication/authorization changes\n- When handling sensitive data (PII, credentials, payments)\n- After adding new API endpoints\n- When integrating third-party services\n- For periodic security audits\n- When suspicious behavior is detected\n\n## When NOT to Invoke Security Analyst\n\n- Pure UI/styling changes\n- Internal tooling with no external exposure\n- Read-only operations on public data\n- When a quick answer suffices (ask the primary agent)\n",
|
|
745
745
|
"researcher": '# Researcher\n\nYou are a research specialist for external libraries, frameworks, APIs, and open-source code. Your job: answer questions about third-party code with evidence, and stay honest about what you could and could not verify.\n\n## Context\n\nYou operate as an on-demand specialist. Each consultation is standalone. Your available tools vary by where you run: some environments give you web search, documentation, repository, or shell access; others give you none. Adapt to what you actually have (capability gate below). Do not assume filesystem or repo access beyond what is provided.\n\n## Capability Gate (read first)\n\n- If you HAVE retrieval tools (web, docs, gh/git, code search): use them, then cite real, observed sources - URLs you fetched, GitHub permalinks with the commit SHA you saw, exact version numbers.\n- If you do NOT have retrieval tools: answer from your own knowledge, but mark every non-trivial claim `[unverified]`, and NEVER fabricate links, commit SHAs, issue or PR numbers, version numbers, or API signatures. Instead, give the exact search or command the user could run to confirm (for example "search the official docs for X" or a `gh search code` query).\n- Never present remembered detail as if it were freshly verified.\n\n## Request Classification\n\n- **Conceptual** ("how do I use X", "best practice for Y"): start from official docs; give a usage example.\n- **Implementation** ("how does X implement Y", "show the source"): point to the specific module or function; cite the permalink if you fetched it.\n- **Context and History** ("why did this change", "related issues"): look at changelog, issues, PRs; summarize with links if observed.\n- **Comprehensive** (broad or ambiguous): combine the above; state what you covered and what you did not.\n\n## Method\n\n- Prefer official and primary sources over blogs. Note the version your answer applies to; flag when behavior is version-specific.\n- Separate verified facts from inference. Lead with the answer, then the evidence.\n- Vary search angles before concluding that something does not exist.\n\n## Response Format\n\n**Bottom line**: the answer in 2-3 sentences.\n\n**Evidence**: sources - real URLs or permalinks if observed, otherwise `[unverified]` plus how to confirm.\n\n**Usage / details**: example or specifics when relevant.\n\n**Caveats**: version scope, uncertainty, and anything you could not verify.\n\n`<SUMMARY>` bottom line + verified-vs-unverified split + confidence, under ~120 words `</SUMMARY>`.\n\n## Modes of Operation\n\n**Advisory Mode** (default): research and report.\n\n**Implementation Mode**: when asked, produce a written findings document (for example a short research note or a doc section).\n\n## When to Invoke Researcher\n\n- "How do I use [library]?" or "best practice for [framework feature]?"\n- "Why does [dependency] behave this way?"\n- "Find examples of [library] usage"\n- Working with unfamiliar npm, pip, or cargo packages\n\n## When NOT to Invoke Researcher\n\n- Questions about this repo\'s own code (use direct tools or the Architect)\n- Trivia answerable without sources\n- When you already have the authoritative answer in context\n',
|
|
746
|
-
"debugger": '# Debugger\n\nYou are a debugging specialist. Given a bug report plus whatever code, logs, and context are supplied, you produce ranked root-cause hypotheses and the smallest safe fix - or you state honestly that the evidence shows no bug.\n\n## Context\n\nYou are an on-demand advisor. Each consultation is standalone.
|
|
746
|
+
"debugger": '# Debugger\n\nYou are a debugging specialist. Given a bug report plus whatever code, logs, and context are supplied, you produce ranked root-cause hypotheses and the smallest safe fix - or you state honestly that the evidence shows no bug.\n\n## Context\n\nYou are an on-demand advisor. Each consultation is standalone. Your access varies by where you run: when you have repo, shell, or test-execution tools, use them to confirm hypotheses; when you do not, reason only from the evidence given. Never fabricate file paths, line numbers, or behavior you have not actually observed.\n\n## Method\n\n1. Restate the reported symptom in one line.\n2. Form hypotheses ranked by likelihood from the actual evidence.\n3. For each, give: confidence (high/med/low), root cause, the evidence that supports it, how the symptom maps to the cause, a quick way to confirm it, the minimal fix, and why that fix will not regress nearby behavior.\n4. Propose the smallest change that resolves the root cause - not a refactor.\n\n## Honesty escape (important)\n\nIf, after a thorough pass, the evidence shows no concrete bug matching the symptom, do NOT hunt or invent one. Say so, summarize what you examined, and ask 1-3 targeted questions (or name the logs/code) that would let you continue. The report may be a misunderstanding.\n\n## Response Format\n\n**Bottom line**: 1-2 sentences - the most likely cause, or "No bug found in the evidence".\n\n**Hypotheses** (ranked): each with confidence, root cause, evidence, confirm-step, minimal fix, regression note.\n\n**If no bug found**: what you examined + the targeted questions to proceed.\n\n`<SUMMARY>` top hypothesis + confidence + the single next action, under ~120 words `</SUMMARY>`.\n\n## When to Invoke\n\n- A reported runtime error, crash, test failure, or wrong output.\n- After 2+ failed fix attempts (fresh ranked hypotheses).\n\n## When NOT to Invoke\n\n- A design question (use Architect) or a code-quality pass (use Code Reviewer).\n- When the fix is obvious from a first read.\n',
|
|
747
747
|
"arbiter": '# Arbiter\n\nYou are the arbiter. You are given a single question and several independent expert opinions on it, gathered without cross-contamination. Your job is to weigh those opinions against each other and produce one synthesized verdict.\n\n## Context\n\nYou operate as an on-demand specialist. Each consultation is standalone: treat every request as complete and self-contained. You have only the question and the opinions supplied in the request. Do not assume access to the filesystem, tools, or the wider repo beyond what was given. The opinions were produced independently, so they may agree, partly overlap, or directly conflict.\n\n## What You Do\n\n- Read every opinion in full before judging any of them.\n- Identify where the opinions agree and treat strong agreement across independent sources as a signal of confidence.\n- Identify where they disagree and decide which view is best supported by reasoning and evidence, not by tone or length.\n- Dismiss a claim only with a stated reason. Every opinion you set aside must come with a short justification for why it is weaker, wrong, or out of scope.\n- Produce exactly one verdict. Do not hedge by listing every option as equally valid.\n\n## Decision Framework\n\n- **Evidence over confidence**: a well-argued minority view beats a confident but unsupported majority.\n- **Agreement is a prior, not a proof**: convergence raises confidence, but two opinions can share the same mistake. Check the reasoning, not just the count.\n- **Name the disagreement**: when opinions conflict on something that matters, say so explicitly and explain which side you took and why.\n- **No silent drops**: if you ignore an opinion or part of one, give the reason. "Opinion 3 assumed X, which the question rules out" is enough.\n- **Stay in scope**: answer the original question. Do not introduce new requirements the opinions did not raise.\n\n## Response Format\n\nProduce your verdict with these parts, in order:\n\n- **Bottom line**: 2-3 sentences capturing the synthesized answer.\n- **Points of agreement**: where the opinions converge, and how much weight that adds.\n- **Points of disagreement**: each genuine conflict, which side you took, and the reason. Include the reason for any opinion you dismissed.\n- **recommendation**: the single, concrete course of action you endorse.\n- **confidence**: high / medium / low, with one phrase on why.\n\nEnd with `<SUMMARY>` recommendation + confidence + the most important point of disagreement, under ~120 words `</SUMMARY>`.\n\n## Uncertainty\n\n- If the opinions are too thin or contradictory to support any verdict, say so plainly and state what additional input would break the tie. Do not invent evidence to force a decision.\n- Never fabricate file paths, line numbers, signatures, or external references. When unsure, hedge: "Based on the provided opinions...".\n'
|
|
748
748
|
};
|
|
749
749
|
module2.exports = { PROMPTS: PROMPTS2 };
|
|
750
750
|
}
|
|
751
751
|
});
|
|
752
752
|
|
|
753
|
+
// ../../core/analyze.js
|
|
754
|
+
var require_analyze = __commonJS({
|
|
755
|
+
"../../core/analyze.js"(exports2, module2) {
|
|
756
|
+
"use strict";
|
|
757
|
+
var SLOW_FACTOR = 2;
|
|
758
|
+
var MIN_BASELINE_MS = 200;
|
|
759
|
+
var MIN_CALLS = 2;
|
|
760
|
+
var ABS_SLOW_MS = 12e4;
|
|
761
|
+
var HIGH_ERROR_RATE = 0.5;
|
|
762
|
+
var HIGH_AGREEMENT = 0.9;
|
|
763
|
+
var MIN_VOTES = 3;
|
|
764
|
+
var OR_PREFIX = "openrouter:";
|
|
765
|
+
function parseDebugLog(text) {
|
|
766
|
+
if (typeof text !== "string" || text.length === 0) return [];
|
|
767
|
+
const out = [];
|
|
768
|
+
for (const line of text.split("\n")) {
|
|
769
|
+
const trimmed = line.trim();
|
|
770
|
+
if (!trimmed) continue;
|
|
771
|
+
let obj;
|
|
772
|
+
try {
|
|
773
|
+
obj = JSON.parse(trimmed);
|
|
774
|
+
} catch {
|
|
775
|
+
continue;
|
|
776
|
+
}
|
|
777
|
+
if (obj && typeof obj === "object" && typeof obj.event === "string") {
|
|
778
|
+
out.push(
|
|
779
|
+
/** @type {DebugEvent} */
|
|
780
|
+
obj
|
|
781
|
+
);
|
|
782
|
+
}
|
|
783
|
+
}
|
|
784
|
+
return out;
|
|
785
|
+
}
|
|
786
|
+
function percentile(sorted, p) {
|
|
787
|
+
if (!sorted.length) return 0;
|
|
788
|
+
if (sorted.length === 1) return sorted[0];
|
|
789
|
+
const idx = p / 100 * (sorted.length - 1);
|
|
790
|
+
const lo = Math.floor(idx);
|
|
791
|
+
const hi = Math.ceil(idx);
|
|
792
|
+
if (lo === hi) return sorted[lo];
|
|
793
|
+
return sorted[lo] + (sorted[hi] - sorted[lo]) * (idx - lo);
|
|
794
|
+
}
|
|
795
|
+
function aggregateByModel(events) {
|
|
796
|
+
const groups = /* @__PURE__ */ new Map();
|
|
797
|
+
for (const e of Array.isArray(events) ? events : []) {
|
|
798
|
+
if (!e || e.event !== "provider_result" || typeof e.provider !== "string") continue;
|
|
799
|
+
const provider = e.provider;
|
|
800
|
+
const model = typeof e.model === "string" ? e.model : "";
|
|
801
|
+
const key = `${provider}|${model}`;
|
|
802
|
+
let g = groups.get(key);
|
|
803
|
+
if (!g) {
|
|
804
|
+
g = { provider, model, ms: [], errors: 0, calls: 0, tokens: [], efforts: /* @__PURE__ */ new Set(), tools: /* @__PURE__ */ new Set() };
|
|
805
|
+
groups.set(key, g);
|
|
806
|
+
}
|
|
807
|
+
g.calls += 1;
|
|
808
|
+
if (e.isError) g.errors += 1;
|
|
809
|
+
if (typeof e.ms === "number" && Number.isFinite(e.ms)) g.ms.push(e.ms);
|
|
810
|
+
const tot = e.usage && typeof e.usage.totalTokens === "number" ? e.usage.totalTokens : void 0;
|
|
811
|
+
if (typeof tot === "number" && Number.isFinite(tot)) g.tokens.push(tot);
|
|
812
|
+
g.efforts.add(e.reasoningEffort == null ? "n/a" : String(e.reasoningEffort));
|
|
813
|
+
if (typeof e.tool === "string") g.tools.add(e.tool);
|
|
814
|
+
}
|
|
815
|
+
const stats = [];
|
|
816
|
+
for (const g of groups.values()) {
|
|
817
|
+
const sorted = g.ms.slice().sort((a, b) => a - b);
|
|
818
|
+
const mean = sorted.length ? sorted.reduce((a, b) => a + b, 0) / sorted.length : 0;
|
|
819
|
+
stats.push({
|
|
820
|
+
provider: g.provider,
|
|
821
|
+
model: g.model,
|
|
822
|
+
calls: g.calls,
|
|
823
|
+
errors: g.errors,
|
|
824
|
+
errorRate: g.calls ? g.errors / g.calls : 0,
|
|
825
|
+
ms: {
|
|
826
|
+
p50: Math.round(percentile(sorted, 50)),
|
|
827
|
+
p95: Math.round(percentile(sorted, 95)),
|
|
828
|
+
max: sorted.length ? sorted[sorted.length - 1] : 0,
|
|
829
|
+
mean: Math.round(mean)
|
|
830
|
+
},
|
|
831
|
+
meanTokens: g.tokens.length ? Math.round(g.tokens.reduce((a, b) => a + b, 0) / g.tokens.length) : null,
|
|
832
|
+
reasoningEfforts: Array.from(g.efforts).sort(),
|
|
833
|
+
tools: Array.from(g.tools).sort()
|
|
834
|
+
});
|
|
835
|
+
}
|
|
836
|
+
stats.sort((a, b) => b.ms.p95 - a.ms.p95);
|
|
837
|
+
return stats;
|
|
838
|
+
}
|
|
839
|
+
function aggregateAgreement(records) {
|
|
840
|
+
const groups = /* @__PURE__ */ new Map();
|
|
841
|
+
for (const rec of Array.isArray(records) ? records : []) {
|
|
842
|
+
if (!rec || !Array.isArray(rec.opinions)) continue;
|
|
843
|
+
const finalVerdict = typeof rec.verdict === "string" ? rec.verdict : null;
|
|
844
|
+
for (const op of rec.opinions) {
|
|
845
|
+
if (!op || typeof op.provider !== "string") continue;
|
|
846
|
+
const provider = op.provider;
|
|
847
|
+
const model = typeof op.model === "string" ? op.model : "";
|
|
848
|
+
const key = `${provider}|${model}`;
|
|
849
|
+
let g = groups.get(key);
|
|
850
|
+
if (!g) {
|
|
851
|
+
g = { provider, model, votes: 0, agreed: 0, abstained: 0 };
|
|
852
|
+
groups.set(key, g);
|
|
853
|
+
}
|
|
854
|
+
const opVerdict = typeof op.verdict === "string" ? op.verdict : null;
|
|
855
|
+
if (finalVerdict && opVerdict) {
|
|
856
|
+
g.votes += 1;
|
|
857
|
+
if (opVerdict === finalVerdict) g.agreed += 1;
|
|
858
|
+
} else {
|
|
859
|
+
g.abstained += 1;
|
|
860
|
+
}
|
|
861
|
+
}
|
|
862
|
+
}
|
|
863
|
+
const out = [];
|
|
864
|
+
for (const g of groups.values()) {
|
|
865
|
+
out.push({
|
|
866
|
+
provider: g.provider,
|
|
867
|
+
model: g.model,
|
|
868
|
+
votes: g.votes,
|
|
869
|
+
agreed: g.agreed,
|
|
870
|
+
agreementRate: g.votes ? g.agreed / g.votes : null,
|
|
871
|
+
abstained: g.abstained
|
|
872
|
+
});
|
|
873
|
+
}
|
|
874
|
+
out.sort((a, b) => {
|
|
875
|
+
const ar = a.agreementRate == null ? Infinity : a.agreementRate;
|
|
876
|
+
const br = b.agreementRate == null ? Infinity : b.agreementRate;
|
|
877
|
+
return ar - br;
|
|
878
|
+
});
|
|
879
|
+
return out;
|
|
880
|
+
}
|
|
881
|
+
function detectOutliers(stats) {
|
|
882
|
+
const eligible = (Array.isArray(stats) ? stats : []).filter((s) => s.calls >= MIN_CALLS);
|
|
883
|
+
if (!eligible.length) return [];
|
|
884
|
+
const fastestP95 = Math.min(...eligible.map((s) => s.ms.p95));
|
|
885
|
+
const baseline = Math.max(fastestP95, MIN_BASELINE_MS);
|
|
886
|
+
const out = [];
|
|
887
|
+
for (const s of eligible) {
|
|
888
|
+
if (s.errorRate >= HIGH_ERROR_RATE) {
|
|
889
|
+
out.push({ provider: s.provider, model: s.model, kind: "high-error", detail: `${Math.round(s.errorRate * 100)}% of ${s.calls} calls errored` });
|
|
890
|
+
}
|
|
891
|
+
if (s.ms.p95 >= ABS_SLOW_MS) {
|
|
892
|
+
out.push({ provider: s.provider, model: s.model, kind: "slow-absolute", detail: `p95 ${s.ms.p95}ms (>= ${ABS_SLOW_MS}ms)` });
|
|
893
|
+
} else if (s.ms.p95 >= SLOW_FACTOR * baseline) {
|
|
894
|
+
out.push({ provider: s.provider, model: s.model, kind: "slow-relative", detail: `p95 ${s.ms.p95}ms vs fastest-peer baseline ${Math.round(baseline)}ms` });
|
|
895
|
+
}
|
|
896
|
+
}
|
|
897
|
+
return out;
|
|
898
|
+
}
|
|
899
|
+
function leverFor(provider) {
|
|
900
|
+
if (provider.startsWith(OR_PREFIX)) return { kind: "openrouter", alias: provider.slice(OR_PREFIX.length) };
|
|
901
|
+
if (provider === "codex" || provider === "gemini") return { kind: "external" };
|
|
902
|
+
if (provider === "grok") return { kind: "grok" };
|
|
903
|
+
return { kind: "unknown" };
|
|
904
|
+
}
|
|
905
|
+
function recommend(stats, agreement, config) {
|
|
906
|
+
const cfg = config && typeof config === "object" ? config : {};
|
|
907
|
+
const models = cfg.models && typeof cfg.models === "object" ? cfg.models : {};
|
|
908
|
+
const outliers = detectOutliers(stats);
|
|
909
|
+
const agreeBy = /* @__PURE__ */ new Map();
|
|
910
|
+
for (const a of Array.isArray(agreement) ? agreement : []) agreeBy.set(a.provider, a);
|
|
911
|
+
const out = [];
|
|
912
|
+
let slowOpenRouterCount = 0;
|
|
913
|
+
for (const o of outliers) {
|
|
914
|
+
if (o.kind === "high-error") {
|
|
915
|
+
const lever2 = leverFor(o.provider);
|
|
916
|
+
out.push({
|
|
917
|
+
target: lever2.kind === "openrouter" ? "deliberation" : "external",
|
|
918
|
+
subject: o.provider,
|
|
919
|
+
configKey: lever2.kind === "openrouter" ? `models.${lever2.alias}.askAll` : null,
|
|
920
|
+
action: lever2.kind === "openrouter" ? `set models.${lever2.alias}.askAll=false until it stabilizes` : `check the ${o.provider} credentials/CLI session`,
|
|
921
|
+
rationale: o.detail
|
|
922
|
+
});
|
|
923
|
+
continue;
|
|
924
|
+
}
|
|
925
|
+
const lever = leverFor(o.provider);
|
|
926
|
+
const agree = agreeBy.get(o.provider);
|
|
927
|
+
const rarelyDissents = !!(agree && agree.agreementRate != null && agree.votes >= MIN_VOTES && agree.agreementRate >= HIGH_AGREEMENT);
|
|
928
|
+
const valueNote = rarelyDissents ? ` It also agreed with the final verdict ${agree ? Math.round((agree.agreementRate || 0) * 100) : 0}% of ${agree ? agree.votes : 0} votes (rarely adds dissent), so it is the strongest cut candidate.` : "";
|
|
929
|
+
if (lever.kind === "openrouter") {
|
|
930
|
+
slowOpenRouterCount += 1;
|
|
931
|
+
const alias = typeof lever.alias === "string" ? lever.alias : "";
|
|
932
|
+
const entry = models[alias] && typeof models[alias] === "object" ? models[alias] : null;
|
|
933
|
+
const effort = entry && typeof entry.reasoningEffort === "string" ? entry.reasoningEffort : null;
|
|
934
|
+
if (effort && effort !== "low") {
|
|
935
|
+
out.push({ target: "deliberation", subject: o.provider, configKey: `models.${alias}.reasoningEffort`, action: `lower models.${alias}.reasoningEffort (currently ${effort})`, rationale: `Slowest in the panel (${o.detail}).${valueNote}` });
|
|
936
|
+
}
|
|
937
|
+
out.push({ target: "deliberation", subject: o.provider, configKey: `models.${alias}.askAll`, action: `set models.${alias}.askAll=false to drop it from /ask-all fan-out`, rationale: `In parallel fan-out, wall-time is the slowest model (${o.detail}).${valueNote}` });
|
|
938
|
+
} else if (lever.kind === "external") {
|
|
939
|
+
out.push({ target: "external", subject: o.provider, configKey: null, action: o.provider === "codex" ? "lower model_reasoning_effort in ~/.codex/config.toml (or pass it per-call)" : "lower the Gemini/agy reasoning setting", rationale: `Slowest in the panel (${o.detail}); its reasoning lever is outside deliberation's config.${valueNote}` });
|
|
940
|
+
} else {
|
|
941
|
+
out.push({ target: "deliberation", subject: o.provider, configKey: null, action: `consider whether ${o.provider} earns its latency in the panel`, rationale: `${o.detail}.${valueNote}` });
|
|
942
|
+
}
|
|
943
|
+
}
|
|
944
|
+
if (slowOpenRouterCount >= 2) {
|
|
945
|
+
const fanout = cfg.routing && typeof cfg.routing.maxFanout === "number" ? cfg.routing.maxFanout : null;
|
|
946
|
+
out.push({ target: "deliberation", subject: "panel", configKey: "routing.maxFanout", action: fanout ? `lower routing.maxFanout (currently ${fanout})` : "set routing.maxFanout to 1-2", rationale: `${slowOpenRouterCount} OpenRouter models are slow outliers; a smaller fan-out cuts cost and parallel wall-time.` });
|
|
947
|
+
}
|
|
948
|
+
return out;
|
|
949
|
+
}
|
|
950
|
+
function buildAnalysis(events, records, config, meta) {
|
|
951
|
+
const evs = Array.isArray(events) ? events : [];
|
|
952
|
+
const recs = Array.isArray(records) ? records : [];
|
|
953
|
+
const stats = aggregateByModel(evs);
|
|
954
|
+
const agreement = aggregateAgreement(recs);
|
|
955
|
+
const outliers = detectOutliers(stats);
|
|
956
|
+
const recommendations = recommend(stats, agreement, config);
|
|
957
|
+
return {
|
|
958
|
+
stats,
|
|
959
|
+
agreement,
|
|
960
|
+
outliers,
|
|
961
|
+
recommendations,
|
|
962
|
+
meta: {
|
|
963
|
+
logPath: meta && meta.logPath,
|
|
964
|
+
debugEnabled: !!(meta && meta.debugEnabled),
|
|
965
|
+
sessionsPersist: !!(meta && meta.sessionsPersist),
|
|
966
|
+
eventsParsed: evs.length,
|
|
967
|
+
sessionsRead: recs.length,
|
|
968
|
+
insufficientData: stats.length === 0
|
|
969
|
+
}
|
|
970
|
+
};
|
|
971
|
+
}
|
|
972
|
+
module2.exports = {
|
|
973
|
+
SLOW_FACTOR,
|
|
974
|
+
MIN_CALLS,
|
|
975
|
+
ABS_SLOW_MS,
|
|
976
|
+
HIGH_ERROR_RATE,
|
|
977
|
+
HIGH_AGREEMENT,
|
|
978
|
+
MIN_VOTES,
|
|
979
|
+
parseDebugLog,
|
|
980
|
+
percentile,
|
|
981
|
+
aggregateByModel,
|
|
982
|
+
aggregateAgreement,
|
|
983
|
+
detectOutliers,
|
|
984
|
+
recommend,
|
|
985
|
+
buildAnalysis
|
|
986
|
+
};
|
|
987
|
+
}
|
|
988
|
+
});
|
|
989
|
+
|
|
753
990
|
// ../../core/sessions.js
|
|
754
991
|
var require_sessions = __commonJS({
|
|
755
992
|
"../../core/sessions.js"(exports2, module2) {
|
|
@@ -4162,6 +4399,7 @@ var require_openrouter = __commonJS({
|
|
|
4162
4399
|
var { makeRegistry, pinAlias } = require_registry();
|
|
4163
4400
|
var { askAll, askOne, consensus, runToConvergence } = require_orchestrate();
|
|
4164
4401
|
var { PROMPTS } = require_prompts();
|
|
4402
|
+
var analyzeCore = require_analyze();
|
|
4165
4403
|
var ADVISORY = { readOnlyHint: true };
|
|
4166
4404
|
var ASK_PROVIDER = { "ask-gpt": "codex", "ask-gemini": "gemini", "ask-grok": "grok", "ask-openrouter": "openrouter" };
|
|
4167
4405
|
var EXPERTS = ["architect", "plan-reviewer", "scope-analyst", "code-reviewer", "security-analyst", "researcher", "debugger"];
|
|
@@ -4183,6 +4421,15 @@ function panelInputSchema() {
|
|
|
4183
4421
|
}
|
|
4184
4422
|
};
|
|
4185
4423
|
}
|
|
4424
|
+
function analyzeInputSchema() {
|
|
4425
|
+
return {
|
|
4426
|
+
type: "object",
|
|
4427
|
+
properties: {
|
|
4428
|
+
sessions: { type: "integer", description: "How many recent session records to read for the agreement lens (default 50)." },
|
|
4429
|
+
limitBytes: { type: "integer", description: "Tail size of the debug log to read, in bytes (default 1048576)." }
|
|
4430
|
+
}
|
|
4431
|
+
};
|
|
4432
|
+
}
|
|
4186
4433
|
function askOneInputSchema() {
|
|
4187
4434
|
return {
|
|
4188
4435
|
type: "object",
|
|
@@ -4294,7 +4541,8 @@ function toolList() {
|
|
|
4294
4541
|
{ name: "consensus", description: "Run the FULL multi-round consensus convergence loop server-side with a provider arbiter (blind pass + peer fan-out -> adjudicate -> revise) and return the converged verdict. Default depth is `consensus.maxRounds` (config, default 5); pass `maxRounds` to override. Pass `synthesizeAlways:true` for a SINGLE arbiter synthesis pass instead of the loop (best for open questions, not plan convergence): it returns a free-text `synthesis` and `maxRounds` is ignored. Configure the arbiter via `consensus.arbiter` - a concrete provider/openrouter alias runs server-side; `host` mode returns the opinions for YOU to synthesize. Advisory; pass `expert` to apply a persona. NOTE (Claude Code): use the `/consensus` slash command for the transcript-visible host-arbiter loop (it drives `consensus-step`); this tool is the provider-arbiter path for any host.", inputSchema: consensusInputSchema(), annotations: ADVISORY },
|
|
4295
4542
|
{ name: "consensus-step", description: "Client-driven consensus loop where YOU (the host model) are the arbiter, one step per call: action=init (start, returns sessionId + blind prompt) -> record_blind (your pre-commit verdict) -> dispatch_peers (server fans out to the providers) -> submit_adjudication (your verdict + per-issue accept/dismiss/defer) -> submit_revision (your revised plan), looping until converged or consensus.maxRounds rounds (default 5). State is held server-side by sessionId. Advisory.", inputSchema: consensusStepInputSchema(), annotations: ADVISORY },
|
|
4296
4543
|
{ name: "panel", description: "Return the names of the providers `ask-all` WOULD dispatch for the current config + expert (enabled built-ins + eligible OpenRouter aliases, fanout cap applied), WITHOUT calling them. Use this to discover the panel, then issue one `ask-one` call per provider in parallel for visible per-provider progress. Advisory, read-only.", inputSchema: panelInputSchema(), annotations: ADVISORY },
|
|
4297
|
-
{ name: "ask-one", description: "Second opinion from ONE named provider in the active panel (e.g. `codex`, `gemini`, `grok`, `openrouter:<alias>` - get the names from `panel`). Returns the standard result envelope. Issue N of these in parallel (one per `panel` name) so each renders independently as it lands. Advisory, single-shot.", inputSchema: askOneInputSchema(), annotations: ADVISORY }
|
|
4544
|
+
{ name: "ask-one", description: "Second opinion from ONE named provider in the active panel (e.g. `codex`, `gemini`, `grok`, `openrouter:<alias>` - get the names from `panel`). Returns the standard result envelope. Issue N of these in parallel (one per `panel` name) so each renders independently as it lands. Advisory, single-shot.", inputSchema: askOneInputSchema(), annotations: ADVISORY },
|
|
4545
|
+
{ name: "analyze", description: "Analyze recent runs from the opt-in debug log (latency/tokens/reasoning-effort per model) plus the session store (verdict agreement rate), and return advisory tuning suggestions (disable a slow/redundant model in ask-all, lower an OpenRouter model's reasoning, adjust maxFanout). Two lenses reported side by side - timing and agreement are NOT joined (no shared run id). Suggestions are advisory; it writes nothing. Requires `debug.enabled` for the timing lens. Read-only. The `/deliberation:analyze` slash command renders this for humans.", inputSchema: analyzeInputSchema(), annotations: ADVISORY }
|
|
4298
4546
|
];
|
|
4299
4547
|
for (const t of Object.keys(ASK_PROVIDER)) {
|
|
4300
4548
|
tools.push({ name: t, description: `Single-provider second opinion via ${ASK_PROVIDER[t]} (advisory, single-shot). Pass \`expert\` to apply one of the expert personas.`, inputSchema: inputSchema(), annotations: ADVISORY });
|
|
@@ -4789,6 +5037,46 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
4789
5037
|
return { error: /expected status/.test(msg) ? "unexpected-action-for-status" : "step-failed", detail: msg };
|
|
4790
5038
|
}
|
|
4791
5039
|
}
|
|
5040
|
+
function runAnalyze(args) {
|
|
5041
|
+
const fs = require("node:fs");
|
|
5042
|
+
const cfg = getConfig() || {};
|
|
5043
|
+
const dbg = cfg.debug || {};
|
|
5044
|
+
const debugEnabled = !!dbg.enabled;
|
|
5045
|
+
const logPath = typeof dbg.path === "string" && dbg.path || resolveDebugLogPath();
|
|
5046
|
+
const limitBytes = Number.isInteger(args.limitBytes) && args.limitBytes > 0 ? args.limitBytes : 1024 * 1024;
|
|
5047
|
+
let text = "";
|
|
5048
|
+
try {
|
|
5049
|
+
const fd = fs.openSync(logPath, "r");
|
|
5050
|
+
try {
|
|
5051
|
+
const size = fs.fstatSync(fd).size;
|
|
5052
|
+
const start = size > limitBytes ? size - limitBytes : 0;
|
|
5053
|
+
const len = size - start;
|
|
5054
|
+
if (len > 0) {
|
|
5055
|
+
const buf = Buffer.alloc(len);
|
|
5056
|
+
fs.readSync(fd, buf, 0, len, start);
|
|
5057
|
+
text = buf.toString("utf8");
|
|
5058
|
+
if (start > 0) {
|
|
5059
|
+
const nl = text.indexOf("\n");
|
|
5060
|
+
if (nl >= 0) text = text.slice(nl + 1);
|
|
5061
|
+
}
|
|
5062
|
+
}
|
|
5063
|
+
} finally {
|
|
5064
|
+
fs.closeSync(fd);
|
|
5065
|
+
}
|
|
5066
|
+
} catch {
|
|
5067
|
+
}
|
|
5068
|
+
const events = analyzeCore.parseDebugLog(text);
|
|
5069
|
+
const records = [];
|
|
5070
|
+
const persist = persistEnabled();
|
|
5071
|
+
if (persist) {
|
|
5072
|
+
const n = Number.isInteger(args.sessions) && args.sessions > 0 ? args.sessions : 50;
|
|
5073
|
+
for (const e of sessions.listSessions({ dir: sessionsDir }).slice(0, n)) {
|
|
5074
|
+
const rec = sessions.readSession(e.id, { dir: sessionsDir });
|
|
5075
|
+
if (rec) records.push(rec);
|
|
5076
|
+
}
|
|
5077
|
+
}
|
|
5078
|
+
return analyzeCore.buildAnalysis(events, records, cfg, { logPath, debugEnabled, sessionsPersist: persist });
|
|
5079
|
+
}
|
|
4792
5080
|
async function call(name, args) {
|
|
4793
5081
|
const namedExpert = EXPERTS.includes(name) ? name : void 0;
|
|
4794
5082
|
const argExpert = typeof args.expert === "string" ? args.expert : void 0;
|
|
@@ -4818,6 +5106,9 @@ function buildServer({ providers, getConfig, getConfigError, sessionsDir, notify
|
|
|
4818
5106
|
const result = await askOne(p, withPersona(req, expert), { logger: currentLogger(), tool: "ask-one", cache: resultCache });
|
|
4819
5107
|
return jsonResult({ result });
|
|
4820
5108
|
}
|
|
5109
|
+
if (name === "analyze") {
|
|
5110
|
+
return jsonResult(runAnalyze(args));
|
|
5111
|
+
}
|
|
4821
5112
|
if (name === "ask-all") {
|
|
4822
5113
|
const { payload, parts } = await runAskAll(req, expert);
|
|
4823
5114
|
const sid = persistRun("ask-all", req, expert, parts);
|
package/package.json
CHANGED
|
@@ -1,6 +1,6 @@
|
|
|
1
1
|
{
|
|
2
2
|
"name": "@antonbabenko/deliberation-mcp",
|
|
3
|
-
"version": "3.
|
|
3
|
+
"version": "3.4.0",
|
|
4
4
|
"description": "Deliberation for Claude Code and any MCP host - GPT, Gemini, Grok, and OpenRouter expert subagents.",
|
|
5
5
|
"mcpName": "io.github.antonbabenko/deliberation",
|
|
6
6
|
"repository": { "type": "git", "url": "git+https://github.com/antonbabenko/deliberation.git", "directory": "server/mcp" },
|