jeevesagent.architecture.rewoo
==============================

.. py:module:: jeevesagent.architecture.rewoo

.. autoapi-nested-parse::

   ReWOO: Reasoning WithOut Observation — plan-then-tool-execute.

   Xu et al. 2023 — `ReWOO: Decoupling Reasoning from Observations
   for Efficient Augmented Language Models
   <https://arxiv.org/abs/2305.18323>`_. The cost-saving sibling of
   :class:`~jeevesagent.architecture.PlanAndExecute`: each step in the
   plan is a real **tool call**, with ``{{En}}`` placeholder
   substitution to reference prior step outputs. Independent steps
   (no dependency on each other) run in **parallel**.

   Total cost: **2 LLM calls + N tool calls**. ReAct on the same task
   needs roughly N+1 LLM calls (one per turn). For tool-heavy workloads
   where the planner can predict the call sequence upfront, ReWOO is
   30-50% cheaper.

   Pattern
   -------

   1. **Planner.** ONE LLM call. Output is a JSON list of steps. Each
      step has shape::

          {"id": "E1", "tool": "<tool_name>", "args": {...}}

      Args may reference prior steps via ``{{En}}`` placeholders —
      ``{"args": {"url": "{{E1}}"}}`` will use E1's output as the
      ``url`` arg when E2 runs.

   2. **Worker.** Compute topological levels from the plan's
      placeholder dependencies. For each level, dispatch all steps
      in parallel via ``deps.tools.call(...)``. Substitute
      ``{{En}}`` placeholders in args from prior step outputs first.

   3. **Solver.** ONE LLM call. Given the original task and the
      step→output map, produce the final answer.

   Strengths
   ---------
   * **Cheaper than ReAct on tool-heavy multi-step tasks.** Two LLM
     calls cap the LLM cost regardless of plan length.
   * **Parallelism for free.** Independent steps run concurrently via
     ``anyio.create_task_group`` (same primitive Supervisor + ReAct
     use for parallel tool dispatch).
   * **Observable plan.** The plan is a structured Pydantic object —
     log it, audit it, override it before execution.

   Weaknesses
   ---------
   * **Planner must predict accurately upfront.** No replanning on
     failure in v1. If a step fails, the worker logs the error and
     the solver sees it as the step's "output."
   * **Limited to known tool names.** A planner that hallucinates a
     tool name produces a step that errors at dispatch time.
   * **Placeholder substitution is string-typed.** Tool outputs get
     stringified. For structured-output tools, the planner has to
     treat outputs as opaque text.



Attributes
----------

.. autoapisummary::

   jeevesagent.architecture.rewoo.DEFAULT_PLANNER_PROMPT
   jeevesagent.architecture.rewoo.DEFAULT_SOLVER_PROMPT


Classes
-------

.. autoapisummary::

   jeevesagent.architecture.rewoo.ReWOO
   jeevesagent.architecture.rewoo.ReWOOPlan
   jeevesagent.architecture.rewoo.ReWOOStep
   jeevesagent.architecture.rewoo.ReWOOStepResult


Module Contents
---------------

.. py:class:: ReWOO(*, max_steps: int = 8, planner_prompt: str | None = None, solver_prompt: str | None = None, parallel_levels: bool = True)

   Plan-then-tool-execute with placeholder substitution.


   .. py:method:: declared_workers() -> dict[str, jeevesagent.agent.api.Agent]


   .. py:method:: run(session: jeevesagent.architecture.base.AgentSession, deps: jeevesagent.architecture.base.Dependencies, prompt: str) -> collections.abc.AsyncIterator[jeevesagent.core.types.Event]
      :async:



   .. py:attribute:: name
      :value: 'rewoo'



.. py:class:: ReWOOPlan(/, **data: Any)

   Bases: :py:obj:`pydantic.BaseModel`


   A list of ReWOO steps (no required ordering — dependencies
   are inferred from ``{{En}}`` placeholders).

   Create a new model by parsing and validating input data from keyword arguments.

   Raises [`ValidationError`][pydantic_core.ValidationError] if the input data cannot be
   validated to form a valid model.

   `self` is explicitly positional-only to allow `self` as a field name.


   .. py:attribute:: steps
      :type:  list[ReWOOStep]
      :value: None



.. py:class:: ReWOOStep(/, **data: Any)

   Bases: :py:obj:`pydantic.BaseModel`


   One step of a ReWOO plan: id + tool + args.

   Create a new model by parsing and validating input data from keyword arguments.

   Raises [`ValidationError`][pydantic_core.ValidationError] if the input data cannot be
   validated to form a valid model.

   `self` is explicitly positional-only to allow `self` as a field name.


   .. py:attribute:: args
      :type:  dict[str, Any]
      :value: None



   .. py:property:: depends_on
      :type: list[str]


      Extract ``{{En}}`` step ids referenced in args.


   .. py:attribute:: id
      :type:  str


   .. py:attribute:: tool
      :type:  str


.. py:class:: ReWOOStepResult(/, **data: Any)

   Bases: :py:obj:`pydantic.BaseModel`


   !!! abstract "Usage Documentation"
       [Models](../concepts/models.md)

   A base class for creating Pydantic models.

   .. attribute:: __class_vars__

      The names of the class variables defined on the model.

   .. attribute:: __private_attributes__

      Metadata about the private attributes of the model.

   .. attribute:: __signature__

      The synthesized `__init__` [`Signature`][inspect.Signature] of the model.

   .. attribute:: __pydantic_complete__

      Whether model building is completed, or if there are still undefined fields.

   .. attribute:: __pydantic_core_schema__

      The core schema of the model.

   .. attribute:: __pydantic_custom_init__

      Whether the model has a custom `__init__` function.

   .. attribute:: __pydantic_decorators__

      Metadata containing the decorators defined on the model.
      This replaces `Model.__validators__` and `Model.__root_validators__` from Pydantic V1.

   .. attribute:: __pydantic_generic_metadata__

      Metadata for generic models; contains data used for a similar purpose to
      __args__, __origin__, __parameters__ in typing-module generics. May eventually be replaced by these.

   .. attribute:: __pydantic_parent_namespace__

      Parent namespace of the model, used for automatic rebuilding of models.

   .. attribute:: __pydantic_post_init__

      The name of the post-init method for the model, if defined.

   .. attribute:: __pydantic_root_model__

      Whether the model is a [`RootModel`][pydantic.root_model.RootModel].

   .. attribute:: __pydantic_serializer__

      The `pydantic-core` `SchemaSerializer` used to dump instances of the model.

   .. attribute:: __pydantic_validator__

      The `pydantic-core` `SchemaValidator` used to validate instances of the model.

   .. attribute:: __pydantic_fields__

      A dictionary of field names and their corresponding [`FieldInfo`][pydantic.fields.FieldInfo] objects.

   .. attribute:: __pydantic_computed_fields__

      A dictionary of computed field names and their corresponding [`ComputedFieldInfo`][pydantic.fields.ComputedFieldInfo] objects.

   .. attribute:: __pydantic_extra__

      A dictionary containing extra values, if [`extra`][pydantic.config.ConfigDict.extra]
      is set to `'allow'`.

   .. attribute:: __pydantic_fields_set__

      The names of fields explicitly set during instantiation.

   .. attribute:: __pydantic_private__

      Values of private attributes set on the model instance.

   Create a new model by parsing and validating input data from keyword arguments.

   Raises [`ValidationError`][pydantic_core.ValidationError] if the input data cannot be
   validated to form a valid model.

   `self` is explicitly positional-only to allow `self` as a field name.


   .. py:attribute:: error
      :type:  str | None
      :value: None



   .. py:attribute:: output
      :type:  str


   .. py:attribute:: step_id
      :type:  str


   .. py:attribute:: tool
      :type:  str


.. py:data:: DEFAULT_PLANNER_PROMPT
   :value: Multiline-String

   .. raw:: html

      <details><summary>Show Value</summary>

   .. code-block:: python

      """You produce a step-by-step plan to solve the user's task using the
      available tools. Each step is a tool call.
      
      Output ONLY a JSON array of step objects. Each step has:
      - "id": a short identifier like "E1", "E2", ... unique within the plan
      - "tool": the name of one of the available tools
      - "args": a dict of arguments to pass to the tool
      
      You may reference a prior step's output in args using `{{En}}`. The
      worker will substitute `{{En}}` with the actual output of step En
      before invoking the tool.
      
      Available tools:
      {tool_descriptions}
      
      Output format example:
      [
        {{"id": "E1", "tool": "web_search", "args": {{"query": "Tokyo weather"}}}},
        {{"id": "E2", "tool": "summarize", "args": {{"text": "{{{{E1}}}}"}}}}
      ]
      
      Output ONLY the JSON array. No prose, no markdown fences.
      """

   .. raw:: html

      </details>



.. py:data:: DEFAULT_SOLVER_PROMPT
   :value: Multiline-String

   .. raw:: html

      <details><summary>Show Value</summary>

   .. code-block:: python

      """You synthesize the final answer from a sequence of tool-call
      results. Use the original task and the step outputs to produce the
      final answer. Be concise."""

   .. raw:: html

      </details>



