The result and items modules define the SDK's type aliases and data carriers for agent responses and conversation history: TResponse* types wrap OpenAI models or dicts, InputItem tracks occurrences by UUID for exactly-once semantics, and RunItemBase maintains weak/strong agent references to enable replay and post-execution inspection. Conversion between output and input items (via to_input_item() and helpers like _output_item_to_input_item) strips fields like created_by to produce replayable conversation history, while result reconciliation ensures nested agent invocations don't create duplicate ownership of history items.
src/agents/items.py defines TResponse, TResponseInputItem, TResponseOutputItem, and TResponseStreamEvent as type aliases for the corresponding OpenAI SDK types.[1] ToolSearchCallRawItem and ToolSearchOutputRawItem in src/agents/items.py are union type aliases that accept either the typed SDK model or a plain dict, supporting partial dict snapshots.[1] ToInputListMode in src/agents/result.py is a Literal type with two valid values: 'preserve_all' (keeps full converted history from new_items) and 'normalized' (returns canonical continuation input, falling back to full history when handoff filtering did not rewrite model history).[2]
InputItem in src/agents/items.py carries an input_id field — a UUID hex string generated at construction — described as "a durable occurrence identifier used for exactly-once conversation tracking".[1] RunItemBase in src/agents/items.py stores a weak reference to the agent alongside the strong reference, so callers can call release_agent() to drop the strong reference while still allowing the agent to be resolved via the weak reference.[1] RunItemBase.agent is accessed via a custom __getattribute__ that lazily resolves the weak reference when the strong reference has been released, so repr and dataclass.asdict continue to work after release_agent() is called.[1] RunItemBase.to_input_item() in src/agents/items.py converts any run item back into a TResponseInputItem suitable for replay to the model by delegating to _output_item_to_input_item.[1]
For shell_call_output items, _output_item_to_input_item in src/agents/items.py performs a two-level strip: it removes created_by from each nested content chunk inside the output list, requiring fresh chunk copies to avoid mutating the caller's mapping.[1] ToolSearchCallItem.to_input_item() and ToolSearchOutputItem.to_input_item() in src/agents/items.py both delegate to _tool_search_item_to_input_item, which pops the created_by field before returning the replayable input item.[1] coerce_tool_search_call_raw_item in src/agents/items.py prefers the typed ResponseToolSearchCall SDK model but tolerates partial dict snapshots by falling back to a raw dict when Pydantic validation fails, and raises AgentsException if the dict's type field is not "tool_search_call".[1]
result.last_agent.name on a RunResult identifies which agent produced the final answer in a multi-agent run.[3] _reconciled_result_owned_item_refs in src/agents/result.py filters _nested_history_owned_session_item_refs from a RunResultBase to retain only the references that match exact positions in the caller-supplied public_input, preventing double-ownership when input is rewritten.[2] _copy_pending_nested_agent_tool_states in src/agents/result.py binds detached nested approval checkpoints from the source result scope into the new outer checkpoint's scope, enabling HITL approval resume across nested agent-tool invocations.[2] src/agents/result.py imports _await_data_redacted_error_boundary, _detach_data_redacted_error_traceback, _is_error_data_redacted, and _should_drain_stream_events_before_raising from src/agents/exceptions.py, making the result layer a consumer of the error-redaction and stream-drain machinery — details of which live on the Exceptions and redaction page.[2]
Sources