feat(validator): add bare FastAgent + Pallas validator for Mnemosyne MCP

A self-contained sub-project under validator/ that wraps Mnemosyne's MCP
server in a single FastAgent. Use it to confirm — outside of Daedalus —
that Mnemosyne's MCP transport works, every tool registers, args/responses
round-trip, and an LLM can actually drive the tools.

The validator is its own Pallas-consuming project with its own pyproject
(pallas-mcp + fast-agent-mcp), agents.yaml, and fastagent.config.yaml —
matching the pattern used by Iolaus and other Pallas consumers. It does
not import Mnemosyne Python code; it only speaks MCP over HTTP.

The agent never sets workspace_id, so all calls run against the global
scope (libraries with workspace_id IS NULL). Workspace-scoped validation
will come once Daedalus's chat path is wired (Daedalus injects
workspace_id server-side, force-overwriting whatever the LLM produces).

Default model is openai.Qwen3.5-35B-A3B-UD-Q4_K_XL.gguf served by
llama.cpp at nyx.helu.ca:22079/v1. Token provisioning via
`python manage.py create_mcp_token --user <u> --name validator`.

Co-Authored-By: Claude Opus 4.7 <noreply@anthropic.com>
This commit is contained in:
2026-04-29 06:53:48 -04:00
parent 2a8a3d75b4
commit 97a14fb03a
9 changed files with 264 additions and 0 deletions

View File

View File

@@ -0,0 +1,56 @@
"""
Mnemosyne Validator Agent
A bare FastAgent that wraps the Mnemosyne MCP server. Exists solely to
exercise the Mnemosyne MCP transport, tool registration, and round-trip
serialization — no production role.
Drive it from the CLI to confirm:
- search works against the running Mnemosyne (vector + fulltext + graph)
- get_chunk fetches full chunk text from S3
- list_libraries / list_collections / list_items return the expected shape
- get_health returns ok/degraded with the right dependency breakdown
When the Daedalus integration ships, the workspace_id parameter will be
injected by Daedalus's chat path (force-overwritten before the call leaves
Daedalus). This validator never sets it — meaning all calls go to the
GLOBAL scope (libraries with workspace_id IS NULL).
"""
from fast_agent import FastAgent
fast = FastAgent("Mnemosyne Validator", parse_cli_args=False)
@fast.agent(
name="mnemosyne_validator",
instruction="""You are a validator for the Mnemosyne knowledge base. Your
job is to exercise its MCP tools when asked, report what you saw, and surface
errors clearly.
You have direct access to Mnemosyne via these tools:
- search(query, library_uid?, library_type?, collection_uid?, limit?, rerank?, include_images?, search_types?)
Hybrid retrieval. Returns ranked chunks with text_preview (~500 chars),
chunk_uid, item_uid, item_title, library_type, score, source.
- get_chunk(chunk_uid)
Fetch the full text of a chunk by uid (typically obtained from search).
- list_libraries(limit?, offset?)
List libraries (uid, name, library_type, description).
- list_collections(library_uid?, limit?, offset?)
List collections, optionally filtered by parent library.
- list_items(collection_uid?, library_uid?, limit?, offset?)
List items (documents) with chunk_count, embedding_status, etc.
- get_health()
Health check: {status: ok|degraded|error, checks: {neo4j, s3, embedding}}.
When the user asks "what libraries exist", call list_libraries and report.
When they ask a research question, call search and surface chunk_uid + score
+ item_title for each candidate. If they want full text, call get_chunk.
Show raw structured output, not flowery prose — this is a validation tool,
not a chat assistant.
If a tool errors, paste the error message verbatim.""",
servers=["mnemosyne"],
)
async def mnemosyne_validator():
pass