feat(agent): ✨ Add goal-driven plan approval action#230
Conversation
Add a new plan approval option "Set goal and implement" that creates a persistent goal before starting implementation, enabling the goal continuation loop to drive execution of approved plans. Previously, users could only approve plans for direct implementation or implementation with context reset. This adds a third option that: - Creates a persistent goal record via GoalManager before the run starts - Uses a simplified implementation prompt referencing the plan file path - Resets context similar to the context-reset action - Is only offered when the thread has no existing goal record - Supports review checkpoints following the plan at each stage The action is surfaced in both backend (Rust PlanApprovalAction enum and approval metadata construction) and frontend (TypeScript types, UI components, and i18n translations in English and Chinese).
AI Code Review SummaryPR: #230 (feat(agent): ✨ Add goal-driven plan approval action) Overall AssessmentDetected 2 actionable findings, prioritize CRITICAL/HIGH before merge. Major Findings by Severity
Actionable Suggestions
Potential Risks
Test Suggestions
File-Level Coverage Notes
Inline Downgraded Items (processed but not inline)
Coverage Status
Uncovered list:
No-patch covered list:
Runtime/Budget
|
| } | ||
| }; | ||
|
|
||
| // For ApplyPlanWithGoal: create a persistent goal before starting the |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
|
|
||
| // For ApplyPlanWithGoal: create a persistent goal before starting the | ||
| // implementation run so the goal continuation loop can drive execution. | ||
| if let PlanApprovalAction::ApplyPlanWithGoal = action { |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
| let plan_path = crate::core::plan_checkpoint::plan_file_path(thread_id) | ||
| .map(|p| p.display().to_string()) | ||
| .unwrap_or_default(); | ||
| format!( |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
|
|
||
| // Only offer the goal-driven option when the thread has no existing goal | ||
| // record (any status: active, paused, budget_limited, or complete). | ||
| if crate::persistence::repo::goal_repo::find_by_thread_id(pool, thread_id) |
This comment was marked as outdated.
This comment was marked as outdated.
Sorry, something went wrong.
…goal-exists approval branch
| } | ||
|
|
||
| pub fn build_approval_prompt_metadata( | ||
| pub async fn build_approval_prompt_metadata( |
There was a problem hiding this comment.
[MEDIUM] New async DB query on hot path without early return
Every plan approval prompt now performs an additional async database query to check for existing goals. While this is a lightweight lookup, it adds latency to the approval flow and could be avoided by caching or deferring the check.
Suggestion: Consider whether the goal-option visibility check can be performed only when the plan message is first built, or cache the existence of goals for the thread in memory. Alternatively, rely on the frontend to always send 'apply_plan_with_goal' and validate server-side only when the action is actually invoked.
Risk: Slight increase in plan approval prompt construction latency (~1-5 ms per DB roundtrip). Not significant for interactive use but adds up under concurrent load.
Confidence: 0.85
| const label = readStringField(optionRecord, "label"); | ||
| if ( | ||
| (action !== "apply_plan" && action !== "apply_plan_with_context_reset") | ||
| (action !== "apply_plan" && action !== "apply_plan_with_context_reset" && action !== "apply_plan_with_goal") |
There was a problem hiding this comment.
[LOW] Frontend data-path guard could miss new action values
The frontend validation regex is duplicated in three places within the same function (option action parsing, and two approvedAction checks), making it easy to miss one when adding new actions in the future.
Suggestion: Extract the valid action list into a constant set or array (e.g., const VALID_ACTIONS = new Set(['apply_plan', 'apply_plan_with_context_reset', 'apply_plan_with_goal'])) and use it for all validation points.
Risk: Future additions of another action could accidentally skip one of the validation branches, resulting in inconsistent behavior where options are allowed but approved actions are rejected or vice versa.
Confidence: 0.85
Summary
Test Plan
cargo test --locked --manifest-path src-tauri/Cargo.toml.npm run typecheck.🤖 Generated with TiyCode