mirror of
https://github.com/hanzoai/python-sdk.git
synced 2026-10-23 20:23:00 +00:00
MCP docs: - quickstart.md - Installation, basic usage, transport modes - configuration.md - CLI options, env vars, config files - vscode.md - VS Code, Cursor, Windsurf integration Agent SDK docs: - agents.md - Creating and configuring agents - running_agents.md - Runner, RunConfig, async/sync - tools.md - Function tools, context, custom tools - guardrails.md - Input/output validation - handoffs.md - Agent delegation patterns - streaming.md - Stream events and responses - tracing.md - Observability and debugging - context.md - Mutable run context - config.md - RunConfig and ModelSettings - results.md - RunResult, items, usage - models.md - Providers and model selection - multi_agent.md - Complex multi-agent patterns
188 lines
4.2 KiB
Markdown
188 lines
4.2 KiB
Markdown
# Context
|
|
|
|
The context is a mutable object passed throughout an agent run.
|
|
|
|
## Basic Context
|
|
|
|
```python
|
|
from dataclasses import dataclass
|
|
from agents import Agent, Runner
|
|
|
|
@dataclass
|
|
class MyContext:
|
|
user_id: str
|
|
session_id: str
|
|
request_count: int = 0
|
|
|
|
context = MyContext(user_id="123", session_id="abc")
|
|
result = await Runner.run(agent, "Hello!", context=context)
|
|
```
|
|
|
|
## Accessing Context in Tools
|
|
|
|
```python
|
|
from agents import function_tool, RunContextWrapper
|
|
|
|
@function_tool
|
|
def get_user_data(ctx: RunContextWrapper[MyContext]) -> str:
|
|
"""Get data for the current user."""
|
|
user_id = ctx.context.user_id
|
|
return f"Data for user {user_id}"
|
|
|
|
@function_tool
|
|
def increment_count(ctx: RunContextWrapper[MyContext]) -> str:
|
|
"""Increment request count."""
|
|
ctx.context.request_count += 1
|
|
return f"Count: {ctx.context.request_count}"
|
|
```
|
|
|
|
## Context in Instructions
|
|
|
|
Dynamic instructions based on context:
|
|
|
|
```python
|
|
from agents import Agent, RunContextWrapper
|
|
|
|
def dynamic_instructions(ctx: RunContextWrapper[MyContext], agent: Agent) -> str:
|
|
user = ctx.context.user_id
|
|
count = ctx.context.request_count
|
|
return f"""You are helping user {user}.
|
|
This is request #{count} in this session.
|
|
Be concise and helpful."""
|
|
|
|
agent = Agent(
|
|
name="contextual",
|
|
instructions=dynamic_instructions,
|
|
)
|
|
```
|
|
|
|
## Context in Guardrails
|
|
|
|
```python
|
|
from agents import input_guardrail, InputGuardrailResult, RunContextWrapper
|
|
|
|
@input_guardrail
|
|
async def check_permissions(
|
|
ctx: RunContextWrapper[MyContext],
|
|
agent,
|
|
input_text: str
|
|
) -> InputGuardrailResult:
|
|
"""Check user permissions."""
|
|
if ctx.context.user_id not in allowed_users:
|
|
return InputGuardrailResult(
|
|
tripwire_triggered=True,
|
|
output_info="User not authorized."
|
|
)
|
|
return InputGuardrailResult(tripwire_triggered=False)
|
|
```
|
|
|
|
## Context in Handoffs
|
|
|
|
```python
|
|
from agents import handoff, Handoff, RunContextWrapper
|
|
|
|
@handoff
|
|
def conditional_handoff(ctx: RunContextWrapper[MyContext]) -> Handoff | None:
|
|
"""Hand off based on context."""
|
|
if ctx.context.user_id.startswith("vip_"):
|
|
return Handoff(target=vip_agent)
|
|
return None
|
|
```
|
|
|
|
## RunContextWrapper
|
|
|
|
The wrapper provides additional functionality:
|
|
|
|
```python
|
|
from agents import RunContextWrapper
|
|
|
|
@function_tool
|
|
def example(ctx: RunContextWrapper[MyContext]) -> str:
|
|
# Access your context
|
|
user = ctx.context.user_id
|
|
|
|
# Access run metadata
|
|
run_id = ctx.run_id
|
|
|
|
# Check current agent
|
|
agent_name = ctx.current_agent.name
|
|
|
|
return f"User: {user}, Run: {run_id}, Agent: {agent_name}"
|
|
```
|
|
|
|
## Context Types
|
|
|
|
### Dataclass (Recommended)
|
|
|
|
```python
|
|
from dataclasses import dataclass, field
|
|
|
|
@dataclass
|
|
class AppContext:
|
|
user_id: str
|
|
permissions: list[str] = field(default_factory=list)
|
|
metadata: dict = field(default_factory=dict)
|
|
```
|
|
|
|
### Pydantic Model
|
|
|
|
```python
|
|
from pydantic import BaseModel
|
|
|
|
class AppContext(BaseModel):
|
|
user_id: str
|
|
permissions: list[str] = []
|
|
|
|
class Config:
|
|
extra = "allow" # Allow additional fields
|
|
```
|
|
|
|
### Simple Dict
|
|
|
|
```python
|
|
# Works but not type-safe
|
|
context = {"user_id": "123", "data": {}}
|
|
result = await Runner.run(agent, "Hello!", context=context)
|
|
```
|
|
|
|
## Context Mutation
|
|
|
|
Context can be modified during the run:
|
|
|
|
```python
|
|
@function_tool
|
|
def update_context(ctx: RunContextWrapper[MyContext], key: str, value: str) -> str:
|
|
"""Update context metadata."""
|
|
ctx.context.metadata[key] = value
|
|
return f"Updated {key}"
|
|
```
|
|
|
|
## Context Persistence
|
|
|
|
For multi-turn conversations:
|
|
|
|
```python
|
|
# Store context between requests
|
|
contexts: dict[str, MyContext] = {}
|
|
|
|
async def handle_message(session_id: str, message: str):
|
|
# Get or create context
|
|
if session_id not in contexts:
|
|
contexts[session_id] = MyContext(
|
|
user_id="user_123",
|
|
session_id=session_id,
|
|
)
|
|
|
|
context = contexts[session_id]
|
|
result = await Runner.run(agent, message, context=context)
|
|
|
|
# Context is updated in place
|
|
return result.final_output
|
|
```
|
|
|
|
## See Also
|
|
|
|
- [Tools](tools.md) - Using context in tools
|
|
- [Guardrails](guardrails.md) - Context in guardrails
|
|
- [Running Agents](running_agents.md) - Passing context
|