Diomedes Git
commited on
Commit
Β·
c2dfc44
1
Parent(s):
8d9d361
rearranging and a few bits of note taking
Browse files- cluas/NOTICE β NOTICE +0 -0
- cluas/src/cluas_mcp/common/formatting.py +0 -0
- experiments/01-first-tool +0 -0
- experiments/02-gradio-integration +0 -0
- experiments/03-multi-tool +0 -0
- gemini.md +55 -0
- main.py +0 -6
- notes_etc/development_guide_01.md +797 -0
- notes_etc/development_guide_02.txt +181 -0
- notes_etc/exposing_cluas_as_an_MCP.py +14 -0
- notes_etc/possible_lightweight_architecture_diagram.txt +53 -0
- reviews/changes.md +60 -0
- {cluas/reviews β reviews}/code_review_2025-11-15_14-30-00.md +0 -0
- {cluas/reviews β reviews}/code_review_2025-11-15_15-00-00.md +0 -0
- {cluas/reviews β reviews}/code_review_2025-11-15_15-30-00.md +0 -0
- {cluas/reviews β reviews}/code_review_2025-11-15_16-00-00.md +0 -0
- reviews/code_review_2025-11-18_10-00-00.md +61 -0
- reviews/code_review_2025-11-18_10-30-00.md +50 -0
- {cluas/src β src}/characters/__init__.py +0 -0
- {cluas/src β src}/characters/corvus.py +0 -0
- {cluas/src β src}/characters/crow.py +0 -0
- {cluas/src β src}/characters/magpie.py +0 -0
- {cluas/src β src}/characters/raven.py +0 -0
- {cluas/src β src}/cluas_mcp/__init__.py +0 -0
- {cluas/src β src}/cluas_mcp/abstract_filtered.py +0 -0
- {cluas/src β src}/cluas_mcp/blah.py +0 -0
- {cluas/src β src}/cluas_mcp/common/__init__.py +0 -0
- {cluas/src β src}/cluas_mcp/common/api_clients.py +54 -0
- {cluas/src β src}/cluas_mcp/common/cache.py +0 -0
- src/cluas_mcp/common/formatting.py +22 -0
- {cluas/src β src}/cluas_mcp/common/memory.py +0 -0
- {cluas/src β src}/cluas_mcp/result.xml +0 -0
- {cluas/src β src}/cluas_mcp/server.py +0 -0
- {cluas/src β src}/cluas_mcp/testing_arxiv.py +0 -0
- {cluas/src β src}/cluas_mcp/tool_router.py +0 -0
- {cluas/src β src}/cluas_mcp/tools.py +0 -0
- {cluas/src β src}/data/cache.json +0 -0
- {cluas/src β src}/gradio/__init__.py +0 -0
- {cluas/src β src}/gradio/app.py +0 -0
- {cluas/tests β tests}/test_corvus.py +0 -0
- {cluas/tests β tests}/test_magpie.py +0 -0
- {cluas/tests β tests}/test_tools.py +0 -0
cluas/NOTICE β NOTICE
RENAMED
|
File without changes
|
cluas/src/cluas_mcp/common/formatting.py
DELETED
|
File without changes
|
experiments/01-first-tool
DELETED
|
File without changes
|
experiments/02-gradio-integration
DELETED
|
File without changes
|
experiments/03-multi-tool
DELETED
|
File without changes
|
gemini.md
ADDED
|
@@ -0,0 +1,55 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Gemini Context: Corvid Council Project
|
| 2 |
+
2
|
| 3 |
+
3 ## Project Overview
|
| 4 |
+
4 - **Name**: Corvid Council (formerly "Cluas")
|
| 5 |
+
5 - **Concept**: A multi-agent group chat where four AI crow
|
| 6 |
+
experts (Corvus, Magpie, Raven, Crow) discuss topics using
|
| 7 |
+
specialized MCP tools. The application has two interfaces: a
|
| 8 |
+
Gradio chat UI for observing the discussion and an external
|
| 9 |
+
MCP tool endpoint for programmatic queries.
|
| 10 |
+
6 - **Goal**: To build this system for the Gradio Agents & MCP
|
| 11 |
+
Hackathon.
|
| 12 |
+
7
|
| 13 |
+
8 ## Current State & Key Components
|
| 14 |
+
9 The project is in the very early stages of development,
|
| 15 |
+
aligning with "Week 1: Days 1-2" of the development guide.
|
| 16 |
+
10
|
| 17 |
+
11 - **`Corvus` Character**: A skeleton implementation exists in
|
| 18 |
+
`src/characters/corvus.py`. It includes logic for searching
|
| 19 |
+
academic papers with a fallback mechanism and integrates with
|
| 20 |
+
the `AgentMemory` system.
|
| 21 |
+
12 - **`AgentMemory`**: A foundational component (
|
| 22 |
+
`src/cluas_mcp/common/memory.py`) has been created to act as
|
| 23 |
+
a shared, persistent knowledge base for the agents. It
|
| 24 |
+
replaces the earlier, simpler `CacheManager`.
|
| 25 |
+
13 - **Supporting Files**: The repository includes a detailed
|
| 26 |
+
`README.md` (acting as the development guide), a
|
| 27 |
+
`requirements.txt` file, and a `.gitignore` file. A
|
| 28 |
+
boilerplate `src/gradio/app.py` has also been added.
|
| 29 |
+
14
|
| 30 |
+
15 ## Identified Issues & Blockers
|
| 31 |
+
16 1. **Broken `corvus.py` Import**: The file
|
| 32 |
+
`src/cluas_mcp/common/formatting.py` is empty, which means
|
| 33 |
+
the `format_authors` and `snippet_abstract` functions
|
| 34 |
+
imported by `corvus.py` do not exist. This prevents the
|
| 35 |
+
`Corvus` character from running.
|
| 36 |
+
17 2. **Missing Core Architecture**: Key components from the
|
| 37 |
+
development guide are not yet implemented:
|
| 38 |
+
18 - `CouncilOrchestrator` class to manage the
|
| 39 |
+
conversation.
|
| 40 |
+
19 - A `Character` base class.
|
| 41 |
+
20 - Integration between the Gradio UI and the agent
|
| 42 |
+
logic.
|
| 43 |
+
21 3. **Incomplete File Structure**: The current file structure
|
| 44 |
+
does not yet match the target structure outlined in the
|
| 45 |
+
development guide (e.g., separation of tools into their own
|
| 46 |
+
modules).
|
| 47 |
+
22 4. **Placeholder API Clients**: The `PubMedClient` and
|
| 48 |
+
`SemanticScholarClient` are still stubs.
|
| 49 |
+
23
|
| 50 |
+
24 ## Session State
|
| 51 |
+
25 - **File System Access Lost**: The project's root directory
|
| 52 |
+
was moved from `/Users/gboa/MCP-course-hf` to
|
| 53 |
+
`/Users/gboa/cluas`. My environment is sandboxed to the
|
| 54 |
+
original path, so I can no longer read from or write to any
|
| 55 |
+
project files.
|
main.py
DELETED
|
@@ -1,6 +0,0 @@
|
|
| 1 |
-
def main():
|
| 2 |
-
print("Hello from mcp-course-hf!")
|
| 3 |
-
|
| 4 |
-
|
| 5 |
-
if __name__ == "__main__":
|
| 6 |
-
main()
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
notes_etc/development_guide_01.md
ADDED
|
@@ -0,0 +1,797 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Corvid Council - Development Guide
|
| 2 |
+
|
| 3 |
+
## Project Overview
|
| 4 |
+
|
| 5 |
+
**Name**: Corvid Council
|
| 6 |
+
**Hackathon**: Gradio Agents & MCP Hackathon - Winter 25
|
| 7 |
+
**Track**: Building MCP (Creative)
|
| 8 |
+
**Tags**: `building-mcp-track-creative`
|
| 9 |
+
|
| 10 |
+
### Concept
|
| 11 |
+
A multi-agent group chat where 4 AI crow experts discuss topics, each using specialized MCP tools. The Gradio app itself also exposes MCP tools, allowing external applications to query the expert panel.
|
| 12 |
+
|
| 13 |
+
### The Hook
|
| 14 |
+
"What if you could consult a panel of AI experts? Use it two ways: watch them research and debate in a group chat, or query them as an MCP tool from Claude Desktop or any MCP client."
|
| 15 |
+
|
| 16 |
+
---
|
| 17 |
+
|
| 18 |
+
## Architecture
|
| 19 |
+
|
| 20 |
+
```
|
| 21 |
+
External User/App (Claude Desktop, etc.)
|
| 22 |
+
β (calls MCP tool)
|
| 23 |
+
ask_crow_council(question)
|
| 24 |
+
β (hits)
|
| 25 |
+
Gradio App (IS an MCP server)
|
| 26 |
+
β (internally orchestrates)
|
| 27 |
+
CouncilOrchestrator
|
| 28 |
+
β (manages)
|
| 29 |
+
4 Character Agents (Corvus, Magpie, Raven, Crow)
|
| 30 |
+
β (each uses)
|
| 31 |
+
Character-Specific MCP Tools (~12-15 total)
|
| 32 |
+
β (which call)
|
| 33 |
+
External APIs (Semantic Scholar, eBird, Weather, etc.)
|
| 34 |
+
β (returns aggregated response)
|
| 35 |
+
Back to User
|
| 36 |
+
```
|
| 37 |
+
|
| 38 |
+
### Two Interfaces, Same Backend
|
| 39 |
+
|
| 40 |
+
**Interface 1: Gradio Chat UI** (Direct access)
|
| 41 |
+
- Users see the full group chat
|
| 42 |
+
- Watch characters use their tools in real-time
|
| 43 |
+
- See sources, debates, synthesis
|
| 44 |
+
- Can inject questions
|
| 45 |
+
|
| 46 |
+
**Interface 2: MCP Tools** (Programmatic access)
|
| 47 |
+
- External apps call `ask_crow_council(question)`
|
| 48 |
+
- Same orchestration happens internally
|
| 49 |
+
- Returns structured, synthesized response
|
| 50 |
+
- Fast, clean API integration
|
| 51 |
+
|
| 52 |
+
---
|
| 53 |
+
|
| 54 |
+
## The Characters
|
| 55 |
+
|
| 56 |
+
### Corvus (The Scholar) - Melancholic
|
| 57 |
+
**Archetype**: Academic, thorough, perfectionist
|
| 58 |
+
**Personality**:
|
| 59 |
+
- PhD researcher studying corvid cognition
|
| 60 |
+
- Every claim needs citation
|
| 61 |
+
- Cautious, analytical, sometimes pedantic
|
| 62 |
+
- Posts rarely but substantively
|
| 63 |
+
- Always verifies before sharing
|
| 64 |
+
|
| 65 |
+
**Communication Style**:
|
| 66 |
+
- Long, structured messages
|
| 67 |
+
- Includes citations and methodology
|
| 68 |
+
- Questions assumptions
|
| 69 |
+
- "According to X study (DOI)..."
|
| 70 |
+
|
| 71 |
+
**MCP Tools** (4 tools):
|
| 72 |
+
- `search_corvid_papers(query, years, min_citations)` - Academic database search
|
| 73 |
+
- `get_paper_details(doi)` - Full paper information
|
| 74 |
+
- `verify_claim_against_literature(claim, context)` - Fact-checking
|
| 75 |
+
- `get_citation_network(doi, depth)` - Related research
|
| 76 |
+
|
| 77 |
+
**Behavior Pattern**:
|
| 78 |
+
1. Sees topic β searches papers
|
| 79 |
+
2. Reads abstract/methods β verifies quality
|
| 80 |
+
3. Composes careful response with citations
|
| 81 |
+
4. If others make claims β verifies against literature
|
| 82 |
+
|
| 83 |
+
---
|
| 84 |
+
|
| 85 |
+
### Magpie (The Enthusiast) - Sanguine
|
| 86 |
+
**Archetype**: Social, optimistic, storyteller
|
| 87 |
+
**Personality**:
|
| 88 |
+
- Collects crow stories like magpies collect shiny things
|
| 89 |
+
- Loves viral videos, human-interest pieces
|
| 90 |
+
- Shares everything excitedly, often unchecked
|
| 91 |
+
- Makes connections between unrelated things
|
| 92 |
+
- High energy, frequent poster
|
| 93 |
+
|
| 94 |
+
**Communication Style**:
|
| 95 |
+
- Rapid-fire short messages
|
| 96 |
+
- Uses emojis
|
| 97 |
+
- "omg you HAVE to see this!"
|
| 98 |
+
- Shares first, verifies later (or never)
|
| 99 |
+
|
| 100 |
+
**MCP Tools** (3 tools):
|
| 101 |
+
- `search_social_media(query, platform, timeframe)` - TikTok, Twitter, Reddit
|
| 102 |
+
- `search_web(query)` - General web search
|
| 103 |
+
- `find_trending_content(topic)` - What's viral right now
|
| 104 |
+
|
| 105 |
+
**Behavior Pattern**:
|
| 106 |
+
1. Sees topic β searches social/web immediately
|
| 107 |
+
2. Shares whatever looks interesting
|
| 108 |
+
3. Sometimes posts old/duplicate content
|
| 109 |
+
4. Creates energy, others moderate
|
| 110 |
+
|
| 111 |
+
**Quirk**: Posts old news 30-40% of the time (doesn't check dates)
|
| 112 |
+
|
| 113 |
+
---
|
| 114 |
+
|
| 115 |
+
### Raven (The Activist) - Choleric
|
| 116 |
+
**Archetype**: Action-oriented, passionate, confrontational
|
| 117 |
+
**Personality**:
|
| 118 |
+
- Environmental activist
|
| 119 |
+
- Sees crows as ecosystem health indicators
|
| 120 |
+
- Aggressive fact-gathering
|
| 121 |
+
- Calls out misinformation
|
| 122 |
+
- Posts urgent updates
|
| 123 |
+
|
| 124 |
+
**Communication Style**:
|
| 125 |
+
- Short, urgent messages
|
| 126 |
+
- Exclamation points
|
| 127 |
+
- "We need to act NOW"
|
| 128 |
+
- Challenges others directly
|
| 129 |
+
- Facts as weapons
|
| 130 |
+
|
| 131 |
+
**MCP Tools** (4 tools):
|
| 132 |
+
- `get_environmental_data(location, metric)` - Pollution, habitat data
|
| 133 |
+
- `search_news(query, recency)` - Current news monitoring
|
| 134 |
+
- `fact_check_claim(claim, source)` - Debunking tool
|
| 135 |
+
- `analyze_sentiment(topic, source)` - What are people saying?
|
| 136 |
+
|
| 137 |
+
**Behavior Pattern**:
|
| 138 |
+
1. Sees topic β looks for environmental angle
|
| 139 |
+
2. Searches news for threats/problems
|
| 140 |
+
3. Fact-checks others' claims aggressively
|
| 141 |
+
4. Rallies for action
|
| 142 |
+
|
| 143 |
+
**Creates drama**: Often disagrees with Corvus (action vs. more research)
|
| 144 |
+
|
| 145 |
+
---
|
| 146 |
+
|
| 147 |
+
### Crow (The Observer) - Phlegmatic
|
| 148 |
+
**Archetype**: Calm, patient, contemplative
|
| 149 |
+
**Personality**:
|
| 150 |
+
- Birdwatcher who observes local populations
|
| 151 |
+
- Philosophical, sees long-term patterns
|
| 152 |
+
- Rarely posts but reads everything
|
| 153 |
+
- When speaks, it's meaningful
|
| 154 |
+
- Patience over urgency
|
| 155 |
+
|
| 156 |
+
**Communication Style**:
|
| 157 |
+
- Rare, brief, profound
|
| 158 |
+
- Long silences then sudden insight
|
| 159 |
+
- "I've been watching..."
|
| 160 |
+
- Ties everything together
|
| 161 |
+
- No wasted words
|
| 162 |
+
|
| 163 |
+
**MCP Tools** (3 tools):
|
| 164 |
+
- `get_bird_sightings(location, species, timeframe)` - eBird data
|
| 165 |
+
- `get_weather_patterns(location, duration)` - Weather effects on behavior
|
| 166 |
+
- `analyze_temporal_patterns(data, timeframe)` - Long-term trends
|
| 167 |
+
|
| 168 |
+
**Behavior Pattern**:
|
| 169 |
+
1. Observes conversation quietly
|
| 170 |
+
2. Uses tools to gather observational data
|
| 171 |
+
3. Waits for pattern to emerge
|
| 172 |
+
4. Posts when has something meaningful
|
| 173 |
+
5. Often provides perspective that settles debates
|
| 174 |
+
|
| 175 |
+
**Special role**: The "wise elder" who cuts through noise
|
| 176 |
+
|
| 177 |
+
---
|
| 178 |
+
|
| 179 |
+
## MCP Tool Architecture
|
| 180 |
+
|
| 181 |
+
### Internal MCP Tools (Consumed by App)
|
| 182 |
+
|
| 183 |
+
All tools live in one MCP server: `crow-chat-mcp`
|
| 184 |
+
|
| 185 |
+
**Tool Categories**:
|
| 186 |
+
1. Academic (Corvus): 4 tools
|
| 187 |
+
2. Social/Web (Magpie): 3 tools
|
| 188 |
+
3. Real-time Data (Raven): 4 tools
|
| 189 |
+
4. Observational (Crow): 3 tools
|
| 190 |
+
|
| 191 |
+
**Total**: ~14 core tools
|
| 192 |
+
|
| 193 |
+
**Tool Definition Pattern**:
|
| 194 |
+
```python
|
| 195 |
+
@mcp.tool()
|
| 196 |
+
async def tool_name(
|
| 197 |
+
param1: str,
|
| 198 |
+
param2: int = default_value
|
| 199 |
+
) -> ReturnType:
|
| 200 |
+
"""
|
| 201 |
+
Clear description of what tool does.
|
| 202 |
+
|
| 203 |
+
Args:
|
| 204 |
+
param1: Description
|
| 205 |
+
param2: Description
|
| 206 |
+
|
| 207 |
+
Returns:
|
| 208 |
+
Description of return value
|
| 209 |
+
"""
|
| 210 |
+
# Implementation
|
| 211 |
+
pass
|
| 212 |
+
```
|
| 213 |
+
|
| 214 |
+
### External MCP Tools (Exposed by App)
|
| 215 |
+
|
| 216 |
+
**The Gradio app exposes these tools**:
|
| 217 |
+
|
| 218 |
+
```python
|
| 219 |
+
@mcp.tool()
|
| 220 |
+
async def ask_crow_council(question: str) -> dict:
|
| 221 |
+
"""
|
| 222 |
+
Consult the Corvid Council expert panel.
|
| 223 |
+
|
| 224 |
+
All four experts research using their specialized tools
|
| 225 |
+
and provide a synthesized answer with sources.
|
| 226 |
+
|
| 227 |
+
Returns:
|
| 228 |
+
{
|
| 229 |
+
"consensus": str, # Synthesized answer
|
| 230 |
+
"expert_opinions": [...], # Individual takes
|
| 231 |
+
"sources": [...], # All citations/links
|
| 232 |
+
"confidence": float # 0-1
|
| 233 |
+
}
|
| 234 |
+
"""
|
| 235 |
+
|
| 236 |
+
@mcp.tool()
|
| 237 |
+
async def ask_specific_expert(
|
| 238 |
+
question: str,
|
| 239 |
+
expert: Literal["corvus", "magpie", "raven", "crow"]
|
| 240 |
+
) -> dict:
|
| 241 |
+
"""
|
| 242 |
+
Query one specific expert.
|
| 243 |
+
"""
|
| 244 |
+
|
| 245 |
+
@mcp.tool()
|
| 246 |
+
async def fact_check_claim(claim: str) -> dict:
|
| 247 |
+
"""
|
| 248 |
+
Have the council verify a claim about crows.
|
| 249 |
+
|
| 250 |
+
Returns:
|
| 251 |
+
{
|
| 252 |
+
"verdict": "verified" | "disputed" | "unknown",
|
| 253 |
+
"evidence": [...],
|
| 254 |
+
"expert_consensus": str
|
| 255 |
+
}
|
| 256 |
+
"""
|
| 257 |
+
```
|
| 258 |
+
|
| 259 |
+
---
|
| 260 |
+
|
| 261 |
+
## Core Components
|
| 262 |
+
|
| 263 |
+
### 1. CouncilOrchestrator
|
| 264 |
+
**Purpose**: Coordinates character responses, manages conversation flow
|
| 265 |
+
|
| 266 |
+
**Key Methods**:
|
| 267 |
+
```python
|
| 268 |
+
class CouncilOrchestrator:
|
| 269 |
+
async def process_query(question: str) -> CouncilResult:
|
| 270 |
+
"""Main entry point for both UI and MCP"""
|
| 271 |
+
|
| 272 |
+
async def facilitate_discussion(question, initial_responses) -> Discussion:
|
| 273 |
+
"""Characters respond to each other"""
|
| 274 |
+
|
| 275 |
+
async def synthesize_consensus(responses) -> str:
|
| 276 |
+
"""Create unified answer for MCP calls"""
|
| 277 |
+
```
|
| 278 |
+
|
| 279 |
+
### 2. Character (Base Class)
|
| 280 |
+
**Purpose**: Encapsulates character behavior
|
| 281 |
+
|
| 282 |
+
**Key Methods**:
|
| 283 |
+
```python
|
| 284 |
+
class Character:
|
| 285 |
+
async def research_and_respond(question: str, context: list) -> Response:
|
| 286 |
+
"""Use tools to research, generate response"""
|
| 287 |
+
|
| 288 |
+
async def use_tools(question: str) -> list[ToolResult]:
|
| 289 |
+
"""Call relevant MCP tools"""
|
| 290 |
+
|
| 291 |
+
async def generate_message(question, tool_results, context) -> str:
|
| 292 |
+
"""Compose message in character voice"""
|
| 293 |
+
```
|
| 294 |
+
|
| 295 |
+
### 3. MCPToolManager
|
| 296 |
+
**Purpose**: Handles all MCP tool calls, error handling, rate limiting
|
| 297 |
+
|
| 298 |
+
**Key Methods**:
|
| 299 |
+
```python
|
| 300 |
+
class MCPToolManager:
|
| 301 |
+
async def call_tool(tool_name: str, params: dict) -> ToolResult:
|
| 302 |
+
"""Execute tool with error handling"""
|
| 303 |
+
|
| 304 |
+
async def batch_call_tools(calls: list) -> list[ToolResult]:
|
| 305 |
+
"""Call multiple tools efficiently"""
|
| 306 |
+
```
|
| 307 |
+
|
| 308 |
+
### 4. GradioInterface
|
| 309 |
+
**Purpose**: Chat UI for direct human interaction
|
| 310 |
+
|
| 311 |
+
**Key Methods**:
|
| 312 |
+
```python
|
| 313 |
+
def create_interface() -> gr.Blocks:
|
| 314 |
+
"""Build Gradio chat interface"""
|
| 315 |
+
|
| 316 |
+
async def handle_user_message(message, history, state):
|
| 317 |
+
"""Process user input, orchestrate responses"""
|
| 318 |
+
|
| 319 |
+
def display_tool_usage(character, tool_name):
|
| 320 |
+
"""Show 'Character is using tool...' indicators"""
|
| 321 |
+
```
|
| 322 |
+
|
| 323 |
+
---
|
| 324 |
+
|
| 325 |
+
## Development Phases
|
| 326 |
+
|
| 327 |
+
### Week 1: Core System (Days 1-7)
|
| 328 |
+
|
| 329 |
+
#### Days 1-2: Foundation
|
| 330 |
+
**Goal**: One character working with tools in Gradio
|
| 331 |
+
|
| 332 |
+
- [ ] Set up project structure
|
| 333 |
+
- [ ] Build `CouncilOrchestrator` skeleton
|
| 334 |
+
- [ ] Implement `Character` base class
|
| 335 |
+
- [ ] Create Corvus with 2 tools (search_papers, get_details)
|
| 336 |
+
- [ ] Basic Gradio interface
|
| 337 |
+
- [ ] Test: Corvus responds to question using tools
|
| 338 |
+
|
| 339 |
+
**Success Metric**: Ask "Are crows smart?", see Corvus search papers and respond with citation
|
| 340 |
+
|
| 341 |
+
#### Days 3-4: Second Character
|
| 342 |
+
**Goal**: Two characters interacting
|
| 343 |
+
|
| 344 |
+
- [ ] Add Magpie with 2 tools (search_web, search_social)
|
| 345 |
+
- [ ] Implement character interaction (they respond to each other)
|
| 346 |
+
- [ ] Staggered response timing (2-3 sec apart)
|
| 347 |
+
- [ ] Test: Both characters respond differently to same question
|
| 348 |
+
|
| 349 |
+
**Success Metric**: Two distinct personalities with different tool usage patterns visible
|
| 350 |
+
|
| 351 |
+
#### Days 5-6: Third & Fourth Characters
|
| 352 |
+
**Goal**: Full council assembled
|
| 353 |
+
|
| 354 |
+
- [ ] Add Raven with 2 tools (get_environmental_data, search_news)
|
| 355 |
+
- [ ] Add Crow with 2 tools (get_sightings, get_weather)
|
| 356 |
+
- [ ] Four-way interaction patterns
|
| 357 |
+
- [ ] Test: All four respond to question, some interact with each other
|
| 358 |
+
|
| 359 |
+
**Success Metric**: Rich multi-agent discussion with varied tool usage
|
| 360 |
+
|
| 361 |
+
#### Day 7: Week 1 Polish
|
| 362 |
+
- [ ] Improve system prompts for distinct personalities
|
| 363 |
+
- [ ] Add typing indicators
|
| 364 |
+
- [ ] Better error handling for tool failures
|
| 365 |
+
- [ ] Test conversation flows
|
| 366 |
+
- [ ] Fix bugs
|
| 367 |
+
|
| 368 |
+
---
|
| 369 |
+
|
| 370 |
+
### Week 2: External MCP & Polish (Days 8-14)
|
| 371 |
+
|
| 372 |
+
#### Days 8-9: MCP Exposure
|
| 373 |
+
**Goal**: Gradio app as MCP server
|
| 374 |
+
|
| 375 |
+
- [ ] Implement external MCP tool exposure
|
| 376 |
+
- [ ] `ask_crow_council()` tool
|
| 377 |
+
- [ ] `ask_specific_expert()` tool
|
| 378 |
+
- [ ] Test from Claude Desktop or MCP inspector
|
| 379 |
+
- [ ] Ensure both interfaces use same orchestrator
|
| 380 |
+
|
| 381 |
+
**Success Metric**: External tool call triggers internal discussion, returns synthesized response
|
| 382 |
+
|
| 383 |
+
#### Days 10-11: Additional Tools & Refinement
|
| 384 |
+
**Goal**: Complete tool sets
|
| 385 |
+
|
| 386 |
+
- [ ] Add remaining tools (3rd-4th tool per character)
|
| 387 |
+
- [ ] Implement `fact_check_claim()` external tool
|
| 388 |
+
- [ ] Add tool chaining where appropriate
|
| 389 |
+
- [ ] Better synthesis algorithm for consensus
|
| 390 |
+
- [ ] Rate limiting and caching
|
| 391 |
+
|
| 392 |
+
#### Days 12-13: Polish & Demo Prep
|
| 393 |
+
**Goal**: Production ready
|
| 394 |
+
|
| 395 |
+
- [ ] UI improvements (avatars, timestamps, theming)
|
| 396 |
+
- [ ] Tool usage visualization
|
| 397 |
+
- [ ] Demo mode with curated scenarios
|
| 398 |
+
- [ ] Write comprehensive README
|
| 399 |
+
- [ ] Create demo video showing both interfaces
|
| 400 |
+
- [ ] Test edge cases
|
| 401 |
+
|
| 402 |
+
#### Day 14: Deployment & Documentation
|
| 403 |
+
**Goal**: Ship it
|
| 404 |
+
|
| 405 |
+
- [ ] Deploy to Hugging Face Spaces
|
| 406 |
+
- [ ] Verify both interfaces work publicly
|
| 407 |
+
- [ ] Final testing in Claude Desktop
|
| 408 |
+
- [ ] Polish documentation
|
| 409 |
+
- [ ] Submit to hackathon
|
| 410 |
+
- [ ] Buffer for last-minute issues
|
| 411 |
+
|
| 412 |
+
---
|
| 413 |
+
|
| 414 |
+
## Technical Stack
|
| 415 |
+
|
| 416 |
+
### Core
|
| 417 |
+
- **Python 3.10+**
|
| 418 |
+
- **Gradio 5.x** (with MCP capabilities)
|
| 419 |
+
- **MCP SDK** (`pip install mcp`)
|
| 420 |
+
- **OpenAI API** (gpt-4o-mini for characters)
|
| 421 |
+
- **Anthropic API** (optional, for variety)
|
| 422 |
+
|
| 423 |
+
### External APIs
|
| 424 |
+
- **Semantic Scholar API** (academic papers) - Free, no key needed
|
| 425 |
+
- **Brave Search API** or **SerpAPI** (web search) - Free tier available
|
| 426 |
+
- **eBird API** (bird sightings) - Free with registration
|
| 427 |
+
- **OpenWeather API** (weather data) - Free tier
|
| 428 |
+
- **News API** (news search) - Free tier
|
| 429 |
+
|
| 430 |
+
### Development Tools
|
| 431 |
+
- **MCP Inspector** (for testing MCP tools)
|
| 432 |
+
- **Claude Desktop** (for testing external tool usage)
|
| 433 |
+
- **Git/GitHub** (version control)
|
| 434 |
+
- **HF Spaces** (deployment)
|
| 435 |
+
|
| 436 |
+
---
|
| 437 |
+
|
| 438 |
+
## File Structure
|
| 439 |
+
|
| 440 |
+
```
|
| 441 |
+
corvid-council/
|
| 442 |
+
βββ README.md
|
| 443 |
+
βββ requirements.txt
|
| 444 |
+
βββ app.py # Main Gradio app
|
| 445 |
+
βββ .env.example # API key template
|
| 446 |
+
βββ src/
|
| 447 |
+
β βββ __init__.py
|
| 448 |
+
β βββ orchestrator.py # CouncilOrchestrator
|
| 449 |
+
β βββ character.py # Character base class
|
| 450 |
+
β βββ characters/
|
| 451 |
+
β β βββ __init__.py
|
| 452 |
+
β β βββ corvus.py # Corvus implementation
|
| 453 |
+
β β βββ magpie.py # Magpie implementation
|
| 454 |
+
β β βββ raven.py # Raven implementation
|
| 455 |
+
β β βββ crow.py # Crow implementation
|
| 456 |
+
β βββ mcp/
|
| 457 |
+
β β βββ __init__.py
|
| 458 |
+
β β βββ server.py # Internal MCP server
|
| 459 |
+
β β βββ tools/
|
| 460 |
+
β β β βββ academic.py # Corvus tools
|
| 461 |
+
β β β βββ social.py # Magpie tools
|
| 462 |
+
β β β βββ realtime.py # Raven tools
|
| 463 |
+
β β β βββ observational.py # Crow tools
|
| 464 |
+
β β βββ external.py # External MCP tools (exposed by app)
|
| 465 |
+
β βββ ui/
|
| 466 |
+
β β βββ __init__.py
|
| 467 |
+
β β βββ interface.py # Gradio interface
|
| 468 |
+
β β βββ components.py # Custom UI components
|
| 469 |
+
β βββ utils/
|
| 470 |
+
β βββ __init__.py
|
| 471 |
+
β βββ prompts.py # System prompts for characters
|
| 472 |
+
β βββ helpers.py # Utility functions
|
| 473 |
+
βββ tests/
|
| 474 |
+
βββ test_orchestrator.py
|
| 475 |
+
βββ test_characters.py
|
| 476 |
+
βββ test_mcp_tools.py
|
| 477 |
+
```
|
| 478 |
+
|
| 479 |
+
---
|
| 480 |
+
|
| 481 |
+
## Key Implementation Patterns
|
| 482 |
+
|
| 483 |
+
### Pattern 1: Staggered Responses
|
| 484 |
+
```python
|
| 485 |
+
async def generate_responses(question, characters):
|
| 486 |
+
"""Characters respond one at a time with delays"""
|
| 487 |
+
responses = []
|
| 488 |
+
|
| 489 |
+
for i, character in enumerate(characters):
|
| 490 |
+
# Show typing indicator
|
| 491 |
+
show_typing(character.name)
|
| 492 |
+
|
| 493 |
+
# Delay based on message length
|
| 494 |
+
await asyncio.sleep(random.uniform(2, 5))
|
| 495 |
+
|
| 496 |
+
# Generate response (includes tool usage)
|
| 497 |
+
response = await character.research_and_respond(
|
| 498 |
+
question,
|
| 499 |
+
context=responses # See previous responses
|
| 500 |
+
)
|
| 501 |
+
|
| 502 |
+
responses.append(response)
|
| 503 |
+
|
| 504 |
+
return responses
|
| 505 |
+
```
|
| 506 |
+
|
| 507 |
+
### Pattern 2: Tool Usage Display
|
| 508 |
+
```python
|
| 509 |
+
async def use_tools_with_display(character, tools_to_use):
|
| 510 |
+
"""Show tool usage in UI"""
|
| 511 |
+
results = []
|
| 512 |
+
|
| 513 |
+
for tool in tools_to_use:
|
| 514 |
+
# Show in UI: "Corvus is searching papers..."
|
| 515 |
+
update_ui(f"{character.name} is using {tool.name}...")
|
| 516 |
+
|
| 517 |
+
try:
|
| 518 |
+
result = await mcp_client.call_tool(tool.name, tool.params)
|
| 519 |
+
results.append(result)
|
| 520 |
+
except Exception as e:
|
| 521 |
+
# Show error gracefully
|
| 522 |
+
update_ui(f"β οΈ Tool {tool.name} failed, continuing...")
|
| 523 |
+
|
| 524 |
+
return results
|
| 525 |
+
```
|
| 526 |
+
|
| 527 |
+
### Pattern 3: Character Decides Which Tools
|
| 528 |
+
```python
|
| 529 |
+
async def research_and_respond(self, question, context):
|
| 530 |
+
"""Character decides which tools to use"""
|
| 531 |
+
|
| 532 |
+
# Ask LLM what tools to use
|
| 533 |
+
tool_plan = await self.llm.generate(
|
| 534 |
+
system_prompt=self.system_prompt,
|
| 535 |
+
user_prompt=f"""
|
| 536 |
+
Question: {question}
|
| 537 |
+
Available tools: {self.tools}
|
| 538 |
+
|
| 539 |
+
Which tools should you use? Return JSON list.
|
| 540 |
+
"""
|
| 541 |
+
)
|
| 542 |
+
|
| 543 |
+
# Execute chosen tools
|
| 544 |
+
tool_results = await self.execute_tools(tool_plan)
|
| 545 |
+
|
| 546 |
+
# Generate response using results
|
| 547 |
+
message = await self.llm.generate(
|
| 548 |
+
system_prompt=self.system_prompt,
|
| 549 |
+
user_prompt=f"""
|
| 550 |
+
Question: {question}
|
| 551 |
+
Tool results: {tool_results}
|
| 552 |
+
|
| 553 |
+
Write your response in character.
|
| 554 |
+
"""
|
| 555 |
+
)
|
| 556 |
+
|
| 557 |
+
return message
|
| 558 |
+
```
|
| 559 |
+
|
| 560 |
+
### Pattern 4: Consensus Synthesis
|
| 561 |
+
```python
|
| 562 |
+
async def synthesize_consensus(self, responses):
|
| 563 |
+
"""Create unified answer for MCP calls"""
|
| 564 |
+
|
| 565 |
+
# Extract key points from each response
|
| 566 |
+
synthesis_prompt = f"""
|
| 567 |
+
Four experts answered the same question. Synthesize their responses:
|
| 568 |
+
|
| 569 |
+
Corvus (Academic): {responses['corvus']}
|
| 570 |
+
Magpie (Social): {responses['magpie']}
|
| 571 |
+
Raven (Activist): {responses['raven']}
|
| 572 |
+
Crow (Observer): {responses['crow']}
|
| 573 |
+
|
| 574 |
+
Create a consensus answer that:
|
| 575 |
+
- Combines their insights
|
| 576 |
+
- Notes where they agree/disagree
|
| 577 |
+
- Includes all sources
|
| 578 |
+
- Rates overall confidence
|
| 579 |
+
"""
|
| 580 |
+
|
| 581 |
+
return await llm.generate(synthesis_prompt)
|
| 582 |
+
```
|
| 583 |
+
|
| 584 |
+
---
|
| 585 |
+
|
| 586 |
+
## Common Pitfalls & Solutions
|
| 587 |
+
|
| 588 |
+
### Pitfall 1: Rate Limiting
|
| 589 |
+
**Problem**: Hitting API rate limits with multiple characters
|
| 590 |
+
|
| 591 |
+
**Solutions**:
|
| 592 |
+
- Stagger API calls (2-3 seconds apart)
|
| 593 |
+
- Use cheaper models (gpt-4o-mini)
|
| 594 |
+
- Cache tool results
|
| 595 |
+
- Implement exponential backoff
|
| 596 |
+
|
| 597 |
+
### Pitfall 2: Tool Failures
|
| 598 |
+
**Problem**: External API is down or returns error
|
| 599 |
+
|
| 600 |
+
**Solutions**:
|
| 601 |
+
- Always wrap tool calls in try-except
|
| 602 |
+
- Have fallback responses
|
| 603 |
+
- Show errors gracefully to user
|
| 604 |
+
- Continue conversation even if one tool fails
|
| 605 |
+
|
| 606 |
+
### Pitfall 3: Repetitive Conversations
|
| 607 |
+
**Problem**: Characters say similar things
|
| 608 |
+
|
| 609 |
+
**Solutions**:
|
| 610 |
+
- Strong, distinct system prompts
|
| 611 |
+
- Different tool sets force different perspectives
|
| 612 |
+
- Include context of previous responses
|
| 613 |
+
- Add personality quirks (Magpie posts old news, etc.)
|
| 614 |
+
|
| 615 |
+
### Pitfall 4: Slow Responses
|
| 616 |
+
**Problem**: Waiting for multiple LLM + tool calls is slow
|
| 617 |
+
|
| 618 |
+
**Solutions**:
|
| 619 |
+
- Show typing indicators
|
| 620 |
+
- Stream responses where possible
|
| 621 |
+
- Call tools in parallel when they don't depend on each other
|
| 622 |
+
- Pre-generate demo scenarios for judging
|
| 623 |
+
|
| 624 |
+
### Pitfall 5: MCP Exposure Not Working
|
| 625 |
+
**Problem**: External apps can't call your tools
|
| 626 |
+
|
| 627 |
+
**Solutions**:
|
| 628 |
+
- Test with MCP Inspector first
|
| 629 |
+
- Check CORS settings
|
| 630 |
+
- Verify tool schemas are valid
|
| 631 |
+
- Ensure server is publicly accessible
|
| 632 |
+
- Check HF Spaces networking settings
|
| 633 |
+
|
| 634 |
+
---
|
| 635 |
+
|
| 636 |
+
## Testing Strategy
|
| 637 |
+
|
| 638 |
+
### Unit Tests
|
| 639 |
+
- Individual tools return expected format
|
| 640 |
+
- Characters generate appropriate responses
|
| 641 |
+
- Orchestrator handles edge cases
|
| 642 |
+
|
| 643 |
+
### Integration Tests
|
| 644 |
+
- Full conversation flow works
|
| 645 |
+
- Both interfaces (UI and MCP) work
|
| 646 |
+
- Tool failures handled gracefully
|
| 647 |
+
|
| 648 |
+
### Manual Testing Scenarios
|
| 649 |
+
|
| 650 |
+
**Scenario 1: Basic Question**
|
| 651 |
+
- Ask: "Are crows smart?"
|
| 652 |
+
- Expect: All 4 respond, use tools, cite sources
|
| 653 |
+
|
| 654 |
+
**Scenario 2: Fact-Checking**
|
| 655 |
+
- Magpie posts dubious claim
|
| 656 |
+
- Expect: Corvus or Raven fact-checks it
|
| 657 |
+
|
| 658 |
+
**Scenario 3: External MCP Call**
|
| 659 |
+
- From Claude Desktop: call `ask_crow_council("Do crows use tools?")`
|
| 660 |
+
- Expect: Structured response with consensus
|
| 661 |
+
|
| 662 |
+
**Scenario 4: Old News**
|
| 663 |
+
- Magpie shares old content
|
| 664 |
+
- Expect: Others notice and comment (first few times)
|
| 665 |
+
|
| 666 |
+
**Scenario 5: Tool Failure**
|
| 667 |
+
- Simulate API down
|
| 668 |
+
- Expect: Graceful degradation, conversation continues
|
| 669 |
+
|
| 670 |
+
---
|
| 671 |
+
|
| 672 |
+
## Demo Script
|
| 673 |
+
|
| 674 |
+
### Demo 1: Gradio UI (2 minutes)
|
| 675 |
+
1. Open interface, introduce the four experts
|
| 676 |
+
2. Ask: "Can crows recognize individual humans?"
|
| 677 |
+
3. Show:
|
| 678 |
+
- Characters using different tools
|
| 679 |
+
- Tool usage indicators
|
| 680 |
+
- Different personality styles
|
| 681 |
+
- Sources and citations
|
| 682 |
+
4. Highlight: Real-time research, transparent process
|
| 683 |
+
|
| 684 |
+
### Demo 2: MCP Tool Usage (2 minutes)
|
| 685 |
+
1. Switch to Claude Desktop
|
| 686 |
+
2. Show available tools: `ask_crow_council`, etc.
|
| 687 |
+
3. Ask same question through MCP tool
|
| 688 |
+
4. Show:
|
| 689 |
+
- Same backend process (quick view of Gradio)
|
| 690 |
+
- Structured response returned
|
| 691 |
+
- Synthesized consensus with sources
|
| 692 |
+
5. Highlight: Same intelligence, two interfaces
|
| 693 |
+
|
| 694 |
+
### Demo 3: Architecture Explanation (1 minute)
|
| 695 |
+
1. Show diagram
|
| 696 |
+
2. Explain: MCP tools consuming MCP tools
|
| 697 |
+
3. Point out: Composability, extensibility
|
| 698 |
+
4. Mention: Could add more experts, more tools
|
| 699 |
+
|
| 700 |
+
---
|
| 701 |
+
|
| 702 |
+
## Success Criteria
|
| 703 |
+
|
| 704 |
+
### Minimum Viable Product (Must Have)
|
| 705 |
+
- β
4 characters with distinct personalities
|
| 706 |
+
- β
8-10 working MCP tools (2-3 per character)
|
| 707 |
+
- β
Gradio chat interface
|
| 708 |
+
- β
External MCP tool exposure (ask_crow_council)
|
| 709 |
+
- β
Both interfaces work reliably
|
| 710 |
+
- β
Deployed to HF Spaces
|
| 711 |
+
- β
Good README and demo
|
| 712 |
+
|
| 713 |
+
### Stretch Goals (Nice to Have)
|
| 714 |
+
- β
12-15 tools (full tool sets)
|
| 715 |
+
- β
Tool chaining (one tool's output β another)
|
| 716 |
+
- β
Advanced interaction patterns (quirk decay)
|
| 717 |
+
- β
Memory across sessions
|
| 718 |
+
- β
Beautiful UI with animations
|
| 719 |
+
- β
Comprehensive error handling
|
| 720 |
+
|
| 721 |
+
### Judging Criteria (What Matters)
|
| 722 |
+
1. **Technical sophistication**: Multi-tool MCP system
|
| 723 |
+
2. **Creativity**: Novel use of MCP (agents-as-tools)
|
| 724 |
+
3. **Completeness**: Both interfaces work well
|
| 725 |
+
4. **Demo quality**: Clear, impressive, functional
|
| 726 |
+
5. **Documentation**: Easy to understand and extend
|
| 727 |
+
|
| 728 |
+
---
|
| 729 |
+
|
| 730 |
+
## Resources
|
| 731 |
+
|
| 732 |
+
### APIs
|
| 733 |
+
- Semantic Scholar: https://api.semanticscholar.org/
|
| 734 |
+
- eBird: https://documenter.getpostman.com/view/664302/S1ENwy59
|
| 735 |
+
- OpenWeather: https://openweathermap.org/api
|
| 736 |
+
- News API: https://newsapi.org/
|
| 737 |
+
|
| 738 |
+
### Documentation
|
| 739 |
+
- MCP Spec: https://spec.modelcontextprotocol.io/
|
| 740 |
+
- Gradio Docs: https://www.gradio.app/docs
|
| 741 |
+
- HF Course: https://huggingface.co/learn/mcp-course/
|
| 742 |
+
|
| 743 |
+
### Tools
|
| 744 |
+
- MCP Inspector: (check course for link)
|
| 745 |
+
- Claude Desktop: https://claude.ai/download
|
| 746 |
+
|
| 747 |
+
---
|
| 748 |
+
|
| 749 |
+
## Quick Start Commands
|
| 750 |
+
|
| 751 |
+
```bash
|
| 752 |
+
# Clone and setup
|
| 753 |
+
git clone <your-repo>
|
| 754 |
+
cd corvid-council
|
| 755 |
+
pip install -r requirements.txt
|
| 756 |
+
|
| 757 |
+
# Set up environment
|
| 758 |
+
cp .env.example .env
|
| 759 |
+
# Edit .env with your API keys
|
| 760 |
+
|
| 761 |
+
# Run locally
|
| 762 |
+
python app.py
|
| 763 |
+
|
| 764 |
+
# Deploy to HF Spaces
|
| 765 |
+
git push hf main
|
| 766 |
+
```
|
| 767 |
+
|
| 768 |
+
---
|
| 769 |
+
|
| 770 |
+
## Support Checklist for LLMs
|
| 771 |
+
|
| 772 |
+
When asking an LLM for help, provide:
|
| 773 |
+
- [ ] This development guide
|
| 774 |
+
- [ ] Specific file you're working on
|
| 775 |
+
- [ ] Error message if debugging
|
| 776 |
+
- [ ] What you've tried already
|
| 777 |
+
- [ ] Specific question or task
|
| 778 |
+
|
| 779 |
+
**Example prompt**:
|
| 780 |
+
```
|
| 781 |
+
I'm building the Corvid Council project (see attached dev guide).
|
| 782 |
+
I'm working on [specific component].
|
| 783 |
+
I'm trying to [specific task].
|
| 784 |
+
I'm getting [error/issue].
|
| 785 |
+
I've tried [what you tried].
|
| 786 |
+
Can you help me [specific ask]?
|
| 787 |
+
```
|
| 788 |
+
|
| 789 |
+
---
|
| 790 |
+
|
| 791 |
+
## Contact & Resources
|
| 792 |
+
|
| 793 |
+
**Hackathon**: Gradio Agents & MCP Hackathon - Winter 25
|
| 794 |
+
**Track**: Building MCP (Creative)
|
| 795 |
+
**Tag**: `building-mcp-track-creative`
|
| 796 |
+
|
| 797 |
+
Good luck! Build something amazing. π―
|
notes_etc/development_guide_02.txt
ADDED
|
@@ -0,0 +1,181 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
Project Overview
|
| 2 |
+
|
| 3 |
+
Name: Cluas
|
| 4 |
+
Hackathon / Track: Gradio Agents & MCP Hackathon β Winter 25, Creative Track
|
| 5 |
+
Concept: A multi-agent MCP system where four AI βcrow expertsβ discuss topics, each using specialized tools. Users can either observe the panel in a Gradio chat interface or query it programmatically via MCP.
|
| 6 |
+
|
| 7 |
+
Hook:
|
| 8 |
+
βWhat if you could consult a panel of AI experts that not only debates, researches, and cross-verifies claims but also maintains a shared memory across sessions?β
|
| 9 |
+
|
| 10 |
+
Architecture Overview
|
| 11 |
+
External User/App (Claude Desktop, etc.)
|
| 12 |
+
β (calls MCP tool)
|
| 13 |
+
ask_crow_council(question)
|
| 14 |
+
β
|
| 15 |
+
Gradio App (MCP server)
|
| 16 |
+
β
|
| 17 |
+
CouncilOrchestrator
|
| 18 |
+
β
|
| 19 |
+
4 Character Agents (Corvus, Magpie, Raven, Crow)
|
| 20 |
+
β
|
| 21 |
+
Character-Specific MCP Tools (~12β15 total)
|
| 22 |
+
β
|
| 23 |
+
External APIs (Semantic Scholar, eBird, Weather, News)
|
| 24 |
+
β
|
| 25 |
+
Shared AgentMemory (JSON / DB)
|
| 26 |
+
β
|
| 27 |
+
Synthesized Response β User
|
| 28 |
+
|
| 29 |
+
|
| 30 |
+
Key Differences vs. earlier plan:
|
| 31 |
+
|
| 32 |
+
AgentMemory is first-class: acts as shared context, not just caching.
|
| 33 |
+
|
| 34 |
+
Cache is memory: supports cross-agent recall, deduplication, βdidnβt we discuss this?β
|
| 35 |
+
|
| 36 |
+
Tool orchestration is separate from UI: backend drives both Gradio interface and MCP endpoint.
|
| 37 |
+
|
| 38 |
+
Characters
|
| 39 |
+
Character Role Personality Core Tools Behavior
|
| 40 |
+
Corvus Scholar Analytical, cautious, thorough search_academic, get_paper_details, verify_claim, citation_network Reads literature, fact-checks, posts rarely but substantively
|
| 41 |
+
Magpie Enthusiast Social, rapid-fire, excited search_social, search_web, find_trending Posts frequently, may repeat info, creates conversational energy
|
| 42 |
+
Raven Activist Urgent, confrontational, data-driven get_environmental_data, search_news, fact_check_claim, analyze_sentiment Searches real-time threats, challenges othersβ claims
|
| 43 |
+
Crow Observer Calm, patient, contemplative get_sightings, get_weather_patterns, analyze_temporal_patterns Rarely posts, synthesizes patterns, provides perspective
|
| 44 |
+
|
| 45 |
+
Notes:
|
| 46 |
+
|
| 47 |
+
Each character writes in a distinct voice.
|
| 48 |
+
|
| 49 |
+
AgentMemory is referenced when appropriate to recall past papers, claims, or events.
|
| 50 |
+
|
| 51 |
+
Tools are abstracted behind MCP methods for modularity.
|
| 52 |
+
|
| 53 |
+
MCP Tool Architecture
|
| 54 |
+
|
| 55 |
+
Internal MCP Tools (Character Tools):
|
| 56 |
+
|
| 57 |
+
Academic (Corvus): 4 tools
|
| 58 |
+
|
| 59 |
+
Social/Web (Magpie): 3 tools
|
| 60 |
+
|
| 61 |
+
Real-time Data (Raven): 4 tools
|
| 62 |
+
|
| 63 |
+
Observational (Crow): 3 tools
|
| 64 |
+
|
| 65 |
+
External MCP Tools (Exposed via Gradio App):
|
| 66 |
+
|
| 67 |
+
@mcp.tool()
|
| 68 |
+
async def ask_crow_council(question: str) -> dict:
|
| 69 |
+
"""Consult all 4 characters; return synthesized response with sources."""
|
| 70 |
+
|
| 71 |
+
@mcp.tool()
|
| 72 |
+
async def ask_specific_expert(question: str, expert: Literal["corvus", "magpie", "raven", "crow"]) -> dict:
|
| 73 |
+
"""Query a single character."""
|
| 74 |
+
|
| 75 |
+
@mcp.tool()
|
| 76 |
+
async def fact_check_claim(claim: str) -> dict:
|
| 77 |
+
"""Have the council verify a claim using AgentMemory and tools."""
|
| 78 |
+
|
| 79 |
+
|
| 80 |
+
AgentMemory Integration:
|
| 81 |
+
|
| 82 |
+
Logs items with metadata: title, DOI/arXiv link, snippet, timestamp, tags.
|
| 83 |
+
|
| 84 |
+
Retrieval methods: get_recent(days), get_by_tag(tag), search_title(query).
|
| 85 |
+
|
| 86 |
+
Can prune old memories; supports both short-term and long-term context.
|
| 87 |
+
|
| 88 |
+
Project Structure (Updated for Modularity)
|
| 89 |
+
cluas/
|
| 90 |
+
βββ README.md
|
| 91 |
+
βββ .env.example
|
| 92 |
+
βββ src/
|
| 93 |
+
β βββ __init__.py
|
| 94 |
+
β βββ orchestrator.py # CouncilOrchestrator
|
| 95 |
+
β βββ character.py # Character base class
|
| 96 |
+
β βββ characters/
|
| 97 |
+
β β βββ corvus.py
|
| 98 |
+
β β βββ magpie.py
|
| 99 |
+
β β βββ raven.py
|
| 100 |
+
β β βββ crow.py
|
| 101 |
+
β βββ mcp/
|
| 102 |
+
β β βββ server.py # Internal MCP server
|
| 103 |
+
β β βββ tools/
|
| 104 |
+
β β β βββ academic.py
|
| 105 |
+
β β β βββ social.py
|
| 106 |
+
β β β βββ realtime.py
|
| 107 |
+
β β β βββ observational.py
|
| 108 |
+
β β βββ external.py # Exposed MCP tools
|
| 109 |
+
β βββ memory/
|
| 110 |
+
β β βββ agent_memory.py # Shared memory / cache
|
| 111 |
+
β βββ ui/
|
| 112 |
+
β β βββ interface.py
|
| 113 |
+
β β βββ components.py
|
| 114 |
+
β βββ utils/
|
| 115 |
+
β βββ prompts.py
|
| 116 |
+
β βββ helpers.py
|
| 117 |
+
βββ tests/
|
| 118 |
+
βββ test_orchestrator.py
|
| 119 |
+
βββ test_characters.py
|
| 120 |
+
βββ test_agent_memory.py
|
| 121 |
+
|
| 122 |
+
Development Phases (Current Scope)
|
| 123 |
+
Phase 1 β Core MVP
|
| 124 |
+
|
| 125 |
+
Corvus implemented with 2 academic tools.
|
| 126 |
+
|
| 127 |
+
Basic AgentMemory operational (short-term storage).
|
| 128 |
+
|
| 129 |
+
Basic Gradio chat interface.
|
| 130 |
+
|
| 131 |
+
Tool orchestration scaffolding in place.
|
| 132 |
+
|
| 133 |
+
Phase 2 β Additional Characters & Tools
|
| 134 |
+
|
| 135 |
+
Add Magpie and Raven with partial tools.
|
| 136 |
+
|
| 137 |
+
Implement staggered responses, typing indicators.
|
| 138 |
+
|
| 139 |
+
Ensure memory integration across agents.
|
| 140 |
+
|
| 141 |
+
Phase 3 β Full Council & MCP Exposure
|
| 142 |
+
|
| 143 |
+
Crow added.
|
| 144 |
+
|
| 145 |
+
Expose ask_crow_council() and ask_specific_expert().
|
| 146 |
+
|
| 147 |
+
Test multi-agent synthesis and external calls.
|
| 148 |
+
|
| 149 |
+
Phase 4 β Polish & Deploy
|
| 150 |
+
|
| 151 |
+
Error handling, retries, and rate limiting.
|
| 152 |
+
|
| 153 |
+
Memory pruning, long-term storage optional (Supabase / MongoDB).
|
| 154 |
+
|
| 155 |
+
UI/UX polish for Gradio.
|
| 156 |
+
|
| 157 |
+
Demo-ready, hackathon-ready deployment.
|
| 158 |
+
|
| 159 |
+
Key Implementation Patterns
|
| 160 |
+
|
| 161 |
+
Tool orchestration per character β each agent decides which tools to use, executes asynchronously.
|
| 162 |
+
|
| 163 |
+
Staggered responses β enhances human-like timing.
|
| 164 |
+
|
| 165 |
+
Memory-driven context β prior discussions inform current responses.
|
| 166 |
+
|
| 167 |
+
Consensus synthesis β LLM generates unified response for MCP output.
|
| 168 |
+
|
| 169 |
+
Technical Stack
|
| 170 |
+
|
| 171 |
+
Python 3.13 (uv-managed)
|
| 172 |
+
|
| 173 |
+
Gradio 5.x with MCP
|
| 174 |
+
|
| 175 |
+
MCP SDK for server and tools
|
| 176 |
+
|
| 177 |
+
LLM: gpt-4o-mini (Anthropic optional)
|
| 178 |
+
|
| 179 |
+
APIs: Semantic Scholar, eBird, News API, OpenWeather
|
| 180 |
+
|
| 181 |
+
Data/Memory: JSON for now, possible future DB (Supabase or MongoDB)
|
notes_etc/exposing_cluas_as_an_MCP.py
ADDED
|
@@ -0,0 +1,14 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# figure something a bit like this
|
| 2 |
+
|
| 3 |
+
|
| 4 |
+
@mcp.tool()
|
| 5 |
+
async def ask_crow_council(question: str) -> dict:
|
| 6 |
+
"""Consult all 4 characters; return synthesized response with sources."""
|
| 7 |
+
|
| 8 |
+
@mcp.tool()
|
| 9 |
+
async def ask_specific_expert(question: str, expert: Literal["corvus", "magpie", "raven", "crow"]) -> dict:
|
| 10 |
+
"""Query a single character."""
|
| 11 |
+
|
| 12 |
+
@mcp.tool()
|
| 13 |
+
async def fact_check_claim(claim: str) -> dict:
|
| 14 |
+
"""Have the council verify a claim using AgentMemory and tools."""
|
notes_etc/possible_lightweight_architecture_diagram.txt
ADDED
|
@@ -0,0 +1,53 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
βββββββββββββββββββββββββββββββ
|
| 2 |
+
β External User / App β
|
| 3 |
+
β (Claude Desktop, API call) β
|
| 4 |
+
βββββββββββββββ¬ββββββββββββββ
|
| 5 |
+
β ask_crow_council(question)
|
| 6 |
+
βΌ
|
| 7 |
+
βββββββββββββββββββββββββββββββ
|
| 8 |
+
β Gradio App / MCP Server β
|
| 9 |
+
β (crow-chat-mcp) β
|
| 10 |
+
βββββββββββββββ¬ββββββββββββββ
|
| 11 |
+
β orchestrates
|
| 12 |
+
βΌ
|
| 13 |
+
βββββββββββββββββββββββββββββββ
|
| 14 |
+
β CouncilOrchestrator β
|
| 15 |
+
β - Handles conversation flow β
|
| 16 |
+
β - Calls Character agents β
|
| 17 |
+
βββββββββββββββ¬ββββββββββββββ
|
| 18 |
+
β interacts with
|
| 19 |
+
βΌ
|
| 20 |
+
βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ βββββββββββββββββ
|
| 21 |
+
β Corvus β β Magpie β β Raven β β Crow β
|
| 22 |
+
β (Scholar) β β (Enthusiast) β β (Activist) β β (Observer) β
|
| 23 |
+
β - Academic β β - Web/Social β β - Real-time β β - Observationalβ
|
| 24 |
+
β Tools β β Tools β β Data Tools β β Tools β
|
| 25 |
+
βββββββββ¬ββββββββ βββββββββ¬ββββββββ βββββββββ¬ββββββββ βββββββββ¬ββββββββ
|
| 26 |
+
β β β β
|
| 27 |
+
β β β β
|
| 28 |
+
βββββββββββββββββ¬ββββββββββββββββββββββββββ΄ββββββββββββββββββββββ
|
| 29 |
+
βΌ
|
| 30 |
+
βββββββββββββββ
|
| 31 |
+
β AgentMemory β
|
| 32 |
+
β (JSON / DB) β
|
| 33 |
+
β - Logs itemsβ
|
| 34 |
+
β - Tags, DOI β
|
| 35 |
+
β - Recency β
|
| 36 |
+
βββββββββββββββ
|
| 37 |
+
β
|
| 38 |
+
βΌ
|
| 39 |
+
βββββββββββββββ
|
| 40 |
+
β LLM / Synthesis β
|
| 41 |
+
β - Creates unifiedβ
|
| 42 |
+
β consensus β
|
| 43 |
+
βββββββββββββββ
|
| 44 |
+
β
|
| 45 |
+
βΌ
|
| 46 |
+
βββββββββββββββ
|
| 47 |
+
β Structured β
|
| 48 |
+
β Response β
|
| 49 |
+
β (JSON / UI)β
|
| 50 |
+
βββββββββββββββ
|
| 51 |
+
β
|
| 52 |
+
βΌ
|
| 53 |
+
External User / App
|
reviews/changes.md
ADDED
|
@@ -0,0 +1,60 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Change Log
|
| 2 |
+
|
| 3 |
+
**Date:** 2025-11-15
|
| 4 |
+
|
| 5 |
+
This document tracks notable changes in the "Corvid Council" repository.
|
| 6 |
+
|
| 7 |
+
---
|
| 8 |
+
|
| 9 |
+
### November 15, 2025
|
| 10 |
+
|
| 11 |
+
#### Summary of Changes
|
| 12 |
+
|
| 13 |
+
A code snippet related to a potential PubMed API implementation was added as comments to `src/cluas_mcp/common/api_clients.py`. No other functional or structural changes were observed in the repository. The core logic, file structure, and administrative files (`README.md`, `.gitignore`, `requirements.txt`) remain the same as the last review.
|
| 14 |
+
|
| 15 |
+
#### Detailed Changes
|
| 16 |
+
|
| 17 |
+
- **Modified `src/cluas_mcp/common/api_clients.py`**:
|
| 18 |
+
- A block of commented-out Python code was added. This code demonstrates how to use the `Bio.Entrez` library to search PubMed for articles related to corvids, parse the results, and extract details like title, authors, abstract, and DOI.
|
| 19 |
+
|
| 20 |
+
#### Analysis
|
| 21 |
+
|
| 22 |
+
- **Significant:**
|
| 23 |
+
- The change itself is minor (it's only comments), but it's significant in what it signals: active exploration of how to implement the `PubMedClient`. This is a direct move towards fulfilling one of the key requirements for making the `Corvus` character fully functional.
|
| 24 |
+
|
| 25 |
+
- **Good:**
|
| 26 |
+
- This is a positive step. It shows that the next phase of development is being actively researched. The example code is relevant and provides a clear path for the real implementation.
|
| 27 |
+
- Using a well-known library like `BioPython` is a good choice for interacting with NCBI services.
|
| 28 |
+
|
| 29 |
+
- **Concerning:**
|
| 30 |
+
- There are no concerns with this change. It's a healthy sign of a project in the early stages of development. The only minor point is that the code is commented out in the main source file rather than being in a separate experimental script, but this is a trivial issue at this stage.
|
| 31 |
+
|
| 32 |
+
---
|
| 33 |
+
|
| 34 |
+
### November 18, 2025
|
| 35 |
+
|
| 36 |
+
#### Summary of Changes
|
| 37 |
+
|
| 38 |
+
A new `notes_etc/` directory was added, containing detailed development guides and an architecture diagram. Crucially, the previously empty `src/cluas_mcp/common/formatting.py` file was implemented, fixing a critical import error.
|
| 39 |
+
|
| 40 |
+
#### Detailed Changes
|
| 41 |
+
|
| 42 |
+
- **New Directory `notes_etc/`**:
|
| 43 |
+
- `development_guide_01.md`: A comprehensive guide detailing the project's concept, architecture, characters, MCP tools, development phases, and technical stack.
|
| 44 |
+
- `development_guide_02.txt`: A more concise version of the guide.
|
| 45 |
+
- `possible_lightweight_architecture_diagram.txt`: A text-based visualization of the system architecture.
|
| 46 |
+
- **Modified `src/cluas_mcp/common/formatting.py`**:
|
| 47 |
+
- Implemented the `snippet_abstract` function to truncate text intelligently.
|
| 48 |
+
- Implemented the `format_authors` function to format author lists.
|
| 49 |
+
|
| 50 |
+
#### Analysis
|
| 51 |
+
|
| 52 |
+
- **Significant:**
|
| 53 |
+
- The implementation of the functions in `formatting.py` is the most significant change, as it directly unblocks the `Corvus` agent and makes a core piece of the application runnable for the first time.
|
| 54 |
+
- The addition of the development guides provides invaluable context and a clear roadmap for the project's future.
|
| 55 |
+
|
| 56 |
+
- **Good:**
|
| 57 |
+
- These changes are overwhelmingly positive. The bug fix is a major step forward, and the planning documents demonstrate a clear and well-thought-out vision for the project. The architecture is sound, and the character-based agent design is creative and well-defined.
|
| 58 |
+
|
| 59 |
+
- **Concerning:**
|
| 60 |
+
- There are no concerning changes. The project is progressing logically and is now in a much better state than before. The next logical step is to implement the placeholder API clients.
|
{cluas/reviews β reviews}/code_review_2025-11-15_14-30-00.md
RENAMED
|
File without changes
|
{cluas/reviews β reviews}/code_review_2025-11-15_15-00-00.md
RENAMED
|
File without changes
|
{cluas/reviews β reviews}/code_review_2025-11-15_15-30-00.md
RENAMED
|
File without changes
|
{cluas/reviews β reviews}/code_review_2025-11-15_16-00-00.md
RENAMED
|
File without changes
|
reviews/code_review_2025-11-18_10-00-00.md
ADDED
|
@@ -0,0 +1,61 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Code Review: Corvid Council - Initial Scaffolding
|
| 2 |
+
|
| 3 |
+
**Date:** 2025-11-18
|
| 4 |
+
|
| 5 |
+
## a) High-Level Summary
|
| 6 |
+
|
| 7 |
+
The Corvid Council project is in its nascent stages, with the foundational scaffolding for a multi-agent research system. The core concept is strong: a group of specialized AI agents collaborating to research and discuss topics, retaining knowledge over time in a shared memory. The initial code sets up a key character, `Corvus`, responsible for academic searches, and a crucial `AgentMemory` component for persistence. However, the project is not yet functional due to missing implementations and architectural gaps. The immediate blockers are broken imports and placeholder API clients, which prevent the `Corvus` agent from executing its primary function.
|
| 8 |
+
|
| 9 |
+
## b) Detailed Component Description
|
| 10 |
+
|
| 11 |
+
### `src/characters/corvus.py`
|
| 12 |
+
|
| 13 |
+
This file defines the `CorvusMCP` class, the first of the AI agents.
|
| 14 |
+
|
| 15 |
+
* **Functionality:** Its main purpose is to `search_papers` across multiple academic databases (PubMed, Semantic Scholar, arXiv) in a fallback sequence.
|
| 16 |
+
* **Integration:** It correctly initializes and uses the `AgentMemory` system by logging every paper it finds. This is a good early integration, ensuring that the agent's "discoveries" contribute to the collective knowledge base.
|
| 17 |
+
* **Issue:** The tool is currently broken. It imports `format_authors` and `snippet_abstract` from `src/cluas_mcp/common/formatting.py`, which is an empty file. This will cause a runtime `ImportError`.
|
| 18 |
+
* **Structure:** The class is straightforward, but it could benefit from being derived from a common `Character` base class in the future to standardize agent interfaces.
|
| 19 |
+
|
| 20 |
+
### `src/cluas_mcp/common/memory.py`
|
| 21 |
+
|
| 22 |
+
This is arguably the most complete and well-realized component so far.
|
| 23 |
+
|
| 24 |
+
* **Functionality:** The `AgentMemory` class provides a simple but effective JSON-backed database for the agents. It allows adding items, retrieving them based on recency or tags, and searching by title.
|
| 25 |
+
* **Persistence:** It handles file I/O for reading and writing to a `memory.json` file, ensuring that the council's knowledge persists between sessions.
|
| 26 |
+
* **Design:** The use of a dictionary with lowercase titles as keys is a simple but effective way to avoid duplicate entries and update reference timestamps. The methods for adding, retrieving, and searching are clear and well-defined.
|
| 27 |
+
|
| 28 |
+
### `src/gradio/app.py`
|
| 29 |
+
|
| 30 |
+
This file contains a boilerplate Gradio `ChatInterface`.
|
| 31 |
+
|
| 32 |
+
* **Functionality:** It sets up a basic chat window and connects it to the Hugging Face Inference API.
|
| 33 |
+
* **Issue:** It is completely disconnected from the Corvid Council agent system. The `respond` function is a generic chatbot implementation and does not interact with `Corvus` or the `AgentMemory`. This is expected at this early stage but is a key area for future development.
|
| 34 |
+
|
| 35 |
+
## c) Opinionated Breakdown & Future Development
|
| 36 |
+
|
| 37 |
+
### Current State
|
| 38 |
+
|
| 39 |
+
The project has a good foundation but is more of an idea sketched in code than a working system. The separation of concerns is logical (characters, common utilities, UI), and the `AgentMemory` component is a solid start.
|
| 40 |
+
|
| 41 |
+
The most significant issue is the lack of a central orchestrator. There is no "council," only a single, non-functional agent. The project's `README.md` and `gemini.md` files clearly outline a vision that the code has not yet begun to implement.
|
| 42 |
+
|
| 43 |
+
### Suggestions for Future Development
|
| 44 |
+
|
| 45 |
+
1. **Fix the `Corvus` Agent:** The immediate priority is to implement the missing functions in `formatting.py` (`format_authors` and `snippet_abstract`). These could be simple implementations to start (e.g., `", ".join(authors)` and `abstract[:250] + "..."`).
|
| 46 |
+
|
| 47 |
+
2. **Implement API Clients:** The `gemini.md` file notes that the API clients are stubs. These need to be implemented to make `Corvus` functional. This involves writing the logic to make actual HTTP requests to PubMed, Semantic Scholar, and arXiv and parse their responses.
|
| 48 |
+
|
| 49 |
+
3. **Create a `CouncilOrchestrator`:** This is the most critical missing piece. A central class is needed to:
|
| 50 |
+
* Manage the roster of agents (Corvus, Magpie, etc.).
|
| 51 |
+
* Receive a user's query.
|
| 52 |
+
* Mediate the conversation between agents (e.g., pass the query to Corvus, then pass Corvus's findings to another agent for critique).
|
| 53 |
+
* Synthesize the final response for the user.
|
| 54 |
+
|
| 55 |
+
4. **Develop a `Character` Base Class:** To ensure all agents have a consistent interface, a `Character` abstract base class would be beneficial. It could define a common method like `process_query(query: str, context: List[str]) -> str` that each specialized agent would implement.
|
| 56 |
+
|
| 57 |
+
5. **Integrate Logic with Gradio UI:** Once the orchestrator is in place, the `respond` function in `gradio/app.py` should be rewritten to call the orchestrator instead of the generic Inference API. The chat history would represent the ongoing discussion of the council.
|
| 58 |
+
|
| 59 |
+
6. **Flesh out Other Characters:** After establishing the core architecture, the other characters (Magpie, Raven, Crow) can be created, each with their own specialized tools and "personalities."
|
| 60 |
+
|
| 61 |
+
In summary, the project has a promising conceptual foundation. The next steps should focus on building the core architectural components that will allow the agents to interact and turning the placeholder code into functional modules.
|
reviews/code_review_2025-11-18_10-30-00.md
ADDED
|
@@ -0,0 +1,50 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# Code Review: Corvid Council - Path to Functionality
|
| 2 |
+
|
| 3 |
+
**Date:** 2025-11-18
|
| 4 |
+
|
| 5 |
+
## a) High-Level Summary
|
| 6 |
+
|
| 7 |
+
The Corvid Council project has made a significant leap forward from a conceptual skeleton to a project with a clear and actionable roadmap. The addition of comprehensive development guides (`notes_etc/`) provides an excellent framework for the project's architecture, agent design, and phased implementation. Most importantly, a critical bug has been fixed by implementing the functions in `src/cluas_mcp/common/formatting.py`, which unblocks the `Corvus` agent. While the system is not yet fully operational (pending API client implementations and an orchestrator), it has moved from a state of being blocked to having a clear path toward achieving its "Week 1" goals.
|
| 8 |
+
|
| 9 |
+
## b) Detailed Component Description
|
| 10 |
+
|
| 11 |
+
### `notes_etc/development_guide_01.md`
|
| 12 |
+
|
| 13 |
+
This new document is the most important addition to the repository. It serves as the project's bible.
|
| 14 |
+
|
| 15 |
+
* **Content:** It lays out the entire vision, from the high-level concept and architecture to the specific personalities and toolsets of the four agents (Corvus, Magpie, Raven, Crow). It also defines the external MCP tools the app will expose, the core software components (`CouncilOrchestrator`, `Character` base class), and a detailed week-by-week development plan.
|
| 16 |
+
* **Impact:** This guide provides invaluable clarity. It solidifies the project's goals and gives a strong indication of the intended structure, which was previously only hinted at in the `README.md`. It's an excellent piece of planning documentation.
|
| 17 |
+
|
| 18 |
+
### `src/cluas_mcp/common/formatting.py`
|
| 19 |
+
|
| 20 |
+
This file has been changed from an empty placeholder to a functional module.
|
| 21 |
+
|
| 22 |
+
* **Functionality:** It now contains `snippet_abstract` and `format_authors`. These functions provide basic but sensible text formatting, ensuring that data retrieved by agents can be presented cleanly.
|
| 23 |
+
* **Impact:** This is a critical fix. It resolves the `ImportError` that previously prevented the `CorvusMCP` tool from running. The `Corvus` agent, while still dependent on placeholder API clients, is now executable.
|
| 24 |
+
|
| 25 |
+
### `src/characters/corvus.py`
|
| 26 |
+
|
| 27 |
+
The `Corvus` agent is now in a much better state due to the fix in `formatting.py`.
|
| 28 |
+
|
| 29 |
+
* **State:** The code is unchanged, but its context has changed. It can now successfully call the formatting functions.
|
| 30 |
+
* **Next Blocker:** The primary blocker for `Corvus` is now the placeholder API clients (`PubMedClient`, `SemanticScholarClient`, etc.) defined in `src/cluas_mcp/common/api_clients.py`. Until these are implemented to make real API calls, `Corvus` cannot retrieve any data.
|
| 31 |
+
|
| 32 |
+
## c) Opinionated Breakdown & Future Development
|
| 33 |
+
|
| 34 |
+
### Current State
|
| 35 |
+
|
| 36 |
+
The project is now on solid ground. The combination of a detailed plan and a critical bug fix has transformed it from a collection of disconnected files into a project with a clear trajectory. The immediate blockers are well-defined, and the long-term vision is compelling. The core challenge remains the same: building the central nervous system of the applicationβthe `CouncilOrchestrator`βand connecting it to the agents and the UI.
|
| 37 |
+
|
| 38 |
+
### Suggestions for Future Development
|
| 39 |
+
|
| 40 |
+
The development plan laid out in `notes_etc/development_guide_01.md` is excellent and should be followed closely. My suggestions are aligned with it:
|
| 41 |
+
|
| 42 |
+
1. **Implement API Clients:** The immediate next step must be to implement the real API call logic in `src/cluas_mcp/common/api_clients.py`. Start with one (e.g., `PubMedClient` or `ArxivClient`) to get `Corvus` working end-to-end, even if it's just one data source.
|
| 43 |
+
|
| 44 |
+
2. **Build the `CouncilOrchestrator` Skeleton:** As per the guide, create `src/orchestrator.py`. It doesn't need to be fully featured at first. A simple version that can take a query, pass it to the `Corvus` agent, and get a result would be a huge step forward.
|
| 45 |
+
|
| 46 |
+
3. **Create the `Character` Base Class:** Create the `src/character.py` file with an abstract base class. Refactor `CorvusMCP` to inherit from this class. This will establish a pattern that will make adding the other three agents much easier.
|
| 47 |
+
|
| 48 |
+
4. **Basic UI Integration:** Wire the `CouncilOrchestrator` to the Gradio UI. The `respond` function in `src/gradio/app.py` should be updated to call `orchestrator.process_query(message)`. This will achieve the "Day 1-2" goal from the development guide: "Ask 'Are crows smart?', see Corvus search papers and respond with citation."
|
| 49 |
+
|
| 50 |
+
The project is well-positioned for rapid progress. By focusing on the "Week 1" goals from the new development guide, the core functionality of a single-agent system can be achieved quickly, providing a solid foundation for the more complex multi-agent interactions to come.
|
{cluas/src β src}/characters/__init__.py
RENAMED
|
File without changes
|
{cluas/src β src}/characters/corvus.py
RENAMED
|
File without changes
|
{cluas/src β src}/characters/crow.py
RENAMED
|
File without changes
|
{cluas/src β src}/characters/magpie.py
RENAMED
|
File without changes
|
{cluas/src β src}/characters/raven.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/__init__.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/abstract_filtered.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/blah.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/common/__init__.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/common/api_clients.py
RENAMED
|
@@ -34,3 +34,57 @@ class ArxivClient:
|
|
| 34 |
"arxiv_link": getattr(entry, "link", "")
|
| 35 |
})
|
| 36 |
return results
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 34 |
"arxiv_link": getattr(entry, "link", "")
|
| 35 |
})
|
| 36 |
return results
|
| 37 |
+
|
| 38 |
+
|
| 39 |
+
|
| 40 |
+
|
| 41 |
+
# possible endpoint?
|
| 42 |
+
# https://eutils.ncbi.nlm.nih.gov/entrez/eutils/esearch.fcgi?db=pubmed&retmode=json&term=corvid+AND+memory
|
| 43 |
+
|
| 44 |
+
|
| 45 |
+
|
| 46 |
+
|
| 47 |
+
# from Bio import Entrez
|
| 48 |
+
# Entrez.email = "your.email@domain.tld" # required by NCBI
|
| 49 |
+
# Entrez.api_key = "YOUR_KEY_IF_YOU_HAVE_ONE"
|
| 50 |
+
|
| 51 |
+
# KEYWORDS = ['corvid','crow','raven','corvus','jay','magpie','jackdaw','rook','chough','nutcracker']
|
| 52 |
+
# SECONDARY = ['memory', 'feeding']
|
| 53 |
+
|
| 54 |
+
# term = "(" + " OR ".join(KEYWORDS) + ")" + " AND (" + " OR ".join(SECONDARY) + ")"
|
| 55 |
+
# handle = Entrez.esearch(db="pubmed", term=term, retmax=100) # adjust retmax
|
| 56 |
+
# record = Entrez.read(handle)
|
| 57 |
+
# ids = record["IdList"]
|
| 58 |
+
|
| 59 |
+
# for pmid in ids:
|
| 60 |
+
# handle2 = Entrez.efetch(db="pubmed", id=pmid, retmode="xml")
|
| 61 |
+
# rec = Entrez.read(handle2)
|
| 62 |
+
# article = rec['PubmedArticle'][0]
|
| 63 |
+
# # parse title
|
| 64 |
+
# title = article['MedlineCitation']['Article']['ArticleTitle']
|
| 65 |
+
# # parse authors
|
| 66 |
+
# authors = article['MedlineCitation']['Article']['AuthorList']
|
| 67 |
+
# first_author = authors[0]['LastName'] + ", " + authors[0]['ForeName']
|
| 68 |
+
# author_str = first_author + (", et al" if len(authors) > 1 else "")
|
| 69 |
+
# # parse abstract
|
| 70 |
+
# abstract = ""
|
| 71 |
+
# if 'Abstract' in article['MedlineCitation']['Article']:
|
| 72 |
+
# abstract = " ".join([x for x in article['MedlineCitation']['Article']['Abstract']['AbstractText']])
|
| 73 |
+
# # parse DOI
|
| 74 |
+
# doi = None
|
| 75 |
+
# for aid in article['PubmedData']['ArticleIdList']:
|
| 76 |
+
# if aid.attributes['IdType'] == 'doi':
|
| 77 |
+
# doi = str(aid)
|
| 78 |
+
# # parse a βconclusionβ if structured abstract includes it
|
| 79 |
+
# conclusion = None
|
| 80 |
+
# # one simple heuristic: look for segments labeled 'CONCLUSION' in structured abstract
|
| 81 |
+
# if 'Abstract' in article['MedlineCitation']['Article']:
|
| 82 |
+
# for sec in article['MedlineCitation']['Article']['Abstract']['AbstractText']:
|
| 83 |
+
# if hasattr(sec, "attributes") and sec.attributes.get('Label', '').upper() == 'CONCLUSION':
|
| 84 |
+
# conclusion = str(sec)
|
| 85 |
+
# # fallback: maybe take the last sentence of abstract
|
| 86 |
+
# if conclusion is None and abstract:
|
| 87 |
+
# conclusion = abstract.split('.')[-2] + '.'
|
| 88 |
+
|
| 89 |
+
# # now you have doi, title, author_str, abstract, conclusion
|
| 90 |
+
# print(pmid, doi, title, author_str, conclusion)
|
{cluas/src β src}/cluas_mcp/common/cache.py
RENAMED
|
File without changes
|
src/cluas_mcp/common/formatting.py
ADDED
|
@@ -0,0 +1,22 @@
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
| 1 |
+
# some thoughts re:formatting
|
| 2 |
+
# havent set up API calls properly yet tho
|
| 3 |
+
|
| 4 |
+
|
| 5 |
+
def snippet_abstract(abstract: str, max_length: int = 200) -> str:
|
| 6 |
+
"""Truncate abstract to first N chars, end at sentence."""
|
| 7 |
+
if len(abstract) <= max_length:
|
| 8 |
+
return abstract
|
| 9 |
+
|
| 10 |
+
truncated = abstract[:max_length]
|
| 11 |
+
last_period = truncated.rfind('.')
|
| 12 |
+
if last_period > 0:
|
| 13 |
+
return truncated[:last_period + 1]
|
| 14 |
+
return truncated + "..."
|
| 15 |
+
|
| 16 |
+
def format_authors(authors: list) -> str:
|
| 17 |
+
"""Format author list as 'First, Second, et al.'"""
|
| 18 |
+
if not authors:
|
| 19 |
+
return "Unknown authors"
|
| 20 |
+
if len(authors) <= 2:
|
| 21 |
+
return ", ".join(authors)
|
| 22 |
+
return f"{authors[0]}, {authors[1]}, et al."
|
{cluas/src β src}/cluas_mcp/common/memory.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/result.xml
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/server.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/testing_arxiv.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/tool_router.py
RENAMED
|
File without changes
|
{cluas/src β src}/cluas_mcp/tools.py
RENAMED
|
File without changes
|
{cluas/src β src}/data/cache.json
RENAMED
|
File without changes
|
{cluas/src β src}/gradio/__init__.py
RENAMED
|
File without changes
|
{cluas/src β src}/gradio/app.py
RENAMED
|
File without changes
|
{cluas/tests β tests}/test_corvus.py
RENAMED
|
File without changes
|
{cluas/tests β tests}/test_magpie.py
RENAMED
|
File without changes
|
{cluas/tests β tests}/test_tools.py
RENAMED
|
File without changes
|