# {{ agent_name }} - TerminalUse Temporal Agent Template

This is a starter template for building asynchronous agents with the TerminalUse framework and Temporal. It provides a basic implementation of the Agent 2 Client Protocol (ACP) with Temporal workflow support to help you get started quickly.

## What You'll Learn

- **Tasks**: A task is a grouping mechanism for related messages. Think of it as a conversation thread or a session.
- **Messages**: Messages are communication objects within a task. They can contain text, data, or instructions.
- **ACP Events**: The agent responds to four main events:
  - `task_received`: When a new task is created
  - `task_message_received`: When a message is sent within a task
  - `task_approved`: When a task is approved
  - `task_canceled`: When a task is canceled
- **Temporal Workflows**: Long-running processes that can handle complex state management and async operations

## Running the Agent

1. Run the agent locally:
```bash
terminaluse agents run --config config.yaml
```

The agent will start on port 8000 and print messages whenever it receives any of the ACP events.

## What's Inside

This template:
- Sets up a basic ACP server with Temporal integration
- Handles each of the required ACP events
- Provides a foundation for building complex async agents
- Includes Temporal workflow and activity definitions

## Next Steps

For more advanced agent development, check out the TerminalUse tutorials:

- **Tutorials 00-08**: Learn about building synchronous agents with ACP
- **Tutorials 09-10**: Learn how to use Temporal to power asynchronous agents
  - Tutorial 09: Basic Temporal workflow setup
  - Tutorial 10: Advanced Temporal patterns and best practices

These tutorials will help you understand:
- How to handle long-running tasks
- Implementing state machines
- Managing complex workflows
- Best practices for async agent development

## The Config File

The `config.yaml` file is your agent's configuration file. It defines:
- How your agent should be built and packaged
- What files are included in your agent's Docker image
- Your agent's name and description
- Local development settings (like the port your agent runs on)
- Temporal worker configuration

This file is essential for both local development and deployment of your agent.

## Project Structure

```
{{ project_name }}/
├── src/                      # Your agent's code
│   ├── __init__.py
│   ├── agent.py              # Agent server and event handlers
│   ├── workflow.py           # Temporal workflow definitions
│   ├── activities.py         # Temporal activity definitions
│   └── run_worker.py         # Temporal worker setup
├── Dockerfile               # Container definition
├── config.yaml            # Deployment config
├── dev.ipynb                # Development notebook for testing
{% if use_uv %}
└── pyproject.toml          # Dependencies (uv)
{% else %}
└── requirements.txt         # Dependencies (pip)
{% endif %}
```

## Development

### 1. Customize Event Handlers
- Modify the handlers in `agent.py` to implement your agent's logic
- Add your own tools and capabilities
- Implement custom state management

### 2. Test Your Agent with the Development Notebook
Use the included `dev.ipynb` Jupyter notebook to test your agent interactively:

```bash
# Start Jupyter notebook (make sure you have jupyter installed)
jupyter notebook dev.ipynb

# Or use VS Code to open the notebook directly
code dev.ipynb
```

The notebook includes:
- **Setup**: Connect to your local TerminalUse backend
- **Task creation**: Create a new task for the conversation
- **Event sending**: Send events to the agent and get responses
- **Async message subscription**: Subscribe to server-side events to receive agent responses
- **Rich message display**: Beautiful formatting with timestamps and author information

The notebook automatically uses your agent name (`{{ agent_name }}`) and demonstrates the async ACP workflow: create task → send event → subscribe to responses.

### 3. Develop Temporal Workflows
- Edit `workflow.py` to define your agent's async workflow logic
- Modify `activities.py` to add custom activities
- Use `run_worker.py` to configure the Temporal worker

### 4. Manage Dependencies

{% if use_uv %}
You chose **uv** for package management. Here's how to work with dependencies:

```bash
# Add new dependencies
terminaluse uv add requests openai anthropic

# Add Temporal-specific dependencies (already included)
terminaluse uv add temporalio

# Install/sync dependencies
terminaluse uv sync

# Run commands with uv
uv run terminaluse agents run --config config.yaml
```

**Benefits of uv:**
- Faster dependency resolution and installation
- Better dependency isolation
- Modern Python packaging standards

{% else %}
You chose **pip** for package management. Here's how to work with dependencies:

```bash
# Probably create a conda env for your agent.
# Optionally add terminaluse editable installation

# Edit requirements.txt manually to add dependencies
echo "requests" >> requirements.txt
echo "openai" >> requirements.txt

# Temporal dependencies are already included
# temporalio is already in requirements.txt

# Install dependencies
pip install -r requirements.txt
```

**Benefits of pip:**
- Familiar workflow for most Python developers
- Simple requirements.txt management
- Wide compatibility
{% endif %}

### 5. Configure Credentials
- Add any required credentials to your config.yaml
- For local development, create a `.env` file in the project directory
- Use `load_dotenv()` only in development mode:

```python
import os
from dotenv import load_dotenv

if os.environ.get("ENVIRONMENT") == "development":
    load_dotenv()
```

## Local Development

### 1. Start the TerminalUse Backend
```bash
# Navigate to the backend directory
cd terminaluse

# Start all services using Docker Compose
make dev

# Optional: In a separate terminal, use lazydocker for a better UI (everything should say "healthy")
lzd
```

### 2. Setup Your Agent's requirements/pyproject.toml
```bash
terminaluse uv sync [--group editable-apy]
source .venv/bin/activate

# OR
conda create -n {{ project_name }} python=3.12
conda activate {{ project_name }}
pip install -r requirements.txt
```
### 3. Run Your Agent
```bash
# From this directory
export ENVIRONMENT=development && [uv run] terminaluse agents run --config config.yaml
```
4. **Interact with your agent**

Option 0: CLI (deprecated - to be replaced once a new CLI is implemented - please use the web UI for now!)
```bash
# Submit a task via CLI
terminaluse tasks submit --agent {{ agent_name }} --task "Your task here"
```

Option 1: Web UI
```bash
# Start the local web interface
cd terminaluse-web
make dev

# Then open http://localhost:3000 in your browser to chat with your agent
```

## Development Tips

### Environment Variables
- Set environment variables in src/.env for any required credentials
- Or configure them in the config.yaml under the `env` section
- The `.env` file is automatically loaded in development mode

### Local Testing
- Use `export ENVIRONMENT=development` before running your agent
- This enables local service discovery and debugging features
- Your agent will automatically connect to locally running services

### Temporal-Specific Tips
- Monitor workflows in the Temporal Web UI at http://localhost:8080
- Use the Temporal CLI for advanced workflow management
- Check workflow logs for debugging async operations

### Debugging
- Check agent logs in the terminal where you ran the agent
- Use the web UI to inspect task history and responses
- Monitor backend services with `lzd` (LazyDocker)
- Use Temporal Web UI for workflow debugging

### To build the agent Docker image locally (normally not necessary):

1. Build the agent image:
```bash
terminaluse agents build --config config.yaml
```

## Advanced Features

### Temporal Workflows
Extend your agent with sophisticated async workflows:

```python
# In src/workflow.py
@workflow.defn
class MyWorkflow(BaseWorkflow):
    async def complex_operation(self):
        # Multi-step async operations
        # Error handling and retries
        # State management
        pass
```

### Custom Activities
Add custom activities for external operations. **Important**: Always specify appropriate timeouts (recommended: 10 minutes):

```python
# In src/activities.py
from datetime import timedelta
from temporalio import activity
from temporalio.common import RetryPolicy

@activity.defn(name="call_external_api")
async def call_external_api(data):
    # HTTP requests, database operations, etc.
    pass

# In your workflow, call it with a timeout:
result = await workflow.execute_activity(
    "call_external_api",
    data,
    start_to_close_timeout=timedelta(minutes=10),  # Recommended: 10 minute timeout
    heartbeat_timeout=timedelta(minutes=1),         # Optional: heartbeat monitoring
    retry_policy=RetryPolicy(maximum_attempts=3)    # Optional: retry policy
)

# Don't forget to register your custom activities in run_worker.py:
# all_activities = get_all_activities() + [your_custom_activity_function]
```

### Integration with External Services
{% if use_uv %}
```bash
# Add service clients
terminaluse uv add httpx requests-oauthlib

# Add AI/ML libraries
terminaluse uv add openai anthropic transformers

# Add database clients
terminaluse uv add asyncpg redis
```
{% else %}
```bash
# Add to requirements.txt
echo "httpx" >> requirements.txt
echo "openai" >> requirements.txt
echo "asyncpg" >> requirements.txt
pip install -r requirements.txt
```
{% endif %}

## Troubleshooting

### Common Issues

1. **Agent not appearing in web UI**
   - Check if agent is running on port 8000
   - Verify `ENVIRONMENT=development` is set
   - Check agent logs for errors

2. **Temporal workflow issues**
   - Check Temporal Web UI at http://localhost:8080
   - Verify Temporal server is running in backend services
   - Check workflow logs for specific errors

3. **Dependency issues**
{% if use_uv %}
   - Run `terminaluse uv sync` to ensure all dependencies are installed
   - Verify temporalio is properly installed
{% else %}
   - Run `pip install -r requirements.txt`
   - Check if all dependencies are correctly listed in requirements.txt
   - Verify temporalio is installed correctly
{% endif %}

4. **Port conflicts**
   - Check if another service is using port 8000
   - Use `lsof -i :8000` to find conflicting processes

### Temporal-Specific Troubleshooting

1. **Workflow not starting**
   - Check if Temporal server is running (`docker ps`)
   - Verify task queue configuration in `run_worker.py`
   - Check workflow registration in the worker

2. **Activity failures**
   - Check activity logs in the console
   - Verify activity registration
   - Check for timeout issues

Happy building with Temporal! 🚀⚡