Skip to main content

Context

Agents are stateless, Context is used to track the state of execution throughout each turn.

AgentContext

The default base context class for agents:

from factorial import AgentContext

context = AgentContext(
query="Tell me a joke",
messages=[], # Conversation history
turn=0, # Current turn number
)

Custom Agent Context

Create a custom agent context classes for specialized agents:

from typing import Any
from factorial import AgentContext

class DualAgentContext(AgentContext):
agent_a_messages: list[dict[str, Any]] = []
agent_b_messages: list[dict[str, Any]] = []

Using Custom Agent Context

from factorial import BaseAgent

class ABTestableAgent(BaseAgent[DualAgentContext]): # For the type checker
def __init__(self):
super().__init__(
description="Executes two agents side by side",
instructions="You are a helpful assistant",
tools=tools,
context_class=DualAgentContext, # For task serialization
)

# Create tasks with custom context
context = DualAgentContext(
query="Research AI developments",
)
task = agent.create_task(owner_id="user123", payload=context)

Execution Context

The ExecutionContext is a per-request context that tracks task-level information such as task ID, owner ID, retries, and pickups during agent execution. Unlike AgentContext, it is not stored with the agent and is automatically managed by the framework.

from factorial import AgentContext, ExecutionContext

class MyAgent(Agent):
def run_turn(self, agent_ctx: AgentContext)
execution_ctx = self.get_execution_context()
# or
execution_ctx = ExecutionContext.current()

print(f"Task ID: {execution_ctx.task_id}")
print(f"Owner ID: {execution_ctx.owner_id}")
print(f"Retries: {execution_ctx.retries}")
print(f"Iterations: {execution_ctx.iterations}")

Using Context in Tools

The agent automatically injects the agent and execution context to tools that require them as arguments.

def stateless_tool(input_args: str) -> str:
...

def stateful_tool(input_args: str, agent_ctx: AgentContext) -> str:
if len(agent_ctx.messages) > 10:
return run_tool_b(input_args)
return run_tool_a(input_args)

def tool_with_fallbacks(input_args: str, agent_ctx: AgentContext, execution_ctx: ExecutionContext) -> str:
if execution_context.retries > 0:
return run_tool_b(input_args)

return run_tool_a(input_args)