Skip to content
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion PERFORMANCE_ANALYSIS.md
Original file line number Diff line number Diff line change
Expand Up @@ -102,7 +102,7 @@ def load_prompts(self) -> None:
**Issue**: Tools are registered in loops without checking for duplicates efficiently.

```python
for skill in self.router.skills:
for skill in self.skills:
tool_manager.register_tool(skill.create_ticket_tool()) # ← Potential duplicate registrations
```

Expand Down
43 changes: 13 additions & 30 deletions docs/api/core.md
Original file line number Diff line number Diff line change
Expand Up @@ -165,19 +165,9 @@ class MemoryItem(BaseModel):
embedding: Optional[List[float]] = None
```

## Router System
## Skill and Service Management

### Router

Routes queries to appropriate skills and services based on content analysis.

```python
class Router:
def __init__(self):
"""Initialize router with empty skill and service registries."""
```

#### Methods
Skills and services are now managed directly by the MainAgent without a separate Router component.

##### `register_skill(skill: Skill, keywords: List[str]) -> None`

Expand Down Expand Up @@ -412,31 +402,24 @@ for result in results:
memory.flush()
```

### Router Usage
### MainAgent Skill Management

```python
from talos.core.router import Router
from talos.core.main_agent import MainAgent
from talos.skills.proposals import ProposalsSkill
from talos.skills.twitter_sentiment import TwitterSentimentSkill

# Create router
router = Router()
# Create main agent (skills are automatically registered)
agent = MainAgent(model=model, prompts_dir="prompts")

# Register skills
router.register_skill(
ProposalsSkill(),
keywords=["proposal", "governance", "vote"]
)
router.register_skill(
TwitterSentimentSkill(),
keywords=["sentiment", "twitter", "social"]
)
# Skills are managed directly by MainAgent
# Access skills through agent.skills list
for skill in agent.skills:
print(f"Available skill: {skill.name}")

# Route queries
handler = router.route("Analyze this governance proposal")
if handler:
result = handler.run(proposal_text="...")
print(result.answers[0])
# Use agent to process queries
result = agent.run("Analyze this governance proposal")
print(result)
```

## Error Handling
Expand Down
5 changes: 3 additions & 2 deletions docs/architecture/agents.md
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,8 @@ The `MainAgent` serves as the top-level orchestrator that integrates all system
```python
class MainAgent:
def __init__(self):
self.router = Router()
self.skills = []
self.services = []
self.hypervisor = Hypervisor()
self.tool_manager = ToolManager()
self.memory = Memory()
Expand All @@ -26,7 +27,7 @@ class MainAgent:

**Workflow:**
1. Receives user input
2. Routes query through Router to appropriate skill/service
2. Routes query directly to appropriate skill/service
3. Executes actions through SupervisedTool wrappers
4. Stores results in Memory for future reference
5. Returns structured response to user
Expand Down
2 changes: 1 addition & 1 deletion docs/architecture/components.md
Original file line number Diff line number Diff line change
Expand Up @@ -76,7 +76,7 @@ Talos uses a variety of tools to interact with external services like Twitter, G

The `MainAgent` serves as the top-level orchestrator that integrates all system components:

- **Router Integration** - Routes queries to appropriate skills/services
- **Direct Skill/Service Management** - Manages skills and services directly
- **Hypervisor Integration** - Ensures all actions are supervised
- **Tool Management** - Manages available tools and their registration
- **Memory System** - Persistent conversation history and semantic search
Expand Down
16 changes: 6 additions & 10 deletions docs/architecture/skills-services.md
Original file line number Diff line number Diff line change
Expand Up @@ -206,14 +206,14 @@ Handles GitHub operations and PR reviews:
4. **Test Coverage** - Ensure adequate test coverage
5. **Documentation** - Verify documentation updates

## Router System
## Skill and Service Management

### Query Routing
### Direct Management

The `Router` directs queries to appropriate skills and services:
The `MainAgent` directly manages skills and services without a separate Router:

```python
class Router:
class MainAgent:
def __init__(self):
self.skills = []
self.services = []
Expand All @@ -235,12 +235,8 @@ class Router:
Skills and services are dynamically registered:

```python
# Skill registration
router.register_skill(ProposalsSkill(), keywords=["proposal", "governance"])
router.register_skill(TwitterSentimentSkill(), keywords=["sentiment", "twitter"])

# Service registration
router.register_service(YieldManagerService(), keywords=["yield", "apr", "staking"])
# Skills and services are automatically registered during MainAgent initialization
# based on available API keys and configuration
```

## Integration Patterns
Expand Down
5 changes: 3 additions & 2 deletions docs/development/contributing.md
Original file line number Diff line number Diff line change
Expand Up @@ -287,9 +287,10 @@ When adding new skills to Talos:
pass
```

2. **Register with router**:
2. **Add to MainAgent setup**:
```python
router.register_skill(MyNewSkill(), keywords=["keyword1", "keyword2"])
# Skills are automatically registered in MainAgent._setup_skills_and_services()
# Add your skill to the skills list in that method
```

3. **Add comprehensive tests**
Expand Down
2 changes: 1 addition & 1 deletion docs/development/performance.md
Original file line number Diff line number Diff line change
Expand Up @@ -209,7 +209,7 @@ class FilePromptManager:
**Issue**: Tools are registered in loops without checking for duplicates efficiently.

```python
for skill in self.router.skills:
for skill in self.skills:
tool_manager.register_tool(skill.create_ticket_tool()) # ← Potential duplicate registrations
```

Expand Down
2 changes: 1 addition & 1 deletion docs/development/testing.md
Original file line number Diff line number Diff line change
Expand Up @@ -20,7 +20,7 @@ tests/
│ ├── core/
│ │ ├── test_agent.py
│ │ ├── test_memory.py
│ │ └── test_router.py
│ │ └── test_main_agent.py
│ ├── skills/
│ │ ├── test_proposals.py
│ │ ├── test_sentiment.py
Expand Down
3 changes: 0 additions & 3 deletions src/talos/cli/daemon.py
Original file line number Diff line number Diff line change
Expand Up @@ -10,7 +10,6 @@
from langchain_openai import ChatOpenAI

from talos.core.main_agent import MainAgent
from talos.core.router import Router
from talos.settings import OpenAISettings

logger = logging.getLogger(__name__)
Expand Down Expand Up @@ -53,12 +52,10 @@ def _initialize_agent(self) -> None:
logger.info("Initializing MainAgent...")

model = ChatOpenAI(model=self.model_name, temperature=self.temperature)
router = Router([], [])

self.main_agent = MainAgent(
prompts_dir=self.prompts_dir,
model=model,
router=router,
schema=None,
)

Expand Down
3 changes: 0 additions & 3 deletions src/talos/cli/main.py
Original file line number Diff line number Diff line change
Expand Up @@ -8,7 +8,6 @@
from langchain_openai import ChatOpenAI

from talos.core.main_agent import MainAgent
from talos.core.router import Router
from talos.services.key_management import KeyManagement
from talos.settings import OpenAISettings
from talos.cli.daemon import TalosDaemon
Expand Down Expand Up @@ -74,11 +73,9 @@ def main_command(

# Create the main agent
model = ChatOpenAI(model=model_name, temperature=temperature)
router = Router([], [])
main_agent = MainAgent(
prompts_dir=prompts_dir,
model=model,
router=router,
schema=None,
user_id=user_id,
use_database_memory=use_database,
Expand Down
30 changes: 16 additions & 14 deletions src/talos/core/main_agent.py
Original file line number Diff line number Diff line change
Expand Up @@ -9,7 +9,6 @@

from talos.core.agent import Agent
from talos.core.job_scheduler import JobScheduler
from talos.core.router import Router
from talos.core.scheduled_job import ScheduledJob
from talos.data.dataset_manager import DatasetManager
from talos.hypervisor.hypervisor import Hypervisor
Expand Down Expand Up @@ -37,7 +36,8 @@ class MainAgent(Agent):
Also manages scheduled jobs for autonomous execution.
"""

router: Optional[Router] = None
skills: list[Skill] = []
services: list[Service] = []
prompts_dir: str
model: BaseChatModel
is_main_agent: bool = True
Expand All @@ -51,7 +51,7 @@ def model_post_init(self, __context: Any) -> None:
self._setup_prompt_manager()
self._ensure_user_id()
self._setup_memory()
self._setup_router()
self._setup_skills_and_services()
self._setup_hypervisor()
self._setup_dataset_manager()
self._setup_tool_manager()
Expand Down Expand Up @@ -152,7 +152,7 @@ def _setup_memory(self) -> None:
verbose=self.verbose,
)

def _setup_router(self) -> None:
def _setup_skills_and_services(self) -> None:
if not self.prompt_manager:
raise ValueError("Prompt manager not initialized.")
services: list[Service] = []
Expand Down Expand Up @@ -198,8 +198,8 @@ def _setup_router(self) -> None:
except ValueError:
pass # Twitter token not available, skip Twitter-dependent skills

if not self.router:
self.router = Router(services=services, skills=skills)
self.skills = skills
self.services = services

def _setup_hypervisor(self) -> None:
if not self.prompt_manager:
Expand All @@ -226,9 +226,8 @@ def _setup_dataset_manager(self) -> None:
self.dataset_manager = DatasetManager(verbose=self.verbose)

def _setup_tool_manager(self) -> None:
assert self.router is not None
tool_manager = ToolManager()
for skill in self.router.skills:
for skill in self.skills:
tool_manager.register_tool(skill.create_ticket_tool())
tool_manager.register_tool(self._get_ticket_status_tool())
tool_manager.register_tool(self._add_memory_tool())
Expand Down Expand Up @@ -339,8 +338,11 @@ def get_ticket_status(service_name: str, ticket_id: str) -> Ticket:
Returns:
The ticket object.
"""
assert self.router is not None
skill = self.router.get_skill(service_name)
skill = None
for s in self.skills:
if s.name == service_name:
skill = s
break
if not skill:
raise ValueError(f"Skill '{service_name}' not found.")
ticket = skill.get_ticket_status(ticket_id)
Expand All @@ -351,16 +353,16 @@ def get_ticket_status(service_name: str, ticket_id: str) -> Ticket:
return get_ticket_status

def _build_context(self, query: str, **kwargs) -> dict:
assert self.router is not None

base_context = super()._build_context(query, **kwargs)

active_tickets = self.router.get_all_tickets()
active_tickets = []
for skill in self.skills:
active_tickets.extend(skill.get_all_tickets())
ticket_info = [f"- {ticket.ticket_id}: last updated at {ticket.updated_at}" for ticket in active_tickets]

main_agent_context = {
"time": datetime.now().isoformat(),
"available_services": ", ".join([service.name for service in self.router.services]),
"available_services": ", ".join([service.name for service in self.services]),
"active_tickets": " ".join(ticket_info),
}

Expand Down
83 changes: 0 additions & 83 deletions src/talos/core/router.py

This file was deleted.

Loading