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.
Files changed (165) hide show
  1. paper_research_agent-0.5.1/.gitignore +14 -0
  2. paper_research_agent-0.5.1/LICENSE +21 -0
  3. paper_research_agent-0.5.1/PKG-INFO +512 -0
  4. paper_research_agent-0.5.1/README.md +471 -0
  5. paper_research_agent-0.5.1/examples/end-to-end-demo.md +629 -0
  6. paper_research_agent-0.5.1/examples/usage-scenarios-zh.md +739 -0
  7. paper_research_agent-0.5.1/planning/PLAN.md +62 -0
  8. paper_research_agent-0.5.1/planning/architecture.md +379 -0
  9. paper_research_agent-0.5.1/planning/m1-acceptance-checklist.md +203 -0
  10. paper_research_agent-0.5.1/planning/milestones/m1-paper-understanding.md +223 -0
  11. paper_research_agent-0.5.1/planning/milestones/m2-idea-workshop.md +123 -0
  12. paper_research_agent-0.5.1/planning/milestones/m3-literature-intelligence.md +179 -0
  13. paper_research_agent-0.5.1/planning/milestones/m4-writing-assistant.md +253 -0
  14. paper_research_agent-0.5.1/planning/milestones/m5-research-automation.md +226 -0
  15. paper_research_agent-0.5.1/planning/notes.md +126 -0
  16. paper_research_agent-0.5.1/pyproject.toml +123 -0
  17. paper_research_agent-0.5.1/src/research_agent/__init__.py +12 -0
  18. paper_research_agent-0.5.1/src/research_agent/agents/__init__.py +1 -0
  19. paper_research_agent-0.5.1/src/research_agent/agents/analyst.py +181 -0
  20. paper_research_agent-0.5.1/src/research_agent/agents/base.py +64 -0
  21. paper_research_agent-0.5.1/src/research_agent/agents/critic.py +199 -0
  22. paper_research_agent-0.5.1/src/research_agent/agents/debate.py +144 -0
  23. paper_research_agent-0.5.1/src/research_agent/agents/illustrator.py +326 -0
  24. paper_research_agent-0.5.1/src/research_agent/agents/memory_keeper.py +213 -0
  25. paper_research_agent-0.5.1/src/research_agent/agents/meta_memory.py +293 -0
  26. paper_research_agent-0.5.1/src/research_agent/agents/orchestrator.py +439 -0
  27. paper_research_agent-0.5.1/src/research_agent/agents/prompts.py +29 -0
  28. paper_research_agent-0.5.1/src/research_agent/agents/schemas.py +444 -0
  29. paper_research_agent-0.5.1/src/research_agent/agents/scribe.py +357 -0
  30. paper_research_agent-0.5.1/src/research_agent/agents/searcher.py +219 -0
  31. paper_research_agent-0.5.1/src/research_agent/agents/writing_pipeline.py +131 -0
  32. paper_research_agent-0.5.1/src/research_agent/chat/__init__.py +6 -0
  33. paper_research_agent-0.5.1/src/research_agent/chat/router.py +289 -0
  34. paper_research_agent-0.5.1/src/research_agent/chat/session.py +139 -0
  35. paper_research_agent-0.5.1/src/research_agent/chat/tools.py +1887 -0
  36. paper_research_agent-0.5.1/src/research_agent/cli.py +709 -0
  37. paper_research_agent-0.5.1/src/research_agent/cli_check.py +105 -0
  38. paper_research_agent-0.5.1/src/research_agent/cli_doctor.py +315 -0
  39. paper_research_agent-0.5.1/src/research_agent/cli_figure.py +265 -0
  40. paper_research_agent-0.5.1/src/research_agent/cli_ideas.py +140 -0
  41. paper_research_agent-0.5.1/src/research_agent/cli_review.py +412 -0
  42. paper_research_agent-0.5.1/src/research_agent/cli_services.py +589 -0
  43. paper_research_agent-0.5.1/src/research_agent/cli_style.py +362 -0
  44. paper_research_agent-0.5.1/src/research_agent/cli_write.py +307 -0
  45. paper_research_agent-0.5.1/src/research_agent/config.py +237 -0
  46. paper_research_agent-0.5.1/src/research_agent/core/__init__.py +1 -0
  47. paper_research_agent-0.5.1/src/research_agent/core/debate_prompts.py +37 -0
  48. paper_research_agent-0.5.1/src/research_agent/core/idea.py +61 -0
  49. paper_research_agent-0.5.1/src/research_agent/core/language.py +51 -0
  50. paper_research_agent-0.5.1/src/research_agent/core/llm.py +374 -0
  51. paper_research_agent-0.5.1/src/research_agent/core/loader.py +36 -0
  52. paper_research_agent-0.5.1/src/research_agent/core/paper.py +38 -0
  53. paper_research_agent-0.5.1/src/research_agent/core/paper_context.py +28 -0
  54. paper_research_agent-0.5.1/src/research_agent/core/paper_resolver.py +350 -0
  55. paper_research_agent-0.5.1/src/research_agent/memory/__init__.py +15 -0
  56. paper_research_agent-0.5.1/src/research_agent/memory/working_memory.py +116 -0
  57. paper_research_agent-0.5.1/src/research_agent/parsers/__init__.py +1 -0
  58. paper_research_agent-0.5.1/src/research_agent/parsers/pdf.py +188 -0
  59. paper_research_agent-0.5.1/src/research_agent/prompts/analyst.yaml +26 -0
  60. paper_research_agent-0.5.1/src/research_agent/prompts/analyst_idea.yaml +20 -0
  61. paper_research_agent-0.5.1/src/research_agent/prompts/analyst_idea_followup.yaml +16 -0
  62. paper_research_agent-0.5.1/src/research_agent/prompts/analyst_writing.yaml +31 -0
  63. paper_research_agent-0.5.1/src/research_agent/prompts/critic.yaml +20 -0
  64. paper_research_agent-0.5.1/src/research_agent/prompts/critic_idea.yaml +21 -0
  65. paper_research_agent-0.5.1/src/research_agent/prompts/critic_idea_followup.yaml +16 -0
  66. paper_research_agent-0.5.1/src/research_agent/prompts/critic_writing.yaml +28 -0
  67. paper_research_agent-0.5.1/src/research_agent/prompts/illustrator_architecture.yaml +35 -0
  68. paper_research_agent-0.5.1/src/research_agent/prompts/illustrator_concept.yaml +40 -0
  69. paper_research_agent-0.5.1/src/research_agent/prompts/illustrator_result.yaml +36 -0
  70. paper_research_agent-0.5.1/src/research_agent/prompts/scribe.yaml +27 -0
  71. paper_research_agent-0.5.1/src/research_agent/prompts/searcher.yaml +33 -0
  72. paper_research_agent-0.5.1/src/research_agent/search/__init__.py +1 -0
  73. paper_research_agent-0.5.1/src/research_agent/search/arxiv.py +56 -0
  74. paper_research_agent-0.5.1/src/research_agent/search/arxiv_search.py +227 -0
  75. paper_research_agent-0.5.1/src/research_agent/search/github.py +1 -0
  76. paper_research_agent-0.5.1/src/research_agent/search/semantic_scholar.py +310 -0
  77. paper_research_agent-0.5.1/src/research_agent/storage/__init__.py +1 -0
  78. paper_research_agent-0.5.1/src/research_agent/storage/database.py +360 -0
  79. paper_research_agent-0.5.1/src/research_agent/storage/discussion_vectors.py +128 -0
  80. paper_research_agent-0.5.1/src/research_agent/storage/discussions.py +90 -0
  81. paper_research_agent-0.5.1/src/research_agent/storage/draft_revisions.py +145 -0
  82. paper_research_agent-0.5.1/src/research_agent/storage/ideas.py +238 -0
  83. paper_research_agent-0.5.1/src/research_agent/storage/reading_queue.py +181 -0
  84. paper_research_agent-0.5.1/src/research_agent/storage/searches.py +201 -0
  85. paper_research_agent-0.5.1/src/research_agent/storage/vector_store.py +135 -0
  86. paper_research_agent-0.5.1/src/research_agent/style/__init__.py +45 -0
  87. paper_research_agent-0.5.1/src/research_agent/style/analyzer.py +351 -0
  88. paper_research_agent-0.5.1/src/research_agent/style/extractor.py +120 -0
  89. paper_research_agent-0.5.1/src/research_agent/style/filters.py +114 -0
  90. paper_research_agent-0.5.1/src/research_agent/style/fingerprint.py +148 -0
  91. paper_research_agent-0.5.1/src/research_agent/style/plagiarism.py +284 -0
  92. paper_research_agent-0.5.1/src/research_agent/style/samples.py +163 -0
  93. paper_research_agent-0.5.1/src/research_agent/ui/__init__.py +1 -0
  94. paper_research_agent-0.5.1/src/research_agent/ui/formatting.py +138 -0
  95. paper_research_agent-0.5.1/src/research_agent/ui/tui.py +1 -0
  96. paper_research_agent-0.5.1/tests/__init__.py +0 -0
  97. paper_research_agent-0.5.1/tests/conftest.py +38 -0
  98. paper_research_agent-0.5.1/tests/e2e/.gitkeep +0 -0
  99. paper_research_agent-0.5.1/tests/e2e/test_queue_batch_read.py +200 -0
  100. paper_research_agent-0.5.1/tests/e2e/test_read_cli.py +135 -0
  101. paper_research_agent-0.5.1/tests/e2e/test_write_and_figure_cli.py +182 -0
  102. paper_research_agent-0.5.1/tests/integration/.gitkeep +0 -0
  103. paper_research_agent-0.5.1/tests/integration/__init__.py +0 -0
  104. paper_research_agent-0.5.1/tests/integration/test_citation_graph_live.py +160 -0
  105. paper_research_agent-0.5.1/tests/integration/test_orchestrator.py +91 -0
  106. paper_research_agent-0.5.1/tests/integration/test_paper_repository.py +99 -0
  107. paper_research_agent-0.5.1/tests/integration/test_parked_idea_alerts.py +228 -0
  108. paper_research_agent-0.5.1/tests/integration/test_recall_perf.py +180 -0
  109. paper_research_agent-0.5.1/tests/integration/test_working_memory_discuss.py +68 -0
  110. paper_research_agent-0.5.1/tests/unit/__init__.py +0 -0
  111. paper_research_agent-0.5.1/tests/unit/test_agent_schemas.py +229 -0
  112. paper_research_agent-0.5.1/tests/unit/test_agents.py +146 -0
  113. paper_research_agent-0.5.1/tests/unit/test_arxiv_fetcher.py +59 -0
  114. paper_research_agent-0.5.1/tests/unit/test_arxiv_search.py +439 -0
  115. paper_research_agent-0.5.1/tests/unit/test_chat_activation_alerts.py +177 -0
  116. paper_research_agent-0.5.1/tests/unit/test_chat_alert_injection.py +213 -0
  117. paper_research_agent-0.5.1/tests/unit/test_chat_citations.py +349 -0
  118. paper_research_agent-0.5.1/tests/unit/test_chat_ideas_update_conditions.py +105 -0
  119. paper_research_agent-0.5.1/tests/unit/test_chat_insights.py +124 -0
  120. paper_research_agent-0.5.1/tests/unit/test_chat_recent_searches.py +189 -0
  121. paper_research_agent-0.5.1/tests/unit/test_chat_refine_slash.py +245 -0
  122. paper_research_agent-0.5.1/tests/unit/test_chat_router.py +260 -0
  123. paper_research_agent-0.5.1/tests/unit/test_chat_tool_loop.py +225 -0
  124. paper_research_agent-0.5.1/tests/unit/test_cli.py +271 -0
  125. paper_research_agent-0.5.1/tests/unit/test_cli_check.py +126 -0
  126. paper_research_agent-0.5.1/tests/unit/test_cli_doctor.py +241 -0
  127. paper_research_agent-0.5.1/tests/unit/test_cli_figure.py +355 -0
  128. paper_research_agent-0.5.1/tests/unit/test_cli_review.py +282 -0
  129. paper_research_agent-0.5.1/tests/unit/test_cli_services.py +123 -0
  130. paper_research_agent-0.5.1/tests/unit/test_cli_style.py +314 -0
  131. paper_research_agent-0.5.1/tests/unit/test_cli_write.py +363 -0
  132. paper_research_agent-0.5.1/tests/unit/test_config.py +102 -0
  133. paper_research_agent-0.5.1/tests/unit/test_config_migration.py +49 -0
  134. paper_research_agent-0.5.1/tests/unit/test_debate.py +123 -0
  135. paper_research_agent-0.5.1/tests/unit/test_debate_prompts.py +19 -0
  136. paper_research_agent-0.5.1/tests/unit/test_discuss_phases.py +87 -0
  137. paper_research_agent-0.5.1/tests/unit/test_discussions.py +21 -0
  138. paper_research_agent-0.5.1/tests/unit/test_draft_revisions.py +70 -0
  139. paper_research_agent-0.5.1/tests/unit/test_ideas.py +107 -0
  140. paper_research_agent-0.5.1/tests/unit/test_illustrator.py +278 -0
  141. paper_research_agent-0.5.1/tests/unit/test_language.py +57 -0
  142. paper_research_agent-0.5.1/tests/unit/test_llm.py +65 -0
  143. paper_research_agent-0.5.1/tests/unit/test_loader.py +44 -0
  144. paper_research_agent-0.5.1/tests/unit/test_memory_keeper.py +285 -0
  145. paper_research_agent-0.5.1/tests/unit/test_memory_recall.py +332 -0
  146. paper_research_agent-0.5.1/tests/unit/test_meta_memory.py +269 -0
  147. paper_research_agent-0.5.1/tests/unit/test_openrouter.py +34 -0
  148. paper_research_agent-0.5.1/tests/unit/test_paper_resolver.py +414 -0
  149. paper_research_agent-0.5.1/tests/unit/test_pdf_parser.py +49 -0
  150. paper_research_agent-0.5.1/tests/unit/test_performance_baseline.py +258 -0
  151. paper_research_agent-0.5.1/tests/unit/test_plagiarism.py +186 -0
  152. paper_research_agent-0.5.1/tests/unit/test_reading_queue.py +356 -0
  153. paper_research_agent-0.5.1/tests/unit/test_scribe.py +246 -0
  154. paper_research_agent-0.5.1/tests/unit/test_search_modes_chat.py +209 -0
  155. paper_research_agent-0.5.1/tests/unit/test_searcher.py +256 -0
  156. paper_research_agent-0.5.1/tests/unit/test_searcher_refinement.py +182 -0
  157. paper_research_agent-0.5.1/tests/unit/test_searches.py +250 -0
  158. paper_research_agent-0.5.1/tests/unit/test_semantic_scholar.py +426 -0
  159. paper_research_agent-0.5.1/tests/unit/test_style_analyzer.py +191 -0
  160. paper_research_agent-0.5.1/tests/unit/test_style_extractor.py +125 -0
  161. paper_research_agent-0.5.1/tests/unit/test_style_filters.py +81 -0
  162. paper_research_agent-0.5.1/tests/unit/test_style_fingerprint.py +147 -0
  163. paper_research_agent-0.5.1/tests/unit/test_style_samples.py +73 -0
  164. paper_research_agent-0.5.1/tests/unit/test_working_memory.py +85 -0
  165. paper_research_agent-0.5.1/tests/unit/test_writing_pipeline.py +214 -0
@@ -0,0 +1,14 @@
1
+ __pycache__/
2
+ *.py[cod]
3
+ *$py.class
4
+ .pytest_cache/
5
+ .mypy_cache/
6
+ .ruff_cache/
7
+ .coverage
8
+ htmlcov/
9
+ dist/
10
+ *.egg-info/
11
+ .venv/
12
+ venv/
13
+ .env
14
+ .idea/
@@ -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/).