Add parallel course correction agent with forced tool call
I'll help you add a course correction agent. Let me first explore the codebase to understand the relevant patterns.
Let me read the key files to understand the patterns better:
Let me also check the thread structure to understand how user messages are added and look at an example tool definition:
Let me also check the tool-service to understand the BaseToolSpec structure and look at the thread-delta for how user messages are added:
Now let me look at thread-delta to see more about user messages and check the thread structure for ThreadUserMessage:
Now let me look at how runInferenceAndUpdateThread works and check when we can inject logic after tool results are added:
Now I understand the structure better. Let me also look at the hooks system since it's used for end-turn handling:
Now let me check the handoff tool definition to understand the pattern better:
Now I have a good understanding of the structure. Let me create the course correction agent. I'll start by creating a new file:
Let me check the thread-markdown.ts file and look at how to format threads as markdown:
Now I have a good understanding. Let me create the course correction agent file:
Now I need to integrate this into the thread-worker. Let me first understand the hooks schema better and then modify the thread-worker:
Now let me look at how InternalHooks is used and where we should add the course correction logic. Let me also check the thread-delta for adding a new delta type for course correction messages:
I see that the source field on user messages can be used to track where a message came from. Let me extend this to support course correction. Let me update the thread.ts to add a new source type:
Now I need to integrate the course correction logic into the thread-worker. Let me look at the end of executeToolBatchesSequentially where inference is triggered:
Now let me understand where to add the course correction logic. I need to look at when tools complete and inference is triggered. Let me look at more of the tool:data handling:
Now I understand the flow. The course correction should run:
- After tool execution completes (before
runInferenceAndUpdateThreadis called) - On
end_turn(if user hasn't sent a message)
Let me now add the course correction logic to the thread-worker. I'll add it as an internal hook and modify the relevant parts:
Now I need to add course correction support. Rather than modifying InternalHooks (which is public-facing), I'll add the logic directly into the thread-worker. Let me add the course correction integration:
Let me look at the class properties and constructor:
Now let me add the course correction operation tracking and the logic. First, let me add the import and the ops field, then modify the relevant parts:
Now let me add the import for course correction and modify the thread-worker:
Now let me add the course correction ops field:
Now let me add a setting flag to enable/disable course correction. Let me first check how configuration settings are accessed:
Let me look at how settings are typically defined:
Now let me add a setting for course correction:
Now let me create the course correction method in the thread-worker. Let me find a good place to add it:
Now let me add the course correction method. I'll add it after the runInferenceAndUpdateThread method and before setTestEphemeralError:
Now I need to hook up the course correction to run at the right times:
- After tools complete (before running inference)
- On end_turn (if no queued messages)
Let me first update the tool:data handler to run course correction after tools complete:
I need to trigger the course correction before runInferenceAndUpdateThread. Let me update the logic:
Now let me add the course correction check for the end_turn case. Let me look at that section again:
Now let me run the typecheck to verify the changes:
Let me fix the errors. First let me find the correct function name for collecting guidance files:
I see - I need to use a different approach. Let me look at how to get guidance file content from the thread:
Let me look at how guidance files are extracted from threads more directly. Let me check how we can get the guidance file content directly from the user messages:
Let me look at the DiscoveredGuidanceFile type:
I see - DiscoveredGuidanceFile only has URI and line count, not content. Let me update the course-correction.ts to use a simpler approach that extracts guidance content directly from the thread messages:
Now let me add the missing documentation for the new setting:
Now let me run the typecheck again:
Let me fix this remaining error:
I see - 'default' is not a valid AgentMode value. Let me fix this:
Typecheck passes. Now let me run lint and format:
All checks pass. Now let me run the tests to make sure nothing is broken:
All tests pass. Let me update the todos:
I've implemented the course correction agent. Here's a summary of the changes:
Summary
New Files
- core/src/threads/course-correction.ts - The course correction agent that:
- Defines the
course_correcttool withneedsCorrection(boolean) andmessage(optional string) fields - Builds a system prompt instructing Gemini to detect when the main agent diverges from the plan
- Uses
runGeminiSyncwithGEMINI_3_PRO_PREVIEWmodel and forced tool calling - Extracts AGENTS.md content from the thread to include in the system prompt
- Defines the
Modified Files
- core/src/threads/thread.ts - Added
course-correctionas a new message source type - core/src/threads/thread-worker.ts - Added:
- Import for
runCourseCorrection courseCorrectionAbortController in opsrunCourseCorrectionCheck()method that calls the course correction agent- Integration points after tool completion (before inference) and on end_turn
- Import for
- core/src/configuration/settings.ts - Added
experimental.courseCorrection.enabledsetting - cli/src/docs.ts - Documented the new setting
How It Works
- Enabled via
experimental.courseCorrection.enabled: true - Runs in parallel after tool execution completes (before next inference)
- Runs on
end_turnwhen no queued messages exist - If
needsCorrectionis true, injects a user message withsource: { type: 'course-correction' }that steers the agent - The course correction message is visible in the thread and can be rendered differently in the UI