jeevesagent.architecture.plan_and_execute
=========================================

.. py:module:: jeevesagent.architecture.plan_and_execute

.. autoapi-nested-parse::

   Plan-and-Execute: planner → step executor → synthesizer.

   Wang et al. 2023 (`Plan-and-Solve Prompting`), He et al. 2025
   (`Plan-then-Execute Pattern Implementation`). The 2026 production
   pattern for cost-sensitive multi-step tasks where ReAct-style
   "think before each action" wastes tokens — Plan-and-Execute
   commits to a plan upfront and executes step-by-step.

   Pattern (v1 simple)
   -------------------

   1. **Plan.** A single planner call produces a JSON list of step
      descriptions. Steps are short, ordered, dependency-free for v1.
   2. **Execute.** Each step is a text-only model call seeded with the
      original problem, the plan, and prior step outputs. Sequential.
   3. **Synthesize.** A final model call combines step outputs into
      the answer.

   What's NOT in v1
   ----------------

   * **Sub-architecture invocation per step.** Each step is a single
     text-only call, NOT a fresh ReAct (or any other architecture)
     invocation. That's the planned v0.5 work — it unblocks Deep Agent
     and a richer ReWOO too.
   * **Replanning on failure.** ``max_replans`` is in the constructor
     but not yet wired; it'll land alongside the sub-architecture
     invocation primitive when steps can fail meaningfully.
   * **Parallel step execution.** Steps run sequentially. DAG-aware
     parallel execution is straightforward to add once dependencies
     are first-class on :class:`PlanStep`.

   Strengths
   ---------
   * **Cheaper than ReAct** for tasks with predictable structure: one
     planner + N step calls + one synthesizer ≪ N×K ReAct turns.
   * **Observable plan.** The plan is a structured Pydantic object you
     can log, audit, or override before execution.

   Weaknesses
   ----------
   * No tool use within steps in v1 (use ReAct or Supervisor for
     tool-heavy work).
   * Plan quality bounds answer quality; bad planner = bad output.



Attributes
----------

.. autoapisummary::

   jeevesagent.architecture.plan_and_execute.DEFAULT_EXECUTOR_PROMPT
   jeevesagent.architecture.plan_and_execute.DEFAULT_PLANNER_PROMPT
   jeevesagent.architecture.plan_and_execute.DEFAULT_SYNTHESIZER_PROMPT


Classes
-------

.. autoapisummary::

   jeevesagent.architecture.plan_and_execute.Plan
   jeevesagent.architecture.plan_and_execute.PlanAndExecute
   jeevesagent.architecture.plan_and_execute.PlanStep
   jeevesagent.architecture.plan_and_execute.StepResult


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

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

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


   A list of plan steps in execution order.

   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[PlanStep]
      :value: None



.. py:class:: PlanAndExecute(*, max_steps: int = 8, planner_prompt: str | None = None, executor_prompt: str | None = None, synthesizer_prompt: str | None = None)

   Planner → step executor → synthesizer.


   .. 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: 'plan-and-execute'



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

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


   One step of a plan.

   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:: description
      :type:  str


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


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

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


   The output of executing one step.

   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:: description
      :type:  str


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


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


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

   .. raw:: html

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

   .. code-block:: python

      """You are executing one step of a multi-step plan. Use the original
      task and the prior step outputs to produce this step's output.
      
      Output ONLY the result of this step (no preamble, no commentary)."""

   .. raw:: html

      </details>



.. 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. The plan
      must be executable: each step should be a concrete sub-task that an
      LLM can complete in a single response.
      
      Output a JSON list of strings — each string is one step description.
      Aim for 3-7 steps; fewer is better when the task is simple. Order
      matters: each step can use prior step outputs.
      
      Output ONLY the JSON list. No prose, no markdown fences."""

   .. raw:: html

      </details>



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

   .. raw:: html

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

   .. code-block:: python

      """You synthesize the final answer from a sequence of step outputs.
      Combine them into a single coherent response that addresses the
      original task. Be concise; don't repeat the steps verbatim."""

   .. raw:: html

      </details>



