Documentation Index
Fetch the complete documentation index at: https://docs.orxhestra.com/llms.txt
Use this file to discover all available pages before exploring further.
Every agent yields a stream of unified Event objects. All events share the same Event class and are distinguished by their type field using the EventType enum.
EventType values
EventType | When emitted | Description |
|---|
USER_MESSAGE | User input persisted by Runner | The user’s message at the start of a turn |
AGENT_MESSAGE | Agent response | Final answers, thoughts, tool call requests, or partial streaming chunks |
TOOL_RESPONSE | Tool execution result | The result returned by a tool after execution |
AGENT_START | Start of astream() | Marks the beginning of an agent’s execution |
AGENT_END | End of astream() | Marks the end of an agent’s execution |
Convenience properties
| Property | Type | Description |
|---|
event.text | str | Concatenated text from all text parts in the event’s content |
event.thinking | str | Concatenated thinking parts (extended thinking models like Claude with thinking enabled) |
event.data | dict | None | First data part’s dict, or None |
event.tool_name | str | None | Name of the tool (for TOOL_RESPONSE events or first tool call) |
event.tool_input | dict | None | Input arguments passed to the first tool call |
event.tool_calls | list[ToolCallPart] | List of ToolCallPart objects from the LLM response (access .tool_name, .args, .tool_call_id) |
event.has_tool_calls | bool | True if the event contains tool call requests |
event.error | str | None | Error message from tool response or metadata |
Key methods
| Method | Description |
|---|
event.is_final_response() | Returns True if this is the agent’s final answer (an AGENT_MESSAGE with no tool calls and not a partial streaming chunk) |
event.to_langchain_message() | Converts the event to the corresponding LangChain message type (HumanMessage, AIMessage, ToolMessage, etc.) |
Event.from_langchain_message(msg) | Class method that creates an Event from a LangChain message |
Event.new_id() | Static method that generates a new unique event ID (UUID) |
Checking event types
Use the EventType enum and convenience methods instead of isinstance checks:
from orxhestra.events.event import Event, EventType
# Check for final response (replaces isinstance(event, FinalAnswerEvent))
if event.is_final_response():
print(event.text)
# Check for tool calls (replaces isinstance(event, ToolCallEvent))
if event.has_tool_calls:
for tc in event.tool_calls:
print(f"Calling {tc.tool_name} with {tc.args}")
# Check for tool results (replaces isinstance(event, ToolResultEvent))
if event.type == EventType.TOOL_RESPONSE:
print(f"{event.tool_name} returned: {event.text}")
# Check for agent lifecycle
if event.type == EventType.AGENT_START:
print(f"Agent {event.agent_name} starting")
Events use the metadata dict for additional context. Common keys:
| Key | Description |
|---|
react_step | The ReAct loop iteration number |
error | Error message string when something went wrong |
exception_type | The Python exception class name (e.g. "ValueError") |
scratchpad | Internal reasoning or planning notes from the agent |
EventActions
Events carry EventActions for side-effects:
class EventActions(BaseModel):
state_delta: dict[str, Any] = {} # merged into session state
artifact_delta: dict[str, int] = {} # artifact filenames → version saved
transfer_to_agent: str | None = None # trigger agent handoff
escalate: bool | None = None # stop parent LoopAgent
skip_summarization: bool | None = None
end_of_agent: bool | None = None
compaction: EventCompaction | None = None
Event Filters
The orxhestra.events.filters module provides reusable functions for preparing session events before they are sent to the LLM. These are used internally by LlmAgent and available for custom agents.
should_include_event(event)
Returns True if the event should be included in LLM context. Filters out:
- Partial (streaming) events
- Lifecycle events (
AGENT_START, AGENT_END)
- Error-only metadata events
- Scratchpad notes
- Empty
AGENT_MESSAGE events (no text, data, or tool calls)
from orxhestra.events.filters import should_include_event
visible = [e for e in session.events if should_include_event(e)]
apply_compaction(events)
Replaces raw events with compaction summaries where applicable. When events carry an EventActions.compaction entry, all raw events within that timestamp range are replaced by a single synthetic event containing the summary.
from orxhestra.events.filters import apply_compaction
events = apply_compaction(session.events)
# Compacted ranges become single summary events
Both functions are also re-exported from orxhestra.events:
from orxhestra.events import should_include_event, apply_compaction
LlmResponse
AGENT_MESSAGE events may carry an llm_response: LlmResponse field with token usage and model version:
event.llm_response.input_tokens
event.llm_response.output_tokens
event.llm_response.model_version
Signed Events
Agents with a signing_key automatically sign every event they emit using Ed25519. This provides cryptographic proof of which agent produced each event.
| Property / Method | Type | Description |
|---|
event.signature | str | None | Base64url-encoded Ed25519 signature |
event.signer_did | str | did:key identifier of the signing agent |
event.is_signed | bool | True if the event carries a signature |
event.verify_signature() | bool | Verify the signature using the signer’s DID public key |
event.signable_payload() | dict | Canonical dict of fields included in the signature (id, type, timestamp, agent_name, branch, content_text) |
# Verify a signed event
if event.is_signed:
valid = event.verify_signature()
print(f"Signed by {event.signer_did}: {'valid' if valid else 'invalid'}")
Requires orxhestra[auth] (pip install orxhestra[auth]).