The New Archon (Beta) - The Operating System for AI Coding Assistants!
20
docs/.gitignore
vendored
Normal file
@@ -0,0 +1,20 @@
|
||||
# Dependencies
|
||||
/node_modules
|
||||
|
||||
# Production
|
||||
/build
|
||||
|
||||
# Generated files
|
||||
.docusaurus
|
||||
.cache-loader
|
||||
|
||||
# Misc
|
||||
.DS_Store
|
||||
.env.local
|
||||
.env.development.local
|
||||
.env.test.local
|
||||
.env.production.local
|
||||
|
||||
npm-debug.log*
|
||||
yarn-debug.log*
|
||||
yarn-error.log*
|
||||
13
docs/Dockerfile
Normal file
@@ -0,0 +1,13 @@
|
||||
# Stage 1: build the Docusaurus site
|
||||
FROM node:18-alpine AS builder
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm install
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
|
||||
# Stage 2: serve with nginx
|
||||
FROM nginx:alpine
|
||||
COPY --from=builder /app/build /usr/share/nginx/html
|
||||
EXPOSE 80
|
||||
CMD ["nginx", "-g", "daemon off;"]
|
||||
33
docs/README.md
Normal file
@@ -0,0 +1,33 @@
|
||||
# Website
|
||||
|
||||
This website is built using [Docusaurus 2](https://docusaurus.io/), a modern static website generator.
|
||||
|
||||
### Installation
|
||||
|
||||
```
|
||||
$ yarn
|
||||
```
|
||||
|
||||
### Local Development
|
||||
|
||||
```
|
||||
$ yarn start
|
||||
```
|
||||
|
||||
This command starts a local development server and opens up a browser window. Most changes are reflected live without having to restart the server.
|
||||
|
||||
### Build
|
||||
|
||||
```
|
||||
$ yarn build
|
||||
```
|
||||
|
||||
This command generates static content into the `build` directory and can be served using any static contents hosting service.
|
||||
|
||||
### Deployment
|
||||
|
||||
```
|
||||
$ GIT_USER=<Your GitHub username> USE_SSH=true yarn deploy
|
||||
```
|
||||
|
||||
If you are using GitHub pages for hosting, this command is a convenient way to build the website and push to the `gh-pages` branch.
|
||||
3
docs/babel.config.js
Normal file
@@ -0,0 +1,3 @@
|
||||
module.exports = {
|
||||
presets: [require.resolve('@docusaurus/core/lib/babel/preset')],
|
||||
};
|
||||
73
docs/docs/README.md
Normal file
@@ -0,0 +1,73 @@
|
||||
# Documentation Structure
|
||||
|
||||
## Overview
|
||||
|
||||
The Archon documentation has been simplified to focus on developer-friendly reference material without excessive styling or marketing language.
|
||||
|
||||
## Key Changes
|
||||
|
||||
### Architecture Documentation
|
||||
- Created `architecture.mdx` - Clear explanation of system design and our recent changes
|
||||
- Shows how FastAPI uses services directly while MCP uses HTTP
|
||||
- Includes code examples of correct patterns
|
||||
|
||||
### Simplified Reference Section
|
||||
- **server-overview.mdx** - Reduced from 278 to 120 lines, removed hero sections
|
||||
- **server-services.mdx** - Replaced verbose cards with clean tables
|
||||
- **mcp-server.mdx** - Emphasized HTTP-only architecture, simplified diagrams
|
||||
- **api-reference.mdx** - Added new `DELETE /api/sources/{source_id}` endpoint
|
||||
|
||||
### Consolidated Files
|
||||
- Combined all testing docs into single `testing.mdx`
|
||||
- Simplified sidebar structure from 4 levels to 2 levels
|
||||
- Removed redundant MCP and agent documentation files
|
||||
|
||||
## Documentation Principles
|
||||
|
||||
1. **Reference = Facts Only** - No heroes, cards, or marketing
|
||||
2. **Tables Over Prose** - Easy to scan information
|
||||
3. **Code Examples** - Show correct usage patterns
|
||||
4. **Clean Hierarchy** - Simple, logical organization
|
||||
5. **No Duplication** - Say things once, clearly
|
||||
|
||||
## File Structure
|
||||
|
||||
```
|
||||
docs/
|
||||
├── intro.mdx # Marketing-friendly introduction
|
||||
├── getting-started/ # Setup and configuration
|
||||
├── features/ # Feature overviews
|
||||
├── reference/ # Technical documentation (clean, no fluff)
|
||||
│ ├── architecture.mdx # System design
|
||||
│ ├── server-*.mdx # Server documentation
|
||||
│ ├── api-reference.mdx # REST API endpoints
|
||||
│ ├── mcp-server.mdx # MCP tools
|
||||
│ └── socketio.mdx # Socket.IO events and real-time communication
|
||||
└── guides/ # How-to guides
|
||||
```
|
||||
|
||||
## Architecture Changes Documented
|
||||
|
||||
### Delete Operation Fix
|
||||
- FastAPI: `SourceManagementService.delete_source()` - Direct service usage
|
||||
- API: `DELETE /api/sources/{source_id}` - New endpoint
|
||||
- MCP: HTTP call to API endpoint - No direct imports
|
||||
|
||||
### Crawl Operation Fix
|
||||
- FastAPI: Uses `CrawlingService` directly with smart URL detection
|
||||
- Progress callbacks for real-time updates
|
||||
- Proper service separation maintained
|
||||
|
||||
### Socket.IO Simplification (2025 Pattern)
|
||||
- **Official Socket.IO 2025 pattern** - Removed complex namespace classes, using simple @sio.event decorators
|
||||
- **Eliminated database polling** - Removed 2-second polling system for task/project changes
|
||||
- **Direct Socket.IO emission** - Services emit events directly to rooms with `sio.emit()`
|
||||
- **Root namespace only** - Everything runs on `/` namespace, no complex namespace management
|
||||
- **Simple room management** - Direct `sio.enter_room()` and `sio.leave_room()` calls
|
||||
- **Simplified flow**: MCP → HTTP API → Services → @sio.event → Rooms → UI
|
||||
|
||||
The documentation now clearly reflects that:
|
||||
- **Server contains ALL business logic**
|
||||
- **MCP is HTTP-only** (no direct imports)
|
||||
- **Services are the single source of truth**
|
||||
- **Socket.IO follows official 2025 patterns** - Simple, clean, and maintainable
|
||||
414
docs/docs/agent-chat.mdx
Normal file
@@ -0,0 +1,414 @@
|
||||
---
|
||||
title: Agent Chat Panel
|
||||
description: Real-time chat interface for AI agents with streaming responses
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Agent Chat Panel
|
||||
|
||||
## Overview
|
||||
|
||||
The Agent Chat Panel provides a real-time interface for interacting with AI agents. It uses Socket.IO for reliable bidirectional communication and supports streaming responses from agents.
|
||||
|
||||
<Admonition type="success" title="Key Features">
|
||||
- **Real-time streaming**: See agent responses as they're generated
|
||||
- **Socket.IO reliability**: Automatic reconnection and state management
|
||||
- **Multiple agent types**: Support for RAG, Document, and Task agents
|
||||
- **Session persistence**: Chat history maintained across connections
|
||||
- **Simple architecture**: Socket.IO ↔ Server ↔ SSE ↔ Agents
|
||||
</Admonition>
|
||||
|
||||
## Architecture
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
UI[React UI] <--> |Socket.IO| Server[FastAPI Server]
|
||||
Server --> |HTTP/SSE| Agents[PydanticAI Agents]
|
||||
Agents --> |SSE Stream| Server
|
||||
Server --> |Socket.IO Events| UI
|
||||
```
|
||||
|
||||
### Communication Flow
|
||||
|
||||
1. **UI to Server**: Socket.IO events and REST endpoints
|
||||
2. **Server to Agents**: HTTP requests with SSE streaming responses
|
||||
3. **Agents to Server**: Server-Sent Events (SSE) for streaming
|
||||
4. **Server to UI**: Socket.IO events for real-time updates
|
||||
|
||||
## Frontend Usage
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="component" label="React Component">
|
||||
|
||||
```tsx
|
||||
import { ArchonChatPanel } from '@/components/layouts/ArchonChatPanel';
|
||||
|
||||
function App() {
|
||||
return (
|
||||
<div className="flex h-screen">
|
||||
{/* Your main content */}
|
||||
<div className="flex-1">
|
||||
{/* ... */}
|
||||
</div>
|
||||
|
||||
{/* Chat Panel */}
|
||||
<ArchonChatPanel />
|
||||
</div>
|
||||
);
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="service" label="Service Usage">
|
||||
|
||||
```typescript
|
||||
import { agentChatService } from '@/services/agentChatService';
|
||||
|
||||
// Create a chat session
|
||||
const { session_id } = await agentChatService.createSession(
|
||||
undefined, // project_id (optional)
|
||||
'rag' // agent_type: 'rag' | 'document' | 'task'
|
||||
);
|
||||
|
||||
// Connect WebSocket for real-time updates
|
||||
await agentChatService.connectWebSocket(
|
||||
session_id,
|
||||
(message) => {
|
||||
// Handle incoming messages
|
||||
console.log('Agent:', message.content);
|
||||
},
|
||||
(isTyping) => {
|
||||
// Handle typing indicator
|
||||
console.log('Agent is typing:', isTyping);
|
||||
},
|
||||
(chunk) => {
|
||||
// Handle streaming chunks
|
||||
console.log('Chunk:', chunk);
|
||||
},
|
||||
() => {
|
||||
// Handle stream completion
|
||||
console.log('Stream complete');
|
||||
}
|
||||
);
|
||||
|
||||
// Send a message
|
||||
await agentChatService.sendMessage(
|
||||
session_id,
|
||||
'What is Archon?',
|
||||
{ match_count: 5 } // Optional context
|
||||
);
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Backend Implementation
|
||||
|
||||
### Socket.IO Events
|
||||
|
||||
The chat system uses Socket.IO events with room-based isolation:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="events" label="Event Handlers">
|
||||
|
||||
```python
|
||||
from ..socketio_app import get_socketio_instance
|
||||
sio = get_socketio_instance()
|
||||
|
||||
@sio.event
|
||||
async def join_chat(sid, data):
|
||||
"""Join a chat room."""
|
||||
session_id = data.get('session_id')
|
||||
await sio.enter_room(sid, f'chat_{session_id}')
|
||||
|
||||
@sio.event
|
||||
async def chat_message(sid, data):
|
||||
"""Handle incoming chat messages."""
|
||||
session_id = data.get('session_id')
|
||||
message = data.get('message')
|
||||
context = data.get('context', {})
|
||||
|
||||
# Process with agent
|
||||
await process_agent_response(session_id, message, context)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="streaming" label="SSE Proxy">
|
||||
|
||||
```python
|
||||
async def process_agent_response(session_id: str, message: str, context: dict):
|
||||
"""Stream agent response via SSE and emit to Socket.IO."""
|
||||
room = f'chat_{session_id}'
|
||||
|
||||
# Call agents service with SSE streaming
|
||||
async with httpx.AsyncClient() as client:
|
||||
async with client.stream(
|
||||
"POST",
|
||||
f"http://archon-agents:8052/agents/rag/stream",
|
||||
json={
|
||||
"prompt": message,
|
||||
"context": context
|
||||
}
|
||||
) as response:
|
||||
# Stream SSE chunks to Socket.IO
|
||||
async for line in response.aiter_lines():
|
||||
if line.startswith("data: "):
|
||||
chunk_data = json.loads(line[6:])
|
||||
|
||||
# Emit streaming chunk
|
||||
await sio.emit('stream_chunk', {
|
||||
"type": "stream_chunk",
|
||||
"content": chunk_data.get('content', '')
|
||||
}, room=room)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### REST Endpoints
|
||||
|
||||
Minimal REST endpoints for session management:
|
||||
|
||||
| Endpoint | Method | Purpose |
|
||||
|----------|--------|---------|
|
||||
| `/api/agent-chat/sessions` | POST | Create chat session |
|
||||
| `/api/agent-chat/sessions/{id}` | GET | Get session info |
|
||||
| `/api/agent-chat/sessions/{id}/messages` | POST | Send message (triggers Socket.IO) |
|
||||
|
||||
## Agent Types
|
||||
|
||||
### RAG Agent
|
||||
- **Purpose**: Knowledge base Q&A with context retrieval
|
||||
- **Context**: `{ match_count: 5, source_filter: "docs.archon.com" }`
|
||||
- **Best for**: Documentation queries, technical questions
|
||||
|
||||
### Document Agent
|
||||
- **Purpose**: Document analysis and content generation
|
||||
- **Context**: `{ format: "markdown", style: "technical" }`
|
||||
- **Best for**: Creating documentation, analyzing documents
|
||||
|
||||
### Task Agent
|
||||
- **Purpose**: Task decomposition and project planning
|
||||
- **Context**: `{ project_id: "uuid", detail_level: "high" }`
|
||||
- **Best for**: Breaking down features, planning implementation
|
||||
|
||||
## Socket.IO Message Types
|
||||
|
||||
### Client to Server
|
||||
|
||||
| Event | Purpose | Data |
|
||||
|-------|---------|------|
|
||||
| `join_chat` | Join chat room | `{session_id: string}` |
|
||||
| `chat_message` | Send message | `{session_id, message, context}` |
|
||||
| `leave_chat` | Leave room | `{session_id: string}` |
|
||||
|
||||
### Server to Client
|
||||
|
||||
| Event | Purpose | Data |
|
||||
|-------|---------|------|
|
||||
| `connection_confirmed` | Confirm connection | `{session_id: string}` |
|
||||
| `message` | Complete message | `{type: "message", data: ChatMessage}` |
|
||||
| `stream_chunk` | Streaming chunk | `{type: "stream_chunk", content: string}` |
|
||||
| `stream_complete` | Stream finished | `{type: "stream_complete"}` |
|
||||
| `typing` | Typing indicator | `{type: "typing", is_typing: boolean}` |
|
||||
| `error` | Error occurred | `{type: "error", error: string}` |
|
||||
|
||||
## Error Handling
|
||||
|
||||
<Admonition type="warning" title="Connection Management">
|
||||
The chat service handles various connection scenarios:
|
||||
|
||||
- **Automatic reconnection**: Socket.IO reconnects with exponential backoff
|
||||
- **Session recovery**: Creates new session if old one is invalid
|
||||
- **Error propagation**: Errors from agents are forwarded to UI
|
||||
- **Graceful degradation**: Shows offline state when server unavailable
|
||||
</Admonition>
|
||||
|
||||
### Common Error Scenarios
|
||||
|
||||
1. **Agent Service Unavailable**
|
||||
```json
|
||||
{
|
||||
"type": "error",
|
||||
"error": "Agent service error: 503"
|
||||
}
|
||||
```
|
||||
|
||||
2. **Invalid Session**
|
||||
- Automatically creates new session
|
||||
- Transfers handlers to new session
|
||||
- Notifies UI of session change
|
||||
|
||||
3. **Network Disconnection**
|
||||
- Socket.IO handles reconnection
|
||||
- UI shows "connecting" state
|
||||
- Messages queued until reconnected
|
||||
|
||||
## Best Practices
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="frontend" label="Frontend">
|
||||
|
||||
1. **Handle connection states**
|
||||
```typescript
|
||||
agentChatService.onStatusChange(sessionId, (status) => {
|
||||
switch(status) {
|
||||
case 'online': showOnlineIndicator(); break;
|
||||
case 'offline': showOfflineMessage(); break;
|
||||
case 'connecting': showLoadingSpinner(); break;
|
||||
}
|
||||
});
|
||||
```
|
||||
|
||||
2. **Clean up on unmount**
|
||||
```typescript
|
||||
useEffect(() => {
|
||||
return () => {
|
||||
agentChatService.disconnectWebSocket(sessionId);
|
||||
agentChatService.offStatusChange(sessionId);
|
||||
};
|
||||
}, [sessionId]);
|
||||
```
|
||||
|
||||
3. **Handle streaming properly**
|
||||
```typescript
|
||||
let accumulatedContent = '';
|
||||
|
||||
const onStreamChunk = (chunk: string) => {
|
||||
accumulatedContent += chunk;
|
||||
updateDisplay(accumulatedContent);
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="backend" label="Backend">
|
||||
|
||||
1. **Use rooms for isolation**
|
||||
```python
|
||||
# Always use room pattern
|
||||
room = f'chat_{session_id}'
|
||||
await sio.emit('message', data, room=room)
|
||||
```
|
||||
|
||||
2. **Handle SSE errors gracefully**
|
||||
```python
|
||||
try:
|
||||
async for line in response.aiter_lines():
|
||||
# Process line
|
||||
except httpx.ReadTimeout:
|
||||
await sio.emit('error', {
|
||||
'error': 'Agent response timeout'
|
||||
}, room=room)
|
||||
```
|
||||
|
||||
3. **Clean up sessions periodically**
|
||||
```python
|
||||
# Remove old sessions after 24 hours
|
||||
for session_id, session in list(sessions.items()):
|
||||
if is_expired(session['created_at']):
|
||||
sessions.pop(session_id, None)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Agent service configuration
|
||||
AGENT_SERVICE_URL=http://archon-agents:8052
|
||||
|
||||
# Socket.IO configuration
|
||||
SOCKETIO_PING_TIMEOUT=60
|
||||
SOCKETIO_PING_INTERVAL=25
|
||||
|
||||
# Session configuration
|
||||
SESSION_TTL_HOURS=24
|
||||
MAX_MESSAGES_PER_SESSION=1000
|
||||
```
|
||||
|
||||
### Frontend Configuration
|
||||
|
||||
```typescript
|
||||
// Adjust WebSocket settings
|
||||
const wsConfig = {
|
||||
maxReconnectAttempts: 5,
|
||||
reconnectInterval: 1000,
|
||||
heartbeatInterval: 30000,
|
||||
enableAutoReconnect: true,
|
||||
enableHeartbeat: true,
|
||||
};
|
||||
```
|
||||
|
||||
## Testing
|
||||
|
||||
### Manual Testing
|
||||
1. Open the UI and verify chat panel appears
|
||||
2. Check connection status indicator
|
||||
3. Send a test message
|
||||
4. Verify streaming response appears
|
||||
5. Test reconnection by restarting server
|
||||
|
||||
### Integration Testing
|
||||
```python
|
||||
# Test Socket.IO events
|
||||
async def test_chat_flow():
|
||||
# Create session
|
||||
response = await client.post("/api/agent-chat/sessions")
|
||||
session_id = response.json()["session_id"]
|
||||
|
||||
# Connect Socket.IO
|
||||
sio_client = socketio.AsyncClient()
|
||||
await sio_client.connect("http://localhost:8080")
|
||||
|
||||
# Join room
|
||||
await sio_client.emit("join_chat", {"session_id": session_id})
|
||||
|
||||
# Send message
|
||||
await sio_client.emit("chat_message", {
|
||||
"session_id": session_id,
|
||||
"message": "Hello",
|
||||
"context": {}
|
||||
})
|
||||
|
||||
# Verify response
|
||||
# ...
|
||||
```
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
<Admonition type="tip" title="Common Issues">
|
||||
|
||||
**Chat shows "offline"**
|
||||
- Check if agents container is running: `docker ps | grep agents`
|
||||
- Verify server logs: `docker logs archon-server`
|
||||
- Check Socket.IO connection in browser DevTools
|
||||
|
||||
**Messages not streaming**
|
||||
- Verify SSE endpoint is accessible
|
||||
- Check agent logs for errors
|
||||
- Ensure proper CORS configuration
|
||||
|
||||
**Session errors**
|
||||
- Sessions are in-memory and lost on server restart
|
||||
- Frontend will create new session automatically
|
||||
- Check session_id in requests matches server state
|
||||
|
||||
</Admonition>
|
||||
|
||||
## Summary
|
||||
|
||||
The Agent Chat Panel provides a robust, real-time interface for AI agent interaction with:
|
||||
- Socket.IO for reliable bidirectional communication
|
||||
- SSE streaming for agent responses
|
||||
- Simple session management
|
||||
- Automatic error recovery
|
||||
- Clean room-based isolation
|
||||
|
||||
Total implementation: ~250 lines of elegant, maintainable code.
|
||||
261
docs/docs/agent-document.mdx
Normal file
@@ -0,0 +1,261 @@
|
||||
---
|
||||
title: Document Agent
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 📄 Document Agent
|
||||
|
||||
<div className="hero hero--secondary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**Intelligent document processing orchestration** using PydanticAI to coordinate document uploads, chunking, and organization through MCP tools.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
The Document Agent is a PydanticAI-powered orchestrator that handles complex document processing workflows. It analyzes documents, determines optimal processing strategies, and coordinates multiple MCP tools to achieve the best results.
|
||||
|
||||
<Admonition type="info" icon="💡" title="Pure Orchestration">
|
||||
The Document Agent contains NO document processing logic. All actual processing is done by the Server service through MCP tool calls.
|
||||
</Admonition>
|
||||
|
||||
## 🤖 Capabilities
|
||||
|
||||
### Document Analysis
|
||||
- **Format Detection**: Identifies document type and structure
|
||||
- **Content Analysis**: Determines optimal chunking strategy
|
||||
- **Metadata Extraction**: Identifies key document properties
|
||||
- **Processing Planning**: Creates multi-step processing workflows
|
||||
|
||||
### Orchestration Patterns
|
||||
- **Single Document**: Upload and process individual files
|
||||
- **Batch Processing**: Handle multiple documents efficiently
|
||||
- **Conditional Workflows**: Different strategies based on content
|
||||
- **Error Recovery**: Intelligent retry and fallback strategies
|
||||
|
||||
## 🔧 MCP Tools Used
|
||||
|
||||
| Tool | Purpose | When Used |
|
||||
|------|---------|-----------|
|
||||
| `upload_document` | Upload and process single documents | Individual file processing |
|
||||
| `store_documents` | Store multiple document chunks | After chunking large documents |
|
||||
| `manage_document` | CRUD operations on project documents | Project documentation management |
|
||||
| `manage_versions` | Version control for documents | When updating existing documents |
|
||||
| `crawl_single_page` | Process web pages as documents | When URL provided instead of file |
|
||||
|
||||
## 📊 Processing Workflows
|
||||
|
||||
### Standard Document Upload
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant DocAgent as Document Agent
|
||||
participant MCP as MCP Tools
|
||||
participant Server
|
||||
|
||||
User->>DocAgent: Upload document request
|
||||
DocAgent->>DocAgent: Analyze document type
|
||||
DocAgent->>MCP: upload_document()
|
||||
MCP->>Server: HTTP POST /api/documents/upload
|
||||
Server->>Server: Process document
|
||||
Server-->>MCP: Processing result
|
||||
MCP-->>DocAgent: Tool result
|
||||
DocAgent->>DocAgent: Evaluate result
|
||||
DocAgent-->>User: Success with metadata
|
||||
```
|
||||
|
||||
### Complex Document Processing
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[Document Input] --> B{Analyze Document}
|
||||
B -->|PDF| C[Extract with PyPDF2]
|
||||
B -->|Word| D[Extract with python-docx]
|
||||
B -->|Text| E[Direct Processing]
|
||||
|
||||
C --> F[Check Size]
|
||||
D --> F
|
||||
E --> F
|
||||
|
||||
F -->|Large| G[Smart Chunking Strategy]
|
||||
F -->|Small| H[Single Chunk]
|
||||
|
||||
G --> I[store_documents]
|
||||
H --> J[upload_document]
|
||||
|
||||
I --> K[Generate Embeddings]
|
||||
J --> K
|
||||
|
||||
K --> L[Store in Database]
|
||||
```
|
||||
|
||||
## 💬 Example Interactions
|
||||
|
||||
### Simple Upload
|
||||
```python
|
||||
# User request
|
||||
"Upload this technical specification document"
|
||||
|
||||
# Document Agent workflow
|
||||
1. Analyze file: technical_spec.pdf
|
||||
2. Detect: PDF format, 45 pages, technical content
|
||||
3. Call: upload_document(
|
||||
file_path="technical_spec.pdf",
|
||||
doc_type="technical",
|
||||
chunk_size=5000
|
||||
)
|
||||
4. Monitor: Processing progress
|
||||
5. Return: "Document uploaded successfully with 23 chunks created"
|
||||
```
|
||||
|
||||
### Intelligent Processing
|
||||
```python
|
||||
# User request
|
||||
"Process this large documentation folder"
|
||||
|
||||
# Document Agent workflow
|
||||
1. Scan folder structure
|
||||
2. Identify: 15 markdown files, 3 PDFs, 2 Word docs
|
||||
3. Plan: Batch processing strategy
|
||||
4. Execute:
|
||||
- Group markdown files for efficient processing
|
||||
- Handle PDFs individually due to size
|
||||
- Convert Word docs to markdown first
|
||||
5. Coordinate: Multiple store_documents calls
|
||||
6. Aggregate: Results from all operations
|
||||
7. Return: "Processed 20 documents creating 145 searchable chunks"
|
||||
```
|
||||
|
||||
## 🔍 Implementation Details
|
||||
|
||||
### Agent Structure
|
||||
```python
|
||||
from pydantic_ai import Agent, RunContext
|
||||
from typing import List, Dict, Any
|
||||
|
||||
class DocumentAgent(Agent):
|
||||
"""Orchestrates document processing operations"""
|
||||
|
||||
name = "document_processor"
|
||||
description = "Handles document uploads and processing"
|
||||
|
||||
tools = [
|
||||
"upload_document",
|
||||
"store_documents",
|
||||
"manage_document",
|
||||
"manage_versions"
|
||||
]
|
||||
|
||||
async def process_request(
|
||||
self,
|
||||
context: RunContext,
|
||||
request: str
|
||||
) -> Dict[str, Any]:
|
||||
# Analyze request and determine strategy
|
||||
strategy = self.analyze_request(request)
|
||||
|
||||
# Execute appropriate workflow
|
||||
if strategy.type == "single_upload":
|
||||
return await self.single_document_workflow(context, strategy)
|
||||
elif strategy.type == "batch_process":
|
||||
return await self.batch_workflow(context, strategy)
|
||||
# ... more strategies
|
||||
```
|
||||
|
||||
### Decision Making
|
||||
The Document Agent makes intelligent decisions about:
|
||||
1. **Chunk Size**: Based on document type and content
|
||||
2. **Processing Order**: Prioritizes based on dependencies
|
||||
3. **Parallelization**: When to process in parallel vs sequential
|
||||
4. **Error Handling**: Retry strategies for failed operations
|
||||
|
||||
## 📈 Performance Optimization
|
||||
|
||||
### Batching Strategy
|
||||
- Groups similar documents for efficient processing
|
||||
- Minimizes API calls by batching operations
|
||||
- Balances batch size with memory constraints
|
||||
|
||||
### Caching Decisions
|
||||
- Remembers processing strategies for similar documents
|
||||
- Caches metadata extraction results
|
||||
- Reuses successful workflow patterns
|
||||
|
||||
## 🚨 Error Handling
|
||||
|
||||
### Common Scenarios
|
||||
1. **Large File Handling**
|
||||
- Automatically switches to streaming mode
|
||||
- Breaks into smaller chunks for processing
|
||||
|
||||
2. **Format Issues**
|
||||
- Falls back to text extraction
|
||||
- Attempts multiple parsing strategies
|
||||
|
||||
3. **Network Failures**
|
||||
- Implements exponential backoff
|
||||
- Saves progress for resume capability
|
||||
|
||||
### Error Recovery Example
|
||||
```python
|
||||
# Workflow with error handling
|
||||
try:
|
||||
result = await upload_document(file_path)
|
||||
except FileTooLargeError:
|
||||
# Switch to chunked upload
|
||||
chunks = await prepare_chunks(file_path)
|
||||
results = []
|
||||
for chunk in chunks:
|
||||
result = await store_documents([chunk])
|
||||
results.append(result)
|
||||
return aggregate_results(results)
|
||||
```
|
||||
|
||||
## 🔗 Integration Examples
|
||||
|
||||
### With Project Management
|
||||
```python
|
||||
# Creating project documentation
|
||||
"Create project documentation from these design files"
|
||||
|
||||
# Agent coordinates:
|
||||
1. manage_project() - Create or find project
|
||||
2. upload_document() - Process each design file
|
||||
3. manage_document() - Link to project
|
||||
4. manage_versions() - Set up version tracking
|
||||
```
|
||||
|
||||
### With Knowledge Base
|
||||
```python
|
||||
# Building knowledge base
|
||||
"Add all our API documentation to the knowledge base"
|
||||
|
||||
# Agent coordinates:
|
||||
1. crawl_single_page() - For online docs
|
||||
2. upload_document() - For local files
|
||||
3. store_documents() - For processed content
|
||||
4. Cross-reference with existing content
|
||||
```
|
||||
|
||||
## 📊 Monitoring & Metrics
|
||||
|
||||
### Key Metrics Tracked
|
||||
- **Processing Time**: Per document and total
|
||||
- **Chunk Count**: Documents to chunks ratio
|
||||
- **Success Rate**: Successful vs failed uploads
|
||||
- **Tool Usage**: Which MCP tools used most
|
||||
|
||||
### Processing Traces
|
||||
The Document Agent provides detailed processing traces showing document type, file size, and processing strategy for each operation.
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [Agents Overview](./agents-overview) - Understanding the Agents service
|
||||
- [Upload Document Tool](./mcp-tools#upload-document) - MCP tool details
|
||||
- [Document Service](./server-services#document-service) - Backend implementation
|
||||
- [Document Storage API](./api-reference#document-management-api) - REST endpoints
|
||||
323
docs/docs/agent-rag.mdx
Normal file
@@ -0,0 +1,323 @@
|
||||
---
|
||||
title: RAG Agent
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 🧠 RAG Agent
|
||||
|
||||
<div className="hero hero--secondary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**Intelligent search orchestration** using PydanticAI to enhance queries, coordinate searches, and interpret results through MCP tools.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
The RAG (Retrieval-Augmented Generation) Agent is a PydanticAI-powered orchestrator that enhances search capabilities by intelligently refining queries, coordinating multiple search strategies, and interpreting results for optimal relevance.
|
||||
|
||||
<Admonition type="info" icon="💡" title="Pure Orchestration">
|
||||
The RAG Agent contains NO embedding models or search logic. All actual search operations are performed by the Server service through MCP tool calls.
|
||||
</Admonition>
|
||||
|
||||
## 🤖 Capabilities
|
||||
|
||||
### Query Enhancement
|
||||
- **Intent Analysis**: Understands what the user is really looking for
|
||||
- **Query Expansion**: Adds synonyms and related terms
|
||||
- **Context Awareness**: Uses conversation history for better results
|
||||
- **Multi-Query Strategy**: Breaks complex queries into sub-queries
|
||||
|
||||
### Search Orchestration
|
||||
- **Source Selection**: Chooses optimal sources to search
|
||||
- **Result Aggregation**: Combines results from multiple searches
|
||||
- **Relevance Filtering**: Removes low-quality matches
|
||||
- **Answer Synthesis**: Creates coherent responses from fragments
|
||||
|
||||
## 🔧 MCP Tools Used
|
||||
|
||||
| Tool | Purpose | When Used |
|
||||
|------|---------|-----------|
|
||||
| `perform_rag_query` | Main semantic search | Primary search operations |
|
||||
| `search_code_examples` | Code-specific search | When looking for code |
|
||||
| `get_available_sources` | List searchable sources | To filter searches |
|
||||
| `crawl_single_page` | Add new content | When current knowledge insufficient |
|
||||
| `smart_crawl_url` | Crawl documentation sites | For comprehensive updates |
|
||||
|
||||
## 📊 Search Workflows
|
||||
|
||||
### Standard RAG Query
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant RAGAgent as RAG Agent
|
||||
participant MCP as MCP Tools
|
||||
participant Server
|
||||
|
||||
User->>RAGAgent: Search query
|
||||
RAGAgent->>RAGAgent: Analyze intent
|
||||
RAGAgent->>MCP: get_available_sources()
|
||||
MCP-->>RAGAgent: Available sources
|
||||
RAGAgent->>RAGAgent: Select relevant sources
|
||||
RAGAgent->>MCP: perform_rag_query()
|
||||
MCP->>Server: HTTP POST /api/rag/query
|
||||
Server->>Server: Generate embeddings
|
||||
Server->>Server: Vector search
|
||||
Server-->>MCP: Search results
|
||||
MCP-->>RAGAgent: Raw results
|
||||
RAGAgent->>RAGAgent: Interpret & rank
|
||||
RAGAgent-->>User: Enhanced results
|
||||
```
|
||||
|
||||
### Multi-Strategy Search
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[User Query] --> B{Analyze Query Type}
|
||||
B -->|Technical| C[Documentation Search]
|
||||
B -->|Code| D[Code Example Search]
|
||||
B -->|Mixed| E[Combined Strategy]
|
||||
|
||||
C --> F[perform_rag_query]
|
||||
D --> G[search_code_examples]
|
||||
E --> H[Both Searches]
|
||||
|
||||
F --> I[Filter by Source]
|
||||
G --> J[Extract Code Context]
|
||||
H --> K[Merge Results]
|
||||
|
||||
I --> L[Rank Results]
|
||||
J --> L
|
||||
K --> L
|
||||
|
||||
L --> M[Synthesize Answer]
|
||||
```
|
||||
|
||||
## 💬 Example Interactions
|
||||
|
||||
### Simple Search
|
||||
```python
|
||||
# User request
|
||||
"How do I implement authentication in React?"
|
||||
|
||||
# RAG Agent workflow
|
||||
1. Analyze: Technical query about React authentication
|
||||
2. Check sources: Find React documentation available
|
||||
3. Enhance query: Add terms like "login", "JWT", "auth context"
|
||||
4. Call: perform_rag_query(
|
||||
query="React authentication implementation login JWT",
|
||||
source="react-docs",
|
||||
match_count=10
|
||||
)
|
||||
5. Filter: Remove generic authentication results
|
||||
6. Return: Focused results with code examples
|
||||
```
|
||||
|
||||
### Complex Multi-Source Search
|
||||
```python
|
||||
# User request
|
||||
"Compare different state management solutions for React"
|
||||
|
||||
# RAG Agent workflow
|
||||
1. Identify: Comparison query requiring multiple sources
|
||||
2. Break down:
|
||||
- "Redux state management"
|
||||
- "MobX state management"
|
||||
- "Zustand state management"
|
||||
- "React Context API"
|
||||
3. Execute parallel searches:
|
||||
- perform_rag_query(query="Redux", source="redux-docs")
|
||||
- perform_rag_query(query="MobX", source="mobx-docs")
|
||||
- search_code_examples(query="state management comparison")
|
||||
4. Aggregate: Combine results from all queries
|
||||
5. Synthesize: Create comparison table
|
||||
6. Return: Structured comparison with pros/cons
|
||||
```
|
||||
|
||||
## 🔍 Implementation Details
|
||||
|
||||
### Agent Structure
|
||||
```python
|
||||
from pydantic_ai import Agent, RunContext
|
||||
from typing import List, Dict, Any
|
||||
|
||||
class RAGAgent(Agent):
|
||||
"""Orchestrates RAG search operations"""
|
||||
|
||||
name = "rag_search"
|
||||
description = "Enhances search queries and interprets results"
|
||||
|
||||
tools = [
|
||||
"perform_rag_query",
|
||||
"search_code_examples",
|
||||
"get_available_sources",
|
||||
"crawl_single_page"
|
||||
]
|
||||
|
||||
async def search(
|
||||
self,
|
||||
context: RunContext,
|
||||
query: str
|
||||
) -> Dict[str, Any]:
|
||||
# Analyze query intent
|
||||
intent = self.analyze_intent(query)
|
||||
|
||||
# Get available sources
|
||||
sources = await context.tools.get_available_sources()
|
||||
|
||||
# Plan search strategy
|
||||
strategy = self.plan_strategy(intent, sources)
|
||||
|
||||
# Execute searches
|
||||
results = await self.execute_strategy(context, strategy)
|
||||
|
||||
# Synthesize response
|
||||
return self.synthesize_answer(results)
|
||||
```
|
||||
|
||||
### Query Enhancement Strategies
|
||||
|
||||
#### Synonym Expansion
|
||||
```python
|
||||
# Original query
|
||||
"fix bug in authentication"
|
||||
|
||||
# Enhanced query
|
||||
"fix bug error issue problem authentication login auth JWT session"
|
||||
```
|
||||
|
||||
#### Contextual Enhancement
|
||||
```python
|
||||
# With context of previous React questions
|
||||
"how to test it"
|
||||
|
||||
# Enhanced with context
|
||||
"React authentication testing unit test integration test Jest React Testing Library"
|
||||
```
|
||||
|
||||
#### Technical Term Addition
|
||||
```python
|
||||
# User query
|
||||
"make it faster"
|
||||
|
||||
# Enhanced for technical search
|
||||
"performance optimization speed improve fast efficient caching memoization"
|
||||
```
|
||||
|
||||
## 📈 Search Optimization
|
||||
|
||||
### Result Ranking Factors
|
||||
1. **Semantic Similarity**: How closely content matches query
|
||||
2. **Source Reliability**: Prefer official documentation
|
||||
3. **Recency**: Newer content scored higher
|
||||
4. **Code Presence**: Boost results with examples
|
||||
5. **Context Relevance**: Match to conversation history
|
||||
|
||||
### Caching Strategy
|
||||
- Cache frequent queries for instant results
|
||||
- Store query enhancement patterns
|
||||
- Remember successful search strategies
|
||||
- Cache source metadata for filtering
|
||||
|
||||
## 🚨 Handling Edge Cases
|
||||
|
||||
### No Results Found
|
||||
```python
|
||||
# Strategy when no results
|
||||
1. Broaden search terms
|
||||
2. Remove source filters
|
||||
3. Try alternative phrasings
|
||||
4. Suggest crawling new content
|
||||
5. Provide helpful error message
|
||||
|
||||
# Example
|
||||
if not results:
|
||||
# Try broader search
|
||||
results = await perform_rag_query(
|
||||
query=simplified_query,
|
||||
source=None, # Search all sources
|
||||
match_count=20 # Get more results
|
||||
)
|
||||
|
||||
if still not results:
|
||||
# Suggest adding content
|
||||
return {
|
||||
"message": "No results found. Would you like me to crawl relevant documentation?",
|
||||
"suggestion": f"crawl_single_page('{suggested_url}')"
|
||||
}
|
||||
```
|
||||
|
||||
### Ambiguous Queries
|
||||
```python
|
||||
# Handle unclear intent
|
||||
"How do I fix this?"
|
||||
|
||||
# Agent response
|
||||
1. Analyze context for clues
|
||||
2. Ask clarifying questions
|
||||
3. Provide multiple interpretations
|
||||
4. Show results for each interpretation
|
||||
```
|
||||
|
||||
## 🔗 Integration Patterns
|
||||
|
||||
### With Document Processing
|
||||
```python
|
||||
# Enhancing knowledge base
|
||||
"This documentation is missing, add it"
|
||||
|
||||
# Agent coordinates:
|
||||
1. Identify missing content area
|
||||
2. Find relevant documentation URL
|
||||
3. crawl_single_page() or smart_crawl_url()
|
||||
4. Verify content was added
|
||||
5. Test with sample query
|
||||
```
|
||||
|
||||
### With Task Management
|
||||
```python
|
||||
# Finding task-related information
|
||||
"What tasks are related to authentication?"
|
||||
|
||||
# Agent coordinates:
|
||||
1. search_code_examples(query="authentication")
|
||||
2. Extract file paths and functions
|
||||
3. Cross-reference with task descriptions
|
||||
4. Return relevant tasks with context
|
||||
```
|
||||
|
||||
## 📊 Performance Metrics
|
||||
|
||||
### Key Metrics
|
||||
- **Query Enhancement Rate**: How often queries are modified
|
||||
- **Result Relevance**: User satisfaction with results
|
||||
- **Search Latency**: Time from query to results
|
||||
- **Cache Hit Rate**: Percentage served from cache
|
||||
|
||||
### Search Monitoring
|
||||
The RAG Agent automatically tracks search performance including original query, enhanced query, and sources searched for each operation.
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### Query Optimization
|
||||
1. **Be Specific**: Add technical context when possible
|
||||
2. **Use Examples**: "like X but for Y" helps
|
||||
3. **Specify Sources**: Filter when you know the source
|
||||
4. **Iterate**: Refine based on initial results
|
||||
|
||||
### Result Interpretation
|
||||
1. **Check Scores**: Higher similarity scores = better matches
|
||||
2. **Verify Sources**: Official docs > community content
|
||||
3. **Look for Code**: Examples often clarify concepts
|
||||
4. **Read Context**: Surrounding text provides clarity
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [Agents Overview](./agents-overview) - Understanding the Agents service
|
||||
- [RAG Query Tool](./mcp-tools#perform-rag-query) - MCP tool details
|
||||
- [Search Service](./server-services#search-service) - Backend implementation
|
||||
- [Knowledge Overview](./knowledge-overview) - Knowledge base features
|
||||
351
docs/docs/agent-task.mdx
Normal file
@@ -0,0 +1,351 @@
|
||||
---
|
||||
title: Task Agent
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 📋 Task Agent
|
||||
|
||||
<div className="hero hero--secondary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**Intelligent task orchestration** using PydanticAI to break down complex work, manage dependencies, and coordinate project workflows through MCP tools.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
The Task Agent is a PydanticAI-powered orchestrator that handles complex project and task management workflows. It can break down high-level requirements into actionable tasks, manage dependencies, and coordinate multiple operations to keep projects organized.
|
||||
|
||||
<Admonition type="info" icon="💡" title="Pure Orchestration">
|
||||
The Task Agent contains NO project management logic. All actual operations are performed by the Server service through MCP tool calls.
|
||||
</Admonition>
|
||||
|
||||
## 🤖 Capabilities
|
||||
|
||||
### Task Analysis
|
||||
- **Requirement Breakdown**: Converts high-level goals into specific tasks
|
||||
- **Dependency Detection**: Identifies task relationships
|
||||
- **Priority Assignment**: Determines task importance
|
||||
- **Effort Estimation**: Suggests task complexity
|
||||
|
||||
### Project Orchestration
|
||||
- **Project Creation**: Sets up new projects with structure
|
||||
- **Task Organization**: Creates and manages related tasks
|
||||
- **Status Management**: Coordinates task state transitions
|
||||
- **Team Coordination**: Assigns work to humans or AI agents
|
||||
|
||||
## 🔧 MCP Tools Used
|
||||
|
||||
| Tool | Purpose | When Used |
|
||||
|------|---------|-----------|
|
||||
| `manage_project` | Project CRUD operations | Project creation/updates |
|
||||
| `manage_task` | Task lifecycle management | All task operations |
|
||||
| `manage_document` | Project documentation | PRDs, specs, notes |
|
||||
| `manage_versions` | Version control | Document updates |
|
||||
| `get_project_features` | Feature retrieval | Planning workflows |
|
||||
|
||||
## 📊 Task Workflows
|
||||
|
||||
### Project Setup
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant TaskAgent as Task Agent
|
||||
participant MCP as MCP Tools
|
||||
participant Server
|
||||
|
||||
User->>TaskAgent: Create project request
|
||||
TaskAgent->>TaskAgent: Analyze requirements
|
||||
TaskAgent->>MCP: manage_project(action="create")
|
||||
MCP->>Server: HTTP POST /api/projects
|
||||
Server-->>MCP: Project created
|
||||
TaskAgent->>TaskAgent: Plan initial tasks
|
||||
TaskAgent->>MCP: manage_task(action="create") x N
|
||||
MCP->>Server: Create multiple tasks
|
||||
Server-->>MCP: Tasks created
|
||||
TaskAgent-->>User: Project ready with tasks
|
||||
```
|
||||
|
||||
### Task Breakdown
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A[High-Level Requirement] --> B{Analyze Complexity}
|
||||
B -->|Simple| C[Single Task]
|
||||
B -->|Complex| D[Break Down]
|
||||
|
||||
D --> E[Identify Components]
|
||||
E --> F[Create Parent Task]
|
||||
F --> G[Create Related Tasks]
|
||||
|
||||
G --> H{Dependencies?}
|
||||
H -->|Yes| I[Set Order]
|
||||
H -->|No| J[Parallel Tasks]
|
||||
|
||||
I --> K[Assign Priorities]
|
||||
J --> K
|
||||
|
||||
K --> L[Set Assignees]
|
||||
L --> M[Create in System]
|
||||
```
|
||||
|
||||
## 💬 Example Interactions
|
||||
|
||||
### Project Creation
|
||||
```python
|
||||
# User request
|
||||
"Create a project for building a user authentication system"
|
||||
|
||||
# Task Agent workflow
|
||||
1. Create project:
|
||||
manage_project(
|
||||
action="create",
|
||||
title="User Authentication System",
|
||||
github_repo="https://github.com/team/auth-system"
|
||||
)
|
||||
|
||||
2. Generate initial tasks:
|
||||
- Design authentication flow
|
||||
- Implement user model
|
||||
- Create login API endpoint
|
||||
- Build registration flow
|
||||
- Add password reset
|
||||
- Write tests
|
||||
- Create documentation
|
||||
|
||||
3. Create each task with relationships:
|
||||
for task in generated_tasks:
|
||||
manage_task(
|
||||
action="create",
|
||||
project_id=project.id,
|
||||
title=task.title,
|
||||
description=task.description,
|
||||
assignee=task.suggested_assignee
|
||||
)
|
||||
|
||||
4. Return: "Created project with 7 initial tasks"
|
||||
```
|
||||
|
||||
### Complex Task Breakdown
|
||||
```python
|
||||
# User request
|
||||
"Break down 'Implement login API endpoint' into smaller tasks"
|
||||
|
||||
# Task Agent workflow
|
||||
1. Analyze the main task
|
||||
2. Identify components:
|
||||
- Input validation
|
||||
- Database query
|
||||
- Password verification
|
||||
- JWT generation
|
||||
- Response formatting
|
||||
- Error handling
|
||||
|
||||
3. Create related tasks:
|
||||
manage_task(action="create", project_id=project_id, ...)
|
||||
|
||||
4. Set logical order and priorities:
|
||||
- Input validation (priority: high)
|
||||
- Database query (priority: high)
|
||||
- Password verification (priority: high)
|
||||
- JWT generation (priority: medium)
|
||||
|
||||
5. Return: "Created 6 related tasks with appropriate priorities"
|
||||
```
|
||||
|
||||
## 🔍 Implementation Details
|
||||
|
||||
### Agent Structure
|
||||
```python
|
||||
from pydantic_ai import Agent, RunContext
|
||||
from typing import List, Dict, Any
|
||||
|
||||
class TaskAgent(Agent):
|
||||
"""Orchestrates task and project management"""
|
||||
|
||||
name = "task_manager"
|
||||
description = "Manages projects and tasks intelligently"
|
||||
|
||||
tools = [
|
||||
"manage_project",
|
||||
"manage_task",
|
||||
"manage_document",
|
||||
"manage_versions",
|
||||
"get_project_features"
|
||||
]
|
||||
|
||||
async def process_request(
|
||||
self,
|
||||
context: RunContext,
|
||||
request: str
|
||||
) -> Dict[str, Any]:
|
||||
# Understand the request
|
||||
intent = self.analyze_intent(request)
|
||||
|
||||
# Execute appropriate workflow
|
||||
if intent.type == "create_project":
|
||||
return await self.create_project_workflow(context, intent)
|
||||
elif intent.type == "break_down_task":
|
||||
return await self.breakdown_workflow(context, intent)
|
||||
elif intent.type == "update_status":
|
||||
return await self.status_workflow(context, intent)
|
||||
# ... more workflows
|
||||
```
|
||||
|
||||
### Intelligence Patterns
|
||||
|
||||
#### Task Generation
|
||||
```python
|
||||
def generate_tasks_for_feature(feature_description: str) -> List[Task]:
|
||||
"""Generate tasks based on feature requirements"""
|
||||
|
||||
# Analyze feature type
|
||||
if "authentication" in feature_description:
|
||||
return [
|
||||
Task("Design auth flow", "User", "high"),
|
||||
Task("Implement auth service", "AI IDE Agent", "high"),
|
||||
Task("Create login UI", "User", "medium"),
|
||||
Task("Add tests", "AI IDE Agent", "high"),
|
||||
Task("Document API", "Archon", "medium")
|
||||
]
|
||||
# ... more patterns
|
||||
```
|
||||
|
||||
#### Dependency Detection
|
||||
```python
|
||||
def detect_dependencies(tasks: List[Task]) -> List[Dependency]:
|
||||
"""Identify task relationships"""
|
||||
|
||||
dependencies = []
|
||||
for task in tasks:
|
||||
if "test" in task.title.lower():
|
||||
# Tests depend on implementation
|
||||
impl_task = find_implementation_task(tasks, task)
|
||||
if impl_task:
|
||||
dependencies.append(Dependency(impl_task, task))
|
||||
|
||||
return dependencies
|
||||
```
|
||||
|
||||
## 📈 Project Management Patterns
|
||||
|
||||
### Sprint Planning
|
||||
```python
|
||||
# Organize tasks into sprints
|
||||
"Plan the next sprint"
|
||||
|
||||
# Agent workflow:
|
||||
1. Get all pending tasks
|
||||
2. Analyze task priorities and sizes
|
||||
3. Group related tasks
|
||||
4. Balance workload
|
||||
5. Create sprint documentation
|
||||
6. Update task assignments
|
||||
```
|
||||
|
||||
### Progress Tracking
|
||||
```python
|
||||
# Monitor project progress
|
||||
"Show me what's blocking progress"
|
||||
|
||||
# Agent workflow:
|
||||
1. Find all "blocked" status tasks
|
||||
2. Analyze blocking reasons
|
||||
3. Identify dependency chains
|
||||
4. Suggest solutions
|
||||
5. Return actionable report
|
||||
```
|
||||
|
||||
## 🚨 Advanced Orchestration
|
||||
|
||||
### Multi-Project Coordination
|
||||
```python
|
||||
# Handle cross-project dependencies
|
||||
"The auth system needs the user service completed first"
|
||||
|
||||
# Agent coordinates:
|
||||
1. Identify both projects
|
||||
2. Find related tasks
|
||||
3. Create cross-project dependency
|
||||
4. Adjust timelines
|
||||
5. Notify relevant assignees
|
||||
```
|
||||
|
||||
### Automated Status Updates
|
||||
```python
|
||||
# Intelligent status management
|
||||
"Update all completed development tasks to review"
|
||||
|
||||
# Agent workflow:
|
||||
1. Find tasks with:
|
||||
- Status: "doing"
|
||||
- Assignee: "AI IDE Agent"
|
||||
- Recent activity
|
||||
2. Check completion criteria
|
||||
3. Update status to "review"
|
||||
4. Notify reviewers
|
||||
```
|
||||
|
||||
## 🔗 Integration Examples
|
||||
|
||||
### With Knowledge Base
|
||||
```python
|
||||
# Link tasks to documentation
|
||||
"Find all tasks related to React hooks"
|
||||
|
||||
# Agent coordinates:
|
||||
1. perform_rag_query("React hooks")
|
||||
2. Extract relevant file paths
|
||||
3. Search tasks mentioning those files
|
||||
4. Create task-knowledge links
|
||||
5. Return related tasks
|
||||
```
|
||||
|
||||
### With Document Management
|
||||
```python
|
||||
# Create project documentation
|
||||
"Generate PRD for the authentication project"
|
||||
|
||||
# Agent coordinates:
|
||||
1. get_project_features(project_id)
|
||||
2. Analyze existing tasks
|
||||
3. Generate PRD structure
|
||||
4. manage_document(action="add", content=prd)
|
||||
5. Link to project
|
||||
```
|
||||
|
||||
## 📊 Performance Metrics
|
||||
|
||||
### Key Metrics
|
||||
- **Task Creation Time**: Speed of generating tasks
|
||||
- **Breakdown Accuracy**: Quality of task decomposition
|
||||
- **Dependency Detection**: Correctly identified relationships
|
||||
- **Assignment Distribution**: Balance across team
|
||||
|
||||
### Performance Tracking
|
||||
The Task Agent automatically tracks operation performance and provides detailed results for each orchestration workflow.
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### Task Creation
|
||||
1. **Clear Titles**: Actionable and specific
|
||||
2. **Descriptions**: Include acceptance criteria
|
||||
3. **Right-Sizing**: Not too big, not too small
|
||||
4. **Assignments**: Match skills to assignees
|
||||
|
||||
### Project Organization
|
||||
1. **Feature Grouping**: Related tasks together
|
||||
2. **Milestone Planning**: Clear project phases
|
||||
3. **Documentation**: Keep PRDs updated
|
||||
4. **Regular Reviews**: Adjust as needed
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [Agents Overview](./agents-overview) - Understanding the Agents service
|
||||
- [Project Management Tools](./mcp-tools#project-tools) - MCP tool details
|
||||
- [Task Service](./server-services#task-service) - Backend implementation
|
||||
- [Projects Overview](./projects-overview) - Project management features
|
||||
224
docs/docs/agents-overview.mdx
Normal file
@@ -0,0 +1,224 @@
|
||||
---
|
||||
title: Agents Overview
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# ⚙️ Agents Service Overview
|
||||
|
||||
<div className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**PydanticAI-powered agents** that orchestrate complex operations by intelligently combining MCP tools. No business logic, pure AI orchestration.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Admonition type="warning" icon="⚠️" title="Critical Architecture Principle">
|
||||
|
||||
**The Agents service is purely an AI orchestration layer that:**
|
||||
- Contains PydanticAI agent implementations
|
||||
- Uses MCP tools for ALL operations
|
||||
- Has NO direct database access
|
||||
- Contains NO ML models or embeddings
|
||||
- Performs NO data processing
|
||||
|
||||
**All actual functionality comes from calling MCP tools, which in turn call the Server service.**
|
||||
|
||||
</Admonition>
|
||||
|
||||
## 🏗️ Architecture Overview
|
||||
|
||||
The Agents Service (`archon-agents`) runs on port 8052 and contains three specialized PydanticAI agents:
|
||||
|
||||
```mermaid
|
||||
%%{init:{
|
||||
'theme':'base',
|
||||
'themeVariables': {
|
||||
'primaryColor':'#1f2937',
|
||||
'primaryTextColor':'#ffffff',
|
||||
'primaryBorderColor':'#8b5cf6'
|
||||
}
|
||||
}}%%
|
||||
graph TB
|
||||
subgraph "Agents Service (Port 8052)"
|
||||
DA[Document Agent]
|
||||
RA[RAG Agent]
|
||||
TA[Task Agent]
|
||||
end
|
||||
|
||||
subgraph "MCP Service (Port 8051)"
|
||||
Tools[14 MCP Tools]
|
||||
end
|
||||
|
||||
subgraph "Server Service (Port 8080)"
|
||||
BL[All Business Logic]
|
||||
ML[ML Models]
|
||||
DB[Database Operations]
|
||||
end
|
||||
|
||||
DA -->|Uses| Tools
|
||||
RA -->|Uses| Tools
|
||||
TA -->|Uses| Tools
|
||||
|
||||
Tools -->|HTTP Calls| BL
|
||||
Tools -->|HTTP Calls| ML
|
||||
Tools -->|HTTP Calls| DB
|
||||
```
|
||||
|
||||
## 🤖 Available Agents
|
||||
|
||||
### 1. Document Agent
|
||||
- **Purpose**: Orchestrates document processing workflows
|
||||
- **Capabilities**: Intelligent document handling and organization
|
||||
- **MCP Tools Used**: `upload_document`, `manage_document`, `store_documents`
|
||||
|
||||
### 2. RAG Agent
|
||||
- **Purpose**: Orchestrates knowledge retrieval and search refinement
|
||||
- **Capabilities**: Query enhancement and result interpretation
|
||||
- **MCP Tools Used**: `perform_rag_query`, `search_code_examples`, `get_available_sources`
|
||||
|
||||
### 3. Task Agent
|
||||
- **Purpose**: Orchestrates project and task management workflows
|
||||
- **Capabilities**: Task breakdown and status management
|
||||
- **MCP Tools Used**: `manage_project`, `manage_task`, `manage_versions`
|
||||
|
||||
## 🎯 How Agents Work
|
||||
|
||||
### PydanticAI Framework
|
||||
All agents are built using the PydanticAI framework, which provides:
|
||||
- Type-safe agent definitions
|
||||
- Structured tool calling
|
||||
- Context management
|
||||
- Error handling
|
||||
|
||||
### Agent Workflow Pattern
|
||||
```python
|
||||
# Conceptual flow (simplified)
|
||||
class DocumentAgent:
|
||||
async def process_document(self, file_path: str, doc_type: str):
|
||||
# 1. Analyze document requirements
|
||||
analysis = self.analyze_document_type(file_path)
|
||||
|
||||
# 2. Call MCP tool to upload
|
||||
result = await mcp_tools.upload_document(
|
||||
file_path=file_path,
|
||||
doc_type=doc_type,
|
||||
metadata=analysis.metadata
|
||||
)
|
||||
|
||||
# 3. Orchestrate additional processing
|
||||
if analysis.needs_chunking:
|
||||
await mcp_tools.store_documents(...)
|
||||
|
||||
# 4. Return structured result
|
||||
return ProcessingResult(...)
|
||||
```
|
||||
|
||||
## 🔧 Technical Implementation
|
||||
|
||||
### Service Configuration
|
||||
- **Framework**: FastAPI for the HTTP server
|
||||
- **Port**: 8052
|
||||
- **Dependencies**: PydanticAI, MCP client libraries
|
||||
- **No Database**: All data operations via MCP tools
|
||||
|
||||
### Communication Flow
|
||||
1. **External Request** → Agents Service
|
||||
2. **Agent Analysis** → Determines required operations
|
||||
3. **MCP Tool Calls** → Multiple coordinated tool calls
|
||||
4. **Server Processing** → Actual work done in Server service
|
||||
5. **Result Aggregation** → Agent combines results
|
||||
6. **Response** → Structured output to caller
|
||||
|
||||
### Health Check
|
||||
```bash
|
||||
curl http://localhost:8052/health
|
||||
|
||||
# Response
|
||||
{
|
||||
"status": "healthy",
|
||||
"service": "archon-agents",
|
||||
"agents_available": ["document", "rag", "task"],
|
||||
"mcp_connection": "active"
|
||||
}
|
||||
```
|
||||
|
||||
## 🚀 Docker Deployment
|
||||
|
||||
```dockerfile
|
||||
# Agents Service Dockerfile
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install dependencies
|
||||
COPY requirements.txt .
|
||||
RUN pip install -r requirements.txt
|
||||
|
||||
# Copy agent implementations
|
||||
COPY src/agents/ src/agents/
|
||||
|
||||
# Environment variables
|
||||
ENV PYTHONPATH=/app/src
|
||||
ENV MCP_SERVER_URL=http://archon-mcp:8051
|
||||
|
||||
# Run the service
|
||||
CMD ["uvicorn", "src.agents.server:app", "--host", "0.0.0.0", "--port", "8052"]
|
||||
```
|
||||
|
||||
## 📊 Monitoring
|
||||
|
||||
### Logfire Integration
|
||||
All agent operations are monitored with Logfire:
|
||||
- Agent invocation tracking
|
||||
- MCP tool call monitoring
|
||||
- Performance metrics
|
||||
- Error tracking
|
||||
|
||||
### Key Metrics
|
||||
- **Agent Response Time**: Time to complete orchestration
|
||||
- **Tool Call Count**: Number of MCP tools used per request
|
||||
- **Success Rate**: Percentage of successful operations
|
||||
- **Error Types**: Common failure patterns
|
||||
|
||||
## 🔗 Integration Points
|
||||
|
||||
### API Endpoints
|
||||
The Agents service is called by the Server service for complex operations:
|
||||
- `POST /api/agent-chat/message` - Main chat interface
|
||||
- `POST /agents/document/process` - Document processing
|
||||
- `POST /agents/rag/search` - Enhanced search
|
||||
- `POST /agents/task/manage` - Task orchestration
|
||||
|
||||
### MCP Tool Usage
|
||||
Agents can use all 14 MCP tools:
|
||||
- 7 Knowledge Management tools
|
||||
- 5 Project Management tools
|
||||
- 2 System tools
|
||||
|
||||
## 🎯 When to Use Agents
|
||||
|
||||
### Use Agents When:
|
||||
- Complex orchestration is needed
|
||||
- Multiple MCP tools must be coordinated
|
||||
- Intelligent decision-making is required
|
||||
- Natural language processing helps
|
||||
|
||||
### Direct MCP Tools When:
|
||||
- Simple, single operations
|
||||
- Performance is critical
|
||||
- Deterministic behavior needed
|
||||
- No orchestration required
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [Agent Chat Panel](./agent-chat) - Real-time UI for interacting with agents
|
||||
- [Document Agent](./agent-document) - Document processing orchestration
|
||||
- [RAG Agent](./agent-rag) - Search and retrieval orchestration
|
||||
- [Task Agent](./agent-task) - Project management orchestration
|
||||
- [MCP Tools Reference](./mcp-tools) - Available MCP tools
|
||||
- [Server Architecture](./server-overview) - Overall system design
|
||||
2046
docs/docs/api-reference.mdx
Normal file
158
docs/docs/architecture.mdx
Normal file
@@ -0,0 +1,158 @@
|
||||
---
|
||||
title: Architecture
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
# Architecture
|
||||
|
||||
## System Overview
|
||||
|
||||
Archon uses a microservices architecture with clear separation of concerns:
|
||||
|
||||
```
|
||||
Frontend (React) AI Clients (Cursor/Windsurf)
|
||||
| |
|
||||
v v
|
||||
Server API (FastAPI:8080) MCP Server (:8051)
|
||||
| |
|
||||
| v
|
||||
| HTTP Calls
|
||||
| |
|
||||
v v
|
||||
Service Layer <----------------------+
|
||||
|
|
||||
v
|
||||
Database (Supabase/pgvector)
|
||||
```
|
||||
|
||||
## Core Principles
|
||||
|
||||
1. **Server contains ALL business logic** - Services, ML models, data operations
|
||||
2. **MCP is HTTP-only** - Makes HTTP calls to Server, no direct imports
|
||||
3. **FastAPI uses services directly** - For performance, no intermediate layers
|
||||
4. **No cross-dependencies** - Each layer only knows about the layer below
|
||||
|
||||
## Service Architecture
|
||||
|
||||
### Service Layer Organization
|
||||
|
||||
| Service Category | Services | Purpose |
|
||||
|-----------------|----------|---------|
|
||||
| **RAG Services** | `CrawlingService` | Web crawling operations |
|
||||
| **Storage Services** | `DocumentStorageService`<br/>`BaseStorageService` | Document storage and processing |
|
||||
| **Search Services** | `SearchService` | Vector search and RAG queries |
|
||||
| **Core Services** | `SourceManagementService` | Knowledge source management |
|
||||
| **Project Services** | `ProjectService`<br/>`TaskService`<br/>`DocumentService`<br/>`VersioningService` | Project management |
|
||||
| **Core Services** | `CredentialService`<br/>`PromptService`<br/>`ThreadingService` | System utilities |
|
||||
| **Storage Services** | `add_documents_to_supabase`<br/>`extract_code_blocks`<br/>`add_code_examples_to_supabase` | Data persistence |
|
||||
| **Embedding Services** | `create_embeddings_batch`<br/>`generate_contextual_embedding` | Vector operations |
|
||||
|
||||
### Access Patterns
|
||||
|
||||
```python
|
||||
# FastAPI Endpoint - Direct Service Usage
|
||||
from ..services.source_management_service import SourceManagementService
|
||||
|
||||
@router.delete("/sources/{source_id}")
|
||||
async def delete_source(source_id: str):
|
||||
service = SourceManagementService(get_supabase_client())
|
||||
success, result = service.delete_source(source_id)
|
||||
return {"success": success, **result}
|
||||
```
|
||||
|
||||
```python
|
||||
# MCP Tool - HTTP Call to Server
|
||||
import httpx
|
||||
|
||||
@mcp.tool()
|
||||
async def delete_source(ctx: Context, source: str) -> str:
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.delete(f"{API_URL}/api/sources/{source}")
|
||||
return response.json()
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### Server Service (Port 8080)
|
||||
- FastAPI application
|
||||
- REST API endpoints
|
||||
- Socket.IO real-time communication
|
||||
- Direct service layer access
|
||||
- Business logic implementation
|
||||
|
||||
### MCP Service (Port 8051)
|
||||
- MCP protocol server
|
||||
- 14 tools (7 RAG + 7 Project)
|
||||
- HTTP client for Server API
|
||||
- No business logic
|
||||
- SSE transport for AI clients
|
||||
|
||||
### Service Layer
|
||||
- Modular service classes
|
||||
- Shared by FastAPI endpoints
|
||||
- Contains all business logic
|
||||
- Database operations
|
||||
- ML model integration
|
||||
|
||||
## Data Flow Examples
|
||||
|
||||
### Delete Source Operation
|
||||
```
|
||||
1. User clicks delete in UI
|
||||
2. UI calls DELETE /api/knowledge-items/{id}
|
||||
3. FastAPI endpoint uses SourceManagementService.delete_source() from `/services/`
|
||||
4. Service deletes from database
|
||||
5. Response sent to UI
|
||||
|
||||
OR
|
||||
|
||||
1. AI client calls MCP delete_source tool
|
||||
2. MCP makes HTTP DELETE to /api/sources/{id}
|
||||
3. Server endpoint uses SourceManagementService.delete_source() from `/services/`
|
||||
4. Service deletes from database
|
||||
5. Response sent through MCP to AI client
|
||||
```
|
||||
|
||||
### Smart Crawl Operation (Simplified Socket.IO)
|
||||
```
|
||||
1. User initiates crawl
|
||||
2. UI calls POST /api/knowledge-items/crawl
|
||||
3. FastAPI endpoint:
|
||||
- Uses CrawlingService to detect URL type
|
||||
- Calls appropriate crawl method
|
||||
- Services emit Socket.IO progress directly to rooms
|
||||
- Uses DocumentStorageService from `/services/storage/` for chunking
|
||||
4. UI listens to Socket.IO room for real-time updates
|
||||
```
|
||||
|
||||
### Task Update Flow (Simplified)
|
||||
```
|
||||
1. MCP tool calls POST /api/tasks
|
||||
2. API endpoint creates task using TaskService
|
||||
3. TaskService emits Socket.IO event directly to project room
|
||||
4. UI subscribed to project room receives update immediately
|
||||
5. No database polling needed
|
||||
```
|
||||
|
||||
## Simplified Real-Time Architecture
|
||||
|
||||
### Simplified Socket.IO (2025 Pattern)
|
||||
```
|
||||
MCP Tools → HTTP API → Services → @sio.event → Rooms → UI
|
||||
```
|
||||
|
||||
Key improvements:
|
||||
- **No database polling** - Eliminated 2-second polling system
|
||||
- **Simple @sio.event handlers** - Official Socket.IO 2025 pattern
|
||||
- **Direct room management** - `sio.enter_room()` and `sio.emit()` calls
|
||||
- **No namespace classes** - Removed complex abstraction layers
|
||||
- **Single root namespace** - Everything on `/` namespace for simplicity
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **No MCP imports in FastAPI** - Services only
|
||||
- **No direct DB access in MCP** - HTTP only
|
||||
- **Services are the single source of truth** - All logic here
|
||||
- **Simple @sio.event handlers** - Official Socket.IO 2025 pattern
|
||||
- **Root namespace only** - No complex namespace management
|
||||
- **Direct room management** - Simple `sio.enter_room()` and `sio.emit()` calls
|
||||
320
docs/docs/background-tasks.mdx
Normal file
@@ -0,0 +1,320 @@
|
||||
---
|
||||
sidebar_position: 25
|
||||
sidebar_label: Background Tasks
|
||||
---
|
||||
|
||||
# Background Tasks Architecture
|
||||
|
||||
## Overview
|
||||
|
||||
This document describes the architecture for handling long-running operations in Archon without blocking the FastAPI/Socket.IO event loop. The key insight is that browser-based operations (crawling) must remain in the main event loop, while only CPU-intensive operations should be offloaded to threads.
|
||||
|
||||
## Architecture Principles
|
||||
|
||||
1. **Keep async I/O operations in the main event loop** - Browser automation, database operations, and network requests must stay async
|
||||
2. **Only offload CPU-intensive work to threads** - Text processing, chunking, and synchronous API calls can run in ThreadPoolExecutor
|
||||
3. **Use asyncio.create_task for background async work** - Don't block the event loop, but keep async operations async
|
||||
4. **Maintain single event loop** - Never create new event loops in threads
|
||||
|
||||
## Architecture Diagram
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Main Event Loop"
|
||||
API[FastAPI Endpoint]
|
||||
SIO[Socket.IO Handler]
|
||||
BGTask[Background Async Task]
|
||||
Crawler[AsyncWebCrawler]
|
||||
DB[Database Operations]
|
||||
Progress[Progress Updates]
|
||||
end
|
||||
|
||||
subgraph "ThreadPoolExecutor"
|
||||
Chunk[Text Chunking]
|
||||
Embed[Embedding Generation]
|
||||
Summary[Summary Extraction]
|
||||
CodeExt[Code Extraction]
|
||||
end
|
||||
|
||||
API -->|asyncio.create_task| BGTask
|
||||
BGTask -->|await| Crawler
|
||||
BGTask -->|await| DB
|
||||
BGTask -->|run_in_executor| Chunk
|
||||
BGTask -->|run_in_executor| Embed
|
||||
BGTask -->|run_in_executor| Summary
|
||||
BGTask -->|run_in_executor| CodeExt
|
||||
BGTask -->|emit| Progress
|
||||
Progress -->|websocket| SIO
|
||||
|
||||
classDef async fill:#e1f5fe,stroke:#01579b,stroke-width:2px
|
||||
classDef sync fill:#fff3e0,stroke:#e65100,stroke-width:2px
|
||||
|
||||
class API,SIO,BGTask,Crawler,DB,Progress async
|
||||
class Chunk,Embed,Summary,CodeExt sync
|
||||
```
|
||||
|
||||
## Core Components
|
||||
|
||||
### CrawlOrchestrationService
|
||||
|
||||
The orchestration service manages the entire crawl workflow while keeping the main event loop responsive:
|
||||
|
||||
```python
|
||||
class CrawlOrchestrationService:
|
||||
def __init__(self, crawler, supabase_client, progress_id=None):
|
||||
self.crawler = crawler
|
||||
self.supabase_client = supabase_client
|
||||
self.progress_id = progress_id
|
||||
self.active_tasks = {}
|
||||
# Thread pool for CPU-intensive operations only
|
||||
self.executor = ThreadPoolExecutor(max_workers=4)
|
||||
|
||||
async def orchestrate_crawl(self, request: Dict[str, Any]) -> Dict[str, Any]:
|
||||
"""Start crawl operation as background task"""
|
||||
url = str(request.get('url', ''))
|
||||
|
||||
# Create background task in the SAME event loop
|
||||
task = asyncio.create_task(
|
||||
self._async_orchestrate_crawl(request)
|
||||
)
|
||||
|
||||
# Store task reference
|
||||
self.active_tasks[self.progress_id] = task
|
||||
|
||||
# Return immediately
|
||||
return {
|
||||
"task_id": self.progress_id,
|
||||
"status": "started",
|
||||
"message": f"Crawl operation started for {url}"
|
||||
}
|
||||
|
||||
async def _async_orchestrate_crawl(self, request: Dict[str, Any]):
|
||||
"""Background async task - runs in main event loop"""
|
||||
try:
|
||||
url = request.get('url', '')
|
||||
|
||||
# Emit initial progress
|
||||
await self._emit_progress({
|
||||
'status': 'analyzing',
|
||||
'percentage': 0,
|
||||
'currentUrl': url,
|
||||
'log': f'Analyzing URL type for {url}'
|
||||
})
|
||||
|
||||
# Step 1: Crawl URLs (MUST stay async in main loop)
|
||||
crawl_results = await self._crawl_urls_async(url, request)
|
||||
|
||||
# Step 2: Process documents (CPU-intensive, can go to thread)
|
||||
loop = asyncio.get_event_loop()
|
||||
doc_results = await loop.run_in_executor(
|
||||
self.executor,
|
||||
self._process_documents_sync, # Sync version
|
||||
crawl_results, request
|
||||
)
|
||||
|
||||
# Step 3: Store in database (MUST stay async in main loop)
|
||||
await self._store_documents_async(doc_results)
|
||||
|
||||
# Step 4: Generate embeddings (CPU-intensive, can go to thread)
|
||||
await loop.run_in_executor(
|
||||
self.executor,
|
||||
self._generate_embeddings_sync,
|
||||
doc_results
|
||||
)
|
||||
|
||||
# Step 5: Extract code (CPU-intensive, can go to thread)
|
||||
code_count = await loop.run_in_executor(
|
||||
self.executor,
|
||||
self._extract_code_sync,
|
||||
crawl_results
|
||||
)
|
||||
|
||||
# Complete
|
||||
await self._emit_progress({
|
||||
'status': 'complete',
|
||||
'percentage': 100,
|
||||
'log': 'Crawl operation completed successfully'
|
||||
})
|
||||
|
||||
except Exception as e:
|
||||
logger.error(f"Crawl orchestration error: {e}")
|
||||
await self._emit_progress({
|
||||
'status': 'error',
|
||||
'percentage': -1,
|
||||
'error': str(e)
|
||||
})
|
||||
|
||||
async def _emit_progress(self, update: Dict[str, Any]):
|
||||
"""Emit progress via Socket.IO"""
|
||||
if self.progress_id:
|
||||
await update_crawl_progress(self.progress_id, update)
|
||||
```
|
||||
|
||||
### Sync Functions for Thread Execution
|
||||
|
||||
Only CPU-intensive operations should have sync versions for thread execution:
|
||||
|
||||
```python
|
||||
def _process_documents_sync(self, crawl_results, request):
|
||||
"""Sync version for thread execution - CPU-intensive text processing"""
|
||||
all_chunks = []
|
||||
for doc in crawl_results:
|
||||
# Text chunking is CPU-intensive
|
||||
chunks = self.chunk_text(doc['markdown'])
|
||||
all_chunks.extend(chunks)
|
||||
return {
|
||||
'chunks': all_chunks,
|
||||
'chunk_count': len(all_chunks)
|
||||
}
|
||||
|
||||
def _generate_embeddings_sync(self, doc_results):
|
||||
"""Sync version - uses synchronous OpenAI client"""
|
||||
client = openai.Client() # Sync client
|
||||
embeddings = []
|
||||
|
||||
for chunk in doc_results['chunks']:
|
||||
# CPU-intensive: preparing embedding request
|
||||
response = client.embeddings.create(
|
||||
input=chunk,
|
||||
model="text-embedding-3-small"
|
||||
)
|
||||
embeddings.append(response.data[0].embedding)
|
||||
|
||||
return embeddings
|
||||
|
||||
def _extract_code_sync(self, crawl_results):
|
||||
"""Sync version - CPU-intensive regex and parsing"""
|
||||
code_examples = []
|
||||
for doc in crawl_results:
|
||||
# Extract code blocks with regex
|
||||
code_blocks = self.extract_code_blocks(doc['markdown'])
|
||||
code_examples.extend(code_blocks)
|
||||
return len(code_examples)
|
||||
```
|
||||
|
||||
### Socket.IO Integration
|
||||
|
||||
Socket.IO handlers remain in the main event loop:
|
||||
|
||||
```python
|
||||
# socketio_handlers.py
|
||||
|
||||
async def update_crawl_progress(progress_id: str, data: dict):
|
||||
"""Emit progress updates to connected clients"""
|
||||
# Check if room has subscribers
|
||||
room_sids = []
|
||||
if hasattr(sio.manager, 'rooms'):
|
||||
namespace_rooms = sio.manager.rooms.get('/', {})
|
||||
room_sids = list(namespace_rooms.get(progress_id, []))
|
||||
|
||||
if not room_sids:
|
||||
logger.warning(f"No subscribers in room {progress_id}")
|
||||
return
|
||||
|
||||
# Emit progress
|
||||
data['progressId'] = progress_id
|
||||
await sio.emit('crawl_progress', data, room=progress_id)
|
||||
|
||||
@sio.event
|
||||
async def subscribe_to_progress(sid, data):
|
||||
"""Client subscribes to progress updates"""
|
||||
progress_id = data.get('progressId')
|
||||
if progress_id:
|
||||
sio.enter_room(sid, progress_id)
|
||||
# Send current status if task is running
|
||||
orchestrator = get_orchestrator_for_progress(progress_id)
|
||||
if orchestrator and progress_id in orchestrator.active_tasks:
|
||||
await sio.emit('crawl_progress', {
|
||||
'progressId': progress_id,
|
||||
'status': 'running',
|
||||
'message': 'Reconnected to running task'
|
||||
}, to=sid)
|
||||
```
|
||||
|
||||
### API Endpoint Pattern
|
||||
|
||||
FastAPI endpoints start background tasks and return immediately:
|
||||
|
||||
```python
|
||||
# knowledge_api.py
|
||||
|
||||
@router.post("/knowledge/add")
|
||||
async def add_knowledge_item(request: KnowledgeAddRequest):
|
||||
"""Start crawl operation - returns immediately"""
|
||||
# Generate progress ID
|
||||
progress_id = str(uuid.uuid4())
|
||||
|
||||
# Create orchestrator
|
||||
orchestrator = CrawlOrchestrationService(
|
||||
crawler=await crawler_manager.get_crawler(),
|
||||
supabase_client=supabase_client,
|
||||
progress_id=progress_id
|
||||
)
|
||||
|
||||
# Start background task
|
||||
result = await orchestrator.orchestrate_crawl(request.dict())
|
||||
|
||||
# Return task info immediately
|
||||
return {
|
||||
"success": True,
|
||||
"task_id": result["task_id"],
|
||||
"progress_id": progress_id,
|
||||
"message": "Crawl started in background"
|
||||
}
|
||||
|
||||
@router.get("/knowledge/status/{task_id}")
|
||||
async def get_task_status(task_id: str):
|
||||
"""Check status of background task"""
|
||||
orchestrator = get_orchestrator_for_task(task_id)
|
||||
if not orchestrator:
|
||||
raise HTTPException(404, "Task not found")
|
||||
|
||||
task = orchestrator.active_tasks.get(task_id)
|
||||
if not task:
|
||||
raise HTTPException(404, "Task not found")
|
||||
|
||||
return {
|
||||
"task_id": task_id,
|
||||
"done": task.done(),
|
||||
"cancelled": task.cancelled()
|
||||
}
|
||||
```
|
||||
|
||||
## Key Patterns
|
||||
|
||||
### What Stays Async (Main Loop)
|
||||
- Browser automation (crawling)
|
||||
- Database operations
|
||||
- Network requests
|
||||
- Socket.IO communications
|
||||
- Task coordination
|
||||
|
||||
### What Goes to Threads
|
||||
- Text chunking
|
||||
- Markdown parsing
|
||||
- Code extraction
|
||||
- Embedding preparation
|
||||
- CPU-intensive calculations
|
||||
|
||||
### Progress Updates
|
||||
- Use asyncio.Queue for async tasks
|
||||
- Regular python Queue for thread tasks
|
||||
- Always emit from main event loop
|
||||
- Include detailed status information
|
||||
|
||||
## Common Pitfalls to Avoid
|
||||
|
||||
1. **Don't create new event loops in threads** - Database connections won't work
|
||||
2. **Don't run browser automation in threads** - It needs the main event loop
|
||||
3. **Don't block the main loop** - Use asyncio.create_task for background work
|
||||
4. **Don't mix async and sync incorrectly** - Keep clear boundaries
|
||||
5. **Don't forget progress updates** - Users need feedback
|
||||
|
||||
## Testing Guidelines
|
||||
|
||||
1. Test with long-running crawls (100+ pages)
|
||||
2. Verify Socket.IO doesn't disconnect
|
||||
3. Check database operations work correctly
|
||||
4. Monitor memory usage in threads
|
||||
5. Test task cancellation
|
||||
6. Verify progress accuracy
|
||||
194
docs/docs/code-extraction-rules.mdx
Normal file
@@ -0,0 +1,194 @@
|
||||
# Code Extraction Rules
|
||||
|
||||
This document outlines the sophisticated rules and algorithms used by Archon's code extraction service to identify, extract, and validate code examples from various sources.
|
||||
|
||||
## Overview
|
||||
|
||||
The code extraction service intelligently extracts meaningful code examples from crawled documents while filtering out non-code content like diagrams, prose, and malformed snippets. It uses dynamic thresholds, language-specific patterns, and quality validation to ensure high-quality code examples.
|
||||
|
||||
## Key Features
|
||||
|
||||
### 1. Dynamic Minimum Length Calculation
|
||||
|
||||
Instead of using a fixed minimum length, the service calculates appropriate thresholds based on:
|
||||
|
||||
- **Language characteristics**: Different languages have different verbosity levels
|
||||
- **Context clues**: Words like "example", "snippet", "implementation" adjust expectations
|
||||
- **Base thresholds by language**:
|
||||
- JSON/YAML/XML: 100 characters
|
||||
- HTML/CSS/SQL: 150 characters
|
||||
- Python/Go: 200 characters
|
||||
- JavaScript/TypeScript/Rust/C: 250 characters
|
||||
- Java/C++: 300 characters
|
||||
|
||||
### 2. Complete Code Block Detection
|
||||
|
||||
The service extends code blocks to natural boundaries rather than cutting off at arbitrary character limits:
|
||||
|
||||
- Looks for closing braces, parentheses, or language-specific patterns
|
||||
- Extends up to 5000 characters to find complete functions/classes
|
||||
- Uses language-specific block end patterns (e.g., unindented line for Python)
|
||||
- Recognizes common code boundaries like double newlines or next function declarations
|
||||
|
||||
### 3. HTML Span Handling
|
||||
|
||||
Sophisticated handling of syntax-highlighted code from various documentation sites:
|
||||
|
||||
- Detects when spans are used for syntax highlighting (no spaces between `</span><span>`)
|
||||
- Preserves code structure while removing HTML markup
|
||||
- Handles various highlighting libraries: Prism.js, highlight.js, Shiki, CodeMirror, Monaco
|
||||
- Special extraction for complex editors like CodeMirror that use nested divs
|
||||
|
||||
### 4. Enhanced Quality Validation
|
||||
|
||||
Multi-layer validation ensures only actual code is extracted:
|
||||
|
||||
#### Exclusion Filters
|
||||
- Diagram languages (Mermaid, PlantUML, GraphViz)
|
||||
- Prose detection (>15% prose indicators like "the", "this", "however")
|
||||
- Excessive comments (>70% comment lines)
|
||||
- Malformed code (concatenated keywords, unresolved HTML entities)
|
||||
|
||||
#### Inclusion Requirements
|
||||
- Minimum 3 code indicators from:
|
||||
- Function calls: `function()`
|
||||
- Assignments: `var = value`
|
||||
- Control flow: `if`, `for`, `while`
|
||||
- Declarations: `class`, `function`, `const`
|
||||
- Imports: `import`, `require`
|
||||
- Operators and brackets
|
||||
- Language-specific indicators (at least 2 required)
|
||||
- Reasonable structure (3+ non-empty lines, reasonable line lengths)
|
||||
|
||||
### 5. Language-Specific Patterns
|
||||
|
||||
Tailored extraction patterns for major languages:
|
||||
|
||||
```javascript
|
||||
// TypeScript/JavaScript
|
||||
{
|
||||
block_start: /^\s*(export\s+)?(class|interface|function|const|type|enum)\s+\w+/,
|
||||
block_end: /^\}(\s*;)?$/,
|
||||
min_indicators: [':', '{', '}', '=>', 'function', 'class']
|
||||
}
|
||||
|
||||
// Python
|
||||
{
|
||||
block_start: /^\s*(class|def|async\s+def)\s+\w+/,
|
||||
block_end: /^\S/, // Unindented line
|
||||
min_indicators: ['def', ':', 'return', 'self', 'import', 'class']
|
||||
}
|
||||
```
|
||||
|
||||
### 6. Context-Aware Extraction
|
||||
|
||||
The service considers surrounding context to make intelligent decisions:
|
||||
|
||||
- Adjusts minimum length based on context words ("example" → shorter, "implementation" → longer)
|
||||
- Uses context to detect language when not explicitly specified
|
||||
- Preserves 1000 characters of context before/after for better summarization
|
||||
|
||||
## Extraction Sources
|
||||
|
||||
### HTML Code Blocks
|
||||
|
||||
Supports extraction from 30+ different HTML patterns including:
|
||||
|
||||
- GitHub/GitLab highlight blocks
|
||||
- Docusaurus code blocks
|
||||
- VitePress/Astro documentation
|
||||
- Raw `<pre><code>` blocks
|
||||
- Standalone `<code>` tags (if multiline)
|
||||
|
||||
### Plain Text Files
|
||||
|
||||
Special handling for `.txt` and `.md` files:
|
||||
|
||||
- Triple backtick blocks with language specifiers
|
||||
- Language-labeled sections (e.g., "TypeScript:", "Python example:")
|
||||
- Consistently indented blocks (4+ spaces)
|
||||
|
||||
### Markdown Content
|
||||
|
||||
Falls back to markdown extraction when HTML extraction fails:
|
||||
|
||||
- Standard markdown code blocks
|
||||
- Handles corrupted markdown (e.g., entire file wrapped in backticks)
|
||||
|
||||
## Code Cleaning Pipeline
|
||||
|
||||
1. **HTML Entity Decoding**: Converts `<`, `>`, etc. to actual characters
|
||||
2. **Tag Removal**: Strips HTML tags while preserving code structure
|
||||
3. **Spacing Fixes**: Repairs concatenated keywords from span removal
|
||||
4. **Backtick Removal**: Removes wrapping backticks if present
|
||||
5. **Indentation Preservation**: Maintains original code formatting
|
||||
|
||||
## Quality Metrics
|
||||
|
||||
The service logs detailed metrics for monitoring:
|
||||
|
||||
- Number of code blocks found per document
|
||||
- Validation pass/fail reasons
|
||||
- Language detection results
|
||||
- Extraction source types (HTML vs markdown vs text)
|
||||
- Character counts before/after cleaning
|
||||
|
||||
## Best Practices for Content Creators
|
||||
|
||||
To ensure your code examples are properly extracted:
|
||||
|
||||
1. **Use standard markdown code blocks** with language specifiers
|
||||
2. **Include complete, runnable code examples** rather than fragments
|
||||
3. **Avoid mixing code with extensive inline comments**
|
||||
4. **Ensure proper HTML structure** if using custom syntax highlighting
|
||||
5. **Keep examples focused** - not too short (under 100 chars) or too long (over 5000 chars)
|
||||
|
||||
## Configuration
|
||||
|
||||
The extraction behavior can be tuned through the Settings page in the UI:
|
||||
|
||||
### Available Settings
|
||||
|
||||
#### Length Settings
|
||||
- **MIN_CODE_BLOCK_LENGTH**: Base minimum length for code blocks (default: 250 chars)
|
||||
- **MAX_CODE_BLOCK_LENGTH**: Maximum length before stopping extension (default: 5000 chars)
|
||||
- **CONTEXT_WINDOW_SIZE**: Characters of context before/after code blocks (default: 1000)
|
||||
|
||||
#### Detection Features
|
||||
- **ENABLE_COMPLETE_BLOCK_DETECTION**: Extend code blocks to natural boundaries (default: true)
|
||||
- **ENABLE_LANGUAGE_SPECIFIC_PATTERNS**: Use language-specific patterns (default: true)
|
||||
- **ENABLE_CONTEXTUAL_LENGTH**: Adjust minimum length based on context (default: true)
|
||||
|
||||
#### Content Filtering
|
||||
- **ENABLE_PROSE_FILTERING**: Filter out documentation text (default: true)
|
||||
- **MAX_PROSE_RATIO**: Maximum allowed prose percentage (default: 0.15)
|
||||
- **MIN_CODE_INDICATORS**: Minimum required code patterns (default: 3)
|
||||
- **ENABLE_DIAGRAM_FILTERING**: Filter out diagram languages (default: true)
|
||||
|
||||
#### Processing Settings
|
||||
- **CODE_EXTRACTION_MAX_WORKERS**: Parallel workers for code summaries (default: 3)
|
||||
- **ENABLE_CODE_SUMMARIES**: Generate AI summaries for code examples (default: true)
|
||||
|
||||
### How Settings Work
|
||||
|
||||
1. **Dynamic Loading**: Settings are loaded from the database on demand, not cached as environment variables
|
||||
2. **Real-time Updates**: Changes take effect on the next extraction run without server restart
|
||||
3. **Graceful Fallbacks**: If settings can't be loaded, sensible defaults are used
|
||||
4. **Type Safety**: Settings are validated and converted to appropriate types
|
||||
|
||||
### Best Practices
|
||||
|
||||
- **Start with defaults**: The default values work well for most content
|
||||
- **Adjust gradually**: Make small changes and test the results
|
||||
- **Monitor logs**: Check extraction logs to see how settings affect results
|
||||
- **Language-specific tuning**: Different content types may need different settings
|
||||
|
||||
## Future Enhancements
|
||||
|
||||
Potential improvements under consideration:
|
||||
|
||||
- Machine learning-based code detection
|
||||
- Support for notebook formats (Jupyter, Observable)
|
||||
- API response extraction from documentation
|
||||
- Multi-file code example correlation
|
||||
- Language-specific AST validation
|
||||
265
docs/docs/coding-best-practices.mdx
Normal file
@@ -0,0 +1,265 @@
|
||||
---
|
||||
title: Coding Best Practices
|
||||
description: Practical patterns and anti-patterns from real-world Archon development
|
||||
sidebar_position: 15
|
||||
---
|
||||
|
||||
# Coding Best Practices
|
||||
|
||||
Essential patterns and pitfalls to avoid when developing Archon.
|
||||
|
||||
## Async/Await Patterns
|
||||
|
||||
### ❌ DON'T: Lambda Functions Returning Unawaited Coroutines
|
||||
|
||||
```python
|
||||
# This will break - the coroutine is never awaited
|
||||
progress_callback=lambda data: update_progress(progress_id, data)
|
||||
```
|
||||
|
||||
### ✅ DO: Use asyncio.create_task for Async Callbacks
|
||||
|
||||
```python
|
||||
# Properly schedule async function execution
|
||||
progress_callback=lambda data: asyncio.create_task(update_progress(progress_id, data))
|
||||
```
|
||||
|
||||
### ❌ DON'T: Call Sync Functions from Async Context
|
||||
|
||||
```python
|
||||
# This causes "event loop already running" errors
|
||||
async def process_data():
|
||||
embeddings = create_embeddings_batch(texts) # Sync function in async context
|
||||
```
|
||||
|
||||
### ✅ DO: Use Async Versions in Async Context
|
||||
|
||||
```python
|
||||
async def process_data():
|
||||
embeddings = await create_embeddings_batch_async(texts)
|
||||
```
|
||||
|
||||
## Socket.IO Best Practices
|
||||
|
||||
### Room-Based Broadcasting
|
||||
|
||||
Always broadcast to specific rooms, not all clients:
|
||||
|
||||
```python
|
||||
# ✅ Good - targeted broadcast
|
||||
await sio.emit('crawl_progress', data, room=progress_id)
|
||||
|
||||
# ❌ Bad - broadcasts to everyone
|
||||
await sio.emit('crawl_progress', data)
|
||||
```
|
||||
|
||||
### Simple Event Handlers
|
||||
|
||||
Keep Socket.IO handlers simple and direct:
|
||||
|
||||
```python
|
||||
# ✅ Good - simple, clear purpose
|
||||
@sio.event
|
||||
async def crawl_subscribe(sid, data):
|
||||
progress_id = data.get('progress_id')
|
||||
if progress_id:
|
||||
await sio.enter_room(sid, progress_id)
|
||||
await sio.emit('crawl_subscribe_ack', {'status': 'subscribed'}, to=sid)
|
||||
```
|
||||
|
||||
## Service Layer Patterns
|
||||
|
||||
### Progress Callbacks
|
||||
|
||||
When services need progress callbacks, ensure proper async handling:
|
||||
|
||||
```python
|
||||
# ✅ Good - service accepts optional async callback
|
||||
async def process_with_progress(data, progress_callback=None):
|
||||
if progress_callback:
|
||||
await progress_callback({'status': 'processing', 'percentage': 50})
|
||||
```
|
||||
|
||||
### Error Handling in Services
|
||||
|
||||
Always provide fallbacks for external service failures:
|
||||
|
||||
```python
|
||||
# ✅ Good - graceful degradation
|
||||
try:
|
||||
embeddings = await create_embeddings_batch_async(texts)
|
||||
except Exception as e:
|
||||
logger.warning(f"Embedding creation failed: {e}")
|
||||
# Return zero embeddings as fallback
|
||||
return [[0.0] * 1536 for _ in texts]
|
||||
```
|
||||
|
||||
## Common Pitfalls
|
||||
|
||||
### Event Loop Issues
|
||||
|
||||
**Problem**: "This event loop is already running"
|
||||
|
||||
**Solution**: Check if you're in an async context before using sync functions:
|
||||
|
||||
```python
|
||||
try:
|
||||
loop = asyncio.get_running_loop()
|
||||
# Already in async context - use async version
|
||||
result = await async_function()
|
||||
except RuntimeError:
|
||||
# No event loop - safe to use sync version
|
||||
result = sync_function()
|
||||
```
|
||||
|
||||
### Socket.IO Progress Updates
|
||||
|
||||
**Problem**: Progress updates not reaching the UI
|
||||
|
||||
**Solution**: Ensure the client is in the correct room and progressId is included:
|
||||
|
||||
```python
|
||||
# Always include progressId in the data
|
||||
data['progressId'] = progress_id
|
||||
await sio.emit('crawl_progress', data, room=progress_id)
|
||||
```
|
||||
|
||||
### Embedding Service Optimization
|
||||
|
||||
**Problem**: Synchronous embedding calls blocking async operations
|
||||
|
||||
**Solution**: Always use async versions and batch operations:
|
||||
|
||||
```python
|
||||
# Process in batches with rate limiting
|
||||
async def create_embeddings_for_documents(documents):
|
||||
batch_size = 20 # OpenAI limit
|
||||
for i in range(0, len(documents), batch_size):
|
||||
batch = documents[i:i + batch_size]
|
||||
embeddings = await create_embeddings_batch_async(batch)
|
||||
await asyncio.sleep(0.5) # Rate limiting
|
||||
```
|
||||
|
||||
## Testing Async Code
|
||||
|
||||
### Mock Async Functions Properly
|
||||
|
||||
```python
|
||||
# ✅ Good - proper async mock
|
||||
mock_update = AsyncMock()
|
||||
with patch('module.update_progress', mock_update):
|
||||
await function_under_test()
|
||||
mock_update.assert_called_once()
|
||||
```
|
||||
|
||||
### Test Socket.IO Events
|
||||
|
||||
```python
|
||||
# ✅ Good - test room management
|
||||
@patch('src.server.socketio_app.sio')
|
||||
async def test_subscribe_joins_room(mock_sio):
|
||||
await crawl_subscribe('sid-123', {'progress_id': 'progress-456'})
|
||||
mock_sio.enter_room.assert_called_with('sid-123', 'progress-456')
|
||||
```
|
||||
|
||||
## React/Frontend Best Practices
|
||||
|
||||
### Performance Anti-Patterns to Avoid
|
||||
|
||||
#### ❌ DON'T: Update State on Every Keystroke Without Debouncing
|
||||
```typescript
|
||||
// This causes excessive re-renders
|
||||
<input
|
||||
value={formData.title}
|
||||
onChange={(e) => setFormData({ ...formData, title: e.target.value })}
|
||||
/>
|
||||
```
|
||||
|
||||
#### ✅ DO: Use Debounced Inputs or Local State
|
||||
```typescript
|
||||
// Use a debounced input component
|
||||
<DebouncedInput
|
||||
value={formData.title}
|
||||
onChange={handleTitleChange}
|
||||
delay={300}
|
||||
/>
|
||||
```
|
||||
|
||||
#### ❌ DON'T: Create New Functions in Render
|
||||
```typescript
|
||||
// Creates new function every render
|
||||
<button onClick={() => handleAction(item.id)}>Click</button>
|
||||
```
|
||||
|
||||
#### ✅ DO: Use useCallback for Stable References
|
||||
```typescript
|
||||
const handleClick = useCallback((id) => {
|
||||
handleAction(id);
|
||||
}, []);
|
||||
|
||||
<button onClick={() => handleClick(item.id)}>Click</button>
|
||||
```
|
||||
|
||||
### Socket.IO Client-Side Patterns
|
||||
|
||||
#### Room Subscription Pattern
|
||||
```typescript
|
||||
useEffect(() => {
|
||||
const ws = createWebSocketService();
|
||||
|
||||
const connect = async () => {
|
||||
await ws.connect('/'); // Always default namespace
|
||||
|
||||
// Join room
|
||||
ws.send({
|
||||
type: 'join_project',
|
||||
data: { project_id: projectId }
|
||||
});
|
||||
|
||||
// Handle messages
|
||||
ws.addMessageHandler('task_updated', handleTaskUpdate);
|
||||
};
|
||||
|
||||
connect();
|
||||
return () => ws.disconnect();
|
||||
}, [projectId]);
|
||||
```
|
||||
|
||||
### State Management Patterns
|
||||
|
||||
#### Batch Updates
|
||||
```typescript
|
||||
// ✅ Good - Single render
|
||||
setState(prev => ({
|
||||
...prev,
|
||||
field1: value1,
|
||||
field2: value2,
|
||||
field3: value3
|
||||
}));
|
||||
|
||||
// ❌ Bad - Three renders
|
||||
setField1(value1);
|
||||
setField2(value2);
|
||||
setField3(value3);
|
||||
```
|
||||
|
||||
#### Local State for Transient Values
|
||||
```typescript
|
||||
// Keep form inputs local until save
|
||||
const [localTitle, setLocalTitle] = useState(title);
|
||||
|
||||
const handleSave = () => {
|
||||
onSave({ title: localTitle });
|
||||
};
|
||||
```
|
||||
|
||||
## Key Takeaways
|
||||
|
||||
1. **Always await async functions** - Never let coroutines go unawaited
|
||||
2. **Use rooms for Socket.IO** - Target specific audiences, not everyone
|
||||
3. **Handle async boundaries** - Know when you're in an async context
|
||||
4. **Fail gracefully** - Always have fallbacks for external services
|
||||
5. **Test async code properly** - Use AsyncMock and proper async test patterns
|
||||
6. **Optimize React renders** - Use memo, useCallback, and debouncing
|
||||
7. **Batch state updates** - Minimize renders with single setState calls
|
||||
8. **Use local state** - Keep transient values local to components
|
||||
339
docs/docs/configuration.mdx
Normal file
@@ -0,0 +1,339 @@
|
||||
---
|
||||
title: Configuration
|
||||
description: Essential configuration for Archon
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Configuration
|
||||
|
||||
## Docker Microservices Architecture
|
||||
|
||||
<Admonition type="info" title="Container Communication">
|
||||
Archon uses a microservices architecture with three separate services. All services run in Docker containers and communicate via the `app-network` bridge network using service names, not localhost. Real-time features use Socket.IO for reliable real-time communication.
|
||||
</Admonition>
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
subgraph "Docker Network: app-network"
|
||||
subgraph "Archon-Server"
|
||||
API[FastAPI<br/>:8080]
|
||||
SIO[Socket.IO<br/>:8080]
|
||||
end
|
||||
|
||||
subgraph "archon-mcp"
|
||||
MCP[MCP Server<br/>:8051]
|
||||
end
|
||||
|
||||
subgraph "archon-agents"
|
||||
Agents[AI Agents<br/>:8052]
|
||||
end
|
||||
|
||||
subgraph "frontend"
|
||||
Vite[Vite Dev Server<br/>:5173]
|
||||
end
|
||||
|
||||
subgraph "docs"
|
||||
Docusaurus[Docusaurus<br/>:80]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph "Host Machine"
|
||||
Browser[Browser]
|
||||
IDE[VS Code/Cursor/Windsurf]
|
||||
end
|
||||
|
||||
subgraph "External Services"
|
||||
Supabase[(Supabase)]
|
||||
OpenAI[OpenAI API]
|
||||
end
|
||||
|
||||
Browser -->|3737| Vite
|
||||
Browser -->|3838| Docusaurus
|
||||
IDE -->|8051| MCP
|
||||
|
||||
Vite -->|proxy| API
|
||||
Vite -.->|Socket.IO| SIO
|
||||
API --> Supabase
|
||||
API --> OpenAI
|
||||
API --> Agents
|
||||
MCP --> Supabase
|
||||
MCP --> API
|
||||
Agents --> Supabase
|
||||
Agents --> OpenAI
|
||||
|
||||
style API fill:#1a1a2e,stroke:#00d4ff,stroke-width:2px,color:#fff
|
||||
style SIO fill:#1a1a2e,stroke:#4ecdc4,stroke-width:2px,color:#fff
|
||||
style MCP fill:#1a1a2e,stroke:#00d4ff,stroke-width:2px,color:#fff
|
||||
style Agents fill:#1a1a2e,stroke:#ff6b6b,stroke-width:2px,color:#fff
|
||||
style Vite fill:#1a1a2e,stroke:#00d4ff,stroke-width:2px,color:#fff
|
||||
```
|
||||
|
||||
### Port Mappings
|
||||
|
||||
| Service | Container Name | Container Port | Host Port | Purpose |
|
||||
|---------|----------------|----------------|-----------|---------|
|
||||
| Frontend | archon-frontend | 5173 | 3737 | React UI |
|
||||
| Server | Archon-Server | 8080 | 8080 | FastAPI + Socket.IO |
|
||||
| MCP Server | archon-mcp | 8051 | 8051 | AI Agent connections |
|
||||
| AI Agents | archon-agents | 8052 | 8052 | AI processing service |
|
||||
| Documentation | archon-docs | 80 | 3838 | This documentation |
|
||||
|
||||
## Essential Configuration
|
||||
|
||||
### 1. Environment Variables
|
||||
|
||||
Create a `.env` file in the root directory:
|
||||
|
||||
```bash
|
||||
# Required - Get from supabase.com dashboard
|
||||
SUPABASE_URL=https://your-project.supabase.co
|
||||
SUPABASE_SERVICE_KEY=eyJ0eXAi...
|
||||
|
||||
# Optional - Set via UI Settings page
|
||||
# OPENAI_API_KEY=sk-...
|
||||
|
||||
# Unified Logging Configuration (Optional)
|
||||
LOGFIRE_ENABLED=false # true=Logfire logging, false=standard logging
|
||||
# LOGFIRE_TOKEN=pylf_... # Only required when LOGFIRE_ENABLED=true
|
||||
|
||||
# Service Discovery (automatically set for Docker)
|
||||
# SERVICE_DISCOVERY_MODE=docker_compose
|
||||
```
|
||||
|
||||
<Admonition type="tip" title="Configuration Options">
|
||||
- **API Keys**: Set through the Settings page UI instead of environment variables
|
||||
- **Logging**: Use `LOGFIRE_ENABLED=true/false` to toggle between standard and enhanced logging
|
||||
- **Zero Setup**: Standard logging works perfectly without any additional configuration
|
||||
</Admonition>
|
||||
|
||||
### Unified Logging Architecture
|
||||
|
||||
Archon includes a unified logging system that works seamlessly with or without Logfire:
|
||||
|
||||
```bash
|
||||
# Standard Logging (Default - Zero Setup)
|
||||
LOGFIRE_ENABLED=false
|
||||
|
||||
# Enhanced Logging with Logfire
|
||||
LOGFIRE_ENABLED=true
|
||||
LOGFIRE_TOKEN=your_token
|
||||
```
|
||||
|
||||
**Key Benefits:**
|
||||
- 🔄 **Single Toggle**: One environment variable controls everything
|
||||
- 🛡️ **Always Works**: Graceful fallback to standard Python logging
|
||||
- 📊 **Consistent**: Same log format and structure in both modes
|
||||
- 🚀 **Zero Dependencies**: Standard logging requires no external services
|
||||
|
||||
### LLM Provider Configuration
|
||||
|
||||
Archon supports multiple LLM providers through the Settings UI:
|
||||
|
||||
- **OpenAI** (default) - Uses your existing OpenAI API key
|
||||
- **Google Gemini** - Google's latest models
|
||||
- **Ollama** - Run models locally (free)
|
||||
|
||||
Configure in **Settings → RAG Settings → LLM Provider**
|
||||
|
||||
<Admonition type="tip" title="Provider Setup">
|
||||
- **API Keys**: Add provider-specific keys in Settings → API Keys
|
||||
- **Ollama**: Requires local installation and custom base URL
|
||||
- **Models**: Each provider has different model naming conventions
|
||||
</Admonition>
|
||||
|
||||
### Socket.IO Configuration
|
||||
|
||||
Archon uses Socket.IO for all real-time features. The default configuration works out of the box:
|
||||
|
||||
```python
|
||||
# Backend Socket.IO settings (socketio_app.py)
|
||||
sio = socketio.AsyncServer(
|
||||
async_mode='asgi',
|
||||
cors_allowed_origins="*", # Allow all origins for development
|
||||
ping_timeout=60,
|
||||
ping_interval=25
|
||||
)
|
||||
```
|
||||
|
||||
**Key Features:**
|
||||
- **Automatic reconnection** with exponential backoff
|
||||
- **Namespace-based** organization for different features
|
||||
- **Room-based** broadcasting for targeted updates
|
||||
- **Built-in** heartbeat and connection monitoring
|
||||
|
||||
### 2. Database Setup
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="new" label="New Installation">
|
||||
|
||||
1. Create a Supabase project at [supabase.com](https://supabase.com)
|
||||
2. Copy credentials from Settings → API
|
||||
3. Tables are auto-created on first run
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="reset" label="Reset Database">
|
||||
|
||||
Run this SQL in Supabase to completely reset:
|
||||
|
||||
```sql
|
||||
-- Run migration/RESET_DB.sql
|
||||
-- This removes ALL data and tables
|
||||
```
|
||||
|
||||
Then restart the backend to recreate tables.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### 3. Starting the Application
|
||||
|
||||
```bash
|
||||
# Start all services
|
||||
docker compose up -d
|
||||
|
||||
# Check status
|
||||
docker compose ps
|
||||
|
||||
# View logs
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
## Docker Networking
|
||||
|
||||
<Admonition type="warning" title="Important">
|
||||
Inside Docker containers, services communicate using container names, not `localhost`:
|
||||
- Frontend → Server: `http://Archon-Server:8080`
|
||||
- API → MCP: `http://archon-mcp:8051`
|
||||
- API → Agents: `http://archon-agents:8052`
|
||||
- Never use `localhost` in container-to-container communication
|
||||
</Admonition>
|
||||
|
||||
### Common Issues
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="connection" label="Connection Refused">
|
||||
|
||||
**Problem**: Frontend can't connect to backend
|
||||
|
||||
**Solution**: Check `vite.config.ts` uses correct service name:
|
||||
```typescript
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://Archon-Server:8080',
|
||||
ws: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="socketio" label="Socket.IO Configuration">
|
||||
|
||||
**Problem**: Socket.IO connection issues
|
||||
|
||||
**Solution**: Ensure proper proxy configuration in `vite.config.ts`:
|
||||
```typescript
|
||||
proxy: {
|
||||
'/api': {
|
||||
target: 'http://Archon-Server:8080',
|
||||
changeOrigin: true,
|
||||
ws: true
|
||||
},
|
||||
'/socket.io': {
|
||||
target: 'http://Archon-Server:8080',
|
||||
changeOrigin: true,
|
||||
ws: true
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
Socket.IO namespaces:
|
||||
- Chat: `/chat`
|
||||
- Crawl Progress: `/crawl`
|
||||
- Task Updates: `/tasks`
|
||||
- Project Creation: `/project`
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Quick Reference
|
||||
|
||||
### Health Checks
|
||||
|
||||
```bash
|
||||
# API Service
|
||||
curl http://localhost:8080/health
|
||||
|
||||
# MCP Server (checks socket connectivity)
|
||||
curl http://localhost:8051/sse
|
||||
|
||||
# AI Agents Service
|
||||
curl http://localhost:8052/health
|
||||
|
||||
# Frontend
|
||||
curl http://localhost:3737
|
||||
```
|
||||
|
||||
#### Frontend Health Check Configuration
|
||||
|
||||
The frontend performs automatic health checks to detect server disconnections. Configuration:
|
||||
|
||||
- **Check Interval**: 30 seconds (defined in `HEALTH_CHECK_INTERVAL_MS` constant)
|
||||
- **Timeout**: 10 seconds per health check request
|
||||
- **Disconnect Threshold**: 2 missed checks (60 seconds total)
|
||||
- **Location**: `archon-ui-main/src/services/serverHealthService.ts`
|
||||
|
||||
To adjust the health check interval, modify the constant at the top of the file:
|
||||
```typescript
|
||||
const HEALTH_CHECK_INTERVAL_MS = 30000; // 30 seconds (default)
|
||||
```
|
||||
|
||||
### Container Management
|
||||
|
||||
```bash
|
||||
# Restart a specific service
|
||||
docker compose restart archon-server
|
||||
|
||||
# Rebuild after code changes
|
||||
docker compose build archon-server
|
||||
docker compose up -d archon-server
|
||||
|
||||
# View real-time logs for a service
|
||||
docker compose logs -f archon-server
|
||||
|
||||
# View all service logs
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
### Service Discovery
|
||||
|
||||
Archon includes automatic service discovery that works across environments:
|
||||
|
||||
```python
|
||||
from src.config.service_discovery import discovery
|
||||
|
||||
# Automatically detects environment
|
||||
api_url = discovery.get_service_url("api")
|
||||
# Docker: http://Archon-Server:8080
|
||||
# Local: http://localhost:8080
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
Once configured and running:
|
||||
|
||||
- **Web Interface**: Access at `http://localhost:3737`
|
||||
- **API Documentation**: Available at `http://localhost:8080/docs`
|
||||
- **MCP Connection**: Use `http://localhost:8051/sse` in your IDE
|
||||
- **AI Agents API**: Available at `http://localhost:8052/docs`
|
||||
|
||||
<Admonition type="tip" title="Configuration Tips">
|
||||
- All settings are stored in the Supabase database
|
||||
- API keys can be configured through the web interface
|
||||
- Knowledge base content can be managed through the web interface
|
||||
- MCP clients connect automatically once configured
|
||||
- Each service can be scaled independently for better performance
|
||||
</Admonition>
|
||||
219
docs/docs/crawling-configuration.mdx
Normal file
@@ -0,0 +1,219 @@
|
||||
---
|
||||
title: Crawling Configuration Guide
|
||||
sidebar_position: 12
|
||||
---
|
||||
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Crawling Configuration Guide
|
||||
|
||||
This guide explains how to configure and optimize the Archon crawling system powered by Crawl4AI.
|
||||
|
||||
## Overview
|
||||
|
||||
Archon uses [Crawl4AI](https://github.com/unclecode/crawl4ai) for web crawling, which provides powerful features for extracting content from various types of websites. The system automatically detects content types and applies appropriate crawling strategies.
|
||||
|
||||
## Basic Configuration
|
||||
|
||||
### Default Settings
|
||||
|
||||
The crawling service uses simple, reliable defaults:
|
||||
|
||||
```python
|
||||
CrawlerRunConfig(
|
||||
cache_mode=CacheMode.BYPASS, # Fresh content
|
||||
stream=False, # Complete pages
|
||||
markdown_generator=DefaultMarkdownGenerator()
|
||||
)
|
||||
```
|
||||
|
||||
<Admonition type="info" title="Simplicity First">
|
||||
The default configuration works well for most sites. Only add complexity when needed.
|
||||
</Admonition>
|
||||
|
||||
## Content Type Detection
|
||||
|
||||
The system automatically detects and handles three main content types:
|
||||
|
||||
### 1. Text Files (.txt)
|
||||
- Direct content extraction
|
||||
- No HTML parsing needed
|
||||
- Fast and efficient
|
||||
|
||||
### 2. Sitemaps (sitemap.xml)
|
||||
- Parses XML structure
|
||||
- Extracts all URLs
|
||||
- Batch crawls pages in parallel
|
||||
|
||||
### 3. Web Pages (HTML)
|
||||
- Recursive crawling to specified depth
|
||||
- Follows internal links
|
||||
- Extracts structured content
|
||||
|
||||
## Code Extraction Configuration
|
||||
|
||||
### Minimum Length Setting
|
||||
|
||||
Code blocks must meet a minimum length to be extracted:
|
||||
|
||||
```bash
|
||||
# Environment variable (optional)
|
||||
CODE_BLOCK_MIN_LENGTH=1000 # Default: 1000 characters
|
||||
```
|
||||
|
||||
This prevents extraction of small snippets and ensures only substantial code examples are indexed.
|
||||
|
||||
### Supported Code Formats
|
||||
|
||||
1. **Markdown Code Blocks**
|
||||
````markdown
|
||||
```language
|
||||
// Code here (must be ≥ 1000 chars)
|
||||
```
|
||||
````
|
||||
|
||||
2. **HTML Code Elements**
|
||||
```html
|
||||
<pre><code class="language-javascript">
|
||||
// Code here
|
||||
</code></pre>
|
||||
```
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
### When to Use Advanced Features
|
||||
|
||||
<Admonition type="warning" title="Use Sparingly">
|
||||
Advanced features like `wait_for` and `js_code` can cause timeouts and should only be used when absolutely necessary.
|
||||
</Admonition>
|
||||
|
||||
### JavaScript Execution
|
||||
|
||||
For sites that require JavaScript interaction:
|
||||
|
||||
```python
|
||||
# Only if content doesn't load otherwise
|
||||
js_code = [
|
||||
"window.scrollTo(0, document.body.scrollHeight);",
|
||||
"document.querySelector('.load-more')?.click();"
|
||||
]
|
||||
```
|
||||
|
||||
### Wait Conditions
|
||||
|
||||
For dynamic content loading:
|
||||
|
||||
```python
|
||||
# CSS selector format
|
||||
wait_for = "css:.content-loaded"
|
||||
|
||||
# JavaScript condition
|
||||
wait_for = "js:() => document.querySelectorAll('.item').length > 10"
|
||||
```
|
||||
|
||||
## Performance Optimization
|
||||
|
||||
### Batch Crawling
|
||||
|
||||
For multiple URLs, use batch processing:
|
||||
|
||||
```python
|
||||
dispatcher = MemoryAdaptiveDispatcher(
|
||||
memory_threshold_percent=70.0,
|
||||
check_interval=1.0,
|
||||
max_session_permit=10 # Concurrent sessions
|
||||
)
|
||||
```
|
||||
|
||||
### Caching Strategy
|
||||
|
||||
- **CacheMode.ENABLED**: Use for development/testing
|
||||
- **CacheMode.BYPASS**: Use for production (fresh content)
|
||||
|
||||
## Troubleshooting Common Issues
|
||||
|
||||
### JavaScript-Heavy Sites
|
||||
|
||||
**Problem**: Content not loading on React/Vue/Angular sites
|
||||
|
||||
**Solution**: The default configuration should work. If not:
|
||||
1. Check if content is server-side rendered
|
||||
2. Verify the page loads without JavaScript in a browser
|
||||
3. Consider if the content is behind authentication
|
||||
|
||||
### Timeouts
|
||||
|
||||
**Problem**: Crawling times out on certain pages
|
||||
|
||||
**Solution**:
|
||||
1. Remove `wait_for` conditions
|
||||
2. Simplify or remove `js_code`
|
||||
3. Reduce `page_timeout` for faster failures
|
||||
|
||||
### Code Not Extracted
|
||||
|
||||
**Problem**: Code blocks aren't being found
|
||||
|
||||
**Solution**:
|
||||
1. Check code block length (≥ 1000 chars)
|
||||
2. Verify markdown formatting (triple backticks)
|
||||
3. Check logs for `backtick_count`
|
||||
4. Ensure markdown generator is using correct settings
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Start Simple**: Use default configuration first
|
||||
2. **Monitor Logs**: Check for extraction counts and errors
|
||||
3. **Test Incrementally**: Crawl single pages before batch/recursive
|
||||
4. **Respect Rate Limits**: Don't overwhelm target servers
|
||||
5. **Cache Wisely**: Use caching during development
|
||||
|
||||
## Configuration Examples
|
||||
|
||||
### Documentation Site
|
||||
|
||||
```python
|
||||
# Handles most documentation sites well
|
||||
config = CrawlerRunConfig(
|
||||
cache_mode=CacheMode.BYPASS,
|
||||
stream=False,
|
||||
markdown_generator=DefaultMarkdownGenerator()
|
||||
)
|
||||
```
|
||||
|
||||
### Blog with Code Examples
|
||||
|
||||
```python
|
||||
# Ensures code extraction works properly
|
||||
config = CrawlerRunConfig(
|
||||
cache_mode=CacheMode.BYPASS,
|
||||
stream=False,
|
||||
markdown_generator=DefaultMarkdownGenerator(
|
||||
content_source="cleaned_html",
|
||||
options={
|
||||
"mark_code": True,
|
||||
"handle_code_in_pre": True,
|
||||
"body_width": 0
|
||||
}
|
||||
)
|
||||
)
|
||||
```
|
||||
|
||||
### Dynamic SPA (Use Cautiously)
|
||||
|
||||
```python
|
||||
# Only if content doesn't load otherwise
|
||||
config = CrawlerRunConfig(
|
||||
cache_mode=CacheMode.BYPASS,
|
||||
stream=False,
|
||||
wait_for="css:.main-content",
|
||||
js_code=["window.scrollTo(0, 1000);"],
|
||||
page_timeout=30000
|
||||
)
|
||||
```
|
||||
|
||||
## Related Documentation
|
||||
|
||||
- [Knowledge Features](./knowledge-features) - Overview of knowledge management
|
||||
- [Server Services](./server-services) - Technical service details
|
||||
- [API Reference](./api-reference#knowledge-management-api) - API endpoints
|
||||
285
docs/docs/deployment.mdx
Normal file
@@ -0,0 +1,285 @@
|
||||
---
|
||||
title: Deployment
|
||||
description: Quick start guide for running Archon
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Deployment
|
||||
|
||||
## Quick Start
|
||||
|
||||
<Admonition type="tip" title="Prerequisites">
|
||||
- Docker and Docker Compose installed
|
||||
- Supabase account (free tier works)
|
||||
- Git for cloning the repository
|
||||
</Admonition>
|
||||
|
||||
### 1. Clone & Setup
|
||||
|
||||
```bash
|
||||
# Clone repository
|
||||
git clone <repository-url>
|
||||
cd archon
|
||||
|
||||
# Create environment file
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
### 2. Configure
|
||||
|
||||
Edit `.env` with your credentials:
|
||||
|
||||
```bash
|
||||
SUPABASE_URL=https://your-project.supabase.co
|
||||
SUPABASE_SERVICE_KEY=eyJ0eXAi...
|
||||
```
|
||||
|
||||
### 3. Launch
|
||||
|
||||
```bash
|
||||
# Start all services
|
||||
docker-compose up -d
|
||||
|
||||
# Check status
|
||||
docker-compose ps
|
||||
```
|
||||
|
||||
### 4. Access
|
||||
|
||||
- **UI**: http://localhost:3737
|
||||
- **API Docs**: http://localhost:8080/docs
|
||||
- **Documentation**: http://localhost:3838
|
||||
|
||||
## Hot Module Reload (HMR)
|
||||
|
||||
<Admonition type="tip" title="Built-in Hot Reload">
|
||||
Archon automatically includes Hot Module Reload for both Python server and React UI. Code changes are reflected immediately without container rebuilds.
|
||||
</Admonition>
|
||||
|
||||
### What Changes Without Rebuild
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="python" label="Python Server">
|
||||
|
||||
**✅ No Rebuild Required:**
|
||||
- Python source code changes (`.py` files)
|
||||
- Configuration changes in code
|
||||
- Business logic updates
|
||||
- API endpoint modifications
|
||||
- Socket.IO event handlers
|
||||
- Service layer changes
|
||||
|
||||
**❌ Rebuild Required:**
|
||||
- New pip dependencies in `requirements.*.txt`
|
||||
- System package installations
|
||||
- Dockerfile modifications
|
||||
- Environment variable changes in docker-compose
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="frontend" label="React UI">
|
||||
|
||||
**✅ No Rebuild Required:**
|
||||
- React components (`.tsx`, `.jsx`)
|
||||
- CSS/Tailwind styles
|
||||
- TypeScript code
|
||||
- Static assets in `public/`
|
||||
- Vite configuration (most changes)
|
||||
|
||||
**❌ Rebuild Required:**
|
||||
- New npm dependencies in `package.json`
|
||||
- Node version changes
|
||||
- Build tool configurations
|
||||
- Environment variable changes
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### How HMR Works
|
||||
|
||||
**Python Server:**
|
||||
- Uses `uvicorn --reload`
|
||||
- Watches file changes automatically
|
||||
- Restarts on save
|
||||
- WebSocket connections re-establish after reload
|
||||
|
||||
**React UI:**
|
||||
- Vite's built-in HMR
|
||||
- Component state preserved when possible
|
||||
- CSS updates without page reload
|
||||
- Fast refresh for React components
|
||||
|
||||
### Tips
|
||||
|
||||
1. **Monitor Logs**: Watch for reload messages
|
||||
```bash
|
||||
docker logs -f Archon-Server
|
||||
```
|
||||
|
||||
2. **Handle Disconnects**: The UI shows a disconnect screen during server reload
|
||||
|
||||
3. **State Persistence**: Server state resets on reload, but database state persists
|
||||
|
||||
<Admonition type="warning" title="MCP Service Note">
|
||||
The MCP service doesn't support hot reload. Restart manually after changes:
|
||||
```bash
|
||||
docker-compose restart archon-mcp
|
||||
```
|
||||
</Admonition>
|
||||
|
||||
## Service Architecture
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
subgraph "Your Computer"
|
||||
Browser[Web Browser<br/>localhost:3737]
|
||||
IDE[VS Code/Cursor<br/>localhost:8051]
|
||||
end
|
||||
|
||||
subgraph "Docker Containers"
|
||||
Frontend[archon-frontend<br/>React UI]
|
||||
API[Archon-Server<br/>FastAPI + Socket.IO]
|
||||
MCP[archon-mcp<br/>MCP Server]
|
||||
Agents[archon-agents<br/>AI Processing]
|
||||
Docs[archon-docs<br/>Documentation]
|
||||
end
|
||||
|
||||
subgraph "Cloud Services"
|
||||
Supabase[Supabase<br/>Database]
|
||||
OpenAI[OpenAI<br/>AI Models]
|
||||
end
|
||||
|
||||
Browser --> Frontend
|
||||
IDE --> MCP
|
||||
Frontend --> API
|
||||
API --> MCP
|
||||
API --> Agents
|
||||
API --> Supabase
|
||||
Agents --> OpenAI
|
||||
MCP --> Supabase
|
||||
|
||||
style Frontend fill:#1a1a2e,stroke:#00d4ff,stroke-width:2px,color:#fff
|
||||
style API fill:#1a1a2e,stroke:#00d4ff,stroke-width:2px,color:#fff
|
||||
style MCP fill:#1a1a2e,stroke:#00d4ff,stroke-width:2px,color:#fff
|
||||
style Agents fill:#1a1a2e,stroke:#ff6b6b,stroke-width:2px,color:#fff
|
||||
style Supabase fill:#16213e,stroke:#00ff88,stroke-width:2px,color:#fff
|
||||
```
|
||||
|
||||
## Common Commands
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="basic" label="Basic Operations">
|
||||
|
||||
```bash
|
||||
# Start services
|
||||
docker-compose up -d
|
||||
|
||||
# Stop services
|
||||
docker-compose down
|
||||
|
||||
# View logs
|
||||
docker-compose logs -f
|
||||
|
||||
# Restart a service
|
||||
docker-compose restart archon-frontend
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="troubleshooting" label="Troubleshooting">
|
||||
|
||||
```bash
|
||||
# Check container status
|
||||
docker ps
|
||||
|
||||
# View service logs
|
||||
docker logs archon-server
|
||||
docker logs archon-mcp
|
||||
docker logs archon-agents
|
||||
|
||||
# Rebuild after changes
|
||||
docker-compose build
|
||||
docker-compose up -d
|
||||
|
||||
# Complete reset
|
||||
docker-compose down -v
|
||||
docker-compose up -d --build
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Advanced Configuration
|
||||
|
||||
<Admonition type="info" title="Scaling Archon">
|
||||
For team deployments, consider:
|
||||
- Using a reverse proxy (nginx/Caddy) for multiple users
|
||||
- Setting up SSL certificates for secure connections
|
||||
- Configuring resource limits based on usage
|
||||
- Using managed Supabase instances
|
||||
</Admonition>
|
||||
|
||||
## Database Management
|
||||
|
||||
### Reset Database
|
||||
|
||||
<Admonition type="warning" title="Data Loss Warning">
|
||||
This will delete ALL data in your database!
|
||||
</Admonition>
|
||||
|
||||
```sql
|
||||
-- Run in Supabase SQL editor
|
||||
-- migration/RESET_DB.sql
|
||||
```
|
||||
|
||||
### Backup Data
|
||||
|
||||
```bash
|
||||
# Export data before reset
|
||||
pg_dump -h your-db-host -U postgres -d postgres > backup.sql
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
### Health Checks
|
||||
|
||||
```bash
|
||||
# API Health
|
||||
curl http://localhost:8080/health
|
||||
|
||||
# Check all services
|
||||
echo "Frontend: http://localhost:3737"
|
||||
curl -s http://localhost:3737 > /dev/null && echo "✓ Running" || echo "✗ Not running"
|
||||
|
||||
echo "API: http://localhost:8080/health"
|
||||
curl -s http://localhost:8080/health | jq '.status' || echo "✗ Not running"
|
||||
|
||||
echo "MCP: http://localhost:8051/sse"
|
||||
curl -s http://localhost:8051/sse > /dev/null && echo "✓ Running" || echo "✗ Not running"
|
||||
|
||||
echo "Agents: http://localhost:8052/health"
|
||||
curl -s http://localhost:8052/health | jq '.status' || echo "✗ Not running"
|
||||
```
|
||||
|
||||
### Container Resources
|
||||
|
||||
```bash
|
||||
# View resource usage
|
||||
docker stats
|
||||
|
||||
# Check disk usage
|
||||
docker system df
|
||||
```
|
||||
|
||||
## Next Steps
|
||||
|
||||
<Admonition type="success" title="Ready to Go!">
|
||||
Your Archon instance is now running. Next:
|
||||
|
||||
1. **Set up API keys** in Settings
|
||||
2. **Configure MCP** for AI agents
|
||||
3. **Start crawling** knowledge sources
|
||||
4. **Create projects** and tasks
|
||||
</Admonition>
|
||||
410
docs/docs/getting-started.mdx
Normal file
@@ -0,0 +1,410 @@
|
||||
---
|
||||
title: 🚀 Getting Started
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
|
||||
# 🚀 Getting Started with Archon
|
||||
|
||||
<div className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**Build Your AI's Knowledge Base** - From zero to operational in under 10 minutes
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<p align="center">
|
||||
<a href="#-quick-start">Quick Start</a> •
|
||||
<a href="#-whats-included">What's Included</a> •
|
||||
<a href="#-next-steps">Next Steps</a> •
|
||||
<a href="#-documentation-guide">Documentation Guide</a>
|
||||
</p>
|
||||
|
||||
---
|
||||
<Admonition type="tip" icon="🎯" title="What You'll Build">
|
||||
By the end of this guide, you'll have a **fully operational Archon system** with:
|
||||
- ✅ **14 MCP tools** enabled and working
|
||||
- 🧠 **RAG system** for intelligent knowledge retrieval
|
||||
- 🌐 **Archon UI** Command Center for knowledge, projects, and tasks
|
||||
- 🔥 **Real-time Logfire monitoring** and debugging
|
||||
- 🌐 **Modern UI** for project and task management
|
||||
</Admonition>
|
||||
---
|
||||
## 🎯 What is Archon?
|
||||
|
||||
Archon is a **Model Context Protocol (MCP) server** that creates a centralized knowledge base for your AI coding assistants. Connect Cursor, Windsurf, or Claude Desktop to give your AI agents access to:
|
||||
|
||||
- **Your documentation** (crawled websites, uploaded PDFs/docs)
|
||||
- **Smart search capabilities** with advanced RAG strategies
|
||||
- **Task management** integrated with your knowledge base
|
||||
- **Real-time updates** as you add new content
|
||||
|
||||
## ⚡ Quick Start
|
||||
|
||||
### Prerequisites
|
||||
- [Docker Desktop](https://www.docker.com/products/docker-desktop/) installed and running
|
||||
- [Supabase](https://supabase.com/) account (free tier works)
|
||||
- [OpenAI API key](https://platform.openai.com/api-keys) for embeddings
|
||||
|
||||
### 1. Clone & Setup
|
||||
|
||||
```bash
|
||||
git clone https://github.com/coleam00/archon.git
|
||||
cd archon
|
||||
|
||||
# Create environment file
|
||||
cp .env.example .env
|
||||
```
|
||||
|
||||
### 2. Configure Environment
|
||||
|
||||
Edit `.env` and add your credentials:
|
||||
|
||||
```bash
|
||||
# Required
|
||||
SUPABASE_URL=https://your-project.supabase.co
|
||||
SUPABASE_SERVICE_KEY=your-service-key-here
|
||||
|
||||
# Optional (but recommended for monitoring)
|
||||
OPENAI_API_KEY=sk-proj-your-openai-key
|
||||
# Unified Logging Configuration (Optional)
|
||||
LOGFIRE_ENABLED=false # true=Logfire logging, false=standard logging
|
||||
LOGFIRE_TOKEN=your-logfire-token-here # Only required when LOGFIRE_ENABLED=true
|
||||
```
|
||||
|
||||
### 3. Set Up Database
|
||||
|
||||
<Admonition type="info" icon="🗄️" title="Database Setup">
|
||||
Create a new [Supabase project](https://supabase.com/dashboard), then follow these setup steps in order:
|
||||
</Admonition>
|
||||
|
||||
#### Step 1: Initial Setup - Enable RAG Crawl and Document Upload
|
||||
**Run `migration/1_initial_setup.sql`** - Creates vector database, settings, and core tables
|
||||
|
||||
#### Step 2: Install Projects Module
|
||||
**Run `migration/2_archon_projects.sql`** - Creates project and task management tables
|
||||
|
||||
#### Step 3: Enable MCP Client Management (Optional)
|
||||
**Run `migration/3_mcp_client_management.sql`** - Adds MCP client connection management features
|
||||
|
||||
#### 🔄 Database Reset (Optional)
|
||||
**Run `migration/RESET_DB.sql`** - ⚠️ **Completely resets database (deletes ALL data!)**
|
||||
|
||||
<details>
|
||||
<summary>🔍 **How to run SQL scripts in Supabase**</summary>
|
||||
|
||||
1. Go to your [Supabase Dashboard](https://supabase.com/dashboard)
|
||||
2. Select your project
|
||||
3. Navigate to **SQL Editor** in the left sidebar
|
||||
4. Click **"New Query"**
|
||||
5. Copy the contents of each migration file from your local files
|
||||
6. Paste and click **"Run"**
|
||||
7. Run each script in order: Step 1 → Step 2 → Step 3 (optional)
|
||||
|
||||
**For database reset:**
|
||||
1. Run `RESET_DB.sql` first to clean everything
|
||||
2. Then run migrations 1, 2, 3 in order to rebuild
|
||||
|
||||
</details>
|
||||
|
||||
### 4. Start Archon
|
||||
|
||||
```bash
|
||||
# Build and start all services
|
||||
docker compose up --build -d
|
||||
|
||||
# View logs (optional)
|
||||
docker compose logs -f
|
||||
```
|
||||
|
||||
<Admonition type="tip" icon="🔥" title="Hot Module Reload">
|
||||
Archon includes Hot Module Reload (HMR) for both Python and React code. Changes to source files automatically reload without container rebuilds.
|
||||
|
||||
**No rebuild needed for:**
|
||||
- Python code changes (`.py` files)
|
||||
- React components (`.tsx`, `.jsx`)
|
||||
- CSS/Tailwind styles
|
||||
- Most configuration changes
|
||||
|
||||
**Rebuild required for:**
|
||||
- New dependencies (`requirements.txt`, `package.json`)
|
||||
- Dockerfile changes
|
||||
- Environment variables
|
||||
</Admonition>
|
||||
|
||||
### 5. Access & Configure
|
||||
|
||||
| Service | URL | Purpose |
|
||||
|---------|-----|---------|
|
||||
| **🌐 Web Interface** | http://localhost:3737 | Main dashboard and controls |
|
||||
| **📚 Documentation** | http://localhost:3838 | Complete setup and usage guides |
|
||||
| **⚡ API Docs** | http://localhost:8080/docs | FastAPI documentation |
|
||||
|
||||
**Initial Configuration:**
|
||||
1. Open the **Web Interface** (http://localhost:3737)
|
||||
2. Go to **Settings** and add your OpenAI API key
|
||||
3. Start the MCP server from the **MCP Dashboard**
|
||||
4. Get connection details for your AI client
|
||||
|
||||
<Admonition type="success" icon="🎉" title="You're Ready!">
|
||||
Your Archon system is now running with **14 MCP tools** available. Your AI agents can now access your knowledge base!
|
||||
</Admonition>
|
||||
|
||||
## 🛠️ What's Included
|
||||
|
||||
When you run `docker compose up -d`, you get:
|
||||
|
||||
### Microservices Architecture
|
||||
- **Frontend** (Port 3737): React dashboard for managing knowledge and tasks
|
||||
- **API Service** (Port 8080): FastAPI server with Socket.IO for real-time features
|
||||
- **MCP Service** (Port 8051): Model Context Protocol server for AI clients
|
||||
- **Agents Service** (Port 8052): AI processing service for document analysis
|
||||
- **Documentation** (Port 3838): Complete Docusaurus documentation site
|
||||
|
||||
### Key Features
|
||||
- **Smart Web Crawling**: Automatically detects sitemaps, text files, or webpages
|
||||
- **Document Processing**: Upload PDFs, Word docs, markdown, and text files
|
||||
- **AI Integration**: Connect any MCP-compatible client (Cursor, Windsurf, etc.)
|
||||
- **Real-time Updates**: Socket.IO-based live progress tracking
|
||||
- **Task Management**: Organize projects and tasks with AI agent integration
|
||||
|
||||
### Architecture Overview
|
||||
|
||||
```mermaid
|
||||
%%{init:{
|
||||
'theme':'base',
|
||||
'themeVariables': {
|
||||
'primaryColor':'#1f2937',
|
||||
'primaryTextColor':'#ffffff',
|
||||
'primaryBorderColor':'#8b5cf6',
|
||||
'lineColor':'#a855f7',
|
||||
'textColor':'#ffffff',
|
||||
'fontFamily':'Inter',
|
||||
'fontSize':'14px',
|
||||
'background':'#000000',
|
||||
'mainBkg':'#1f2937',
|
||||
'secondBkg':'#111827',
|
||||
'borderColor':'#8b5cf6',
|
||||
'clusterBkg':'#111827',
|
||||
'clusterBorder':'#8b5cf6'
|
||||
}
|
||||
}}%%
|
||||
graph TB
|
||||
subgraph "🚀 Docker Microservices Stack"
|
||||
Frontend["🌐 Frontend Container<br/>React + Vite<br/>archon-frontend<br/>Port 3737"]
|
||||
API["⚡ Server Container<br/>FastAPI + Socket.IO<br/>Archon-Server<br/>Port 8080"]
|
||||
MCP["🔧 MCP Server<br/>14 MCP Tools<br/>archon-mcp<br/>Port 8051"]
|
||||
Agents["🤖 Agents Service<br/>AI Processing<br/>archon-agents<br/>Port 8052"]
|
||||
Docs["📚 Documentation<br/>Docusaurus<br/>archon-docs<br/>Port 3838"]
|
||||
end
|
||||
|
||||
subgraph "☁️ External Services"
|
||||
Supabase["🗄️ Supabase<br/>PostgreSQL + pgvector"]
|
||||
OpenAI["🤖 OpenAI API<br/>Embeddings + Chat"]
|
||||
Logfire["🔥 Logfire<br/>Real-time Monitoring"]
|
||||
end
|
||||
|
||||
Frontend --> API
|
||||
API --> MCP
|
||||
API --> Agents
|
||||
API --> Supabase
|
||||
API --> OpenAI
|
||||
MCP --> Logfire
|
||||
API --> Logfire
|
||||
Agents --> Logfire
|
||||
MCP --> Supabase
|
||||
Agents --> Supabase
|
||||
```
|
||||
|
||||
## ⚡ Quick Test
|
||||
|
||||
Once everything is running:
|
||||
|
||||
1. **Test Document Upload**: Go to http://localhost:3737 → Documents → Upload a PDF
|
||||
2. **Test Web Crawling**: Knowledge Base → "Crawl Website" → Enter a docs URL
|
||||
3. **Test AI Integration**: MCP Dashboard → Copy connection config for your AI client
|
||||
|
||||
## 🔌 Connecting to Cursor IDE
|
||||
|
||||
To connect Cursor to your Archon MCP server, add this configuration:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="cursor" label="Cursor IDE" default>
|
||||
|
||||
**File**: `~/.cursor/mcp.json`
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"archon": {
|
||||
"command": "docker",
|
||||
"args": [
|
||||
"exec",
|
||||
"-i",
|
||||
"-e", "TRANSPORT=stdio",
|
||||
"-e", "HOST=localhost",
|
||||
"-e", "PORT=8051",
|
||||
"archon-mcp",
|
||||
"python", "src/mcp_server.py"
|
||||
]
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="other" label="Other Clients">
|
||||
|
||||
**For Windsurf, Claude Desktop, or other MCP clients:**
|
||||
|
||||
Check the **[MCP Overview](./mcp-overview)** for specific connection instructions for your AI client.
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## 🎯 Next Steps
|
||||
|
||||
### Immediate Actions
|
||||
1. **📚 [Build Your Knowledge Base](#building-your-knowledge-base)** - Start crawling and uploading content
|
||||
2. **🔌 [Connect Your AI Client](./mcp-overview)** - Set up Cursor, Windsurf, or Claude Desktop
|
||||
3. **📊 [Monitor Performance](./configuration.mdx)** - Set up Logfire for real-time debugging
|
||||
|
||||
### Building Your Knowledge Base
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="crawl" label="🕷️ Web Crawling" default>
|
||||
|
||||
**Crawl Documentation Sites:**
|
||||
1. Go to **Knowledge Base** in the web interface
|
||||
2. Click **"Crawl Website"**
|
||||
3. Enter a documentation URL (e.g., `https://docs.python.org`)
|
||||
4. Monitor progress in real-time
|
||||
|
||||
**Pro Tips:**
|
||||
- Start with well-structured documentation sites
|
||||
- Use sitemap URLs when available (e.g., `sitemap.xml`)
|
||||
- Monitor crawl progress via Socket.IO updates
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="upload" label="📄 Document Upload">
|
||||
|
||||
**Upload Documents:**
|
||||
1. Go to **Documents** in the web interface
|
||||
2. Click **"Upload Document"**
|
||||
3. Select PDFs, Word docs, or text files
|
||||
4. Add tags for better organization
|
||||
|
||||
**Supported Formats:**
|
||||
- PDF files
|
||||
- Word documents (.docx)
|
||||
- Markdown files (.md)
|
||||
- Plain text files (.txt)
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Advanced Setup
|
||||
|
||||
For production deployments and advanced features:
|
||||
|
||||
- **[Deployment Guide](./deployment.mdx)** - Production deployment strategies
|
||||
- **[RAG Configuration](./rag.mdx)** - Advanced search and retrieval optimization
|
||||
- **[Configuration Guide](./configuration.mdx)** - Comprehensive setup and monitoring
|
||||
- **[API Reference](./api-reference.mdx)** - Complete REST API documentation
|
||||
|
||||
## 📖 Documentation Guide
|
||||
|
||||
This documentation is organized for different use cases:
|
||||
|
||||
### 🚀 Getting Started (You Are Here)
|
||||
**QuickStart guide** to get Archon running in minutes
|
||||
|
||||
### 🔌 MCP Integration
|
||||
**[MCP Overview](./mcp-overview)** - Connect Cursor, Windsurf, Claude Desktop, and other MCP clients
|
||||
|
||||
### 🧠 RAG & Search
|
||||
**[RAG Strategies](./rag.mdx)** - Configure intelligent search and retrieval for optimal AI responses
|
||||
|
||||
### 📊 Configuration & Monitoring
|
||||
**[Configuration Guide](./configuration.mdx)** - Setup, monitoring, and Logfire integration
|
||||
|
||||
### 🚀 Production Deployment
|
||||
**[Deployment Guide](./deployment.mdx)** - Scale Archon for team and production use
|
||||
|
||||
### 🛠️ Development
|
||||
**[API Reference](./api-reference.mdx)** - REST API endpoints and development guides
|
||||
**[Testing Guide](./testing.mdx)** - Development setup and testing procedures
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
<details>
|
||||
<summary>**🐳 Container Issues**</summary>
|
||||
|
||||
```bash
|
||||
# Check Docker status
|
||||
docker --version
|
||||
docker compose version
|
||||
|
||||
# Rebuild containers
|
||||
docker compose down
|
||||
docker compose up --build -d
|
||||
|
||||
# Check container logs
|
||||
docker compose logs archon-server
|
||||
docker compose logs archon-mcp
|
||||
docker compose logs archon-agents
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>**🔌 Connection Issues**</summary>
|
||||
|
||||
```bash
|
||||
# Verify environment variables
|
||||
docker compose exec archon-server env | grep -E "(SUPABASE|OPENAI)"
|
||||
|
||||
# Check MCP server health
|
||||
curl http://localhost:8051/sse
|
||||
|
||||
# Check API health
|
||||
curl http://localhost:8080/health
|
||||
|
||||
# Check Agents service health
|
||||
curl http://localhost:8052/health
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
<details>
|
||||
<summary>**🧠 Empty RAG Results**</summary>
|
||||
|
||||
```bash
|
||||
# Check available sources
|
||||
curl http://localhost:8080/api/sources
|
||||
|
||||
# Test basic query
|
||||
curl -X POST http://localhost:8080/api/rag/query \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{"query": "test", "match_count": 1}'
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## 💬 Getting Help
|
||||
|
||||
- **📖 [Complete Documentation](http://localhost:3838)** - Comprehensive guides
|
||||
- **🐛 [GitHub Issues](https://github.com/coleam00/archon/issues)** - Bug reports and feature requests
|
||||
- **📊 [Logfire Dashboard](https://logfire.pydantic.dev/)** - Optional enhanced logging (when `LOGFIRE_ENABLED=true`)
|
||||
|
||||
---
|
||||
|
||||
<p align="center">
|
||||
<strong>Supercharging AI IDE's with knowledge and tasks</strong><br/>
|
||||
<em>Transform your AI coding experience with Archon</em>
|
||||
</p>
|
||||
206
docs/docs/intro.mdx
Normal file
@@ -0,0 +1,206 @@
|
||||
---
|
||||
title: Welcome to Archon
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
<div className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h1 className="hero__title">Archon</h1>
|
||||
<p className="hero__subtitle">Supercharge your AI development workflow. Plug Claude Code, Cursor, Windsurf, or any AI IDE into Archon to unlock instant access to your business knowledge, technical docs, project requirements, and development tasks. Your AI gets smarter, your code gets better.</p>
|
||||
<div>
|
||||
<a
|
||||
className="button button--green-neon button--lg"
|
||||
href="/docs/getting-started"
|
||||
>
|
||||
Get Started - Quick Setup ⚡
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎯 What is Archon?
|
||||
|
||||
Archon is a powerful knowledge engine that integrates the [Model Context Protocol (MCP)](https://modelcontextprotocol.io) with [Crawl4AI](https://crawl4ai.com) and [Supabase](https://supabase.com/) to create a centralized knowledge base for your AI agents and coding assistants.
|
||||
|
||||
**Connect your Cursor or Windsurf agents to Archon** and give them access to:
|
||||
- Your technical documentation
|
||||
- Your business/project documentation
|
||||
- Any website content you've crawled
|
||||
- Uploaded documents (PDFs, Word docs, markdown files)
|
||||
- A searchable knowledge base with advanced RAG capabilities
|
||||
|
||||
With Archon's web interface, you can **manage all your knowledge in one place** - crawl websites, upload documents, organize by type, and even chat with your knowledge base to test queries before your AI agents use them.
|
||||
|
||||
## ✨ Core Features
|
||||
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3>🧠 Archon Knowledge</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p>
|
||||
<strong>Build your AI's memory bank</strong> with powerful knowledge management:
|
||||
</p>
|
||||
<ul>
|
||||
<li>📚 Crawl entire documentation sites automatically</li>
|
||||
<li>📄 Upload PDFs, Word docs, and markdown files</li>
|
||||
<li>🔍 Semantic search with AI-enhanced results</li>
|
||||
<li>💻 Code example extraction and indexing</li>
|
||||
<li>🎯 Source filtering for precise queries</li>
|
||||
</ul>
|
||||
<a href="/docs/knowledge-overview" className="button button--primary">
|
||||
Explore Archon Knowledge →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3>📊 Archon Projects</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p>
|
||||
<strong>AI-powered project management</strong> integrated with your workflow:
|
||||
</p>
|
||||
<ul>
|
||||
<li>📋 Hierarchical task management</li>
|
||||
<li>🤖 AI agents can create and update tasks</li>
|
||||
<li>📝 Rich document editing with version control</li>
|
||||
<li>🔗 GitHub repository integration</li>
|
||||
<li>📈 Kanban and table views</li>
|
||||
</ul>
|
||||
<a href="/docs/projects-overview" className="button button--primary">
|
||||
Explore Archon Projects →
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🔌 Universal AI Integration
|
||||
|
||||
<div className="row margin-top--lg">
|
||||
<div className="col col--4">
|
||||
<div className="text--center">
|
||||
<img src="/img/cursor.svg" alt="Cursor" style={{height: '60px', marginBottom: '1rem'}} />
|
||||
<h4>Cursor IDE</h4>
|
||||
<p>One-click setup with deeplink support</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--4">
|
||||
<div className="text--center">
|
||||
<img src="/img/windsurf-white-symbol.svg" alt="Windsurf" style={{height: '60px', marginBottom: '1rem'}} />
|
||||
<h4>Windsurf</h4>
|
||||
<p>Native MCP integration</p>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--4">
|
||||
<div className="text--center">
|
||||
<img src="/img/claude-logo.svg" alt="Claude" style={{height: '60px', marginBottom: '1rem'}} />
|
||||
<h4>Claude Code</h4>
|
||||
<p>Full MCP tool support</p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
Ready to get started? Follow our comprehensive setup guide:
|
||||
|
||||
👉 **[Getting Started Guide](./getting-started)** - Complete setup from installation to first knowledge base
|
||||
|
||||
## 📚 Documentation Sections
|
||||
|
||||
| Section | Description |
|
||||
|---------|-------------|
|
||||
| **[Getting Started](./getting-started)** | Complete setup guide from prerequisites to first crawl |
|
||||
| **[Configuration](./configuration)** | Environment variables, database setup, and service configuration |
|
||||
| **[MCP Integration](./mcp-overview)** | Connect AI clients like Cursor, Windsurf, Claude Desktop |
|
||||
| **[API Reference](./api-reference)** | Complete REST API documentation with examples |
|
||||
| **[Socket.IO Communication](./websockets)** | Real-time updates, progress tracking, and troubleshooting |
|
||||
| **[RAG Strategies](./rag)** | Configure advanced retrieval strategies for optimal performance |
|
||||
| **[Task Management](./tasks)** | Organize projects and tasks with AI agent integration |
|
||||
| **[Web Interface](./ui)** | Comprehensive guide to the React frontend |
|
||||
| **[Server Architecture](./server)** | Technical details about the backend and MCP server |
|
||||
| **[Testing](./testing)** | Testing strategies and troubleshooting guides |
|
||||
| **[Deployment](./deployment)** | Production deployment with Docker and scaling |
|
||||
|
||||
## 🛠️ Architecture Overview
|
||||
|
||||
```mermaid
|
||||
%%{init:{
|
||||
'theme':'base',
|
||||
'themeVariables': {
|
||||
'primaryColor':'#1f2937',
|
||||
'primaryTextColor':'#ffffff',
|
||||
'primaryBorderColor':'#8b5cf6',
|
||||
'lineColor':'#a855f7',
|
||||
'textColor':'#ffffff',
|
||||
'fontFamily':'Inter',
|
||||
'fontSize':'14px',
|
||||
'background':'#000000',
|
||||
'mainBkg':'#1f2937',
|
||||
'secondBkg':'#111827',
|
||||
'borderColor':'#8b5cf6',
|
||||
'clusterBkg':'#111827',
|
||||
'clusterBorder':'#8b5cf6'
|
||||
}
|
||||
}}%%
|
||||
graph TB
|
||||
subgraph "AI Clients"
|
||||
Cursor(Cursor IDE)
|
||||
Windsurf(Windsurf IDE)
|
||||
Claude(Claude Desktop)
|
||||
end
|
||||
|
||||
subgraph "Archon Microservices"
|
||||
UI["Frontend Service<br/>archon-frontend<br/>Port 3737"]
|
||||
API["Server Service<br/>Archon-Server<br/>Port 8080"]
|
||||
MCP["MCP Service<br/>archon-mcp<br/>Port 8051"]
|
||||
Agents["Agents Service<br/>archon-agents<br/>Port 8052"]
|
||||
Docs["Documentation<br/>archon-docs<br/>Port 3838"]
|
||||
end
|
||||
|
||||
subgraph "External Services"
|
||||
Supabase["Supabase<br/>PostgreSQL + Vector DB"]
|
||||
OpenAI["OpenAI API<br/>Embeddings"]
|
||||
end
|
||||
|
||||
Cursor -.->|MCP Protocol| MCP
|
||||
Windsurf -.->|MCP Protocol| MCP
|
||||
Claude -.->|MCP Protocol| MCP
|
||||
|
||||
UI --> API
|
||||
MCP --> API
|
||||
API --> Agents
|
||||
API --> Supabase
|
||||
Agents --> OpenAI
|
||||
MCP --> Supabase
|
||||
```
|
||||
|
||||
## 🔮 Real-Time Features
|
||||
|
||||
Archon implements comprehensive real-time communication:
|
||||
|
||||
- **🔄 Live Progress Tracking**: Real-time updates during crawling operations
|
||||
- **📡 Server Log Streaming**: Socket.IO-based log streaming from MCP server to UI
|
||||
- **🎯 Progress Callbacks**: Business logic reports progress via callbacks to Socket.IO broadcasts
|
||||
- **🔗 Auto-Reconnection**: Robust connection handling with automatic reconnect on failures
|
||||
- **📱 Responsive UI Updates**: Instant feedback without polling or page refreshes
|
||||
|
||||
📋 **[Complete Socket.IO Guide](./server#socket-io-communication)** - Implementation patterns and best practices
|
||||
|
||||
## 🎯 Next Steps
|
||||
|
||||
1. **[Set up Archon](./getting-started)** - Get your knowledge engine running
|
||||
2. **[Connect your AI client](./mcp-overview)** - Integrate with Cursor, Windsurf, or Claude Desktop
|
||||
3. **[Build your knowledge base](./getting-started#building-your-knowledge-base)** - Start crawling and uploading content
|
||||
4. **[Optimize for your use case](./rag)** - Configure RAG strategies
|
||||
5. **[Deploy to production](./deployment)** - Scale for team or enterprise use
|
||||
|
||||
---
|
||||
|
||||
**Transform your AI coding experience with Archon** - *Build once, query everywhere*
|
||||
285
docs/docs/knowledge-features.mdx
Normal file
@@ -0,0 +1,285 @@
|
||||
---
|
||||
title: Archon Knowledge Features
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 🧠 Archon Knowledge: Complete Feature Reference
|
||||
|
||||
<div className="hero hero--secondary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
Everything you can do with Archon Knowledge - from web crawling to semantic search, document processing to code extraction.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎯 Core Knowledge Management Features
|
||||
|
||||
### Content Acquisition
|
||||
- **Smart Web Crawling**: Intelligent crawling with automatic content type detection
|
||||
- **Document Upload**: Support for PDF, Word, Markdown, and text files
|
||||
- **Sitemap Processing**: Crawl entire documentation sites efficiently
|
||||
- **Recursive Crawling**: Follow links to specified depth
|
||||
- **Batch Processing**: Handle multiple URLs simultaneously
|
||||
|
||||
### Content Processing
|
||||
- **Smart Chunking**: Intelligent text splitting preserving context
|
||||
- **Contextual Embeddings**: Enhanced embeddings for better retrieval
|
||||
- **Code Extraction**: Automatic detection and indexing of code examples
|
||||
- Only extracts substantial code blocks (≥ 1000 characters by default)
|
||||
- Supports markdown code blocks (triple backticks)
|
||||
- Falls back to HTML extraction for `<pre>` and `<code>` tags
|
||||
- Generates AI summaries for each code example
|
||||
- **Metadata Extraction**: Headers, sections, and document structure
|
||||
- **Source Management**: Track and manage content sources
|
||||
|
||||
### Search & Retrieval
|
||||
- **Semantic Search**: Vector similarity search with pgvector
|
||||
- **Code Search**: Specialized search for code examples
|
||||
- **Source Filtering**: Search within specific sources
|
||||
- **Result Reranking**: Optional ML-based result reranking
|
||||
- **Hybrid Search**: Combine keyword and semantic search
|
||||
|
||||
## 🤖 AI Integration Features
|
||||
|
||||
### MCP Tools Available
|
||||
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>Knowledge Tools</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li><code>perform_rag_query</code> - Semantic search</li>
|
||||
<li><code>search_code_examples</code> - Code-specific search</li>
|
||||
<li><code>crawl_single_page</code> - Index one page</li>
|
||||
<li><code>smart_crawl_url</code> - Intelligent crawling</li>
|
||||
<li><code>get_available_sources</code> - List sources</li>
|
||||
<li><code>upload_document</code> - Process documents</li>
|
||||
<li><code>delete_source</code> - Remove content</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>AI Capabilities</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>AI can search your entire knowledge base</li>
|
||||
<li>Automatic query refinement for better results</li>
|
||||
<li>Context-aware answer generation</li>
|
||||
<li>Code example recommendations</li>
|
||||
<li>Source citation in responses</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎨 User Interface Features
|
||||
|
||||
### Knowledge Table View
|
||||
- **Source Overview**: See all indexed sources at a glance
|
||||
- **Document Count**: Track content volume per source
|
||||
- **Last Updated**: Monitor content freshness
|
||||
- **Quick Actions**: Delete or refresh sources
|
||||
- **Search Interface**: Test queries directly in UI
|
||||
|
||||
### Upload Interface
|
||||
- **Drag & Drop**: Easy file uploads
|
||||
- **Progress Tracking**: Real-time processing status
|
||||
- **Batch Upload**: Multiple files simultaneously
|
||||
- **Format Detection**: Automatic file type handling
|
||||
|
||||
### Crawl Interface
|
||||
- **URL Input**: Simple URL entry with validation
|
||||
- **Crawl Options**: Configure depth, filters
|
||||
- **Progress Monitoring**: Live crawl status via Socket.IO
|
||||
- **Stop Functionality**: Cancel crawls immediately with proper cleanup
|
||||
- **Result Preview**: See crawled content immediately
|
||||
|
||||
## 🔧 Technical Capabilities
|
||||
|
||||
### Backend Services
|
||||
|
||||
#### RAG Services
|
||||
- **Crawling Service**: Web page crawling and parsing
|
||||
- **Document Storage Service**: Chunking and storage
|
||||
- **Search Service**: Query processing and retrieval
|
||||
- **Source Management Service**: Source metadata handling
|
||||
|
||||
#### Embedding Services
|
||||
- **Embedding Service**: OpenAI embeddings with rate limiting
|
||||
- **Contextual Embedding Service**: Context-aware embeddings
|
||||
|
||||
#### Storage Services
|
||||
- **Document Storage Service**: Parallel document processing
|
||||
- **Code Storage Service**: Code extraction and indexing
|
||||
|
||||
### Processing Pipeline
|
||||
1. **Content Acquisition**: Crawl or upload
|
||||
2. **Text Extraction**: Parse HTML/PDF/DOCX
|
||||
3. **Smart Chunking**: Split into optimal chunks
|
||||
4. **Embedding Generation**: Create vector embeddings
|
||||
5. **Storage**: Save to Supabase with pgvector
|
||||
6. **Indexing**: Update search indices
|
||||
|
||||
### Performance Features
|
||||
- **Rate Limiting**: 200k tokens/minute OpenAI limit
|
||||
- **Parallel Processing**: ThreadPoolExecutor optimization
|
||||
- **Batch Operations**: Process multiple documents efficiently
|
||||
- **Socket.IO Progress**: Real-time status updates
|
||||
- **Caching**: Intelligent result caching
|
||||
|
||||
### Crawl Cancellation
|
||||
- **Immediate Response**: Stop button provides instant UI feedback
|
||||
- **Proper Cleanup**: Cancels both orchestration service and asyncio tasks
|
||||
- **State Persistence**: Uses localStorage to prevent zombie crawls on refresh
|
||||
- **Socket.IO Events**: Real-time cancellation status via `crawl:stopping` and `crawl:stopped`
|
||||
- **Resource Management**: Ensures all server resources are properly released
|
||||
|
||||
## 🚀 Advanced Features
|
||||
|
||||
### Content Types
|
||||
|
||||
#### Web Crawling
|
||||
- **Sitemap Support**: Process sitemap.xml files
|
||||
- **Text File Support**: Direct .txt file processing
|
||||
- **Markdown Support**: Native .md file handling
|
||||
- **Dynamic Content**: JavaScript-rendered pages
|
||||
- **Authentication**: Basic auth support
|
||||
|
||||
#### Document Processing
|
||||
- **PDF Extraction**: Full text and metadata
|
||||
- **Word Documents**: .docx and .doc support
|
||||
- **Markdown Files**: Preserve formatting
|
||||
- **Plain Text**: Simple text processing
|
||||
- **Code Files**: Syntax-aware processing
|
||||
|
||||
### Search Features
|
||||
- **Query Enhancement**: Automatic query expansion
|
||||
- **Contextual Results**: Include surrounding context
|
||||
- **Code Highlighting**: Syntax highlighting in results
|
||||
- **Similarity Scoring**: Relevance scores for ranking
|
||||
- **Faceted Search**: Filter by metadata
|
||||
|
||||
### Monitoring & Analytics
|
||||
- **Logfire Integration**: Real-time performance monitoring
|
||||
- **Search Analytics**: Track popular queries
|
||||
- **Content Analytics**: Usage patterns
|
||||
- **Performance Metrics**: Query times, throughput
|
||||
|
||||
### Debugging Tips
|
||||
|
||||
#### Code Extraction Not Working?
|
||||
1. **Check code block size**: Only blocks ≥ 1000 characters are extracted
|
||||
2. **Verify markdown format**: Code must be in triple backticks (```)
|
||||
3. **Check crawl results**: Look for `backtick_count` in logs
|
||||
4. **HTML fallback**: System will try HTML if markdown has no code blocks
|
||||
|
||||
#### Crawling Issues?
|
||||
1. **Timeouts**: The system uses simple crawling without complex waits
|
||||
2. **JavaScript sites**: Content should render without special interactions
|
||||
3. **Progress stuck**: Check logs for batch processing updates
|
||||
4. **Different content types**:
|
||||
- `.txt` files: Direct text extraction
|
||||
- `sitemap.xml`: Batch crawl all URLs
|
||||
- Regular URLs: Recursive crawl with depth limit
|
||||
|
||||
## 📊 Usage Examples
|
||||
|
||||
### Crawling Documentation
|
||||
```
|
||||
AI Assistant: "Crawl the React documentation"
|
||||
```
|
||||
The system will:
|
||||
1. Detect it's a documentation site
|
||||
2. Find and process the sitemap
|
||||
3. Crawl all pages with progress updates
|
||||
4. Extract code examples
|
||||
5. Create searchable chunks
|
||||
|
||||
### Searching Knowledge
|
||||
```
|
||||
AI Assistant: "Find information about React hooks"
|
||||
```
|
||||
The search will:
|
||||
1. Generate embeddings for the query
|
||||
2. Search across all React documentation
|
||||
3. Return relevant chunks with context
|
||||
4. Include code examples
|
||||
5. Provide source links
|
||||
|
||||
### Document Upload
|
||||
```
|
||||
User uploads "system-design.pdf"
|
||||
```
|
||||
The system will:
|
||||
1. Extract text from PDF
|
||||
2. Identify sections and headers
|
||||
3. Create smart chunks
|
||||
4. Generate embeddings
|
||||
5. Make searchable immediately
|
||||
|
||||
## 🔗 Real-time Features
|
||||
|
||||
### Socket.IO Progress
|
||||
- **Crawl Progress**: Percentage completion with smooth updates
|
||||
- **Current URL**: What's being processed in real-time
|
||||
- **Batch Updates**: Processing batches with accurate progress
|
||||
- **Stop Support**: Cancel crawls with immediate feedback
|
||||
- **Error Reporting**: Failed URLs with detailed errors
|
||||
- **Completion Status**: Final statistics and results
|
||||
|
||||
### Live Updates
|
||||
```javascript
|
||||
// Connect to Socket.IO and subscribe to progress
|
||||
import { io } from 'socket.io-client';
|
||||
|
||||
const socket = io('/crawl');
|
||||
socket.emit('subscribe', { progress_id: 'uuid' });
|
||||
|
||||
// Handle progress updates
|
||||
socket.on('progress_update', (data) => {
|
||||
console.log(`Progress: ${data.percentage}%`);
|
||||
console.log(`Status: ${data.status}`);
|
||||
console.log(`Current URL: ${data.currentUrl}`);
|
||||
console.log(`Pages: ${data.processedPages}/${data.totalPages}`);
|
||||
});
|
||||
|
||||
// Handle completion
|
||||
socket.on('progress_complete', (data) => {
|
||||
console.log('Crawl completed!');
|
||||
console.log(`Chunks stored: ${data.chunksStored}`);
|
||||
console.log(`Word count: ${data.wordCount}`);
|
||||
});
|
||||
|
||||
// Stop a crawl
|
||||
socket.emit('crawl_stop', { progress_id: 'uuid' });
|
||||
|
||||
// Handle stop events
|
||||
socket.on('crawl:stopping', (data) => {
|
||||
console.log('Crawl is stopping...');
|
||||
});
|
||||
|
||||
socket.on('crawl:stopped', (data) => {
|
||||
console.log('Crawl cancelled successfully');
|
||||
});
|
||||
```
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [Knowledge Overview](./knowledge-overview) - High-level introduction
|
||||
- [API Reference](./api-reference#knowledge-management-api) - Detailed API documentation
|
||||
- [MCP Tools Reference](./mcp-tools#knowledge-tools) - MCP tool specifications
|
||||
- [RAG Agent Documentation](./agent-rag) - How the AI searches knowledge
|
||||
- [Server Services](./server-services#rag-services) - Technical service details
|
||||
209
docs/docs/knowledge-overview.mdx
Normal file
@@ -0,0 +1,209 @@
|
||||
---
|
||||
title: Archon Knowledge Overview
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 🧠 Archon Knowledge: Your AI's Memory Bank
|
||||
|
||||
<div className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**Build a powerful knowledge base** for your AI assistants. Crawl websites, upload documents, and give your AI instant access to all your technical and business information.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Archon Knowledge transforms your documentation, websites, and files into a searchable knowledge base that your AI coding assistants can instantly access. Never explain the same concept twice - your AI remembers everything.
|
||||
|
||||
<Admonition type="tip" icon="🎉" title="Fully Operational RAG System">
|
||||
The RAG system is **now fully functional** with 14 MCP tools enabled, comprehensive error handling, and threading optimizations for high performance.
|
||||
</Admonition>
|
||||
|
||||
## 🏗️ How RAG Works
|
||||
|
||||
```mermaid
|
||||
%%{init:{
|
||||
'theme':'base',
|
||||
'themeVariables': {
|
||||
'primaryColor':'#1f2937',
|
||||
'primaryTextColor':'#ffffff',
|
||||
'primaryBorderColor':'#8b5cf6',
|
||||
'lineColor':'#a855f7',
|
||||
'textColor':'#ffffff',
|
||||
'fontFamily':'Inter',
|
||||
'fontSize':'14px',
|
||||
'background':'#000000',
|
||||
'mainBkg':'#1f2937',
|
||||
'secondBkg':'#111827',
|
||||
'borderColor':'#8b5cf6'
|
||||
}
|
||||
}}%%
|
||||
flowchart TD
|
||||
A[🤖 AI Agent Query] --> B[🧠 Generate Embeddings]
|
||||
B --> C[🔍 Vector Search]
|
||||
C --> D[📄 Matching Documents]
|
||||
D --> E[⚡ Filter & Rank]
|
||||
E --> F[📋 Return Results]
|
||||
```
|
||||
|
||||
## ⚡ Performance Features
|
||||
|
||||
Archon Knowledge is optimized for speed and efficiency:
|
||||
|
||||
- **Smart Concurrency**: Adaptive processing based on system resources
|
||||
- **Batch Processing**: Processes multiple documents efficiently
|
||||
- **Rate Limiting**: Respects API limits while maximizing throughput
|
||||
- **Memory Management**: Automatically adjusts to available system memory
|
||||
|
||||
## 🔍 Using the Knowledge Base
|
||||
|
||||
### Basic Search
|
||||
|
||||
The `perform_rag_query` tool is the primary interface for semantic search across your knowledge base:
|
||||
|
||||
```javascript title="Basic RAG Query"
|
||||
// Simple search across all sources
|
||||
await mcp.callTool('perform_rag_query', {
|
||||
query: "authentication best practices",
|
||||
match_count: 5 // Optional, defaults to 5
|
||||
});
|
||||
```
|
||||
|
||||
### Filtered Search by Source
|
||||
|
||||
Filter results to specific domains or sources:
|
||||
|
||||
```javascript title="Source-Filtered Search"
|
||||
// Search only within a specific domain
|
||||
await mcp.callTool('perform_rag_query', {
|
||||
query: "MCP session management",
|
||||
source: "modelcontextprotocol.io", // Filter by domain
|
||||
match_count: 10
|
||||
});
|
||||
|
||||
// Get available sources first
|
||||
const sources = await mcp.callTool('get_available_sources', {});
|
||||
// Returns: ["ai.pydantic.dev", "modelcontextprotocol.io", ...]
|
||||
```
|
||||
|
||||
### Advanced Usage Examples
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="technical" label="Technical Documentation" default>
|
||||
|
||||
```javascript
|
||||
// Search for technical implementation details
|
||||
await mcp.callTool('perform_rag_query', {
|
||||
query: "SSE transport implementation MCP protocol",
|
||||
source: "modelcontextprotocol.io",
|
||||
match_count: 5
|
||||
});
|
||||
|
||||
// Response includes:
|
||||
// - Matched content chunks
|
||||
// - Source URLs
|
||||
// - Similarity scores
|
||||
// - Metadata (headers, context)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="code" label="Code Examples">
|
||||
|
||||
```javascript
|
||||
// Search for code examples
|
||||
await mcp.callTool('search_code_examples', {
|
||||
query: "React hooks useState useEffect",
|
||||
source_id: "react.dev", // Optional source filter
|
||||
match_count: 10
|
||||
});
|
||||
|
||||
// Returns:
|
||||
// - Code snippets with syntax highlighting
|
||||
// - AI-generated summaries
|
||||
// - Full context (before/after code)
|
||||
// - Source file information
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="multi-source" label="Multi-Source Search">
|
||||
|
||||
```javascript
|
||||
// Search across all indexed sources
|
||||
const results = await mcp.callTool('perform_rag_query', {
|
||||
query: "best practices for API design REST GraphQL",
|
||||
// No source filter - searches everything
|
||||
match_count: 15
|
||||
});
|
||||
|
||||
// Group results by source
|
||||
const groupedResults = results.reduce((acc, result) => {
|
||||
const source = result.metadata.source;
|
||||
if (!acc[source]) acc[source] = [];
|
||||
acc[source].push(result);
|
||||
return acc;
|
||||
}, {});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## 🔧 Advanced Features
|
||||
|
||||
- **Contextual Embeddings**: Enhanced understanding through document context
|
||||
- **Source Filtering**: Search within specific domains or documentation sources
|
||||
- **Code Search**: Specialized search for code examples and implementations
|
||||
- **Multi-Source**: Search across all your indexed knowledge sources simultaneously
|
||||
|
||||
## ⚡ Performance
|
||||
|
||||
<Admonition type="success" icon="📊" title="Fast & Efficient">
|
||||
- **Average Query Time**: 200-300ms
|
||||
- **Optimized Processing**: Smart batching and concurrency
|
||||
- **Memory Adaptive**: Automatically adjusts to system resources
|
||||
- **Rate Limited**: Respects API limits for reliable operation
|
||||
</Admonition>
|
||||
|
||||
## 📊 Real-Time Progress
|
||||
|
||||
When processing large amounts of content, Archon provides real-time progress updates via Socket.IO:
|
||||
|
||||
- **Smooth Progress**: Linear progression from 0-100%
|
||||
- **Batch Details**: Clear information about processing status
|
||||
- **Real-Time Updates**: Live updates as documents are processed
|
||||
- **Memory Awareness**: Automatically adjusts based on system resources
|
||||
|
||||
## 🗄️ Data Storage
|
||||
|
||||
Archon uses a vector database to store and search your knowledge:
|
||||
|
||||
- **Vector Embeddings**: Content is converted to high-dimensional vectors for semantic search
|
||||
- **Source Tracking**: Each document is linked to its original source
|
||||
- **Code Examples**: Special handling for code snippets with language detection
|
||||
- **Metadata Storage**: Additional context and headers are preserved
|
||||
|
||||
## 🔧 Common Issues
|
||||
|
||||
### Performance
|
||||
- **Slow searches**: Usually due to large document sets - the system automatically optimizes batch sizes
|
||||
- **Memory usage**: Adaptive processing automatically adjusts based on available system memory
|
||||
- **Rate limiting**: Built-in rate limiting prevents API quota issues
|
||||
|
||||
### Search Quality
|
||||
- **Poor results**: Try different search terms or use source filtering to narrow results
|
||||
- **Missing content**: Ensure documents are properly crawled and indexed
|
||||
- **Code examples**: Use the specialized `search_code_examples` tool for better code results
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
1. **Add Knowledge Sources**: Use MCP tools to crawl websites and upload documents
|
||||
2. **Search Your Knowledge**: Use `perform_rag_query` to find relevant information
|
||||
3. **Filter by Source**: Search within specific domains when you need focused results
|
||||
4. **Find Code Examples**: Use `search_code_examples` for code-specific searches
|
||||
|
||||
## 🔮 What's Next
|
||||
|
||||
Future enhancements include multi-model processing, hybrid search combining vector and keyword search, and advanced neural reranking for even better results.
|
||||
429
docs/docs/mcp-overview.mdx
Normal file
@@ -0,0 +1,429 @@
|
||||
---
|
||||
title: 🔌 Model Context Protocol (MCP) Overview
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Model Context Protocol (MCP) Overview
|
||||
|
||||
<Admonition type="info" icon="🎯" title="Architecture Clarification">
|
||||
|
||||
**Archon's MCP implementation follows a clear separation of concerns:**
|
||||
- The **Server service** contains ALL business logic, ML models, and data operations
|
||||
- The **MCP service** is a lightweight HTTP-based wrapper that exposes Server functionality as MCP tools
|
||||
- **MCP communicates with Server exclusively via HTTP APIs** - maintaining true microservices separation
|
||||
|
||||
</Admonition>
|
||||
|
||||
## What is MCP?
|
||||
|
||||
The Model Context Protocol (MCP) is an open standard that enables AI applications to securely access external data sources and tools. Archon implements both sides of MCP:
|
||||
|
||||
- **MCP Server**: Exposes 14 tools following action-based patterns for knowledge management and task organization
|
||||
- **MCP Client**: Universal SSE-based client for connecting to any MCP server using Streamable HTTP transport
|
||||
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3>MCP Server</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p>Archon as an MCP Server - Expose your knowledge base to AI clients</p>
|
||||
<ul>
|
||||
<li>14 comprehensive tools using flexible action-based patterns</li>
|
||||
<li>Real-time Logfire monitoring of all tool calls</li>
|
||||
<li>Compatible with Cursor, Windsurf, Claude Desktop</li>
|
||||
<li>SSE transport for all clients (stdio via docker exec)</li>
|
||||
</ul>
|
||||
<a href="/mcp-server" className="button button--primary">
|
||||
MCP Server Documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h3>MCP Client</h3>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<p>Universal MCP Client - Connect to any SSE-based MCP server from Archon's UI</p>
|
||||
<ul>
|
||||
<li>Connect to any MCP server using Streamable HTTP (SSE) transport</li>
|
||||
<li>Interactive tool testing with real-time results</li>
|
||||
<li>Socket.IO real-time updates for collaborative workflows</li>
|
||||
<li>Simple configuration - just provide the SSE endpoint URL</li>
|
||||
</ul>
|
||||
<a href="/mcp-client" className="button button--primary">
|
||||
MCP Client Documentation
|
||||
</a>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## Archon MCP Architecture
|
||||
|
||||
```mermaid
|
||||
%%{init:{
|
||||
'theme':'base',
|
||||
'themeVariables': {
|
||||
'primaryColor':'#1f2937',
|
||||
'primaryTextColor':'#ffffff',
|
||||
'primaryBorderColor':'#8b5cf6',
|
||||
'lineColor':'#a855f7',
|
||||
'textColor':'#ffffff',
|
||||
'fontFamily':'Inter',
|
||||
'fontSize':'14px',
|
||||
'background':'#000000',
|
||||
'mainBkg':'#1f2937',
|
||||
'secondBkg':'#111827',
|
||||
'borderColor':'#8b5cf6',
|
||||
'clusterBkg':'#111827',
|
||||
'clusterBorder':'#8b5cf6'
|
||||
}
|
||||
}}%%
|
||||
graph TB
|
||||
subgraph "🤖 External AI Clients"
|
||||
Cursor["💻 Cursor IDE<br/>connects via stdio"]
|
||||
Windsurf["🏄 Windsurf IDE<br/>connects via stdio"]
|
||||
Claude["🧠 Claude Desktop<br/>connects via stdio"]
|
||||
Other["🔧 Other MCP Clients<br/>connects via SSE"]
|
||||
end
|
||||
|
||||
subgraph "🏰 Archon Instance"
|
||||
subgraph "🔌 Universal MCP Client (Port 3737)"
|
||||
ClientUI["🎨 Client UI<br/>Tool Testing & Management"]
|
||||
ClientWS["📡 Socket.IO Real-time Updates"]
|
||||
end
|
||||
|
||||
subgraph "🛠️ Archon MCP Server (Port 8051)"
|
||||
MCPCore["⚡ MCP Core Server<br/>+ Logfire Monitoring"]
|
||||
Tools["🛠️ 14 MCP Tools"]
|
||||
Health["🏥 Health & Session"]
|
||||
end
|
||||
|
||||
subgraph "🏗️ Backend Services (Port 8080)"
|
||||
RAGModule["🧠 RAG Module<br/>7 tools"]
|
||||
ProjectModule["📊 Project Module<br/>5 consolidated tools"]
|
||||
FastAPI["⚡ FastAPI Backend"]
|
||||
Supabase["🗄️ Supabase Database<br/>pgvector"]
|
||||
Logfire["🔥 Logfire Dashboard<br/>Real-time Monitoring"]
|
||||
end
|
||||
end
|
||||
|
||||
subgraph "🌐 External MCP Servers"
|
||||
ExtMCP1["🔧 Brave Search MCP"]
|
||||
ExtMCP2["📁 Filesystem MCP"]
|
||||
ExtMCP3["🐙 GitHub MCP"]
|
||||
end
|
||||
|
||||
%% External clients to Archon MCP Server
|
||||
Cursor -.->|JSON-RPC<br/>stdio| MCPCore
|
||||
Windsurf -.->|JSON-RPC<br/>stdio| MCPCore
|
||||
Claude -.->|JSON-RPC<br/>stdio| MCPCore
|
||||
Other -.->|SSE| MCPCore
|
||||
|
||||
%% Archon's Universal Client to external servers
|
||||
ClientUI -.->|JSON-RPC<br/>Various Transports| ExtMCP1
|
||||
ClientUI -.->|JSON-RPC<br/>Various Transports| ExtMCP2
|
||||
ClientUI -.->|JSON-RPC<br/>Various Transports| ExtMCP3
|
||||
|
||||
%% Archon's Client can also connect to its own server
|
||||
ClientUI -.->|JSON-RPC<br/>SSE| MCPCore
|
||||
|
||||
%% Internal connections
|
||||
MCPCore --> Tools
|
||||
MCPCore --> Health
|
||||
Tools --> RAGModule
|
||||
Tools --> ProjectModule
|
||||
RAGModule --> FastAPI
|
||||
ProjectModule --> FastAPI
|
||||
FastAPI --> Supabase
|
||||
MCPCore --> Logfire
|
||||
RAGModule --> Logfire
|
||||
ProjectModule --> Logfire
|
||||
ClientWS --> FastAPI
|
||||
```
|
||||
|
||||
## Quick Start Guide
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="server" label="Using Archon as MCP Server" default>
|
||||
|
||||
Connect your AI client to Archon's knowledge base:
|
||||
|
||||
1. Start Archon (Docker or local)
|
||||
2. Configure your AI client (Cursor, Windsurf, etc.)
|
||||
3. Begin using 14 comprehensive tools
|
||||
|
||||
**For Cursor:**
|
||||
```json title="MCP Settings"
|
||||
{
|
||||
"mcpServers": {
|
||||
"archon": {
|
||||
"uri": "http://localhost:8051/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**For Claude Code:**
|
||||
```bash
|
||||
claude mcp add --transport sse archon http://localhost:8051/sse
|
||||
```
|
||||
|
||||
**For Windsurf:**
|
||||
```json
|
||||
{
|
||||
"mcp.servers": {
|
||||
"archon": {
|
||||
"uri": "http://localhost:8051/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
**Available capabilities:**
|
||||
- RAG queries across your crawled knowledge
|
||||
- Create and manage tasks/projects
|
||||
- Search code examples with AI summaries
|
||||
- Document management with versioning
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="client" label="Using Universal MCP Client">
|
||||
|
||||
Connect to any MCP server from Archon's UI:
|
||||
|
||||
1. Open Archon UI → Navigate to MCP Client tab
|
||||
2. Add MCP servers (Brave Search, GitHub, Filesystem, etc.)
|
||||
3. Test tools interactively with real-time results
|
||||
4. Monitor all connections with Socket.IO updates
|
||||
|
||||
**Connect to Popular MCP Servers:**
|
||||
- **Brave Search**: Web search capabilities
|
||||
- **GitHub**: Repository management
|
||||
- **Filesystem**: Local file operations
|
||||
- **Archon**: Your own knowledge base
|
||||
- **Custom**: Any MCP-compatible server
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## 📊 Tool Distribution
|
||||
|
||||
<Admonition type="info" icon="📊" title="Complete Tool Overview">
|
||||
|
||||
**Archon provides 14 comprehensive MCP tools following modern patterns:**
|
||||
|
||||
</Admonition>
|
||||
|
||||
| Category | Tools | Description | Key Features |
|
||||
|----------|-------|-------------|--------------|
|
||||
| **🧠 RAG & Knowledge Management** | 7 tools | Search, crawl, and manage knowledge | RAG queries, web crawling, document upload, code search, source management |
|
||||
| **📊 Project & Task Management** | 5 tools | Complete project lifecycle management | Consolidated action-based patterns for projects, tasks, documents, and versions |
|
||||
| **🏥 System Health** | 2 tools | Health monitoring and diagnostics | Comprehensive system status and session management |
|
||||
|
||||
### Tool Categories Deep Dive
|
||||
|
||||
<div className="row">
|
||||
<div className="col col--4">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>🧠 **RAG & Knowledge Tools (7)**</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>`perform_rag_query` - Semantic search</li>
|
||||
<li>`search_code_examples` - Code-specific search</li>
|
||||
<li>`crawl_single_page` - Web page indexing</li>
|
||||
<li>`smart_crawl_url` - Intelligent crawling</li>
|
||||
<li>`upload_document` - Document processing</li>
|
||||
<li>`get_available_sources` - Source management</li>
|
||||
<li>`delete_source` - Source cleanup</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--4">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>📊 **Project Tools (5)**</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>`manage_project` - Create, list, get, delete projects</li>
|
||||
<li>`manage_task` - Create, list, get, update, delete, archive tasks</li>
|
||||
<li>`manage_document` - Add, list, get, update, delete documents</li>
|
||||
<li>`manage_versions` - Create, list, get, restore versions</li>
|
||||
<li>`get_project_features` - Retrieve project features</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--4">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>🏥 **System & Monitoring (2)**</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>`health_check` - System health diagnostics</li>
|
||||
<li>`session_info` - Session management info</li>
|
||||
<li>**Real-time Logfire tracing** for all tools</li>
|
||||
<li>**Performance metrics** and timing</li>
|
||||
<li>**Client identification** (Cursor, Windsurf, etc.)</li>
|
||||
<li>**Error tracking** and debugging</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🔥 Why Choose Archon's MCP Implementation?
|
||||
|
||||
### 🏆 Industry-Leading Features
|
||||
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>⚡ **Performance & Reliability**</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>🚀 **Sub-second response times** for most queries</li>
|
||||
<li>🔄 **Automatic reconnection** and error recovery</li>
|
||||
<li>📊 **Comprehensive monitoring** with Logfire</li>
|
||||
<li>🏥 **Health checks** and system diagnostics</li>
|
||||
<li>⚖️ **Load balancing** for high-volume usage</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>🛡️ **Security & Scalability**</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>🔐 **Encrypted credential storage** in Supabase</li>
|
||||
<li>🌐 **Multi-transport support** (stdio, SSE)</li>
|
||||
<li>🔄 **Real-time synchronization** across clients</li>
|
||||
<li>📈 **Horizontal scaling** ready</li>
|
||||
<li>🎯 **Rate limiting** and abuse protection</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
### 🔧 Developer Experience
|
||||
|
||||
<Admonition type="tip" icon="🔥" title="Built for Developers, by Developers">
|
||||
|
||||
**Archon's MCP implementation prioritizes developer experience with comprehensive tooling, detailed documentation, and real-time debugging capabilities.**
|
||||
|
||||
</Admonition>
|
||||
|
||||
- **📝 Extensive Documentation**: Every tool documented with examples
|
||||
- **🧪 Interactive Testing**: Test tools directly in the UI
|
||||
- **🔍 Real-time Debugging**: Logfire traces for every operation
|
||||
- **⚡ Hot Reloading**: Development-friendly configuration
|
||||
- **🌐 Universal Compatibility**: Works with any MCP client
|
||||
|
||||
## 📚 Documentation Structure
|
||||
|
||||
### 📖 Detailed Guides
|
||||
|
||||
| Document | Purpose | Audience |
|
||||
|----------|---------|----------|
|
||||
| **[🛠️ MCP Server Guide](/mcp-server)** | Complete server setup, configuration, and troubleshooting | Developers using Archon as an MCP server |
|
||||
| **[🔌 MCP Client Guide](/mcp-client)** | Universal client usage, server connections, and testing | Developers connecting to MCP servers |
|
||||
|
||||
### 🎯 Quick Navigation
|
||||
|
||||
<div className="row">
|
||||
<div className="col col--4">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>🚀 **Getting Started**</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>[Server Setup](/mcp-server#setup)</li>
|
||||
<li>[Client Configuration](/mcp-client#configuration)</li>
|
||||
<li>[First Tool Call](/mcp-server#first-tool-call)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--4">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>🔧 **Troubleshooting**</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>[Server Issues](/mcp-server#troubleshooting)</li>
|
||||
<li>[Client Problems](/mcp-client#troubleshooting)</li>
|
||||
<li>[Environment Variables](/mcp-server#environment-setup)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--4">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>📊 **Advanced Usage**</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>[Tool Development](/mcp-server#custom-tools)</li>
|
||||
<li>[Performance Tuning](/mcp-server#performance)</li>
|
||||
<li>[Monitoring Setup](/mcp-server#monitoring)</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎉 Ready to Get Started?
|
||||
|
||||
Choose your path based on how you want to use Archon's MCP capabilities:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="expose" label="🛠️ Expose Archon as MCP Server">
|
||||
|
||||
**You want to connect external AI clients (Cursor, Windsurf, etc.) to Archon's knowledge base**
|
||||
|
||||
👉 **[Start with MCP Server Documentation](/mcp-server)**
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="connect" label="🔌 Connect to MCP Servers">
|
||||
|
||||
**You want to use Archon's UI to connect to and test various MCP servers**
|
||||
|
||||
👉 **[Start with MCP Client Documentation](/mcp-client)**
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="both" label="🚀 Use Both Capabilities">
|
||||
|
||||
**You want to use Archon as both a server and client for maximum functionality**
|
||||
|
||||
👉 **Start with [MCP Server](/mcp-server), then [MCP Client](/mcp-client)**
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
---
|
||||
|
||||
<div className="text--center">
|
||||
<p><strong>🔥 Ready to experience the most powerful MCP implementation available?</strong></p>
|
||||
<p>Join thousands of developers already using Archon's MCP tools to supercharge their AI workflows!</p>
|
||||
</div>
|
||||
176
docs/docs/mcp-server.mdx
Normal file
@@ -0,0 +1,176 @@
|
||||
---
|
||||
title: MCP Server
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
# MCP Server
|
||||
|
||||
The MCP service provides a Model Context Protocol interface for AI clients to access Archon's functionality via HTTP.
|
||||
|
||||
## Architecture
|
||||
|
||||
MCP is a **protocol adapter** that:
|
||||
1. Receives MCP tool calls from AI clients
|
||||
2. Translates them to HTTP requests to the Server API
|
||||
3. Returns formatted responses to AI clients
|
||||
|
||||
```
|
||||
AI Client (Cursor/Windsurf) → MCP Protocol → MCP Server → HTTP → Server API
|
||||
```
|
||||
|
||||
## Available Tools
|
||||
|
||||
### RAG Tools (7)
|
||||
|
||||
| Tool | Purpose | Server Endpoint |
|
||||
|------|---------|----------------|
|
||||
| `perform_rag_query` | Semantic search | `POST /api/rag/query` |
|
||||
| `search_code_examples` | Code search | `POST /api/rag/code-search` |
|
||||
| `crawl_single_page` | Crawl one URL | `POST /api/knowledge-items/crawl` |
|
||||
| `smart_crawl_url` | Smart crawling | `POST /api/knowledge-items/crawl` |
|
||||
| `get_available_sources` | List sources | `GET /api/rag/sources` |
|
||||
| `upload_document` | Upload docs | `POST /api/documents/upload` |
|
||||
| `delete_source` | Delete source | `DELETE /api/sources/{id}` |
|
||||
|
||||
### Project Tools (5)
|
||||
|
||||
| Tool | Actions | Description |
|
||||
|------|---------|-------------|
|
||||
| `manage_project` | create, list, get, delete | Project CRUD operations |
|
||||
| `manage_task` | create, list, get, update, delete, archive | Task management |
|
||||
| `manage_document` | add, list, get, update, delete | Document management |
|
||||
| `manage_versions` | create, list, get, restore | Version control |
|
||||
| `get_project_features` | - | Get project features |
|
||||
|
||||
### System Tools (2)
|
||||
|
||||
| Tool | Purpose |
|
||||
|------|---------|
|
||||
| `health_check` | System health status |
|
||||
| `session_info` | Active session info |
|
||||
|
||||
## Implementation Pattern
|
||||
|
||||
All MCP tools follow the same pattern:
|
||||
|
||||
```python
|
||||
@mcp.tool()
|
||||
async def delete_source(ctx: Context, source: str) -> str:
|
||||
"""Delete a source via HTTP call to Server API"""
|
||||
client = get_mcp_service_client()
|
||||
async with httpx.AsyncClient() as http:
|
||||
response = await http.delete(
|
||||
f"{client.api_url}/api/sources/{source}",
|
||||
headers=client._get_headers()
|
||||
)
|
||||
return json.dumps(response.json())
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
### Environment Variables
|
||||
|
||||
```bash
|
||||
# Server connection
|
||||
API_BASE_URL=http://archon-server:8080
|
||||
AGENTS_BASE_URL=http://archon-agents:8052
|
||||
|
||||
# Authentication
|
||||
MCP_SERVICE_KEY=your-service-key
|
||||
|
||||
# Unified Logging Configuration (Optional)
|
||||
LOGFIRE_ENABLED=false # true=Logfire logging, false=standard logging
|
||||
LOGFIRE_TOKEN=your-logfire-token # Only required when LOGFIRE_ENABLED=true
|
||||
```
|
||||
|
||||
### Docker Service
|
||||
|
||||
```yaml
|
||||
archon-mcp:
|
||||
build: ./python
|
||||
ports:
|
||||
- "8051:8000"
|
||||
environment:
|
||||
- API_BASE_URL=http://archon-server:8080
|
||||
command: ["python", "-m", "src.mcp.mcp_server"]
|
||||
```
|
||||
|
||||
## Client Configuration
|
||||
|
||||
Archon MCP server uses **SSE (Server-Sent Events) transport only**.
|
||||
|
||||
### Cursor IDE
|
||||
|
||||
Add to MCP settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcpServers": {
|
||||
"archon": {
|
||||
"uri": "http://localhost:8051/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Claude Code
|
||||
|
||||
```bash
|
||||
claude mcp add --transport sse archon http://localhost:8051/sse
|
||||
```
|
||||
|
||||
### Windsurf IDE
|
||||
|
||||
Add to settings:
|
||||
|
||||
```json
|
||||
{
|
||||
"mcp.servers": {
|
||||
"archon": {
|
||||
"uri": "http://localhost:8051/sse"
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
## Tool Usage Examples
|
||||
|
||||
### RAG Query
|
||||
```typescript
|
||||
const results = await mcp.perform_rag_query({
|
||||
query: "How to implement authentication",
|
||||
source: "fastapi.tiangolo.com",
|
||||
match_count: 5
|
||||
});
|
||||
```
|
||||
|
||||
### Create Project
|
||||
```typescript
|
||||
const project = await mcp.manage_project({
|
||||
action: "create",
|
||||
title: "New AI Project",
|
||||
github_repo: "https://github.com/user/repo"
|
||||
});
|
||||
```
|
||||
|
||||
### Delete Source
|
||||
```typescript
|
||||
const result = await mcp.delete_source({
|
||||
source: "outdated-docs.com"
|
||||
});
|
||||
```
|
||||
|
||||
## Monitoring
|
||||
|
||||
All MCP operations are tracked in Logfire:
|
||||
- Tool invocation metrics
|
||||
- HTTP request/response times
|
||||
- Error rates and debugging
|
||||
- Session management
|
||||
|
||||
## Important Notes
|
||||
|
||||
- **No business logic** - MCP only translates protocols
|
||||
- **HTTP-only communication** - No direct database access
|
||||
- **Stateless operations** - Each tool call is independent
|
||||
- **Full observability** - Every operation is logged
|
||||
499
docs/docs/mcp-tools.mdx
Normal file
@@ -0,0 +1,499 @@
|
||||
---
|
||||
title: MCP Tools Reference
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 🛠️ MCP Tools Reference
|
||||
|
||||
<div className="hero hero--secondary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
Complete reference for all 14 MCP tools available in Archon, with parameters, return types, and usage examples.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
<Admonition type="info" icon="📚" title="Tool Organization">
|
||||
|
||||
Archon provides 14 MCP tools organized into three categories:
|
||||
- **🧠 RAG & Knowledge Management** (7 tools)
|
||||
- **📊 Project & Task Management** (5 tools)
|
||||
- **🏥 System & Monitoring** (2 tools)
|
||||
|
||||
All tools communicate with the Server service via HTTP APIs.
|
||||
|
||||
</Admonition>
|
||||
|
||||
## 🧠 RAG & Knowledge Management Tools
|
||||
|
||||
### perform_rag_query
|
||||
|
||||
**Purpose**: Perform semantic search across your knowledge base
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `query` | `string` | ✅ | Search query text |
|
||||
| `source` | `string` | ❌ | Filter by source domain |
|
||||
| `match_count` | `integer` | ❌ | Max results (default: 5) |
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": 123,
|
||||
"content": "Matched content...",
|
||||
"url": "https://source.com/page",
|
||||
"title": "Page Title",
|
||||
"similarity_score": 0.92,
|
||||
"metadata": {
|
||||
"source_id": "source.com",
|
||||
"headers": ["Section 1", "Section 2"]
|
||||
}
|
||||
}
|
||||
],
|
||||
"query": "original query",
|
||||
"total_results": 5
|
||||
}
|
||||
```
|
||||
|
||||
**Example Usage**:
|
||||
```
|
||||
"Search for React hooks documentation"
|
||||
|
||||
Tool call:
|
||||
perform_rag_query(
|
||||
query="React hooks useState useEffect",
|
||||
source="react-docs",
|
||||
match_count=10
|
||||
)
|
||||
```
|
||||
|
||||
### search_code_examples
|
||||
|
||||
**Purpose**: Search for code examples with AI-generated summaries
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `query` | `string` | ✅ | Code search query |
|
||||
| `source_id` | `string` | ❌ | Filter by source |
|
||||
| `match_count` | `integer` | ❌ | Max results (default: 5) |
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"results": [
|
||||
{
|
||||
"id": 456,
|
||||
"code": "const [state, setState] = useState(initialValue);",
|
||||
"language": "javascript",
|
||||
"file_path": "hooks/useState.js",
|
||||
"summary": "React useState hook initialization",
|
||||
"url": "https://source.com/examples",
|
||||
"similarity_score": 0.89
|
||||
}
|
||||
],
|
||||
"total_results": 3
|
||||
}
|
||||
```
|
||||
|
||||
### crawl_single_page
|
||||
|
||||
**Purpose**: Crawl and index a single web page
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `url` | `string` | ✅ | URL to crawl |
|
||||
| `chunk_size` | `integer` | ❌ | Chunk size (default: 5000) |
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"url": "https://example.com/page",
|
||||
"title": "Page Title",
|
||||
"chunks_created": 12,
|
||||
"content_length": 45000,
|
||||
"metadata": {
|
||||
"crawled_at": "2024-01-15T10:30:00Z",
|
||||
"processing_time": 2.5
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### smart_crawl_url
|
||||
|
||||
**Purpose**: Intelligently crawl based on URL type (sitemap, text file, or webpage)
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `url` | `string` | ✅ | URL to crawl |
|
||||
| `max_depth` | `integer` | ❌ | Max crawl depth (default: 3) |
|
||||
| `chunk_size` | `integer` | ❌ | Chunk size (default: 5000) |
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"crawl_type": "sitemap",
|
||||
"urls_processed": 150,
|
||||
"chunks_created": 1250,
|
||||
"errors": [],
|
||||
"duration": 180.5,
|
||||
"source_id": "docs.example.com"
|
||||
}
|
||||
```
|
||||
|
||||
**Crawl Types**:
|
||||
- **Sitemap**: Automatically detects and processes sitemap.xml
|
||||
- **Text File**: Direct processing of .txt files
|
||||
- **Webpage**: Recursive crawling following links
|
||||
|
||||
### get_available_sources
|
||||
|
||||
**Purpose**: List all indexed sources in the knowledge base
|
||||
|
||||
**Parameters**: None
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"sources": [
|
||||
{
|
||||
"source_id": "react-docs",
|
||||
"title": "React Documentation",
|
||||
"description": "Official React documentation",
|
||||
"url": "https://react.dev",
|
||||
"document_count": 450,
|
||||
"last_updated": "2024-01-14T08:00:00Z",
|
||||
"tags": ["react", "javascript", "frontend"]
|
||||
}
|
||||
],
|
||||
"total_count": 12
|
||||
}
|
||||
```
|
||||
|
||||
### upload_document
|
||||
|
||||
**Purpose**: Upload and process documents (PDF, Word, Markdown, Text)
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `filename` | `string` | ✅ | Name of the document |
|
||||
| `content` | `string` | ✅ | Document content (base64 for binary) |
|
||||
| `doc_type` | `string` | ❌ | Type: general/technical/business |
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"document": {
|
||||
"id": 789,
|
||||
"filename": "architecture.pdf",
|
||||
"doc_type": "technical",
|
||||
"chunks_created": 45,
|
||||
"processing_time": 5.2,
|
||||
"file_size": 2048576
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### delete_source
|
||||
|
||||
**Purpose**: Remove all content from a specific source
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `source` | `string` | ✅ | Source identifier to delete |
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"source": "old-docs.com",
|
||||
"documents_deleted": 125,
|
||||
"chunks_deleted": 890,
|
||||
"code_examples_deleted": 45
|
||||
}
|
||||
```
|
||||
|
||||
## 📊 Project & Task Management Tools
|
||||
|
||||
### manage_project
|
||||
|
||||
**Purpose**: Unified project management with action-based patterns
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `action` | `string` | ✅ | Action: create/list/get/delete |
|
||||
| `project_id` | `string` | Conditional | Required for get/delete |
|
||||
| `title` | `string` | Conditional | Required for create |
|
||||
| `prd` | `object` | ❌ | Product requirements document |
|
||||
| `github_repo` | `string` | ❌ | GitHub repository URL |
|
||||
|
||||
**Actions & Returns**:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="create" label="Create">
|
||||
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"action": "create",
|
||||
"title": "Authentication System",
|
||||
"github_repo": "https://github.com/team/auth"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"success": true,
|
||||
"project": {
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"title": "Authentication System",
|
||||
"github_repo": "https://github.com/team/auth",
|
||||
"created_at": "2024-01-15T10:00:00Z"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="list" label="List">
|
||||
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"action": "list"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"success": true,
|
||||
"projects": [
|
||||
{
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"title": "Authentication System",
|
||||
"updated_at": "2024-01-15T10:00:00Z"
|
||||
}
|
||||
],
|
||||
"total_count": 5
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="get" label="Get">
|
||||
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"action": "get",
|
||||
"project_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"success": true,
|
||||
"project": {
|
||||
"id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"title": "Authentication System",
|
||||
"prd": {...},
|
||||
"features": [...],
|
||||
"docs": [...]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="delete" label="Delete">
|
||||
|
||||
```json
|
||||
// Request
|
||||
{
|
||||
"action": "delete",
|
||||
"project_id": "550e8400-e29b-41d4-a716-446655440000"
|
||||
}
|
||||
|
||||
// Response
|
||||
{
|
||||
"success": true,
|
||||
"message": "Project deleted successfully"
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### manage_task
|
||||
|
||||
**Purpose**: Complete task lifecycle management
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `action` | `string` | ✅ | Action: create/list/get/update/delete/archive |
|
||||
| `task_id` | `string` | Conditional | Required for get/update/delete/archive |
|
||||
| `project_id` | `string` | Conditional | Required for create, optional for list |
|
||||
| `filter_by` | `string` | ❌ | Filter: status/project |
|
||||
| `filter_value` | `string` | ❌ | Value for filter |
|
||||
| `title` | `string` | Conditional | Required for create |
|
||||
| `description` | `string` | ❌ | Task description |
|
||||
| `assignee` | `string` | ❌ | User/Archon/AI IDE Agent |
|
||||
| `update_fields` | `object` | Conditional | Fields to update |
|
||||
|
||||
**Example Task Creation**:
|
||||
```json
|
||||
{
|
||||
"action": "create",
|
||||
"project_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"title": "Implement login endpoint",
|
||||
"description": "Create POST /api/auth/login endpoint",
|
||||
"assignee": "AI IDE Agent",
|
||||
"sources": [
|
||||
{"name": "Auth Spec", "url": "https://docs/auth"}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
### manage_document
|
||||
|
||||
**Purpose**: Document management within projects
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `action` | `string` | ✅ | Action: add/list/get/update/delete |
|
||||
| `project_id` | `string` | ✅ | Project UUID |
|
||||
| `doc_id` | `string` | Conditional | Required for get/update/delete |
|
||||
| `document_type` | `string` | Conditional | Required for add |
|
||||
| `title` | `string` | Conditional | Required for add |
|
||||
| `content` | `object` | ❌ | Document content |
|
||||
| `metadata` | `object` | ❌ | Tags, status, version |
|
||||
|
||||
### manage_versions
|
||||
|
||||
**Purpose**: Document version control
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `action` | `string` | ✅ | Action: create/list/get/restore |
|
||||
| `project_id` | `string` | ✅ | Project UUID |
|
||||
| `field_name` | `string` | ✅ | Field to version |
|
||||
| `version_number` | `integer` | Conditional | For get/restore |
|
||||
| `content` | `object` | Conditional | For create |
|
||||
| `change_summary` | `string` | ❌ | Version description |
|
||||
|
||||
### get_project_features
|
||||
|
||||
**Purpose**: Retrieve features from a project
|
||||
|
||||
**Parameters**:
|
||||
| Name | Type | Required | Description |
|
||||
|------|------|----------|-------------|
|
||||
| `project_id` | `string` | ✅ | Project UUID |
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"success": true,
|
||||
"features": [
|
||||
{
|
||||
"id": "feat-001",
|
||||
"name": "User Authentication",
|
||||
"description": "Login/logout functionality",
|
||||
"priority": "high",
|
||||
"tasks": ["task-001", "task-002"]
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 🏥 System & Monitoring Tools
|
||||
|
||||
### health_check
|
||||
|
||||
**Purpose**: Check system health and service status
|
||||
|
||||
**Parameters**: None
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"status": "healthy",
|
||||
"services": {
|
||||
"server": "running",
|
||||
"database": "connected",
|
||||
"mcp": "active"
|
||||
},
|
||||
"tools_available": 14,
|
||||
"version": "2.0.0",
|
||||
"uptime": "5:23:45",
|
||||
"last_error": null
|
||||
}
|
||||
```
|
||||
|
||||
### session_info
|
||||
|
||||
**Purpose**: Get MCP session information
|
||||
|
||||
**Parameters**: None
|
||||
|
||||
**Returns**:
|
||||
```json
|
||||
{
|
||||
"current_session": {
|
||||
"id": "abc-123-def",
|
||||
"created_at": "2024-01-15T10:00:00Z",
|
||||
"last_activity": "2024-01-15T10:45:00Z",
|
||||
"client_type": "cursor"
|
||||
},
|
||||
"active_sessions": 3,
|
||||
"total_tool_calls": 1250,
|
||||
"uptime_seconds": 19425
|
||||
}
|
||||
```
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### Error Handling
|
||||
All tools return consistent error responses:
|
||||
```json
|
||||
{
|
||||
"success": false,
|
||||
"error": "Error message",
|
||||
"error_type": "ValidationError",
|
||||
"details": {
|
||||
"field": "url",
|
||||
"message": "Invalid URL format"
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Performance Tips
|
||||
1. **Use source filters** when searching to improve speed
|
||||
2. **Batch operations** when possible (e.g., multiple task creates)
|
||||
3. **Set appropriate chunk_size** for your content type
|
||||
4. **Use match_count** wisely - more results = slower
|
||||
|
||||
### Tool Selection
|
||||
- Use `perform_rag_query` for general searches
|
||||
- Use `search_code_examples` specifically for code
|
||||
- Use `smart_crawl_url` for unknown URL types
|
||||
- Use `manage_*` tools for CRUD operations
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [MCP Server Setup](./mcp-server) - Configure MCP server
|
||||
- [MCP Overview](./mcp-overview) - Architecture overview
|
||||
- [API Reference](./api-reference) - REST API details
|
||||
- [Agent Documentation](./agents-overview) - How agents use tools
|
||||
170
docs/docs/projects-features.mdx
Normal file
@@ -0,0 +1,170 @@
|
||||
---
|
||||
title: Archon Projects Features
|
||||
sidebar_position: 2
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 📊 Archon Projects: Complete Feature Reference
|
||||
|
||||
<div className="hero hero--secondary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
Everything you can do with Archon Projects - from simple task tracking to complex project orchestration with AI assistance.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎯 Core Project Management Features
|
||||
|
||||
### Project Organization
|
||||
- **Organized Structure**: Projects contain tasks, documents, and features
|
||||
- **GitHub Integration**: Link projects to repositories for seamless context
|
||||
- **PRD Management**: Store and version Product Requirements Documents
|
||||
- **Feature Tracking**: Organize work by features with associated tasks
|
||||
|
||||
### Task Management
|
||||
- **Status Workflow**: Todo → Doing → Review → Done
|
||||
- **Task Organization**: Group related tasks together
|
||||
- **Task Assignment**: Assign to User, Archon, or AI IDE Agent
|
||||
- **Priority Levels**: High, Medium, Low priority organization
|
||||
- **Archive Support**: Soft delete with recovery options
|
||||
|
||||
### Document Management
|
||||
- **Multiple Document Types**: PRDs, specs, notes, documentation
|
||||
- **Version Control**: Automatic versioning with restore capabilities
|
||||
- **Rich Text Editing**: BlockNote editor for formatted content
|
||||
- **Metadata Tracking**: Tags, status, author information
|
||||
|
||||
## 🤖 AI Integration Features
|
||||
|
||||
### MCP Tools Available
|
||||
|
||||
<div className="row">
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>Project Tools</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li><code>manage_project</code> - Create, list, get, delete projects</li>
|
||||
<li><code>manage_task</code> - Full task lifecycle management</li>
|
||||
<li><code>manage_document</code> - Document CRUD operations</li>
|
||||
<li><code>manage_versions</code> - Version control operations</li>
|
||||
<li><code>get_project_features</code> - Retrieve project features</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
<div className="col col--6">
|
||||
<div className="card">
|
||||
<div className="card__header">
|
||||
<h4>AI Capabilities</h4>
|
||||
</div>
|
||||
<div className="card__body">
|
||||
<ul>
|
||||
<li>AI can create projects from requirements</li>
|
||||
<li>Automatic task breakdown from descriptions</li>
|
||||
<li>Smart task prioritization</li>
|
||||
<li>Context-aware task suggestions</li>
|
||||
<li>Automated status updates</li>
|
||||
</ul>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎨 User Interface Features
|
||||
|
||||
### Views Available
|
||||
1. **Board View**: Kanban-style task organization
|
||||
2. **Table View**: Spreadsheet-like task management
|
||||
3. **Project Dashboard**: Overview with tabs for Docs, Features, Data
|
||||
|
||||
### Interactive Elements
|
||||
- **Drag & Drop**: Move tasks between status columns
|
||||
- **Quick Actions**: Single-click status updates
|
||||
- **Real-time Updates**: Socket.IO powered live synchronization
|
||||
- **Search & Filter**: Find tasks by status, assignee, or text
|
||||
|
||||
## 🔧 Technical Capabilities
|
||||
|
||||
### Backend Services
|
||||
- **Project Service**: Core project operations
|
||||
- **Task Service**: Task management logic
|
||||
- **Document Service**: Document handling
|
||||
- **Versioning Service**: Version control system
|
||||
|
||||
### Database Schema
|
||||
- **Projects Table**: Stores project metadata and JSONB fields
|
||||
- **Tasks Table**: Task storage with project relationships
|
||||
- **Project Versions**: Complete version history
|
||||
|
||||
### API Endpoints
|
||||
- `POST /api/projects` - Create new project
|
||||
- `GET /api/projects` - List all projects
|
||||
- `GET /api/projects/:id` - Get project details
|
||||
- `DELETE /api/projects/:id` - Delete project
|
||||
- `GET /api/tasks` - List tasks with filters
|
||||
- `POST /api/tasks` - Create new task
|
||||
- `PATCH /api/tasks/:id` - Update task
|
||||
- `POST /api/tasks/:id/archive` - Archive task
|
||||
|
||||
## 🚀 Advanced Features
|
||||
|
||||
### Workflow Automation
|
||||
- **Smart Task Creation**: AI analyzes requirements and creates tasks
|
||||
- **Automatic Linking**: Connect tasks to code examples and documentation
|
||||
- **Progress Tracking**: Real-time progress updates via Socket.IO
|
||||
|
||||
### Integration Points
|
||||
- **Knowledge Base**: Link tasks to documentation
|
||||
- **Code Examples**: Attach relevant code snippets
|
||||
- **Source References**: Connect to crawled content
|
||||
|
||||
### Collaboration Features
|
||||
- **Multi-Agent Support**: Multiple AI assistants can work on tasks
|
||||
- **Activity Tracking**: See who (human or AI) did what
|
||||
- **Comment System**: Discussion threads on tasks
|
||||
|
||||
## 📊 Usage Examples
|
||||
|
||||
### Creating a Project with AI
|
||||
```
|
||||
AI Assistant: "Create a new project for building a user authentication system"
|
||||
```
|
||||
The AI will:
|
||||
1. Create the project with appropriate metadata
|
||||
2. Generate initial tasks based on common patterns
|
||||
3. Set up a basic PRD structure
|
||||
4. Link to relevant documentation
|
||||
|
||||
### Task Breakdown
|
||||
```
|
||||
AI Assistant: "Break down the 'Implement login form' task into smaller tasks"
|
||||
```
|
||||
The AI will create:
|
||||
- Design login UI component
|
||||
- Implement form validation
|
||||
- Add authentication API call
|
||||
- Handle error states
|
||||
- Write unit tests
|
||||
|
||||
### Smart Status Updates
|
||||
```
|
||||
AI Assistant: "Update all testing tasks to 'In Progress'"
|
||||
```
|
||||
The AI will:
|
||||
- Find all tasks with "test" in the title
|
||||
- Update their status appropriately
|
||||
- Add notes about the changes
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [Projects Overview](./projects-overview) - High-level introduction
|
||||
- [API Reference](./api-reference#project-management-api) - Detailed API documentation
|
||||
- [MCP Tools Reference](./mcp-tools#project-tools) - MCP tool specifications
|
||||
- [Task Agent Documentation](./agent-task) - How the AI manages tasks
|
||||
786
docs/docs/projects-overview.mdx
Normal file
@@ -0,0 +1,786 @@
|
||||
---
|
||||
title: Archon Projects Overview
|
||||
sidebar_position: 1
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 📊 Archon Projects: AI-Powered Project Management
|
||||
|
||||
<div className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**Manage your development projects** with AI assistance. Track tasks, organize documentation, and connect your entire workflow with Cursor, Windsurf, and other AI coding assistants.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Archon Projects brings intelligent project management to your AI development workflow. Your AI assistants can understand project context, create and update tasks, manage documentation, and help you stay organized while you code.
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
The Archon task management system provides:
|
||||
|
||||
- **Project Organization**: Structured project management with PRDs, features, and documentation
|
||||
- **Task Organization**: Organize and group related tasks
|
||||
- **Status Tracking**: Todo, Doing, Review, Done status management
|
||||
- **MCP Integration**: AI agents can create, update, and query tasks autonomously
|
||||
- **Reference Management**: Link tasks to code examples and documentation sources
|
||||
- **GitHub Integration**: Connect projects to repositories for context
|
||||
|
||||
## 🏗️ System Architecture
|
||||
|
||||
```mermaid
|
||||
%%{init:{
|
||||
'theme':'base',
|
||||
'themeVariables': {
|
||||
'primaryColor':'#1f2937',
|
||||
'primaryTextColor':'#ffffff',
|
||||
'primaryBorderColor':'#8b5cf6',
|
||||
'lineColor':'#a855f7',
|
||||
'textColor':'#ffffff',
|
||||
'fontFamily':'Inter',
|
||||
'fontSize':'14px',
|
||||
'background':'#000000',
|
||||
'mainBkg':'#1f2937',
|
||||
'secondBkg':'#111827',
|
||||
'borderColor':'#8b5cf6',
|
||||
'clusterBkg':'#111827',
|
||||
'clusterBorder':'#8b5cf6'
|
||||
}
|
||||
}}%%
|
||||
graph TB
|
||||
subgraph "Frontend (React)"
|
||||
TaskUI(Project Management UI)
|
||||
ProjectUI(Project Dashboard)
|
||||
end
|
||||
|
||||
subgraph "Backend API"
|
||||
ProjectAPI["Projects API<br/>Service Layer"]
|
||||
TaskAPI["Task Management<br/>Endpoints"]
|
||||
MCPTools["MCP Project Tools<br/>5 consolidated tools"]
|
||||
end
|
||||
|
||||
subgraph "Service Layer"
|
||||
ProjectService["ProjectService<br/>Project operations"]
|
||||
TaskService["TaskService<br/>Task operations"]
|
||||
DocumentService["DocumentService<br/>Document operations"]
|
||||
VersioningService["VersioningService<br/>Version control"]
|
||||
end
|
||||
|
||||
subgraph "Database (Supabase)"
|
||||
ProjectsTable(("projects table"))
|
||||
TasksTable(("tasks table"))
|
||||
VersionsTable(("document_versions"))
|
||||
end
|
||||
|
||||
subgraph "AI Clients"
|
||||
Cursor(Cursor IDE)
|
||||
Windsurf(Windsurf IDE)
|
||||
Claude(Claude Code)
|
||||
end
|
||||
|
||||
TaskUI --> ProjectAPI
|
||||
ProjectUI --> ProjectAPI
|
||||
|
||||
ProjectAPI --> ProjectService
|
||||
ProjectAPI --> TaskService
|
||||
ProjectAPI --> DocumentService
|
||||
|
||||
MCPTools --> ProjectService
|
||||
MCPTools --> TaskService
|
||||
MCPTools --> DocumentService
|
||||
MCPTools --> VersioningService
|
||||
|
||||
ProjectService --> ProjectsTable
|
||||
TaskService --> TasksTable
|
||||
DocumentService --> ProjectsTable
|
||||
VersioningService --> VersionsTable
|
||||
|
||||
Cursor --> MCPTools
|
||||
Windsurf --> MCPTools
|
||||
Claude --> MCPTools
|
||||
```
|
||||
|
||||
## 📊 Data Structure
|
||||
|
||||
Archon uses a simple but flexible data structure:
|
||||
|
||||
- **Projects**: Main containers with title, description, PRD, features, and GitHub integration
|
||||
- **Tasks**: Organized under projects with logical grouping
|
||||
- **Documents**: JSONB-based document storage for PRDs, specs, and other project docs
|
||||
- **Status Tracking**: Simple workflow - Todo → Doing → Review → Done
|
||||
|
||||
## 🚀 Getting Started
|
||||
|
||||
### Creating Your First Project
|
||||
|
||||
#### Via Web Interface
|
||||
|
||||
1. **Open Archon**: Navigate to http://localhost:3737
|
||||
2. **Go to Projects**: Click the "Projects" tab in the navigation
|
||||
3. **Create Project**: Click "New Project"
|
||||
4. **Fill Details**:
|
||||
- **Title**: "My Documentation Project"
|
||||
- **Description**: Brief project overview
|
||||
- **GitHub Repo**: (optional) Repository URL
|
||||
5. **Save Project**: Click "Create"
|
||||
|
||||
#### Via API
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/projects" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"title": "API Documentation Overhaul",
|
||||
"prd": {
|
||||
"overview": "Improve API documentation for better developer experience",
|
||||
"goals": [
|
||||
"Add comprehensive examples",
|
||||
"Improve navigation structure",
|
||||
"Add interactive API explorer"
|
||||
],
|
||||
"success_criteria": [
|
||||
"Reduce support tickets by 30%",
|
||||
"Increase API adoption by 50%"
|
||||
]
|
||||
},
|
||||
"github_repo": "https://github.com/company/api-docs"
|
||||
}'
|
||||
```
|
||||
|
||||
#### Via MCP (AI Agent)
|
||||
|
||||
AI agents can autonomously create projects:
|
||||
|
||||
```
|
||||
User: "I need to start a new project to improve our API documentation"
|
||||
AI: [Uses create_project MCP tool]
|
||||
"I've created a new project 'API Documentation Improvement' with a comprehensive PRD..."
|
||||
```
|
||||
|
||||
### Creating Tasks
|
||||
|
||||
#### Via Web Interface
|
||||
|
||||
1. **Select Project**: Choose your project from the project list
|
||||
2. **Add Task**: Click "New Task"
|
||||
3. **Fill Details**:
|
||||
- **Title**: Clear, actionable task name
|
||||
- **Description**: Detailed requirements
|
||||
- **Status**: Initial status (usually "todo")
|
||||
- **Assignee**: Choose from User, Archon, or AI IDE Agent
|
||||
- **Sources**: Add reference documentation
|
||||
- **Code Examples**: Add relevant code snippets
|
||||
4. **Save Task**: Click "Create"
|
||||
|
||||
#### Via API
|
||||
|
||||
```bash
|
||||
curl -X POST "http://localhost:8080/api/tasks" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"project_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"title": "Create authentication examples",
|
||||
"description": "Write comprehensive examples showing how to implement JWT authentication with our API, including token generation, validation, and error handling.",
|
||||
"assignee": "Archon",
|
||||
"sources": [
|
||||
{
|
||||
"name": "JWT.io Introduction",
|
||||
"url": "https://jwt.io/introduction/",
|
||||
"description": "Basic JWT concepts and structure"
|
||||
},
|
||||
{
|
||||
"name": "FastAPI Security",
|
||||
"url": "https://fastapi.tiangolo.com/tutorial/security/",
|
||||
"description": "FastAPI authentication patterns"
|
||||
}
|
||||
],
|
||||
"code_examples": [
|
||||
{
|
||||
"language": "python",
|
||||
"description": "JWT token generation",
|
||||
"code": "import jwt\nfrom datetime import datetime, timedelta\n\ndef create_token(user_id: str) -> str:\n payload = {\n 'user_id': user_id,\n 'exp': datetime.utcnow() + timedelta(hours=24)\n }\n return jwt.encode(payload, SECRET_KEY, algorithm='HS256')"
|
||||
}
|
||||
],
|
||||
"status": "todo"
|
||||
}'
|
||||
```
|
||||
|
||||
## 🔧 Task Management Features
|
||||
|
||||
### Task Organization
|
||||
|
||||
Break down complex work into manageable tasks:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="api" label="API Example">
|
||||
|
||||
```bash
|
||||
# Create main task
|
||||
curl -X POST "http://localhost:8080/api/tasks" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"project_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"title": "Implement user authentication system",
|
||||
"description": "Complete authentication system with JWT tokens",
|
||||
"status": "todo"
|
||||
}'
|
||||
|
||||
# Create related tasks
|
||||
curl -X POST "http://localhost:8080/api/tasks" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"project_id": "550e8400-e29b-41d4-a716-446655440000",
|
||||
"title": "Design JWT token structure",
|
||||
"description": "Define token payload and expiration strategy",
|
||||
"status": "todo",
|
||||
"feature": "Authentication"
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="mcp" label="MCP (AI) Example">
|
||||
|
||||
```
|
||||
User: "Break down the authentication task into smaller pieces"
|
||||
AI: [Uses create_task MCP tool multiple times]
|
||||
"I've broken down your authentication task into 5 related tasks:
|
||||
1. Design JWT token structure
|
||||
2. Implement token generation
|
||||
3. Create middleware for validation
|
||||
4. Add authentication endpoints
|
||||
5. Write comprehensive tests"
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Status Management
|
||||
|
||||
Update task status as work progresses:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="api" label="API Status Update">
|
||||
|
||||
```bash
|
||||
# Update task status
|
||||
curl -X PATCH "http://localhost:8080/api/tasks/task-uuid-here" \
|
||||
-H "Content-Type: application/json" \
|
||||
-d '{
|
||||
"status": "doing",
|
||||
"description": "Started implementing JWT token generation. Updated payload structure to include user roles and permissions."
|
||||
}'
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="mcp" label="MCP Status Update">
|
||||
|
||||
```
|
||||
User: "I finished implementing the authentication middleware"
|
||||
AI: [Uses update_task_status MCP tool]
|
||||
"Great! I've updated the authentication middleware task to 'done' and added your completion notes."
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
#### Status Workflow
|
||||
|
||||
```mermaid
|
||||
%%{init:{
|
||||
'theme':'base',
|
||||
'themeVariables': {
|
||||
'primaryColor':'#1f2937',
|
||||
'primaryTextColor':'#ffffff',
|
||||
'primaryBorderColor':'#8b5cf6',
|
||||
'lineColor':'#a855f7',
|
||||
'textColor':'#ffffff',
|
||||
'fontFamily':'Inter',
|
||||
'fontSize':'14px',
|
||||
'background':'#000000',
|
||||
'mainBkg':'#1f2937',
|
||||
'secondBkg':'#111827',
|
||||
'borderColor':'#8b5cf6'
|
||||
}
|
||||
}}%%
|
||||
flowchart TD
|
||||
A["Task Created"] --> B["todo"]
|
||||
B --> C{"Dependencies Met?"}
|
||||
C -->|Yes| D["doing"]
|
||||
C -->|No| E["review"]
|
||||
E --> F{"Dependencies Resolved?"}
|
||||
F -->|Yes| D
|
||||
F -->|No| E
|
||||
D --> G{"Work Complete?"}
|
||||
G -->|Yes| H["done"]
|
||||
G -->|No| I{"Blocked?"}
|
||||
I -->|Yes| E
|
||||
I -->|No| D
|
||||
```
|
||||
|
||||
### Task Filtering and Queries
|
||||
|
||||
#### Get Tasks by Status
|
||||
|
||||
```bash
|
||||
# Get all "doing" tasks
|
||||
curl "http://localhost:8080/api/tasks?status=doing"
|
||||
|
||||
# Get all tasks for a project
|
||||
curl "http://localhost:8080/api/tasks?project_id=550e8400-e29b-41d4-a716-446655440000"
|
||||
|
||||
# Get tasks by feature
|
||||
curl "http://localhost:8080/api/tasks?project_id=550e8400-e29b-41d4-a716-446655440000&feature=Authentication"
|
||||
```
|
||||
|
||||
#### Advanced Filtering
|
||||
|
||||
```bash
|
||||
# Get tasks by status with project filter
|
||||
curl "http://localhost:8080/api/tasks?project_id=550e8400-e29b-41d4-a716-446655440000&status=review"
|
||||
```
|
||||
|
||||
## 🤖 MCP Integration
|
||||
|
||||
AI coding assistants can autonomously manage tasks through MCP tools:
|
||||
|
||||
### Available MCP Tools (5 Consolidated Tools)
|
||||
|
||||
<Admonition type="success" title="Streamlined MCP Tools">
|
||||
Following MCP best practices, we've consolidated 22 individual tools into 5 flexible, action-based tools. This provides better performance, easier maintenance, and more intuitive usage for AI agents.
|
||||
</Admonition>
|
||||
|
||||
#### Consolidated Project & Task Tools
|
||||
|
||||
| Tool | Actions | Description | Parameters |
|
||||
|------|---------|-------------|------------|
|
||||
| **`manage_project`** | `create`, `list`, `get`, `delete` | Complete project lifecycle | `action`, `project_id`, `title`, `prd`, `github_repo` |
|
||||
| **`manage_task`** | `create`, `list`, `get`, `update`, `delete`, `archive` | All task operations | `action`, `task_id`, `project_id`, `filter_by`, `filter_value`, `update_fields` |
|
||||
| **`manage_document`** | `add`, `list`, `get`, `update`, `delete` | Document management *(Not yet implemented)* | `action`, `project_id`, `doc_id`, `document_type`, `title`, `content`, `metadata` |
|
||||
| **`manage_versions`** | `create`, `list`, `get`, `restore` | Version control *(Not yet implemented)* | `action`, `project_id`, `field_name`, `version_number`, `content` |
|
||||
| **`get_project_features`** | *(query only)* | Retrieve features | `project_id` |
|
||||
|
||||
<Admonition type="info" title="Implementation Status">
|
||||
The `manage_document` and `manage_versions` tools are defined in the MCP module but require corresponding Server API endpoints to be implemented. Currently, these tools will return "not yet implemented" errors. The other tools (`manage_project`, `manage_task`, and `get_project_features`) are fully functional.
|
||||
</Admonition>
|
||||
|
||||
#### Action Patterns
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="project" label="Project Operations">
|
||||
|
||||
```python
|
||||
# Create a new project
|
||||
result = await manage_project(
|
||||
action="create",
|
||||
title="AI Documentation System",
|
||||
prd={"overview": "Automated docs generation", "goals": ["Generate API docs", "Maintain accuracy"]},
|
||||
github_repo="https://github.com/user/ai-docs"
|
||||
)
|
||||
|
||||
# List all projects
|
||||
projects = await manage_project(action="list")
|
||||
|
||||
# Get specific project
|
||||
project = await manage_project(
|
||||
action="get",
|
||||
project_id="550e8400-e29b-41d4-a716-446655440000"
|
||||
)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="task" label="Task Operations">
|
||||
|
||||
```python
|
||||
# Create a task
|
||||
task = await manage_task(
|
||||
action="create",
|
||||
project_id="project-uuid",
|
||||
title="Implement JWT authentication",
|
||||
description="Add JWT-based auth to all API endpoints",
|
||||
assignee="Archon"
|
||||
)
|
||||
|
||||
# Update task status
|
||||
await manage_task(
|
||||
action="update",
|
||||
task_id="task-uuid",
|
||||
update_fields={"status": "done", "description": "Completed with tests"}
|
||||
)
|
||||
|
||||
# List tasks by status
|
||||
tasks = await manage_task(
|
||||
action="list",
|
||||
filter_by="status",
|
||||
filter_value="doing",
|
||||
project_id="project-uuid"
|
||||
)
|
||||
|
||||
# Get tasks by feature
|
||||
tasks = await manage_task(
|
||||
action="list",
|
||||
project_id="project-uuid",
|
||||
feature="Authentication"
|
||||
)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="document" label="Document Operations">
|
||||
|
||||
```python
|
||||
# Add a document (MUST use clean MCP format)
|
||||
doc = await manage_document(
|
||||
action="add",
|
||||
project_id="project-uuid",
|
||||
document_type="prd",
|
||||
title="System Architecture Document",
|
||||
content={
|
||||
"project_overview": {
|
||||
"description": "Microservices architecture",
|
||||
"target_completion": "Q2 2024"
|
||||
},
|
||||
"architecture": {
|
||||
"frontend": ["React", "TypeScript"],
|
||||
"backend": ["FastAPI", "PostgreSQL"]
|
||||
}
|
||||
},
|
||||
metadata={
|
||||
"tags": ["architecture", "technical"],
|
||||
"author": "System Architect"
|
||||
}
|
||||
)
|
||||
|
||||
# Update document
|
||||
await manage_document(
|
||||
action="update",
|
||||
project_id="project-uuid",
|
||||
doc_id="doc-uuid",
|
||||
content={
|
||||
"project_overview": {
|
||||
"description": "Updated microservices architecture with event sourcing"
|
||||
}
|
||||
}
|
||||
)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Admonition type="warning" title="Document Format Requirements">
|
||||
When using `manage_document` with `add` or `update` actions, the `content` field MUST follow the structured MCP format. The UI will automatically convert this to editable blocks. Do not use flat text or unstructured data.
|
||||
</Admonition>
|
||||
|
||||
### AI-Driven Task Management Examples
|
||||
|
||||
#### Scenario 1: Project Planning
|
||||
|
||||
**User Prompt**:
|
||||
```
|
||||
I need to plan a new feature for user profile management.
|
||||
Create a project and break it down into tasks.
|
||||
```
|
||||
|
||||
**AI Actions**:
|
||||
1. `manage_project` with `action="create"` - Creates "User Profile Management" project with comprehensive PRD
|
||||
2. `perform_rag_query` - Finds existing user management patterns in knowledge base
|
||||
3. `manage_task` with `action="create"` (multiple calls) - Creates structured task breakdown:
|
||||
- Design user profile schema
|
||||
- Implement profile CRUD endpoints
|
||||
- Add profile validation
|
||||
- Create profile UI components
|
||||
- Write integration tests
|
||||
4. Links relevant documentation in task sources
|
||||
|
||||
#### Scenario 2: Progress Tracking
|
||||
|
||||
**User Prompt**:
|
||||
```
|
||||
I just finished implementing the user registration endpoint.
|
||||
Update my tasks and suggest what to work on next.
|
||||
```
|
||||
|
||||
**AI Actions**:
|
||||
1. `manage_task` with `action="list"` and `filter_by="project"` - Gets current project tasks
|
||||
2. `manage_task` with `filter_by="status"` and `filter_value="doing"` - Finds active tasks
|
||||
3. `manage_task` with `action="update"` - Marks registration task as "done"
|
||||
4. `manage_task` with `filter_by="status"` and `filter_value="todo"` - Finds next tasks
|
||||
5. Provides recommendations for next priority tasks
|
||||
|
||||
#### Scenario 3: Code Review Integration
|
||||
|
||||
**User Prompt**:
|
||||
```
|
||||
Review this authentication code and create tasks for any improvements needed:
|
||||
[code snippet]
|
||||
```
|
||||
|
||||
**AI Actions**:
|
||||
1. `perform_rag_query` - Finds coding standards and security patterns
|
||||
2. Analyzes code against documented best practices
|
||||
3. `manage_task` with `action="create"` - Creates improvement tasks:
|
||||
- Add input validation
|
||||
- Implement rate limiting
|
||||
- Add comprehensive error handling
|
||||
- Improve test coverage
|
||||
4. `manage_document` with `action="add"` - Documents findings
|
||||
5. Sets appropriate priorities and dependencies
|
||||
|
||||
## 📊 Project Management Patterns
|
||||
|
||||
### PRD (Product Requirements Document) Structure
|
||||
|
||||
When creating projects, Archon automatically generates a structured PRD:
|
||||
|
||||
```json
|
||||
{
|
||||
"prd": {
|
||||
"overview": "Clear description of what we're building and why",
|
||||
"problem_statement": "What problem are we solving?",
|
||||
"goals": [
|
||||
"Specific, measurable objectives",
|
||||
"User experience improvements",
|
||||
"Technical achievements"
|
||||
],
|
||||
"success_criteria": [
|
||||
"Quantifiable success metrics",
|
||||
"User satisfaction targets",
|
||||
"Performance benchmarks"
|
||||
],
|
||||
"scope": {
|
||||
"in_scope": ["Features to include"],
|
||||
"out_of_scope": ["Features explicitly excluded"]
|
||||
},
|
||||
"technical_requirements": [
|
||||
"Performance requirements",
|
||||
"Security requirements",
|
||||
"Scalability requirements"
|
||||
],
|
||||
"stakeholders": [
|
||||
{
|
||||
"name": "Product Manager",
|
||||
"role": "Requirements owner",
|
||||
"contact": "pm@company.com"
|
||||
}
|
||||
]
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Document Management
|
||||
|
||||
Projects can contain various types of documents:
|
||||
|
||||
- **PRD (Product Requirements Document)**: Project overview, goals, and technical requirements
|
||||
- **Technical Specs**: Detailed implementation plans and architecture
|
||||
- **Feature Plans**: Feature breakdowns and user stories
|
||||
- **Meeting Notes**: Team discussions and decisions
|
||||
|
||||
Documents are stored in a structured format that works well with AI agents while providing rich editing through the BlockNote editor.
|
||||
|
||||
### Feature Tracking
|
||||
|
||||
Track feature development progress:
|
||||
|
||||
```json
|
||||
{
|
||||
"features": [
|
||||
{
|
||||
"name": "User Authentication",
|
||||
"status": "done",
|
||||
"priority": "high",
|
||||
"effort_estimate": "5 days",
|
||||
"actual_effort": "4 days",
|
||||
"dependencies": [],
|
||||
"tasks": [
|
||||
"660e8400-e29b-41d4-a716-446655440001",
|
||||
"660e8400-e29b-41d4-a716-446655440002"
|
||||
]
|
||||
},
|
||||
{
|
||||
"name": "User Profile Management",
|
||||
"status": "in_progress",
|
||||
"priority": "medium",
|
||||
"effort_estimate": "8 days",
|
||||
"dependencies": ["User Authentication"],
|
||||
"blockers": []
|
||||
}
|
||||
]
|
||||
}
|
||||
```
|
||||
|
||||
## 🎨 Frontend Integration
|
||||
|
||||
The React frontend (`ProjectPage.tsx` - 593 lines) provides intuitive task management interfaces:
|
||||
|
||||
### Project Dashboard Features
|
||||
|
||||
- **Project Overview**: Title, description, GitHub integration
|
||||
- **Task Summary**: Status breakdown, progress indicators
|
||||
- **Document Management**: PRD viewer, document creation
|
||||
- **Feature Tracking**: Feature status and dependencies
|
||||
|
||||
### Task Management Interface
|
||||
|
||||
- **Task List**: Filterable by status, searchable
|
||||
- **Task Details**: Full task information, sources, code examples
|
||||
- **Status Updates**: Drag-and-drop status changes
|
||||
- **Task Grouping**: Organize tasks by feature or category
|
||||
|
||||
### Real-time Updates
|
||||
|
||||
The frontend receives real-time updates via Socket.IO connections when:
|
||||
- Tasks are created or updated by AI agents
|
||||
- Project status changes
|
||||
- Documents are added or modified
|
||||
|
||||
## 📈 Progress Tracking
|
||||
|
||||
Archon provides built-in progress tracking:
|
||||
|
||||
- **Project completion percentage** based on completed tasks
|
||||
- **Task velocity** showing development pace over time
|
||||
- **Status distribution** showing work distribution across todo/doing/review/done
|
||||
- **Real-time updates** via Socket.IO when AI agents or users update tasks
|
||||
|
||||
## 🔍 Best Practices
|
||||
|
||||
### Task Writing Guidelines
|
||||
|
||||
#### Good Task Examples
|
||||
|
||||
✅ **Good**: "Implement JWT authentication middleware for FastAPI"
|
||||
- Specific technology mentioned
|
||||
- Clear deliverable
|
||||
- Actionable
|
||||
|
||||
✅ **Good**: "Write unit tests for user registration endpoint covering happy path and validation errors"
|
||||
- Specific scope
|
||||
- Clear acceptance criteria
|
||||
- Testable outcome
|
||||
|
||||
#### Poor Task Examples
|
||||
|
||||
❌ **Poor**: "Fix authentication"
|
||||
- Too vague
|
||||
- No clear scope
|
||||
- Not actionable
|
||||
|
||||
❌ **Poor**: "Make the app better"
|
||||
- No specific deliverable
|
||||
- Subjective criteria
|
||||
- Not measurable
|
||||
|
||||
### Project Organization
|
||||
|
||||
#### Recommended Project Structure
|
||||
|
||||
```
|
||||
Project: "User Management System"
|
||||
├── Epic: "Authentication"
|
||||
│ ├── Task: "Design JWT token structure"
|
||||
│ ├── Task: "Implement login endpoint"
|
||||
│ ├── Task: "Implement logout endpoint"
|
||||
│ └── Task: "Add authentication middleware"
|
||||
├── Epic: "User Profiles"
|
||||
│ ├── Task: "Design user profile schema"
|
||||
│ ├── Task: "Implement profile CRUD endpoints"
|
||||
│ └── Task: "Add profile validation"
|
||||
└── Epic: "Testing & Documentation"
|
||||
├── Task: "Write integration tests"
|
||||
├── Task: "Update API documentation"
|
||||
└── Task: "Create user guides"
|
||||
```
|
||||
|
||||
### Status Management Best Practices
|
||||
|
||||
#### When to Use Each Status
|
||||
|
||||
- **Todo**: Task is ready to start, all dependencies met
|
||||
- **Doing**: Work is actively in progress
|
||||
- **Blocked**: Cannot proceed due to external dependencies
|
||||
- **Done**: Task is completed and verified
|
||||
|
||||
#### Status Transition Guidelines
|
||||
|
||||
```mermaid
|
||||
flowchart TD
|
||||
A["Task Created"] --> B["todo"]
|
||||
B --> C{"Dependencies Met?"}
|
||||
C -->|Yes| D["doing"]
|
||||
C -->|No| E["review"]
|
||||
E --> F{"Dependencies Resolved?"}
|
||||
F -->|Yes| D
|
||||
F -->|No| E
|
||||
D --> G{"Work Complete?"}
|
||||
G -->|Yes| H["done"]
|
||||
G -->|No| I{"Blocked?"}
|
||||
I -->|Yes| E
|
||||
I -->|No| D
|
||||
```
|
||||
|
||||
## 🚀 Integration Examples
|
||||
|
||||
### Cursor IDE Integration
|
||||
|
||||
Example of AI-assisted task management in Cursor:
|
||||
|
||||
```
|
||||
User: "I need to implement user authentication for our API"
|
||||
|
||||
AI Response:
|
||||
I'll help you plan the authentication implementation. Let me create a project and break this down into manageable tasks.
|
||||
|
||||
[AI uses MCP tools to:]
|
||||
1. manage_project(action="create") with authentication project details
|
||||
2. perform_rag_query("FastAPI authentication JWT")
|
||||
3. manage_task(action="create") for each implementation step
|
||||
4. Link relevant documentation from knowledge base
|
||||
|
||||
I've created a project "User Authentication System" with the following tasks:
|
||||
|
||||
1. ✅ Design JWT token structure
|
||||
- Status: todo
|
||||
- Sources: FastAPI Security docs, JWT.io guide
|
||||
- Code examples: Token generation and validation
|
||||
|
||||
2. ✅ Implement authentication middleware
|
||||
- Status: todo
|
||||
- Sources: FastAPI middleware documentation
|
||||
- Code examples: Dependency injection patterns
|
||||
|
||||
3. ✅ Create login/logout endpoints
|
||||
- Status: todo
|
||||
- Sources: FastAPI routing documentation
|
||||
- Code examples: Request/response models
|
||||
|
||||
4. ✅ Add password hashing
|
||||
- Status: todo
|
||||
- Sources: Security best practices
|
||||
- Code examples: bcrypt implementation
|
||||
|
||||
5. ✅ Write authentication tests
|
||||
- Status: todo
|
||||
- Sources: FastAPI testing guide
|
||||
- Code examples: Test fixtures and mocks
|
||||
|
||||
Would you like me to start with any specific task?
|
||||
```
|
||||
|
||||
### GitHub Integration
|
||||
|
||||
Projects can be linked to GitHub repositories for context. Future versions will include bidirectional sync with GitHub issues and pull requests.
|
||||
|
||||
## 🔮 What's Next
|
||||
|
||||
Upcoming features include time tracking, task templates, team collaboration, and enhanced GitHub integration.
|
||||
|
||||
---
|
||||
|
||||
**Next Steps**:
|
||||
- Learn about [RAG System](./rag) for knowledge-driven task creation
|
||||
- Explore [User Interface](./ui) for task management workflows
|
||||
- Check [API Reference](./api-reference) for programmatic task management
|
||||
- Review [MCP Integration](./mcp-overview) for AI client setup
|
||||
396
docs/docs/rag.mdx
Normal file
@@ -0,0 +1,396 @@
|
||||
---
|
||||
title: 🧠 RAG Configuration & Strategies
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 🧠 RAG Configuration & Strategies
|
||||
|
||||
<div className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**Configure intelligent search and retrieval** for optimal AI responses using advanced RAG strategies
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 🎯 Overview
|
||||
|
||||
Archon's RAG (Retrieval-Augmented Generation) system provides configurable search strategies to optimize how your AI agents find and use information from your knowledge base. This guide covers configuration options and optimization strategies.
|
||||
|
||||
<Admonition type="tip" icon="⚡" title="Quick Configuration">
|
||||
Access RAG settings in the **Web Interface** → **Settings** → **RAG Settings** for easy configuration without code changes.
|
||||
</Admonition>
|
||||
|
||||
## 🛠️ RAG Configuration Options
|
||||
|
||||
### Core Settings
|
||||
|
||||
| Setting | Description | Default | Impact |
|
||||
|---------|-------------|---------|--------|
|
||||
| **MODEL_CHOICE** | Chat model for query enhancement | `gpt-4o-mini` | Response quality |
|
||||
| **EMBEDDING_MODEL** | Model for vector embeddings | `text-embedding-3-small` | Search accuracy |
|
||||
| **LLM_PROVIDER** | Provider (openai/google/ollama/) | `openai` | Model availability |
|
||||
|
||||
### Advanced Strategies
|
||||
|
||||
| Strategy | Purpose | Performance Impact | Use Cases |
|
||||
|----------|---------|-------------------|-----------|
|
||||
| **Contextual Embeddings** | Enhanced embeddings with context | +30% accuracy, +2x time | Technical docs, code |
|
||||
| **Hybrid Search** | Vector + keyword combination | +20% accuracy, +50% time | Mixed content types |
|
||||
| **Agentic RAG** | AI-powered query enhancement | +40% accuracy, +3x time | Complex queries |
|
||||
| **Reranking** | AI-powered result reordering | +25% accuracy, +2x time | High-precision needs |
|
||||
|
||||
## ⚙️ Configuration Strategies
|
||||
|
||||
### 1. Basic Configuration (Fastest)
|
||||
**Best for**: General documentation, simple queries
|
||||
```bash
|
||||
# Minimal settings for speed
|
||||
USE_CONTEXTUAL_EMBEDDINGS=false
|
||||
USE_HYBRID_SEARCH=false
|
||||
USE_AGENTIC_RAG=false
|
||||
USE_RERANKING=false
|
||||
```
|
||||
|
||||
### 2. Balanced Configuration (Recommended)
|
||||
**Best for**: Most production use cases
|
||||
```bash
|
||||
# Balanced performance and accuracy
|
||||
USE_CONTEXTUAL_EMBEDDINGS=true
|
||||
CONTEXTUAL_EMBEDDINGS_MAX_WORKERS=3
|
||||
USE_HYBRID_SEARCH=true
|
||||
USE_AGENTIC_RAG=false
|
||||
USE_RERANKING=false
|
||||
```
|
||||
|
||||
### 3. High-Accuracy Configuration
|
||||
**Best for**: Critical applications, complex technical docs
|
||||
```bash
|
||||
# Maximum accuracy (slower)
|
||||
USE_CONTEXTUAL_EMBEDDINGS=true
|
||||
CONTEXTUAL_EMBEDDINGS_MAX_WORKERS=3
|
||||
USE_HYBRID_SEARCH=true
|
||||
USE_AGENTIC_RAG=true
|
||||
USE_RERANKING=true
|
||||
```
|
||||
|
||||
## 🔍 RAG Strategies Explained
|
||||
|
||||
### Contextual Embeddings
|
||||
**Enhances embeddings with surrounding document context**
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="how" label="How It Works" default>
|
||||
|
||||
```python
|
||||
# Standard embedding
|
||||
"authentication" → [0.1, 0.3, 0.7, ...]
|
||||
|
||||
# Contextual embedding (with document context)
|
||||
"authentication in React components using JWT tokens" → [0.2, 0.4, 0.8, ...]
|
||||
```
|
||||
|
||||
**Benefits:**
|
||||
- Better understanding of domain-specific terms
|
||||
- Improved accuracy for technical content
|
||||
- Context-aware search results
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="config" label="Configuration">
|
||||
|
||||
```bash
|
||||
# Enable contextual embeddings
|
||||
USE_CONTEXTUAL_EMBEDDINGS=true
|
||||
|
||||
# Control API rate limiting (1-20 workers)
|
||||
CONTEXTUAL_EMBEDDINGS_MAX_WORKERS=3
|
||||
```
|
||||
|
||||
**Performance Tuning:**
|
||||
- **Workers = 1**: Slowest, no rate limiting issues
|
||||
- **Workers = 3**: Balanced speed and reliability
|
||||
- **Workers = 8+**: Fastest, may hit OpenAI rate limits
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Hybrid Search
|
||||
**Combines vector similarity with keyword matching**
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="strategy" label="Search Strategy" default>
|
||||
|
||||
```mermaid
|
||||
flowchart LR
|
||||
A[User Query] --> B[Vector Search]
|
||||
A --> C[Keyword Search]
|
||||
B --> D[Vector Results]
|
||||
C --> E[Keyword Results]
|
||||
D --> F[Combine & Rank]
|
||||
E --> F
|
||||
F --> G[Final Results]
|
||||
```
|
||||
|
||||
**Use Cases:**
|
||||
- Mixed content (docs + code + APIs)
|
||||
- Exact term matching needed
|
||||
- Better coverage of rare terms
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="example" label="Example Results">
|
||||
|
||||
**Query**: "React authentication JWT"
|
||||
|
||||
**Vector Search Results:**
|
||||
- Authentication patterns in React
|
||||
- JWT token handling best practices
|
||||
- Security considerations for SPAs
|
||||
|
||||
**Keyword Search Results:**
|
||||
- Exact matches for "JWT"
|
||||
- Code examples with "React" + "auth"
|
||||
- API documentation mentioning tokens
|
||||
|
||||
**Combined Results:**
|
||||
- Higher relevance through multiple signals
|
||||
- Better coverage of technical terms
|
||||
- Reduced false negatives
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Agentic RAG
|
||||
**AI-powered query enhancement and result interpretation**
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="workflow" label="Enhanced Workflow" default>
|
||||
|
||||
```mermaid
|
||||
sequenceDiagram
|
||||
participant User
|
||||
participant Agent as RAG Agent
|
||||
participant Search as Search Engine
|
||||
|
||||
User->>Agent: "How to fix auth bug?"
|
||||
Agent->>Agent: Analyze intent
|
||||
Agent->>Agent: Enhance query
|
||||
Note over Agent: "React authentication debugging<br/>JWT token validation errors<br/>login session issues"
|
||||
Agent->>Search: Enhanced multi-query
|
||||
Search-->>Agent: Raw results
|
||||
Agent->>Agent: Interpret & synthesize
|
||||
Agent-->>User: Contextual answer
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="capabilities" label="AI Capabilities">
|
||||
|
||||
**Query Enhancement:**
|
||||
- Intent analysis and clarification
|
||||
- Synonym expansion and context addition
|
||||
- Multi-query strategy for complex questions
|
||||
|
||||
**Result Processing:**
|
||||
- Relevance filtering and ranking
|
||||
- Answer synthesis from multiple sources
|
||||
- Code example extraction and formatting
|
||||
|
||||
**Adaptive Learning:**
|
||||
- Learns from successful query patterns
|
||||
- Adapts to user terminology and context
|
||||
- Improves over time with usage
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
### Reranking
|
||||
**AI-powered result reordering for optimal relevance**
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="process" label="Reranking Process" default>
|
||||
|
||||
```python
|
||||
# Initial search results (vector similarity)
|
||||
results = [
|
||||
{"content": "JWT basics", "score": 0.85},
|
||||
{"content": "React auth patterns", "score": 0.83},
|
||||
{"content": "Token validation", "score": 0.81}
|
||||
]
|
||||
|
||||
# AI reranking (considering query context)
|
||||
reranked = [
|
||||
{"content": "React auth patterns", "score": 0.95}, # ↑ More relevant
|
||||
{"content": "Token validation", "score": 0.88}, # ↑ Contextually better
|
||||
{"content": "JWT basics", "score": 0.78} # ↓ Too generic
|
||||
]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="benefits" label="Benefits">
|
||||
|
||||
**Improved Relevance:**
|
||||
- Context-aware ranking beyond similarity
|
||||
- Understands query intent and user needs
|
||||
- Reduces noise from generic results
|
||||
|
||||
**Better User Experience:**
|
||||
- Most relevant results appear first
|
||||
- Reduced time to find information
|
||||
- Higher satisfaction with search results
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## 📊 Performance Optimization
|
||||
|
||||
### Speed vs Accuracy Trade-offs
|
||||
|
||||
```mermaid
|
||||
graph LR
|
||||
A[Basic RAG<br/>~200ms] --> B[+ Contextual<br/>~600ms]
|
||||
B --> C[+ Hybrid<br/>~800ms]
|
||||
C --> D[+ Agentic<br/>~2000ms]
|
||||
D --> E[+ Reranking<br/>~3000ms]
|
||||
|
||||
style A fill:#e1f5fe
|
||||
style B fill:#f3e5f5
|
||||
style C fill:#fff3e0
|
||||
style D fill:#ffebee
|
||||
style E fill:#fce4ec
|
||||
```
|
||||
|
||||
### Recommended Configurations by Use Case
|
||||
|
||||
#### Development & Testing
|
||||
```bash
|
||||
# Fast iteration, basic accuracy
|
||||
USE_CONTEXTUAL_EMBEDDINGS=false
|
||||
USE_HYBRID_SEARCH=false
|
||||
USE_AGENTIC_RAG=false
|
||||
USE_RERANKING=false
|
||||
# ~200ms average query time
|
||||
```
|
||||
|
||||
#### Production Documentation
|
||||
```bash
|
||||
# Balanced performance
|
||||
USE_CONTEXTUAL_EMBEDDINGS=true
|
||||
CONTEXTUAL_EMBEDDINGS_MAX_WORKERS=3
|
||||
USE_HYBRID_SEARCH=true
|
||||
USE_AGENTIC_RAG=false
|
||||
USE_RERANKING=false
|
||||
# ~800ms average query time
|
||||
```
|
||||
|
||||
#### Mission-Critical Applications
|
||||
```bash
|
||||
# Maximum accuracy
|
||||
USE_CONTEXTUAL_EMBEDDINGS=true
|
||||
CONTEXTUAL_EMBEDDINGS_MAX_WORKERS=2 # Conservative for reliability
|
||||
USE_HYBRID_SEARCH=true
|
||||
USE_AGENTIC_RAG=true
|
||||
USE_RERANKING=true
|
||||
# ~3000ms average query time
|
||||
```
|
||||
|
||||
## 🔧 Provider-Specific Configuration
|
||||
|
||||
### OpenAI (Recommended)
|
||||
```bash
|
||||
LLM_PROVIDER=openai
|
||||
MODEL_CHOICE=gpt-4o-mini
|
||||
EMBEDDING_MODEL=text-embedding-3-small
|
||||
# Pros: Best accuracy, reliable API
|
||||
# Cons: Cost per query
|
||||
```
|
||||
|
||||
### Google Gemini
|
||||
```bash
|
||||
LLM_PROVIDER=google
|
||||
LLM_BASE_URL=https://generativelanguage.googleapis.com/v1beta
|
||||
MODEL_CHOICE=gemini-2.5-flash
|
||||
EMBEDDING_MODEL=text-embedding-004
|
||||
# Pros: Good performance, competitive pricing
|
||||
# Cons: Different API patterns
|
||||
```
|
||||
|
||||
### Ollama (Local/Private)
|
||||
```bash
|
||||
LLM_PROVIDER=ollama
|
||||
LLM_BASE_URL=http://localhost:11434/v1
|
||||
MODEL_CHOICE=llama2
|
||||
EMBEDDING_MODEL=nomic-embed-text
|
||||
# Pros: Privacy, no API costs
|
||||
# Cons: Local compute requirements
|
||||
```
|
||||
|
||||
## 📈 Monitoring & Analytics
|
||||
|
||||
### Key Metrics to Track
|
||||
|
||||
```bash
|
||||
# Query Performance
|
||||
- Average response time
|
||||
- Cache hit rate
|
||||
- Error rate by strategy
|
||||
|
||||
# Search Quality
|
||||
- Result relevance scores
|
||||
- User interaction patterns
|
||||
- Query refinement frequency
|
||||
|
||||
# System Health
|
||||
- API rate limit usage
|
||||
- Embedding generation time
|
||||
- Memory usage patterns
|
||||
```
|
||||
|
||||
### Optimization Recommendations
|
||||
|
||||
#### If Queries Are Too Slow:
|
||||
1. Reduce `CONTEXTUAL_EMBEDDINGS_MAX_WORKERS`
|
||||
2. Disable `USE_AGENTIC_RAG` for simple queries
|
||||
3. Implement result caching
|
||||
4. Use lighter embedding models
|
||||
|
||||
#### If Results Are Inaccurate:
|
||||
1. Enable `USE_CONTEXTUAL_EMBEDDINGS`
|
||||
2. Add `USE_HYBRID_SEARCH` for mixed content
|
||||
3. Consider `USE_RERANKING` for critical applications
|
||||
4. Improve source document quality
|
||||
|
||||
#### If Hitting Rate Limits:
|
||||
1. Reduce max workers: `CONTEXTUAL_EMBEDDINGS_MAX_WORKERS=1`
|
||||
2. Implement exponential backoff
|
||||
3. Use caching more aggressively
|
||||
4. Consider switching to local models (Ollama)
|
||||
|
||||
## 🎯 Best Practices
|
||||
|
||||
### Content Optimization
|
||||
1. **Document Structure**: Use clear headings and sections
|
||||
2. **Code Examples**: Include working code snippets
|
||||
3. **Context**: Provide sufficient surrounding context
|
||||
4. **Tags**: Use descriptive tags for better categorization
|
||||
|
||||
### Query Optimization
|
||||
1. **Be Specific**: "React authentication with JWT" vs "auth"
|
||||
2. **Use Technical Terms**: Include framework/library names
|
||||
3. **Provide Context**: Mention your specific use case
|
||||
4. **Iterate**: Refine queries based on initial results
|
||||
|
||||
### System Tuning
|
||||
1. **Start Simple**: Begin with basic configuration
|
||||
2. **Measure Impact**: Enable one strategy at a time
|
||||
3. **Monitor Performance**: Track both speed and accuracy
|
||||
4. **User Feedback**: Collect feedback on result quality
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [RAG Agent](./agent-rag) - AI agent that orchestrates RAG searches
|
||||
- [MCP Tools](./mcp-tools) - RAG-related MCP tools and endpoints
|
||||
- [Knowledge Features](./knowledge-features) - Knowledge base management
|
||||
- [Configuration Guide](./configuration) - Complete system configuration
|
||||
718
docs/docs/server-deployment.mdx
Normal file
@@ -0,0 +1,718 @@
|
||||
---
|
||||
title: Server Deployment
|
||||
sidebar_position: 5
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 🐳 Server Deployment & Configuration
|
||||
|
||||
<div className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
Deploy Archon with Docker: **Production-ready microservices** with health checks, scaling, and monitoring
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
This guide covers deploying Archon's server architecture using Docker and Docker Compose, including configuration, scaling, and production best practices.
|
||||
|
||||
## 📁 Project Structure
|
||||
|
||||
<details>
|
||||
<summary>📂 **Click to expand complete project structure**</summary>
|
||||
|
||||
```
|
||||
archon/
|
||||
├── python/ # Python backend microservices
|
||||
│ ├── src/ # Main application source
|
||||
│ │ ├── main.py # FastAPI application entry point
|
||||
│ │ ├── socketio_app.py # Socket.IO configuration
|
||||
│ │ ├── mcp_server.py # MCP server implementation
|
||||
│ │ ├── config.py # Configuration management
|
||||
│ │ ├── utils.py # Utility functions (compatibility layer)
|
||||
│ │ ├── logfire_config.py # Unified logging configuration
|
||||
│ │ ├── api/ # 🎯 Modular API routers (6 modules)
|
||||
│ │ │ ├── knowledge_api.py # Knowledge & crawling endpoints
|
||||
│ │ │ ├── mcp_api.py # MCP server control & monitoring
|
||||
│ │ │ ├── settings_api.py # Settings & credential management
|
||||
│ │ │ ├── projects_api.py # Project & task management
|
||||
│ │ │ ├── agent_chat_api.py# AI agent chat interface
|
||||
│ │ │ └── tests_api.py # Test execution with streaming
|
||||
│ │ ├── agents/ # 🤖 AI agent microservice
|
||||
│ │ │ ├── server.py # Agents service FastAPI app
|
||||
│ │ │ ├── base_agent.py # Base agent class
|
||||
│ │ │ ├── document_agent.py# Documentation processing agent
|
||||
│ │ │ └── rag_agent.py # RAG operations agent
|
||||
│ │ ├── config/ # 🔧 Service configuration
|
||||
│ │ │ ├── __init__.py # Config module init
|
||||
│ │ │ └── service_discovery.py # Inter-service communication
|
||||
│ │ ├── modules/ # 📦 MCP tool modules (14 total tools)
|
||||
│ │ │ ├── models.py # Pydantic data models
|
||||
│ │ │ ├── rag_module.py # RAG functionality (7 MCP tools)
|
||||
│ │ │ └── project_module.py# Project & task management (7 MCP tools)
|
||||
│ │ ├── services/ # 🔧 Modular service layer (20+ services)
|
||||
│ │ │ ├── embeddings/ # Embedding operations
|
||||
│ │ │ │ ├── embedding_service.py # OpenAI embeddings with rate limiting
|
||||
│ │ │ │ └── contextual_embedding_service.py # Contextual embeddings
|
||||
│ │ │ ├── storage/ # Storage operations
|
||||
│ │ │ │ ├── document_storage_service.py # Document storage with parallel processing
|
||||
│ │ │ │ └── code_storage_service.py # Code example extraction & storage
|
||||
│ │ │ ├── search/ # Search operations
|
||||
│ │ │ │ └── vector_search_service.py # Vector similarity search
|
||||
│ │ │ ├── projects/ # Project management services
|
||||
│ │ │ │ ├── project_service.py # Core project operations
|
||||
│ │ │ │ ├── task_service.py # Task management operations
|
||||
│ │ │ │ ├── document_service.py # Document operations
|
||||
│ │ │ │ └── versioning_service.py# Version control operations
|
||||
│ │ │ ├── rag/ # RAG services
|
||||
│ │ │ │ ├── crawling_service.py # Web crawling functionality
|
||||
│ │ │ │ ├── document_storage_service.py # RAG document storage
|
||||
│ │ │ │ ├── search_service.py # RAG search & reranking
|
||||
│ │ │ │ └── source_management_service.py# Source management
|
||||
│ │ │ ├── client_manager.py # Database client management
|
||||
│ │ │ ├── credential_service.py # Credential management (in services/)
|
||||
│ │ │ ├── source_management_service.py # Source metadata management
|
||||
│ │ │ ├── threading_service.py # Thread pool & rate limiting
|
||||
│ │ │ ├── mcp_service_client.py # MCP HTTP client
|
||||
│ │ │ ├── mcp_session_manager.py # MCP session handling
|
||||
│ │ │ └── prompt_service.py # Prompt management
|
||||
│ │ └── models/ # 📊 Data models
|
||||
│ ├── Dockerfile.server # Server service container
|
||||
│ ├── Dockerfile.mcp # MCP service container
|
||||
│ ├── Dockerfile.agents # Agents service container
|
||||
│ ├── pyproject.toml # Python project configuration
|
||||
│ └── uv.lock # Dependency lock file
|
||||
├── archon-ui-main/ # React frontend application
|
||||
│ ├── src/ # Frontend source code
|
||||
│ │ ├── components/ # React components
|
||||
│ │ ├── pages/ # Page components
|
||||
│ │ ├── services/ # API service layer
|
||||
│ │ └── types/ # TypeScript definitions
|
||||
│ ├── Dockerfile # Frontend container
|
||||
│ └── vite.config.ts # Vite configuration
|
||||
├── docs/ # Docusaurus documentation
|
||||
├── migration/ # Database migration scripts
|
||||
├── docker-compose.yml # Container orchestration
|
||||
└── .env # Environment configuration
|
||||
```
|
||||
|
||||
</details>
|
||||
|
||||
## 🐳 Docker Deployment
|
||||
|
||||
### Microservices Configuration
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="docker-compose" label="🐳 docker-compose.yml">
|
||||
|
||||
```yaml title="docker-compose.yml"
|
||||
services:
|
||||
# Server Service (FastAPI + Socket.IO)
|
||||
archon-server:
|
||||
build:
|
||||
context: ./python
|
||||
dockerfile: Dockerfile.server
|
||||
container_name: Archon-Server
|
||||
ports:
|
||||
- "8080:8080"
|
||||
environment:
|
||||
- SUPABASE_URL=${SUPABASE_URL}
|
||||
- SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
||||
- LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-}
|
||||
- SERVICE_DISCOVERY_MODE=docker_compose
|
||||
- LOG_LEVEL=${LOG_LEVEL:-INFO}
|
||||
volumes:
|
||||
- ./python/src:/app/src:ro
|
||||
networks:
|
||||
- app-network
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8080/health')"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
start_period: 40s
|
||||
|
||||
# MCP Server Service
|
||||
archon-mcp:
|
||||
build:
|
||||
context: ./python
|
||||
dockerfile: Dockerfile.mcp
|
||||
container_name: archon-mcp
|
||||
ports:
|
||||
- "8051:8051"
|
||||
environment:
|
||||
- SUPABASE_URL=${SUPABASE_URL}
|
||||
- SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
||||
- LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-}
|
||||
- SERVICE_DISCOVERY_MODE=docker_compose
|
||||
- TRANSPORT=sse
|
||||
- LOG_LEVEL=${LOG_LEVEL:-INFO}
|
||||
volumes:
|
||||
- ./python/src:/app/src:ro
|
||||
networks:
|
||||
- app-network
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import socket; s=socket.socket(); s.connect(('localhost', 8051)); s.close()"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# AI Agents Service
|
||||
archon-agents:
|
||||
build:
|
||||
context: ./python
|
||||
dockerfile: Dockerfile.agents
|
||||
container_name: archon-agents
|
||||
ports:
|
||||
- "8052:8052"
|
||||
environment:
|
||||
- SUPABASE_URL=${SUPABASE_URL}
|
||||
- SUPABASE_SERVICE_KEY=${SUPABASE_SERVICE_KEY}
|
||||
- OPENAI_API_KEY=${OPENAI_API_KEY:-}
|
||||
- LOGFIRE_TOKEN=${LOGFIRE_TOKEN:-}
|
||||
- SERVICE_DISCOVERY_MODE=docker_compose
|
||||
- LOG_LEVEL=${LOG_LEVEL:-INFO}
|
||||
volumes:
|
||||
- ./python/src:/app/src:ro
|
||||
networks:
|
||||
- app-network
|
||||
healthcheck:
|
||||
test: ["CMD", "python", "-c", "import urllib.request; urllib.request.urlopen('http://localhost:8052/health')"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
|
||||
# Frontend
|
||||
frontend:
|
||||
build: ./archon-ui-main
|
||||
container_name: archon-frontend
|
||||
ports:
|
||||
- "3737:5173"
|
||||
environment:
|
||||
- VITE_API_URL=http://localhost:8080
|
||||
networks:
|
||||
- app-network
|
||||
healthcheck:
|
||||
test: ["CMD", "curl", "-f", "http://localhost:5173"]
|
||||
interval: 30s
|
||||
timeout: 10s
|
||||
retries: 3
|
||||
volumes:
|
||||
- ./archon-ui-main/src:/app/src
|
||||
- ./archon-ui-main/public:/app/public
|
||||
depends_on:
|
||||
- archon-server
|
||||
|
||||
# Documentation
|
||||
docs:
|
||||
build:
|
||||
context: ./docs
|
||||
dockerfile: Dockerfile
|
||||
container_name: archon-docs
|
||||
ports:
|
||||
- "3838:80"
|
||||
networks:
|
||||
- app-network
|
||||
depends_on:
|
||||
- archon-server
|
||||
- frontend
|
||||
|
||||
networks:
|
||||
app-network:
|
||||
driver: bridge
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="dockerfiles" label="🐳 Dockerfiles">
|
||||
|
||||
#### Server Service Dockerfile
|
||||
|
||||
```dockerfile title="Dockerfile.server"
|
||||
# Multi-stage build for smaller image size
|
||||
FROM python:3.12-slim AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
git \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install uv for faster dependency installation
|
||||
RUN pip install --no-cache-dir uv
|
||||
|
||||
# Copy dependency files
|
||||
COPY pyproject.toml uv.lock ./
|
||||
|
||||
# Install dependencies
|
||||
RUN uv sync --all-extras
|
||||
|
||||
# Copy application files
|
||||
COPY src/ src/
|
||||
|
||||
# Compile Python files for faster startup
|
||||
RUN python -m compileall src/
|
||||
|
||||
# Runtime stage
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy virtual environment from builder
|
||||
COPY --from=builder /app/.venv /app/.venv
|
||||
COPY --from=builder /app/src /app/src
|
||||
|
||||
# Set environment variables
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
ENV PYTHONPATH="/app/src:$PYTHONPATH"
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8080
|
||||
|
||||
# Run the FastAPI application with Socket.IO
|
||||
CMD ["python", "-m", "uvicorn", "src.main:socket_app", "--host", "0.0.0.0", "--port", "8080", "--workers", "1"]
|
||||
```
|
||||
|
||||
#### MCP Service Dockerfile
|
||||
|
||||
```dockerfile title="Dockerfile.mcp"
|
||||
FROM python:3.12-slim AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
git \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install uv
|
||||
RUN pip install --no-cache-dir uv
|
||||
|
||||
# Copy dependency files
|
||||
COPY pyproject.toml uv.lock ./
|
||||
|
||||
# Install dependencies
|
||||
RUN uv sync --all-extras
|
||||
|
||||
# Copy application files
|
||||
COPY src/ src/
|
||||
|
||||
# Compile Python files
|
||||
RUN python -m compileall src/
|
||||
|
||||
# Runtime stage
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy virtual environment from builder
|
||||
COPY --from=builder /app/.venv /app/.venv
|
||||
COPY --from=builder /app/src /app/src
|
||||
|
||||
# Set environment variables
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
ENV PYTHONPATH="/app/src:$PYTHONPATH"
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
# Default to SSE transport
|
||||
ENV TRANSPORT=sse
|
||||
ENV MCP_PORT=8051
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8051
|
||||
|
||||
# Run the MCP server
|
||||
CMD ["python", "src/mcp_server.py"]
|
||||
```
|
||||
|
||||
#### Agents Service Dockerfile
|
||||
|
||||
```dockerfile title="Dockerfile.agents"
|
||||
FROM python:3.12-slim AS builder
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Install system dependencies
|
||||
RUN apt-get update && apt-get install -y \
|
||||
curl \
|
||||
git \
|
||||
build-essential \
|
||||
&& rm -rf /var/lib/apt/lists/*
|
||||
|
||||
# Install uv
|
||||
RUN pip install --no-cache-dir uv
|
||||
|
||||
# Copy dependency files
|
||||
COPY pyproject.toml uv.lock ./
|
||||
|
||||
# Install dependencies
|
||||
RUN uv sync --all-extras
|
||||
|
||||
# Copy application files
|
||||
COPY src/ src/
|
||||
|
||||
# Compile Python files
|
||||
RUN python -m compileall src/
|
||||
|
||||
# Runtime stage
|
||||
FROM python:3.12-slim
|
||||
|
||||
WORKDIR /app
|
||||
|
||||
# Copy virtual environment from builder
|
||||
COPY --from=builder /app/.venv /app/.venv
|
||||
COPY --from=builder /app/src /app/src
|
||||
|
||||
# Set environment variables
|
||||
ENV PATH="/app/.venv/bin:$PATH"
|
||||
ENV PYTHONPATH="/app/src:$PYTHONPATH"
|
||||
ENV PYTHONUNBUFFERED=1
|
||||
|
||||
# Expose port
|
||||
EXPOSE 8052
|
||||
|
||||
# Run the Agents service
|
||||
CMD ["python", "-m", "uvicorn", "src.agents.server:app", "--host", "0.0.0.0", "--port", "8052"]
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## ⚙️ Environment Configuration
|
||||
|
||||
### Required Environment Variables
|
||||
|
||||
Create a `.env` file in the project root:
|
||||
|
||||
```bash title=".env"
|
||||
# Database Configuration
|
||||
SUPABASE_URL=https://your-project.supabase.co
|
||||
SUPABASE_SERVICE_KEY=your-service-key-here
|
||||
|
||||
# OpenAI Configuration
|
||||
OPENAI_API_KEY=sk-your-openai-api-key
|
||||
|
||||
# Unified Logging Configuration
|
||||
LOGFIRE_ENABLED=false # true=Logfire logging, false=standard logging
|
||||
LOGFIRE_TOKEN=your-logfire-token # Only required when LOGFIRE_ENABLED=true
|
||||
|
||||
# Service Configuration
|
||||
SERVICE_DISCOVERY_MODE=docker_compose
|
||||
LOG_LEVEL=INFO
|
||||
|
||||
# Optional: Custom Ports
|
||||
API_PORT=8080
|
||||
MCP_PORT=8051
|
||||
AGENTS_PORT=8052
|
||||
FRONTEND_PORT=3737
|
||||
DOCS_PORT=3838
|
||||
```
|
||||
|
||||
### Environment Variable Reference
|
||||
|
||||
| Variable | Required | Default | Description |
|
||||
|----------|----------|---------|-------------|
|
||||
| `SUPABASE_URL` | ✅ | - | Supabase project URL |
|
||||
| `SUPABASE_SERVICE_KEY` | ✅ | - | Supabase service role key |
|
||||
| `OPENAI_API_KEY` | ✅ | - | OpenAI API key for embeddings |
|
||||
| `LOGFIRE_ENABLED` | ❌ | `false` | Enable unified Logfire logging (`true`/`false`) |
|
||||
| `LOGFIRE_TOKEN` | ❌ | - | Logfire token (only required when enabled) |
|
||||
| `SERVICE_DISCOVERY_MODE` | ❌ | `local` | Service discovery mode (`docker_compose` or `local`) |
|
||||
| `LOG_LEVEL` | ❌ | `INFO` | Logging level (`DEBUG`, `INFO`, `WARNING`, `ERROR`) |
|
||||
| `TRANSPORT` | ❌ | `sse` | MCP transport mode (`sse`, `stdio`, `websocket`) |
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
1. **Clone the repository**
|
||||
```bash
|
||||
git clone https://github.com/archon/archon.git
|
||||
cd archon
|
||||
```
|
||||
|
||||
2. **Set up environment variables**
|
||||
```bash
|
||||
cp .env.example .env
|
||||
# Edit .env with your credentials
|
||||
```
|
||||
|
||||
3. **Start all services**
|
||||
```bash
|
||||
docker compose up -d
|
||||
```
|
||||
|
||||
4. **Verify services are running**
|
||||
```bash
|
||||
docker compose ps
|
||||
# All services should show as "healthy"
|
||||
```
|
||||
|
||||
5. **Access the application**
|
||||
- Web UI: http://localhost:3737
|
||||
- API Docs: http://localhost:8080/docs
|
||||
- MCP Connection: http://localhost:8051/sse
|
||||
- Agents API: http://localhost:8052/docs
|
||||
- Documentation: http://localhost:3838
|
||||
|
||||
## 📈 Performance Optimization
|
||||
|
||||
### Service-Specific Optimizations
|
||||
|
||||
1. **Server Service**
|
||||
- Connection pooling for database
|
||||
- Request caching with Redis
|
||||
- Async request handling
|
||||
|
||||
2. **MCP Service**
|
||||
- Tool execution timeout management
|
||||
- Connection recycling
|
||||
- Memory-efficient streaming
|
||||
|
||||
3. **Agents Service**
|
||||
- PydanticAI agent orchestration
|
||||
- MCP tool call optimization
|
||||
- Intelligent request routing to appropriate tools
|
||||
|
||||
### Resource Limits
|
||||
|
||||
Add resource limits for production deployments:
|
||||
|
||||
```yaml title="docker-compose.prod.yml"
|
||||
services:
|
||||
archon-server:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2'
|
||||
memory: 4G
|
||||
reservations:
|
||||
cpus: '1'
|
||||
memory: 2G
|
||||
|
||||
archon-mcp:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '1'
|
||||
memory: 2G
|
||||
reservations:
|
||||
cpus: '0.5'
|
||||
memory: 1G
|
||||
|
||||
archon-agents:
|
||||
deploy:
|
||||
resources:
|
||||
limits:
|
||||
cpus: '2'
|
||||
memory: 4G
|
||||
reservations:
|
||||
cpus: '1'
|
||||
memory: 2G
|
||||
```
|
||||
|
||||
## 🔄 Scaling Services
|
||||
|
||||
Each microservice can be scaled independently:
|
||||
|
||||
```bash
|
||||
# Scale the Agents service for more processing power
|
||||
docker compose up -d --scale archon-agents=3
|
||||
|
||||
# Scale the Server service for more concurrent requests
|
||||
docker compose up -d --scale archon-server=2
|
||||
|
||||
# MCP typically doesn't need scaling as it's connection-based
|
||||
```
|
||||
|
||||
### Load Balancing
|
||||
|
||||
For production deployments with multiple instances, use a load balancer:
|
||||
|
||||
```yaml title="docker-compose.lb.yml"
|
||||
services:
|
||||
nginx:
|
||||
image: nginx:alpine
|
||||
ports:
|
||||
- "80:80"
|
||||
volumes:
|
||||
- ./nginx.conf:/etc/nginx/nginx.conf:ro
|
||||
depends_on:
|
||||
- archon-server
|
||||
networks:
|
||||
- app-network
|
||||
```
|
||||
|
||||
## 🔒 Security Best Practices
|
||||
|
||||
### 1. Use Docker Secrets
|
||||
|
||||
```yaml title="docker-compose.secrets.yml"
|
||||
services:
|
||||
archon-server:
|
||||
environment:
|
||||
- OPENAI_API_KEY_FILE=/run/secrets/openai_key
|
||||
secrets:
|
||||
- openai_key
|
||||
|
||||
secrets:
|
||||
openai_key:
|
||||
file: ./secrets/openai_key.txt
|
||||
```
|
||||
|
||||
### 2. Network Isolation
|
||||
|
||||
```yaml
|
||||
networks:
|
||||
frontend-network:
|
||||
driver: bridge
|
||||
backend-network:
|
||||
driver: bridge
|
||||
internal: true
|
||||
```
|
||||
|
||||
### 3. Read-Only Volumes
|
||||
|
||||
Mount source code as read-only in production:
|
||||
|
||||
```yaml
|
||||
volumes:
|
||||
- ./python/src:/app/src:ro
|
||||
```
|
||||
|
||||
## 🛠️ Development Mode
|
||||
|
||||
For local development with hot reloading:
|
||||
|
||||
```yaml title="docker-compose.dev.yml"
|
||||
services:
|
||||
archon-server:
|
||||
command: ["python", "-m", "uvicorn", "src.main:socket_app", "--host", "0.0.0.0", "--port", "8080", "--reload"]
|
||||
volumes:
|
||||
- ./python/src:/app/src
|
||||
environment:
|
||||
- LOG_LEVEL=DEBUG
|
||||
```
|
||||
|
||||
## 📊 Monitoring & Health Checks
|
||||
|
||||
### Service Health Endpoints
|
||||
|
||||
- **Server**: `http://localhost:8080/health`
|
||||
- **MCP**: `http://localhost:8051/sse` (SSE endpoint)
|
||||
- **Agents**: `http://localhost:8052/health`
|
||||
|
||||
### Docker Health Checks
|
||||
|
||||
All services include health checks that:
|
||||
- Run every 30 seconds
|
||||
- Timeout after 10 seconds
|
||||
- Retry 3 times before marking unhealthy
|
||||
- Wait 40 seconds before first check
|
||||
|
||||
### Monitoring Commands
|
||||
|
||||
```bash
|
||||
# View service logs
|
||||
docker compose logs -f archon-server
|
||||
|
||||
# Check service health
|
||||
docker inspect archon-server | grep -A 5 Health
|
||||
|
||||
# Monitor resource usage
|
||||
docker stats
|
||||
|
||||
# View running processes
|
||||
docker compose top
|
||||
```
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
### Common Issues
|
||||
|
||||
#### Services Not Starting
|
||||
|
||||
```bash
|
||||
# Check logs for specific service
|
||||
docker compose logs archon-server
|
||||
|
||||
# Verify environment variables
|
||||
docker compose config
|
||||
|
||||
# Rebuild images
|
||||
docker compose build --no-cache
|
||||
```
|
||||
|
||||
#### Database Connection Issues
|
||||
|
||||
```bash
|
||||
# Test database connectivity
|
||||
docker exec archon-server python -c "
|
||||
from src.services.client_manager import get_supabase_client
|
||||
client = get_supabase_client()
|
||||
print('Database connected successfully')
|
||||
"
|
||||
```
|
||||
|
||||
#### Port Conflicts
|
||||
|
||||
```bash
|
||||
# Check for port usage
|
||||
lsof -i :8080
|
||||
netstat -tulpn | grep 8080
|
||||
|
||||
# Use alternative ports in .env
|
||||
API_PORT=8090
|
||||
MCP_PORT=8061
|
||||
```
|
||||
|
||||
## 🚢 Production Deployment
|
||||
|
||||
### 1. Use Production Images
|
||||
|
||||
```bash
|
||||
# Build optimized images
|
||||
docker compose -f docker-compose.yml -f docker-compose.prod.yml build
|
||||
|
||||
# Push to registry
|
||||
docker tag archon-server:latest your-registry/archon-server:v1.0.0
|
||||
docker push your-registry/archon-server:v1.0.0
|
||||
```
|
||||
|
||||
### 2. Enable Swarm Mode
|
||||
|
||||
```bash
|
||||
# Initialize swarm
|
||||
docker swarm init
|
||||
|
||||
# Deploy stack
|
||||
docker stack deploy -c docker-compose.yml archon
|
||||
```
|
||||
|
||||
### 3. Configure Logging
|
||||
|
||||
```yaml
|
||||
services:
|
||||
archon-server:
|
||||
logging:
|
||||
driver: "json-file"
|
||||
options:
|
||||
max-size: "10m"
|
||||
max-file: "3"
|
||||
```
|
||||
|
||||
---
|
||||
|
||||
**Next Steps**:
|
||||
- Learn about [Server Monitoring](./server-monitoring) with Logfire
|
||||
- Review [Server Services](./server-services) documentation
|
||||
- Explore the [API Reference](./api-reference) for endpoints
|
||||
- Check [MCP Server Setup](./mcp-server) for AI client integration
|
||||
172
docs/docs/server-monitoring.mdx
Normal file
@@ -0,0 +1,172 @@
|
||||
---
|
||||
title: Server Monitoring
|
||||
sidebar_position: 6
|
||||
---
|
||||
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 📊 Server Monitoring & Health
|
||||
|
||||
<div className="hero hero--primary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
**Monitor your Archon services**: Health checks, performance metrics, and troubleshooting tools
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
Archon provides built-in monitoring and health checking across all services to help you maintain optimal performance and quickly troubleshoot issues.
|
||||
|
||||
## 🏥 Health Checks
|
||||
|
||||
### API Health Endpoints
|
||||
|
||||
Each service provides health check endpoints:
|
||||
|
||||
```bash
|
||||
# Server API health
|
||||
curl http://localhost:8080/api/projects/health
|
||||
curl http://localhost:8080/api/settings/health
|
||||
|
||||
# MCP Server health
|
||||
curl http://localhost:8051/health
|
||||
|
||||
# Database health
|
||||
curl http://localhost:8080/api/database/metrics
|
||||
```
|
||||
|
||||
### Service Status
|
||||
|
||||
Monitor the status of all Archon services:
|
||||
|
||||
| Service | Port | Health Endpoint | Purpose |
|
||||
|---------|------|----------------|---------|
|
||||
| **Server** | 8080 | `/api/projects/health` | Main API status |
|
||||
| **MCP** | 8051 | `/health` | MCP server status |
|
||||
| **Frontend** | 3737 | Direct access | Web UI availability |
|
||||
| **Docs** | 3838 | Direct access | Documentation site |
|
||||
|
||||
## 📈 Performance Monitoring
|
||||
|
||||
### Key Metrics
|
||||
|
||||
Archon tracks important performance metrics:
|
||||
|
||||
- **RAG Query Performance**: Average search times and accuracy
|
||||
- **Database Performance**: Connection pool health and query times
|
||||
- **Memory Usage**: Adaptive processing based on available resources
|
||||
- **API Response Times**: Endpoint performance across all services
|
||||
|
||||
### Real-Time Updates
|
||||
|
||||
Socket.IO connections provide real-time monitoring:
|
||||
|
||||
- **Progress Tracking**: Live updates during document processing
|
||||
- **Connection Health**: Automatic reconnection handling
|
||||
- **Service Communication**: Inter-service request monitoring
|
||||
|
||||
## 🔧 Troubleshooting
|
||||
|
||||
<Admonition type="tip" title="Quick Debugging">
|
||||
Use the health endpoints and browser developer tools to quickly diagnose issues with your Archon installation.
|
||||
</Admonition>
|
||||
|
||||
### Common Issues
|
||||
|
||||
| Symptom | Likely Cause | Solution |
|
||||
|---------|--------------|----------|
|
||||
| Slow search responses | High memory usage | System automatically adjusts batch sizes |
|
||||
| Connection errors | Service startup order | Restart services with `docker-compose restart` |
|
||||
| Missing search results | Database connection | Check Supabase configuration |
|
||||
| UI not loading | Frontend build issues | Check frontend service logs |
|
||||
|
||||
### Docker Logs
|
||||
|
||||
Monitor service logs:
|
||||
|
||||
```bash
|
||||
# All services
|
||||
docker-compose logs -f
|
||||
|
||||
# Specific service
|
||||
docker-compose logs -f archon-server
|
||||
docker-compose logs -f archon-mcp
|
||||
```
|
||||
|
||||
### Database Monitoring
|
||||
|
||||
Check database health and metrics:
|
||||
|
||||
```bash
|
||||
# Database metrics
|
||||
curl http://localhost:8080/api/database/metrics
|
||||
|
||||
# Returns:
|
||||
# - Table record counts
|
||||
# - Connection status
|
||||
# - Performance indicators
|
||||
```
|
||||
|
||||
## 🛠️ Configuration
|
||||
|
||||
### Environment Monitoring
|
||||
|
||||
Monitor key environment variables:
|
||||
|
||||
```bash
|
||||
# Database connectivity
|
||||
SUPABASE_URL=your_supabase_url
|
||||
SUPABASE_SERVICE_KEY=your_service_key
|
||||
|
||||
# AI services
|
||||
OPENAI_API_KEY=your_openai_key
|
||||
|
||||
# Unified Logging Configuration
|
||||
LOGFIRE_ENABLED=false # true=Logfire logging, false=standard logging
|
||||
LOGFIRE_TOKEN=your_logfire_token # Only required when LOGFIRE_ENABLED=true
|
||||
|
||||
# Service communication
|
||||
API_BASE_URL=http://archon-server:8080
|
||||
```
|
||||
|
||||
### Unified Logging System
|
||||
|
||||
Archon includes a unified logging system with optional [Logfire](https://logfire.pydantic.dev/) integration:
|
||||
|
||||
**Standard Logging (Default)**:
|
||||
```bash
|
||||
LOGFIRE_ENABLED=false
|
||||
```
|
||||
- Uses Python's standard logging framework
|
||||
- Logs to console with structured format
|
||||
- Perfect for development and basic monitoring
|
||||
- Zero external dependencies
|
||||
|
||||
**Enhanced Logging with Logfire**:
|
||||
```bash
|
||||
LOGFIRE_ENABLED=true
|
||||
LOGFIRE_TOKEN=your_logfire_token # Get from logfire.pydantic.dev
|
||||
```
|
||||
- Real-time traces and performance monitoring
|
||||
- Advanced debugging for RAG queries and MCP tool calls
|
||||
- Automatic request/response tracking
|
||||
- Visual dashboards and analytics
|
||||
|
||||
**Key Benefits**:
|
||||
- 🔄 **Seamless Toggle**: Switch between modes with a single environment variable
|
||||
- 🛡️ **Graceful Fallback**: Always works even without Logfire
|
||||
- 📊 **Consistent Format**: Same log structure in both modes
|
||||
- 🚀 **Zero Setup**: Standard logging works out of the box
|
||||
|
||||
### Resource Management
|
||||
|
||||
Archon automatically manages resources:
|
||||
|
||||
- **Memory Adaptive Processing**: Adjusts concurrency based on available memory
|
||||
- **Rate Limiting**: Prevents API quota exhaustion
|
||||
- **Connection Pooling**: Optimizes database performance
|
||||
- **Batch Processing**: Efficiently handles large document sets
|
||||
|
||||
---
|
||||
|
||||
**Need Help?** Check the [Troubleshooting Guide](./troubleshooting) for detailed debugging steps.
|
||||
119
docs/docs/server-overview.mdx
Normal file
@@ -0,0 +1,119 @@
|
||||
---
|
||||
title: Server Overview
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
# Server Overview
|
||||
|
||||
The Server service is the core of Archon, containing all business logic, services, and data operations.
|
||||
|
||||
## Architecture
|
||||
|
||||
### Service Responsibilities
|
||||
|
||||
| Service | Port | Purpose | Contains |
|
||||
|---------|------|---------|----------|
|
||||
| **Server** | 8080 | Core API & business logic | Services, ML models, data operations |
|
||||
| **MCP** | 8051 | Protocol adapter for AI clients | HTTP client, MCP tool definitions |
|
||||
| **Agents** | 8052 | AI processing | PydanticAI agents only |
|
||||
| **Frontend** | 3737 | Web UI | React application |
|
||||
| **Docs** | 3838 | Documentation | Docusaurus site |
|
||||
|
||||
### Communication Flow
|
||||
|
||||
```
|
||||
Frontend → Server API ← MCP (via HTTP) ← AI Clients
|
||||
↓
|
||||
Services
|
||||
↓
|
||||
Database
|
||||
```
|
||||
|
||||
## Docker Services
|
||||
|
||||
```yaml
|
||||
services:
|
||||
archon-server: # FastAPI + Socket.IO (port 8080)
|
||||
archon-mcp: # MCP Server (port 8051)
|
||||
archon-agents: # AI Agents (port 8052)
|
||||
archon-frontend: # React UI (port 3737)
|
||||
archon-docs: # Documentation (port 3838)
|
||||
```
|
||||
|
||||
## Key Components
|
||||
|
||||
### FastAPI Application
|
||||
- REST API endpoints
|
||||
- Socket.IO server for real-time communication
|
||||
- Service layer integration
|
||||
|
||||
### Service Layer
|
||||
All business logic is organized into service modules:
|
||||
- **RAG Services**: Crawling, search, document storage
|
||||
- **Project Services**: Project and task management
|
||||
- **Core Services**: Authentication, configuration
|
||||
- **Storage Services**: Database operations
|
||||
- **Embedding Services**: Vector generation
|
||||
|
||||
### External Services
|
||||
- **Supabase**: PostgreSQL + pgvector for data storage
|
||||
- **OpenAI API**: Embeddings generation
|
||||
|
||||
## API Structure
|
||||
|
||||
| Router | Path | Purpose |
|
||||
|--------|------|---------|
|
||||
| `knowledge_api.py` | `/api/knowledge-items` | Knowledge management, crawling |
|
||||
| `projects_api.py` | `/api/projects` | Project and task management |
|
||||
| `mcp_api.py` | `/api/mcp` | MCP server control |
|
||||
| `settings_api.py` | `/api/settings` | Configuration management |
|
||||
| `agent_chat_api.py` | `/api/agent-chat` | AI agent interactions |
|
||||
|
||||
## Environment Configuration
|
||||
|
||||
Key environment variables:
|
||||
|
||||
```bash
|
||||
# Database
|
||||
SUPABASE_URL=your_supabase_url
|
||||
SUPABASE_SERVICE_KEY=your_service_key
|
||||
|
||||
# AI Services
|
||||
OPENAI_API_KEY=your_openai_key
|
||||
|
||||
# Unified Logging Configuration (Optional)
|
||||
LOGFIRE_ENABLED=false # true=Logfire logging, false=standard logging
|
||||
LOGFIRE_TOKEN=your_logfire_token # Only required when LOGFIRE_ENABLED=true
|
||||
|
||||
# Service URLs (for inter-service communication)
|
||||
API_BASE_URL=http://archon-server:8080
|
||||
AGENTS_BASE_URL=http://archon-agents:8052
|
||||
```
|
||||
|
||||
## Development Setup
|
||||
|
||||
1. **Clone repository**
|
||||
```bash
|
||||
git clone https://github.com/ArchonInnovations/archon.git
|
||||
cd archon
|
||||
```
|
||||
|
||||
2. **Start services**
|
||||
```bash
|
||||
docker-compose up
|
||||
```
|
||||
|
||||
3. **Access services**
|
||||
- API Docs: http://localhost:8080/docs
|
||||
- Frontend: http://localhost:3737
|
||||
- Documentation: http://localhost:3838
|
||||
|
||||
## Monitoring
|
||||
|
||||
Logfire provides real-time observability:
|
||||
- Request/response tracking
|
||||
- Performance metrics
|
||||
- Error monitoring
|
||||
- Service health checks
|
||||
|
||||
Access your Logfire dashboard to monitor all services in real-time.
|
||||
484
docs/docs/server-services.mdx
Normal file
@@ -0,0 +1,484 @@
|
||||
---
|
||||
title: Server Services
|
||||
sidebar_position: 4
|
||||
---
|
||||
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Server Services
|
||||
|
||||
The Server's business logic is organized into modular service classes and functions.
|
||||
|
||||
## Service Organization
|
||||
|
||||
### Storage Services (`/services/storage/`)
|
||||
|
||||
| Service/Module | Purpose | Key Components |
|
||||
|---------|---------|-------------|
|
||||
| **BaseStorageService** | Abstract base class for storage operations | `smart_chunk_text()`, `extract_metadata()`, `batch_process_with_progress()` |
|
||||
| **storage_services.py** | Contains DocumentStorageService class | `upload_document()`, `store_documents()`, `process_document()` |
|
||||
| **document_storage_service.py** | Storage utility functions | `add_documents_to_supabase()`, `add_documents_to_supabase_parallel()` |
|
||||
| **code_storage_service.py** | Code extraction utilities | `extract_code_blocks()`, `generate_code_example_summary()`, `add_code_examples_to_supabase()` |
|
||||
|
||||
<Admonition type="info" title="Storage Module Organization">
|
||||
The storage module has both service classes and utility functions:
|
||||
- **storage_services.py** contains the `DocumentStorageService` class that extends `BaseStorageService`
|
||||
- **document_storage_service.py** and **code_storage_service.py** contain standalone utility functions
|
||||
- This separation allows both object-oriented and functional approaches as needed
|
||||
</Admonition>
|
||||
|
||||
### Search Services (`/services/search/`)
|
||||
|
||||
| Service/Module | Purpose | Key Components |
|
||||
|---------|---------|-------------|
|
||||
| **search_services.py** | Contains SearchService class | `perform_rag_query()`, `search_code_examples_service()`, `rerank_results()` |
|
||||
| **vector_search_service.py** | Vector search utilities | `search_documents()`, `search_code_examples()`, `search_documents_async()` |
|
||||
|
||||
<Admonition type="info" title="Search Module Organization">
|
||||
- **search_services.py** contains the `SearchService` class for high-level search operations
|
||||
- **vector_search_service.py** contains low-level vector search utility functions
|
||||
- The SearchService uses vector search utilities internally
|
||||
</Admonition>
|
||||
|
||||
### RAG Services (`/services/rag/`)
|
||||
|
||||
| Service | Purpose | Key Methods |
|
||||
|---------|---------|-------------|
|
||||
| **CrawlingService** | Web crawling operations | `crawl_single_page()`, `crawl_batch_with_progress()`, `crawl_recursive_with_progress()` |
|
||||
|
||||
### Knowledge Services (`/services/knowledge/`)
|
||||
|
||||
**Recent Refactoring**: The Knowledge API was refactored from a 1,076-line monolith to a 550-line API layer (49% reduction) by extracting business logic into specialized services.
|
||||
|
||||
| Service | Purpose | Key Methods |
|
||||
|---------|---------|-------------|
|
||||
| **CrawlOrchestrationService** | Orchestrates entire crawl workflow | `orchestrate_crawl()`, `set_progress_id()`, `cancel()`, `is_cancelled()` |
|
||||
| **KnowledgeItemService** | CRUD operations for knowledge items | `list_items()`, `update_item()`, `get_available_sources()` |
|
||||
| **CodeExtractionService** | Code block extraction and processing | `extract_and_store_code_examples()`, `extract_code_blocks_from_html()` |
|
||||
| **DatabaseMetricsService** | Database statistics and metrics | `get_metrics()` |
|
||||
|
||||
**Service Layer Benefits:**
|
||||
- **Separation of Concerns**: Business logic separated from API routing
|
||||
- **Testability**: Services can be unit tested without Socket.IO dependencies
|
||||
- **Reusability**: Services used by both API endpoints and MCP tools
|
||||
- **Progress Tracking**: Integrated with ProgressTracker utility
|
||||
|
||||
### Project Services (`/services/projects/`)
|
||||
|
||||
**Recent Refactoring**: The Projects API was refactored from a monolithic 1,690-line file to a clean service layer architecture, reducing the main API file to 868 lines (42% reduction) while extracting business logic into specialized services.
|
||||
|
||||
| Service | File | Purpose | Key Methods |
|
||||
|---------|------|---------|-------------|
|
||||
| **ProjectService** | `project_service.py` | Core project CRUD operations | `create_project()`, `get_project()`, `update_project()`, `delete_project()`, `list_projects()` |
|
||||
| **TaskService** | `task_service.py` | Task lifecycle management | `create_task()`, `update_task()`, `archive_task()`, `list_tasks()` |
|
||||
| **ProjectCreationService** | `project_creation_service.py` | AI-assisted project creation workflow | `create_project_with_ai()`, `generate_features()`, `process_github_repo()` |
|
||||
| **SourceLinkingService** | `source_linking_service.py` | Project-knowledge source relationships | `update_project_sources()`, `format_projects_with_sources()` |
|
||||
| **ProgressService** | `progress_service.py` | Real-time operation tracking via Socket.IO | `start_operation()`, `update_progress()`, `complete_operation()`, `error_operation()` |
|
||||
| **DocumentService** | `document_service.py` | Project document management | `add_document()`, `get_documents()`, `update_document()` |
|
||||
| **VersioningService** | `versioning_service.py` | JSONB field version control | `create_version()`, `get_versions()`, `restore_version()` |
|
||||
|
||||
**Service Layer Benefits:**
|
||||
- **Separation of Concerns**: Business logic separated from API routing
|
||||
- **Reusability**: Services can be used by multiple API endpoints and MCP tools
|
||||
- **Testability**: Each service can be unit tested independently
|
||||
- **Socket.IO Integration**: Real-time updates handled at the service layer
|
||||
|
||||
**Example Service Coordination:**
|
||||
```python
|
||||
# projects_api.py - Thin API layer
|
||||
@router.post("/projects")
|
||||
async def create_project(request: CreateProjectRequest):
|
||||
progress_id = secrets.token_hex(16)
|
||||
|
||||
# Start progress tracking
|
||||
progress_service.start_operation(progress_id, 'project_creation')
|
||||
|
||||
# Background task coordinates multiple services
|
||||
asyncio.create_task(_create_project_with_ai(progress_id, request))
|
||||
|
||||
return {"progress_id": progress_id}
|
||||
|
||||
# Background workflow using multiple services
|
||||
async def _create_project_with_ai(progress_id: str, request: CreateProjectRequest):
|
||||
creation_service = ProjectCreationService()
|
||||
|
||||
# AI-assisted creation with real-time updates
|
||||
success, result = await creation_service.create_project_with_ai(
|
||||
progress_id=progress_id,
|
||||
title=request.title,
|
||||
github_repo=request.github_repo
|
||||
)
|
||||
|
||||
if success:
|
||||
# Broadcast update to Socket.IO clients
|
||||
await broadcast_project_update()
|
||||
await progress_service.complete_operation(progress_id, result)
|
||||
```
|
||||
|
||||
### Core Services (`/services/`)
|
||||
|
||||
| Service | Purpose | Key Methods |
|
||||
|---------|---------|-------------|
|
||||
| **SourceManagementService** | Manage knowledge sources | `get_available_sources()`, `delete_source()`, `update_source_metadata()` |
|
||||
| **CredentialService** | Secure credential storage | `get_credential()`, `set_credential()` |
|
||||
| **PromptService** | AI prompt management | `get_prompt()`, `reload_prompts()` |
|
||||
| **ThreadingService** | Threading & rate limiting | `batch_process()`, `rate_limited_operation()` |
|
||||
| **MCPServiceClient** | HTTP client for MCP | `crawl_url()`, `search()`, `delete_source()` |
|
||||
| **ClientManager** | Database client management | `get_supabase_client()` |
|
||||
| **MCPSessionManager** | MCP session management | `create_session()`, `validate_session()`, `cleanup_expired()` |
|
||||
| **CrawlerManager** | Global crawler instance management | `get_crawler()`, `initialize()`, `cleanup()` |
|
||||
| **LLMProviderService** | Multi-provider LLM support | `get_llm_client()`, `get_llm_client_sync()`, `get_embedding_model()` |
|
||||
|
||||
### Modular Architecture Pattern
|
||||
|
||||
The services follow a clear architectural pattern:
|
||||
|
||||
- **Utility Modules**: Low-level functions for specific operations
|
||||
- `vector_search_service.py` - Vector database operations
|
||||
- `document_storage_service.py` - Document storage functions
|
||||
- `code_storage_service.py` - Code extraction functions
|
||||
|
||||
- **Service Classes**: High-level orchestration of utilities
|
||||
- `SearchService` in `search_services.py`
|
||||
- `DocumentStorageService` in `storage_services.py`
|
||||
- Knowledge services in `/services/knowledge/`
|
||||
- Project services in `/services/projects/`
|
||||
|
||||
- **Base Classes**: Abstract implementations for extensibility
|
||||
- `BaseStorageService` - Common storage patterns
|
||||
|
||||
- **Manager Classes**: Singleton instances for global resources
|
||||
- `CrawlerManager` - Global crawler instance
|
||||
- `MCPSessionManager` - Session management
|
||||
|
||||
- **Single Responsibility**: Each module has one focused purpose
|
||||
|
||||
### Embedding Services (`/services/embeddings/`)
|
||||
|
||||
| Module | Purpose | Key Functions |
|
||||
|--------|---------|---------------|
|
||||
| **embedding_service.py** | OpenAI embedding creation | `create_embeddings_batch()`, `create_embeddings_batch_async()` |
|
||||
| **contextual_embedding_service.py** | Context-aware embeddings | `generate_contextual_embedding()`, `generate_contextual_embeddings_batch()` |
|
||||
|
||||
### Utility Classes (`/utils/progress/`)
|
||||
|
||||
| Utility | Purpose | Key Methods |
|
||||
|---------|---------|-------------|
|
||||
| **ProgressTracker** | Consolidated Socket.IO progress tracking | `start()`, `update()`, `complete()`, `error()`, `update_batch_progress()`, `update_crawl_stats()` |
|
||||
|
||||
<Admonition type="tip" title="Async/Sync Boundaries">
|
||||
The embedding service provides both sync and async versions:
|
||||
- Use `create_embeddings_batch_async()` in async contexts (recommended)
|
||||
- Sync versions exist for backward compatibility but will return zero embeddings if called from async context
|
||||
- Always prefer async versions for better performance and proper event loop handling
|
||||
</Admonition>
|
||||
|
||||
## Service Usage Patterns
|
||||
|
||||
### Direct Service Usage (FastAPI)
|
||||
```python
|
||||
# Import from new locations
|
||||
from ..services.source_management_service import SourceManagementService
|
||||
from ..services.storage import DocumentStorageService
|
||||
from ..services.search import SearchService
|
||||
from ..services.knowledge import CrawlOrchestrationService, KnowledgeItemService
|
||||
from ..services.crawler_manager import get_crawler
|
||||
|
||||
# Example: Knowledge item crawling
|
||||
@router.post("/knowledge-items/crawl")
|
||||
async def crawl_knowledge_item(request: KnowledgeItemRequest):
|
||||
crawler = await get_crawler()
|
||||
orchestration_service = CrawlOrchestrationService(crawler, get_supabase_client())
|
||||
result = await orchestration_service.orchestrate_crawl(request.dict())
|
||||
return result
|
||||
|
||||
# Example: Crawl cancellation
|
||||
@router.post("/knowledge-items/stop/{progress_id}")
|
||||
async def stop_crawl_task(progress_id: str):
|
||||
# Cancel orchestration service
|
||||
orchestration = get_active_orchestration(progress_id)
|
||||
if orchestration:
|
||||
orchestration.cancel()
|
||||
|
||||
# Cancel asyncio task
|
||||
if progress_id in active_crawl_tasks:
|
||||
task = active_crawl_tasks[progress_id]
|
||||
if not task.done():
|
||||
task.cancel()
|
||||
try:
|
||||
await asyncio.wait_for(task, timeout=2.0)
|
||||
except (asyncio.CancelledError, asyncio.TimeoutError):
|
||||
pass
|
||||
del active_crawl_tasks[progress_id]
|
||||
|
||||
# Emit Socket.IO events
|
||||
await sio.emit('crawl:stopped', {
|
||||
'progressId': progress_id,
|
||||
'status': 'cancelled',
|
||||
'message': 'Crawl cancelled by user'
|
||||
}, room=progress_id)
|
||||
|
||||
return {'success': True}
|
||||
|
||||
# Example: Source deletion
|
||||
@router.delete("/sources/{source_id}")
|
||||
async def delete_source(source_id: str):
|
||||
service = SourceManagementService(get_supabase_client())
|
||||
success, result = service.delete_source(source_id)
|
||||
return {"success": success, **result}
|
||||
```
|
||||
|
||||
### HTTP Service Usage (MCP)
|
||||
```python
|
||||
async def delete_source(ctx: Context, source: str) -> str:
|
||||
async with httpx.AsyncClient() as client:
|
||||
response = await client.delete(f"{API_URL}/api/sources/{source}")
|
||||
return response.json()
|
||||
```
|
||||
|
||||
### Simplified Socket.IO Emission Pattern (2025)
|
||||
```python
|
||||
from ..socketio_app import get_socketio_instance
|
||||
|
||||
# Get Socket.IO instance
|
||||
sio = get_socketio_instance()
|
||||
|
||||
async def crawl_with_progress(url: str, progress_id: str):
|
||||
crawling_service = CrawlingService(crawler, supabase_client)
|
||||
|
||||
# Simple direct emission - no complex utils
|
||||
await sio.emit('progress_update', {
|
||||
'status': 'crawling',
|
||||
'percentage': 10,
|
||||
'log': f'Starting crawl of {url}'
|
||||
}, room=progress_id)
|
||||
|
||||
results = await crawling_service.crawl_batch_with_progress(urls=[url])
|
||||
return results
|
||||
```
|
||||
|
||||
### ProgressTracker Utility Pattern
|
||||
```python
|
||||
from ..utils.progress import ProgressTracker
|
||||
|
||||
# Create tracker for an operation
|
||||
tracker = ProgressTracker(sio, progress_id, 'crawl')
|
||||
|
||||
# Start tracking
|
||||
await tracker.start({
|
||||
'currentUrl': url,
|
||||
'totalPages': 0,
|
||||
'processedPages': 0
|
||||
})
|
||||
|
||||
# Update progress
|
||||
await tracker.update('crawling', 25, 'Processing page 1 of 4')
|
||||
await tracker.update_crawl_stats(1, 4, 'https://example.com/page1')
|
||||
|
||||
# Complete or error
|
||||
await tracker.complete({
|
||||
'chunksStored': 150,
|
||||
'wordCount': 5000
|
||||
})
|
||||
# OR
|
||||
await tracker.error('Failed to crawl: Network timeout')
|
||||
```
|
||||
|
||||
## Key Service Features
|
||||
|
||||
### Simplified Real-Time Communication (2025 Pattern)
|
||||
|
||||
**Architecture Changes:**
|
||||
- **No database polling** - Eliminated 2-second polling system that checked for task/project changes
|
||||
- **Simple @sio.event handlers** - Uses official Socket.IO 2025 documentation pattern
|
||||
- **No namespace classes** - Removed complex `TasksNamespace` and `ProjectNamespace` classes
|
||||
- **Root namespace only** - Everything runs on `/` namespace for simplicity
|
||||
- **Direct room management** - Simple `sio.enter_room()` and `sio.emit()` calls
|
||||
|
||||
**Simplified Socket.IO Integration:**
|
||||
```python
|
||||
# Services import and use Socket.IO directly
|
||||
from ..socketio_app import get_socketio_instance
|
||||
|
||||
sio = get_socketio_instance()
|
||||
|
||||
# Simple emission to rooms - no namespace complexity
|
||||
await sio.emit('task_updated', task_data, room=project_id)
|
||||
await sio.emit('progress_update', {'status': 'processing', 'percentage': 50}, room=progress_id)
|
||||
|
||||
# Event handlers use simple @sio.event decorators
|
||||
@sio.event
|
||||
async def join_project(sid, data):
|
||||
await sio.enter_room(sid, data['project_id'])
|
||||
tasks = get_tasks_for_project(data['project_id'])
|
||||
await sio.emit('initial_tasks', tasks, to=sid)
|
||||
```
|
||||
|
||||
### Threading Service
|
||||
- Rate limiting for OpenAI API (200k tokens/min)
|
||||
- Thread pools for CPU and I/O operations
|
||||
- Socket.IO-safe batch processing
|
||||
- System metrics monitoring
|
||||
|
||||
### Credential Service
|
||||
- Encrypted credential storage
|
||||
- Category-based organization
|
||||
- Runtime caching for performance
|
||||
- Environment variable compatibility
|
||||
|
||||
### Document Storage
|
||||
- Parallel document processing
|
||||
- Progress reporting via callbacks
|
||||
- Automatic embedding generation
|
||||
- Batch operations for efficiency
|
||||
|
||||
### Crawler Manager
|
||||
- Singleton pattern for global crawler instance
|
||||
- Automatic Docker environment detection
|
||||
- Proper initialization and cleanup
|
||||
- Prevents circular imports
|
||||
|
||||
### LLM Provider Service
|
||||
- Supports multiple providers: OpenAI, Google Gemini, Ollama
|
||||
- OpenAI-compatible interface for all providers
|
||||
- Automatic provider detection from environment
|
||||
- Both async and sync client creation
|
||||
|
||||
## Service Dependencies
|
||||
|
||||
**Refactored Architecture (2025):**
|
||||
|
||||
```
|
||||
FastAPI Endpoints (projects_api.py)
|
||||
↓
|
||||
Socket.IO Handlers (socketio_handlers.py)
|
||||
↓
|
||||
Service Classes (ProjectService, TaskService, etc.)
|
||||
↓
|
||||
Service Functions (add_documents_to_supabase, etc.)
|
||||
↓
|
||||
Database (Supabase) / External APIs (OpenAI)
|
||||
```
|
||||
|
||||
**Key Architectural Changes:**
|
||||
- **Extracted Socket.IO Handlers**: Moved from embedded namespace classes to dedicated `socketio_handlers.py` file (~225 lines)
|
||||
- **Service Layer Separation**: Business logic now in separate service classes instead of embedded in API routes
|
||||
- **Simplified Socket.IO**: Eliminated complex namespace hierarchy in favor of simple `@sio.event` decorators
|
||||
- **Progress Tracking**: Centralized in `ProgressService` with real-time Socket.IO broadcasting
|
||||
|
||||
## Architecture Benefits
|
||||
|
||||
### Improved Code Organization
|
||||
- **Clear Separation**: Utilities vs. service classes are clearly separated
|
||||
- **Single Responsibility**: Each module has one focused purpose
|
||||
- **Reduced Duplication**: Common functionality in base classes
|
||||
- **Better Maintainability**: Easy to find and update specific functionality
|
||||
- **Service Layers**: Business logic separated from API routing (knowledge, projects)
|
||||
|
||||
### Enhanced Extensibility
|
||||
- **Base Classes**: New storage services can extend `BaseStorageService`
|
||||
- **Modular Design**: Easy to add new search algorithms or storage backends
|
||||
- **Service Composition**: Services can be composed for complex operations
|
||||
- **Provider Flexibility**: Easy to add new LLM providers via LLMProviderService
|
||||
|
||||
### Testing & Development
|
||||
- **Isolated Testing**: Each service can be unit tested independently
|
||||
- **Mock Injection**: Services accept clients via dependency injection
|
||||
- **Clear Interfaces**: Well-defined service contracts
|
||||
- **Progress Tracking**: Centralized progress management via ProgressTracker
|
||||
|
||||
## Service Directory Summary
|
||||
|
||||
Complete listing of all service modules organized by functionality:
|
||||
|
||||
```
|
||||
services/
|
||||
├── storage/ # Document and code storage
|
||||
│ ├── base_storage_service.py # Abstract base class
|
||||
│ ├── storage_services.py # DocumentStorageService class
|
||||
│ ├── document_storage_service.py # Storage utilities
|
||||
│ └── code_storage_service.py # Code extraction utilities
|
||||
├── search/ # Search and retrieval
|
||||
│ ├── search_services.py # SearchService class
|
||||
│ └── vector_search_service.py # Vector search utilities
|
||||
├── knowledge/ # Knowledge management (refactored)
|
||||
│ ├── crawl_orchestration_service.py
|
||||
│ ├── knowledge_item_service.py
|
||||
│ ├── code_extraction_service.py
|
||||
│ └── database_metrics_service.py
|
||||
├── projects/ # Project management (refactored)
|
||||
│ ├── project_service.py
|
||||
│ ├── task_service.py
|
||||
│ ├── project_creation_service.py
|
||||
│ ├── source_linking_service.py
|
||||
│ ├── progress_service.py
|
||||
│ ├── document_service.py
|
||||
│ └── versioning_service.py
|
||||
├── rag/ # RAG operations
|
||||
│ └── crawling_service.py # Web crawling
|
||||
├── embeddings/ # Embedding generation
|
||||
│ ├── embedding_service.py
|
||||
│ └── contextual_embedding_service.py
|
||||
└── (core services) # Infrastructure services
|
||||
├── client_manager.py # Database client
|
||||
├── crawler_manager.py # Crawler instance
|
||||
├── credential_service.py # Credentials
|
||||
├── prompt_service.py # Prompts
|
||||
├── threading_service.py # Threading/rate limiting
|
||||
├── mcp_service_client.py # MCP HTTP client
|
||||
├── mcp_session_manager.py # MCP sessions
|
||||
├── source_management_service.py # Sources
|
||||
└── llm_provider_service.py # LLM providers
|
||||
```
|
||||
|
||||
## Configuration
|
||||
|
||||
Services are configured via environment variables:
|
||||
- `SUPABASE_URL` - Database URL
|
||||
- `SUPABASE_SERVICE_KEY` - Database service key
|
||||
- `OPENAI_API_KEY` - For embeddings (or other provider keys)
|
||||
- `LLM_PROVIDER` - LLM provider selection (openai, google, ollama)
|
||||
- `CODE_BLOCK_MIN_LENGTH` - Minimum code block length in characters (default: 1000)
|
||||
- `USE_CONTEXTUAL_EMBEDDINGS` - Enable contextual embeddings
|
||||
- `USE_HYBRID_SEARCH` - Enable hybrid search mode
|
||||
- `USE_RERANKING` - Enable search result reranking
|
||||
|
||||
All services use dependency injection for testability and flexibility.
|
||||
|
||||
## Troubleshooting
|
||||
|
||||
### Code Extraction Issues
|
||||
|
||||
If code blocks are not being extracted properly:
|
||||
|
||||
1. **Check the minimum length**: The default `CODE_BLOCK_MIN_LENGTH` is 1000 characters. This ensures only substantial code blocks are extracted, not small snippets.
|
||||
|
||||
2. **Verify markdown format**: Code blocks must be wrapped in triple backticks (```) to be recognized.
|
||||
|
||||
3. **HTML fallback**: If markdown doesn't contain code blocks, the system will try to extract from HTML using `<pre>` and `<code>` tags.
|
||||
|
||||
### Crawling Performance
|
||||
|
||||
The crawling service uses simple configurations for reliability:
|
||||
|
||||
- No complex JavaScript waiting by default
|
||||
- No forced element clicking
|
||||
- Straightforward markdown extraction
|
||||
|
||||
If you need advanced crawling features for specific sites:
|
||||
|
||||
1. Consider implementing site-specific handlers
|
||||
2. Use the `js_code` parameter only when necessary
|
||||
3. Avoid `wait_for` selectors unless you're certain the elements exist
|
||||
|
||||
### Progress Tracking
|
||||
|
||||
Progress updates during crawling:
|
||||
|
||||
- **0-45%**: Crawling pages
|
||||
- **45-50%**: Processing crawl results
|
||||
- **50-75%**: Storing documents with real-time batch updates
|
||||
- **75-90%**: Extracting and storing code examples
|
||||
- **90-100%**: Finalizing and cleanup
|
||||
|
||||
If progress appears stuck, check the logs for batch processing updates.
|
||||
457
docs/docs/socketio.mdx
Normal file
@@ -0,0 +1,457 @@
|
||||
---
|
||||
title: Real-time Communication (Socket.IO)
|
||||
description: Simple Socket.IO implementation for real-time features
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# Real-time Communication with Socket.IO
|
||||
|
||||
## Overview
|
||||
|
||||
Archon uses **Socket.IO** for real-time communication between the frontend and backend. We follow 2025 best practices - all events on the default namespace with room-based organization.
|
||||
|
||||
<Admonition type="success" title="Simple by Design">
|
||||
- **Default namespace only**: Everything on root `/` namespace
|
||||
- **Room-based organization**: Projects, progress tracking, and features use rooms
|
||||
- **Simple events**: Clear event names with `@sio.event` decorators
|
||||
- **Automatic reconnection**: Socket.IO handles connection reliability
|
||||
- **~100 lines total**: For the entire real-time system
|
||||
</Admonition>
|
||||
|
||||
## Socket.IO Rooms Architecture
|
||||
|
||||
Rooms provide isolated communication channels within the default namespace:
|
||||
|
||||
### Room Types
|
||||
|
||||
| Room Pattern | Purpose | Example Room ID | Members |
|
||||
|--------------|---------|-----------------|---------|
|
||||
| `project_list` | Project list updates | `project_list` | Users viewing project dashboard |
|
||||
| `{project_id}` | Project-specific updates | `abc123-def456` | Users viewing that project |
|
||||
| `{progress_id}` | Progress tracking | `progress_789` | Users tracking creation/crawl progress |
|
||||
| `chat_{session_id}` | Agent chat sessions | `chat_session_123` | Individual chat participants |
|
||||
|
||||
## Socket.IO Events
|
||||
|
||||
All events use simple names on the root namespace:
|
||||
|
||||
| Event | Direction | Purpose | Data Format |
|
||||
|-------|-----------|---------|-------------|
|
||||
| `connect` | Server→Client | Connection established | `{sid: string}` |
|
||||
| `disconnect` | Server→Client | Connection closed | None |
|
||||
| `join_project` | Client→Server | Join project room for task updates | `{project_id: string}` |
|
||||
| `leave_project` | Client→Server | Leave project room | `{project_id: string}` |
|
||||
| `subscribe_projects` | Client→Server | Subscribe to project list updates | None |
|
||||
| `unsubscribe_projects` | Client→Server | Unsubscribe from project list | None |
|
||||
| `subscribe_progress` | Client→Server | Subscribe to creation progress | `{progress_id: string}` |
|
||||
| `unsubscribe_progress` | Client→Server | Unsubscribe from progress | `{progress_id: string}` |
|
||||
| `crawl_subscribe` | Client→Server | Subscribe to crawl progress | `{progress_id: string}` |
|
||||
| `crawl_unsubscribe` | Client→Server | Unsubscribe from crawl | `{progress_id: string}` |
|
||||
| `crawl_stop` | Client→Server | Stop an active crawl | `{progress_id: string}` |
|
||||
|
||||
## Broadcast Events
|
||||
|
||||
These are emitted by the server to rooms:
|
||||
|
||||
| Event | Purpose | Room | Data |
|
||||
|-------|---------|------|------|
|
||||
| `task_created` | New task created | project_id | Task object |
|
||||
| `task_updated` | Task modified | project_id | Task object |
|
||||
| `task_deleted` | Task removed | project_id | `{task_id: string}` |
|
||||
| `projects_update` | Project list changed | 'project_list' | `{projects: Array}` |
|
||||
| `project_progress` | Creation progress | progress_id | Progress data |
|
||||
| `crawl_progress` | Crawl progress | progress_id | Progress data |
|
||||
| `crawl:stopping` | Crawl is stopping | progress_id | `{progressId, status, message}` |
|
||||
| `crawl:stopped` | Crawl has stopped | progress_id | `{progressId, status, message, timestamp}` |
|
||||
|
||||
## Frontend Usage
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="basic" label="Room-Based Connection">
|
||||
|
||||
```typescript
|
||||
import { createWebSocketService } from './services/webSocketService';
|
||||
|
||||
// Always connect to default namespace
|
||||
const ws = createWebSocketService();
|
||||
await ws.connect('/');
|
||||
|
||||
// Join specific rooms via events
|
||||
ws.send({
|
||||
type: 'join_project',
|
||||
data: { project_id: 'abc123' }
|
||||
});
|
||||
|
||||
// Subscribe to project list room
|
||||
ws.send({ type: 'subscribe_projects' });
|
||||
|
||||
// Listen for room-specific updates
|
||||
ws.addMessageHandler('task_created', (message) => {
|
||||
console.log('New task in project room:', message.data);
|
||||
});
|
||||
|
||||
ws.addMessageHandler('projects_update', (message) => {
|
||||
console.log('Project list updated:', message.data.projects);
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="progress" label="Progress Room Tracking">
|
||||
|
||||
```typescript
|
||||
// Subscribe to progress room
|
||||
ws.send({
|
||||
type: 'subscribe_progress',
|
||||
data: { progress_id: progressId }
|
||||
});
|
||||
|
||||
// Handle progress updates from room
|
||||
ws.addMessageHandler('project_progress', (message) => {
|
||||
const { percentage, status, step } = message.data;
|
||||
updateProgress(percentage, status, step);
|
||||
});
|
||||
|
||||
// Unsubscribe from progress room
|
||||
ws.send({
|
||||
type: 'unsubscribe_progress',
|
||||
data: { progress_id: progressId }
|
||||
});
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="service" label="Service Pattern">
|
||||
|
||||
```typescript
|
||||
class ProjectProgressService {
|
||||
private wsService: WebSocketService | null = null;
|
||||
|
||||
async streamProgress(progressId: string, onMessage: (data: any) => void) {
|
||||
this.wsService = createWebSocketService();
|
||||
|
||||
// Always connect to default namespace
|
||||
await this.wsService.connect('/');
|
||||
|
||||
// Subscribe to progress room
|
||||
this.wsService.send({
|
||||
type: 'subscribe_progress',
|
||||
data: { progress_id: progressId }
|
||||
});
|
||||
|
||||
// Handle room messages
|
||||
this.wsService.addMessageHandler('project_progress', (message) => {
|
||||
onMessage(message.data);
|
||||
});
|
||||
}
|
||||
|
||||
disconnect() {
|
||||
if (this.wsService) {
|
||||
// Rooms are cleaned up automatically
|
||||
this.wsService.disconnect();
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Backend Implementation
|
||||
|
||||
All Socket.IO code lives in `projects_api.py`:
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="events" label="Event Handlers">
|
||||
|
||||
```python
|
||||
# Get Socket.IO instance
|
||||
from ..socketio_app import get_socketio_instance
|
||||
sio = get_socketio_instance()
|
||||
|
||||
# Simple event handlers
|
||||
@sio.event
|
||||
async def connect(sid, environ):
|
||||
print(f'Client connected: {sid}')
|
||||
|
||||
@sio.event
|
||||
async def join_project(sid, data):
|
||||
project_id = data.get('project_id')
|
||||
if project_id:
|
||||
await sio.enter_room(sid, project_id)
|
||||
# Send initial tasks
|
||||
tasks = await get_project_tasks(project_id)
|
||||
await sio.emit('initial_tasks', tasks, to=sid)
|
||||
|
||||
@sio.event
|
||||
async def subscribe_projects(sid):
|
||||
await sio.enter_room(sid, 'project_list')
|
||||
# Send current projects
|
||||
projects = await get_all_projects()
|
||||
await sio.emit('projects_update', {'projects': projects}, to=sid)
|
||||
|
||||
@sio.event
|
||||
async def crawl_subscribe(sid, data):
|
||||
progress_id = data.get('progress_id')
|
||||
if progress_id:
|
||||
await sio.enter_room(sid, progress_id)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="broadcast" label="Broadcasting">
|
||||
|
||||
```python
|
||||
# Simple broadcast helpers
|
||||
async def broadcast_task_update(project_id: str, event_type: str, task_data: dict):
|
||||
"""Broadcast task updates to project room."""
|
||||
await sio.emit(event_type, task_data, room=project_id)
|
||||
|
||||
async def broadcast_project_update():
|
||||
"""Broadcast project list to subscribers."""
|
||||
projects = await get_all_projects()
|
||||
await sio.emit('projects_update', {'projects': projects}, room='project_list')
|
||||
|
||||
async def broadcast_crawl_progress(progress_id: str, data: dict):
|
||||
"""Broadcast crawl progress to subscribers."""
|
||||
# Include the progress_id in data for client-side filtering
|
||||
data['progressId'] = progress_id
|
||||
await sio.emit('crawl_progress', data, room=progress_id)
|
||||
|
||||
# Usage in services
|
||||
await broadcast_task_update(project_id, 'task_created', new_task)
|
||||
await broadcast_crawl_progress(progress_id, {'percentage': 50, 'status': 'crawling'})
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## Server Configuration
|
||||
|
||||
The Socket.IO server is configured in `socketio_app.py`:
|
||||
|
||||
```python
|
||||
import socketio
|
||||
|
||||
# Create server with simple settings
|
||||
sio = socketio.AsyncServer(
|
||||
async_mode='asgi',
|
||||
cors_allowed_origins="*",
|
||||
logger=False,
|
||||
engineio_logger=False,
|
||||
max_http_buffer_size=1000000, # 1MB
|
||||
ping_timeout=60,
|
||||
ping_interval=25
|
||||
)
|
||||
|
||||
# Wrap with FastAPI
|
||||
def create_socketio_app(app: FastAPI):
|
||||
return socketio.ASGIApp(sio, other_asgi_app=app)
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
<Admonition type="tip" title="Room-Based Organization">
|
||||
1. **Default namespace only** - Never use custom namespaces like `/chat` or `/project`
|
||||
2. **Rooms for isolation** - Use rooms to group related clients
|
||||
3. **Clear room naming** - Use IDs like `project_abc123` or descriptive names like `project_list`
|
||||
4. **Join on connect** - Add clients to appropriate rooms immediately after connection
|
||||
5. **Leave on disconnect** - Socket.IO handles room cleanup automatically
|
||||
6. **Broadcast to rooms** - Target specific audiences with `room=room_id`
|
||||
</Admonition>
|
||||
|
||||
### Room Management Best Practices
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="joining" label="Joining Rooms">
|
||||
|
||||
```python
|
||||
@sio.event
|
||||
async def join_project(sid, data):
|
||||
"""Join a project room for real-time updates."""
|
||||
project_id = data.get('project_id')
|
||||
if project_id:
|
||||
# Join the project-specific room
|
||||
await sio.enter_room(sid, project_id)
|
||||
|
||||
# Send current state to the new member
|
||||
tasks = await get_project_tasks(project_id)
|
||||
await sio.emit('initial_tasks', tasks, to=sid)
|
||||
|
||||
logger.info(f"Client {sid} joined project room {project_id}")
|
||||
|
||||
@sio.event
|
||||
async def subscribe_projects(sid, data=None):
|
||||
"""Subscribe to project list updates."""
|
||||
await sio.enter_room(sid, 'project_list')
|
||||
|
||||
# Send current project list
|
||||
projects = await get_all_projects()
|
||||
await sio.emit('projects_update', {'projects': projects}, to=sid)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="broadcasting" label="Broadcasting to Rooms">
|
||||
|
||||
```python
|
||||
async def broadcast_task_update(project_id: str, event_type: str, task_data: dict):
|
||||
"""Broadcast task updates to all project members."""
|
||||
await sio.emit(event_type, task_data, room=project_id)
|
||||
|
||||
async def broadcast_project_list_update():
|
||||
"""Notify all project list subscribers."""
|
||||
projects = await get_all_projects()
|
||||
await sio.emit('projects_update', {'projects': projects}, room='project_list')
|
||||
|
||||
async def broadcast_progress_update(progress_id: str, progress_data: dict):
|
||||
"""Update progress subscribers."""
|
||||
await sio.emit('progress_update', progress_data, room=progress_id)
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="cleanup" label="Room Cleanup">
|
||||
|
||||
```python
|
||||
@sio.event
|
||||
async def leave_project(sid, data):
|
||||
"""Leave a project room."""
|
||||
project_id = data.get('project_id')
|
||||
if project_id:
|
||||
await sio.leave_room(sid, project_id)
|
||||
logger.info(f"Client {sid} left project room {project_id}")
|
||||
|
||||
@sio.event
|
||||
async def disconnect(sid):
|
||||
"""Handle client disconnection."""
|
||||
# Socket.IO automatically removes client from all rooms
|
||||
logger.info(f"Client {sid} disconnected")
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
<Admonition type="warning" title="Common Mistakes">
|
||||
- **Don't use namespaces** - Stick to the default `/` namespace
|
||||
- **Don't broadcast to all** - Use rooms to target specific audiences
|
||||
- **Don't forget room cleanup** - Let Socket.IO handle it automatically
|
||||
- **Don't create custom reconnection logic** - Socket.IO handles it
|
||||
</Admonition>
|
||||
|
||||
## Common Patterns
|
||||
|
||||
### Task Updates
|
||||
```python
|
||||
# In task service
|
||||
async def create_task(...):
|
||||
task = await db.create_task(...)
|
||||
await broadcast_task_update(task.project_id, 'task_created', task)
|
||||
return task
|
||||
```
|
||||
|
||||
### Progress Tracking
|
||||
```python
|
||||
# In crawl service
|
||||
async def update_progress(progress_id: str, percentage: int):
|
||||
await broadcast_crawl_progress(progress_id, {
|
||||
'percentage': percentage,
|
||||
'status': 'crawling',
|
||||
'timestamp': datetime.now().isoformat()
|
||||
})
|
||||
```
|
||||
|
||||
### Crawl Cancellation
|
||||
```python
|
||||
# Client-side stop request
|
||||
ws.send({
|
||||
type: 'crawl_stop',
|
||||
data: { progress_id: progressId }
|
||||
});
|
||||
|
||||
# Server-side handler
|
||||
@sio.event
|
||||
async def crawl_stop(sid, data):
|
||||
progress_id = data.get('progress_id')
|
||||
|
||||
# Emit immediate feedback
|
||||
await sio.emit('crawl:stopping', {
|
||||
'progressId': progress_id,
|
||||
'status': 'stopping',
|
||||
'message': 'Stopping crawl operation...'
|
||||
}, room=progress_id)
|
||||
|
||||
# Cancel orchestration and asyncio task
|
||||
orchestration = get_active_orchestration(progress_id)
|
||||
if orchestration:
|
||||
orchestration.cancel()
|
||||
|
||||
# Cancel asyncio task if exists
|
||||
if progress_id in active_crawl_tasks:
|
||||
task = active_crawl_tasks[progress_id]
|
||||
if not task.done():
|
||||
task.cancel()
|
||||
|
||||
# Emit completion
|
||||
await sio.emit('crawl:stopped', {
|
||||
'progressId': progress_id,
|
||||
'status': 'cancelled',
|
||||
'message': 'Crawl operation cancelled',
|
||||
'timestamp': datetime.utcnow().isoformat()
|
||||
}, room=progress_id)
|
||||
```
|
||||
|
||||
### Async Progress Callbacks
|
||||
|
||||
<Admonition type="warning" title="Critical: Async Callback Pattern">
|
||||
When passing progress callbacks to services, ensure proper async handling:
|
||||
|
||||
```python
|
||||
# ❌ WRONG - Creates unawaited coroutine
|
||||
progress_callback=lambda data: update_crawl_progress(progress_id, data)
|
||||
|
||||
# ✅ CORRECT - Properly schedules async execution
|
||||
progress_callback=lambda data: asyncio.create_task(update_crawl_progress(progress_id, data))
|
||||
```
|
||||
|
||||
This pattern is essential when services need to report progress through async Socket.IO broadcasts.
|
||||
</Admonition>
|
||||
|
||||
## Room-Based Architecture Summary
|
||||
|
||||
<Admonition type="info" title="2025 Socket.IO Best Practices">
|
||||
Archon follows modern Socket.IO patterns with:
|
||||
- **Default namespace only** - No custom namespaces like `/chat` or `/project`
|
||||
- **Room-based isolation** - Each feature uses specific rooms for targeted communication
|
||||
- **Automatic cleanup** - Socket.IO handles room membership and reconnection
|
||||
- **Simple event names** - Clear, descriptive event names for better debugging
|
||||
</Admonition>
|
||||
|
||||
### Key Benefits
|
||||
|
||||
1. **Scalability**: Rooms allow targeting specific user groups without broadcasting to all
|
||||
2. **Isolation**: Project updates don't affect users in other projects
|
||||
3. **Reliability**: Socket.IO handles reconnection and room re-joining automatically
|
||||
4. **Simplicity**: No namespace complexity, just rooms within the default namespace
|
||||
5. **Performance**: Targeted broadcasts reduce unnecessary network traffic
|
||||
|
||||
### Architecture Diagram
|
||||
|
||||
```mermaid
|
||||
graph TB
|
||||
Client1[Client 1] --> Namespace[Default Namespace '/']
|
||||
Client2[Client 2] --> Namespace
|
||||
Client3[Client 3] --> Namespace
|
||||
|
||||
Namespace --> ProjectRoom[Project Room 'abc123']
|
||||
Namespace --> ListRoom[Project List Room 'project_list']
|
||||
Namespace --> ProgressRoom[Progress Room 'progress_789']
|
||||
|
||||
ProjectRoom --> Client1
|
||||
ListRoom --> Client1
|
||||
ListRoom --> Client2
|
||||
ProgressRoom --> Client3
|
||||
```
|
||||
|
||||
## That's It!
|
||||
|
||||
No namespaces. No complex patterns. Room-based organization within the default namespace. Simple events with clear targeting. Total complexity: ~100 lines of Socket.IO code for a production-ready real-time system.
|
||||
441
docs/docs/testing-python-strategy.mdx
Normal file
@@ -0,0 +1,441 @@
|
||||
---
|
||||
title: Python Testing Strategy
|
||||
sidebar_position: 9
|
||||
---
|
||||
|
||||
# Python Testing Strategy with pytest
|
||||
|
||||
This document outlines Archon's Python testing strategy for our multi-container architecture, emphasizing simplicity and effectiveness.
|
||||
|
||||
## 🎯 Testing Philosophy
|
||||
|
||||
Our Python testing follows these core principles:
|
||||
|
||||
1. **Fast Tests**: Each test runs in milliseconds, entire suite in <30 seconds
|
||||
2. **Simple Names**: `test_<what>_<condition>_<expected_result>` pattern
|
||||
3. **Independent Tests**: No shared state, each test is self-contained
|
||||
4. **Minimal Fixtures**: Only essential mocks, no complex hierarchies
|
||||
5. **Container Isolation**: Test each container's boundaries separately
|
||||
|
||||
## 📁 Multi-Container Test Structure
|
||||
|
||||
```
|
||||
python/tests/
|
||||
├── conftest.py # Minimal shared fixtures
|
||||
├── pytest.ini # Simple pytest configuration
|
||||
├── server/ # Server container tests (FastAPI + Socket.IO)
|
||||
│ ├── test_api.py # API endpoint tests
|
||||
│ ├── test_services.py # Service layer tests
|
||||
│ └── test_socketio.py # Socket.IO event tests
|
||||
├── mcp/ # MCP container tests
|
||||
│ ├── test_server.py # MCP server lifecycle
|
||||
│ └── test_tools.py # Tool execution tests
|
||||
├── agents/ # Agents container tests
|
||||
│ ├── test_rag.py # RAG agent tests
|
||||
│ └── test_document.py # Document agent tests
|
||||
└── integration/ # Cross-container tests
|
||||
└── test_workflows.py # End-to-end scenarios
|
||||
```
|
||||
|
||||
## 🔧 Minimal Configuration
|
||||
|
||||
### pytest.ini
|
||||
|
||||
```ini
|
||||
[pytest]
|
||||
testpaths = tests
|
||||
python_files = test_*.py
|
||||
python_functions = test_*
|
||||
addopts = -v --tb=short --strict-markers
|
||||
markers =
|
||||
server: Server container tests
|
||||
mcp: MCP container tests
|
||||
agents: Agents container tests
|
||||
integration: Cross-container tests
|
||||
slow: Slow tests (skip with -m "not slow")
|
||||
asyncio_mode = auto
|
||||
```
|
||||
|
||||
### pyproject.toml
|
||||
|
||||
```toml
|
||||
[project.optional-dependencies]
|
||||
test = [
|
||||
"pytest>=8.0.0",
|
||||
"pytest-asyncio>=0.21.0",
|
||||
"pytest-mock>=3.12.0",
|
||||
"httpx>=0.24.0",
|
||||
"pytest-cov>=4.1.0",
|
||||
]
|
||||
|
||||
[tool.pytest.ini_options]
|
||||
testpaths = ["tests"]
|
||||
addopts = [
|
||||
"-v",
|
||||
"--tb=short",
|
||||
"--cov=src",
|
||||
"--cov-report=term-missing:skip-covered",
|
||||
"--cov-fail-under=80"
|
||||
]
|
||||
|
||||
[tool.coverage.run]
|
||||
source = ["src"]
|
||||
omit = ["*/tests/*", "*/__init__.py"]
|
||||
```
|
||||
|
||||
## 🧪 Container-Specific Testing Patterns
|
||||
|
||||
### 1. Server Container Tests (FastAPI + Socket.IO)
|
||||
|
||||
```python
|
||||
# tests/server/test_api.py
|
||||
import pytest
|
||||
from httpx import AsyncClient
|
||||
|
||||
@pytest.mark.server
|
||||
class TestKnowledgeAPI:
|
||||
"""API contract tests - verify endpoint behavior without implementation details."""
|
||||
|
||||
async def test_upload_document_returns_success(self, client: AsyncClient):
|
||||
"""Upload endpoint should return 200 with document_id."""
|
||||
# Arrange
|
||||
files = {"file": ("test.pdf", b"PDF content", "application/pdf")}
|
||||
|
||||
# Act
|
||||
response = await client.post("/api/documents/upload", files=files)
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
assert "document_id" in response.json()
|
||||
|
||||
async def test_upload_invalid_file_returns_400(self, client: AsyncClient):
|
||||
"""Upload endpoint should reject invalid files."""
|
||||
# Arrange
|
||||
files = {"file": ("test.exe", b"EXE content", "application/x-executable")}
|
||||
|
||||
# Act
|
||||
response = await client.post("/api/documents/upload", files=files)
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 400
|
||||
```
|
||||
|
||||
```python
|
||||
# tests/server/test_socketio.py
|
||||
import pytest
|
||||
from unittest.mock import AsyncMock, patch
|
||||
|
||||
@pytest.mark.server
|
||||
class TestSocketIO:
|
||||
"""Test Socket.IO events with focus on room management and broadcasting."""
|
||||
|
||||
@patch('src.server.socketio_app.sio')
|
||||
async def test_crawl_subscribe_joins_room(self, mock_sio):
|
||||
"""crawl_subscribe should add client to progress room."""
|
||||
# Arrange
|
||||
sid = "test-sid-123"
|
||||
progress_id = "progress-456"
|
||||
|
||||
# Act
|
||||
from src.server.fastapi.socketio_handlers import crawl_subscribe
|
||||
await crawl_subscribe(sid, {"progress_id": progress_id})
|
||||
|
||||
# Assert
|
||||
mock_sio.enter_room.assert_called_once_with(sid, progress_id)
|
||||
```
|
||||
|
||||
### 2. MCP Container Tests
|
||||
|
||||
```python
|
||||
# tests/mcp/test_tools.py
|
||||
import pytest
|
||||
import json
|
||||
|
||||
@pytest.mark.mcp
|
||||
class TestMCPTools:
|
||||
"""Test MCP tools with focus on input/output contracts."""
|
||||
|
||||
async def test_health_check_returns_status(self, mcp_server):
|
||||
"""health_check tool should return system status."""
|
||||
# Act
|
||||
result = await mcp_server.call_tool("health_check", {})
|
||||
|
||||
# Assert
|
||||
assert len(result) > 0
|
||||
data = json.loads(result[0].text)
|
||||
assert data["status"] in ["healthy", "degraded", "unhealthy"]
|
||||
|
||||
async def test_manage_project_creates_project(self, mcp_server):
|
||||
"""manage_project with action=create should return project."""
|
||||
# Arrange
|
||||
params = {
|
||||
"action": "create",
|
||||
"title": "Test Project"
|
||||
}
|
||||
|
||||
# Act
|
||||
result = await mcp_server.call_tool("manage_project", params)
|
||||
|
||||
# Assert
|
||||
data = json.loads(result[0].text)
|
||||
assert data["success"] is True
|
||||
assert "project_id" in data
|
||||
```
|
||||
|
||||
### 3. Agents Container Tests
|
||||
|
||||
```python
|
||||
# tests/agents/test_rag.py
|
||||
import pytest
|
||||
|
||||
@pytest.mark.agents
|
||||
class TestRAGAgent:
|
||||
"""Test RAG agent query/response functionality."""
|
||||
|
||||
async def test_rag_query_returns_results(self, rag_agent_client):
|
||||
"""RAG query should return relevant documents."""
|
||||
# Arrange
|
||||
query = "How to implement authentication?"
|
||||
|
||||
# Act
|
||||
response = await rag_agent_client.post("/query", json={"query": query})
|
||||
|
||||
# Assert
|
||||
assert response.status_code == 200
|
||||
data = response.json()
|
||||
assert "results" in data
|
||||
assert len(data["results"]) > 0
|
||||
```
|
||||
|
||||
### 4. Integration Tests
|
||||
|
||||
```python
|
||||
# tests/integration/test_workflows.py
|
||||
import pytest
|
||||
|
||||
@pytest.mark.integration
|
||||
class TestCrossContainerWorkflows:
|
||||
"""Test complete workflows across containers."""
|
||||
|
||||
async def test_crawl_to_query_workflow(self, server_client, mcp_client):
|
||||
"""Test full crawl -> store -> query workflow."""
|
||||
# Step 1: Start crawl via Server
|
||||
crawl_response = await server_client.post("/api/knowledge/crawl", json={
|
||||
"url": "https://example.com"
|
||||
})
|
||||
assert crawl_response.status_code == 200
|
||||
progress_id = crawl_response.json()["progress_id"]
|
||||
|
||||
# Step 2: Wait for completion (simplified)
|
||||
await asyncio.sleep(2)
|
||||
|
||||
# Step 3: Query via MCP
|
||||
result = await mcp_client.call_tool("perform_rag_query", {
|
||||
"query": "What is example.com about?",
|
||||
"source": "example.com"
|
||||
})
|
||||
|
||||
# Assert
|
||||
assert len(result) > 0
|
||||
data = json.loads(result[0].text)
|
||||
assert data["success"] is True
|
||||
```
|
||||
|
||||
## 🔧 Minimal Fixtures
|
||||
|
||||
```python
|
||||
# tests/conftest.py - Keep it simple!
|
||||
import pytest
|
||||
from httpx import AsyncClient, ASGITransport
|
||||
from unittest.mock import AsyncMock
|
||||
|
||||
@pytest.fixture
|
||||
async def server_client():
|
||||
"""Test client for Server container."""
|
||||
from src.server.main import app
|
||||
transport = ASGITransport(app=app)
|
||||
async with AsyncClient(transport=transport, base_url="http://test") as client:
|
||||
yield client
|
||||
|
||||
@pytest.fixture
|
||||
async def mcp_server():
|
||||
"""Mock MCP server for testing tools."""
|
||||
from src.mcp.mcp_server import ArchonMCPServer
|
||||
server = ArchonMCPServer()
|
||||
# Mock dependencies
|
||||
server.supabase_client = AsyncMock()
|
||||
server.supabase_client.from_.return_value.select.return_value.execute.return_value.data = []
|
||||
return server
|
||||
|
||||
@pytest.fixture
|
||||
def mock_supabase():
|
||||
"""Simple Supabase mock."""
|
||||
mock = AsyncMock()
|
||||
mock.from_.return_value.select.return_value.execute.return_value.data = []
|
||||
mock.from_.return_value.insert.return_value.execute.return_value.data = [{"id": "test-123"}]
|
||||
return mock
|
||||
|
||||
# That's it! No complex factories, no session management, just the basics.
|
||||
```
|
||||
|
||||
## 🚀 Testing Commands
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Run all tests
|
||||
pytest
|
||||
|
||||
# Run with coverage
|
||||
pytest --cov=src --cov-report=html
|
||||
|
||||
# Run specific test categories
|
||||
pytest -m unit # Unit tests only
|
||||
pytest -m integration # Integration tests only
|
||||
pytest -m "not slow" # Skip slow tests
|
||||
|
||||
# Run specific test file or directory
|
||||
pytest tests/unit/test_services/
|
||||
pytest tests/unit/test_services/test_project_service.py::TestProjectService::test_create_project_with_valid_data_should_succeed
|
||||
|
||||
# Run with different verbosity
|
||||
pytest -v # Verbose output
|
||||
pytest -vv # Very verbose output
|
||||
pytest -q # Quiet mode
|
||||
|
||||
# Run tests in parallel
|
||||
pytest -n auto # Requires pytest-xdist
|
||||
|
||||
# Run with specific Python warnings
|
||||
pytest -W error # Treat warnings as errors
|
||||
```
|
||||
|
||||
### Debugging Tests
|
||||
|
||||
```bash
|
||||
# Drop into debugger on failure
|
||||
pytest --pdb
|
||||
|
||||
# Show local variables on failure
|
||||
pytest -l
|
||||
|
||||
# Show full diff on assertion failure
|
||||
pytest -vv
|
||||
|
||||
# Run only last failed tests
|
||||
pytest --lf
|
||||
|
||||
# Run failed tests first, then others
|
||||
pytest --ff
|
||||
```
|
||||
|
||||
## 📊 Code Coverage
|
||||
|
||||
### Coverage Requirements
|
||||
|
||||
- **Overall Coverage**: Minimum 80%
|
||||
- **Critical Paths**: 95%+ (authentication, payments, data operations)
|
||||
- **New Code**: 90%+ coverage required for all PRs
|
||||
|
||||
### Coverage Reports
|
||||
|
||||
```bash
|
||||
# Generate HTML coverage report
|
||||
pytest --cov=src --cov-report=html
|
||||
# Open htmlcov/index.html in browser
|
||||
|
||||
# Generate terminal report
|
||||
pytest --cov=src --cov-report=term-missing
|
||||
|
||||
# Generate XML for CI/CD
|
||||
pytest --cov=src --cov-report=xml
|
||||
|
||||
# Check coverage thresholds
|
||||
pytest --cov=src --cov-fail-under=80
|
||||
```
|
||||
|
||||
## 🔄 CI/CD Integration
|
||||
|
||||
### GitHub Actions Workflow
|
||||
|
||||
```yaml
|
||||
name: Python Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
strategy:
|
||||
matrix:
|
||||
python-version: ["3.11", "3.12"]
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Set up Python
|
||||
uses: actions/setup-python@v4
|
||||
with:
|
||||
python-version: ${{ matrix.python-version }}
|
||||
|
||||
- name: Install dependencies
|
||||
run: |
|
||||
python -m pip install --upgrade pip
|
||||
pip install -e ".[test]"
|
||||
|
||||
- name: Run tests with coverage
|
||||
run: |
|
||||
pytest --cov=src --cov-report=xml --cov-report=term
|
||||
|
||||
- name: Upload coverage to Codecov
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: ./coverage.xml
|
||||
fail_ci_if_error: true
|
||||
```
|
||||
|
||||
## 🎯 Testing Checklist
|
||||
|
||||
### For New Features
|
||||
|
||||
- [ ] Write unit tests for all new functions/methods
|
||||
- [ ] Write integration tests for API endpoints
|
||||
- [ ] Add edge case tests
|
||||
- [ ] Add error handling tests
|
||||
- [ ] Update or add fixtures as needed
|
||||
- [ ] Ensure 90%+ coverage for new code
|
||||
- [ ] Run full test suite locally
|
||||
- [ ] Update documentation
|
||||
|
||||
### For Bug Fixes
|
||||
|
||||
- [ ] Write a failing test that reproduces the bug
|
||||
- [ ] Fix the bug
|
||||
- [ ] Ensure test now passes
|
||||
- [ ] Add regression tests
|
||||
- [ ] Check for similar issues elsewhere
|
||||
- [ ] Run related test suites
|
||||
|
||||
## 📚 Best Practices Summary
|
||||
|
||||
1. **Use Descriptive Test Names**: Test names should describe what is being tested and expected outcome
|
||||
2. **Follow AAA Pattern**: Arrange, Act, Assert for clear test structure
|
||||
3. **One Assertion Per Test**: Keep tests focused on single behavior
|
||||
4. **Use Fixtures Wisely**: Share setup code but avoid over-coupling
|
||||
5. **Mock External Dependencies**: Keep tests fast and deterministic
|
||||
6. **Parameterize Similar Tests**: Use `@pytest.mark.parametrize` for test variations
|
||||
7. **Test Edge Cases**: Include boundary conditions and error scenarios
|
||||
8. **Keep Tests Fast**: Aim for entire suite to run in under 5 minutes
|
||||
9. **Use Markers**: Organize tests with markers for selective execution
|
||||
10. **Continuous Improvement**: Regularly review and refactor tests
|
||||
|
||||
---
|
||||
|
||||
For more details, see:
|
||||
- [Testing Overview](./testing) - General testing documentation
|
||||
- [Vitest Strategy](./testing-vitest-strategy) - Frontend testing with Vitest
|
||||
- [API Reference](./api-reference) - API endpoint documentation
|
||||
912
docs/docs/testing-vitest-strategy.mdx
Normal file
@@ -0,0 +1,912 @@
|
||||
---
|
||||
title: Vitest Testing Strategy
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
# Vitest Testing Strategy for React & TypeScript
|
||||
|
||||
This document outlines Archon's comprehensive frontend testing strategy using Vitest with React and TypeScript, incorporating the latest best practices and our current implementation.
|
||||
|
||||
## 🎯 Testing Philosophy
|
||||
|
||||
Our frontend testing follows these core principles:
|
||||
|
||||
1. **User-Centric Testing**: Test behavior from the user's perspective, not implementation details
|
||||
2. **Component Isolation**: Each component test should be independent
|
||||
3. **TypeScript Safety**: Leverage TypeScript for type-safe tests
|
||||
4. **Fast Feedback**: Vitest's speed enables rapid test-driven development
|
||||
5. **Meaningful Coverage**: Focus on critical user paths over coverage numbers
|
||||
6. **Socket.IO Safety**: Never create real Socket.IO connections in tests
|
||||
|
||||
## 📁 Current Project Structure
|
||||
|
||||
```
|
||||
archon-ui-main/
|
||||
├── vitest.config.ts # Vitest configuration with coverage
|
||||
├── vite.config.ts # Dev server with test endpoints
|
||||
├── test/
|
||||
│ ├── setup.ts # Enhanced test setup with comprehensive mocks
|
||||
│ ├── README_TEST_GUIDE.md # Comprehensive testing guide
|
||||
│ ├── TEST_STRUCTURE.md # File structure documentation
|
||||
│ ├── components/ # Component tests (68 files planned)
|
||||
│ │ ├── ui/ # UI component tests (8 files)
|
||||
│ │ ├── layouts/ # Layout component tests (3 files)
|
||||
│ │ ├── mcp/ # MCP component tests (3 files)
|
||||
│ │ ├── settings/ # Settings component tests (5 files)
|
||||
│ │ ├── project-tasks/ # Project task component tests (10 files)
|
||||
│ │ ├── knowledge-base/ # Knowledge component tests (1 file)
|
||||
│ │ └── animations/ # Animation component tests (1 file)
|
||||
│ ├── services/ # Service layer tests (12 files)
|
||||
│ ├── pages/ # Page component tests (5 files)
|
||||
│ ├── hooks/ # Custom hook tests (2 files)
|
||||
│ ├── contexts/ # Context provider tests (3 files)
|
||||
│ ├── lib/ # Utility function tests (2 files)
|
||||
│ ├── integration/ # Integration tests (8 files)
|
||||
│ ├── e2e/ # End-to-end tests (5 files)
|
||||
│ ├── performance/ # Performance tests (3 files)
|
||||
│ ├── fixtures/ # Test data and mocks
|
||||
│ └── utils/ # Test utilities
|
||||
└── coverage/ # Generated coverage reports
|
||||
├── index.html # HTML coverage report
|
||||
├── coverage-summary.json # Coverage summary for UI
|
||||
└── test-results.json # Test execution results
|
||||
```
|
||||
|
||||
## 🔧 Configuration
|
||||
|
||||
### vitest.config.ts
|
||||
|
||||
```typescript
|
||||
import { defineConfig } from 'vitest/config'
|
||||
import react from '@vitejs/plugin-react'
|
||||
import { resolve } from 'path'
|
||||
|
||||
export default defineConfig({
|
||||
plugins: [react()],
|
||||
resolve: {
|
||||
alias: {
|
||||
'@': resolve(__dirname, './src'),
|
||||
'@test': resolve(__dirname, './test'),
|
||||
},
|
||||
},
|
||||
test: {
|
||||
globals: true,
|
||||
environment: 'jsdom',
|
||||
setupFiles: './test/setup.ts',
|
||||
include: ['test/**/*.{test,spec}.{js,mjs,cjs,ts,mts,cts,jsx,tsx}'],
|
||||
exclude: ['node_modules', 'dist', '.git', '.cache'],
|
||||
reporters: ['default', 'json'],
|
||||
outputFile: {
|
||||
json: './coverage/test-results.json'
|
||||
},
|
||||
coverage: {
|
||||
provider: 'v8',
|
||||
reporter: [
|
||||
'text-summary',
|
||||
'html',
|
||||
'json',
|
||||
'json-summary',
|
||||
'lcov'
|
||||
],
|
||||
reportsDirectory: './coverage',
|
||||
thresholds: {
|
||||
global: {
|
||||
statements: 70,
|
||||
branches: 65,
|
||||
functions: 70,
|
||||
lines: 70,
|
||||
},
|
||||
'src/services/**/*.ts': {
|
||||
statements: 80,
|
||||
branches: 75,
|
||||
functions: 80,
|
||||
lines: 80,
|
||||
}
|
||||
},
|
||||
exclude: [
|
||||
'src/**/*.d.ts',
|
||||
'src/env.d.ts',
|
||||
'src/types/**',
|
||||
'test/**/*',
|
||||
'node_modules/**',
|
||||
],
|
||||
},
|
||||
// Improve test performance
|
||||
pool: 'forks',
|
||||
poolOptions: {
|
||||
forks: {
|
||||
singleFork: true,
|
||||
},
|
||||
},
|
||||
},
|
||||
})
|
||||
```
|
||||
|
||||
### Enhanced Test Setup (test/setup.ts)
|
||||
|
||||
```typescript
|
||||
import '@testing-library/jest-dom'
|
||||
import { cleanup } from '@testing-library/react'
|
||||
import { afterEach, beforeAll, afterAll, vi } from 'vitest'
|
||||
import React from 'react'
|
||||
|
||||
// Clean up after each test
|
||||
afterEach(() => {
|
||||
cleanup()
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
// Comprehensive Lucide React icon mocks (170+ icons)
|
||||
vi.mock('lucide-react', () => ({
|
||||
// Core UI icons
|
||||
Settings: ({ className, ...props }: any) =>
|
||||
React.createElement('span', {
|
||||
className,
|
||||
'data-testid': 'settings-icon',
|
||||
'data-lucide': 'Settings',
|
||||
...props
|
||||
}, 'Settings'),
|
||||
|
||||
User: ({ className, ...props }: any) =>
|
||||
React.createElement('span', {
|
||||
className,
|
||||
'data-testid': 'user-icon',
|
||||
'data-lucide': 'User',
|
||||
...props
|
||||
}, 'User'),
|
||||
|
||||
Bot: ({ className, ...props }: any) =>
|
||||
React.createElement('span', {
|
||||
className,
|
||||
'data-testid': 'bot-icon',
|
||||
'data-lucide': 'Bot',
|
||||
...props
|
||||
}, 'Bot'),
|
||||
|
||||
// Action icons
|
||||
Play: ({ className, ...props }: any) =>
|
||||
React.createElement('span', {
|
||||
className,
|
||||
'data-testid': 'play-icon',
|
||||
'data-lucide': 'Play',
|
||||
...props
|
||||
}, 'Play'),
|
||||
|
||||
Pause: ({ className, ...props }: any) =>
|
||||
React.createElement('span', {
|
||||
className,
|
||||
'data-testid': 'pause-icon',
|
||||
'data-lucide': 'Pause',
|
||||
...props
|
||||
}, 'Pause'),
|
||||
|
||||
// Navigation icons
|
||||
ChevronRight: ({ className, ...props }: any) =>
|
||||
React.createElement('span', {
|
||||
className,
|
||||
'data-testid': 'chevron-right-icon',
|
||||
'data-lucide': 'ChevronRight',
|
||||
...props
|
||||
}, 'ChevronRight'),
|
||||
|
||||
// ... and 164+ more icon mocks for complete coverage
|
||||
}))
|
||||
|
||||
// Enhanced Socket.IO mocking with lifecycle simulation
|
||||
export class MockSocketIO {
|
||||
static CONNECTING = 0
|
||||
static OPEN = 1
|
||||
static CLOSING = 2
|
||||
static CLOSED = 3
|
||||
|
||||
url: string
|
||||
readyState: number = MockSocketIO.CONNECTING
|
||||
onopen: ((event: Event) => void) | null = null
|
||||
onclose: ((event: CloseEvent) => void) | null = null
|
||||
onmessage: ((event: MessageEvent) => void) | null = null
|
||||
onerror: ((event: Event) => void) | null = null
|
||||
|
||||
constructor(url: string) {
|
||||
this.url = url
|
||||
// Simulate connection opening asynchronously
|
||||
setTimeout(() => {
|
||||
this.readyState = MockSocketIO.OPEN
|
||||
if (this.onopen) {
|
||||
this.onopen(new Event('open'))
|
||||
}
|
||||
}, 0)
|
||||
}
|
||||
|
||||
send = vi.fn()
|
||||
close = vi.fn(() => {
|
||||
this.readyState = MockSocketIO.CLOSED
|
||||
if (this.onclose) {
|
||||
this.onclose(new CloseEvent('close'))
|
||||
}
|
||||
})
|
||||
|
||||
addEventListener = vi.fn()
|
||||
removeEventListener = vi.fn()
|
||||
dispatchEvent = vi.fn()
|
||||
}
|
||||
|
||||
// Replace global Socket.IO with mock
|
||||
global.io = () => new MockSocketIO('') as any
|
||||
|
||||
// Enhanced Socket.IO service mock
|
||||
vi.mock('@/services/websocketService', () => ({
|
||||
websocketService: {
|
||||
connect: vi.fn().mockResolvedValue(undefined),
|
||||
disconnect: vi.fn(),
|
||||
subscribe: vi.fn().mockReturnValue(vi.fn()),
|
||||
send: vi.fn(),
|
||||
getConnectionState: vi.fn().mockReturnValue('connected'),
|
||||
waitForConnection: vi.fn().mockResolvedValue(undefined),
|
||||
isConnected: vi.fn().mockReturnValue(true),
|
||||
reconnect: vi.fn().mockResolvedValue(undefined)
|
||||
}
|
||||
}))
|
||||
|
||||
// Mock window.matchMedia
|
||||
Object.defineProperty(window, 'matchMedia', {
|
||||
writable: true,
|
||||
value: vi.fn().mockImplementation(query => ({
|
||||
matches: false,
|
||||
media: query,
|
||||
onchange: null,
|
||||
addListener: vi.fn(),
|
||||
removeListener: vi.fn(),
|
||||
addEventListener: vi.fn(),
|
||||
removeEventListener: vi.fn(),
|
||||
dispatchEvent: vi.fn(),
|
||||
})),
|
||||
})
|
||||
|
||||
// Mock IntersectionObserver
|
||||
global.IntersectionObserver = vi.fn().mockImplementation(() => ({
|
||||
observe: vi.fn(),
|
||||
unobserve: vi.fn(),
|
||||
disconnect: vi.fn(),
|
||||
}))
|
||||
|
||||
// Mock ResizeObserver
|
||||
global.ResizeObserver = vi.fn().mockImplementation(() => ({
|
||||
observe: vi.fn(),
|
||||
unobserve: vi.fn(),
|
||||
disconnect: vi.fn(),
|
||||
}))
|
||||
|
||||
// Mock scrollIntoView
|
||||
Element.prototype.scrollIntoView = vi.fn()
|
||||
```
|
||||
|
||||
## 🧪 Testing Patterns
|
||||
|
||||
### 1. Component Testing
|
||||
|
||||
```typescript
|
||||
// test/components/settings/TestStatus.test.tsx
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { render, screen, waitFor } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { TestStatus } from '@/components/settings/TestStatus'
|
||||
import { testService } from '@/services/testService'
|
||||
|
||||
// Mock the test service
|
||||
vi.mock('@/services/testService')
|
||||
|
||||
describe('TestStatus', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should show Test Results button after successful test run', async () => {
|
||||
// Arrange
|
||||
const mockCoverageData = {
|
||||
total: { statements: { pct: 85 }, branches: { pct: 80 } }
|
||||
}
|
||||
const mockTestResults = {
|
||||
numTotalTests: 10,
|
||||
numPassedTests: 8,
|
||||
numFailedTests: 2
|
||||
}
|
||||
|
||||
vi.mocked(testService.hasTestResults).mockReturnValue(true)
|
||||
vi.mocked(testService.getCoverageData).mockResolvedValue(mockCoverageData)
|
||||
vi.mocked(testService.getTestResults).mockResolvedValue(mockTestResults)
|
||||
|
||||
// Act
|
||||
render(<TestStatus />)
|
||||
|
||||
// Assert
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Test Results')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
it('should hide Test Results button when no test results exist', () => {
|
||||
// Arrange
|
||||
vi.mocked(testService.hasTestResults).mockReturnValue(false)
|
||||
|
||||
// Act
|
||||
render(<TestStatus />)
|
||||
|
||||
// Assert
|
||||
expect(screen.queryByText('Test Results')).not.toBeInTheDocument()
|
||||
})
|
||||
|
||||
it('should open Test Results Modal when button is clicked', async () => {
|
||||
// Arrange
|
||||
const user = userEvent.setup()
|
||||
vi.mocked(testService.hasTestResults).mockReturnValue(true)
|
||||
|
||||
render(<TestStatus />)
|
||||
|
||||
// Act
|
||||
const button = screen.getByText('Test Results')
|
||||
await user.click(button)
|
||||
|
||||
// Assert
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Test Health Score')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 2. Service Testing with Socket.IO Safety
|
||||
|
||||
```typescript
|
||||
// test/services/websocketService.test.ts
|
||||
import { describe, it, expect, vi, beforeEach, afterEach } from 'vitest'
|
||||
import { websocketService } from '@/services/websocketService'
|
||||
|
||||
// CRITICAL: Always mock Socket.IO service
|
||||
vi.mock('@/services/websocketService', () => ({
|
||||
websocketService: {
|
||||
connect: vi.fn(),
|
||||
disconnect: vi.fn(),
|
||||
subscribe: vi.fn(),
|
||||
send: vi.fn(),
|
||||
getConnectionState: vi.fn()
|
||||
}
|
||||
}))
|
||||
|
||||
describe('Socket.IO Service (Mocked)', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
afterEach(() => {
|
||||
// Critical: Clean up any subscriptions
|
||||
vi.restoreAllMocks()
|
||||
})
|
||||
|
||||
it('should handle connection lifecycle', async () => {
|
||||
// Arrange
|
||||
const mockCallback = vi.fn()
|
||||
vi.mocked(websocketService.connect).mockResolvedValue(undefined)
|
||||
vi.mocked(websocketService.subscribe).mockReturnValue(vi.fn())
|
||||
|
||||
// Act
|
||||
await websocketService.connect('/test-endpoint')
|
||||
const unsubscribe = websocketService.subscribe('test-channel', mockCallback)
|
||||
|
||||
// Assert
|
||||
expect(websocketService.connect).toHaveBeenCalledWith('/test-endpoint')
|
||||
expect(websocketService.subscribe).toHaveBeenCalledWith('test-channel', mockCallback)
|
||||
expect(typeof unsubscribe).toBe('function')
|
||||
})
|
||||
|
||||
it('should handle message subscription', () => {
|
||||
// Arrange
|
||||
const mockHandler = vi.fn()
|
||||
const mockUnsubscribe = vi.fn()
|
||||
vi.mocked(websocketService.subscribe).mockReturnValue(mockUnsubscribe)
|
||||
|
||||
// Act
|
||||
const unsubscribe = websocketService.subscribe('progress', mockHandler)
|
||||
|
||||
// Assert
|
||||
expect(websocketService.subscribe).toHaveBeenCalledWith('progress', mockHandler)
|
||||
expect(unsubscribe).toBe(mockUnsubscribe)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 3. Hook Testing
|
||||
|
||||
```typescript
|
||||
// test/hooks/useNeonGlow.test.ts
|
||||
import { renderHook, act } from '@testing-library/react'
|
||||
import { describe, it, expect, vi, beforeEach } from 'vitest'
|
||||
import { useNeonGlow } from '@/hooks/useNeonGlow'
|
||||
|
||||
describe('useNeonGlow', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should initialize with default glow state', () => {
|
||||
// Act
|
||||
const { result } = renderHook(() => useNeonGlow())
|
||||
|
||||
// Assert
|
||||
expect(result.current.isGlowing).toBe(false)
|
||||
expect(typeof result.current.startGlow).toBe('function')
|
||||
expect(typeof result.current.stopGlow).toBe('function')
|
||||
})
|
||||
|
||||
it('should handle glow activation', () => {
|
||||
// Arrange
|
||||
const { result } = renderHook(() => useNeonGlow())
|
||||
|
||||
// Act
|
||||
act(() => {
|
||||
result.current.startGlow()
|
||||
})
|
||||
|
||||
// Assert
|
||||
expect(result.current.isGlowing).toBe(true)
|
||||
})
|
||||
|
||||
it('should handle glow deactivation', () => {
|
||||
// Arrange
|
||||
const { result } = renderHook(() => useNeonGlow())
|
||||
|
||||
// Act
|
||||
act(() => {
|
||||
result.current.startGlow()
|
||||
})
|
||||
act(() => {
|
||||
result.current.stopGlow()
|
||||
})
|
||||
|
||||
// Assert
|
||||
expect(result.current.isGlowing).toBe(false)
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
### 4. Integration Testing
|
||||
|
||||
```typescript
|
||||
// test/integration/test-results-flow.test.tsx
|
||||
import { describe, it, expect, beforeEach } from 'vitest'
|
||||
import { render, screen, waitFor } from '@testing-library/react'
|
||||
import userEvent from '@testing-library/user-event'
|
||||
import { SettingsPage } from '@/pages/SettingsPage'
|
||||
import { testService } from '@/services/testService'
|
||||
|
||||
vi.mock('@/services/testService')
|
||||
|
||||
describe('Test Results Integration Flow', () => {
|
||||
beforeEach(() => {
|
||||
vi.clearAllMocks()
|
||||
})
|
||||
|
||||
it('should show complete test results workflow', async () => {
|
||||
// Arrange
|
||||
const user = userEvent.setup()
|
||||
const mockCoverageData = {
|
||||
total: {
|
||||
statements: { pct: 85 },
|
||||
branches: { pct: 80 },
|
||||
functions: { pct: 90 },
|
||||
lines: { pct: 85 }
|
||||
}
|
||||
}
|
||||
const mockTestResults = {
|
||||
numTotalTests: 20,
|
||||
numPassedTests: 18,
|
||||
numFailedTests: 2,
|
||||
testResults: [
|
||||
{
|
||||
name: 'Component Tests',
|
||||
status: 'passed',
|
||||
numPassedTests: 15,
|
||||
numFailedTests: 0
|
||||
},
|
||||
{
|
||||
name: 'Service Tests',
|
||||
status: 'failed',
|
||||
numPassedTests: 3,
|
||||
numFailedTests: 2
|
||||
}
|
||||
]
|
||||
}
|
||||
|
||||
vi.mocked(testService.hasTestResults).mockReturnValue(true)
|
||||
vi.mocked(testService.getCoverageData).mockResolvedValue(mockCoverageData)
|
||||
vi.mocked(testService.getTestResults).mockResolvedValue(mockTestResults)
|
||||
|
||||
// Act
|
||||
render(<SettingsPage />)
|
||||
|
||||
// Navigate to test results
|
||||
const testResultsButton = await screen.findByText('Test Results')
|
||||
await user.click(testResultsButton)
|
||||
|
||||
// Assert modal appears with comprehensive data
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Test Health Score')).toBeInTheDocument()
|
||||
expect(screen.getByText('90%')).toBeInTheDocument() // Health score
|
||||
expect(screen.getByText('18 Passed')).toBeInTheDocument()
|
||||
expect(screen.getByText('2 Failed')).toBeInTheDocument()
|
||||
expect(screen.getByText('Statements: 85%')).toBeInTheDocument()
|
||||
expect(screen.getByText('Component Tests')).toBeInTheDocument()
|
||||
expect(screen.getByText('Service Tests')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## 🎯 UI Test Runner Integration
|
||||
|
||||
Archon includes a sophisticated UI test runner accessible from the Settings page:
|
||||
|
||||
### Test Results Modal Features
|
||||
|
||||
```typescript
|
||||
// Example of testing the Test Results Modal
|
||||
describe('TestResultsModal', () => {
|
||||
it('should display comprehensive test health information', async () => {
|
||||
const mockData = {
|
||||
testHealthScore: 90,
|
||||
testSummary: {
|
||||
totalTests: 20,
|
||||
passedTests: 18,
|
||||
failedTests: 2,
|
||||
duration: 15.5
|
||||
},
|
||||
coverage: {
|
||||
statements: 85,
|
||||
branches: 80,
|
||||
functions: 90,
|
||||
lines: 85
|
||||
},
|
||||
testSuites: [
|
||||
{ name: 'Components', status: 'passed', passed: 15, failed: 0 },
|
||||
{ name: 'Services', status: 'failed', passed: 3, failed: 2 }
|
||||
]
|
||||
}
|
||||
|
||||
render(<TestResultsModal isOpen={true} data={mockData} onClose={vi.fn()} />)
|
||||
|
||||
expect(screen.getByText('Test Health Score: 90%')).toBeInTheDocument()
|
||||
expect(screen.getByText('18 Passed, 2 Failed')).toBeInTheDocument()
|
||||
expect(screen.getByText('Duration: 15.5s')).toBeInTheDocument()
|
||||
|
||||
// Coverage progress bars
|
||||
expect(screen.getByText('Statements: 85%')).toBeInTheDocument()
|
||||
expect(screen.getByText('Branches: 80%')).toBeInTheDocument()
|
||||
|
||||
// Individual test suites
|
||||
expect(screen.getByText('Components')).toBeInTheDocument()
|
||||
expect(screen.getByText('Services')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
```
|
||||
|
||||
## 🚀 Quick Start
|
||||
|
||||
### Running Tests
|
||||
|
||||
```bash
|
||||
# Navigate to frontend directory
|
||||
cd archon-ui-main
|
||||
|
||||
# Run all tests
|
||||
npm test
|
||||
|
||||
# Run tests with coverage and results generation
|
||||
npm run test:coverage
|
||||
|
||||
# Run tests in watch mode
|
||||
npm test -- --watch
|
||||
|
||||
# Run tests with UI interface
|
||||
npm run test:ui
|
||||
|
||||
# Run specific test file
|
||||
npm test -- TestStatus.test.tsx
|
||||
|
||||
# Run tests matching pattern
|
||||
npm test -- --grep "should handle"
|
||||
|
||||
# Run tests for specific directory
|
||||
npm test -- test/components/settings/
|
||||
```
|
||||
|
||||
### Test Development Workflow
|
||||
|
||||
```bash
|
||||
# 1. Create test file alongside component
|
||||
touch test/components/ui/NewComponent.test.tsx
|
||||
|
||||
# 2. Run test in watch mode during development
|
||||
npm test -- --watch NewComponent.test.tsx
|
||||
|
||||
# 3. Check coverage for the specific component
|
||||
npm run test:coverage -- --reporter=text NewComponent.test.tsx
|
||||
|
||||
# 4. Run all tests before committing
|
||||
npm run test:coverage
|
||||
```
|
||||
|
||||
## 📊 Coverage Analysis
|
||||
|
||||
### Current Coverage Goals
|
||||
|
||||
```typescript
|
||||
// vitest.config.ts coverage thresholds
|
||||
coverage: {
|
||||
thresholds: {
|
||||
global: {
|
||||
statements: 70,
|
||||
branches: 65,
|
||||
functions: 70,
|
||||
lines: 70,
|
||||
},
|
||||
'src/services/**/*.ts': {
|
||||
statements: 80,
|
||||
branches: 75,
|
||||
functions: 80,
|
||||
lines: 80,
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Coverage Reports Generated
|
||||
|
||||
1. **HTML Report**: `coverage/index.html` - Interactive coverage browser
|
||||
2. **JSON Summary**: `coverage/coverage-summary.json` - For UI integration
|
||||
3. **LCOV**: `coverage/lcov.info` - For CI/CD integration
|
||||
4. **Text Summary**: Console output during test runs
|
||||
|
||||
### Using Coverage Data in UI
|
||||
|
||||
```typescript
|
||||
// Example of how Test Results Modal consumes coverage data
|
||||
const TestResultsModal = () => {
|
||||
const [coverageData, setCoverageData] = useState(null)
|
||||
|
||||
useEffect(() => {
|
||||
const loadCoverageData = async () => {
|
||||
try {
|
||||
const data = await testService.getCoverageData()
|
||||
setCoverageData(data)
|
||||
} catch (error) {
|
||||
console.error('Failed to load coverage data:', error)
|
||||
}
|
||||
}
|
||||
|
||||
loadCoverageData()
|
||||
}, [])
|
||||
|
||||
const calculateHealthScore = (testResults, coverage) => {
|
||||
const testSuccessRate = (testResults.numPassedTests / testResults.numTotalTests) * 100
|
||||
const avgCoverage = (coverage.statements + coverage.branches + coverage.functions + coverage.lines) / 4
|
||||
return Math.round((testSuccessRate + avgCoverage) / 2)
|
||||
}
|
||||
|
||||
// ... render logic
|
||||
}
|
||||
```
|
||||
|
||||
## 🛠️ Socket.IO Testing Best Practices
|
||||
|
||||
### ⚠️ Critical Safety Rules
|
||||
|
||||
1. **NEVER create real Socket.IO connections in tests**
|
||||
2. **ALWAYS mock the websocketService module**
|
||||
3. **NEVER include Socket.IO functions in useCallback dependencies**
|
||||
4. **ALWAYS clean up subscriptions in afterEach**
|
||||
|
||||
### Safe Socket.IO Testing Pattern
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT: Always mock the service
|
||||
vi.mock('@/services/websocketService', () => ({
|
||||
websocketService: {
|
||||
connect: vi.fn().mockResolvedValue(undefined),
|
||||
disconnect: vi.fn(),
|
||||
subscribe: vi.fn().mockReturnValue(vi.fn()),
|
||||
send: vi.fn(),
|
||||
getConnectionState: vi.fn().mockReturnValue('connected')
|
||||
}
|
||||
}))
|
||||
|
||||
// ✅ CORRECT: Test Socket.IO interactions safely
|
||||
it('should handle Socket.IO message updates', async () => {
|
||||
const mockCallback = vi.fn()
|
||||
let capturedCallback: Function
|
||||
|
||||
vi.mocked(websocketService.subscribe).mockImplementation((channel, callback) => {
|
||||
capturedCallback = callback
|
||||
return vi.fn() // unsubscribe function
|
||||
})
|
||||
|
||||
render(<ComponentWithSocketIO />)
|
||||
|
||||
// Simulate Socket.IO message
|
||||
act(() => {
|
||||
capturedCallback!({ type: 'progress', data: { percent: 50 } })
|
||||
})
|
||||
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Progress: 50%')).toBeInTheDocument()
|
||||
})
|
||||
})
|
||||
|
||||
// ❌ WRONG: Never create real Socket.IO connections
|
||||
it('should connect to real Socket.IO', () => {
|
||||
const socket = io('http://localhost:8080') // DON'T DO THIS
|
||||
// This will break tests and potentially affect running services
|
||||
})
|
||||
```
|
||||
|
||||
## 🎯 Test Implementation Status
|
||||
|
||||
### Completed Tests ✅
|
||||
|
||||
- `test/App.test.tsx` - Basic app rendering
|
||||
- `test/services/api.test.ts` - API service functionality
|
||||
- `test/services/mcpService.test.ts` - MCP service operations
|
||||
- `test/services/knowledgeBaseService.test.ts` - Knowledge base operations
|
||||
- `test/pages/MCPPage.test.tsx` - MCP page rendering
|
||||
- `test/pages/KnowledgeBasePage.test.tsx` - Knowledge base page
|
||||
- `test/pages/CrawlingProgress.test.tsx` - Crawling progress page
|
||||
|
||||
### High Priority (Next Phase) 📝
|
||||
|
||||
1. **Services Layer** (Critical)
|
||||
- `socketioService.test.ts` - Socket.IO connection management
|
||||
- `projectService.test.ts` - Project CRUD operations
|
||||
- `testService.test.ts` - Test execution and results
|
||||
- `credentialsService.test.ts` - Credentials management
|
||||
|
||||
2. **Settings Components** (High)
|
||||
- `TestStatus.test.tsx` - Test Results Modal integration
|
||||
- `APIKeysSection.test.tsx` - API key management
|
||||
- `FeaturesSection.test.tsx` - Feature toggles
|
||||
- `RAGSettings.test.tsx` - RAG configuration
|
||||
|
||||
3. **Project Components** (High)
|
||||
- `TasksTab.test.tsx` - Task management interface
|
||||
- `TaskTableView.test.tsx` - Task table functionality
|
||||
- `TaskBoardView.test.tsx` - Kanban board interface
|
||||
|
||||
### Coverage Progress
|
||||
|
||||
- **Total Files Planned**: 68 test files
|
||||
- **Currently Implemented**: 7 files (10%)
|
||||
- **Target Coverage**: 80% overall, 90% for critical paths
|
||||
- **Current Coverage**: ~15% overall
|
||||
|
||||
## 🔄 CI/CD Integration
|
||||
|
||||
### GitHub Actions Workflow
|
||||
|
||||
```yaml
|
||||
name: Frontend Tests
|
||||
|
||||
on:
|
||||
push:
|
||||
branches: [main, develop]
|
||||
pull_request:
|
||||
branches: [main]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
|
||||
steps:
|
||||
- uses: actions/checkout@v4
|
||||
|
||||
- name: Setup Node.js
|
||||
uses: actions/setup-node@v4
|
||||
with:
|
||||
node-version: '20'
|
||||
cache: 'npm'
|
||||
cache-dependency-path: archon-ui-main/package-lock.json
|
||||
|
||||
- name: Install dependencies
|
||||
working-directory: ./archon-ui-main
|
||||
run: npm ci
|
||||
|
||||
- name: Type check
|
||||
working-directory: ./archon-ui-main
|
||||
run: npm run type-check
|
||||
|
||||
- name: Run tests with coverage
|
||||
working-directory: ./archon-ui-main
|
||||
run: npm run test:coverage
|
||||
|
||||
- name: Upload coverage reports
|
||||
uses: codecov/codecov-action@v3
|
||||
with:
|
||||
file: ./archon-ui-main/coverage/coverage-final.json
|
||||
flags: frontend
|
||||
fail_ci_if_error: true
|
||||
```
|
||||
|
||||
## 📚 Best Practices Checklist
|
||||
|
||||
### Before Writing Tests
|
||||
- [ ] Component/service is implemented and working
|
||||
- [ ] Identify critical user paths to test
|
||||
- [ ] Plan test scenarios (happy path, error cases, edge cases)
|
||||
- [ ] Ensure Socket.IO mocking is in place if needed
|
||||
|
||||
### Writing Tests
|
||||
- [ ] Use descriptive test names (`should do X when Y happens`)
|
||||
- [ ] Follow AAA pattern (Arrange, Act, Assert)
|
||||
- [ ] Test user behavior, not implementation details
|
||||
- [ ] Mock external dependencies appropriately
|
||||
- [ ] Use proper TypeScript types in tests
|
||||
|
||||
### After Writing Tests
|
||||
- [ ] Tests pass consistently
|
||||
- [ ] Coverage meets threshold requirements
|
||||
- [ ] No console errors or warnings
|
||||
- [ ] Tests run quickly (under 100ms per test ideally)
|
||||
- [ ] Clean up resources in afterEach hooks
|
||||
|
||||
### Socket.IO-Specific Checklist
|
||||
- [ ] Socket.IO service is mocked, never real connections
|
||||
- [ ] Subscription cleanup is handled
|
||||
- [ ] No function references in useCallback dependencies
|
||||
- [ ] Connection state changes are tested
|
||||
- [ ] Error scenarios are covered
|
||||
|
||||
## 🛠️ Troubleshooting Common Issues
|
||||
|
||||
### Test Environment Issues
|
||||
|
||||
```typescript
|
||||
// Issue: Icons not rendering in tests
|
||||
// Solution: Comprehensive Lucide React mocking in setup.ts
|
||||
|
||||
// Issue: Socket.IO connection errors in tests
|
||||
// Solution: Always mock websocketService module
|
||||
|
||||
// Issue: Async timing issues
|
||||
// Solution: Use waitFor and findBy queries
|
||||
await waitFor(() => {
|
||||
expect(screen.getByText('Expected text')).toBeInTheDocument()
|
||||
})
|
||||
|
||||
// Issue: State update warnings
|
||||
// Solution: Wrap state updates in act()
|
||||
act(() => {
|
||||
// state updates
|
||||
})
|
||||
```
|
||||
|
||||
### Coverage Issues
|
||||
|
||||
```bash
|
||||
# Issue: Low coverage on specific files
|
||||
# Solution: Check what's not covered
|
||||
npm run test:coverage -- --reporter=text-summary
|
||||
|
||||
# Issue: Coverage threshold failures
|
||||
# Solution: Either improve tests or adjust thresholds in vitest.config.ts
|
||||
```
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- **[Testing Overview](./testing)** - General testing strategy and architecture
|
||||
- **[Python Testing Strategy](./testing-python-strategy)** - Backend testing guide
|
||||
- **[Socket.IO Documentation](./socketio)** - Real-time communication patterns
|
||||
- **[UI Documentation](./ui)** - Component design and usage guidelines
|
||||
|
||||
---
|
||||
|
||||
**Quick Navigation:**
|
||||
- 🚀 [Quick Start](#quick-start) - Get started with testing immediately
|
||||
- 🎯 [UI Test Runner Integration](#ui-test-runner-integration) - Use the Settings page test runner
|
||||
- 🛠️ [Socket.IO Testing](#socketio-testing-best-practices) - Safe Socket.IO testing patterns
|
||||
- 📊 [Coverage Analysis](#coverage-analysis) - Understanding and improving coverage
|
||||
204
docs/docs/testing.mdx
Normal file
@@ -0,0 +1,204 @@
|
||||
---
|
||||
title: Testing
|
||||
sidebar_position: 7
|
||||
---
|
||||
|
||||
# Testing
|
||||
|
||||
Archon uses a comprehensive testing strategy across all services.
|
||||
|
||||
## Testing Stack
|
||||
|
||||
| Service | Framework | Test Types | Coverage Target |
|
||||
|---------|-----------|------------|-----------------|
|
||||
| **Frontend** | Vitest + React Testing Library | Unit, Component, Integration | 80% |
|
||||
| **Server** | Pytest + FastAPI TestClient | Unit, Integration, E2E | 85% |
|
||||
| **MCP** | Pytest | Unit, Protocol | 80% |
|
||||
| **Agents** | Pytest + PydanticAI | Unit, Agent behavior | 75% |
|
||||
|
||||
## Running Tests
|
||||
|
||||
### All Services
|
||||
```bash
|
||||
# Run all tests
|
||||
./scripts/test-all.sh
|
||||
|
||||
# With coverage
|
||||
./scripts/test-all.sh --coverage
|
||||
```
|
||||
|
||||
### Frontend Tests
|
||||
```bash
|
||||
cd ui
|
||||
npm test # Run tests
|
||||
npm run test:coverage # With coverage
|
||||
npm run test:watch # Watch mode
|
||||
```
|
||||
|
||||
### Python Tests
|
||||
```bash
|
||||
cd python
|
||||
pytest # All tests
|
||||
pytest tests/test_server.py # Specific file
|
||||
pytest -k "test_delete_source" # Specific test
|
||||
pytest --cov=src # With coverage
|
||||
```
|
||||
|
||||
## Test Organization
|
||||
|
||||
### Frontend Structure
|
||||
```
|
||||
ui/
|
||||
├── src/
|
||||
│ ├── components/
|
||||
│ │ ├── Button.tsx
|
||||
│ │ └── Button.test.tsx
|
||||
│ └── hooks/
|
||||
│ ├── useAuth.ts
|
||||
│ └── useAuth.test.ts
|
||||
└── tests/
|
||||
├── setup.ts
|
||||
└── e2e/
|
||||
```
|
||||
|
||||
### Python Structure
|
||||
```
|
||||
python/
|
||||
├── src/
|
||||
│ └── server/
|
||||
│ └── services/
|
||||
└── tests/
|
||||
├── conftest.py
|
||||
├── test_server.py
|
||||
├── test_services.py
|
||||
└── fixtures/
|
||||
```
|
||||
|
||||
## Key Testing Patterns
|
||||
|
||||
### FastAPI Testing
|
||||
```python
|
||||
from fastapi.testclient import TestClient
|
||||
from src.server.main import app
|
||||
|
||||
client = TestClient(app)
|
||||
|
||||
def test_delete_source():
|
||||
response = client.delete("/api/sources/test-source")
|
||||
assert response.status_code == 200
|
||||
assert response.json()["success"] is True
|
||||
```
|
||||
|
||||
### Service Testing
|
||||
```python
|
||||
import pytest
|
||||
from src.server.services.source_management_service import SourceManagementService
|
||||
|
||||
@pytest.fixture
|
||||
def source_service(mock_supabase):
|
||||
return SourceManagementService(mock_supabase)
|
||||
|
||||
def test_delete_source_success(source_service):
|
||||
success, result = source_service.delete_source("test-id")
|
||||
assert success is True
|
||||
assert result["source_id"] == "test-id"
|
||||
```
|
||||
|
||||
### React Component Testing
|
||||
```typescript
|
||||
import { render, screen, fireEvent } from '@testing-library/react';
|
||||
import { DeleteButton } from './DeleteButton';
|
||||
|
||||
test('calls onDelete when clicked', () => {
|
||||
const handleDelete = jest.fn();
|
||||
render(<DeleteButton onDelete={handleDelete} />);
|
||||
|
||||
fireEvent.click(screen.getByRole('button'));
|
||||
expect(handleDelete).toHaveBeenCalledTimes(1);
|
||||
});
|
||||
```
|
||||
|
||||
## Mocking Strategies
|
||||
|
||||
### Mock Supabase
|
||||
```python
|
||||
@pytest.fixture
|
||||
def mock_supabase():
|
||||
client = Mock()
|
||||
client.table.return_value.delete.return_value.eq.return_value.execute.return_value = Mock(data=[])
|
||||
return client
|
||||
```
|
||||
|
||||
### Mock HTTP Calls
|
||||
```python
|
||||
@pytest.fixture
|
||||
def mock_httpx():
|
||||
with patch('httpx.AsyncClient') as mock:
|
||||
yield mock
|
||||
```
|
||||
|
||||
### Mock Socket.IO
|
||||
```python
|
||||
@pytest.fixture
|
||||
async def websocket_client():
|
||||
async with TestClient(app).websocket_connect("/ws") as ws:
|
||||
yield ws
|
||||
```
|
||||
|
||||
## CI/CD Integration
|
||||
|
||||
### GitHub Actions
|
||||
```yaml
|
||||
name: Tests
|
||||
on: [push, pull_request]
|
||||
|
||||
jobs:
|
||||
test:
|
||||
runs-on: ubuntu-latest
|
||||
steps:
|
||||
- uses: actions/checkout@v3
|
||||
- name: Run Tests
|
||||
run: ./scripts/test-all.sh --coverage
|
||||
- name: Upload Coverage
|
||||
uses: codecov/codecov-action@v3
|
||||
```
|
||||
|
||||
## Best Practices
|
||||
|
||||
1. **Test Isolation** - Each test should be independent
|
||||
2. **Mock External Services** - Don't call real APIs in tests
|
||||
3. **Use Fixtures** - Share common test setup
|
||||
4. **Test Business Logic** - Focus on services, not just endpoints
|
||||
5. **Fast Tests** - Keep unit tests under 100ms
|
||||
6. **Descriptive Names** - `test_delete_source_removes_all_related_data`
|
||||
|
||||
## Performance Testing
|
||||
|
||||
```python
|
||||
import pytest
|
||||
import time
|
||||
|
||||
@pytest.mark.performance
|
||||
def test_bulk_delete_performance(source_service):
|
||||
start = time.time()
|
||||
for i in range(100):
|
||||
source_service.delete_source(f"source-{i}")
|
||||
duration = time.time() - start
|
||||
assert duration < 5.0 # Should complete in under 5 seconds
|
||||
```
|
||||
|
||||
## Debugging Tests
|
||||
|
||||
```bash
|
||||
# Verbose output
|
||||
pytest -vv
|
||||
|
||||
# Show print statements
|
||||
pytest -s
|
||||
|
||||
# Drop into debugger on failure
|
||||
pytest --pdb
|
||||
|
||||
# Run specific test with debugging
|
||||
pytest -vvs -k "test_delete" --pdb
|
||||
```
|
||||
404
docs/docs/ui-components.mdx
Normal file
@@ -0,0 +1,404 @@
|
||||
---
|
||||
title: UI Components Reference
|
||||
sidebar_position: 3
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
import Admonition from '@theme/Admonition';
|
||||
|
||||
# 🎨 UI Components Reference
|
||||
|
||||
<div className="hero hero--secondary">
|
||||
<div className="container">
|
||||
<h2 className="hero__subtitle">
|
||||
Complete reference for Archon's React component library built with Vite, Tailwind CSS, and modern UI patterns.
|
||||
</h2>
|
||||
</div>
|
||||
</div>
|
||||
|
||||
## 📁 Component Structure
|
||||
|
||||
```
|
||||
src/components/
|
||||
├── animations/ # Animation components
|
||||
├── knowledge-base/ # Knowledge management UI
|
||||
├── layouts/ # Layout components
|
||||
├── mcp/ # MCP client components
|
||||
├── project-tasks/ # Project management UI
|
||||
├── settings/ # Settings components
|
||||
└── shared/ # Shared/common components
|
||||
```
|
||||
|
||||
## 🎭 Animation Components
|
||||
|
||||
### Animations.tsx
|
||||
**Purpose**: Provides animated UI elements and transitions
|
||||
|
||||
**Key Components**:
|
||||
- `FadeIn`: Fade-in animation wrapper
|
||||
- `SlideIn`: Slide-in from direction
|
||||
- `LoadingSpinner`: Animated loading indicator
|
||||
- `ProgressBar`: Animated progress display
|
||||
|
||||
**Usage Example**:
|
||||
```jsx
|
||||
<FadeIn duration={500}>
|
||||
<YourContent />
|
||||
</FadeIn>
|
||||
```
|
||||
|
||||
## 📚 Knowledge Base Components
|
||||
|
||||
### KnowledgeTable.tsx
|
||||
**Purpose**: Display and manage knowledge base entries
|
||||
|
||||
**Features**:
|
||||
- Sortable columns
|
||||
- Search/filter functionality
|
||||
- Source management actions
|
||||
- Real-time updates
|
||||
|
||||
**Props**:
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `sources` | `Source[]` | Array of knowledge sources |
|
||||
| `onDelete` | `(id: string) => void` | Delete handler |
|
||||
| `onRefresh` | `(id: string) => void` | Refresh handler |
|
||||
| `loading` | `boolean` | Loading state |
|
||||
|
||||
### CrawlProgress.tsx
|
||||
**Purpose**: Real-time crawling progress display
|
||||
|
||||
**Features**:
|
||||
- Socket.IO connection for live updates
|
||||
- Progress bar with percentage
|
||||
- Current URL display
|
||||
- Log message stream
|
||||
|
||||
**Performance Notes**:
|
||||
- Uses Socket.IO room subscription for targeted updates
|
||||
- Minimal re-renders - only updates on progress changes
|
||||
- Example of proper real-time pattern
|
||||
|
||||
## 🏗️ Layout Components
|
||||
|
||||
### MainLayout.tsx
|
||||
**Purpose**: Primary application layout wrapper
|
||||
|
||||
**Structure**:
|
||||
```jsx
|
||||
<MainLayout>
|
||||
<SideNavigation />
|
||||
<main>
|
||||
{children}
|
||||
</main>
|
||||
<ArchonChatPanel />
|
||||
</MainLayout>
|
||||
```
|
||||
|
||||
### SideNavigation.tsx
|
||||
**Purpose**: Left sidebar navigation menu
|
||||
|
||||
**Features**:
|
||||
- Collapsible menu
|
||||
- Active route highlighting
|
||||
- Icon-based navigation
|
||||
- Responsive design
|
||||
|
||||
**Menu Items**:
|
||||
- Knowledge Base
|
||||
- Projects
|
||||
- MCP Clients
|
||||
- Settings
|
||||
|
||||
### ArchonChatPanel.tsx
|
||||
**Purpose**: AI chat interface panel
|
||||
|
||||
**Features**:
|
||||
- Collapsible right panel
|
||||
- Message history
|
||||
- Real-time responses
|
||||
- Context awareness
|
||||
|
||||
**Performance Considerations**:
|
||||
- Uses Socket.IO for streaming AI responses
|
||||
- Consider virtualization for long chat histories
|
||||
- Implements proper cleanup in useEffect returns
|
||||
|
||||
## 🔌 MCP Components
|
||||
|
||||
### MCPClients.tsx
|
||||
**Purpose**: Manage MCP server connections
|
||||
|
||||
**Features**:
|
||||
- Add/remove MCP servers
|
||||
- Connection status display
|
||||
- Tool exploration
|
||||
- Test interface
|
||||
|
||||
### ClientCard.tsx
|
||||
**Purpose**: Individual MCP client display card
|
||||
|
||||
**Props**:
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `client` | `MCPClient` | Client configuration |
|
||||
| `onConnect` | `() => void` | Connect handler |
|
||||
| `onDisconnect` | `() => void` | Disconnect handler |
|
||||
| `onDelete` | `() => void` | Delete handler |
|
||||
|
||||
### ToolTestingPanel.tsx
|
||||
**Purpose**: Interactive MCP tool testing interface
|
||||
|
||||
**Features**:
|
||||
- Tool selection dropdown
|
||||
- Dynamic parameter inputs
|
||||
- Execute tool calls
|
||||
- Display results
|
||||
- Error handling
|
||||
|
||||
## 📊 Project & Task Components
|
||||
|
||||
### TaskBoardView.tsx
|
||||
**Purpose**: Kanban board for task management
|
||||
|
||||
**Features**:
|
||||
- Drag-and-drop between columns
|
||||
- Status-based organization
|
||||
- Task quick actions
|
||||
- Real-time updates
|
||||
|
||||
**Columns**:
|
||||
- Todo
|
||||
- Doing
|
||||
- Review
|
||||
- Done
|
||||
|
||||
**Performance Notes**:
|
||||
- Uses Socket.IO for real-time task updates from AI agents
|
||||
- Implements React DnD for smooth drag operations
|
||||
- Optimized with React.memo to prevent unnecessary re-renders
|
||||
|
||||
### TaskTableView.tsx
|
||||
**Purpose**: Table view for task management
|
||||
|
||||
**Features**:
|
||||
- Sortable columns
|
||||
- Inline editing
|
||||
- Bulk actions
|
||||
- Filter by status/assignee
|
||||
|
||||
### DraggableTaskCard.tsx
|
||||
**Purpose**: Individual task card component
|
||||
|
||||
**Props**:
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `task` | `Task` | Task data |
|
||||
| `onUpdate` | `(task: Task) => void` | Update handler |
|
||||
| `onDelete` | `(id: string) => void` | Delete handler |
|
||||
| `isDragging` | `boolean` | Drag state |
|
||||
|
||||
### BlockNoteEditor.tsx
|
||||
**Purpose**: Rich text editor for documents
|
||||
|
||||
**Features**:
|
||||
- WYSIWYG editing
|
||||
- Markdown support
|
||||
- Code blocks
|
||||
- Image embedding
|
||||
- Auto-save
|
||||
|
||||
### Project Tab Components
|
||||
|
||||
#### DocsTab.tsx
|
||||
**Purpose**: Project documentation management
|
||||
|
||||
**Features**:
|
||||
- Document list
|
||||
- Create/edit documents
|
||||
- Version history
|
||||
- Search functionality
|
||||
|
||||
#### FeaturesTab.tsx
|
||||
**Purpose**: Project features organization
|
||||
|
||||
**Features**:
|
||||
- Feature list display
|
||||
- Task grouping by feature
|
||||
- Progress tracking
|
||||
- Priority indicators
|
||||
|
||||
#### DataTab.tsx
|
||||
**Purpose**: Project data and analytics
|
||||
|
||||
**Features**:
|
||||
- Task statistics
|
||||
- Progress charts
|
||||
- Team performance
|
||||
- Timeline views
|
||||
|
||||
## ⚙️ Settings Components
|
||||
|
||||
### SettingsPanel.tsx
|
||||
**Purpose**: Application settings management
|
||||
|
||||
**Sections**:
|
||||
- API Keys
|
||||
- Model Configuration
|
||||
- UI Preferences
|
||||
- Data Management
|
||||
|
||||
**⚠️ Performance Warning**:
|
||||
- RAGSettings component has 11 onChange handlers without optimization
|
||||
- Needs debounced inputs or local state pattern
|
||||
- See performance best practices in UI documentation
|
||||
|
||||
### CredentialManager.tsx
|
||||
**Purpose**: Secure credential storage UI
|
||||
|
||||
**Features**:
|
||||
- Add/edit credentials
|
||||
- Encrypted storage
|
||||
- Category organization
|
||||
- Validation
|
||||
|
||||
## 🔄 Shared Components
|
||||
|
||||
### Button.tsx
|
||||
**Purpose**: Consistent button styling
|
||||
|
||||
**Variants**:
|
||||
- `primary`: Main actions
|
||||
- `secondary`: Secondary actions
|
||||
- `danger`: Destructive actions
|
||||
- `ghost`: Minimal styling
|
||||
|
||||
### Modal.tsx
|
||||
**Purpose**: Modal dialog wrapper
|
||||
|
||||
**Props**:
|
||||
| Prop | Type | Description |
|
||||
|------|------|-------------|
|
||||
| `isOpen` | `boolean` | Open state |
|
||||
| `onClose` | `() => void` | Close handler |
|
||||
| `title` | `string` | Modal title |
|
||||
| `size` | `'sm' \| 'md' \| 'lg'` | Modal size |
|
||||
|
||||
### SearchInput.tsx
|
||||
**Purpose**: Reusable search input
|
||||
|
||||
**Features**:
|
||||
- Debounced input
|
||||
- Clear button
|
||||
- Loading state
|
||||
- Keyboard shortcuts
|
||||
|
||||
## 🎨 Styling System
|
||||
|
||||
### Tailwind Configuration
|
||||
```javascript
|
||||
// tailwind.config.js
|
||||
module.exports = {
|
||||
theme: {
|
||||
extend: {
|
||||
colors: {
|
||||
primary: '#8b5cf6',
|
||||
secondary: '#1f2937',
|
||||
accent: '#a855f7'
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
```
|
||||
|
||||
### Component Styling Pattern
|
||||
```jsx
|
||||
// Consistent class naming
|
||||
const buttonClasses = clsx(
|
||||
'px-4 py-2 rounded-lg font-medium transition-colors',
|
||||
{
|
||||
'bg-primary text-white hover:bg-primary-dark': variant === 'primary',
|
||||
'bg-gray-200 text-gray-800 hover:bg-gray-300': variant === 'secondary'
|
||||
}
|
||||
);
|
||||
```
|
||||
|
||||
## 🔗 Component Integration
|
||||
|
||||
### With Socket.IO
|
||||
```jsx
|
||||
// Real-time updates in components
|
||||
useEffect(() => {
|
||||
socket.on('task:updated', (task) => {
|
||||
updateTaskInState(task);
|
||||
});
|
||||
|
||||
return () => socket.off('task:updated');
|
||||
}, []);
|
||||
```
|
||||
|
||||
### With API Services
|
||||
```jsx
|
||||
// Service integration pattern
|
||||
const KnowledgeTable = () => {
|
||||
const { data, loading, error } = useKnowledgeBase();
|
||||
|
||||
if (loading) return <LoadingSpinner />;
|
||||
if (error) return <ErrorDisplay error={error} />;
|
||||
|
||||
return <Table data={data} />;
|
||||
};
|
||||
```
|
||||
|
||||
### Performance Patterns
|
||||
|
||||
#### Optimized Input Components
|
||||
```jsx
|
||||
// Use DebouncedInput for forms/modals
|
||||
import { DebouncedInput } from './components/project-tasks/TaskInputComponents';
|
||||
|
||||
<DebouncedInput
|
||||
value={formData.title}
|
||||
onChange={handleTitleChange}
|
||||
placeholder="Enter title..."
|
||||
delay={300}
|
||||
/>
|
||||
```
|
||||
|
||||
#### Real-time Update Pattern
|
||||
```jsx
|
||||
// Efficient real-time updates
|
||||
const TaskComponent = memo(({ task }) => {
|
||||
// Component only re-renders when task changes
|
||||
return <TaskCard {...task} />;
|
||||
}, (prev, next) => prev.task.id === next.task.id);
|
||||
```
|
||||
|
||||
## 📱 Responsive Design
|
||||
|
||||
### Breakpoint Usage
|
||||
- `sm`: 640px - Mobile landscape
|
||||
- `md`: 768px - Tablets
|
||||
- `lg`: 1024px - Small desktops
|
||||
- `xl`: 1280px - Large desktops
|
||||
|
||||
### Mobile Adaptations
|
||||
- Collapsible navigation
|
||||
- Stack layouts on small screens
|
||||
- Touch-friendly interactions
|
||||
- Simplified table views
|
||||
|
||||
## 🔗 Related Documentation
|
||||
|
||||
- [UI Overview](./ui) - UI architecture, setup, and **performance best practices**
|
||||
- [Socket.IO Integration](./socketio) - Real-time features and room patterns
|
||||
- [Frontend Testing](./testing-vitest-strategy) - Component testing
|
||||
- [API Reference](./api-reference) - Backend integration
|
||||
- [Coding Best Practices](./coding-best-practices) - React patterns and anti-patterns
|
||||
|
||||
### Performance Resources
|
||||
- See **Performance Best Practices** section in [UI Documentation](./ui#performance-best-practices)
|
||||
- Example implementation: `TaskInputComponents.tsx` for debounced inputs
|
||||
- Components needing optimization listed in [UI docs](./ui#components-requiring-performance-optimization)
|
||||
829
docs/docs/ui.mdx
Normal file
@@ -0,0 +1,829 @@
|
||||
---
|
||||
title: UI
|
||||
sidebar_position: 10
|
||||
---
|
||||
|
||||
import Tabs from '@theme/Tabs';
|
||||
import TabItem from '@theme/TabItem';
|
||||
|
||||
# UI
|
||||
|
||||
Built with React and Vite.
|
||||
|
||||
## Directory Structure
|
||||
|
||||
```text
|
||||
src/
|
||||
├── components/
|
||||
│ ├── animations/
|
||||
│ │ └── Animations.tsx
|
||||
│ ├── knowledge-base/
|
||||
│ │ └── KnowledgeTable.tsx
|
||||
│ ├── layouts/
|
||||
│ │ ├── ArchonChatPanel.tsx
|
||||
│ │ ├── MainLayout.tsx
|
||||
│ │ └── SideNavigation.tsx
|
||||
│ ├── mcp/
|
||||
│ │ ├── ClientCard.tsx
|
||||
│ │ ├── MCPClients.tsx
|
||||
│ │ └── ToolTestingPanel.tsx
|
||||
│ ├── project-tasks/
|
||||
│ │ ├── BlockNoteEditor.tsx
|
||||
│ │ ├── DataTab.tsx
|
||||
│ │ ├── DocsTab.tsx
|
||||
│ │ ├── DraggableTaskCard.tsx
|
||||
│ │ ├── FeaturesTab.tsx
|
||||
│ │ ├── Tabs.tsx
|
||||
│ │ ├── TaskBoardView.tsx
|
||||
│ │ ├── TaskTableView.tsx
|
||||
│ │ └── VersionHistoryModal.tsx
|
||||
│ ├── settings/
|
||||
│ │ ├── APIKeysSection.tsx
|
||||
│ │ ├── FeaturesSection.tsx
|
||||
│ │ ├── IDEGlobalRules.tsx
|
||||
│ │ ├── RAGSettings.tsx
|
||||
│ │ └── TestStatus.tsx
|
||||
│ ├── ui/
|
||||
│ │ ├── Badge.tsx
|
||||
│ │ ├── Button.tsx
|
||||
│ │ ├── Card.tsx
|
||||
│ │ ├── Input.tsx
|
||||
│ │ ├── Select.tsx
|
||||
│ │ ├── ThemeToggle.tsx
|
||||
│ │ └── Toggle.tsx
|
||||
│ ├── CrawlingProgressCard.tsx
|
||||
│ └── ProjectCreationProgressCard.tsx
|
||||
├── contexts/
|
||||
│ ├── SettingsContext.tsx
|
||||
│ ├── ThemeContext.tsx
|
||||
│ └── ToastContext.tsx
|
||||
├── hooks/
|
||||
│ ├── useNeonGlow.ts
|
||||
│ └── useStaggeredEntrance.ts
|
||||
├── lib/
|
||||
│ ├── projectSchemas.ts
|
||||
│ ├── task-utils.tsx
|
||||
│ └── utils.ts
|
||||
├── pages/
|
||||
│ ├── KnowledgeBasePage.tsx
|
||||
│ ├── MCPPage.tsx
|
||||
│ ├── ProjectPage.tsx
|
||||
│ └── SettingsPage.tsx
|
||||
├── services/
|
||||
│ ├── agentChatService.ts
|
||||
│ ├── api.ts
|
||||
│ ├── crawlProgressService.ts
|
||||
│ ├── credentialsService.ts
|
||||
│ ├── knowledgeBaseService.ts
|
||||
│ ├── mcpClientService.ts
|
||||
│ ├── mcpServerService.ts
|
||||
│ ├── mcpService.ts
|
||||
│ ├── projectCreationProgressService.ts
|
||||
│ ├── projectService.ts
|
||||
│ ├── testService.ts
|
||||
│ └── webSocketService.ts
|
||||
└── types/
|
||||
├── knowledge.ts
|
||||
└── project.ts
|
||||
```
|
||||
|
||||
## Environment Variables
|
||||
|
||||
| Variable | Description |
|
||||
|---------------------------|-----------------------------------|
|
||||
| VITE_API_URL | Backend API base URL |
|
||||
| VITE_API_BASE_URL | Base URL used by some services |
|
||||
|
||||
## Running Locally
|
||||
|
||||
```bash
|
||||
cd archon-ui-main
|
||||
npm install
|
||||
npm run dev
|
||||
```
|
||||
|
||||
## Component Communication
|
||||
|
||||
```mermaid
|
||||
%%{init:{
|
||||
'theme':'base',
|
||||
'themeVariables': {
|
||||
'primaryColor':'#0a0a0a',
|
||||
'primaryTextColor':'#ffffff',
|
||||
'primaryBorderColor':'#6f55ff',
|
||||
'secondaryColor':'#111111',
|
||||
'secondaryBorderColor':'#3fb1ff',
|
||||
'tertiaryColor':'#1a1a1a',
|
||||
'tertiaryBorderColor':'#00d38a',
|
||||
'lineColor':'#3fb1ff',
|
||||
'textColor':'#ffffff',
|
||||
'fontFamily':'Inter',
|
||||
'fontSize':'14px',
|
||||
'background':'#0a0a0a',
|
||||
'mainBkg':'#111111',
|
||||
'secondBkg':'#1a1a1a',
|
||||
'clusterBkg':'rgba(17, 17, 17, 0.8)',
|
||||
'nodeTextColor':'#ffffff'
|
||||
}
|
||||
}}%%
|
||||
flowchart LR
|
||||
A["User"] --> B["React Form"]
|
||||
B --> C["API Call"]
|
||||
C --> D["Display Answer"]
|
||||
```
|
||||
|
||||
See [Getting Started](getting-started) for details.
|
||||
|
||||
# Archon UI - Knowledge Engine Web Interface
|
||||
|
||||
A modern React-based web interface for the Archon Knowledge Engine MCP Server. Built with TypeScript, Vite, and Tailwind CSS.
|
||||
|
||||
## 🎨 UI Overview
|
||||
|
||||
Archon UI provides a comprehensive dashboard for managing your AI's knowledge base:
|
||||
|
||||

|
||||
|
||||
### Key Features
|
||||
|
||||
- **📊 MCP Dashboard**: Monitor and control the MCP server
|
||||
- **⚙️ Settings Management**: Configure credentials and RAG strategies
|
||||
- **📚 Knowledge Management**: Browse, search, and organize knowledge items
|
||||
- **📈 Real-time Updates**: Socket.IO-based live updates across the UI
|
||||
|
||||
## 🏗️ Architecture
|
||||
|
||||
### Technology Stack
|
||||
|
||||
- **React 18.3**: Modern React with hooks and functional components
|
||||
- **TypeScript**: Full type safety and IntelliSense support
|
||||
- **Vite**: Fast build tool and dev server
|
||||
- **Tailwind CSS**: Utility-first styling
|
||||
- **Framer Motion**: Smooth animations and transitions
|
||||
- **Lucide Icons**: Beautiful and consistent iconography
|
||||
- **React Router**: Client-side routing
|
||||
|
||||
|
||||
## 📄 Pages Documentation
|
||||
|
||||
### 1. Knowledge Base (`/`)
|
||||
|
||||
Browse and manage your knowledge items with multiple view modes.
|
||||
|
||||
**Components:**
|
||||
- **Knowledge Grid**: Card-based knowledge display with domain grouping
|
||||
- **Knowledge Table**: Full-width table view with sortable columns
|
||||
- **Search/Filter**: Search by title, type, tags
|
||||
- **Crawling Progress**: Real-time progress tracking for URL crawling
|
||||
- **Actions**: Delete, add sources, file upload
|
||||
|
||||
**Features:**
|
||||
- Grid and table view modes
|
||||
- Real-time updates via Socket.IO
|
||||
- Type-based filtering (technical/business)
|
||||
- Domain-based grouping for URLs
|
||||
- Tag tooltips for overflow
|
||||
- Progress tracking for crawling operations
|
||||
|
||||
### 2. Projects (`/projects`)
|
||||
|
||||
Project dashboard with task management and documentation tabs.
|
||||
|
||||
**Components:**
|
||||
- **Project List**: Create and select projects
|
||||
- **Task Tabs**: Manage tasks, features, docs and data
|
||||
- **Progress Cards**: Real-time project creation status
|
||||
|
||||
**Features:**
|
||||
- Hierarchical tasks
|
||||
- GitHub repository links
|
||||
- Socket.IO project progress
|
||||
|
||||
### 3. Settings (`/settings`)
|
||||
|
||||
Comprehensive configuration management with organized sections.
|
||||
|
||||
**Sections:**
|
||||
- **Features**:
|
||||
- Projects toggle (enable/disable Projects feature)
|
||||
- Other feature flags
|
||||
- **API Keys**:
|
||||
- OpenAI API key (encrypted storage)
|
||||
- Other API credentials
|
||||
- **RAG Settings**:
|
||||
- Contextual Embeddings toggle
|
||||
- Hybrid Search toggle
|
||||
- Agentic RAG (code extraction) toggle
|
||||
- Reranking toggle
|
||||
- Model selection
|
||||
- **Archon Unit Tests** (Collapsible):
|
||||
- Python MCP tests with real-time output
|
||||
- React UI tests with local execution
|
||||
- Pretty/Raw view modes
|
||||
- Error summary display
|
||||
|
||||
**Features:**
|
||||
- Secure credential storage with encryption
|
||||
- Real-time test execution and monitoring
|
||||
- Toast notifications for actions
|
||||
- Collapsible test section (collapsed by default)
|
||||
|
||||
### 4. MCP Dashboard (`/mcp`)
|
||||
|
||||
Central control panel for the MCP server.
|
||||
|
||||
**Components:**
|
||||
- **Server Control Panel**: Start/stop server, view status, select transport mode
|
||||
- **Server Logs Viewer**: Real-time log streaming with auto-scroll
|
||||
- **Available Tools Table**: Dynamic tool discovery and documentation
|
||||
- **MCP Test Panel**: Interactive tool testing interface
|
||||
|
||||
**Features:**
|
||||
- Dual transport support (SSE/stdio)
|
||||
- Real-time status polling (5-second intervals)
|
||||
- Socket.IO-based log streaming
|
||||
- Copy-to-clipboard configuration
|
||||
- Tool parameter validation
|
||||
|
||||
Browse and manage your knowledge items.
|
||||
|
||||
**Components:**
|
||||
- **Knowledge Grid**: Card-based knowledge display
|
||||
- **Search/Filter**: Search by title, type, tags
|
||||
- **Knowledge Details**: View full item details
|
||||
- **Actions**: Delete, refresh, organize
|
||||
|
||||
**Features:**
|
||||
- Pagination support
|
||||
- Real-time updates via Socket.IO
|
||||
- Type-based filtering (technical/business)
|
||||
- Metadata display
|
||||
|
||||
|
||||
## 🧩 Component Library
|
||||
|
||||
### Base UI Components
|
||||
|
||||
#### Button
|
||||
```tsx
|
||||
<Button
|
||||
variant="primary|secondary|ghost"
|
||||
size="sm|md|lg"
|
||||
accentColor="blue|green|purple|orange|pink"
|
||||
onClick={handleClick}
|
||||
>
|
||||
Click me
|
||||
</Button>
|
||||
```
|
||||
|
||||
#### Card
|
||||
```tsx
|
||||
<Card accentColor="blue" className="p-6">
|
||||
<h3>Card Title</h3>
|
||||
<p>Card content</p>
|
||||
</Card>
|
||||
```
|
||||
|
||||
#### LoadingSpinner
|
||||
```tsx
|
||||
<LoadingSpinner size="sm|md|lg" />
|
||||
```
|
||||
|
||||
### Layout Components
|
||||
|
||||
#### Sidebar
|
||||
- Collapsible navigation
|
||||
- Active route highlighting
|
||||
- Icon + text navigation items
|
||||
- Responsive design
|
||||
|
||||
#### Header
|
||||
- Dark mode toggle
|
||||
- User menu
|
||||
- Breadcrumb navigation
|
||||
|
||||
### Animation Components
|
||||
|
||||
#### PageTransition
|
||||
Wraps pages with smooth fade/slide animations:
|
||||
```tsx
|
||||
<PageTransition>
|
||||
<YourPageContent />
|
||||
</PageTransition>
|
||||
```
|
||||
|
||||
## 🔌 Socket.IO Integration
|
||||
|
||||
All real-time connections use **Socket.IO** with a room-based architecture on the default namespace for improved reliability and organization:
|
||||
|
||||
### Key Services Using Socket.IO
|
||||
|
||||
| Service | Purpose | Room Pattern | Status |
|
||||
|---------|---------|--------------|--------|
|
||||
| `crawlProgressService` | Progress tracking for crawling | `progress_{id}` | ✅ Room-based |
|
||||
| `projectCreationProgressService` | Project creation progress | `progress_{id}` | ✅ Room-based |
|
||||
| `webSocketService` | Socket.IO client wrapper | Default namespace | ✅ Room-based |
|
||||
| `taskUpdateService` | Real-time task updates | `{project_id}` | ✅ Room-based |
|
||||
| `agentChatService` | Agent chat streaming | `chat_{session_id}` | ✅ Room-based |
|
||||
|
||||
### Room-Based Socket.IO Pattern
|
||||
|
||||
```typescript
|
||||
import { createWebSocketService } from './services/webSocketService';
|
||||
|
||||
// Always connect to default namespace
|
||||
const wsService = createWebSocketService({
|
||||
maxReconnectAttempts: 5,
|
||||
reconnectInterval: 1000
|
||||
});
|
||||
|
||||
// Connect to default namespace only
|
||||
await wsService.connect('/');
|
||||
|
||||
// Join specific rooms via subscription events
|
||||
wsService.send({
|
||||
type: 'subscribe_progress',
|
||||
data: { progress_id: progressId }
|
||||
});
|
||||
|
||||
// Handle room-specific messages
|
||||
wsService.addMessageHandler('progress_update', (message) => {
|
||||
updateProgressUI(message.data);
|
||||
});
|
||||
|
||||
// Clean up (rooms cleaned automatically)
|
||||
wsService.disconnect();
|
||||
```
|
||||
|
||||
### Component Integration with Rooms
|
||||
|
||||
```typescript
|
||||
useEffect(() => {
|
||||
const ws = createWebSocketService();
|
||||
|
||||
// Connect to default namespace
|
||||
ws.connect('/').then(() => {
|
||||
// Join relevant rooms
|
||||
ws.send({
|
||||
type: 'join_project',
|
||||
data: { project_id: projectId }
|
||||
});
|
||||
|
||||
// Handle room messages
|
||||
ws.addMessageHandler('task_created', (message) => {
|
||||
setTasks(prev => [...prev, message.data]);
|
||||
});
|
||||
});
|
||||
|
||||
return () => ws.disconnect();
|
||||
}, [projectId]); // Stable dependencies only
|
||||
```
|
||||
|
||||
### Room Subscription Patterns
|
||||
|
||||
<Tabs>
|
||||
<TabItem value="project" label="Project Rooms">
|
||||
|
||||
```typescript
|
||||
// Subscribe to project-specific updates
|
||||
const subscribeToProject = (projectId: string) => {
|
||||
wsService.send({
|
||||
type: 'join_project',
|
||||
data: { project_id: projectId }
|
||||
});
|
||||
|
||||
// Handle project room events
|
||||
wsService.addMessageHandler('task_created', handleTaskCreated);
|
||||
wsService.addMessageHandler('task_updated', handleTaskUpdated);
|
||||
wsService.addMessageHandler('task_deleted', handleTaskDeleted);
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="progress" label="Progress Rooms">
|
||||
|
||||
```typescript
|
||||
// Subscribe to progress tracking
|
||||
const subscribeToProgress = (progressId: string) => {
|
||||
wsService.send({
|
||||
type: 'subscribe_progress',
|
||||
data: { progress_id: progressId }
|
||||
});
|
||||
|
||||
// Handle progress updates
|
||||
wsService.addMessageHandler('project_progress', (message) => {
|
||||
updateProgressBar(message.data.percentage);
|
||||
updateStatus(message.data.status);
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
<TabItem value="list" label="List Rooms">
|
||||
|
||||
```typescript
|
||||
// Subscribe to project list updates
|
||||
const subscribeToProjectList = () => {
|
||||
wsService.send({ type: 'subscribe_projects' });
|
||||
|
||||
// Handle list updates
|
||||
wsService.addMessageHandler('projects_update', (message) => {
|
||||
setProjects(message.data.projects);
|
||||
});
|
||||
};
|
||||
```
|
||||
|
||||
</TabItem>
|
||||
</Tabs>
|
||||
|
||||
## 🔌 Services
|
||||
|
||||
### mcpService
|
||||
Handles all MCP server communication:
|
||||
- `startServer()`: Start the MCP server
|
||||
- `stopServer()`: Stop the MCP server
|
||||
- `getStatus()`: Get current server status
|
||||
- `streamLogs()`: Socket.IO log streaming
|
||||
- `getAvailableTools()`: Fetch MCP tools
|
||||
|
||||
### api
|
||||
Base API configuration with:
|
||||
- Automatic error handling
|
||||
- Request/response interceptors
|
||||
- Base URL configuration
|
||||
- TypeScript generics
|
||||
|
||||
### chatService
|
||||
RAG query interface:
|
||||
- `sendMessage()`: Send RAG query
|
||||
- `streamResponse()`: Stream responses
|
||||
- `getSources()`: Get available sources
|
||||
|
||||
## 🎨 Styling
|
||||
|
||||
### Tailwind Configuration
|
||||
- Custom color palette
|
||||
- Dark mode support
|
||||
- Custom animations
|
||||
- Responsive breakpoints
|
||||
|
||||
### Theme Variables
|
||||
```css
|
||||
--primary: Blue accent colors
|
||||
--secondary: Gray/neutral colors
|
||||
--success: Green indicators
|
||||
--warning: Orange indicators
|
||||
--error: Red indicators
|
||||
```
|
||||
|
||||
## 🚀 Development
|
||||
|
||||
### Setup
|
||||
```bash
|
||||
# Install dependencies
|
||||
npm install
|
||||
|
||||
# Start dev server
|
||||
npm run dev
|
||||
|
||||
# Build for production
|
||||
npm run build
|
||||
|
||||
# Run tests
|
||||
npm test
|
||||
```
|
||||
|
||||
### Environment Variables
|
||||
```env
|
||||
VITE_API_URL=http://localhost:8080
|
||||
VITE_API_BASE_URL=http://localhost:8080
|
||||
```
|
||||
|
||||
### Hot Module Replacement
|
||||
Vite provides instant HMR for:
|
||||
- React components
|
||||
- CSS modules
|
||||
- TypeScript files
|
||||
|
||||
## 🧪 Testing
|
||||
|
||||
### Unit Tests
|
||||
- Component testing with React Testing Library
|
||||
- Service mocking with MSW
|
||||
- Hook testing with @testing-library/react-hooks
|
||||
|
||||
### Integration Tests
|
||||
- Page-level testing
|
||||
- API integration tests
|
||||
- Socket.IO testing
|
||||
|
||||
## 📦 Build & Deployment
|
||||
|
||||
### Docker Support
|
||||
```dockerfile
|
||||
FROM node:18-alpine
|
||||
WORKDIR /app
|
||||
COPY package*.json ./
|
||||
RUN npm ci
|
||||
COPY . .
|
||||
RUN npm run build
|
||||
EXPOSE 5173
|
||||
CMD ["npm", "run", "preview"]
|
||||
```
|
||||
|
||||
### Production Optimization
|
||||
- Code splitting by route
|
||||
- Lazy loading for pages
|
||||
- Image optimization
|
||||
- Bundle size analysis
|
||||
|
||||
## 🔧 Configuration Files
|
||||
|
||||
### vite.config.ts
|
||||
- Path aliases
|
||||
- Build optimization
|
||||
- Development server config
|
||||
|
||||
### tsconfig.json
|
||||
- Strict type checking
|
||||
- Path mappings
|
||||
- Compiler options
|
||||
|
||||
### tailwind.config.js
|
||||
- Custom theme
|
||||
- Plugin configuration
|
||||
- Purge settings
|
||||
|
||||
## ✅ Frontend Development Standards
|
||||
|
||||
### Performance Best Practices
|
||||
|
||||
#### Input Performance Optimization
|
||||
|
||||
**Problem**: Typing lag and screen flickering in modals/forms due to excessive re-renders.
|
||||
|
||||
**Real Example**: EditTaskModal had 148 renders during typing!
|
||||
|
||||
**Solution**: Use debounced input components that manage their own state:
|
||||
|
||||
```typescript
|
||||
// ✅ GOOD: Debounced input component
|
||||
export const DebouncedInput = memo(({ value, onChange, delay = 300 }) => {
|
||||
const [localValue, setLocalValue] = useState(value);
|
||||
|
||||
// Local state for immediate feedback
|
||||
const handleChange = (e) => {
|
||||
setLocalValue(e.target.value);
|
||||
// Debounced parent update
|
||||
debouncedOnChange(e.target.value);
|
||||
};
|
||||
|
||||
return <input value={localValue} onChange={handleChange} />;
|
||||
});
|
||||
|
||||
// Usage in modal
|
||||
<DebouncedInput
|
||||
value={task.title}
|
||||
onChange={handleTitleChange}
|
||||
/>
|
||||
```
|
||||
|
||||
**❌ BAD: Direct state updates**
|
||||
```typescript
|
||||
// Causes re-render on every keystroke
|
||||
<input
|
||||
value={formData.title}
|
||||
onChange={(e) => setFormData({ ...formData, title: e.target.value })}
|
||||
/>
|
||||
```
|
||||
|
||||
#### State Management Best Practices
|
||||
|
||||
**1. Use React.memo with Custom Comparison**
|
||||
```typescript
|
||||
export const MyComponent = memo(({ props }) => {
|
||||
// Component logic
|
||||
}, (prevProps, nextProps) => {
|
||||
// Return true to skip re-render
|
||||
return prevProps.id === nextProps.id &&
|
||||
prevProps.status === nextProps.status;
|
||||
});
|
||||
```
|
||||
|
||||
**2. Stable Event Handlers with useCallback**
|
||||
```typescript
|
||||
// ✅ GOOD: Stable reference
|
||||
const handleChange = useCallback((value: string) => {
|
||||
setData(prev => ({ ...prev, field: value }));
|
||||
}, []); // Empty deps = stable forever
|
||||
|
||||
// ❌ BAD: New function every render
|
||||
onChange={(e) => setData({ ...data, field: e.target.value })}
|
||||
```
|
||||
|
||||
**3. Batch State Updates**
|
||||
```typescript
|
||||
// ✅ GOOD: Single update
|
||||
setFormData(prev => ({
|
||||
...prev,
|
||||
title: newTitle,
|
||||
description: newDescription,
|
||||
status: newStatus
|
||||
}));
|
||||
|
||||
// ❌ BAD: Multiple updates = multiple renders
|
||||
setTitle(newTitle);
|
||||
setDescription(newDescription);
|
||||
setStatus(newStatus);
|
||||
```
|
||||
|
||||
### Real-time Updates Best Practices
|
||||
|
||||
#### When to Use Socket.IO (Real-time)
|
||||
|
||||
Use Socket.IO for features that require immediate updates across users:
|
||||
|
||||
**1. Progress Tracking**
|
||||
- **Example**: CrawlingProgressCard
|
||||
- **Why**: Users need to see live crawling progress
|
||||
- **Pattern**: Progress room subscription
|
||||
```typescript
|
||||
// Subscribe to crawl progress
|
||||
ws.send({
|
||||
type: 'crawl_subscribe',
|
||||
data: { progress_id: crawlId }
|
||||
});
|
||||
|
||||
ws.addMessageHandler('crawl_progress', (message) => {
|
||||
updateProgressBar(message.data.percentage);
|
||||
updateCurrentUrl(message.data.current_url);
|
||||
});
|
||||
```
|
||||
|
||||
**2. AI Agent Communication**
|
||||
- **Example**: ArchonChatPanel
|
||||
- **Why**: Stream AI responses as they generate
|
||||
- **Pattern**: Chat session room
|
||||
```typescript
|
||||
// Join chat session
|
||||
ws.send({
|
||||
type: 'join_chat',
|
||||
data: { session_id: sessionId }
|
||||
});
|
||||
|
||||
ws.addMessageHandler('agent_message', (message) => {
|
||||
appendToChat(message.data.content);
|
||||
});
|
||||
```
|
||||
|
||||
**3. Collaborative Features**
|
||||
- **Example**: TasksTab with MCP agent updates
|
||||
- **Why**: Multiple agents/users updating tasks
|
||||
- **Pattern**: Project room subscription
|
||||
```typescript
|
||||
// Real-time task updates from AI agents
|
||||
ws.send({
|
||||
type: 'join_project',
|
||||
data: { project_id: projectId }
|
||||
});
|
||||
|
||||
ws.addMessageHandler('task_updated', (message) => {
|
||||
// Update task immediately when AI agent modifies it
|
||||
updateTaskInUI(message.data);
|
||||
});
|
||||
```
|
||||
|
||||
#### When NOT to Use Socket.IO
|
||||
|
||||
Use REST API calls for:
|
||||
- User-triggered actions (save, delete, create)
|
||||
- Initial data loading
|
||||
- Infrequent updates
|
||||
- Actions that need confirmation
|
||||
|
||||
### Performance Testing
|
||||
|
||||
Add this to components during development:
|
||||
```typescript
|
||||
const renderCount = useRef(0);
|
||||
useEffect(() => {
|
||||
renderCount.current++;
|
||||
console.log(`[ComponentName] Render #${renderCount.current}`);
|
||||
});
|
||||
```
|
||||
|
||||
**Performance Targets**:
|
||||
- Typing: < 5 renders/second
|
||||
- Modal open/close: < 3 renders
|
||||
- State changes: 1-2 renders per action
|
||||
|
||||
### Socket.IO Room-Based Best Practices
|
||||
|
||||
**DO:**
|
||||
- ✅ Always connect to default namespace `/` only
|
||||
- ✅ Use room subscription events to join specific rooms
|
||||
- ✅ Handle room-specific messages with clear event names
|
||||
- ✅ Clean up connections in useEffect return (rooms auto-cleanup)
|
||||
- ✅ Use typed message handlers with proper data extraction
|
||||
- ✅ Follow the subscription pattern: connect → subscribe → handle messages
|
||||
|
||||
**DON'T:**
|
||||
- ❌ Use custom namespaces like `/chat`, `/project`, `/crawl`
|
||||
- ❌ Create direct WebSocket instances or native Socket.IO clients
|
||||
- ❌ Broadcast to all clients - use rooms for targeting
|
||||
- ❌ Include unstable functions in useCallback dependencies
|
||||
- ❌ Create multiple connections to the same endpoint
|
||||
- ❌ Forget to handle reconnection scenarios
|
||||
|
||||
### Room Subscription Pattern
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT: Room-based subscription
|
||||
useEffect(() => {
|
||||
const ws = createWebSocketService();
|
||||
|
||||
const connectAndSubscribe = async () => {
|
||||
// Always connect to default namespace
|
||||
await ws.connect('/');
|
||||
|
||||
// Subscribe to specific rooms
|
||||
ws.send({
|
||||
type: 'subscribe_progress',
|
||||
data: { progress_id: progressId }
|
||||
});
|
||||
|
||||
// Handle room messages
|
||||
ws.addMessageHandler('progress_update', (message) => {
|
||||
setProgress(message.data);
|
||||
});
|
||||
};
|
||||
|
||||
connectAndSubscribe();
|
||||
return () => ws.disconnect();
|
||||
}, [progressId]);
|
||||
|
||||
// ❌ WRONG: Custom namespace connection
|
||||
await ws.connect('/project-creation-progress/123'); // Don't do this
|
||||
```
|
||||
|
||||
### Stable Dependencies Pattern
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT: Only stable dependencies
|
||||
const handleUpdate = useCallback(() => {
|
||||
updateData(value);
|
||||
showToast('Updated', 'success'); // Can call without dependency
|
||||
}, [value]); // Only primitive values
|
||||
|
||||
// ❌ WRONG: Unstable function dependencies
|
||||
const handleUpdate = useCallback(() => {
|
||||
updateData(value);
|
||||
showToast('Updated', 'success');
|
||||
}, [value, showToast]); // showToast causes re-renders
|
||||
```
|
||||
|
||||
### Event Handling Pattern
|
||||
|
||||
**Single Source of Truth**: Avoid duplicate event handlers for the same action.
|
||||
|
||||
```typescript
|
||||
// ✅ CORRECT: One place handles completion
|
||||
const handleSocketMessage = (message) => {
|
||||
if (message.type === 'completed') {
|
||||
showToast('Operation completed', 'success');
|
||||
refreshData();
|
||||
}
|
||||
};
|
||||
|
||||
// ❌ WRONG: Multiple handlers for same event
|
||||
// In Socket.IO handler:
|
||||
showToast('Operation completed', 'success');
|
||||
// In API callback:
|
||||
showToast('Operation completed', 'success');
|
||||
// Causes duplicate toasts!
|
||||
```
|
||||
|
||||
### Components Requiring Performance Optimization
|
||||
|
||||
Based on code analysis, these components need performance improvements:
|
||||
|
||||
#### High Priority
|
||||
1. **RAGSettings** (`/components/settings/RAGSettings.tsx`)
|
||||
- 11 onChange handlers without optimization
|
||||
- Direct state updates on every change
|
||||
- Fix: Implement debounced inputs or batch updates
|
||||
|
||||
2. **DataTab - EditTableModal** (`/components/project-tasks/DataTab.tsx`)
|
||||
- 6+ onChange handlers for table columns
|
||||
- Multiple state updates per edit
|
||||
- Fix: Use local state with save button
|
||||
|
||||
3. **EditKnowledgeItemModal** (`/components/knowledge-base/EditKnowledgeItemModal.tsx`)
|
||||
- Direct state updates in onChange
|
||||
- Fix: Apply DebouncedInput pattern
|
||||
|
||||
#### Medium Priority
|
||||
4. **APIKeysSection** - Dynamic list with multiple input fields
|
||||
5. **ToolTestingPanel** - Complex parameter inputs
|
||||
6. **ArchonChatPanel** - Consider virtualization for long chat histories
|
||||
|
||||
189
docs/docusaurus.config.js
Normal file
@@ -0,0 +1,189 @@
|
||||
// @ts-check
|
||||
|
||||
/** @type {import('@docusaurus/types').Config} */
|
||||
export default {
|
||||
title: 'Archon',
|
||||
tagline: 'Knowledge Engine for AI Coding Assistants',
|
||||
url: 'http://localhost:3838',
|
||||
baseUrl: '/',
|
||||
onBrokenLinks: 'warn',
|
||||
onBrokenMarkdownLinks: 'warn',
|
||||
favicon: 'img/favicon.svg',
|
||||
organizationName: 'archon',
|
||||
projectName: 'archon',
|
||||
|
||||
markdown: {
|
||||
mermaid: true,
|
||||
},
|
||||
|
||||
themes: ['@docusaurus/theme-mermaid'],
|
||||
|
||||
// Client scripts to handle SVG rounded corners
|
||||
scripts: [
|
||||
{
|
||||
src: '/js/mermaid-rounded-corners.js',
|
||||
async: true,
|
||||
},
|
||||
],
|
||||
|
||||
presets: [
|
||||
[
|
||||
'@docusaurus/preset-classic',
|
||||
/** @type {import('@docusaurus/preset-classic').Options} */
|
||||
({
|
||||
docs: {
|
||||
path: 'docs',
|
||||
routeBasePath: '/',
|
||||
sidebarPath: './sidebars.js', // Enable proper sidebar
|
||||
editUrl: 'https://github.com/coleam00/archon/edit/main/docs/',
|
||||
showLastUpdateTime: true,
|
||||
showLastUpdateAuthor: true,
|
||||
},
|
||||
blog: false,
|
||||
theme: {
|
||||
customCss: './src/css/custom.css',
|
||||
},
|
||||
}),
|
||||
],
|
||||
],
|
||||
|
||||
themeConfig:
|
||||
/** @type {import('@docusaurus/preset-classic').ThemeConfig} */
|
||||
({
|
||||
// Proper Mermaid configuration according to official docs
|
||||
mermaid: {
|
||||
theme: {
|
||||
light: 'base',
|
||||
dark: 'base'
|
||||
},
|
||||
options: {
|
||||
darkMode: true,
|
||||
themeVariables: {
|
||||
// Primary colors - Aurora borealis theme
|
||||
primaryColor: '#0a0a0a',
|
||||
primaryTextColor: '#ffffff',
|
||||
primaryBorderColor: '#6f55ff',
|
||||
|
||||
// Secondary colors
|
||||
secondaryColor: '#111111',
|
||||
secondaryTextColor: '#ffffff',
|
||||
secondaryBorderColor: '#3fb1ff',
|
||||
|
||||
// Tertiary colors
|
||||
tertiaryColor: '#1a1a1a',
|
||||
tertiaryTextColor: '#ffffff',
|
||||
tertiaryBorderColor: '#00d38a',
|
||||
|
||||
// Background and main colors
|
||||
background: '#0a0a0a',
|
||||
mainBkg: '#111111',
|
||||
secondBkg: '#1a1a1a',
|
||||
|
||||
// Lines and text with aurora colors
|
||||
lineColor: '#3fb1ff',
|
||||
textColor: '#ffffff',
|
||||
|
||||
// Font configuration - Force Inter family throughout
|
||||
fontFamily: '"Inter", -apple-system, BlinkMacSystemFont, "Segoe UI", Roboto, sans-serif',
|
||||
fontSize: '14px',
|
||||
fontWeight: '400',
|
||||
|
||||
// Flowchart specific variables
|
||||
nodeBorder: '#6f55ff',
|
||||
clusterBkg: 'rgba(17, 17, 17, 0.8)',
|
||||
clusterBorder: '#3fb1ff',
|
||||
defaultLinkColor: '#3fb1ff',
|
||||
edgeLabelBackground: '#0a0a0a',
|
||||
nodeTextColor: '#ffffff',
|
||||
|
||||
// Color scales for different elements
|
||||
cScale0: '#00d38a',
|
||||
cScale1: '#0fcaa6',
|
||||
cScale2: '#36b5ef',
|
||||
cScale3: '#3fb1ff',
|
||||
cScale4: '#fe6aff',
|
||||
cScale5: '#d964ff',
|
||||
cScale6: '#ab5dff',
|
||||
cScale7: '#8a59ff',
|
||||
cScale8: '#7656ff',
|
||||
cScale9: '#6f55ff',
|
||||
cScale10: '#9a3df8',
|
||||
cScale11: '#ed0fed',
|
||||
|
||||
// Sequence diagram specific
|
||||
actorBkg: '#111111',
|
||||
actorBorder: '#6f55ff',
|
||||
actorTextColor: '#ffffff',
|
||||
|
||||
// Class diagram
|
||||
classText: '#ffffff',
|
||||
|
||||
// State diagram
|
||||
labelColor: '#ffffff',
|
||||
}
|
||||
},
|
||||
},
|
||||
colorMode: {
|
||||
defaultMode: 'dark',
|
||||
disableSwitch: true,
|
||||
respectPrefersColorScheme: false,
|
||||
},
|
||||
navbar: {
|
||||
title: 'Archon',
|
||||
logo: {
|
||||
alt: 'Archon Logo',
|
||||
src: 'img/logo-neon.svg',
|
||||
},
|
||||
items: [
|
||||
{
|
||||
href: 'https://github.com/coleam00/archon',
|
||||
label: 'GitHub',
|
||||
position: 'right',
|
||||
},
|
||||
],
|
||||
},
|
||||
|
||||
tableOfContents: {
|
||||
minHeadingLevel: 2,
|
||||
maxHeadingLevel: 4,
|
||||
},
|
||||
|
||||
footer: {
|
||||
style: 'dark',
|
||||
links: [
|
||||
{
|
||||
title: 'Getting Started',
|
||||
items: [
|
||||
{ label: 'Installation', to: '/getting-started' },
|
||||
{ label: 'Quick Setup', to: '/getting-started#quick-start' },
|
||||
{ label: 'Configuration', to: '/configuration' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'API & Integration',
|
||||
items: [
|
||||
{ label: 'API Reference', to: '/api-reference' },
|
||||
{ label: 'MCP Integration', to: '/mcp-overview' },
|
||||
{ label: 'Task Management', to: '/tasks' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'User Interface',
|
||||
items: [
|
||||
{ label: 'Web Interface', to: '/ui' },
|
||||
{ label: 'Testing Guide', to: '/testing' },
|
||||
{ label: 'Deployment', to: '/deployment' },
|
||||
],
|
||||
},
|
||||
{
|
||||
title: 'Community',
|
||||
items: [
|
||||
{ label: 'GitHub', href: 'https://github.com/coleam00/archon' },
|
||||
{ label: 'Issues', href: 'https://github.com/coleam00/archon/issues' },
|
||||
],
|
||||
},
|
||||
],
|
||||
copyright: `Copyright © ${new Date().getFullYear()} Archon Project`,
|
||||
},
|
||||
}),
|
||||
};
|
||||
18946
docs/package-lock.json
generated
Normal file
40
docs/package.json
Normal file
@@ -0,0 +1,40 @@
|
||||
{
|
||||
"name": "docs",
|
||||
"version": "0.0.0",
|
||||
"private": true,
|
||||
"scripts": {
|
||||
"docusaurus": "docusaurus",
|
||||
"start": "docusaurus start",
|
||||
"build": "docusaurus build",
|
||||
"swizzle": "docusaurus swizzle",
|
||||
"deploy": "docusaurus deploy",
|
||||
"clear": "docusaurus clear",
|
||||
"serve": "docusaurus serve",
|
||||
"write-translations": "docusaurus write-translations",
|
||||
"write-heading-ids": "docusaurus write-heading-ids"
|
||||
},
|
||||
"dependencies": {
|
||||
"@docusaurus/core": "^3.8.0",
|
||||
"@docusaurus/preset-classic": "^3.8.0",
|
||||
"@docusaurus/theme-mermaid": "^3.8.0",
|
||||
"@mdx-js/react": "^3.0.0",
|
||||
"clsx": "^2.0.0",
|
||||
"lucide-react": "^0.513.0",
|
||||
"prism-react-renderer": "^2.4.0",
|
||||
"react": "^18.0.0",
|
||||
"react-dom": "^18.0.0",
|
||||
"@xyflow/react": "^12.6.0"
|
||||
},
|
||||
"browserslist": {
|
||||
"production": [
|
||||
">0.5%",
|
||||
"not dead",
|
||||
"not op_mini all"
|
||||
],
|
||||
"development": [
|
||||
"last 1 chrome version",
|
||||
"last 1 firefox version",
|
||||
"last 1 safari version"
|
||||
]
|
||||
}
|
||||
}
|
||||
69
docs/sidebars.js
Normal file
@@ -0,0 +1,69 @@
|
||||
module.exports = {
|
||||
docs: [
|
||||
// INTRO & GETTING STARTED
|
||||
{
|
||||
type: 'doc',
|
||||
id: 'intro',
|
||||
label: 'Introduction',
|
||||
},
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Getting Started',
|
||||
items: [
|
||||
'getting-started',
|
||||
'configuration',
|
||||
'deployment',
|
||||
],
|
||||
},
|
||||
|
||||
// CORE FEATURES
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Features',
|
||||
items: [
|
||||
'projects-overview',
|
||||
'knowledge-overview',
|
||||
'code-extraction-rules',
|
||||
],
|
||||
},
|
||||
|
||||
// REFERENCE SECTION
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Reference',
|
||||
items: [
|
||||
'architecture',
|
||||
'server-overview',
|
||||
'server-services',
|
||||
'api-reference',
|
||||
'mcp-server',
|
||||
'socketio',
|
||||
'testing',
|
||||
'coding-best-practices',
|
||||
],
|
||||
},
|
||||
|
||||
// AGENTS & AI
|
||||
{
|
||||
type: 'category',
|
||||
label: 'AI Agents',
|
||||
items: [
|
||||
'agents-overview',
|
||||
'agent-rag',
|
||||
'agent-document',
|
||||
'agent-task',
|
||||
'agent-chat',
|
||||
],
|
||||
},
|
||||
|
||||
// GUIDES
|
||||
{
|
||||
type: 'category',
|
||||
label: 'Guides',
|
||||
items: [
|
||||
'ui',
|
||||
'server-monitoring',
|
||||
],
|
||||
},
|
||||
],
|
||||
};
|
||||
1210
docs/src/css/custom.css
Normal file
575
docs/src/pages/index.js
Normal file
@@ -0,0 +1,575 @@
|
||||
import React, { useEffect, useCallback, useState } from 'react';
|
||||
import clsx from 'clsx';
|
||||
import Layout from '@theme/Layout';
|
||||
import Link from '@docusaurus/Link';
|
||||
import useDocusaurusContext from '@docusaurus/useDocusaurusContext';
|
||||
import styles from './index.module.css';
|
||||
import {
|
||||
ArrowRight,
|
||||
Database,
|
||||
Zap,
|
||||
Globe,
|
||||
FileText,
|
||||
Cpu,
|
||||
CheckSquare,
|
||||
Plug
|
||||
} from 'lucide-react';
|
||||
import Heading from '@theme/Heading';
|
||||
|
||||
// Architecture Diagram Component
|
||||
const ArchitectureDiagram = () => {
|
||||
const [reactFlowInstance, setReactFlowInstance] = useState(null);
|
||||
const [lucideIcons, setLucideIcons] = useState(null);
|
||||
|
||||
useEffect(() => {
|
||||
const loadComponents = async () => {
|
||||
if (typeof window !== 'undefined') {
|
||||
try {
|
||||
// Import React Flow CSS first
|
||||
await import('@xyflow/react/dist/style.css');
|
||||
|
||||
const reactFlow = await import('@xyflow/react');
|
||||
const lucide = await import('lucide-react');
|
||||
setReactFlowInstance(reactFlow);
|
||||
setLucideIcons(lucide);
|
||||
} catch (error) {
|
||||
console.error('Error loading components:', error);
|
||||
}
|
||||
}
|
||||
};
|
||||
loadComponents();
|
||||
}, []);
|
||||
|
||||
if (!reactFlowInstance || !lucideIcons) {
|
||||
return <div style={{ height: '600px', width: '100%' }}>Loading...</div>;
|
||||
}
|
||||
|
||||
return <ReactFlowDiagram reactFlowInstance={reactFlowInstance} lucideIcons={lucideIcons} />;
|
||||
};
|
||||
|
||||
// Separate component for React Flow diagram to ensure hooks are called consistently
|
||||
const ReactFlowDiagram = ({ reactFlowInstance, lucideIcons }) => {
|
||||
const { ReactFlow, useNodesState, useEdgesState, addEdge, Handle, Position } = reactFlowInstance;
|
||||
const { Database, Zap, Globe, FileText, CheckSquare } = lucideIcons;
|
||||
|
||||
// Node definitions with organized layout matching the screenshot
|
||||
const initialNodes = [
|
||||
// IDEs on the left (organized vertically)
|
||||
{
|
||||
id: 'cursor',
|
||||
type: 'ide',
|
||||
position: { x: 50, y: 50 },
|
||||
data: { label: 'Cursor', icon: '/img/cursor.svg' },
|
||||
draggable: false
|
||||
},
|
||||
{
|
||||
id: 'claude',
|
||||
type: 'ide',
|
||||
position: { x: 50, y: 150 },
|
||||
data: { label: 'Claude Code', icon: '/img/claude-logo.svg' },
|
||||
draggable: false
|
||||
},
|
||||
{
|
||||
id: 'windsurf',
|
||||
type: 'ide',
|
||||
position: { x: 50, y: 250 },
|
||||
data: { label: 'Windsurf', icon: '/img/windsurf-white-symbol.svg' },
|
||||
draggable: false
|
||||
},
|
||||
{
|
||||
id: 'vscode',
|
||||
type: 'ide',
|
||||
position: { x: 50, y: 350 },
|
||||
data: { label: 'VS Code', icon: '/img/Visual_Studio_Code_1.35_icon.svg' },
|
||||
draggable: false
|
||||
},
|
||||
|
||||
// Archon in the center (raised higher)
|
||||
{
|
||||
id: 'archon',
|
||||
type: 'archon',
|
||||
position: { x: 330, y: 50 },
|
||||
data: { label: 'ARCHON', subtitle: 'Knowledge Engine' },
|
||||
draggable: false
|
||||
},
|
||||
|
||||
// MCP Logo positioned on connector line
|
||||
{
|
||||
id: 'mcp-logo',
|
||||
type: 'mcp',
|
||||
position: { x: 210, y: 135 },
|
||||
data: { label: 'MCP' },
|
||||
draggable: false
|
||||
},
|
||||
|
||||
// FastApi Logo positioned on connector line
|
||||
{
|
||||
id: 'fastapi',
|
||||
type: 'fastapi',
|
||||
position: { x: 355, y: 275 },
|
||||
data: { label: 'FastAPI' },
|
||||
draggable: false
|
||||
},
|
||||
|
||||
// Archon UI Control below Archon
|
||||
{
|
||||
id: 'archon-ui',
|
||||
type: 'ui-control',
|
||||
position: { x: 313, y: 350 },
|
||||
data: {
|
||||
title: 'Archon UI',
|
||||
subtitle: 'Control all of Archon\'s Features'
|
||||
},
|
||||
draggable: false
|
||||
},
|
||||
|
||||
// Knowledge Sources container
|
||||
{
|
||||
id: 'knowledge-sources',
|
||||
type: 'container',
|
||||
position: { x: 700, y: 50 },
|
||||
data: {
|
||||
title: 'Knowledge Sources',
|
||||
type: 'knowledge',
|
||||
items: [
|
||||
{ label: 'Web Crawling', icon: Globe },
|
||||
{ label: 'Document Upload', icon: FileText },
|
||||
{ label: 'Advanced RAG', icon: Zap },
|
||||
{ label: 'Semantic Search', icon: Database }
|
||||
]
|
||||
},
|
||||
draggable: false
|
||||
},
|
||||
|
||||
// Project Intelligence container
|
||||
{
|
||||
id: 'project-intelligence',
|
||||
type: 'container',
|
||||
position: { x: 700, y: 300 },
|
||||
data: {
|
||||
title: 'Project Intelligence',
|
||||
type: 'intelligence',
|
||||
items: [
|
||||
{ label: 'PRD Management', icon: FileText },
|
||||
{ label: 'Feature Planning', icon: CheckSquare },
|
||||
{ label: 'Data Architecture', icon: Database },
|
||||
{ label: 'Task Management', icon: CheckSquare }
|
||||
]
|
||||
},
|
||||
draggable: false
|
||||
}
|
||||
];
|
||||
|
||||
// Simplified edges - now 7 total connections (solid lines)
|
||||
const initialEdges = [
|
||||
// IDEs to Archon (4 purple lines)
|
||||
{
|
||||
id: 'cursor-archon',
|
||||
source: 'cursor',
|
||||
target: 'archon',
|
||||
type: 'smoothstep',
|
||||
style: {
|
||||
stroke: '#8b5cf6',
|
||||
strokeWidth: 3
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'claude-archon',
|
||||
source: 'claude',
|
||||
target: 'archon',
|
||||
type: 'smoothstep',
|
||||
style: {
|
||||
stroke: '#8b5cf6',
|
||||
strokeWidth: 3
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'windsurf-archon',
|
||||
source: 'windsurf',
|
||||
target: 'archon',
|
||||
type: 'smoothstep',
|
||||
style: {
|
||||
stroke: '#8b5cf6',
|
||||
strokeWidth: 3
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'vscode-archon',
|
||||
source: 'vscode',
|
||||
target: 'archon',
|
||||
type: 'smoothstep',
|
||||
style: {
|
||||
stroke: '#8b5cf6',
|
||||
strokeWidth: 3
|
||||
}
|
||||
},
|
||||
|
||||
// Archon to Archon UI (1 blue line)
|
||||
{
|
||||
id: 'archon-ui',
|
||||
source: 'archon',
|
||||
sourceHandle: 'bottom',
|
||||
target: 'archon-ui',
|
||||
type: 'smoothstep',
|
||||
style: {
|
||||
stroke: '#3b82f6',
|
||||
strokeWidth: 3
|
||||
}
|
||||
},
|
||||
|
||||
// Archon to containers (2 lines)
|
||||
{
|
||||
id: 'archon-knowledge',
|
||||
source: 'archon',
|
||||
sourceHandle: 'right',
|
||||
target: 'knowledge-sources',
|
||||
type: 'smoothstep',
|
||||
style: {
|
||||
stroke: '#10b981',
|
||||
strokeWidth: 3
|
||||
}
|
||||
},
|
||||
{
|
||||
id: 'archon-intelligence',
|
||||
source: 'archon',
|
||||
sourceHandle: 'right',
|
||||
target: 'project-intelligence',
|
||||
type: 'smoothstep',
|
||||
style: {
|
||||
stroke: '#f59e0b',
|
||||
strokeWidth: 3
|
||||
}
|
||||
}
|
||||
];
|
||||
|
||||
const [nodes, setNodes, onNodesChange] = useNodesState(initialNodes);
|
||||
const [edges, setEdges, onEdgesChange] = useEdgesState(initialEdges);
|
||||
|
||||
// Custom node components
|
||||
const nodeTypes = {
|
||||
ide: ({ data }) => (
|
||||
<div className={styles.ideNode}>
|
||||
<img src={data.icon} alt={data.label} className={styles.nodeIcon} />
|
||||
<span className={styles.nodeLabel}>{data.label}</span>
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
style={{ background: '#8b5cf6', border: '2px solid #8b5cf6' }}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
archon: ({ data }) => (
|
||||
<div className={styles.archonNode}>
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
id="left"
|
||||
style={{ background: '#8b5cf6', border: '2px solid #8b5cf6' }}
|
||||
/>
|
||||
<img src="/img/Python-logo-notext.svg" alt="Python" className={styles.pythonIcon} />
|
||||
<img src="/img/logo-neon.svg" alt="Archon" className={styles.archonIcon} />
|
||||
<div className={styles.archonText}>
|
||||
<h3>{data.label}</h3>
|
||||
<p>{data.subtitle}</p>
|
||||
</div>
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Right}
|
||||
id="right"
|
||||
style={{ background: '#10b981', border: '2px solid #10b981' }}
|
||||
/>
|
||||
<Handle
|
||||
type="source"
|
||||
position={Position.Bottom}
|
||||
id="bottom"
|
||||
style={{ background: '#3b82f6', border: '2px solid #3b82f6' }}
|
||||
/>
|
||||
</div>
|
||||
),
|
||||
'ui-control': ({ data }) => (
|
||||
<div className={styles.uiControlNode}>
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Top}
|
||||
style={{ background: '#3b82f6', border: '2px solid #3b82f6' }}
|
||||
/>
|
||||
<img src="/img/React-icon.svg" alt="React" className={styles.reactIcon} />
|
||||
<h3 className={styles.uiControlTitle}>{data.title}</h3>
|
||||
<p className={styles.uiControlSubtitle}>{data.subtitle}</p>
|
||||
</div>
|
||||
),
|
||||
mcp: ({ data }) => (
|
||||
<div className={styles.mcpNode}>
|
||||
<img src="/img/mcp.svg" alt="MCP" className={styles.mcpIcon} />
|
||||
</div>
|
||||
),
|
||||
fastapi: ({ data }) => (
|
||||
<div className={styles.fastapiNode}>
|
||||
<img src="/img/fastapi-seeklogo.svg" alt="FastAPI" className={styles.fastapiIcon} />
|
||||
</div>
|
||||
),
|
||||
container: ({ data }) => (
|
||||
<div className={styles.containerNode} data-type={data.type}>
|
||||
<h3 className={styles.containerTitle}>{data.title}</h3>
|
||||
<div className={styles.containerGrid}>
|
||||
{data.items.map((item, index) => (
|
||||
<div key={index} className={styles.containerItem}>
|
||||
<item.icon size={16} className={styles.itemIcon} />
|
||||
<span className={styles.itemLabel}>{item.label}</span>
|
||||
</div>
|
||||
))}
|
||||
</div>
|
||||
<Handle
|
||||
type="target"
|
||||
position={Position.Left}
|
||||
style={{ background: '#10b981', border: '2px solid #10b981' }}
|
||||
/>
|
||||
</div>
|
||||
)
|
||||
};
|
||||
|
||||
return (
|
||||
<div style={{ height: '450px', width: '100%', position: 'relative' }}>
|
||||
<ReactFlow
|
||||
nodes={nodes}
|
||||
edges={edges}
|
||||
onNodesChange={onNodesChange}
|
||||
onEdgesChange={onEdgesChange}
|
||||
nodeTypes={nodeTypes}
|
||||
fitView={false}
|
||||
nodesDraggable={false}
|
||||
nodesConnectable={false}
|
||||
elementsSelectable={false}
|
||||
panOnDrag={false}
|
||||
panOnScroll={false}
|
||||
zoomOnScroll={false}
|
||||
zoomOnPinch={false}
|
||||
zoomOnDoubleClick={false}
|
||||
preventScrolling={false}
|
||||
proOptions={{ hideAttribution: true }}
|
||||
style={{ background: 'transparent' }}
|
||||
minZoom={1}
|
||||
maxZoom={1}
|
||||
defaultViewport={{ x: 0, y: 0, zoom: 1 }}
|
||||
translateExtent={[
|
||||
[0, 0],
|
||||
[1000, 550],
|
||||
]}
|
||||
/>
|
||||
</div>
|
||||
);
|
||||
};
|
||||
|
||||
function HomepageHeader() {
|
||||
const {siteConfig} = useDocusaurusContext();
|
||||
return (
|
||||
<header className={clsx('hero hero--primary', styles.heroBanner)}>
|
||||
<div className="container">
|
||||
<div className={styles.heroContent}>
|
||||
<h1 className="hero__title">{siteConfig.title}</h1>
|
||||
<p className="hero__subtitle">Supercharge your AI development workflow. Plug Cursor, Windsurf, or any AI IDE into Archon to unlock instant access to your business knowledge, technical docs, project requirements, and development tasks.</p>
|
||||
<div className={styles.buttons}>
|
||||
<Link
|
||||
className="button button--green-neon button--lg"
|
||||
to="/getting-started">
|
||||
Get Started - Quick Setup ⚡
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</header>
|
||||
);
|
||||
}
|
||||
|
||||
function HomepageContent() {
|
||||
const [lucideIcons, setLucideIcons] = useState(null);
|
||||
const [isClient, setIsClient] = useState(false);
|
||||
|
||||
useEffect(() => {
|
||||
setIsClient(true);
|
||||
|
||||
// Dynamically import Lucide React only on client side
|
||||
const loadLucideIcons = async () => {
|
||||
try {
|
||||
const { Database, Zap, Globe, FileText, CheckSquare, Plug } = await import('lucide-react');
|
||||
setLucideIcons({ Database, Zap, Globe, FileText, CheckSquare, Plug });
|
||||
} catch (error) {
|
||||
console.error('Error loading Lucide icons:', error);
|
||||
}
|
||||
};
|
||||
|
||||
loadLucideIcons();
|
||||
}, []);
|
||||
|
||||
if (!isClient || !lucideIcons) {
|
||||
return (
|
||||
<main>
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<h2 className="text--center margin-bottom--xl">✨ Key Features</h2>
|
||||
<div className="row">
|
||||
<div className="col col--12">
|
||||
<div style={{ display: 'flex', justifyContent: 'center', alignItems: 'center', height: '200px', color: '#ffffff' }}>
|
||||
Loading Features...
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
const { Database, Zap, Globe, FileText, CheckSquare, Plug } = lucideIcons;
|
||||
|
||||
const features = [
|
||||
{
|
||||
title: 'Knowledge Management',
|
||||
icon: Database,
|
||||
description: 'Intelligently crawl documentation sites, upload PDFs and documents, and organize knowledge by type (technical vs business). Advanced source filtering enables precise RAG queries across your entire knowledge base.'
|
||||
},
|
||||
{
|
||||
title: 'Advanced RAG Capabilities',
|
||||
icon: Zap,
|
||||
description: 'Smart URL detection, contextual embeddings, hybrid search, and reranking deliver superior search results. Special handling for code snippets and technical documentation with AI-powered content understanding.'
|
||||
},
|
||||
{
|
||||
title: 'MCP Integration',
|
||||
icon: Plug,
|
||||
description: 'Universal compatibility with Cursor, Windsurf, Claude Desktop, and any MCP client. Dual transport support (SSE/stdio) with real-time access to your knowledge base directly from your AI coding assistants.'
|
||||
},
|
||||
{
|
||||
title: 'Document Processing',
|
||||
icon: FileText,
|
||||
description: 'Dual-engine PDF extraction, Word document support, markdown processing, and smart chunking. AI-generated metadata and automatic code example extraction for comprehensive document understanding.'
|
||||
},
|
||||
{
|
||||
title: 'Web Interface',
|
||||
icon: Globe,
|
||||
description: 'Complete web dashboard for MCP server management, document upload, crawling operations, and interactive knowledge chat. Real-time log streaming and progress tracking for all operations.'
|
||||
},
|
||||
{
|
||||
title: 'Task Management',
|
||||
icon: CheckSquare,
|
||||
description: 'Integrated project and task management with AI agent integration. Create, track, and organize development tasks with automatic linking to relevant documentation and code examples.'
|
||||
}
|
||||
];
|
||||
|
||||
return (
|
||||
<main>
|
||||
<section className={styles.features}>
|
||||
<div className="container">
|
||||
<h2 className="text--center margin-bottom--xl">✨ Key Features</h2>
|
||||
|
||||
{/* First Row - 3 cards */}
|
||||
<div className="row">
|
||||
{features.slice(0, 3).map((feature, idx) => {
|
||||
const IconComponent = feature.icon;
|
||||
return (
|
||||
<div key={idx} className="col col--4">
|
||||
<div className={styles.glassContainer}>
|
||||
<div className={styles.featureHeader}>
|
||||
<IconComponent
|
||||
size={36}
|
||||
className={styles.featureIcon}
|
||||
/>
|
||||
<h3>{feature.title}</h3>
|
||||
</div>
|
||||
<p className={styles.featureDescription}>{feature.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
|
||||
{/* Second Row - 3 cards */}
|
||||
<div className={`row ${styles.featureRowSpacing}`}>
|
||||
{features.slice(3, 6).map((feature, idx) => {
|
||||
const IconComponent = feature.icon;
|
||||
return (
|
||||
<div key={idx + 3} className="col col--4">
|
||||
<div className={styles.glassContainer}>
|
||||
<div className={styles.featureHeader}>
|
||||
<IconComponent
|
||||
size={36}
|
||||
className={styles.featureIcon}
|
||||
/>
|
||||
<h3>{feature.title}</h3>
|
||||
</div>
|
||||
<p className={styles.featureDescription}>{feature.description}</p>
|
||||
</div>
|
||||
</div>
|
||||
);
|
||||
})}
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className={styles.quickStart}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--8 col--offset-2">
|
||||
<h2>🚀 Quick Start</h2>
|
||||
<p>Ready to get started? Follow our comprehensive setup guide:</p>
|
||||
<div className="text--center">
|
||||
<Link
|
||||
className="button button--green-neon button--lg"
|
||||
to="/getting-started">
|
||||
👉 Getting Started Guide - Complete setup from installation to first knowledge base
|
||||
</Link>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className={styles.nextSteps}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--8 col--offset-2">
|
||||
<h2>🎯 Next Steps</h2>
|
||||
<ol>
|
||||
<li><strong><Link to="/getting-started">Set up Archon</Link></strong> - Get your knowledge engine running</li>
|
||||
<li><strong><Link to="/mcp-overview">Connect your AI client</Link></strong> - Integrate with Cursor, Windsurf, or Claude Desktop</li>
|
||||
<li><strong><Link to="/getting-started#building-your-knowledge-base">Build your knowledge base</Link></strong> - Start crawling and uploading content</li>
|
||||
<li><strong><Link to="/rag">Optimize for your use case</Link></strong> - Configure RAG strategies</li>
|
||||
<li><strong><Link to="/deployment">Deploy to production</Link></strong> - Scale for team or enterprise use</li>
|
||||
</ol>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
|
||||
<section className={styles.callToAction}>
|
||||
<div className="container">
|
||||
<div className="row">
|
||||
<div className="col col--8 col--offset-2 text--center">
|
||||
<hr />
|
||||
<p><strong>Archon</strong> - <em>Supercharging AI IDE's with knowledge and tasks</em></p>
|
||||
</div>
|
||||
</div>
|
||||
</div>
|
||||
</section>
|
||||
</main>
|
||||
);
|
||||
}
|
||||
|
||||
export default function Home() {
|
||||
const {siteConfig} = useDocusaurusContext();
|
||||
|
||||
return (
|
||||
<Layout
|
||||
title={`Hello from ${siteConfig.title}`}
|
||||
description="Description will go into a meta tag in <head />">
|
||||
<HomepageHeader />
|
||||
<main>
|
||||
{/* Architecture Diagram */}
|
||||
<section className={styles.architectureSection}>
|
||||
<ArchitectureDiagram />
|
||||
</section>
|
||||
|
||||
<HomepageContent />
|
||||
</main>
|
||||
</Layout>
|
||||
);
|
||||
}
|
||||
948
docs/src/pages/index.module.css
Normal file
@@ -0,0 +1,948 @@
|
||||
/**
|
||||
* CSS files with the .module.css suffix will be treated as CSS modules
|
||||
* and scoped locally.
|
||||
*/
|
||||
|
||||
.heroBanner {
|
||||
padding: 6rem 0;
|
||||
text-align: center;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.heroBanner::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
left: -25%;
|
||||
top: 50%;
|
||||
transform: translateY(-50%);
|
||||
width: 55%;
|
||||
height: 95%;
|
||||
background-image: url('/img/logo-neon.svg');
|
||||
background-size: contain;
|
||||
background-repeat: no-repeat;
|
||||
background-position: center right;
|
||||
opacity: 0.2;
|
||||
z-index: 0;
|
||||
filter:
|
||||
blur(1px)
|
||||
drop-shadow(0 0 30px rgba(168, 85, 247, 0.8))
|
||||
drop-shadow(0 0 60px rgba(59, 130, 246, 0.6))
|
||||
drop-shadow(0 0 90px rgba(236, 72, 153, 0.4))
|
||||
drop-shadow(0 0 120px rgba(16, 185, 129, 0.3));
|
||||
animation: logoGlow 4s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes logoGlow {
|
||||
0% {
|
||||
opacity: 0.15;
|
||||
filter:
|
||||
blur(1px)
|
||||
drop-shadow(0 0 20px rgba(168, 85, 247, 0.6))
|
||||
drop-shadow(0 0 40px rgba(59, 130, 246, 0.4))
|
||||
drop-shadow(0 0 60px rgba(236, 72, 153, 0.3))
|
||||
drop-shadow(0 0 80px rgba(16, 185, 129, 0.2));
|
||||
}
|
||||
100% {
|
||||
opacity: 0.25;
|
||||
filter:
|
||||
blur(0.5px)
|
||||
drop-shadow(0 0 40px rgba(168, 85, 247, 1.0))
|
||||
drop-shadow(0 0 80px rgba(59, 130, 246, 0.8))
|
||||
drop-shadow(0 0 120px rgba(236, 72, 153, 0.6))
|
||||
drop-shadow(0 0 160px rgba(16, 185, 129, 0.4));
|
||||
}
|
||||
}
|
||||
|
||||
@media screen and (max-width: 966px) {
|
||||
.heroBanner {
|
||||
padding: 2rem;
|
||||
}
|
||||
}
|
||||
|
||||
.buttons {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-top: 2rem;
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
}
|
||||
|
||||
.heroBanner .container {
|
||||
position: relative;
|
||||
z-index: 2;
|
||||
display: flex;
|
||||
justify-content: center;
|
||||
align-items: center;
|
||||
min-height: 100%;
|
||||
}
|
||||
|
||||
.heroContent {
|
||||
max-width: 60%;
|
||||
text-align: left;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
/* Architecture Diagram Section */
|
||||
.architectureSection {
|
||||
padding: 20px 0 10px 0;
|
||||
background: transparent;
|
||||
}
|
||||
|
||||
.architectureSection::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
bottom: 0;
|
||||
background:
|
||||
linear-gradient(90deg, transparent 0%, rgba(139, 92, 246, 0.03) 50%, transparent 100%),
|
||||
linear-gradient(0deg, transparent 0%, rgba(16, 185, 129, 0.02) 50%, transparent 100%);
|
||||
pointer-events: none;
|
||||
z-index: -1;
|
||||
}
|
||||
|
||||
/* Node Styles */
|
||||
|
||||
/* Section Labels */
|
||||
.sectionLabel {
|
||||
color: #ffffff;
|
||||
font-size: 18px;
|
||||
font-weight: 700;
|
||||
text-shadow: 0 0 10px rgba(139, 92, 246, 0.5);
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
padding: 8px 16px;
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(10px);
|
||||
border: 1px solid rgba(139, 92, 246, 0.3);
|
||||
}
|
||||
|
||||
.features {
|
||||
padding: 2rem 0 1rem 0;
|
||||
}
|
||||
|
||||
.featureRowSpacing {
|
||||
margin-top: 2rem !important;
|
||||
}
|
||||
|
||||
.features .row {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.features .row:last-child {
|
||||
margin-bottom: 0 !important;
|
||||
}
|
||||
|
||||
.features .col {
|
||||
margin-bottom: 0 !important;
|
||||
padding: 0 0.5rem;
|
||||
}
|
||||
|
||||
.glassContainer {
|
||||
height: 100%;
|
||||
padding: 1.2rem;
|
||||
border-radius: 16px;
|
||||
transition: all 0.3s ease;
|
||||
position: relative;
|
||||
backdrop-filter: blur(20px);
|
||||
-webkit-backdrop-filter: blur(20px);
|
||||
background: rgba(0, 0, 0, 0.6);
|
||||
border: 1px solid rgba(168, 85, 247, 0.3);
|
||||
box-shadow: 0 15px 35px -10px rgba(0, 0, 0, 0.8);
|
||||
margin-bottom: 0 !important;
|
||||
overflow: hidden; /* Ensures glows stay within border-radius */
|
||||
}
|
||||
|
||||
.glassContainer::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 3px;
|
||||
background: linear-gradient(90deg, #a855f7, #3b82f6, #ec4899, #10b981);
|
||||
box-shadow:
|
||||
0 0 20px 4px rgba(168, 85, 247, 0.4),
|
||||
inset 0 0 20px 2px rgba(168, 85, 247, 0.2);
|
||||
border-radius: 16px 16px 0 0;
|
||||
}
|
||||
|
||||
.glassContainer::after {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: 0;
|
||||
right: 0;
|
||||
height: 100px;
|
||||
background: linear-gradient(to bottom, rgba(168, 85, 247, 0.2), rgba(168, 85, 247, 0.05));
|
||||
border-radius: 16px 16px 0 0;
|
||||
pointer-events: none;
|
||||
z-index: 0;
|
||||
}
|
||||
|
||||
.glassContainer > * {
|
||||
position: relative;
|
||||
z-index: 1;
|
||||
}
|
||||
|
||||
.glassContainer:hover {
|
||||
transform: translateY(-8px);
|
||||
box-shadow:
|
||||
0 30px 70px rgba(168, 85, 247, 0.3),
|
||||
0 0 40px rgba(168, 85, 247, 0.2);
|
||||
border-color: rgba(168, 85, 247, 0.5);
|
||||
}
|
||||
|
||||
.glassContainer h3 {
|
||||
color: #ffffff;
|
||||
text-shadow: 0 0 15px rgba(168, 85, 247, 0.7);
|
||||
font-size: 1.15rem;
|
||||
font-weight: 700;
|
||||
margin: 0;
|
||||
line-height: 1.3;
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
flex: 1;
|
||||
}
|
||||
|
||||
.glassContainer p {
|
||||
color: #f8fafc;
|
||||
line-height: 1.6;
|
||||
font-size: 0.95rem;
|
||||
z-index: 10;
|
||||
position: relative;
|
||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
|
||||
}
|
||||
|
||||
.featureHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.75rem;
|
||||
margin-bottom: 1rem;
|
||||
}
|
||||
|
||||
.featureIcon {
|
||||
color: #a855f7;
|
||||
filter: drop-shadow(0 0 10px rgba(168, 85, 247, 0.6));
|
||||
transition: all 0.3s ease;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.featureDescription {
|
||||
color: #9ca3af !important;
|
||||
line-height: 1.6;
|
||||
font-size: 0.95rem;
|
||||
text-align: left;
|
||||
text-shadow: 0 1px 3px rgba(0, 0, 0, 0.8);
|
||||
margin: 0;
|
||||
}
|
||||
|
||||
.glassContainer:hover .featureIcon {
|
||||
color: #c084fc;
|
||||
filter: drop-shadow(0 0 20px rgba(168, 85, 247, 0.8));
|
||||
transform: scale(1.1);
|
||||
}
|
||||
|
||||
.quickStart {
|
||||
padding: 4rem 0;
|
||||
background: rgba(0, 0, 0, 0.2);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.nextSteps {
|
||||
padding: 4rem 0;
|
||||
}
|
||||
|
||||
.callToAction {
|
||||
padding: 4rem 0;
|
||||
background: rgba(0, 0, 0, 0.3);
|
||||
backdrop-filter: blur(5px);
|
||||
}
|
||||
|
||||
.diagramContainer {
|
||||
margin: 2rem 0;
|
||||
padding: 2rem;
|
||||
background: rgba(0, 0, 0, 0.4);
|
||||
border-radius: 16px;
|
||||
border: 1px solid rgba(168, 85, 247, 0.2);
|
||||
backdrop-filter: blur(10px);
|
||||
overflow-x: auto;
|
||||
}
|
||||
|
||||
.archonDiagram {
|
||||
padding: 2rem 0 1rem 0;
|
||||
}
|
||||
|
||||
/* App Icon Styling */
|
||||
.appIcon {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.appIcon:hover {
|
||||
transform: translateY(-8px);
|
||||
}
|
||||
|
||||
.iconBox {
|
||||
width: 80px;
|
||||
height: 80px;
|
||||
border-radius: 20px;
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin-bottom: 0.75rem;
|
||||
border: 2px solid rgba(255, 255, 255, 0.3);
|
||||
box-shadow:
|
||||
0 10px 30px rgba(0, 0, 0, 0.5),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
transition: all 0.3s ease;
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
.iconBox:hover {
|
||||
transform: scale(1.1);
|
||||
box-shadow:
|
||||
0 20px 50px rgba(168, 85, 247, 0.4),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.cursorIcon, .windsurfIcon, .vscodeIcon {
|
||||
font-size: 2.5rem;
|
||||
filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.8));
|
||||
}
|
||||
|
||||
.claudeIcon, .archonLogo {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.8));
|
||||
}
|
||||
|
||||
.ideIcon {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
filter: drop-shadow(0 0 10px rgba(255, 255, 255, 0.8));
|
||||
}
|
||||
|
||||
.appName {
|
||||
color: #ffffff;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
text-shadow: 0 0 10px rgba(255, 255, 255, 0.5);
|
||||
}
|
||||
|
||||
/* Neon Connector Lines */
|
||||
.neonConnector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
margin: 2rem 0;
|
||||
gap: 1rem;
|
||||
}
|
||||
|
||||
.connectionLine {
|
||||
flex: 1;
|
||||
height: 2px;
|
||||
background: linear-gradient(90deg, transparent 0%, #a855f7 20%, #3b82f6 50%, #ec4899 80%, transparent 100%);
|
||||
box-shadow: 0 0 10px rgba(168, 85, 247, 0.8);
|
||||
animation: neonPulse 2s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
.connectionText {
|
||||
color: #a855f7;
|
||||
font-weight: 600;
|
||||
font-size: 0.9rem;
|
||||
text-shadow: 0 0 10px rgba(168, 85, 247, 0.8);
|
||||
background: rgba(0, 0, 0, 0.8);
|
||||
padding: 0.5rem 1rem;
|
||||
border-radius: 20px;
|
||||
border: 1px solid rgba(168, 85, 247, 0.5);
|
||||
backdrop-filter: blur(10px);
|
||||
}
|
||||
|
||||
@keyframes neonPulse {
|
||||
0% { opacity: 0.7; box-shadow: 0 0 5px rgba(168, 85, 247, 0.5); }
|
||||
100% { opacity: 1; box-shadow: 0 0 20px rgba(168, 85, 247, 1); }
|
||||
}
|
||||
|
||||
/* Horizontal Connector for three-column layout */
|
||||
.horizontalConnector {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
gap: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.connectionArrow {
|
||||
font-size: 2rem;
|
||||
color: #a855f7;
|
||||
text-shadow: 0 0 15px rgba(168, 85, 247, 0.8);
|
||||
animation: arrowPulse 2s ease-in-out infinite alternate;
|
||||
}
|
||||
|
||||
@keyframes arrowPulse {
|
||||
0% {
|
||||
color: #a855f7;
|
||||
text-shadow: 0 0 10px rgba(168, 85, 247, 0.6);
|
||||
transform: scale(1);
|
||||
}
|
||||
100% {
|
||||
color: #c084fc;
|
||||
text-shadow: 0 0 20px rgba(168, 85, 247, 1);
|
||||
transform: scale(1.1);
|
||||
}
|
||||
}
|
||||
|
||||
/* IDE Node Styling */
|
||||
.ideNode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
background: rgba(31, 41, 55, 0.8);
|
||||
border: 1px solid rgba(139, 92, 246, 0.5);
|
||||
border-radius: 12px;
|
||||
backdrop-filter: blur(8px);
|
||||
box-shadow: 0 0 20px rgba(139, 92, 246, 0.3);
|
||||
min-width: 100px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.ideNode:hover {
|
||||
border-color: rgba(139, 92, 246, 0.8);
|
||||
box-shadow: 0 0 30px rgba(139, 92, 246, 0.5);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.nodeIcon {
|
||||
width: 32px;
|
||||
height: 32px;
|
||||
margin-bottom: 6px;
|
||||
border-radius: 6px;
|
||||
}
|
||||
|
||||
/* Make cursor logo white */
|
||||
.ideNode img[alt="Cursor"] {
|
||||
filter: invert(1) brightness(1.2);
|
||||
}
|
||||
|
||||
.nodeIconSvg {
|
||||
margin-bottom: 6px;
|
||||
}
|
||||
|
||||
.nodeLabel {
|
||||
color: #ffffff;
|
||||
font-size: 12px;
|
||||
font-weight: 600;
|
||||
text-align: center;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* Archon Node Styling */
|
||||
.archonNode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 30px 25px;
|
||||
background: linear-gradient(135deg, rgba(139, 92, 246, 0.2), rgba(168, 85, 247, 0.2));
|
||||
border: 2px solid rgba(139, 92, 246, 0.6);
|
||||
border-radius: 20px;
|
||||
backdrop-filter: blur(12px);
|
||||
box-shadow: 0 0 40px rgba(139, 92, 246, 0.4);
|
||||
min-width: 200px;
|
||||
min-height: 140px;
|
||||
position: relative;
|
||||
overflow: hidden;
|
||||
}
|
||||
|
||||
.archonNode::before {
|
||||
content: '';
|
||||
position: absolute;
|
||||
top: 0;
|
||||
left: -100%;
|
||||
width: 100%;
|
||||
height: 100%;
|
||||
background: linear-gradient(90deg, transparent, rgba(255, 255, 255, 0.1), transparent);
|
||||
animation: shimmer 3s infinite;
|
||||
}
|
||||
|
||||
@keyframes shimmer {
|
||||
0% { left: -100%; }
|
||||
100% { left: 100%; }
|
||||
}
|
||||
|
||||
.archonIcon {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
margin-bottom: 12px;
|
||||
}
|
||||
|
||||
.archonText h3 {
|
||||
color: #ffffff;
|
||||
font-size: 22px;
|
||||
font-weight: 700;
|
||||
margin: 0 0 6px 0;
|
||||
text-shadow: 0 0 10px rgba(139, 92, 246, 0.5);
|
||||
}
|
||||
|
||||
.archonText p {
|
||||
color: #9ca3af;
|
||||
font-size: 0.9rem;
|
||||
margin: 0;
|
||||
text-shadow: 0 0 10px rgba(139, 92, 246, 0.5);
|
||||
}
|
||||
|
||||
.pythonIcon {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
z-index: 10;
|
||||
filter: drop-shadow(0 0 8px rgba(255, 212, 59, 0.8));
|
||||
}
|
||||
|
||||
/* Knowledge Node Styling */
|
||||
.knowledgeNode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
background: rgba(16, 185, 129, 0.1);
|
||||
border: 1px solid rgba(16, 185, 129, 0.5);
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(8px);
|
||||
box-shadow: 0 0 15px rgba(16, 185, 129, 0.2);
|
||||
min-width: 120px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.knowledgeNode:hover {
|
||||
border-color: rgba(16, 185, 129, 0.8);
|
||||
box-shadow: 0 0 25px rgba(16, 185, 129, 0.4);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.knowledgeNode .nodeIconSvg {
|
||||
color: #10b981;
|
||||
}
|
||||
|
||||
.intelligenceNode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 12px;
|
||||
background: rgba(245, 158, 11, 0.1);
|
||||
border: 1px solid rgba(245, 158, 11, 0.5);
|
||||
border-radius: 8px;
|
||||
backdrop-filter: blur(8px);
|
||||
box-shadow: 0 0 15px rgba(245, 158, 11, 0.2);
|
||||
min-width: 120px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.intelligenceNode:hover {
|
||||
border-color: rgba(245, 158, 11, 0.8);
|
||||
box-shadow: 0 0 25px rgba(245, 158, 11, 0.4);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.intelligenceNode .nodeIconSvg {
|
||||
color: #f59e0b;
|
||||
}
|
||||
|
||||
.knowledgeHeader {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
margin-bottom: 1rem;
|
||||
gap: 0.75rem;
|
||||
}
|
||||
|
||||
.knowledgeIcon {
|
||||
font-size: 2rem;
|
||||
filter: drop-shadow(0 0 10px rgba(59, 130, 246, 0.6));
|
||||
}
|
||||
|
||||
.knowledgeNode h4 {
|
||||
margin: 0;
|
||||
color: #ffffff;
|
||||
font-size: 1.2rem;
|
||||
font-weight: 600;
|
||||
text-shadow: 0 1px 2px rgba(0, 0, 0, 0.3);
|
||||
}
|
||||
|
||||
.knowledgeFeatures {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 0.5rem;
|
||||
}
|
||||
|
||||
.featureItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 0.5rem;
|
||||
padding: 0.5rem;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border-radius: 8px;
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
font-size: 0.85rem;
|
||||
color: #d1d5db;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.featureItem:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-color: rgba(59, 130, 246, 0.3);
|
||||
color: #ffffff;
|
||||
}
|
||||
|
||||
.featureIcon {
|
||||
font-size: 1rem;
|
||||
filter: drop-shadow(0 0 5px rgba(59, 130, 246, 0.4));
|
||||
}
|
||||
|
||||
/* React Flow Edge Styling - SOLID GLOWING LINES */
|
||||
:global(.react-flow__edge-path) {
|
||||
stroke-width: 3 !important;
|
||||
filter: drop-shadow(0 0 10px currentColor) !important;
|
||||
stroke-dasharray: none !important;
|
||||
animation: solidGlow 2s ease-in-out infinite alternate !important;
|
||||
}
|
||||
|
||||
:global(.react-flow__edge) {
|
||||
pointer-events: none !important;
|
||||
}
|
||||
|
||||
@keyframes solidGlow {
|
||||
0% {
|
||||
filter: drop-shadow(0 0 8px currentColor);
|
||||
}
|
||||
100% {
|
||||
filter: drop-shadow(0 0 20px currentColor);
|
||||
}
|
||||
}
|
||||
|
||||
/* Responsive design */
|
||||
@media (max-width: 768px) {
|
||||
.flowContainer {
|
||||
height: 500px;
|
||||
}
|
||||
|
||||
.ideNode, .knowledgeNode {
|
||||
min-width: 100px;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.archonNode {
|
||||
min-width: 150px;
|
||||
padding: 1.5rem;
|
||||
}
|
||||
|
||||
.knowledgeFeatures {
|
||||
grid-template-columns: 1fr;
|
||||
}
|
||||
}
|
||||
|
||||
@media (max-width: 480px) {
|
||||
.heroBanner {
|
||||
padding: 3rem 0;
|
||||
}
|
||||
|
||||
.heroBanner::before {
|
||||
left: -20%;
|
||||
width: 60%;
|
||||
height: 70%;
|
||||
opacity: 0.08;
|
||||
}
|
||||
|
||||
.glassContainer {
|
||||
padding: 1rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.glassContainer h3 {
|
||||
font-size: 1rem;
|
||||
}
|
||||
|
||||
.glassContainer p {
|
||||
font-size: 0.85rem;
|
||||
}
|
||||
|
||||
.featureIcon {
|
||||
width: 36px;
|
||||
height: 36px;
|
||||
}
|
||||
|
||||
.heroContent {
|
||||
max-width: 90%;
|
||||
text-align: center;
|
||||
margin: 0 auto;
|
||||
}
|
||||
|
||||
.architectureSection, .quickStart, .nextSteps, .callToAction {
|
||||
padding: 2.5rem 0;
|
||||
}
|
||||
|
||||
.diagramContainer {
|
||||
padding: 1rem;
|
||||
margin: 1rem 0;
|
||||
}
|
||||
|
||||
.iconBox {
|
||||
width: 50px;
|
||||
height: 50px;
|
||||
border-radius: 12px;
|
||||
}
|
||||
|
||||
.cursorIcon, .windsurfIcon, .vscodeIcon {
|
||||
font-size: 1.5rem;
|
||||
}
|
||||
|
||||
.claudeIcon, .archonLogo {
|
||||
width: 25px;
|
||||
height: 25px;
|
||||
}
|
||||
|
||||
.systemBox {
|
||||
padding: 1rem;
|
||||
}
|
||||
|
||||
.systemBox h4 {
|
||||
font-size: 1.2rem;
|
||||
}
|
||||
|
||||
.archonCore {
|
||||
padding: 1rem;
|
||||
max-width: 200px;
|
||||
}
|
||||
|
||||
.archonCore h3 {
|
||||
font-size: 1.4rem;
|
||||
}
|
||||
|
||||
.archonIconBox {
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
}
|
||||
|
||||
.powerFeature {
|
||||
padding: 1.25rem;
|
||||
margin-bottom: 1.25rem;
|
||||
}
|
||||
|
||||
.powerFeature h3 {
|
||||
font-size: 1.1rem;
|
||||
}
|
||||
|
||||
.powerFeature p {
|
||||
font-size: 0.9rem;
|
||||
}
|
||||
}
|
||||
|
||||
/* Container Node Styling */
|
||||
.containerNode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
padding: 16px;
|
||||
background: rgba(31, 41, 55, 0.8);
|
||||
border: 1px solid rgba(139, 92, 246, 0.5);
|
||||
border-radius: 12px;
|
||||
backdrop-filter: blur(8px);
|
||||
box-shadow: 0 0 20px rgba(139, 92, 246, 0.3);
|
||||
min-width: 200px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.containerNode:hover {
|
||||
border-color: rgba(139, 92, 246, 0.8);
|
||||
box-shadow: 0 0 30px rgba(139, 92, 246, 0.5);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
/* Knowledge Sources - Green */
|
||||
.containerNode[data-type="knowledge"] {
|
||||
border-color: rgba(16, 185, 129, 0.6);
|
||||
box-shadow: 0 0 25px rgba(16, 185, 129, 0.3);
|
||||
}
|
||||
|
||||
.containerNode[data-type="knowledge"]:hover {
|
||||
border-color: rgba(16, 185, 129, 0.9);
|
||||
box-shadow: 0 0 40px rgba(16, 185, 129, 0.5);
|
||||
}
|
||||
|
||||
.containerNode[data-type="knowledge"] .containerTitle {
|
||||
text-shadow: 0 0 10px rgba(16, 185, 129, 0.6);
|
||||
}
|
||||
|
||||
/* Project Intelligence - Orange */
|
||||
.containerNode[data-type="intelligence"] {
|
||||
border-color: rgba(245, 158, 11, 0.6);
|
||||
box-shadow: 0 0 25px rgba(245, 158, 11, 0.3);
|
||||
}
|
||||
|
||||
.containerNode[data-type="intelligence"]:hover {
|
||||
border-color: rgba(245, 158, 11, 0.9);
|
||||
box-shadow: 0 0 40px rgba(245, 158, 11, 0.5);
|
||||
}
|
||||
|
||||
.containerNode[data-type="intelligence"] .containerTitle {
|
||||
text-shadow: 0 0 10px rgba(245, 158, 11, 0.6);
|
||||
}
|
||||
|
||||
.containerTitle {
|
||||
color: #ffffff;
|
||||
font-size: 16px;
|
||||
font-weight: 700;
|
||||
margin: 0 0 12px 0;
|
||||
text-align: center;
|
||||
text-shadow: 0 0 10px rgba(139, 92, 246, 0.5);
|
||||
}
|
||||
|
||||
.containerGrid {
|
||||
display: grid;
|
||||
grid-template-columns: 1fr 1fr;
|
||||
gap: 8px;
|
||||
}
|
||||
|
||||
.containerItem {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
gap: 6px;
|
||||
padding: 8px;
|
||||
background: rgba(255, 255, 255, 0.05);
|
||||
border: 1px solid rgba(255, 255, 255, 0.1);
|
||||
border-radius: 6px;
|
||||
transition: all 0.2s ease;
|
||||
}
|
||||
|
||||
.containerItem:hover {
|
||||
background: rgba(255, 255, 255, 0.1);
|
||||
border-color: rgba(139, 92, 246, 0.3);
|
||||
}
|
||||
|
||||
.itemIcon {
|
||||
color: #8b5cf6;
|
||||
flex-shrink: 0;
|
||||
}
|
||||
|
||||
.itemLabel {
|
||||
color: #ffffff;
|
||||
font-size: 11px;
|
||||
font-weight: 500;
|
||||
line-height: 1.2;
|
||||
}
|
||||
|
||||
/* UI Control Node Styling */
|
||||
.uiControlNode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
padding: 20px;
|
||||
background: rgba(31, 41, 55, 0.9);
|
||||
border: 1px solid rgba(59, 130, 246, 0.6);
|
||||
border-radius: 12px;
|
||||
backdrop-filter: blur(8px);
|
||||
box-shadow: 0 0 25px rgba(59, 130, 246, 0.3);
|
||||
min-width: 180px;
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.uiControlNode:hover {
|
||||
border-color: rgba(59, 130, 246, 0.8);
|
||||
box-shadow: 0 0 35px rgba(59, 130, 246, 0.5);
|
||||
transform: translateY(-2px);
|
||||
}
|
||||
|
||||
.uiControlTitle {
|
||||
color: #ffffff;
|
||||
font-size: 1.3rem;
|
||||
font-weight: 700;
|
||||
margin: 0 0 0.5rem 0;
|
||||
text-shadow: 0 0 15px rgba(59, 130, 246, 0.7);
|
||||
text-align: center;
|
||||
}
|
||||
|
||||
.reactIcon {
|
||||
position: absolute;
|
||||
top: 8px;
|
||||
left: 8px;
|
||||
width: 24px;
|
||||
height: 24px;
|
||||
z-index: 10;
|
||||
filter: drop-shadow(0 0 8px rgba(97, 218, 251, 0.8));
|
||||
}
|
||||
|
||||
.uiControlSubtitle {
|
||||
color: rgba(255, 255, 255, 0.8);
|
||||
font-size: 13px;
|
||||
margin: 0;
|
||||
text-align: center;
|
||||
line-height: 1.3;
|
||||
}
|
||||
|
||||
.mcpNode {
|
||||
display: flex;
|
||||
flex-direction: column;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(139, 92, 246, 0.2);
|
||||
border: 2px solid #8b5cf6;
|
||||
border-radius: 50%;
|
||||
width: 60px;
|
||||
height: 60px;
|
||||
box-shadow:
|
||||
0 0 20px rgba(139, 92, 246, 0.6),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
backdrop-filter: blur(10px);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.mcpNode:hover {
|
||||
transform: scale(1.1);
|
||||
box-shadow:
|
||||
0 0 30px rgba(139, 92, 246, 0.8),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.mcpIcon {
|
||||
width: 40px;
|
||||
height: 40px;
|
||||
filter: brightness(0) invert(1) drop-shadow(0 0 10px rgba(255, 255, 255, 0.8));
|
||||
}
|
||||
|
||||
.fastapiNode {
|
||||
display: flex;
|
||||
align-items: center;
|
||||
justify-content: center;
|
||||
background: rgba(0, 150, 136, 0.2);
|
||||
border: 2px solid #009688;
|
||||
border-radius: 12px;
|
||||
padding: 8px 12px;
|
||||
min-width: 120px;
|
||||
height: 40px;
|
||||
box-shadow:
|
||||
0 0 20px rgba(0, 150, 136, 0.4),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.2);
|
||||
backdrop-filter: blur(10px);
|
||||
transition: all 0.3s ease;
|
||||
}
|
||||
|
||||
.fastapiNode:hover {
|
||||
transform: scale(1.05);
|
||||
box-shadow:
|
||||
0 0 30px rgba(0, 150, 136, 0.6),
|
||||
inset 0 1px 0 rgba(255, 255, 255, 0.3);
|
||||
}
|
||||
|
||||
.fastapiIcon {
|
||||
height: 24px;
|
||||
width: auto;
|
||||
filter: brightness(0) invert(1) drop-shadow(0 0 8px rgba(255, 255, 255, 0.6));
|
||||
}
|
||||
|
||||
|
||||
|
||||
7
docs/src/pages/markdown-page.md
Normal file
@@ -0,0 +1,7 @@
|
||||
---
|
||||
title: Markdown page example
|
||||
---
|
||||
|
||||
# Markdown page example
|
||||
|
||||
You don't need React to write simple standalone pages.
|
||||
0
docs/static/.nojekyll
vendored
Normal file
265
docs/static/img/Python-logo-notext.svg
vendored
Normal file
@@ -0,0 +1,265 @@
|
||||
<?xml version="1.0" encoding="UTF-8" standalone="no"?>
|
||||
<!-- Created with Inkscape (http://www.inkscape.org/) -->
|
||||
|
||||
<svg
|
||||
version="1.0"
|
||||
id="svg2"
|
||||
sodipodi:version="0.32"
|
||||
inkscape:version="1.2.1 (9c6d41e410, 2022-07-14)"
|
||||
sodipodi:docname="python-logo-only.svg"
|
||||
width="92.070236pt"
|
||||
height="101.00108pt"
|
||||
inkscape:export-filename="python-logo-only.png"
|
||||
inkscape:export-xdpi="232.44"
|
||||
inkscape:export-ydpi="232.44"
|
||||
xmlns:inkscape="http://www.inkscape.org/namespaces/inkscape"
|
||||
xmlns:sodipodi="http://sodipodi.sourceforge.net/DTD/sodipodi-0.dtd"
|
||||
xmlns:xlink="http://www.w3.org/1999/xlink"
|
||||
xmlns="http://www.w3.org/2000/svg"
|
||||
xmlns:svg="http://www.w3.org/2000/svg"
|
||||
xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"
|
||||
xmlns:cc="http://creativecommons.org/ns#"
|
||||
xmlns:dc="http://purl.org/dc/elements/1.1/">
|
||||
<metadata
|
||||
id="metadata371">
|
||||
<rdf:RDF>
|
||||
<cc:Work
|
||||
rdf:about="">
|
||||
<dc:format>image/svg+xml</dc:format>
|
||||
<dc:type
|
||||
rdf:resource="http://purl.org/dc/dcmitype/StillImage" />
|
||||
</cc:Work>
|
||||
</rdf:RDF>
|
||||
</metadata>
|
||||
<sodipodi:namedview
|
||||
inkscape:window-height="2080"
|
||||
inkscape:window-width="1976"
|
||||
inkscape:pageshadow="2"
|
||||
inkscape:pageopacity="0.0"
|
||||
guidetolerance="10.0"
|
||||
gridtolerance="10.0"
|
||||
objecttolerance="10.0"
|
||||
borderopacity="1.0"
|
||||
bordercolor="#666666"
|
||||
pagecolor="#ffffff"
|
||||
id="base"
|
||||
inkscape:zoom="2.1461642"
|
||||
inkscape:cx="91.558698"
|
||||
inkscape:cy="47.9926"
|
||||
inkscape:window-x="1092"
|
||||
inkscape:window-y="72"
|
||||
inkscape:current-layer="svg2"
|
||||
width="210mm"
|
||||
height="40mm"
|
||||
units="mm"
|
||||
inkscape:showpageshadow="2"
|
||||
inkscape:pagecheckerboard="0"
|
||||
inkscape:deskcolor="#d1d1d1"
|
||||
inkscape:document-units="pt"
|
||||
showgrid="false"
|
||||
inkscape:window-maximized="0" />
|
||||
<defs
|
||||
id="defs4">
|
||||
<linearGradient
|
||||
id="linearGradient2795">
|
||||
<stop
|
||||
style="stop-color:#b8b8b8;stop-opacity:0.49803922;"
|
||||
offset="0"
|
||||
id="stop2797" />
|
||||
<stop
|
||||
style="stop-color:#7f7f7f;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop2799" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient2787">
|
||||
<stop
|
||||
style="stop-color:#7f7f7f;stop-opacity:0.5;"
|
||||
offset="0"
|
||||
id="stop2789" />
|
||||
<stop
|
||||
style="stop-color:#7f7f7f;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop2791" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3676">
|
||||
<stop
|
||||
style="stop-color:#b2b2b2;stop-opacity:0.5;"
|
||||
offset="0"
|
||||
id="stop3678" />
|
||||
<stop
|
||||
style="stop-color:#b3b3b3;stop-opacity:0;"
|
||||
offset="1"
|
||||
id="stop3680" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient3236">
|
||||
<stop
|
||||
style="stop-color:#f4f4f4;stop-opacity:1"
|
||||
offset="0"
|
||||
id="stop3244" />
|
||||
<stop
|
||||
style="stop-color:white;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop3240" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4671">
|
||||
<stop
|
||||
style="stop-color:#ffd43b;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4673" />
|
||||
<stop
|
||||
style="stop-color:#ffe873;stop-opacity:1"
|
||||
offset="1"
|
||||
id="stop4675" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
id="linearGradient4689">
|
||||
<stop
|
||||
style="stop-color:#5a9fd4;stop-opacity:1;"
|
||||
offset="0"
|
||||
id="stop4691" />
|
||||
<stop
|
||||
style="stop-color:#306998;stop-opacity:1;"
|
||||
offset="1"
|
||||
id="stop4693" />
|
||||
</linearGradient>
|
||||
<linearGradient
|
||||
x1="224.23996"
|
||||
y1="144.75717"
|
||||
x2="-65.308502"
|
||||
y2="144.75717"
|
||||
id="linearGradient2987"
|
||||
xlink:href="#linearGradient4671"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(100.2702,99.61116)" />
|
||||
<linearGradient
|
||||
x1="172.94208"
|
||||
y1="77.475983"
|
||||
x2="26.670298"
|
||||
y2="76.313133"
|
||||
id="linearGradient2990"
|
||||
xlink:href="#linearGradient4689"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(100.2702,99.61116)" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4689"
|
||||
id="linearGradient2587"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(100.2702,99.61116)"
|
||||
x1="172.94208"
|
||||
y1="77.475983"
|
||||
x2="26.670298"
|
||||
y2="76.313133" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4671"
|
||||
id="linearGradient2589"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(100.2702,99.61116)"
|
||||
x1="224.23996"
|
||||
y1="144.75717"
|
||||
x2="-65.308502"
|
||||
y2="144.75717" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4689"
|
||||
id="linearGradient2248"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(100.2702,99.61116)"
|
||||
x1="172.94208"
|
||||
y1="77.475983"
|
||||
x2="26.670298"
|
||||
y2="76.313133" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4671"
|
||||
id="linearGradient2250"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="translate(100.2702,99.61116)"
|
||||
x1="224.23996"
|
||||
y1="144.75717"
|
||||
x2="-65.308502"
|
||||
y2="144.75717" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4671"
|
||||
id="linearGradient2255"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.562541,0,0,0.567972,-11.5974,-7.60954)"
|
||||
x1="224.23996"
|
||||
y1="144.75717"
|
||||
x2="-65.308502"
|
||||
y2="144.75717" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4689"
|
||||
id="linearGradient2258"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.562541,0,0,0.567972,-11.5974,-7.60954)"
|
||||
x1="172.94208"
|
||||
y1="76.176224"
|
||||
x2="26.670298"
|
||||
y2="76.313133" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2795"
|
||||
id="radialGradient2801"
|
||||
cx="61.518883"
|
||||
cy="132.28575"
|
||||
fx="61.518883"
|
||||
fy="132.28575"
|
||||
r="29.036913"
|
||||
gradientTransform="matrix(1,0,0,0.177966,0,108.7434)"
|
||||
gradientUnits="userSpaceOnUse" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4671"
|
||||
id="linearGradient1475"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.562541,0,0,0.567972,-14.99112,-11.702371)"
|
||||
x1="150.96111"
|
||||
y1="192.35176"
|
||||
x2="112.03144"
|
||||
y2="137.27299" />
|
||||
<linearGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient4689"
|
||||
id="linearGradient1478"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(0.562541,0,0,0.567972,-14.99112,-11.702371)"
|
||||
x1="26.648937"
|
||||
y1="20.603781"
|
||||
x2="135.66525"
|
||||
y2="114.39767" />
|
||||
<radialGradient
|
||||
inkscape:collect="always"
|
||||
xlink:href="#linearGradient2795"
|
||||
id="radialGradient1480"
|
||||
gradientUnits="userSpaceOnUse"
|
||||
gradientTransform="matrix(1.7490565e-8,-0.23994696,1.054668,3.7915457e-7,-83.7008,142.46201)"
|
||||
cx="61.518883"
|
||||
cy="132.28575"
|
||||
fx="61.518883"
|
||||
fy="132.28575"
|
||||
r="29.036913" />
|
||||
</defs>
|
||||
<path
|
||||
style="fill:url(#linearGradient1478);fill-opacity:1"
|
||||
d="M 54.918785,9.1927389e-4 C 50.335132,0.02221727 45.957846,0.41313697 42.106285,1.0946693 30.760069,3.0991731 28.700036,7.2947714 28.700035,15.032169 v 10.21875 h 26.8125 v 3.40625 h -26.8125 -10.0625 c -7.792459,0 -14.6157588,4.683717 -16.7499998,13.59375 -2.46181998,10.212966 -2.57101508,16.586023 0,27.25 1.9059283,7.937852 6.4575432,13.593748 14.2499998,13.59375 h 9.21875 v -12.25 c 0,-8.849902 7.657144,-16.656248 16.75,-16.65625 h 26.78125 c 7.454951,0 13.406253,-6.138164 13.40625,-13.625 v -25.53125 c 0,-7.2663386 -6.12998,-12.7247771 -13.40625,-13.9374997 C 64.281548,0.32794397 59.502438,-0.02037903 54.918785,9.1927389e-4 Z m -14.5,8.21875012611 c 2.769547,0 5.03125,2.2986456 5.03125,5.1249996 -2e-6,2.816336 -2.261703,5.09375 -5.03125,5.09375 -2.779476,-1e-6 -5.03125,-2.277415 -5.03125,-5.09375 -10e-7,-2.826353 2.251774,-5.1249996 5.03125,-5.1249996 z"
|
||||
id="path1948" />
|
||||
<path
|
||||
style="fill:url(#linearGradient1475);fill-opacity:1"
|
||||
d="m 85.637535,28.657169 v 11.90625 c 0,9.230755 -7.825895,16.999999 -16.75,17 h -26.78125 c -7.335833,0 -13.406249,6.278483 -13.40625,13.625 v 25.531247 c 0,7.266344 6.318588,11.540324 13.40625,13.625004 8.487331,2.49561 16.626237,2.94663 26.78125,0 6.750155,-1.95439 13.406253,-5.88761 13.40625,-13.625004 V 86.500919 h -26.78125 v -3.40625 h 26.78125 13.406254 c 7.792461,0 10.696251,-5.435408 13.406241,-13.59375 2.79933,-8.398886 2.68022,-16.475776 0,-27.25 -1.92578,-7.757441 -5.60387,-13.59375 -13.406241,-13.59375 z m -15.0625,64.65625 c 2.779478,3e-6 5.03125,2.277417 5.03125,5.093747 -2e-6,2.826354 -2.251775,5.125004 -5.03125,5.125004 -2.76955,0 -5.03125,-2.29865 -5.03125,-5.125004 2e-6,-2.81633 2.261697,-5.093747 5.03125,-5.093747 z"
|
||||
id="path1950" />
|
||||
<ellipse
|
||||
style="opacity:0.44382;fill:url(#radialGradient1480);fill-opacity:1;fill-rule:nonzero;stroke:none;stroke-width:15.4174;stroke-miterlimit:4;stroke-dasharray:none;stroke-opacity:1"
|
||||
id="path1894"
|
||||
cx="55.816761"
|
||||
cy="127.70079"
|
||||
rx="35.930977"
|
||||
ry="6.9673119" />
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 9.4 KiB |
9
docs/static/img/React-icon.svg
vendored
Normal file
@@ -0,0 +1,9 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" viewBox="-11.5 -10.23174 23 20.46348">
|
||||
<title>React Logo</title>
|
||||
<circle cx="0" cy="0" r="2.05" fill="#61dafb"/>
|
||||
<g stroke="#61dafb" stroke-width="1" fill="none">
|
||||
<ellipse rx="11" ry="4.2"/>
|
||||
<ellipse rx="11" ry="4.2" transform="rotate(60)"/>
|
||||
<ellipse rx="11" ry="4.2" transform="rotate(120)"/>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 366 B |
41
docs/static/img/Visual_Studio_Code_1.35_icon.svg
vendored
Normal file
@@ -0,0 +1,41 @@
|
||||
<svg viewBox="0 0 100 100" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<mask id="mask0" mask-type="alpha" maskUnits="userSpaceOnUse" x="0" y="0" width="100" height="100">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.9119 99.3171C72.4869 99.9307 74.2828 99.8914 75.8725 99.1264L96.4608 89.2197C98.6242 88.1787 100 85.9892 100 83.5872V16.4133C100 14.0113 98.6243 11.8218 96.4609 10.7808L75.8725 0.873756C73.7862 -0.130129 71.3446 0.11576 69.5135 1.44695C69.252 1.63711 69.0028 1.84943 68.769 2.08341L29.3551 38.0415L12.1872 25.0096C10.589 23.7965 8.35363 23.8959 6.86933 25.2461L1.36303 30.2549C-0.452552 31.9064 -0.454633 34.7627 1.35853 36.417L16.2471 50.0001L1.35853 63.5832C-0.454633 65.2374 -0.452552 68.0938 1.36303 69.7453L6.86933 74.7541C8.35363 76.1043 10.589 76.2037 12.1872 74.9905L29.3551 61.9587L68.769 97.9167C69.3925 98.5406 70.1246 99.0104 70.9119 99.3171ZM75.0152 27.2989L45.1091 50.0001L75.0152 72.7012V27.2989Z" fill="white"/>
|
||||
</mask>
|
||||
<g mask="url(#mask0)">
|
||||
<path d="M96.4614 10.7962L75.8569 0.875542C73.4719 -0.272773 70.6217 0.211611 68.75 2.08333L1.29858 63.5832C-0.515693 65.2373 -0.513607 68.0937 1.30308 69.7452L6.81272 74.754C8.29793 76.1042 10.5347 76.2036 12.1338 74.9905L93.3609 13.3699C96.086 11.3026 100 13.2462 100 16.6667V16.4275C100 14.0265 98.6246 11.8378 96.4614 10.7962Z" fill="#0065A9"/>
|
||||
<g filter="url(#filter0_d)">
|
||||
<path d="M96.4614 89.2038L75.8569 99.1245C73.4719 100.273 70.6217 99.7884 68.75 97.9167L1.29858 36.4169C-0.515693 34.7627 -0.513607 31.9063 1.30308 30.2548L6.81272 25.246C8.29793 23.8958 10.5347 23.7964 12.1338 25.0095L93.3609 86.6301C96.086 88.6974 100 86.7538 100 83.3334V83.5726C100 85.9735 98.6246 88.1622 96.4614 89.2038Z" fill="#007ACC"/>
|
||||
</g>
|
||||
<g filter="url(#filter1_d)">
|
||||
<path d="M75.8578 99.1263C73.4721 100.274 70.6219 99.7885 68.75 97.9166C71.0564 100.223 75 98.5895 75 95.3278V4.67213C75 1.41039 71.0564 -0.223106 68.75 2.08329C70.6219 0.211402 73.4721 -0.273666 75.8578 0.873633L96.4587 10.7807C98.6234 11.8217 100 14.0112 100 16.4132V83.5871C100 85.9891 98.6234 88.1786 96.4586 89.2196L75.8578 99.1263Z" fill="#1F9CF0"/>
|
||||
</g>
|
||||
<g style="mix-blend-mode:overlay" opacity="0.25">
|
||||
<path fill-rule="evenodd" clip-rule="evenodd" d="M70.8511 99.3171C72.4261 99.9306 74.2221 99.8913 75.8117 99.1264L96.4 89.2197C98.5634 88.1787 99.9392 85.9892 99.9392 83.5871V16.4133C99.9392 14.0112 98.5635 11.8217 96.4001 10.7807L75.8117 0.873695C73.7255 -0.13019 71.2838 0.115699 69.4527 1.44688C69.1912 1.63705 68.942 1.84937 68.7082 2.08335L29.2943 38.0414L12.1264 25.0096C10.5283 23.7964 8.29285 23.8959 6.80855 25.246L1.30225 30.2548C-0.513334 31.9064 -0.515415 34.7627 1.29775 36.4169L16.1863 50L1.29775 63.5832C-0.515415 65.2374 -0.513334 68.0937 1.30225 69.7452L6.80855 74.754C8.29285 76.1042 10.5283 76.2036 12.1264 74.9905L29.2943 61.9586L68.7082 97.9167C69.3317 98.5405 70.0638 99.0104 70.8511 99.3171ZM74.9544 27.2989L45.0483 50L74.9544 72.7012V27.2989Z" fill="url(#paint0_linear)"/>
|
||||
</g>
|
||||
</g>
|
||||
<defs>
|
||||
<filter id="filter0_d" x="-8.39411" y="15.8291" width="116.727" height="92.2456" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="4.16667"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="overlay" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<filter id="filter1_d" x="60.4167" y="-8.07558" width="47.9167" height="116.151" filterUnits="userSpaceOnUse" color-interpolation-filters="sRGB">
|
||||
<feFlood flood-opacity="0" result="BackgroundImageFix"/>
|
||||
<feColorMatrix in="SourceAlpha" type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 127 0"/>
|
||||
<feOffset/>
|
||||
<feGaussianBlur stdDeviation="4.16667"/>
|
||||
<feColorMatrix type="matrix" values="0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0 0.25 0"/>
|
||||
<feBlend mode="overlay" in2="BackgroundImageFix" result="effect1_dropShadow"/>
|
||||
<feBlend mode="normal" in="SourceGraphic" in2="effect1_dropShadow" result="shape"/>
|
||||
</filter>
|
||||
<linearGradient id="paint0_linear" x1="49.9392" y1="0.257812" x2="49.9392" y2="99.7423" gradientUnits="userSpaceOnUse">
|
||||
<stop stop-color="white"/>
|
||||
<stop offset="1" stop-color="white" stop-opacity="0"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 4.3 KiB |
1
docs/static/img/claude-logo.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg xmlns="http://www.w3.org/2000/svg" shape-rendering="geometricPrecision" text-rendering="geometricPrecision" image-rendering="optimizeQuality" fill-rule="evenodd" clip-rule="evenodd" viewBox="0 0 512 509.64"><path fill="#D77655" d="M115.612 0h280.775C459.974 0 512 52.026 512 115.612v278.415c0 63.587-52.026 115.612-115.613 115.612H115.612C52.026 509.639 0 457.614 0 394.027V115.612C0 52.026 52.026 0 115.612 0z"/><path fill="#FCF2EE" fill-rule="nonzero" d="M142.27 316.619l73.655-41.326 1.238-3.589-1.238-1.996-3.589-.001-12.31-.759-42.084-1.138-36.498-1.516-35.361-1.896-8.897-1.895-8.34-10.995.859-5.484 7.482-5.03 10.717.935 23.683 1.617 35.537 2.452 25.782 1.517 38.193 3.968h6.064l.86-2.451-2.073-1.517-1.618-1.517-36.776-24.922-39.81-26.338-20.852-15.166-11.273-7.683-5.687-7.204-2.451-15.721 10.237-11.273 13.75.935 3.513.936 13.928 10.716 29.749 23.027 38.848 28.612 5.687 4.727 2.275-1.617.278-1.138-2.553-4.271-21.13-38.193-22.546-38.848-10.035-16.101-2.654-9.655c-.935-3.968-1.617-7.304-1.617-11.374l11.652-15.823 6.445-2.073 15.545 2.073 6.547 5.687 9.655 22.092 15.646 34.78 24.265 47.291 7.103 14.028 3.791 12.992 1.416 3.968 2.449-.001v-2.275l1.997-26.641 3.69-32.707 3.589-42.084 1.239-11.854 5.863-14.206 11.652-7.683 9.099 4.348 7.482 10.716-1.036 6.926-4.449 28.915-8.72 45.294-5.687 30.331h3.313l3.792-3.791 15.342-20.372 25.782-32.227 11.374-12.789 13.27-14.129 8.517-6.724 16.1-.001 11.854 17.617-5.307 18.199-16.581 21.029-13.75 17.819-19.716 26.54-12.309 21.231 1.138 1.694 2.932-.278 44.536-9.479 24.062-4.347 28.714-4.928 12.992 6.066 1.416 6.167-5.106 12.613-30.71 7.583-36.018 7.204-53.636 12.689-.657.48.758.935 24.164 2.275 10.337.556h25.301l47.114 3.514 12.309 8.139 7.381 9.959-1.238 7.583-18.957 9.655-25.579-6.066-59.702-14.205-20.474-5.106-2.83-.001v1.694l17.061 16.682 31.266 28.233 39.152 36.397 1.997 8.999-5.03 7.102-5.307-.758-34.401-25.883-13.27-11.651-30.053-25.302-1.996-.001v2.654l6.926 10.136 36.574 54.975 1.895 16.859-2.653 5.485-9.479 3.311-10.414-1.895-21.408-30.054-22.092-33.844-17.819-30.331-2.173 1.238-10.515 113.261-4.929 5.788-11.374 4.348-9.478-7.204-5.03-11.652 5.03-23.027 6.066-30.052 4.928-23.886 4.449-29.674 2.654-9.858-.177-.657-2.173.278-22.37 30.71-34.021 45.977-26.919 28.815-6.445 2.553-11.173-5.789 1.037-10.337 6.243-9.2 37.257-47.392 22.47-29.371 14.508-16.961-.101-2.451h-.859l-98.954 64.251-17.618 2.275-7.583-7.103.936-11.652 3.589-3.791 29.749-20.474-.101.102.024.101z"/></svg>
|
||||
|
After Width: | Height: | Size: 2.4 KiB |
1
docs/static/img/cursor.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>Cursor</title><path d="M11.925 24l10.425-6-10.425-6L1.5 18l10.425 6z" fill="url(#lobe-icons-cursorundefined-fill-0)"></path><path d="M22.35 18V6L11.925 0v12l10.425 6z" fill="url(#lobe-icons-cursorundefined-fill-1)"></path><path d="M11.925 0L1.5 6v12l10.425-6V0z" fill="url(#lobe-icons-cursorundefined-fill-2)"></path><path d="M22.35 6L11.925 24V12L22.35 6z" fill="#555"></path><path d="M22.35 6l-10.425 6L1.5 6h20.85z" fill="#000"></path><defs><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-0" x1="11.925" x2="11.925" y1="12" y2="24"><stop offset=".16" stop-color="#000" stop-opacity=".39"></stop><stop offset=".658" stop-color="#000" stop-opacity=".8"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-1" x1="22.35" x2="11.925" y1="6.037" y2="12.15"><stop offset=".182" stop-color="#000" stop-opacity=".31"></stop><stop offset=".715" stop-color="#000" stop-opacity="0"></stop></linearGradient><linearGradient gradientUnits="userSpaceOnUse" id="lobe-icons-cursorundefined-fill-2" x1="11.925" x2="1.5" y1="0" y2="18"><stop stop-color="#000" stop-opacity=".6"></stop><stop offset=".667" stop-color="#000" stop-opacity=".22"></stop></linearGradient></defs></svg>
|
||||
|
After Width: | Height: | Size: 1.3 KiB |
BIN
docs/static/img/docusaurus.png
vendored
Normal file
|
After Width: | Height: | Size: 5.0 KiB |
8
docs/static/img/fastapi-seeklogo.svg
vendored
Normal file
|
After Width: | Height: | Size: 9.6 KiB |
BIN
docs/static/img/favicon.ico
vendored
Normal file
|
After Width: | Height: | Size: 3.5 KiB |
32
docs/static/img/favicon.svg
vendored
Normal file
@@ -0,0 +1,32 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 62 62" width="32" height="32">
|
||||
<defs>
|
||||
<style>
|
||||
.neon-path {
|
||||
fill: none;
|
||||
stroke: url(#neon-gradient);
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 2.5px;
|
||||
filter: drop-shadow(0 0 3px #00d38a);
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="neon-gradient" x1=".53" y1="31.13" x2="61.72" y2="31.13" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#00d38a"/>
|
||||
<stop offset=".08" stop-color="#0fcaa6"/>
|
||||
<stop offset=".25" stop-color="#36b5ef"/>
|
||||
<stop offset=".28" stop-color="#3fb1ff"/>
|
||||
<stop offset=".39" stop-color="#fe6aff"/>
|
||||
<stop offset=".42" stop-color="#d964ff"/>
|
||||
<stop offset=".48" stop-color="#ab5dff"/>
|
||||
<stop offset=".53" stop-color="#8a59ff"/>
|
||||
<stop offset=".57" stop-color="#7656ff"/>
|
||||
<stop offset=".6" stop-color="#6f55ff"/>
|
||||
<stop offset=".67" stop-color="#9a3df8"/>
|
||||
<stop offset=".75" stop-color="#c624f2"/>
|
||||
<stop offset=".81" stop-color="#e214ee"/>
|
||||
<stop offset=".85" stop-color="#ed0fed"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<path class="neon-path" d="M60.22,60.22s-2.71-4.5-6.53-11.26l-8.65-5.19h5.74c-7.01-12.65-15.94-29.93-19.66-41.75-1.71,5.18-3.72,10.25-6.05,15.18l4.78,6.33-6.88-1.87C13.95,40.44,2.03,60.22,2.03,60.22c6.84-4.68,14.39-8.24,22.37-10.52-.58-1.48-.87-3.06-.86-4.66,0-5.59,3.39-10.12,7.59-10.12s7.59,4.53,7.59,10.12c.01,1.59-.28,3.17-.86,4.66,7.97,2.29,15.52,5.84,22.37,10.52Z"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.6 KiB |
44
docs/static/img/logo-neon.svg
vendored
Normal file
@@ -0,0 +1,44 @@
|
||||
<?xml version="1.0" encoding="UTF-8"?>
|
||||
<svg id="Layer_1" xmlns="http://www.w3.org/2000/svg" xmlns:xlink="http://www.w3.org/1999/xlink" version="1.1" viewBox="0 0 62 62">
|
||||
<!-- Generator: Adobe Illustrator 29.5.1, SVG Export Plug-In . SVG Version: 2.1.0 Build 141) -->
|
||||
<defs>
|
||||
<style>
|
||||
.st0 {
|
||||
isolation: isolate;
|
||||
}
|
||||
|
||||
.st1 {
|
||||
fill: none;
|
||||
stroke: url(#linear-gradient);
|
||||
stroke-linecap: round;
|
||||
stroke-linejoin: round;
|
||||
stroke-width: 3px;
|
||||
}
|
||||
</style>
|
||||
<linearGradient id="linear-gradient" x1=".53" y1="31.13" x2="61.72" y2="31.13" gradientUnits="userSpaceOnUse">
|
||||
<stop offset="0" stop-color="#00d38a"/>
|
||||
<stop offset=".08" stop-color="#0fcaa6"/>
|
||||
<stop offset=".25" stop-color="#36b5ef"/>
|
||||
<stop offset=".28" stop-color="#3fb1ff"/>
|
||||
<stop offset=".39" stop-color="#fe6aff"/>
|
||||
<stop offset=".42" stop-color="#d964ff"/>
|
||||
<stop offset=".48" stop-color="#ab5dff"/>
|
||||
<stop offset=".53" stop-color="#8a59ff"/>
|
||||
<stop offset=".57" stop-color="#7656ff"/>
|
||||
<stop offset=".6" stop-color="#6f55ff"/>
|
||||
<stop offset=".67" stop-color="#9a3df8"/>
|
||||
<stop offset=".75" stop-color="#c624f2"/>
|
||||
<stop offset=".81" stop-color="#e214ee"/>
|
||||
<stop offset=".85" stop-color="#ed0fed"/>
|
||||
</linearGradient>
|
||||
</defs>
|
||||
<g id="items" class="st0">
|
||||
<g id="blend">
|
||||
<g id="g-root-ic_linu_18fp2amr8t1q9-stroke">
|
||||
<g id="ic_linu_18fp2amr8t1q9-stroke">
|
||||
<path class="st1" d="M60.22,60.22s-2.71-4.5-6.53-11.26l-8.65-5.19h5.74c-7.01-12.65-15.94-29.93-19.66-41.75-1.71,5.18-3.72,10.25-6.05,15.18l4.78,6.33-6.88-1.87C13.95,40.44,2.03,60.22,2.03,60.22c6.84-4.68,14.39-8.24,22.37-10.52-.58-1.48-.87-3.06-.86-4.66,0-5.59,3.39-10.12,7.59-10.12s7.59,4.53,7.59,10.12c.01,1.59-.28,3.17-.86,4.66,7.97,2.29,15.52,5.84,22.37,10.52Z"/>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</g>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.9 KiB |
1
docs/static/img/logo.svg
vendored
Normal file
|
After Width: | Height: | Size: 6.3 KiB |
1
docs/static/img/mcp.svg
vendored
Normal file
@@ -0,0 +1 @@
|
||||
<svg fill="currentColor" fill-rule="evenodd" height="1em" style="flex:none;line-height:1" viewBox="0 0 24 24" width="1em" xmlns="http://www.w3.org/2000/svg"><title>ModelContextProtocol</title><path d="M15.688 2.343a2.588 2.588 0 00-3.61 0l-9.626 9.44a.863.863 0 01-1.203 0 .823.823 0 010-1.18l9.626-9.44a4.313 4.313 0 016.016 0 4.116 4.116 0 011.204 3.54 4.3 4.3 0 013.609 1.18l.05.05a4.115 4.115 0 010 5.9l-8.706 8.537a.274.274 0 000 .393l1.788 1.754a.823.823 0 010 1.18.863.863 0 01-1.203 0l-1.788-1.753a1.92 1.92 0 010-2.754l8.706-8.538a2.47 2.47 0 000-3.54l-.05-.049a2.588 2.588 0 00-3.607-.003l-7.172 7.034-.002.002-.098.097a.863.863 0 01-1.204 0 .823.823 0 010-1.18l7.273-7.133a2.47 2.47 0 00-.003-3.537z"></path><path d="M14.485 4.703a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a4.115 4.115 0 000 5.9 4.314 4.314 0 006.016 0l7.12-6.982a.823.823 0 000-1.18.863.863 0 00-1.204 0l-7.119 6.982a2.588 2.588 0 01-3.61 0 2.47 2.47 0 010-3.54l7.12-6.982z"></path></svg>
|
||||
|
After Width: | Height: | Size: 978 B |
BIN
docs/static/img/tutorial/docsVersionDropdown.png
vendored
Normal file
|
After Width: | Height: | Size: 24 KiB |
BIN
docs/static/img/tutorial/localeDropdown.png
vendored
Normal file
|
After Width: | Height: | Size: 29 KiB |
3
docs/static/img/windsurf-white-symbol.svg
vendored
Normal file
@@ -0,0 +1,3 @@
|
||||
<svg width="1024" height="1024" viewBox="0 0 1024 1024" fill="none" xmlns="http://www.w3.org/2000/svg">
|
||||
<path d="M897.246 286.869H889.819C850.735 286.808 819.017 318.46 819.017 357.539V515.589C819.017 547.15 792.93 572.716 761.882 572.716C743.436 572.716 725.02 563.433 714.093 547.85L552.673 317.304C539.28 298.16 517.486 286.747 493.895 286.747C457.094 286.747 423.976 318.034 423.976 356.657V515.619C423.976 547.181 398.103 572.746 366.842 572.746C348.335 572.746 329.949 563.463 319.021 547.881L138.395 289.882C134.316 284.038 125.154 286.93 125.154 294.052V431.892C125.154 438.862 127.285 445.619 131.272 451.34L309.037 705.2C319.539 720.204 335.033 731.344 352.9 735.392C397.616 745.557 438.77 711.135 438.77 667.278V508.406C438.77 476.845 464.339 451.279 495.904 451.279H495.995C515.02 451.279 532.857 460.562 543.785 476.145L705.235 706.661C718.659 725.835 739.327 737.218 763.983 737.218C801.606 737.218 833.841 705.9 833.841 667.308V508.376C833.841 476.815 859.41 451.249 890.975 451.249H897.276C901.233 451.249 904.43 448.053 904.43 444.097V294.021C904.43 290.065 901.233 286.869 897.276 286.869H897.246Z" fill="white"/>
|
||||
</svg>
|
||||
|
After Width: | Height: | Size: 1.1 KiB |
155
docs/static/js/mermaid-rounded-corners.js
vendored
Normal file
@@ -0,0 +1,155 @@
|
||||
/**
|
||||
* Mermaid Rounded Corners Fallback
|
||||
*
|
||||
* This script ensures that Mermaid diagrams have rounded corners by:
|
||||
* 1. First trying to use CSS rx/ry properties (modern approach)
|
||||
* 2. Falling back to setting SVG attributes directly if CSS doesn't work
|
||||
* 3. Using MutationObserver to handle dynamically loaded diagrams
|
||||
*/
|
||||
|
||||
(function() {
|
||||
'use strict';
|
||||
|
||||
const CORNER_RADIUS = 8;
|
||||
|
||||
/**
|
||||
* Test if the browser supports CSS rx/ry properties on SVG elements
|
||||
*/
|
||||
function testCSSRxRySupport() {
|
||||
try {
|
||||
const testRect = document.createElementNS('http://www.w3.org/2000/svg', 'rect');
|
||||
testRect.style.rx = '10px';
|
||||
// If CSS rx works, the style property should be set
|
||||
return testRect.style.rx === '10px';
|
||||
} catch (e) {
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
/**
|
||||
* Apply rounded corners to SVG rectangles using attributes
|
||||
*/
|
||||
function applyRoundedCorners(container) {
|
||||
if (!container) return;
|
||||
|
||||
// Find all rect elements in the container
|
||||
const rects = container.querySelectorAll('rect');
|
||||
|
||||
rects.forEach(rect => {
|
||||
// Only apply if not already set or if set to 0
|
||||
const currentRx = rect.getAttribute('rx');
|
||||
const currentRy = rect.getAttribute('ry');
|
||||
|
||||
if (!currentRx || currentRx === '0' || parseInt(currentRx) < CORNER_RADIUS) {
|
||||
rect.setAttribute('rx', CORNER_RADIUS);
|
||||
}
|
||||
|
||||
if (!currentRy || currentRy === '0' || parseInt(currentRy) < CORNER_RADIUS) {
|
||||
rect.setAttribute('ry', CORNER_RADIUS);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Process all existing Mermaid diagrams
|
||||
*/
|
||||
function processExistingDiagrams() {
|
||||
const mermaidContainers = document.querySelectorAll('.mermaid');
|
||||
|
||||
mermaidContainers.forEach(container => {
|
||||
const svg = container.querySelector('svg');
|
||||
if (svg) {
|
||||
applyRoundedCorners(svg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
/**
|
||||
* Initialize the rounded corners functionality
|
||||
*/
|
||||
function initialize() {
|
||||
const supportsCSS = testCSSRxRySupport();
|
||||
|
||||
if (!supportsCSS) {
|
||||
console.log('CSS rx/ry not supported, using attribute fallback for Mermaid rounded corners');
|
||||
|
||||
// Add fallback class to body for CSS targeting
|
||||
document.body.classList.add('mermaid-rounded-fallback');
|
||||
} else {
|
||||
console.log('CSS rx/ry supported, but applying attribute fallback as additional insurance');
|
||||
}
|
||||
|
||||
// Always apply attribute-based rounded corners as insurance
|
||||
// This ensures compatibility across all browsers and Mermaid versions
|
||||
|
||||
// Process existing diagrams
|
||||
processExistingDiagrams();
|
||||
|
||||
// Watch for new diagrams being added dynamically
|
||||
const observer = new MutationObserver(mutations => {
|
||||
mutations.forEach(mutation => {
|
||||
mutation.addedNodes.forEach(node => {
|
||||
if (node.nodeType === Node.ELEMENT_NODE) {
|
||||
// Check if the added node is a Mermaid container
|
||||
if (node.classList && node.classList.contains('mermaid')) {
|
||||
const svg = node.querySelector('svg');
|
||||
if (svg) {
|
||||
applyRoundedCorners(svg);
|
||||
}
|
||||
}
|
||||
|
||||
// Check if the added node contains Mermaid containers
|
||||
const mermaidContainers = node.querySelectorAll && node.querySelectorAll('.mermaid');
|
||||
if (mermaidContainers) {
|
||||
mermaidContainers.forEach(container => {
|
||||
const svg = container.querySelector('svg');
|
||||
if (svg) {
|
||||
applyRoundedCorners(svg);
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
// Check if the added node is an SVG inside a Mermaid container
|
||||
if (node.tagName === 'svg' && node.closest('.mermaid')) {
|
||||
applyRoundedCorners(node);
|
||||
}
|
||||
}
|
||||
});
|
||||
});
|
||||
});
|
||||
|
||||
// Start observing
|
||||
observer.observe(document.body, {
|
||||
childList: true,
|
||||
subtree: true
|
||||
});
|
||||
|
||||
// Also re-process after Mermaid renders (if Mermaid is available)
|
||||
if (typeof window.mermaid !== 'undefined') {
|
||||
// Hook into Mermaid's callback if possible
|
||||
const originalInit = window.mermaid.init;
|
||||
if (originalInit) {
|
||||
window.mermaid.init = function(...args) {
|
||||
const result = originalInit.apply(this, args);
|
||||
// Small delay to ensure rendering is complete
|
||||
setTimeout(processExistingDiagrams, 100);
|
||||
return result;
|
||||
};
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// Initialize when DOM is ready
|
||||
if (document.readyState === 'loading') {
|
||||
document.addEventListener('DOMContentLoaded', initialize);
|
||||
} else {
|
||||
// DOM is already ready
|
||||
initialize();
|
||||
}
|
||||
|
||||
// Also initialize after window load as backup
|
||||
window.addEventListener('load', () => {
|
||||
setTimeout(processExistingDiagrams, 500);
|
||||
});
|
||||
|
||||
})();
|
||||