类 PlanNotebook

java.lang.Object
io.agentscope.core.plan.PlanNotebook
所有已实现的接口:
StateModule

public class PlanNotebook extends Object implements StateModule
Plan notebook for managing complex tasks through structured planning.

Provides tool functions for agents to create, manage, and track plans. Automatically injects contextual hints to guide agent execution through a hook-based mechanism.

Core Features:

  • Plan Management: Create, revise, and finish plans with multiple subtasks
  • Automatic Hint Injection: Injects contextual hints before each reasoning step
  • State Tracking: Tracks subtask states (todo/in_progress/done/abandoned)
  • Historical Plans: Stores and recovers historical plans

Usage Example:


 // Create PlanNotebook with custom configuration
 PlanNotebook planNotebook = PlanNotebook.builder()
     .planToHint(new DefaultPlanToHint())
     .storage(new InMemoryPlanStorage())
     .maxSubtasks(10)
     .build();

 // Create Agent with PlanNotebook (automatically registers tools and hook)
 ReActAgent agent = ReActAgent.builder()
     .name("Assistant")
     .model(model)
     .toolkit(toolkit)
     .planNotebook(planNotebook)
     .build();

 // Or use default PlanNotebook configuration
 ReActAgent agent = ReActAgent.builder()
     .name("Assistant")
     .model(model)
     .toolkit(toolkit)
     .enablePlan()
     .build();

 // Now agent will automatically receive hints before each reasoning step
 agent.call(msg).block();
 

Tool Functions: PlanNotebook provides 10 tool functions:

  • 字段详细资料

  • 方法详细资料

    • builder

      public static PlanNotebook.Builder builder()
      Creates a new builder for constructing PlanNotebook instances.
      返回:
      A new builder instance with default settings
    • saveTo

      public void saveTo(Session session, SessionKey sessionKey)
      Save PlanNotebook state to the session.

      Always saves the current state, including when currentPlan is null, to ensure cleared state is persisted.

      指定者:
      saveTo 在接口中 StateModule
      参数:
      session - the session to save state to
      sessionKey - the session identifier
    • loadFrom

      public void loadFrom(Session session, SessionKey sessionKey)
      Load PlanNotebook state from the session.
      指定者:
      loadFrom 在接口中 StateModule
      参数:
      session - the session to load state from
      sessionKey - the session identifier
    • createPlan

      @Tool(name="create_plan", description="Create a plan by given name and sub-tasks") public reactor.core.publisher.Mono<String> createPlan(@ToolParam(name="name",description="The plan name, should be concise, descriptive and not exceed 10 words") String name, @ToolParam(name="description",description="The plan description, including the constraints, target and outcome to be achieved. The description should be clear, specific and concise, and all the constraints, target and outcome should be specific and measurable") String description, @ToolParam(name="expected_outcome",description="The expected outcome of the plan, which should be specific, concrete and measurable") String expectedOutcome, @ToolParam(name="subtasks",description="A list of sequential sub-tasks. Each subtask must be an object with: \'name\' (string, required), \'description\' (string), \'expected_outcome\' (string). Example: [{\"name\": \"Calculate area\", \"description\": \"Multiply length by width\", \"expected_outcome\": \"Area value\"}]") List<Map<String,Object>> subtasks)
      Create a plan by given name and sub-tasks.
      参数:
      name - The plan name, should be concise, descriptive and not exceed 10 words
      description - The plan description, including the constraints, target and outcome
      expectedOutcome - The expected outcome of the plan
      subtasks - A list of sequential sub-tasks that make up the plan
      返回:
      Tool response message
    • updatePlanInfo

      @Tool(name="update_plan_info", description="Update the current plan\'s name, description, or expected outcome. Pass null or empty string to keep a field unchanged.") public reactor.core.publisher.Mono<String> updatePlanInfo(@ToolParam(name="name",description="The new plan name (optional, pass null or empty to keep unchanged)") String name, @ToolParam(name="description",description="The new plan description (optional, pass null or empty to keep unchanged)") String description, @ToolParam(name="expected_outcome",description="The new expected outcome (optional, pass null or empty to keep unchanged)") String expectedOutcome)
      Update the current plan's name, description, or expected outcome.
      参数:
      name - The new plan name (optional, pass null or empty to keep unchanged)
      description - The new plan description (optional, pass null or empty to keep unchanged)
      expectedOutcome - The new expected outcome (optional, pass null or empty to keep unchanged)
      返回:
      Tool response message
    • createPlanWithSubTasks

      public reactor.core.publisher.Mono<String> createPlanWithSubTasks(String name, String description, String expectedOutcome, List<SubTask> subtasks)
      Create a plan with SubTask objects (convenience method for tests and Java code).
      参数:
      name - The plan name
      description - The plan description
      expectedOutcome - The expected outcome
      subtasks - The list of SubTask objects
      返回:
      Tool response message
    • subtasksToMaps

      public static List<Map<String,Object>> subtasksToMaps(List<SubTask> subtasks)
      Helper method to convert a list of SubTask objects to a list of Maps.
      参数:
      subtasks - List of SubTask objects
      返回:
      List of Maps
    • subtaskToMap

      public static Map<String,Object> subtaskToMap(SubTask subtask)
      Helper method to convert a SubTask object to a Map.
      参数:
      subtask - SubTask object
      返回:
      Map representation
    • reviseCurrentPlan

      @Tool(name="revise_current_plan", description="Revise the current plan by adding, revising or deleting a sub-task") public reactor.core.publisher.Mono<String> reviseCurrentPlan(@ToolParam(name="subtask_idx",description="The index of the sub-task to be revised, starting from 0") int subtaskIdx, @ToolParam(name="action",description="The action to be performed: add/revise/delete") String action, @ToolParam(name="subtask",description="The sub-task to be added or revised (required for add/revise)") Map<String,Object> subtaskMap)
      Revise the current plan by adding, revising or deleting a sub-task.
      参数:
      subtaskIdx - The index of the sub-task to be revised, starting from 0
      action - The action to be performed: add/revise/delete
      subtaskMap - The sub-task to be added or revised (required for add/revise)
      返回:
      Tool response message
    • updateSubtaskState

      @Tool(name="update_subtask_state", description="Update the state of a subtask by given index and state") public reactor.core.publisher.Mono<String> updateSubtaskState(@ToolParam(name="subtask_idx",description="The index of the subtask to be updated, starting from 0") int subtaskIdx, @ToolParam(name="state",description="The new state: todo/in_progress/abandoned") String stateStr)
      Update the state of a subtask by given index and state.

      Note: To mark a subtask as done, you SHOULD call finishSubtask(int, java.lang.String) instead with the specific outcome.

      参数:
      subtaskIdx - The index of the subtask to be updated, starting from 0
      stateStr - The new state: todo/in_progress/abandoned
      返回:
      Tool response message
    • finishSubtask

      @Tool(name="finish_subtask", description="Label the subtask as done by given index and outcome") public reactor.core.publisher.Mono<String> finishSubtask(@ToolParam(name="subtask_idx",description="The index of the sub-task to be marked as done, starting from 0") int subtaskIdx, @ToolParam(name="subtask_outcome",description="The specific outcome of the sub-task, should exactly match the expected outcome in the sub-task description. SHOULDN\'T be what you did or general description, e.g. \"I have searched xxx\", \"I have written the code for xxx\", etc. It SHOULD be the specific data, information, or path to the file, e.g. \"There are 5 articles about xxx, they are\\n- xxx\\n- xxx\\n...\"") String outcome)
      Label the subtask as done by given index and outcome.
      参数:
      subtaskIdx - The index of the sub-task to be marked as done, starting from 0
      outcome - The specific outcome of the sub-task
      返回:
      Tool response message
    • viewSubtasks

      @Tool(name="view_subtasks", description="View the details of the sub-tasks by given indexes") public reactor.core.publisher.Mono<String> viewSubtasks(@ToolParam(name="subtask_idx",description="The indexes of the sub-tasks to be viewed, starting from 0") List<Integer> indexes)
      View the details of the sub-tasks by given indexes.
      参数:
      indexes - The indexes of the sub-tasks to be viewed, starting from 0
      返回:
      Tool response message with subtask details
    • getSubtaskCount

      @Tool(name="get_subtask_count", description="Get the number of subtasks in the current plan") public reactor.core.publisher.Mono<String> getSubtaskCount()
      Get the number of subtasks in the current plan.
      返回:
      Tool response message with subtask count
    • finishPlan

      @Tool(name="finish_plan", description="Finish the current plan by given outcome, or abandon it") public reactor.core.publisher.Mono<String> finishPlan(@ToolParam(name="state",description="The state to finish the plan: done/abandoned") String stateStr, @ToolParam(name="outcome",description="The specific outcome of the plan if done, or reason if abandoned") String outcome)
      Finish the current plan by given outcome, or abandon it.
      参数:
      stateStr - The state to finish the plan: done/abandoned
      outcome - The specific outcome of the plan if done, or reason if abandoned
      返回:
      Tool response message
    • viewHistoricalPlans

      @Tool(name="view_historical_plans", description="View the historical plans") public reactor.core.publisher.Mono<String> viewHistoricalPlans()
      View the historical plans.
    • recoverHistoricalPlan

      @Tool(name="recover_historical_plan", description="Recover a historical plan by given plan ID") public reactor.core.publisher.Mono<String> recoverHistoricalPlan(@ToolParam(name="plan_id",description="The ID of the historical plan to be recovered") String planId)
      Recover a historical plan by given plan ID.
      参数:
      planId - The ID of the historical plan to be recovered
      返回:
      Tool response message
    • getCurrentHint

      public reactor.core.publisher.Mono<Msg> getCurrentHint()
      Gets the current hint message based on plan state.

      This is called internally by the injected hook before each reasoning step to provide contextual guidance to the agent.

      返回:
      A Mono emitting a USER role message containing the hint, or empty Mono if no hint is applicable
    • getCurrentPlan

      public Plan getCurrentPlan()
      Gets the current active plan.
      返回:
      The current plan, or null if no plan is active
    • isNeedUserConfirm

      public boolean isNeedUserConfirm()
      Checks if user confirmation is required before executing plans.
      返回:
      true if user confirmation is required, false otherwise
    • getMaxSubtasks

      public Integer getMaxSubtasks()
      Gets the maximum number of subtasks allowed per plan.
      返回:
      maximum number of subtasks
    • addChangeHook

      public void addChangeHook(String id, BiConsumer<PlanNotebook,Plan> hook)
      Adds a change hook that will be triggered whenever the plan changes.

      The hook receives the PlanNotebook instance and the current plan (which may be null if the plan was finished or cleared).

      参数:
      id - unique identifier for the hook (used for removal)
      hook - the callback to execute when plan changes
    • removeChangeHook

      public void removeChangeHook(String id)
      Removes a previously registered change hook.
      参数:
      id - the identifier of the hook to remove