-
Notifications
You must be signed in to change notification settings - Fork 1
Core Systems
The core systems that power Amadeus's intelligence and safety.
File: src/runtime/cognitive/core.py
The central state machine that governs the lifecycle of every task. It replaces implicit chat loops with explicit, auditable, and resumable state transitions.
-
RECEIVED: Task is accepted and a unique
request_idis assigned. -
PLANNING: The
PlanEnginedecomposes the task into a graph ofPlanSteps. -
EXECUTING: Ready steps are dispatched to the
ToolExecutoror LLM. - VERIFYING: Results are checked against safety and completion criteria.
- REFLECTING: The agent evaluates progress and decides to proceed, replan, or finish.
- DONE: Final output is synthesized and returned.
Every state transition and observation is persisted as Episodic Memory, enabling restart recovery and long-term behavioral audit.
File: src/app/services/semantic_router.py
Replaces the legacy sklearn SVM classifier with a purely mathematical router — no retraining ever needed.
- At startup, every tool's
name + description + categorystring is embedded usingsentence-transformers/all-mpnet-base-v2into a 768-dimensional L2-normalised float32 vector. - The embedding matrix is cached to
Model/semantic_tool_embeddings.npz. A fingerprint (MD5 of sorted tool names) detects registry changes and triggers automatic cache invalidation. - At query time: the user message is embedded and a single NumPy matrix multiply computes cosine similarity against all tool vectors — under 10 ms on an Intel i3.
- If
best_score >= 0.50: the matched tool name is returned. Otherwise,Noneis returned and the LLM triage fallback takes over.
Use the bundled calibration script to find the optimal threshold for your tool set:
python scripts/calibrate_semantic_threshold.pyRegister a new Tool in the registry and restart. The router rebuilds its index automatically. No labels, no training data, no retraining.
# Check router readiness
GET /api/v1/health/detailed
# {"classifier_enabled": true, ...}File: src/infra/workspace_indexer.py
CLI: scripts/index_workspace.py
Builds a persistent hybrid retrieval index over a local file tree.
.py · .md · .txt · .toml · .yaml · .yml · .env · .json · .cfg · .ini · .rst · .pdf
Query
├─▶ Dense search (all-mpnet-base-v2 · cosine sim) ──▶ Top-N semantic matches
└─▶ BM25 search (BM25Okapi · code-aware tokeniser)──▶ Top-N lexical matches
RRF score = 1/(k + rank_semantic) + 1/(k + rank_bm25) [k = 60]
Final results: sorted by RRF score, max 2 hits per file
The BM25 tokeniser preserves underscores, so AUTH_UUID_7392 stays a single token — fixing the core failure mode of pure semantic search on code.
Each chunk is enriched with a file-level metadata header before being passed to the embedding model:
[File: amadeus_service.py | Type: Python | Imports: asyncio, logging, genai | Globals: TOOL_TIMEOUTS]
class AmadeusService:
...
The display snippet and BM25 corpus always use raw chunk text. Only the encoder input is enriched.
Only files with changed mtime or MD5 content hash are re-embedded. A 10,000-file workspace re-indexes in seconds after a single file change.
Default max_chunks=15,000 → ~46 MB embedding matrix + ~20 MB BM25 corpus. Safe on 4 GB machines.
# Full rebuild
python scripts/index_workspace.py --root "~/Projects" --force
# Custom root and output directory
python scripts/index_workspace.py --root "~/Projects" --index-dir "data/my_index"File: src/infra/memory_service.py — class FlashMemoryCache
A Tier-1 L1 cache that intercepts QdrantMemoryService.retrieve() calls using in-process NumPy.
| Property | Value |
|---|---|
| Capacity | 100 entries (ring buffer — oldest overwritten) |
| Memory | 100 × 768 × 4 bytes ≈ 307 KB |
| Threshold |
cosine_similarity >= 0.85 → cache hit |
| Latency | ~1 µs (single BLAS @ multiply) vs ~5 ms Qdrant round-trip |
| Invalidation |
clear_conversation() → FlashMemoryCache.invalidate()
|
When a new memory is stored via QdrantMemoryService.store(), its embedding is simultaneously pushed to the ring buffer. The next retrieval call checks the L1 cache first and only falls through to Qdrant on a miss.
File: src/app/services/agent_loop.py
Amadeus runs a ReAct (Reason + Act) agent implemented as an async state machine over asyncio.Queue.
START → THINK → ACT → OBSERVE → THINK → ... → SYNTHESIZE → END
The AgentOrchestrator runs a background worker loop that pulls tasks off a bounded queue (maxsize=50). Requests exceeding queue capacity receive QueueFullError, surfaced as HTTP 429.
| Agent | Max Iterations | Domain |
|---|---|---|
SystemAgent |
3 | OS, volume, screenshots, process control |
ResearchAgent |
5 | Web search, news, weather, documents |
ReActAgent (general) |
4 | Everything else + multi-step reasoning |
Routing between sub-agents uses the legacy SVM classifier if Model/router_classifier.joblib exists, falling back to keyword heuristics.
Tools decorated with requires_confirmation=True are paused before execution. The ToolExecutor calls ConfirmationCallback.request_approval() and blocks until approved, denied, or timed out (60 s → auto-deny).
| Class | Transport | Used In |
|---|---|---|
TerminalConfirmationCallback |
stdin y/n
|
CLI / tests |
APIConfirmationCallback |
HTTP — POST /api/v1/confirm/{request_id}
|
FastAPI server |
TelegramConfirmationCallback |
Inline keyboard buttons | Telegram long-polling |
terminate_program · delete_file · execute_python_script · fs_write_file · send_outlook_email · send_email · send_slack_message
Hard-denies all requires_confirmation=True tools regardless of the callback — prevents guest-tier users from executing destructive operations.
← Architecture | Tool-Registry →
Amadeus-AI · v6.0.0· Apache License 2.0 · Report a Bug
Getting Started
Architecture
Reference
Integrations
Operations
Development
Project
Links