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
75 changes: 75 additions & 0 deletions app/src/agents/docs/agents/calendar-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,75 @@
# CalendarAgent

The **CalendarAgent** is the specialized component within the Perry ecosystem responsible for managing schedules and organizing meetings in **Odoo Calendar**. It is designed with a focus on temporal accuracy and chronological integrity, ensuring that administrative tasks are handled with extreme punctuality.

## Overview

The `CalendarAgent` acts as a bridge between natural language scheduling requests and Odoo's chronological records. It handles date normalization (transforming "tomorrow at 5" into a valid timestamp) and enforces business rules such as preventing the scheduling of events in the past—while maintaining a **Human-in-the-Loop (HITL)** safety layer.

### Key responsibilities:
* **Temporal normalization**: Converting relative user timeframes into strict `YYYY-MM-DD HH:MM:SS` formats.
* **Chronological validation**: Performing real-time checks to ensure events are not scheduled retroactively.
* **Meeting preparation**: Gathering mandatory data (`title` and `start_datetime`) to build a pending Odoo event.
* **System consistency**: Ensuring all communication follows the formal "Perry" persona and JSON-only structural requirements.

## Technical logic

### 1. Persona and system prompt
The agent is initialized as a "Specialized Calendar AI Assistant for Odoo" with strict operational rules:
* **Action logic**: If data is incomplete, it uses `chat` to request missing details. If complete, it triggers `create_event`.
* **Mandatory fields**: It must extract a title and a start time. It defaults the duration to 1.0 hour if not specified.
* **Past date policy**: Strictly forbidden. If a past date is detected, the agent explains the limitation and reverts to a chat response.

### 2. Reasoning process (PerryThought)
The `CalendarAgent` implements a transparent reasoning flow, yielding `PerryThought` objects to inform the user of its progress:

| Step ID | Reasoning Description |
| :--- | :--- |
| `history_parsing` | Analyzes schedule requests and checks historical context for previous mentions of dates or topics. |
| `llm_query` | Consults the LLM model to perform temporal normalization and intent extraction. |
| `json_parsing` | Extracts and parses the structured JSON logic from the model's response. |
| `validation` | Verifies meeting parameters against Odoo business rules and Pydantic schemas. |
| `date_check` | Performs a chronological integrity check to ensure the requested time is in the future. |
| `mcp_call` | Connects to the Odoo MCP server to prepare the pending calendar invitation. |
| `conclusion` | Finalizes the professional response and presents the confirmation link. |

## Data models

### CalendarAction
The agent uses a Pydantic model to structure the scheduling parameters and validate the data extracted by the LLM.

```python
class CalendarAction(BaseModel):
action: Literal["create_event", "chat"] = Field(default="chat")
title: Optional[str] = Field(None, description="Title of the meeting")
start_datetime: Optional[str] = Field(None, description="YYYY-MM-DD HH:MM:SS format")
duration: Optional[float] = Field(1.0, description="Duration in hours")
description: Optional[str] = Field(None, description="Meeting details")
reply_content: Optional[str] = Field(default="Organizing your agenda...")
```

## Execution flow (`act` method)

1. **Memory check**: Verifies conversation history presence.
2. **Temporal normalization**: The LLM processes the user query to determine the intended date and time.
3. **Parsing and cleanup**:
* Removes Markdown wrappers (`` ```json ``).
* **Fallback**: If `json.loads` fails, it utilizes `ast.literal_eval` to recover the dictionary.
4. **Business logic validation**:
* Validates the schema via Pydantic.
* **Chronological check**: Compares the target `start_datetime` against `datetime.now()`.
5. **Odoo integration**:
* If valid, it calls the `create_event` tool via **OdooMCPClient**.
* Generates a pending action record in Odoo and returns a styled HTML link to the user for final review and confirmation.
6. **Response generation**: Yields the final message or the failure state.

## Observability (Logfire)

The `CalendarAgent` is deeply integrated with **Logfire** for tracing:
* **Spans**: Every significant operation (`thinking_step`, LLM run, MCP call) is wrapped in a Logfire span.
* **Logging**: Records specific events, such as rejections due to past dates or parsing successes.
* **Diagnostics**: Logs metadata like `message_length`, `raw_response_length`, and Odoo service success/failure status.

## Example interaction

![Example interaction](../imgs/calendar_agent_ex.png)
74 changes: 74 additions & 0 deletions app/src/agents/docs/agents/finance-agent.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,74 @@
# FinanceAgent

The **FinanceAgent** is a specialized Artificial Intelligence Assistant integrated within the Perry ecosystem, specifically designed to handle **Odoo Finance** operations. It operates with a strictly professional and formal persona, ensuring that critical financial tasks like balance inquiries and payment preparations are executed with high precision and security.

## Overview

The `FinanceAgent` acts as a secure intermediary between user requests and the Odoo financial ledger. It focuses on two primary administrative tasks: retrieving real-time bank balances and preparing payment drafts for human confirmation. By employing a **Human-in-the-Loop (HITL)** strategy, it ensures that no actual funds are moved without explicit manual verification.

### Key responsibilities:
* **Balance inquiries**: Retrieves current liquidity from the Odoo "Bank" journal.
* **Payment preparation**: Collects and validates transaction data (amount, recipient, and payment method).
* **Safety enforcement**: Prevents direct execution of transfers; instead, it generates secure review links.
* **Data integrity**: Overrides previous context with the latest user corrections to ensure the "absolute truth" of the transaction.

## Technical logic

### 1. Persona and System Prompt
The agent is initialized with a specialized system prompt that enforces:
* **Formal communication**: Strictly professional language, avoiding humor or informality.
* **Validation rules**: Requirement of three specific fields (`amount`, `recipient_name`, `journal_name`) before attempting a `create_payment` action.
* **Consistency**: Balance checks are restricted solely to the **Bank** journal to maintain financial accuracy.

### 2. Reasoning process (PerryThought)
The `FinanceAgent` implements a transparent reasoning flow by yielding `PerryThought` objects. This allows users and the orchestrator to monitor the internal decision-making steps:

| Step ID | Reasoning Description |
| :--- | :--- |
| `analysis` | Evaluates the financial request against the existing conversation history. |
| `llm_run` | Queries the specialized finance model to determine the appropriate administrative action. |
| `parsing_start` | Initiates the extraction of internal decision logic from the model's output. |
| `validation` | Checks financial parameters against Odoo business rules. |
| `mcp_balance` | Establishes a connection to the Odoo bank ledger via the MCP client. |
| `mcp_payment` | Prepares the formal payment record for Odoo's pending action queue. |
| `conclusion` | Finalizes the professional response, often including formatted Odoo links. |

## Data models

### FinanceAction
The agent utilizes a Pydantic model to enforce a strict schema on the LLM's output.

```python
class FinanceAction(BaseModel):
action: Literal["create_payment", "check_balance", "chat"] = Field(default="chat")
amount: Optional[float] = None
recipient_name: Optional[str] = None
journal_name: Optional[str] = None
reply_content: Optional[str] = Field(default="Processing the request...")
```

## Execution flow (`act` method)

1. **Context analysis**: Verifies memory presence and analyzes the latest message.
2. **Specialized inference**: Runs the internal LLM to map natural language to a `FinanceAction`.
3. **Robust parsing**:
* Handles various output formats, including Markdown blocks and `AgentRunResult` wrappers.
* **Fallback**: Uses `ast.literal_eval` if standard JSON parsing fails.
4. **Action routing**:
* **`check_balance`**: Interfaces with the `OdooMCPClient` to fetch current bank funds.
* **`create_payment`**: Validates the presence of the "Big Three" fields (Amount, Recipient, Journal). If valid, it triggers `create_pending_action`.
5. **HITL Generation**: For payments, it generates a styled HTML button pointing to the specific `perry.pending.action` record in Odoo for human review.

## Observability (Logfire)

The `FinanceAgent` is fully instrumented with **Logfire** for deep traceability:
* **Spans**: Every major logic block, from initialization to MCP integration, is wrapped in a span.
* **Attribute tracking**: Logs metadata such as `current_balance`, `requested_payment`, and `journal_name`.
* **Exception handling**: Parsing and validation failures are logged as exceptions with the full raw response for debugging.

## Example interaction

![Example interaction](../imgs/finance_agent_ex.png)

![Example interaction](../imgs/finance_agent_ex_2.png)

Binary file added app/src/agents/docs/imgs/calendar_agent_ex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/agents/docs/imgs/finance_agent_ex.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added app/src/agents/docs/imgs/finance_agent_ex_2.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Loading