diff --git a/app/src/agents/README.md b/app/src/agents/README.md index e94eeca..a1e0717 100644 --- a/app/src/agents/README.md +++ b/app/src/agents/README.md @@ -17,10 +17,10 @@ Each specialized agent inherits from `BaseAgent`, which defines the shared execu ### Agent-specific documentation -- [Chat Agent](docs/chat-agent.md) -- [CRM Agent](docs/crm-agent.md) -- [Finance Agent](docs/finance-agent.md) -- [Calendar Agent](docs/calendar-agent.md) +- [Chat Agent](docs/agents/chat-agent.md) +- [CRM Agent](docs/agents/crm-agent.md) +- [Finance Agent](docs/agents/finance-agent.md) +- [Calendar Agent](docs/agents/calendar-agent.md) ### LLM provider documentation diff --git a/app/src/agents/docs/agents/chat-agent.md b/app/src/agents/docs/agents/chat-agent.md index 1392da6..9712329 100644 --- a/app/src/agents/docs/agents/chat-agent.md +++ b/app/src/agents/docs/agents/chat-agent.md @@ -61,6 +61,6 @@ The `ChatAgent` is fully instrumented with **Logfire** for real-time tracing: * **Metadata**: Logs include `agent_name`, `sender`, `receiver`, and `message_length`. * **Error Handling**: Failed parsing or validation attempts are logged as exceptions with full raw response data for debugging. -## Example Interaction +## Example interaction ![Example interaction](../imgs/chat_agent_ex.png) \ No newline at end of file diff --git a/app/src/agents/docs/agents/crm-agent.md b/app/src/agents/docs/agents/crm-agent.md new file mode 100644 index 0000000..3451e4c --- /dev/null +++ b/app/src/agents/docs/agents/crm-agent.md @@ -0,0 +1,83 @@ +# CRMAgent + +The **CRMAgent** is the specialized component responsible for managing **Odoo CRM** leads and opportunities. It is engineered for surgical precision, eliminating the risk of incorrect data entry through a strict validation policy and a **Human-in-the-Loop (HITL)** workflow. + +## Overview + +The `CRMAgent` prepares complex administrative actions. Its primary function is to transform natural language into validated data structures for Odoo's CRM module, utilizing the **Model Context Protocol (MCP)** to interact with the backend safely. + +### Key responsibilities: +* **Lead management**: Prepares new records while validating mandatory business fields. +* **Pipeline vision**: Queries and filters opportunities and sales funnel stages. +* **Data integrity**: Active hallucination prevention (strictly forbidden from inventing names, revenue, or dates). +* **Multi-turn context**: Remembers fields provided in previous messages to complete a single record. + +## Technical logic + +### 1. Persona and system prompt +The agent is initialized with a strict system instruction set: +* **Role**: Specialized CRM AI Assistant for Odoo. +* **The 6-Field Rule**: For the `create_lead` action, the agent **must** explicitly obtain: `lead_name`, `email_from`, `expected_revenue`, `probability`, `date_deadline`, and `priority`. +* **Constraint**: If a single field is missing, the agent enters `chat` mode to request the information instead of attempting creation. + +### 2. Reasoning process (PerryThought) +The `CRMAgent` implements a transparent reasoning flow by yielding `PerryThought` objects during its execution. This allows the user to see exactly what Perry is doing in the background: + +| Step ID | Reasoning Description | +| :--- | :--- | +| `history_parsing` | Analyzes history to merge new info with previously provided data. | +| `llm_run` | Executes the CRM intent model to determine the next administrative action. | +| `extraction` | Extracts structured parameters (IDs, revenue, dates) from the model's response. | +| `parsing` | Cleans and processes raw JSON with fallback support (`ast.literal_eval`). | +| `validation` | Verifies CRM action parameters against Odoo business rules. | +| `lead_prep` | Checks required fields for new lead preparation. | +| `mcp_call` | Connects to Odoo to prepare a pending action for human review (HITL). | +| `mcp_list` | Searches the Odoo database for matching CRM records. | +| `conclusion` | Finalizes the professional communication and generates the response. | + +## Data models + +### CRMAction +The agent uses a Pydantic model to route actions and validate parameters for CRM operations. + +```python +class CRMAction(BaseModel): + action: Literal["create_lead", "list_opportunities", "chat"] + opportunity_id: Optional[int] + search_query: Optional[str] + lead_name: Optional[str] + email_from: Optional[str] + expected_revenue: Optional[float] + probability: Optional[float] + date_deadline: Optional[str] + priority: Optional[str] + reply_content: Optional[str] +``` + +## Execution flow (`act` method) + +1. **Memory check**: Verifies message history; if empty, yields a `Failed` state. +2. **Context parsing**: Extracts the last user input, attempting to parse JSON history if available. +3. **LLM interaction**: Runs the CRM intent model to decide the action. +4. **Advanced parsing**: + * Uses **Regex** to extract JSON from the raw text. + * **Fallback**: If `json.loads` fails, it attempts `ast.literal_eval`. +5. **Validation**: Validates the payload against the `CRMAction` model. +6. **Action routing**: + * **create_lead**: Validates the "6-Field Rule." If complete, calls `create_pending_action` via MCP to generate a confirmation link. + * **list_opportunities**: Calls `odoo_get_opportunities` via MCP to fetch pipeline data. +7. **Output**: Yields the final `Message` containing either requested data or an Odoo validation link. + +## Observability (Logfire) + +The `CRMAgent` is fully instrumented with **Logfire** for real-time tracing: +* **Initialization**: Logs the status of the MCP client connection. +* **Spans**: Every administrative step (parsing, LLM run, MCP calls) is wrapped in a Logfire span. +* **Metadata**: Logs include `action` type, field presence (e.g., `has_opportunity_id`), and validation failures. +* **Error handling**: Logs missing fields as warnings and service failures as errors for audit purposes. + +## Example interaction + +![Example interaction](../imgs/crm_agent_ex_2.png) + +![Example interaction](../imgs/crm_agent_ex.png) \ No newline at end of file diff --git a/app/src/agents/docs/imgs/crm_agent_ex.png b/app/src/agents/docs/imgs/crm_agent_ex.png new file mode 100644 index 0000000..0156c6a Binary files /dev/null and b/app/src/agents/docs/imgs/crm_agent_ex.png differ diff --git a/app/src/agents/docs/imgs/crm_agent_ex_2.png b/app/src/agents/docs/imgs/crm_agent_ex_2.png new file mode 100644 index 0000000..285f171 Binary files /dev/null and b/app/src/agents/docs/imgs/crm_agent_ex_2.png differ