From e677b3193544fbecb00d84953b10056cbda66435 Mon Sep 17 00:00:00 2001 From: Jason Yang Date: Thu, 16 Oct 2025 16:24:47 -0700 Subject: [PATCH 1/4] Cleanup the readmes --- .../tutorials/00_sync/000_hello_acp/README.md | 26 +- .../tutorials/00_sync/010_multiturn/README.md | 37 +- .../tutorials/00_sync/020_streaming/README.md | 25 +- .../00_base/000_hello_acp/README.md | 31 +- .../00_base/010_multiturn/README.md | 17 +- .../00_base/020_streaming/README.md | 29 +- .../10_agentic/00_base/030_tracing/README.md | 34 +- .../00_base/040_other_sdks/README.md | 26 +- .../00_base/080_batch_events/README.md | 27 +- .../10_temporal/000_hello_acp/README.md | 42 ++- .../10_temporal/010_agent_chat/README.md | 29 +- .../10_temporal/020_state_machine/README.md | 52 ++- .../050_agent_chat_guardrails/README.md | 9 + .../README.md | 321 ++--------------- .../070_open_ai_agents_sdk_tools/README.md | 329 ++--------------- .../README.md | 336 +++--------------- 16 files changed, 449 insertions(+), 921 deletions(-) diff --git a/examples/tutorials/00_sync/000_hello_acp/README.md b/examples/tutorials/00_sync/000_hello_acp/README.md index d2d1eb6c..c450d085 100644 --- a/examples/tutorials/00_sync/000_hello_acp/README.md +++ b/examples/tutorials/00_sync/000_hello_acp/README.md @@ -1,7 +1,27 @@ # [Sync] Hello ACP -This is a simple AgentEx agent that just says hello and acknowledges the user's message to show which ACP methods need to be implemented for the sync ACP type. +## What You'll Learn -## Official Documentation +The simplest agent type: synchronous request/response pattern with a single `@acp.on_message_send` handler. Best for stateless operations that complete immediately. -[000 Hello ACP](https://dev.agentex.scale.com/docs/tutorials/sync/000_hello_acp) +**When to use sync:** Quick responses, no long-running operations, no need for task management or durability. + +## Quick Start + +```bash +cd examples/tutorials/00_sync/000_hello_acp +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Code + +```python +@acp.on_message_send +async def handle_message_send(params: SendMessageParams): + return TextContent( + author="agent", + content=f"Echo: {params.content.content}" + ) +``` + +That's it - one handler, immediate response. No task creation, no state management. diff --git a/examples/tutorials/00_sync/010_multiturn/README.md b/examples/tutorials/00_sync/010_multiturn/README.md index e095927d..bbb07add 100644 --- a/examples/tutorials/00_sync/010_multiturn/README.md +++ b/examples/tutorials/00_sync/010_multiturn/README.md @@ -1,7 +1,38 @@ # [Sync] Multiturn -This tutorial demonstrates how to handle multiturn conversations in AgentEx agents using the Agent 2 Client Protocol (ACP). +## What You'll Learn -## Official Documentation +Handle multi-turn conversations in synchronous agents by maintaining conversation history and context between messages. -[010 Multiturn](https://dev.agentex.scale.com/docs/tutorials/sync/010_multiturn) \ No newline at end of file +**Use case:** Chatbots that need to reference previous messages within the same session. + +## Quick Start + +```bash +cd examples/tutorials/00_sync/010_multiturn +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Pattern + +Sync agents are stateless by default. To handle multi-turn conversations, you need to: +1. Accept conversation history in the request +2. Maintain context across messages +3. Return responses that build on previous exchanges + +```python +@acp.on_message_send +async def handle_message_send(params: SendMessageParams): + # Accept conversation history from client + history = params.conversation_history + + # Build context from history + context = build_context(history) + + # Generate response considering full context + response = generate_response(params.content, context) + + return TextContent(author="agent", content=response) +``` + +The handler accepts history, builds context, and returns responses that reference previous exchanges. diff --git a/examples/tutorials/00_sync/020_streaming/README.md b/examples/tutorials/00_sync/020_streaming/README.md index b936628f..37d995ae 100644 --- a/examples/tutorials/00_sync/020_streaming/README.md +++ b/examples/tutorials/00_sync/020_streaming/README.md @@ -1,9 +1,28 @@ # [Sync] Streaming -This tutorial demonstrates how to implement streaming responses in AgentEx agents using the Agent 2 Client Protocol (ACP). +## What You'll Learn -## Official Documentation +Stream responses progressively using async generators instead of returning a single message. Enables showing partial results as they're generated. -[020 Streaming](https://dev.agentex.scale.com/docs/tutorials/sync/020_streaming) +**Use case:** LLM responses, large data processing, or any operation where you want to show progress. +## Quick Start +```bash +cd examples/tutorials/00_sync/020_streaming +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Code + +```python +@acp.on_message_send +async def handle_message_send(params: SendMessageParams): + async def stream_response(): + for chunk in response_chunks: + yield TaskMessageUpdate(content=TextContent(...)) + + return stream_response() +``` + +Return an async generator instead of a single response - each `yield` sends an update to the client. diff --git a/examples/tutorials/10_agentic/00_base/000_hello_acp/README.md b/examples/tutorials/10_agentic/00_base/000_hello_acp/README.md index 36008586..3b4be8a2 100644 --- a/examples/tutorials/10_agentic/00_base/000_hello_acp/README.md +++ b/examples/tutorials/10_agentic/00_base/000_hello_acp/README.md @@ -1,7 +1,32 @@ # [Agentic] Hello ACP -This tutorial demonstrates how to implement the base agentic ACP type in AgentEx agents. +## What You'll Learn -## Official Documentation +Agentic agents use three handlers for async task management: `on_task_create`, `on_task_event_send`, and `on_task_cancel`. Unlike sync agents, tasks persist and can receive multiple events over time. -[000 Hello Base Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/base/hello_acp/) \ No newline at end of file +**When to use agentic:** Long-running conversations, stateful operations, or when you need task lifecycle management. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/00_base/000_hello_acp +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Pattern + +```python +@acp.on_task_create +async def handle_task_create(params: CreateTaskParams): + # Initialize task state, send welcome message + +@acp.on_task_event_send +async def handle_event_send(params: SendEventParams): + # Handle each message/event in the task + +@acp.on_task_cancel +async def handle_task_cancel(params: CancelTaskParams): + # Cleanup when task is cancelled +``` + +Three handlers instead of one, giving you full control over task lifecycle. Tasks can receive multiple events and maintain state across them. diff --git a/examples/tutorials/10_agentic/00_base/010_multiturn/README.md b/examples/tutorials/10_agentic/00_base/010_multiturn/README.md index 40eb8d84..304faa10 100644 --- a/examples/tutorials/10_agentic/00_base/010_multiturn/README.md +++ b/examples/tutorials/10_agentic/00_base/010_multiturn/README.md @@ -1,7 +1,18 @@ # [Agentic] Multiturn -This tutorial demonstrates how to handle multiturn conversations in AgentEx agents using the agentic ACP type. +## What You'll Learn -## Official Documentation +Handle multi-turn conversations in agentic agents with task-based state management. Each task maintains its own conversation history. -[010 Multiturn Base Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/base/multiturn/) +**Use case:** Conversational agents that need to remember context across multiple exchanges within a task. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/00_base/010_multiturn +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Pattern + +In sync agents, you manually pass conversation history. In agentic agents, the task itself maintains state across multiple `on_task_event_send` calls, making it easier to build stateful conversations. diff --git a/examples/tutorials/10_agentic/00_base/020_streaming/README.md b/examples/tutorials/10_agentic/00_base/020_streaming/README.md index bbd1d90b..518d8358 100644 --- a/examples/tutorials/10_agentic/00_base/020_streaming/README.md +++ b/examples/tutorials/10_agentic/00_base/020_streaming/README.md @@ -1,7 +1,30 @@ # [Agentic] Streaming -This tutorial demonstrates how to implement streaming responses in AgentEx agents using the agentic ACP type. +## What You'll Learn -## Official Documentation +Stream responses in agentic agents using `adk.messages.create()` to send progressive updates. More flexible than sync streaming since you can send multiple messages at any time. -[020 Streaming Base Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/base/streaming/) \ No newline at end of file +**Use case:** Long-running operations where you want to show progress, or multi-step processes with intermediate results. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/00_base/020_streaming +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Pattern + +```python +@acp.on_task_event_send +async def handle_event_send(params: SendEventParams): + # Send first message + await adk.messages.create(task_id=task_id, content=...) + + # Do work... + + # Send second message + await adk.messages.create(task_id=task_id, content=...) +``` + +Unlike sync streaming (which uses async generators), agentic streaming uses explicit message creation calls, giving you more control over when and what to send. diff --git a/examples/tutorials/10_agentic/00_base/030_tracing/README.md b/examples/tutorials/10_agentic/00_base/030_tracing/README.md index ea41a8f8..9ed3c3f1 100644 --- a/examples/tutorials/10_agentic/00_base/030_tracing/README.md +++ b/examples/tutorials/10_agentic/00_base/030_tracing/README.md @@ -1,7 +1,35 @@ # [Agentic] Tracing -This tutorial demonstrates how to implement hierarchical and custom tracing in AgentEx agents using the agentic ACP type. +## What You'll Learn -## Official Documentation +Add observability to your agents with spans and traces using `adk.tracing.start_span()`. Track execution flow, measure performance, and debug complex agent behaviors. -[030 Tracing Base Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/base/tracing/) \ No newline at end of file +**Use case:** Understanding agent behavior, debugging issues, monitoring performance in production. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/00_base/030_tracing +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Pattern + +```python +# Start a span to track an operation +span = await adk.tracing.start_span( + trace_id=task.id, + name="LLM Call", + input={"prompt": prompt} +) + +# Do work... + +# End span with output +await adk.tracing.end_span( + span_id=span.id, + output={"response": response} +) +``` + +Spans create a hierarchical view of agent execution, making it easy to see which operations take time and where errors occur. diff --git a/examples/tutorials/10_agentic/00_base/040_other_sdks/README.md b/examples/tutorials/10_agentic/00_base/040_other_sdks/README.md index 8be83e82..7d804e21 100644 --- a/examples/tutorials/10_agentic/00_base/040_other_sdks/README.md +++ b/examples/tutorials/10_agentic/00_base/040_other_sdks/README.md @@ -1,7 +1,27 @@ # [Agentic] Other SDKs -This tutorial demonstrates how to use other SDKs in AgentEx agents to show the flexibility that agents are just code. +## What You'll Learn -## Official Documentation +Agents are just Python code - integrate any SDK you want (OpenAI, Anthropic, LangChain, LlamaIndex, custom libraries, etc.). AgentEx doesn't lock you into a specific framework. -[040 Other SDKs Base Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/base/other_sdks/) \ No newline at end of file +**Use case:** Using your preferred LLM provider, existing agent frameworks, or custom tooling. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/00_base/040_other_sdks +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Insight + +AgentEx provides: +- ACP protocol implementation (task management, message handling) +- Deployment infrastructure +- Monitoring and observability + +You provide: +- Agent logic using whatever SDK/library you want +- Tools and capabilities specific to your use case + +Mix and match OpenAI, Anthropic, LangChain, or roll your own - it's all just Python. diff --git a/examples/tutorials/10_agentic/00_base/080_batch_events/README.md b/examples/tutorials/10_agentic/00_base/080_batch_events/README.md index bddd3ed6..0a0777ed 100644 --- a/examples/tutorials/10_agentic/00_base/080_batch_events/README.md +++ b/examples/tutorials/10_agentic/00_base/080_batch_events/README.md @@ -1,7 +1,28 @@ # [Agentic] Batch Events -This tutorial demonstrates batch event processing and the limitations of the base agentic ACP protocol. +## What You'll Learn -## Official Documentation +Demonstrates limitations of the base agentic protocol with concurrent event processing. When multiple events arrive rapidly, base agentic agents handle them sequentially, which can cause issues. -[080 Batch Events Base Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/base/batch_events/) +**Problem shown:** Race conditions and ordering issues when events arrive faster than the agent can process them. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/00_base/080_batch_events +uv run agentex agents run --manifest manifest.yaml +``` + +## Why This Matters + +This tutorial shows **when you need Temporal**. If your agent needs to: +- Handle events that might arrive out of order +- Process multiple events in parallel safely +- Maintain consistent state under concurrent load + +Then you should use Temporal workflows (see tutorials 10_agentic/10_temporal/) which provide: +- Deterministic event ordering +- Safe concurrent processing +- Guaranteed state consistency + +This is the "breaking point" tutorial that motivates moving to Temporal for production agents. diff --git a/examples/tutorials/10_agentic/10_temporal/000_hello_acp/README.md b/examples/tutorials/10_agentic/10_temporal/000_hello_acp/README.md index 3cb435ec..9171ea0b 100644 --- a/examples/tutorials/10_agentic/10_temporal/000_hello_acp/README.md +++ b/examples/tutorials/10_agentic/10_temporal/000_hello_acp/README.md @@ -1,7 +1,41 @@ -# [Agentic] Hello ACP with Temporal +# [Temporal] Hello ACP -This tutorial demonstrates how to implement the agentic ACP type with Temporal workflows in AgentEx agents. +## What You'll Learn -## Official Documentation +Temporal workflows make agents durable - they survive restarts and can run indefinitely without consuming resources while idle. Instead of handlers, you define a workflow class with `@workflow.run` and `@workflow.signal` methods. -[000 Hello Temporal Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/temporal/hello_acp/) \ No newline at end of file +**When to use Temporal:** Production agents that need guaranteed execution, long-running tasks (hours/days/weeks), or operations that must survive system failures. + +**Coming from base agentic?** See tutorial `080_batch_events` to understand when you need Temporal. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/10_temporal/000_hello_acp +uv run agentex agents run --manifest manifest.yaml +``` + +**Monitor:** Check Temporal UI at http://localhost:8080 to see your durable workflow running. + +## Key Pattern + +```python +@workflow.defn(name="my-workflow") +class MyWorkflow(BaseWorkflow): + @workflow.run + async def on_task_create(self, params: CreateTaskParams): + # Wait indefinitely for events - workflow stays alive + await workflow.wait_condition(lambda: self._complete) + + @workflow.signal(name=SignalName.RECEIVE_EVENT) + async def on_task_event_send(self, params: SendEventParams): + # Handle events as signals to the workflow +``` + +## Why This Matters + +**Without Temporal:** If your worker crashes, the agent loses all state and has to start over. + +**With Temporal:** The workflow resumes exactly where it left off. If it crashes mid-conversation, Temporal brings it back up with full context intact. Can run for years if needed, only consuming resources when actively processing. + +This is the foundation for production-ready agents that handle real-world reliability requirements. diff --git a/examples/tutorials/10_agentic/10_temporal/010_agent_chat/README.md b/examples/tutorials/10_agentic/10_temporal/010_agent_chat/README.md index 3b809817..0940bc46 100644 --- a/examples/tutorials/10_agentic/10_temporal/010_agent_chat/README.md +++ b/examples/tutorials/10_agentic/10_temporal/010_agent_chat/README.md @@ -1,7 +1,28 @@ -# [Agentic] Agent Chat with Temporal +# [Temporal] Agent Chat -This tutorial demonstrates how to implement streaming multiturn tool-enabled chat with tracing using Temporal workflows in AgentEx agents. +## What You'll Learn -## Official Documentation +Combine streaming responses, multi-turn chat, tool calling, and tracing - all with Temporal's durability guarantees. This shows how to build a complete conversational agent that can survive failures. -[010 Agent Chat Temporal Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/temporal/agent_chat/) \ No newline at end of file +**Use case:** Production chatbots with tools, long-running customer service conversations, or any agent that needs both capabilities and reliability. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/10_temporal/010_agent_chat +uv run agentex agents run --manifest manifest.yaml +``` + +## Key Pattern + +- **Streaming**: Progressive response generation with `adk.messages.create()` +- **Multi-turn**: Conversation history maintained in durable workflow state +- **Tools**: Agent can call functions to perform actions +- **Tracing**: Full observability of tool calls and LLM interactions +- **Durability**: All of the above survives worker restarts + +**Monitor:** Open Temporal UI at http://localhost:8080 to see the workflow and all tool call activities. + +## Key Insight + +In base agentic agents, all this state lives in memory and is lost on crash. With Temporal, the entire conversation - history, tool calls, intermediate state - is durably persisted. The agent can pick up a conversation that paused days ago as if no time passed. diff --git a/examples/tutorials/10_agentic/10_temporal/020_state_machine/README.md b/examples/tutorials/10_agentic/10_temporal/020_state_machine/README.md index b1f25661..924f86da 100644 --- a/examples/tutorials/10_agentic/10_temporal/020_state_machine/README.md +++ b/examples/tutorials/10_agentic/10_temporal/020_state_machine/README.md @@ -1,7 +1,51 @@ -# [Agentic] State Machine with Temporal +# [Temporal] State Machine -This tutorial demonstrates how to use state machines to manage complex agentic workflows with Temporal in AgentEx agents. +## What You'll Learn -## Official Documentation +Build complex multi-state workflows using state machines with Temporal. This tutorial shows a "deep research" agent that transitions through states: clarify query → wait for input → perform research → wait for follow-ups. -[020 State Machine Temporal Agentic](https://dev.agentex.scale.com/docs/tutorials/agentic/temporal/state_machine/) \ No newline at end of file +**Use case:** Complex multi-step processes with branching logic, agents that need to orchestrate multiple sub-workflows, or any operation with distinct phases. + +## Quick Start + +```bash +cd examples/tutorials/10_agentic/10_temporal/020_state_machine +uv run agentex agents run --manifest manifest.yaml +``` + +**Monitor:** Open Temporal UI at http://localhost:8080 to see state transitions and sub-workflows. + +## Architecture + +The workflow uses three sub-workflows, each handling a specific state: +- `ClarifyUserQueryWorkflow` - Asks follow-up questions to understand user intent +- `WaitingForUserInputWorkflow` - Waits for user responses +- `PerformingDeepResearchWorkflow` - Executes the research with full context + +State transitions are explicit and tracked, with each sub-workflow handling its own logic. + +## Why State Machines Matter + +Complex agents often need to: +- Wait for user input at specific points +- Branch behavior based on conditions +- Orchestrate multiple steps with clear transitions +- Resume at the exact state after failures + +State machines provide this structure. Each state is a sub-workflow, and Temporal ensures transitions are durable and resumable. + +## Key Pattern + +```python +self.state_machine = DeepResearchStateMachine( + initial_state=DeepResearchState.WAITING_FOR_USER_INPUT, + states=[ + State(name=DeepResearchState.CLARIFYING, workflow=ClarifyWorkflow()), + State(name=DeepResearchState.RESEARCHING, workflow=ResearchWorkflow()), + ] +) + +await self.state_machine.transition(DeepResearchState.RESEARCHING) +``` + +This is an advanced pattern - only needed when your agent has complex, multi-phase behavior. diff --git a/examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails/README.md b/examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails/README.md index 9eb75f98..90341f30 100644 --- a/examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails/README.md +++ b/examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails/README.md @@ -6,6 +6,15 @@ This tutorial demonstrates how to implement streaming multiturn tool-enabled cha This example extends the basic agent chat functionality by adding guardrails that can filter both user inputs and AI outputs. This is useful for content moderation, compliance, or preventing certain topics from being discussed. +## Quick Start + +```bash +cd examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails +uv run agentex agents run --manifest manifest.yaml +``` + +**Monitor:** Open Temporal UI at http://localhost:8080 to see guardrail checks as workflow activities. + ## Guardrails ### Input Guardrails diff --git a/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md b/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md index c46722b8..087ae2af 100644 --- a/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md +++ b/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md @@ -1,317 +1,46 @@ -# example-tutorial - AgentEx Temporal Agent Template - -This is a starter template for building asynchronous agents with the AgentEx 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. +# [Temporal] OpenAI Agents SDK - Hello World ## 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 -agentex agents run --manifest manifest.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 AgentEx 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 OpenAI Agents SDK plugin automatically converts LLM calls into durable Temporal activities. When `Runner.run()` executes, the LLM invocation becomes an `invoke_model_activity` visible in Temporal UI with full observability, automatic retries, and durability. -## The Manifest File +**Key insight:** You don't need to wrap agent calls in activities manually - the plugin handles this automatically, making non-deterministic LLM calls work seamlessly in Temporal workflows. -The `manifest.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 - -``` -example_tutorial/ -├── project/ # Your agent's code -│ ├── __init__.py -│ ├── acp.py # ACP server and event handlers -│ ├── workflow.py # Temporal workflow definitions -│ ├── activities.py # Temporal activity definitions -│ └── run_worker.py # Temporal worker setup -├── Dockerfile # Container definition -├── manifest.yaml # Deployment config -├── dev.ipynb # Development notebook for testing - -└── pyproject.toml # Dependencies (uv) - -``` - -## Development - -### 1. Customize Event Handlers -- Modify the handlers in `acp.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: +## Quick Start ```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 AgentEx 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 (`example-tutorial`) and demonstrates the agentic 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 - - -You chose **uv** for package management. Here's how to work with dependencies: - -```bash -# Add new dependencies -agentex uv add requests openai anthropic - -# Add Temporal-specific dependencies (already included) -agentex uv add temporalio - -# Install/sync dependencies -agentex uv sync - -# Run commands with uv +cd examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world uv run agentex agents run --manifest manifest.yaml ``` -**Benefits of uv:** -- Faster dependency resolution and installation -- Better dependency isolation -- Modern Python packaging standards - - - -### 5. Configure Credentials -- Add any required credentials to your manifest.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 Agentex Backend -```bash -# Navigate to the backend directory -cd agentex - -# 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 -agentex uv sync [--group editable-apy] -source .venv/bin/activate - -# OR -conda create -n example_tutorial python=3.12 -conda activate example_tutorial -pip install -r requirements.txt -``` -### 3. Run Your Agent -```bash -# From this directory -export ENVIRONMENT=development && [uv run] agentex agents run --manifest manifest.yaml -``` -4. **Interact with your agent** +**Monitor:** Open Temporal UI at http://localhost:8080 to see automatic activity creation. -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 -agentex tasks submit --agent example-tutorial --task "Your task here" -``` +## Try It -Option 1: Web UI -```bash -# Start the local web interface -cd agentex-web -make dev - -# Then open http://localhost:3000 in your browser to chat with your agent -``` - -## Development Tips - -### Environment Variables -- Set environment variables in project/.env for any required credentials -- Or configure them in the manifest.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 -agentex agents build --manifest manifest.yaml -``` +1. Send a message to the agent (it responds in haikus) +2. Open Temporal UI at http://localhost:8080 +3. Find your workflow execution +4. Look for the `invoke_model_activity` - this was created automatically +5. Inspect the activity to see: + - Input parameters (your message) + - Output (agent's haiku response) + - Execution time + - Retry attempts (if any failures occurred) -## Advanced Features - -### Temporal Workflows -Extend your agent with sophisticated async workflows: - -```python -# In project/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): +## Key Code ```python -# In project/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 - -```bash -# Add service clients -agentex uv add httpx requests-oauthlib - -# Add AI/ML libraries -agentex uv add openai anthropic transformers - -# Add database clients -agentex uv add asyncpg redis +# This simple call automatically becomes a durable Temporal activity: +agent = Agent(name="Haiku Assistant", instructions="...") +result = await Runner.run(agent, user_message) ``` +The magic happens behind the scenes - no manual activity wrapping needed. The conversation is now durable and survives process restarts. -## 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** - - - Run `agentex uv sync` to ensure all dependencies are installed - - Verify temporalio is properly installed - - -4. **Port conflicts** - - Check if another service is using port 8000 - - Use `lsof -i :8000` to find conflicting processes - -### Temporal-Specific Troubleshooting +## Why This Matters -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 +**Durability:** If your worker crashes mid-conversation, Temporal resumes exactly where it left off. No lost context, no repeated work. -2. **Activity failures** - - Check activity logs in the console - - Verify activity registration - - Check for timeout issues +**Observability:** Every LLM call is tracked as an activity with full execution history. -Happy building with Temporal! 🚀⚡ \ No newline at end of file +**Reliability:** Failed LLM calls are automatically retried with exponential backoff. diff --git a/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md b/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md index c46722b8..76713b15 100644 --- a/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md +++ b/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md @@ -1,317 +1,60 @@ -# example-tutorial - AgentEx Temporal Agent Template - -This is a starter template for building asynchronous agents with the AgentEx 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. +# [Temporal] OpenAI Agents SDK - Tools ## 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 -agentex agents run --manifest manifest.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 AgentEx 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 Manifest File - -The `manifest.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 - -``` -example_tutorial/ -├── project/ # Your agent's code -│ ├── __init__.py -│ ├── acp.py # ACP server and event handlers -│ ├── workflow.py # Temporal workflow definitions -│ ├── activities.py # Temporal activity definitions -│ └── run_worker.py # Temporal worker setup -├── Dockerfile # Container definition -├── manifest.yaml # Deployment config -├── dev.ipynb # Development notebook for testing - -└── pyproject.toml # Dependencies (uv) - -``` - -## Development +Two patterns for making agent tools durable with Temporal: -### 1. Customize Event Handlers -- Modify the handlers in `acp.py` to implement your agent's logic -- Add your own tools and capabilities -- Implement custom state management +**Pattern 1: `activity_as_tool()`** - Single activity per tool call +- Use for: Single API calls, DB queries, external operations +- Example: `get_weather` tool → creates one `get_weather` activity +- 1:1 mapping between tool calls and activities -### 2. Test Your Agent with the Development Notebook -Use the included `dev.ipynb` Jupyter notebook to test your agent interactively: +**Pattern 2: Function tools with multiple activities** - Multiple activities per tool call +- Use for: Multi-step operations needing guaranteed sequencing +- Example: `move_money` tool → creates `withdraw_money` activity THEN `deposit_money` activity +- 1:many mapping - your code controls execution order, not the LLM +- Ensures atomic operations (withdraw always happens before deposit) -```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 AgentEx 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 (`example-tutorial`) and demonstrates the agentic 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 - - -You chose **uv** for package management. Here's how to work with dependencies: +## Quick Start ```bash -# Add new dependencies -agentex uv add requests openai anthropic - -# Add Temporal-specific dependencies (already included) -agentex uv add temporalio - -# Install/sync dependencies -agentex uv sync - -# Run commands with uv +cd examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools uv run agentex agents run --manifest manifest.yaml ``` -**Benefits of uv:** -- Faster dependency resolution and installation -- Better dependency isolation -- Modern Python packaging standards - - - -### 5. Configure Credentials -- Add any required credentials to your manifest.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 Agentex Backend -```bash -# Navigate to the backend directory -cd agentex - -# 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 -agentex uv sync [--group editable-apy] -source .venv/bin/activate - -# OR -conda create -n example_tutorial python=3.12 -conda activate example_tutorial -pip install -r requirements.txt -``` -### 3. Run Your Agent -```bash -# From this directory -export ENVIRONMENT=development && [uv run] agentex agents run --manifest manifest.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 -agentex tasks submit --agent example-tutorial --task "Your task here" -``` - -Option 1: Web UI -```bash -# Start the local web interface -cd agentex-web -make dev - -# Then open http://localhost:3000 in your browser to chat with your agent -``` - -## Development Tips - -### Environment Variables -- Set environment variables in project/.env for any required credentials -- Or configure them in the manifest.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): +**Monitor:** Open Temporal UI at http://localhost:8080 to see tool calls as activities. -1. Build the agent image: -```bash -agentex agents build --manifest manifest.yaml -``` - -## Advanced Features +## Try It -### Temporal Workflows -Extend your agent with sophisticated async workflows: +**Pattern 1 (implemented):** Ask "What's the weather in San Francisco?" +- Open Temporal UI (localhost:8080) +- See a single `get_weather` activity created +- The activity shows the external call with retry capability -```python -# In project/workflow.py -@workflow.defn -class MyWorkflow(BaseWorkflow): - async def complex_operation(self): - # Multi-step async operations - # Error handling and retries - # State management - pass -``` +**Pattern 2 (commented out in code):** Uncomment the `move_money` section, then ask to move money +- See TWO sequential activities: `withdraw_money` → `deposit_money` +- If the system crashes after withdraw but before deposit, Temporal resumes exactly where it left off +- The deposit will still happen - guaranteed transactional integrity -### Custom Activities -Add custom activities for external operations. **Important**: Always specify appropriate timeouts (recommended: 10 minutes): +## Key Code ```python -# In project/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 +# Pattern 1: Direct activity conversion +weather_agent = Agent( + tools=[ + activity_as_tool(get_weather, start_to_close_timeout=timedelta(seconds=10)) + ] ) -# 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 - -```bash -# Add service clients -agentex uv add httpx requests-oauthlib - -# Add AI/ML libraries -agentex uv add openai anthropic transformers - -# Add database clients -agentex uv add asyncpg redis +# Pattern 2: Function tool coordinating multiple activities (see code for full example) +# The tool internally calls workflow.start_activity_method() multiple times +# guaranteeing the sequence and making each step durable ``` +## Why This Matters -## 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** - - - Run `agentex uv sync` to ensure all dependencies are installed - - Verify temporalio is properly installed - - -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 +**Without Temporal:** If you withdraw money but crash before depositing, you're stuck in a broken state. The money is gone from the source account with no way to recover. -2. **Activity failures** - - Check activity logs in the console - - Verify activity registration - - Check for timeout issues +**With Temporal:** Guaranteed execution with exact resumption after failures. Either both operations complete, or the workflow can handle partial completion. This is what makes agents production-ready for real-world operations like financial transactions, order fulfillment, or any multi-step process. -Happy building with Temporal! 🚀⚡ \ No newline at end of file +**Key insight:** Pattern 2 moves sequencing control from the LLM (which might call tools in wrong order) to your deterministic code (which guarantees correct order). diff --git a/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md b/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md index c46722b8..74814d3b 100644 --- a/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md +++ b/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md @@ -1,317 +1,67 @@ -# example-tutorial - AgentEx Temporal Agent Template - -This is a starter template for building asynchronous agents with the AgentEx 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. +# [Temporal] OpenAI Agents SDK - Human in the Loop ## 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 -agentex agents run --manifest manifest.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 AgentEx 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 Manifest File - -The `manifest.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 - -``` -example_tutorial/ -├── project/ # Your agent's code -│ ├── __init__.py -│ ├── acp.py # ACP server and event handlers -│ ├── workflow.py # Temporal workflow definitions -│ ├── activities.py # Temporal activity definitions -│ └── run_worker.py # Temporal worker setup -├── Dockerfile # Container definition -├── manifest.yaml # Deployment config -├── dev.ipynb # Development notebook for testing - -└── pyproject.toml # Dependencies (uv) - -``` - -## Development +How to pause agent execution and wait indefinitely for human approval using Temporal's child workflows and signals. The agent can wait for hours, days, or weeks for human input without consuming resources - and if the system crashes, it resumes exactly where it left off. -### 1. Customize Event Handlers -- Modify the handlers in `acp.py` to implement your agent's logic -- Add your own tools and capabilities -- Implement custom state management +**Pattern:** +1. Agent calls `wait_for_confirmation` tool +2. Tool spawns a child workflow that waits for a signal +3. Human approves/rejects via Temporal CLI or web UI +4. Child workflow completes, agent continues with the response -### 2. Test Your Agent with the Development Notebook -Use the included `dev.ipynb` Jupyter notebook to test your agent interactively: +## Quick Start ```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 AgentEx 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 (`example-tutorial`) and demonstrates the agentic 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 - - -You chose **uv** for package management. Here's how to work with dependencies: - -```bash -# Add new dependencies -agentex uv add requests openai anthropic - -# Add Temporal-specific dependencies (already included) -agentex uv add temporalio - -# Install/sync dependencies -agentex uv sync - -# Run commands with uv +cd examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop uv run agentex agents run --manifest manifest.yaml ``` -**Benefits of uv:** -- Faster dependency resolution and installation -- Better dependency isolation -- Modern Python packaging standards - +**Monitor:** Open Temporal UI at http://localhost:8080 to see child workflows and signals. +## Try It -### 5. Configure Credentials -- Add any required credentials to your manifest.yaml -- For local development, create a `.env` file in the project directory -- Use `load_dotenv()` only in development mode: +1. Ask the agent to do something that requires approval (e.g., "Order 100 widgets") +2. The agent will call `wait_for_confirmation` and pause +3. Open Temporal UI (localhost:8080) and find the child workflow ID +4. Send approval signal via CLI: -```python -import os -from dotenv import load_dotenv - -if os.environ.get("ENVIRONMENT") == "development": - load_dotenv() -``` - -## Local Development - -### 1. Start the Agentex Backend ```bash -# Navigate to the backend directory -cd agentex - -# Start all services using Docker Compose -make dev - -# Optional: In a separate terminal, use lazydocker for a better UI (everything should say "healthy") -lzd +temporal workflow signal \ + --workflow-id="" \ + --name="fulfill_order_signal" \ + --input=true ``` -### 2. Setup Your Agent's requirements/pyproject.toml -```bash -agentex uv sync [--group editable-apy] -source .venv/bin/activate +5. The agent resumes and completes the action -# OR -conda create -n example_tutorial python=3.12 -conda activate example_tutorial -pip install -r requirements.txt -``` -### 3. Run Your Agent -```bash -# From this directory -export ENVIRONMENT=development && [uv run] agentex agents run --manifest manifest.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 -agentex tasks submit --agent example-tutorial --task "Your task here" -``` - -Option 1: Web UI -```bash -# Start the local web interface -cd agentex-web -make dev - -# Then open http://localhost:3000 in your browser to chat with your agent -``` - -## Development Tips - -### Environment Variables -- Set environment variables in project/.env for any required credentials -- Or configure them in the manifest.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 -agentex agents build --manifest manifest.yaml -``` - -## Advanced Features - -### Temporal Workflows -Extend your agent with sophisticated async workflows: +## Key Code ```python -# In project/workflow.py -@workflow.defn -class MyWorkflow(BaseWorkflow): - async def complex_operation(self): - # Multi-step async operations - # Error handling and retries - # State management - pass +# Tool that spawns child workflow for human approval +@function_tool +async def wait_for_confirmation(request: str) -> str: + child_workflow_id = f"approval-{workflow.uuid4()}" + + # Spawn child workflow that waits for signal + await workflow.start_child_workflow( + ConfirmationWorkflow.run, + id=child_workflow_id, + ) + + # Wait for human to send signal + approved = await workflow.wait_condition(...) + return "Approved!" if approved else "Rejected" ``` -### Custom Activities -Add custom activities for external operations. **Important**: Always specify appropriate timeouts (recommended: 10 minutes): - -```python -# In project/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 - -```bash -# Add service clients -agentex uv add httpx requests-oauthlib - -# Add AI/ML libraries -agentex uv add openai anthropic transformers - -# Add database clients -agentex uv add asyncpg redis -``` - - -## 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** - - - Run `agentex uv sync` to ensure all dependencies are installed - - Verify temporalio is properly installed - - -4. **Port conflicts** - - Check if another service is using port 8000 - - Use `lsof -i :8000` to find conflicting processes - -### Temporal-Specific Troubleshooting +## Why This Matters -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 +**Without Temporal:** If your system crashes while waiting for human approval, you lose all context about what was being approved. The user has to start over. -2. **Activity failures** - - Check activity logs in the console - - Verify activity registration - - Check for timeout issues +**With Temporal:** The workflow waits durably. If the system crashes and restarts days later, the moment a human sends approval, the workflow resumes exactly where it left off with full context. -Happy building with Temporal! 🚀⚡ \ No newline at end of file +This enables real production patterns like: +- Financial transaction approvals +- Legal document reviews +- Multi-step purchasing workflows +- Any operation requiring human judgment in the loop From 3aff9ff6d3f3b6455ff0b956275d7f66a9531c67 Mon Sep 17 00:00:00 2001 From: Jason Yang Date: Thu, 16 Oct 2025 21:26:25 -0700 Subject: [PATCH 2/4] Adding cahnges to openai agents temporal sdk tutorials --- .../README.md | 57 ++++++- .../070_open_ai_agents_sdk_tools/README.md | 130 ++++++++++++-- .../README.md | 159 +++++++++++++++--- 3 files changed, 308 insertions(+), 38 deletions(-) diff --git a/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md b/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md index 087ae2af..10eaff31 100644 --- a/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md +++ b/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md @@ -1,11 +1,53 @@ # [Temporal] OpenAI Agents SDK - Hello World +**Part of the [OpenAI SDK + Temporal integration series](../README.md)** + ## What You'll Learn The OpenAI Agents SDK plugin automatically converts LLM calls into durable Temporal activities. When `Runner.run()` executes, the LLM invocation becomes an `invoke_model_activity` visible in Temporal UI with full observability, automatic retries, and durability. **Key insight:** You don't need to wrap agent calls in activities manually - the plugin handles this automatically, making non-deterministic LLM calls work seamlessly in Temporal workflows. +## Prerequisites + +1. Agentex backend running with Temporal (`make dev` in agentex repo) +2. OpenAI API key configured (see setup below) + +## Setup + +This tutorial uses the OpenAI Agents SDK plugin, which needs to be added in two places: + +### 1. Add Plugin to ACP (`project/acp.py`) +```python +from agentex.lib.plugins.openai_agents import OpenAIAgentsPlugin + +acp = FastACP.create( + config=TemporalACPConfig( + plugins=[OpenAIAgentsPlugin()] # Add this + ) +) +``` + +### 2. Add Plugin to Worker (`project/run_worker.py`) +```python +from agentex.lib.plugins.openai_agents import OpenAIAgentsPlugin + +worker = AgentexWorker( + task_queue=task_queue_name, + plugins=[OpenAIAgentsPlugin()], # Add this +) +``` + +### 3. Configure OpenAI API Key +Add to `manifest.yaml`: +```yaml +secrets: + - name: OPENAI_API_KEY + value: "your-openai-api-key-here" +``` + +Or set in `.env` file: `OPENAI_API_KEY=your-key-here` + ## Quick Start ```bash @@ -18,10 +60,17 @@ uv run agentex agents run --manifest manifest.yaml ## Try It 1. Send a message to the agent (it responds in haikus) -2. Open Temporal UI at http://localhost:8080 -3. Find your workflow execution -4. Look for the `invoke_model_activity` - this was created automatically -5. Inspect the activity to see: +2. Check the agent response: + +![Agent Response](../_images/hello_world_response.png) + +3. Open Temporal UI at http://localhost:8080 +4. Find your workflow execution +5. Look for the `invoke_model_activity` - this was created automatically: + +![Temporal UI](../_images/hello_world_temporal.png) + +6. Inspect the activity to see: - Input parameters (your message) - Output (agent's haiku response) - Execution time diff --git a/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md b/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md index 76713b15..841019f3 100644 --- a/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md +++ b/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md @@ -1,5 +1,7 @@ # [Temporal] OpenAI Agents SDK - Tools +**Part of the [OpenAI SDK + Temporal integration series](../README.md)** → Previous: [060 Hello World](../060_open_ai_agents_sdk_hello_world/) + ## What You'll Learn Two patterns for making agent tools durable with Temporal: @@ -15,6 +17,10 @@ Two patterns for making agent tools durable with Temporal: - 1:many mapping - your code controls execution order, not the LLM - Ensures atomic operations (withdraw always happens before deposit) +## Prerequisites + +See [Hello World tutorial](../060_open_ai_agents_sdk_hello_world/) for basic setup of the OpenAI Agents SDK plugin. + ## Quick Start ```bash @@ -26,35 +32,131 @@ uv run agentex agents run --manifest manifest.yaml ## Try It -**Pattern 1 (implemented):** Ask "What's the weather in San Francisco?" -- Open Temporal UI (localhost:8080) -- See a single `get_weather` activity created -- The activity shows the external call with retry capability +### Pattern 1: Single Activity Tool + +Ask "What's the weather in San Francisco?" + +1. Check the agent response: + +![Weather Response](../_images/weather_response.png) + +2. Open Temporal UI (localhost:8080) +3. See a single `get_weather` activity created: + +![Weather Activity](../_images/weather_activity_tool.png) + +The activity shows the external call with retry capability. Each step (model invocation → tool call → model invocation) is durable. + +### Pattern 2: Multi-Activity Tool (Optional) + +To try the advanced banking example, uncomment the `move_money` sections in the code, then ask to move money. + +1. Check the agent response: -**Pattern 2 (commented out in code):** Uncomment the `move_money` section, then ask to move money -- See TWO sequential activities: `withdraw_money` → `deposit_money` -- If the system crashes after withdraw but before deposit, Temporal resumes exactly where it left off -- The deposit will still happen - guaranteed transactional integrity +![Money Transfer Response](../_images/move_money_response.png) + +2. Open Temporal UI and see TWO sequential activities: + +![Money Transfer Workflow](../_images/move_money_temporal.png) + +- First: `withdraw_money` activity executes +- Then: `deposit_money` activity executes +- Each activity shows its parameters and execution time + +**Critical insight:** If the system crashes after withdraw but before deposit, Temporal resumes exactly where it left off. The deposit will still happen - guaranteed transactional integrity. ## Key Code +### Pattern 1: Single Activity Tool ```python -# Pattern 1: Direct activity conversion +# Define the activity +@activity.defn +async def get_weather(city: str) -> str: + """Get the weather for a given city""" + # This could be an API call - Temporal handles retries + return f"The weather in {city} is sunny" + +# Use activity_as_tool to convert it weather_agent = Agent( + name="Weather Assistant", + instructions="Use the get_weather tool to answer weather questions.", tools=[ activity_as_tool(get_weather, start_to_close_timeout=timedelta(seconds=10)) ] ) +``` -# Pattern 2: Function tool coordinating multiple activities (see code for full example) -# The tool internally calls workflow.start_activity_method() multiple times -# guaranteeing the sequence and making each step durable +### Pattern 2: Multi-Activity Tool +```python +# Define individual activities +@activity.defn +async def withdraw_money(from_account: str, amount: float) -> str: + # Simulate API call + await asyncio.sleep(5) + return f"Withdrew ${amount} from {from_account}" + +@activity.defn +async def deposit_money(to_account: str, amount: float) -> str: + # Simulate API call + await asyncio.sleep(10) + return f"Deposited ${amount} into {to_account}" + +# Create a function tool that orchestrates both activities +@function_tool +async def move_money(from_account: str, to_account: str, amount: float) -> str: + """Move money from one account to another""" + + # Step 1: Withdraw (becomes an activity) + await workflow.start_activity( + "withdraw_money", + args=[from_account, amount], + start_to_close_timeout=timedelta(days=1) + ) + + # Step 2: Deposit (becomes an activity) + await workflow.start_activity( + "deposit_money", + args=[to_account, amount], + start_to_close_timeout=timedelta(days=1) + ) + + return "Money transferred successfully" + +# Use the tool in your agent +money_agent = Agent( + name="Money Mover", + instructions="Use move_money to transfer funds between accounts.", + tools=[move_money] +) ``` +## When to Use Each Pattern + +### Use Pattern 1 when: +- Tool performs a single external operation (API call, DB query) +- Operation is already idempotent +- No sequencing guarantees needed + +### Use Pattern 2 when: +- Tool requires multiple sequential operations +- Order must be guaranteed (withdraw THEN deposit) +- Operations need to be atomic from the agent's perspective +- You want transactional integrity across steps + ## Why This Matters **Without Temporal:** If you withdraw money but crash before depositing, you're stuck in a broken state. The money is gone from the source account with no way to recover. -**With Temporal:** Guaranteed execution with exact resumption after failures. Either both operations complete, or the workflow can handle partial completion. This is what makes agents production-ready for real-world operations like financial transactions, order fulfillment, or any multi-step process. +**With Temporal (Pattern 2):** +- Guaranteed execution with exact resumption after failures +- If the system crashes after withdraw, Temporal resumes and completes deposit +- Each step is tracked and retried independently +- Full observability of the entire operation + +**Key insight:** Pattern 2 moves sequencing control from the LLM (which might call tools in wrong order) to your deterministic code (which guarantees correct order). The LLM still decides *when* to call the tool, but your code controls *how* the operations execute. -**Key insight:** Pattern 2 moves sequencing control from the LLM (which might call tools in wrong order) to your deterministic code (which guarantees correct order). +This makes agents production-ready for: +- Financial transactions +- Order fulfillment workflows +- Multi-step API integrations +- Any operation where partial completion is dangerous diff --git a/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md b/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md index 74814d3b..afd14e32 100644 --- a/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md +++ b/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md @@ -1,5 +1,7 @@ # [Temporal] OpenAI Agents SDK - Human in the Loop +**Part of the [OpenAI SDK + Temporal integration series](../README.md)** → Previous: [070 Tools](../070_open_ai_agents_sdk_tools/) + ## What You'll Learn How to pause agent execution and wait indefinitely for human approval using Temporal's child workflows and signals. The agent can wait for hours, days, or weeks for human input without consuming resources - and if the system crashes, it resumes exactly where it left off. @@ -10,6 +12,44 @@ How to pause agent execution and wait indefinitely for human approval using Temp 3. Human approves/rejects via Temporal CLI or web UI 4. Child workflow completes, agent continues with the response +## New Temporal Concepts + +### Signals +Signals are a way for external systems to interact with running workflows. Think of them as secure, durable messages sent to your workflow from the outside world. + +**Use cases:** +- User approving/rejecting an action in a web app +- Payment confirmation triggering shipping +- Live data feeds (stock prices) triggering trades +- Webhooks from external services updating workflow state + +**How it works:** Define a function in your workflow class with the `@workflow.signal` decorator. External systems can then send signals using: +- Temporal SDK (by workflow ID) +- Another Temporal workflow +- Temporal CLI +- Temporal Web UI + +[Learn more about signals](https://docs.temporal.io/develop/python/message-passing#send-signal-from-client) + +### Child Workflows +Child workflows are like spawning a new workflow from within your current workflow. Similar to calling a function in traditional programming, but the child workflow: +- Runs independently with its own execution history +- Inherits all Temporal durability guarantees +- Can be monitored separately in Temporal UI +- Continues running even if the parent has issues + +**Why use child workflows for human-in-the-loop?** +- The parent workflow can continue processing while waiting +- The child workflow can wait indefinitely for human input +- Full isolation between waiting logic and main agent logic +- Clean separation of concerns + +[Learn more about child workflows](https://docs.temporal.io/develop/python/child-workflows) + +## Prerequisites + +See [Hello World tutorial](../060_open_ai_agents_sdk_hello_world/) for basic setup of the OpenAI Agents SDK plugin. + ## Quick Start ```bash @@ -23,8 +63,16 @@ uv run agentex agents run --manifest manifest.yaml 1. Ask the agent to do something that requires approval (e.g., "Order 100 widgets") 2. The agent will call `wait_for_confirmation` and pause -3. Open Temporal UI (localhost:8080) and find the child workflow ID -4. Send approval signal via CLI: +3. Open Temporal UI (localhost:8080) +4. Find the parent workflow - you'll see it's waiting on the child workflow: + +![Parent Workflow Waiting](../_images/human_in_the_loop_workflow.png) + +5. Find the child workflow - it's waiting for a signal: + +![Child Workflow Waiting](../_images/human_in_the_loop_child_workflow.png) + +6. Send approval signal via CLI: ```bash temporal workflow signal \ @@ -33,35 +81,106 @@ temporal workflow signal \ --input=true ``` -5. The agent resumes and completes the action +7. Watch both workflows complete - the agent resumes and finishes the action ## Key Code +### The Tool: Spawning a Child Workflow ```python -# Tool that spawns child workflow for human approval -@function_tool -async def wait_for_confirmation(request: str) -> str: - child_workflow_id = f"approval-{workflow.uuid4()}" +from agents import function_tool +from temporalio import workflow +from project.child_workflow import ChildWorkflow +from temporalio.workflow import ParentClosePolicy - # Spawn child workflow that waits for signal - await workflow.start_child_workflow( - ConfirmationWorkflow.run, - id=child_workflow_id, +@function_tool +async def wait_for_confirmation(confirmation: bool) -> str: + """Wait for human confirmation before proceeding""" + + # Spawn a child workflow that will wait for a signal + result = await workflow.execute_child_workflow( + ChildWorkflow.on_task_create, + environment_variables.WORKFLOW_NAME + "_child", + id="child-workflow-id", + parent_close_policy=ParentClosePolicy.TERMINATE, ) - # Wait for human to send signal - approved = await workflow.wait_condition(...) - return "Approved!" if approved else "Rejected" + return result +``` + +### The Child Workflow: Waiting for Signals +```python +import asyncio +from temporalio import workflow + +@workflow.defn(name=environment_variables.WORKFLOW_NAME + "_child") +class ChildWorkflow(): + def __init__(self): + # Queue to hold signals + self._pending_confirmation: asyncio.Queue[bool] = asyncio.Queue() + + @workflow.run + async def on_task_create(self, name: str) -> str: + logger.info(f"Child workflow started: {name}") + + # Wait indefinitely until we receive a signal + await workflow.wait_condition( + lambda: not self._pending_confirmation.empty() + ) + + # Signal received - complete the workflow + return "Task completed" + + @workflow.signal + async def fulfill_order_signal(self, success: bool) -> None: + """External systems call this to approve/reject""" + if success: + await self._pending_confirmation.put(True) +``` + +### Using the Tool in Your Agent +```python +confirm_order_agent = Agent( + name="Confirm Order", + instructions="When user asks to confirm an order, use wait_for_confirmation tool.", + tools=[wait_for_confirmation] +) + +result = await Runner.run(confirm_order_agent, params.event.content.content) ``` +## How It Works + +1. **Agent calls tool**: The LLM decides to call `wait_for_confirmation` +2. **Child workflow spawned**: A new workflow is created with its own ID +3. **Child waits**: Uses `workflow.wait_condition()` to block until signal arrives +4. **Parent waits**: Parent workflow is blocked waiting for child to complete +5. **Signal sent**: External system (CLI, web app, API) sends signal with workflow ID +6. **Signal received**: Child workflow's `fulfill_order_signal()` method is called +7. **Queue updated**: Signal handler adds item to queue +8. **Wait condition satisfied**: `wait_condition()` unblocks +9. **Child completes**: Returns result to parent +10. **Parent resumes**: Agent continues with the response + +**Critical insight:** At any point, if the system crashes: +- Both workflows are durable and will resume +- No context is lost +- The moment the signal arrives, execution continues + ## Why This Matters **Without Temporal:** If your system crashes while waiting for human approval, you lose all context about what was being approved. The user has to start over. -**With Temporal:** The workflow waits durably. If the system crashes and restarts days later, the moment a human sends approval, the workflow resumes exactly where it left off with full context. +**With Temporal:** +- The workflow waits durably (hours, days, weeks) +- If the system crashes and restarts, context is preserved +- The moment a human sends approval, workflow resumes exactly where it left off +- Full audit trail of who approved what and when + +**Production use cases:** +- **Financial transactions**: Agent initiates transfer, human approves +- **Legal document processing**: AI extracts data, lawyer reviews +- **Multi-step purchasing**: Agent negotiates, manager approves +- **Compliance workflows**: System flags issue, human decides action +- **High-stakes decisions**: Any operation requiring human judgment -This enables real production patterns like: -- Financial transaction approvals -- Legal document reviews -- Multi-step purchasing workflows -- Any operation requiring human judgment in the loop +This pattern transforms agents from fully automated systems into **collaborative AI assistants** that know when to ask for help. From b980b45c14ef65fa378d7c74b2afdb6bc91c3823 Mon Sep 17 00:00:00 2001 From: Jason Yang Date: Fri, 31 Oct 2025 09:31:55 -0700 Subject: [PATCH 3/4] Cleanup tutorials --- .../tutorials/00_sync/000_hello_acp/README.md | 22 +- .../tutorials/00_sync/010_multiturn/README.md | 22 +- .../tutorials/00_sync/020_streaming/README.md | 23 +- .../00_base/000_hello_acp/README.md | 23 +- .../00_base/010_multiturn/README.md | 51 ++- .../00_base/020_streaming/README.md | 23 +- .../10_agentic/00_base/030_tracing/README.md | 24 +- .../00_base/040_other_sdks/README.md | 24 +- .../00_base/080_batch_events/README.md | 24 +- .../090_multi_agent_non_temporal/README.md | 17 +- .../10_temporal/000_hello_acp/README.md | 26 +- .../10_temporal/010_agent_chat/README.md | 27 +- .../10_temporal/020_state_machine/README.md | 27 +- .../030_custom_activities/README.md | 333 ++++-------------- .../050_agent_chat_guardrails/README.md | 29 +- .../README.md | 20 +- .../070_open_ai_agents_sdk_tools/README.md | 26 +- .../README.md | 21 +- 18 files changed, 436 insertions(+), 326 deletions(-) diff --git a/examples/tutorials/00_sync/000_hello_acp/README.md b/examples/tutorials/00_sync/000_hello_acp/README.md index c450d085..ac7f1c63 100644 --- a/examples/tutorials/00_sync/000_hello_acp/README.md +++ b/examples/tutorials/00_sync/000_hello_acp/README.md @@ -1,10 +1,15 @@ # [Sync] Hello ACP -## What You'll Learn - The simplest agent type: synchronous request/response pattern with a single `@acp.on_message_send` handler. Best for stateless operations that complete immediately. -**When to use sync:** Quick responses, no long-running operations, no need for task management or durability. +## What You'll Learn +- Building a basic synchronous agent +- The `@acp.on_message_send` handler pattern +- When to use sync vs agentic agents + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root ## Quick Start @@ -25,3 +30,14 @@ async def handle_message_send(params: SendMessageParams): ``` That's it - one handler, immediate response. No task creation, no state management. + +## When to Use +- Simple chatbots with no memory requirements +- Quick Q&A or information lookup agents +- Prototyping and testing agent responses +- Operations that complete in under a second + +## Why This Matters +Sync agents are the simplest way to get started with AgentEx. They're perfect for learning the basics and building stateless agents. Once you need conversation memory or task tracking, you'll graduate to agentic agents. + +**Next:** [010_multiturn](../010_multiturn/) - Add conversation memory to your agent diff --git a/examples/tutorials/00_sync/010_multiturn/README.md b/examples/tutorials/00_sync/010_multiturn/README.md index bbb07add..92abab5f 100644 --- a/examples/tutorials/00_sync/010_multiturn/README.md +++ b/examples/tutorials/00_sync/010_multiturn/README.md @@ -1,10 +1,16 @@ # [Sync] Multiturn -## What You'll Learn +Handle multi-turn conversations in synchronous agents by manually maintaining conversation history and context between messages. -Handle multi-turn conversations in synchronous agents by maintaining conversation history and context between messages. +## What You'll Learn +- How to handle conversation history in sync agents +- Building context from previous messages +- The limitations of stateless multiturn patterns -**Use case:** Chatbots that need to reference previous messages within the same session. +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Understanding of basic sync agents (see [000_hello_acp](../000_hello_acp/)) ## Quick Start @@ -36,3 +42,13 @@ async def handle_message_send(params: SendMessageParams): ``` The handler accepts history, builds context, and returns responses that reference previous exchanges. + +## When to Use +- Simple chatbots that need conversation memory +- When client can maintain and send conversation history +- Quick prototypes before building full agentic agents + +## Why This Matters +While sync agents can handle conversations, you're responsible for managing state on the client side. This becomes complex quickly. For production conversational agents, consider agentic agents ([10_agentic/00_base/010_multiturn](../../10_agentic/00_base/010_multiturn/)) where the platform manages state automatically. + +**Next:** [020_streaming](../020_streaming/) - Stream responses in real-time diff --git a/examples/tutorials/00_sync/020_streaming/README.md b/examples/tutorials/00_sync/020_streaming/README.md index 37d995ae..0204bf37 100644 --- a/examples/tutorials/00_sync/020_streaming/README.md +++ b/examples/tutorials/00_sync/020_streaming/README.md @@ -1,10 +1,16 @@ # [Sync] Streaming -## What You'll Learn - Stream responses progressively using async generators instead of returning a single message. Enables showing partial results as they're generated. -**Use case:** LLM responses, large data processing, or any operation where you want to show progress. +## What You'll Learn +- How to stream responses using async generators +- The `yield` pattern for progressive updates +- When streaming improves user experience + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Understanding of basic sync agents (see [000_hello_acp](../000_hello_acp/)) ## Quick Start @@ -26,3 +32,14 @@ async def handle_message_send(params: SendMessageParams): ``` Return an async generator instead of a single response - each `yield` sends an update to the client. + +## When to Use +- Streaming LLM responses (OpenAI, Anthropic, etc.) +- Large data processing with progress updates +- Any operation that takes >1 second to complete +- Improving perceived responsiveness + +## Why This Matters +Streaming dramatically improves user experience for longer operations. Instead of waiting 10 seconds for a complete response, users see results immediately as they're generated. This is essential for modern AI agents. + +**Next:** Ready for task management? → [10_agentic/00_base/000_hello_acp](../../10_agentic/00_base/000_hello_acp/) diff --git a/examples/tutorials/10_agentic/00_base/000_hello_acp/README.md b/examples/tutorials/10_agentic/00_base/000_hello_acp/README.md index 3b4be8a2..59bf95d6 100644 --- a/examples/tutorials/10_agentic/00_base/000_hello_acp/README.md +++ b/examples/tutorials/10_agentic/00_base/000_hello_acp/README.md @@ -1,10 +1,16 @@ # [Agentic] Hello ACP -## What You'll Learn - Agentic agents use three handlers for async task management: `on_task_create`, `on_task_event_send`, and `on_task_cancel`. Unlike sync agents, tasks persist and can receive multiple events over time. -**When to use agentic:** Long-running conversations, stateful operations, or when you need task lifecycle management. +## What You'll Learn +- The three-handler pattern for agentic agents +- How tasks differ from sync messages +- When to use agentic vs sync agents + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Understanding of sync agents (see [00_sync/000_hello_acp](../../../00_sync/000_hello_acp/)) ## Quick Start @@ -30,3 +36,14 @@ async def handle_task_cancel(params: CancelTaskParams): ``` Three handlers instead of one, giving you full control over task lifecycle. Tasks can receive multiple events and maintain state across them. + +## When to Use +- Conversational agents that need memory +- Operations that require task tracking +- Agents that need lifecycle management (initialization, cleanup) +- Building towards production systems + +## Why This Matters +The task-based model is the foundation of production agents. Unlike sync agents where each message is independent, agentic agents maintain persistent tasks that can receive multiple events, store state, and have full lifecycle management. This is the stepping stone to Temporal-based agents. + +**Next:** [010_multiturn](../010_multiturn/) - Add conversation memory diff --git a/examples/tutorials/10_agentic/00_base/010_multiturn/README.md b/examples/tutorials/10_agentic/00_base/010_multiturn/README.md index 304faa10..6c7b3a4f 100644 --- a/examples/tutorials/10_agentic/00_base/010_multiturn/README.md +++ b/examples/tutorials/10_agentic/00_base/010_multiturn/README.md @@ -1,10 +1,16 @@ # [Agentic] Multiturn -## What You'll Learn +Handle multi-turn conversations in agentic agents with task-based state management. Each task maintains its own conversation history automatically. -Handle multi-turn conversations in agentic agents with task-based state management. Each task maintains its own conversation history. +## What You'll Learn +- How tasks maintain conversation state across multiple exchanges +- Difference between sync and agentic multiturn patterns +- Building stateful conversational agents with minimal code -**Use case:** Conversational agents that need to remember context across multiple exchanges within a task. +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Understanding of basic agentic agents (see [000_hello_acp](../000_hello_acp/)) ## Quick Start @@ -15,4 +21,41 @@ uv run agentex agents run --manifest manifest.yaml ## Key Pattern -In sync agents, you manually pass conversation history. In agentic agents, the task itself maintains state across multiple `on_task_event_send` calls, making it easier to build stateful conversations. +Unlike sync agents where you manually track conversation history, agentic agents automatically maintain state within each task: + +```python +@app.on_task_event_send() +async def on_task_event_send(event_send: TaskEventSendInput): + # The task's messages list automatically includes all previous exchanges + messages = event_send.task.messages + + # No need to manually pass history - it's already there! + response = await openai_client.chat.completions.create( + model="gpt-4o-mini", + messages=messages + ) + + return {"content": response.choices[0].message.content} +``` + +## Try It + +1. Start the agent with the command above +2. Open the web UI or use the notebook to create a task +3. Send multiple messages in the same task: + - "What's 25 + 17?" + - "What was that number again?" + - "Multiply it by 2" +4. Notice the agent remembers context from previous exchanges + +## When to Use +- Conversational agents that need memory across exchanges +- Chat interfaces where users ask follow-up questions +- Agents that build context over time within a session + +## Why This Matters +Task-based state management eliminates the complexity of manually tracking conversation history. The AgentEx platform handles state persistence automatically, making it easier to build stateful agents without custom session management code. + +**Comparison:** In the sync version ([00_sync/010_multiturn](../../../00_sync/010_multiturn/)), you manually manage conversation history. Here, the task object does it for you. + +**Next:** [020_streaming](../020_streaming/) - Add real-time streaming responses diff --git a/examples/tutorials/10_agentic/00_base/020_streaming/README.md b/examples/tutorials/10_agentic/00_base/020_streaming/README.md index 518d8358..43026b42 100644 --- a/examples/tutorials/10_agentic/00_base/020_streaming/README.md +++ b/examples/tutorials/10_agentic/00_base/020_streaming/README.md @@ -1,10 +1,16 @@ # [Agentic] Streaming -## What You'll Learn - Stream responses in agentic agents using `adk.messages.create()` to send progressive updates. More flexible than sync streaming since you can send multiple messages at any time. -**Use case:** Long-running operations where you want to show progress, or multi-step processes with intermediate results. +## What You'll Learn +- How to stream with explicit message creation +- Difference between sync and agentic streaming patterns +- When to send multiple messages vs single streamed response + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Understanding of agentic basics (see [000_hello_acp](../000_hello_acp/)) ## Quick Start @@ -28,3 +34,14 @@ async def handle_event_send(params: SendEventParams): ``` Unlike sync streaming (which uses async generators), agentic streaming uses explicit message creation calls, giving you more control over when and what to send. + +## When to Use +- Multi-step processes with intermediate results +- Long-running operations with progress updates +- Agents that need to send messages at arbitrary times +- More complex streaming patterns than simple LLM responses + +## Why This Matters +Agentic streaming is more powerful than sync streaming. You can send messages at any time, from anywhere in your code, and even from background tasks. This flexibility is essential for complex agents with multiple concurrent operations. + +**Next:** [030_tracing](../030_tracing/) - Add observability to your agents diff --git a/examples/tutorials/10_agentic/00_base/030_tracing/README.md b/examples/tutorials/10_agentic/00_base/030_tracing/README.md index 9ed3c3f1..8a67c5dc 100644 --- a/examples/tutorials/10_agentic/00_base/030_tracing/README.md +++ b/examples/tutorials/10_agentic/00_base/030_tracing/README.md @@ -1,10 +1,17 @@ # [Agentic] Tracing -## What You'll Learn - Add observability to your agents with spans and traces using `adk.tracing.start_span()`. Track execution flow, measure performance, and debug complex agent behaviors. -**Use case:** Understanding agent behavior, debugging issues, monitoring performance in production. +## What You'll Learn +- How to instrument agents with tracing +- Creating hierarchical spans to track operations +- Viewing traces in Scale Groundplane +- Performance debugging with observability + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Understanding of agentic agents (see [000_hello_acp](../000_hello_acp/)) ## Quick Start @@ -33,3 +40,14 @@ await adk.tracing.end_span( ``` Spans create a hierarchical view of agent execution, making it easy to see which operations take time and where errors occur. + +## When to Use +- Debugging complex agent behaviors +- Performance optimization and bottleneck identification +- Production monitoring and observability +- Understanding execution flow in multi-step agents + +## Why This Matters +Without tracing, debugging agents is like flying blind. Tracing gives you visibility into what your agent is doing, how long operations take, and where failures occur. It's essential for production agents and invaluable during development. + +**Next:** [040_other_sdks](../040_other_sdks/) - Integrate any SDK or framework diff --git a/examples/tutorials/10_agentic/00_base/040_other_sdks/README.md b/examples/tutorials/10_agentic/00_base/040_other_sdks/README.md index 7d804e21..7234f3d6 100644 --- a/examples/tutorials/10_agentic/00_base/040_other_sdks/README.md +++ b/examples/tutorials/10_agentic/00_base/040_other_sdks/README.md @@ -1,10 +1,17 @@ # [Agentic] Other SDKs -## What You'll Learn - Agents are just Python code - integrate any SDK you want (OpenAI, Anthropic, LangChain, LlamaIndex, custom libraries, etc.). AgentEx doesn't lock you into a specific framework. -**Use case:** Using your preferred LLM provider, existing agent frameworks, or custom tooling. +## What You'll Learn +- How to integrate OpenAI, Anthropic, or any SDK +- What AgentEx provides vs what you bring +- Framework-agnostic agent development +- Building agents with your preferred tools + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Understanding of agentic agents (see [000_hello_acp](../000_hello_acp/)) ## Quick Start @@ -25,3 +32,14 @@ You provide: - Tools and capabilities specific to your use case Mix and match OpenAI, Anthropic, LangChain, or roll your own - it's all just Python. + +## When to Use +- You have an existing agent codebase to migrate +- Your team prefers specific SDKs or frameworks +- You need features from multiple providers +- You want full control over your agent logic + +## Why This Matters +AgentEx is infrastructure, not a framework. We handle deployment, task management, and protocol implementation - you handle the agent logic with whatever tools you prefer. This keeps you flexible and avoids vendor lock-in. + +**Next:** [080_batch_events](../080_batch_events/) - See when you need Temporal diff --git a/examples/tutorials/10_agentic/00_base/080_batch_events/README.md b/examples/tutorials/10_agentic/00_base/080_batch_events/README.md index 0a0777ed..7a2efce3 100644 --- a/examples/tutorials/10_agentic/00_base/080_batch_events/README.md +++ b/examples/tutorials/10_agentic/00_base/080_batch_events/README.md @@ -1,10 +1,17 @@ # [Agentic] Batch Events -## What You'll Learn - Demonstrates limitations of the base agentic protocol with concurrent event processing. When multiple events arrive rapidly, base agentic agents handle them sequentially, which can cause issues. -**Problem shown:** Race conditions and ordering issues when events arrive faster than the agent can process them. +## What You'll Learn +- Limitations of non-Temporal agentic agents +- Race conditions and ordering issues in concurrent scenarios +- When you need workflow orchestration +- Why this motivates Temporal adoption + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Understanding of agentic patterns (see previous tutorials) ## Quick Start @@ -26,3 +33,14 @@ Then you should use Temporal workflows (see tutorials 10_agentic/10_temporal/) w - Guaranteed state consistency This is the "breaking point" tutorial that motivates moving to Temporal for production agents. + +## When to Use (This Pattern) +This tutorial shows what NOT to use for production. Use base agentic agents only when: +- Events are infrequent (< 1 per second) +- Order doesn't matter +- State consistency isn't critical + +## Why This Matters +Every production agent eventually hits concurrency issues. This tutorial shows you those limits early, so you know when to graduate to Temporal. Better to learn this lesson in a tutorial than in production! + +**Next:** Ready for production? → [../10_temporal/000_hello_acp](../../10_temporal/000_hello_acp/) or explore [090_multi_agent_non_temporal](../090_multi_agent_non_temporal/) for complex non-Temporal coordination diff --git a/examples/tutorials/10_agentic/00_base/090_multi_agent_non_temporal/README.md b/examples/tutorials/10_agentic/00_base/090_multi_agent_non_temporal/README.md index 2cba9e17..476b75ee 100644 --- a/examples/tutorials/10_agentic/00_base/090_multi_agent_non_temporal/README.md +++ b/examples/tutorials/10_agentic/00_base/090_multi_agent_non_temporal/README.md @@ -45,9 +45,11 @@ The system uses a shared build configuration with type-safe interfaces: ## 🚀 Quick Start ### Prerequisites -- Python 3.12+ -- uv package manager +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Python 3.12+ and uv package manager - OpenAI API key (set `OPENAI_API_KEY` or create `.env` file) +- Understanding of agentic patterns (see previous tutorials) ### Running the System @@ -195,3 +197,14 @@ This tutorial demonstrates: - **AgentEx CLI usage** for development and deployment - **Inter-agent communication patterns** with proper error handling - **Scalable agent architecture** with clear separation of concerns + +## When to Use +- Complex workflows requiring multiple specialized agents +- Content pipelines with review/approval steps +- Systems where each stage needs different capabilities +- When you want agent separation without Temporal (though Temporal is recommended for production) + +## Why This Matters +This shows how far you can go with non-Temporal multi-agent systems. However, note the limitations: manual state management, potential race conditions, and no built-in durability. For production multi-agent systems, consider Temporal ([../10_temporal/](../../10_temporal/)) which provides workflow orchestration, durability, and state management out of the box. + +**Next:** Ready for production workflows? → [../../10_temporal/000_hello_acp](../../10_temporal/000_hello_acp/) diff --git a/examples/tutorials/10_agentic/10_temporal/000_hello_acp/README.md b/examples/tutorials/10_agentic/10_temporal/000_hello_acp/README.md index 9171ea0b..6a5431f5 100644 --- a/examples/tutorials/10_agentic/10_temporal/000_hello_acp/README.md +++ b/examples/tutorials/10_agentic/10_temporal/000_hello_acp/README.md @@ -1,12 +1,18 @@ # [Temporal] Hello ACP -## What You'll Learn - Temporal workflows make agents durable - they survive restarts and can run indefinitely without consuming resources while idle. Instead of handlers, you define a workflow class with `@workflow.run` and `@workflow.signal` methods. -**When to use Temporal:** Production agents that need guaranteed execution, long-running tasks (hours/days/weeks), or operations that must survive system failures. +## What You'll Learn +- Building durable agents with Temporal workflows +- The workflow and signal pattern +- How workflows survive failures and resume automatically +- When to use Temporal vs base agentic agents -**Coming from base agentic?** See tutorial `080_batch_events` to understand when you need Temporal. +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root (includes Temporal) +- Temporal UI available at http://localhost:8233 +- Understanding of base agentic agents (see [../../00_base/080_batch_events](../../00_base/080_batch_events/) to understand why Temporal) ## Quick Start @@ -15,7 +21,7 @@ cd examples/tutorials/10_agentic/10_temporal/000_hello_acp uv run agentex agents run --manifest manifest.yaml ``` -**Monitor:** Check Temporal UI at http://localhost:8080 to see your durable workflow running. +**Monitor:** Check Temporal UI at http://localhost:8233 to see your durable workflow running. ## Key Pattern @@ -32,10 +38,18 @@ class MyWorkflow(BaseWorkflow): # Handle events as signals to the workflow ``` -## Why This Matters +## When to Use +- Production agents that need guaranteed execution +- Long-running tasks (hours, days, weeks, or longer) +- Operations that must survive system failures +- Agents with concurrent event handling requirements +- When you need durability and observability +## Why This Matters **Without Temporal:** If your worker crashes, the agent loses all state and has to start over. **With Temporal:** The workflow resumes exactly where it left off. If it crashes mid-conversation, Temporal brings it back up with full context intact. Can run for years if needed, only consuming resources when actively processing. This is the foundation for production-ready agents that handle real-world reliability requirements. + +**Next:** [010_agent_chat](../010_agent_chat/) - Build a complete conversational agent with tools diff --git a/examples/tutorials/10_agentic/10_temporal/010_agent_chat/README.md b/examples/tutorials/10_agentic/10_temporal/010_agent_chat/README.md index 0940bc46..4707472c 100644 --- a/examples/tutorials/10_agentic/10_temporal/010_agent_chat/README.md +++ b/examples/tutorials/10_agentic/10_temporal/010_agent_chat/README.md @@ -1,10 +1,18 @@ # [Temporal] Agent Chat -## What You'll Learn - Combine streaming responses, multi-turn chat, tool calling, and tracing - all with Temporal's durability guarantees. This shows how to build a complete conversational agent that can survive failures. -**Use case:** Production chatbots with tools, long-running customer service conversations, or any agent that needs both capabilities and reliability. +## What You'll Learn +- Building a complete conversational agent with Temporal +- Combining streaming, multiturn, tools, and tracing +- How all agent capabilities work together with durability +- Production-ready conversational patterns + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Temporal UI available at http://localhost:8233 +- Understanding of Temporal basics (see [000_hello_acp](../000_hello_acp/)) ## Quick Start @@ -21,8 +29,19 @@ uv run agentex agents run --manifest manifest.yaml - **Tracing**: Full observability of tool calls and LLM interactions - **Durability**: All of the above survives worker restarts -**Monitor:** Open Temporal UI at http://localhost:8080 to see the workflow and all tool call activities. +**Monitor:** Open Temporal UI at http://localhost:8233 to see the workflow and all tool call activities. ## Key Insight In base agentic agents, all this state lives in memory and is lost on crash. With Temporal, the entire conversation - history, tool calls, intermediate state - is durably persisted. The agent can pick up a conversation that paused days ago as if no time passed. + +## When to Use +- Production chatbots with tool capabilities +- Long-running customer service conversations +- Agents that need both reliability and rich features +- Any conversational agent handling real user traffic + +## Why This Matters +This is the pattern for real production agents. By combining all capabilities (streaming, tools, tracing) with Temporal's durability, you get an agent that's both feature-rich and reliable. This is what enterprise conversational AI looks like. + +**Next:** [020_state_machine](../020_state_machine/) - Add complex multi-phase workflows diff --git a/examples/tutorials/10_agentic/10_temporal/020_state_machine/README.md b/examples/tutorials/10_agentic/10_temporal/020_state_machine/README.md index 924f86da..05e0fe1c 100644 --- a/examples/tutorials/10_agentic/10_temporal/020_state_machine/README.md +++ b/examples/tutorials/10_agentic/10_temporal/020_state_machine/README.md @@ -1,10 +1,18 @@ # [Temporal] State Machine -## What You'll Learn - Build complex multi-state workflows using state machines with Temporal. This tutorial shows a "deep research" agent that transitions through states: clarify query → wait for input → perform research → wait for follow-ups. -**Use case:** Complex multi-step processes with branching logic, agents that need to orchestrate multiple sub-workflows, or any operation with distinct phases. +## What You'll Learn +- Building state machines with Temporal sub-workflows +- Explicit state transitions and phase management +- When to use state machines vs simple workflows +- Handling complex multi-phase agent behaviors + +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Temporal UI available at http://localhost:8233 +- Understanding of Temporal workflows (see [010_agent_chat](../010_agent_chat/)) ## Quick Start @@ -13,7 +21,7 @@ cd examples/tutorials/10_agentic/10_temporal/020_state_machine uv run agentex agents run --manifest manifest.yaml ``` -**Monitor:** Open Temporal UI at http://localhost:8080 to see state transitions and sub-workflows. +**Monitor:** Open Temporal UI at http://localhost:8233 to see state transitions and sub-workflows. ## Architecture @@ -49,3 +57,14 @@ await self.state_machine.transition(DeepResearchState.RESEARCHING) ``` This is an advanced pattern - only needed when your agent has complex, multi-phase behavior. + +## When to Use +- Multi-step processes with clear phases +- Workflows that wait for user input at specific points +- Operations with branching logic based on state +- Complex coordination patterns requiring explicit transitions + +## Why This Matters +State machines provide structure for complex agent behaviors. While simple agents can use basic workflows, complex agents benefit from explicit state management. Temporal ensures state transitions are durable and resumable, even after failures. + +**Next:** [030_custom_activities](../030_custom_activities/) - Extend workflows with custom activities diff --git a/examples/tutorials/10_agentic/10_temporal/030_custom_activities/README.md b/examples/tutorials/10_agentic/10_temporal/030_custom_activities/README.md index 0be65ef7..92aa8a03 100644 --- a/examples/tutorials/10_agentic/10_temporal/030_custom_activities/README.md +++ b/examples/tutorials/10_agentic/10_temporal/030_custom_activities/README.md @@ -1,301 +1,106 @@ -# at030-custom-activities - AgentEx Temporal Agent Template +# [Temporal] Custom Activities -This is a starter template for building asynchronous agents with the AgentEx 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. +Learn how to extend Temporal workflows with custom activities for external operations like API calls, database queries, or complex computations. ## What You'll Learn +- How to define custom Temporal activities +- When to use activities vs inline workflow code +- Activity retry and timeout configuration +- Integrating external services into workflows -- **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 +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Temporal UI available at http://localhost:8233 +- Understanding of basic Temporal workflows (see [000_hello_acp](../000_hello_acp/)) -## Running the Agent +## Quick Start -1. Run the agent locally: +**Terminal 1 - Start Worker:** ```bash -agentex agents run --manifest manifest.yaml +cd examples/tutorials/10_agentic/10_temporal/030_custom_activities +uv run python project/run_worker.py ``` -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 AgentEx 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 Manifest File - -The `manifest.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 - -``` -030_custom_activities/ -├── project/ # Your agent's code -│ ├── __init__.py -│ ├── acp.py # ACP server and event handlers -│ ├── workflow.py # Temporal workflow definitions -│ ├── activities.py # Temporal activity definitions -│ └── run_worker.py # Temporal worker setup -├── Dockerfile # Container definition -├── manifest.yaml # Deployment config -├── dev.ipynb # Development notebook for testing - -└── pyproject.toml # Dependencies (uv) - -``` - -## Development - -### 1. Customize Event Handlers -- Modify the handlers in `acp.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: - +**Terminal 2 - Run Agent:** ```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 AgentEx 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 (`at030-custom-activities`) and demonstrates the agentic 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 - - -You chose **uv** for package management. Here's how to work with dependencies: - -```bash -# Add new dependencies -agentex uv add requests openai anthropic - -# Add Temporal-specific dependencies (already included) -agentex uv add temporalio - -# Install/sync dependencies -agentex uv sync - -# Run commands with uv uv run agentex agents run --manifest manifest.yaml ``` -**Benefits of uv:** -- Faster dependency resolution and installation -- Better dependency isolation -- Modern Python packaging standards - - - -### 5. Configure Credentials -- Add any required credentials to your manifest.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 Agentex Backend -```bash -# Navigate to the backend directory -cd agentex - -# 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 +**Terminal 3 - Test via Notebook:** ```bash -agentex uv sync [--group editable-apy] -source .venv/bin/activate - -# OR -conda create -n 030_custom_activities python=3.12 -conda activate 030_custom_activities -pip install -r requirements.txt -``` -### 3. Run Your Agent -```bash -# From this directory -export ENVIRONMENT=development && [uv run] agentex agents run --manifest manifest.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 -agentex tasks submit --agent at030-custom-activities --task "Your task here" -``` - -Option 1: Web UI -```bash -# Start the local web interface -cd agentex-web -make dev - -# Then open http://localhost:3000 in your browser to chat with your agent +jupyter notebook dev.ipynb ``` -## Development Tips +## Key Concepts -### Environment Variables -- Set environment variables in project/.env for any required credentials -- Or configure them in the manifest.yaml under the `env` section -- The `.env` file is automatically loaded in development mode +### Activities vs Workflow Code -### 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 +**Use activities for:** +- External API calls +- Database operations +- File I/O or network operations +- Non-deterministic operations (random, time, external state) -### 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 +**Use workflow code for:** +- Orchestration logic +- State management +- Decision making based on activity results -### 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 +### Defining a Custom Activity -### To build the agent Docker image locally (normally not necessary): +```python +# In project/activities.py +from temporalio import activity -1. Build the agent image: -```bash -agentex agents build --manifest manifest.yaml +@activity.defn +async def call_external_api(endpoint: str, data: dict) -> dict: + """Activities can perform non-deterministic operations.""" + import httpx + async with httpx.AsyncClient() as client: + response = await client.post(endpoint, json=data) + return response.json() ``` -## Advanced Features - -### Temporal Workflows -Extend your agent with sophisticated async workflows: +### Using Activities in Workflows ```python # In project/workflow.py +from temporalio import workflow + @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: - -```python -# In project/activities.py -@activity.defn -async def call_external_api(data): - # HTTP requests, database operations, etc. - pass -``` - -### Integration with External Services - -```bash -# Add service clients -agentex uv add httpx requests-oauthlib - -# Add AI/ML libraries -agentex uv add openai anthropic transformers - -# Add database clients -agentex uv add asyncpg redis + @workflow.run + async def run(self, input: dict): + # Activities are executed with retry and timeout policies + result = await workflow.execute_activity( + call_external_api, + args=["https://api.example.com", input], + start_to_close_timeout=timedelta(seconds=30), + retry_policy=RetryPolicy(maximum_attempts=3) + ) + return result ``` +## Try It -## 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** - - - Run `agentex uv sync` to ensure all dependencies are installed - - Verify temporalio is properly installed - +1. Modify `project/activities.py` to add a new activity +2. Update `project/workflow.py` to call your activity +3. Register the activity in `project/run_worker.py` +4. Restart the worker and test via the notebook +5. Check Temporal UI at http://localhost:8233 to see activity execution and retries -4. **Port conflicts** - - Check if another service is using port 8000 - - Use `lsof -i :8000` to find conflicting processes +## When to Use +- Integrating external services (OpenAI, databases, APIs) +- Operations that may fail and need automatic retries +- Long-running computations that should be checkpointed +- Separating business logic from orchestration -### Temporal-Specific Troubleshooting +## Why This Matters +Activities are Temporal's way of handling the real world's messiness: network failures, API rate limits, and transient errors. They provide automatic retries, timeouts, and observability for operations that would otherwise require extensive error handling code. -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 +**For detailed setup instructions, see [TEMPLATE_GUIDE.md](./TEMPLATE_GUIDE.md)** -Happy building with Temporal! 🚀⚡ \ No newline at end of file +**Next:** [050_agent_chat_guardrails](../050_agent_chat_guardrails/) - Add safety and validation to your workflows diff --git a/examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails/README.md b/examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails/README.md index 90341f30..8f6d3bc1 100644 --- a/examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails/README.md +++ b/examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails/README.md @@ -1,10 +1,18 @@ -# [Agentic] Agent Chat with Guardrails +# [Temporal] Agent Chat with Guardrails This tutorial demonstrates how to implement streaming multiturn tool-enabled chat with input and output guardrails using Temporal workflows in AgentEx agents. -## Overview +## What You'll Learn +- Adding safety guardrails to conversational agents +- Input validation and output filtering +- Implementing content moderation with Temporal +- When to block vs warn vs allow content -This example extends the basic agent chat functionality by adding guardrails that can filter both user inputs and AI outputs. This is useful for content moderation, compliance, or preventing certain topics from being discussed. +## Prerequisites +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Temporal UI available at http://localhost:8233 +- Understanding of agent chat patterns (see [010_agent_chat](../010_agent_chat/)) ## Quick Start @@ -13,7 +21,7 @@ cd examples/tutorials/10_agentic/10_temporal/050_agent_chat_guardrails uv run agentex agents run --manifest manifest.yaml ``` -**Monitor:** Open Temporal UI at http://localhost:8080 to see guardrail checks as workflow activities. +**Monitor:** Open Temporal UI at http://localhost:8233 to see guardrail checks as workflow activities. ## Guardrails @@ -48,4 +56,15 @@ The guardrails are implemented as functions that: - `output_info`: Metadata about the check - `rejection_message`: Custom message shown when content is blocked -See `workflow.py` for the complete implementation. \ No newline at end of file +See `workflow.py` for the complete implementation. + +## When to Use +- Content moderation and safety requirements +- Compliance with regulatory restrictions +- Brand safety and reputation protection +- Preventing agents from discussing sensitive topics + +## Why This Matters +Production agents need safety rails. This pattern shows how to implement content filtering without sacrificing the benefits of Temporal workflows. Guardrail checks become durable activities, visible in Temporal UI for audit and debugging. + +**Next:** [060_open_ai_agents_sdk_hello_world](../060_open_ai_agents_sdk_hello_world/) - Integrate OpenAI Agents SDK with Temporal \ No newline at end of file diff --git a/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md b/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md index 10eaff31..6594f105 100644 --- a/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md +++ b/examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/README.md @@ -9,9 +9,11 @@ The OpenAI Agents SDK plugin automatically converts LLM calls into durable Tempo **Key insight:** You don't need to wrap agent calls in activities manually - the plugin handles this automatically, making non-deterministic LLM calls work seamlessly in Temporal workflows. ## Prerequisites - -1. Agentex backend running with Temporal (`make dev` in agentex repo) -2. OpenAI API key configured (see setup below) +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root (includes Temporal) +- Temporal UI available at http://localhost:8233 +- OpenAI API key configured (see setup below) +- Understanding of Temporal workflows (see [000_hello_acp](../000_hello_acp/)) ## Setup @@ -55,7 +57,7 @@ cd examples/tutorials/10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world uv run agentex agents run --manifest manifest.yaml ``` -**Monitor:** Open Temporal UI at http://localhost:8080 to see automatic activity creation. +**Monitor:** Open Temporal UI at http://localhost:8233 to see automatic activity creation. ## Try It @@ -64,7 +66,7 @@ uv run agentex agents run --manifest manifest.yaml ![Agent Response](../_images/hello_world_response.png) -3. Open Temporal UI at http://localhost:8080 +3. Open Temporal UI at http://localhost:8233 4. Find your workflow execution 5. Look for the `invoke_model_activity` - this was created automatically: @@ -93,3 +95,11 @@ The magic happens behind the scenes - no manual activity wrapping needed. The co **Observability:** Every LLM call is tracked as an activity with full execution history. **Reliability:** Failed LLM calls are automatically retried with exponential backoff. + +## When to Use +- Building agents with OpenAI's SDK +- Need durability for LLM calls +- Want automatic activity creation without manual wrapping +- Leveraging OpenAI's agent patterns with Temporal's durability + +**Next:** [070_open_ai_agents_sdk_tools](../070_open_ai_agents_sdk_tools/) - Add durable tools to your agents diff --git a/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md b/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md index 841019f3..9dee3544 100644 --- a/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md +++ b/examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools/README.md @@ -18,8 +18,10 @@ Two patterns for making agent tools durable with Temporal: - Ensures atomic operations (withdraw always happens before deposit) ## Prerequisites - -See [Hello World tutorial](../060_open_ai_agents_sdk_hello_world/) for basic setup of the OpenAI Agents SDK plugin. +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Temporal UI available at http://localhost:8233 +- OpenAI Agents SDK plugin configured (see [060_hello_world](../060_open_ai_agents_sdk_hello_world/)) ## Quick Start @@ -28,7 +30,7 @@ cd examples/tutorials/10_agentic/10_temporal/070_open_ai_agents_sdk_tools uv run agentex agents run --manifest manifest.yaml ``` -**Monitor:** Open Temporal UI at http://localhost:8080 to see tool calls as activities. +**Monitor:** Open Temporal UI at http://localhost:8233 to see tool calls as activities. ## Try It @@ -40,7 +42,7 @@ Ask "What's the weather in San Francisco?" ![Weather Response](../_images/weather_response.png) -2. Open Temporal UI (localhost:8080) +2. Open Temporal UI (localhost:8233) 3. See a single `get_weather` activity created: ![Weather Activity](../_images/weather_activity_tool.png) @@ -160,3 +162,19 @@ This makes agents production-ready for: - Order fulfillment workflows - Multi-step API integrations - Any operation where partial completion is dangerous + +## When to Use + +**Pattern 1 (activity_as_tool):** +- Single API calls +- Database queries +- External service integrations +- Operations that are naturally atomic + +**Pattern 2 (Multi-activity tools):** +- Financial transactions requiring sequencing +- Multi-step operations with dependencies +- Operations where order matters critically +- Workflows needing guaranteed atomicity + +**Next:** [080_open_ai_agents_sdk_human_in_the_loop](../080_open_ai_agents_sdk_human_in_the_loop/) - Add human approval workflows diff --git a/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md b/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md index afd14e32..2c7ea850 100644 --- a/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md +++ b/examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/README.md @@ -47,8 +47,11 @@ Child workflows are like spawning a new workflow from within your current workfl [Learn more about child workflows](https://docs.temporal.io/develop/python/child-workflows) ## Prerequisites - -See [Hello World tutorial](../060_open_ai_agents_sdk_hello_world/) for basic setup of the OpenAI Agents SDK plugin. +- Development environment set up (see [main repo README](https://github.com/scaleapi/scale-agentex)) +- Backend services running: `make dev` from repository root +- Temporal UI available at http://localhost:8233 +- OpenAI Agents SDK plugin configured (see [060_hello_world](../060_open_ai_agents_sdk_hello_world/)) +- Understanding of tools (see [070_tools](../070_open_ai_agents_sdk_tools/)) ## Quick Start @@ -57,13 +60,13 @@ cd examples/tutorials/10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the uv run agentex agents run --manifest manifest.yaml ``` -**Monitor:** Open Temporal UI at http://localhost:8080 to see child workflows and signals. +**Monitor:** Open Temporal UI at http://localhost:8233 to see child workflows and signals. ## Try It 1. Ask the agent to do something that requires approval (e.g., "Order 100 widgets") 2. The agent will call `wait_for_confirmation` and pause -3. Open Temporal UI (localhost:8080) +3. Open Temporal UI (localhost:8233) 4. Find the parent workflow - you'll see it's waiting on the child workflow: ![Parent Workflow Waiting](../_images/human_in_the_loop_workflow.png) @@ -184,3 +187,13 @@ result = await Runner.run(confirm_order_agent, params.event.content.content) - **High-stakes decisions**: Any operation requiring human judgment This pattern transforms agents from fully automated systems into **collaborative AI assistants** that know when to ask for help. + +## When to Use +- Financial transactions requiring approval +- High-stakes decisions needing human judgment +- Compliance workflows with mandatory review steps +- Legal or contractual operations +- Any operation where errors have serious consequences +- Workflows where AI assists but humans decide + +**Congratulations!** You've completed all AgentEx tutorials. You now know how to build production-ready agents from simple sync patterns to complex durable workflows with human oversight. From 19c437bc50d249e49dd165503220833bfdafc8c3 Mon Sep 17 00:00:00 2001 From: Jason Yang Date: Fri, 31 Oct 2025 09:32:03 -0700 Subject: [PATCH 4/4] Add README --- examples/tutorials/README.md | 155 +++++++++++++++++++++++++++++++++++ 1 file changed, 155 insertions(+) create mode 100644 examples/tutorials/README.md diff --git a/examples/tutorials/README.md b/examples/tutorials/README.md new file mode 100644 index 00000000..ecdd2225 --- /dev/null +++ b/examples/tutorials/README.md @@ -0,0 +1,155 @@ +# AgentEx Tutorials + +Progressive tutorials for learning AgentEx from basics to production-ready patterns. + +## Prerequisites + +**Before starting any tutorial:** +1. Set up your development environment following the [main repo README](https://github.com/scaleapi/scale-agentex#setup) +2. Start backend services from repository root: + ```bash + cd /path/to/agentex-python + make dev + ``` +3. Verify Temporal UI is accessible at http://localhost:8233 + +For troubleshooting, see the [AgentEx debugging guide](https://github.com/scaleapi/scale-agentex#troubleshooting). + +## Learning Path + +```mermaid +graph TD + A[👋 Start Here] --> B[00_sync/000_hello_acp] + B --> C[00_sync/010_multiturn] + C --> D[00_sync/020_streaming] + + D --> E{Need Task
Management?} + E -->|Yes| F[10_agentic/00_base/
000_hello_acp] + E -->|No| G[Continue with
sync patterns] + + F --> H[00_base/010_multiturn] + H --> I[00_base/020_streaming] + I --> J[00_base/030_tracing] + J --> K[00_base/040_other_sdks] + K --> L[00_base/080_batch_events] + + L --> M{Building for
Production?} + M -->|Yes| N[10_temporal/
000_hello_acp] + M -->|No| O[00_base/090_multi_agent] + + N --> P[10_temporal/010_agent_chat] + P --> Q[10_temporal/020_state_machine] + Q --> R[10_temporal/030_custom_activities] + R --> S[10_temporal/050_guardrails] + + S --> T{Using
OpenAI SDK?} + T -->|Yes| U[10_temporal/060_openai_hello] + U --> V[10_temporal/070_openai_tools] + V --> W[10_temporal/080_openai_hitl] + T -->|No| X[🎉 Production Ready!] + W --> X + + style A fill:#e1f5e1 + style X fill:#fff3cd + style E fill:#e3f2fd + style M fill:#e3f2fd + style T fill:#e3f2fd +``` + +## Tutorial Structure + +### 00_sync/ - Synchronous Agents +Simple request-response patterns without task management. Start here if you're new to AgentEx. + +- **[000_hello_acp](00_sync/000_hello_acp/)** - Your first agent +- **[010_multiturn](00_sync/010_multiturn/)** - Maintaining conversation context +- **[020_streaming](00_sync/020_streaming/)** - Real-time response streaming + +**When to use:** Simple chatbots, stateless Q&A, quick prototypes + +--- + +### 10_agentic/ - Task-Based Agents + +#### 00_base/ - Non-Temporal Patterns +Task-based architecture without workflow orchestration. Adds task management on top of sync patterns. + +- **[000_hello_acp](10_agentic/00_base/000_hello_acp/)** - Task-based hello world +- **[010_multiturn](10_agentic/00_base/010_multiturn/)** - Multiturn with task management +- **[020_streaming](10_agentic/00_base/020_streaming/)** - Streaming with tasks +- **[030_tracing](10_agentic/00_base/030_tracing/)** - Observability with Scale Groundplane +- **[040_other_sdks](10_agentic/00_base/040_other_sdks/)** - Integrating OpenAI, Anthropic, etc. +- **[080_batch_events](10_agentic/00_base/080_batch_events/)** - Event batching (shows limitations → Temporal) +- **[090_multi_agent_non_temporal](10_agentic/00_base/090_multi_agent_non_temporal/)** - Complex multi-agent coordination + +**When to use:** Task tracking needed but workflows are simple, no durability requirements + +--- + +#### 10_temporal/ - Production Workflows +Durable, fault-tolerant agents with Temporal workflow orchestration. + +**Core Patterns:** +- **[000_hello_acp](10_agentic/10_temporal/000_hello_acp/)** - Temporal basics +- **[010_agent_chat](10_agentic/10_temporal/010_agent_chat/)** - Stateful conversations +- **[020_state_machine](10_agentic/10_temporal/020_state_machine/)** - Structured state management +- **[030_custom_activities](10_agentic/10_temporal/030_custom_activities/)** - Custom Temporal activities +- **[050_agent_chat_guardrails](10_agentic/10_temporal/050_agent_chat_guardrails/)** - Safety & validation + +**OpenAI Agents SDK Series:** +- **[060_openai_hello_world](10_agentic/10_temporal/060_open_ai_agents_sdk_hello_world/)** - Plugin-based agents +- **[070_openai_tools](10_agentic/10_temporal/070_open_ai_agents_sdk_tools/)** - Tool integration patterns +- **[080_openai_hitl](10_agentic/10_temporal/080_open_ai_agents_sdk_human_in_the_loop/)** - Human oversight workflows + +**When to use:** Production systems requiring durability, fault tolerance, long-running workflows, or complex state management + +--- + +## Quick Start + +```bash +# 1. Start backend services (from repo root) +make dev + +# 2. Navigate to a tutorial +cd examples/tutorials/00_sync/000_hello_acp + +# 3. Run it +uv run python hello_acp.py +``` + +## Common Commands + +```bash +# Format tutorial code (always scope to specific files you're modifying) +rye run format examples/tutorials/00_sync/000_hello_acp/ + +# Run all agentic tutorial tests +cd examples/tutorials +./run_all_agentic_tests.sh + +# Run specific tutorial test +cd examples/tutorials +uv run pytest 00_sync/000_hello_acp/ -v + +# Check Temporal UI (when running temporal tutorials) +open http://localhost:8233 +``` + +## Tutorial Categories at a Glance + +| Category | Tutorials | Focus | Use When | +|----------|-----------|-------|----------| +| **Sync** | 3 | Request-response basics | Learning fundamentals, simple chatbots | +| **Agentic Base** | 7 | Task management without workflows | Need task tracking, simple coordination | +| **Temporal** | 8 | Production-grade workflows | Need durability, fault tolerance, complex state | + +## Getting Help + +- **Each tutorial includes:** README explaining concepts, annotated source code, and tests +- **Common issues?** See [AgentEx troubleshooting guide](https://github.com/scaleapi/scale-agentex#troubleshooting) +- **Need more context?** Check the [main AgentEx documentation](https://github.com/scaleapi/scale-agentex) + +--- + +**Ready to start?** → Begin with [00_sync/000_hello_acp](00_sync/000_hello_acp/)