"""Agent: the tool-calling loop.
The class is assembled from mixins: `runtime` (turn lifecycle), `streaming` (the
turn loop), `tools` (tool execution), `compression` (context gates) and
`context` (tool lists, backend lookup, context window). The module-level
helpers live in `helpers`.
Flow:
1. Receive user message, load session + profile
2. Build tool schemas from profile's enabled_tools
3. Loop (up to max_iterations):
a. Call LLM with session.context (may be compressed) + tool schemas
b. If finish_reason == "stop" -> stream final response
c. If finish_reason == "tool_calls" -> execute tools, append to both
session.messages (display history) and session.context (LLM context)
4. After StreamEnd: run workers sequentially (e.g. context compression)
session.messages — full display history, never compressed
session.context — what the LLM sees; workers may compress this
"""
from navi.exceptions import MaxIterationsReached
from ..agent_run_context import AgentTurnContext, StreamState
from ..stream_guard import _iter_stream_guarded
from .core import Agent
from .helpers import (
_FINAL_INTERCEPT_NUDGES,
_PROTOCOL_FINAL_NUDGE,
_TOOL_DONE,
_inline_images_notice,
_protocol_progress_message,
_TaggedSink,
_todo_progress_message,
)
__all__ = [
"_FINAL_INTERCEPT_NUDGES",
"_PROTOCOL_FINAL_NUDGE",
"_TOOL_DONE",
"Agent",
"AgentTurnContext",
"MaxIterationsReached",
"StreamState",
"_TaggedSink",
"_inline_images_notice",
"_iter_stream_guarded",
"_protocol_progress_message",
"_todo_progress_message",
]