diff --git a/codex-rs/core/prompt.md b/codex-rs/core/prompt.md index df9161dd..ff5c2acd 100644 --- a/codex-rs/core/prompt.md +++ b/codex-rs/core/prompt.md @@ -39,7 +39,13 @@ Before making tool calls, send a brief preamble to the user explaining what you ## Planning -You have access to an `update_plan` tool which tracks steps and progress and renders them to the user. Using the tool helps demonstrate that you've understood the task and convey how you're approaching it. Plans can help to make complex, ambiguous, or multi-phase work clearer and more collaborative for the user. A good plan should break the task into meaningful, logically ordered steps that are easy to verify as you go. Note that plans are not for padding out simple work with filler steps or stating the obvious. Do not repeat the full contents of the plan after an `update_plan` call — the harness already displays it. Instead, summarize the change made and highlight any important context or next step. +You have access to an `update_plan` tool which tracks steps and progress and renders them to the user. Using the tool helps demonstrate that you've understood the task and convey how you're approaching it. Plans can help to make complex, ambiguous, or multi-phase work clearer and more collaborative for the user. A good plan should break the task into meaningful, logically ordered steps that are easy to verify as you go. + +Note that plans are not for padding out simple work with filler steps or stating the obvious. The content of your plan should not involve doing anything that you aren't capable of doing (i.e. don't try to test things that you can't test). Do not use plans for simple or single-step queries that you can just do or answer immediately. + +Do not repeat the full contents of the plan after an `update_plan` call — the harness already displays it. Instead, summarize the change made and highlight any important context or next step. + +Before running a command, consider whether or not you have completed the previous step, and make sure to mark it as completed before moving on to the next step. It may be the case that you complete all steps in your plan after a single pass of implementation. If this is the case, you can simply mark all the planned steps as completed. Sometimes, you may need to change plans in the middle of a task: call `update_plan` with the updated plan and make sure to provide an `explanation` of the rationale when doing so. Use a plan when: @@ -51,15 +57,6 @@ Use a plan when: - The user has asked you to use the plan tool (aka "TODOs") - You generate additional steps while working, and plan to do them before yielding to the user -Skip a plan when: - -- The task is simple and direct. -- Breaking it down would only produce literal or trivial steps. - -Planning steps are called "steps" in the tool, but really they're more like tasks or TODOs. As such they should be very concise descriptions of non-obvious work that an engineer might do like "Write the API spec", then "Update the backend", then "Implement the frontend". On the other hand, it's obvious that you'll usually have to "Explore the codebase" or "Implement the changes", so those are not worth tracking in your plan. - -It may be the case that you complete all steps in your plan after a single pass of implementation. If this is the case, you can simply mark all the planned steps as completed. The content of your plan should not involve doing anything that you aren't capable of doing (i.e. don't try to test things that you can't test). Do not use plans for simple or single-step queries that you can just do or answer immediately. - ### Examples **High-quality plans** diff --git a/codex-rs/core/src/plan_tool.rs b/codex-rs/core/src/plan_tool.rs index bba53632..9e81abcd 100644 --- a/codex-rs/core/src/plan_tool.rs +++ b/codex-rs/core/src/plan_tool.rs @@ -42,7 +42,9 @@ pub(crate) static PLAN_TOOL: LazyLock = LazyLock::new(|| { plan_item_props.insert("step".to_string(), JsonSchema::String { description: None }); plan_item_props.insert( "status".to_string(), - JsonSchema::String { description: None }, + JsonSchema::String { + description: Some("One of: pending, in_progress, completed".to_string()), + }, ); let plan_items_schema = JsonSchema::Array { @@ -63,17 +65,11 @@ pub(crate) static PLAN_TOOL: LazyLock = LazyLock::new(|| { OpenAiTool::Function(ResponsesApiTool { name: "update_plan".to_string(), - description: r#"Use the update_plan tool to keep the user updated on the current plan for the task. -After understanding the user's task, call the update_plan tool with an initial plan. An example of a plan: -1. Explore the codebase to find relevant files (status: in_progress) -2. Implement the feature in the XYZ component (status: pending) -3. Commit changes and make a pull request (status: pending) -Each step should be a short, 1-sentence description. -Until all the steps are finished, there should always be exactly one in_progress step in the plan. -Call the update_plan tool whenever you finish a step, marking the completed step as `completed` and marking the next step as `in_progress`. -Before running a command, consider whether or not you have completed the previous step, and make sure to mark it as completed before moving on to the next step. -Sometimes, you may need to change plans in the middle of a task: call `update_plan` with the updated plan and make sure to provide an `explanation` of the rationale when doing so. -When all steps are completed, call update_plan one last time with all steps marked as `completed`."#.to_string(), + description: r#"Updates the task plan. +Provide an optional explanation and a list of plan items, each with a step and status. +At most one step can be in_progress at a time. +"# + .to_string(), strict: false, parameters: JsonSchema::Object { properties,