Skip to content

fix: duplicate agent name reset and missing group inheritance#833

Open
pedramamini wants to merge 3 commits intomainfrom
fix/827-duplicate-agent-name-and-group
Open

fix: duplicate agent name reset and missing group inheritance#833
pedramamini wants to merge 3 commits intomainfrom
fix/827-duplicate-agent-name-and-group

Conversation

@pedramamini
Copy link
Copy Markdown
Collaborator

@pedramamini pedramamini commented Apr 13, 2026

Summary

Fixes two bugs in the duplicate agent flow reported in #827:

  • Name reverts to "(Copy)" on save: The useEffect in NewInstanceModal depended on the full sourceSession object. When the sessions store updated during modal interaction, sourceSession got a new reference, re-fired the effect, and overwrote the user's typed name with {name} (Copy). Fixed by depending on sourceSession?.id instead.
  • Group not inherited: sourceSession.groupId was never passed through the duplication call chain. Threaded groupId from sourceSession through handleCreateonCreateonCreateSessioncreateNewSession so the duplicated agent lands in the same group.

Test plan

  • All 72 NewInstanceModal tests pass (updated 7 assertions for new groupId parameter)
  • npm run lint passes
  • npm run test passes (22444 tests)
  • Manual: Duplicate an agent, edit the name, click Create — name should persist
  • Manual: Duplicate an agent that belongs to a group — new agent should appear in the same group

Closes #827

Summary by CodeRabbit

  • Documentation

    • Reformatted release notes for improved readability with standard Markdown formatting.
  • Tests

    • Updated session creation modal test assertions.

Fix two bugs in the duplicate agent flow:

1. Name reverts to "(Copy)" on save: The useEffect depended on the full
   sourceSession object, which gets a new reference on any sessions store
   update, re-triggering the pre-fill and overwriting the user's typed name.
   Changed dependency to sourceSession?.id so it only fires when the
   identity changes.

2. Group not inherited: sourceSession.groupId was never threaded through
   the duplication flow. Added groupId parameter to onCreate, onCreateSession,
   and createNewSession, passing sourceSession?.groupId from handleCreate.

Closes #827
@coderabbitai
Copy link
Copy Markdown

coderabbitai Bot commented Apr 13, 2026

📝 Walkthrough

Walkthrough

This PR fixes two bugs in the agent duplication flow: (1) corrects a modal effect dependency to prevent form values from reverting when the sessions store updates, and (2) threads groupId through the duplication call chain so duplicated agents inherit their source agent's group.

Changes

Cohort / File(s) Summary
Documentation Formatting
docs/releases.md
Reformats file by replacing Windows-style line endings and mixed list markers with standard Markdown syntax; content unchanged.
Public API Signatures
src/renderer/components/AppModals.tsx
Extends onCreateSession callback type in AppSessionModalsProps and AppModalsProps with optional groupId?: string parameter.
Core Implementation
src/renderer/components/NewInstanceModal.tsx, src/renderer/hooks/session/useSessionCrud.ts
Adds optional groupId?: string parameter to session creation, passes sourceSession?.groupId during duplication, and fixes modal effect dependency from sourceSession to sourceSessionId to prevent unintended re-fills.
Test Assertions
src/__tests__/renderer/components/NewInstanceModal.test.tsx
Updates onCreate call assertions to include final undefined argument matching new callback signature.

Estimated code review effort

🎯 3 (Moderate) | ⏱️ ~20 minutes

Possibly related PRs

Suggested labels

ready to merge

Poem

🐰 A copy once made lost its way,
Forgetting home where it would stay,
But now the group flows true and right,
And names stay put—what sweet delight!
No more rewrites when sessions bloom,
Just peaceful dupes throughout the room. 🌱

🚥 Pre-merge checks | ✅ 3 | ❌ 2

❌ Failed checks (2 warnings)

Check name Status Explanation Resolution
Out of Scope Changes check ⚠️ Warning The changes include a formatting fix to docs/releases.md that is unrelated to the linked issue #827 requirements for bug fixes. Remove the docs/releases.md formatting changes or address them in a separate pull request focused on documentation updates.
Docstring Coverage ⚠️ Warning Docstring coverage is 50.00% which is insufficient. The required threshold is 80.00%. Write docstrings for the functions missing them to satisfy the coverage threshold.
✅ Passed checks (3 passed)
Check name Status Explanation
Description Check ✅ Passed Check skipped - CodeRabbit’s high-level summary is enabled.
Title check ✅ Passed The title accurately summarizes the main fixes: preventing the name reset bug and ensuring group inheritance in the duplicate agent flow.
Linked Issues check ✅ Passed All requirements from issue #827 are met: the effect dependency changed to sourceSession?.id (Bug 1), and groupId is threaded through NewInstanceModal, AppModals, and useSessionCrud (Bug 2).

✏️ 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 fix/827-duplicate-agent-name-and-group

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.

@greptile-apps
Copy link
Copy Markdown

greptile-apps Bot commented Apr 13, 2026

Greptile Summary

This PR fixes two bugs in the duplicate-agent flow: a useEffect in NewInstanceModal was depending on the full sourceSession object (causing the name field to reset whenever the sessions store emitted updates), and groupId was never threaded through the duplication call chain so duplicated agents always landed outside any group. Both fixes are targeted and correct.

Confidence Score: 5/5

Safe to merge — both bugs are correctly fixed and all findings are P2 (style/coverage) that don't block the changes.

Both root causes are correctly addressed: the useEffect dependency is narrowed to sourceSession?.id and groupId is properly threaded through the full call chain. The only findings are a missing useCallback dependency (stale closure that can't produce a visible bug today) and a missing test case for groupId forwarding. All 72 modal tests pass.

src/renderer/components/NewInstanceModal.tsx — handleCreate deps array is missing sourceSession.

Important Files Changed

Filename Overview
src/renderer/components/NewInstanceModal.tsx Core fix: useEffect now depends on sourceSession?.id instead of the full object, preventing name reset on store updates; handleCreate passes sourceSession?.groupId to onCreate — minor: sourceSession missing from handleCreate deps array.
src/renderer/hooks/session/useSessionCrud.ts groupId already existed as last parameter of createNewSession and is correctly assigned to the new session object; threading confirmed, no issues.
src/renderer/components/AppModals.tsx sourceSession correctly derived via useMemo from duplicatingSessionId + sessions and passed to AppSessionModals; onCreateSession type updated to include groupId.
src/tests/renderer/components/NewInstanceModal.test.tsx 7 existing assertions updated to include the new groupId (undefined) argument; missing a test that verifies groupId is forwarded when sourceSession.groupId is set.
docs/releases.md Whitespace-only formatting changes (blank lines added between sections); no content changes.

Sequence Diagram

sequenceDiagram
    participant U as User
    participant NIM as NewInstanceModal
    participant AM as AppModals
    participant CRUD as useSessionCrud
    participant Store as sessionStore

    U->>AM: click "Duplicate Agent"
    AM->>AM: useMemo sourceSession from sessions.find(id)
    AM->>NIM: sourceSession prop
    NIM->>NIM: sourceSessionId = sourceSession?.id
    NIM->>NIM: useEffect([isOpen, sourceSessionId]): loadAgents(sourceSession)
    Note over NIM: Pre-fills name as "{name} (Copy)",<br/>workingDir, agentType from sourceSession

    Store-->>AM: sessions update (new reference)
    AM->>AM: useMemo re-runs, sourceSession same id
    AM->>NIM: new sourceSession reference, same id
    Note over NIM: useEffect does NOT re-fire<br/>(sourceSessionId unchanged)<br/>User's typed name is preserved

    U->>NIM: click "Create Agent"
    NIM->>NIM: handleCreate() reads sourceSession?.groupId
    NIM->>AM: onCreate(agentId, dir, name, ..., groupId)
    AM->>CRUD: onCreateSession(agentId, dir, name, ..., groupId)
    CRUD->>Store: setSessions([...prev, newSession{groupId}])
    Note over Store: Duplicated agent lands in same group
Loading

Comments Outside Diff (2)

  1. src/renderer/components/NewInstanceModal.tsx, line 500-515 (link)

    P2 Missing sourceSession in handleCreate dependency array

    handleCreate accesses sourceSession?.groupId (line 483) but sourceSession is absent from its useCallback dependency array. If the sessions store emits an update while the modal is open, AppModals recomputes sourceSession via useMemo and passes a new prop reference to NewInstanceModal. Because sourceSession is not in deps, handleCreate keeps the stale closure from the previous render.

    In practice the groupId of the source session is stable during modal interaction, so this won't cause an observable bug today. But it violates React's exhaustive-deps contract and will suppress any lint warning that would otherwise catch a regression here.

  2. src/__tests__/renderer/components/NewInstanceModal.test.tsx, line 2150 (link)

    P2 No test verifying groupId is forwarded when source session has one

    The existing duplication tests check that onCreate is called with undefined for groupId when no sourceSession is provided (the 12th argument in the updated assertions). There is no test that renders the modal with a sourceSession that has a groupId and then asserts onCreate was called with that value.

    Consider adding a case like:

    it('should pass sourceSession.groupId to onCreate', async () => {
      const sourceSession = {
        ...minimalSession,
        groupId: 'group-abc',
      } as Session;
    
      // render, fill required fields, click Create ...
    
      expect(onCreate).toHaveBeenCalledWith(
        expect.any(String), // agentId
        expect.any(String), // workingDir
        expect.any(String), // name
        undefined, undefined, undefined, undefined, undefined, undefined, undefined,
        expect.any(Object), // sessionSshRemoteConfig
        'group-abc'         // groupId should be forwarded
      );
    });

Reviews (1): Last reviewed commit: "style: format docs/releases.md with pret..." | Re-trigger Greptile

Copy link
Copy Markdown

@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: 2

Caution

Some comments are outside the diff and can’t be posted inline due to platform limitations.

⚠️ Outside diff range comments (1)
src/renderer/components/NewInstanceModal.tsx (1)

471-484: ⚠️ Potential issue | 🟡 Minor

handleCreate can capture a stale groupId.

Line 483 reads sourceSession?.groupId, but sourceSession is not in the useCallback dependency list (lines 500–515). Since sourceSession is a prop that may change while the modal is open, the callback will use a stale group ID if the source session updates.

💡 Suggested fix
+	const sourceGroupId = sourceSession?.groupId;
+
 	const handleCreate = React.useCallback(() => {
 		...
 		onCreate(
 			selectedAgent,
 			expandedWorkingDir,
 			name,
 			nudgeMessage.trim() || undefined,
 			agentCustomPath,
 			agentCustomArgs,
 			agentCustomEnvVars,
 			agentCustomModel,
 			agentCustomContextWindow,
 			agentCustomProviderPath,
 			sessionSshRemoteConfig,
-			sourceSession?.groupId
+			sourceGroupId
 		);
 		...
 	}, [
 		instanceName,
 		selectedAgent,
 		workingDir,
 		nudgeMessage,
 		customAgentPaths,
 		customAgentArgs,
 		customAgentEnvVars,
 		agentConfigs,
 		agentSshRemoteConfigs,
 		onCreate,
 		onClose,
 		expandTilde,
 		handleWorkingDirChange,
 		existingSessions,
+		sourceGroupId,
 	]);
🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@src/renderer/components/NewInstanceModal.tsx` around lines 471 - 484,
handleCreate captures a stale sourceSession.groupId because sourceSession isn't
listed in the useCallback dependencies; update the useCallback that defines
handleCreate to include sourceSession (or at minimum sourceSession?.groupId) in
its dependency array so onCreate(...) is invoked with the current groupId,
ensuring handleCreate uses the latest sourceSession when calling onCreate.
🧹 Nitpick comments (1)
docs/releases.md (1)

20-20: Use nested heading levels within release sections

These headings are currently # (H1) inside sectioned content. Please switch them to ### (or #### where appropriate) to preserve Markdown hierarchy and avoid TOC/anchor structure regressions.

Also applies to: 80-80, 143-143, 147-147, 151-151, 176-176, 268-268, 276-276, 286-286, 291-291, 297-297

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/releases.md` at line 20, Several release-section headings (e.g., the
"Major 0.15.x Additions" heading and the other release headings referenced) are
using top-level H1 (#) inside the releases document; change those headings to
nested levels (use ### or #### as appropriate) to preserve markdown hierarchy
and TOC anchors—scan the releases.md for headings that are currently single '#'
within release sections and replace them with the correct subheading level
(prefer ### for section titles, use #### for sub-subsections) so the document
structure is consistent.
🤖 Prompt for all review comments with AI agents
Verify each finding against the current code and only fix it if needed.

Inline comments:
In `@docs/releases.md`:
- Line 74: Fix two visible typos in the release notes: replace the incorrect
capitalized token "FIle" in the sentence starting with "🗄️ Document Graphs.
Launch from file preview..." with "File", and correct the version string "014.x"
to "0.14.x" wherever it appears (notably the occurrence around line 80). Ensure
both replacements preserve surrounding punctuation and capitalization in the
release note text.
- Line 22: Standardize wording in the release notes: replace any occurrence of
"Github" with "GitHub", pick one consistent form for "pre-release"/"prerelease"
and apply it everywhere, and hyphenate compound modifiers such as "open-source",
"cross-context", and "built-in" (e.g., in the "Maestro Symphony" blurb and other
instances). Search for the literal strings "Github", "pre-release"/"prerelease",
"open source"/"open-source", "cross context"/"cross-context", and "built
in"/"built-in" and update them to the chosen, consistent spellings across the
document.

---

Outside diff comments:
In `@src/renderer/components/NewInstanceModal.tsx`:
- Around line 471-484: handleCreate captures a stale sourceSession.groupId
because sourceSession isn't listed in the useCallback dependencies; update the
useCallback that defines handleCreate to include sourceSession (or at minimum
sourceSession?.groupId) in its dependency array so onCreate(...) is invoked with
the current groupId, ensuring handleCreate uses the latest sourceSession when
calling onCreate.

---

Nitpick comments:
In `@docs/releases.md`:
- Line 20: Several release-section headings (e.g., the "Major 0.15.x Additions"
heading and the other release headings referenced) are using top-level H1 (#)
inside the releases document; change those headings to nested levels (use ### or
#### as appropriate) to preserve markdown hierarchy and TOC anchors—scan the
releases.md for headings that are currently single '#' within release sections
and replace them with the correct subheading level (prefer ### for section
titles, use #### for sub-subsections) so the document structure is consistent.
🪄 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: Path: .coderabbit.yaml

Review profile: CHILL

Plan: Pro

Run ID: b2ab28d3-a934-49e7-b954-406e163ca8f7

📥 Commits

Reviewing files that changed from the base of the PR and between 94ccdf8 and e5dcdb3.

📒 Files selected for processing (5)
  • docs/releases.md
  • src/__tests__/renderer/components/NewInstanceModal.test.tsx
  • src/renderer/components/AppModals.tsx
  • src/renderer/components/NewInstanceModal.tsx
  • src/renderer/hooks/session/useSessionCrud.ts

Comment thread docs/releases.md
- **Default worktree directory:** Worktree configuration now defaults to the parent of the agent's working directory instead of blank
# Major 0.15.x Additions

🎶 **Maestro Symphony** — Contribute to open source with AI assistance! Browse curated issues from projects with the `runmaestro.ai` label, clone repos with one click, and automatically process the relevant Auto Run playbooks. Track your contributions, streaks, and stats. You're contributing CPU and tokens towards your favorite open source projects and features.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Standardize wording and product spelling for consistency

Please normalize a few terms for consistency/readability:

  • Line 174: GithubGitHub
  • Line 239: choose one form and keep it consistent (pre-release vs prerelease)
  • Line 22 / Line 63 / Line 149: hyphenate compound modifiers where needed (open-source, cross-context, built-in).

Also applies to: 63-63, 149-149, 174-174, 239-239

🧰 Tools
🪛 LanguageTool

[grammar] ~22-~22: Use a hyphen to join words.
Context: ...PU and tokens towards your favorite open source projects and features. 🎬 **Dire...

(QB_NEW_EN_HYPHEN)

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/releases.md` at line 22, Standardize wording in the release notes:
replace any occurrence of "Github" with "GitHub", pick one consistent form for
"pre-release"/"prerelease" and apply it everywhere, and hyphenate compound
modifiers such as "open-source", "cross-context", and "built-in" (e.g., in the
"Maestro Symphony" blurb and other instances). Search for the literal strings
"Github", "pre-release"/"prerelease", "open source"/"open-source", "cross
context"/"cross-context", and "built in"/"built-in" and update them to the
chosen, consistent spellings across the document.

Comment thread docs/releases.md

The major contributions to 0.14.x remain:

🗄️ Document Graphs. Launch from file preview or from the FIle tree panel. Explore relationships between Markdown documents that contain links between documents and to URLs.
Copy link
Copy Markdown

Choose a reason for hiding this comment

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

⚠️ Potential issue | 🟡 Minor

Fix visible typos in release notes

There are two user-facing typos: Line 74 uses FIle and Line 80 uses 014.x (missing dot after zero). These should be corrected for release-note quality.

Also applies to: 80-80

🤖 Prompt for AI Agents
Verify each finding against the current code and only fix it if needed.

In `@docs/releases.md` at line 74, Fix two visible typos in the release notes:
replace the incorrect capitalized token "FIle" in the sentence starting with
"🗄️ Document Graphs. Launch from file preview..." with "File", and correct the
version string "014.x" to "0.14.x" wherever it appears (notably the occurrence
around line 80). Ensure both replacements preserve surrounding punctuation and
capitalization in the release note text.

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.

[Bug] Duplicate agent: renamed name reverts to "(Copy)" on save, and group is not inherited

1 participant