mirror of
https://github.com/temporal-community/temporal-ai-agent.git
synced 2026-03-17 06:58:09 +01:00
Compare commits
6 Commits
poetry-loc
...
review-dal
| Author | SHA1 | Date | |
|---|---|---|---|
|
|
a4567c4e42 | ||
|
|
ae4811a8d0 | ||
|
|
470ef08615 | ||
|
|
3e9439022e | ||
|
|
f8e0dd3b2a | ||
|
|
2f3afd6954 |
30
Dockerfile
Normal file
30
Dockerfile
Normal file
@@ -0,0 +1,30 @@
|
|||||||
|
FROM python:3.10-slim
|
||||||
|
|
||||||
|
WORKDIR /app
|
||||||
|
|
||||||
|
# Install system dependencies
|
||||||
|
RUN apt-get update && \
|
||||||
|
apt-get install -y --no-install-recommends gcc build-essential && \
|
||||||
|
apt-get clean && \
|
||||||
|
rm -rf /var/lib/apt/lists/*
|
||||||
|
|
||||||
|
# Copy requirements first for better caching
|
||||||
|
RUN pip install --no-cache-dir poetry
|
||||||
|
|
||||||
|
# Install Python dependencies without creating a virtualenv
|
||||||
|
COPY pyproject.toml poetry.lock ./
|
||||||
|
RUN poetry config virtualenvs.create false \
|
||||||
|
&& poetry install --without dev --no-interaction --no-ansi --no-root
|
||||||
|
|
||||||
|
# Copy application code
|
||||||
|
COPY . .
|
||||||
|
|
||||||
|
# Set Python to run in unbuffered mode (recommended for Docker)
|
||||||
|
ENV PYTHONUNBUFFERED=1
|
||||||
|
ENV PYTHONPATH=/app
|
||||||
|
|
||||||
|
# Expose the port the app will run on
|
||||||
|
EXPOSE 8000
|
||||||
|
|
||||||
|
# Default to running only the API server; worker and train-api are separate Compose services
|
||||||
|
CMD ["uvicorn", "api.main:app", "--host", "0.0.0.0", "--port", "8000"]
|
||||||
20
docker-compose.override.yml
Normal file
20
docker-compose.override.yml
Normal file
@@ -0,0 +1,20 @@
|
|||||||
|
services:
|
||||||
|
api:
|
||||||
|
volumes:
|
||||||
|
- ./:/app:cached
|
||||||
|
command: uvicorn api.main:app --host 0.0.0.0 --port 8000 --reload
|
||||||
|
|
||||||
|
worker:
|
||||||
|
volumes:
|
||||||
|
- ./:/app:cached
|
||||||
|
command: python scripts/run_worker.py
|
||||||
|
|
||||||
|
train-api:
|
||||||
|
volumes:
|
||||||
|
- ./:/app:cached
|
||||||
|
command: python thirdparty/train_api.py
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
volumes:
|
||||||
|
- ./frontend:/app:cached
|
||||||
|
command: sh -c "apk update && apk add --no-cache xdg-utils && npm install && npx vite --host 0.0.0.0 --port 5173"
|
||||||
120
docker-compose.yml
Normal file
120
docker-compose.yml
Normal file
@@ -0,0 +1,120 @@
|
|||||||
|
services:
|
||||||
|
# Database service
|
||||||
|
postgresql:
|
||||||
|
image: postgres:14
|
||||||
|
container_name: temporal-postgresql
|
||||||
|
environment:
|
||||||
|
POSTGRES_USER: temporal
|
||||||
|
POSTGRES_PASSWORD: temporal
|
||||||
|
POSTGRES_DB: temporal
|
||||||
|
volumes:
|
||||||
|
- postgresql:/var/lib/postgresql/data
|
||||||
|
networks:
|
||||||
|
- temporal-network
|
||||||
|
|
||||||
|
# Temporal services
|
||||||
|
temporal:
|
||||||
|
image: temporalio/auto-setup:1.27.2
|
||||||
|
container_name: temporal
|
||||||
|
ports:
|
||||||
|
- "7233:7233"
|
||||||
|
environment:
|
||||||
|
- DB=postgres12
|
||||||
|
- DB_PORT=5432
|
||||||
|
- POSTGRES_USER=temporal
|
||||||
|
- POSTGRES_PWD=temporal
|
||||||
|
- POSTGRES_SEEDS=postgresql
|
||||||
|
depends_on:
|
||||||
|
- postgresql
|
||||||
|
networks:
|
||||||
|
- temporal-network
|
||||||
|
|
||||||
|
temporal-admin-tools:
|
||||||
|
image: temporalio/admin-tools:1.27
|
||||||
|
container_name: temporal-admin-tools
|
||||||
|
depends_on:
|
||||||
|
- temporal
|
||||||
|
environment:
|
||||||
|
- TEMPORAL_CLI_ADDRESS=temporal:7233
|
||||||
|
networks:
|
||||||
|
- temporal-network
|
||||||
|
|
||||||
|
temporal-ui:
|
||||||
|
image: temporalio/ui:2.37.2
|
||||||
|
container_name: temporal-ui
|
||||||
|
ports:
|
||||||
|
- "8080:8080"
|
||||||
|
environment:
|
||||||
|
- TEMPORAL_ADDRESS=temporal:7233
|
||||||
|
- TEMPORAL_CORS_ORIGINS=http://localhost:8080
|
||||||
|
depends_on:
|
||||||
|
- temporal
|
||||||
|
networks:
|
||||||
|
- temporal-network
|
||||||
|
|
||||||
|
api:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: temporal-ai-agent-api
|
||||||
|
ports:
|
||||||
|
- "8000:8000"
|
||||||
|
depends_on:
|
||||||
|
- temporal
|
||||||
|
networks:
|
||||||
|
- temporal-network
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
- TEMPORAL_ADDRESS=temporal:7233
|
||||||
|
|
||||||
|
worker:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: temporal-ai-agent-worker
|
||||||
|
depends_on:
|
||||||
|
- temporal
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
- TEMPORAL_ADDRESS=temporal:7233
|
||||||
|
command: python scripts/run_worker.py
|
||||||
|
networks:
|
||||||
|
- temporal-network
|
||||||
|
|
||||||
|
train-api:
|
||||||
|
build:
|
||||||
|
context: .
|
||||||
|
dockerfile: Dockerfile
|
||||||
|
container_name: temporal-ai-agent-train-api
|
||||||
|
depends_on:
|
||||||
|
- temporal
|
||||||
|
env_file:
|
||||||
|
- .env
|
||||||
|
environment:
|
||||||
|
- TEMPORAL_ADDRESS=temporal:7233
|
||||||
|
command: python thirdparty/train_api.py
|
||||||
|
networks:
|
||||||
|
- temporal-network
|
||||||
|
|
||||||
|
frontend:
|
||||||
|
image: node:18-alpine
|
||||||
|
container_name: temporal-ai-agent-frontend
|
||||||
|
working_dir: /app
|
||||||
|
volumes:
|
||||||
|
- ./frontend:/app
|
||||||
|
command: sh -c "apk update && apk add --no-cache xdg-utils && npm install && npx vite --host 0.0.0.0"
|
||||||
|
ports:
|
||||||
|
- "5173:5173"
|
||||||
|
depends_on:
|
||||||
|
- api
|
||||||
|
networks:
|
||||||
|
- temporal-network
|
||||||
|
|
||||||
|
networks:
|
||||||
|
temporal-network:
|
||||||
|
driver: bridge
|
||||||
|
|
||||||
|
volumes:
|
||||||
|
postgresql:
|
||||||
33
setup.md
33
setup.md
@@ -93,10 +93,32 @@ temporal server start-dev
|
|||||||
```
|
```
|
||||||
See the [Temporal documentation](https://learn.temporal.io/getting_started/python/dev_environment/) for other platforms.
|
See the [Temporal documentation](https://learn.temporal.io/getting_started/python/dev_environment/) for other platforms.
|
||||||
|
|
||||||
|
You can also run a local Temporal server using Docker Compose. See the `Development with Docker` section below.
|
||||||
|
|
||||||
## Running the Application
|
## Running the Application
|
||||||
|
|
||||||
### Python Backend
|
### Docker
|
||||||
|
- All services are defined in `docker-compose.yml` (includes a Temporal server).
|
||||||
|
- **Dev overrides** (mounted code, live‑reload commands) live in `docker-compose.override.yml` and are **auto‑merged** on `docker compose up`.
|
||||||
|
- To start **development** mode (with hot‑reload):
|
||||||
|
```bash
|
||||||
|
docker compose up -d
|
||||||
|
# quick rebuild without infra:
|
||||||
|
docker compose up -d --no-deps --build api train-api worker frontend
|
||||||
|
```
|
||||||
|
- To run **production** mode (ignore dev overrides):
|
||||||
|
```bash
|
||||||
|
docker compose -f docker-compose.yml up -d
|
||||||
|
```
|
||||||
|
|
||||||
|
Default urls:
|
||||||
|
* Temporal UI: [http://localhost:8080](http://localhost:8080)
|
||||||
|
* API: [http://localhost:8000](http://localhost:8000)
|
||||||
|
* Frontend: [http://localhost:5173](http://localhost:5173)
|
||||||
|
|
||||||
|
### Local Machine (no docker)
|
||||||
|
|
||||||
|
**Python Backend**
|
||||||
|
|
||||||
Requires [Poetry](https://python-poetry.org/) to manage dependencies.
|
Requires [Poetry](https://python-poetry.org/) to manage dependencies.
|
||||||
|
|
||||||
@@ -119,7 +141,7 @@ poetry run uvicorn api.main:app --reload
|
|||||||
```
|
```
|
||||||
Access the API at `/docs` to see the available endpoints.
|
Access the API at `/docs` to see the available endpoints.
|
||||||
|
|
||||||
### React UI
|
**React UI**
|
||||||
Start the frontend:
|
Start the frontend:
|
||||||
```bash
|
```bash
|
||||||
cd frontend
|
cd frontend
|
||||||
@@ -127,8 +149,7 @@ npm install
|
|||||||
npx vite
|
npx vite
|
||||||
```
|
```
|
||||||
Access the UI at `http://localhost:5173`
|
Access the UI at `http://localhost:5173`
|
||||||
|
|
||||||
|
|
||||||
|
|
||||||
## Goal-Specific Tool Configuration
|
## Goal-Specific Tool Configuration
|
||||||
Here is configuration guidance for specific goals. Travel and financial goals have configuration & setup as below.
|
Here is configuration guidance for specific goals. Travel and financial goals have configuration & setup as below.
|
||||||
@@ -145,7 +166,7 @@ Here is configuration guidance for specific goals. Travel and financial goals ha
|
|||||||
* Requires a Stripe key for the `create_invoice` tool. Set this in the `STRIPE_API_KEY` environment variable in .env
|
* Requires a Stripe key for the `create_invoice` tool. Set this in the `STRIPE_API_KEY` environment variable in .env
|
||||||
* It's free to sign up and get a key at [Stripe](https://stripe.com/)
|
* It's free to sign up and get a key at [Stripe](https://stripe.com/)
|
||||||
* Set permissions for read-write on: `Credit Notes, Invoices, Customers and Customer Sessions`
|
* Set permissions for read-write on: `Credit Notes, Invoices, Customers and Customer Sessions`
|
||||||
* If you're lazy go to `tools/create_invoice.py` and replace the `create_invoice` function with the mock `create_invoice_example` that exists in the same file.
|
* If you don't have a Stripe key, comment out the STRIPE_API_KEY in the .env file, and a dummy invoice will be created rather than a Stripe invoice. The function can be found in `tools/create_invoice.py`
|
||||||
|
|
||||||
### Goal: Find a Premier League match, book train tickets to it and invoice the user for the cost (Replay 2025 Keynote)
|
### Goal: Find a Premier League match, book train tickets to it and invoice the user for the cost (Replay 2025 Keynote)
|
||||||
- `AGENT_GOAL=goal_match_train_invoice` - Focuses on Premier League match attendance with train booking and invoice generation
|
- `AGENT_GOAL=goal_match_train_invoice` - Focuses on Premier League match attendance with train booking and invoice generation
|
||||||
@@ -231,4 +252,4 @@ For more details, check out [adding goals and tools guide](./adding-goals-and-to
|
|||||||
[ ] `cd frontend`, `npm install`, `npx vite` <br />
|
[ ] `cd frontend`, `npm install`, `npx vite` <br />
|
||||||
[ ] Access the UI at `http://localhost:5173` <br />
|
[ ] Access the UI at `http://localhost:5173` <br />
|
||||||
|
|
||||||
And that's it! Happy AI Agent Exploring!
|
And that's it! Happy AI Agent Exploring!
|
||||||
|
|||||||
@@ -27,7 +27,7 @@ def ensure_customer_exists(
|
|||||||
def create_invoice(args: dict) -> dict:
|
def create_invoice(args: dict) -> dict:
|
||||||
"""Create and finalize a Stripe invoice."""
|
"""Create and finalize a Stripe invoice."""
|
||||||
# If an API key exists in the env file, find or create customer
|
# If an API key exists in the env file, find or create customer
|
||||||
if stripe.api_key is not None:
|
if stripe.api_key is not None and stripe.api_key != "":
|
||||||
customer_id = ensure_customer_exists(
|
customer_id = ensure_customer_exists(
|
||||||
args.get("customer_id"), args.get("email", "default@example.com")
|
args.get("customer_id"), args.get("email", "default@example.com")
|
||||||
)
|
)
|
||||||
@@ -69,15 +69,3 @@ def create_invoice(args: dict) -> dict:
|
|||||||
"invoiceURL": "https://pay.example.com/invoice/12345",
|
"invoiceURL": "https://pay.example.com/invoice/12345",
|
||||||
"reference": "INV-12345",
|
"reference": "INV-12345",
|
||||||
}
|
}
|
||||||
|
|
||||||
def create_invoice_example(args: dict) -> dict:
|
|
||||||
"""
|
|
||||||
This is an example implementation of the CreateInvoice tool
|
|
||||||
Doesn't call any external services, just returns a dummy response
|
|
||||||
"""
|
|
||||||
print("[CreateInvoice] Creating invoice with:", args)
|
|
||||||
return {
|
|
||||||
"invoiceStatus": "generated",
|
|
||||||
"invoiceURL": "https://pay.example.com/invoice/12345",
|
|
||||||
"reference": "INV-12345",
|
|
||||||
}
|
|
||||||
|
|||||||
Reference in New Issue
Block a user