# =============================================================================
# MANUAL SEED OVERRIDES
# =============================================================================
# This file contains hand-curated extras and configuration that should NOT be
# overwritten by `just seed`. The seed_generator merges this file into the
# auto-generated seed.toml via the --merge flag.
#
# Sections:
#   [renames]         - Builder name overrides (e.g. LlmAgent -> Agent)
#   [[builders.X.extras]] - Manual extra methods per builder
#   [[manual_exports]] - Extra imports appended to __init__.py
#

# ---------------------------------------------------------------------------
# FIELD DOCSTRINGS
# ---------------------------------------------------------------------------
# Override auto-generated field docstrings in builders and .pyi stubs.
# Keys are field names (or alias names); values are the docstring text.

[field_docs]
description = "Set agent description (metadata for transfer routing and topology display — NOT sent to the LLM as instruction). Always set this on sub-agents so the coordinator LLM can pick the right specialist."
global_instruction = "Set instruction shared by ALL agents in a workflow. Only meaningful on the root agent. Prepended to every agent's system prompt."
static_instruction = "Set cached instruction. When set, ``.instruct()`` text moves from system to user content, enabling context caching. Use for large, stable prompt sections that rarely change."
output_schema = """Force the LLM to respond with structured JSON matching a Pydantic model.

When set, the agent replies **only** with JSON data conforming to
this schema. The agent **cannot use tools** while ``output_schema``
is active.

.. note::

   Prefer ``.returns(Model)`` or ``@ Model`` over this method.
   ``.returns()`` sets the same ADK constraint AND automatically
   parses the response in ``.ask()`` calls. This method sets the
   raw ADK field without automatic parsing.

   - ``.returns(Model)`` / ``@ Model`` → LLM constraint + parsing (HAS runtime effect)
   - ``.output_schema(Model)`` → LLM constraint only (raw field)
   - ``.writes(key)`` → stores text in state (no format constraint)
   - ``.produces(Model)`` → contract annotation (NO runtime effect)
"""
input_schema = """Schema defining the expected input structure when this agent is invoked as a tool by another agent.

When another agent invokes this agent via ``AgentTool``, the calling
agent's arguments are validated against this Pydantic model. Irrelevant
for top-level agents — only for agents that serve as tools.

.. note::

   Prefer ``.accepts(Model)`` over this method for clarity.
   ``.accepts()`` is the recommended alias on BuilderBase.

   - ``.accepts(Model)`` → tool-mode input validation (same as this, HAS runtime effect)
   - ``.consumes(Model)`` → contract annotation (NO runtime effect)
"""
output_key = "Deprecated: use ``.writes(key)`` instead. Session state key where the agent's response text is stored."
disallow_transfer_to_parent = "Prevent this agent from transferring control back to its parent. Also forces an auto-handoff back to parent on the next turn. Equivalent to ``.stay()``. See also ``.isolate()``."
disallow_transfer_to_peers = "Prevent this agent from transferring control to sibling agents. Equivalent to ``.no_peers()``. See also ``.isolate()``."

# ---------------------------------------------------------------------------
# BUILDER RENAMES
# ---------------------------------------------------------------------------
# Maps ADK class names to friendlier builder names.
[renames]
LlmAgent = "Agent"
SequentialAgent = "Pipeline"
ParallelAgent = "FanOut"
LoopAgent = "Loop"

# ---------------------------------------------------------------------------
# OPTIONAL CONSTRUCTOR ARGS
# ---------------------------------------------------------------------------
# These add optional positional params to __init__:
#   Agent("name", "model") works alongside Agent("name").model("model")

[builders.Agent]
optional_constructor_args = ["model"]

# New aliases added via merge into auto-generated aliases
[builders.Agent.manual_aliases]

# Deprecated aliases — still work but emit DeprecationWarning
[builders.Agent.deprecated_aliases]
save_as = { field = "output_key", use = "writes" }
outputs = { field = "output_key", use = "writes" }
output_key = { field = "output_key", use = "writes" }
output_schema = { field = "output_schema", use = "returns" }
input_schema = { field = "input_schema", use = "accepts" }
history = { field = "include_contents", use = "context" }
include_history = { field = "include_contents", use = "context" }
static_instruct = { field = "static_instruction", use = "static" }
retry_if = { field = "_retry_if", use = "loop_while" }
inject_context = { field = "_inject_context", use = "prepend" }
guardrail = { field = "_guardrail", use = "guard" }
delegate = { field = "_delegate", use = "agent_tool", doc = "Deprecated: wraps an agent as a callable tool. Use .agent_tool() instead." }

# ---------------------------------------------------------------------------
# AGENT EXTRAS (Phase 1)
# ---------------------------------------------------------------------------

[[builders.Agent.extras]]
name = "tool"
signature = "(self, fn_or_tool: Any, *, require_confirmation: bool = False) -> Self"
doc = "Add a single tool (appends). Wraps plain callables in FunctionTool when require_confirmation=True."
behavior = "runtime_helper"
helper_func = "_add_tool"
example = '''
def search(query: str) -> str:
    """Search the web."""
    return f"Results for {query}"

agent = Agent("helper").tool(search).build()
'''
see_also = ["FunctionTool", "Agent.guard"]

[[builders.Agent.extras]]
name = "tools"
signature = "(self, value: Any) -> Self"
doc = "Set tools. Accepts a list, a TComposite chain (T.fn(x) | T.fn(y)), or a single tool/toolset."
behavior = "runtime_helper"
helper_func = "_add_tools"

[[builders.Agent.extras]]
name = "ui"
signature = "(self, spec: Any) -> Self"
doc = "Attach A2UI surface for rich UI output. Declarative: .ui(UI.form(...)). LLM-guided: .ui(UI.auto()). Component tree: .ui(UI.column(UI.text('Hi'), UI.button('Go', action='go')))."
behavior = "runtime_helper"
helper_func = "_add_ui_spec"
example = '''
from adk_fluent import Agent, UI

# Declarative form
agent = Agent("support", "gemini-2.5-flash").ui(
    UI.form("Contact", fields={"name": "text", "email": "email"})
).build()

# LLM-guided mode
agent = Agent("creative", "gemini-2.5-flash").ui(UI.auto()).build()
'''
see_also = ["UI.surface", "UI.form", "UI.auto"]

[[builders.Agent.extras]]
name = "guard"
signature = "(self, value: Any) -> Self"
doc = "Add an output validation guard. Accepts a G composite (G.pii() | G.length(max=500)) or a plain callable. Guards run as after_model callbacks and validate/transform the LLM response before it is returned."
behavior = "runtime_helper"
helper_func = "_guard_dispatch"
example = '''
from adk_fluent import G

# Declarative guards
agent = Agent("safe", "gemini-2.5-flash").guard(G.pii("redact") | G.budget(5000))

# Legacy callable guard (still works)
agent = Agent("safe", "gemini-2.5-flash").guard(my_guard_fn)
'''
see_also = ["Agent.before_model", "Agent.after_model"]

[[builders.Agent.extras]]
name = "ask"
signature = "(self, prompt: str) -> str"
doc = "One-shot SYNC execution (blocking). Builds agent, sends prompt, returns response text. Raises RuntimeError inside async event loops (Jupyter, FastAPI) — use .ask_async() instead."
behavior = "runtime_helper"
helper_func = "run_one_shot"
example = '''
reply = Agent("qa", "gemini-2.5-flash").instruct("Answer questions.").ask("What is Python?")
print(reply)
'''
see_also = ["Agent.ask_async", "Agent.stream"]

[[builders.Agent.extras]]
name = "ask_async"
signature = "(self, prompt: str) -> str"
doc = "One-shot ASYNC execution (non-blocking, use with await). Safe in Jupyter, FastAPI, and other async contexts."
behavior = "runtime_helper_async"
helper_func = "run_one_shot_async"

[[builders.Agent.extras]]
name = "stream"
signature = "(self, prompt: str) -> AsyncIterator[str]"
doc = "ASYNC streaming execution. Yields response text chunks as they arrive. Use with ``async for chunk in agent.stream(prompt):``."
behavior = "runtime_helper_async_gen"
helper_func = "run_stream"
example = '''
async for chunk in Agent("writer", "gemini-2.5-flash").instruct("Write a poem.").stream("About the sea"):
    print(chunk, end="")
'''
see_also = ["Agent.ask", "Agent.events"]

[[builders.Agent.extras]]
name = "test"
signature = "(self, prompt: str, *, contains: str | None = None, matches: str | None = None, equals: str | None = None) -> Self"
doc = "Run a smoke test. Calls .ask() internally, asserts output matches condition."
behavior = "runtime_helper"
helper_func = "run_inline_test"

[[builders.Agent.extras]]
name = "session"
signature = "(self) -> Any"
doc = "Create an interactive multi-turn chat session. Returns an async context manager — use with ``async with agent.session() as chat:``. The agent is auto-built."
behavior = "runtime_helper_ctx"
helper_func = "create_session"

[[builders.Agent.extras]]
name = "map"
signature = "(self, prompts: list[str], *, concurrency: int = 5) -> list[str]"
doc = "Batch SYNC execution (blocking). Run agent against multiple prompts with bounded concurrency. Raises RuntimeError inside async event loops — use .map_async() instead."
behavior = "runtime_helper"
helper_func = "run_map"

[[builders.Agent.extras]]
name = "map_async"
signature = "(self, prompts: list[str], *, concurrency: int = 5) -> list[str]"
doc = "Batch ASYNC execution (non-blocking, use with await). Safe in Jupyter, FastAPI, and other async contexts."
behavior = "runtime_helper_async"
helper_func = "run_map_async"

[[builders.Agent.extras]]
name = "events"
signature = "(self, prompt: str) -> AsyncIterator[Any]"
doc = "Stream raw ADK Event objects. Yields every event including state deltas and function calls."
behavior = "runtime_helper_async_gen"
helper_func = "run_events"

# ---------------------------------------------------------------------------
# CONTEXT ENGINEERING EXTRAS (Phase 5.1)
# ---------------------------------------------------------------------------

[[builders.Agent.extras]]
name = "instruct"
signature = "(self, value: str | Callable[[ReadonlyContext], str | Awaitable[str]]) -> Self"
doc = "Set the main instruction / system prompt — what the LLM is told to do. Accepts plain text, a callable, or a P module composition (P.role() + P.task()). Raises TypeError if passed a CTransform (use .context() instead)."
behavior = "runtime_helper"
helper_func = "_instruct_with_guard"

[[builders.Agent.extras]]
name = "context"
signature = "(self, spec: Any) -> Self"
doc = "Declare what conversation context this agent should see. Accepts a C module transform (C.none(), C.user_only(), C.from_state(), etc.)."
behavior = "runtime_helper"
helper_func = "_context_with_guard"
example = '''
from adk_fluent import C

agent = (
    Agent("writer")
    .model("gemini-2.5-flash")
    .instruct("Write about {topic}.")
    .context(C.from_state("topic"))
    .build()
)
'''
see_also = ["C", "Agent.memory"]

[[builders.Agent.extras]]
name = "show"
signature = "(self) -> Self"
doc = "Force this agent's events to be user-facing (override topology inference)."
behavior = "runtime_helper_ctx"
helper_func = "_show_agent"
example = '''
# Force intermediate agent output to be visible to users
agent = Agent("logger").model("m").instruct("Log progress.").show()
'''
see_also = ["Agent.hide"]

[[builders.Agent.extras]]
name = "hide"
signature = "(self) -> Self"
doc = "Force this agent's events to be internal (override topology inference)."
behavior = "runtime_helper_ctx"
helper_func = "_hide_agent"
example = '''
# Suppress terminal agent output from user view
agent = Agent("cleanup").model("m").instruct("Clean up.").hide()
'''
see_also = ["Agent.show"]

[[builders.Agent.extras]]
name = "memory"
signature = "(self, mode: str = 'preload') -> Self"
doc = "Add memory tools to this agent. Modes: 'preload', 'on_demand', 'both'."
behavior = "runtime_helper"
helper_func = "_add_memory"
example = '''
agent = Agent("assistant", "gemini-2.5-flash").memory("preload").build()
'''
see_also = ["Agent.memory_auto_save", "Agent.context"]

[[builders.Agent.extras]]
name = "memory_auto_save"
signature = "(self) -> Self"
doc = "Auto-save session to memory after each agent run."
behavior = "runtime_helper_ctx"
helper_func = "_add_memory_auto_save"

# ---------------------------------------------------------------------------
# DELEGATION EXTRAS
# ---------------------------------------------------------------------------

[[builders.Agent.extras]]
name = "agent_tool"
signature = "(self, agent: Any) -> Self"
doc = "Wrap another agent as a callable AgentTool and add it to this agent's tools. The parent LLM invokes the child like any other tool, stays in control, and receives the response. Compare with .sub_agent() which fully transfers control to the child."
behavior = "runtime_helper"
helper_func = "add_agent_tool"
example = '''
specialist = Agent("invoice_parser", "gemini-2.5-flash").instruct("Parse invoices.")
coordinator = (
    Agent("router", "gemini-2.5-flash")
    .instruct("Route tasks to specialists.")
    .agent_tool(specialist)
    .build()
)
'''
see_also = ["Agent.tool", "Agent.isolate"]

# ---------------------------------------------------------------------------
# TRANSFER CONTROL EXTRAS
# ---------------------------------------------------------------------------

[[builders.Agent.extras]]
name = "isolate"
signature = "(self) -> Self"
doc = "Prevent this agent from transferring to parent or peers. Sets both disallow_transfer_to_parent and disallow_transfer_to_peers to True. Use for specialist agents that should complete their task and return."
behavior = "runtime_helper"
helper_func = "_isolate_agent"
example = '''
# Specialist agent that completes its task without transferring
specialist = (
    Agent("invoice_parser", "gemini-2.5-flash")
    .instruct("Parse the invoice and extract line items.")
    .isolate()
    .returns(Invoice)
    .build()
)
'''
see_also = ["Agent.disallow_transfer_to_parent", "Agent.disallow_transfer_to_peers"]

[[builders.Agent.extras]]
name = "stay"
signature = "(self) -> Self"
doc = "Prevent transfer to parent only (can still transfer to sibling peers). Equivalent to .disallow_transfer_to_parent(True). Use for agents in peer-to-peer handoff chains where the coordinator should not regain control mid-sequence."
behavior = "runtime_helper"
helper_func = "_stay_agent"
example = '''
specialist = (
    Agent("invoice_parser", "gemini-2.5-flash")
    .instruct("Parse the invoice.")
    .stay()  # Must finish before returning to coordinator
    .build()
)
'''
see_also = ["Agent.isolate", "Agent.no_peers"]

[[builders.Agent.extras]]
name = "no_peers"
signature = "(self) -> Self"
doc = "Prevent this agent from transferring to sibling agents. The agent can still return to its parent."
behavior = "runtime_helper"
helper_func = "_no_peers_agent"
example = '''
focused = (
    Agent("researcher", "gemini-2.5-flash")
    .instruct("Research the topic thoroughly.")
    .no_peers()  # Don't hand off to sibling agents
    .build()
)
'''
see_also = ["Agent.isolate", "Agent.stay"]

# ---------------------------------------------------------------------------
# SCHEMA EXTRAS
# ---------------------------------------------------------------------------

[[builders.Agent.extras]]
name = "artifacts"
signature = "(self, *transforms: Any) -> Self"
doc = "Attach artifact operations (A.publish, A.snapshot, etc.) that fire after this agent completes."
behavior = "runtime_helper"
helper_func = "_add_artifacts"
example = '''Agent("writer").artifacts(A.publish("report.md", from_key="output"))'''
see_also = ["A", "ATransform"]

[[builders.Agent.extras]]
name = "tool_schema"
signature = "(self, schema: type) -> Self"
doc = "Attach a ToolSchema declaring tool state dependencies."
behavior = "field_set"
target_field = "_tool_schema"

[[builders.Agent.extras]]
name = "callback_schema"
signature = "(self, schema: type) -> Self"
doc = "Attach a CallbackSchema declaring callback state dependencies."
behavior = "field_set"
target_field = "_callback_schema"

[[builders.Agent.extras]]
name = "prompt_schema"
signature = "(self, schema: type) -> Self"
doc = "Attach a PromptSchema declaring prompt state dependencies."
behavior = "field_set"
target_field = "_prompt_schema"

[[builders.Agent.extras]]
name = "artifact_schema"
signature = "(self, schema: type) -> Self"
doc = "Attach an ArtifactSchema declaring artifact dependencies."
behavior = "field_set"
target_field = "_artifact_schema"
example = '''Agent("researcher").artifact_schema(ResearchArtifacts)'''
see_also = ["ArtifactSchema", "Produces", "Consumes"]

# ---------------------------------------------------------------------------
# EVALUATION EXTRAS (E module)
# ---------------------------------------------------------------------------

[[builders.Agent.extras]]
name = "eval"
signature = "(self, prompt: str, *, expect: str | None = None, criteria: Any | None = None) -> Any"
doc = "Inline evaluation. Run a single eval case against this agent. Returns an EvalSuite ready to .run()."
behavior = "runtime_helper"
helper_func = "_eval_inline"
example = '''
from adk_fluent import E

report = await agent.eval("What is 2+2?", expect="4").run()
assert report.ok

# With custom criteria
report = await agent.eval("query", criteria=E.semantic_match()).run()
'''
see_also = ["E", "Agent.eval_suite", "Agent.test"]

[[builders.Agent.extras]]
name = "eval_suite"
signature = "(self) -> Any"
doc = "Create an evaluation suite builder for this agent. Returns an EvalSuite bound to this agent."
behavior = "runtime_helper_ctx"
helper_func = "_eval_suite"
example = '''
from adk_fluent import E

report = await (
    agent.eval_suite()
    .case("What is 2+2?", expect="4")
    .criteria(E.trajectory() | E.response_match())
    .run()
)
'''
see_also = ["E", "Agent.eval", "EvalSuite"]

# ---------------------------------------------------------------------------
# IR CONVERSION EXTRAS
# ---------------------------------------------------------------------------
# These wire to_ir() through the codegen so it survives regeneration.

[[builders.Agent.extras]]
name = "to_ir"
signature = "(self) -> Any"
doc = "Convert this Agent builder to an AgentNode IR node."
behavior = "runtime_helper_ctx"
helper_func = "_agent_to_ir"

[[builders.Agent.extras]]
name = "skill"
signature = "(self, skill_id: str, name: str, *, description: str = '', tags: list[str] | None = None, examples: list[str] | None = None, input_modes: list[str] | None = None, output_modes: list[str] | None = None) -> Self"
doc = "Declare an A2A skill for this agent's AgentCard. Skills are metadata consumed by ``A2AServer`` during card generation. They have no effect on local agent execution. If no skills are declared, ``A2AServer`` auto-infers them from the agent's tools and sub-agents."
behavior = "runtime_helper"
helper_func = "_add_skill"

[[builders.Agent.extras]]
name = "publish"
signature = "(self, *, port: int = 8000, host: str = '0.0.0.0') -> Any"
doc = "Publish this agent as an A2A server (returns Starlette app). Shorthand for ``A2AServer(self).port(port).host(host).build()``."
behavior = "runtime_helper"
helper_func = "_publish_agent"

[[builders.Pipeline.extras]]
name = "to_ir"
signature = "(self) -> Any"
doc = "Convert this Pipeline builder to a SequenceNode IR node."
behavior = "runtime_helper_ctx"
helper_func = "_pipeline_to_ir"

[[builders.Pipeline.extras]]
name = "ask"
signature = "(self, prompt: str) -> str"
doc = "One-shot SYNC execution (blocking). Builds pipeline, sends prompt, returns response text."
behavior = "runtime_helper"
helper_func = "run_one_shot"

[[builders.Pipeline.extras]]
name = "ask_async"
signature = "(self, prompt: str) -> str"
doc = "One-shot ASYNC execution (non-blocking, use with await)."
behavior = "runtime_helper_async"
helper_func = "run_one_shot_async"

[[builders.Pipeline.extras]]
name = "stream"
signature = "(self, prompt: str) -> AsyncIterator[str]"
doc = "ASYNC streaming execution. Yields response text chunks as they arrive."
behavior = "runtime_helper_async_gen"
helper_func = "run_stream"

[[builders.Pipeline.extras]]
name = "events"
signature = "(self, prompt: str) -> AsyncIterator[Any]"
doc = "Stream raw ADK Event objects. Yields every event including state deltas and function calls."
behavior = "runtime_helper_async_gen"
helper_func = "run_events"

[[builders.Pipeline.extras]]
name = "session"
signature = "(self) -> Any"
doc = "Create an interactive multi-turn chat session. Returns an async context manager."
behavior = "runtime_helper_ctx"
helper_func = "create_session"

[[builders.Pipeline.extras]]
name = "map"
signature = "(self, prompts: list[str], *, concurrency: int = 5) -> list[str]"
doc = "Batch SYNC execution (blocking). Run pipeline against multiple prompts with bounded concurrency."
behavior = "runtime_helper"
helper_func = "run_map"

[[builders.Pipeline.extras]]
name = "map_async"
signature = "(self, prompts: list[str], *, concurrency: int = 5) -> list[str]"
doc = "Batch ASYNC execution (non-blocking, use with await)."
behavior = "runtime_helper_async"
helper_func = "run_map_async"

[[builders.Pipeline.extras]]
name = "test"
signature = "(self, prompt: str, *, contains: str | None = None, matches: str | None = None, equals: str | None = None) -> Self"
doc = "Run a smoke test. Calls .ask() internally, asserts output matches condition."
behavior = "runtime_helper"
helper_func = "run_inline_test"

[[builders.Pipeline.extras]]
name = "eval"
signature = "(self, prompt: str, *, expect: str | None = None, criteria: Any | None = None) -> Any"
doc = "Inline evaluation. Run a single eval case against this pipeline."
behavior = "runtime_helper"
helper_func = "_eval_inline"

[[builders.Pipeline.extras]]
name = "eval_suite"
signature = "(self) -> Any"
doc = "Create an evaluation suite builder for this pipeline."
behavior = "runtime_helper_ctx"
helper_func = "_eval_suite"

[[builders.FanOut.extras]]
name = "to_ir"
signature = "(self) -> Any"
doc = "Convert this FanOut builder to a ParallelNode IR node."
behavior = "runtime_helper_ctx"
helper_func = "_fanout_to_ir"

[[builders.FanOut.extras]]
name = "ask"
signature = "(self, prompt: str) -> str"
doc = "One-shot SYNC execution (blocking). Builds fan-out, sends prompt, returns response text."
behavior = "runtime_helper"
helper_func = "run_one_shot"

[[builders.FanOut.extras]]
name = "ask_async"
signature = "(self, prompt: str) -> str"
doc = "One-shot ASYNC execution (non-blocking, use with await)."
behavior = "runtime_helper_async"
helper_func = "run_one_shot_async"

[[builders.FanOut.extras]]
name = "stream"
signature = "(self, prompt: str) -> AsyncIterator[str]"
doc = "ASYNC streaming execution. Yields response text chunks as they arrive."
behavior = "runtime_helper_async_gen"
helper_func = "run_stream"

[[builders.FanOut.extras]]
name = "events"
signature = "(self, prompt: str) -> AsyncIterator[Any]"
doc = "Stream raw ADK Event objects. Yields every event including state deltas and function calls."
behavior = "runtime_helper_async_gen"
helper_func = "run_events"

[[builders.FanOut.extras]]
name = "session"
signature = "(self) -> Any"
doc = "Create an interactive multi-turn chat session. Returns an async context manager."
behavior = "runtime_helper_ctx"
helper_func = "create_session"

[[builders.FanOut.extras]]
name = "map"
signature = "(self, prompts: list[str], *, concurrency: int = 5) -> list[str]"
doc = "Batch SYNC execution (blocking). Run fan-out against multiple prompts with bounded concurrency."
behavior = "runtime_helper"
helper_func = "run_map"

[[builders.FanOut.extras]]
name = "map_async"
signature = "(self, prompts: list[str], *, concurrency: int = 5) -> list[str]"
doc = "Batch ASYNC execution (non-blocking, use with await)."
behavior = "runtime_helper_async"
helper_func = "run_map_async"

[[builders.FanOut.extras]]
name = "test"
signature = "(self, prompt: str, *, contains: str | None = None, matches: str | None = None, equals: str | None = None) -> Self"
doc = "Run a smoke test. Calls .ask() internally, asserts output matches condition."
behavior = "runtime_helper"
helper_func = "run_inline_test"

[[builders.FanOut.extras]]
name = "eval"
signature = "(self, prompt: str, *, expect: str | None = None, criteria: Any | None = None) -> Any"
doc = "Inline evaluation. Run a single eval case against this fan-out."
behavior = "runtime_helper"
helper_func = "_eval_inline"

[[builders.FanOut.extras]]
name = "eval_suite"
signature = "(self) -> Any"
doc = "Create an evaluation suite builder for this fan-out."
behavior = "runtime_helper_ctx"
helper_func = "_eval_suite"

[[builders.Loop.extras]]
name = "to_ir"
signature = "(self) -> Any"
doc = "Convert this Loop builder to a LoopNode IR node."
behavior = "runtime_helper_ctx"
helper_func = "_loop_to_ir"

[[builders.Loop.extras]]
name = "ask"
signature = "(self, prompt: str) -> str"
doc = "One-shot SYNC execution (blocking). Builds loop, sends prompt, returns response text."
behavior = "runtime_helper"
helper_func = "run_one_shot"

[[builders.Loop.extras]]
name = "ask_async"
signature = "(self, prompt: str) -> str"
doc = "One-shot ASYNC execution (non-blocking, use with await)."
behavior = "runtime_helper_async"
helper_func = "run_one_shot_async"

[[builders.Loop.extras]]
name = "stream"
signature = "(self, prompt: str) -> AsyncIterator[str]"
doc = "ASYNC streaming execution. Yields response text chunks as they arrive."
behavior = "runtime_helper_async_gen"
helper_func = "run_stream"

[[builders.Loop.extras]]
name = "events"
signature = "(self, prompt: str) -> AsyncIterator[Any]"
doc = "Stream raw ADK Event objects. Yields every event including state deltas and function calls."
behavior = "runtime_helper_async_gen"
helper_func = "run_events"

[[builders.Loop.extras]]
name = "session"
signature = "(self) -> Any"
doc = "Create an interactive multi-turn chat session. Returns an async context manager."
behavior = "runtime_helper_ctx"
helper_func = "create_session"

[[builders.Loop.extras]]
name = "map"
signature = "(self, prompts: list[str], *, concurrency: int = 5) -> list[str]"
doc = "Batch SYNC execution (blocking). Run loop against multiple prompts with bounded concurrency."
behavior = "runtime_helper"
helper_func = "run_map"

[[builders.Loop.extras]]
name = "map_async"
signature = "(self, prompts: list[str], *, concurrency: int = 5) -> list[str]"
doc = "Batch ASYNC execution (non-blocking, use with await)."
behavior = "runtime_helper_async"
helper_func = "run_map_async"

[[builders.Loop.extras]]
name = "test"
signature = "(self, prompt: str, *, contains: str | None = None, matches: str | None = None, equals: str | None = None) -> Self"
doc = "Run a smoke test. Calls .ask() internally, asserts output matches condition."
behavior = "runtime_helper"
helper_func = "run_inline_test"

[[builders.Loop.extras]]
name = "eval"
signature = "(self, prompt: str, *, expect: str | None = None, criteria: Any | None = None) -> Any"
doc = "Inline evaluation. Run a single eval case against this loop."
behavior = "runtime_helper"
helper_func = "_eval_inline"

[[builders.Loop.extras]]
name = "eval_suite"
signature = "(self) -> Any"
doc = "Create an evaluation suite builder for this loop."
behavior = "runtime_helper_ctx"
helper_func = "_eval_suite"
