paper-research-agent 0.5.1__tar.gz
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.
- paper_research_agent-0.5.1/.gitignore +14 -0
- paper_research_agent-0.5.1/LICENSE +21 -0
- paper_research_agent-0.5.1/PKG-INFO +512 -0
- paper_research_agent-0.5.1/README.md +471 -0
- paper_research_agent-0.5.1/examples/end-to-end-demo.md +629 -0
- paper_research_agent-0.5.1/examples/usage-scenarios-zh.md +739 -0
- paper_research_agent-0.5.1/planning/PLAN.md +62 -0
- paper_research_agent-0.5.1/planning/architecture.md +379 -0
- paper_research_agent-0.5.1/planning/m1-acceptance-checklist.md +203 -0
- paper_research_agent-0.5.1/planning/milestones/m1-paper-understanding.md +223 -0
- paper_research_agent-0.5.1/planning/milestones/m2-idea-workshop.md +123 -0
- paper_research_agent-0.5.1/planning/milestones/m3-literature-intelligence.md +179 -0
- paper_research_agent-0.5.1/planning/milestones/m4-writing-assistant.md +253 -0
- paper_research_agent-0.5.1/planning/milestones/m5-research-automation.md +226 -0
- paper_research_agent-0.5.1/planning/notes.md +126 -0
- paper_research_agent-0.5.1/pyproject.toml +123 -0
- paper_research_agent-0.5.1/src/research_agent/__init__.py +12 -0
- paper_research_agent-0.5.1/src/research_agent/agents/__init__.py +1 -0
- paper_research_agent-0.5.1/src/research_agent/agents/analyst.py +181 -0
- paper_research_agent-0.5.1/src/research_agent/agents/base.py +64 -0
- paper_research_agent-0.5.1/src/research_agent/agents/critic.py +199 -0
- paper_research_agent-0.5.1/src/research_agent/agents/debate.py +144 -0
- paper_research_agent-0.5.1/src/research_agent/agents/illustrator.py +326 -0
- paper_research_agent-0.5.1/src/research_agent/agents/memory_keeper.py +213 -0
- paper_research_agent-0.5.1/src/research_agent/agents/meta_memory.py +293 -0
- paper_research_agent-0.5.1/src/research_agent/agents/orchestrator.py +439 -0
- paper_research_agent-0.5.1/src/research_agent/agents/prompts.py +29 -0
- paper_research_agent-0.5.1/src/research_agent/agents/schemas.py +444 -0
- paper_research_agent-0.5.1/src/research_agent/agents/scribe.py +357 -0
- paper_research_agent-0.5.1/src/research_agent/agents/searcher.py +219 -0
- paper_research_agent-0.5.1/src/research_agent/agents/writing_pipeline.py +131 -0
- paper_research_agent-0.5.1/src/research_agent/chat/__init__.py +6 -0
- paper_research_agent-0.5.1/src/research_agent/chat/router.py +289 -0
- paper_research_agent-0.5.1/src/research_agent/chat/session.py +139 -0
- paper_research_agent-0.5.1/src/research_agent/chat/tools.py +1887 -0
- paper_research_agent-0.5.1/src/research_agent/cli.py +709 -0
- paper_research_agent-0.5.1/src/research_agent/cli_check.py +105 -0
- paper_research_agent-0.5.1/src/research_agent/cli_doctor.py +315 -0
- paper_research_agent-0.5.1/src/research_agent/cli_figure.py +265 -0
- paper_research_agent-0.5.1/src/research_agent/cli_ideas.py +140 -0
- paper_research_agent-0.5.1/src/research_agent/cli_review.py +412 -0
- paper_research_agent-0.5.1/src/research_agent/cli_services.py +589 -0
- paper_research_agent-0.5.1/src/research_agent/cli_style.py +362 -0
- paper_research_agent-0.5.1/src/research_agent/cli_write.py +307 -0
- paper_research_agent-0.5.1/src/research_agent/config.py +237 -0
- paper_research_agent-0.5.1/src/research_agent/core/__init__.py +1 -0
- paper_research_agent-0.5.1/src/research_agent/core/debate_prompts.py +37 -0
- paper_research_agent-0.5.1/src/research_agent/core/idea.py +61 -0
- paper_research_agent-0.5.1/src/research_agent/core/language.py +51 -0
- paper_research_agent-0.5.1/src/research_agent/core/llm.py +374 -0
- paper_research_agent-0.5.1/src/research_agent/core/loader.py +36 -0
- paper_research_agent-0.5.1/src/research_agent/core/paper.py +38 -0
- paper_research_agent-0.5.1/src/research_agent/core/paper_context.py +28 -0
- paper_research_agent-0.5.1/src/research_agent/core/paper_resolver.py +350 -0
- paper_research_agent-0.5.1/src/research_agent/memory/__init__.py +15 -0
- paper_research_agent-0.5.1/src/research_agent/memory/working_memory.py +116 -0
- paper_research_agent-0.5.1/src/research_agent/parsers/__init__.py +1 -0
- paper_research_agent-0.5.1/src/research_agent/parsers/pdf.py +188 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/analyst.yaml +26 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/analyst_idea.yaml +20 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/analyst_idea_followup.yaml +16 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/analyst_writing.yaml +31 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/critic.yaml +20 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/critic_idea.yaml +21 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/critic_idea_followup.yaml +16 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/critic_writing.yaml +28 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/illustrator_architecture.yaml +35 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/illustrator_concept.yaml +40 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/illustrator_result.yaml +36 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/scribe.yaml +27 -0
- paper_research_agent-0.5.1/src/research_agent/prompts/searcher.yaml +33 -0
- paper_research_agent-0.5.1/src/research_agent/search/__init__.py +1 -0
- paper_research_agent-0.5.1/src/research_agent/search/arxiv.py +56 -0
- paper_research_agent-0.5.1/src/research_agent/search/arxiv_search.py +227 -0
- paper_research_agent-0.5.1/src/research_agent/search/github.py +1 -0
- paper_research_agent-0.5.1/src/research_agent/search/semantic_scholar.py +310 -0
- paper_research_agent-0.5.1/src/research_agent/storage/__init__.py +1 -0
- paper_research_agent-0.5.1/src/research_agent/storage/database.py +360 -0
- paper_research_agent-0.5.1/src/research_agent/storage/discussion_vectors.py +128 -0
- paper_research_agent-0.5.1/src/research_agent/storage/discussions.py +90 -0
- paper_research_agent-0.5.1/src/research_agent/storage/draft_revisions.py +145 -0
- paper_research_agent-0.5.1/src/research_agent/storage/ideas.py +238 -0
- paper_research_agent-0.5.1/src/research_agent/storage/reading_queue.py +181 -0
- paper_research_agent-0.5.1/src/research_agent/storage/searches.py +201 -0
- paper_research_agent-0.5.1/src/research_agent/storage/vector_store.py +135 -0
- paper_research_agent-0.5.1/src/research_agent/style/__init__.py +45 -0
- paper_research_agent-0.5.1/src/research_agent/style/analyzer.py +351 -0
- paper_research_agent-0.5.1/src/research_agent/style/extractor.py +120 -0
- paper_research_agent-0.5.1/src/research_agent/style/filters.py +114 -0
- paper_research_agent-0.5.1/src/research_agent/style/fingerprint.py +148 -0
- paper_research_agent-0.5.1/src/research_agent/style/plagiarism.py +284 -0
- paper_research_agent-0.5.1/src/research_agent/style/samples.py +163 -0
- paper_research_agent-0.5.1/src/research_agent/ui/__init__.py +1 -0
- paper_research_agent-0.5.1/src/research_agent/ui/formatting.py +138 -0
- paper_research_agent-0.5.1/src/research_agent/ui/tui.py +1 -0
- paper_research_agent-0.5.1/tests/__init__.py +0 -0
- paper_research_agent-0.5.1/tests/conftest.py +38 -0
- paper_research_agent-0.5.1/tests/e2e/.gitkeep +0 -0
- paper_research_agent-0.5.1/tests/e2e/test_queue_batch_read.py +200 -0
- paper_research_agent-0.5.1/tests/e2e/test_read_cli.py +135 -0
- paper_research_agent-0.5.1/tests/e2e/test_write_and_figure_cli.py +182 -0
- paper_research_agent-0.5.1/tests/integration/.gitkeep +0 -0
- paper_research_agent-0.5.1/tests/integration/__init__.py +0 -0
- paper_research_agent-0.5.1/tests/integration/test_citation_graph_live.py +160 -0
- paper_research_agent-0.5.1/tests/integration/test_orchestrator.py +91 -0
- paper_research_agent-0.5.1/tests/integration/test_paper_repository.py +99 -0
- paper_research_agent-0.5.1/tests/integration/test_parked_idea_alerts.py +228 -0
- paper_research_agent-0.5.1/tests/integration/test_recall_perf.py +180 -0
- paper_research_agent-0.5.1/tests/integration/test_working_memory_discuss.py +68 -0
- paper_research_agent-0.5.1/tests/unit/__init__.py +0 -0
- paper_research_agent-0.5.1/tests/unit/test_agent_schemas.py +229 -0
- paper_research_agent-0.5.1/tests/unit/test_agents.py +146 -0
- paper_research_agent-0.5.1/tests/unit/test_arxiv_fetcher.py +59 -0
- paper_research_agent-0.5.1/tests/unit/test_arxiv_search.py +439 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_activation_alerts.py +177 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_alert_injection.py +213 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_citations.py +349 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_ideas_update_conditions.py +105 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_insights.py +124 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_recent_searches.py +189 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_refine_slash.py +245 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_router.py +260 -0
- paper_research_agent-0.5.1/tests/unit/test_chat_tool_loop.py +225 -0
- paper_research_agent-0.5.1/tests/unit/test_cli.py +271 -0
- paper_research_agent-0.5.1/tests/unit/test_cli_check.py +126 -0
- paper_research_agent-0.5.1/tests/unit/test_cli_doctor.py +241 -0
- paper_research_agent-0.5.1/tests/unit/test_cli_figure.py +355 -0
- paper_research_agent-0.5.1/tests/unit/test_cli_review.py +282 -0
- paper_research_agent-0.5.1/tests/unit/test_cli_services.py +123 -0
- paper_research_agent-0.5.1/tests/unit/test_cli_style.py +314 -0
- paper_research_agent-0.5.1/tests/unit/test_cli_write.py +363 -0
- paper_research_agent-0.5.1/tests/unit/test_config.py +102 -0
- paper_research_agent-0.5.1/tests/unit/test_config_migration.py +49 -0
- paper_research_agent-0.5.1/tests/unit/test_debate.py +123 -0
- paper_research_agent-0.5.1/tests/unit/test_debate_prompts.py +19 -0
- paper_research_agent-0.5.1/tests/unit/test_discuss_phases.py +87 -0
- paper_research_agent-0.5.1/tests/unit/test_discussions.py +21 -0
- paper_research_agent-0.5.1/tests/unit/test_draft_revisions.py +70 -0
- paper_research_agent-0.5.1/tests/unit/test_ideas.py +107 -0
- paper_research_agent-0.5.1/tests/unit/test_illustrator.py +278 -0
- paper_research_agent-0.5.1/tests/unit/test_language.py +57 -0
- paper_research_agent-0.5.1/tests/unit/test_llm.py +65 -0
- paper_research_agent-0.5.1/tests/unit/test_loader.py +44 -0
- paper_research_agent-0.5.1/tests/unit/test_memory_keeper.py +285 -0
- paper_research_agent-0.5.1/tests/unit/test_memory_recall.py +332 -0
- paper_research_agent-0.5.1/tests/unit/test_meta_memory.py +269 -0
- paper_research_agent-0.5.1/tests/unit/test_openrouter.py +34 -0
- paper_research_agent-0.5.1/tests/unit/test_paper_resolver.py +414 -0
- paper_research_agent-0.5.1/tests/unit/test_pdf_parser.py +49 -0
- paper_research_agent-0.5.1/tests/unit/test_performance_baseline.py +258 -0
- paper_research_agent-0.5.1/tests/unit/test_plagiarism.py +186 -0
- paper_research_agent-0.5.1/tests/unit/test_reading_queue.py +356 -0
- paper_research_agent-0.5.1/tests/unit/test_scribe.py +246 -0
- paper_research_agent-0.5.1/tests/unit/test_search_modes_chat.py +209 -0
- paper_research_agent-0.5.1/tests/unit/test_searcher.py +256 -0
- paper_research_agent-0.5.1/tests/unit/test_searcher_refinement.py +182 -0
- paper_research_agent-0.5.1/tests/unit/test_searches.py +250 -0
- paper_research_agent-0.5.1/tests/unit/test_semantic_scholar.py +426 -0
- paper_research_agent-0.5.1/tests/unit/test_style_analyzer.py +191 -0
- paper_research_agent-0.5.1/tests/unit/test_style_extractor.py +125 -0
- paper_research_agent-0.5.1/tests/unit/test_style_filters.py +81 -0
- paper_research_agent-0.5.1/tests/unit/test_style_fingerprint.py +147 -0
- paper_research_agent-0.5.1/tests/unit/test_style_samples.py +73 -0
- paper_research_agent-0.5.1/tests/unit/test_working_memory.py +85 -0
- paper_research_agent-0.5.1/tests/unit/test_writing_pipeline.py +214 -0
|
@@ -0,0 +1,21 @@
|
|
|
1
|
+
MIT License
|
|
2
|
+
|
|
3
|
+
Copyright (c) 2026 Yanan Sun
|
|
4
|
+
|
|
5
|
+
Permission is hereby granted, free of charge, to any person obtaining a copy
|
|
6
|
+
of this software and associated documentation files (the "Software"), to deal
|
|
7
|
+
in the Software without restriction, including without limitation the rights
|
|
8
|
+
to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
|
|
9
|
+
copies of the Software, and to permit persons to whom the Software is
|
|
10
|
+
furnished to do so, subject to the following conditions:
|
|
11
|
+
|
|
12
|
+
The above copyright notice and this permission notice shall be included in all
|
|
13
|
+
copies or substantial portions of the Software.
|
|
14
|
+
|
|
15
|
+
THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
|
|
16
|
+
IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
|
|
17
|
+
FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
|
|
18
|
+
AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
|
|
19
|
+
LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
|
|
20
|
+
OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN THE
|
|
21
|
+
SOFTWARE.
|
|
@@ -0,0 +1,512 @@
|
|
|
1
|
+
Metadata-Version: 2.4
|
|
2
|
+
Name: paper-research-agent
|
|
3
|
+
Version: 0.5.1
|
|
4
|
+
Summary: Local-first multi-agent CLI for paper understanding, critical debate, literature intelligence, Scribe-powered writing, and figure generation.
|
|
5
|
+
Project-URL: Homepage, https://github.com/ynsun-tw/research-helper
|
|
6
|
+
Project-URL: Repository, https://github.com/ynsun-tw/research-helper
|
|
7
|
+
Project-URL: Issues, https://github.com/ynsun-tw/research-helper/issues
|
|
8
|
+
Project-URL: Changelog, https://github.com/ynsun-tw/research-helper/releases
|
|
9
|
+
Author-email: Yanan Sun <yanan.sun.external@tkelevator.com>
|
|
10
|
+
License-Expression: MIT
|
|
11
|
+
License-File: LICENSE
|
|
12
|
+
Keywords: arxiv,cli,literature-review,llm,multi-agent,paper-summarization,research
|
|
13
|
+
Classifier: Development Status :: 4 - Beta
|
|
14
|
+
Classifier: Environment :: Console
|
|
15
|
+
Classifier: Intended Audience :: Science/Research
|
|
16
|
+
Classifier: Operating System :: OS Independent
|
|
17
|
+
Classifier: Programming Language :: Python :: 3
|
|
18
|
+
Classifier: Programming Language :: Python :: 3.11
|
|
19
|
+
Classifier: Programming Language :: Python :: 3.12
|
|
20
|
+
Classifier: Topic :: Scientific/Engineering :: Artificial Intelligence
|
|
21
|
+
Classifier: Topic :: Scientific/Engineering :: Information Analysis
|
|
22
|
+
Classifier: Topic :: Text Processing :: Linguistic
|
|
23
|
+
Requires-Python: >=3.11
|
|
24
|
+
Requires-Dist: chromadb>=0.5
|
|
25
|
+
Requires-Dist: openai>=1.30
|
|
26
|
+
Requires-Dist: pydantic-settings>=2.2
|
|
27
|
+
Requires-Dist: pydantic>=2.7
|
|
28
|
+
Requires-Dist: pymupdf>=1.24
|
|
29
|
+
Requires-Dist: pyyaml>=6.0
|
|
30
|
+
Requires-Dist: rich>=13.7
|
|
31
|
+
Requires-Dist: textual>=0.47
|
|
32
|
+
Requires-Dist: typer>=0.12
|
|
33
|
+
Provides-Extra: dev
|
|
34
|
+
Requires-Dist: mypy>=1.10; extra == 'dev'
|
|
35
|
+
Requires-Dist: pytest-asyncio>=0.23; extra == 'dev'
|
|
36
|
+
Requires-Dist: pytest-cov>=5.0; extra == 'dev'
|
|
37
|
+
Requires-Dist: pytest>=8.0; extra == 'dev'
|
|
38
|
+
Requires-Dist: ruff>=0.4; extra == 'dev'
|
|
39
|
+
Requires-Dist: types-pyyaml>=6.0; extra == 'dev'
|
|
40
|
+
Description-Content-Type: text/markdown
|
|
41
|
+
|
|
42
|
+
# Research Agent
|
|
43
|
+
|
|
44
|
+
Local-first conversational CLI for research paper understanding, critical
|
|
45
|
+
discussion, and literature intelligence. Multi-agent (Analyst + Critic +
|
|
46
|
+
Searcher + MemoryKeeper) with explicit slash commands **and** LLM tool
|
|
47
|
+
calling — pick whichever feels natural per turn.
|
|
48
|
+
|
|
49
|
+
## Requirements
|
|
50
|
+
|
|
51
|
+
- Python 3.11+
|
|
52
|
+
- An [OpenRouter](https://openrouter.ai/) API key (any OpenAI-compatible
|
|
53
|
+
endpoint works; OpenRouter is the default)
|
|
54
|
+
|
|
55
|
+
## Install
|
|
56
|
+
|
|
57
|
+
> Distribution name on PyPI is **`paper-research-agent`** (the
|
|
58
|
+
> Python import name stays `research_agent`). Currently published to
|
|
59
|
+
> Test PyPI while the release stabilises; a production PyPI upload
|
|
60
|
+
> follows once the Test PyPI build has soaked.
|
|
61
|
+
|
|
62
|
+
### Option A — From Test PyPI (current)
|
|
63
|
+
|
|
64
|
+
The actual runtime dependencies (PyMuPDF, ChromaDB, openai, …) only
|
|
65
|
+
live on real PyPI, so you need both indexes:
|
|
66
|
+
|
|
67
|
+
```bash
|
|
68
|
+
pip install \
|
|
69
|
+
--index-url https://test.pypi.org/simple/ \
|
|
70
|
+
--extra-index-url https://pypi.org/simple/ \
|
|
71
|
+
paper-research-agent
|
|
72
|
+
```
|
|
73
|
+
|
|
74
|
+
Or with [pipx](https://pipx.pypa.io/) for an isolated install:
|
|
75
|
+
|
|
76
|
+
```bash
|
|
77
|
+
pipx install \
|
|
78
|
+
--index-url https://test.pypi.org/simple/ \
|
|
79
|
+
--pip-args="--extra-index-url https://pypi.org/simple/" \
|
|
80
|
+
paper-research-agent
|
|
81
|
+
```
|
|
82
|
+
|
|
83
|
+
### Option B — From PyPI (once published)
|
|
84
|
+
|
|
85
|
+
```bash
|
|
86
|
+
pip install paper-research-agent # or: pipx install paper-research-agent
|
|
87
|
+
```
|
|
88
|
+
|
|
89
|
+
### Option C — From source (development)
|
|
90
|
+
|
|
91
|
+
```bash
|
|
92
|
+
git clone https://github.com/ynsun-tw/research-helper.git
|
|
93
|
+
cd research-helper
|
|
94
|
+
pip install -e ".[dev]"
|
|
95
|
+
```
|
|
96
|
+
|
|
97
|
+
After any of the above, `research --help` should list the writing
|
|
98
|
+
suite (`write`, `review`, `check`, `style`) alongside `config` and
|
|
99
|
+
`insights`, and the conversational REPL is one `research` away.
|
|
100
|
+
|
|
101
|
+
> Latest published build: **0.5.0** (M5 polish — figure generation,
|
|
102
|
+
> doctor, performance, CI, packaging) on Test PyPI —
|
|
103
|
+
> [project page](https://test.pypi.org/project/paper-research-agent/0.5.0/).
|
|
104
|
+
|
|
105
|
+
## Configure
|
|
106
|
+
|
|
107
|
+
```bash
|
|
108
|
+
# API key from https://openrouter.ai/keys
|
|
109
|
+
research config set api_key <your-openrouter-key>
|
|
110
|
+
|
|
111
|
+
# Default model: deepseek/deepseek-chat — change to any OpenRouter model id
|
|
112
|
+
research config set model anthropic/claude-3.5-sonnet
|
|
113
|
+
research config set language zh # or: en (default), zh, 中文
|
|
114
|
+
|
|
115
|
+
research config show
|
|
116
|
+
```
|
|
117
|
+
|
|
118
|
+
Configuration is stored at `~/.research-agent/config.yaml` (file mode `600`).
|
|
119
|
+
|
|
120
|
+
| Key | Default | Description |
|
|
121
|
+
|-----|---------|-------------|
|
|
122
|
+
| `api_key` | — | OpenRouter API key |
|
|
123
|
+
| `model` | `deepseek/deepseek-chat` | Model slug on OpenRouter |
|
|
124
|
+
| `base_url` | `https://openrouter.ai/api/v1` | API base (change only if self-hosting a proxy) |
|
|
125
|
+
| `app_title` | `Research Agent` | Sent as `X-Title` header to OpenRouter |
|
|
126
|
+
| `app_url` | `https://github.com/research-agent` | Sent as `HTTP-Referer` header |
|
|
127
|
+
| `language` | `en` | Agent reply language: `en` or `zh` |
|
|
128
|
+
| `alert_threshold` | `0.8` | Cosine similarity threshold for the parked-idea alert that fires on `/read` (range `[0.0, 1.0]`; lower = more reminders) |
|
|
129
|
+
|
|
130
|
+
All local state lives under `~/.research-agent/`: `memory.db` (SQLite),
|
|
131
|
+
`chroma/` (vector indexes for ideas + discussions), and `cache/`
|
|
132
|
+
(downloaded PDFs).
|
|
133
|
+
|
|
134
|
+
## Usage
|
|
135
|
+
|
|
136
|
+
Running `research` with no arguments drops you into the conversational
|
|
137
|
+
REPL. Everything else happens inside it.
|
|
138
|
+
|
|
139
|
+
```bash
|
|
140
|
+
research # enter the REPL
|
|
141
|
+
research config set api_key sk-or-... # the only remaining subcommand
|
|
142
|
+
research --help
|
|
143
|
+
```
|
|
144
|
+
|
|
145
|
+
Inside the REPL you can either type **slash commands** for explicit
|
|
146
|
+
control or **plain text** to let the LLM pick the right tool.
|
|
147
|
+
|
|
148
|
+
### Slash commands
|
|
149
|
+
|
|
150
|
+
| Command | What it does |
|
|
151
|
+
|---|---|
|
|
152
|
+
| `/search [--mode theoretical\|applied\|group:<author>] <keywords>` | Paper search with LLM relevance scoring; primary source is arXiv with a Semantic Scholar fallback if arXiv rate-limits or errors. Sorted by score; flags papers already in your library. Optional `--mode` biases the candidate set: `theoretical` (analysis / proofs), `applied` (benchmarks / experiments), or `group:"<author name>"` (quote multi-word names) |
|
|
153
|
+
| `/history [N]` | Recent `/search` queries across sessions, with hit counts and read markers |
|
|
154
|
+
| `/recall <query>` | Semantic search across **past** REPL discussions (cross-session) |
|
|
155
|
+
| `/read <arxiv-id \| title \| path.pdf>` | Download + Analyst + Critic; sets the conversation anchor; auto-marks the queue entry done if present |
|
|
156
|
+
| `/discuss <idea or follow-up>` | First turn: structured Analyst (contributions / impact / related work) + Critic (objections / score / suggestions). Follow-up turns: grounded prose, no re-scoring. Must run `/read` first. |
|
|
157
|
+
| `/queue` | List pending entries (alias for `/queue list`) |
|
|
158
|
+
| `/queue add <id> [title…]` | Save a paper for later (pending) |
|
|
159
|
+
| `/queue list [all\|pending\|done\|skipped\|in_progress]` | Filter the queue |
|
|
160
|
+
| `/queue next` | Preview the next pending entry without state change |
|
|
161
|
+
| `/queue read` | Load + analyze the next pending entry, auto-mark done |
|
|
162
|
+
| `/queue done\|skip\|remove <id>` | Manual state transitions |
|
|
163
|
+
| `/cites [arxiv-id]` | Papers that cite the anchor (or given) paper — forward references via Semantic Scholar |
|
|
164
|
+
| `/refs [arxiv-id]` | Papers cited by the anchor (or given) paper — backward references via Semantic Scholar |
|
|
165
|
+
| `/refine` | Ask Searcher to propose the **next** search query from your recent discussion (query + optional `--mode` + reason + confidence); interactively accept / edit / skip |
|
|
166
|
+
| `/insights [--since 30d\|7d\|6m\|all]` | Deterministic Markdown summary of your local activity: papers (by year, top tags / authors / venues), ideas (by status, average critic score, most-debated, top-scored) and discussion volume. No LLM call - safe to run anywhere |
|
|
167
|
+
| `/paper` | Summary of the current anchor paper |
|
|
168
|
+
| `/idea save [title]` | Persist the active debate as a saved idea |
|
|
169
|
+
| `/ideas` | List saved ideas with their latest critic score |
|
|
170
|
+
| `/idea show <id-prefix>` | Show one idea + its full score history |
|
|
171
|
+
| `/ideas update <id> [--status <s>] [--feedback <note>] [--condition "<phrase>"] [--clear-conditions]` | Update status, log score feedback, or pin / clear activation conditions (multiple `--condition` flags allowed) |
|
|
172
|
+
| `/help` | List every slash command |
|
|
173
|
+
| `/exit` | Persist + flush vector indexes + quit |
|
|
174
|
+
|
|
175
|
+
After every `/read`, Research Agent quietly checks your `shelved` /
|
|
176
|
+
`waiting` ideas; if the paper looks topically related (cosine
|
|
177
|
+
similarity ≥ `alert_threshold`, default `0.8`), it prints a
|
|
178
|
+
one-line banner with `/idea show <prefix>` shortcuts so you can
|
|
179
|
+
revisit context you parked earlier. Tune the trigger via
|
|
180
|
+
`research config set alert_threshold 0.85` (range `[0.0, 1.0]`;
|
|
181
|
+
lower = more reminders, higher = fewer false positives).
|
|
182
|
+
|
|
183
|
+
You can also pin **activation conditions** on a shelved idea — free-form
|
|
184
|
+
phrases that describe what would unblock it (a dataset release, a
|
|
185
|
+
checkpoint, a baseline result). Set them via
|
|
186
|
+
`/ideas update <id> --condition "FineWeb-Edu dataset"` (repeatable in one
|
|
187
|
+
command, clear with `--clear-conditions`). Every `/search` then scans
|
|
188
|
+
incoming hits for those phrases (case-insensitive substring) and prints
|
|
189
|
+
a "Shelved idea(s) may have an unblock" banner whenever a new paper
|
|
190
|
+
mentions one — letting search results pull an idea back into your
|
|
191
|
+
attention automatically.
|
|
192
|
+
|
|
193
|
+
### Natural language → tools
|
|
194
|
+
|
|
195
|
+
Plain text is sent to the LLM, which has function-calling access to the
|
|
196
|
+
backend. Available tools:
|
|
197
|
+
|
|
198
|
+
`search_arxiv`, `recent_searches`, `recall_history`, `load_paper`,
|
|
199
|
+
`discuss_idea`, `save_current_idea`, `list_ideas`, `queue_add`,
|
|
200
|
+
`queue_list`, `queue_next`, `get_citations`, `get_references`,
|
|
201
|
+
`suggest_search_refinement`, `research_insights`.
|
|
202
|
+
|
|
203
|
+
The model is instructed to chain them: `"open the BERT paper I searched
|
|
204
|
+
last week"` → `recent_searches` → `load_paper`. `"read the next one on my
|
|
205
|
+
list"` → `queue_next` → `load_paper`. `"what did we conclude about
|
|
206
|
+
positional encodings?"` → `recall_history` then a synthesized recap.
|
|
207
|
+
`"who built on this paper?"` → `get_citations` on the anchor paper.
|
|
208
|
+
`"what does this paper rely on?"` → `get_references`.
|
|
209
|
+
`"what should I search next?"` → `suggest_search_refinement` →
|
|
210
|
+
`search_arxiv`. `"how am I doing this month?"` → `research_insights`.
|
|
211
|
+
|
|
212
|
+
## Quick start (5 minutes)
|
|
213
|
+
|
|
214
|
+
```bash
|
|
215
|
+
# 1. Install (pick one)
|
|
216
|
+
pipx install --index-url https://test.pypi.org/simple/ \
|
|
217
|
+
--pip-args="--extra-index-url https://pypi.org/simple/" \
|
|
218
|
+
paper-research-agent
|
|
219
|
+
# or → pip install -e ".[dev]" from the repo root for a dev install
|
|
220
|
+
|
|
221
|
+
# 2. Verify (no API key needed yet)
|
|
222
|
+
research --version # → research-agent 0.5.0
|
|
223
|
+
research doctor # → environment health check (config, DB, disk, chromadb)
|
|
224
|
+
|
|
225
|
+
# 3. Configure
|
|
226
|
+
research config set api_key sk-or-... # OpenRouter key from https://openrouter.ai/keys
|
|
227
|
+
research config set language zh # or en (default)
|
|
228
|
+
|
|
229
|
+
# 4. Drive the REPL
|
|
230
|
+
research # enter the conversational shell
|
|
231
|
+
# inside the REPL:
|
|
232
|
+
› /search efficient transformer long context
|
|
233
|
+
› /read 1706.03762
|
|
234
|
+
› /discuss replace dense attention with top-k sparse attention
|
|
235
|
+
› /idea save sparse-attention
|
|
236
|
+
› /exit
|
|
237
|
+
|
|
238
|
+
# 5. Author with Scribe
|
|
239
|
+
research style train arxiv:2305.14314 arxiv:2301.07041 # learn your voice
|
|
240
|
+
research style fingerprint # build the fingerprint
|
|
241
|
+
research write introduction --context "sparse top-k attention" --output intro.md
|
|
242
|
+
research review intro.md --section introduction --interactive
|
|
243
|
+
|
|
244
|
+
# 6. Diagrams
|
|
245
|
+
research figure --type architecture --desc "three-layer sparse encoder"
|
|
246
|
+
research figure --type result --data "ours 85, baseline 80" --verify
|
|
247
|
+
|
|
248
|
+
# 7. Sanity checks
|
|
249
|
+
research check intro.md # self-plagiarism scan against your training corpus
|
|
250
|
+
research insights --since 30d # Markdown rollup of recent activity
|
|
251
|
+
```
|
|
252
|
+
|
|
253
|
+
If anything looks off, `research doctor` prints a single Rich table
|
|
254
|
+
with every check, its status, and a one-line hint. Set
|
|
255
|
+
`RESEARCH_AGENT_DEBUG=1` to see the full Python traceback when an
|
|
256
|
+
unexpected error fires (otherwise you only get one coloured line).
|
|
257
|
+
|
|
258
|
+
```text
|
|
259
|
+
› /search --mode applied efficient transformer long context
|
|
260
|
+
› /queue add 1706.03762 Attention Is All You Need
|
|
261
|
+
› /read 1706.03762
|
|
262
|
+
› /discuss replace dense attention with top-k sparse attention for 32k contexts
|
|
263
|
+
› /idea save sparse-routing-attention
|
|
264
|
+
› /ideas update <id-prefix> --status shelved --condition "FlashAttention-3 release"
|
|
265
|
+
› /refine # ask Searcher for the next query
|
|
266
|
+
› /insights --since 30d # weekly research review
|
|
267
|
+
› /exit
|
|
268
|
+
```
|
|
269
|
+
|
|
270
|
+
See [`examples/end-to-end-demo.md`](examples/end-to-end-demo.md) for a
|
|
271
|
+
full scripted walkthrough that exercises every feature (search →
|
|
272
|
+
relevance scoring → queue → read → citation graph → two-phase debate →
|
|
273
|
+
parked-idea alerts → activation conditions → dynamic refinement →
|
|
274
|
+
cross-session recall → research insights) on a real paper.
|
|
275
|
+
|
|
276
|
+
## Writing assistant (M4, in progress)
|
|
277
|
+
|
|
278
|
+
Train the upcoming Scribe agent on your own published papers so it
|
|
279
|
+
writes in a voice that actually sounds like yours. Today the M4
|
|
280
|
+
surface covers **sample import** (S4.1.1); fingerprint analysis +
|
|
281
|
+
draft generation + writing-review pipeline land in subsequent stories.
|
|
282
|
+
|
|
283
|
+
```bash
|
|
284
|
+
# Pull paragraphs from a folder of PDFs
|
|
285
|
+
research style train --dir ~/papers
|
|
286
|
+
|
|
287
|
+
# Or hand-pick sources (arXiv ids and local PDFs may be mixed)
|
|
288
|
+
research style train arxiv:2301.07041 ~/papers/my-thesis.pdf
|
|
289
|
+
|
|
290
|
+
# Inspect the corpus
|
|
291
|
+
research style show
|
|
292
|
+
```
|
|
293
|
+
|
|
294
|
+
`style train` parses each source, splits it into paragraphs, drops
|
|
295
|
+
non-prose (references, acknowledgements, formula-dense methodology,
|
|
296
|
+
single-sentence captions), and writes the survivors into the
|
|
297
|
+
`style_samples` table under `~/.research-agent/memory.db`. Re-running
|
|
298
|
+
the same source replaces its prior samples by default; pass
|
|
299
|
+
`--append` to accumulate instead.
|
|
300
|
+
|
|
301
|
+
Once samples exist, build a **fingerprint** that captures how you
|
|
302
|
+
write:
|
|
303
|
+
|
|
304
|
+
```bash
|
|
305
|
+
research style fingerprint
|
|
306
|
+
```
|
|
307
|
+
|
|
308
|
+
The fingerprint is computed entirely offline (no LLM call) and lands
|
|
309
|
+
at `~/.research-agent/style/fingerprint.json`. It has three layers:
|
|
310
|
+
|
|
311
|
+
| Layer | What it captures |
|
|
312
|
+
|---|---|
|
|
313
|
+
| **Macro** | abstract opener, intro opener, related-work organization (chronological / thematic / comparison), avg sections per paper |
|
|
314
|
+
| **Micro** | sentence-length distribution (avg / median / p10 / p90), avg paragraph length, top transition words & their per-100-sentence rates, hedging / confidence / passive rates, type-token ratio |
|
|
315
|
+
| **Markers** | dominant citation format (`latex_cite` / `bracket_num` / `author_year` / `mixed`), figure & table reference style (`Figure` vs `Fig.`), em-dash usage, your top section titles |
|
|
316
|
+
|
|
317
|
+
`research style show` prints the corpus inventory and (if present)
|
|
318
|
+
the fingerprint summary, side by side.
|
|
319
|
+
|
|
320
|
+
### Draft a section with Scribe
|
|
321
|
+
|
|
322
|
+
```bash
|
|
323
|
+
research write abstract --words 250
|
|
324
|
+
research write introduction \
|
|
325
|
+
--context "this paper studies sparse top-k attention for 32k contexts" \
|
|
326
|
+
--versions 3 \
|
|
327
|
+
--output drafts/intro.md
|
|
328
|
+
```
|
|
329
|
+
|
|
330
|
+
`research write <section>` invokes the Scribe agent, which produces
|
|
331
|
+
**three stylistic variants** by default — *concise*, *technical depth*,
|
|
332
|
+
and *narrative arc* — by issuing the LLM calls in parallel (use
|
|
333
|
+
`--sequential` to disable). Each draft is rendered in its own Rich
|
|
334
|
+
panel with a one-line note explaining how it differs from the others;
|
|
335
|
+
pass `--output drafts.md` to also save the bouquet to disk.
|
|
336
|
+
|
|
337
|
+
Supported section names (aliases in parentheses): `abstract`,
|
|
338
|
+
`introduction` (`intro`), `related_work` (`related`), `method`
|
|
339
|
+
(`methods` / `approach`), `results` (`experiments` / `evaluation`),
|
|
340
|
+
`discussion`, `conclusion`.
|
|
341
|
+
|
|
342
|
+
When `~/.research-agent/style/fingerprint.json` exists, the Scribe
|
|
343
|
+
mimics it (sentence length, transitions, hedging vs confidence
|
|
344
|
+
balance, citation format). Without a fingerprint it falls back to
|
|
345
|
+
neutral academic prose and says so in each draft's style note.
|
|
346
|
+
|
|
347
|
+
#### Context-aware writing
|
|
348
|
+
|
|
349
|
+
When you pass `--context "<description>"`, the Scribe doesn't just
|
|
350
|
+
parrot the description — it also pulls related material from your
|
|
351
|
+
memory store and injects it into the prompt:
|
|
352
|
+
|
|
353
|
+
- **Related ideas** from your library (semantic similarity ≥ 0.5,
|
|
354
|
+
top 3) — title, status, last critic score, summary.
|
|
355
|
+
- **Recent cross-session discussion excerpts** that look topically
|
|
356
|
+
relevant (top 3).
|
|
357
|
+
- **Existing drafts** you point it at with `--check-against PATH`
|
|
358
|
+
(repeatable) — body included verbatim (truncated to ~2 KB each)
|
|
359
|
+
with an explicit instruction not to duplicate or contradict.
|
|
360
|
+
|
|
361
|
+
```bash
|
|
362
|
+
research write conclusion \
|
|
363
|
+
--context "sparse top-k attention for 32k contexts" \
|
|
364
|
+
--check-against drafts/intro.md \
|
|
365
|
+
--check-against drafts/method.md \
|
|
366
|
+
--versions 3
|
|
367
|
+
```
|
|
368
|
+
|
|
369
|
+
The CLI prints a one-line `Scribe context: user context, 2 related
|
|
370
|
+
idea(s), 1 discussion excerpt(s), 2 draft(s) to stay consistent
|
|
371
|
+
with` summary before the panels so you can see what the agent saw.
|
|
372
|
+
|
|
373
|
+
### Review a draft (Analyst + Critic → Scribe)
|
|
374
|
+
|
|
375
|
+
```bash
|
|
376
|
+
research review drafts/intro.md --section introduction --output drafts/intro.review.md
|
|
377
|
+
```
|
|
378
|
+
|
|
379
|
+
`research review <file>` runs the **auto-review pipeline**:
|
|
380
|
+
|
|
381
|
+
1. **Analyst (writing mode)** — flags weak argumentation,
|
|
382
|
+
missing differentiation from related work, evidence-claim
|
|
383
|
+
gaps, undefined terms.
|
|
384
|
+
2. **Critic (writing mode)** — flags overclaim, unsupported
|
|
385
|
+
conclusions, logical gaps, hedging mismatch. Runs in parallel
|
|
386
|
+
with the Analyst (`asyncio.gather`).
|
|
387
|
+
3. **Scribe revision** — produces a single revised draft that
|
|
388
|
+
addresses both reviews while preserving your fingerprinted
|
|
389
|
+
voice. Skips the LLM entirely if both reviews come back empty.
|
|
390
|
+
|
|
391
|
+
The console prints four panels (original draft, analyst review,
|
|
392
|
+
critic review, revised draft); `--output review.md` also writes the
|
|
393
|
+
whole bundle to a Markdown file for diffing.
|
|
394
|
+
|
|
395
|
+
```bash
|
|
396
|
+
research review drafts/intro.md --section introduction --interactive
|
|
397
|
+
```
|
|
398
|
+
|
|
399
|
+
Pass `--interactive` to walk through each reviewer issue and
|
|
400
|
+
suggestion one at a time (y / N). The Scribe revision will only
|
|
401
|
+
address the items you accepted, and at the end you get a coloured
|
|
402
|
+
unified diff between original and revised. The (original, revised,
|
|
403
|
+
selected_*, rejected_*) tuple is persisted to the
|
|
404
|
+
`draft_revisions` SQLite table by default — pass `--no-save` to opt
|
|
405
|
+
out. The continuous-learning loop (next subsection) consumes these
|
|
406
|
+
rows to keep the fingerprint in sync with how you actually edit
|
|
407
|
+
Scribe output.
|
|
408
|
+
|
|
409
|
+
#### Continuous fingerprint learning
|
|
410
|
+
|
|
411
|
+
```bash
|
|
412
|
+
research style update # refresh fingerprint from samples + accepted revisions
|
|
413
|
+
research style history # list all saved fingerprint versions
|
|
414
|
+
```
|
|
415
|
+
|
|
416
|
+
`research style update` recomputes the fingerprint by combining the
|
|
417
|
+
static `style_samples` corpus with every accepted Scribe revision
|
|
418
|
+
(`revised_text` from the `draft_revisions` table) and bumps the
|
|
419
|
+
version. The previous `fingerprint.json` is archived next to it as
|
|
420
|
+
`fingerprint_v<N>.json`; `research style history` lists every
|
|
421
|
+
version side by side so you can see how your voice drifts as you
|
|
422
|
+
keep using Scribe.
|
|
423
|
+
|
|
424
|
+
The flow is:
|
|
425
|
+
|
|
426
|
+
1. `research style train` (one-shot, from your published papers) →
|
|
427
|
+
seeds the corpus.
|
|
428
|
+
2. `research style fingerprint` → v1 baseline.
|
|
429
|
+
3. `research write <section> --context …` → drafts.
|
|
430
|
+
4. `research review <file> --interactive` → accept / reject
|
|
431
|
+
suggestions; the (original, revised) pair is saved.
|
|
432
|
+
5. `research style update` → folds those accepted revisions back
|
|
433
|
+
into the fingerprint as v2, v3, …
|
|
434
|
+
|
|
435
|
+
### Figure generation (M5 — `research figure`)
|
|
436
|
+
|
|
437
|
+
```bash
|
|
438
|
+
research figure --type architecture --desc "three-layer encoder with residual connections" --versions 2 --output figs/arch.md
|
|
439
|
+
research figure --type result --desc "accuracy comparison across 3 baselines" --data "ours 85, baseline-A 80, baseline-B 78" --verify
|
|
440
|
+
research figure --type concept --desc "attention mechanism flow" --versions 3 --output figs/concept.md
|
|
441
|
+
```
|
|
442
|
+
|
|
443
|
+
`research figure` drives the **Illustrator agent** to produce N
|
|
444
|
+
variant drafts of a paper figure in parallel. Three modes:
|
|
445
|
+
|
|
446
|
+
- `--type architecture` → **TikZ** snippets ready to paste into LaTeX.
|
|
447
|
+
Includes `\usetikzlibrary` declarations and a `\tikzset{}` style
|
|
448
|
+
block. Variants cycle through layered horizontal / hub-and-spoke /
|
|
449
|
+
encoder-decoder vertical layouts.
|
|
450
|
+
- `--type result` → **matplotlib / seaborn Python** scripts that
|
|
451
|
+
write to `output.png` (no `plt.show()`, paper-ready rcParams,
|
|
452
|
+
colorblind palette). Variants cycle through grouped bar / line
|
|
453
|
+
with shaded variance / paired boxplot. Pass `--verify` to actually
|
|
454
|
+
execute each draft in a subprocess (30 s timeout, `MPLBACKEND=Agg`)
|
|
455
|
+
and report run / fail per draft.
|
|
456
|
+
- `--type concept` → **text-to-image prompts** for DALL·E 3,
|
|
457
|
+
Midjourney v6, and Stable Diffusion (one variant per ecosystem,
|
|
458
|
+
with model-specific phrasing and a `negative_prompt` for SD/MJ).
|
|
459
|
+
Direct API rendering (uploading to DALL·E) is left to a follow-up.
|
|
460
|
+
|
|
461
|
+
Each draft includes a `notes` summary of what makes it distinct and
|
|
462
|
+
a `suggested_use` phrase telling you which paper context it fits.
|
|
463
|
+
With `--output PATH` the whole bouquet is written to a Markdown file
|
|
464
|
+
with fenced code blocks and verification status; without it the
|
|
465
|
+
output stays in the terminal as syntax-highlighted Rich panels.
|
|
466
|
+
|
|
467
|
+
### Self-plagiarism check
|
|
468
|
+
|
|
469
|
+
```bash
|
|
470
|
+
research check drafts/intro.md --threshold 0.4 --output reports/intro.similarity.md
|
|
471
|
+
```
|
|
472
|
+
|
|
473
|
+
`research check <file>` scans each paragraph of the draft against
|
|
474
|
+
every paragraph in your `style_samples` corpus using paragraph-level
|
|
475
|
+
**TF-IDF + cosine similarity** (pure Python, no heavy dependencies).
|
|
476
|
+
The default threshold is 0.4 (per the M4 milestone); raise it for a
|
|
477
|
+
stricter scan or lower it to surface light echoes.
|
|
478
|
+
|
|
479
|
+
The console renders one panel summary plus a Markdown report:
|
|
480
|
+
|
|
481
|
+
- For every flagged paragraph: the draft text, the matching corpus
|
|
482
|
+
paragraph (with `arxiv:<id>` source label), the similarity %, and
|
|
483
|
+
concrete rewrite suggestions that scale with severity (≥ 0.7 →
|
|
484
|
+
"rewrite from scratch", ≥ 0.5 → "paraphrase and cite", ≥ 0.4 →
|
|
485
|
+
"trim or merge").
|
|
486
|
+
- Exit code is `0` for a clean check and `2` when at least one match
|
|
487
|
+
trips the threshold, so it slots cleanly into CI.
|
|
488
|
+
|
|
489
|
+
## Development
|
|
490
|
+
|
|
491
|
+
```bash
|
|
492
|
+
ruff check src tests
|
|
493
|
+
ruff format --check src tests
|
|
494
|
+
mypy src
|
|
495
|
+
pytest
|
|
496
|
+
```
|
|
497
|
+
|
|
498
|
+
Live network tests (hit arXiv / Semantic Scholar) are skipped by
|
|
499
|
+
default. To run them:
|
|
500
|
+
|
|
501
|
+
```bash
|
|
502
|
+
RUN_NETWORK_TESTS=1 pytest -m network
|
|
503
|
+
```
|
|
504
|
+
|
|
505
|
+
Skip them explicitly with `pytest -m 'not network'` (already the
|
|
506
|
+
default via `RUN_NETWORK_TESTS` being unset).
|
|
507
|
+
|
|
508
|
+
## Planning
|
|
509
|
+
|
|
510
|
+
See [planning/PLAN.md](planning/PLAN.md) and
|
|
511
|
+
[planning/architecture.md](planning/architecture.md). Milestone notes
|
|
512
|
+
live under [`planning/milestones/`](planning/milestones/).
|