# Agent Lifecycle & Context

> How the Agent class manages resource cleanup via AsyncExitStack and provides high-level streaming interfaces for thoughts and tool calls.

- Repository: google-antigravity/antigravity-sdk-python
- GitHub: https://github.com/google-antigravity/antigravity-sdk-python
- Human wiki: https://grok-wiki.com/public/wiki/google-antigravity-antigravity-sdk-python-2abd361a7867
- Complete Markdown: https://grok-wiki.com/public/wiki/google-antigravity-antigravity-sdk-python-2abd361a7867/llms-full.txt

## Source Files

- `google/antigravity/agent.py`
- `google/antigravity/types.py`
- `examples/getting_started/streaming.py`
- `google/antigravity/hooks/hook_runner.py`

---

<details>
<summary>Relevant source files</summary>
The following files were used as context for generating this wiki page:
- [google/antigravity/agent.py](google/antigravity/agent.py)
- [google/antigravity/conversation/conversation.py](google/antigravity/conversation/conversation.py)
- [google/antigravity/types.py](google/antigravity/types.py)
- [examples/getting_started/streaming.py](examples/getting_started/streaming.py)
- [google/antigravity/hooks/hook_runner.py](google/antigravity/hooks/hook_runner.py)
- [google/antigravity/hooks/hooks.py](google/antigravity/hooks/hooks.py)
</details>

# Agent Lifecycle & Context

The `Agent` class serves as the primary entry point for the Antigravity SDK, orchestrating the complex interactions between model connections, conversation history, tool execution, and lifecycle management. It provides a high-level, asynchronous interface that simplifies session handling while exposing powerful streaming capabilities for real-time thoughts and content.

## Lifecycle Management with AsyncExitStack

The SDK utilizes `contextlib.AsyncExitStack` to manage the cleanup of various asynchronous resources. This ensures that even in the event of errors, resources like MCP server connections, conversation sessions, and trigger runners are gracefully terminated.

### Session Initialization and Cleanup
An `Agent` session is started using the `async with` statement, which triggers the `__aenter__` and `__aexit__` methods. During startup, the agent:
1.  **Initializes Runners**: Sets up `HookRunner`, `ToolRunner`, and optionally `TriggerRunner`.
2.  **Connects MCP Servers**: Establishes connections to any configured Model Context Protocol (MCP) servers and adds their tools to the `ToolRunner`.
3.  **Creates Conversation**: Establishes the stateful Layer 2 session.
4.  **Automatic Cleanup**: Registers callback such as `mcp_bridge.stop` and enters sub-contexts like `Conversation.create` within the `_exit_stack`.

```python
# google/antigravity/agent.py:92-182
async def __aenter__(self) -> "Agent":
  try:
    # ... initialization logic ...
    self._mcp_bridge = bridge.McpBridge()
    self._exit_stack.push_async_callback(self._mcp_bridge.stop)
    # ...
    self._conversation = await self._exit_stack.enter_async_context(
        conversation.Conversation.create(self._strategy)
    )
    return self
  except Exception:
    await self._exit_stack.aclose()
    raise
```
Sources: [google/antigravity/agent.py:92-182](), [google/antigravity/agent.py:184-193]()

## Streaming Interfaces

The `Agent.chat()` method returns a `ChatResponse` object, which is a sophisticated wrapper around an async generator of `StreamChunk` objects. This allows for real-time consumption of different types of output.

### The ChatResponse Model
`ChatResponse` provides multiple independent cursors over a shared internal buffer. This means you can iterate over thoughts, text deltas, and tool calls simultaneously or sequentially without losing data.

*   **`async for token in response`**: Directly yields text token strings (the primary response).
*   **`.thoughts`**: An async iterator yielding internal model reasoning deltas.
*   **`.tool_calls`**: An async iterator yielding `ToolCall` objects as they are dispatched.
*   **`.chunks`**: The raw stream of all `StreamChunk` derivatives (`Thought`, `Text`, `ToolCall`).

```python
# examples/getting_started/streaming.py:43-55
response = await my_agent.chat(prompt)

print("Agent (Streaming thoughts):")
async for thought in response.thoughts:
  print(thought, end="", flush=True)

print("Agent (Streaming final answer):")
async for token in response:
  print(token, end="", flush=True)
```
Sources: [google/antigravity/types.py:763-860](), [google/antigravity/conversation/conversation.py:160-226](), [examples/getting_started/streaming.py:43-55]()

## Context Hierarchy

The SDK manages state across different scopes using a hierarchical context system, primarily used within the Hook system but also reflected in how the Agent manages its internal state.

| Context Type | Scope | Persistence |
| :--- | :--- | :--- |
| `SessionContext` | Entire `Agent` session | Lifetime of the `Agent` instance. |
| `TurnContext` | Single `chat()` turn | Reset at the start of each user message. |
| `OperationContext` | Specific tool call or hook | Lifetime of the individual operation. |

These contexts allow hooks and internal logic to share state (via `.get()` and `.set()`) across different layers of the execution loop while maintaining clear boundaries.

Sources: [google/antigravity/hooks/hooks.py:34-86](), [google/antigravity/hooks/hook_runner.py:67]()

## State and History
The underlying `Conversation` object tracks the full transcript of steps. The `Agent` provides properties to access this state after the session has started:
*   **`conversation_id`**: The identifier used to resume sessions.
*   **`history`**: The full list of `Step` objects (model turns, tool results, compactions).
*   **`usage_metadata`**: Accumulated token counts for the session.

Sources: [google/antigravity/agent.py:211-238](), [google/antigravity/conversation/conversation.py:231-262]()

The `Agent` class effectively bridges high-level user intent with low-level resource and stream management, ensuring a robust and responsive developer experience.
Sources: [google/antigravity/agent.py:36-62]()
