Skip to content

feat(agent): add progress todo tool#1635

Open
zerob13 wants to merge 6 commits into
devfrom
feat/add-todo-progress
Open

feat(agent): add progress todo tool#1635
zerob13 wants to merge 6 commits into
devfrom
feat/add-todo-progress

Conversation

@zerob13
Copy link
Copy Markdown
Collaborator

@zerob13 zerob13 commented May 18, 2026

Summary

  • add an agent-core update_plan tool with strict plan validation and guidance
  • publish plan updates through chat.plan.updated without inserting todo blocks into the message list
  • add a default-collapsed animated progress float backed by a renderer plan store
  • document the SDD spec, plan, and tasks for the progress todo feature

Tests

  • pnpm run format
  • pnpm run i18n
  • pnpm run typecheck
  • pnpm run lint
  • pnpm exec vitest run test/main/presenter/agentRuntimePresenter/dispatch.test.ts test/renderer/components/AgentProgressFloat.test.ts test/renderer/stores/agentPlanStore.test.ts test/renderer/components/ChatPage.test.ts test/main/presenter/toolPresenter/agentTools/agentPlanTool.test.ts test/renderer/components/message/MessageBlockBasics.test.ts

Note: local Node is v22.13.1, while package engines request >=24.14.1 <25; commands completed with engine warnings.

Summary by CodeRabbit

  • New Features

    • Collapsible floating agent progress panel, richer in-message plan checklist, live revisioned plan snapshots and a tool-driven "update plan" workflow.
  • Bug Fixes

    • Prevented renderer crash from null/invalid assistant action types.
    • Internal progress updates are hidden from normal tool UI and message rendering.
  • Documentation

    • Added feature spec, implementation plan, tasks and crash spec with rollout and testing guidance.
  • Tests

    • Added/updated unit and UI tests for progress events, hydration, store behavior and rendering.

Review Change Stack

@coderabbitai
Copy link
Copy Markdown
Contributor

coderabbitai Bot commented May 18, 2026

📝 Walkthrough

<review_stack_artifact>

🚥 Pre-merge checks | ✅ 4 | ❌ 1

❌ Failed checks (1 warning)

Check name Status Explanation Resolution
Docstring Coverage ⚠️ Warning Docstring coverage is 0.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (4 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title 'feat(agent): add progress todo tool' directly and accurately summarizes the main change: adding a progress/todo tool for the agent feature.
Linked Issues check ✅ Passed Check skipped because no linked issues were found for this pull request.
Out of Scope Changes check ✅ Passed Check skipped because no linked issues were found for this pull request.

✏️ Tip: You can configure your own custom pre-merge checks in the settings.

✨ Finishing Touches
📝 Generate docstrings
  • Create stacked PR
  • Commit on current branch
🧪 Generate unit tests (beta)
  • Create PR with unit tests
  • Commit unit tests in branch feat/add-todo-progress

Warning

There were issues while running some tools. Please review the errors and either fix the tool's configuration or disable the tool if it's a critical failure.

🔧 ESLint

If the error stems from missing dependencies, add them to the package.json file. For unrecoverable errors (e.g., due to private dependencies), disable the tool in the CodeRabbit configuration.

ESLint skipped: no ESLint configuration detected in root package.json. To enable, add eslint to devDependencies.


Thanks for using CodeRabbit! It's free for OSS, and your support helps us grow. If you like it, consider giving us a shout-out.

❤️ Share

Comment @coderabbitai help to get the list of available commands and usage tips.

Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 4

🧹 Nitpick comments (1)
src/main/presenter/agentRuntimePresenter/dispatch.ts (1)

362-363: ⚡ Quick win

Use shared tool-name constant instead of string literal.

Line 362 hardcodes 'update_plan'; this can drift from the source constant and silently stop internal plan-block marking if renamed.

♻️ Suggested patch
-import type { AgentPlanSnapshot } from '`@shared/types/agent-plan`'
+import type { AgentPlanSnapshot } from '`@shared/types/agent-plan`'
+import { UPDATE_PLAN_TOOL_NAME } from '../toolPresenter/agentTools'

 function markInternalPlanToolCallBlock(blocks: AssistantMessageBlock[], toolCallId: string): void {
@@
-  if (!block?.tool_call || block.tool_call.name !== 'update_plan') {
+  if (!block?.tool_call || block.tool_call.name !== UPDATE_PLAN_TOOL_NAME) {
     return
   }
🤖 Prompt for AI Agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

In `@src/main/presenter/agentRuntimePresenter/dispatch.ts` around lines 362 - 363,
The conditional currently compares block.tool_call.name to the hardcoded string
'update_plan'; change it to use the centralized tool-name constant exported by
the tools module (e.g. UPDATE_PLAN_TOOL_NAME or the exported symbol that
represents the update-plan tool) instead, updating the import at the top of
dispatch.ts and replacing the literal in the if check that references
block?.tool_call and block.tool_call.name so the code always uses the shared
constant.
🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/features/agent-progress-todo/plan.md`:
- Line 175: The doc currently contradicts the architecture by calling the
renderer store / event `chat.plan.updated` canonical while line 175 instructs to
keep the message block as canonical; update the wording so the message block is
explicitly the single source-of-truth for DeepChat progress state and describe
`chat.plan.updated` and the renderer store as derived/secondary views used for
UI rendering and fallback only; change the sentence at line 175 to state the
floating panel should be collapsed by default and that the message block is
canonical, and scan other mentions of `chat.plan.updated` and "renderer store"
to rephrase them as derived or fallback mechanisms to avoid implementation
drift.

In `@docs/features/agent-progress-todo/spec.md`:
- Line 7: Replace the machine-specific absolute path
`/Users/zerob13/Downloads/agent-progress-todo-spec.md` in
docs/features/agent-progress-todo/spec.md with a portable reference: either a
repo-relative path (e.g.,
docs/features/agent-progress-todo/agent-progress-todo-spec.md) or a generic
external-note like "see agent-progress-todo-spec.md in project docs"; keep the
`update_plan` mention and any other identifiers unchanged so reviewers can still
find the referenced model behavior.

In `@src/renderer/src/components/chat/AgentProgressFloat.vue`:
- Line 43: Replace the hardcoded ARIA label construction in
AgentProgressFloat.vue that directly interpolates entry.status and entry.step
with the vue-i18n translation lookup; map the possible status tokens (e.g.,
in_progress, completed, failed) to i18n keys in src/renderer/src/i18n and build
the aria-label via $t(...) (or the composable useI18n) so aria-label uses
translated status text and the translated step label rather than raw tokens
(refer to entry.status, entry.step and the :aria-label binding when making the
change).

In `@src/renderer/src/components/message/MessageBlockPlan.vue`:
- Line 31: The aria-label currently hardcodes "[${entry.status}] ${entry.label}"
in MessageBlockPlan.vue; replace this with a vue-i18n lookup that composes a
localized message and localized status label (e.g. use a key like
message.planEntryAria with params { status: $t(`status.${entry.status}`), label:
entry.label }) and ensure corresponding i18n keys exist in src/renderer/src/i18n
(message.planEntryAria and status.<statusName> entries); implement the lookup
either inline in the template using $t or via a computed property (referencing
entry.status and entry.label) so assistive text is fully translatable.

---

Nitpick comments:
In `@src/main/presenter/agentRuntimePresenter/dispatch.ts`:
- Around line 362-363: The conditional currently compares block.tool_call.name
to the hardcoded string 'update_plan'; change it to use the centralized
tool-name constant exported by the tools module (e.g. UPDATE_PLAN_TOOL_NAME or
the exported symbol that represents the update-plan tool) instead, updating the
import at the top of dispatch.ts and replacing the literal in the if check that
references block?.tool_call and block.tool_call.name so the code always uses the
shared constant.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 98d1b010-58bd-466c-8884-b50bff61bebc

📥 Commits

Reviewing files that changed from the base of the PR and between 2b8816d and d3b4622.

📒 Files selected for processing (38)
  • docs/features/agent-progress-todo/plan.md
  • docs/features/agent-progress-todo/spec.md
  • docs/features/agent-progress-todo/tasks.md
  • docs/issues/assistant-action-type-null-renderer-crash/plan.md
  • docs/issues/assistant-action-type-null-renderer-crash/spec.md
  • docs/issues/assistant-action-type-null-renderer-crash/tasks.md
  • src/main/presenter/agentRuntimePresenter/dispatch.ts
  • src/main/presenter/agentRuntimePresenter/messageStore.ts
  • src/main/presenter/toolPresenter/agentTools/agentPlanTool.ts
  • src/main/presenter/toolPresenter/agentTools/agentToolManager.ts
  • src/main/presenter/toolPresenter/agentTools/index.ts
  • src/main/presenter/toolPresenter/index.ts
  • src/renderer/api/ChatClient.ts
  • src/renderer/src/components/chat/AgentProgressFloat.vue
  • src/renderer/src/components/chat/messageListItems.ts
  • src/renderer/src/components/message/MessageBlockPlan.vue
  • src/renderer/src/components/message/MessageItemAssistant.vue
  • src/renderer/src/pages/ChatPage.vue
  • src/renderer/src/stores/ui/agentPlan.ts
  • src/shared/chat.d.ts
  • src/shared/contracts/common.ts
  • src/shared/contracts/events.ts
  • src/shared/contracts/events/chat.events.ts
  • src/shared/types/agent-interface.d.ts
  • src/shared/types/agent-plan.ts
  • src/shared/types/core/chat.ts
  • src/shared/types/presenters/tool.presenter.d.ts
  • test/main/presenter/agentRuntimePresenter/dispatch.test.ts
  • test/main/presenter/agentRuntimePresenter/messageStore.test.ts
  • test/main/presenter/toolPresenter/agentTools/agentPlanTool.test.ts
  • test/main/presenter/toolPresenter/toolPresenter.test.ts
  • test/main/routes/contracts.test.ts
  • test/renderer/api/clients.test.ts
  • test/renderer/components/AgentProgressFloat.test.ts
  • test/renderer/components/ChatPage.test.ts
  • test/renderer/components/McpIndicator.test.ts
  • test/renderer/components/message/MessageBlockBasics.test.ts
  • test/renderer/stores/agentPlanStore.test.ts

Comment thread docs/features/agent-progress-todo/plan.md Outdated
Comment thread docs/features/agent-progress-todo/spec.md Outdated
Comment thread src/renderer/src/components/chat/AgentProgressFloat.vue Outdated
Comment thread src/renderer/src/components/message/MessageBlockPlan.vue Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@docs/features/agent-progress-todo/spec.md`:
- Line 60: The line claiming the floating panel "retains persistent records in
messages" conflicts with the rule that update_plan must not write plan blocks
into assistant messages; reword it to state that the floating progress panel
provides a lightweight, collapsible UI that shows real-time progress while
persisting state outside of assistant messages (e.g., in the UI
state/storage/logging), and explicitly reference update_plan and "plan" blocks
to clarify they must not be injected into assistant messages.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: 53fa7856-c354-42d1-8ea5-0671bdd62064

📥 Commits

Reviewing files that changed from the base of the PR and between d3b4622 and 3a7cd0d.

📒 Files selected for processing (19)
  • docs/features/agent-progress-todo/plan.md
  • docs/features/agent-progress-todo/spec.md
  • src/main/presenter/agentRuntimePresenter/dispatch.ts
  • src/renderer/src/components/chat/AgentProgressFloat.vue
  • src/renderer/src/components/message/MessageBlockPlan.vue
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/en-US/chat.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/pt-BR/chat.json
  • src/renderer/src/i18n/ru-RU/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/zh-TW/chat.json
  • test/renderer/components/AgentProgressFloat.test.ts
  • test/renderer/components/message/MessageBlockBasics.test.ts
✅ Files skipped from review due to trivial changes (8)
  • src/renderer/src/i18n/he-IL/chat.json
  • src/renderer/src/i18n/ja-JP/chat.json
  • src/renderer/src/i18n/ko-KR/chat.json
  • src/renderer/src/i18n/zh-HK/chat.json
  • src/renderer/src/i18n/fa-IR/chat.json
  • src/renderer/src/i18n/zh-CN/chat.json
  • src/renderer/src/i18n/da-DK/chat.json
  • src/renderer/src/i18n/fr-FR/chat.json
🚧 Files skipped from review as they are similar to previous changes (5)
  • src/renderer/src/components/chat/AgentProgressFloat.vue
  • test/renderer/components/AgentProgressFloat.test.ts
  • test/renderer/components/message/MessageBlockBasics.test.ts
  • src/renderer/src/components/message/MessageBlockPlan.vue
  • src/main/presenter/agentRuntimePresenter/dispatch.ts

Comment thread docs/features/agent-progress-todo/spec.md Outdated
Copy link
Copy Markdown
Contributor

@coderabbitai coderabbitai Bot left a comment

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Actionable comments posted: 1

🤖 Prompt for all review comments with AI agents
Verify each finding against current code. Fix only still-valid issues, skip the
rest with a brief reason, keep changes minimal, and validate.

Inline comments:
In `@src/renderer/src/pages/ChatPage.vue`:
- Around line 283-294: syncPlanFloatReservedHeight currently uses only the
trigger's offsetHeight which causes the expanded plan body to overlap messages;
modify syncPlanFloatReservedHeight to reserve the full floating panel height by
using the layer's full offsetHeight (or, if there is an expanded-inner element,
query its offsetHeight) instead of just the trigger height, then add
PLAN_FLOAT_SAFE_GAP and set planFloatReservedHeight.value accordingly; reference
planFloatLayer, latestPlanSnapshot, syncPlanFloatReservedHeight,
PLAN_FLOAT_SAFE_GAP and planFloatReservedHeight when making the change.
🪄 Autofix (Beta)

Fix all unresolved CodeRabbit comments on this PR:

  • Push a commit to this branch (recommended)
  • Create a new PR with the fixes

ℹ️ Review info
⚙️ Run configuration

Configuration used: defaults

Review profile: CHILL

Plan: Pro

Run ID: e801c8b2-513d-4b2b-b84b-02314f867667

📥 Commits

Reviewing files that changed from the base of the PR and between 1eef9b5 and 4f1bfe2.

📒 Files selected for processing (3)
  • src/renderer/src/components/chat/AgentProgressFloat.vue
  • src/renderer/src/pages/ChatPage.vue
  • test/renderer/components/ChatPage.test.ts
🚧 Files skipped from review as they are similar to previous changes (1)
  • test/renderer/components/ChatPage.test.ts

Comment thread src/renderer/src/pages/ChatPage.vue
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment

Labels

None yet

Projects

None yet

Development

Successfully merging this pull request may close these issues.

2 participants