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
3 changes: 3 additions & 0 deletions src/agentex/lib/cli/commands/init.py
Original file line number Diff line number Diff line change
Expand Up @@ -29,6 +29,7 @@ class TemplateType(str, Enum):
DEFAULT = "default"
DEFAULT_LANGGRAPH = "default-langgraph"
DEFAULT_PYDANTIC_AI = "default-pydantic-ai"
DEFAULT_OPENAI_AGENTS = "default-openai-agents"
SYNC = "sync"
SYNC_OPENAI_AGENTS = "sync-openai-agents"
SYNC_OPENAI_AGENTS_LOCAL_SANDBOX = "sync-openai-agents-local-sandbox"
Expand Down Expand Up @@ -69,6 +70,7 @@ def create_project_structure(
TemplateType.DEFAULT: ["acp.py"],
TemplateType.DEFAULT_LANGGRAPH: ["acp.py", "graph.py", "tools.py"],
TemplateType.DEFAULT_PYDANTIC_AI: ["acp.py", "agent.py", "tools.py"],
TemplateType.DEFAULT_OPENAI_AGENTS: ["acp.py"],
TemplateType.SYNC: ["acp.py"],
TemplateType.SYNC_OPENAI_AGENTS: ["acp.py"],
TemplateType.SYNC_OPENAI_AGENTS_LOCAL_SANDBOX: ["acp.py", "agent.py", "tools.py"],
Expand Down Expand Up @@ -184,6 +186,7 @@ def validate_agent_name(text: str) -> bool | str:
"Which Async template would you like to use?",
choices=[
{"name": "Basic Async ACP", "value": TemplateType.DEFAULT},
{"name": "Async ACP + OpenAI Agents SDK", "value": TemplateType.DEFAULT_OPENAI_AGENTS},
{"name": "Async ACP + LangGraph", "value": TemplateType.DEFAULT_LANGGRAPH},
{"name": "Async ACP + Pydantic AI", "value": TemplateType.DEFAULT_PYDANTIC_AI},
],
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# Python
__pycache__/
*.py[cod]
*$py.class
*.so
.Python
build/
develop-eggs/
dist/
downloads/
eggs/
.eggs/
lib/
lib64/
parts/
sdist/
var/
wheels/
*.egg-info/
.installed.cfg
*.egg

# Environments
.env**
.venv
env/
venv/
ENV/
env.bak/
venv.bak/

# IDE
.idea/
.vscode/
*.swp
*.swo

# Git
.git
.gitignore

# Misc
.DS_Store
Original file line number Diff line number Diff line change
@@ -0,0 +1,13 @@
# {{ agent_name }} - Environment Variables
# Copy this file to .env and fill in the values

# API key for your LLM provider
LITELLM_API_KEY=

# LLM base URL (optional - override to use a different provider)
# OPENAI_BASE_URL=

# SGP Configuration (optional - for tracing)
# SGP_API_KEY=
# SGP_ACCOUNT_ID=
# SGP_CLIENT_BASE_URL=
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
# syntax=docker/dockerfile:1.3
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:0.6.4 /uv /uvx /bin/

# Install system dependencies
RUN apt-get update && apt-get install -y \
htop \
vim \
curl \
tar \
python3-dev \
postgresql-client \
build-essential \
libpq-dev \
gcc \
cmake \
netcat-openbsd \
nodejs \
npm \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/**

ENV UV_COMPILE_BYTECODE=1
ENV UV_LINK_MODE=copy
ENV UV_HTTP_TIMEOUT=1000

WORKDIR /app/{{ project_path_from_build_root }}

# Copy dependency files for layer caching
COPY {{ project_path_from_build_root }}/pyproject.toml {{ project_path_from_build_root }}/uv.lock ./

# Install dependencies (without project itself, for layer caching)
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-install-project --no-dev
Comment thread
greptile-apps[bot] marked this conversation as resolved.

# Copy the project code
COPY {{ project_path_from_build_root }}/project ./project

# Install the project
RUN --mount=type=cache,target=/root/.cache/uv \
uv sync --locked --no-dev

ENV PATH="/app/{{ project_path_from_build_root }}/.venv/bin:$PATH"
ENV PYTHONPATH=/app

# Run the agent using uvicorn
CMD ["uvicorn", "project.acp:acp", "--host", "0.0.0.0", "--port", "8000"]
43 changes: 43 additions & 0 deletions src/agentex/lib/cli/templates/default-openai-agents/Dockerfile.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,43 @@
# syntax=docker/dockerfile:1.3
FROM python:3.12-slim
COPY --from=ghcr.io/astral-sh/uv:0.6.4 /uv /uvx /bin/

# Install system dependencies
RUN apt-get update && apt-get install -y \
htop \
vim \
curl \
tar \
python3-dev \
postgresql-client \
build-essential \
libpq-dev \
gcc \
cmake \
netcat-openbsd \
nodejs \
npm \
&& apt-get clean \
&& rm -rf /var/lib/apt/lists/*

RUN uv pip install --system --upgrade pip setuptools wheel

ENV UV_HTTP_TIMEOUT=1000

# Copy just the requirements file to optimize caching
COPY {{ project_path_from_build_root }}/requirements.txt /app/{{ project_path_from_build_root }}/requirements.txt

WORKDIR /app/{{ project_path_from_build_root }}

# Install the required Python packages
RUN uv pip install --system -r requirements.txt

# Copy the project code
COPY {{ project_path_from_build_root }}/project /app/{{ project_path_from_build_root }}/project


# Set environment variables
ENV PYTHONPATH=/app

# Run the agent using uvicorn
CMD ["uvicorn", "project.acp:acp", "--host", "0.0.0.0", "--port", "8000"]
69 changes: 69 additions & 0 deletions src/agentex/lib/cli/templates/default-openai-agents/README.md.j2
Original file line number Diff line number Diff line change
@@ -0,0 +1,69 @@
# {{ agent_name }} - AgentEx Async OpenAI Agents SDK Agent

This template builds an **asynchronous** (non-Temporal) agent built on the
**OpenAI Agents SDK**, delivered through the unified harness surface on AgentEx:
- Defines an OpenAI Agents SDK `Agent` (with an example weather tool) inline in
`acp.py`
- Wraps the SDK run in an `OpenAITurn`
- Delivers canonical `StreamTaskMessage*` events via `UnifiedEmitter.auto_send_turn`
(the async Redis push path), so the UI receives output in real time
- Tracing integration to SGP / AgentEx

## Prerequisites

- An `OPENAI_API_KEY` in your environment (or a `LITELLM_API_KEY`, which is
copied to `OPENAI_API_KEY` for LiteLLM-proxy compatibility)

## Running the Agent

```bash
agentex agents run --manifest manifest.yaml
```

## Project Structure

```
{{ project_name }}/
β”œβ”€β”€ project/
β”‚ β”œβ”€β”€ __init__.py
β”‚ └── acp.py # ACP server, agent + tool definitions, event handlers
β”œβ”€β”€ Dockerfile
β”œβ”€β”€ manifest.yaml
β”œβ”€β”€ dev.ipynb
{% if use_uv %}
└── pyproject.toml
{% else %}
└── requirements.txt
{% endif %}
```

## Key Concepts

### Async ACP with the harness
The async ACP model streams events over Redis instead of an HTTP response. The
`@acp.on_task_event_send` handler runs the OpenAI Agents SDK and pushes the
harness events to the task stream.

### The unified harness surface
`OpenAITurn` + `UnifiedEmitter` are the unified harness surface. The turn
normalizes the SDK's streamed run into canonical AgentEx events; the emitter
traces and delivers them.

## Development

### 1. Add Your Own Tools
Define new `@function_tool` functions in `project/acp.py` and add them to the
agent's `tools=[...]` list in `create_agent()`.

### 2. Customize the Agent
Edit `MODEL_NAME` and `INSTRUCTIONS` in `project/acp.py` to change the model or
system prompt.

### 3. Configure Credentials
Set your credentials via `manifest.yaml`, an exported environment variable, or a
`.env` file in the project directory.

### 4. Run Locally
```bash
export ENVIRONMENT=development && agentex agents run --manifest manifest.yaml
```
Loading
Loading