dsh-aris-panel 0.1.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/LICENSE +21 -0
- package/README.md +98 -0
- package/README_CN.md +87 -0
- package/dsh/checkout.patch.yml +38 -0
- package/dsh/client.js +634 -0
- package/dsh/cordis.patch.yml +44 -0
- package/dsh/index.mjs +76 -0
- package/dsh/run-status.mjs +182 -0
- package/dsh/scope-limits.mjs +50 -0
- package/dsh/workbench.mjs +291 -0
- package/mcp-servers/claude-review/README.md +93 -0
- package/mcp-servers/claude-review/run_with_claude_aws.sh +49 -0
- package/mcp-servers/claude-review/server.py +718 -0
- package/mcp-servers/codex-image2/README.md +65 -0
- package/mcp-servers/codex-image2/server.py +893 -0
- package/mcp-servers/feishu-bridge/requirements.txt +1 -0
- package/mcp-servers/feishu-bridge/server.py +240 -0
- package/mcp-servers/gemini-review/README.md +171 -0
- package/mcp-servers/gemini-review/server.py +1856 -0
- package/mcp-servers/llm-chat/requirements.txt +1 -0
- package/mcp-servers/llm-chat/server.py +664 -0
- package/mcp-servers/manual-review/README.md +133 -0
- package/mcp-servers/manual-review/server.py +910 -0
- package/mcp-servers/manual-review/ui.html +279 -0
- package/mcp-servers/minimax-chat/requirements.txt +1 -0
- package/mcp-servers/minimax-chat/server.py +381 -0
- package/package.json +51 -0
- package/skills/ablation-planner/SKILL.md +123 -0
- package/skills/alphaxiv/SKILL.md +196 -0
- package/skills/analyze-results/SKILL.md +46 -0
- package/skills/arxiv/SKILL.md +248 -0
- package/skills/auto-paper-improvement-loop/SKILL.md +651 -0
- package/skills/auto-review-loop/SKILL.md +1137 -0
- package/skills/auto-review-loop-llm/SKILL.md +259 -0
- package/skills/auto-review-loop-minimax/SKILL.md +302 -0
- package/skills/citation-audit/SKILL.md +502 -0
- package/skills/claims-drafting/SKILL.md +227 -0
- package/skills/comm-lit-review/SKILL.md +297 -0
- package/skills/deepxiv/SKILL.md +263 -0
- package/skills/dse-loop/SKILL.md +296 -0
- package/skills/embodiment-description/SKILL.md +129 -0
- package/skills/exa-search/SKILL.md +205 -0
- package/skills/experiment-audit/SKILL.md +311 -0
- package/skills/experiment-bridge/SKILL.md +376 -0
- package/skills/experiment-plan/SKILL.md +249 -0
- package/skills/experiment-queue/SKILL.md +431 -0
- package/skills/experiment-queue/scripts/build_manifest.py +142 -0
- package/skills/experiment-queue/scripts/queue_manager.py +433 -0
- package/skills/feishu-notify/SKILL.md +156 -0
- package/skills/figure-description/SKILL.md +138 -0
- package/skills/figure-spec/SKILL.md +262 -0
- package/skills/figure-spec/scripts/figure_renderer.py +799 -0
- package/skills/formula-derivation/SKILL.md +280 -0
- package/skills/gemini-search/SKILL.md +231 -0
- package/skills/grant-proposal/SKILL.md +698 -0
- package/skills/idea-creator/SKILL.md +542 -0
- package/skills/idea-discovery/SKILL.md +521 -0
- package/skills/idea-discovery-robot/SKILL.md +363 -0
- package/skills/integrity-forensics/SKILL.md +284 -0
- package/skills/interview-cheatsheet/SKILL.md +245 -0
- package/skills/invention-structuring/SKILL.md +188 -0
- package/skills/jurisdiction-format/SKILL.md +192 -0
- package/skills/kill-argument/SKILL.md +437 -0
- package/skills/mermaid-diagram/SKILL.md +419 -0
- package/skills/meta-apply/SKILL.md +141 -0
- package/skills/meta-optimize/SKILL.md +437 -0
- package/skills/monitor-experiment/SKILL.md +140 -0
- package/skills/novelty-check/SKILL.md +101 -0
- package/skills/openalex/SKILL.md +237 -0
- package/skills/overleaf-sync/SKILL.md +220 -0
- package/skills/paper-claim-audit/SKILL.md +348 -0
- package/skills/paper-compile/SKILL.md +266 -0
- package/skills/paper-figure/SKILL.md +312 -0
- package/skills/paper-illustration/SKILL.md +736 -0
- package/skills/paper-illustration-image2/SKILL.md +391 -0
- package/skills/paper-illustration-image2/scripts/paper_illustration_image2.py +255 -0
- package/skills/paper-plan/SKILL.md +386 -0
- package/skills/paper-poster/SKILL.md +19 -0
- package/skills/paper-poster-html/DESIGN_FINAL.md +176 -0
- package/skills/paper-poster-html/IMPLEMENTATION_CONVENTIONS.md +161 -0
- package/skills/paper-poster-html/LICENSES/posterly-MIT.txt +21 -0
- package/skills/paper-poster-html/NOTICE.md +57 -0
- package/skills/paper-poster-html/SKILL.md +323 -0
- package/skills/paper-poster-html/scripts/_posterly/__init__.py +0 -0
- package/skills/paper-poster-html/scripts/_posterly/canvas.py +200 -0
- package/skills/paper-poster-html/scripts/_posterly/measure.py +588 -0
- package/skills/paper-poster-html/scripts/_posterly/polish.py +498 -0
- package/skills/paper-poster-html/scripts/_posterly/preflight.py +489 -0
- package/skills/paper-poster-html/scripts/_posterly/render.py +215 -0
- package/skills/paper-poster-html/scripts/_posterly/textutil.py +16 -0
- package/skills/paper-poster-html/scripts/_posterly/verify_final.py +171 -0
- package/skills/paper-poster-html/scripts/asset_check.py +897 -0
- package/skills/paper-poster-html/scripts/extract_pdf_figures.py +666 -0
- package/skills/paper-poster-html/scripts/poster_check.py +251 -0
- package/skills/paper-poster-html/scripts/preprocess_figures.py +238 -0
- package/skills/paper-poster-html/scripts/render_preview.py +217 -0
- package/skills/paper-poster-html/scripts/run_gates.py +556 -0
- package/skills/paper-poster-html/scripts/style_check.py +1324 -0
- package/skills/paper-poster-html/templates/COMPONENTS.md +462 -0
- package/skills/paper-poster-html/templates/README.md +170 -0
- package/skills/paper-poster-html/templates/landscape_4col.html +1032 -0
- package/skills/paper-poster-html/templates/landscape_hero.html +1046 -0
- package/skills/paper-poster-html/templates/portrait_2col.html +947 -0
- package/skills/paper-poster-html/templates/tokens/acl.json +9 -0
- package/skills/paper-poster-html/templates/tokens/cvpr.json +9 -0
- package/skills/paper-poster-html/templates/tokens/generic.json +9 -0
- package/skills/paper-poster-html/templates/tokens/iclr.json +9 -0
- package/skills/paper-poster-html/templates/tokens/icml.json +9 -0
- package/skills/paper-poster-html/templates/tokens/neurips.json +9 -0
- package/skills/paper-slides/SKILL.md +635 -0
- package/skills/paper-talk/SKILL.md +381 -0
- package/skills/paper-write/SKILL.md +604 -0
- package/skills/paper-write/templates/IEEEtran.bst +2409 -0
- package/skills/paper-write/templates/IEEEtran.cls +6347 -0
- package/skills/paper-write/templates/iclr2026.tex +84 -0
- package/skills/paper-write/templates/icml2025.tex +87 -0
- package/skills/paper-write/templates/ieee_conference.tex +89 -0
- package/skills/paper-write/templates/ieee_journal.tex +93 -0
- package/skills/paper-write/templates/math_commands.tex +48 -0
- package/skills/paper-write/templates/neurips2025.tex +80 -0
- package/skills/paper-writing/SKILL.md +916 -0
- package/skills/patent-novelty-check/SKILL.md +153 -0
- package/skills/patent-pipeline/SKILL.md +344 -0
- package/skills/patent-review/SKILL.md +203 -0
- package/skills/pixel-art/SKILL.md +137 -0
- package/skills/prior-art-search/SKILL.md +146 -0
- package/skills/proof-checker/SKILL.md +866 -0
- package/skills/proof-orchestrator/NOTICE.md +24 -0
- package/skills/proof-orchestrator/SKILL.md +254 -0
- package/skills/proof-orchestrator/references/audit-output-contract.md +126 -0
- package/skills/proof-orchestrator/references/deepseek-routing.md +74 -0
- package/skills/proof-orchestrator/references/dispatch-prompts.md +227 -0
- package/skills/proof-orchestrator/references/notation-audit.md +135 -0
- package/skills/proof-orchestrator/references/proof-audit-rubric.md +70 -0
- package/skills/proof-orchestrator/references/stress-tests.md +38 -0
- package/skills/proof-writer/SKILL.md +223 -0
- package/skills/qzcli/SKILL.md +324 -0
- package/skills/rebuttal/SKILL.md +376 -0
- package/skills/render-html/SKILL.md +316 -0
- package/skills/render-html/scripts/render_html.py +1006 -0
- package/skills/render-html/scripts/templates/academic.html +703 -0
- package/skills/render-html/scripts/templates/dashboard.html +333 -0
- package/skills/research-lit/SKILL.md +756 -0
- package/skills/research-pipeline/SKILL.md +384 -0
- package/skills/research-refine/SKILL.md +770 -0
- package/skills/research-refine-pipeline/SKILL.md +186 -0
- package/skills/research-review/SKILL.md +198 -0
- package/skills/research-wiki/SKILL.md +461 -0
- package/skills/resubmit-pipeline/SKILL.md +447 -0
- package/skills/result-to-claim/SKILL.md +311 -0
- package/skills/run-experiment/SKILL.md +313 -0
- package/skills/semantic-scholar/SKILL.md +236 -0
- package/skills/serverless-modal/SKILL.md +335 -0
- package/skills/shared-references/acceptance-gate.md +324 -0
- package/skills/shared-references/assurance-contract.md +248 -0
- package/skills/shared-references/capture-antipatterns.md +78 -0
- package/skills/shared-references/citation-discipline.md +583 -0
- package/skills/shared-references/compute-env-contract.md +163 -0
- package/skills/shared-references/effort-contract.md +183 -0
- package/skills/shared-references/evidence-precheck.md +65 -0
- package/skills/shared-references/experiment-integrity.md +49 -0
- package/skills/shared-references/external-cadence.md +326 -0
- package/skills/shared-references/fan-out-pattern.md +366 -0
- package/skills/shared-references/injection-hygiene.md +127 -0
- package/skills/shared-references/integration-contract.md +461 -0
- package/skills/shared-references/output-composition.md +93 -0
- package/skills/shared-references/output-language.md +45 -0
- package/skills/shared-references/output-manifest.md +49 -0
- package/skills/shared-references/output-versioning.md +111 -0
- package/skills/shared-references/patent-format-cn.md +199 -0
- package/skills/shared-references/patent-format-ep.md +173 -0
- package/skills/shared-references/patent-format-us.md +161 -0
- package/skills/shared-references/patent-writing-principles.md +197 -0
- package/skills/shared-references/prior-art-databases.md +141 -0
- package/skills/shared-references/resumable-runs.md +109 -0
- package/skills/shared-references/review-scope-limits.md +81 -0
- package/skills/shared-references/review-tracing.md +391 -0
- package/skills/shared-references/reviewer-independence.md +79 -0
- package/skills/shared-references/reviewer-routing.md +852 -0
- package/skills/shared-references/skill-governance.md +104 -0
- package/skills/shared-references/taste-calibration.md +85 -0
- package/skills/shared-references/venue-checklists.md +114 -0
- package/skills/shared-references/wiki-helper-resolution.md +134 -0
- package/skills/shared-references/writing-principles.md +525 -0
- package/skills/skills-codex/README.md +102 -0
- package/skills/skills-codex/README_CN.md +100 -0
- package/skills/skills-codex/ablation-planner/SKILL.md +126 -0
- package/skills/skills-codex/alphaxiv/SKILL.md +186 -0
- package/skills/skills-codex/analyze-results/SKILL.md +45 -0
- package/skills/skills-codex/arxiv/SKILL.md +210 -0
- package/skills/skills-codex/auto-paper-improvement-loop/SKILL.md +574 -0
- package/skills/skills-codex/auto-review-loop/SKILL.md +500 -0
- package/skills/skills-codex/auto-review-loop-llm/SKILL.md +247 -0
- package/skills/skills-codex/auto-review-loop-minimax/SKILL.md +290 -0
- package/skills/skills-codex/citation-audit/SKILL.md +504 -0
- package/skills/skills-codex/claims-drafting/SKILL.md +239 -0
- package/skills/skills-codex/comm-lit-review/SKILL.md +299 -0
- package/skills/skills-codex/comm-lit-review/references/domain-taxonomy.md +57 -0
- package/skills/skills-codex/comm-lit-review/references/output-template.md +37 -0
- package/skills/skills-codex/comm-lit-review/references/source-policy.md +99 -0
- package/skills/skills-codex/comm-lit-review/references/venue-tiering.md +112 -0
- package/skills/skills-codex/deepxiv/SKILL.md +142 -0
- package/skills/skills-codex/dse-loop/SKILL.md +285 -0
- package/skills/skills-codex/embodiment-description/SKILL.md +129 -0
- package/skills/skills-codex/exa-search/SKILL.md +192 -0
- package/skills/skills-codex/experiment-audit/SKILL.md +286 -0
- package/skills/skills-codex/experiment-bridge/SKILL.md +356 -0
- package/skills/skills-codex/experiment-plan/SKILL.md +249 -0
- package/skills/skills-codex/experiment-queue/SKILL.md +401 -0
- package/skills/skills-codex/feishu-notify/SKILL.md +155 -0
- package/skills/skills-codex/figure-description/SKILL.md +138 -0
- package/skills/skills-codex/figure-spec/SKILL.md +252 -0
- package/skills/skills-codex/formula-derivation/SKILL.md +280 -0
- package/skills/skills-codex/gemini-search/SKILL.md +205 -0
- package/skills/skills-codex/grant-proposal/SKILL.md +626 -0
- package/skills/skills-codex/idea-creator/SKILL.md +405 -0
- package/skills/skills-codex/idea-discovery/SKILL.md +475 -0
- package/skills/skills-codex/idea-discovery-robot/SKILL.md +362 -0
- package/skills/skills-codex/integrity-forensics/SKILL.md +106 -0
- package/skills/skills-codex/interview-cheatsheet/SKILL.md +245 -0
- package/skills/skills-codex/invention-structuring/SKILL.md +188 -0
- package/skills/skills-codex/jurisdiction-format/SKILL.md +192 -0
- package/skills/skills-codex/kill-argument/SKILL.md +403 -0
- package/skills/skills-codex/mermaid-diagram/SKILL.md +379 -0
- package/skills/skills-codex/meta-apply/SKILL.md +154 -0
- package/skills/skills-codex/meta-optimize/SKILL.md +348 -0
- package/skills/skills-codex/monitor-experiment/SKILL.md +98 -0
- package/skills/skills-codex/novelty-check/SKILL.md +89 -0
- package/skills/skills-codex/openalex/SKILL.md +228 -0
- package/skills/skills-codex/overleaf-sync/SKILL.md +220 -0
- package/skills/skills-codex/paper-claim-audit/SKILL.md +350 -0
- package/skills/skills-codex/paper-compile/SKILL.md +253 -0
- package/skills/skills-codex/paper-figure/SKILL.md +311 -0
- package/skills/skills-codex/paper-illustration/SKILL.md +690 -0
- package/skills/skills-codex/paper-illustration-image2/SKILL.md +383 -0
- package/skills/skills-codex/paper-illustration-image2/scripts/paper_illustration_image2.py +255 -0
- package/skills/skills-codex/paper-plan/SKILL.md +278 -0
- package/skills/skills-codex/paper-poster/SKILL.md +19 -0
- package/skills/skills-codex/paper-poster-html/SKILL.md +377 -0
- package/skills/skills-codex/paper-slides/SKILL.md +571 -0
- package/skills/skills-codex/paper-talk/SKILL.md +381 -0
- package/skills/skills-codex/paper-write/SKILL.md +411 -0
- package/skills/skills-codex/paper-write/templates/IEEEtran.bst +2409 -0
- package/skills/skills-codex/paper-write/templates/IEEEtran.cls +6347 -0
- package/skills/skills-codex/paper-write/templates/aaai2026.bst +1493 -0
- package/skills/skills-codex/paper-write/templates/aaai2026.sty +315 -0
- package/skills/skills-codex/paper-write/templates/aaai2026.tex +952 -0
- package/skills/skills-codex/paper-write/templates/acl.sty +312 -0
- package/skills/skills-codex/paper-write/templates/acl2026.tex +377 -0
- package/skills/skills-codex/paper-write/templates/acl_natbib.bst +1940 -0
- package/skills/skills-codex/paper-write/templates/acm.bst +3081 -0
- package/skills/skills-codex/paper-write/templates/acm_mm2026.tex +204 -0
- package/skills/skills-codex/paper-write/templates/acmart.cls +3520 -0
- package/skills/skills-codex/paper-write/templates/cvpr.bst +1448 -0
- package/skills/skills-codex/paper-write/templates/cvpr.sty +508 -0
- package/skills/skills-codex/paper-write/templates/cvpr2026.tex +63 -0
- package/skills/skills-codex/paper-write/templates/iclr2026.tex +84 -0
- package/skills/skills-codex/paper-write/templates/iclr2026_conference.bst +1440 -0
- package/skills/skills-codex/paper-write/templates/iclr2026_conference.sty +246 -0
- package/skills/skills-codex/paper-write/templates/icml2026.sty +767 -0
- package/skills/skills-codex/paper-write/templates/icml2026.tex +662 -0
- package/skills/skills-codex/paper-write/templates/ieee_conference.tex +89 -0
- package/skills/skills-codex/paper-write/templates/ieee_journal.tex +93 -0
- package/skills/skills-codex/paper-write/templates/math_commands.tex +48 -0
- package/skills/skills-codex/paper-write/templates/neurips2026.tex +493 -0
- package/skills/skills-codex/paper-write/templates/neurips_2026.sty +437 -0
- package/skills/skills-codex/paper-writing/SKILL.md +731 -0
- package/skills/skills-codex/patent-novelty-check/SKILL.md +153 -0
- package/skills/skills-codex/patent-pipeline/SKILL.md +344 -0
- package/skills/skills-codex/patent-review/SKILL.md +202 -0
- package/skills/skills-codex/pixel-art/SKILL.md +139 -0
- package/skills/skills-codex/prior-art-search/SKILL.md +146 -0
- package/skills/skills-codex/proof-checker/SKILL.md +554 -0
- package/skills/skills-codex/proof-orchestrator/SKILL.md +260 -0
- package/skills/skills-codex/proof-orchestrator/references/audit-output-contract.md +126 -0
- package/skills/skills-codex/proof-orchestrator/references/deepseek-routing.md +76 -0
- package/skills/skills-codex/proof-orchestrator/references/dispatch-prompts.md +227 -0
- package/skills/skills-codex/proof-orchestrator/references/notation-audit.md +135 -0
- package/skills/skills-codex/proof-orchestrator/references/proof-audit-rubric.md +70 -0
- package/skills/skills-codex/proof-orchestrator/references/stress-tests.md +38 -0
- package/skills/skills-codex/proof-writer/SKILL.md +222 -0
- package/skills/skills-codex/qzcli/SKILL.md +324 -0
- package/skills/skills-codex/rebuttal/SKILL.md +305 -0
- package/skills/skills-codex/render-html/SKILL.md +305 -0
- package/skills/skills-codex/render-html/scripts/__pycache__/render_html.cpython-314.pyc +0 -0
- package/skills/skills-codex/render-html/scripts/render_html.py +909 -0
- package/skills/skills-codex/render-html/scripts/templates/academic.html +342 -0
- package/skills/skills-codex/render-html/scripts/templates/dashboard.html +333 -0
- package/skills/skills-codex/research-lit/SKILL.md +464 -0
- package/skills/skills-codex/research-pipeline/SKILL.md +340 -0
- package/skills/skills-codex/research-refine/SKILL.md +721 -0
- package/skills/skills-codex/research-refine-pipeline/SKILL.md +186 -0
- package/skills/skills-codex/research-review/SKILL.md +135 -0
- package/skills/skills-codex/research-wiki/SKILL.md +421 -0
- package/skills/skills-codex/resubmit-pipeline/SKILL.md +444 -0
- package/skills/skills-codex/result-to-claim/SKILL.md +246 -0
- package/skills/skills-codex/run-experiment/SKILL.md +236 -0
- package/skills/skills-codex/semantic-scholar/SKILL.md +219 -0
- package/skills/skills-codex/serverless-modal/SKILL.md +335 -0
- package/skills/skills-codex/shared-references/acceptance-gate.md +336 -0
- package/skills/skills-codex/shared-references/assurance-contract.md +139 -0
- package/skills/skills-codex/shared-references/capture-antipatterns.md +84 -0
- package/skills/skills-codex/shared-references/citation-discipline.md +452 -0
- package/skills/skills-codex/shared-references/compute-env-contract.md +163 -0
- package/skills/skills-codex/shared-references/effort-contract.md +143 -0
- package/skills/skills-codex/shared-references/evidence-precheck.md +73 -0
- package/skills/skills-codex/shared-references/experiment-integrity.md +49 -0
- package/skills/skills-codex/shared-references/external-cadence.md +334 -0
- package/skills/skills-codex/shared-references/fan-out-pattern.md +375 -0
- package/skills/skills-codex/shared-references/injection-hygiene.md +132 -0
- package/skills/skills-codex/shared-references/integration-contract.md +372 -0
- package/skills/skills-codex/shared-references/output-composition.md +98 -0
- package/skills/skills-codex/shared-references/output-language.md +45 -0
- package/skills/skills-codex/shared-references/output-manifest.md +40 -0
- package/skills/skills-codex/shared-references/output-versioning.md +111 -0
- package/skills/skills-codex/shared-references/patent-format-cn.md +199 -0
- package/skills/skills-codex/shared-references/patent-format-ep.md +173 -0
- package/skills/skills-codex/shared-references/patent-format-us.md +161 -0
- package/skills/skills-codex/shared-references/patent-writing-principles.md +197 -0
- package/skills/skills-codex/shared-references/prior-art-databases.md +141 -0
- package/skills/skills-codex/shared-references/resumable-runs.md +125 -0
- package/skills/skills-codex/shared-references/review-scope-limits.md +81 -0
- package/skills/skills-codex/shared-references/review-tracing.md +144 -0
- package/skills/skills-codex/shared-references/reviewer-independence.md +66 -0
- package/skills/skills-codex/shared-references/reviewer-routing.md +128 -0
- package/skills/skills-codex/shared-references/skill-governance.md +119 -0
- package/skills/skills-codex/shared-references/taste-calibration.md +90 -0
- package/skills/skills-codex/shared-references/venue-checklists.md +73 -0
- package/skills/skills-codex/shared-references/wiki-helper-resolution.md +69 -0
- package/skills/skills-codex/shared-references/writing-principles.md +525 -0
- package/skills/skills-codex/slides-polish/SKILL.md +563 -0
- package/skills/skills-codex/specification-writing/SKILL.md +211 -0
- package/skills/skills-codex/system-profile/SKILL.md +103 -0
- package/skills/skills-codex/training-check/SKILL.md +83 -0
- package/skills/skills-codex/vast-gpu/SKILL.md +394 -0
- package/skills/skills-codex/web-debug-search/SKILL.md +334 -0
- package/skills/skills-codex/wiki-enrich/SKILL.md +255 -0
- package/skills/skills-codex/writing-systems-papers/SKILL.md +184 -0
- package/skills/skills-codex-claude-review/README.md +79 -0
- package/skills/skills-codex-claude-review/README_CN.md +78 -0
- package/skills/skills-codex-claude-review/auto-paper-improvement-loop/SKILL.md +581 -0
- package/skills/skills-codex-claude-review/auto-review-loop/SKILL.md +510 -0
- package/skills/skills-codex-claude-review/novelty-check/SKILL.md +102 -0
- package/skills/skills-codex-claude-review/paper-figure/SKILL.md +319 -0
- package/skills/skills-codex-claude-review/paper-plan/SKILL.md +287 -0
- package/skills/skills-codex-claude-review/paper-write/SKILL.md +420 -0
- package/skills/skills-codex-claude-review/research-refine/SKILL.md +732 -0
- package/skills/skills-codex-claude-review/research-review/SKILL.md +149 -0
- package/skills/skills-codex-gemini-review/README.md +176 -0
- package/skills/skills-codex-gemini-review/README_CN.md +175 -0
- package/skills/skills-codex-gemini-review/auto-paper-improvement-loop/SKILL.md +331 -0
- package/skills/skills-codex-gemini-review/auto-review-loop/SKILL.md +304 -0
- package/skills/skills-codex-gemini-review/grant-proposal/SKILL.md +630 -0
- package/skills/skills-codex-gemini-review/idea-creator/SKILL.md +263 -0
- package/skills/skills-codex-gemini-review/idea-discovery/SKILL.md +275 -0
- package/skills/skills-codex-gemini-review/idea-discovery-robot/SKILL.md +365 -0
- package/skills/skills-codex-gemini-review/novelty-check/SKILL.md +92 -0
- package/skills/skills-codex-gemini-review/paper-figure/SKILL.md +289 -0
- package/skills/skills-codex-gemini-review/paper-plan/SKILL.md +265 -0
- package/skills/skills-codex-gemini-review/paper-poster-html/SKILL.md +102 -0
- package/skills/skills-codex-gemini-review/paper-slides/SKILL.md +582 -0
- package/skills/skills-codex-gemini-review/paper-write/SKILL.md +346 -0
- package/skills/skills-codex-gemini-review/paper-writing/SKILL.md +312 -0
- package/skills/skills-codex-gemini-review/research-refine/SKILL.md +674 -0
- package/skills/skills-codex-gemini-review/research-review/SKILL.md +112 -0
- package/skills/slides-polish/SKILL.md +565 -0
- package/skills/specification-writing/SKILL.md +211 -0
- package/skills/system-profile/SKILL.md +103 -0
- package/skills/training-check/SKILL.md +132 -0
- package/skills/vast-gpu/SKILL.md +394 -0
- package/skills/web-debug-search/SKILL.md +334 -0
- package/skills/wiki-enrich/SKILL.md +257 -0
- package/skills/writing-systems-papers/SKILL.md +184 -0
- package/templates/CLAUDE_MD_TEMPLATE.md +29 -0
- package/templates/EXPERIMENT_LOG_TEMPLATE.md +47 -0
- package/templates/EXPERIMENT_PLAN_TEMPLATE.md +51 -0
- package/templates/EXPERIMENT_PLAN_TEMPLATE_CN.md +53 -0
- package/templates/FINDINGS_TEMPLATE.md +52 -0
- package/templates/IDEA_CANDIDATES_TEMPLATE.md +47 -0
- package/templates/IDEA_CANDIDATES_TEMPLATE_CN.md +47 -0
- package/templates/INVENTION_BRIEF_TEMPLATE.md +87 -0
- package/templates/MANIFEST_TEMPLATE.md +7 -0
- package/templates/NARRATIVE_REPORT_TEMPLATE.md +49 -0
- package/templates/PAPER_PLAN_TEMPLATE.md +47 -0
- package/templates/PATENT_CLAIMS_TEMPLATE.md +78 -0
- package/templates/PATENT_SPECIFICATION_TEMPLATE.md +68 -0
- package/templates/README.md +57 -0
- package/templates/RESEARCH_BRIEF_TEMPLATE.md +35 -0
- package/templates/RESEARCH_BRIEF_TEMPLATE_CN.md +41 -0
- package/templates/RESEARCH_CONTRACT_TEMPLATE.md +60 -0
- package/templates/claude-hooks/corpus_write_guard.json +16 -0
- package/templates/claude-hooks/corpus_write_guard.py +85 -0
- package/templates/claude-hooks/meta_logging.json +74 -0
- package/templates/gitignore-trace.txt +3 -0
- package/tools/__pycache__/check_skills_inventory.cpython-314.pyc +0 -0
- package/tools/arxiv_fetch.py +311 -0
- package/tools/capture_filter.py +126 -0
- package/tools/check_skills_inventory.py +273 -0
- package/tools/convert_skills_to_llm_chat.py +282 -0
- package/tools/copilot_native_evidence.py +818 -0
- package/tools/deepxiv_fetch.py +213 -0
- package/tools/evidence_check.py +212 -0
- package/tools/exa_search.py +425 -0
- package/tools/experiment_queue/README.md +118 -0
- package/tools/experiment_queue/build_manifest.py +44 -0
- package/tools/experiment_queue/queue_manager.py +44 -0
- package/tools/extract_paper_style.py +560 -0
- package/tools/figure_renderer.py +69 -0
- package/tools/forensics_gate.py +669 -0
- package/tools/generate_codex_claude_review_overrides.py +299 -0
- package/tools/idea_discovery_gate.py +256 -0
- package/tools/install_aris.ps1 +1372 -0
- package/tools/install_aris.sh +1370 -0
- package/tools/install_aris_codex.sh +1023 -0
- package/tools/install_aris_copilot.sh +1052 -0
- package/tools/iteration_log.py +143 -0
- package/tools/lint_skills_helpers.sh +84 -0
- package/tools/meta_opt/check_ready.sh +80 -0
- package/tools/meta_opt/log_event.sh +91 -0
- package/tools/meta_opt/trigger_eval.py +280 -0
- package/tools/meta_opt/trigger_evals.sample.json +28 -0
- package/tools/openalex_fetch.py +326 -0
- package/tools/overleaf_audit.sh +104 -0
- package/tools/overleaf_setup.sh +150 -0
- package/tools/paper_illustration_image2.py +62 -0
- package/tools/provenance.py +294 -0
- package/tools/research_wiki.py +1720 -0
- package/tools/review_gate.py +502 -0
- package/tools/run_state.py +399 -0
- package/tools/save_trace.sh +477 -0
- package/tools/semantic_scholar_fetch.py +438 -0
- package/tools/skill-groups.tsv +116 -0
- package/tools/skill_picker.py +238 -0
- package/tools/smart_update.ps1 +521 -0
- package/tools/smart_update.sh +591 -0
- package/tools/smart_update_codex.sh +419 -0
- package/tools/smart_update_copilot.sh +605 -0
- package/tools/threat_scan.py +222 -0
- package/tools/verify_paper_audits.sh +487 -0
- package/tools/verify_papers.py +613 -0
- package/tools/verify_wiki_coverage.sh +176 -0
- package/tools/watchdog.py +485 -0
|
@@ -0,0 +1 @@
|
|
|
1
|
+
httpx>=0.27,<1.0
|
|
@@ -0,0 +1,664 @@
|
|
|
1
|
+
#!/usr/bin/env python3
|
|
2
|
+
"""Generic LLM Chat MCP Server - Supports any OpenAI-compatible API
|
|
3
|
+
|
|
4
|
+
Environment Variables:
|
|
5
|
+
LLM_API_KEY - API key (required)
|
|
6
|
+
LLM_BASE_URL - API base URL (default: https://api.openai.com/v1)
|
|
7
|
+
LLM_MODEL - Model name (default: gpt-4o)
|
|
8
|
+
LLM_FALLBACK_MODEL - Fallback model on 504 timeout (default: gpt-4o)
|
|
9
|
+
LLM_SERVER_NAME - Server name for MCP (default: llm-chat)
|
|
10
|
+
LLM_REVIEW_FALLBACK_ENABLED
|
|
11
|
+
- Expose review/review_reply tools when true (default: false)
|
|
12
|
+
|
|
13
|
+
Supported Providers (examples):
|
|
14
|
+
OpenAI: LLM_BASE_URL=https://api.openai.com/v1 LLM_MODEL=gpt-4o
|
|
15
|
+
DeepSeek: LLM_BASE_URL=https://api.deepseek.com/v1 LLM_MODEL=deepseek-chat
|
|
16
|
+
Kimi: LLM_BASE_URL=https://api.moonshot.cn/v1 LLM_MODEL=moonshot-v1-32k
|
|
17
|
+
MiniMax: LLM_BASE_URL=https://api.minimax.io/v1 LLM_MODEL=MiniMax-M3
|
|
18
|
+
"""
|
|
19
|
+
|
|
20
|
+
import datetime
|
|
21
|
+
import json
|
|
22
|
+
import os
|
|
23
|
+
import re
|
|
24
|
+
import sys
|
|
25
|
+
import tempfile
|
|
26
|
+
import uuid
|
|
27
|
+
from pathlib import Path
|
|
28
|
+
import httpx
|
|
29
|
+
|
|
30
|
+
_stdio_initialized = False
|
|
31
|
+
|
|
32
|
+
|
|
33
|
+
def _init_stdio():
|
|
34
|
+
"""Rebind stdio to raw unbuffered binary streams for MCP framing.
|
|
35
|
+
|
|
36
|
+
Deferred into a function (called at the top of main()) so that merely
|
|
37
|
+
IMPORTING this module has no stdio side effects. os.fdopen(fileno) defaults
|
|
38
|
+
to closefd=True and thus seizes ownership of the fd; doing that at import
|
|
39
|
+
time under a test harness that captures stdio (pytest fd-capture) closes the
|
|
40
|
+
harness's capture fd and corrupts capture for every subsequent test. Real
|
|
41
|
+
server launch (python server.py) still calls this first via main(), so
|
|
42
|
+
runtime behavior is unchanged. Idempotent."""
|
|
43
|
+
global _stdio_initialized
|
|
44
|
+
if _stdio_initialized:
|
|
45
|
+
return
|
|
46
|
+
# Force unbuffered stdout/stdin
|
|
47
|
+
sys.stdout = os.fdopen(sys.stdout.fileno(), 'wb', buffering=0)
|
|
48
|
+
sys.stdin = os.fdopen(sys.stdin.fileno(), 'rb', buffering=0)
|
|
49
|
+
_stdio_initialized = True
|
|
50
|
+
|
|
51
|
+
# Configuration from environment
|
|
52
|
+
API_KEY = os.environ.get("LLM_API_KEY", "")
|
|
53
|
+
BASE_URL = os.environ.get("LLM_BASE_URL", "https://api.openai.com/v1")
|
|
54
|
+
DEFAULT_MODEL = os.environ.get("LLM_MODEL", "gpt-4o")
|
|
55
|
+
FALLBACK_MODEL = os.environ.get("LLM_FALLBACK_MODEL", "gpt-4o")
|
|
56
|
+
SERVER_NAME = os.environ.get("LLM_SERVER_NAME", "llm-chat")
|
|
57
|
+
REVIEW_FALLBACK_ENABLED = os.environ.get(
|
|
58
|
+
"LLM_REVIEW_FALLBACK_ENABLED", "false"
|
|
59
|
+
).strip().lower() in {"1", "true", "yes", "on"}
|
|
60
|
+
|
|
61
|
+
# Debug logging
|
|
62
|
+
DEBUG_LOG = os.path.join(tempfile.gettempdir(), f"{SERVER_NAME}-mcp-debug.log")
|
|
63
|
+
|
|
64
|
+
def debug_log(msg):
|
|
65
|
+
try:
|
|
66
|
+
with open(DEBUG_LOG, "a") as f:
|
|
67
|
+
f.write(f"{datetime.datetime.now()}: {msg}\n")
|
|
68
|
+
f.flush()
|
|
69
|
+
except Exception:
|
|
70
|
+
pass
|
|
71
|
+
|
|
72
|
+
def log_error(msg):
|
|
73
|
+
try:
|
|
74
|
+
with open(DEBUG_LOG, "a") as f:
|
|
75
|
+
f.write(f"{datetime.datetime.now()}: ERROR: {msg}\n")
|
|
76
|
+
except Exception:
|
|
77
|
+
pass
|
|
78
|
+
|
|
79
|
+
debug_log(f"=== {SERVER_NAME} MCP Server Starting (v2.2) ===")
|
|
80
|
+
debug_log(f"BASE_URL: {BASE_URL}")
|
|
81
|
+
debug_log(f"MODEL: {DEFAULT_MODEL}")
|
|
82
|
+
debug_log(f"FALLBACK_MODEL: {FALLBACK_MODEL}")
|
|
83
|
+
debug_log(f"REVIEW_FALLBACK_ENABLED: {REVIEW_FALLBACK_ENABLED}")
|
|
84
|
+
debug_log(f"API_KEY set: {bool(API_KEY)}")
|
|
85
|
+
|
|
86
|
+
_use_ndjson = False
|
|
87
|
+
_review_threads = {}
|
|
88
|
+
|
|
89
|
+
def send_response(response):
|
|
90
|
+
global _use_ndjson
|
|
91
|
+
json_str = json.dumps(response, separators=(',', ':'))
|
|
92
|
+
json_bytes = json_str.encode('utf-8')
|
|
93
|
+
|
|
94
|
+
if _use_ndjson:
|
|
95
|
+
output = json_bytes + b'\n'
|
|
96
|
+
else:
|
|
97
|
+
header = f"Content-Length: {len(json_bytes)}\r\n\r\n".encode('utf-8')
|
|
98
|
+
output = header + json_bytes
|
|
99
|
+
|
|
100
|
+
sys.stdout.write(output)
|
|
101
|
+
sys.stdout.flush()
|
|
102
|
+
|
|
103
|
+
def _call_llm_detailed(messages, model=None):
|
|
104
|
+
"""Call LLM Chat Completions API and return content, error, actual model."""
|
|
105
|
+
if not API_KEY:
|
|
106
|
+
return None, "LLM_API_KEY environment variable not set", None
|
|
107
|
+
|
|
108
|
+
use_model = model or DEFAULT_MODEL
|
|
109
|
+
url = f"{BASE_URL.rstrip('/')}/chat/completions"
|
|
110
|
+
headers = {
|
|
111
|
+
"Content-Type": "application/json",
|
|
112
|
+
"Authorization": f"Bearer {API_KEY}"
|
|
113
|
+
}
|
|
114
|
+
|
|
115
|
+
# Try: original model → retry same model → fallback model.
|
|
116
|
+
# This retrying behavior is intentionally legacy-chat-only. Verdict-bearing
|
|
117
|
+
# review/review_reply calls use _call_llm_review_once below so ambiguous
|
|
118
|
+
# failures can never duplicate a paid review or produce conflicting verdicts.
|
|
119
|
+
for attempt in range(3):
|
|
120
|
+
current_model = use_model if attempt < 2 else FALLBACK_MODEL
|
|
121
|
+
payload = {
|
|
122
|
+
"model": current_model,
|
|
123
|
+
"messages": messages,
|
|
124
|
+
"max_tokens": 4096
|
|
125
|
+
}
|
|
126
|
+
|
|
127
|
+
debug_log(f"Calling LLM API (attempt {attempt + 1}): model={current_model}")
|
|
128
|
+
|
|
129
|
+
try:
|
|
130
|
+
with httpx.Client(timeout=300.0) as client:
|
|
131
|
+
response = client.post(url, headers=headers, json=payload)
|
|
132
|
+
|
|
133
|
+
if response.status_code == 504:
|
|
134
|
+
debug_log(f"504 Gateway Timeout on attempt {attempt + 1} with model {current_model}")
|
|
135
|
+
if attempt < 2:
|
|
136
|
+
continue # retry or fallback
|
|
137
|
+
|
|
138
|
+
if response.status_code != 200:
|
|
139
|
+
error_msg = f"API error {response.status_code}: {response.text[:500]}"
|
|
140
|
+
debug_log(f"API error: {error_msg}")
|
|
141
|
+
return None, error_msg, None
|
|
142
|
+
|
|
143
|
+
data = response.json()
|
|
144
|
+
try:
|
|
145
|
+
content = data["choices"][0]["message"]["content"]
|
|
146
|
+
except (KeyError, IndexError, TypeError) as e:
|
|
147
|
+
return None, f"Unexpected API response structure: {e}", None
|
|
148
|
+
|
|
149
|
+
# Prefer the model identity reported by the provider. If absent,
|
|
150
|
+
# use the exact model id sent in this successful request.
|
|
151
|
+
actual_model = str(data.get("model") or current_model).strip()
|
|
152
|
+
|
|
153
|
+
if current_model != use_model:
|
|
154
|
+
fallback_note = f"\n\n[Note: Used fallback model {current_model} after 504 timeout with {use_model}]"
|
|
155
|
+
content = fallback_note + "\n" + content
|
|
156
|
+
debug_log(f"API success with fallback model {actual_model}, response length: {len(content)}")
|
|
157
|
+
elif attempt > 0:
|
|
158
|
+
debug_log(f"API success on retry (attempt {attempt + 1}), response length: {len(content)}")
|
|
159
|
+
else:
|
|
160
|
+
debug_log(f"API success, response length: {len(content)}")
|
|
161
|
+
return content, None, actual_model
|
|
162
|
+
except Exception as e:
|
|
163
|
+
debug_log(f"API exception on attempt {attempt + 1}: {str(e)}")
|
|
164
|
+
if attempt == 2:
|
|
165
|
+
return None, str(e), None
|
|
166
|
+
|
|
167
|
+
return None, "All attempts failed with 504 Gateway Timeout", None
|
|
168
|
+
|
|
169
|
+
def call_llm(messages, model=None):
|
|
170
|
+
"""Backward-compatible two-value wrapper for the existing chat tool."""
|
|
171
|
+
content, error, _actual_model = _call_llm_detailed(messages, model)
|
|
172
|
+
return content, error
|
|
173
|
+
|
|
174
|
+
|
|
175
|
+
def _call_llm_review_once(messages, model=None):
|
|
176
|
+
"""Single-attempt, fail-closed call for verdict-bearing reviewer tools.
|
|
177
|
+
|
|
178
|
+
Once the HTTP request is dispatched, a timeout, 504, malformed response, or
|
|
179
|
+
transport exception is ambiguous: the remote reviewer may already have run.
|
|
180
|
+
Never retry or switch to FALLBACK_MODEL here. Surface the error so the
|
|
181
|
+
orchestrator/gate records REVIEW_UNAVAILABLE instead of issuing a duplicate
|
|
182
|
+
paid review with a potentially conflicting verdict.
|
|
183
|
+
"""
|
|
184
|
+
if not API_KEY:
|
|
185
|
+
return None, "LLM_API_KEY environment variable not set", None
|
|
186
|
+
|
|
187
|
+
use_model = model or DEFAULT_MODEL
|
|
188
|
+
url = f"{BASE_URL.rstrip('/')}/chat/completions"
|
|
189
|
+
headers = {
|
|
190
|
+
"Content-Type": "application/json",
|
|
191
|
+
"Authorization": f"Bearer {API_KEY}"
|
|
192
|
+
}
|
|
193
|
+
payload = {
|
|
194
|
+
"model": use_model,
|
|
195
|
+
"messages": messages,
|
|
196
|
+
"max_tokens": 4096
|
|
197
|
+
}
|
|
198
|
+
|
|
199
|
+
debug_log(f"Calling verdict-bearing LLM review once: model={use_model}")
|
|
200
|
+
try:
|
|
201
|
+
with httpx.Client(timeout=300.0) as client:
|
|
202
|
+
response = client.post(url, headers=headers, json=payload)
|
|
203
|
+
if response.status_code != 200:
|
|
204
|
+
error_msg = f"API error {response.status_code}: {response.text[:500]}"
|
|
205
|
+
debug_log(f"Review API error (no retry): {error_msg}")
|
|
206
|
+
return None, error_msg, None
|
|
207
|
+
|
|
208
|
+
try:
|
|
209
|
+
data = response.json()
|
|
210
|
+
except Exception as exc:
|
|
211
|
+
error_msg = f"Invalid API JSON response: {exc}"
|
|
212
|
+
debug_log(f"Review API parse error (no retry): {error_msg}")
|
|
213
|
+
return None, error_msg, None
|
|
214
|
+
|
|
215
|
+
try:
|
|
216
|
+
content = data["choices"][0]["message"]["content"]
|
|
217
|
+
except (KeyError, IndexError, TypeError) as exc:
|
|
218
|
+
error_msg = f"Unexpected API response structure: {exc}"
|
|
219
|
+
debug_log(f"Review API structure error (no retry): {error_msg}")
|
|
220
|
+
return None, error_msg, None
|
|
221
|
+
|
|
222
|
+
actual_model = str(data.get("model") or use_model).strip()
|
|
223
|
+
debug_log(
|
|
224
|
+
f"Verdict-bearing API success: model={actual_model}, "
|
|
225
|
+
f"response length={len(content)}"
|
|
226
|
+
)
|
|
227
|
+
return content, None, actual_model
|
|
228
|
+
except Exception as exc:
|
|
229
|
+
debug_log(f"Review API exception (no retry): {str(exc)}")
|
|
230
|
+
return None, str(exc), None
|
|
231
|
+
|
|
232
|
+
|
|
233
|
+
# Coarse model families used only by the opt-in verdict-bearing review tools.
|
|
234
|
+
_FAMILY = [
|
|
235
|
+
("anthropic", ("claude", "opus", "sonnet", "haiku", "anthropic")),
|
|
236
|
+
("openai", ("gpt", "codex", "chatgpt", "o1", "o3", "o4", "openai")),
|
|
237
|
+
("google", ("gemini", "google", "palm", "bard")),
|
|
238
|
+
("deepseek", ("deepseek",)),
|
|
239
|
+
("zhipu", ("glm", "zhipu")),
|
|
240
|
+
("minimax", ("minimax", "abab")),
|
|
241
|
+
("moonshot", ("kimi", "moonshot")),
|
|
242
|
+
("qwen", ("qwen", "tongyi")),
|
|
243
|
+
("xiaomi", ("mimo", "xiaomi")),
|
|
244
|
+
("bytedance", ("doubao", "bytedance", "volcengine")),
|
|
245
|
+
("xai", ("grok",)),
|
|
246
|
+
("meta", ("llama",)),
|
|
247
|
+
("mistral", ("mistral", "mixtral")),
|
|
248
|
+
]
|
|
249
|
+
_SHORT = {"o1", "o3", "o4"}
|
|
250
|
+
|
|
251
|
+
def model_family(name):
|
|
252
|
+
"""Map a model id to a coarse family; collisions fail closed.
|
|
253
|
+
|
|
254
|
+
Match family needles at token boundaries, mirroring review_gate.py, so a
|
|
255
|
+
provider prefix such as ``ollama/deepseek-r1`` does not accidentally match
|
|
256
|
+
the ``llama`` model family inside ``ollama``.
|
|
257
|
+
"""
|
|
258
|
+
n = str(name or "").strip().lower()
|
|
259
|
+
matched = set()
|
|
260
|
+
for family, needles in _FAMILY:
|
|
261
|
+
for needle in needles:
|
|
262
|
+
suffix = "" if needle in _SHORT else r"[0-9.]*"
|
|
263
|
+
pattern = rf"(^|[^a-z0-9]){re.escape(needle)}{suffix}([^a-z0-9]|$)"
|
|
264
|
+
if re.search(pattern, n):
|
|
265
|
+
matched.add(family)
|
|
266
|
+
break
|
|
267
|
+
return next(iter(matched)) if len(matched) == 1 else "unknown"
|
|
268
|
+
|
|
269
|
+
def _cross_family_error(executor_model, reviewer_model):
|
|
270
|
+
executor_family = model_family(executor_model)
|
|
271
|
+
reviewer_family = model_family(reviewer_model)
|
|
272
|
+
if executor_family == "unknown":
|
|
273
|
+
return (f"Cannot verify HTTP reviewer independence: executor_model is "
|
|
274
|
+
f"missing or unrecognized ({executor_model!r})")
|
|
275
|
+
if reviewer_family == "unknown":
|
|
276
|
+
return f"Cannot verify HTTP reviewer model family: {reviewer_model!r}"
|
|
277
|
+
if executor_family == reviewer_family:
|
|
278
|
+
return (f"HTTP reviewer must use a different model family: "
|
|
279
|
+
f"executor={executor_model} ({executor_family}), "
|
|
280
|
+
f"reviewer={reviewer_model} ({reviewer_family})")
|
|
281
|
+
return None
|
|
282
|
+
|
|
283
|
+
def _tool_success(request_id, payload):
|
|
284
|
+
return {
|
|
285
|
+
"jsonrpc": "2.0",
|
|
286
|
+
"id": request_id,
|
|
287
|
+
"result": {
|
|
288
|
+
"content": [{"type": "text", "text": json.dumps(payload, ensure_ascii=False)}]
|
|
289
|
+
}
|
|
290
|
+
}
|
|
291
|
+
|
|
292
|
+
def _tool_error(request_id, message):
|
|
293
|
+
return {
|
|
294
|
+
"jsonrpc": "2.0",
|
|
295
|
+
"id": request_id,
|
|
296
|
+
"result": {
|
|
297
|
+
"content": [{"type": "text", "text": json.dumps({"error": message}, ensure_ascii=False)}],
|
|
298
|
+
"isError": True
|
|
299
|
+
}
|
|
300
|
+
}
|
|
301
|
+
|
|
302
|
+
def _read_review_files(paths):
|
|
303
|
+
"""Read explicit primary artifacts that will be sent to the HTTP endpoint."""
|
|
304
|
+
if paths is None:
|
|
305
|
+
return ""
|
|
306
|
+
if not isinstance(paths, list):
|
|
307
|
+
raise ValueError("files must be an array of file paths")
|
|
308
|
+
|
|
309
|
+
sections = []
|
|
310
|
+
for raw_path in paths:
|
|
311
|
+
path = Path(str(raw_path)).expanduser()
|
|
312
|
+
if not path.is_file():
|
|
313
|
+
raise ValueError(f"review file not found or not a regular file: {path}")
|
|
314
|
+
try:
|
|
315
|
+
text = path.read_text(encoding="utf-8", errors="replace")
|
|
316
|
+
except OSError as exc:
|
|
317
|
+
raise ValueError(f"cannot read review file {path}: {exc}") from exc
|
|
318
|
+
sections.append(
|
|
319
|
+
f"\n\n--- ARIS PRIMARY ARTIFACT: {path} ---\n{text}"
|
|
320
|
+
f"\n--- END ARIS PRIMARY ARTIFACT: {path} ---"
|
|
321
|
+
)
|
|
322
|
+
return "".join(sections)
|
|
323
|
+
|
|
324
|
+
def _review_user_content(prompt, files):
|
|
325
|
+
return prompt + _read_review_files(files)
|
|
326
|
+
|
|
327
|
+
def _review_messages(history, prompt, system=""):
|
|
328
|
+
messages = []
|
|
329
|
+
if system:
|
|
330
|
+
messages.append({"role": "system", "content": system})
|
|
331
|
+
messages.extend(history)
|
|
332
|
+
messages.append({"role": "user", "content": prompt})
|
|
333
|
+
return messages
|
|
334
|
+
|
|
335
|
+
def _handle_review(arguments, request_id):
|
|
336
|
+
prompt = str(arguments.get("prompt", "")).strip()
|
|
337
|
+
executor_model = str(arguments.get("executor_model", "")).strip()
|
|
338
|
+
model = str(arguments.get("model", DEFAULT_MODEL)).strip() or DEFAULT_MODEL
|
|
339
|
+
system = str(arguments.get("system", "")).strip()
|
|
340
|
+
files = arguments.get("files", [])
|
|
341
|
+
|
|
342
|
+
if not prompt:
|
|
343
|
+
return _tool_error(request_id, "prompt is required")
|
|
344
|
+
if not executor_model:
|
|
345
|
+
return _tool_error(request_id, "executor_model is required for cross-family review")
|
|
346
|
+
|
|
347
|
+
try:
|
|
348
|
+
user_content = _review_user_content(prompt, files)
|
|
349
|
+
except ValueError as exc:
|
|
350
|
+
return _tool_error(request_id, str(exc))
|
|
351
|
+
|
|
352
|
+
content, error, actual_model = _call_llm_review_once(
|
|
353
|
+
_review_messages([], user_content, system), model
|
|
354
|
+
)
|
|
355
|
+
if error:
|
|
356
|
+
return _tool_error(request_id, error)
|
|
357
|
+
|
|
358
|
+
independence_error = _cross_family_error(executor_model, actual_model)
|
|
359
|
+
if independence_error:
|
|
360
|
+
return _tool_error(request_id, independence_error)
|
|
361
|
+
|
|
362
|
+
thread_id = uuid.uuid4().hex[:12]
|
|
363
|
+
_review_threads[thread_id] = {
|
|
364
|
+
"messages": [
|
|
365
|
+
{"role": "user", "content": user_content},
|
|
366
|
+
{"role": "assistant", "content": content},
|
|
367
|
+
],
|
|
368
|
+
"model": model,
|
|
369
|
+
"system": system,
|
|
370
|
+
"executor_model": executor_model,
|
|
371
|
+
}
|
|
372
|
+
return _tool_success(request_id, {
|
|
373
|
+
"threadId": thread_id,
|
|
374
|
+
"content": content,
|
|
375
|
+
"reviewer_model": actual_model,
|
|
376
|
+
"reviewer_family": model_family(actual_model),
|
|
377
|
+
"executor_model": executor_model,
|
|
378
|
+
"executor_family": model_family(executor_model),
|
|
379
|
+
"family_relation": "different",
|
|
380
|
+
"independence_verified": "unverified",
|
|
381
|
+
})
|
|
382
|
+
|
|
383
|
+
def _handle_review_reply(arguments, request_id):
|
|
384
|
+
thread_id = str(arguments.get("threadId", "")).strip()
|
|
385
|
+
prompt = str(arguments.get("prompt", "")).strip()
|
|
386
|
+
if not thread_id:
|
|
387
|
+
return _tool_error(request_id, "threadId is required")
|
|
388
|
+
if thread_id not in _review_threads:
|
|
389
|
+
return _tool_error(request_id, f"Unknown threadId: {thread_id}")
|
|
390
|
+
if not prompt:
|
|
391
|
+
return _tool_error(request_id, "prompt is required")
|
|
392
|
+
|
|
393
|
+
thread = _review_threads[thread_id]
|
|
394
|
+
executor_model = str(arguments.get("executor_model", thread["executor_model"])).strip()
|
|
395
|
+
if executor_model != thread["executor_model"]:
|
|
396
|
+
return _tool_error(request_id, "executor_model cannot change within a review thread")
|
|
397
|
+
model = str(arguments.get("model", thread["model"])).strip() or thread["model"]
|
|
398
|
+
if model != thread["model"]:
|
|
399
|
+
return _tool_error(request_id, "reviewer model cannot change within a review thread")
|
|
400
|
+
system = str(arguments.get("system", thread["system"])).strip()
|
|
401
|
+
files = arguments.get("files", [])
|
|
402
|
+
|
|
403
|
+
try:
|
|
404
|
+
user_content = _review_user_content(prompt, files)
|
|
405
|
+
except ValueError as exc:
|
|
406
|
+
return _tool_error(request_id, str(exc))
|
|
407
|
+
|
|
408
|
+
history = list(thread["messages"])
|
|
409
|
+
content, error, actual_model = _call_llm_review_once(
|
|
410
|
+
_review_messages(history, user_content, system), model
|
|
411
|
+
)
|
|
412
|
+
if error:
|
|
413
|
+
return _tool_error(request_id, error)
|
|
414
|
+
|
|
415
|
+
independence_error = _cross_family_error(executor_model, actual_model)
|
|
416
|
+
if independence_error:
|
|
417
|
+
return _tool_error(request_id, independence_error)
|
|
418
|
+
|
|
419
|
+
thread["messages"].extend([
|
|
420
|
+
{"role": "user", "content": user_content},
|
|
421
|
+
{"role": "assistant", "content": content},
|
|
422
|
+
])
|
|
423
|
+
return _tool_success(request_id, {
|
|
424
|
+
"threadId": thread_id,
|
|
425
|
+
"content": content,
|
|
426
|
+
"reviewer_model": actual_model,
|
|
427
|
+
"reviewer_family": model_family(actual_model),
|
|
428
|
+
"executor_model": executor_model,
|
|
429
|
+
"executor_family": model_family(executor_model),
|
|
430
|
+
"family_relation": "different",
|
|
431
|
+
"independence_verified": "unverified",
|
|
432
|
+
})
|
|
433
|
+
|
|
434
|
+
def _review_tool_definitions():
|
|
435
|
+
common = {
|
|
436
|
+
"prompt": {"type": "string", "description": "The substantive ARIS review prompt"},
|
|
437
|
+
"executor_model": {
|
|
438
|
+
"type": "string",
|
|
439
|
+
"description": "Actual executor model id; required to enforce cross-family review"
|
|
440
|
+
},
|
|
441
|
+
"model": {"type": "string", "description": f"Reviewer model (default: {DEFAULT_MODEL})"},
|
|
442
|
+
"system": {"type": "string", "description": "Optional reviewer system prompt"},
|
|
443
|
+
"files": {
|
|
444
|
+
"type": "array",
|
|
445
|
+
"items": {"type": "string"},
|
|
446
|
+
"description": "Local primary-artifact paths to send verbatim to the HTTP reviewer"
|
|
447
|
+
},
|
|
448
|
+
}
|
|
449
|
+
return [
|
|
450
|
+
{
|
|
451
|
+
"name": "review",
|
|
452
|
+
"description": "Start an independent HTTP reviewer thread.",
|
|
453
|
+
"inputSchema": {
|
|
454
|
+
"type": "object",
|
|
455
|
+
"properties": dict(common),
|
|
456
|
+
"required": ["prompt", "executor_model"]
|
|
457
|
+
}
|
|
458
|
+
},
|
|
459
|
+
{
|
|
460
|
+
"name": "review_reply",
|
|
461
|
+
"description": "Continue an HTTP reviewer thread with prior message history.",
|
|
462
|
+
"inputSchema": {
|
|
463
|
+
"type": "object",
|
|
464
|
+
"properties": dict(common, threadId={
|
|
465
|
+
"type": "string",
|
|
466
|
+
"description": "threadId returned by review"
|
|
467
|
+
}),
|
|
468
|
+
"required": ["threadId", "prompt"]
|
|
469
|
+
}
|
|
470
|
+
}
|
|
471
|
+
]
|
|
472
|
+
|
|
473
|
+
def handle_request(request):
|
|
474
|
+
"""Handle a JSON-RPC request"""
|
|
475
|
+
method = request.get("method", "")
|
|
476
|
+
params = request.get("params", {})
|
|
477
|
+
request_id = request.get("id")
|
|
478
|
+
|
|
479
|
+
debug_log(f"Handling method: {method}, id: {request_id}")
|
|
480
|
+
|
|
481
|
+
# Handle notifications (no id, no response needed)
|
|
482
|
+
if request_id is None:
|
|
483
|
+
if method == "notifications/initialized":
|
|
484
|
+
debug_log("Client initialized successfully")
|
|
485
|
+
return None
|
|
486
|
+
|
|
487
|
+
if method == "initialize":
|
|
488
|
+
return {
|
|
489
|
+
"jsonrpc": "2.0",
|
|
490
|
+
"id": request_id,
|
|
491
|
+
"result": {
|
|
492
|
+
"protocolVersion": "2024-11-05",
|
|
493
|
+
"capabilities": {
|
|
494
|
+
"tools": {}
|
|
495
|
+
},
|
|
496
|
+
"serverInfo": {
|
|
497
|
+
"name": SERVER_NAME,
|
|
498
|
+
"version": "2.2.0"
|
|
499
|
+
}
|
|
500
|
+
}
|
|
501
|
+
}
|
|
502
|
+
|
|
503
|
+
elif method == "ping":
|
|
504
|
+
return {"jsonrpc": "2.0", "id": request_id, "result": {}}
|
|
505
|
+
|
|
506
|
+
elif method == "tools/list":
|
|
507
|
+
tools = [{
|
|
508
|
+
"name": "chat",
|
|
509
|
+
"description": f"Send a message to {DEFAULT_MODEL} and get a response. Use this for research reviews, code analysis, and general AI tasks.",
|
|
510
|
+
"inputSchema": {
|
|
511
|
+
"type": "object",
|
|
512
|
+
"properties": {
|
|
513
|
+
"prompt": {
|
|
514
|
+
"type": "string",
|
|
515
|
+
"description": "The prompt to send"
|
|
516
|
+
},
|
|
517
|
+
"model": {
|
|
518
|
+
"type": "string",
|
|
519
|
+
"description": f"Model to use (default: {DEFAULT_MODEL})"
|
|
520
|
+
},
|
|
521
|
+
"system": {
|
|
522
|
+
"type": "string",
|
|
523
|
+
"description": "Optional system prompt"
|
|
524
|
+
}
|
|
525
|
+
},
|
|
526
|
+
"required": ["prompt"]
|
|
527
|
+
}
|
|
528
|
+
}]
|
|
529
|
+
if REVIEW_FALLBACK_ENABLED:
|
|
530
|
+
tools.extend(_review_tool_definitions())
|
|
531
|
+
return {
|
|
532
|
+
"jsonrpc": "2.0",
|
|
533
|
+
"id": request_id,
|
|
534
|
+
"result": {"tools": tools}
|
|
535
|
+
}
|
|
536
|
+
|
|
537
|
+
elif method == "tools/call":
|
|
538
|
+
tool_name = params.get("name", "")
|
|
539
|
+
arguments = params.get("arguments", {})
|
|
540
|
+
|
|
541
|
+
if tool_name == "chat":
|
|
542
|
+
prompt = arguments.get("prompt", "")
|
|
543
|
+
model = arguments.get("model", DEFAULT_MODEL)
|
|
544
|
+
system = arguments.get("system", "")
|
|
545
|
+
|
|
546
|
+
messages = []
|
|
547
|
+
if system:
|
|
548
|
+
messages.append({"role": "system", "content": system})
|
|
549
|
+
messages.append({"role": "user", "content": prompt})
|
|
550
|
+
|
|
551
|
+
debug_log(f"Tool call: chat, prompt length: {len(prompt)}")
|
|
552
|
+
content, error = call_llm(messages, model)
|
|
553
|
+
|
|
554
|
+
if error:
|
|
555
|
+
return {
|
|
556
|
+
"jsonrpc": "2.0",
|
|
557
|
+
"id": request_id,
|
|
558
|
+
"result": {
|
|
559
|
+
"content": [{"type": "text", "text": f"Error: {error}"}],
|
|
560
|
+
"isError": True
|
|
561
|
+
}
|
|
562
|
+
}
|
|
563
|
+
|
|
564
|
+
return {
|
|
565
|
+
"jsonrpc": "2.0",
|
|
566
|
+
"id": request_id,
|
|
567
|
+
"result": {
|
|
568
|
+
"content": [{"type": "text", "text": content}]
|
|
569
|
+
}
|
|
570
|
+
}
|
|
571
|
+
|
|
572
|
+
if tool_name == "review":
|
|
573
|
+
if not REVIEW_FALLBACK_ENABLED:
|
|
574
|
+
return _tool_error(
|
|
575
|
+
request_id,
|
|
576
|
+
"HTTP reviewer fallback is disabled. Set "
|
|
577
|
+
"LLM_REVIEW_FALLBACK_ENABLED=true and restart the MCP server."
|
|
578
|
+
)
|
|
579
|
+
return _handle_review(arguments, request_id)
|
|
580
|
+
|
|
581
|
+
if tool_name == "review_reply":
|
|
582
|
+
if not REVIEW_FALLBACK_ENABLED:
|
|
583
|
+
return _tool_error(
|
|
584
|
+
request_id,
|
|
585
|
+
"HTTP reviewer fallback is disabled. Set "
|
|
586
|
+
"LLM_REVIEW_FALLBACK_ENABLED=true and restart the MCP server."
|
|
587
|
+
)
|
|
588
|
+
return _handle_review_reply(arguments, request_id)
|
|
589
|
+
|
|
590
|
+
return {
|
|
591
|
+
"jsonrpc": "2.0",
|
|
592
|
+
"id": request_id,
|
|
593
|
+
"error": {"code": -32601, "message": f"Unknown tool: {tool_name}"}
|
|
594
|
+
}
|
|
595
|
+
|
|
596
|
+
else:
|
|
597
|
+
return {
|
|
598
|
+
"jsonrpc": "2.0",
|
|
599
|
+
"id": request_id,
|
|
600
|
+
"error": {"code": -32601, "message": f"Unknown method: {method}"}
|
|
601
|
+
}
|
|
602
|
+
|
|
603
|
+
def read_message():
|
|
604
|
+
"""Read a single JSON-RPC message from stdin."""
|
|
605
|
+
global _use_ndjson
|
|
606
|
+
|
|
607
|
+
line = sys.stdin.readline()
|
|
608
|
+
if not line:
|
|
609
|
+
return None
|
|
610
|
+
|
|
611
|
+
line = line.decode('utf-8').rstrip('\r\n')
|
|
612
|
+
|
|
613
|
+
if line.lower().startswith("content-length:"):
|
|
614
|
+
try:
|
|
615
|
+
content_length = int(line.split(":", 1)[1].strip())
|
|
616
|
+
except ValueError:
|
|
617
|
+
return None
|
|
618
|
+
|
|
619
|
+
while True:
|
|
620
|
+
hdr = sys.stdin.readline()
|
|
621
|
+
if not hdr:
|
|
622
|
+
return None
|
|
623
|
+
hdr = hdr.decode('utf-8').rstrip('\r\n')
|
|
624
|
+
if hdr == "":
|
|
625
|
+
break
|
|
626
|
+
|
|
627
|
+
body = sys.stdin.read(content_length)
|
|
628
|
+
try:
|
|
629
|
+
return json.loads(body.decode('utf-8'))
|
|
630
|
+
except Exception:
|
|
631
|
+
return None
|
|
632
|
+
|
|
633
|
+
elif line.startswith("{") or line.startswith("["):
|
|
634
|
+
_use_ndjson = True
|
|
635
|
+
try:
|
|
636
|
+
return json.loads(line)
|
|
637
|
+
except Exception:
|
|
638
|
+
return None
|
|
639
|
+
|
|
640
|
+
return None
|
|
641
|
+
|
|
642
|
+
def main():
|
|
643
|
+
"""Main loop - read JSON-RPC messages from stdin"""
|
|
644
|
+
_init_stdio()
|
|
645
|
+
debug_log("Entering main loop")
|
|
646
|
+
|
|
647
|
+
while True:
|
|
648
|
+
try:
|
|
649
|
+
request = read_message()
|
|
650
|
+
if request is None:
|
|
651
|
+
debug_log("EOF, exiting")
|
|
652
|
+
break
|
|
653
|
+
|
|
654
|
+
response = handle_request(request)
|
|
655
|
+
if response:
|
|
656
|
+
send_response(response)
|
|
657
|
+
|
|
658
|
+
except Exception as e:
|
|
659
|
+
log_error(f"Exception: {e}")
|
|
660
|
+
|
|
661
|
+
debug_log("=== Server Exiting ===")
|
|
662
|
+
|
|
663
|
+
if __name__ == "__main__":
|
|
664
|
+
main()
|