Agent Factory is a powerful plugin for Cheshire Cat AI that introduces a flexible factory pattern for creating and managing custom agents. Build specialized agents with native LLM Function Calling support, advanced tool integration, and easy memory access.
- π§ Extensible Architecture: Create specialized agents for different use cases
- β‘ Native Function Calling: Built-in support for LLM Function Calling with multiple parameters
- π§ Memory Integration: Full access to Cheshire Cat's episodic and declarative memory
- π οΈ Tool Management: Advanced input handling for complex tools
- ποΈ Easy Management: Simple UI-based agent selection and configuration
Create custom agents by inheriting from BaseAgent or LangchainBaseAgent - build agents with advanced function calling capabilities and memory access.
Full support for LLM Function Calling with automatic tool binding. Define tools with any number of parameters:
@tool
def calculate_distance(lat1: float, lon1: float, lat2: float, lon2: float, cat) -> float:
"""Calculate distance between two coordinates.
Args:
lat1: Latitude of first point
lon1: Longitude of first point
lat2: Latitude of second point
lon2: Longitude of second point
"""
# Your calculation logic here
return distanceLangchainBaseAgent provides powerful methods to interact with Cheshire Cat's ecosystem:
- Memory Access: Query episodic and declarative memory
- Tool Execution: Execute any registered tool or form
- Chain Management: Advanced LLM interaction patterns
- Result Persistence: Automatic chat history management
- UI-based agent selection from the admin panel
- Hot-swappable agents without restarts
- Default fallback to standard Cheshire Cat behavior
- Open the Cheshire Cat admin panel
- Navigate to Plugins β Registry
- Search for "Agent Factory"
- Click Install and wait for completion
- The plugin will be automatically activated
Create a new Python file in your plugin (e.g., agents/echo_agent.py):
from cat.looking_glass.stray_cat import StrayCat
from cat.plugins.agent_factory import LangchainBaseAgent
from cat.plugins.agent_factory import AgentOutput
class EchoAgent(LangchainBaseAgent):
"""A simple agent that echoes user messages with a twist."""
def execute(self, cat: StrayCat) -> AgentOutput:
# Get the user's message from working memory
user_message = cat.working_memory.user_message_json
# Create a response with some personality
response = f"π Echo: {user_message.text}\n\nDid you know I'm powered by Agent Factory?"
return AgentOutput(output=response)In your plugin's main file or __init__.py, register the agent:
from typing import List, Tuple
from cat.mad_hatter.decorators import hook
from cat.plugins.agent_factory import BaseAgent
# Import your custom agent
from .agents.echo_agent import EchoAgent
@hook
def plugin_factory_allowed_agents(agents: List, cat) -> List[Tuple[BaseAgent, str, str]]:
"""Register custom agents with the factory."""
agents.append(
(EchoAgent, "ECHO_AGENT", "Echo Agent - Simple Message Repeater")
)
return agentsπ‘ Registration Tuple Format:
AgentClass: Your agent implementation"UNIQUE_ID": Unique identifier (uppercase recommended)"Display Name": Human-readable name for the UI
- Go to Plugins β Agent Factory in the admin panel
- Select your agent from the dropdown
- Save the configuration
- Start chatting with your new agent!
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
β Cheshire Cat AI β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Agent Factory Plugin β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββ β
β β BaseAgent β β LangchainBase β β Custom β β
β β β β Agent β β Agents β β
β βββββββββββββββββββ βββββββββββββββββββ βββββββββββββββ β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Function Calling β Memory Access β Tool Integration β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ€
β Cheshire Cat Core (Memory, Tools, Forms) β
βββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββββ
class AgentOutput(BaseModelDict):
output: str | None = None # The agent's response text
actions: List[LLMAction] = [] # List of actions performedclass LLMAction(BaseModel):
id: str | None = None # Unique action identifier given by the llm provider
name: str # Tool/action name
input: Dict # Parameters for the action
output: str | None = None # Action result output
return_direct: bool = False # Whether to return output directlyThe LangchainBaseAgent base class provides powerful utilities:
def run_chain(self,
cat: StrayCat,
system_prompt: str,
procedures: Dict[str, CatTool | CatForm] = {},
chat_history: List[CatMessage | HumanMessage] | None = None,
max_procedures_calls: int = 1,
execute_procedures: bool = True,
chain_name: str = "Langchain Chain") -> AgentOutput:
"""Run a LangChain chain with function calling capabilities."""
pass@staticmethod
def execute_procedure(procedure: CatTool | CatForm, input: str | Dict, cat: StrayCat, call_id: str | None = None) -> LLMAction:
"""Execute a tool or form procedure with the given input."""
pass
def execute_action(self, action: LLMAction, cat: StrayCat) -> LLMAction:
"""Execute an action and return the result."""
pass
def save_action(self, action: LLMAction, cat: StrayCat) -> None:
"""Save action results to chat history."""
passdef get_recalled_procedures_names(self, cat: StrayCat) -> Set[str]:
"""Get names of recalled tools/forms."""
pass
def get_recalled_episodic_memory(self, cat: StrayCat) -> List[Tuple[str, Dict]]:
"""Access recalled episodic memory as (text, metadata) tuples."""
pass
def get_recalled_declarative_memory(self, cat: StrayCat) -> List[Tuple[str, Dict]]:
"""Access recalled declarative memory as (text, metadata) tuples."""
pass
def get_recalled_procedures(self, cat: StrayCat) -> Dict[str, CatTool | CatForm]:
"""Get the recalled procedures from the MadHatter."""
pass
def get_procedures(self, procedures_name: List[str]) -> Dict[str, CatTool | CatForm]:
"""Get procedures by name from the MadHatter."""
pass
def handle_active_form(self, cat: StrayCat) -> AgentOutput | None:
"""Handle active forms in the working memory."""
passThe Agent Factory plugin provides several configuration options:
- Agent Selection: Choose which agent to use from the dropdown menu
- Stream Tool Calls: Enable/disable streaming of tool call execution messages to the chat
- Notify Tool Calls: Enable/disable notifications when tools are executed
The plugin automatically loads settings and manages agent switching without requiring restarts. If an invalid agent is selected, it automatically falls back to the default Cheshire Cat agent.
Problem: Your agent doesn't show up in the dropdown menu.
Solutions:
- Verify the
plugin_factory_allowed_agentshook is properly implemented - Check that your agent class inherits from
LangchainBaseAgent - Ensure there are no import errors in your agent file
- Restart the Cheshire Cat instance
Problem: Tools aren't being called by the agent.
Solutions:
- Verify tools are properly decorated with
@tool - Check tool function signatures include the
catparameter - Ensure tools are available in the current context
- Review LLM model supports function calling
Problem: Agent can't access recalled memories.
Solutions:
- Verify memory is populated (check admin panel)
- Ensure proper method calls (
get_recalled_episodic_memory, etc.) - Check memory retrieval settings in Cheshire Cat configuration
Problem: Forms are not being handled correctly by the agent.
Solutions:
- Ensure your agent calls
self.handle_active_form(cat)at the beginning of theexecutemethod - Check that forms are properly registered in Cheshire Cat
- Verify form state management in the working memory
This project is licensed under the GNU General Public License v3.0 - see the LICENSE file for details.